fix: add encoding selector to file-open dialog

Refs #2268
This commit is contained in:
Ansgar Becker
2025-11-26 12:55:28 +01:00
parent bac0d7a585
commit 56b783d829
5 changed files with 109 additions and 27 deletions

View File

@@ -28,12 +28,11 @@ object frmExtFileDialog: TfrmExtFileDialog
AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = pnlBottom
AnchorSideRight.Control = comboFileType
Left = 77
Left = 73
Height = 28
Top = 0
Width = 505
Width = 549
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Left = 10
BorderSpacing.Right = 10
TabOrder = 0
Text = 'editFilename'
@@ -45,18 +44,19 @@ object frmExtFileDialog: TfrmExtFileDialog
Left = 0
Height = 20
Top = 4
Width = 67
Caption = 'File name:'
Width = 63
BorderSpacing.Right = 10
Caption = 'Filename:'
end
object comboFileType: TComboBox
AnchorSideLeft.Control = btnOk
AnchorSideTop.Control = pnlBottom
AnchorSideRight.Control = pnlBottom
AnchorSideRight.Side = asrBottom
Left = 592
Left = 632
Height = 28
Top = 0
Width = 260
Width = 220
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Bottom = 10
ItemHeight = 20
@@ -74,14 +74,15 @@ object frmExtFileDialog: TfrmExtFileDialog
AnchorSideRight.Control = btnCancel
AnchorSideBottom.Control = pnlBottom
AnchorSideBottom.Side = asrBottom
Left = 592
Left = 632
Height = 30
Top = 38
Width = 125
Width = 105
Anchors = [akTop, akRight, akBottom]
AutoSize = True
BorderSpacing.Right = 10
Caption = 'OK'
Constraints.MinWidth = 125
Constraints.MinWidth = 105
Default = True
ModalResult = 1
TabOrder = 2
@@ -91,18 +92,45 @@ object frmExtFileDialog: TfrmExtFileDialog
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = pnlBottom
AnchorSideRight.Side = asrBottom
Left = 727
Left = 747
Height = 30
Top = 38
Width = 125
Width = 105
Anchors = [akTop, akRight]
AutoSize = True
Cancel = True
Caption = 'Cancel'
Constraints.MinWidth = 125
Constraints.MinWidth = 105
ModalResult = 2
TabOrder = 3
end
object comboEncoding: TComboBox
AnchorSideTop.Control = comboFileType
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = btnOk
Left = 402
Height = 28
Top = 38
Width = 220
Anchors = [akTop, akRight]
BorderSpacing.Right = 10
ItemHeight = 20
Style = csDropDownList
TabOrder = 4
OnChange = comboEncodingChange
end
object lblEncoding: TLabel
AnchorSideTop.Control = comboEncoding
AnchorSideTop.Side = asrCenter
AnchorSideRight.Control = comboEncoding
Left = 327
Height = 20
Top = 42
Width = 65
Anchors = [akTop, akRight]
BorderSpacing.Right = 10
Caption = 'Encoding:'
end
end
object ShellTreeView: TShellTreeView
Left = 10

View File

