#107, simplify access to main menu with a single service

This commit is contained in:
Basile Burg 2016-11-27 08:13:15 +01:00
parent 7b39f9d5e6
commit f654811f37
No known key found for this signature in database
GPG Key ID: 1868039F415CB8CF
6 changed files with 120 additions and 282 deletions

View File

@ -315,7 +315,7 @@ type
TAddWatchPointKind = (wpkRead, wpkWrite, wpkReadWrite); TAddWatchPointKind = (wpkRead, wpkWrite, wpkReadWrite);
{ TCEGdbWidget } { TCEGdbWidget }
TCEGdbWidget = class(TCEWidget, ICEProjectObserver, ICEDocumentObserver, ICEDebugger, ICEMainMenuProvider) TCEGdbWidget = class(TCEWidget, ICEProjectObserver, ICEDocumentObserver, ICEDebugger)
btnContinue: TCEToolButton; btnContinue: TCEToolButton;
btnVariables: TCEToolButton; btnVariables: TCEToolButton;
btnNext: TCEToolButton; btnNext: TCEToolButton;
@ -373,7 +373,6 @@ type
fOutputName: string; fOutputName: string;
fInputName: string; fInputName: string;
fShowFromCustomCommand: boolean; fShowFromCustomCommand: boolean;
fUpdateMenu: boolean;
fGdbState: TGdbState; fGdbState: TGdbState;
fSubj: TCEDebugObserverSubject; fSubj: TCEDebugObserverSubject;
fDoc: TCESynMemo; fDoc: TCESynMemo;
@ -392,12 +391,9 @@ type
fOptions: TCEDebugOptions; fOptions: TCEDebugOptions;
fAddWatchPointKind: TAddWatchPointKind; fAddWatchPointKind: TAddWatchPointKind;
fBreakPoints: TPersistentBreakPoints; fBreakPoints: TPersistentBreakPoints;
// fMenu: TMenuItem;
procedure updateMenu;
procedure optionsChangesApplied(sender: TObject); procedure optionsChangesApplied(sender: TObject);
procedure menuDeclare(item: TMenuItem);
procedure menuUpdate(item: TMenuItem);
function menuHasItems: boolean;
//
procedure disableEditor; procedure disableEditor;
procedure setState(value: TGdbState); procedure setState(value: TGdbState);
procedure updateButtonsState; procedure updateButtonsState;
@ -951,6 +947,7 @@ begin
fAddWatchPointKind := wpkWrite; fAddWatchPointKind := wpkWrite;
fBreakPoints := TPersistentBreakPoints.create(self); fBreakPoints := TPersistentBreakPoints.create(self);
// //
updateMenu;
AssignPng(btnSendCom, 'ACCEPT'); AssignPng(btnSendCom, 'ACCEPT');
setState(gsNone); setState(gsNone);
end; end;
@ -976,157 +973,136 @@ begin
btnSendCom.Flat:=value; btnSendCom.Flat:=value;
end; end;
procedure TCEGdbWidget.menuDeclare(item: TMenuItem); procedure TCEGdbWidget.updateMenu;
var var
mnu: ICEMainMenu;
itm: TMenuItem; itm: TMenuItem;
bmp: TBitmap; bmp: TBitmap;
i: integer; i: integer;
begin begin
item.Caption:='Debugger'; mnu := getMainMenu;
item.Clear; if not assigned(mnu) then
exit;
if fMenu.isNil then
begin
fMenu := mnu.mnuAdd;
fMenu.Caption:='Debugger';
end;
fMenu.Clear;
bmp := TBitmap.Create; bmp := TBitmap.Create;
itm := TMenuItem.Create(item); itm := TMenuItem.Create(fMenu);
itm.ShortCut:=fOptions.shortcuts.start; itm.ShortCut:=fOptions.shortcuts.start;
itm.Caption:='Start'; itm.Caption:='Start';
itm.OnClick:= @executeFromShortcut; itm.OnClick:= @executeFromShortcut;
itm.Tag:=0; itm.Tag:=0;
item.Add(itm); fMenu.Add(itm);
btnStart.toBitmap(bmp); btnStart.toBitmap(bmp);
itm.Bitmap.Assign(bmp); itm.Bitmap.Assign(bmp);
i := item.GetImageList.Add(bmp, nil); i := fMenu.GetImageList.Add(bmp, nil);
itm.ImageIndex:= i; itm.ImageIndex:= i;
itm := TMenuItem.Create(item); itm := TMenuItem.Create(fMenu);
itm.ShortCut:=fOptions.shortcuts.stop; itm.ShortCut:=fOptions.shortcuts.stop;
itm.Caption:='Stop'; itm.Caption:='Stop';
itm.OnClick:= @executeFromShortcut; itm.OnClick:= @executeFromShortcut;
itm.Tag:=1; itm.Tag:=1;
item.Add(itm); fMenu.Add(itm);
btnStop.toBitmap(bmp); btnStop.toBitmap(bmp);
itm.Bitmap.Assign(bmp); itm.Bitmap.Assign(bmp);
i := item.GetImageList.Add(bmp, nil); i := fMenu.GetImageList.Add(bmp, nil);
itm.ImageIndex:= i; itm.ImageIndex:= i;
itm := TMenuItem.Create(item); itm := TMenuItem.Create(fMenu);
itm.ShortCut:=fOptions.shortcuts.pause; itm.ShortCut:=fOptions.shortcuts.pause;
itm.Caption:='Pause'; itm.Caption:='Pause';
itm.OnClick:= @executeFromShortcut; itm.OnClick:= @executeFromShortcut;
itm.Tag:=2; itm.Tag:=2;
item.Add(itm); fMenu.Add(itm);
btnPause.toBitmap(bmp); btnPause.toBitmap(bmp);
itm.Bitmap.Assign(bmp); itm.Bitmap.Assign(bmp);
i := item.GetImageList.Add(bmp, nil); i := fMenu.GetImageList.Add(bmp, nil);
itm.ImageIndex:= i; itm.ImageIndex:= i;
itm := TMenuItem.Create(item); itm := TMenuItem.Create(fMenu);
itm.ShortCut:=fOptions.shortcuts.continue; itm.ShortCut:=fOptions.shortcuts.continue;
itm.Caption:='Continue'; itm.Caption:='Continue';
itm.OnClick:= @executeFromShortcut; itm.OnClick:= @executeFromShortcut;
itm.Tag:=3; itm.Tag:=3;
item.Add(itm); fMenu.Add(itm);
btnContinue.toBitmap(bmp); btnContinue.toBitmap(bmp);
itm.Bitmap.Assign(bmp); itm.Bitmap.Assign(bmp);
i := item.GetImageList.Add(bmp, nil); i := fMenu.GetImageList.Add(bmp, nil);
itm.ImageIndex:= i; itm.ImageIndex:= i;
itm := TMenuItem.Create(item); itm := TMenuItem.Create(fMenu);
itm.ShortCut:=fOptions.shortcuts.step; itm.ShortCut:=fOptions.shortcuts.step;
itm.Caption:='Step'; itm.Caption:='Step';
itm.OnClick:= @executeFromShortcut; itm.OnClick:= @executeFromShortcut;
itm.Tag:=4; itm.Tag:=4;
item.Add(itm); fMenu.Add(itm);
btnNext.toBitmap(bmp); btnNext.toBitmap(bmp);
itm.Bitmap.Assign(bmp); itm.Bitmap.Assign(bmp);
i := item.GetImageList.Add(bmp, nil); i := fMenu.GetImageList.Add(bmp, nil);
itm.ImageIndex:= i; itm.ImageIndex:= i;
itm := TMenuItem.Create(item); itm := TMenuItem.Create(fMenu);
itm.ShortCut:=fOptions.shortcuts.stepOver; itm.ShortCut:=fOptions.shortcuts.stepOver;
itm.Caption:='Step over'; itm.Caption:='Step over';
itm.OnClick:= @executeFromShortcut; itm.OnClick:= @executeFromShortcut;
itm.Tag:=5; itm.Tag:=5;
item.Add(itm); fMenu.Add(itm);
btnOver.toBitmap(bmp); btnOver.toBitmap(bmp);
itm.Bitmap.Assign(bmp); itm.Bitmap.Assign(bmp);
i := item.GetImageList.Add(bmp, nil); i := fMenu.GetImageList.Add(bmp, nil);
itm.ImageIndex:= i; itm.ImageIndex:= i;
itm := TMenuItem.Create(item); itm := TMenuItem.Create(fMenu);
itm.Caption:= '-'; itm.Caption:= '-';
itm.Tag:=-1; itm.Tag:=-1;
item.Add(itm); fMenu.Add(itm);
itm := TMenuItem.Create(item); itm := TMenuItem.Create(fMenu);
itm.ShortCut:=fOptions.shortcuts.updateRegisters; itm.ShortCut:=fOptions.shortcuts.updateRegisters;
itm.Caption:='Update registers'; itm.Caption:='Update registers';
itm.OnClick:= @executeFromShortcut; itm.OnClick:= @executeFromShortcut;
itm.Tag:=6; itm.Tag:=6;
item.Add(itm); fMenu.Add(itm);
btnReg.toBitmap(bmp); btnReg.toBitmap(bmp);
itm.Bitmap.Assign(bmp); itm.Bitmap.Assign(bmp);
i := item.GetImageList.Add(bmp, nil); i := fMenu.GetImageList.Add(bmp, nil);
itm.ImageIndex:= i; itm.ImageIndex:= i;
itm := TMenuItem.Create(item); itm := TMenuItem.Create(fMenu);
itm.ShortCut:=fOptions.shortcuts.updateStack; itm.ShortCut:=fOptions.shortcuts.updateStack;
itm.Caption:='Update call stack'; itm.Caption:='Update call stack';
itm.OnClick:= @executeFromShortcut; itm.OnClick:= @executeFromShortcut;
itm.Tag:=7; itm.Tag:=7;
item.Add(itm); fMenu.Add(itm);
btnStack.toBitmap(bmp); btnStack.toBitmap(bmp);
itm.Bitmap.Assign(bmp); itm.Bitmap.Assign(bmp);
i := item.GetImageList.Add(bmp, nil); i := fMenu.GetImageList.Add(bmp, nil);
itm.ImageIndex:= i; itm.ImageIndex:= i;
itm := TMenuItem.Create(item); itm := TMenuItem.Create(fMenu);
itm.ShortCut:=fOptions.shortcuts.updateVariables; itm.ShortCut:=fOptions.shortcuts.updateVariables;
itm.Caption:='Update the variables'; itm.Caption:='Update the variables';
itm.OnClick:= @executeFromShortcut; itm.OnClick:= @executeFromShortcut;
itm.Tag:=8; itm.Tag:=8;
item.Add(itm); fMenu.Add(itm);
btnVariables.toBitmap(bmp); btnVariables.toBitmap(bmp);
itm.Bitmap.Assign(bmp); itm.Bitmap.Assign(bmp);
i := item.GetImageList.Add(bmp, nil); i := fMenu.GetImageList.Add(bmp, nil);
itm.ImageIndex:= i; itm.ImageIndex:= i;
bmp.Free; bmp.Free;
end; end;
procedure TCEGdbWidget.menuUpdate(item: TMenuItem);
var
i: integer;
itm: TMenuItem;
begin
if item.isNil or not fUpdateMenu then
exit;
fUpdateMenu := false;
for i:= 0 to item.Count-1 do
begin
itm := item.Items[i];
case itm.Tag of
0: itm.ShortCut:=fOptions.shortcuts.start;
1: itm.ShortCut:=fOptions.shortcuts.stop;
2: itm.ShortCut:=fOptions.shortcuts.pause;
3: itm.ShortCut:=fOptions.shortcuts.continue;
4: itm.ShortCut:=fOptions.shortcuts.step;
5: itm.ShortCut:=fOptions.shortcuts.stepOver;
6: itm.ShortCut:=fOptions.shortcuts.updateRegisters;
7: itm.ShortCut:=fOptions.shortcuts.updateStack;
8: itm.ShortCut:=fOptions.shortcuts.updateVariables;
end;
end;
end;
function TCEGdbWidget.menuHasItems: boolean;
begin
exit(true);
end;
procedure TCEGdbWidget.optionsChangesApplied(sender: TObject); procedure TCEGdbWidget.optionsChangesApplied(sender: TObject);
begin begin
fUpdateMenu:=true; updateMenu;
end; end;
procedure TCEGdbWidget.executeFromShortcut(sender: TObject); procedure TCEGdbWidget.executeFromShortcut(sender: TObject);

