mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-21 06:19:44 +02:00
Revert the earlier commit for Menu editor. Wrong code was removed.
This commit is contained in:
parent
af75c766b1
commit
e8bf5ae849
@ -38,7 +38,7 @@ uses
|
|||||||
IdeIntfStrConsts, PropEdits,
|
IdeIntfStrConsts, PropEdits,
|
||||||
// IDE
|
// IDE
|
||||||
LazarusIDEStrConsts, LazIDEIntf, MenuDesignerBase, MenuEditorForm, MenuShortcutDisplay,
|
LazarusIDEStrConsts, LazIDEIntf, MenuDesignerBase, MenuEditorForm, MenuShortcutDisplay,
|
||||||
MenuTemplates;
|
MenuTemplates, MenuResolveConflicts;
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
@ -168,7 +168,7 @@ type
|
|||||||
popAddImgListIcon, popItemAddOnClick,
|
popAddImgListIcon, popItemAddOnClick,
|
||||||
popItemOISep,
|
popItemOISep,
|
||||||
popShortcuts_,
|
popShortcuts_,
|
||||||
popListShortcuts, popListShortcutsAccelerators,
|
popListShortcuts, popListShortcutsAccelerators, popResolveShortcutConflicts,
|
||||||
popTemplates_,
|
popTemplates_,
|
||||||
popSaveAsTemplate, popAddFromTemplate, popDeleteTemplate);{%endregion}
|
popSaveAsTemplate, popAddFromTemplate, popDeleteTemplate);{%endregion}
|
||||||
|
|
||||||
@ -221,6 +221,7 @@ type
|
|||||||
procedure MoveItemAfter(Sender: TObject);
|
procedure MoveItemAfter(Sender: TObject);
|
||||||
procedure MoveItemBefore(Sender: TObject);
|
procedure MoveItemBefore(Sender: TObject);
|
||||||
procedure RemoveAllSeparators(Sender: TObject);
|
procedure RemoveAllSeparators(Sender: TObject);
|
||||||
|
procedure ResolveShortcutConflicts(Sender: TObject);
|
||||||
procedure SaveAsTemplate(Sender: TObject);
|
procedure SaveAsTemplate(Sender: TObject);
|
||||||
private
|
private
|
||||||
FDesigner: TMenuDesigner;
|
FDesigner: TMenuDesigner;
|
||||||
@ -1207,6 +1208,8 @@ begin
|
|||||||
NewPopSub(primaryItem, '', @ListShortcuts);
|
NewPopSub(primaryItem, '', @ListShortcuts);
|
||||||
popListShortcutsAccelerators:
|
popListShortcutsAccelerators:
|
||||||
NewPopSub(primaryItem, '', @ListShortcutsAndAccelerators);
|
NewPopSub(primaryItem, '', @ListShortcutsAndAccelerators);
|
||||||
|
popResolveShortcutConflicts:
|
||||||
|
NewPopSub(primaryItem, lisMenuEditorResolveShortcutConflicts, @ResolveshortcutConflicts);
|
||||||
popTemplates_:
|
popTemplates_:
|
||||||
NewPopPrimary(lisMenuEditorTemplates);
|
NewPopPrimary(lisMenuEditorTemplates);
|
||||||
popSaveAsTemplate:
|
popSaveAsTemplate:
|
||||||
@ -1403,6 +1406,19 @@ begin
|
|||||||
ListShortCutDlg(FDesigner.Shortcuts, False, Self, Nil);
|
ListShortCutDlg(FDesigner.Shortcuts, False, Self, Nil);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TShadowMenu.ResolveShortcutConflicts(Sender: TObject);
|
||||||
|
var
|
||||||
|
dlg: TResolveConflictsDlg;
|
||||||
|
begin
|
||||||
|
dlg:=TResolveConflictsDlg.Create(FDesigner.Shortcuts, Self);
|
||||||
|
try
|
||||||
|
if dlg.ShowModal <> mrCancel then
|
||||||
|
UpdateActionsEnabledness;
|
||||||
|
finally
|
||||||
|
dlg.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TShadowMenu.SaveAsTemplate(Sender: TObject);
|
procedure TShadowMenu.SaveAsTemplate(Sender: TObject);
|
||||||
var
|
var
|
||||||
dlg: TMenuTemplateDialog;
|
dlg: TMenuTemplateDialog;
|
||||||
@ -1627,7 +1643,7 @@ end;
|
|||||||
|
|
||||||
procedure TShadowMenu.UpdateActionsEnabledness;
|
procedure TShadowMenu.UpdateActionsEnabledness;
|
||||||
var
|
var
|
||||||
ac, ac1, ac2: TAction;
|
ac, ac1, ac2, ac3: TAction;
|
||||||
pe: TPopEnum;
|
pe: TPopEnum;
|
||||||
isInBar, isFirst, isSeparator, isLast, prevIsSeparator, nextIsSeparator,
|
isInBar, isFirst, isSeparator, isLast, prevIsSeparator, nextIsSeparator,
|
||||||
levelZero, levelZeroOr1, primarySCEnabled: boolean;
|
levelZero, levelZeroOr1, primarySCEnabled: boolean;
|
||||||
@ -1731,6 +1747,8 @@ begin
|
|||||||
ac.Enabled:=(FDesigner.Shortcuts.ShortcutList.AcceleratorsInContainerCount > 0);
|
ac.Enabled:=(FDesigner.Shortcuts.ShortcutList.AcceleratorsInContainerCount > 0);
|
||||||
ac.Caption:=Format(lisMenuEditorListShortcutsAndAccelerators,[FLookupRoot.Name]);
|
ac.Caption:=Format(lisMenuEditorListShortcutsAndAccelerators,[FLookupRoot.Name]);
|
||||||
end;
|
end;
|
||||||
|
popResolveShortcutConflicts: ac.Enabled:=
|
||||||
|
(FDesigner.Shortcuts.ShortcutList.InitialDuplicates.Count > 0);
|
||||||
popTemplates_: ac.Enabled:=levelZero or FDesigner.TemplatesSaved;
|
popTemplates_: ac.Enabled:=levelZero or FDesigner.TemplatesSaved;
|
||||||
popSaveAsTemplate: ac.Enabled:=levelZeroOr1;
|
popSaveAsTemplate: ac.Enabled:=levelZeroOr1;
|
||||||
popAddFromTemplate: ac.Enabled:=levelZero;
|
popAddFromTemplate: ac.Enabled:=levelZero;
|
||||||
@ -1740,7 +1758,8 @@ begin
|
|||||||
ac:=GetActionForEnum(popShortcuts_);
|
ac:=GetActionForEnum(popShortcuts_);
|
||||||
ac1:=GetActionForEnum(popListShortcuts);
|
ac1:=GetActionForEnum(popListShortcuts);
|
||||||
ac2:=GetActionForEnum(popListShortcutsAccelerators);
|
ac2:=GetActionForEnum(popListShortcutsAccelerators);
|
||||||
ac.Enabled:=ac1.Enabled or ac2.Enabled;
|
ac3:=GetActionForEnum(popResolveShortcutConflicts);
|
||||||
|
ac.Enabled:=ac1.Enabled or ac2.Enabled or ac3.Enabled;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
constructor TShadowMenu.Create(aDesigner: TMenuDesigner; aForm: TForm;
|
constructor TShadowMenu.Create(aDesigner: TMenuDesigner; aForm: TForm;
|
||||||
|
322
designer/menuresolveconflicts.pas
Normal file
322
designer/menuresolveconflicts.pas
Normal file
@ -0,0 +1,322 @@
|
|||||||
|
{***************************************************************************
|
||||||
|
* *
|
||||||
|
* This source is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This code is distributed in the hope that it will be useful, but *
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||||
|
* General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* A copy of the GNU General Public License is available on the World *
|
||||||
|
* Wide Web at <http://www.gnu.org/copyleft/gpl.html>. You can also *
|
||||||
|
* obtain it by writing to the Free Software Foundation, *
|
||||||
|
* Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1335, USA. *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
Author: Howard Page-Clark }
|
||||||
|
|
||||||
|
unit MenuResolveConflicts;
|
||||||
|
|
||||||
|
{$mode objfpc}{$H+}
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
// FCL
|
||||||
|
Classes, SysUtils,
|
||||||
|
// LCL
|
||||||
|
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.InitialDuplicates.Count;
|
||||||
|
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.InitialDuplicates.Count]);
|
||||||
|
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;
|
||||||
|
infDup: TSCInfo;
|
||||||
|
begin
|
||||||
|
FConflictsListBox.OnSelectionChange:=nil;
|
||||||
|
FConflictsListBox.Items.Clear;
|
||||||
|
for infDup 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.InitialDuplicates.Count > 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.InitialDuplicates.Count > 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.
|
||||||
|
|
@ -31,7 +31,7 @@ uses
|
|||||||
// LazUtils
|
// LazUtils
|
||||||
LazUTF8,
|
LazUTF8,
|
||||||
// IdeIntf
|
// IdeIntf
|
||||||
PropEdits,
|
IDEDialogs, PropEdits,
|
||||||
// IDE
|
// IDE
|
||||||
LazarusIDEStrConsts;
|
LazarusIDEStrConsts;
|
||||||
|
|
||||||
@ -141,6 +141,35 @@ type
|
|||||||
property OldShortcut: TShortCut write FOldShortcut;
|
property OldShortcut: TShortCut write FOldShortcut;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
TMenuShortcuts = class;
|
||||||
|
|
||||||
|
{ TEditShortcutCaptionDialog }
|
||||||
|
|
||||||
|
TEditShortcutCaptionDialog = class(TForm)
|
||||||
|
strict private
|
||||||
|
FEditingCaption: boolean;
|
||||||
|
FInfo: TSCInfo;
|
||||||
|
FNewCaption: string;
|
||||||
|
FNewShortcut: TShortCut;
|
||||||
|
FOldCaption: string;
|
||||||
|
// GUI controls
|
||||||
|
FButtonPanel: TButtonPanel;
|
||||||
|
FEdit: TEdit;
|
||||||
|
FGrabBox: TCustomShortCutGrabBox;
|
||||||
|
FGroupBox: TGroupBox;
|
||||||
|
FShortcuts: TMenuShortcuts;
|
||||||
|
procedure CaptionEditChange(Sender: TObject);
|
||||||
|
procedure GrabBoxEnter(Sender: TObject);
|
||||||
|
procedure GrabBoxExit(Sender: TObject);
|
||||||
|
procedure OKButtonOnClick(Sender: TObject);
|
||||||
|
protected
|
||||||
|
procedure Activate; override;
|
||||||
|
public
|
||||||
|
constructor {%H-}CreateNew(aShortcuts: TMenuShortcuts; aSCInfo: TSCInfo);
|
||||||
|
property NewCaption: string read FNewCaption;
|
||||||
|
property NewShortcut: TShortCut read FNewShortcut;
|
||||||
|
end;
|
||||||
|
|
||||||
TDualDisplay = class;
|
TDualDisplay = class;
|
||||||
|
|
||||||
TContents = class(TCustomControl)
|
TContents = class(TCustomControl)
|
||||||
@ -243,6 +272,9 @@ function AmpersandStripped(const aText: string): string;
|
|||||||
function AddNewOrEditShortcutDlg(aMI: TMenuItem; isMainSCut: boolean;
|
function AddNewOrEditShortcutDlg(aMI: TMenuItem; isMainSCut: boolean;
|
||||||
var aShortcut: TShortCut): boolean;
|
var aShortcut: TShortCut): boolean;
|
||||||
function HasAccelerator(const aText: string; out aShortcut: TShortCut): boolean;
|
function HasAccelerator(const aText: string; out aShortcut: TShortCut): boolean;
|
||||||
|
function NewShortcutOrCaptionIsValidDlg(aConflictingInfo: TSCInfo;
|
||||||
|
out aNewShortcut: TShortCut;
|
||||||
|
out aNewCaption: string): boolean;
|
||||||
function KindToPropertyName(aKind: TSCKind): string;
|
function KindToPropertyName(aKind: TSCKind): string;
|
||||||
function SplitCommaText(const aCommaText: string; out firstBit: string): string;
|
function SplitCommaText(const aCommaText: string; out firstBit: string): string;
|
||||||
function SortByComponentPropertyName(List: TStringList; Index1, Index2: Integer): Integer;
|
function SortByComponentPropertyName(List: TStringList; Index1, Index2: Integer): Integer;
|
||||||
@ -414,6 +446,41 @@ begin
|
|||||||
aSCList.ScanList.Count,'DoShortcutAccelScanCount: internal counting error');
|
aSCList.ScanList.Count,'DoShortcutAccelScanCount: internal counting error');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function NewShortcutOrCaptionIsValidDlg(aConflictingInfo: TSCInfo; out
|
||||||
|
aNewShortcut: TShortCut; out aNewCaption: string): boolean;
|
||||||
|
var
|
||||||
|
dlg: TEditShortcutCaptionDialog;
|
||||||
|
ok: boolean;
|
||||||
|
sc: TShortCut;
|
||||||
|
begin
|
||||||
|
dlg:=TEditShortcutCaptionDialog.CreateNew(nil, aConflictingInfo);
|
||||||
|
try
|
||||||
|
Result:=(dlg.ShowModal = mrOK);
|
||||||
|
case (aConflictingInfo.Kind in Accelerator_Kinds) of
|
||||||
|
True: begin
|
||||||
|
if HasAccelerator(dlg.NewCaption, sc) then
|
||||||
|
ok:=(sc <> aConflictingInfo.Shortcut)
|
||||||
|
else
|
||||||
|
ok:=True;
|
||||||
|
end;
|
||||||
|
False: ok:=(aConflictingInfo.Shortcut <> dlg.NewShortcut);
|
||||||
|
end;
|
||||||
|
Result:=Result and ok;
|
||||||
|
if Result then
|
||||||
|
begin
|
||||||
|
aNewShortcut:=dlg.NewShortcut;
|
||||||
|
aNewCaption:=dlg.NewCaption;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
aNewShortcut:=0;
|
||||||
|
aNewCaption:='';
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
FreeAndNil(dlg);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
function KindToPropertyName(aKind: TSCKind): string;
|
function KindToPropertyName(aKind: TSCKind): string;
|
||||||
begin
|
begin
|
||||||
Result:='';
|
Result:='';
|
||||||
@ -730,6 +797,196 @@ begin
|
|||||||
FShortCutGrabBox.ShiftState:=[];
|
FShortCutGrabBox.ShiftState:=[];
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TEditShortcutCaptionDialog }
|
||||||
|
|
||||||
|
constructor TEditShortcutCaptionDialog.CreateNew(aShortcuts: TMenuShortcuts;
|
||||||
|
aSCInfo: TSCInfo);
|
||||||
|
var
|
||||||
|
s: string;
|
||||||
|
sse: TShiftStateEnum;
|
||||||
|
i: integer;
|
||||||
|
begin
|
||||||
|
FShortcuts:=aShortcuts;
|
||||||
|
FInfo:=aSCInfo;
|
||||||
|
Assert(aSCInfo<>nil,'TEditShortcutCaptionDialog.CreateNew: aSCInfo is nil');
|
||||||
|
Assert(aSCInfo.Kind<>scUnknown,'TEditShortcutCaptionDialog.CreateNew: aSCInfo is unknown type');
|
||||||
|
Assert(FShortcuts.ShortcutList.UniqueCount>0,'TEditShortcutCaptionDialog.CreateNew: unique list is empty');
|
||||||
|
inherited CreateNew(Nil);
|
||||||
|
FEditingCaption:=(FInfo.Kind in Accelerator_Kinds);
|
||||||
|
Position:=poScreenCenter;
|
||||||
|
BorderStyle:=bsDialog;
|
||||||
|
Constraints.MinWidth:=300;
|
||||||
|
|
||||||
|
FGroupBox:=TGroupBox.Create(Self);
|
||||||
|
if FEditingCaption then
|
||||||
|
begin
|
||||||
|
Caption:=Format(lisMenuEditorChangeConflictingAcceleratorS,
|
||||||
|
[ShortCutToText(FInfo.Shortcut)]);
|
||||||
|
if (FInfo.Kind = scMenuItemAccel) then
|
||||||
|
FOldCaption:=FInfo.MenuItem.Caption;
|
||||||
|
FEdit:=TEdit.Create(Self);
|
||||||
|
with FEdit do
|
||||||
|
begin
|
||||||
|
Align:=alClient;
|
||||||
|
BorderSpacing.Around:=Margin;
|
||||||
|
AutoSize:=True;
|
||||||
|
Text:=FOldCaption;
|
||||||
|
OnChange:=@CaptionEditChange;
|
||||||
|
Parent:=FGroupBox;
|
||||||
|
end;
|
||||||
|
s:=lisMenuEditorCaption;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
Caption:=Format(lisMenuEditorChangeShortcutConflictS,
|
||||||
|
[ShortCutToText(FInfo.Shortcut)]);
|
||||||
|
s:=KindToPropertyName(FInfo.Kind);
|
||||||
|
// don't set values to old shortcut since they need to be changed anyhow
|
||||||
|
FGrabBox:=TCustomShortCutGrabBox.Create(Self);
|
||||||
|
with FGrabBox do
|
||||||
|
begin
|
||||||
|
Align:=alClient;
|
||||||
|
BorderSpacing.Around:=Margin;
|
||||||
|
AutoSize:=True;
|
||||||
|
GrabButton.Caption:=lisMenuEditorGrabKey;
|
||||||
|
// this rather restricted list covers most of the common values needed
|
||||||
|
with KeyComboBox.Items do
|
||||||
|
begin
|
||||||
|
Clear;
|
||||||
|
BeginUpdate;
|
||||||
|
for i:=Low(ShortCutKeys) to High(ShortCutKeys) do
|
||||||
|
Add(ShortCutToText(ShortCutKeys[i]));
|
||||||
|
EndUpdate;
|
||||||
|
end;
|
||||||
|
GrabButton.OnEnter:=@GrabBoxEnter; // we can't alter any grabBox OnClick event
|
||||||
|
KeyComboBox.OnEnter:=@GrabBoxEnter;
|
||||||
|
for sse in ShiftButtons do
|
||||||
|
ShiftCheckBox[sse].OnEnter:=@GrabBoxEnter;
|
||||||
|
OnExit:=@GrabBoxExit;
|
||||||
|
FGrabBox.Caption:=Format(lisMenuEditorChangeShortcutCaptionForComponent,
|
||||||
|
[s, FInfo.Component.Name]);
|
||||||
|
Parent:=FGroupBox;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
FGroupBox.Caption:=Format(lisMenuEditorEditingSForS,[s, FInfo.Component.Name]);
|
||||||
|
FGroupBox.Align:=alTop;
|
||||||
|
FGroupBox.BorderSpacing.Around:=Margin;
|
||||||
|
FGroupBox.AutoSize:=True;
|
||||||
|
FGroupBox.Parent:=Self;
|
||||||
|
|
||||||
|
FButtonPanel:=TButtonPanel.Create(Self);
|
||||||
|
with FButtonPanel do
|
||||||
|
begin
|
||||||
|
ShowButtons:=[pbOK, pbCancel];
|
||||||
|
Top:=1;
|
||||||
|
Align:=alTop;
|
||||||
|
OKButton.OnClick:=@OKButtonOnClick;
|
||||||
|
OKButton.ModalResult:=mrNone;
|
||||||
|
OKButton.Enabled:=False;
|
||||||
|
ShowBevel:=False;
|
||||||
|
Parent:=Self;
|
||||||
|
end;
|
||||||
|
AutoSize:=True;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TEditShortcutCaptionDialog.CaptionEditChange(Sender: TObject);
|
||||||
|
var
|
||||||
|
newSC: TShortCut;
|
||||||
|
hasAccel: boolean;
|
||||||
|
ed: TEdit absolute Sender;
|
||||||
|
inf: TSCInfo;
|
||||||
|
begin
|
||||||
|
if not (Sender is TEdit) then
|
||||||
|
Exit;
|
||||||
|
if HasAccelerator(ed.Text, newSC) then
|
||||||
|
begin
|
||||||
|
if FShortcuts.ShortcutList.UniqueListContainsShortcut(newSC) then
|
||||||
|
begin
|
||||||
|
inf:=FShortcuts.ShortcutList.FindUniqueInfoForShortcut(newSC);
|
||||||
|
IDEMessageDialogAb(lisMenuEditorFurtherShortcutConflict,
|
||||||
|
Format(lisMenuEditorSIsAlreadyInUse,
|
||||||
|
[ShortCutToText(newSC), inf.Component.Name]),
|
||||||
|
mtWarning, [mbOK], False);
|
||||||
|
FEdit.Text:=AmpersandStripped(FOldCaption);
|
||||||
|
FEdit.SetFocus;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
FNewShortcut:=newSC;
|
||||||
|
FNewCaption:=ed.Text;
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
FNewShortcut:=0;
|
||||||
|
FNewCaption:=ed.Text;
|
||||||
|
end;
|
||||||
|
hasAccel:=HasAccelerator(FEdit.Text, newSC);
|
||||||
|
FButtonPanel.OKButton.Enabled:=not hasAccel or (hasAccel and (newSC <> FInfo.Shortcut));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TEditShortcutCaptionDialog.GrabBoxEnter(Sender: TObject);
|
||||||
|
begin
|
||||||
|
if not FButtonPanel.OKButton.Enabled then
|
||||||
|
FButtonPanel.OKButton.Enabled:=True;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TEditShortcutCaptionDialog.GrabBoxExit(Sender: TObject);
|
||||||
|
var
|
||||||
|
newSC: TShortCut;
|
||||||
|
inf: TSCInfo;
|
||||||
|
begin
|
||||||
|
newSC:=KeyToShortCut(FGrabBox.Key, FGrabBox.ShiftState);
|
||||||
|
if (FInfo.Shortcut = newSC) then
|
||||||
|
begin
|
||||||
|
IDEMessageDialogAb(lisMenuEditorShortcutNotYetChanged,
|
||||||
|
Format(lisMenuEditorYouHaveToChangeTheShortcutFromSStoAvoidAConflict,
|
||||||
|
[ShortCutToText(FInfo.Shortcut)]),
|
||||||
|
mtWarning, [mbOK], False);
|
||||||
|
FGrabBox.KeyComboBox.SetFocus;
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
if FShortcuts.ShortcutList.UniqueListContainsShortcut(newSC) then
|
||||||
|
begin
|
||||||
|
inf:=FShortcuts.ShortcutList.FindUniqueInfoForShortcut(newSC);
|
||||||
|
IDEMessageDialogAb(lisMenuEditorFurtherShortcutConflict,
|
||||||
|
Format(lisMenuEditorSIsAlreadyInUse,
|
||||||
|
[ShortCutToText(newSC), inf.Component.Name]),
|
||||||
|
mtWarning, [mbOK], False);
|
||||||
|
FGrabBox.KeyComboBox.SetFocus;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
FNewShortcut:=newSC;
|
||||||
|
FButtonPanel.OKButton.Enabled:=True;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TEditShortcutCaptionDialog.OKButtonOnClick(Sender: TObject);
|
||||||
|
begin
|
||||||
|
if FEditingCaption then
|
||||||
|
begin
|
||||||
|
if (FEdit.Text = '') then
|
||||||
|
begin
|
||||||
|
IDEMessageDialogAb(lisMenuEditorCaptionShouldNotBeBlank,
|
||||||
|
lisMenuEditorYouMustEnterTextForTheCaption,
|
||||||
|
mtWarning, [mbOK], False);
|
||||||
|
FEdit.Text:=AmpersandStripped(FOldCaption);
|
||||||
|
FEdit.SetFocus;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
ModalResult:=mrOK;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
ModalResult:=mrOK;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TEditShortcutCaptionDialog.Activate;
|
||||||
|
begin
|
||||||
|
inherited Activate;
|
||||||
|
FButtonPanel.OKButton.Enabled:=False;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TContents }
|
{ TContents }
|
||||||
|
|
||||||
constructor TContents.Create(AOwner: TComponent);
|
constructor TContents.Create(AOwner: TComponent);
|
||||||
|
Loading…
Reference in New Issue
Block a user