mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-05 01:08:12 +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,
|
||||
// IDE
|
||||
LazarusIDEStrConsts, LazIDEIntf, MenuDesignerBase, MenuEditorForm, MenuShortcutDisplay,
|
||||
MenuTemplates;
|
||||
MenuTemplates, MenuResolveConflicts;
|
||||
|
||||
type
|
||||
|
||||
@ -168,7 +168,7 @@ type
|
||||
popAddImgListIcon, popItemAddOnClick,
|
||||
popItemOISep,
|
||||
popShortcuts_,
|
||||
popListShortcuts, popListShortcutsAccelerators,
|
||||
popListShortcuts, popListShortcutsAccelerators, popResolveShortcutConflicts,
|
||||
popTemplates_,
|
||||
popSaveAsTemplate, popAddFromTemplate, popDeleteTemplate);{%endregion}
|
||||
|
||||
@ -221,6 +221,7 @@ type
|
||||
procedure MoveItemAfter(Sender: TObject);
|
||||
procedure MoveItemBefore(Sender: TObject);
|
||||
procedure RemoveAllSeparators(Sender: TObject);
|
||||
procedure ResolveShortcutConflicts(Sender: TObject);
|
||||
procedure SaveAsTemplate(Sender: TObject);
|
||||
private
|
||||
FDesigner: TMenuDesigner;
|
||||
@ -1207,6 +1208,8 @@ begin
|
||||
NewPopSub(primaryItem, '', @ListShortcuts);
|
||||
popListShortcutsAccelerators:
|
||||
NewPopSub(primaryItem, '', @ListShortcutsAndAccelerators);
|
||||
popResolveShortcutConflicts:
|
||||
NewPopSub(primaryItem, lisMenuEditorResolveShortcutConflicts, @ResolveshortcutConflicts);
|
||||
popTemplates_:
|
||||
NewPopPrimary(lisMenuEditorTemplates);
|
||||
popSaveAsTemplate:
|
||||
@ -1403,6 +1406,19 @@ begin
|
||||
ListShortCutDlg(FDesigner.Shortcuts, False, Self, Nil);
|
||||
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);
|
||||
var
|
||||
dlg: TMenuTemplateDialog;
|
||||
@ -1627,7 +1643,7 @@ end;
|
||||
|
||||
procedure TShadowMenu.UpdateActionsEnabledness;
|
||||
var
|
||||
ac, ac1, ac2: TAction;
|
||||
ac, ac1, ac2, ac3: TAction;
|
||||
pe: TPopEnum;
|
||||
isInBar, isFirst, isSeparator, isLast, prevIsSeparator, nextIsSeparator,
|
||||
levelZero, levelZeroOr1, primarySCEnabled: boolean;
|
||||
@ -1731,6 +1747,8 @@ begin
|
||||
ac.Enabled:=(FDesigner.Shortcuts.ShortcutList.AcceleratorsInContainerCount > 0);
|
||||
ac.Caption:=Format(lisMenuEditorListShortcutsAndAccelerators,[FLookupRoot.Name]);
|
||||
end;
|
||||
popResolveShortcutConflicts: ac.Enabled:=
|
||||
(FDesigner.Shortcuts.ShortcutList.InitialDuplicates.Count > 0);
|
||||
popTemplates_: ac.Enabled:=levelZero or FDesigner.TemplatesSaved;
|
||||
popSaveAsTemplate: ac.Enabled:=levelZeroOr1;
|
||||
popAddFromTemplate: ac.Enabled:=levelZero;
|
||||
@ -1740,7 +1758,8 @@ begin
|
||||
ac:=GetActionForEnum(popShortcuts_);
|
||||
ac1:=GetActionForEnum(popListShortcuts);
|
||||
ac2:=GetActionForEnum(popListShortcutsAccelerators);
|
||||
ac.Enabled:=ac1.Enabled or ac2.Enabled;
|
||||
ac3:=GetActionForEnum(popResolveShortcutConflicts);
|
||||
ac.Enabled:=ac1.Enabled or ac2.Enabled or ac3.Enabled;
|
||||
end;
|
||||
|
||||
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
|
||||
LazUTF8,
|
||||
// IdeIntf
|
||||
PropEdits,
|
||||
IDEDialogs, PropEdits,
|
||||
// IDE
|
||||
LazarusIDEStrConsts;
|
||||
|
||||
@ -141,6 +141,35 @@ type
|
||||
property OldShortcut: TShortCut write FOldShortcut;
|
||||
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;
|
||||
|
||||
TContents = class(TCustomControl)
|
||||
@ -243,6 +272,9 @@ function AmpersandStripped(const aText: string): string;
|
||||
function AddNewOrEditShortcutDlg(aMI: TMenuItem; isMainSCut: boolean;
|
||||
var 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 SplitCommaText(const aCommaText: string; out firstBit: string): string;
|
||||
function SortByComponentPropertyName(List: TStringList; Index1, Index2: Integer): Integer;
|
||||
@ -414,6 +446,41 @@ begin
|
||||
aSCList.ScanList.Count,'DoShortcutAccelScanCount: internal counting error');
|
||||
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;
|
||||
begin
|
||||
Result:='';
|
||||
@ -730,6 +797,196 @@ begin
|
||||
FShortCutGrabBox.ShiftState:=[];
|
||||
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 }
|
||||
|
||||
constructor TContents.Create(AOwner: TComponent);
|
||||
|
Loading…
Reference in New Issue
Block a user