View File

@ -163,47 +163,6 @@ type
(**
* An implementer can add a main menu entry.
*)
ICEMainMenuProvider = interface(IObserverType)
['ICEMainMenuProvider']
// item is a new mainMenu entry. item must be filled with the sub-items to be added.
procedure menuDeclare(item: TMenuItem);
// item is the mainMenu entry declared previously. the sub items can be updated, deleted.
procedure menuUpdate(item: TMenuItem);
// indicates if menuDeclare should be called.
function menuHasItems: boolean;
end;
(**
* An implementer collects and updates its observers menus.
*)
TCEMainMenuSubject = specialize TCECustomSubject<ICEMainMenuProvider>;
(**
* An implementer declares some actions which have their own main menu entry and
* whose shortcuts are automatically handled
*)
ICEActionProvider = interface(IObserverType)
['ICEActionProvider']
// the action handler will clear the references to the actions collected previously and start collecting if result.
function actHandlerWantRecollect: boolean;
// the action handler starts to collect the actions if result.
function actHandlerWantFirst: boolean;
// the handler continue collecting action if result.
function actHandlerWantNext(out category: string; out action: TCustomAction): boolean;
// the handler update the state of a particular action.
procedure actHandleUpdater(action: TCustomAction);
end;
(**
* An implementer handles its observers actions.
*)
TCEActionProviderSubject = specialize TCECustomSubject<ICEActionProvider>;
(** (**
* An implementer can expose customizable shortcuts to be edited in a dedicated widget. * An implementer can expose customizable shortcuts to be edited in a dedicated widget.
*) *)
@ -402,6 +361,16 @@ type
procedure getCompilerImports(value: DCompiler; paths: TStrings); procedure getCompilerImports(value: DCompiler; paths: TStrings);
end; end;
(**
* Single service that provides access to the main menu.
*)
ICEMainMenu = interface(ICESingleService)
// adds a main menu entry
function mnuAdd: TMenuItem;
// removes a main menu entry
procedure mnuDelete(value: TMenuItem);
end;
TDCDCompletionKind = ( TDCDCompletionKind = (
dckClass, dckClass,
@ -454,15 +423,16 @@ type
{ {
Service getters: Service getters:
} }
function getMessageDisplay(var obj: ICEMessagesDisplay): ICEMessagesDisplay; function getMessageDisplay(var obj: ICEMessagesDisplay): ICEMessagesDisplay; inline;
function getMessageDisplay: ICEMessagesDisplay; function getMessageDisplay: ICEMessagesDisplay; inline;
function getprocInputHandler: ICEProcInputHandler; function getprocInputHandler: ICEProcInputHandler; inline;
function getMultiDocHandler: ICEMultiDocHandler; function getMultiDocHandler: ICEMultiDocHandler; inline;
function getSymStringExpander: ICESymStringExpander; function getSymStringExpander: ICESymStringExpander; inline;
function getProjectGroup: ICEProjectGroup; function getProjectGroup: ICEProjectGroup; inline;
function getExplorer: ICEExplorer; function getExplorer: ICEExplorer; inline;
function getOptionsEditor: ICEOptionsEditor; function getOptionsEditor: ICEOptionsEditor; inline;
function getCompilerSelector: ICECompilerSelector; function getCompilerSelector: ICECompilerSelector; inline;
function getMainMenu: ICEMainMenu; inline;
implementation implementation
@ -612,6 +582,11 @@ function getCompilerSelector: ICECompilerSelector;
begin begin
exit(EntitiesConnector.getSingleService('ICECompilerSelector') as ICECompilerSelector); exit(EntitiesConnector.getSingleService('ICECompilerSelector') as ICECompilerSelector);
end; end;
function getMainMenu: ICEMainMenu;
begin
exit(EntitiesConnector.getSingleService('ICEMainMenu') as ICEMainMenu);
end;
{$ENDREGION} {$ENDREGION}
end. end.

View File

@ -4801,8 +4801,8 @@ object CEMainForm: TCEMainForm
end end
object Actions: TActionList object Actions: TActionList
Images = imgList Images = imgList
OnUpdate = ActionsUpdate
left = 32 left = 32
top = 1
object actEdCopy: TAction object actEdCopy: TAction
Category = 'Edit' Category = 'Edit'
Caption = 'Copy' Caption = 'Copy'

View File

@ -77,7 +77,7 @@ type
end; end;
{ TCEMainForm } { TCEMainForm }
TCEMainForm = class(TForm, ICEDocumentObserver, ICEEditableShortCut, ICEProjectObserver) TCEMainForm = class(TForm, ICEDocumentObserver, ICEEditableShortCut, ICEProjectObserver, ICEMainMenu)
actFileCompAndRun: TAction; actFileCompAndRun: TAction;
actFileSaveAll: TAction; actFileSaveAll: TAction;
actFileClose: TAction; actFileClose: TAction;
@ -298,7 +298,6 @@ type
procedure actProjCompileExecute(Sender: TObject); procedure actProjCompileExecute(Sender: TObject);
procedure actEdCopyExecute(Sender: TObject); procedure actEdCopyExecute(Sender: TObject);
procedure actEdCutExecute(Sender: TObject); procedure actEdCutExecute(Sender: TObject);
procedure ActionsUpdate(AAction: TBasicAction; var Handled: Boolean);
procedure actEdMacPlayExecute(Sender: TObject); procedure actEdMacPlayExecute(Sender: TObject);
procedure actEdMacStartStopExecute(Sender: TObject); procedure actEdMacStartStopExecute(Sender: TObject);
procedure actFileNewExecute(Sender: TObject); procedure actFileNewExecute(Sender: TObject);
@ -338,7 +337,6 @@ type
fDscanUnittests: boolean; fDscanUnittests: boolean;
fDoc: TCESynMemo; fDoc: TCESynMemo;
fFirstTimeCoedit: boolean; fFirstTimeCoedit: boolean;
fActionHandler: TCEActionProviderSubject;
fMultidoc: ICEMultiDocHandler; fMultidoc: ICEMultiDocHandler;
fScCollectCount: Integer; fScCollectCount: Integer;
fUpdateCount: NativeInt; fUpdateCount: NativeInt;
@ -379,18 +377,18 @@ type
fInitialized: boolean; fInitialized: boolean;
fRunProc: TCEProcess; fRunProc: TCEProcess;
fMsgs: ICEMessagesDisplay; fMsgs: ICEMessagesDisplay;
fMainMenuSubj: TCEMainMenuSubject;
fAppliOpts: TCEApplicationOptions; fAppliOpts: TCEApplicationOptions;
fProjActionsLock: boolean; fProjActionsLock: boolean;
fCompilerSelector: ICECompilerSelector; fCompilerSelector: ICECompilerSelector;
procedure updateMainMenuProviders;
procedure updateFloatingWidgetOnTop(onTop: boolean); procedure updateFloatingWidgetOnTop(onTop: boolean);
procedure widgetDockingChanged(sender: TCEWidget; newState: TWidgetDockingState); procedure widgetDockingChanged(sender: TCEWidget; newState: TWidgetDockingState);
procedure mnuOptsItemClick(sender: TObject); procedure mnuOptsItemClick(sender: TObject);
// action provider handling;
procedure clearActProviderEntries; // ICEMainMenu
procedure collectedActProviderEntries; function singleServiceName: string;
function mnuAdd: TMenuItem;
procedure mnuDelete(value: TMenuItem);
// ICEDocumentObserver // ICEDocumentObserver
procedure docNew(document: TCESynMemo); procedure docNew(document: TCESynMemo);
@ -1126,11 +1124,10 @@ end;
constructor TCEMainForm.create(aOwner: TComponent); constructor TCEMainForm.create(aOwner: TComponent);
begin begin
inherited create(aOwner); inherited create(aOwner);
fMainMenuSubj := TCEMainMenuSubject.create;
fActionHandler := TCEActionProviderSubject.create;
fOptionCategories := TCEEditableOptionsSubject.create; fOptionCategories := TCEEditableOptionsSubject.create;
EntitiesConnector.addObserver(self); EntitiesConnector.addObserver(self);
EntitiesConnector.addSingleService(self);
InitMRUs; InitMRUs;
InitWidgets; InitWidgets;
@ -1141,7 +1138,6 @@ begin
OnDragDrop:= @ddHandler.DragDrop; OnDragDrop:= @ddHandler.DragDrop;
OnDragOver:= @ddHandler.DragOver; OnDragOver:= @ddHandler.DragOver;
updateMainMenuProviders;
EntitiesConnector.forceUpdate; EntitiesConnector.forceUpdate;
fSymStringExpander:= getSymStringExpander; fSymStringExpander:= getSymStringExpander;
fProjectGroup := getProjectGroup; fProjectGroup := getProjectGroup;
@ -1810,8 +1806,6 @@ begin
fPrjGrpMru.Free; fPrjGrpMru.Free;
FreeRunnableProc; FreeRunnableProc;
// //
fMainMenuSubj.Free;
fActionHandler.Free;
fOptionCategories.Free; fOptionCategories.Free;
EntitiesConnector.removeObserver(self); EntitiesConnector.removeObserver(self);
inherited; inherited;
@ -1873,66 +1867,6 @@ begin
TAction(sender).Enabled := false; TAction(sender).Enabled := false;
end; end;
procedure TCEMainForm.ActionsUpdate(AAction: TBasicAction; var Handled: Boolean);
begin
Handled := false;
if fUpdateCount > 0 then
exit;
Inc(fUpdateCount);
try
clearActProviderEntries;
collectedActProviderEntries;
if AAction.isNotNil and not AAction.Update then
TAction(AAction).enabled := true;
updateMainMenuProviders;
finally
Dec(fUpdateCount);
end;
end;
procedure TCEMainForm.updateMainMenuProviders;
var
i, j: Integer;
itm: TMenuItem;
hasItems: boolean;
doneUpdate: boolean;
begin
if not assigned(mainMenu.Images) then
exit;
for j := 0 to fMainMenuSubj.observersCount-1 do
begin
doneUpdate := false;
hasItems := (fMainMenuSubj.observers[j] as ICEMainMenuProvider).menuHasItems;
// try to update existing entry.
for i := mainMenu.Items.Count-1 downto 0 do
if PtrInt(fMainMenuSubj.observers[j]) = mainMenu.Items[i].Tag then
begin
if not hasItems then
begin
doneUpdate:=true;
mainMenu.Items[i].Clear;
mainMenu.Items.Delete(i);
break;
end
else
begin
(fMainMenuSubj.observers[j] as ICEMainMenuProvider).menuUpdate(mainMenu.Items[i]);
doneUpdate := true;
break;
end;
end;
if doneUpdate or not hasItems then
continue;
// otherwise propose to create a new entry
itm := TMenuItem.Create(Self);
mainMenu.Items.Add(itm);
(fMainMenuSubj.observers[j] as ICEMainMenuProvider).menuDeclare(itm);
itm.Tag:= PtrInt(fMainMenuSubj.observers[j]);
if itm.Count = 0 then
itm.Free;
end;
end;
procedure TCEMainForm.mruChange(Sender: TObject); procedure TCEMainForm.mruChange(Sender: TObject);
var var
srcLst: TCEMruFileList; srcLst: TCEMruFileList;
@ -2152,55 +2086,28 @@ begin
end; end;
{$ENDREGION} {$ENDREGION}
{$REGION TCEActionProviderHandler ----------------------------------------------} {$REGION ICEMAinMenu -----------------------------------------------------------}
procedure TCEMainForm.clearActProviderEntries; function TCEMainForm.singleServiceName: string;
var
prov: ICEActionProvider;
act: TContainedAction;
i, j: Integer;
begin begin
for i:= 0 to fActionHandler.observersCount-1 do exit('ICEMainMenu');
begin
prov := fActionHandler[i] as ICEActionProvider;
if not prov.actHandlerWantRecollect then
continue;
for j := Actions.ActionCount-1 downto 0 do
begin
act := Actions.Actions[j];
if (act.Owner <> Self) and (act.Tag = PtrInt(prov)) then
act.ActionList := nil;
end;
end;
end; end;
procedure TCEMainForm.collectedActProviderEntries; function TCEMainForm.mnuAdd: TMenuItem;
var
prov: ICEActionProvider;
act: TCustomAction;
cat: string;
i: Integer;
procedure addAction;
begin
act.ActionList := Actions;
act.Tag := ptrInt(prov);
act.Category := cat;
act := nil;
cat := '';
end;
begin begin
for i:= 0 to fActionHandler.observersCount-1 do result := TMenuItem.Create(nil);
begin mainMenu.Items.Add(result);
prov := fActionHandler[i] as ICEActionProvider; exit(result);
if not prov.actHandlerWantFirst then end;
continue;
act := nil; procedure TCEMainForm.mnuDelete(value: TMenuItem);
cat := ''; var
while prov.actHandlerWantNext(cat, act) do i: integer;
addAction; begin
addAction; if value.isNil then
end; exit;
i := mainMenu.Items.IndexOf(value);
if i <> -1 then
mainMenu.Items.Delete(i);
end; end;
{$ENDREGION} {$ENDREGION}

View File

@ -66,17 +66,15 @@ type
function findTool(const value: string): TCEToolItem; function findTool(const value: string): TCEToolItem;
end; end;
TCETools = class(TWritableLfmTextComponent, ICEMainMenuProvider, ICEEditableShortcut, ICEDocumentObserver) TCETools = class(TWritableLfmTextComponent, ICEEditableShortcut, ICEDocumentObserver)
private private
fTools: TCEToolItems; fTools: TCEToolItems;
fShctCount: Integer; fShctCount: Integer;
fDoc: TCESynMemo; fDoc: TCESynMemo;
fMenu: TMenuItem;
function getTool(index: Integer): TCEToolItem; function getTool(index: Integer): TCEToolItem;
procedure setTools(value: TCEToolItems); procedure setTools(value: TCEToolItems);
// //
procedure menuDeclare(item: TMenuItem);
procedure menuUpdate(item: TMenuItem);
function menuHasItems: boolean;
procedure executeToolFromMenu(sender: TObject); procedure executeToolFromMenu(sender: TObject);
// //
procedure docNew(document: TCESynMemo); procedure docNew(document: TCESynMemo);
@ -94,6 +92,7 @@ type
constructor create(aOwner: TComponent); override; constructor create(aOwner: TComponent); override;
destructor destroy; override; destructor destroy; override;
// //
procedure updateMenu;
function addTool: TCEToolItem; function addTool: TCEToolItem;
procedure executeTool(tool: TCEToolItem); overload; procedure executeTool(tool: TCEToolItem); overload;
procedure executeTool(index: Integer); overload; procedure executeTool(index: Integer); overload;
@ -290,60 +289,37 @@ end;
{$ENDREGION} {$ENDREGION}
{$REGION ICEMainMenuProvider ---------------------------------------------------} {$REGION ICEMainMenuProvider ---------------------------------------------------}
procedure TCETools.executeToolFromMenu(sender: TObject); procedure TCETools.updateMenu;
begin
executeTool(TCEToolItem(TMenuItem(sender).tag));
end;
procedure TCETools.menuDeclare(item: TMenuItem);
var var
i: Integer; mnu: ICEMainMenu = nil;
itm: TMenuItem; itm: TMenuItem;
colitm: TCEToolItem; colitm: TCEToolItem;
i: integer;
begin begin
if tools.Count = 0 then exit; if fMenu.isNil then
// begin
item.Caption := 'Custom tools'; mnu := getMainMenu;
item.Clear; if not assigned(mnu) then
exit;
fMenu := mnu.mnuAdd;
fMenu.Caption:='Custom tools';
end;
fMenu.Clear;
for i := 0 to tools.Count-1 do for i := 0 to tools.Count-1 do
begin begin
colitm := tool[i]; colitm := tool[i];
// itm := TMenuItem.Create(fMenu);
itm := TMenuItem.Create(item);
itm.ShortCut:= colitm.shortcut; itm.ShortCut:= colitm.shortcut;
itm.Caption := colitm.toolAlias; itm.Caption := colitm.toolAlias;
itm.tag := ptrInt(colitm); itm.tag := ptrInt(colitm);
itm.onClick := @executeToolFromMenu; itm.onClick := @executeToolFromMenu;
item.add(itm); fMenu.add(itm);
end; end;
end; end;
procedure TCETools.menuUpdate(item: TMenuItem); procedure TCETools.executeToolFromMenu(sender: TObject);
var
i: Integer;
colitm: TCEToolItem;
mnuitm: TMenuItem;
begin begin
if item.isNil then exit; executeTool(TCEToolItem(TMenuItem(sender).tag));
if item.Count <> tools.Count then
menuDeclare(item)
else for i:= 0 to tools.Count-1 do
begin
colitm := tool[i];
mnuitm := item.Items[i];
//
if mnuitm.Tag <> ptrInt(colitm) then
mnuitm.Tag := ptrInt(colitm);
if mnuitm.Caption <> colitm.toolAlias then
mnuitm.Caption := colitm.toolAlias;
if mnuitm.shortcut <> colitm.shortcut then
mnuitm.shortcut := colitm.shortcut;
end;
end;
function TCETools.menuHasItems: boolean;
begin
result := tools.Count <> 0;
end; end;
{$ENDREGION} {$ENDREGION}

View File

@ -48,6 +48,7 @@ constructor TCEToolsEditorWidget.create(aOwner: TComponent);
begin begin
inherited; inherited;
propsEd.CheckboxForBoolean := true; propsEd.CheckboxForBoolean := true;
propsEd.PropertyEditorHook.AddHandlerModified(@propsEdModified);
rebuildToolList; rebuildToolList;
end; end;
@ -68,6 +69,7 @@ begin
lstTools.AddItem(CustomTools[i].toolAlias, nil); lstTools.AddItem(CustomTools[i].toolAlias, nil);
if lstTools.Count > 0 then if lstTools.Count > 0 then
lstTools.ItemIndex := 0; lstTools.ItemIndex := 0;
CustomTools.updateMenu;
end; end;
procedure TCEToolsEditorWidget.updateToolList; procedure TCEToolsEditorWidget.updateToolList;
@ -76,6 +78,7 @@ var
begin begin
for i := 0 to CustomTools.tools.Count-1 do for i := 0 to CustomTools.tools.Count-1 do
lstTools.Items[i] := CustomTools[i].toolAlias; lstTools.Items[i] := CustomTools[i].toolAlias;
CustomTools.updateMenu;
end; end;
procedure TCEToolsEditorWidget.lstToolsSelectionChange(Sender: TObject; procedure TCEToolsEditorWidget.lstToolsSelectionChange(Sender: TObject;
@ -90,7 +93,8 @@ procedure TCEToolsEditorWidget.propsEdModified(Sender: TObject);
begin begin
if propsEd.ItemIndex = -1 then if propsEd.ItemIndex = -1 then
exit; exit;
if propsEd.Rows[propsEd.ItemIndex].Name = 'toolAlias' then if (propsEd.Rows[propsEd.ItemIndex].Name = 'toolAlias')
or (propsEd.Rows[propsEd.ItemIndex].Name = 'shortcut') then
updateToolList; updateToolList;
end; end;