Skip to content

Commit 70e6b20

Browse files
committed
Merge branch 'feature/issue#13&#24-prefs-dlg' into develop
2 parents 6b4278f + e8e1310 commit 70e6b20

14 files changed

+286
-101
lines changed

Docs/Design/FileFormats/config.html

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -732,6 +732,27 @@ <h4>
732732
</dd>
733733
</dl>
734734

735+
<h4>
736+
[Prefs] section
737+
</h4>
738+
739+
<p>
740+
Stores information about the Preferences dialogue box itself, rather than actual preferences data. Actual preference data is stored in sections with names like [Prefs:XXX] where XXX is a preferences sub-section.
741+
</p>
742+
743+
<p>
744+
Name / Value pairs:
745+
</p>
746+
747+
<dl class="indent">
748+
<dt>
749+
<code class="key">LastTab</code> (string)
750+
</dt>
751+
<dd>
752+
Name of the tab that was open when the dialogue box was last closed. May be the empty string if the dialogue box has not yet been opened.
753+
</dd>
754+
</dl>
755+
735756
<h4>
736757
[Prefs:CodeGen] section
737758
</h4>

Src/FmPreferencesDlg.dfm

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,37 @@ inherited PreferencesDlg: TPreferencesDlg
33
Top = 138
44
Caption = 'Preferences'
55
ClientHeight = 421
6-
ClientWidth = 462
7-
ExplicitWidth = 468
8-
ExplicitHeight = 447
6+
ClientWidth = 722
7+
ExplicitWidth = 728
8+
ExplicitHeight = 450
99
PixelsPerInch = 96
1010
TextHeight = 13
1111
inherited pnlBody: TPanel
12-
Width = 446
13-
Height = 377
14-
ExplicitWidth = 446
15-
ExplicitHeight = 377
12+
Width = 609
13+
Height = 329
14+
ExplicitWidth = 609
15+
ExplicitHeight = 329
1616
object pcMain: TPageControl
17-
Left = 0
17+
Left = 163
1818
Top = 0
1919
Width = 446
20-
Height = 377
21-
Align = alClient
20+
Height = 329
21+
Align = alRight
2222
MultiLine = True
23+
TabOrder = 1
24+
ExplicitLeft = 159
25+
ExplicitHeight = 377
26+
end
27+
object lbPages: TListBox
28+
Left = 0
29+
Top = 0
30+
Width = 153
31+
Height = 329
32+
Align = alLeft
33+
ItemHeight = 13
2334
TabOrder = 0
24-
OnChange = pcMainChange
25-
OnChanging = pcMainChanging
26-
OnMouseDown = pcMainMouseDown
35+
OnClick = lbPagesClick
36+
ExplicitHeight = 377
2737
end
2838
end
2939
inherited btnOK: TButton

Src/FmPreferencesDlg.pas

