diff options
| author | Tomas Bzatek <tbzatek@users.sourceforge.net> | 2008-06-07 20:40:48 +0200 |
|---|---|---|
| committer | Tomas Bzatek <tbzatek@users.sourceforge.net> | 2008-06-07 20:40:48 +0200 |
| commit | a0f1e0e9db4b0edee45018c47a08761916af0ce6 (patch) | |
| tree | dc9d05f5772442f61ec913631540b24cf67d5e8a | |
| parent | ecde167da74c86bc047aaf84c5e548cf65a5da98 (diff) | |
| download | tuxcmd-a0f1e0e9db4b0edee45018c47a08761916af0ce6.tar.xz | |
Revised UTF-8 filenames supportv0.6.38
| -rw-r--r-- | UChecksum.pas | 71 | ||||
| -rw-r--r-- | UChecksumDruid.pas | 62 | ||||
| -rw-r--r-- | UChmod.pas | 6 | ||||
| -rw-r--r-- | UChown.pas | 38 | ||||
| -rw-r--r-- | UColumns.pas | 1 | ||||
| -rw-r--r-- | UConfig.pas | 14 | ||||
| -rw-r--r-- | UConnectionProperties.pas | 34 | ||||
| -rw-r--r-- | UCore.pas | 266 | ||||
| -rw-r--r-- | UCoreClasses.pas | 12 | ||||
| -rw-r--r-- | UCoreUtils.pas | 153 | ||||
| -rw-r--r-- | UEngines.pas | 47 | ||||
| -rw-r--r-- | UFileAssoc.pas | 4 | ||||
| -rw-r--r-- | UFileTypeSettings.pas | 16 | ||||
| -rw-r--r-- | UGnome.pas | 25 | ||||
| -rw-r--r-- | UMain.pas | 323 | ||||
| -rw-r--r-- | UMounterPrefs.pas | 20 | ||||
| -rw-r--r-- | UOverwrite.pas | 34 | ||||
| -rw-r--r-- | UPreferences.pas | 14 | ||||
| -rw-r--r-- | USearch.pas | 28 | ||||
| -rw-r--r-- | UTestPlugin.pas | 2 | ||||
| -rw-r--r-- | UToolTips.pas | 2 | ||||
| -rw-r--r-- | UViewer.pas | 14 | ||||
| -rw-r--r-- | vfs/UVFSCore.pas | 11 | ||||
| -rw-r--r-- | vfs/uVFSprototypes.pas | 5 |
24 files changed, 685 insertions, 517 deletions
diff --git a/UChecksum.pas b/UChecksum.pas index 895f7ec..5f0e4db 100644 --- a/UChecksum.pas +++ b/UChecksum.pas @@ -1,28 +1,28 @@ (* Tux Commander - UChecksum - Checksum dialog - Copyright (C) 2004 Tomas Bzatek <tbzatek@users.sourceforge.net>
- Check for updates on tuxcmd.sourceforge.net
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Copyright (C) 2004 Tomas Bzatek <tbzatek@users.sourceforge.net> + Check for updates on tuxcmd.sourceforge.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *) unit UChecksum; interface uses - glib2, gdk2, gtk2, SysUtils, Types, Classes, Variants, GTKControls, GTKForms, GTKStdCtrls, GTKExtCtrls, GTKConsts, GTKView, GTKText, + glib2, gdk2, gtk2, pango, SysUtils, Types, Classes, Variants, GTKControls, GTKForms, GTKStdCtrls, GTKExtCtrls, GTKConsts, GTKView, GTKText, UEngines; type @@ -154,6 +154,7 @@ begin CommentTextView := TGTKTextView.Create(Self); CommentTextView.ReadOnly := True; CommentTextView.CursorVisible := True; + gtk_widget_modify_font(CommentTextView.FWidget, pango_font_description_from_string('Monospace')) end; procedure TFChecksum.FormDestroy(Sender: TObject); @@ -205,10 +206,10 @@ begin Result := False; Stat := Engine.GetFileInfoSL(FileName); if (Stat.Size > 128*1024) then begin - i := integer(Application.MessageBox(Format(LANGTheFileSYouAreTryingToOpenIsQuiteBig, [ANSIToUTF8(ExtractFileName(FileName))]), [mbYes, mbNo], mbWarning, mbNone, mbNo)); + i := integer(Application.MessageBox(Format(LANGTheFileSYouAreTryingToOpenIsQuiteBig, [StrToUTF8(ExtractFileName(FileName))]), [mbYes, mbNo], mbWarning, mbNone, mbNo)); if (i = integer(mbNo)) or (i = 251) then Exit; end; - IsMD5 := (Pos('MD5', ANSIUpperCase(FileName)) > 0) or ((Pos('SFV', ANSIUpperCase(FileName)) = 0) and (Pos('SUM', ANSIUpperCase(FileName)) > 0)); + IsMD5 := (Pos('MD5', WideUpperCase(FileName)) > 0) or ((Pos('SFV', WideUpperCase(FileName)) = 0) and (Pos('SUM', WideUpperCase(FileName)) > 0)); if IsMD5 then MD5Present := True else SFVPresent := True; if MD5Present and SFVPresent then FileList.Columns[1].Caption := 'CRC32/MD5' @@ -222,9 +223,10 @@ begin Application.MessageBox(LANGAnErrorOccuredWhileInitializingMemoryBlock, [mbOK], mbError, mbNone, mbOK); Exit; end; + Error := 0; FD := Engine.OpenFile(FileName, omRead, Error); if Error <> 0 then begin - Application.MessageBox(Format(LANGAnErrorOccuredWhileOpeningFileSS, [ANSIToUTF8(ExtractFileName(FileName)), ANSIToUTF8(GetErrorString(Error))]), [mbOK], mbError, mbNone, mbOK); + Application.MessageBox(Format(LANGAnErrorOccuredWhileOpeningFileSS, [StrToUTF8(ExtractFileName(FileName)), GetErrorString(Error)]), [mbOK], mbError, mbNone, mbOK); Libc.free(Buffer); Exit; end; @@ -233,7 +235,7 @@ begin repeat Count := Engine.ReadFile(FD, Buffer, ChksumBlockSize, Error); if Error <> 0 then begin - Application.MessageBox(Format(LANGAnErrorOccuredWhileReadingFileSS, [ANSIToUTF8(ExtractFileName(FileName)), ANSIToUTF8(GetErrorString(Error))]), [mbOK], mbError, mbNone, mbOK); + Application.MessageBox(Format(LANGAnErrorOccuredWhileReadingFileSS, [StrToUTF8(ExtractFileName(FileName)), GetErrorString(Error)]), [mbOK], mbError, mbNone, mbOK); Engine.CloseFile(FD); Libc.free(Buffer); Exit; @@ -275,10 +277,10 @@ begin if CommentTextView.TextBuffer.LineCount > 1 then begin s1 := ''; for i := 1 to 50 do s1 := s1 + Chr($2212); - CommentTextView.TextBuffer.InsertText(s1 + #13); + CommentTextView.TextBuffer.InsertText(StrToUTF8(s1 + #13)); end; end; - CommentTextView.TextBuffer.InsertText(ANSIToUTF8(Copy(s, 2, Length(s) - 1) + #13)); + CommentTextView.TextBuffer.InsertText(StrToUTF8(Copy(s, 2, Length(s) - 1) + #13)); end else begin Trim(s); if Pos(' ', s) = 0 then Exit; @@ -326,13 +328,13 @@ begin if not Application.GTKVersion_2_0_5_Up then gtk_tree_model_get(tree_model, iter, 0, @Data, -1) else begin Path := gtk_tree_model_get_path(tree_model, iter); - if not Assigned(Path) then Exit;
- (Sender as TGTKListView).ConvertPathToChild(Path);
- Data := List[gtk_tree_path_get_indices(Path)^];
- gtk_tree_path_free(Path);
- end;
+ if not Assigned(Path) then Exit; + (Sender as TGTKListView).ConvertPathToChild(Path); + Data := List[gtk_tree_path_get_indices(Path)^]; + gtk_tree_path_free(Path); + end; case gtk_tree_view_column_get_sort_column_id(tree_column) of - 0: g_object_set(cell, 'text', PChar(Format('[%s] %s', [StatusStr[Data.Status], ANSIToUTF8(Data.Name)])), nil); + 0: g_object_set(cell, 'text', StrToUTF8(PChar(Format('[%s] %s', [StatusStr[Data.Status], Data.Name]))), nil); -1: if not Data.IsMD5 then g_object_set(cell, 'text', PChar('0x' + IntToHex(Data.CRC, 8)), nil) else g_object_set(cell, 'text', PChar(Data.MD5), nil); end; @@ -348,12 +350,12 @@ begin gtk_tree_model_get(model, b, 0, @Data2, -1); end else begin Path := gtk_tree_model_get_path(model, a); - if not Assigned(Path) then Exit;
- Data1 := List[gtk_tree_path_get_indices(Path)^];
+ if not Assigned(Path) then Exit; + Data1 := List[gtk_tree_path_get_indices(Path)^]; gtk_tree_path_free(Path); Path := gtk_tree_model_get_path(model, b); - if not Assigned(Path) then Exit;
- Data2 := List[gtk_tree_path_get_indices(Path)^];
+ if not Assigned(Path) then Exit; + Data2 := List[gtk_tree_path_get_indices(Path)^]; gtk_tree_path_free(Path); end; if (Sender as TGTKView).SortColumnID = 0 then Result := CompareTextsEx(PChar(Data1.Name), PChar(Data2.Name)); @@ -411,6 +413,7 @@ begin CRC := $FFFFFFFF; MD5Hash := nil; if Data.IsMD5 then MD5Hash := THash_MD5.Create; + Error := 0; FD := Engine.OpenFile(Data.FullPath, omRead, Error); if Error <> 0 then begin Data.Status := 3; @@ -464,7 +467,7 @@ begin if DataList.Count > 0 then for i := 0 to DataList.Count - 1 do if (not PDataItem(DataList[i])^.IsDir) and (not PDataItem(DataList[i])^.UpDir) and - (AnsiCompareText(Trim(PDataItem(DataList[i])^.AName), ExtractFileName(FileName)) = 0) then + (WideCompareText(Trim(PDataItem(DataList[i])^.FDisplayName), ExtractFileName(FileName)) = 0) then begin PDataItem(DataList[i])^.Selected := True; AListView.Items[i].RedrawRow; diff --git a/UChecksumDruid.pas b/UChecksumDruid.pas index 81266f6..121be80 100644 --- a/UChecksumDruid.pas +++ b/UChecksumDruid.pas @@ -1,21 +1,21 @@ (* Tux Commander - UChecksumDruid - Checksum calculation druid - Copyright (C) 2004 Tomas Bzatek <tbzatek@users.sourceforge.net>
- Check for updates on tuxcmd.sourceforge.net
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Copyright (C) 2004 Tomas Bzatek <tbzatek@users.sourceforge.net> + Check for updates on tuxcmd.sourceforge.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *) unit UChecksumDruid; @@ -310,10 +310,10 @@ var s: string; begin // A simple test before we can continue if (CurrentPage = 3) and (not SeparateFileCheckBox.Checked) and GoingForward then begin - s := UTF8ToANSI(FileNameEntry.Text); + s := UTF8ToStr(FileNameEntry.Text); i := Engine.OpenFile(s, omWrite, Error); if Error <> 0 then begin - Application.MessageBox(Format(LANGCCHKSUMAnErrorOccuredWhileOpeningFileSS, [ANSIToUTF8(ExtractFileName(s)), ANSIToUTF8(GetErrorString(Error))]), + Application.MessageBox(Format(LANGCCHKSUMAnErrorOccuredWhileOpeningFileSS, [StrToUTF8(ExtractFileName(s)), GetErrorString(Error)]), [mbOK], mbError, mbNone, mbOK); Exit; end; @@ -357,8 +357,8 @@ begin SeparateFileCheckBox.Visible := MD5RadioButton.Checked and (FileNames.Count > 1); FileNameEntry.Enabled := (not SeparateFileCheckBox.Checked) or (not SeparateFileCheckBox.Visible); if FileNames.Count = 1 - then FileNameEntry.Text := ANSIToUTF8(ExtractFileName(FileNames[0]) + Ext[SFVRadioButton.Checked]) - else FileNameEntry.Text := ANSIToUTF8(DirName + Ext[SFVRadioButton.Checked]); + then FileNameEntry.Text := StrToUTF8(ExtractFileName(FileNames[0]) + Ext[SFVRadioButton.Checked]) + else FileNameEntry.Text := StrToUTF8(DirName + Ext[SFVRadioButton.Checked]); FileNameEntry.SetFocus; FileNameEntryChanged(Self); end; @@ -446,17 +446,17 @@ begin Progress.Value := 0; Progress.Text := '0 %'; - if SFVRadioButton.Checked then WriteSFVComment(ProcessPattern(Engine, UTF8ToANSI(FileNameEntry.Text), IncludeTrailingPathDelimiter(ExtractFilePath(FileNames[0])), '', False)); + if SFVRadioButton.Checked then WriteSFVComment(ProcessPattern(Engine, UTF8ToStr(FileNameEntry.Text), IncludeTrailingPathDelimiter(ExtractFilePath(FileNames[0])), '', False)); // Process each file for i := 0 to FileNames.Count - 1 do begin - ProcessingLabel.Caption := Format(LANGCCHKSUMNowProcessingFileS, [ANSIToUTF8(ExtractFileName(FileNames[i]))]); + ProcessingLabel.Caption := Format(LANGCCHKSUMNowProcessingFileS, [StrToUTF8(ExtractFileName(FileNames[i]))]); LastValue := Progress.Value; Stat := Engine.GetFileInfoSL(FileNames[i]); Application.ProcessMessages; try if ProcessFile(FileNames[i], SFVRadioButton.Checked, s) then begin if not SeparateFileCheckBox.Checked - then s2 := ProcessPattern(Engine, UTF8ToANSI(FileNameEntry.Text), IncludeTrailingPathDelimiter(ExtractFilePath(FileNames[0])), '', False) + then s2 := ProcessPattern(Engine, StrToUTF8(FileNameEntry.Text), IncludeTrailingPathDelimiter(ExtractFilePath(FileNames[0])), '', False) else s2 := IncludeTrailingPathDelimiter(ExtractFilePath(FileNames[i])) + ExtractFileName(FileNames[i]) + Ext[SFVRadioButton.Checked]; WriteLine(s2, FileNames[i], s, SFVRadioButton.Checked, ((i = 0) and MD5RadioButton.Checked) or SeparateFileCheckBox.Checked, (i = FileNames.Count - 1) or SeparateFileCheckBox.Checked); @@ -500,13 +500,13 @@ begin FD := Engine.OpenFile(FName, omRead, Error); if Error <> 0 then begin - ErrorLabel.Caption := ErrorLabel.Caption + Format(LANGCCHKSUMAnErrorOccuredWhileOpeningFileSS, [ANSIToUTF8(ExtractFileName(FName)), ANSIToUTF8(GetErrorString(Error))]); + ErrorLabel.Caption := ErrorLabel.Caption + Format(LANGCCHKSUMAnErrorOccuredWhileOpeningFileSS, [StrToUTF8(ExtractFileName(FName)), GetErrorString(Error)]); Exit; end; repeat Count := Engine.ReadFile(FD, Buffer, ChksumBlockSize, Error); if Error <> 0 then begin - ErrorLabel.Caption := ErrorLabel.Caption + Format(LANGCCHKSUMAnErrorOccuredWhileReadingFileSS, [ANSIToUTF8(ExtractFileName(FName)), ANSIToUTF8(GetErrorString(Error))]); + ErrorLabel.Caption := ErrorLabel.Caption + Format(LANGCCHKSUMAnErrorOccuredWhileReadingFileSS, [StrToUTF8(ExtractFileName(FName)), GetErrorString(Error)]); Engine.CloseFile(FD); Exit; end; @@ -538,7 +538,7 @@ begin if CreateFile then begin FileDes := Engine.OpenFile(FName, omWrite, Error); if Error <> 0 then begin - ErrorLabel.Caption := ErrorLabel.Caption + Format(LANGCCHKSUMAnErrorOccuredWhileOpeningFileSS, [ANSIToUTF8(ExtractFileName(FName)), ANSIToUTF8(GetErrorString(Error))]); + ErrorLabel.Caption := ErrorLabel.Caption + Format(LANGCCHKSUMAnErrorOccuredWhileOpeningFileSS, [StrToUTF8(ExtractFileName(FName)), GetErrorString(Error)]); Exit; end; try @@ -552,14 +552,14 @@ begin end; if Buffer = nil then Exit; - if IsItSFV then s := Format('%s %s'#13#10, [ExtractFileName(CheckedFName), Trim(ANSIUpperCase(HashString))]) + if IsItSFV then s := Format('%s %s'#13#10, [ExtractFileName(CheckedFName), Trim(WideUpperCase(HashString))]) else s := Format('%s %s'#10, [Trim(AnsiLowerCase(HashString)), ExtractFileName(CheckedFName)]); for i := 1 to Length(s) do begin if BufferPos + 1 >= ChksumBlockSize then begin Count := Engine.WriteFile(FileDes, Buffer, ChksumBlockSize, Error); BufferPos := -1; if (Error <> 0) or (Count <> ChksumBlockSize) then begin - ErrorLabel.Caption := ErrorLabel.Caption + Format(LANGCCHKSUMAnErrorOccuredWhileWritingFileSS, [ANSIToUTF8(ExtractFileName(FName)), ANSIToUTF8(GetErrorString(Error))]); + ErrorLabel.Caption := ErrorLabel.Caption + Format(LANGCCHKSUMAnErrorOccuredWhileWritingFileSS, [StrToUTF8(ExtractFileName(FName)), GetErrorString(Error)]); Exit; end; end; @@ -571,7 +571,7 @@ begin Inc(BufferPos); // Counting with zero-starting element Count := Engine.WriteFile(FileDes, Buffer, BufferPos, Error); if (Error <> 0) or (Count <> BufferPos) then begin - ErrorLabel.Caption := ErrorLabel.Caption + Format(LANGCCHKSUMAnErrorOccuredWhileWritingFileSS, [ANSIToUTF8(ExtractFileName(FName)), ANSIToUTF8(GetErrorString(Error))]); + ErrorLabel.Caption := ErrorLabel.Caption + Format(LANGCCHKSUMAnErrorOccuredWhileWritingFileSS, [StrToUTF8(ExtractFileName(FName)), GetErrorString(Error)]); Exit; end; BufferPos := -1; @@ -587,7 +587,7 @@ var i, Error, Count: integer; begin FileDes := Engine.OpenFile(FName, omWrite, Error); if Error <> 0 then begin - ErrorLabel.Caption := ErrorLabel.Caption + Format(LANGCCHKSUMAnErrorOccuredWhileOpeningFileSS, [ANSIToUTF8(ExtractFileName(FName)), ANSIToUTF8(GetErrorString(Error))]); + ErrorLabel.Caption := ErrorLabel.Caption + Format(LANGCCHKSUMAnErrorOccuredWhileOpeningFileSS, [StrToUTF8(ExtractFileName(FName)), GetErrorString(Error)]); Exit; end; try @@ -615,7 +615,7 @@ begin Count := Engine.WriteFile(FileDes, Buffer, ChksumBlockSize, Error); BufferPos := -1; if (Error <> 0) or (Count <> ChksumBlockSize) then begin - ErrorLabel.Caption := ErrorLabel.Caption + Format(LANGCCHKSUMAnErrorOccuredWhileWritingFileSS, [ANSIToUTF8(ExtractFileName(FName)), ANSIToUTF8(GetErrorString(Error))]); + ErrorLabel.Caption := ErrorLabel.Caption + Format(LANGCCHKSUMAnErrorOccuredWhileWritingFileSS, [StrToUTF8(ExtractFileName(FName)), GetErrorString(Error)]); Exit; end; end; @@ -179,7 +179,7 @@ var Mode: Cardinal; begin if Busy then Exit; Busy := True; Mode := 0; - {$WARNINGS OFF} + { $WARNINGS OFF} Mode := Mode or (Ord(cbSUID.Checked) * __S_ISUID); Mode := Mode or (Ord(cbSGID.Checked) * __S_ISGID); Mode := Mode or (Ord(cbSticky.Checked) * __S_ISVTX); @@ -192,7 +192,7 @@ begin Mode := Mode or (Ord(cbALLRead.Checked) * S_IROTH); Mode := Mode or (Ord(cbALLWrite.Checked) * S_IWOTH); Mode := Mode or (Ord(cbALLExec.Checked) * S_IXOTH); - {$WARNINGS ON} + { $WARNINGS ON} LastMode := Mode; TextLabel.Caption := Format(LANGFChmod_TextLabel, [AttrToStr(Mode, False)]);; TextLabel.UseMarkup := True; @@ -227,7 +227,7 @@ procedure TFChmod.AssignMode(const Mode: Cardinal; const FileName, User, Group: begin LastMode := Mode mod $1000; OctalEntry.Text := Format('%.4d', [AttrToOctal(LastMode)]); - FileLabel.Caption := Format(LANGFChmod_FileLabel, [ANSIToUTF8(FileName), AttrToStr(Mode), AttrToOctal(Mode), ANSIToUTF8(User), ANSIToUTF8(Group)]); + FileLabel.Caption := Format(LANGFChmod_FileLabel, [StrToUTF8(FileName), AttrToStr(Mode), AttrToOctal(Mode), User, Group]); FileLabel.UseMarkup := True; if Length(FileName) > 20 then FileLabel.SetSizeRequest(200, -1); end; @@ -1,21 +1,21 @@ (* Tux Commander - UChown - Change owner dialog - Copyright (C) 2004 Tomas Bzatek <tbzatek@users.sourceforge.net>
- Check for updates on tuxcmd.sourceforge.net
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Copyright (C) 2004 Tomas Bzatek <tbzatek@users.sourceforge.net> + Check for updates on tuxcmd.sourceforge.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *) unit UChown; @@ -153,7 +153,7 @@ begin Break; end; // Fill more info - FileLabel.Caption := Format(LANGFChmod_FileLabel, [ANSIToUTF8(FileName), AttrToStr(Mode), AttrToOctal(Mode), susr, sgrp]); + FileLabel.Caption := Format(LANGFChmod_FileLabel, [StrToUTF8(FileName), AttrToStr(Mode), AttrToOctal(Mode), susr, sgrp]); FileLabel.UseMarkup := True; if Length(FileName) > 20 then FileLabel.SetSizeRequest(200, -1); OwnerListView.OnSelectionChanged := OwnerListViewSelectionChanged; @@ -170,13 +170,13 @@ begin if UsrManager.UserList.Count > 0 then for i := 0 to UsrManager.UserList.Count - 1 do begin Item := OwnerListView.Items.Add; - Item.SetValue(0, ANSIToUTF8(TUser(UsrManager.UserList[i]).UserName)); + Item.SetValue(0, TUser(UsrManager.UserList[i]).UserName); Item.SetValue(1, TUser(UsrManager.UserList[i]).UID); end; if UsrManager.GroupList.Count > 0 then for i := 0 to UsrManager.GroupList.Count - 1 do begin Item := GroupListView.Items.Add; - Item.SetValue(0, ANSIToUTF8(TGroup(UsrManager.GroupList[i]).GroupName)); + Item.SetValue(0, TGroup(UsrManager.GroupList[i]).GroupName); Item.SetValue(1, TGroup(UsrManager.GroupList[i]).GID); end; finally diff --git a/UColumns.pas b/UColumns.pas index 70c736f..d9af552 100644 --- a/UColumns.pas +++ b/UColumns.pas @@ -186,6 +186,7 @@ end; procedure TFColumns.ListViewColumnToggled(Sender: TObject; Column: TGTKTreeViewColumn; Item: TGTKListItem); begin + DebugMsg(['(II) TFColumns.ListViewColumnToggled: Item.AsBoolean(0) = ', Item.AsBoolean(0), ', Item.AsInteger(0) = ', Item.AsInteger(0)]); if Assigned(Item) then Item.SetValue(0, not Item.AsBoolean(0)); end; diff --git a/UConfig.pas b/UConfig.pas index 68da691..b662f58 100644 --- a/UConfig.pas +++ b/UConfig.pas @@ -25,8 +25,8 @@ uses Classes, ULocale; resourcestring ConstAppTitle = 'Tux Commander'; - ConstAboutVersion = '0.6.36'; - ConstAboutBuildDate = '2008-06-01'; + ConstAboutVersion = '0.6.38-dev'; + ConstAboutBuildDate = '2008-06-07'; {$IFDEF __FPC__} {$INCLUDE fpcver.inc} @@ -663,21 +663,29 @@ end; (********************************************************************************************************************************) procedure ReadBookmarks; var s: string; + i: integer; begin try s := IncludeTrailingPathDelimiter(IncludeTrailingPathDelimiter(GetHomePath) + ConfDefaultSettingsDir) + 'bookmarks'; Bookmarks.LoadFromFile(s); InternalBookmarksConfmtime := GetFileTime(s); + if Bookmarks.Count > 0 then + for i := Bookmarks.Count - 1 downto 0 do + if Length(Trim(Bookmarks[i])) = 0 then Bookmarks.Delete(i); except end; end; procedure WriteBookmarks; var s: string; + i: integer; begin if InternalQuickExit then Exit; try s := IncludeTrailingPathDelimiter(IncludeTrailingPathDelimiter(GetHomePath) + ConfDefaultSettingsDir) + 'bookmarks'; + if Bookmarks.Count > 0 then + for i := Bookmarks.Count - 1 downto 0 do + if Length(Trim(Bookmarks[i])) = 0 then Bookmarks.Delete(i); Bookmarks.SaveToFile(s); InternalBookmarksConfmtime := GetFileTime(s); except @@ -1042,7 +1050,7 @@ var i: integer; begin if ParamCount > 0 then for i := 1 to ParamCount do begin - s := AnsiUpperCase(ParamStr(i)); + s := UpperCase(ParamStr(i)); if s = '--DEBUG' then ParamDebug := True else if s = '--DISABLE-GNOME' then ParamDisableGnome := True else if s = '--DELETE-HISTORY' then InternalDeleteHistory := True else diff --git a/UConnectionProperties.pas b/UConnectionProperties.pas index 0731eab..27d5bbe 100644 --- a/UConnectionProperties.pas +++ b/UConnectionProperties.pas @@ -1,21 +1,21 @@ (* Tux Commander - UConnectionProperties - Connection properties dialog - Copyright (C) 2004 Tomas Bzatek <tbzatek@users.sourceforge.net>
- Check for updates on tuxcmd.sourceforge.net
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Copyright (C) 2004 Tomas Bzatek <tbzatek@users.sourceforge.net> + Check for updates on tuxcmd.sourceforge.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *) unit UConnectionProperties; @@ -191,7 +191,7 @@ begin for i := 0 to PluginList.Count - 1 do begin MenuItem := TGTKMenuItem.CreateTyped(Self, itImageText); MenuItem.SetCaptionPlain(Format('%s [%s]', [TVFSPlugin(PluginList[i]).VFSName, - ANSIToUTF8(ExtractFileName(TVFSPlugin(PluginList[i]).FullPath))])); + ExtractFileName(TVFSPlugin(PluginList[i]).FullPath)])); PluginOptionMenu.Items.Add(MenuItem); end; @@ -158,6 +158,7 @@ procedure GetDirSize(AListView: TGTKListView; Engine: TPanelEngine; DataList: TL type TMounterItem = class public + // Strings are in locale encoding (ANSI) DisplayText, MountPath, Device, IconPath, MountCommand, UmountCommand: string; DeviceType: integer; function Mounted: boolean; @@ -238,7 +239,8 @@ begin with Data^ do begin UpDir := True; IsDotFile := False; - AName := nil; + FName := nil; + FDisplayName := nil; LnkPointTo := nil; Selected := False; IsLnk := False; @@ -304,10 +306,10 @@ begin if i + Ord(not IsRoot) > ItemCount - 1 then ListItem := ListView.Items.Add else ListItem := ListView.Items[i + Ord(not IsRoot)]; - s := String(AName); + s := String(FDisplayName); Ext := ''; if not IsDir then SeparateExt(s, s, Ext); - Ext := ANSIToUTF8(Ext); +// Ext := ANSIToUTF8(Ext); // Fill the column data for j := 1 to ConstNumPanelColumns do @@ -315,20 +317,20 @@ begin case ConfColumnIDs[j] of 1: begin if IsDir and (not ConfDisableDirectoryBrackets) - then s2 := ANSIToUTF8(Format('[%s]', [s])) - else s2 := ANSIToUTF8(s); + then s2 := Format('[%s]', [s]) + else s2 := s; ColumnData[ConfColumnIDs[j] - 1] := strdup(PChar(s2)); end; 2: begin if IsDir and (not ConfDisableDirectoryBrackets) - then s2 := ANSIToUTF8(Format('[%s]', [AName])) - else s2 := ANSIToUTF8(AName); + then s2 := Format('[%s]', [FDisplayName]) + else s2 := FDisplayName; ColumnData[ConfColumnIDs[j] - 1] := strdup(PChar(s2)); end; 3: ColumnData[ConfColumnIDs[j] - 1] := strdup(PChar(Ext)); 4: begin if IsDir then s2 := LANGDIR - else s2 := ANSIToUTF8(FormatSize(Size, 0)); + else s2 := FormatSize(Size, 0); ColumnData[ConfColumnIDs[j] - 1] := strdup(PChar(s2)); end; 5: begin @@ -346,14 +348,14 @@ begin 8: begin if ConfShowTextUIDs then begin if not Assigned(UsrManager) then UsrManager := TUserManager.Create; - s2 := AnsiToUTF8(UsrManager.GetUserName(UID, False)); + s2 := UsrManager.GetUserName(UID, False); end else s2 := IntToStr(UID); ColumnData[ConfColumnIDs[j] - 1] := strdup(PChar(s2)); end; 9: begin if ConfShowTextUIDs then begin if not Assigned(UsrManager) then UsrManager := TUserManager.Create; - s2 := AnsiToUTF8(UsrManager.GetGroupName(GID, False)); + s2 := UsrManager.GetGroupName(GID, False); end else s2 := IntToStr(GID); ColumnData[ConfColumnIDs[j] - 1] := strdup(PChar(s2)); end; @@ -451,7 +453,7 @@ begin try Error := Engine.MakeDir(IncludeTrailingPathDelimiter(Engine.Path) + NewDir); if Error <> 0 then begin - Application.MessageBox(Format(LANGErrorCreatingNewDirectorySInSPanel, [NewDir, LANGPanelStrings[LeftPanel], ANSIToUTF8(GetErrorString(Error))]), [mbOK], mbError, mbNone, mbOK); + Application.MessageBox(Format(LANGErrorCreatingNewDirectorySInSPanel, [StrToUTF8(NewDir), LANGPanelStrings[LeftPanel], GetErrorString(Error)]), [mbOK], mbError, mbNone, mbOK); Exit; end; Result := True; @@ -473,13 +475,13 @@ var SkipAll: boolean; Result := True; // DebugMsg(['Debug: IsDir: ', AFileRec^.IsDir, ', Stage1: ', AFileRec^.Stage1, ', IsLnk: ', AFileRec^.IsLnk, '; Result = ', AFileRec^.IsDir and AFileRec^.Stage1 and (not AFileRec^.IsLnk)]); if AFileRec^.IsDir and AFileRec^.Stage1 and (not AFileRec^.IsLnk) then Exit; - Res := SenderThread.Engine.Remove(String(AFileRec^.AName)); + Res := SenderThread.Engine.Remove(String(AFileRec^.FName)); // DebugMsg(['Result : ', Res]); if Res <> 0 then if SkipAll then Result := True else begin - Response := SenderThread.ShowDirDeleteDialog(1, LANGTheFileDirectory, ANSIToUTF8(String(AFileRec^.AName)), - Format(LANGCouldNotBeDeletedS, [ANSIToUTF8(GetErrorString(Res))])); + Response := SenderThread.ShowDirDeleteDialog(1, LANGTheFileDirectory, String(AFileRec^.FDisplayName), + Format(LANGCouldNotBeDeletedS, [GetErrorString(Res)])); case Response of 1 : Result := True; 3 : begin @@ -510,13 +512,13 @@ begin with PDataItem(DataList[i])^ do if (not UpDir) and Selected then if IsDir and (not IsLnk) - then Engine.FillDirFiles(CurrPath + String(AName), AList, 1) - else AList.Add(Engine.GetFileInfoSL(CurrPath + String(AName))); + then Engine.FillDirFiles(CurrPath + String(FName), AList, 1) + else AList.Add(Engine.GetFileInfoSL(CurrPath + String(FName))); if (AList.Count = 0) and Assigned(SelectedItem) and (not SelectedItem^.UpDir) then with SelectedItem^ do if IsDir and (not IsLnk) - then Engine.FillDirFiles(CurrPath + String(AName), AList, 1) - else AList.Add(Engine.GetFileInfoSL(CurrPath + String(AName))); + then Engine.FillDirFiles(CurrPath + String(FName), AList, 1) + else AList.Add(Engine.GetFileInfoSL(CurrPath + String(FName))); if Engine.ChangeDir(CurrPath, False) <> 0 then DebugMsg(['*** WARNING: Cannot change to the origin location, strange behaviour might occur.']); Engine.ExplicitChDir('/'); @@ -544,7 +546,7 @@ begin if (not DeleteAll) and (PDataItemSL(AList[i])^.Level = 1) and PDataItemSL(AList[i])^.Stage1 and PDataItemSL(AList[i])^.IsDir and (not PDataItemSL(AList[i])^.IsLnk) and (i < AList.Count - 2) and (PDataItemSL(AList[i + 1])^.Level = 2) then begin - Response := ShowDirDeleteDialog(4, Format(LANGTheDirectorySIsNotEmpty, [ANSIToUTF8(string(PDataItemSL(AList[i])^.AName))]), + Response := ShowDirDeleteDialog(4, Format(LANGTheDirectorySIsNotEmpty, [string(PDataItemSL(AList[i])^.FDisplayName)]), LANGDoYouWantToDeleteItWithAllItsFilesAndSubdirectories); case Response of 1 : ; // Do nothing in this case - I will not bother with changing the structure; it works :-) @@ -556,7 +558,7 @@ begin // Process delete if not HandleDelete(AList[i]) then Break; UpdateProgress1(i, Format('%d%%', [Round(Fr * i)])); - UpdateCaption1(ANSIToUTF8(PDataItemSL(AList[i])^.AName)); + UpdateCaption1(PDataItemSL(AList[i])^.FDisplayName); CommitGUIUpdate; end; @@ -618,9 +620,9 @@ end; end; if ParamBool1 then s2 := LANGCopyError else s2 := LANGMoveError; - if ErrorType <> 1 then s3 := ANSIToUTF8(FileName) + if ErrorType <> 1 then s3 := StrToUTF8(FileName) else s3 := ''; - case ShowDirDeleteDialog(3, s, s3, ANSIToUTF8(GetErrorString(ErrorNum)), s2) of + case ShowDirDeleteDialog(3, s, s3, GetErrorString(ErrorNum), s2) of 0 : begin // Cancel button Result := False; CancelIt; @@ -754,7 +756,7 @@ var DefResponse: integer; // Global variables for this function function IsOnSameFS(SrcPath, DestPath: string): boolean; begin - DebugMsg(['### IsOnSameFS: "', SrcPath, '" vs. "', DestPath, '"'#10'## Prefix = "', SenderThread.SrcEngine.GetPrefix, '" vs. "', SenderThread.DestEngine.GetPrefix, '"']); +// DebugMsg(['### IsOnSameFS: "', SrcPath, '" vs. "', DestPath, '"'#10'## Prefix = "', SenderThread.SrcEngine.GetPrefix, '" vs. "', SenderThread.DestEngine.GetPrefix, '"']); with SenderThread do if SrcEngine.GetPrefix <> DestEngine.GetPrefix then Result := False @@ -765,7 +767,7 @@ var DefResponse: integer; // Global variables for this function begin with SenderThread do begin if SrcEngine.GetPrefix <> DestEngine.GetPrefix then Result := False else - if AnsiCompareStr(Path1, Path2) = 0 then Result := True else + if WideCompareStr(Path1, Path2) = 0 then Result := True else Result := TestCaseInsensitiveFS and DestEngine.TwoSameFiles(Path1, Path2); end; end; @@ -779,41 +781,41 @@ var DefResponse: integer; // Global variables for this function with AFileRec^ do begin if IsLnk then begin // Explicit copy the file - if ParamBool3 or (not IsOnSameFS(String(AName), ExtractFileDir(Dst))) then begin + if ParamBool3 or (not IsOnSameFS(String(FName), ExtractFileDir(Dst))) then begin ErrorKind := DestEngine.MakeSymLink(Dst, String(LnkPointTo)); if ErrorKind <> 0 then Result := ERRCreateLink; if not ParamBool3 then begin - ErrorKind := SrcEngine.Remove(String(AName)); + ErrorKind := SrcEngine.Remove(String(FName)); if ErrorKind <> 0 then Result := ERRRemove; end; end else begin // Move the file - ErrorKind := DestEngine.RenameFile(String(AName), Dst); + ErrorKind := DestEngine.RenameFile(String(FName), Dst); if ErrorKind <> 0 then Result := ERRCopyMove; end; end else // is not link if ParamBool3 then begin // Copy mode - if LocalCopyFile(String(AName), Dst, Append) then begin + if LocalCopyFile(String(FName), Dst, Append) then begin if IsOnRO and ConfClearReadOnlyAttr and (Mode and S_IWUSR = 0) then Mode := Mode or S_IWUSR; DestEngine.Chmod(Dst, Mode); DestEngine.Chown(Dst, UID, GID); DestEngine.ChangeTimes(Dst, mtime, atime); end; end else // Move mode - if IsOnSameFS(String(AName), ExtractFileDir(Dst)) then begin - if TwoSameFiles(String(AName), Dst, True) and (not TwoSameFiles(String(AName), Dst, False)) then begin + if IsOnSameFS(String(FName), ExtractFileDir(Dst)) then begin + if TwoSameFiles(String(FName), Dst, True) and (not TwoSameFiles(String(FName), Dst, False)) then begin DebugMsg(['*** Activating double-rename due to renaming on case-insensitive FS']); - ErrorKind := DestEngine.RenameFile(String(AName), Dst + '_tcmd'); + ErrorKind := DestEngine.RenameFile(String(FName), Dst + '_tcmd'); if ErrorKind = 0 then ErrorKind := DestEngine.RenameFile(Dst + '_tcmd', Dst); - end else ErrorKind := DestEngine.RenameFile(String(AName), Dst); + end else ErrorKind := DestEngine.RenameFile(String(FName), Dst); if ErrorKind <> 0 then Result := ERRCopyMove; end else begin - if LocalCopyFile(String(AName), Dst, Append) then begin + if LocalCopyFile(String(FName), Dst, Append) then begin if IsOnRO and ConfClearReadOnlyAttr and (Mode and S_IWUSR = 0) then Mode := Mode or S_IWUSR; DestEngine.Chmod(Dst, Mode); DestEngine.Chown(Dst, UID, GID); DestEngine.ChangeTimes(Dst, mtime, atime); if not Cancelled then begin - ErrorKind := SrcEngine.Remove(String(AName)); + ErrorKind := SrcEngine.Remove(String(FName)); if ErrorKind <> 0 then Result := ERRRemove; end; end; @@ -842,7 +844,7 @@ var DefResponse: integer; // Global variables for this function DestEngine.Chmod(NewFilePath, Mode); DestEngine.Chown(NewFilePath, UID, GID); DestEngine.ChangeTimes(NewFilePath, mtime, atime); - if not ParamBool3 then SrcEngine.Remove(String(AName)); // Remove directory + if not ParamBool3 then SrcEngine.Remove(String(FName)); // Remove directory Exit; end; @@ -851,13 +853,13 @@ var DefResponse: integer; // Global variables for this function Res := 0; if AFileRec^.ForceMove and (not ParamBool3) then begin - if TwoSameFiles(ExcludeTrailingPathDelimiter(string(AFileRec^.AName)), ExcludeTrailingPathDelimiter(string(AFileRec^.ADestination)), True) and (not - TwoSameFiles(ExcludeTrailingPathDelimiter(string(AFileRec^.AName)), ExcludeTrailingPathDelimiter(string(AFileRec^.ADestination)), False)) then + if TwoSameFiles(ExcludeTrailingPathDelimiter(string(AFileRec^.FName)), ExcludeTrailingPathDelimiter(string(AFileRec^.ADestination)), True) and (not + TwoSameFiles(ExcludeTrailingPathDelimiter(string(AFileRec^.FName)), ExcludeTrailingPathDelimiter(string(AFileRec^.ADestination)), False)) then begin DebugMsg(['*** Activating double-rename due to renaming on case-insensitive FS']); - ErrorKind := DestEngine.RenameFile(string(AFileRec^.AName), ExcludeTrailingPathDelimiter(string(AFileRec^.ADestination)) + '_tcmd'); + ErrorKind := DestEngine.RenameFile(string(AFileRec^.FName), ExcludeTrailingPathDelimiter(string(AFileRec^.ADestination)) + '_tcmd'); if ErrorKind = 0 then ErrorKind := DestEngine.RenameFile(ExcludeTrailingPathDelimiter(string(AFileRec^.ADestination)) + '_tcmd', ExcludeTrailingPathDelimiter(string(AFileRec^.ADestination))); - end else ErrorKind := DestEngine.RenameFile(string(AFileRec^.AName), string(AFileRec^.ADestination)); + end else ErrorKind := DestEngine.RenameFile(string(AFileRec^.FName), string(AFileRec^.ADestination)); if ErrorKind <> 0 then Res := ERRCopyMove else Res := 0; end else @@ -873,16 +875,16 @@ var DefResponse: integer; // Global variables for this function CopyFilesWorker_ProgressFunc(SenderThread, 0); Res := 0; if DestEngine.FileExists(NewFilePath, True) and - (not (not ParamBool3 and (not TwoSameFiles(NewFilePath, AFileRec^.AName, False)) and TwoSameFiles(NewFilePath, AFileRec^.AName, True))) + (not (not ParamBool3 and (not TwoSameFiles(NewFilePath, AFileRec^.FName, False)) and TwoSameFiles(NewFilePath, AFileRec^.FName, True))) then begin Response := DefResponse; Item := DestEngine.GetFileInfoSL(NewFilePath); if Response = 0 then begin - Response := ShowOverwriteDialog(1 + Ord(ParamBool3), Format(LANGOverwriteS, [ANSIToUTF8(NewFilePath)]), + Response := ShowOverwriteDialog(1 + Ord(ParamBool3), Format(LANGOverwriteS, [StrToUTF8(NewFilePath)]), Format(LANGOvewriteSBytesS, [FormatSize(Item^.Size, 0), FormatDateTime('ddddd t', Item^.ModifyTime)]), - Format(LANGWithFileS, [ANSIToUTF8(AFileRec^.AName)]), + Format(LANGWithFileS, [AFileRec^.FDisplayName]), Format(LANGOvewriteSBytesS, [FormatSize(AFileRec^.Size, 0), FormatDateTime('ddddd t', AFileRec^.ModifyTime)]), - ANSIToUTF8(ExtractFileName(NewFilePath)), ExtractFileName(AFileRec^.AName), ExtractFileName(NewFilePath)); + ExtractFileName(StrToUTF8(NewFilePath)), ExtractFileName(AFileRec^.FDisplayName), ExtractFileName(StrToUTF8(NewFilePath))); s := FOverwriteRenameStr; case Response of // 1: Overwrite @@ -907,8 +909,8 @@ var DefResponse: integer; // Global variables for this function if (Response in [1, 2]) or ((Response = 5) and (Item^.ModifyTime < AFileRec^.ModifyTime)) then begin r := DestEngine.Remove(NewFilePath); while r <> 0 do begin - Res := ShowDirDeleteDialog(1, LANGTheFile, ANSIToUTF8(String(NewFilePath)), - Format(LANGCouldNotBeDeletedS, [ANSIToUTF8(GetErrorString(r))]), LANGCopyError); + Res := ShowDirDeleteDialog(1, LANGTheFile, StrToUTF8(String(NewFilePath)), + Format(LANGCouldNotBeDeletedS, [GetErrorString(r)]), LANGCopyError); case Res of 1: begin Result := True; @@ -934,28 +936,28 @@ var DefResponse: integer; // Global variables for this function ERRCreateLink: begin s1 := LANGTheSymbolicLink; if ErrorKind = 0 then s3 := LANGCouldNotBeCreated else - s3 := Format(LANGCouldNotBeCreatedS, [ANSIToUTF8(GetErrorString(ErrorKind))]); + s3 := Format(LANGCouldNotBeCreatedS, [GetErrorString(ErrorKind)]); end; ERRMkDir: begin s1 := LANGTheDirectory; if ErrorKind = 0 then s3 := LANGCouldNotBeCreated else - s3 := Format(LANGCouldNotBeCreatedS, [ANSIToUTF8(GetErrorString(ErrorKind))]); + s3 := Format(LANGCouldNotBeCreatedS, [GetErrorString(ErrorKind)]); end; ERRRemove: begin if AFileRec^.IsDir then s1 := LANGTheDirectory else if AFileRec^.IsLnk then s1 := LANGTheSymbolicLink else s1 := LANGTheFile; if ErrorKind = 0 then s3 := LANGCouldNotBeDeleted else - s3 := Format(LANGCouldNotBeDeletedS, [ANSIToUTF8(GetErrorString(ErrorKind))]); + s3 := Format(LANGCouldNotBeDeletedS, [GetErrorString(ErrorKind)]); end; ERRCopyMove: begin if ParamBool3 then s1 := LANGCannotCopyFile else s1 := LANGCannotMoveFile; if ErrorKind = 0 then s3 := '' else - s3 := ANSIToUTF8(GetErrorString(ErrorKind)); + s3 := GetErrorString(ErrorKind); end; end; - Response := ShowDirDeleteDialog(1, s1, ANSIToUTF8(String(NewFilePath)), s3, cap); + Response := ShowDirDeleteDialog(1, s1, StrToUTF8(String(NewFilePath)), s3, cap); case Response of 1 : Result := True; // Skip 2 : Result := HandleCopy(AFileRec, NewFilePath); // Retry @@ -988,7 +990,7 @@ var DefResponse: integer; // Global variables for this function end; end else begin s := ProcessPattern(DestEngine, ParamString1, CurrPath, ParamFileName, ParamDir); - CaseInsensitiveRename := (AnsiCompareStr(ParamString1, ParamFileName) <> 0) and (AnsiCompareText(ParamString1, ParamFileName) = 0) and + CaseInsensitiveRename := (WideCompareStr(ParamString1, ParamFileName) <> 0) and (WideCompareText(ParamString1, ParamFileName) = 0) and ParamDir and DestEngine.TwoSameFiles(IncludeTrailingPathDelimiter(CurrPath) + ParamString1, IncludeTrailingPathDelimiter(CurrPath) + ParamFileName); // DebugMsg(['HandleProcessPattern: s = ', s]); b := False; @@ -1040,21 +1042,21 @@ begin end else if ParamBool4 then begin // Quick-Rename with ParamDataItem1^ do - HandleProcessPattern(List, CurrPath, CurrPath + String(AName), String(AName), IsDir and (not IsLnk), True); + HandleProcessPattern(List, CurrPath, CurrPath + String(FName), String(FName), IsDir and (not IsLnk), True); end else begin // Not Quick-Rename if not ExtractFromVFSMode then begin if DataList.Count > 0 then for i := 0 to DataList.Count - 1 do with PDataItem(DataList[i])^ do if (not UpDir) and Selected - then HandleProcessPattern(List, CurrPath, CurrPath + String(AName), String(AName), IsDir and (not IsLnk), not ParamBool3); + then HandleProcessPattern(List, CurrPath, CurrPath + String(FName), String(FName), IsDir and (not IsLnk), not ParamBool3); if (List.Count = 0) and Assigned(SelectedItem) and (not SelectedItem^.UpDir) then with SelectedItem^ do - HandleProcessPattern(List, CurrPath, CurrPath + String(AName), String(AName), IsDir and (not IsLnk), not ParamBool3); + HandleProcessPattern(List, CurrPath, CurrPath + String(FName), String(FName), IsDir and (not IsLnk), not ParamBool3); end else begin // Extract from VFS mode DebugMsg(['CopyFilesWorker: Should not be reached']); if (not ExtractFromVFSAll) and Assigned(SelectedItem) - then HandleProcessPattern(List, CurrPath, CurrPath + String(SelectedItem^.AName), String(SelectedItem^.AName), SelectedItem^.IsDir and (not SelectedItem^.IsLnk), not ParamBool3) + then HandleProcessPattern(List, CurrPath, CurrPath + String(SelectedItem^.FName), String(SelectedItem^.FName), SelectedItem^.IsDir and (not SelectedItem^.IsLnk), not ParamBool3) else begin SaveSrcPath := IncludeTrailingPathDelimiter(SrcEngine.Path); SrcEngine.SetPath('/'); @@ -1096,20 +1098,20 @@ begin then s := string(PDataItemSL(List[i])^.ADestination) else begin - s := ProcessPattern(DestEngine, ParamString1, CurrPath, Copy(PDataItemSL(List[i])^.AName, Length(CurrPath) + 1, Length(PDataItemSL(List[i])^.AName) - Length(CurrPath)), + s := ProcessPattern(DestEngine, ParamString1, CurrPath, Copy(PDataItemSL(List[i])^.FName, Length(CurrPath) + 1, Length(PDataItemSL(List[i])^.FName) - Length(CurrPath)), PDataItemSL(List[i])^.IsDir and (not PDataItemSL(List[i])^.IsLnk)); // DebugMsg(['s2 = ', Copy(PDataItemSL(List[i])^.AName, Length(CurrPath) + 1, Length(PDataItemSL(List[i])^.AName) - Length(CurrPath)), ', s = ', s]); end; - UpdateCaption1(Format(LANGFromS, [ANSIToUTF8(string(PDataItemSL(List[i])^.AName))])); - UpdateCaption2(Format(LANGToS, [ANSIToUTF8(s)])); + UpdateCaption1(Format(LANGFromS, [string(PDataItemSL(List[i])^.FDisplayName)])); + UpdateCaption2(Format(LANGToS, [StrToUTF8(s)])); CommitGUIUpdate; - if TwoSameFiles(s, string(PDataItemSL(List[i])^.AName), ParamBool3) and (not PDataItemSL(List[i])^.IsDir) then begin + if TwoSameFiles(s, string(PDataItemSL(List[i])^.FName), ParamBool3) and (not PDataItemSL(List[i])^.IsDir) then begin FCancelMessage := LANGCannotCopyFileToItself; FShowCancelMessage := True; ErrorHappened := True; Break; end; - if s <> string(PDataItemSL(List[i])^.AName) then + if s <> string(PDataItemSL(List[i])^.FName) then if not HandleCopy(List[i], s) then begin ErrorHappened := True; Break; @@ -1172,7 +1174,7 @@ begin WriteLn('**** List Item idx ', i, '; base @ ', integer(List[i]), '; sizeof = ', SizeOf(List[i])); Item := List[i]; WriteLn(' Stage1: ', Item^.Stage1, ', Level: ', Item^.Level, ', IsDir: ', Item^.IsDir, ', IsLnk: ', Item^.IsLnk, ', ForceMove: ', Item^.ForceMove{, ', Size: ', Item^.Size}); - WriteLn(' AName: ', Item^.AName); + WriteLn(' FName: ', Item^.FName); WriteLn(' LnkPointTo: ', Item^.LnkPointTo); WriteLn(' ADestination: ', Item^.ADestination); except @@ -1201,7 +1203,7 @@ begin WriteLn('**** List Item idx ', i, '; base @ ', integer(List[i]), '; sizeof = ', SizeOf(List[i])); Item := List[i]; WriteLn(' IsDir: ', Item^.IsDir, ', IsLnk: ', Item^.IsLnk, ', Size: ', Item^.Size); - WriteLn(' AName: ', Item^.AName); + WriteLn(' FName: ', Item^.FName); WriteLn(' LnkPointTo: ', Item^.LnkPointTo); except on E: Exception do @@ -1223,12 +1225,12 @@ begin for i := 0 to DataList.Count - 1 do with PDataItem(DataList[i])^ do if Selected and (not UpDir) then Inc(SelCount); - Item1 := string(PDataItem(ListView.Selected.Data)^.AName); + Item1 := string(PDataItem(ListView.Selected.Data)^.FDisplayName); if (PDataItem(ListView.Selected.Data)^.Selected and (SelCount > 0)) or (SelCount = 0) then begin if ListView.ConvertToSorted(ListView.Selected.Index) < ListView.Items.Count then for i := ListView.ConvertToSorted(ListView.Selected.Index) + 1 to DataList.Count - 1 do if not PDataItem(DataList[ListView.ConvertFromSorted(i)])^.Selected then begin - Item2 := string(PDataItem(DataList[ListView.ConvertFromSorted(i)])^.AName); + Item2 := string(PDataItem(DataList[ListView.ConvertFromSorted(i)])^.FDisplayName); Break; end; if (Item2 = '') and (ListView.ConvertToSorted(ListView.Selected.Index) > 0) then @@ -1236,7 +1238,7 @@ begin if (not PDataItem(DataList[ListView.ConvertFromSorted(i)])^.Selected) and (not PDataItem(DataList[ListView.ConvertFromSorted(i)])^.UpDir) then begin - Item2 := string(PDataItem(DataList[ListView.ConvertFromSorted(i)])^.AName); + Item2 := string(PDataItem(DataList[ListView.ConvertFromSorted(i)])^.FDisplayName); Break; end; end; @@ -1266,7 +1268,7 @@ function CRCGetInfo(FileName: string; Engine: TPanelEngine; var TargetName: stri try TrimCRLFESC(Str); if Length(Str) < 1 then Exit; - UPS := AnsiUpperCase(Str); + UPS := WideUpperCase(Str); if Pos('FILENAME', UPS) = 1 then TargetName := Trim(Copy(Str, Pos('=', Str) + 1, Length(Str) - Pos('=', Str))) else if Pos('SIZE', UPS) = 1 then Size := StrToInt64Def(Trim(Copy(Str, Pos('=', Str) + 1, Length(Str) - Pos('=', Str))), 0) else if Pos('CRC32', UPS) = 1 then TargetCRC := StrToInt64Def('$' + Trim(Copy(Str, Pos('=', Str) + 1, Length(Str) - Pos('=', Str))), 0); @@ -1346,8 +1348,8 @@ var FD: TEngineFileDes; begin Result := False; with SenderThread do begin - if ParamBool1 then UpdateCaption2(Format(LANGToS, [ANSIToUTF8(FName)])) - else UpdateCaption1(Format(LANGFromS, [ANSIToUTF8(FName)])); + if ParamBool1 then UpdateCaption2(Format(LANGToS, [StrToUTF8(FName)])) + else UpdateCaption1(Format(LANGFromS, [StrToUTF8(FName)])); UpdateProgress1(0, '0 %'); CommitGUIUpdate; Stat := Engine.GetFileInfoSL(FName); @@ -1363,7 +1365,7 @@ var FD: TEngineFileDes; end; wCount := Engine.WriteFile(FD, Buffer, Count, Error); if (Error <> 0) or (Count <> wCount) then begin - FCancelMessage := Format(LANGAnErrorOccuredWhileWritingFileSS, [ANSIToUTF8(ExtractFileName(TargetName)), ANSIToUTF8(GetErrorString(Error))]); + FCancelMessage := Format(LANGAnErrorOccuredWhileWritingFileSS, [ExtractFileName(TargetName), GetErrorString(Error)]); FShowCancelMessage := True; PrivateCancel := True; Result := True; // Fake this to don't show next disc dialog @@ -1388,18 +1390,18 @@ begin with SenderThread do begin HasFinalCRC := ParamBool1; TargetFinalName := ParamString3; - if (Length(ParamString2) > 4) and (ANSIUpperCase(RightStr(ParamString2, 4)) = '.CRC') + if (Length(ParamString2) > 4) and (WideUpperCase(RightStr(ParamString2, 4)) = '.CRC') then CurrFile := ChangeFileExt(ExtractFileName(ParamString2), '.001') else CurrFile := ExtractFileName(ParamString2); SourcePath := ExtractFilePath(ParamString2); if ParamString3 = '' then ParamString3 := ChangeFileExt(ExtractFileName(ParamString2), '.out'); TargetName := ProcessPattern(Engine, ParamString1, Engine.Path, ParamString3, False); if Engine.FileExists(TargetName, True) then - if ShowMessageBox(Format(LANGTheTargetFileSAlreadyExistsDoYouWantToOverwriteIt, [ANSIToUTF8(TargetName)]), [mbYes, mbNo], mbQuestion, mbNone, mbNo) = mbYes then + if ShowMessageBox(Format(LANGTheTargetFileSAlreadyExistsDoYouWantToOverwriteIt, [StrToUTF8(TargetName)]), [mbYes, mbNo], mbQuestion, mbNone, mbNo) = mbYes then begin Error := Engine.Remove(TargetName); if Error <> 0 then begin - FCancelMessage := Format(LANGTheTargetFileSCannotBeRemovedS, [ANSIToUTF8(ExtractFileName(TargetName)), ANSIToUTF8(GetErrorString(Error))]); + FCancelMessage := Format(LANGTheTargetFileSCannotBeRemovedS, [StrToUTF8(ExtractFileName(TargetName)), GetErrorString(Error)]); FShowCancelMessage := True; Exit; end; @@ -1418,7 +1420,7 @@ begin end; FD := Engine.OpenFile(TargetName, omWrite, Error); if Error <> 0 then begin - FCancelMessage := Format(LANGAnErrorOccuredWhileOpeningFileSS, [ANSIToUTF8(TargetName), ANSIToUTF8(GetErrorString(Error))]); + FCancelMessage := Format(LANGAnErrorOccuredWhileOpeningFileSS, [StrToUTF8(TargetName), GetErrorString(Error)]); FShowCancelMessage := True; Libc.free(Buffer); Exit; @@ -1430,7 +1432,7 @@ begin if ParamBool1 then begin SetProgress2Params(ParamInt64); UpdateProgress2(0, '0 %'); - UpdateCaption2(Format(LANGFromS, [ANSIToUTF8(TargetName)])); + UpdateCaption2(Format(LANGFromS, [StrToUTF8(TargetName)])); CommitGUIUpdate; end; { else begin Label2.XAlign := 0; @@ -1440,9 +1442,9 @@ begin repeat b := PasteFile(IncludeTrailingPathDelimiter(SourcePath) + CurrFile); if not b then begin - PrivateCancel := ShowNewDirDialog(LANGMergeCaption, LANGPleaseInsertNextDiskOrGiveDifferentLocation, ANSIToUTF8(SourcePath)) <> integer(mbOK); + PrivateCancel := ShowNewDirDialog(LANGMergeCaption, LANGPleaseInsertNextDiskOrGiveDifferentLocation, StrToUTF8(SourcePath)) <> integer(mbOK); if not PrivateCancel then begin - SourcePath := UTF8ToANSI(FNewDirEdit); + SourcePath := UTF8ToStr(FNewDirEdit); if not HasFinalCRC then HasFinalCRC := CRCGetInfo(IncludeTrailingPathDelimiter(SourcePath) + CurrFile, Engine, TargetFinalName, ParamLongWord1, ParamInt64); Continue; @@ -1463,9 +1465,9 @@ begin if not (Cancelled or PrivateCancel) then if HasFinalCRC then begin if not CurrentCRC = ParamLongWord1 - then ShowMessageBox(Format(LANGMergeOfSSucceeded, [ANSIToUTF8(ExtractFileName(TargetFinalName))]), [mbOK], mbInfo, mbNone, mbOK) + then ShowMessageBox(Format(LANGMergeOfSSucceeded, [StrToUTF8(ExtractFileName(TargetFinalName))]), [mbOK], mbInfo, mbNone, mbOK) else ShowMessageBox(LANGWarningCreatedFileFailsCRCCheck, [mbOK], mbWarning, mbNone, mbOK); - end else ShowMessageBox(Format(LANGMergeOfSSucceeded_NoCRCFileAvailable, [ANSIToUTF8(ExtractFileName(TargetFinalName))]), [mbOK], mbInfo, mbNone, mbOK); + end else ShowMessageBox(Format(LANGMergeOfSSucceeded_NoCRCFileAvailable, [StrToUTF8(ExtractFileName(TargetFinalName))]), [mbOK], mbInfo, mbNone, mbOK); Engine.CloseFile(FD); end; Libc.free(Buffer); @@ -1483,13 +1485,13 @@ begin else TargetFile := TargetFile + '.crc'; FD := Engine.OpenFile(TargetFile, omWrite, Error); if Error <> 0 then begin - Application.MessageBox(Format(LANGAnErrorOccuredWhileOpeningFileSS, [ANSIToUTF8(TargetFile), ANSIToUTF8(GetErrorString(Error))]), [mbOK], mbError, mbNone, mbOK); + Application.MessageBox(Format(LANGAnErrorOccuredWhileOpeningFileSS, [TargetFile, GetErrorString(Error)]), [mbOK], mbError, mbNone, mbOK); Exit; end; - s := Format('filename=%s'#13#10'size=%d'#13#10'crc32=%s'#13#10, [SplitFileName, FileSize, ANSIUpperCase(IntToHex(FileCRC, 8))]); + s := Format('filename=%s'#13#10'size=%d'#13#10'crc32=%s'#13#10, [SplitFileName, FileSize, WideUpperCase(IntToHex(FileCRC, 8))]); Count := Engine.WriteFile(FD, @s[1], Length(s), Error); if (Error <> 0) or (Count <> Length(s)) then begin - Application.MessageBox(Format(LANGAnErrorOccuredWhileWritingFileSS, [ANSIToUTF8(TargetFile), ANSIToUTF8(GetErrorString(Error))]), [mbOK], mbError, mbNone, mbOK); + Application.MessageBox(Format(LANGAnErrorOccuredWhileWritingFileSS, [TargetFile, GetErrorString(Error)]), [mbOK], mbError, mbNone, mbOK); Exit; end; Engine.CloseFile(FD); @@ -1524,10 +1526,10 @@ var FD: TEngineFileDes; DebugMsg(['-- Opening file ', ExtractFileName(TargetFile), ', PartSize = ', PartSize]); if Error <> 0 then Exit; if ParamInt64 > 0 then begin - UpdateCaption2(Format(LANGToS, [ANSIToUTF8(TargetFile)])); + UpdateCaption2(Format(LANGToS, [StrToUTF8(TargetFile)])); SetProgress1Params(PartSize); UpdateProgress1(0, '0 %'); - end else UpdateCaption1(Format(LANGToS, [ANSIToUTF8(TargetFile)])); + end else UpdateCaption1(Format(LANGToS, [StrToUTF8(TargetFile)])); CommitGUIUpdate; repeat DebugMsg(['Seek to ', Engine.FileSeek(FD, SizeDone + Written, Error), ', Written = ', Written]); @@ -1576,8 +1578,8 @@ var FD: TEngineFileDes; DebugMsg(['-- New disk question']); Engine.ExplicitChDir('/'); PrivateCancel := ShowNewDirDialog(LANGSplitCaption, LANGPleaseInsertNextDiskOrGiveDifferentLocation, - ANSIToUTF8(FilePath)) <> integer(mbOK); - if not PrivateCancel then FilePath := UTF8ToANSI(FNewDirEdit); + StrToUTF8(FilePath)) <> integer(mbOK); + if not PrivateCancel then FilePath := UTF8ToStr(FNewDirEdit); Result := PrivateCancel; end; end; @@ -1594,7 +1596,7 @@ begin with SenderThread do begin Stat := Engine.GetFileInfoSL(ParamString1); if not Assigned(Stat) then begin - FCancelMessage := Format(LANGCannotOpenFileS, [ANSIToUTF8(ParamString1)]); + FCancelMessage := Format(LANGCannotOpenFileS, [StrToUTF8(ParamString1)]); FShowCancelMessage := True; Exit; end; @@ -1618,7 +1620,7 @@ begin end; FD := Engine.OpenFile(ParamString1, omRead, Error); if Error <> 0 then begin - FCancelMessage := Format(LANGAnErrorOccuredWhileOpeningFileSS, [ANSIToUTF8(ParamString1), ANSIToUTF8(GetErrorString(Error))]); + FCancelMessage := Format(LANGAnErrorOccuredWhileOpeningFileSS, [StrToUTF8(ParamString1), GetErrorString(Error)]); Libc.free(Buffer); Exit; end; @@ -1636,7 +1638,7 @@ begin SetProgress1Params(FileSize); UpdateProgress1(0, '0 %'); end; - UpdateCaption1(Format(LANGFromS, [ANSIToUTF8(IncludeTrailingPathDelimiter(FilePath) + OriginalFName)])); + UpdateCaption1(Format(LANGFromS, [StrToUTF8(IncludeTrailingPathDelimiter(FilePath) + OriginalFName)])); CommitGUIUpdate; repeat @@ -1652,23 +1654,23 @@ begin st := ''; if List.Count < 6 then begin for i := 0 to List.Count - 1 do - st := st + ' ' + AnsiToUTF8(string(PDataItem(List[i])^.AName)) + #10; - b := ShowMessageBox(Format(LANGThereAreSomeFilesInTheTargetDirectorySDoYouWantToDeleteThem, [st]), [mbYes, mbNo], mbQuestion, mbNone, mbNo) = mbYes; + st := st + ' ' + string(PDataItem(List[i])^.FDisplayName) + #10; + b := ShowMessageBox(Format(LANGThereAreSomeFilesInTheTargetDirectorySDoYouWantToDeleteThem, [StrToUTF8(st)]), [mbYes, mbNo], mbQuestion, mbNone, mbNo) = mbYes; end else b := ShowMessageBox(Format(LANGThereAreDFilesInTheTargetDirectoryDoYouWantToDeleteThem, [List.Count]), [mbYes, mbNo], mbQuestion, mbNone, mbNo) = mbYes; if b then for i := 0 to List.Count - 1 do begin - Error := Engine.Remove(IncludeTrailingPathDelimiter(FilePath) + string(PDataItem(List[i])^.AName)); - if Error <> 0 then ShowMessageBox(Format(LANGTheTargetFileSCannotBeRemovedS, [ANSIToUTF8(IncludeTrailingPathDelimiter(FilePath) + string(PDataItem(List[i])^.AName)), ANSIToUTF8(GetErrorString(Error))]), [mbOK], mbError, mbNone, mbOK); + Error := Engine.Remove(IncludeTrailingPathDelimiter(FilePath) + string(PDataItem(List[i])^.FName)); + if Error <> 0 then ShowMessageBox(Format(LANGTheTargetFileSCannotBeRemovedS, [StrToUTF8(IncludeTrailingPathDelimiter(FilePath)) + string(PDataItem(List[i])^.FDisplayName), GetErrorString(Error)]), [mbOK], mbError, mbNone, mbOK); end; end; except end; // Test for target file existence if Engine.FileExists(IncludeTrailingPathDelimiter(FilePath) + FileName) then begin - b := ShowMessageBox(Format(LANGTheTargetFileSAlreadyExistsDoYouWantToOverwriteIt, [ANSIToUTF8(IncludeTrailingPathDelimiter(FilePath) + FileName)]), [mbYes, mbNo], mbQuestion, mbNone, mbNo) = mbYes; + b := ShowMessageBox(Format(LANGTheTargetFileSAlreadyExistsDoYouWantToOverwriteIt, [StrToUTF8(IncludeTrailingPathDelimiter(FilePath) + FileName)]), [mbYes, mbNo], mbQuestion, mbNone, mbNo) = mbYes; if b then begin Error := Engine.Remove(IncludeTrailingPathDelimiter(FilePath) + FileName); if Error <> 0 then begin - FCancelMessage := Format(LANGTheTargetFileSCannotBeRemovedS, [ANSIToUTF8(IncludeTrailingPathDelimiter(FilePath) + FileName), ANSIToUTF8(GetErrorString(Error))]); + FCancelMessage := Format(LANGTheTargetFileSCannotBeRemovedS, [StrToUTF8(IncludeTrailingPathDelimiter(FilePath) + FileName), GetErrorString(Error)]); FShowCancelMessage := True; PrivateCancel := True; Break; @@ -1685,7 +1687,7 @@ begin if (CurrSize >= 512) and (TDF >= CurrSize) then begin b := WriteSplitPart(IncludeTrailingPathDelimiter(FilePath) + FileName, CurrSize, ws); if (not b) and (ParamInt64 > 0) then begin - FCancelMessage := Format(LANGAnErrorOccuredWhileOperationS, [ANSIToUTF8(GetErrorString(Error))]); + FCancelMessage := Format(LANGAnErrorOccuredWhileOperationS, [GetErrorString(Error)]); FShowCancelMessage := True; PrivateCancel := True; Break; @@ -1716,9 +1718,9 @@ begin if (TDF < 512) and (not NewDiskQuestion) then Break; until (TDF >= 512) or PrivateCancel or Cancelled; if WriteCRCFile(Engine, IncludeTrailingPathDelimiter(FilePath) + FileName, OriginalFName, SizeDone, not FileCRC) - then ShowMessageBox(Format(LANGSplitOfSSucceeded, [ANSIToUTF8(OriginalFName)]), [mbOK], mbInfo, mbNone, mbOK) + then ShowMessageBox(Format(LANGSplitOfSSucceeded, [StrToUTF8(OriginalFName)]), [mbOK], mbInfo, mbNone, mbOK) else begin - FCancelMessage := Format(LANGSplitOfSFailed, [ANSIToUTF8(OriginalFName)]); + FCancelMessage := Format(LANGSplitOfSFailed, [StrToUTF8(OriginalFName)]); FShowCancelMessage := True; end; end; @@ -1745,13 +1747,13 @@ var SkipAll: boolean; if AFileRec^.IsDir and ParamBool1 and AFileRec^.Stage1 and (not AFileRec^.IsLnk) then Exit; if (not AFileRec^.IsDir) and ParamBool1 and (ParamInt1 = 1) then Exit; // Directories only if AFileRec^.IsDir and ParamBool1 and (ParamInt1 = 2) then Exit; // Files only - Res := Engine.Chmod(String(AFileRec^.AName), ParamCardinal1); + Res := Engine.Chmod(String(AFileRec^.FName), ParamCardinal1); // DebugMsg(['Result : ', Res]); if Res <> 0 then if SkipAll then Result := True else begin - Response := ShowDirDeleteDialog(1, LANGTheFileDirectory, ANSIToUTF8(String(AFileRec^.AName)), Format(LANGCouldNotBeChmoddedS, - [ANSIToUTF8(GetErrorString(Res))]), LANGDialogChangePermissions); + Response := ShowDirDeleteDialog(1, LANGTheFileDirectory, String(AFileRec^.FDisplayName), Format(LANGCouldNotBeChmoddedS, + [GetErrorString(Res)]), LANGDialogChangePermissions); case Response of 1 : Result := True; 3 : begin @@ -1780,13 +1782,13 @@ begin with PDataItem(DataList[i])^ do if (not UpDir) and Selected then if IsDir and (not IsLnk) and ParamBool1 - then Engine.FillDirFiles(CurrPath + String(AName), AList, 1) - else AList.Add(Engine.GetFileInfoSL(CurrPath + String(AName))); + then Engine.FillDirFiles(CurrPath + String(FName), AList, 1) + else AList.Add(Engine.GetFileInfoSL(CurrPath + String(FName))); if (AList.Count = 0) and Assigned(SelectedItem) and (not SelectedItem^.UpDir) then with SelectedItem^ do if IsDir and (not IsLnk) and ParamBool1 - then Engine.FillDirFiles(CurrPath + String(AName), AList, 1) - else AList.Add(Engine.GetFileInfoSL(CurrPath + String(AName))); + then Engine.FillDirFiles(CurrPath + String(FName), AList, 1) + else AList.Add(Engine.GetFileInfoSL(CurrPath + String(FName))); Engine.ExplicitChDir('/'); SetProgress1Params(AList.Count); UpdateProgress1(0, '0 %'); @@ -1805,7 +1807,7 @@ begin // Process chmod if not HandleChmod(AList[i]) then Break; UpdateProgress1(i, Format('%d%%', [Round(Fr * i)])); - UpdateCaption1(ANSIToUTF8(PDataItemSL(AList[i])^.AName)); + UpdateCaption1(PDataItemSL(AList[i])^.FDisplayName); CommitGUIUpdate; end; @@ -1834,13 +1836,13 @@ var SkipAll: boolean; // DebugMsg(['Chown Debug: IsDir: ', AFileRec^.IsDir, ', Stage1: ', AFileRec^.Stage1, ', IsLnk: ', AFileRec^.IsLnk, '; Result = ', AFileRec^.IsDir and AFileRec^.Stage1 and (not AFileRec^.IsLnk)]); if (AFileRec^.IsDir and ParamBool1 and AFileRec^.Stage1 and (not AFileRec^.IsLnk)) or ((not AFileRec^.IsDir) and ParamBool1) then Exit; - Res := Engine.Chown(String(AFileRec^.AName), ParamCardinal1, ParamCardinal2); + Res := Engine.Chown(String(AFileRec^.FName), ParamCardinal1, ParamCardinal2); // DebugMsg(['Result : ', Res]); if Res <> 0 then if SkipAll then Result := True else begin - Response := ShowDirDeleteDialog(1, LANGTheFileDirectory, ANSIToUTF8(String(AFileRec^.AName)), Format(LANGCouldNotBeChownedS, - [ANSIToUTF8(GetErrorString(Res))]), LANGDialogChangeOwner); + Response := ShowDirDeleteDialog(1, LANGTheFileDirectory, String(AFileRec^.FDisplayName), Format(LANGCouldNotBeChownedS, + [GetErrorString(Res)]), LANGDialogChangeOwner); case Response of 1 : Result := True; 3 : begin @@ -1869,13 +1871,13 @@ begin with PDataItem(DataList[i])^ do if (not UpDir) and Selected then if IsDir and (not IsLnk) and ParamBool1 - then Engine.FillDirFiles(CurrPath + String(AName), AList, 1) - else AList.Add(Engine.GetFileInfoSL(CurrPath + String(AName))); + then Engine.FillDirFiles(CurrPath + String(FName), AList, 1) + else AList.Add(Engine.GetFileInfoSL(CurrPath + String(FName))); if (AList.Count = 0) and Assigned(SelectedItem) and (not SelectedItem^.UpDir) then with SelectedItem^ do if IsDir and (not IsLnk) and ParamBool1 - then Engine.FillDirFiles(CurrPath + String(AName), AList, 1) - else AList.Add(Engine.GetFileInfoSL(CurrPath + String(AName))); + then Engine.FillDirFiles(CurrPath + String(FName), AList, 1) + else AList.Add(Engine.GetFileInfoSL(CurrPath + String(FName))); Engine.ExplicitChDir('/'); SetProgress1Params(AList.Count); UpdateProgress1(0, '0 %'); @@ -1894,7 +1896,7 @@ begin // Process chmod if not HandleChown(AList[i]) then Break; UpdateProgress1(i, Format('%d%%', [Round(Fr * i)])); - UpdateCaption1(ANSIToUTF8(PDataItemSL(AList[i])^.AName)); + UpdateCaption1(PDataItemSL(AList[i])^.FDisplayName); CommitGUIUpdate; end; @@ -1949,8 +1951,8 @@ var AFSymLink: TFSymlink; FDirDelete.Caption := LANGDialogMakeSymlink; FDirDelete.AddButtons(2); FDirDelete.Label1.Caption := LANGTheSymbolicLink; - FDirDelete.Label2.Caption := ANSIToUTF8(NewName); - FDirDelete.Label3.Caption := Format(LANGCouldNotBeCreatedS, [ANSIToUTF8(GetErrorString(Res))]); + FDirDelete.Label2.Caption := NewName; + FDirDelete.Label3.Caption := Format(LANGCouldNotBeCreatedS, [GetErrorString(Res)]); FDirDelete.Label3.Visible := True; Response := Integer(FDirDelete.Run); finally @@ -1968,12 +1970,12 @@ begin Result := False; try AFSymlink := TFSymlink.Create(Application.MainForm); - AFSymlink.FromEntry.Text := ANSIToUTF8(FileName); - AFSymlink.ToEntry.Text := ANSIToUTF8(PossibleNewName); + AFSymlink.FromEntry.Text := StrToUTF8(FileName); + AFSymlink.ToEntry.Text := StrToUTF8(PossibleNewName); AFSymlink.ToEntry.SetFocus; AFSymlink.ToEntry.SelectAll; - if AFSymlink.Run = mbOK then Result := HandleCreateSymlink(UTF8ToANSI(AFSymlink.FromEntry.Text), - ProcessPattern(Engine, UTF8ToANSI(AFSymlink.ToEntry.Text), Engine.Path, '', False)); + if AFSymlink.Run = mbOK then Result := HandleCreateSymlink(UTF8ToStr(AFSymlink.FromEntry.Text), + ProcessPattern(Engine, UTF8ToStr(AFSymlink.ToEntry.Text), Engine.Path, '', False)); finally AFSymlink.Free; end; @@ -1995,8 +1997,8 @@ var Data: PDataItemSL; FDirDelete.Caption := LANGDialogEditSymlink; FDirDelete.AddButtons(2); FDirDelete.Label1.Caption := LANGTheSymbolicLink; - FDirDelete.Label2.Caption := ANSIToUTF8(ExistingName); - FDirDelete.Label3.Caption := Format(LANGCouldNotBeDeletedS, [ANSIToUTF8(GetErrorString(Res))]); + FDirDelete.Label2.Caption := StrToUTF8(ExistingName); + FDirDelete.Label3.Caption := Format(LANGCouldNotBeDeletedS, [GetErrorString(Res)]); FDirDelete.Label3.Visible := True; Response := Integer(FDirDelete.Run); finally @@ -2015,8 +2017,8 @@ var Data: PDataItemSL; FDirDelete.Caption := LANGDialogMakeSymlink; FDirDelete.AddButtons(2); FDirDelete.Label1.Caption := LANGTheSymbolicLink; - FDirDelete.Label2.Caption := ANSIToUTF8(ExistingName); - FDirDelete.Label3.Caption := Format(LANGCouldNotBeCreatedS, [ANSIToUTF8(GetErrorString(Res))]); + FDirDelete.Label2.Caption := StrToUTF8(ExistingName); + FDirDelete.Label3.Caption := Format(LANGCouldNotBeCreatedS, [GetErrorString(Res)]); FDirDelete.Label3.Visible := True; Response := Integer(FDirDelete.Run); finally @@ -2035,15 +2037,15 @@ begin try AFSymlink := TFSymlink.Create(Application); AFSymlink.Caption := LANGFEditSymlink_Caption; - AFSymlink.FromEntry.Text := ANSIToUTF8(FileName); + AFSymlink.FromEntry.Text := StrToUTF8(FileName); AFSymlink.Label1.Caption := LANGFEditSymlink_SymbolicLinkFilename; AFSymlink.Label1.UseUnderline := True; AFSymlink.Label2.Caption := LANGFEditSymlink_SymbolicLinkPointsTo; AFSymlink.Label2.UseUnderline := True; AFSymlink.FromEntry.Enabled := False; - AFSymlink.ToEntry.Text := ANSIToUTF8(Data^.LnkPointTo); + AFSymlink.ToEntry.Text := StrToUTF8(Data^.LnkPointTo); AFSymlink.ToEntry.SelectAll; - if AFSymlink.Run = mbOK then Result := HandleEditSymlink(UTF8ToANSI(AFSymlink.FromEntry.Text), UTF8ToANSI(AFSymlink.ToEntry.Text)); + if AFSymlink.Run = mbOK then Result := HandleEditSymlink(UTF8ToStr(AFSymlink.FromEntry.Text), UTF8ToStr(AFSymlink.ToEntry.Text)); finally AFSymlink.Free; end; @@ -2140,7 +2142,7 @@ begin AFOverwrite.SourceFile := SenderThread.FOverwriteSourceFile; AFOverwrite.DestFile := SenderThread.FOverwriteDestFile; SenderThread.FDialogResultOverwrite := Integer(AFOverwrite.Run); - SenderThread.FOverwriteRenameStr := UTF8ToANSI(AFOverwrite.RenameStr); + SenderThread.FOverwriteRenameStr := UTF8ToStr(AFOverwrite.RenameStr); finally AFOverwrite.Free; end; @@ -2453,7 +2455,7 @@ begin s := ReplaceStr(MountCommand, '%dev', Device); s := ReplaceStr(s, '%dir', MountPath); end; - Result := HandleSystemCommand(s, Format(LANGErrorMount, [ANSIToUTF8(MountPath)])); + Result := HandleSystemCommand(s, Format(LANGErrorMount, [StrToUTF8(MountPath)])); end; function TMounterItem.Umount: boolean; @@ -2466,7 +2468,7 @@ begin s := ReplaceStr(UmountCommand, '%dev', Device); s := ReplaceStr(s, '%dir', MountPath); end; - Result := HandleSystemCommand(s, Format(LANGErrorUmount, [ANSIToUTF8(MountPath)])); + Result := HandleSystemCommand(s, Format(LANGErrorUmount, [StrToUTF8(MountPath)])); end; function TMounterItem.Eject: boolean; @@ -2479,7 +2481,7 @@ begin s := ReplaceStr(UmountCommand, '%dev', Device); s := ReplaceStr(s, '%dir', MountPath); end; - Result := HandleSystemCommand(s, Format(LANGErrorEject, [ANSIToUTF8(MountPath)])); + Result := HandleSystemCommand(s, Format(LANGErrorEject, [StrToUTF8(MountPath)])); end; (********************************************************************************************************************************) @@ -2547,7 +2549,7 @@ var t: __time_t; if not Assigned(Item) then Exit; Data := Item.Data; if (not Assigned(Data)) or (not Data^.IsDir) then Exit; - APath := IncludeTrailingPathDelimiter(Engine.Path) + string(Data^.AName); + APath := IncludeTrailingPathDelimiter(Engine.Path) + string(Data^.FName); { List := TList.Create; Engine.FillDirFiles(APath, List, 1); @@ -2578,7 +2580,7 @@ var t: __time_t; if (ASize < 0) or FMainEscPressed or (Assigned(FRemoteWait) and FRemoteWait.Cancelled) then Exit; Data^.Size := ASize; - s := ANSIToUTF8(FormatSize(ASize, 0)); + s := FormatSize(ASize, 0); Libc.free(Data^.ColumnData[3]); // Data^.ColumnData[3] := Libc.malloc(Length(s) + 1); // Libc.memset(Data^.ColumnData[3], 0, Length(s) + 1); diff --git a/UCoreClasses.pas b/UCoreClasses.pas index c53289f..0267843 100644 --- a/UCoreClasses.pas +++ b/UCoreClasses.pas @@ -118,10 +118,10 @@ begin pwd := getpwent; while pwd <> nil do begin User := TUser.Create; - User.UserName := PgcharToString(pwd^.pw_name); - User.FullName := PgcharToString(pwd^.pw_gecos); - User.HomeDir := PgcharToString(pwd^.pw_dir); - User.LoginShell := PgcharToString(pwd^.pw_shell); + User.UserName := String(StrToUTF8(pwd^.pw_name)); + User.FullName := String(StrToUTF8(pwd^.pw_gecos)); + User.HomeDir := String(StrToUTF8(pwd^.pw_dir)); + User.LoginShell := String(StrToUTF8(pwd^.pw_shell)); User.UID := pwd^.pw_uid; User.GID := pwd^.pw_gid; UserList.Add(User); @@ -135,14 +135,14 @@ begin grp := getgrent; while grp <> nil do begin Group := TGroup.Create; - Group.GroupName := PgcharToString(grp^.gr_name); + Group.GroupName := String(StrToUTF8(grp^.gr_name)); Group.GID := grp^.gr_gid; Group.Users := TStringList.Create; {$R-} if grp^.gr_mem^ <> nil then begin i := 0; repeat - Group.Users.Add(PgcharToString(PCharArray(grp^.gr_mem^)[i])); + Group.Users.Add(String(StrToUTF8(PCharArray(grp^.gr_mem^)[i]))); Inc(i); until PCharArray(grp^.gr_mem^)[i] = nil; end; diff --git a/UCoreUtils.pas b/UCoreUtils.pas index 0e12550..1781a41 100644 --- a/UCoreUtils.pas +++ b/UCoreUtils.pas @@ -91,7 +91,7 @@ procedure ShowAbout; procedure TrimCRLFESC(var s: string); procedure TrimQuotes(var s: string); function QuoteStr(const Str: string): string; -function QuoteMarkupStr(const Str: string): string; +function QuoteMarkupStr(const Str: string; MarkupUnderscore: boolean = False): string; function QuotePercentStr(const Str: string): string; function RemoveQuotation(const Str: string): string; function GetStrSize(s: string): Int64; @@ -119,6 +119,14 @@ function UnixToDateTime(const AValue: Int64): TDateTime; procedure SaveItemToHistory(s: string; History: TStringList); +// All the UTF-8 conversion functions do strdup() +function StrToUTF8(s: string): string; overload; +function UTF8ToStr(s: string): string; overload; +function StrToUTF8(s: PChar): PChar; overload; +function UTF8ToStr(s: PChar): PChar; overload; +// function EnsureUTF8String(s: string): string; overload; +function EnsureUTF8String(s: PChar): PChar; overload; + // Calculate CRC32 Checksum, CRC is default $FFFFFFFF, @@ -149,7 +157,7 @@ uses DateUtils, GTKForms, GTKUtils, GTKView, ULocale, UConfig, UCore, UGnome, UM (********************************************************************************************************************************) function GetErrorString(ErrorNo: integer): string; begin - if ErrorNo >= 0 then Result := String(strerror(ErrorNo)) + if ErrorNo >= 0 then Result := StrToUTF8(String(strerror(ErrorNo))) else case ErrorNo of ERRException : Result := LANGUnknownException; @@ -161,7 +169,7 @@ end; (********************************************************************************************************************************) function GetSignalString(SignalNo: integer): string; begin - Result := strsignal(SignalNo); + Result := StrToUTF8(strsignal(SignalNo)); end; (********************************************************************************************************************************) @@ -430,8 +438,8 @@ begin MaxInputWord := Length(InputStr); MaxWilds := Length(Wilds); if IgnoreCase then begin { upcase all letters } - InputStr := AnsiUpperCase(InputStr); - Wilds := AnsiUpperCase(Wilds); + InputStr := WideUpperCase(InputStr); + Wilds := WideUpperCase(Wilds); end; if (MaxWilds = 0) or (MaxInputWord = 0) then begin Result := False; @@ -639,7 +647,7 @@ var Path : string; function CaseDirExists(DPath, DFileName: string): boolean; begin - if (AnsiCompareStr(Pattern, FileName) <> 0) and (AnsiCompareText(Pattern, FileName) = 0) and Directory and + if (WideCompareStr(Pattern, FileName) <> 0) and (WideCompareText(Pattern, FileName) = 0) and Directory and Engine.TwoSameFiles(DPath + Pattern, DPath + FileName) then Result := False else Result := Engine.DirectoryExists(DPath + DFileName); @@ -765,7 +773,7 @@ begin end; (********************************************************************************************************************************) -function QuoteMarkupStr(const Str: string): string; +function QuoteMarkupStr(const Str: string; MarkupUnderscore: boolean = False): string; var i: integer; begin Result := ''; @@ -774,7 +782,7 @@ begin if Str[i] = '<' then Result := Result + '<' else if Str[i] = '>' then Result := Result + '>' else if Str[i] = '&' then Result := Result + '&' else -// if Str[i] = '_' then Result := Result + '__' else + if (Str[i] = '_') and MarkupUnderscore then Result := Result + '__' else Result := Result + Str[i]; end; end; @@ -847,7 +855,7 @@ var i: integer; begin Result := 0; x := 0; - s := AnsiUpperCase(Trim(s)); + s := WideUpperCase(Trim(s)); if Length(s) = 0 then Exit; for i := Length(s) downto 1 do if s[i] in [#32, ThousandSeparator] then Delete(s, i, 1); @@ -1041,6 +1049,7 @@ begin Result := False; try DebugMsg(['*** Running ExecuteProgram begin']); +// DebugMsg(['ExecuteProgram: ConfTerminalCommand = "', ConfTerminalCommand, '"']); s := Trim(AppCMDLine); ErrorSignal := 0; Term := RunInTerminal; @@ -1211,7 +1220,7 @@ begin end; Result := Length(s) = 0; - if not Result then Application.MessageBox(Format('%s%s', [ErrorText, ANSIToUTF8(s)]), [mbOK], mbError, mbOK, mbOK); + if not Result then Application.MessageBox(Format('%s%s', [ErrorText, StrToUTF8(s)]), [mbOK], mbError, mbOK, mbOK); except on E: Exception do DebugMsg(['***** function HandleSystemCommand(''', Command, '''):Exception: ', E.Message]); end; @@ -1262,40 +1271,40 @@ begin if Data2^.IsDir and (not Data1^.IsDir) then Result := 1*mp else case SortColumnID of 1, 2 : begin - Result := CompareTextsEx(Data1^.AName, Data2^.AName); + Result := CompareTextsEx(Data1^.FDisplayName, Data2^.FDisplayName); if Data1^.IsDir and Data2^.IsDir then Result := Result * mp; end; - 3 : if Data1^.IsDir and Data2^.IsDir then Result := CompareTextsEx(Data1^.AName, Data2^.AName)*mp else begin - SeparateExt(String(Data1^.AName), s1, s2); - SeparateExt(String(Data2^.AName), s3, s4); - if ANSIUpperCase(s2) <> ANSIUpperCase(s4) + 3 : if Data1^.IsDir and Data2^.IsDir then Result := CompareTextsEx(Data1^.FDisplayName, Data2^.FDisplayName)*mp else begin + SeparateExt(String(Data1^.FDisplayName), s1, s2); + SeparateExt(String(Data2^.FDisplayName), s3, s4); + if WideUpperCase(s2) <> WideUpperCase(s4) then Result := CompareTextsEx(PChar(s2), PChar(s4)) else Result := CompareTextsEx(PChar(s1), PChar(s3)); end; - 4 : if Data1^.IsDir and Data2^.IsDir then Result := CompareTextsEx(Data1^.AName, Data2^.AName)*mp else + 4 : if Data1^.IsDir and Data2^.IsDir then Result := CompareTextsEx(Data1^.FDisplayName, Data2^.FDisplayName)*mp else if Data1^.Size > Data2^.Size then Result := -1 else if Data1^.Size < Data2^.Size then Result := 1 else - Result := CompareTextsEx(Data1^.AName, Data2^.AName); - 5, 6 : if Data1^.IsDir and Data2^.IsDir then Result := CompareTextsEx(Data1^.AName, Data2^.AName)*mp else + Result := CompareTextsEx(Data1^.FDisplayName, Data2^.FDisplayName); + 5, 6 : if Data1^.IsDir and Data2^.IsDir then Result := CompareTextsEx(Data1^.FDisplayName, Data2^.FDisplayName)*mp else if Data1^.ModifyTime > Data2^.ModifyTime then Result := -1 else if Data1^.ModifyTime < Data2^.ModifyTime then Result := 1 else - Result := CompareTextsEx(Data1^.AName, Data2^.AName); - 7 : if Data1^.IsDir and Data2^.IsDir then Result := CompareTextsEx(Data1^.AName, Data2^.AName)*mp else + Result := CompareTextsEx(Data1^.FDisplayName, Data2^.FDisplayName); + 7 : if Data1^.IsDir and Data2^.IsDir then Result := CompareTextsEx(Data1^.FDisplayName, Data2^.FDisplayName)*mp else if Frac(Data1^.ModifyTime) > Frac(Data2^.ModifyTime) then Result := -1 else if Frac(Data1^.ModifyTime) < Frac(Data2^.ModifyTime) then Result := 1 else - Result := CompareTextsEx(Data1^.AName, Data2^.AName); - 8 : if Data1^.IsDir and Data2^.IsDir then Result := CompareTextsEx(Data1^.AName, Data2^.AName)*mp else + Result := CompareTextsEx(Data1^.FDisplayName, Data2^.FDisplayName); + 8 : if Data1^.IsDir and Data2^.IsDir then Result := CompareTextsEx(Data1^.FDisplayName, Data2^.FDisplayName)*mp else if Data1^.UID > Data2^.UID then Result := -1 else if Data1^.UID < Data2^.UID then Result := 1 else - Result := CompareTextsEx(Data1^.AName, Data2^.AName); - 9 : if Data1^.IsDir and Data2^.IsDir then Result := CompareTextsEx(Data1^.AName, Data2^.AName)*mp else + Result := CompareTextsEx(Data1^.FDisplayName, Data2^.FDisplayName); + 9 : if Data1^.IsDir and Data2^.IsDir then Result := CompareTextsEx(Data1^.FDisplayName, Data2^.FDisplayName)*mp else if Data1^.GID > Data2^.GID then Result := -1 else if Data1^.GID < Data2^.GID then Result := 1 else - Result := CompareTextsEx(Data1^.AName, Data2^.AName); - 10 : if Data1^.IsDir and Data2^.IsDir then Result := CompareTextsEx(Data1^.AName, Data2^.AName)*mp else + Result := CompareTextsEx(Data1^.FDisplayName, Data2^.FDisplayName); + 10 : if Data1^.IsDir and Data2^.IsDir then Result := CompareTextsEx(Data1^.FDisplayName, Data2^.FDisplayName)*mp else if Data1^.Mode > Data2^.Mode then Result := -1 else if Data1^.Mode < Data2^.Mode then Result := 1 else - Result := CompareTextsEx(Data1^.AName, Data2^.AName); + Result := CompareTextsEx(Data1^.FDisplayName, Data2^.FDisplayName); else Result := 0; end; end; @@ -1331,6 +1340,90 @@ begin QuickSort(0, List.Count - 1); end; + + +(********************************************************************************************************************************) +function StrToUTF8(s: string): string; +begin + Result := String(StrToUTF8(PChar(s))); +end; + +function UTF8ToStr(s: string): string; +var bytes_read, bytes_written: gsize; + error: PGError; +begin + error := nil; + bytes_read := 0; + bytes_written := 0; + Result := g_locale_from_utf8(PChar(s), Length(s), @bytes_read, @bytes_written, @error); + if error <> nil then begin + // fallback to original string to avoid data loss + Result := s; + DebugMsg(['*** UTF8ToStr: error converting "', s, '" from UTF-8 (read ', bytes_read, ', written ', bytes_written, '): ', error^.message]); + g_error_free(error); + end; +end; + +function StrToUTF8(s: PChar): PChar; +var bytes_read, bytes_written: gsize; + error: PGError; + ns: PChar; + m: PChar; +begin + if g_utf8_validate(s, strlen(s), nil) then begin + Result := g_strndup(s, strlen(s)); + Exit; + end; +// DebugMsg(['StrToUTF8: string "', s, '" is not valid UTF-8.']); + error := nil; + bytes_read := 0; + bytes_written := 0; + ns := g_locale_to_utf8(s, strlen(s), @bytes_read, @bytes_written, @error); + if ns = nil then begin + // fallback to original string to avoid data loss + ns := g_strdup(s); + if error <> nil then m := error^.message + else m := 'unknown'; + DebugMsg(['*** StrToUTF8: error converting "', s, '" to UTF-8 (read ', bytes_read, ', written ', bytes_written, '): ', m]); + g_error_free(error); + end; + if @g_filename_display_name <> nil then begin + Result := g_filename_display_name(ns); + g_free(ns); + end else Result := ns; +end; + +function UTF8ToStr(s: PChar): PChar; +var bytes_read, bytes_written: gsize; + error: PGError; +begin + error := nil; + bytes_read := 0; + bytes_written := 0; + Result := g_locale_from_utf8(s, strlen(s), @bytes_read, @bytes_written, @error); + if error <> nil then begin + // fallback to original string to avoid data loss + Result := s; + DebugMsg(['*** UTF8ToStr: error converting "', s, '" from UTF-8 (read ', bytes_read, ', written ', bytes_written, '): ', error^.message]); + g_error_free(error); + end; +end; + +{ +function EnsureUTF8String(s: string): string; +begin + Result := s; + if @g_filename_display_name <> nil then Result := g_filename_display_name(PChar(s)); +end; +} + +function EnsureUTF8String(s: PChar): PChar; +begin + Result := s; + if @g_filename_display_name <> nil then Result := g_filename_display_name(s); +end; + + (********************************************************************************************************************************) {$IFDEF CPU64} function CRC32(CRC: LongWord; Data: Pointer; DataSize: LongWord): LongWord; @@ -1435,10 +1528,10 @@ begin end; function THash_MD5.DigestKey: string; -type TCharArray = array[1..40] of char; - PCharArray = ^TCharArray; +type TxCharArray = array[1..40] of char; + PxCharArray = ^TxCharArray; begin - Result := Copy(PCharArray(@FDigest)^, 1, 16); + Result := Copy(PxCharArray(@FDigest)^, 1, 16); end; procedure THash_MD5.Init; diff --git a/UEngines.pas b/UEngines.pas index 0541316..89fb4dd 100644 --- a/UEngines.pas +++ b/UEngines.pas @@ -37,10 +37,13 @@ const ERRException = -1; ConfDefaultDirCreationMask = 755; + type PDataItem = ^TDataItem; TDataItem = record - AName, LnkPointTo: PChar; + FName: PChar; // ANSI + FDisplayName: PChar; // always-valid UTF-8 + LnkPointTo: PChar; // ANSI ColumnData: array[0..9] of PChar; Size: Int64; UpDir: boolean; @@ -54,7 +57,10 @@ type PDataItemSL = ^TDataItemSL; TDataItemSL = record Stage1: boolean; - AName, LnkPointTo, ADestination: PChar; + FName: PChar; // ANSI + FDisplayName: PChar; // always-valid UTF-8 + LnkPointTo: PChar; // ANSI + ADestination: PChar; Size: Int64; Mode, UID, GID: Cardinal; IsDir, IsLnk, ForceMove, IsOnRO, IsExecutable: boolean; @@ -279,10 +285,13 @@ begin // DebugMsg(['x7']); with Item^ do begin // DebugMsg(['x8']); - AName := nil; + FName := nil; + FDisplayName := nil; LnkPointTo := nil; for i := 0 to Length(ColumnData) - 1 do ColumnData[i] := nil; - AName := strdup(Buf); + FName := strdup(Buf); + FDisplayName := StrToUTF8(Buf); +// FDisplayName := strdup(Buf); // DebugMsg(['x']); StatBuf := Libc.malloc(sizeof(TGlibc_stat64)); Libc.memset(StatBuf, 0, sizeof(TGlibc_stat64)); @@ -305,9 +314,9 @@ begin ModifyTime := UnixTimeToTDateTime(StatBuf^.st_mtim.tv_sec); {$ENDIF} if StatBuf^.st_uid = 4294967295 then UID := getuid - else UID := StatBuf^.st_uid; + else UID := StatBuf^.st_uid; if StatBuf^.st_gid = 4294967295 then GID := getgid - else GID := StatBuf^.st_gid; + else GID := StatBuf^.st_gid; UpDir := False; Selected := False; // DebugMsg(['(II) TLocalTreeEngine.GetListing(APath=', APath, '): freeing StatBuf...']); @@ -545,11 +554,13 @@ var Handle : PDirectoryStream; Item := Libc.malloc(SizeOf(TDataItemSL)); Libc.memset(Item, 0, SizeOf(TDataItemSL)); with Item^ do begin - AName := nil; + FName := nil; + FDisplayName := nil; LnkPointTo := nil; ADestination := nil; Stage1 := AStage1; - AName := strdup(PChar(FPath)); + FName := strdup(PChar(FPath)); + FDisplayName := StrToUTF8(PChar(FPath)); Size := StatBuf_local^.st_size; Mode := StatBuf_local^.st_mode; IsDir := __S_ISTYPE(StatBuf_local^.st_mode, __S_IFDIR); @@ -575,7 +586,7 @@ var Handle : PDirectoryStream; LnkBuf[i] := #0; LnkPointTo := Libc.malloc(i + 1); Libc.memset(LnkPointTo, 0, i + 1); - LnkPointTo := Libc.strncpy(LnkPointTo, @LnkBuf[0], i); + LnkPointTo := Libc.strncpy(LnkPointTo, @LnkBuf[0], i); // StrLCopy(LnkPointTo, @LnkBuf[0], i); end; end; @@ -644,12 +655,14 @@ begin Libc.memset(Result, 0, SizeOf(TDataItemSL)); // DebugMsg(['x1']); with Result^ do begin - AName := nil; + FName := nil; + FDisplayName := nil; LnkPointTo := nil; ADestination := nil; Stage1 := True; // DebugMsg(['x1']); - AName := strdup(PChar(APath)); + FName := strdup(PChar(APath)); + FDisplayName := StrToUTF8(PChar(APath)); Size := StatBuf^.st_size; Mode := StatBuf^.st_mode; IsDir := __S_ISTYPE(StatBuf^.st_mode, __S_IFDIR); @@ -786,7 +799,7 @@ var fsrc, fdest: PIOFile; try Res := True; repeat - DebugMsg(['Copy(sendfile): offset = ', offset, ', BytesDone = ', BytesDone, ', ftell(fsrc) = ', ftell(fsrc)]); + DebugMsg(['Copy(sendfile): offset = ', offset, ', BytesDone = ', BytesDone, ', ftell(fsrc) = ', ftell(fsrc)]); BytesRead := Libc.sendfile(glibc_fileno(fdest), glibc_fileno(fsrc), offset, FBlockSize); if BytesRead = -1 then begin if errno = EINVAL then begin @@ -908,7 +921,7 @@ end; function TLocalTreeEngine.IsOnSameFS(const Path1, Path2: string): boolean; var FStat1, FStat2: PGlibc_stat64; begin - DebugMsg(['** TLocalTreeEngine.IsOnSameFS("', Path1, '", "', Path2, '")']); +// DebugMsg(['** TLocalTreeEngine.IsOnSameFS("', Path1, '", "', Path2, '")']); Result := False; // Default fallback result (forces copy + delete) FStat1 := Libc.malloc(sizeof(TGlibc_stat64)); FStat2 := Libc.malloc(sizeof(TGlibc_stat64)); @@ -925,7 +938,7 @@ begin Result := FStat1^.st_dev = FStat2^.st_dev; Libc.free(FStat1); Libc.free(FStat2); - DebugMsg(['** TLocalTreeEngine.IsOnSameFS("', Path1, '", "', Path2, '") Result = ', Result]); +// DebugMsg(['** TLocalTreeEngine.IsOnSameFS("', Path1, '", "', Path2, '") Result = ', Result]); end; (********************************************************************************************************************************) @@ -1109,7 +1122,8 @@ begin try if Assigned(DataItem) then begin with DataItem^ do begin - if AName <> nil then Libc.free(AName); + if FName <> nil then Libc.free(FName); + if FDisplayName <> nil then Libc.free(FDisplayName); // if Assigned(ADestination) then Dispose(ADestination); if LnkPointTo <> nil then Libc.free(LnkPointTo); end; @@ -1125,7 +1139,8 @@ begin try if Assigned(DataItem) then begin with DataItem^ do begin - if AName <> nil then Libc.free(AName); + if FName <> nil then Libc.free(FName); + if FDisplayName <> nil then Libc.free(FDisplayName); if LnkPointTo <> nil then Libc.free(LnkPointTo); for i := 0 to Length(ColumnData) - 1 do if ColumnData[i] <> nil then Libc.free(ColumnData[i]); diff --git a/UFileAssoc.pas b/UFileAssoc.pas index 2764df8..2c1f708 100644 --- a/UFileAssoc.pas +++ b/UFileAssoc.pas @@ -176,8 +176,8 @@ begin begin if not IsLnk then Icon := FileIconCached.FPixbuf else Icon := FileIconLnkCached.FPixbuf; - if (Pos('.', AName) > 1) and (LastDelimiter('.', AName) < Length(AName)) then begin - Ext := ANSIUpperCase(Trim(Copy(AName, LastDelimiter('.', AName) + 1, Length(AName) - LastDelimiter('.', AName)))); + if (Pos('.', FName) > 1) and (LastDelimiter('.', FName) < Length(FName)) then begin + Ext := WideUpperCase(Trim(Copy(FDisplayName, LastDelimiter('.', FDisplayName) + 1, Length(FDisplayName) - LastDelimiter('.', FDisplayName)))); // Try to find a plugin which can handle this archive type b := False; diff --git a/UFileTypeSettings.pas b/UFileTypeSettings.pas index 3917e43..10fbeae 100644 --- a/UFileTypeSettings.pas +++ b/UFileTypeSettings.pas @@ -601,8 +601,8 @@ begin if Length(Trim(FNameExtEntry.Text)) = 0 then Exit; if FNameExtListView.Items.Count > 0 then for i := 0 to FNameExtListView.Items.Count - 1 do - if ANSIUpperCase(FNameExtListView.Items[i].AsString(0)) = ANSIUpperCase(Trim(FNameExtEntry.Text)) then Exit; - sx := ANSILowerCase(Trim(FNameExtEntry.Text)); + if WideUpperCase(FNameExtListView.Items[i].AsString(0)) = WideUpperCase(Trim(FNameExtEntry.Text)) then Exit; + sx := WideLowerCase(Trim(FNameExtEntry.Text)); if sx[1] = '.' then Delete(sx, 1, 1); FNameExtListView.Items.Add.SetValue(0, sx); s := TFileAssoc(ListView.Selected.AsPointer(2)).Extensions; @@ -789,10 +789,10 @@ begin then DefIcon := FolderIconCached else DefIcon := FileIconCached; TFileAssoc(ListView.Selected.AsPointer(2)).FileTypeIcon := IconEntry.Text; - if not FileExists(UTF8ToANSI(IconEntry.Text)) then Icon.CopyFromPixbuf(DefIcon) else + if not FileExists(IconEntry.Text) then Icon.CopyFromPixbuf(DefIcon) else begin Pixmap := TGDKPixbuf.Create(Self); - Pixmap.LoadFromFile(UTF8ToANSI(IconEntry.Text)); + Pixmap.LoadFromFile(IconEntry.Text); if Pixmap.FPixbuf <> nil then begin Pixmap.ScaleSimple(ConfRowHeightReal, ConfRowHeightReal); Icon.SetFromPixbuf(Pixmap); @@ -802,8 +802,8 @@ begin end; ListView.Selected.SetValue(3, Icon.GetPixbuf); if FUseGnomeIconEntry then - if FileExists(UTF8ToANSI(IconEntry.Text)) then GnomeIconButton.Filename := UTF8ToANSI(IconEntry.Text) - else GnomeIconButton.Filename := ''; + if FileExists(IconEntry.Text) then GnomeIconButton.Filename := IconEntry.Text + else GnomeIconButton.Filename := ''; end; end; @@ -814,8 +814,8 @@ begin Dialog := TGTKFileSelectionDialog.CreateWithTitle(Self, LANGBrowseForIcon); try Dialog.ShowFileOpButtons := False; - if FileExists(UTF8ToANSI(IconEntry.Text)) then Dialog.FileName := IconEntry.Text - else Dialog.FileName := IconPath; + if FileExists(IconEntry.Text) then Dialog.FileName := IconEntry.Text + else Dialog.FileName := IconPath; if Byte(Dialog.Run) = 251 then IconEntry.Text := Dialog.FileName; IconPath := IncludeTrailingPathDelimiter(ExtractFilePath(Dialog.FileName)); finally @@ -156,7 +156,7 @@ type PGnomeColorPicker = PGtkWidget; const AFTER_ALL_TABS = -1; NOT_IN_APP_WINDOWS = -2; -var libGnomeUI2Handle, libGnome2Handle, libGtk2Handle: Pointer; +var libGlib2Handle, libGtk2Handle, libGnome2Handle, libGnomeUI2Handle: Pointer; gnome_about_new: function (const name, version, copyright, comments: Pchar; const authors, documenters: PPchar; const translator_credits: Pchar; logo_pixbuf: PGdkPixbuf): PGtkWidget; cdecl; {$IFDEF KYLIX} @@ -179,6 +179,7 @@ var libGnomeUI2Handle, libGnome2Handle, libGtk2Handle: Pointer; gnome_date_edit_get_time: function (gde: PGnomeDateEdit): time_t; cdecl; gtk_event_box_set_visible_window: procedure (event_box: PGtkEventBox; visible_window: gboolean); cdecl; gtk_icon_size_lookup_for_settings: function (settings: PGtkSettings; size: TGtkIconSize; width, height: Pgint): gboolean; cdecl; + g_filename_display_name: function (const filename: PChar): PChar; cdecl; @@ -1228,6 +1229,20 @@ begin @gtk_event_box_set_visible_window := nil; // Dynamic loading + libGlib2Handle := dlopen('libglib-2.0.so.0', RTLD_LAZY); + if libGlib2Handle = nil then libGlib2Handle := dlopen('libglib-2.0.so', RTLD_LAZY); + if libGlib2Handle <> nil then begin + @g_filename_display_name := dlsym(libGlib2Handle, 'g_filename_display_name'); + DebugMsg(['libglib-2.0.so loaded, @g_filename_display_name = 0x', IntToHex(QWORD(@g_filename_display_name), 8)]); + end; + libGtk2Handle := dlopen('libgtk-x11-2.0.so.0', RTLD_LAZY); + if libGtk2Handle = nil then libGtk2Handle := dlopen('libgtk-x11-2.0.so', RTLD_LAZY); + if libGtk2Handle <> nil then begin + @gtk_event_box_set_visible_window := dlsym(libGtk2Handle, 'gtk_event_box_set_visible_window'); + @gtk_icon_size_lookup_for_settings := dlsym(libGtk2Handle, 'gtk_icon_size_lookup_for_settings'); + DebugMsg(['libgtk-x11-2.0.so loaded, @gtk_event_box_set_visible_window = 0x', IntToHex(QWORD(@gtk_event_box_set_visible_window), 8), + ', @gtk_icon_size_lookup_for_settings = 0x', IntToHex(QWORD(@gtk_icon_size_lookup_for_settings), 8)]); + end; libGnome2Handle := dlopen('libgnome-2.so.0', RTLD_LAZY); if libGnome2Handle = nil then libGnome2Handle := dlopen('libgnome-2.so', RTLD_LAZY); if libGnome2Handle <> nil then begin @@ -1254,14 +1269,6 @@ begin ', @gnome_icon_entry_new = 0x', IntToHex(QWORD(@gnome_icon_entry_new), 8), ', @gnome_date_edit_new = 0x', IntToHex(QWORD(@gnome_date_edit_new), 8), ', @libgnomeui_module_info_get = 0x', IntToHex(QWORD(@libgnomeui_module_info_get), 8)]); end; - libGtk2Handle := dlopen('libgtk-x11-2.0.so.0', RTLD_LAZY); - if libGtk2Handle = nil then libGtk2Handle := dlopen('libgtk-x11-2.0.so.0', RTLD_LAZY); - if libGtk2Handle <> nil then begin - @gtk_event_box_set_visible_window := dlsym(libGtk2Handle, 'gtk_event_box_set_visible_window'); - @gtk_icon_size_lookup_for_settings := dlsym(libGtk2Handle, 'gtk_icon_size_lookup_for_settings'); - DebugMsg(['libgtk-x11-2.0.so loaded, @gtk_event_box_set_visible_window = 0x', IntToHex(QWORD(@gtk_event_box_set_visible_window), 8), - ', @gtk_icon_size_lookup_for_settings = 0x', IntToHex(QWORD(@gtk_icon_size_lookup_for_settings), 8)]); - end; SetupGnomeLibs; end; @@ -1528,7 +1528,7 @@ begin DeactivateQuickFind(LeftPanel); if Application.GTKVersion_2_0_5_Up then Data := DataList[ItemIndex] else Data := AListView.Items[ItemIndex].AsPointer(0); - DebugMsg(['Selected:', Data^.AName]); + DebugMsg(['Selected:', Data^.FDisplayName]); if not Assigned(Data) then Exit; if Data^.UpDir then ChangingDir(LeftPanel, '..') else if Data^.IsDir then begin @@ -1536,16 +1536,16 @@ begin if AListView.Items.Count > 0 then AListView.Items[0].Selected := True; Application.ProcessMessages; end; - ChangingDir(LeftPanel, String(Data^.AName)); + ChangingDir(LeftPanel, Data^.FName); end else begin - Ext := ANSIUpperCase(Trim(Copy(String(Data^.AName), LastDelimiter('.', String(Data^.AName)) + 1, Length(String(Data^.AName)) - LastDelimiter('.', String(Data^.AName))))); + Ext := WideUpperCase(Trim(Copy(String(Data^.FDisplayName), LastDelimiter('.', String(Data^.FDisplayName)) + 1, Length(String(Data^.FDisplayName)) - LastDelimiter('.', String(Data^.FDisplayName))))); // Test for known internal functions if (Ext = 'SFV') or (Ext = 'MD5') then miVerifyChecksumsClick(Self) else if (Ext = 'CRC') or (Ext = '001') then miMergeFilesClick(Self) else - if not ((Engine is TLocalTreeEngine) and HandleVFSArchive(Ext, IncludeTrailingPathDelimiter(Engine.Path) + String(Data^.AName), String(Data^.AName), '/')) then + if not ((Engine is TLocalTreeEngine) and HandleVFSArchive(Ext, IncludeTrailingPathDelimiter(Engine.Path) + String(Data^.FName), String(Data^.FName), '/')) then if (not ConfUseURI) or ((Engine is TVFSEngine) and TVFSEngine(Engine).ArchiveMode) - then RunFile(IncludeTrailingPathDelimiter(Engine.Path) + String(Data^.AName), Engine, -1) - else RunFile(ExcludeTrailingPathDelimiter(Engine.GetPrefix) + IncludeTrailingPathDelimiter(Engine.Path) + String(Data^.AName), Engine, -1); + then RunFile(IncludeTrailingPathDelimiter(Engine.Path) + String(Data^.FName), Engine, -1) + else RunFile(ExcludeTrailingPathDelimiter(Engine.GetPrefix) + IncludeTrailingPathDelimiter(Engine.Path) + String(Data^.FName), Engine, -1); end; end; @@ -1568,8 +1568,8 @@ var ListView: TGTKListView; begin Result := False; for i := 0 to DataList.Count - 1 do - if (CaseSensitive and (ANSICompareStr(string(PDataItem(DataList[i])^.AName), AName) = 0)) or - ((not CaseSensitive) and (ANSICompareText(string(PDataItem(DataList[i])^.AName), AName) = 0)) then + if (CaseSensitive and (WideCompareStr(string(PDataItem(DataList[i])^.FDisplayName), AName) = 0)) or + ((not CaseSensitive) and (WideCompareText(string(PDataItem(DataList[i])^.FDisplayName), AName) = 0)) then begin Sel := i; Result := True; @@ -1647,7 +1647,7 @@ begin if DataList.Count > 0 then for i := 0 to DataList.Count - 1 do if PDataItem(DataList[i])^.Selected and (not PDataItem(DataList[i])^.UpDir) - then SelectedFiles.Add(PDataItem(DataList[i])^.AName); + then SelectedFiles.Add(PDataItem(DataList[i])^.FName); end; Editing := False; DeactivateQuickFind(LeftPanel); @@ -1687,12 +1687,12 @@ begin end else if OpenDirThread.ChDirResult <> 0 then begin if OpenDirThread.ChDirResult = 1 then Application.MessageBox(Format(LANGErrorGettingListingForSPanelNoPath, [LANGPanelStrings[LeftPanel], 'Exception']), [mbOK], mbError, mbNone, mbOK) - else Application.MessageBox(Format(LANGErrorGettingListingForSPanel, [LANGPanelStrings[LeftPanel], ANSIToUTF8(GetErrorString(OpenDirThread.ChDirResult)), ANSIToUTF8(NewPath)]), [mbOK], mbError, mbNone, mbOK); + else Application.MessageBox(Format(LANGErrorGettingListingForSPanel, [LANGPanelStrings[LeftPanel], GetErrorString(OpenDirThread.ChDirResult), NewPath]), [mbOK], mbError, mbNone, mbOK); DebugMsg(['TFMain.ChangingDir: Freeing thread...']); OpenDirThread.Free; end else begin if OpenDirThread.ListingResult <> 0 then begin - Application.MessageBox(Format(LANGErrorGettingListingForSPanel, [LANGPanelStrings[LeftPanel], ANSIToUTF8(GetErrorString(OpenDirThread.ListingResult)), Engine.Path]), [mbOK], mbError, mbNone, mbOK); + Application.MessageBox(Format(LANGErrorGettingListingForSPanel, [LANGPanelStrings[LeftPanel], GetErrorString(OpenDirThread.ListingResult), Engine.Path]), [mbOK], mbError, mbNone, mbOK); Exit; end; s := OpenDirThread.ASelItem; @@ -1707,15 +1707,16 @@ begin if DataList.Count > 0 then begin if PreserveSelection and (SelectedFiles.Count > 0) and (DataList.Count > 0) then for i := 0 to DataList.Count - 1 do - if (not PDataItem(DataList[i])^.UpDir) and (SelectedFiles.IndexOf(PDataItem(DataList[i])^.AName) >= 0) + if (not PDataItem(DataList[i])^.UpDir) and (SelectedFiles.IndexOf(PDataItem(DataList[i])^.FName) >= 0) then PDataItem(DataList[i])^.Selected := True; Sel := 0; - b := (NewPath = '..') and (Length(Trim(s)) > 0) and LookupItem(s, True); + b := (NewPath = '..') and (Length(Trim(s)) > 0) and LookupItem(StrToUTF8(s), True); if not b then b := (HiliString1 <> '') and LookupItem(HiliString1, True); - if (not b) and (HiliString1 <> '') then LookupItem(HiliString1, False); - if (not b) and (HiliString2 <> '') then LookupItem(HiliString2, True); - if (not b) and (HiliString2 <> '') then LookupItem(HiliString2, False); - if (Engine.Path = '/') and (NewPath = '/') then Sel := ListView.ConvertFromSorted(0); + if (not b) and (HiliString1 <> '') then b := LookupItem(HiliString1, False); + if (not b) and (HiliString2 <> '') then b := LookupItem(HiliString2, True); + if (not b) and (HiliString2 <> '') then b := LookupItem(HiliString2, False); +// DebugMsg(['TFMain.ChangingDir: Engine.Path = "', Engine.Path, '", NewPath = "', NewPath, '", HiliString1 = "', HiliString1, '", HiliString2 = "', HiliString2, '"']); + if (not b) and ((Engine.Path = '/') or (NewPath = '/')) and (HiliString1 = '') and (HiliString2 = '') then Sel := ListView.ConvertFromSorted(0); ListView.Items[Sel].Selected := True; // Application.ProcessMessages; ListView.Items[Sel].SetCursor(0, False, not Application.GTKVersion_2_2_0_Up, 0.5, 0); @@ -1729,7 +1730,7 @@ begin TabEngines[ANotebook.PageIndex] := Engine; s := ExtractFileName(ExcludeTrailingPathDelimiter(Engine.Path)); if s = '' then s := '/'; - SetTabLabel(ANotebook, ANotebook.PageIndex, ANSIToUTF8(s), ANSIToUTF8(Engine.Path)); + SetTabLabel(ANotebook, ANotebook.PageIndex, StrToUTF8(s), StrToUTF8(Engine.Path)); end; end; // of Chdir, Listing, ... Engine.ExplicitChDir('/'); @@ -1769,12 +1770,12 @@ begin if RightListView.Focused then LeftPanel := False else LeftPanel := LeftLastFocused; if LeftPanel then begin - if LeftPanelEngine.GetPrefix <> '' then s := ANSIToUTF8(Format(ConstFullPathFormatStr, [LeftPanelEngine.GetPrefix, LeftPanelEngine.Path])) - else s := ANSIToUTF8(LeftPanelEngine.Path); + if LeftPanelEngine.GetPrefix <> '' then s := Format(ConstFullPathFormatStr, [LeftPanelEngine.GetPrefix, LeftPanelEngine.Path]) + else s := LeftPanelEngine.Path; end else - if RightPanelEngine.GetPrefix <> '' then s := ANSIToUTF8(Format(ConstFullPathFormatStr, [RightPanelEngine.GetPrefix, RightPanelEngine.Path])) - else s := ANSIToUTF8(RightPanelEngine.Path); - Caption := Format('Tux Commander [%s]', [s]); + if RightPanelEngine.GetPrefix <> '' then s := Format(ConstFullPathFormatStr, [RightPanelEngine.GetPrefix, RightPanelEngine.Path]) + else s := RightPanelEngine.Path; + Caption := Format('Tux Commander [%s]', [StrToUTF8(s)]); end; procedure TFMain.UpdatePanelInfo; @@ -1785,11 +1786,11 @@ begin UpdateCaption; Time1 := Now; if LeftPanelEngine.GetPrefix <> '' - then LeftPathLabel.Caption := ANSIToUTF8(Format(ConstFullPathFormatStr, [LeftPanelEngine.GetPrefix, LeftPanelEngine.Path])) - else LeftPathLabel.Caption := ANSIToUTF8(LeftPanelEngine.Path); + then LeftPathLabel.Caption := StrToUTF8(Format(ConstFullPathFormatStr, [LeftPanelEngine.GetPrefix, LeftPanelEngine.Path])) + else LeftPathLabel.Caption := StrToUTF8(LeftPanelEngine.Path); if RightPanelEngine.GetPrefix <> '' - then RightPathLabel.Caption := ANSIToUTF8(Format(ConstFullPathFormatStr, [RightPanelEngine.GetPrefix, RightPanelEngine.Path])) - else RightPathLabel.Caption := ANSIToUTF8(RightPanelEngine.Path); + then RightPathLabel.Caption := StrToUTF8(Format(ConstFullPathFormatStr, [RightPanelEngine.GetPrefix, RightPanelEngine.Path])) + else RightPathLabel.Caption := StrToUTF8(RightPanelEngine.Path); LeftPathLabel.UseMarkup := True; RightPathLabel.UseMarkup := True; if LeftLastFocused then s := LeftPathLabel.Caption @@ -1798,19 +1799,19 @@ begin LeftPanelEngine.GetFileSystemInfo(LeftPanelEngine.Path, FSSize, FSFree, FSName); if FSName <> '' then LeftDiskInfoLabel.Caption := Format(LANGDiskStatVolNameFmt, [FSName, - ANSIToUTF8(FormatSize(FSFree, 1024)), - ANSIToUTF8(FormatSize(FSSize, 1024))]) + FormatSize(FSFree, 1024), + FormatSize(FSSize, 1024)]) else LeftDiskInfoLabel.Caption := Format(LANGDiskStatFmt, - [ANSIToUTF8(FormatSize(FSFree, 1024)), - ANSIToUTF8(FormatSize(FSSize, 1024))]); + [FormatSize(FSFree, 1024), + FormatSize(FSSize, 1024)]); RightPanelEngine.GetFileSystemInfo(RightPanelEngine.Path, FSSize, FSFree, FSName); if FSName <> '' then RightDiskInfoLabel.Caption := Format(LANGDiskStatVolNameFmt, [FSName, - ANSIToUTF8(FormatSize(FSFree, 1024)), - ANSIToUTF8(FormatSize(FSSize, 1024))]) + FormatSize(FSFree, 1024), + FormatSize(FSSize, 1024)]) else RightDiskInfoLabel.Caption := Format(LANGDiskStatFmt, - [ANSIToUTF8(FormatSize(FSFree, 1024)), - ANSIToUTF8(FormatSize(FSSize, 1024))]); + [FormatSize(FSFree, 1024), + FormatSize(FSSize, 1024)]); LeftDiskInfoLabel.UseMarkup := True; RightDiskInfoLabel.UseMarkup := True; @@ -1853,8 +1854,8 @@ begin end; end; end; - s := Format(LANGStatusLineFmt, [ANSIToUTF8(FormatSize(Size, 1024)), - ANSIToUTF8(FormatSize(TotalSize, 1024)), NumSel, TotalFiles]); + s := Format(LANGStatusLineFmt, [FormatSize(Size, 1024), + FormatSize(TotalSize, 1024), NumSel, TotalFiles]); if LeftPanel then LeftStatusLine.Caption := s else RightStatusLine.Caption := s; end; @@ -1981,7 +1982,7 @@ begin if Assigned(Data) and (not Data^.UpDir) and (ConfSelectAllDirs or (not Data^.IsDir)) {and (Data^.Selected <> ExpandSel)} then begin b := False; for j := 0 to Length(Wilds) - 1 do - b := b or IsWild(String(Data^.AName), Wilds[j], True); + b := b or IsWild(String(Data^.FDisplayName), Wilds[j], True); if b then begin Data^.Selected := ExpandSel; Found := True; @@ -2114,7 +2115,7 @@ begin if not ImageCol then begin if Editing and (InplaceEditItem.Data = Data) and (ColumnID < 3) and ((ColumnID = 0) or (ColumnID = 1) or Assigned(tree_column^.editable_widget)) then begin - if (ColumnID = 0) or (ColumnID = 1) then s := PChar(ANSIToUTF8(string(AName))) else s := nil; + if (ColumnID = 0) or (ColumnID = 1) then s := FDisplayName else s := nil; g_object_set(cell, 'text', s, 'foreground-gdk', AFGColor, nil); if Application.GTKVersion_2_2_0_Up or (not ConfUseFileTypeIcons) then g_object_set(cell, 'background-gdk', ABGColor, nil); @@ -2162,7 +2163,7 @@ begin try FNewDir := TFNewDir.Create(Self); if FNewDir.Run = mbOK - then NewDir := Utf8ToAnsi(FNewDir.Entry.Text) + then NewDir := UTF8ToStr(FNewDir.Entry.Text) else Exit; finally FNewDir.Free; @@ -2170,7 +2171,7 @@ begin if NewDir = '' then Exit; if not MakeDirectory(ListView, Engine, LeftPanel, NewDir) then Exit; - ChangingDir(LeftPanel, Engine.Path, NewDir); + ChangingDir(LeftPanel, Engine.Path, StrToUTF8(NewDir)); DoRefresh(not LeftPanel, True, True); except end; finally @@ -2233,7 +2234,7 @@ begin for i := 0 to DataList.Count - 1 do with PDataItem(DataList[i])^ do if Selected and (not UpDir) then begin - s2 := s2 + #10 + AName; + s2 := s2 + #10 + FDisplayName; Inc(j); if j = 5 then Break; end; @@ -2242,8 +2243,8 @@ begin smsg := Format(LANGDoYouReallyWantToDeleteTheSS, [s, s2]); end else begin if Assigned(Data) then - if Data^.IsDir then s := Format(LANGDirectoryS, [ANSIToUTF8(string(Data^.AName))]) - else s := Format(LANGFileS, [ANSIToUTF8(string(Data^.AName))]); + if Data^.IsDir then s := Format(LANGDirectoryS, [string(Data^.FDisplayName)]) + else s := Format(LANGFileS, [string(Data^.FDisplayName)]); smsg := Format(LANGDoYouReallyWantToDeleteTheS, [s]); end; if Application.MessageBox(QuotePercentStr(smsg), [mbYes, mbNo], mbQuestion, mbNone, mbNo) <> mbYes then Exit; @@ -2370,7 +2371,7 @@ end; procedure TFMain.DoCopyMove(LeftPanel, CopyMode, ShiftPressed: boolean; ListView: TGTKListView; Engine: TPanelEngine; DataList: TList); var i: integer; SelCount: longint; - NewPath, SelSingle, NextItem1, NextItem2: string; + NewPath, NewPathx, SelSingle, NextItem1, NextItem2: string; AWorkingThread: TWorkerThread; AFProgress: TFProgress; CurrentEngine, OppositeEngine: TPanelEngine; @@ -2392,7 +2393,7 @@ begin SelSingle := ''; if SelCount = 0 then begin SelCount := 1; - SelSingle := PDataItem(ListView.Selected.Data)^.AName; + SelSingle := PDataItem(ListView.Selected.Data)^.FDisplayName; end; if LeftPanel then begin @@ -2413,17 +2414,19 @@ begin FCopyMove.Label1.Caption := Format(LANGMoveRenameDFileDirectoriesTo, [SelCount]); end; if ShiftPressed then begin - if SelSingle <> '' then FCopyMove.Entry.Text := ANSIToUTF8(SelSingle) + if SelSingle <> '' then FCopyMove.Entry.Text := SelSingle else FCopyMove.Entry.Text := '*.*'; end else - if OppositeEngine is TLocalTreeEngine then FCopyMove.Entry.Text := ANSIToUTF8(OppositeEngine.Path) - else FCopyMove.Entry.Text := ANSIToUTF8(Format(ConstFullPathFormatStr, [OppositeEngine.GetPrefix, OppositeEngine.Path])); + if OppositeEngine is TLocalTreeEngine then FCopyMove.Entry.Text := OppositeEngine.Path + else FCopyMove.Entry.Text := Format(ConstFullPathFormatStr, [OppositeEngine.GetPrefix, OppositeEngine.Path]); FCopyMove.Entry.SelectAll; if FCopyMove.Run <> mbOK then Exit; - NewPath := UTF8ToANSI(FCopyMove.Entry.Text); + NewPathx := FCopyMove.Entry.Text; + NewPath := UTF8ToStr(FCopyMove.Entry.Text); finally FCopyMove.Free; end; + DebugMsg(['TFMain.DoCopyMove: NewPath = "', NewPath, '"']); // Handle password in archives if (CurrentEngine is TVFSEngine) and (CurrentEngine as TVFSEngine).GetPasswordRequired and (Length((CurrentEngine as TVFSEngine).Password) < 1) then @@ -2431,7 +2434,11 @@ begin if (OppositeEngine is TVFSEngine) and (OppositeEngine as TVFSEngine).GetPasswordRequired and (Length((OppositeEngine as TVFSEngine).Password) < 1) then if not HandleSetPassword(OppositeEngine) then Exit; + NextItem1 := ''; NextItem2 := ''; FindNextSelected(ListView, DataList, NextItem1, NextItem2); + DebugMsg(['TFMain.DoCopyMove: FindNextSelected, NextItem1 = "', NextItem1, '", NextItem2 = "', NextItem2, '"']); + if ShiftPressed then NextItem1 := NewPathx; + AWorkingThread := TWorkerThread.Create; DebugMsg(['TFMain.DoCopyMove: Creating thread...']); AFProgress := TFProgress.Create(Self); @@ -2620,8 +2627,9 @@ begin DataList := RightPanelData; end; Editing := False; + DebugMsg(['TFMain.ListViewEdited: FDisplayName = "', String(PDataItem(InplaceEditItem.Data)^.FDisplayName), '", NewText = "', NewText, '"']); if (AListView.Selected = InplaceEditItem) and (AListView.Selected.Data = InplaceEditItem.Data) and - (String(PDataItem(InplaceEditItem.Data)^.AName) <> NewText) then + (String(PDataItem(InplaceEditItem.Data)^.FDisplayName) <> NewText) then begin AWorkingThread := TWorkerThread.Create; DebugMsg(['TFMain.ListViewEdited: Creating thread...']); @@ -2639,7 +2647,7 @@ begin AWorkingThread.WorkerProcedure := CopyFilesWorker; AWorkingThread.ParamBool3 := False; AWorkingThread.ParamBool4 := True; - AWorkingThread.ParamString1 := UTF8ToANSI(NewText); + AWorkingThread.ParamString1 := UTF8ToStr(NewText); AWorkingThread.ParamDataItem1 := InplaceEditItem.Data; AWorkingThread.Resume; // AWorkingThread.WorkerProcedure(AWorkingThread); @@ -2654,6 +2662,7 @@ begin end; s1 := ''; s2 := ''; FindNextSelected(AListView, DataList, s1, s2); + DebugMsg(['TFMain.ListViewEdited: FindNextSelected, s1 = "', s1, '", s2 = "', s2, '"']); ChangingDir(AListView = LeftListView, Engine.Path, {String(PDataItem(InplaceEditItem.Data)^.AName),} NewText, s2); DoRefresh(AListView <> LeftListView, True, True); end; @@ -2680,11 +2689,11 @@ begin if Sender = LeftListView then begin if LeftPanelNotebook.Visible and (LeftPathsHighlight.Count > LeftPanelNotebook.PageIndex) and (LeftPanelNotebook.PageIndex >= 0) and Assigned(LeftListView.Selected) and Assigned(LeftListView.Selected.Data) - then LeftPathsHighlight[LeftPanelNotebook.PageIndex] := PDataItem(LeftListView.Selected.Data)^.AName; + then LeftPathsHighlight[LeftPanelNotebook.PageIndex] := PDataItem(LeftListView.Selected.Data)^.FName; end else if RightPanelNotebook.Visible and (RightPathsHighlight.Count > RightPanelNotebook.PageIndex) and (RightPanelNotebook.PageIndex >= 0) and Assigned(RightListView.Selected) and Assigned(RightListView.Selected.Data) - then RightPathsHighlight[RightPanelNotebook.PageIndex] := PDataItem(RightListView.Selected.Data)^.AName; + then RightPathsHighlight[RightPanelNotebook.PageIndex] := PDataItem(RightListView.Selected.Data)^.FName; { if Application.GTKVersion_2_6_0_Up then begin AListView := Sender as TGTKListView; if Assigned(AListView) and Assigned(AListView.Selected) and Assigned(AListView.Selected.Data) and Assigned(PDataItem(AListView.Selected.Data)^.ItemColor) @@ -2728,6 +2737,7 @@ var Entry: TGTKEntry; Data: PDataItem; Found: boolean; OldSelectionChangedEvent: TNotifyEvent; + g: PChar; begin Result := False; if not QuickFind then Exit; @@ -2741,18 +2751,26 @@ begin DataList := RightPanelData; end; if Key = GDK_BACKSPACE then begin - if Length(Entry.Text) > 0 then Entry.Text := AnsiToUTF8(Copy(UTF8ToAnsi(Entry.Text), 1, Length(UTF8ToAnsi(Entry.Text)) - 1)); - NewText := UTF8ToAnsi(Entry.Text); + if g_utf8_strlen(PChar(Entry.Text), -1) > 0 then begin +// DebugMsg(['TFMain.QuickFindSendKey: before delete: "', Entry.Text, '", ansi = "', UTF8ToStr(Entry.Text), '"']); + g := malloc(Length(Entry.Text)); + memset(g, 0, Length(Entry.Text)); + g_utf8_strncpy(g, PChar(Entry.Text), g_utf8_strlen(PChar(Entry.Text), -1) - 1); +// DebugMsg(['TFMain.QuickFindSendKey: after delete: "', g, '", ansi = "', UTF8ToStr(g), '"']); + Entry.Text := g; + Libc.free(g); + end; + NewText := Entry.Text; end else begin - s := UTF8ToANSI(UTF8Encode(WideChar(KeyValToUnicode(Key)))); + s := UTF8Encode(WideChar(KeyValToUnicode(Key))); if (Length(s) = 0) or (s = #0) then Exit; - NewText := UTF8ToAnsi(Entry.Text) + s; + NewText := Entry.Text + s; end; if (DataList.Count > 0) and (Length(NewText) > 0) then begin Found := False; for i := 0 to DataList.Count - 1 do begin Data := DataList[AListView.ConvertFromSorted(i)]; - if Assigned(Data) and (not Data^.UpDir) and (Pos(AnsiUpperCase(NewText), AnsiUpperCase(Data^.AName)) = 1) then begin + if Assigned(Data) and (not Data^.UpDir) and (Pos(WideUpperCase(NewText), WideUpperCase(Data^.FDisplayName)) = 1) then begin Found := True; OldSelectionChangedEvent := AListView.OnSelectionChanged; AListView.OnSelectionChanged := nil; @@ -2762,7 +2780,7 @@ begin Break; end; end; - if Found then Entry.Text := AnsiToUTF8(NewText) + if Found then Entry.Text := NewText else Beep; Result := True; end; @@ -2807,13 +2825,13 @@ begin FChecksum.Engine := Engine; FChecksum.DataList := DataList; FChecksum.AListView := AListView; - if SelCount = 0 then b := FChecksum.ProcessFile(IncludeTrailingPathDelimiter(Engine.Path) + string(PDataItem(AListView.Selected.Data)^.AName)) + if SelCount = 0 then b := FChecksum.ProcessFile(IncludeTrailingPathDelimiter(Engine.Path) + string(PDataItem(AListView.Selected.Data)^.FName)) else begin b := False; for i := 0 to DataList.Count - 1 do with PDataItem(DataList[i])^ do if (not UpDir) and (not IsDir) and Selected then {$B+} - b := b or FChecksum.ProcessFile(IncludeTrailingPathDelimiter(Engine.Path) + string(AName)); + b := b or FChecksum.ProcessFile(IncludeTrailingPathDelimiter(Engine.Path) + string(FName)); {$B-} end; if b and (FChecksum.List.Count > 0) then FChecksum.Run; @@ -2865,17 +2883,17 @@ begin FChecksumDruid.Engine := Engine; if Engine.Path = '/' then FChecksumDruid.DirName := 'root' else FChecksumDruid.DirName := ExtractFileName(ExcludeTrailingPathDelimiter(Engine.Path)); - if SelCount = 0 then FChecksumDruid.FileNames.Add(IncludeTrailingPathDelimiter(Engine.Path) + string(PDataItem(AListView.Selected.Data)^.AName)) + if SelCount = 0 then FChecksumDruid.FileNames.Add(IncludeTrailingPathDelimiter(Engine.Path) + string(PDataItem(AListView.Selected.Data)^.FName)) else for i := 0 to DataList.Count - 1 do with PDataItem(DataList[i])^ do if (not UpDir) and (not IsDir) and Selected then - FChecksumDruid.FileNames.Add(IncludeTrailingPathDelimiter(Engine.Path) + string(AName)); + FChecksumDruid.FileNames.Add(IncludeTrailingPathDelimiter(Engine.Path) + string(FName)); FChecksumDruid.Run; finally if FChecksumDruid.SeparateFileCheckBox.Checked then DoRefresh(AListView = LeftListView, True, True) - else ChangingDir(AListView = LeftListView, Engine.Path, FChecksumDruid.FileNameEntry.Text, PDataItem(AListView.Selected.Data)^.AName); + else ChangingDir(AListView = LeftListView, Engine.Path, FChecksumDruid.FileNameEntry.Text, PDataItem(AListView.Selected.Data)^.FName); DoRefresh(AListView <> LeftListView, True, True); FChecksumDruid.Free; Engine.ExplicitChDir('/'); @@ -2923,12 +2941,12 @@ begin FNewDir := TFNewDir.Create(Self); FNewDir.Caption := LANGMergeCaption; FNewDir.Label1.SetSizeRequest(500, -1); - FNewDir.Label1.Caption := Format(LANGMergeSAndAllFilesWithAscendingNamesToTheFollowingDirectory, [ANSIToUTF8(PDataItem(AListView.Selected.Data)^.AName)]); - if LeftPanel then FNewDir.Entry.Text := ANSIToUTF8(RightPanelEngine.Path) - else FNewDir.Entry.Text := ANSIToUTF8(LeftPanelEngine.Path); + FNewDir.Label1.Caption := Format(LANGMergeSAndAllFilesWithAscendingNamesToTheFollowingDirectory, [PDataItem(AListView.Selected.Data)^.FDisplayName]); + if LeftPanel then FNewDir.Entry.Text := StrToUTF8(RightPanelEngine.Path) + else FNewDir.Entry.Text := StrToUTF8(LeftPanelEngine.Path); FNewDir.Entry.SelectAll; if FNewDir.Run = mbOK - then FilePath := UTF8ToAnsi(FNewDir.Entry.Text) + then FilePath := UTF8ToStr(FNewDir.Entry.Text) else Exit; finally FNewDir.Free; @@ -2940,7 +2958,7 @@ begin AFProgress := TFProgress.Create(Self); try AWorkingThread.ParamString1 := FilePath; - AWorkingThread.ParamString2 := IncludeTrailingPathDelimiter(Engine.Path) + PDataItem(AListView.Selected.Data)^.AName; + AWorkingThread.ParamString2 := IncludeTrailingPathDelimiter(Engine.Path) + PDataItem(AListView.Selected.Data)^.FName; HasInitialCRC := CRCGetInfo(AWorkingThread.ParamString2, Engine, TargetName, TargetCRC, TargetSize); AWorkingThread.ParamString3 := TargetName; AWorkingThread.ParamBool1 := HasInitialCRC; @@ -2965,7 +2983,7 @@ begin AWorkingThread.Free; end; - ChangingDir(LeftPanel, Engine.Path, s, PDataItem(AListView.Selected.Data)^.AName); + ChangingDir(LeftPanel, Engine.Path, s, PDataItem(AListView.Selected.Data)^.FName); DoRefresh(not LeftPanel, True, True); finally Application.ProcessMessages; @@ -3008,23 +3026,23 @@ begin FilePath := ''; try FSplitFile := TFSplitFile.Create(Self); - FSplitFile.Label1.Caption := Format(LANGSplitTheFileSToDirectory, [ANSIToUTF8(PDataItem(AListView.Selected.Data)^.AName)]); + FSplitFile.Label1.Caption := Format(LANGSplitTheFileSToDirectory, [PDataItem(AListView.Selected.Data)^.FDisplayName]); FSplitFile.Label1.UseUnderline := True; - if LeftPanel then FSplitFile.Entry.Text := AnsiToUtf8(RightPanelEngine.Path) - else FSplitFile.Entry.Text := AnsiToUtf8(LeftPanelEngine.Path); + if LeftPanel then FSplitFile.Entry.Text := StrToUTF8(RightPanelEngine.Path) + else FSplitFile.Entry.Text := StrToUTF8(LeftPanelEngine.Path); FSplitFile.Entry.SelectAll; if FSplitFile.Run = mbOK - then FilePath := UTF8ToAnsi(FSplitFile.Entry.Text) + then FilePath := UTF8ToStr(FSplitFile.Entry.Text) else Exit; DeleteTarget := FSplitFile.DeleteTargetCheckBox.Checked; MaxSize := 0; for i := 1 to Length(SplitConsts) do - if Trim(AnsiUpperCase(SplitConsts[i].Title)) = Trim(AnsiUpperCase(FSplitFile.SizeCombo.Entry.Text)) then + if Trim(WideUpperCase(SplitConsts[i].Title)) = Trim(WideUpperCase(FSplitFile.SizeCombo.Entry.Text)) then begin MaxSize := SplitConsts[i].PartSize; Break; end; - if MaxSize = 0 then MaxSize := GetStrSize(UTF8ToANSI(FSplitFile.SizeCombo.Entry.Text)); + if MaxSize = 0 then MaxSize := GetStrSize(FSplitFile.SizeCombo.Entry.Text); finally FSplitFile.Free; end; @@ -3034,7 +3052,7 @@ begin DebugMsg(['TFMain.miSplitFileClick: Creating thread...']); AFProgress := TFProgress.Create(Self); try - AWorkingThread.ParamString1 := IncludeTrailingPathDelimiter(Engine.Path) + PDataItem(AListView.Selected.Data)^.AName; + AWorkingThread.ParamString1 := IncludeTrailingPathDelimiter(Engine.Path) + PDataItem(AListView.Selected.Data)^.FName; AWorkingThread.ParamString2 := FilePath; AWorkingThread.ParamBool1 := DeleteTarget; AWorkingThread.ParamInt64 := MaxSize; @@ -3105,7 +3123,7 @@ begin if (not Assigned(AListView.Selected)) or (not Assigned(AListView.Selected.Data)) or PDataItem(AListView.Selected.Data)^.UpDir or (not PDataItem(AListView.Selected.Data)^.IsDir) then begin if Length(s) > 1 then s := IncludeTrailingPathDelimiter(Copy(s, 1, LastDelimiter(PathDelim, s))); end - else s := IncludeTrailingPathDelimiter(IncludeTrailingPathDelimiter(s) + PDataItem(AListView.Selected.Data)^.AName); + else s := IncludeTrailingPathDelimiter(IncludeTrailingPathDelimiter(s) + PDataItem(AListView.Selected.Data)^.FName); end; if IncludeTrailingPathDelimiter(TargetEngine.Path) <> s then begin if LeftPanel then RightPanelEngine := TargetEngine @@ -3182,15 +3200,15 @@ begin ANewDir.Label1.FocusControl := ANewDir.Entry; if Assigned(AListView.Selected) and Assigned(AListView.Selected.Data) and (not PDataItem(AListView.Selected.Data)^.IsDir) and (not PDataItem(AListView.Selected.Data)^.UpDir) - then ANewDir.Entry.Text := AnsiToUTF8(PDataItem(AListView.Selected.Data)^.AName) + then ANewDir.Entry.Text := PDataItem(AListView.Selected.Data)^.FDisplayName else ANewDir.Entry.Text := ''; if Length(ANewDir.Entry.Text) > 0 then ANewDir.Entry.SelectAll; if ANewDir.Run <> mbOK then Exit; - AFile := IncludeTrailingPathDelimiter(Engine.Path) + UTF8ToAnsi(ANewDir.Entry.Text); + AFile := IncludeTrailingPathDelimiter(Engine.Path) + UTF8ToStr(ANewDir.Entry.Text); finally ANewDir.Free; end; - end else AFile := IncludeTrailingPathDelimiter(Engine.Path) + PDataItem(AListView.Selected.Data)^.AName; + end else AFile := IncludeTrailingPathDelimiter(Engine.Path) + PDataItem(AListView.Selected.Data)^.FName; EditViewFileInternal(Self, AFile, Engine, View, NewFile); @@ -3226,7 +3244,7 @@ begin end else AViewer.Resume; *) AViewer := TFViewer.Create(ParentWindow); if not AViewer.LoadFile(Filename) then begin - Application.MessageBox(Format(LANGCannotLoadFile, [ANSIToUTF8(Filename)]), [mbOK], mbError, mbNone, mbOK); + Application.MessageBox(Format(LANGCannotLoadFile, [Filename]), [mbOK], mbError, mbNone, mbOK); AViewer.Free; end else begin // gtk_window_set_transient_for(PGtkWindow(AViewer.FWidget), PGtkWindow(ParentWindow.FWidget)); @@ -3236,7 +3254,7 @@ begin if View then x := ConfViewerTerminalBehaviour else x := ConfEditorTerminalBehaviour; if not ExecuteProgram(Format('%s %s', [s, QuoteStr(Filename)]), ExtractFilePath(Filename), x = 0, x = 1, Error) then - Application.MessageBox(Format(LANGCannotExecuteSPleaseCheckTheConfiguration, [ANSIToUTF8(s)]), [mbOK], mbError, mbNone, mbOK); + Application.MessageBox(Format(LANGCannotExecuteSPleaseCheckTheConfiguration, [s]), [mbOK], mbError, mbNone, mbOK); end; end; @@ -3285,24 +3303,24 @@ begin AutodetectGUI := True; RunInTerminal := False; if (Pos('.', ExtractFileName(Path)) > 0) and (LastDelimiter('.', ExtractFileName(Path)) < Length(ExtractFileName(Path))) then begin - Ext := ANSIUpperCase(Trim(Copy(ExtractFileName(Path), LastDelimiter('.', ExtractFileName(Path)) + 1, Length(ExtractFileName(Path)) - LastDelimiter('.', ExtractFileName(Path))))); + Ext := WideUpperCase(Trim(Copy(ExtractFileName(Path), LastDelimiter('.', ExtractFileName(Path)) + 1, Length(ExtractFileName(Path)) - LastDelimiter('.', ExtractFileName(Path))))); // Search in the association list if AssocList.Count > 0 then for i := 0 to AssocList.Count - 1 do with TFileAssoc(AssocList[i]) do if (ActionList.Count > 0) and (Length(Trim(Extensions)) > 0) then begin b := False; - if Pos(';', Extensions) = 0 then b := ANSIUpperCase(Trim(Extensions)) = Ext else begin + if Pos(';', Extensions) = 0 then b := WideUpperCase(Trim(Extensions)) = Ext else begin Last := 0; for j := 1 to Length(Extensions) do if Extensions[j] = ';' then begin - if ANSIUpperCase(Trim(Copy(Extensions, Last + 1, j - Last - 1))) = Ext then begin + if WideUpperCase(Trim(Copy(Extensions, Last + 1, j - Last - 1))) = Ext then begin b := True; Break; end; Last := j; end; - if not b then b := ANSIUpperCase(Trim(Copy(Extensions, LastDelimiter(';', Extensions) + 1, Length(Extensions) - LastDelimiter(';', Extensions)))) = Ext; + if not b then b := WideUpperCase(Trim(Copy(Extensions, LastDelimiter(';', Extensions) + 1, Length(Extensions) - LastDelimiter(';', Extensions)))) = Ext; end; if b then begin FileTypeDesc := FileTypeName; @@ -3311,7 +3329,7 @@ begin else ac := CustomAction; if ac > ActionList.Count - 1 then ac := 0; if ActionList.Count >= ac then begin - Command := Trim(TAssocAction(ActionList[ac]).ActionCommand); + Command := UTF8ToStr(Trim(TAssocAction(ActionList[ac]).ActionCommand)); AutodetectGUI := TAssocAction(ActionList[ac]).AutodetectGUI; RunInTerminal := TAssocAction(ActionList[ac]).RunInTerminal; end; @@ -3341,7 +3359,7 @@ begin HandleRunFromArchive(Path, Engine, Command, FileTypeDesc, False); b := True; end else - if Application.MessageBox(Format(LANGThereIsNoApplicationAssociatedWithS, [ANSIToUTF8(ExtractFileName(Path))]), [mbYes, mbNo], mbQuestion, mbNone, mbNo) = mbYes + if Application.MessageBox(Format(LANGThereIsNoApplicationAssociatedWithS, [StrToUTF8(ExtractFileName(Path))]), [mbYes, mbNo], mbQuestion, mbNone, mbNo) = mbYes then miFileTypesClick(Self); Exit; end; @@ -3360,7 +3378,7 @@ begin Libc.__chdir(PChar('/')); end else b := True; // Mask cancelled extraction from VFS end; - if not b then Application.MessageBox(Format(LANGCannotExecuteSPleaseCheckTheConfiguration, [ANSIToUTF8(s)]), [mbOK], mbError, mbNone, mbOK); + if not b then Application.MessageBox(Format(LANGCannotExecuteSPleaseCheckTheConfiguration, [s]), [mbOK], mbError, mbNone, mbOK); finally Application.ProcessMessages; InternalUnLock; @@ -3385,7 +3403,7 @@ begin if LeftLastFocused then AListView := LeftListView else AListView := RightListView; if Assigned(AListView.Selected) and Assigned(AListView.Selected.Data) and (not PDataItem(AListView.Selected.Data)^.UpDir) then begin - s2 := QuoteStr(String(PDataItem(AListView.Selected.Data)^.AName)) + ' '; + s2 := QuoteStr(String(PDataItem(AListView.Selected.Data)^.FDisplayName)) + ' '; if Length(CommandLineCombo.Entry.Text) = 0 then begin CommandLineCombo.Entry.Text := Format('./%s', [s2]); CommandLineCombo.Entry.CursorPosition := Length(s2); @@ -3402,16 +3420,16 @@ begin Orig := Trim(CommandLineCombo.Entry.Text); if Length(Orig) > 0 then begin - if ANSIUpperCase(Orig) = 'CD' then begin + if WideUpperCase(Orig) = 'CD' then begin if LeftLastFocused then PathButtonClick(LeftHomeButton) else PathButtonClick(RightHomeButton); end else - if (Length(Orig) > 3) and (ANSIUpperCase(Copy(Orig, 1, 3)) = 'CD ') then begin - ChangingDir(LeftLastFocused, ProcessPattern(Engine, Copy(Orig, 4, Length(Orig) - 3), Engine.Path, '', True)); + if (Length(Orig) > 3) and (WideUpperCase(Copy(Orig, 1, 3)) = 'CD ') then begin + ChangingDir(LeftLastFocused, ProcessPattern(Engine, UTF8ToStr(Copy(Orig, 4, Length(Orig) - 3)), Engine.Path, '', True)); end else begin while not (Engine is TLocalTreeEngine) do Engine := Engine.ParentEngine; ChDir(Engine.Path); - if not ExecuteProgram(Orig, Engine.Path, ConfCmdLineTerminalBehaviour = 0 , ConfCmdLineTerminalBehaviour = 1, Error) then + if not ExecuteProgram(UTF8ToStr(Orig), Engine.Path, ConfCmdLineTerminalBehaviour = 0 , ConfCmdLineTerminalBehaviour = 1, Error) then Application.MessageBox(LANGErrorExecutingCommand, [mbOK], mbError, mbNone, mbOK); ChDir('/'); end; @@ -3515,7 +3533,7 @@ begin if ActualPosition and CommandLineCombo.Entry.Focused then begin OldPos := CommandLineCombo.Entry.CursorPosition; s2 := CommandLineCombo.Entry.Text; - Insert(s, s2, Length(ANSILeftStr(s2, OldPos)) + 1); + Insert(s, s2, Length(LeftStr(s2, OldPos)) + 1); CommandLineCombo.Entry.Text := s2; CommandLineCombo.Entry.CursorPosition := OldPos + 1; end else begin @@ -3683,11 +3701,11 @@ begin end; AFile := ''; - if SelCount = 0 then AFile := PDataItem(AListView.Selected.Data)^.AName else + if SelCount = 0 then AFile := PDataItem(AListView.Selected.Data)^.FName else for i := 0 to DataList.Count - 1 do with PDataItem(DataList[i])^ do if Selected and (not UpDir) then begin - AFile := AName; + AFile := FName; Break; end; @@ -3783,11 +3801,11 @@ begin end; AFile := ''; - if SelCount = 0 then AFile := PDataItem(AListView.Selected.Data)^.AName else + if SelCount = 0 then AFile := PDataItem(AListView.Selected.Data)^.FName else for i := 0 to DataList.Count - 1 do with PDataItem(DataList[i])^ do if Selected and (not UpDir) then begin - AFile := AName; + AFile := FName; Break; end; @@ -3865,9 +3883,9 @@ begin if (not Assigned(AListView.Selected)) or (not Assigned(AListView.Selected.Data)) or PDataItem(AListView.Selected.Data)^.UpDir then s1 := ExcludeTrailingPathDelimiter(Engine.Path) - else s1 := IncludeTrailingPathDelimiter(Engine.Path) + PDataItem(AListView.Selected.Data)^.AName; + else s1 := IncludeTrailingPathDelimiter(Engine.Path) + PDataItem(AListView.Selected.Data)^.FName; if Engine.Path <> EngineOpposite.Path - then s2 := IncludeTrailingPathDelimiter(EngineOpposite.Path) + PDataItem(AListView.Selected.Data)^.AName + then s2 := IncludeTrailingPathDelimiter(EngineOpposite.Path) + PDataItem(AListView.Selected.Data)^.FName else s2 := ''; // Handle password @@ -3913,7 +3931,7 @@ begin if (Engine is TVFSEngine) and TVFSEngine(Engine).GetPasswordRequired and (Length(TVFSEngine(Engine).Password) < 1) then if not HandleSetPassword(Engine) then Exit; - if EditSymlink(IncludeTrailingPathDelimiter(Engine.Path) + PDataItem(AListView.Selected.Data)^.AName, Engine) then begin + if EditSymlink(IncludeTrailingPathDelimiter(Engine.Path) + PDataItem(AListView.Selected.Data)^.FName, Engine) then begin DoRefresh(LeftPanel, True, True); DoRefresh(not LeftPanel, True, True); end; @@ -3953,7 +3971,7 @@ begin end; FileName := IncludeTrailingPathDelimiter(Engine.Path); if Assigned(AListView.Selected) and Assigned(AListView.Selected.Data) and (not PDataItem(AListView.Selected.Data)^.UpDir) - then FileName := FileName + PDataItem(AListView.Selected.Data)^.AName; + then FileName := FileName + PDataItem(AListView.Selected.Data)^.FName; ShortFName := ExtractFileName(ExcludeTrailingPathDelimiter(FileName)); DataItem := Engine.GetFileInfoSL(FileName); if not Assigned(DataItem) then begin @@ -3964,7 +3982,7 @@ begin if not DataItem^.IsDir then begin Item := TGTKMenuItem.CreateTyped(Self, itImageText); - Item.Caption := Format(LANGPopupRunS, [ANSIToUTF8(QuoteMarkupStr(ShortFName))]); + Item.Caption := Format(LANGPopupRunS, [QuoteMarkupStr(StrToUTF8(ShortFName), True)]); Item.StockIcon := 'gtk-execute'; Item.Data := Pointer(1); Item.OnClick := FilePopupMenuItemClick; @@ -3973,7 +3991,7 @@ begin end else begin Item := TGTKMenuItem.CreateTyped(Self, itImageText); if UpDir then Item.Caption := LANGPopupGoUp - else Item.Caption := Format(LANGPopupOpenS, [ANSIToUTF8(QuoteMarkupStr(ShortFName))]); + else Item.Caption := Format(LANGPopupOpenS, [QuoteMarkupStr(StrToUTF8(ShortFName), True)]); Item.StockIcon := 'gtk-open'; Item.Data := Pointer(1); Item.OnClick := FilePopupMenuItemClick; @@ -4002,23 +4020,23 @@ begin // Find and add actions for this file type Found := False; if Pos('.', ShortFName) > 0 then begin - Ext := ANSIUpperCase(Trim(Copy(ShortFName, LastDelimiter('.', ShortFName) + 1, Length(ShortFName) - LastDelimiter('.', ShortFName)))); + Ext := WideUpperCase(Trim(Copy(ShortFName, LastDelimiter('.', ShortFName) + 1, Length(ShortFName) - LastDelimiter('.', ShortFName)))); if AssocList.Count > 0 then for i := 0 to AssocList.Count - 1 do with TFileAssoc(AssocList[i]) do if (ActionList.Count > 0) and (Length(Trim(Extensions)) > 0) then begin b := False; - if Pos(';', Extensions) = 0 then b := ANSIUpperCase(Trim(Extensions)) = Ext else begin + if Pos(';', Extensions) = 0 then b := Trim(Extensions) = Ext else begin Last := 0; for j := 1 to Length(Extensions) do if Extensions[j] = ';' then begin - if ANSIUpperCase(Trim(Copy(Extensions, Last + 1, j - Last - 1))) = Ext then begin + if WideUpperCase(Trim(Copy(Extensions, Last + 1, j - Last - 1))) = Ext then begin b := True; Break; end; Last := j; end; - if not b then b := ANSIUpperCase(Trim(Copy(Extensions, LastDelimiter(';', Extensions) + 1, Length(Extensions) - LastDelimiter(';', Extensions)))) = Ext; + if not b then b := WideUpperCase(Trim(Copy(Extensions, LastDelimiter(';', Extensions) + 1, Length(Extensions) - LastDelimiter(';', Extensions)))) = Ext; end; if b and (ActionList.Count > 0) then begin Found := True; @@ -4126,7 +4144,7 @@ begin end; FileName := IncludeTrailingPathDelimiter(Engine.Path); if Assigned(AListView.Selected) and Assigned(AListView.Selected.Data) and (not PDataItem(AListView.Selected.Data)^.UpDir) - then FileName := FileName + PDataItem(AListView.Selected.Data)^.AName; + then FileName := FileName + PDataItem(AListView.Selected.Data)^.FName; ShortFName := ExtractFileName(ExcludeTrailingPathDelimiter(FileName)); DataItem := Engine.GetFileInfoSL(FileName); if not Assigned(DataItem) then begin @@ -4148,11 +4166,11 @@ begin end else b := True; // Mask cancelled extraction from VFS if not b then Application.MessageBox(LANGErrorExecutingCommand, [mbOK], mbError, mbNone, mbOK); end; - 2: if Application.MessageBox(Format(LANGThereIsNoApplicationAssociatedWithS, [ANSIToUTF8(ShortFName)]), [mbYes, mbNo], mbQuestion, mbNone, mbNo) = mbYes + 2: if Application.MessageBox(Format(LANGThereIsNoApplicationAssociatedWithS, [ShortFName]), [mbYes, mbNo], mbQuestion, mbNone, mbNo) = mbYes then miFileTypesClick(Self); else begin b := True; - s := TAssocAction((Sender as TGTKMenuItem).Data).ActionCommand; + s := UTF8ToStr(Trim(TAssocAction((Sender as TGTKMenuItem).Data).ActionCommand)); if Engine is TVFSEngine then b := HandleRunFromArchive(FileName, Engine, s, '', False); // not a local engine, extract to local first if Pos('%s', s) > 0 then s := Format(s, ['''' + QuoteStr(FileName) + '''']) else s := Format('%s %s', [s, QuoteStr(FileName)]); @@ -4162,7 +4180,7 @@ begin TAssocAction((Sender as TGTKMenuItem).Data).RunInTerminal, Error); Libc.__chdir(PChar('/')); end else b := True; // Mask cancelled extraction from VFS - if not b then Application.MessageBox(Format(LANGCannotExecuteSPleaseCheckTheConfiguration, [ANSIToUTF8(FileName)]), [mbOK], mbError, mbNone, mbOK); + if not b then Application.MessageBox(Format(LANGCannotExecuteSPleaseCheckTheConfiguration, [FileName]), [mbOK], mbError, mbNone, mbOK); end; end; finally @@ -4323,8 +4341,8 @@ const ShortcutKeys = '1234567890'; var i: integer; Item: TGTKMenuItem; begin - if mnuBookmarks.Count > 4 then - for i := mnuBookmarks.Count - 1 downto 4 do begin + if mnuBookmarks.Count > 3 then + for i := mnuBookmarks.Count - 1 downto 3 do begin mnuBookmarks.Items[i].Free; mnuBookmarks.Delete(i); end; @@ -4335,8 +4353,9 @@ begin if Bookmarks.Count > 0 then begin miBookmarksSeparator.Visible := True; for i := 0 to Bookmarks.Count - 1 do begin + if Length(Trim(Bookmarks[i])) = 0 then Continue; Item := TGTKMenuItem.CreateTyped(Self, itLabel); - Item.Caption := Format('_%s %s', [Chr(Ord('a') + i), ANSIToUTF8(QuoteMarkupStr(Bookmarks[i]))]); + Item.Caption := Format('_%s %s', [Chr(Ord('a') + i), StrToUTF8(QuoteMarkupStr(Bookmarks[i]))]); Item.Data := Pointer(i); Item.OnClick := miBookmarkClick; Item.OnMouseUp := BookmarkItemMouseUp; @@ -4359,7 +4378,7 @@ begin else s := RightPanelEngine.Path; s := ExcludeTrailingPathDelimiter(s); if Bookmarks.IndexOf(s) > -1 then begin - Application.MessageBox(LANGTheCurrentDirectoryAlreadyExistsInTheBookmarksList, [mbOK], mbError); + Application.MessageBox(LANGTheCurrentDirectoryAlreadyExistsInTheBookmarksList, [mbOK], mbWarning); Exit; end; Bookmarks.Add(s); @@ -4604,7 +4623,7 @@ begin s := ExcludeTrailingPathDelimiter(SrcEngine.Path); if (OrigSrcEngine = SrcEngine) and Assigned(AListView.Selected) and Assigned(AListView.Selected.Data) and (not PDataItem(AListView.Selected.Data)^.UpDir) and PDataItem(AListView.Selected.Data)^.IsDir - then s := IncludeTrailingPathDelimiter(IncludeTrailingPathDelimiter(s) + PDataItem(AListView.Selected.Data)^.AName); + then s := IncludeTrailingPathDelimiter(IncludeTrailingPathDelimiter(s) + PDataItem(AListView.Selected.Data)^.FName); if IncludeTrailingPathDelimiter(TargetEngine.Path) <> s then begin if LeftPanel then RightPanelEngine := TargetEngine else LeftPanelEngine := TargetEngine; @@ -4663,7 +4682,7 @@ procedure TFMain.FillMounterBar; {$ELSE} Button.Tag := Longint(MounterList[i]); {$ENDIF} - Button.Tooltip := Format(LANGMountPointDevice, [ANSIToUTF8(MountPath), ANSIToUTF8(Device)]); + Button.Tooltip := Format(LANGMountPointDevice, [StrToUTF8(MountPath), StrToUTF8(Device)]); Button.BorderStyle := bsNone; Button.PopupMenu := MounterButtonPopupMenu; Button.OnMouseDown := MounterButtonMouseDown; @@ -4988,7 +5007,7 @@ begin end else for i := 0 to PluginList.Count - 1 do begin MenuItem1 := TGTKMenuItem.CreateTyped(Self, itImageText); - MenuItem1.Caption := ANSIToUTF8(TVFSPlugin(PluginList[i]).VFSName); + MenuItem1.Caption := TVFSPlugin(PluginList[i]).VFSName; MenuItem2 := TGTKMenuItem.CreateTyped(Self, itImageText); MenuItem2.Caption := LANGPluginAbout; MenuItem2.Tag := i; @@ -5007,7 +5026,7 @@ begin FTestPlugin := TFTestPlugin.Create(Self); if (FTestPlugin.Run = mbOK) and (PluginList.Count > 0) then begin Engine := TVFSEngine.Create(PluginList[FTestPlugin.PluginOptionMenu.ItemIndex]); - if not Engine.VFSOpenURI(UTF8ToANSI(FTestPlugin.CommandEntry.Text)) then begin + if not Engine.VFSOpenURI(FTestPlugin.CommandEntry.Text) then begin Application.MessageBox(LANGCouldntOpenURI, [mbOK], mbError, mbOK, mbOK); Exit; end; @@ -5108,22 +5127,22 @@ begin if i = 0 then APathSave := APath; VBox := TGTKVBox.Create(Self); AVBoxList.Insert(InsertPos, VBox); - PathsHighlight.Insert(InsertPos, PDataItem(AListView.Selected.Data)^.AName); + PathsHighlight.Insert(InsertPos, PDataItem(AListView.Selected.Data)^.FName); TabSortIDs.Insert(InsertPos, Pointer(AListView.SortColumnID)); TabSortTypes.Insert(InsertPos, Pointer(Integer(AListView.SortOrder))); TabEngines.Insert(InsertPos, AEngine); end; if not DockedToNotebook then begin - ANotebook.InsertPage(0, AVBoxList[0], APathSave); - SetTabLabel(ANotebook, 0, APathSave, ATabList[0]); + ANotebook.InsertPage(0, AVBoxList[0], StrToUTF8(APathSave)); + SetTabLabel(ANotebook, 0, StrToUTF8(APathSave), StrToUTF8(ATabList[0])); end; InsertPos := NewTabPosition; if InsertPos > ATabList.Count then InsertPos := ATabList.Count; if not ANotebook.Visible then ANotebook.Visible := True; - i := ANotebook.InsertPage(InsertPos, VBox, APath); - SetTabLabel(ANotebook, i, APath, ATabList[InsertPos]); + i := ANotebook.InsertPage(InsertPos, VBox, StrToUTF8(APath)); + SetTabLabel(ANotebook, i, StrToUTF8(APath), StrToUTF8(ATabList[InsertPos])); ANotebook.PageIndex := i; end; @@ -5408,8 +5427,8 @@ begin ATabSortTypes.Add(TabSortTypes[i]); if LeftPanel then TabEngines.Add(LeftPanelEngine) else TabEngines.Add(RightPanelEngine); - ANotebook.AppendPage(VBox, APath); - SetTabLabel(ANotebook, ANotebook.ChildrenCount - 1, APath, TabList[i]); + ANotebook.AppendPage(VBox, StrToUTF8(APath)); + SetTabLabel(ANotebook, ANotebook.ChildrenCount - 1, StrToUTF8(APath), StrToUTF8(TabList[i])); end; if not ANotebook.Visible then ANotebook.Visible := True; @@ -5418,9 +5437,15 @@ begin end; procedure TFMain.SetTabLabel(Notebook: TEphyNotebook; PageIndex: integer; ALabel, Tooltip: string); +var g: PChar; begin - if (ConfTabMaxLength > 0) and (Length(ALabel) > ConfTabMaxLength) then - ALabel := Copy(ALabel, 1, ConfTabMaxLength) + '...'; + if (ConfTabMaxLength > 0) and (g_utf8_strlen(PChar(ALabel), -1) > ConfTabMaxLength) then begin + g := malloc(Length(ALabel) + 4); + memset(g, 0, Length(ALabel) + 4); + g_utf8_strncpy(g, PChar(ALabel), ConfTabMaxLength); + ALabel := g + '...'; + Libc.free(g); + end; Notebook.SetTabCaption(PageIndex, ALabel); Notebook.SetTabTooltip(PageIndex, Tooltip); end; @@ -5602,7 +5627,7 @@ begin if Length(Plugin.Extensions) > 0 then for j := 0 to Length(Plugin.Extensions) - 1 do begin // DebugMsg(['Extension = "', Plugin.Extensions[j], '", Ext = "', Ext, '"']); - if AnsiCompareText(Plugin.Extensions[j], Ext) = 0 then begin + if WideCompareText(Plugin.Extensions[j], Ext) = 0 then begin Result := True; Break; end; @@ -5623,7 +5648,8 @@ begin if not Assigned(Engine.ParentEngine) or (not (Engine is TVFSEngine)) then Exit; if LeftPanel then LeftPanelEngine := Engine.ParentEngine else RightPanelEngine := Engine.ParentEngine; - if not SurpressRefresh then ChangingDir(LeftPanel, Engine.SavePath, Engine.ParentEngine.LastHighlightItem, '', False, True); + if not SurpressRefresh then ChangingDir(LeftPanel, Engine.SavePath, StrToUTF8(Engine.ParentEngine.LastHighlightItem), + Engine.ParentEngine.LastHighlightItem, False, True); if not TVFSEngine(Engine).VFSClose then DebugMsg(['Error closing the engine...']); Engine.Free; @@ -5667,13 +5693,14 @@ begin FSearch := TFSearch.Create(Self); FSearch.ParentForm := FMain; FSearch.Engine := Engine; - FSearch.SearchInEntry.Text := ANSIToUTF8(ExcludeTrailingPathDelimiter(Engine.Path)); + FSearch.SearchInEntry.Text := StrToUTF8(ExcludeTrailingPathDelimiter(Engine.Path)); if Length(FSearch.SearchInEntry.Text) < 1 then FSearch.SearchInEntry.Text := '/'; case FSearch.Run of mbOK: ; mbApply: begin + DebugMsg(['TFMain.miSearchClick: FSearch.GoToFileArchive = "', FSearch.GoToFileArchive, '", FSearch.GoToFile = "', FSearch.GoToFile, '"']); if Length(FSearch.GoToFileArchive) > 0 then begin - Ext := ANSIUpperCase(Trim(Copy(FSearch.GoToFileArchive, LastDelimiter('.', FSearch.GoToFileArchive) + 1, Length(FSearch.GoToFileArchive) - LastDelimiter('.', FSearch.GoToFileArchive)))); + Ext := WideUpperCase(Trim(Copy(FSearch.GoToFileArchive, LastDelimiter('.', FSearch.GoToFileArchive) + 1, Length(FSearch.GoToFileArchive) - LastDelimiter('.', FSearch.GoToFileArchive)))); HandleVFSArchive(Ext, FSearch.GoToFileArchive, ExtractFileName(FSearch.GoToFileArchive), ExtractFilePath(FSearch.GoToFile)); if LeftLastFocused then begin @@ -5690,13 +5717,13 @@ begin Engine.SavePath := ExtractFilePath(FSearch.GoToFileArchive); // (Engine as TVFSEngine).ParentEngine.LastHighlightItem := ExtractFileName(FSearch.GoToFileArchive); for i := 0 to DataList.Count - 1 do - if ANSICompareText(string(PDataItem(DataList[i])^.AName), ExtractFileName(FSearch.GoToFile)) = 0 then begin + if WideCompareText(string(PDataItem(DataList[i])^.FName), ExtractFileName(FSearch.GoToFile)) = 0 then begin AListView.Items[i].Selected := True; AListView.Items[i].SetCursor(0, False, not Application.GTKVersion_2_2_0_Up, 0.5, 0); Break; end; end; - end else ChangingDir(LeftLastFocused, ExtractFilePath(FSearch.GoToFile), ExtractFileName(FSearch.GoToFile)); + end else ChangingDir(LeftLastFocused, ExtractFilePath(FSearch.GoToFile), StrToUTF8(ExtractFileName(FSearch.GoToFile))); end; end; finally @@ -5743,7 +5770,7 @@ begin for i := 0 to PluginList.Count - 1 do begin if Length(TVFSPlugin(PluginList[i]).Services) > 0 then for j := 0 to Length(TVFSPlugin(PluginList[i]).Services) - 1 do - if AnsiCompareText(TVFSPlugin(PluginList[i]).Services[j], ConnInfo.ServiceType) = 0 then begin + if WideCompareText(TVFSPlugin(PluginList[i]).Services[j], ConnInfo.ServiceType) = 0 then begin VFSPlugin := PluginList[i]; Break; end; @@ -5764,7 +5791,7 @@ begin Engine := TVFSEngine.Create(VFSPlugin); Engine.ParentEngine := SourceEngine; Engine.SavePath := SourceEngine.Path; - if not Engine.VFSOpenURI(ConnInfo.URI) then begin + if not Engine.VFSOpenURI(UTF8ToStr(ConnInfo.URI)) then begin Application.MessageBox(LANGCouldntOpenURI, [mbOK], mbError, mbOK, mbOK); Exit; end; @@ -5853,11 +5880,11 @@ begin end; AFile := ''; - if SelCount = 0 then AFile := PDataItem(AListView.Selected.Data)^.AName else + if SelCount = 0 then AFile := PDataItem(AListView.Selected.Data)^.FName else for i := 0 to DataList.Count - 1 do with PDataItem(DataList[i])^ do if Selected and (not UpDir) then begin - AFile := AName; + AFile := FName; Break; end; @@ -5939,7 +5966,7 @@ begin then Exit; // Silently do nothing if SelCount = 0 then begin - s := PDataItem(AListView.Selected.Data)^.AName; + s := PDataItem(AListView.Selected.Data)^.FName; if FullPaths then s := IncludeTrailingPathDelimiter(Engine.GetPath) + s; end else begin s := ''; @@ -5948,13 +5975,13 @@ begin x := AListView.ConvertFromSorted(i); if (x >= 0) and (x < DataList.Count) and PDataItem(DataList[x])^.Selected then begin if FullPaths then s := s + IncludeTrailingPathDelimiter(Engine.GetPath); - s := s + PDataItem(DataList[x])^.AName + #10; + s := s + PDataItem(DataList[x])^.FName + #10; end; end; end; clip := gtk_clipboard_get(gdk_atom_intern('CLIPBOARD', False)); - gtk_clipboard_set_text(clip, StringToPgchar(s), Length(s)); + gtk_clipboard_set_text(clip, PChar(StrToUTF8(s)), Length(StrToUTF8(s))); end; @@ -5976,14 +6003,14 @@ begin if not BypassDialog then begin Stat := Engine.GetFileInfoSL(APath); FRunFromVFS := TFRunFromVFS.Create(Self); - FRunFromVFS.FileNameLabel2.Caption := Format('%s<span weight="ultrabold"> </span>', [APath]); + FRunFromVFS.FileNameLabel2.Caption := Format('%s<span weight="ultrabold"> </span>', [StrToUTF8(APath)]); if FileTypeDesc = '' then FileTypeDesc := LANGHandleRunFromArchive_FileTypeDesc_Unknown; FRunFromVFS.FileTypeLabel2.Caption := Format('%s<span weight="ultrabold"> </span>', [FileTypeDesc]); if Assigned(Stat) then begin if (ConfSizeFormat < 5) or (Stat^.Size < 1024) then s := Format(' %s', [LANGHandleRunFromArchive_Bytes]); - FRunFromVFS.SizeLabel2.Caption := Format('%s%s<span weight="ultrabold"> </span>', [ANSIToUTF8(FormatSize(Stat^.Size, 0)), s]); + FRunFromVFS.SizeLabel2.Caption := Format('%s%s<span weight="ultrabold"> </span>', [FormatSize(Stat^.Size, 0), s]); if (ConfSizeFormat < 5) or (Stat^.Size < 1024) then s := Format(' %s', [LANGHandleRunFromArchive_Bytes]); - FRunFromVFS.PackedSizeLabel2.Caption := Format('%s%s<span weight="ultrabold"> </span>', [ANSIToUTF8(FormatSize(Stat^.Size, 0)), s]); + FRunFromVFS.PackedSizeLabel2.Caption := Format('%s%s<span weight="ultrabold"> </span>', [FormatSize(Stat^.Size, 0), s]); FRunFromVFS.DateLabel2.Caption := Format('%s<span weight="ultrabold"> </span>', [FormatDateTime('ddddd tt', Stat^.ModifyTime)]); if (Command = '') and (not Stat^.IsExecutable) then begin FRunFromVFS.OpensWithLabel2.Caption := Format('%s<span weight="ultrabold"> </span>', [LANGHandleRunFromArchive_NotAssociated]); diff --git a/UMounterPrefs.pas b/UMounterPrefs.pas index 6a08454..6a2f3cf 100644 --- a/UMounterPrefs.pas +++ b/UMounterPrefs.pas @@ -321,10 +321,10 @@ begin end; Item := ListView.Selected.AsPointer(3); DisplayTextEntry.Text := Item.DisplayText; - MountPointEntry.Text := AnsiToUTF8(Item.MountPath); - MountDeviceEntry.Text := AnsiToUTF8(Item.Device); - MountCommandEntry.Text := AnsiToUTF8(Item.MountCommand); - UmountCommandEntry.Text := AnsiToUTF8(Item.UmountCommand); + MountPointEntry.Text := StrToUTF8(Item.MountPath); + MountDeviceEntry.Text := StrToUTF8(Item.Device); + MountCommandEntry.Text := StrToUTF8(Item.MountCommand); + UmountCommandEntry.Text := StrToUTF8(Item.UmountCommand); DeviceTypeOptionMenu.ItemIndex := Item.DeviceType; if FUseGnomeIconEntry then IconEntry.Filename := Item.IconPath; end; @@ -401,7 +401,7 @@ end; procedure TFMounterPrefs.MountPointEntryChanged(Sender: TObject); begin if Assigned(ListView.Selected) and Assigned(ListView.Selected.AsPointer(3)) and (not UseFSTabDefaultsCheckBox.Checked) then begin - TMounterItem(ListView.Selected.AsPointer(3)).MountPath := UTF8ToANSI(MountPointEntry.Text); + TMounterItem(ListView.Selected.AsPointer(3)).MountPath := UTF8ToStr(MountPointEntry.Text); ListView.Selected.SetValue(1, MountPointEntry.Text); end; end; @@ -409,7 +409,7 @@ end; procedure TFMounterPrefs.MountDeviceEntryChanged(Sender: TObject); begin if Assigned(ListView.Selected) and Assigned(ListView.Selected.AsPointer(3)) and (not UseFSTabDefaultsCheckBox.Checked) then begin - TMounterItem(ListView.Selected.AsPointer(3)).Device := UTF8ToANSI(MountDeviceEntry.Text); + TMounterItem(ListView.Selected.AsPointer(3)).Device := UTF8ToStr(MountDeviceEntry.Text); ListView.Selected.SetValue(2, MountDeviceEntry.Text); end; end; @@ -417,14 +417,14 @@ end; procedure TFMounterPrefs.MountCommandEntryChanged(Sender: TObject); begin if Assigned(ListView.Selected) and Assigned(ListView.Selected.AsPointer(3)) and (not UseFSTabDefaultsCheckBox.Checked) then begin - TMounterItem(ListView.Selected.AsPointer(3)).MountCommand := UTF8ToANSI(MountCommandEntry.Text); + TMounterItem(ListView.Selected.AsPointer(3)).MountCommand := UTF8ToStr(MountCommandEntry.Text); end; end; procedure TFMounterPrefs.UmountCommandEntryChanged(Sender: TObject); begin if Assigned(ListView.Selected) and Assigned(ListView.Selected.AsPointer(3)) and (not UseFSTabDefaultsCheckBox.Checked) then begin - TMounterItem(ListView.Selected.AsPointer(3)).UmountCommand := UTF8ToANSI(UmountCommandEntry.Text); + TMounterItem(ListView.Selected.AsPointer(3)).UmountCommand := UTF8ToStr(UmountCommandEntry.Text); end; end; @@ -516,8 +516,8 @@ begin with TMounterItem(InternalMounterList[i]) do begin ListItem := ListView.Items.Add; ListItem.SetValue(0, DisplayText); - ListItem.SetValue(1, ANSIToUTF8(MountPath)); - ListItem.SetValue(2, ANSIToUTF8(Device)); + ListItem.SetValue(1, StrToUTF8(MountPath)); + ListItem.SetValue(2, StrToUTF8(Device)); ListItem.SetValue(3, InternalMounterList[i]); RefreshIcon(i); end; diff --git a/UOverwrite.pas b/UOverwrite.pas index 04cbd1c..b35a197 100644 --- a/UOverwrite.pas +++ b/UOverwrite.pas @@ -1,21 +1,21 @@ (* Tux Commander - UOverwrite - Overwrite dialog form and related funcions - Copyright (C) 2004 Tomas Bzatek <tbzatek@users.sourceforge.net>
- Check for updates on tuxcmd.sourceforge.net
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Copyright (C) 2004 Tomas Bzatek <tbzatek@users.sourceforge.net> + Check for updates on tuxcmd.sourceforge.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *) unit UOverwrite; @@ -161,7 +161,7 @@ end; procedure TFOverwrite.DoAppend; begin - if Application.MessageBox(Format(LANGAppendQuestion, [ANSIToUTF8(SourceFile), ANSIToUTF8(DestFile)]), [mbYes, mbNo], mbQuestion, mbNone, mbNo) = mbYes + if Application.MessageBox(Format(LANGAppendQuestion, [SourceFile, DestFile]), [mbYes, mbNo], mbQuestion, mbNone, mbNo) = mbYes then ModalResult := TMessageButton(8); end; diff --git a/UPreferences.pas b/UPreferences.pas index ca4733f..c1c75b0 100644 --- a/UPreferences.pas +++ b/UPreferences.pas @@ -197,7 +197,7 @@ begin SizeFormatOptionMenu := TGTKOptionMenu.Create(Self); SizeFormatLabel.FocusControl := SizeFormatOptionMenu; miSizeFormat1 := TGTKMenuItem.CreateTyped(Self, itLabel); - miSizeFormat1.Caption := Format('%s %s', [LANGPreferencesmiSizeFormat1, ANSIToUTF8(FormatFloat('(###,###,###)', 123456))]); + miSizeFormat1.Caption := Format('%s %s', [LANGPreferencesmiSizeFormat1, FormatFloat('(###,###,###)', 123456)]); miSizeFormat2 := TGTKMenuItem.CreateTyped(Self, itLabel); miSizeFormat2.Caption := '123456'; miSizeFormat3 := TGTKMenuItem.CreateTyped(Self, itLabel); @@ -704,9 +704,9 @@ begin ClearROAttr.Checked := ConfClearReadOnlyAttr; DisableMouseRename.Checked := ConfDisableMouseRename; ShowFiletypeIcons.Checked := ConfUseFileTypeIcons; - ViewerCombo.Entry.Text := ANSIToUTF8(ConfViewer); - EditorCombo.Entry.Text := ANSIToUTF8(ConfEditor); - TerminalCombo.Entry.Text := ANSIToUTF8(ConfTerminalCommand); + ViewerCombo.Entry.Text := StrToUTF8(ConfViewer); + EditorCombo.Entry.Text := StrToUTF8(ConfEditor); + TerminalCombo.Entry.Text := StrToUTF8(ConfTerminalCommand); DefaultFontCheckBox.Checked := ConfUseSystemFont; if not StringToGDKColor(ConfNormalItemFGColor, AColor) then StringToGDKColor(ConfDefaultNormalItemFGColor, AColor); @@ -774,9 +774,9 @@ begin ConfClearReadOnlyAttr := ClearROAttr.Checked; ConfDisableMouseRename := DisableMouseRename.Checked; ConfUseFileTypeIcons := ShowFiletypeIcons.Checked; - ConfViewer := UTF8ToANSI(ViewerCombo.Entry.Text); - ConfEditor := UTF8ToANSI(EditorCombo.Entry.Text); - ConfTerminalCommand := UTF8ToANSI(TerminalCombo.Entry.Text); + ConfViewer := UTF8ToStr(ViewerCombo.Entry.Text); + ConfEditor := UTF8ToStr(EditorCombo.Entry.Text); + ConfTerminalCommand := UTF8ToStr(TerminalCombo.Entry.Text); ConfUseSystemFont := DefaultFontCheckBox.Checked; if not ConfUseSystemFont then ConfPanelFont := ListFontPreview.Caption; diff --git a/USearch.pas b/USearch.pas index 4cd49f1..a451fb6 100644 --- a/USearch.pas +++ b/USearch.pas @@ -591,8 +591,8 @@ begin AEngine := TLocalTreeEngine.Create; b := True; end; - if b then FMain.EditViewFileInternal(Self, string(PDataItem(FileList.Selected.AsPointer(0))^.AName), AEngine, True, False) - else Application.MessageBox(Format(LANGCannotLoadFile, [ANSIToUTF8(string(PDataItem(FileList.Selected.AsPointer(0))^.AName))]), [mbOK], mbError, mbNone, mbOK); + if b then FMain.EditViewFileInternal(Self, string(PDataItem(FileList.Selected.AsPointer(0))^.FDisplayName), AEngine, True, False) + else Application.MessageBox(Format(LANGCannotLoadFile, [string(PDataItem(FileList.Selected.AsPointer(0))^.FDisplayName)]), [mbOK], mbError, mbNone, mbOK); if AEngine is TVFSEngine then (AEngine as TVFSEngine).VFSClose; AEngine.Free; end; @@ -600,7 +600,7 @@ end; procedure TFSearch.GoToFileButtonClick(Sender: TObject); begin if not (Assigned(FileList.Selected) and Assigned(FileList.Selected.AsPointer(0))) then Exit; - GoToFile := string(PDataItem(FileList.Selected.AsPointer(0))^.AName); + GoToFile := string(PDataItem(FileList.Selected.AsPointer(0))^.FDisplayName); if Assigned(PDataItem(FileList.Selected.AsPointer(0))^.LnkPointTo) then GoToFileArchive := string(PDataItem(FileList.Selected.AsPointer(0))^.LnkPointTo); ModalResult := mbApply; @@ -683,9 +683,9 @@ begin // Set the parameters FSearchThread := TSearchThread.Create(Engine); with FSearchThread do begin - FStartPath := UTF8ToANSI(SearchInEntry.Text); - FFileMask := UTF8ToANSI(FileMaskEntry.Entry.Text); - FStringFind := UTF8ToANSI(FindTextEntry.Text); + FStartPath := UTF8ToStr(SearchInEntry.Text); + FFileMask := UTF8ToStr(FileMaskEntry.Entry.Text); + FStringFind := FindTextEntry.Text; FDontLeaveFS := not StayCurrentFSCheckButton.Checked; FCaseSensitiveMask := CaseSensitiveMatchCheckButton.Checked; FCaseSensitiveStrings := CaseSensitiveCheckButton.Checked; @@ -745,7 +745,7 @@ begin Sleep(ConstInternalProgressTimer); FSearchThread.GUIMutex.Acquire; - StatusLabel.Caption := Format('<span weight="ultrabold">%s</span> %s', [LANGSearch_SearchInProgress, FSearchThread.CurrentDir]); + StatusLabel.Caption := Format('<span weight="ultrabold">%s</span> %s', [LANGSearch_SearchInProgress, StrToUTF8(FSearchThread.CurrentDir)]); FSearchThread.GUIMutex.Release; StatusLabel.UseMarkup := True; @@ -758,8 +758,8 @@ begin ListItem := FileList.Items.Add; ListItem.SetValue(0, FSearchThread.FList[i]); if PDataItem(FSearchThread.FList[i])^.LnkPointTo <> nil - then ListItem.SetValue(1, Format('%s%s%s', [string(PDataItem(FSearchThread.FList[i])^.LnkPointTo), ConstPathDelim, string(PDataItem(FSearchThread.FList[i])^.AName)])) - else ListItem.SetValue(1, string(PDataItem(FSearchThread.FList[i])^.AName)); + then ListItem.SetValue(1, Format('%s%s%s', [StrToUTF8(string(PDataItem(FSearchThread.FList[i])^.LnkPointTo)), ConstPathDelim, StrToUTF8(string(PDataItem(FSearchThread.FList[i])^.FDisplayName))])) + else ListItem.SetValue(1, StrToUTF8(string(PDataItem(FSearchThread.FList[i])^.FDisplayName))); if i mod 30 = 0 then Application.ProcessMessages; // Refresh UI only after some amount of items added end; LastItems := FSearchThread.FList.Count; @@ -883,7 +883,7 @@ begin Data := LocalList[i]; // DebugMsg([' --- found ', Data^.AName]); - FileName := Data^.AName; + FileName := Data^.FName; Matches := True; // Test if the file is on the same FS @@ -924,8 +924,8 @@ begin if Matches then begin GUIMutex.Acquire; FList.Add(LocalList[i]); - Libc.free(Data^.AName); - PDataItem(LocalList[i])^.AName := strdup(PChar(StartDir + FileName)); + Libc.free(Data^.FDisplayName); + PDataItem(LocalList[i])^.FDisplayName := strdup(PChar(StartDir + FileName)); if Assigned(PDataItem(LocalList[i])^.LnkPointTo) then begin Libc.free(PDataItem(LocalList[i])^.LnkPointTo); PDataItem(LocalList[i])^.LnkPointTo := nil; @@ -940,14 +940,14 @@ begin // Handle archives if (not Data^.IsDir) and FSearchArchives and (not (FEngine is TVFSEngine)) then begin b := False; - s := ANSIUpperCase(Trim(Copy(FileName, LastDelimiter('.', FileName) + 1, Length(FileName) - LastDelimiter('.', FileName)))); + s := WideUpperCase(Trim(Copy(FileName, LastDelimiter('.', FileName) + 1, Length(FileName) - LastDelimiter('.', FileName)))); if (Length(s) > 1) and (s[1] = '.') then Delete(s, 1, 1); if PluginList.Count > 0 then for k := 0 to PluginList.Count - 1 do begin Plugin := TVFSPlugin(PluginList[k]); if Length(Plugin.Extensions) > 0 then for j := 0 to Length(Plugin.Extensions) - 1 do - if AnsiCompareText(Plugin.Extensions[j], s) = 0 then begin + if WideCompareText(Plugin.Extensions[j], s) = 0 then begin b := True; Break; end; diff --git a/UTestPlugin.pas b/UTestPlugin.pas index d30301a..7991e32 100644 --- a/UTestPlugin.pas +++ b/UTestPlugin.pas @@ -153,7 +153,7 @@ begin for i := 0 to PluginList.Count - 1 do begin MenuItem := TGTKMenuItem.CreateTyped(Self, itImageText); MenuItem.SetCaptionPlain(Format('%s [%s]', [TVFSPlugin(PluginList[i]).VFSName, - ANSIToUTF8(ExtractFileName(TVFSPlugin(PluginList[i]).FullPath))])); + ExtractFileName(TVFSPlugin(PluginList[i]).FullPath)])); PluginOptionMenu.Items.Add(MenuItem); end; diff --git a/UToolTips.pas b/UToolTips.pas index 7a79075..2ad128f 100644 --- a/UToolTips.pas +++ b/UToolTips.pas @@ -299,7 +299,7 @@ begin end; if IsFNameExtColumn then begin - Text := PChar(ANSIToUTF8(Data^.AName)); + Text := PChar(Data^.FDisplayName); gtk_tree_view_get_cell_area(data_panel, data_row, gtk_tree_view_get_column(data_panel, Col - Ord(ColID = 3)), @rect); if ((Col - Ord(ColID = 3)) = 0) and ConfUseFileTypeIcons then begin Inc(Rect.x, ConfRowHeightReal + 2); diff --git a/UViewer.pas b/UViewer.pas index d7d1c4c..70d3a64 100644 --- a/UViewer.pas +++ b/UViewer.pas @@ -393,19 +393,23 @@ begin Valid := True; for i := 0 to LineBuffer.Count - 1 do begin - Valid := Valid and g_utf8_validate(PChar(LineBuffer[i]), -1, nil); - if not Valid then Break; + Valid := Valid and g_utf8_validate(PChar(LineBuffer[i]), Length(LineBuffer[i]), nil); + if not Valid then begin + DebugMsg(['** TFViewer.LoadFile(', FileName, ', Line ', i + 1, ') is not UTF-8 valid.']); + Break; + end; end; - + if Valid then TextView.Lines.SetText(LineBuffer.Text) - else + else begin for i := 0 to LineBuffer.Count - 1 do TextView.Lines.InsertText(AnsiToUtf8(LineBuffer[i]) + #10); + end; { LineHeight := 16; NumLines := LineBuffer.Count; } - Caption := Format('TuxView [%s]', [ANSIToUTF8(FileName)]); + Caption := Format('TuxView [%s]', [StrToUTF8(FileName)]); // FDrawingArea.SetSizeRequest(-1, NumLines * LineHeight); Result := True; except diff --git a/vfs/UVFSCore.pas b/vfs/UVFSCore.pas index 21fc21b..88277ae 100644 --- a/vfs/UVFSCore.pas +++ b/vfs/UVFSCore.pas @@ -381,7 +381,8 @@ begin // DebugMsg(['Checkpoint 3']); with Item^ do try - AName := strdup(P^.sFileName); + FName := strdup(P^.sFileName); + FDisplayName := StrToUTF8(P^.sFileName); if P^.sLinkTo <> nil then begin LnkPointTo := strdup(P^.sLinkTo); @@ -389,7 +390,7 @@ begin end else LnkPointTo := nil; Mode := P^.iMode; // DebugMsg(['Checkpoint 4']); - IsDotFile := (Length(AName) > 1) and (AName[0] = '.') and (AName[1] <> '.'); + IsDotFile := (Length(FName) > 1) and (FName[0] = '.') and (FName[1] <> '.'); IsDir := TVFSItemType(P^.ItemType) = vDirectory; IsLnk := TVFSItemType(P^.ItemType) = vSymlink; IsBlk := TVFSItemType(P^.ItemType) = vBlockdev; @@ -574,7 +575,8 @@ begin Item := Libc.malloc(SizeOf(TDataItemSL)); Libc.memset(Item, 0, SizeOf(TDataItemSL)); with Item^ do begin - AName := strdup(P^.sFileName); + FName := strdup(P^.sFileName); + FDisplayName := StrToUTF8(P^.sFileName); if P^.sLinkTo <> nil then LnkPointTo := strdup(P^.sLinkTo) else LnkPointTo := nil; ADestination := nil; @@ -633,7 +635,8 @@ var Item: PDataItemSL; with Item^ do begin // AName := Libc.malloc(Length(FPath) + 1); // Libc.memset(AName, 0, Length(FPath) + 1); - AName := strdup(PChar(FPath)); + FName := strdup(PChar(FPath)); + FDisplayName := StrToUTF8(PChar(FPath)); if P^.sLinkTo <> nil then LnkPointTo := strdup(P^.sLinkTo) else LnkPointTo := nil; ADestination := nil; diff --git a/vfs/uVFSprototypes.pas b/vfs/uVFSprototypes.pas index 7a87aa0..dbc9547 100644 --- a/vfs/uVFSprototypes.pas +++ b/vfs/uVFSprototypes.pas @@ -86,6 +86,11 @@ type ShortBool = boolean; {$ENDIF} + + +// All filenames should be UTF-8 as much as possible + + PVFSItem = ^TVFSItem; TVFSItem = packed record {$IFNDEF CPU64} // 32-bit platform |
