Issue #1503: move SaveListSetup and RestoreListSetup to extra_controls unit, and handle column widths DPI independently

This commit is contained in:
Ansgar Becker
2021-12-26 13:58:25 +01:00
parent 500cad6e9a
commit 142e26ec22
7 changed files with 166 additions and 163 deletions

View File

@ -349,7 +349,7 @@ begin
AppSettings.WriteIntDpiAware(asSessionManagerWindowHeight, Self, Height); AppSettings.WriteIntDpiAware(asSessionManagerWindowHeight, Self, Height);
AppSettings.WriteInt(asSessionManagerWindowLeft, Left); AppSettings.WriteInt(asSessionManagerWindowLeft, Left);
AppSettings.WriteInt(asSessionManagerWindowTop, Top); AppSettings.WriteInt(asSessionManagerWindowTop, Top);
MainForm.SaveListSetup(ListSessions); SaveListSetup(ListSessions);
end; end;
@ -369,7 +369,7 @@ begin
pnlLeft.Width := AppSettings.ReadIntDpiAware(asSessionManagerListWidth, Self); pnlLeft.Width := AppSettings.ReadIntDpiAware(asSessionManagerListWidth, Self);
splitterMain.OnMoved(Sender); splitterMain.OnMoved(Sender);
FixVT(ListSessions); FixVT(ListSessions);
MainForm.RestoreListSetup(ListSessions); RestoreListSetup(ListSessions);
// Init sessions tree // Init sessions tree
RefreshSessions(nil); RefreshSessions(nil);

View File