Lines changed: 86 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -32,26 +32,14 @@ interface
3232
/// </remarks>
3333
TPreferencesDlg = class(TGenericOKDlg, INoPublicConstruct)
3434
pcMain: TPageControl;
35+
lbPages: TListBox;
3536
/// <summary>OK button click event handler. Writes preference data to
3637
/// persistent storage.</summary>
3738
procedure btnOKClick(Sender: TObject);
38-
/// <param>Called when current tab sheet has changed. Gets newly selected
39-
/// page to re-initialise its controls from local preferences.</param>
40-
/// <remarks>This enables any pages that depend on preferences that may
41-
/// have been changed in other pages to update appropriately.</remarks>
42-
procedure pcMainChange(Sender: TObject);
43-
/// <summary>Called just before active tab sheet is changed. Causes page
44-
/// about to be deselected to update local preferences with any changes.
45-
/// </summary>
46-
/// <remarks>We do this in case another page needs to update due to changes
47-
/// made on current page.</remarks>
48-
procedure pcMainChanging(Sender: TObject; var AllowChange: Boolean);
49-
/// <summary>Handles event triggered when user clicks on one of page
50-
/// control tabs. Ensures page control has focus.</summary>
51-
/// <remarks>Without this fix, page control does not always get focus when
52-
/// a tab is clicked.</remarks>
53-
procedure pcMainMouseDown(Sender: TObject; Button: TMouseButton;
54-
Shift: TShiftState; X, Y: Integer);
39+
/// <summary>Handles event triggered when list box is clicked or changed
40+
/// via keyboard.</summary>
41+
procedure lbPagesClick(Sender: TObject);
42+
procedure FormDestroy(Sender: TObject);
5543
strict private
5644
class var
5745
/// <summary>List of registered page frames</summary>
@@ -62,6 +50,10 @@ TPreferencesDlg = class(TGenericOKDlg, INoPublicConstruct)
6250
/// <summary>Records if main UI needs to be updated to reflect changed
6351
/// preferences.</summary>
6452
fUpdateUI: Boolean;
53+
/// <summary>Records flags to be passed to frames.</summary>
54+
fFrameFlags: UInt64;
55+
/// <summary>Records index of currently select tab/list item.</summary>
56+
fCurrentPageIdx: Integer;
6557
/// <summary>Creates the required frames and displays each in a tab sheet
6658
/// within the page control.</summary>
6759
/// <param name="FrameClasses">array of TPrefsFrameClass [in] Class
@@ -83,6 +75,13 @@ TPreferencesDlg = class(TGenericOKDlg, INoPublicConstruct)
8375
/// <summary>Gets reference to preferences frame on currently selected tab.
8476
/// </summary>
8577
function GetSelectedPage: TPrefsBaseFrame;
78+
/// <summary>Selects given tab.</summary>
79+
/// <remarks>Stores state of tab being closed and restores state of tab
80+
/// being opened.</remarks>
81+
procedure SelectTab(TS: TTabSheet);
82+
/// <summary>Returns index of tab selected when dialogue box was last
83+
/// closed or -1 if no tab recorded or tab doesn't exist.</summary>
84+
function GetLastTabIdx: Integer;
8685
strict protected
8786
/// <summary>Gets the help A-link keyword to be used when help button
8887
/// clicked.</summary>
@@ -111,7 +110,8 @@ TPreferencesDlg = class(TGenericOKDlg, INoPublicConstruct)
111110
/// <returns>Boolean. True if user clicks OK to accept changes or False if
112111
/// user cancels and no changes made.</returns>
113112
class function Execute(AOwner: TComponent;
114-
const Pages: array of TPrefsFrameClass; out UpdateUI: Boolean): Boolean;
113+
const Pages: array of TPrefsFrameClass; out UpdateUI: Boolean;
114+
const Flags: UInt64 = 0): Boolean;
115115
overload;
116116
/// <summary>Displays dialog with pages for each specified preferences
117117
/// frame.</summary>
@@ -122,7 +122,8 @@ TPreferencesDlg = class(TGenericOKDlg, INoPublicConstruct)
122122
/// <returns>Boolean. True if user clicks OK to accept changes or False if
123123
/// user cancels and no changes made.</returns>
124124
class function Execute(AOwner: TComponent;
125-
const Pages: array of TPrefsFrameClass): Boolean; overload;
125+
const Pages: array of TPrefsFrameClass; const Flags: UInt64 = 0):
126+
Boolean; overload;
126127
/// <summary>Displays preferences dialog with all registered preference
127128
/// frames.</summary>
128129
/// <param name="AOwner">TComponent [in] Component that owns dialog.
@@ -131,8 +132,8 @@ TPreferencesDlg = class(TGenericOKDlg, INoPublicConstruct)
131132
/// be updated as a result of preference changes.</param>
132133
/// <returns>Boolean. True if user clicks OK to accept changes or False if
133134
/// user cancels and no changes made.</returns>
134-
class function Execute(AOwner: TComponent; out UpdateUI: Boolean): Boolean;
135-
overload;
135+
class function Execute(AOwner: TComponent; out UpdateUI: Boolean;
136+
const Flags: UInt64 = 0): Boolean; overload;
136137
/// <summary>Displays dialogue with showing a single frame, specified by
137138
/// its class name.</summary>
138139
/// <param name="AOwner">TComponent [in] Component that owns dialog.
@@ -144,7 +145,7 @@ TPreferencesDlg = class(TGenericOKDlg, INoPublicConstruct)
144145
/// <returns>Boolean. True if user clicks OK to accept changes or False if
145146
/// user cancels and no changes made.</returns>
146147
class function Execute(AOwner: TComponent; const PageClsName: string;
147-
out UpdateUI: Boolean): Boolean; overload;
148+
out UpdateUI: Boolean; const Flags: UInt64 = 0): Boolean; overload;
148149
/// <summary>Registers given preferences frame class for inclusion in the
149150
/// preferences dialog box.</summary>
150151
/// <remarks>Registered frames are created when the dialog box is displayed
@@ -177,7 +178,8 @@ implementation
177178

