From f72156d2adf1b46d549f9727136ecc3ff45bf30d Mon Sep 17 00:00:00 2001 From: Ansgar Becker Date: Thu, 18 Dec 2025 09:57:33 +0100 Subject: [PATCH] fix: missing control anchors and tab order on column selector --- source/column_selection.lfm | 87 ++++--- source/column_selection.pas | 496 ++++++++++++++++++------------------ 2 files changed, 304 insertions(+), 279 deletions(-) diff --git a/source/column_selection.lfm b/source/column_selection.lfm index 683333f9..dbda20e1 100644 --- a/source/column_selection.lfm +++ b/source/column_selection.lfm @@ -3,6 +3,7 @@ object frmColumnSelection: TfrmColumnSelection Height = 304 Top = 0 Width = 250 + AutoSize = True BorderStyle = bsSizeToolWin Caption = 'Select columns' ClientHeight = 304 @@ -17,74 +18,96 @@ object frmColumnSelection: TfrmColumnSelection OnDestroy = FormDestroy OnShow = FormShow object btnCancel: TButton - Left = 146 - Height = 31 - Top = 264 - Width = 94 + AnchorSideRight.Control = Owner + AnchorSideRight.Side = asrBottom + AnchorSideBottom.Control = Owner + AnchorSideBottom.Side = asrBottom + Left = 144 + Height = 30 + Top = 268 + Width = 100 Anchors = [akRight, akBottom] + AutoSize = True BorderSpacing.Around = 6 Cancel = True Caption = 'Cancel' + Constraints.MinWidth = 100 ModalResult = 2 - TabOrder = 0 + TabOrder = 6 OnClick = btnCancelClick end object btnOK: TButton - Left = 48 - Height = 31 - Top = 264 - Width = 94 + AnchorSideRight.Control = btnCancel + AnchorSideBottom.Control = Owner + AnchorSideBottom.Side = asrBottom + Left = 38 + Height = 30 + Top = 268 + Width = 100 Anchors = [akRight, akBottom] + AutoSize = True BorderSpacing.Around = 6 Caption = 'OK' + Constraints.MinWidth = 100 Default = True - TabOrder = 1 + TabOrder = 5 OnClick = btnOKClick end object chkSort: TCheckBox + AnchorSideLeft.Control = Owner AnchorSideTop.Control = chklistColumns AnchorSideTop.Side = asrBottom - Left = 10 + AnchorSideBottom.Control = chkShowRowId + Left = 6 Height = 24 - Top = 198 - Width = 230 - Anchors = [akLeft, akRight, akBottom] + Top = 208 + Width = 145 + Anchors = [akLeft, akBottom] BorderSpacing.Around = 6 Caption = 'Sort alphabetically' - TabOrder = 2 + TabOrder = 3 OnClick = PopulateList end object chkSelectAll: TCheckBox + AnchorSideLeft.Control = Owner AnchorSideTop.Control = Owner - Left = 10 + Left = 6 Height = 24 Hint = 'Select / Deselect all' Top = 6 Width = 39 BorderSpacing.Around = 6 Caption = 'All' - TabOrder = 3 + TabOrder = 0 OnClick = chkSelectAllClick end object chklistColumns: TCheckListBox + AnchorSideLeft.Control = Owner AnchorSideTop.Control = editFilter AnchorSideTop.Side = asrBottom - Left = 10 - Height = 152 + AnchorSideRight.Control = Owner + AnchorSideRight.Side = asrBottom + AnchorSideBottom.Control = chkSort + Left = 6 + Height = 162 Top = 40 - Width = 230 + Width = 238 Anchors = [akTop, akLeft, akRight, akBottom] BorderSpacing.Around = 6 ItemHeight = 0 - TabOrder = 4 + TabOrder = 2 OnClickCheck = chklistColumnsClickCheck end object editFilter: TEditButton + AnchorSideLeft.Control = chkSelectAll + AnchorSideLeft.Side = asrBottom AnchorSideTop.Control = Owner - Left = 79 + AnchorSideRight.Control = Owner + AnchorSideRight.Side = asrBottom + Left = 51 Height = 28 Top = 6 - Width = 161 + Width = 193 Anchors = [akTop, akLeft, akRight] BorderSpacing.Around = 6 ButtonWidth = 29 @@ -92,22 +115,24 @@ object frmColumnSelection: TfrmColumnSelection ImageIndex = 146 MaxLength = 0 NumGlyphs = 1 + PasswordChar = #0 + TabOrder = 1 + TextHint = 'Filter' OnButtonClick = editFilterButtonClick OnChange = PopulateList - PasswordChar = #0 - TabOrder = 5 - TextHint = 'Filter' end object chkShowRowId: TCheckBox + AnchorSideLeft.Control = Owner AnchorSideTop.Control = chkSort AnchorSideTop.Side = asrBottom - Left = 10 + AnchorSideBottom.Control = btnOK + Left = 6 Height = 24 - Top = 227 - Width = 230 - Anchors = [akLeft, akRight, akBottom] + Top = 238 + Width = 195 + Anchors = [akLeft, akBottom] BorderSpacing.Around = 6 Caption = 'Show static row id column' - TabOrder = 6 + TabOrder = 4 end end diff --git a/source/column_selection.pas b/source/column_selection.pas index de110d29..efdd1e1b 100644 --- a/source/column_selection.pas +++ b/source/column_selection.pas @@ -1,248 +1,248 @@ -unit column_selection; - -{$mode delphi}{$H+} - -interface - -uses - Classes, Controls, Forms, StdCtrls, CheckLst, ExtCtrls, SysUtils, - apphelpers, extra_controls, EditBtn; - -type - - { TfrmColumnSelection } - - TfrmColumnSelection = class(TExtForm) - btnCancel: TButton; - btnOK: TButton; - chkSelectAll: TCheckBox; - chklistColumns: TCheckListBox; - chkSort: TCheckBox; - editFilter: TEditButton; - chkShowRowId: TCheckBox; - procedure btnCancelClick(Sender: TObject); - procedure FormDestroy(Sender: TObject); - procedure FormShow(Sender: TObject); - procedure chklistColumnsClickCheck(Sender: TObject); - procedure chkSelectAllClick(Sender: TObject); - procedure btnOKClick(Sender: TObject); - procedure PopulateList(Sender: TObject); - procedure FormClose(Sender: TObject; var Action: TCloseAction); - procedure FormDeactivate(Sender: TObject); - procedure FormCreate(Sender: TObject); - procedure editFilterButtonClick(Sender: TObject); - private - { Private declarations } - FCheckedColumns: TStringList; - FLastFilter: String; - public - { Public declarations } - end; - - -implementation - -uses main; - - -{$R *.lfm} - - - -procedure TfrmColumnSelection.FormCreate(Sender: TObject); -begin - HasSizeGrip := True; - FCheckedColumns := TStringList.Create; - Width := AppSettings.ReadInt(asColumnSelectorWidth); - Height := AppSettings.ReadInt(asColumnSelectorHeight); -end; - - -{** - FormShow -} -procedure TfrmColumnSelection.FormShow(Sender: TObject); -var - i: Integer; - Col: String; -begin - FCheckedColumns.Clear; - for i:=0 to Mainform.SelectedTableColumns.Count-1 do begin - Col := Mainform.SelectedTableColumns[i].Name; - chklistColumns.Items.Add(Col); - if (Mainform.DataGridHiddenColumns.Count = 0) or - (Mainform.DataGridHiddenColumns.IndexOf(chklistColumns.Items[i]) = -1) - then begin - FCheckedColumns.Add(Col); - chklistColumns.Checked[i] := True; - end; - end; - - // Call check-event to update state of "Select / Deselect all" checkbox - chklistColumnsClickCheck( Sender ); - - // Restore last used sorting state from registry - chkSort.Checked := AppSettings.ReadBool(asDisplayedColumnsSorted); - chkShowRowId.Checked := AppSettings.ReadBool(asShowRowId); -end; - - -{** - OK clicked -} -procedure TfrmColumnSelection.btnOKClick(Sender: TObject); -var - i: Integer; - Col: String; -begin - AppSettings.WriteBool(asShowRowId, chkShowRowId.Checked); - // Prepare string for storing in registry. - // Use quote-character as separator to ensure columnnames can - // be extracted safely later - Mainform.DataGridHiddenColumns.Clear; - for i:=0 to Mainform.SelectedTableColumns.Count-1 do begin - Col := Mainform.SelectedTableColumns[i].Name; - if FCheckedColumns.IndexOf(Col) = -1 then - Mainform.DataGridHiddenColumns.Add(Col); - end; - InvalidateVT(Mainform.DataGrid, VTREE_NOTLOADED_PURGECACHE, False); - btnCancel.OnClick(Sender); -end; - - -{** - Select / Deselect all -} -procedure TfrmColumnSelection.chkSelectAllClick(Sender: TObject); -var - cb: TCheckBox; - i: Integer; -begin - // Avoid executing when checkbox was toggled by code (see proc below) - cb := Sender as TCheckBox; - if cb.Focused then begin - chklistColumns.CheckAll(cb.State); - for i:=0 to chklistColumns.Items.Count-1 do begin - if (FCheckedColumns.IndexOf(chklistColumns.Items[i]) = -1) and (cb.State = cbChecked) then - FCheckedColumns.Add(chklistColumns.Items[i]); - if (FCheckedColumns.IndexOf(chklistColumns.Items[i]) > -1) and (cb.State = cbUnchecked) then - FCheckedColumns.Delete(FCheckedColumns.IndexOf(chklistColumns.Items[i])); - end; - end; -end; - - -procedure TfrmColumnSelection.editFilterButtonClick(Sender: TObject); -begin - if IsNotEmpty(editFilter.Text) then begin - FLastFilter := editFilter.Text; - editFilter.Text := ''; - end else if not FLastFilter.IsEmpty then begin - editFilter.Text := FLastFilter; - FLastFilter := ''; - end; -end; - - -{** - Click within column list - Updates state of "Select / deselect all" checkbox -} -procedure TfrmColumnSelection.chklistColumnsClickCheck(Sender: TObject); -var - i : Integer; - AllSelected, NoneSelected : Boolean; - FocusedItem: String; - FocusedItemIndex: Integer; -begin - // Add or remove clicked item from list - if chklistColumns.ItemIndex > -1 then begin - FocusedItem := chklistColumns.Items[chklistColumns.ItemIndex]; - if chklistColumns.Checked[chklistColumns.ItemIndex] then begin - FCheckedColumns.Add(FocusedItem) - end else begin - FocusedItemIndex := FCheckedColumns.IndexOf(FocusedItem); - if FocusedItemIndex > -1 then - FCheckedColumns.Delete(FocusedItemIndex); - end; - end; - - Allselected := True; - NoneSelected := True; - for i:=0 to chklistColumns.Items.Count-1 do begin - if chklistColumns.Checked[i] then - NoneSelected := False - else - AllSelected := False; - end; - if NoneSelected then - chkSelectAll.State := cbUnchecked - else if AllSelected then - chkSelectAll.State := cbChecked - else - chkSelectAll.State := cbGrayed; -end; - - -{** - Sort / Unsort the list with fields -} -procedure TfrmColumnSelection.PopulateList(Sender: TObject); -var - i: Integer; - Col: String; -begin - // Setting Sorted to false doesn't resort anything in the list. - // So we have to add all items again in original order - chklistColumns.Sorted := chkSort.Checked; - // Add all fieldnames again - chklistColumns.Items.BeginUpdate; - chklistColumns.Clear; - for i:=0 to Mainform.SelectedTableColumns.Count-1 do begin - Col := Mainform.SelectedTableColumns[i].Name; - if IsEmpty(editFilter.Text) or (Pos(LowerCase(editFilter.Text), LowerCase(Col)) > 0) then - chklistColumns.Items.Add(Col); - end; - chklistColumns.Items.EndUpdate; - - // check those which remembered as checked - for i:=0 to chklistColumns.Items.Count-1 do begin - chklistColumns.Checked[i] := FCheckedColumns.IndexOf(chklistColumns.Items[i]) > -1; - end; -end; - - -procedure TfrmColumnSelection.btnCancelClick(Sender: TObject); -begin - Mainform.tbtnDataColumns.Down := False; - Close; -end; - -procedure TfrmColumnSelection.FormDestroy(Sender: TObject); -begin - AppSettings.WriteInt(asColumnSelectorWidth, ScaleFormToDesign(Width)); - AppSettings.WriteInt(asColumnSelectorHeight, ScaleFormToDesign(Height)); -end; - - -{** - Cancel this dialog if the user clicks elsewhere on mainform -} -procedure TfrmColumnSelection.FormDeactivate(Sender: TObject); -begin - btnCancel.OnClick(Sender); -end; - - -{** - Be sure the form is destroyed after closing. -} -procedure TfrmColumnSelection.FormClose(Sender: TObject; var Action: - TCloseAction); -begin - Action := caFree; - FCheckedColumns.Free; -end; - - -end. +unit column_selection; + +{$mode delphi}{$H+} + +interface + +uses + Classes, Controls, Forms, StdCtrls, CheckLst, ExtCtrls, SysUtils, + apphelpers, extra_controls, EditBtn; + +type + + { TfrmColumnSelection } + + TfrmColumnSelection = class(TExtForm) + btnCancel: TButton; + btnOK: TButton; + chkSelectAll: TCheckBox; + chklistColumns: TCheckListBox; + chkSort: TCheckBox; + editFilter: TEditButton; + chkShowRowId: TCheckBox; + procedure btnCancelClick(Sender: TObject); + procedure FormDestroy(Sender: TObject); + procedure FormShow(Sender: TObject); + procedure chklistColumnsClickCheck(Sender: TObject); + procedure chkSelectAllClick(Sender: TObject); + procedure btnOKClick(Sender: TObject); + procedure PopulateList(Sender: TObject); + procedure FormClose(Sender: TObject; var Action: TCloseAction); + procedure FormDeactivate(Sender: TObject); + procedure FormCreate(Sender: TObject); + procedure editFilterButtonClick(Sender: TObject); + private + { Private declarations } + FCheckedColumns: TStringList; + FLastFilter: String; + public + { Public declarations } + end; + + +implementation + +uses main; + + +{$R *.lfm} + + + +procedure TfrmColumnSelection.FormCreate(Sender: TObject); +begin + HasSizeGrip := True; + FCheckedColumns := TStringList.Create; + Width := AppSettings.ReadInt(asColumnSelectorWidth); + Height := AppSettings.ReadInt(asColumnSelectorHeight); +end; + + +{** + FormShow +} +procedure TfrmColumnSelection.FormShow(Sender: TObject); +var + i: Integer; + Col: String; +begin + FCheckedColumns.Clear; + for i:=0 to Mainform.SelectedTableColumns.Count-1 do begin + Col := Mainform.SelectedTableColumns[i].Name; + chklistColumns.Items.Add(Col); + if (Mainform.DataGridHiddenColumns.Count = 0) or + (Mainform.DataGridHiddenColumns.IndexOf(chklistColumns.Items[i]) = -1) + then begin + FCheckedColumns.Add(Col); + chklistColumns.Checked[i] := True; + end; + end; + + // Call check-event to update state of "Select / Deselect all" checkbox + chklistColumnsClickCheck( Sender ); + + // Restore last used sorting state from registry + chkSort.Checked := AppSettings.ReadBool(asDisplayedColumnsSorted); + chkShowRowId.Checked := AppSettings.ReadBool(asShowRowId); +end; + + +{** + OK clicked +} +procedure TfrmColumnSelection.btnOKClick(Sender: TObject); +var + i: Integer; + Col: String; +begin + AppSettings.WriteBool(asShowRowId, chkShowRowId.Checked); + // Prepare string for storing in registry. + // Use quote-character as separator to ensure columnnames can + // be extracted safely later + Mainform.DataGridHiddenColumns.Clear; + for i:=0 to Mainform.SelectedTableColumns.Count-1 do begin + Col := Mainform.SelectedTableColumns[i].Name; + if FCheckedColumns.IndexOf(Col) = -1 then + Mainform.DataGridHiddenColumns.Add(Col); + end; + InvalidateVT(Mainform.DataGrid, VTREE_NOTLOADED_PURGECACHE, False); + btnCancel.OnClick(Sender); +end; + + +{** + Select / Deselect all +} +procedure TfrmColumnSelection.chkSelectAllClick(Sender: TObject); +var + cb: TCheckBox; + i: Integer; +begin + // Avoid executing when checkbox was toggled by code (see proc below) + cb := Sender as TCheckBox; + if cb.Focused then begin + chklistColumns.CheckAll(cb.State); + for i:=0 to chklistColumns.Items.Count-1 do begin + if (FCheckedColumns.IndexOf(chklistColumns.Items[i]) = -1) and (cb.State = cbChecked) then + FCheckedColumns.Add(chklistColumns.Items[i]); + if (FCheckedColumns.IndexOf(chklistColumns.Items[i]) > -1) and (cb.State = cbUnchecked) then + FCheckedColumns.Delete(FCheckedColumns.IndexOf(chklistColumns.Items[i])); + end; + end; +end; + + +procedure TfrmColumnSelection.editFilterButtonClick(Sender: TObject); +begin + if IsNotEmpty(editFilter.Text) then begin + FLastFilter := editFilter.Text; + editFilter.Text := ''; + end else if not FLastFilter.IsEmpty then begin + editFilter.Text := FLastFilter; + FLastFilter := ''; + end; +end; + + +{** + Click within column list + Updates state of "Select / deselect all" checkbox +} +procedure TfrmColumnSelection.chklistColumnsClickCheck(Sender: TObject); +var + i : Integer; + AllSelected, NoneSelected : Boolean; + FocusedItem: String; + FocusedItemIndex: Integer; +begin + // Add or remove clicked item from list + if chklistColumns.ItemIndex > -1 then begin + FocusedItem := chklistColumns.Items[chklistColumns.ItemIndex]; + if chklistColumns.Checked[chklistColumns.ItemIndex] then begin + FCheckedColumns.Add(FocusedItem) + end else begin + FocusedItemIndex := FCheckedColumns.IndexOf(FocusedItem); + if FocusedItemIndex > -1 then + FCheckedColumns.Delete(FocusedItemIndex); + end; + end; + + Allselected := True; + NoneSelected := True; + for i:=0 to chklistColumns.Items.Count-1 do begin + if chklistColumns.Checked[i] then + NoneSelected := False + else + AllSelected := False; + end; + if NoneSelected then + chkSelectAll.State := cbUnchecked + else if AllSelected then + chkSelectAll.State := cbChecked + else + chkSelectAll.State := cbGrayed; +end; + + +{** + Sort / Unsort the list with fields +} +procedure TfrmColumnSelection.PopulateList(Sender: TObject); +var + i: Integer; + Col: String; +begin + // Setting Sorted to false doesn't resort anything in the list. + // So we have to add all items again in original order + chklistColumns.Sorted := chkSort.Checked; + // Add all fieldnames again + chklistColumns.Items.BeginUpdate; + chklistColumns.Clear; + for i:=0 to Mainform.SelectedTableColumns.Count-1 do begin + Col := Mainform.SelectedTableColumns[i].Name; + if IsEmpty(editFilter.Text) or (Pos(LowerCase(editFilter.Text), LowerCase(Col)) > 0) then + chklistColumns.Items.Add(Col); + end; + chklistColumns.Items.EndUpdate; + + // check those which remembered as checked + for i:=0 to chklistColumns.Items.Count-1 do begin + chklistColumns.Checked[i] := FCheckedColumns.IndexOf(chklistColumns.Items[i]) > -1; + end; +end; + + +procedure TfrmColumnSelection.btnCancelClick(Sender: TObject); +begin + Mainform.tbtnDataColumns.Down := False; + Close; +end; + +procedure TfrmColumnSelection.FormDestroy(Sender: TObject); +begin + AppSettings.WriteInt(asColumnSelectorWidth, ScaleFormToDesign(Width)); + AppSettings.WriteInt(asColumnSelectorHeight, ScaleFormToDesign(Height)); +end; + + +{** + Cancel this dialog if the user clicks elsewhere on mainform +} +procedure TfrmColumnSelection.FormDeactivate(Sender: TObject); +begin + btnCancel.OnClick(Sender); +end; + + +{** + Be sure the form is destroyed after closing. +} +procedure TfrmColumnSelection.FormClose(Sender: TObject; var Action: + TCloseAction); +begin + Action := caFree; + FCheckedColumns.Free; +end; + + +end.