From e2e9aa8bfee744c044c4404393618a364d7edc12 Mon Sep 17 00:00:00 2001 From: Basile Burg Date: Tue, 26 May 2015 11:08:45 +0200 Subject: [PATCH] updated options editor interface - custom editor can indicated if there are any unvalidated modifications - shortcuts editor modifications can be canceled --- src/ce_dockoptions.pas | 6 +++ src/ce_editoroptions.pas | 5 +++ src/ce_interfaces.pas | 34 +++++++++++++++- src/ce_messages.pas | 6 +++ src/ce_optionseditor.pas | 54 ++++++++++++++++--------- src/ce_shortcutseditor.pas | 80 +++++++++++++++++++++++++++++++------- src/ce_staticmacro.pas | 6 +++ src/ce_symlist.pas | 6 +++ src/ce_todolist.pas | 5 +++ 9 files changed, 168 insertions(+), 34 deletions(-) diff --git a/src/ce_dockoptions.pas b/src/ce_dockoptions.pas index 111aa3b0..e33739a2 100644 --- a/src/ce_dockoptions.pas +++ b/src/ce_dockoptions.pas @@ -21,6 +21,7 @@ type function optionedWantEditorKind: TOptionEditorKind; function optionedWantContainer: TPersistent; procedure optionedEvent(anEvent: TOptionEditorEvent); + function optionedOptionsModified: boolean; // procedure doChanged(Sender: TObject); public @@ -110,6 +111,11 @@ begin end; end; +function TDockOptionsEditor.optionedOptionsModified: boolean; +begin + exit(false); +end; + procedure TDockOptionsEditor.doChanged(Sender: TObject); var hasHeaders: boolean; diff --git a/src/ce_editoroptions.pas b/src/ce_editoroptions.pas index 449c871e..d852525a 100644 --- a/src/ce_editoroptions.pas +++ b/src/ce_editoroptions.pas @@ -103,6 +103,7 @@ type function optionedWantEditorKind: TOptionEditorKind; function optionedWantContainer: TPersistent; procedure optionedEvent(anEvent: TOptionEditorEvent); + function optionedOptionsModified: boolean; // procedure docNew(aDoc: TCESynMemo); procedure docFocused(aDoc: TCESynMemo); @@ -439,6 +440,10 @@ begin end; end; +function TCEEditorOptions.optionedOptionsModified: boolean; +begin + exit(false); +end; {$ENDREGION} {$REGION ICEEditableOptions ----------------------------------------------------} diff --git a/src/ce_interfaces.pas b/src/ce_interfaces.pas index 12fe9495..a7a606c8 100644 --- a/src/ce_interfaces.pas +++ b/src/ce_interfaces.pas @@ -160,6 +160,8 @@ type function optionedWantContainer: TPersistent; // the option editor informs that something has happened. procedure optionedEvent(anEvent: TOptionEditorEvent); + // the option editor wants to know if an editor allows another category to be displayed (not called for oekGeneric). + function optionedOptionsModified: boolean; end; (** * An implementer displays its observers editable options. @@ -199,7 +201,7 @@ type // removes an entry. procedure removeProcess(aProcess: TProcess); // indicates the current process - function process(): TProcess; + function process: TProcess; end; @@ -223,6 +225,21 @@ type end; + + (** + * Single service provided by the library manager + * In both cases, if someAliases is empty then all the available entries are passed. + *) + ICELibraryInformer = interface(ICESingleService) + // fills aList with the filenames of the static libraries matching to someAliases content. + procedure getLibsFiles(someAliases: TStrings; aList: TStrings); + // fills aList with the path to static libraries sources matching to someAliases content. + procedure getLibsPaths(someAliases: TStrings; aList: TStrings); + // fills aList with all the available libraries aliases. + procedure getLibsAliases(aList: TStrings); + end; + + { subject primitives: @@ -265,6 +282,9 @@ type function getMultiDocHandler(var obj: ICEMultiDocHandler): ICEMultiDocHandler; overload; function getMultiDocHandler: ICEMultiDocHandler; overload; + function getLibraryInformer(var obj: ICELibraryInformer): ICELibraryInformer; overload; + function getLibraryInformer: ICELibraryInformer; overload; + implementation {$REGION TCEMultiDocSubject ----------------------------------------------------} @@ -411,6 +431,18 @@ function getMultiDocHandler: ICEMultiDocHandler; begin exit(EntitiesConnector.getSingleService('ICEMultiDocHandler') as ICEMultiDocHandler); end; + +function getLibraryInformer(var obj: ICELibraryInformer): ICELibraryInformer; +begin + if obj = nil then + obj := EntitiesConnector.getSingleService('ICELibraryInformer') as ICELibraryInformer; + exit(obj); +end; + +function getLibraryInformer: ICELibraryInformer; +begin + exit(EntitiesConnector.getSingleService('ICELibraryInformer') as ICELibraryInformer); +end; {$ENDREGION} end. diff --git a/src/ce_messages.pas b/src/ce_messages.pas index 8a1910d0..15a8a452 100644 --- a/src/ce_messages.pas +++ b/src/ce_messages.pas @@ -107,6 +107,7 @@ type function optionedWantEditorKind: TOptionEditorKind; function optionedWantContainer: TPersistent; procedure optionedEvent(anEvent: TOptionEditorEvent); + function optionedOptionsModified: boolean; // function singleServiceName: string; procedure message(const aValue: string; aData: Pointer; aCtxt: TCEAppMessageCtxt; aKind: TCEAppMessageKind); @@ -389,6 +390,11 @@ begin end; fOptions.AssignTo(self); end; + +function TCEMessagesWidget.optionedOptionsModified: boolean; +begin + exit(false); +end; {$ENDREGION} {$REGION ICEContextualActions---------------------------------------------------} diff --git a/src/ce_optionseditor.pas b/src/ce_optionseditor.pas index d7fefbaa..0675857e 100644 --- a/src/ce_optionseditor.pas +++ b/src/ce_optionseditor.pas @@ -47,6 +47,7 @@ type fCatChanged: boolean; fEdOptsSubj: TCEEditableOptionsSubject; procedure updateCategories; + function allowCategoryChange: boolean; function sortCategories(Cat1, Cat2: TTreeNode): integer; public constructor create(aOwner: TComponent); override; @@ -56,6 +57,9 @@ type implementation {$R *.lfm} +const + msg_mod = 'The current category modifications are not validated, discard them and continue ?'; + {$REGION Standard Comp/Obj------------------------------------------------------} constructor TCEOptionEditorWidget.create(aOwner: TComponent); var @@ -124,23 +128,43 @@ begin Dispose(PCategoryData(node.Data)); end; -procedure TCEOptionEditorWidget.selCatChanging(Sender: TObject; - Node: TTreeNode; var AllowChange: Boolean); +function TCEOptionEditorWidget.allowCategoryChange: boolean; +var + dt: PCategoryData; begin + result := true; if selCat.Selected = nil then exit; if selCat.Selected.Data = nil then exit; // accept/cancel is relative to a single category - if fCatChanged then begin - AllowChange := dlgOkCancel( - 'The modifications of the current category are not validated, ' + - 'discard them and continue ?' - ) = mrOk; - fCatChanged := not AllowChange; - if AllowChange then - btnCancelClick(nil); + dt := PCategoryData(selCat.Selected.Data); + // generic editor, changes are tracked directly here + if dt^.kind = oekGeneric then + begin + if fCatChanged then + begin + result := dlgOkCancel(msg_mod) = mrOk; + fCatChanged := not result; + if result then btnCancelClick(nil); + end; + // custom editor, changes are notified by optionedCatChange() + end else + begin + dt := PCategoryData(selCat.Selected.Data); + if dt^.container = nil then exit; + if dt^.observer.optionedOptionsModified() then + begin + result := dlgOkCancel(msg_mod) = mrOk; + if result then btnCancelClick(nil); + end; end; end; +procedure TCEOptionEditorWidget.selCatChanging(Sender: TObject;Node: TTreeNode; + var AllowChange: Boolean); +begin + AllowChange := allowCategoryChange; +end; + procedure TCEOptionEditorWidget.selCatSelectionChanged(Sender: TObject); var dt: PCategoryData; @@ -208,15 +232,7 @@ end; procedure TCEOptionEditorWidget.FormCloseQuery(Sender: TObject; var CanClose: boolean); begin - if fCatChanged then - begin - CanClose := dlgOkCancel( - 'The modifications of the current category are not validated, ' + - 'discard them and continue ?' ) = mrOk; - if CanClose then - btnCancelClick(nil); - end - else CanClose := true; + canClose := allowCategoryChange; end; procedure TCEOptionEditorWidget.inspectorEditorFilter(Sender: TObject;aEditor: diff --git a/src/ce_shortcutseditor.pas b/src/ce_shortcutseditor.pas index 14d413b8..319d0311 100644 --- a/src/ce_shortcutseditor.pas +++ b/src/ce_shortcutseditor.pas @@ -66,16 +66,20 @@ type fObservers: TCEEditableShortCutSubject; fShortcuts: TShortCutCollection; fBackup: TShortCutCollection; + fHasChanged: boolean; // function optionedWantCategory(): string; function optionedWantEditorKind: TOptionEditorKind; function optionedWantContainer: TPersistent; procedure optionedEvent(anEvent: TOptionEditorEvent); + function optionedOptionsModified: boolean; // function findCategory(const aName: string; aData: Pointer): TTreeNode; + function findCategory(const aShortcutItem: TShortcutItem): string; function sortCategories(Cat1, Cat2: TTreeNode): integer; - procedure updateFromObservers; + procedure receiveShortcuts; procedure updateEditCtrls; + procedure sendShortcuts; protected procedure UpdateShowing; override; public @@ -222,17 +226,33 @@ end; function TCEShortcutEditor.optionedWantContainer: TPersistent; begin - updateFromObservers; + receiveShortcuts; exit(self); end; procedure TCEShortcutEditor.optionedEvent(anEvent: TOptionEditorEvent); begin case anEvent of - oeeSelectCat: updateFromObservers; - //TODO-cfeature: cancel modifications using fBackup + oeeSelectCat: receiveShortcuts; + oeeCancel: + begin + fShortcuts.assign(fBackup); + sendShortcuts; + fHasChanged := false; + end; + oeeAccept: + begin + fBackup.assign(fShortcuts); + sendShortcuts; + fHasChanged := false; + end; end; end; + +function TCEShortcutEditor.optionedOptionsModified: boolean; +begin + exit(fHasChanged); +end; {$ENDREGION} {$REGION shortcut editor things ------------------------------------------------} @@ -268,10 +288,11 @@ begin if tree.Selected.Level = 0 then exit; if tree.Selected.Data = nil then exit; // - TShortcutItem(tree.Selected.Data).data := 0; - TShortcutItem(tree.Selected.Data).declarator.scedSendItem( - tree.Selected.Parent.Text, - tree.Selected.Text, 0); + if TShortcutItem(tree.Selected.Data).data <> 0 then + begin + TShortcutItem(tree.Selected.Data).data := 0; + fHasChanged := true; + end; // updateEditCtrls; end; @@ -289,10 +310,11 @@ begin else begin sh := Shortcut(Key, Shift); - TShortcutItem(tree.Selected.Data).data := sh; - TShortcutItem(tree.Selected.Data).declarator.scedSendItem( - tree.Selected.Parent.Text, - tree.Selected.Text, sh ); + if TShortcutItem(tree.Selected.Data).data <> sh then + begin + TShortcutItem(tree.Selected.Data).data := sh; + fHasChanged := true; + end; end; // updateEditCtrls; @@ -312,7 +334,7 @@ end; function TCEShortcutEditor.findCategory(const aName: string; aData: Pointer): TTreeNode; var - i: Integer; + i: integer; begin result := nil; for i:= 0 to tree.Items.Count-1 do @@ -321,12 +343,23 @@ begin exit(tree.Items[i]); end; +function TCEShortcutEditor.findCategory(const aShortcutItem: TShortcutItem): string; +var + i, j: integer; +begin + result := ''; + for i := 0 to tree.Items.Count-1 do + for j:= 0 to tree.Items.Item[i].Count-1 do + if tree.Items.Item[i].Items[j].Data = Pointer(aShortcutItem) then + exit(tree.Items.Item[i].Text); +end; + function TCEShortcutEditor.sortCategories(Cat1, Cat2: TTreeNode): integer; begin result := CompareText(Cat1.Text, Cat2.Text); end; -procedure TCEShortcutEditor.updateFromObservers; +procedure TCEShortcutEditor.receiveShortcuts; var i: Integer; obs: ICEEditableShortCut; @@ -372,6 +405,25 @@ begin tree.Items.SortTopLevelNodes(@sortCategories); fBackup.Assign(fShortcuts); end; + +procedure TCEShortcutEditor.sendShortcuts; +var + i: integer; + shc: TShortcutItem; + cat: string; +begin + for i := 0 to fShortcuts.count-1 do + begin + shc := fShortcuts[i]; + cat := findCategory(shc); + if cat = '' then + continue; + if shc.declarator = nil then + continue; + shc.declarator.scedSendItem(cat, shc.identifier, shc.data); + end; +end; + {$ENDREGION} initialization diff --git a/src/ce_staticmacro.pas b/src/ce_staticmacro.pas index 46a86500..856d458c 100644 --- a/src/ce_staticmacro.pas +++ b/src/ce_staticmacro.pas @@ -65,6 +65,7 @@ type function optionedWantEditorKind: TOptionEditorKind; function optionedWantContainer: TPersistent; procedure optionedEvent(anEvent: TOptionEditorEvent); + function optionedOptionsModified: boolean; // ICEEditableShortcut function scedWantFirst: boolean; function scedWantNext(out category, identifier: string; out aShortcut: TShortcut): boolean; @@ -296,6 +297,11 @@ begin oeeChange: fOptions.AssignTo(self); end; end; + +function TCEStaticEditorMacro.optionedOptionsModified: boolean; +begin + exit(false); +end; {$ENDREGION} {$REGION ICEEditableShortCut ---------------------------------------------------} diff --git a/src/ce_symlist.pas b/src/ce_symlist.pas index 814e78b8..2dddb9f0 100644 --- a/src/ce_symlist.pas +++ b/src/ce_symlist.pas @@ -159,6 +159,7 @@ type function optionedWantEditorKind: TOptionEditorKind; function optionedWantContainer: TPersistent; procedure optionedEvent(anEvent: TOptionEditorEvent); + function optionedOptionsModified: boolean; protected procedure updateDelayed; override; // @@ -488,6 +489,11 @@ begin fOptions.AssignTo(self); callToolProc; end; + +function TCESymbolListWidget.optionedOptionsModified: boolean; +begin + exit(false); +end; {$ENDREGION} {$REGION ICEMultiDocObserver ---------------------------------------------------} diff --git a/src/ce_todolist.pas b/src/ce_todolist.pas index a17e020e..4e95bb71 100644 --- a/src/ce_todolist.pas +++ b/src/ce_todolist.pas @@ -104,6 +104,7 @@ type function optionedWantEditorKind: TOptionEditorKind; function optionedWantContainer: TPersistent; procedure optionedEvent(anEvent: TOptionEditorEvent); + function optionedOptionsModified: boolean; // TODOlist things function getContext: TTodoContext; procedure killToolProcess; @@ -301,6 +302,10 @@ begin fOptions.AssignTo(self); end; +function TCETodoListWidget.optionedOptionsModified: boolean; +begin + exit(false); +end; {$ENDREGION} {$REGION ICEMultiDocObserver ---------------------------------------------------}