178179
uses
179180
// Project
180-
IntfCommon;
181+
IntfCommon,
182+
UStrUtils;
181183

182184

183185
{$R *.dfm}
@@ -241,6 +243,10 @@ procedure TPreferencesDlg.CreatePages(
241243
Frame.Top := 4;
242244
// set tab sheet caption to frame's display name
243245
TS.Caption := Frame.DisplayName;
246+
TS.TabVisible := False;
247+
248+
// Create list box item for page
249+
lbPages.Items.AddObject(Frame.DisplayName, TS);
244250
end;
245251
end;
246252

@@ -256,10 +262,12 @@ function TPreferencesDlg.CustomHelpKeyword: string;
256262
end;
257263

258264
class function TPreferencesDlg.Execute(AOwner: TComponent;
259-
const Pages: array of TPrefsFrameClass; out UpdateUI: Boolean): Boolean;
265+
const Pages: array of TPrefsFrameClass; out UpdateUI: Boolean;
266+
const Flags: UInt64): Boolean;
260267
begin
261268
with InternalCreate(AOwner) do
262269
try
270+
fFrameFlags := Flags;
263271
CreatePages(Pages);
264272
Result := ShowModal = mrOK;
265273
if Result then
@@ -272,21 +280,22 @@ class function TPreferencesDlg.Execute(AOwner: TComponent;
272280
end;
273281

274282
class function TPreferencesDlg.Execute(AOwner: TComponent;
275-
out UpdateUI: Boolean): Boolean;
283+
out UpdateUI: Boolean; const Flags: UInt64): Boolean;
276284
begin
277-
Result := Execute(AOwner, fPages.ToArray, UpdateUI);
285+
Result := Execute(AOwner, fPages.ToArray, UpdateUI, Flags);
278286
end;
279287

280288
class function TPreferencesDlg.Execute(AOwner: TComponent;
281-
const Pages: array of TPrefsFrameClass): Boolean;
289+
const Pages: array of TPrefsFrameClass; const Flags: UInt64): Boolean;
282290
var
283291
Dummy: Boolean; // unused UpdateUI parameters
284292
begin
285-
Result := Execute(AOwner, Pages, Dummy);
293+
Result := Execute(AOwner, Pages, Dummy, Flags);
286294
end;
287295

