fix: missing control anchors and tab order on column selector

This commit is contained in:
Ansgar Becker
2025-12-18 09:57:33 +01:00
parent ba9442b296
commit f72156d2ad
2 changed files with 304 additions and 279 deletions

View File

@@ -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

View File

@@ -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.