UPD: HotMan: automatically update actions shortcuts.

This commit is contained in:
cobines 2011-08-17 00:38:10 +00:00
commit e15e9a53bb
2 changed files with 147 additions and 31 deletions

View file

@ -646,7 +646,7 @@ uses
uFileSourceOperationTypes, uFileSourceCopyOperation, uFileSourceMoveOperation,
fFileOpDlg, uFileSourceProperty, uFileSourceExecuteOperation, uArchiveFileSource,
uShellExecute, uActs, fSymLink, fHardLink, uExceptions, uUniqueInstance, Clipbrd,
uFileSourceOperationOptionsUI, uDebug
uFileSourceOperationOptionsUI, uDebug, uHotkeyManager
{$IFDEF LCLQT}
, qtwidgets
{$ENDIF}
@ -688,6 +688,7 @@ procedure TfrmMain.FormCreate(Sender: TObject);
var
slCommandHistory: TStringListEx;
I: Integer;
HMMainForm: THMForm;
begin
Application.OnException := @AppException;
Application.OnActivate := @AppActivate;
@ -703,7 +704,7 @@ begin
HidingTrayIcon := False;
FResizingFilePanels := False;
HotMan.Register(Self, 'Main');
HMMainForm := HotMan.Register(Self, 'Main');
HotMan.Register(edtCommand, 'CommandLine');
nbLeft := CreateNotebook(pnlLeft, fpLeft);
@ -752,14 +753,15 @@ begin
btnRightUp.Hint := btnLeftUp.Hint;
{ *HotKeys* }
for i:=0 to actionLst.ActionCount -1 do
if actionLst[i] is TAction then
Actions.AddAction(TAction(actionLst[i]));
if (HotMan.Forms.Count = 0) or (HotMan.Version < hkVersion) then
LoadDefaultHotkeyBindings;
// load shortcuts to action list for showing it in menu
HotMan.LoadShortCutToActionList(ActionLst, 'Main');
for i:=0 to actionLst.ActionCount -1 do
// Have to cast TContainedAction to TAction here, which may be unsafe.
Actions.AddAction(TAction(actionLst[i]));
// Assign correct action list to main form hotkeys.
HMMainForm.Hotkeys.ActionList := actionlst;
{ *HotKeys* }
LoadWindowState;

View file