288296
class function TPreferencesDlg.Execute(AOwner: TComponent;
289-
const PageClsName: string; out UpdateUI: Boolean): Boolean;
297+
const PageClsName: string; out UpdateUI: Boolean; const Flags: UInt64):
298+
Boolean;
290299
var
291300
FrameClass: TPrefsFrameClass;
292301
begin
@@ -295,14 +304,36 @@ class function TPreferencesDlg.Execute(AOwner: TComponent;
295304
Result := Execute(AOwner, [FrameClass], UpdateUI);
296305
end;
297306

307+
procedure TPreferencesDlg.FormDestroy(Sender: TObject);
308+
begin
309+
// Save current tab
310+
if Assigned(pcMain.ActivePage) then
311+
Preferences.LastTab := MapTabSheetToPage(pcMain.ActivePage).DisplayName;
312+
inherited;
313+
end;
314+
315+
function TPreferencesDlg.GetLastTabIdx: Integer;
316+
var
317+
TabName: string;
318+
ListIdx: Integer;
319+
begin
320+
TabName := Preferences.LastTab;
321+
if TabName = '' then
322+
Exit(-1);
323+
for ListIdx := 0 to Pred(lbPages.Count) do
324+
if StrSameText(TabName, lbPages.Items[ListIdx]) then
325+
Exit(ListIdx);
326+
Result := -1;
327+
end;
328+
298329
function TPreferencesDlg.GetSelectedPage: TPrefsBaseFrame;
299330
begin
300331
Result := MapTabSheetToPage(pcMain.ActivePage);
301332
end;
302333

303334
procedure TPreferencesDlg.InitForm;
304335
var
305-
TabIdx: Integer; // loops thru tabs in page control
336+
TabIdx: Integer; // loops thru tabs in page control
306337
begin
307338
inherited;
308339
// Take local copy of global preferences. This local copy will be updated as
@@ -311,9 +342,22 @@ procedure TPreferencesDlg.InitForm;
311342
fLocalPrefs := (Preferences as IClonable).Clone as IPreferences;
312343
// Display and initialise required pages
313344
for TabIdx := 0 to Pred(pcMain.PageCount) do
314-
MapTabSheetToPage(TabIdx).LoadPrefs(fLocalPrefs);
315-
// Select first TabSheet
316-
pcMain.ActivePageIndex := 0;
345+
MapTabSheetToPage(TabIdx).LoadPrefs(fLocalPrefs, fFrameFlags);
346+
// Select last use tab sheet (or 1st if last not known)
347+
fCurrentPageIdx := GetLastTabIdx;
348+
if fCurrentPageIdx < 0 then
349+
fCurrentPageIdx := 0;
350+
pcMain.ActivePageIndex := fCurrentPageIdx;
351+
lbPages.ItemIndex := fCurrentPageIdx;
352+
end;
353+
354+
procedure TPreferencesDlg.lbPagesClick(Sender: TObject);
355+
begin
356+
if lbPages.ItemIndex < 0 then
357+
Exit;
358+
if lbPages.ItemIndex = fCurrentPageIdx then
359+
Exit;
360+
SelectTab(lbPages.Items.Objects[lbPages.ItemIndex] as TTabSheet)
317361
end;
318362

319363
class function TPreferencesDlg.MapClassNameToPageClass(const ClsName: string):
@@ -351,24 +395,6 @@ function TPreferencesDlg.MapTabSheetToPage(
351395
Assert(Assigned(Result), ClassName + '.MapTabSheetToPage: Frame not found');
352396
end;
353397

354-
procedure TPreferencesDlg.pcMainChange(Sender: TObject);
355-
begin
356-
GetSelectedPage.Activate(fLocalPrefs);
357-
end;
358-
359-
procedure TPreferencesDlg.pcMainChanging(Sender: TObject;
360-
var AllowChange: Boolean);
361-
begin
362-
GetSelectedPage.Deactivate(fLocalPrefs);
363-
end;
364-
365-
procedure TPreferencesDlg.pcMainMouseDown(Sender: TObject; Button: TMouseButton;
366-
Shift: TShiftState; X, Y: Integer);
367-
begin
368-
if htOnItem in pcMain.GetHitTestInfoAt(X, Y) then
369-
pcMain.SetFocus;
370-
end;
371-
372398
class procedure TPreferencesDlg.RegisterPage(const FrameCls: TPrefsFrameClass);
373399
var
374400
PageIdx: Integer; // loops through all registered frames
@@ -389,5 +415,14 @@ class procedure TPreferencesDlg.RegisterPage(const FrameCls: TPrefsFrameClass);
389415
fPages.Insert(InsIdx, FrameCls);
390416
end;
391417

418+
procedure TPreferencesDlg.SelectTab(TS: TTabSheet);
419+
begin
420+
Assert(Assigned(TS), ClassName + '.SelectTab: TS is nil');
421+
GetSelectedPage.Deactivate(fLocalPrefs);
422+
pcMain.ActivePage := TS;
423+
GetSelectedPage.Activate(fLocalPrefs, fFrameFlags);
424+
fCurrentPageIdx := pcMain.ActivePageIndex;
425+
end;
426+
392427
end.
393428

Src/FmPrintDlg.pas

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,11 @@ procedure TPrintDlg.btnPrefencesClick(Sender: TObject);
130130
sMessage = 'Your preferences will take effect the next time you start the '
131131
+ 'application';
132132
begin
133-
if TPreferencesDlg.Execute(Self, [TPrintingPrefsFrame]) then
133+
if TPreferencesDlg.Execute(
134+
Self,
135+
[TPrintingPrefsFrame],
136+
TPrintingPrefsFrame.MakeFrameFlag(TPrintingPrefsFrame.HideRestartMessage)
137+
) then
134138
begin
135139
if TMessageBox.Confirm(Self, sQuery) then
136140
begin

Src/FrCodeGenPrefs.pas

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,8 @@ TCodeGenPrefsFrame = class(TPrefsBaseFrame)
176176
/// <summary>Records details of warnings from given preferences object and
177177
/// updates controls accordingly.</summary>
178178
/// <remarks>Called when page is activated.</remarks>
179-
procedure Activate(const Prefs: IPreferences); override;
179+
procedure Activate(const Prefs: IPreferences; const Flags: UInt64);
180+
override;
180181
/// <summary>Updates given preferences object with details of warnings as
181182
/// modified by user.</summary>
182183
/// <remarks>Called when page is deactivated.</remarks>
@@ -322,7 +323,8 @@ procedure TCodeGenPrefsFrame.actDeleteUpdate(Sender: TObject);
322323
actDelete.Enabled := Assigned(fLVWarnings.Selected);
323324
end;
324325

325-
procedure TCodeGenPrefsFrame.Activate(const Prefs: IPreferences);
326+
procedure TCodeGenPrefsFrame.Activate(const Prefs: IPreferences;
327+
const Flags: UInt64);
326328
begin
327329
(fWarnings as IAssignable).Assign(Prefs.Warnings);
328330
chkWARNEnabled.Checked := fWarnings.Enabled;

Src/FrDisplayPrefs.pas

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ TDisplayPrefsFrame = class(TPrefsBaseFrame)
6363
{Class constructor. Sets up frame and populates controls.
6464
@param AOwner [in] Component that owns frame.
6565
}
66-
procedure Activate(const Prefs: IPreferences); override;
66+
procedure Activate(const Prefs: IPreferences; const Flags: UInt64);
67+
override;
6768
{Called when page activated. Updates controls.
6869
@param Prefs [in] Object that provides info used to update controls.
6970
}
@@ -106,7 +107,8 @@ implementation
106107

107108
{ TDisplayPrefsFrame }
108109

109-
procedure TDisplayPrefsFrame.Activate(const Prefs: IPreferences);
110+
procedure TDisplayPrefsFrame.Activate(const Prefs: IPreferences;
111+
const Flags: UInt64);
110112
{Called when page activated. Updates controls.
111113
@param Prefs [in] Object that provides info used to update controls.
112114
}

0 commit comments

Comments
 (0)