@@ -6,22 +6,25 @@ interface
uses
Classes, SysUtils, LCLType, Forms, Controls, Graphics, Dialogs,
ExtCtrls, StdCtrls, ShellCtrls, ComCtrls, apphelpers;
ExtCtrls, StdCtrls, ShellCtrls, ComCtrls, apphelpers, extra_controls;
type
{ TfrmExtFileDialog }
TfrmExtFileDialog = class(TForm)
TfrmExtFileDialog = class(TExtForm)
btnCancel: TButton;
btnOk: TButton;
comboEncoding: TComboBox;
comboFileType: TComboBox;
editFilename: TEdit;
lblEncoding: TLabel;
lblFilename: TLabel;
pnlBottom: TPanel;
ShellListView: TShellListView;
ShellTreeView: TShellTreeView;
splitterMain: TSplitter;
procedure comboEncodingChange(Sender: TObject);
procedure comboFileTypeChange(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
@@ -57,13 +60,16 @@ type
end;
// File-open-dialog with encoding selector
TExtFileOpenDialog = class(TfrmExtFileDialog);
TExtFileOpenDialog = class(TfrmExtFileDialog)
procedure FormCreate(Sender: TObject); overload;
end;
implementation
{$R *.lfm}
function TfrmExtFileDialog.Execute: Boolean;
begin
Result := ShowModal = mrOK;
@@ -78,12 +84,16 @@ end;
procedure TfrmExtFileDialog.FormCreate(Sender: TObject);
begin
if ClassType = TfrmExtFileDialog then
raise Exception.CreateFmt('Constructor of base class %s called. Use one of its descendants instead.', [ClassName]);
FFilterNames := TStringList.Create;
FFilterMasks := TStringList.Create;
FEncodings := TStringList.Create;
FFiles := TStringList.Create;
comboFileType.Items.Clear;
editFilename.Text := '';
lblEncoding.Enabled := False;
comboEncoding.Enabled := False;
end;
procedure TfrmExtFileDialog.FormDestroy(Sender: TObject);
@@ -106,8 +116,13 @@ begin
else
SetInitialDir(GetUserDir);
end;
comboFileType.ItemIndex := 0;
comboFileType.OnChange(Sender);
comboEncoding.Items.AddStrings(FEncodings, True);
if (FEncodingIndex >=0) and (FEncodingIndex < comboEncoding.Items.Count) then
comboEncoding.ItemIndex := FEncodingIndex;
end;
procedure TfrmExtFileDialog.comboFileTypeChange(Sender: TObject);
@@ -121,6 +136,11 @@ begin
ShellListView.Mask := FileMask;
end;
procedure TfrmExtFileDialog.comboEncodingChange(Sender: TObject);
begin
FEncodingIndex := comboEncoding.ItemIndex;
end;
procedure TfrmExtFileDialog.ShellListViewClick(Sender: TObject);
begin
if ShellListView.Selected <> nil then
@@ -131,7 +151,8 @@ end;
procedure TfrmExtFileDialog.ShellListViewDblClick(Sender: TObject);
begin
ModalResult := mrOK;
if ShellListView.Selected <> nil then
ModalResult := mrOK;
end;
procedure TfrmExtFileDialog.ShellListViewSelectItem(Sender: TObject;
@@ -170,5 +191,17 @@ begin
ShellTreeView.Path := AValue;
end;
{ TExtFileOpenDialog }
procedure TExtFileOpenDialog.FormCreate(Sender: TObject);
begin
inherited;
lblEncoding.Enabled := True;
comboEncoding.Enabled := True;
end;
end.

View File

@@ -667,6 +667,7 @@ end;
procedure Tloaddataform.btnOpenFileClick(Sender: TObject);
var
Dialog: TExtFileOpenDialog;
TestStream: TFileStream;
begin
AppSettings.ResetPath;
Dialog := TExtFileOpenDialog.Create(Self);
@@ -680,7 +681,16 @@ begin
Dialog.EncodingIndex := AppSettings.ReadInt(asFileDialogEncoding, Self.Name);
if Dialog.Execute then begin
editfilename.Text := Dialog.FileName;
FFileEncoding := TEncoding.UTF8;
FFileEncoding := Mainform.GetEncodingByName(Dialog.Encodings[Dialog.EncodingIndex]);
if FFileEncoding = nil then begin
MessageDialog(_('Auto detecting the encoding of a file is highly discouraged. You may experience data loss if the detection fails.') +
SLineBreak + SLineBreak +
_('To avoid this message select the correct encoding before pressing Open.'),
mtWarning, [mbOK]);
TestStream := TFileStream.Create(Dialog.Filename, fmOpenRead or fmShareDenyNone);
FFileEncoding := DetectEncoding(TestStream);
TestStream.Free;
end;
grpParseMethod.OnClick(Sender);
AppSettings.WriteInt(asFileDialogEncoding, Dialog.EncodingIndex, Self.Name);
end;

View File

@@ -3943,7 +3943,7 @@ end;
// Load SQL-file, make sure that SheetQuery is activated
procedure TMainForm.actLoadSQLExecute(Sender: TObject);
var
i: Integer;
i, ProceedResult: Integer;
Dialog: TExtFileOpenDialog;
Encoding: TEncoding;
Tab: TQueryTab;
@@ -3957,13 +3957,24 @@ begin
Dialog.Encodings.Assign(FileEncodings);
Dialog.EncodingIndex := AppSettings.ReadInt(asFileDialogEncoding, Self.Name);
if Dialog.Execute then begin
Encoding := TEncoding.UTF8;
if not RunQueryFiles(Dialog.Files, Encoding, Sender=actRunSQL) then begin
for i:=0 to Dialog.Files.Count-1 do begin
Tab := GetOrCreateEmptyQueryTab(False);
Tab.LoadContents(Dialog.Files[i], True, Encoding);
if i = Dialog.Files.Count-1 then
SetMainTab(Tab.TabSheet);
Encoding := GetEncodingByName(Dialog.Encodings[Dialog.EncodingIndex]);
if Encoding = nil then begin
ProceedResult := MessageDialog(_('Really auto-detect file encoding?') + SLineBreak + SLineBreak +
_('Auto detecting the encoding of a file is highly discouraged. You may experience data loss if the detection fails.') + SLineBreak + SLineBreak +
_('To avoid this message select the correct encoding before pressing Open.'),
mtConfirmation, [mbYes, mbCancel]);
end else begin
ProceedResult := mrYes;
end;
if ProceedResult = mrYes then begin
if not RunQueryFiles(Dialog.Files, Encoding, Sender=actRunSQL) then begin
for i:=0 to Dialog.Files.Count-1 do begin
Tab := GetOrCreateEmptyQueryTab(False);
Tab.LoadContents(Dialog.Files[i], True, Encoding);
if i = Dialog.Files.Count-1 then
SetMainTab(Tab.TabSheet);
end;
end;
end;
AppSettings.WriteInt(asFileDialogEncoding, Dialog.EncodingIndex, Self.Name);

View File

@@ -421,7 +421,7 @@ begin
d.EncodingIndex := AppSettings.ReadInt(asFileDialogEncoding, Self.Name);
if d.Execute then try
Screen.Cursor := crHourglass;
MemoText.Text := ReadTextFile(d.FileName, TEncoding.UTF8);
MemoText.Text := ReadTextFile(d.FileName, MainForm.GetEncodingByName(d.Encodings[d.EncodingIndex]));
if (FMaxLength > 0) and (Length(MemoText.Text) > FMaxLength) then
MemoText.Text := copy(MemoText.Text, 0, FMaxLength);
AppSettings.WriteInt(asFileDialogEncoding, d.EncodingIndex, Self.Name);