@ -5,7 +5,7 @@ interface
uses uses
Classes, SysUtils, Forms, Windows, Messages, System.Types, StdCtrls, Clipbrd, Classes, SysUtils, Forms, Windows, Messages, System.Types, StdCtrls, Clipbrd,
SizeGrip, apphelpers, Vcl.Graphics, Vcl.Dialogs, gnugettext, Vcl.ImgList, Vcl.ComCtrls, SizeGrip, apphelpers, Vcl.Graphics, Vcl.Dialogs, gnugettext, Vcl.ImgList, Vcl.ComCtrls,
ShLwApi, Vcl.ExtCtrls, VirtualTrees, SynRegExpr; ShLwApi, Vcl.ExtCtrls, VirtualTrees, SynRegExpr, Vcl.Controls;
type type
// Form with a sizegrip in the lower right corner, without the need for a statusbar // Form with a sizegrip in the lower right corner, without the need for a statusbar
@ -22,6 +22,8 @@ type
class procedure InheritFont(AFont: TFont); class procedure InheritFont(AFont: TFont);
property HasSizeGrip: Boolean read GetHasSizeGrip write SetHasSizeGrip default False; property HasSizeGrip: Boolean read GetHasSizeGrip write SetHasSizeGrip default False;
class procedure FixControls(ParentComp: TComponent); class procedure FixControls(ParentComp: TComponent);
class procedure SaveListSetup(List: TVirtualStringTree);
class procedure RestoreListSetup(List: TVirtualStringTree);
end; end;
@ -148,6 +150,136 @@ begin
end; end;
{**
Save setup of a VirtualStringTree to registry
}
class procedure TExtForm.SaveListSetup( List: TVirtualStringTree );
var
i, ColWidth: Integer;
ColWidths, ColsVisible, ColPos, Regname: String;
OwnerForm: TWinControl;
begin
// Prevent sporadic crash on startup
if List = nil then
Exit;
OwnerForm := GetParentFormOrFrame(List);
// On a windows shutdown, GetParentForm() seems sporadically unable to find the owner form
// In that case we would cause an exception when accessing it. Emergency break in that case.
// See issue #1462
// TODO: Test this, probably fixed by implementing GetParentFormOrFrame, and then again, probably not.
if not Assigned(OwnerForm) then
Exit;
ColWidths := '';
ColsVisible := '';
ColPos := '';
for i := 0 to List.Header.Columns.Count - 1 do
begin
// Column widths
if ColWidths <> '' then
ColWidths := ColWidths + ',';
ColWidth := Round(List.Header.Columns[i].Width / OwnerForm.ScaleFactor);
ColWidths := ColWidths + IntToStr(ColWidth);
// Column visibility
if coVisible in List.Header.Columns[i].Options then
begin
if ColsVisible <> '' then
ColsVisible := ColsVisible + ',';
ColsVisible := ColsVisible + IntToStr(i);
end;
// Column position
if ColPos <> '' then
ColPos := ColPos + ',';
ColPos := ColPos + IntToStr(List.Header.Columns[i].Position);
end;
// Lists can have the same name over different forms or frames. Find parent form or frame,
// so we can prepend its name into the registry value name.
Regname := OwnerForm.Name + '.' + List.Name;
AppSettings.ResetPath;
AppSettings.WriteString(asListColWidths, ColWidths, Regname);
AppSettings.WriteString(asListColsVisible, ColsVisible, Regname);
AppSettings.WriteString(asListColPositions, ColPos, Regname);
AppSettings.WriteString(asListColSort, IntToStr(List.Header.SortColumn) + ',' + IntToStr(Integer(List.Header.SortDirection)), RegName);
end;
{**
Restore setup of VirtualStringTree from registry
}
class procedure TExtForm.RestoreListSetup( List: TVirtualStringTree );
var
i : Byte;
ColWidth, colpos : Integer;
Value : String;
ValueList : TStringList;
Regname: String;
OwnerForm: TWinControl;
begin
ValueList := TStringList.Create;
// Column widths
OwnerForm := GetParentFormOrFrame(List);
Regname := OwnerForm.Name + '.' + List.Name;
Value := AppSettings.ReadString(asListColWidths, Regname);
if Value <> '' then begin
ValueList := Explode( ',', Value );
for i := 0 to ValueList.Count - 1 do
begin
ColWidth := MakeInt(ValueList[i]);
ColWidth := Round(ColWidth * OwnerForm.ScaleFactor);
// Check if column number exists and width is at least 1 pixel
if (List.Header.Columns.Count > i) and (ColWidth > 0) and (ColWidth < 1000) then
List.Header.Columns[i].Width := ColWidth;
end;
end;
// Column visibility
Value := AppSettings.ReadString(asListColsVisible, Regname);
if Value <> '' then begin
ValueList := Explode( ',', Value );
for i:=0 to List.Header.Columns.Count-1 do begin
if ValueList.IndexOf( IntToStr(i) ) > -1 then
List.Header.Columns[i].Options := List.Header.Columns[i].Options + [coVisible]
else
List.Header.Columns[i].Options := List.Header.Columns[i].Options - [coVisible];
end;
end;
// Column position
Value := AppSettings.ReadString(asListColPositions, Regname);
if Value <> '' then begin
ValueList := Explode( ',', Value );
for i := 0 to ValueList.Count - 1 do
begin
colpos := MakeInt(ValueList[i]);
// Check if column number exists
if List.Header.Columns.Count > i then
List.Header.Columns[i].Position := colpos;
end;
end;
// Sort column and direction
Value := AppSettings.ReadString(asListColSort, Regname);
if Value <> '' then begin
ValueList := Explode(',', Value);
if ValueList.Count = 2 then begin
List.Header.SortColumn := MakeInt(ValueList[0]);
if MakeInt(ValueList[1]) = 0 then
List.Header.SortDirection := sdAscending
else
List.Header.SortDirection := sdDescending;
end;
end;
ValueList.Free;
end;
procedure TExtForm.FilterNodesByEdit(Edit: TButtonedEdit; Tree: TVirtualStringTree); procedure TExtForm.FilterNodesByEdit(Edit: TButtonedEdit; Tree: TVirtualStringTree);
var var
rx: TRegExpr; rx: TRegExpr;

View File

@ -118,10 +118,6 @@ begin
HasSizeGrip := True; HasSizeGrip := True;
ListFiles.Images := GetSystemImageList; ListFiles.Images := GetSystemImageList;
DragAcceptFiles(Handle, True); DragAcceptFiles(Handle, True);
MainForm.RestoreListSetup(ListColumns);
MainForm.RestoreListSetup(ListFiles);
FixVT(ListFiles);
FixVT(ListColumns);
end; end;
@ -129,8 +125,8 @@ procedure TfrmInsertFiles.FormDestroy(Sender: TObject);
begin begin
AppSettings.WriteIntDpiAware(asFileImportWindowWidth, Self, Width); AppSettings.WriteIntDpiAware(asFileImportWindowWidth, Self, Width);
AppSettings.WriteIntDpiAware(asFileImportWindowHeight, Self, Height); AppSettings.WriteIntDpiAware(asFileImportWindowHeight, Self, Height);
MainForm.SaveListSetup(ListColumns); SaveListSetup(ListColumns);
MainForm.SaveListSetup(listFiles); SaveListSetup(listFiles);
end; end;
@ -138,6 +134,10 @@ procedure TfrmInsertFiles.FormShow(Sender: TObject);
begin begin
Width := AppSettings.ReadIntDpiAware(asFileImportWindowWidth, Self); Width := AppSettings.ReadIntDpiAware(asFileImportWindowWidth, Self);
Height := AppSettings.ReadIntDpiAware(asFileImportWindowHeight, Self); Height := AppSettings.ReadIntDpiAware(asFileImportWindowHeight, Self);
RestoreListSetup(ListColumns);
RestoreListSetup(ListFiles);
FixVT(ListFiles);
FixVT(ListColumns);
FConnection := Mainform.ActiveConnection; FConnection := Mainform.ActiveConnection;
Caption := FConnection.Parameters.SessionName + ' - ' + MainForm.actInsertFiles.Caption; Caption := FConnection.Parameters.SessionName + ' - ' + MainForm.actInsertFiles.Caption;
comboDBs.Items.Clear; comboDBs.Items.Clear;