@ -50,17 +50,42 @@ type
TBaseHotkeysList = specialize TFPGObjectList<THotkey>;
{ TActionListFreeNotifier }
TActionListFreeNotifier = class(TComponent)
private
FOwnerHotkeys: TObject;
protected
constructor Create(OwnerHotkeys: TObject); reintroduce;
procedure Notification(AComponent: TComponent;
Operation: TOperation); override;
end;
{ THotkeys }
THotkeys = class(TBaseHotkeysList)
private
{en
Used for notifying when ActionList is destroyed.
}
FFreeNotificationComponent: TActionListFreeNotifier;
FActionList: TActionList;
function GetActionByCommand(Command: String): TAction;
procedure RemoveActionShortcut(hotkey: THotkey);
procedure SetActionList(AValue: TActionList);
procedure SetActionShortcut(hotkey: THotkey);
public
constructor Create(AFreeObjects: Boolean = True); reintroduce;
destructor Destroy; override;
function Add(Shortcut: TShortCut; Command, Params: String): THotkey; overload;
function Add(sShortcut: String; Command, Params: String): THotkey; overload;
function AddIfNotExists(sShortcut: String; Command, Params: String): THotkey; overload;
procedure Delete(Shortcut: TShortCut); overload;
procedure Delete(sShortcut: String); overload;
procedure Remove(var hotkey: THotkey); reintroduce;
function Find(Shortcut: TShortCut): THotkey; overload;
function Find(sShortcut: String): THotkey; overload;
property ActionList: TActionList read FActionList write SetActionList;
end;
{ THMBaseObject }
@ -135,8 +160,6 @@ type
constructor Create;
destructor Destroy; override;
//---------------------
procedure LoadShortCutToActionList(ActionList: TActionList; AFormName: String);
//---------------------
procedure Save(FileName: String);
procedure Load(FileName: String);
//---------------------
@ -256,8 +279,36 @@ begin
Inc(Result, scWin);
end;
{ TActionListFreeNotifier }
constructor TActionListFreeNotifier.Create(OwnerHotkeys: TObject);
begin
inherited Create(nil);
FOwnerHotkeys := OwnerHotkeys;
end;
procedure TActionListFreeNotifier.Notification(AComponent: TComponent; Operation: TOperation);
begin
if Operation = opRemove then
(FOwnerHotkeys as THotkeys).ActionList := nil;
inherited Notification(AComponent, Operation);
end;
{ THotkeys }
constructor THotkeys.Create(AFreeObjects: Boolean);
begin
FActionList := nil;
FFreeNotificationComponent := nil;
inherited Create(AFreeObjects);
end;
destructor THotkeys.Destroy;
begin
inherited Destroy;
FFreeNotificationComponent.Free;
end;
function THotkeys.Add(Shortcut: TShortCut; Command, Params: String): THotkey;
begin
Result := THotkey.Create;
@ -265,6 +316,7 @@ begin
Result.Command := Command;
Result.Params := Params;
Add(Result);
SetActionShortcut(Result);
end;
function THotkeys.Add(sShortcut: String; Command, Params: String): THotkey;
@ -289,6 +341,7 @@ begin
for i := 0 to Count - 1 do
if Items[i].ShortCut = Shortcut then
begin
RemoveActionShortcut(Items[i]);
Delete(i);
Exit;
end;
@ -302,6 +355,14 @@ begin
Delete(Shortcut);
end;
procedure THotkeys.Remove(var hotkey: THotkey);
begin
RemoveActionShortcut(hotkey);
inherited Remove(hotkey);
if FreeObjects then
hotkey := nil;
end;
function THotkeys.Find(Shortcut: TShortCut): THotkey;
var
i: Integer;
@ -320,6 +381,81 @@ begin
Result := Find(Shortcut);
end;
function THotkeys.GetActionByCommand(Command: String): TAction;
var
action: TContainedAction;
begin
Result := nil;
if Assigned(FActionList) then
begin
action := FActionList.ActionByName('act' + Copy(Command, 4, Length(Command) - 3));
if action is TAction then
Result := action as TAction;
end;
end;
procedure THotkeys.RemoveActionShortcut(hotkey: THotkey);
var
action: TAction;
i: Integer;
newShortcut: TShortCut;
begin
action := GetActionByCommand(hotkey.Command);
if Assigned(action) then
begin
if action.Shortcut = hotkey.Shortcut then
begin
newShortcut := VK_UNKNOWN;
// Search for another possible hotkey assigned for the same command.
for i := 0 to Count - 1 do
if (Items[i].Command = hotkey.Command) and (Items[i] <> hotkey) then
begin
newShortcut := Items[i].Shortcut;
Break;
end;
action.ShortCut := newShortcut;
end;
end;
end;
procedure THotkeys.SetActionList(AValue: TActionList);
var
i: Integer;
begin
if FActionList = AValue then
Exit;
if Assigned(FActionList) then
FActionList.RemoveFreeNotification(FFreeNotificationComponent);
FActionList := AValue;
if Assigned(FActionList) then
begin
if not Assigned(FFreeNotificationComponent) then
FFreeNotificationComponent := TActionListFreeNotifier.Create(Self);
FActionList.FreeNotification(FFreeNotificationComponent);
for i := 0 to Count - 1 do
SetActionShortcut(Items[i]);
end;
end;
procedure THotkeys.SetActionShortcut(hotkey: THotkey);
var
action: TAction;
begin
action := GetActionByCommand(hotkey.Command);
if Assigned(action) then
begin
// Don't override previous shortcut.
if action.Shortcut = VK_UNKNOWN then
action.ShortCut := hotkey.Shortcut;
end;
end;
{ THMForm }
constructor THMForm.Create(AName: String);
@ -486,28 +622,6 @@ begin
FForms.Free;
end;
procedure THotKeyManager.LoadShortCutToActionList(ActionList: TActionList; AFormName: String);
var
form: THMForm;
i: Integer;
hotkey: THotkey;
action: TContainedAction;
begin
// Only set shortcuts of hotkeys for the form itself.
form := FForms.Find(AFormName);
if Assigned(form) then
begin
for i := 0 to form.Hotkeys.Count - 1 do
begin
hotkey := form.Hotkeys[i];
action := ActionList.ActionByName(
'act' + Copy(hotkey.Command, 4, Length(hotkey.Command) - 3));
if action is TAction then
(action as TAction).ShortCut := hotkey.Shortcut;
end;
end;
end;
procedure THotKeyManager.Save(FileName: String);
var
Config: TXmlConfig = nil;