@@ -32,26 +32,14 @@ interface
32
32
// / </remarks>
33
33
TPreferencesDlg = class (TGenericOKDlg, INoPublicConstruct)
34
34
pcMain: TPageControl;
35
+ lbPages: TListBox;
35
36
// / <summary>OK button click event handler. Writes preference data to
36
37
// / persistent storage.</summary>
37
38
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);
55
43
strict private
56
44
class var
57
45
// / <summary>List of registered page frames</summary>
@@ -62,6 +50,10 @@ TPreferencesDlg = class(TGenericOKDlg, INoPublicConstruct)
62
50
// / <summary>Records if main UI needs to be updated to reflect changed
63
51
// / preferences.</summary>
64
52
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;
65
57
// / <summary>Creates the required frames and displays each in a tab sheet
66
58
// / within the page control.</summary>
67
59
// / <param name="FrameClasses">array of TPrefsFrameClass [in] Class
@@ -83,6 +75,13 @@ TPreferencesDlg = class(TGenericOKDlg, INoPublicConstruct)
83
75
// / <summary>Gets reference to preferences frame on currently selected tab.
84
76
// / </summary>
85
77
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;
86
85
strict protected
87
86
// / <summary>Gets the help A-link keyword to be used when help button
88
87
// / clicked.</summary>
@@ -111,7 +110,8 @@ TPreferencesDlg = class(TGenericOKDlg, INoPublicConstruct)
111
110
// / <returns>Boolean. True if user clicks OK to accept changes or False if
112
111
// / user cancels and no changes made.</returns>
113
112
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;
115
115
overload;
116
116
// / <summary>Displays dialog with pages for each specified preferences
117
117
// / frame.</summary>
@@ -122,7 +122,8 @@ TPreferencesDlg = class(TGenericOKDlg, INoPublicConstruct)
122
122
// / <returns>Boolean. True if user clicks OK to accept changes or False if
123
123
// / user cancels and no changes made.</returns>
124
124
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;
126
127
// / <summary>Displays preferences dialog with all registered preference
127
128
// / frames.</summary>
128
129
// / <param name="AOwner">TComponent [in] Component that owns dialog.
@@ -131,8 +132,8 @@ TPreferencesDlg = class(TGenericOKDlg, INoPublicConstruct)
131
132
// / be updated as a result of preference changes.</param>
132
133
// / <returns>Boolean. True if user clicks OK to accept changes or False if
133
134
// / 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;
136
137
// / <summary>Displays dialogue with showing a single frame, specified by
137
138
// / its class name.</summary>
138
139
// / <param name="AOwner">TComponent [in] Component that owns dialog.
@@ -144,7 +145,7 @@ TPreferencesDlg = class(TGenericOKDlg, INoPublicConstruct)
144
145
// / <returns>Boolean. True if user clicks OK to accept changes or False if
145
146
// / user cancels and no changes made.</returns>
146
147
class function Execute (AOwner: TComponent; const PageClsName: string;
147
- out UpdateUI: Boolean): Boolean; overload;
148
+ out UpdateUI: Boolean; const Flags: UInt64 = 0 ): Boolean; overload;
148
149
// / <summary>Registers given preferences frame class for inclusion in the
149
150
// / preferences dialog box.</summary>
150
151
// / <remarks>Registered frames are created when the dialog box is displayed
@@ -177,7 +178,8 @@ implementation
177
178
178
179
uses
179
180
// Project
180
- IntfCommon;
181
+ IntfCommon,
182
+ UStrUtils;
181
183
182
184
183
185
{ $R *.dfm}
@@ -241,6 +243,10 @@ procedure TPreferencesDlg.CreatePages(
241
243
Frame.Top := 4 ;
242
244
// set tab sheet caption to frame's display name
243
245
TS.Caption := Frame.DisplayName;
246
+ TS.TabVisible := False;
247
+
248
+ // Create list box item for page
249
+ lbPages.Items.AddObject(Frame.DisplayName, TS);
244
250
end ;
245
251
end ;
246
252
@@ -256,10 +262,12 @@ function TPreferencesDlg.CustomHelpKeyword: string;
256
262
end ;
257
263
258
264
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;
260
267
begin
261
268
with InternalCreate(AOwner) do
262
269
try
270
+ fFrameFlags := Flags;
263
271
CreatePages(Pages);
264
272
Result := ShowModal = mrOK;
265
273
if Result then
@@ -272,21 +280,22 @@ class function TPreferencesDlg.Execute(AOwner: TComponent;
272
280
end ;
273
281
274
282
class function TPreferencesDlg.Execute (AOwner: TComponent;
275
- out UpdateUI: Boolean): Boolean;
283
+ out UpdateUI: Boolean; const Flags: UInt64 ): Boolean;
276
284
begin
277
- Result := Execute(AOwner, fPages.ToArray, UpdateUI);
285
+ Result := Execute(AOwner, fPages.ToArray, UpdateUI, Flags );
278
286
end ;
279
287
280
288
class function TPreferencesDlg.Execute (AOwner: TComponent;
281
- const Pages: array of TPrefsFrameClass): Boolean;
289
+ const Pages: array of TPrefsFrameClass; const Flags: UInt64 ): Boolean;
282
290
var
283
291
Dummy: Boolean; // unused UpdateUI parameters
284
292
begin
285
- Result := Execute(AOwner, Pages, Dummy);
293
+ Result := Execute(AOwner, Pages, Dummy, Flags );
286
294
end ;
287
295
288
296
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;
290
299
var
291
300
FrameClass: TPrefsFrameClass;
292
301
begin
@@ -295,14 +304,36 @@ class function TPreferencesDlg.Execute(AOwner: TComponent;
295
304
Result := Execute(AOwner, [FrameClass], UpdateUI);
296
305
end ;
297
306
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
+
298
329
function TPreferencesDlg.GetSelectedPage : TPrefsBaseFrame;
299
330
begin
300
331
Result := MapTabSheetToPage(pcMain.ActivePage);
301
332
end ;
302
333
303
334
procedure TPreferencesDlg.InitForm ;
304
335
var
305
- TabIdx: Integer; // loops thru tabs in page control
336
+ TabIdx: Integer; // loops thru tabs in page control
306
337
begin
307
338
inherited ;
308
339
// Take local copy of global preferences. This local copy will be updated as
@@ -311,9 +342,22 @@ procedure TPreferencesDlg.InitForm;
311
342
fLocalPrefs := (Preferences as IClonable).Clone as IPreferences;
312
343
// Display and initialise required pages
313
344
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)
317
361
end ;
318
362
319
363
class function TPreferencesDlg.MapClassNameToPageClass (const ClsName: string):
@@ -351,24 +395,6 @@ function TPreferencesDlg.MapTabSheetToPage(
351
395
Assert(Assigned(Result), ClassName + ' .MapTabSheetToPage: Frame not found' );
352
396
end ;
353
397
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
-
372
398
class procedure TPreferencesDlg.RegisterPage (const FrameCls: TPrefsFrameClass);
373
399
var
374
400
PageIdx: Integer; // loops through all registered frames
@@ -389,5 +415,14 @@ class procedure TPreferencesDlg.RegisterPage(const FrameCls: TPrefsFrameClass);
389
415
fPages.Insert(InsIdx, FrameCls);
390
416
end ;
391
417
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
+
392
427
end .
393
428
0 commit comments