View File

@ -1313,8 +1313,6 @@ type
procedure CalcNullColors; procedure CalcNullColors;
procedure HandleDataGridAttributes(RefreshingData: Boolean); procedure HandleDataGridAttributes(RefreshingData: Boolean);
function GetRegKeyTable: String; function GetRegKeyTable: String;
procedure SaveListSetup( List: TVirtualStringTree );
procedure RestoreListSetup( List: TVirtualStringTree );
procedure UpdateEditorTab; procedure UpdateEditorTab;
procedure SetWindowCaption; procedure SetWindowCaption;
procedure DefaultHandler(var Message); override; procedure DefaultHandler(var Message); override;
@ -8305,133 +8303,6 @@ begin
end; end;
{**
Save setup of a VirtualStringTree to registry
}
procedure TMainForm.SaveListSetup( List: TVirtualStringTree );
var
i, ColWidth: Integer;
ColWidths, ColsVisible, ColPos, Regname: String;
OwnerForm: TWinControl;
begin
// Prevent sporadic crash on startup
if List = nil then
Exit;
ColWidths := '';
ColsVisible := '';
ColPos := '';
OwnerForm := GetParentFormOrFrame(List);
for i := 0 to List.Header.Columns.Count - 1 do
begin
// Column widths
if ColWidths <> '' then
ColWidths := ColWidths + ',';
ColWidth := List.Header.Columns[i].Width;
ColWidths := ColWidths + IntToStr(ColWidth);
// Column visibility
if coVisible in List.Header.Columns[i].Options then
begin
if ColsVisible <> '' then
ColsVisible := ColsVisible + ',';
ColsVisible := ColsVisible + IntToStr(i);
end;
// Column position
if ColPos <> '' then
ColPos := ColPos + ',';
ColPos := ColPos + IntToStr(List.Header.Columns[i].Position);
end;
// On a windows shutdown, GetParentForm() seems sporadically unable to find the owner form
// In that case we would cause an exception when accessing it. Emergency break in that case.
// See issue #1462
// TODO: Test this, probably fixed by implementing GetParentFormOrFrame, and then again, probably not.
if not Assigned(OwnerForm) then
Exit;
// Lists can have the same name over different forms or frames. Find parent form or frame,
// so we can prepend its name into the registry value name.
Regname := OwnerForm.Name + '.' + List.Name;
AppSettings.ResetPath;
AppSettings.WriteString(asListColWidths, ColWidths, Regname);
AppSettings.WriteString(asListColsVisible, ColsVisible, Regname);
AppSettings.WriteString(asListColPositions, ColPos, Regname);
AppSettings.WriteString(asListColSort, IntToStr(List.Header.SortColumn) + ',' + IntToStr(Integer(List.Header.SortDirection)), RegName);
end;
{**
Restore setup of VirtualStringTree from registry
}
procedure TMainForm.RestoreListSetup( List: TVirtualStringTree );
var
i : Byte;
colwidth, colpos : Integer;
Value : String;
ValueList : TStringList;
Regname: String;
OwnerForm: TWinControl;
begin
ValueList := TStringList.Create;
// Column widths
OwnerForm := GetParentFormOrFrame(List);
Regname := OwnerForm.Name + '.' + List.Name;
Value := AppSettings.ReadString(asListColWidths, Regname);
if Value <> '' then begin
ValueList := Explode( ',', Value );
for i := 0 to ValueList.Count - 1 do
begin
colwidth := MakeInt(ValueList[i]);
// Check if column number exists and width is at least 1 pixel
if (List.Header.Columns.Count > i) and (colwidth > 0) and (colwidth < 1000) then
List.Header.Columns[i].Width := colwidth;
end;
end;
// Column visibility
Value := AppSettings.ReadString(asListColsVisible, Regname);
if Value <> '' then begin
ValueList := Explode( ',', Value );
for i:=0 to List.Header.Columns.Count-1 do begin
if ValueList.IndexOf( IntToStr(i) ) > -1 then
List.Header.Columns[i].Options := List.Header.Columns[i].Options + [coVisible]
else
List.Header.Columns[i].Options := List.Header.Columns[i].Options - [coVisible];
end;
end;
// Column position
Value := AppSettings.ReadString(asListColPositions, Regname);
if Value <> '' then begin
ValueList := Explode( ',', Value );
for i := 0 to ValueList.Count - 1 do
begin
colpos := MakeInt(ValueList[i]);
// Check if column number exists
if List.Header.Columns.Count > i then
List.Header.Columns[i].Position := colpos;
end;
end;
// Sort column and direction
Value := AppSettings.ReadString(asListColSort, Regname);
if Value <> '' then begin
ValueList := Explode(',', Value);
if ValueList.Count = 2 then begin
List.Header.SortColumn := MakeInt(ValueList[0]);
if MakeInt(ValueList[1]) = 0 then
List.Header.SortDirection := sdAscending
else
List.Header.SortDirection := sdDescending;
end;
end;
ValueList.Free;
end;
{** {**
Start writing logfile. Start writing logfile.
Called either in FormShow or after closing preferences dialog Called either in FormShow or after closing preferences dialog

View File

@ -4,7 +4,7 @@ interface
uses uses
Windows, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, SynEdit, SynMemo, StdCtrls, Windows, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, SynEdit, SynMemo, StdCtrls,
ComCtrls, ToolWin, VirtualTrees, SynRegExpr, ComCtrls, ToolWin, VirtualTrees, SynRegExpr, extra_controls,
dbconnection, apphelpers, gnugettext, Vcl.Menus, Vcl.ExtCtrls; dbconnection, apphelpers, gnugettext, Vcl.Menus, Vcl.ExtCtrls;
type type
@ -112,8 +112,6 @@ begin
comboSecurity.Items.Add('Definer'); comboSecurity.Items.Add('Definer');
comboSecurity.Items.Add('Invoker'); comboSecurity.Items.Add('Invoker');
Mainform.SynCompletionProposal.AddEditor(SynMemoBody); Mainform.SynCompletionProposal.AddEditor(SynMemoBody);
FixVT(listParameters);
Mainform.RestoreListSetup(listParameters);
Parameters := TRoutineParamList.Create; Parameters := TRoutineParamList.Create;
editName.MaxLength := NAME_LEN; editName.MaxLength := NAME_LEN;
end; end;
@ -122,7 +120,7 @@ end;
destructor TfrmRoutineEditor.Destroy; destructor TfrmRoutineEditor.Destroy;
begin begin
// Store GUI setup // Store GUI setup
Mainform.SaveListSetup(listParameters); TExtForm.SaveListSetup(listParameters);
inherited; inherited;
end; end;
@ -132,6 +130,8 @@ var
i: Integer; i: Integer;
begin begin
inherited; inherited;
FixVT(listParameters);
TExtForm.RestoreListSetup(listParameters);
if Obj.NodeType = lntProcedure then FAlterRoutineType := 'PROCEDURE' if Obj.NodeType = lntProcedure then FAlterRoutineType := 'PROCEDURE'
else FAlterRoutineType := 'FUNCTION'; else FAlterRoutineType := 'FUNCTION';
editName.Text := DBObject.Name; editName.Text := DBObject.Name;

View File

@ -6,7 +6,7 @@ uses
Windows, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Windows, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls,
ComCtrls, ToolWin, VirtualTrees, SynRegExpr, ActiveX, ExtCtrls, SynEdit, ComCtrls, ToolWin, VirtualTrees, SynRegExpr, ActiveX, ExtCtrls, SynEdit,
SynMemo, Menus, Clipbrd, Math, System.UITypes, SynMemo, Menus, Clipbrd, Math, System.UITypes,
grideditlinks, dbstructures, dbconnection, apphelpers, gnugettext, StrUtils; grideditlinks, dbstructures, dbconnection, apphelpers, gnugettext, StrUtils, extra_controls;
type type
TFrame = TDBObjectEditor; TFrame = TDBObjectEditor;
@ -242,19 +242,6 @@ uses main;
constructor TfrmTableEditor.Create(AOwner: TComponent); constructor TfrmTableEditor.Create(AOwner: TComponent);
begin begin
inherited; inherited;
FixVT(listColumns);
FixVT(treeIndexes);
FixVT(listForeignKeys);
FixVT(listCheckConstraints);
// Try the best to auto fit various column widths, respecting a custom DPI setting and a pulldown arrow
listColumns.Header.Columns[2].Width := Mainform.Canvas.TextWidth('GEOMETRYCOLLECTION') + 6*listColumns.TextMargin;
listColumns.Header.Columns[7].Width := Mainform.Canvas.TextWidth('AUTO_INCREMENT') + 4*listColumns.TextMargin;
listColumns.Header.Columns[9].Width := Mainform.Canvas.TextWidth('macroman_general_ci') + 6*listColumns.TextMargin;
// Overide column widths by custom values
Mainform.RestoreListSetup(listColumns);
Mainform.RestoreListSetup(treeIndexes);
Mainform.RestoreListSetup(listForeignKeys);
MainForm.RestoreListSetup(listCheckConstraints);
comboRowFormat.Items.CommaText := 'DEFAULT,DYNAMIC,FIXED,COMPRESSED,REDUNDANT,COMPACT'; comboRowFormat.Items.CommaText := 'DEFAULT,DYNAMIC,FIXED,COMPRESSED,REDUNDANT,COMPACT';
comboInsertMethod.Items.CommaText := 'NO,FIRST,LAST'; comboInsertMethod.Items.CommaText := 'NO,FIRST,LAST';
FColumns := TTableColumnList.Create; FColumns := TTableColumnList.Create;
@ -271,10 +258,10 @@ end;
destructor TfrmTableEditor.Destroy; destructor TfrmTableEditor.Destroy;
begin begin
// Store GUI setup // Store GUI setup
Mainform.SaveListSetup(listColumns); TExtForm.SaveListSetup(listColumns);
Mainform.SaveListSetup(treeIndexes); TExtForm.SaveListSetup(treeIndexes);
Mainform.SaveListSetup(listForeignKeys); TExtForm.SaveListSetup(listForeignKeys);
MainForm.SaveListSetup(listCheckConstraints); TExtForm.SaveListSetup(listCheckConstraints);
inherited; inherited;
end; end;
@ -285,8 +272,21 @@ var
rx: TRegExpr; rx: TRegExpr;
begin begin
inherited; inherited;
FLoaded := False; FLoaded := False;
FixVT(listColumns);
FixVT(treeIndexes);
FixVT(listForeignKeys);
FixVT(listCheckConstraints);
// Try the best to auto fit various column widths, respecting a custom DPI setting and a pulldown arrow
listColumns.Header.Columns[2].Width := Mainform.Canvas.TextWidth('GEOMETRYCOLLECTION') + 6*listColumns.TextMargin;
listColumns.Header.Columns[7].Width := Mainform.Canvas.TextWidth('AUTO_INCREMENT') + 4*listColumns.TextMargin;
listColumns.Header.Columns[9].Width := Mainform.Canvas.TextWidth('macroman_general_ci') + 6*listColumns.TextMargin;
// Overide column widths by custom values
TExtForm.RestoreListSetup(listColumns);
TExtForm.RestoreListSetup(treeIndexes);
TExtForm.RestoreListSetup(listForeignKeys);
TExtForm.RestoreListSetup(listCheckConstraints);
comboEngine.Items := DBObject.Connection.TableEngines; comboEngine.Items := DBObject.Connection.TableEngines;
comboEngine.Items.Insert(0, '<'+_('Server default')+'>'); comboEngine.Items.Insert(0, '<'+_('Server default')+'>');
comboEngine.ItemIndex := 0; comboEngine.ItemIndex := 0;

View File

@ -249,7 +249,7 @@ begin
pnlLeft.Width := AppSettings.ReadIntDpiAware(asUsermanagerListWidth, Self); pnlLeft.Width := AppSettings.ReadIntDpiAware(asUsermanagerListWidth, Self);
FixVT(listUsers); FixVT(listUsers);
FixVT(treePrivs); FixVT(treePrivs);
Mainform.RestoreListSetup(listUsers); RestoreListSetup(listUsers);
FConnection := Mainform.ActiveConnection; FConnection := Mainform.ActiveConnection;
Version := FConnection.ServerVersionInt; Version := FConnection.ServerVersionInt;
@ -407,7 +407,7 @@ begin
AppSettings.WriteIntDpiAware(asUsermanagerWindowWidth, Self, Width); AppSettings.WriteIntDpiAware(asUsermanagerWindowWidth, Self, Width);
AppSettings.WriteIntDpiAware(asUsermanagerWindowHeight, Self, Height); AppSettings.WriteIntDpiAware(asUsermanagerWindowHeight, Self, Height);
AppSettings.WriteIntDpiAware(asUsermanagerListWidth, Self, pnlLeft.Width); AppSettings.WriteIntDpiAware(asUsermanagerListWidth, Self, pnlLeft.Width);
Mainform.SaveListSetup(listUsers); SaveListSetup(listUsers);
end; end;