From 8536adb4575adfc38b68d80f9588abd0b5a5005c Mon Sep 17 00:00:00 2001 From: juha Date: Sat, 13 Feb 2016 12:58:47 +0000 Subject: [PATCH] New files refactored from MenuShadows. git-svn-id: trunk@51614 - --- .gitattributes | 2 + designer/menuresolveconflicts.pas | 301 ++++++++++++++++++ designer/menushortcutdisplay.pas | 490 ++++++++++++++++++++++++++++++ 3 files changed, 793 insertions(+) create mode 100644 designer/menuresolveconflicts.pas create mode 100644 designer/menushortcutdisplay.pas diff --git a/.gitattributes b/.gitattributes index a72e1b4254..1a2b72ad5c 100644 --- a/.gitattributes +++ b/.gitattributes @@ -4546,7 +4546,9 @@ designer/jitforms.pp svneol=native#text/pascal designer/menudesignerbase.pas svneol=native#text/pascal designer/menueditorform.lfm svneol=native#text/pascal designer/menueditorform.pas svneol=native#text/pascal +designer/menuresolveconflicts.pas svneol=native#text/pascal designer/menushadows.pp svneol=native#text/pascal +designer/menushortcutdisplay.pas svneol=native#text/pascal designer/menushortcuts.pas svneol=native#text/pascal designer/menutemplates.pas svneol=native#text/pascal designer/noncontroldesigner.pas svneol=native#text/pascal diff --git a/designer/menuresolveconflicts.pas b/designer/menuresolveconflicts.pas new file mode 100644 index 0000000000..67b95500fd --- /dev/null +++ b/designer/menuresolveconflicts.pas @@ -0,0 +1,301 @@ +unit MenuResolveConflicts; + +{$mode objfpc}{$H+} + +interface + +uses + // FCL + LCL + Classes, SysUtils, + ActnList, ButtonPanel, Controls, StdCtrls, Menus, Forms, Graphics, LCLProc, + // IdeIntf + FormEditingIntf, PropEdits, + // IDE + LazarusIDEStrConsts, MenuDesignerBase, MenuShortcuts; + +type + + { TResolveConflictsDlg } + + TResolveConflictsDlg = class(TForm) + strict private + FButtonPanel: TButtonPanel; + FConflictsGroupBox: TGroupBox; + FConflictsListBox: TListBox; + FCurrentEdit: TEdit; + FInitialConflictsCount: integer; + FRemainingConflictsCountLabel: TLabel; + FResolvedConflictsCount: integer; + FResolvedConflictsCountLabel: TLabel; + FSelectedDuplicate: TSCInfo; + FSelectedInfo: TSCInfo; + FSelectedUnique: TSCInfo; + FShortcuts: TMenuShortcuts; + FShadowMenu: TShadowMenuBase; + procedure ConflictsBoxSelectionChange(Sender: TObject; {%H-}User: boolean); + procedure CreateListboxItems; + procedure InitialPopulateListBox; + procedure OKButtonClick(Sender: TObject); + procedure RePopulateListBox; + procedure UpdateStatistics; + public + constructor Create(aShortcuts: TMenuShortcuts; aShadowMenu: TShadowMenuBase); reintroduce; + destructor Destroy; override; + end; + + +implementation + +{ TResolveConflictsDlg } + +constructor TResolveConflictsDlg.Create(aShortcuts: TMenuShortcuts; + aShadowMenu: TShadowMenuBase); +begin + inherited CreateNew(Nil); + FShortcuts:=aShortcuts; + FShortcuts.ShortcutList.ScanContainerForShortcutsAndAccelerators; + FInitialConflictsCount:=FShortcuts.ShortcutList.InitialDuplicatesCount; + FShadowMenu:=aShadowMenu; + FResolvedConflictsCount:=0; + Position:=poScreenCenter; + Constraints.MinWidth:=400; + Constraints.MinHeight:=256; + Caption:=Format(lisMenuEditorMenuItemShortcutConflictsInS, + [(GlobalDesignHook.LookupRoot as TComponent).Name]); + FConflictsGroupBox:=TGroupBox.Create(Self); + with FConflictsGroupBox do begin + Caption:=Format(lisMenuEditorConflictsFoundInitiallyD, + [FShortcuts.ShortcutList.InitialDuplicatesCount]); + Align:=alTop; + Top:=0; + BorderSpacing.Around:=Margin; + BorderSpacing.Top:=Margin; + Parent:=Self; + end; + + FResolvedConflictsCountLabel:=TLabel.Create(Self); + with FResolvedConflictsCountLabel do begin + BorderSpacing.Around:=Margin; + Align:=alTop; + Top:=1; + Name:='ResolvedConflictsCountLabel'; + Caption:=Name; + Parent:=FConflictsGroupBox; + end; + + FRemainingConflictsCountLabel:=TLabel.Create(Self); + with FRemainingConflictsCountLabel do begin + BorderSpacing.Around:=Margin; + Align:=alTop; + Top:=2; + Name:='RemainingConflictsCountLabel'; + Caption:=Name; + Parent:=FConflictsGroupBox; + end; + + FConflictsListBox:=TListBox.Create(Self); + with FConflictsListBox do begin + Color:=clBtnFace; + Align:=alTop; + Top:=3; + BorderSpacing.Around:=Margin; + Height:=100; + Name:='ConflictsListBox'; + OnSelectionChange:=@ConflictsBoxSelectionChange; + Parent:=FConflictsGroupBox; + end; + + FCurrentEdit:=TEdit.Create(Self); + with FCurrentEdit do begin + Align:=alTop; + Top:=4; + BorderSpacing.Around:=Margin; + ReadOnly:=True; + Name:='CurrentEdit'; + Text:=Name; + Parent:=FConflictsGroupBox; + end; + + FConflictsGroupBox.AutoSize:=True; + + FButtonPanel:=TButtonPanel.Create(Self); + with FButtonPanel do begin + Align:=alTop; + Top:=1; + BorderSpacing.Right:=Margin; + ShowBevel:=False; + ShowButtons:=[pbOK, pbCancel]; + ShowGlyphs:=[pbClose]; + OKButton.Enabled:=False; + OKButton.ModalResult:=mrNone; + OKButton.Caption:=lisMenuEditorResolveSelectedConflict; + OKButton.OnClick:=@OKButtonClick; + Parent:=Self; + end; + + InitialPopulateListBox; + AutoSize:=True; +end; + +destructor TResolveConflictsDlg.Destroy; +begin + inherited Destroy; +end; + +procedure TResolveConflictsDlg.ConflictsBoxSelectionChange(Sender: TObject; User: boolean); +begin + if (FConflictsListBox.ItemIndex < 0) then + Exit; + FSelectedDuplicate:=TSCInfo(FConflictsListBox.Items.Objects[FConflictsListBox.ItemIndex]); + Assert(FSelectedDuplicate<>nil,'TResolveConflictsDlg.ConflictsBoxSelectionChange: FSelectedDuplicate is nil'); + FSelectedUnique:=FShortcuts.ShortcutList.FindUniqueInfoForShortcut(FSelectedDuplicate.Shortcut); + Assert(FSelectedDuplicate<>nil,'TResolveConflictsDlg.ConflictsBoxSelectionChange: FSelectedDuplicate is nil'); + Assert(FSelectedUnique<>nil,'TResolveConflictsDlg.ConflictsBoxSelectionChange: FSelectedUnique is nil'); + if (FSelectedDuplicate.Kind in MenuItem_Kinds) then + FSelectedInfo:=FSelectedDuplicate + else if (FSelectedUnique.Kind in MenuItem_Kinds) then + FSelectedInfo:=FSelectedUnique + else FSelectedInfo:=FSelectedDuplicate; + FCurrentEdit.Text:=Format(lisMenuEditorEditingSdotS, + [FSelectedInfo.ComponentName, KindToPropertyName(FSelectedInfo.Kind)]); + FButtonPanel.OKButton.Enabled:=True; +end; + +procedure TResolveConflictsDlg.CreateListboxItems; +var + sUnique: string; + sDup: string; + infUnique: TSCInfo; + p: pointer; + infDup: TSCInfo absolute p; +begin + FConflictsListBox.OnSelectionChange:=nil; + FConflictsListBox.Items.Clear; + for p in FShortcuts.ShortcutList.InitialDuplicates do begin + sDup:=Format(lisMenuEditorSInS, [ShortCutToText(infDup.Shortcut), + infDup.ComponentName]); + infUnique:=FShortcuts.ShortcutList.FindUniqueInfoForShortcut(infDup.Shortcut); + Assert(infUnique<>nil,'TResolveConflictsDlg.PopulateListBox: missing unique shortcut'); + sUnique:=Format(lisMenuEditorSInS, [ShortCutToText(infUnique.Shortcut), + infUnique.ComponentName]); + FConflictsListBox.Items.AddObject(Format(lisMenuEditorSConflictsWithS,[sDup,sUnique]), + infDup); + end; + FConflictsListBox.OnSelectionChange:=@ConflictsBoxSelectionChange; +end; + +procedure TResolveConflictsDlg.OKButtonClick(Sender: TObject); +var + newShortcut: TShortCut; + newCaption: string; + si: TShadowItemBase = nil; + + procedure AddSecondaryShortcut; + var + scList: TShortCutList; + begin + scList:=TShortCutList.Create; + try + scList.Add(ShortCutToText(newShortcut)); + TAction(FSelectedInfo.Component).SecondaryShortCuts.Assign(scList); + finally + scList.Free; + end; + end; + +begin + Assert(FSelectedInfo<>nil,'TShortcutScanDlg.ResolveConflictClick: FSelectedInfo is nil'); + if NewShortcutOrCaptionIsValidDlg(FSelectedInfo, newShortcut, newCaption) then + begin + case FSelectedInfo.Kind of + scMenuItemAccel: FSelectedInfo.MenuItem.Caption:=newCaption; + scMenuItemSC: FSelectedInfo.MenuItem.ShortCut:=newShortcut; + scMenuItemKey2: FSelectedInfo.MenuItem.ShortCutKey2:=newShortcut; + scActionAccel: TAction(FSelectedInfo.Component).Caption:=newCaption; + scActionSC: TAction(FSelectedInfo.Component).ShortCut:=newShortcut; + scActionSecondary: AddSecondaryShortcut; + scOtherCompAccel: TControl(FSelectedInfo.Component).Caption:=newCaption; + end; + if (FSelectedInfo.Kind in MenuItem_Kinds) then begin + FShadowMenu.EditorDesigner.PropertyEditorHook.RefreshPropertyValues; + FShadowMenu.EditorDesigner.Modified; + si:=FShadowMenu.GetShadowForMenuItem(FSelectedInfo.MenuItem); + if (si <> nil) then begin + FShadowMenu.UpdateBoxLocationsAndSizes; + si.Repaint; + end; + end + else case FSelectedInfo.Kind of + scActionAccel, scActionSC, scActionSecondary: begin + GlobalDesignHook.RefreshPropertyValues; + GlobalDesignHook.Modified(TAction(FSelectedInfo.Component)); + end; + scOtherCompAccel: begin + GlobalDesignHook.RefreshPropertyValues; + GlobalDesignHook.Modified(TControl(FSelectedInfo.Component)); + end; + end; + + RePopulateListBox; + end; +end; + +procedure TResolveConflictsDlg.InitialPopulateListBox; +begin + if (FShortcuts.ShortcutList.InitialDuplicatesCount > 0) then begin + FResolvedConflictsCount:=0; + FResolvedConflictsCountLabel.Caption:=Format( + lisMenuEditorResolvedConflictsS, [IntToStr(FResolvedConflictsCount)]); + CreateListboxItems; + FRemainingConflictsCountLabel.Caption:=Format( + lisMenuEditorRemainingConflictsS, [IntToStr(FConflictsListBox.Count)]); + FConflictsListBox.ItemIndex:=0; + end + else begin + FButtonPanel.OKButton.Enabled:=False; + FSelectedInfo:=nil; + FConflictsListBox.OnSelectionChange:=nil; + FConflictsListBox.Items.Add(lisMenuEditorNoShortcutConflicts); + FCurrentEdit.Text:=lisMenuEditorNoShortcutConflicts; + FResolvedConflictsCountLabel.Caption:=Format(lisMenuEditorResolvedConflictsS,['0']); + FRemainingConflictsCountLabel.Caption:=Format(lisMenuEditorRemainingConflictsS,['0']); + end; +end; + +procedure TResolveConflictsDlg.RePopulateListBox; +begin + FConflictsListBox.OnSelectionChange:=nil; + FConflictsListBox.Items.Clear; + FConflictsListBox.ItemIndex:= -1; + FButtonPanel.OKButton.Enabled:=False; + FShortcuts.ShortcutList.ScanContainerForShortcutsAndAccelerators; + if (FShortcuts.ShortcutList.InitialDuplicatesCount > 0) then begin + CreateListboxItems; + UpdateStatistics; + FConflictsListBox.ItemIndex:=0; + FConflictsListBox.OnSelectionChange:=@ConflictsBoxSelectionChange; + end + else begin + FButtonPanel.OKButton.Enabled:=False; + FSelectedInfo:=nil; + FConflictsListBox.OnSelectionChange:=nil; + FRemainingConflictsCountLabel.Caption:=Format(lisMenuEditorRemainingConflictsS,['0']); + FResolvedConflictsCountLabel.Caption:=Format( + lisMenuEditorResolvedConflictsS, [FInitialConflictsCount]); + FConflictsListBox.Items.Add(lisMenuEditorNoShortcutConflicts); + FCurrentEdit.Text:=lisMenuEditorConflictResolutionComplete; + FButtonPanel.CancelButton.Caption:=lisBtnClose; + end; +end; + +procedure TResolveConflictsDlg.UpdateStatistics; +begin + FResolvedConflictsCount:=FInitialConflictsCount - FConflictsListBox.Count; + FResolvedConflictsCountLabel.Caption:=Format(lisMenuEditorResolvedConflictsS, + [IntToStr(FResolvedConflictsCount)]); + FRemainingConflictsCountLabel.Caption:=Format( + lisMenuEditorRemainingConflictsS, [IntToStr(FInitialConflictsCount-FResolvedConflictsCount)]); +end; + +end. + diff --git a/designer/menushortcutdisplay.pas b/designer/menushortcutdisplay.pas new file mode 100644 index 0000000000..2f00bb69fb --- /dev/null +++ b/designer/menushortcutdisplay.pas @@ -0,0 +1,490 @@ +unit MenuShortcutDisplay; + +{$mode objfpc}{$H+} + +interface + +uses + // FCL + LCL + Classes, SysUtils, + ButtonPanel, Controls, StdCtrls, Menus, Forms, LCLIntf, LCLProc, + // LazUtils + LazUTF8, + // IdeIntf + FormEditingIntf, PropEdits, + // IDE + LazarusIDEStrConsts, MenuDesignerBase, MenuShortcuts; + +type + + { TShortcutDisplayDlg } + + TShortcutDisplayDlg = class(TForm) + strict private + FLastSortIndex: integer; + FMenu: TMenu; + FscList: TStringList; + FSingleMenuOnly: boolean; + FShortcutsOnly: boolean; + FShortcuts: TMenuShortcuts; + FShadowMenu: TShadowMenuBase; + // GUI + FBPanel: TButtonPanel; + FDualDisplay: TDualDisplay; + FGBDisplay: TGroupBox; + FLabel: TLabel; + procedure AddSCitemToListRecursive(anItem: TMenuItem); + procedure DisplayAllDlgClick(isHeader: boolean; index: integer); + procedure DisplaySingleMenuClick(isHeader: boolean; index: integer); + procedure UpdateContents(singleMenuOnly: boolean=False); + procedure UpdateFromMenu(anIndex: integer= -1); + public + constructor CreateWithShortcutsOnly(aShortcuts: TMenuShortcuts; shortcutsOnly: boolean; + aShadowMenu: TShadowMenuBase; aMenu: TMenu=nil); + destructor Destroy; override; + end; + + { TEditCaptionDialog } + + TEditCaptionDialog = class(TForm) + strict private + FButtonPanel: TButtonPanel; + FEdit: TEdit; + FGBEdit: TGroupBox; + FMenuItem: TMenuItem; + FNewShortcut: TShortCut; + FOldShortcut: TShortCut; + procedure EditOnChange(Sender: TObject); + procedure OKButtonClick(Sender: TObject); + public + constructor CreateWithMenuItem(AOwner: TComponent; aMI: TMenuItem; aSC: TShortCut); + property NewShortcut: TShortCut read FNewShortcut; + end; + +function ListShortCutDlg(aShortcuts: TMenuShortcuts; shortcutsOnly: boolean; + aShadowMenu: TShadowMenuBase; aMenu: TMenu): TModalResult; +function EditCaptionDlg(aMI: TMenuItem; var aShortcut: TShortCut): boolean; + +implementation + +function ListShortCutDlg(aShortcuts: TMenuShortcuts; shortcutsOnly: boolean; + aShadowMenu: TShadowMenuBase; aMenu: TMenu): TModalResult; +var + dlg: TShortcutDisplayDlg; +begin + dlg:=TShortcutDisplayDlg.CreateWithShortcutsOnly(aShortcuts, shortcutsOnly, + aShadowMenu, aMenu); + try + Result:=dlg.ShowModal; + finally + FreeAndNil(dlg); + end; +end; + +function EditCaptionDlg(aMI: TMenuItem; var aShortcut: TShortCut): boolean; +var + dlg: TEditCaptionDialog; +begin + dlg := TEditCaptionDialog.CreateWithMenuItem(nil, aMI, aShortcut); + try + Result := dlg.ShowModal = mrOK; + if Result then + aShortcut := dlg.NewShortcut; + finally + dlg.Free; + end; +end; + +{ TShortcutDisplayDlg } + +constructor TShortcutDisplayDlg.CreateWithShortcutsOnly(aShortcuts: TMenuShortcuts; + shortcutsOnly: boolean; aShadowMenu: TShadowMenuBase; aMenu: TMenu); +var + s: string; + lurStr: string; +begin + inherited CreateNew(nil); + FShortcutsOnly:=shortcutsOnly; + FShortcuts:=aShortcuts; + FMenu:=aMenu; + FShadowMenu:=aShadowMenu; + FSingleMenuOnly:=(FMenu <> nil); + FLastSortIndex:= -1; + if FSingleMenuOnly then + Caption:=Format(lisMenuEditorShortcutsUsedInS, [FMenu.Name]) + else begin + if shortcutsOnly then + s:=lisMenuEditorSShortcuts + else + s:=lisMenuEditorSShortcutsAndAcceleratorKeys; + lurStr:=TComponent(GlobalDesignHook.LookupRoot).Name; + Caption:=Format(s, [lurStr]); + end; + + BorderStyle:=bsDialog; + Position:=poScreenCenter; + Constraints.MinWidth:=460; + Constraints.MaxHeight:=460; + + FBPanel:=TButtonPanel.Create(Self); + with FBPanel do begin + ShowBevel:=False; + BorderSpacing.Around:=Spacing; + BorderSpacing.Right:=Spacing; + Constraints.MinHeight:=42; + ShowButtons:=[pbClose]; + CloseButton.Constraints.MaxHeight:=30; + Parent:=Self; + end; + + FLabel:=TLabel.Create(Self); + FLabel.WordWrap:=True; + FLabel.Constraints.MaxWidth:=340; + FLabel.BorderSpacing.Left:=Margin; + FLabel.AutoSize:=True; + FLabel.Parent:=FBPanel; + + FGBDisplay:=TGroupBox.Create(Self); + with FGBDisplay do begin + Align:=alClient; + BorderSpacing.Around:=Margin*2; + AutoSize:=True; + Parent:=Self; + end; + + FDualDisplay:=TDualDisplay.Create(Self); + with FDualDisplay do begin + Align:=alClient; + BorderSpacing.Around:=Margin; + Parent:=FGBDisplay; + if FSingleMenuOnly then begin + OnDisplayClick:=@DisplaySingleMenuClick; + AddHeader(lisMenuEditorShortcutSourceProperty); + Caption:=lisMenuEditorShortcuts; + end + else begin + OnDisplayClick:=@DisplayAllDlgClick; + if FShortcutsOnly then begin + AddHeader(lisMenuEditorShortcutSourceProperty); + Caption:=Format(lisMenuEditorSShortcuts, [lurStr]); + end + else begin + AddHeader(lisMenuEditorShortcutSourceProperty); + Caption:=Format(lisMenuEditorSShortcutsAndAcceleratorKeys, [lurStr]); + end; + end; + end; + UpdateContents(FSingleMenuOnly); + FLabel.Caption:=lisMenuEditorClickANonGreyedItemToEditItsShortcut; + AutoSize:=True; +end; + +destructor TShortcutDisplayDlg.Destroy; +begin + FreeAndNil(FscList); + inherited Destroy; +end; + +procedure TShortcutDisplayDlg.DisplaySingleMenuClick(isHeader: boolean; index: integer); +var + mi: TMenuItem; + sc: TShortCut; + result: boolean; + si: TShadowItemBase; + info: TSCInfo; + isMainSC: boolean; +begin + case isHeader of + + True: begin // header click + if (FLastSortIndex = index) or (FscList.Count = 0) then + Exit; + FLastSortIndex:=index; + UpdateFromMenu(index); + end; + + False: begin // contents click + info:=TSCInfo(FscList.Objects[index]); + mi:=info.MenuItem; + if (mi <> nil) then + begin + sc:=info.Shortcut; + isMainSC:=(info.Kind = scMenuItemSC); + result:=AddNewOrEditShortcutDlg(mi, isMainSC, sc); + if result then + begin + if isMainSC then + mi.ShortCut:=sc + else + mi.ShortCutKey2:=sc; + si:=FShadowMenu.GetShadowForMenuItem(mi); + if (si <> nil) then begin + FShadowMenu.UpdateBoxLocationsAndSizes; + si.Repaint; + end; + FShortcuts.UpdateShortcutList(False); + UpdateFromMenu; + GlobalDesignHook.RefreshPropertyValues; + GlobalDesignHook.Modified(mi); + FShadowMenu.RefreshFakes; + end; + end; + end; + + end; // case +end; + +procedure TShortcutDisplayDlg.DisplayAllDlgClick(isHeader: boolean; index: integer); +var + i: integer; + dt: TDisplayType; + inf: TSCInfo; + mi: TMenuItem; + sc: TShortCut; + isMainSC, isCaptionSC, result: boolean; + si: TShadowItemBase; +begin + case isHeader of + True: begin + if (FLastSortIndex = index) or (FDualDisplay.ContentsCount = 0) then + Exit; + FLastSortIndex:=index; + FDualDisplay.ClearContents; + case index of + 0: FShortcuts.ShortcutList.ScanList.Sort; + 1: FShortcuts.ShortcutList.SortByComponentPropertyName; + end; + for i:=0 to FShortcuts.ShortcutList.ScanList.Count-1 do + begin + inf:=TSCInfo(FShortcuts.ShortcutList.ScanList.Objects[i]); + if (inf.Kind in MenuItem_Kinds) then + dt:=dtBlack + else + dt:=dtGreyed; + FDualDisplay.AddLine(FShortcuts.ShortcutList.ScanList[i] + ',' + + inf.Component.Name+ '.' + KindToPropertyName(inf.Kind), dt); + end; + end; + False: begin + inf:=TSCInfo(FShortcuts.ShortcutList.ScanList.Objects[index]); + mi:=inf.MenuItem; + if (mi <> nil) then + begin + isMainSC:=(inf.Kind in ShortcutOnly_Kinds); + isCaptionSC:=(inf.Kind in Accelerator_Kinds); + sc:=inf.Shortcut; + if isCaptionSC then + result:=EditCaptionDlg(mi, sc) + else result:=AddNewOrEditShortcutDlg(mi, isMainSC, sc); + if result then + begin + if not isCaptionSC and isMainSC then + mi.ShortCut:=sc + else if not isCaptionSC then + mi.ShortCutKey2:=sc; + si:=FShadowMenu.GetShadowForMenuItem(mi); + if (si <> nil) then + begin + FShadowMenu.UpdateBoxLocationsAndSizes; + si.Repaint; + end; + FShortcuts.UpdateShortcutList(True); + UpdateContents; + GlobalDesignHook.RefreshPropertyValues; + GlobalDesignHook.Modified(mi); + FShadowMenu.RefreshFakes; + end; + end; + end; + end; // case +end; + +procedure TShortcutDisplayDlg.UpdateContents(singleMenuOnly: boolean); +var + i: integer; + dt: TDisplayType; + kind: TSCKind; + inf: TSCInfo; +begin + FDualDisplay.ClearContents; + if singleMenuOnly then + UpdateFromMenu + else begin + FShortcuts.UpdateShortcutList(not FShortcutsOnly); + if (FShortcuts.ShortcutList.ScanList.Count = 0) then + begin + FDualDisplay.AddLine(lisMenuEditorNoneNone, dtGreyed); + if FShortcutsOnly then + FGBDisplay.Caption:=lisMenuEditorShortcuts + else + FGBDisplay.Caption:=lisMenuEditorShortcutsAndAcceleratorKeys; + end + else + begin + if FShortcutsOnly then + FGBDisplay.Caption:=Format(lisMenuEditorShortcutsD, + [FShortcuts.ShortcutList.ShortcutsInContainerCount]) + else + FGBDisplay.Caption:=Format(lisMenuEditorShortcutsDAndAcceleratorKeysD, + [FShortcuts.ShortcutList.ShortcutsInContainerCount, + FShortcuts.ShortcutList.AcceleratorsInContainerCount]); + + FDualDisplay.BeginUpdate; + for i:=0 to FShortcuts.ShortcutList.ScanList.Count-1 do + begin + inf:=TSCInfo(FShortcuts.ShortcutList.ScanList.Objects[i]); + kind:=inf.Kind; + if (kind in MenuItem_Kinds) then + dt:=dtBlack + else + dt:=dtGreyed; + FDualDisplay.AddLine(FShortcuts.ShortcutList.ScanList[i] + ',' + + inf.Component.Name + '.' + KindToPropertyName(inf.Kind), dt); + end; + FDualDisplay.EndUpdate; + end; + end; +end; + +procedure TShortcutDisplayDlg.AddSCitemToListRecursive(anItem: TMenuItem); +var + inf: TSCInfo; + i: integer; +begin + if (anItem.ShortCut <> 0) then begin + inf:=TSCInfo.CreateWithParams(anItem, scMenuItemSC, anItem.ShortCut); + FscList.AddObject(ShortCutToText(anItem.ShortCut), TObject(inf)); + end; + if (anItem.ShortCutKey2 <> 0) and (anItem.ShortCutKey2 <> anItem.ShortCut) then begin + inf:=TSCInfo.CreateWithParams(anItem, scMenuItemKey2, anItem.ShortCutKey2); + FscList.AddObject(ShortCutToText(anItem.ShortCutKey2), TObject(inf)); + end; + for i:=0 to anItem.Count-1 do + AddSCitemToListRecursive(anItem[i]); +end; + +procedure TShortcutDisplayDlg.UpdateFromMenu(anIndex: integer); +var + i: integer; + inf: TSCInfo; +begin + Assert(FMenu<>nil,'TShortcutDisplayDlg.UpdateFromMenu: FMenu is nil'); + FreeAndNil(FscList); + FscList:=TStringList.Create; + FscList.CaseSensitive:=False; + FDualDisplay.ClearContents; + for i:=0 to FMenu.Items.Count-1 do + AddSCitemToListRecursive(FMenu.Items[i]); + if (FscList.Count = 0) then + begin + FDualDisplay.AddLine(lisMenuEditorNoneNone, dtGreyed); + FGBDisplay.Caption:=lisMenuEditorShortcuts; + end + else + begin + FGBDisplay.Caption := Format(lisMenuEditorShortcutsUsedInSD, + [FMenu.Name, FscList.Count]); + case anIndex of + -1: ; // unsorted + 0: FscList.Sort; + 1: FscList.CustomSort(@SortByComponentPropertyName); + end; + FDualDisplay.BeginUpdate; + for i:=0 to FscList.Count-1 do + begin + inf:=TSCInfo(FscList.Objects[i]); + FDualDisplay.AddLine(FscList[i] + ',' + + inf.Component.Name + '.' + KindToPropertyName(inf.Kind), dtBlack); + end; + FDualDisplay.EndUpdate; + FDualDisplay.InvalidateContents; + end; +end; + +{ TEditCaptionDialog } + +constructor TEditCaptionDialog.CreateWithMenuItem(AOwner: TComponent; + aMI: TMenuItem; aSC: TShortCut); +var + key: word; + sstate: TShiftState; + p: integer; + ch: Char; +begin + inherited CreateNew(AOwner); + FMenuItem:=aMI; + FOldShortcut:=aSC; + ShortCutToKey(aSC, key, sstate); + Position:=poScreenCenter; + BorderStyle:=bsDialog; + Caption:=Format(lisMenuEditorEditingCaptionOfS, [FMenuItem.Name]); + + FButtonPanel:=TButtonPanel.Create(Self); + with FButtonPanel do + begin + ShowButtons:=[pbOK, pbCancel]; + OKButton.Name:='OKButton'; + OKButton.DefaultCaption:=True; + OKButton.Enabled:=False; + OKButton.OnClick:=@OKButtonClick; + CancelButton.Name:='CancelButton'; + CancelButton.DefaultCaption:=True; + ShowBevel:=False; + Parent:=Self; + end; + + FGBEdit:=TGroupBox.Create(Self); + with FGBEdit do + begin + BorderSpacing.Around:=Margin; + p:=UTF8Pos('&', aMI.Caption); + if (p > 0) and (p < UTF8Length(aMI.Caption)) then + ch:=aMI.Caption[Succ(p)] // gets correct case of key + else + ch:=Chr(Ord(key)); // fallback + Caption:=Format(lisMenuEditorAcceleratorKeySNeedsChanging, [ch]); + Align:=alClient; + Parent:=Self; + end; + + FEdit:=TEdit.Create(Self); + with FEdit do + begin; + BorderSpacing.Around:=Margin; + Text:=FMenuItem.Caption; + Align:=alClient; + OnChange:=@EditOnChange; + Parent:=FGBEdit; + end; + + AutoSize:=True; +end; + +procedure TEditCaptionDialog.EditOnChange(Sender: TObject); +var + hasAccel: boolean; + sc: TShortCut; +begin + if (FEdit.Text = '') then + begin + FEdit.Text:=lisMenuEditorCaptionShouldNotBeBlank; + FEdit.SetFocus; + end + else + begin + hasAccel:=HasAccelerator(FEdit.Text, sc); + if (not hasAccel) or (hasAccel and (sc <> FOldShortcut)) then + begin + FNewShortcut:=sc; + FButtonPanel.OKButton.Enabled:=True; + end; + end; +end; + +procedure TEditCaptionDialog.OKButtonClick(Sender: TObject); +begin + FMenuItem.Caption:=FEdit.Text; +end; + +end. +