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.WriteInt(asSessionManagerWindowLeft, Left);
AppSettings.WriteInt(asSessionManagerWindowTop, Top);
MainForm.SaveListSetup(ListSessions);
SaveListSetup(ListSessions);
end;
@ -369,7 +369,7 @@ begin
pnlLeft.Width := AppSettings.ReadIntDpiAware(asSessionManagerListWidth, Self);
splitterMain.OnMoved(Sender);
FixVT(ListSessions);
MainForm.RestoreListSetup(ListSessions);
RestoreListSetup(ListSessions);
// Init sessions tree
RefreshSessions(nil);

View File

@ -5,7 +5,7 @@ interface
uses
Classes, SysUtils, Forms, Windows, Messages, System.Types, StdCtrls, Clipbrd,
SizeGrip, apphelpers, Vcl.Graphics, Vcl.Dialogs, gnugettext, Vcl.ImgList, Vcl.ComCtrls,
ShLwApi, Vcl.ExtCtrls, VirtualTrees, SynRegExpr;
ShLwApi, Vcl.ExtCtrls, VirtualTrees, SynRegExpr, Vcl.Controls;
type
// 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);
property HasSizeGrip: Boolean read GetHasSizeGrip write SetHasSizeGrip default False;
class procedure FixControls(ParentComp: TComponent);
class procedure SaveListSetup(List: TVirtualStringTree);
class procedure RestoreListSetup(List: TVirtualStringTree);
end;
@ -148,6 +150,136 @@ begin
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);
var
rx: TRegExpr;

View File

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

View File

@ -1313,8 +1313,6 @@ type
procedure CalcNullColors;
procedure HandleDataGridAttributes(RefreshingData: Boolean);
function GetRegKeyTable: String;
procedure SaveListSetup( List: TVirtualStringTree );
procedure RestoreListSetup( List: TVirtualStringTree );
procedure UpdateEditorTab;
procedure SetWindowCaption;
procedure DefaultHandler(var Message); override;
@ -8305,133 +8303,6 @@ begin
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.
Called either in FormShow or after closing preferences dialog

View File

@ -4,7 +4,7 @@ interface
uses
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;
type
@ -112,8 +112,6 @@ begin
comboSecurity.Items.Add('Definer');
comboSecurity.Items.Add('Invoker');
Mainform.SynCompletionProposal.AddEditor(SynMemoBody);
FixVT(listParameters);
Mainform.RestoreListSetup(listParameters);
Parameters := TRoutineParamList.Create;
editName.MaxLength := NAME_LEN;
end;
@ -122,7 +120,7 @@ end;
destructor TfrmRoutineEditor.Destroy;
begin
// Store GUI setup
Mainform.SaveListSetup(listParameters);
TExtForm.SaveListSetup(listParameters);
inherited;
end;
@ -132,6 +130,8 @@ var
i: Integer;
begin
inherited;
FixVT(listParameters);
TExtForm.RestoreListSetup(listParameters);
if Obj.NodeType = lntProcedure then FAlterRoutineType := 'PROCEDURE'
else FAlterRoutineType := 'FUNCTION';
editName.Text := DBObject.Name;

View File

@ -6,7 +6,7 @@ uses
Windows, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls,
ComCtrls, ToolWin, VirtualTrees, SynRegExpr, ActiveX, ExtCtrls, SynEdit,
SynMemo, Menus, Clipbrd, Math, System.UITypes,
grideditlinks, dbstructures, dbconnection, apphelpers, gnugettext, StrUtils;
grideditlinks, dbstructures, dbconnection, apphelpers, gnugettext, StrUtils, extra_controls;
type
TFrame = TDBObjectEditor;
@ -242,19 +242,6 @@ uses main;
constructor TfrmTableEditor.Create(AOwner: TComponent);
begin
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';
comboInsertMethod.Items.CommaText := 'NO,FIRST,LAST';
FColumns := TTableColumnList.Create;
@ -271,10 +258,10 @@ end;
destructor TfrmTableEditor.Destroy;
begin
// Store GUI setup
Mainform.SaveListSetup(listColumns);
Mainform.SaveListSetup(treeIndexes);
Mainform.SaveListSetup(listForeignKeys);
MainForm.SaveListSetup(listCheckConstraints);
TExtForm.SaveListSetup(listColumns);
TExtForm.SaveListSetup(treeIndexes);
TExtForm.SaveListSetup(listForeignKeys);
TExtForm.SaveListSetup(listCheckConstraints);
inherited;
end;
@ -285,8 +272,21 @@ var
rx: TRegExpr;
begin
inherited;
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.Insert(0, '<'+_('Server default')+'>');
comboEngine.ItemIndex := 0;

View File

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