mirror of
https://github.com/doublecmd/doublecmd.git
synced 2026-06-21 09:58:13 +00:00
ADD: Support for shortcuts sequences, i.e., commands can be executed after two or more consecutive shortcuts.
This commit is contained in:
parent
83d857d61a
commit
bb006cbb99
10 changed files with 765 additions and 413 deletions
|
|
@ -207,7 +207,7 @@ begin
|
|||
begin
|
||||
hotkey := HMForm.Hotkeys[i];
|
||||
if hotkey.Command = cHotKeyCommand then
|
||||
FHotKeyList.AddObject(hotkey.Shortcut, hotkey);
|
||||
FHotKeyList.AddObject(hotkey.Shortcuts[0], hotkey);// TODO fix for multiple hotkeys
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
|
@ -522,13 +522,20 @@ end;
|
|||
procedure TfrmConfigToolBar.btnClearHotKeyClick(Sender: TObject);
|
||||
var
|
||||
HMForm: THMForm;
|
||||
Hotkey: THotkey;
|
||||
Shortcuts: array of String = nil;
|
||||
begin
|
||||
edtHotKeys.Text:= EmptyStr;
|
||||
btnClearHotKey.Enabled:= False;
|
||||
ktbBar.SetButtonX(LastToolButton, MiskX, EmptyStr);
|
||||
HMForm := HotMan.Forms.Find('Main');
|
||||
if Assigned(HMForm) then
|
||||
HMForm.Hotkeys.Delete(GetHotKey(LastToolButton));
|
||||
begin
|
||||
// TODO find by multiple shortcuts
|
||||
AddString(Shortcuts, GetHotKey(LastToolButton));
|
||||
Hotkey := HMForm.Hotkeys.Find(Shortcuts);
|
||||
HMForm.Hotkeys.Remove(Hotkey);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TfrmConfigToolBar.edtHotKeysKeyDown(Sender: TObject; var Key: Word;
|
||||
|
|
@ -536,6 +543,7 @@ procedure TfrmConfigToolBar.edtHotKeysKeyDown(Sender: TObject; var Key: Word;
|
|||
var
|
||||
sShortCut: String;
|
||||
Shortcut: TShortCut;
|
||||
Shortcuts: array of String = nil;
|
||||
HMForm: THMForm;
|
||||
hotkey: THotkey;
|
||||
begin
|
||||
|
|
@ -550,10 +558,11 @@ begin
|
|||
HMForm := HotMan.Forms.Find('Main');
|
||||
if Assigned(HMForm) then
|
||||
begin
|
||||
hotkey := HMForm.Hotkeys.Find(sShortCut);
|
||||
AddString(Shortcuts, sShortCut);
|
||||
hotkey := HMForm.Hotkeys.FindByBeginning(Shortcuts, True);
|
||||
if Assigned(hotkey) then
|
||||
begin
|
||||
ShowHint(edtHotKeys, Format(rsOptHotkeysShortCutUsedText1, [sShortCut, hotkey.Command]));
|
||||
ShowHint(edtHotKeys, Format(rsOptHotkeysShortCutUsedText1, [ShortcutsToText(Shortcuts), hotkey.Command]));
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
|
@ -569,13 +578,14 @@ end;
|
|||
procedure TfrmConfigToolBar.SetButtonHotKey;
|
||||
var
|
||||
sShortCut: String;
|
||||
Shortcuts: array of String = nil;
|
||||
HMForm: THMForm;
|
||||
hotkey: THotkey;
|
||||
|
||||
//< local function for add hot key,
|
||||
procedure AddHotKeyButton(Hotkeys: THotkeys);
|
||||
begin
|
||||
Hotkeys.Add(sShortCut, cHotKeyCommand, [sShortCut]);
|
||||
Hotkeys.Add(Shortcuts, [sShortCut], cHotKeyCommand);
|
||||
ktbBar.SetButtonX(LastToolButton, MiskX, edtHotKeys.Text);
|
||||
end;
|
||||
|
||||
|
|
@ -585,9 +595,10 @@ begin
|
|||
else
|
||||
begin
|
||||
sShortCut := edtHotKeys.Text;
|
||||
AddString(Shortcuts, sShortCut);
|
||||
|
||||
HMForm := HotMan.Forms.FindOrCreate('Main');
|
||||
hotkey := HMForm.Hotkeys.Find(sShortCut);
|
||||
hotkey := HMForm.Hotkeys.FindByBeginning(Shortcuts, True);
|
||||
if not Assigned(hotkey) then
|
||||
begin
|
||||
AddHotKeyButton(HMForm.Hotkeys);
|
||||
|
|
@ -598,12 +609,12 @@ begin
|
|||
if (hotkey.Command = cHotKeyCommand) or
|
||||
(MessageDlg(rsOptHotkeysShortCutUsed,
|
||||
Format(rsOptHotkeysShortCutUsedText1,
|
||||
[sShortCut, hotkey.Command]) + LineEnding +
|
||||
[ShortcutsToText(Shortcuts), hotkey.Command]) + LineEnding +
|
||||
Format(rsOptHotkeysShortCutUsedText2,
|
||||
[cHotKeyCommand]),
|
||||
mtConfirmation, mbYesNo, 0) = mrYes) then
|
||||
begin
|
||||
HMForm.Hotkeys.Delete(sShortCut);
|
||||
HMForm.Hotkeys.Remove(hotkey);
|
||||
AddHotKeyButton(HMForm.Hotkeys);
|
||||
end;
|
||||
end;
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ implementation
|
|||
{$R *.lfm}
|
||||
|
||||
uses
|
||||
fMain, LCLType, LCLVersion, uGlobs, uLng, uHotkeyManager;
|
||||
fMain, LCLType, LCLVersion, uGlobs, uLng, uHotkeyManager, uDCUtils;
|
||||
|
||||
const
|
||||
HotkeysCategory = 'Copy/Move Dialog';
|
||||
|
|
@ -362,7 +362,7 @@ begin
|
|||
Hotkey := HMForm.Hotkeys.FindByCommand('cm_AddToQueue');
|
||||
|
||||
if Assigned(Hotkey) then
|
||||
btnAddToQueue.Caption := btnAddToQueue.Caption + ' (' + Hotkey.Shortcut + ')';
|
||||
btnAddToQueue.Caption := btnAddToQueue.Caption + ' (' + ShortcutsToText(Hotkey.Shortcuts) + ')';
|
||||
end;
|
||||
|
||||
procedure TfrmCopyDlg.FormDestroy(Sender: TObject);
|
||||
|
|
@ -405,4 +405,4 @@ end;
|
|||
initialization
|
||||
TFormCommands.RegisterCommandsForm(TfrmCopyDlg, HotkeysCategory, @rsHotkeyCategoryCopyMoveDialog);
|
||||
|
||||
end.
|
||||
end.
|
||||
|
|
|
|||
|
|
@ -1,54 +1,57 @@
|
|||
object frmEditHotkey: TfrmEditHotkey
|
||||
Left = 337
|
||||
Height = 450
|
||||
Height = 465
|
||||
Top = 120
|
||||
Width = 464
|
||||
ActiveControl = edtHotKey
|
||||
Width = 458
|
||||
BorderIcons = [biSystemMenu]
|
||||
ClientHeight = 450
|
||||
ClientWidth = 464
|
||||
ClientHeight = 465
|
||||
ClientWidth = 458
|
||||
Constraints.MinHeight = 200
|
||||
Constraints.MinWidth = 200
|
||||
OnCreate = FormCreate
|
||||
OnShow = FormShow
|
||||
Position = poScreenCenter
|
||||
LCLVersion = '1.1'
|
||||
object lblHotKey: TLabel
|
||||
LCLVersion = '0.9.31'
|
||||
object lblShortcuts: TLabel
|
||||
AnchorSideLeft.Control = edtParameters
|
||||
AnchorSideTop.Control = Owner
|
||||
Left = 8
|
||||
Height = 22
|
||||
Top = 6
|
||||
Width = 55
|
||||
Width = 69
|
||||
BorderSpacing.Top = 6
|
||||
Caption = 'Hot key:'
|
||||
Caption = 'Shortcuts:'
|
||||
ParentColor = False
|
||||
end
|
||||
object edtHotKey: TEdit
|
||||
object pnlShortcuts: TPanel
|
||||
AnchorSideLeft.Control = edtParameters
|
||||
AnchorSideTop.Control = lblHotKey
|
||||
AnchorSideTop.Control = btnAddShortcut
|
||||
AnchorSideTop.Side = asrBottom
|
||||
AnchorSideRight.Control = edtParameters
|
||||
AnchorSideRight.Side = asrBottom
|
||||
Left = 8
|
||||
Height = 29
|
||||
Height = 0
|
||||
Top = 28
|
||||
Width = 448
|
||||
Width = 442
|
||||
Anchors = [akTop, akLeft, akRight]
|
||||
OnKeyDown = edtHotKeyKeyDown
|
||||
OnKeyPress = edtHotKeyKeyPress
|
||||
AutoSize = True
|
||||
BevelOuter = bvNone
|
||||
ChildSizing.EnlargeHorizontal = crsHomogenousChildResize
|
||||
ChildSizing.EnlargeVertical = crsHomogenousChildResize
|
||||
ChildSizing.Layout = cclLeftToRightThenTopToBottom
|
||||
ChildSizing.ControlsPerLine = 1
|
||||
TabOrder = 0
|
||||
end
|
||||
object lblHotKeyConflict: TLabel
|
||||
AnchorSideLeft.Control = edtParameters
|
||||
AnchorSideTop.Control = edtHotKey
|
||||
AnchorSideTop.Control = pnlShortcuts
|
||||
AnchorSideTop.Side = asrBottom
|
||||
AnchorSideRight.Control = edtParameters
|
||||
AnchorSideRight.Side = asrBottom
|
||||
Left = 8
|
||||
Height = 1
|
||||
Top = 61
|
||||
Width = 448
|
||||
Top = 32
|
||||
Width = 442
|
||||
Anchors = [akTop, akLeft, akRight]
|
||||
BorderSpacing.Top = 4
|
||||
BorderSpacing.Bottom = 4
|
||||
|
|
@ -64,7 +67,7 @@ object frmEditHotkey: TfrmEditHotkey
|
|||
AnchorSideTop.Side = asrBottom
|
||||
Left = 8
|
||||
Height = 22
|
||||
Top = 68
|
||||
Top = 39
|
||||
Width = 247
|
||||
BorderSpacing.Top = 6
|
||||
Caption = 'Parameters (each in a separate line):'
|
||||
|
|
@ -78,9 +81,9 @@ object frmEditHotkey: TfrmEditHotkey
|
|||
AnchorSideRight.Side = asrBottom
|
||||
AnchorSideBottom.Control = btnShowCommandHelp
|
||||
Left = 8
|
||||
Height = 228
|
||||
Top = 90
|
||||
Width = 448
|
||||
Height = 272
|
||||
Top = 61
|
||||
Width = 442
|
||||
HelpType = htKeyword
|
||||
Anchors = [akTop, akLeft, akRight, akBottom]
|
||||
BorderSpacing.Left = 8
|
||||
|
|
@ -97,8 +100,8 @@ object frmEditHotkey: TfrmEditHotkey
|
|||
AnchorSideBottom.Control = cgHKControls
|
||||
Left = 8
|
||||
Height = 10
|
||||
Top = 322
|
||||
Width = 448
|
||||
Top = 337
|
||||
Width = 442
|
||||
Anchors = [akLeft, akRight, akBottom]
|
||||
AutoSize = True
|
||||
BorderSpacing.Top = 4
|
||||
|
|
@ -112,8 +115,8 @@ object frmEditHotkey: TfrmEditHotkey
|
|||
AnchorSideBottom.Control = btnOK
|
||||
Left = 8
|
||||
Height = 68
|
||||
Top = 332
|
||||
Width = 448
|
||||
Top = 347
|
||||
Width = 442
|
||||
Anchors = [akLeft, akRight, akBottom]
|
||||
AutoFill = True
|
||||
AutoSize = True
|
||||
|
|
@ -136,7 +139,7 @@ object frmEditHotkey: TfrmEditHotkey
|
|||
AnchorSideBottom.Side = asrBottom
|
||||
Left = 8
|
||||
Height = 40
|
||||
Top = 404
|
||||
Top = 419
|
||||
Width = 120
|
||||
Anchors = [akLeft, akBottom]
|
||||
AutoSize = True
|
||||
|
|
@ -155,9 +158,9 @@ object frmEditHotkey: TfrmEditHotkey
|
|||
AnchorSideRight.Side = asrBottom
|
||||
AnchorSideBottom.Control = Owner
|
||||
AnchorSideBottom.Side = asrBottom
|
||||
Left = 336
|
||||
Left = 330
|
||||
Height = 40
|
||||
Top = 404
|
||||
Top = 419
|
||||
Width = 120
|
||||
Anchors = [akRight, akBottom]
|
||||
AutoSize = True
|
||||
|
|
@ -170,4 +173,33 @@ object frmEditHotkey: TfrmEditHotkey
|
|||
ModalResult = 2
|
||||
TabOrder = 5
|
||||
end
|
||||
object btnAddShortcut: TSpeedButton
|
||||
AnchorSideTop.Control = btnRemoveShortcut
|
||||
AnchorSideRight.Control = btnRemoveShortcut
|
||||
Left = 406
|
||||
Height = 22
|
||||
Hint = 'Add new shortcut to sequence'
|
||||
Top = 6
|
||||
Width = 22
|
||||
Anchors = [akTop, akRight]
|
||||
NumGlyphs = 0
|
||||
OnClick = btnAddShortcutClick
|
||||
ShowHint = True
|
||||
ParentShowHint = False
|
||||
end
|
||||
object btnRemoveShortcut: TSpeedButton
|
||||
AnchorSideTop.Control = lblShortcuts
|
||||
AnchorSideRight.Control = edtParameters
|
||||
AnchorSideRight.Side = asrBottom
|
||||
Left = 428
|
||||
Height = 22
|
||||
Hint = 'Remove last shortcut from sequence'
|
||||
Top = 6
|
||||
Width = 22
|
||||
Anchors = [akTop, akRight]
|
||||
NumGlyphs = 0
|
||||
OnClick = btnRemoveShortcutClick
|
||||
ShowHint = True
|
||||
ParentShowHint = False
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
TFRMEDITHOTKEY.LBLHOTKEY.CAPTION=Hot key:
|
||||
TFRMEDITHOTKEY.LBLSHORTCUTS.CAPTION=Shortcuts:
|
||||
TFRMEDITHOTKEY.LBLPARAMETERS.CAPTION=Parameters (each in a separate line):
|
||||
TFRMEDITHOTKEY.CGHKCONTROLS.CAPTION=Only for these controls
|
||||
TFRMEDITHOTKEY.BTNADDSHORTCUT.HINT=Add new shortcut to sequence
|
||||
TFRMEDITHOTKEY.BTNREMOVESHORTCUT.HINT=Remove last shortcut from sequence
|
||||
|
|
|
|||
|
|
@ -40,38 +40,47 @@ type
|
|||
btnCancel: TBitBtn;
|
||||
btnShowCommandHelp: TButton;
|
||||
cgHKControls: TCheckGroup;
|
||||
edtHotKey: TEdit;
|
||||
lblHotKey: TLabel;
|
||||
lblShortcuts: TLabel;
|
||||
lblHotKeyConflict: TLabel;
|
||||
lblParameters: TLabel;
|
||||
edtParameters: TMemo;
|
||||
pnlShortcuts: TPanel;
|
||||
btnAddShortcut: TSpeedButton;
|
||||
btnRemoveShortcut: TSpeedButton;
|
||||
procedure btnAddShortcutClick(Sender: TObject);
|
||||
procedure btnRemoveShortcutClick(Sender: TObject);
|
||||
procedure btnShowCommandHelpClick(Sender: TObject);
|
||||
procedure cgHKControlsItemClick(Sender: TObject; Index: integer);
|
||||
procedure edtHotKeyKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
|
||||
procedure edtHotKeyKeyPress(Sender: TObject; var Key: char);
|
||||
procedure edtShortcutKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
|
||||
procedure edtShortcutKeyPress(Sender: TObject; var Key: char);
|
||||
procedure FormCreate(Sender: TObject);
|
||||
procedure FormShow(Sender: TObject);
|
||||
private
|
||||
FCommand: String;
|
||||
FControls: TDynamicStringArray;
|
||||
FShortcutsEditors: Integer;
|
||||
FForm: String;
|
||||
FForms, FFormsTranslated: TStringList;
|
||||
function ApplyHotkey: Boolean;
|
||||
procedure AddShortcutEditor;
|
||||
{en
|
||||
Check if combination of pressed hotkey and checked controls are already in use.
|
||||
Conflicting hotkeys are deleted if DeleteConflicts parameter is true.
|
||||
}
|
||||
procedure CheckHotKeyConflicts(DeleteConflicts: Boolean = false);
|
||||
procedure FillHKControlList;
|
||||
function GetShortcutsEditorsCount: Integer;
|
||||
function GetParameters: TDynamicStringArray;
|
||||
function GetShortcut: String;
|
||||
function GetShortcuts: TDynamicStringArray;
|
||||
function GetTranslatedControlName(const AName: String): String;
|
||||
function GetTranslatedFormName(const AName: String): String;
|
||||
procedure RemoveLastShortcutEditor;
|
||||
procedure SetBitmapOrCaption(Button: TSpeedButton; const AIconName, ACaption: String);
|
||||
procedure SetCommand(NewCommand: String);
|
||||
procedure SetControls(NewControls: TDynamicStringArray);
|
||||
procedure SetControls(const NewControls: TDynamicStringArray);
|
||||
procedure SetHotkey(Hotkey: THotkey);
|
||||
procedure SetParameters(NewParameters: TDynamicStringArray);
|
||||
procedure SetShortcut(NewShortcut: String);
|
||||
procedure SetParameters(const NewParameters: TDynamicStringArray);
|
||||
procedure SetShortcuts(const NewShortcuts: TDynamicStringArray);
|
||||
public
|
||||
destructor Destroy; override;
|
||||
function Execute(EditMode: Boolean;
|
||||
|
|
@ -79,7 +88,7 @@ type
|
|||
Command: String;
|
||||
Hotkey: THotkey;
|
||||
AControls: TDynamicStringArray): Boolean;
|
||||
property NewShortcut: String read GetShortcut;
|
||||
function CloneNewHotkey: THotkey;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
|
@ -87,15 +96,31 @@ implementation
|
|||
{$R *.lfm}
|
||||
|
||||
uses
|
||||
HelpIntfs, LCLType, uKeyboard, uLng, uGlobs, uFormCommands;
|
||||
HelpIntfs, LCLType, uKeyboard, uLng, uGlobs, uFormCommands, uDCUtils,
|
||||
uPixMapManager;
|
||||
|
||||
const
|
||||
MaxShortcutSequenceLength = 5;
|
||||
|
||||
{ TfrmEditHotkey }
|
||||
|
||||
procedure TfrmEditHotkey.AddShortcutEditor;
|
||||
var
|
||||
EditControl: TEdit;
|
||||
begin
|
||||
if GetShortcutsEditorsCount < MaxShortcutSequenceLength then
|
||||
begin
|
||||
EditControl := TEdit.Create(Self);
|
||||
EditControl.Parent := pnlShortcuts;
|
||||
EditControl.OnKeyDown := @edtShortcutKeyDown;
|
||||
EditControl.OnKeyPress := @edtShortcutKeyPress;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TfrmEditHotkey.ApplyHotkey: Boolean;
|
||||
var
|
||||
i: Integer;
|
||||
sShortCut: String;
|
||||
Params: array of String;
|
||||
Shortcuts, Params: array of String;
|
||||
HMForm: THMForm;
|
||||
HMControl: THMControl;
|
||||
hotkey: THotkey;
|
||||
|
|
@ -103,10 +128,9 @@ var
|
|||
begin
|
||||
Result := False;
|
||||
|
||||
sShortCut := edtHotKey.Text;
|
||||
|
||||
Shortcuts := GetShortcuts;
|
||||
// check for invalid hotkey
|
||||
if sShortCut = EmptyStr then
|
||||
if Length(Shortcuts) = 0 then
|
||||
Exit;
|
||||
|
||||
Params := GetParameters;
|
||||
|
|
@ -115,7 +139,7 @@ begin
|
|||
begin
|
||||
if (MessageDlg(rsOptHotkeysShortCutUsed, // delete command on assigned shortcut
|
||||
Format(rsOptHotkeysShortCutUsedText1, // if another was applied
|
||||
[sShortCut]) + LineEnding +
|
||||
[ShortcutsToText(Shortcuts)]) + LineEnding +
|
||||
Format(rsOptHotkeysShortCutUsedText2,
|
||||
[FCommand]),
|
||||
mtConfirmation, mbYesNo, 0) = mrYes) then
|
||||
|
|
@ -133,7 +157,7 @@ begin
|
|||
continue;
|
||||
|
||||
// delete previous hotkey if exists
|
||||
hotkey := HMControl.Hotkeys.Find(sShortCut);
|
||||
hotkey := HMControl.Hotkeys.Find(Shortcuts);
|
||||
if Assigned(hotkey) and (hotkey.Command = FCommand) then
|
||||
HMControl.Hotkeys.Remove(hotkey);
|
||||
|
||||
|
|
@ -141,21 +165,31 @@ begin
|
|||
if cgHKControls.Checked[i] then
|
||||
begin
|
||||
isFormHotkey := false;
|
||||
HMControl.Hotkeys.Add(sShortCut, FCommand, Params);
|
||||
HMControl.Hotkeys.Add(Shortcuts, Params, FCommand);
|
||||
end;
|
||||
end;
|
||||
|
||||
// delete previous hotkey if exists
|
||||
hotkey := HMForm.Hotkeys.Find(sShortCut);
|
||||
hotkey := HMForm.Hotkeys.Find(Shortcuts);
|
||||
if Assigned(hotkey) and (hotkey.Command = FCommand) then
|
||||
HMForm.Hotkeys.Remove(hotkey);
|
||||
|
||||
if isFormHotkey then
|
||||
HMForm.Hotkeys.Add(sShortCut, FCommand, Params);
|
||||
HMForm.Hotkeys.Add(Shortcuts, Params, FCommand);
|
||||
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
procedure TfrmEditHotkey.btnAddShortcutClick(Sender: TObject);
|
||||
begin
|
||||
AddShortcutEditor;
|
||||
end;
|
||||
|
||||
procedure TfrmEditHotkey.btnRemoveShortcutClick(Sender: TObject);
|
||||
begin
|
||||
RemoveLastShortcutEditor;
|
||||
end;
|
||||
|
||||
procedure TfrmEditHotkey.btnShowCommandHelpClick(Sender: TObject);
|
||||
begin
|
||||
ShowHelpOrErrorForKeyword('', edtParameters.HelpKeyword);
|
||||
|
|
@ -179,7 +213,7 @@ procedure TfrmEditHotkey.CheckHotKeyConflicts(DeleteConflicts: Boolean);
|
|||
var
|
||||
HMForm: THMForm;
|
||||
HMControl: THMControl;
|
||||
sShortCut: String;
|
||||
Shortcuts: TDynamicStringArray;
|
||||
hotkey: THotkey;
|
||||
i, count: Integer;
|
||||
isFormHotKey: Boolean;
|
||||
|
|
@ -191,7 +225,7 @@ begin
|
|||
if not Assigned(HMForm) then
|
||||
Exit;
|
||||
|
||||
sShortCut := edtHotKey.Text;
|
||||
Shortcuts := GetShortcuts;
|
||||
|
||||
count := 0;
|
||||
isFormHotKey := true;
|
||||
|
|
@ -207,7 +241,7 @@ begin
|
|||
if not Assigned(HMControl) then
|
||||
continue;
|
||||
|
||||
hotkey := HMControl.Hotkeys.Find(sShortCut);
|
||||
hotkey := HMControl.Hotkeys.Find(Shortcuts);
|
||||
if Assigned(hotkey) and (hotkey.command <> FCommand) then
|
||||
begin
|
||||
Inc(count);
|
||||
|
|
@ -221,7 +255,7 @@ begin
|
|||
|
||||
if isFormHotKey then
|
||||
begin
|
||||
hotkey := HMForm.Hotkeys.Find(sShortCut);
|
||||
hotkey := HMForm.Hotkeys.Find(Shortcuts);
|
||||
if Assigned(hotkey) and (hotkey.command <> FCommand) then
|
||||
begin
|
||||
Inc(count);
|
||||
|
|
@ -242,6 +276,14 @@ begin
|
|||
lblHotKeyConflict.Visible := count > 0;
|
||||
end;
|
||||
|
||||
function TfrmEditHotkey.CloneNewHotkey: THotkey;
|
||||
begin
|
||||
Result := THotkey.Create;
|
||||
Result.Shortcuts := GetShortcuts;
|
||||
Result.Params := GetParameters;
|
||||
Result.Command := FCommand;
|
||||
end;
|
||||
|
||||
destructor TfrmEditHotkey.Destroy;
|
||||
begin
|
||||
inherited Destroy;
|
||||
|
|
@ -249,31 +291,36 @@ begin
|
|||
FFormsTranslated.Free;
|
||||
end;
|
||||
|
||||
procedure TfrmEditHotkey.edtHotKeyKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
|
||||
procedure TfrmEditHotkey.edtShortcutKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
|
||||
var
|
||||
ShortCut: TShortCut;
|
||||
sShortCut: String;
|
||||
EditControl: TEdit;
|
||||
begin
|
||||
ShortCut := KeyToShortCutEx(Key,GetKeyShiftStateEx);
|
||||
ShortCut := KeyToShortCutEx(Key, GetKeyShiftStateEx);
|
||||
sShortCut := ShortCutToTextEx(ShortCut);
|
||||
EditControl := Sender as TEdit;
|
||||
|
||||
// Allow closing the dialog if Escape pressed twice.
|
||||
if (ShortCut <> VK_ESCAPE) or (edtHotKey.Text <> sShortCut) then
|
||||
if (ShortCut <> VK_ESCAPE) or (EditControl.Text <> sShortCut) then
|
||||
begin
|
||||
edtHotKey.Text := sShortCut;
|
||||
EditControl.Text := sShortCut;
|
||||
Key := 0;
|
||||
btnOK.Enabled := edtHotKey.Text <> '';
|
||||
btnOK.Enabled := sShortCut <> '';
|
||||
lblHotKeyConflict.Caption := '';
|
||||
|
||||
CheckHotKeyConflicts;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TfrmEditHotkey.edtHotKeyKeyPress(Sender: TObject; var Key: char);
|
||||
procedure TfrmEditHotkey.edtShortcutKeyPress(Sender: TObject; var Key: char);
|
||||
var
|
||||
EditControl: TEdit;
|
||||
begin
|
||||
Key := #0;
|
||||
edtHotKey.Text := '';
|
||||
EditControl := Sender as TEdit;
|
||||
EditControl.Text := '';
|
||||
btnOK.Enabled := False;
|
||||
Key := #0;
|
||||
end;
|
||||
|
||||
function TfrmEditHotkey.Execute(
|
||||
|
|
@ -329,11 +376,24 @@ begin
|
|||
FForms := TStringList.Create;
|
||||
FFormsTranslated := TStringList.Create;
|
||||
TFormCommands.GetCategoriesList(FForms, FFormsTranslated);
|
||||
|
||||
SetBitmapOrCaption(btnAddShortcut, 'list-add', '+');
|
||||
SetBitmapOrCaption(btnRemoveShortcut, 'list-remove', '-');
|
||||
|
||||
AddShortcutEditor;
|
||||
end;
|
||||
|
||||
procedure TfrmEditHotkey.FormShow(Sender: TObject);
|
||||
var
|
||||
EditControl: TEdit;
|
||||
begin
|
||||
edtHotKey.SetFocus;
|
||||
if pnlShortcuts.ControlCount > 0 then
|
||||
begin
|
||||
EditControl := pnlShortcuts.Controls[0] as TEdit;
|
||||
EditControl.SetFocus;
|
||||
EditControl.SelStart := Length(EditControl.Text);
|
||||
EditControl.SelLength := 0;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TfrmEditHotkey.GetParameters: TDynamicStringArray;
|
||||
|
|
@ -352,9 +412,23 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
function TfrmEditHotkey.GetShortcut: String;
|
||||
function TfrmEditHotkey.GetShortcuts: TDynamicStringArray;
|
||||
var
|
||||
i: Integer;
|
||||
EditControl: TEdit;
|
||||
begin
|
||||
Result := edtHotKey.Text;
|
||||
Result := nil;
|
||||
for i := 0 to pnlShortcuts.ControlCount - 1 do
|
||||
begin
|
||||
EditControl := pnlShortcuts.Controls[i] as TEdit;
|
||||
if EditControl.Text <> '' then
|
||||
AddString(Result, EditControl.Text);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TfrmEditHotkey.GetShortcutsEditorsCount: Integer;
|
||||
begin
|
||||
Result := pnlShortcuts.ControlCount;
|
||||
end;
|
||||
|
||||
function TfrmEditHotkey.GetTranslatedControlName(const AName: String): String;
|
||||
|
|
@ -374,6 +448,34 @@ begin
|
|||
Result := AName;
|
||||
end;
|
||||
|
||||
procedure TfrmEditHotkey.RemoveLastShortcutEditor;
|
||||
begin
|
||||
if pnlShortcuts.ControlCount > 1 then
|
||||
pnlShortcuts.Controls[pnlShortcuts.ControlCount - 1].Free;
|
||||
end;
|
||||
|
||||
procedure TfrmEditHotkey.SetBitmapOrCaption(Button: TSpeedButton; const AIconName, ACaption: String);
|
||||
var
|
||||
Bmp: TBitmap = nil;
|
||||
IconIndex: PtrInt;
|
||||
begin
|
||||
IconIndex := PixMapManager.GetIconByName(AIconName);
|
||||
if IconIndex <> -1 then
|
||||
Bmp := PixMapManager.GetBitmap(IconIndex);
|
||||
|
||||
if Assigned(Bmp) then
|
||||
begin
|
||||
Button.Glyph := Bmp;
|
||||
Button.Height := gIconsSize;
|
||||
Button.Width := gIconsSize;
|
||||
Bmp.Free;
|
||||
end
|
||||
else
|
||||
begin
|
||||
Button.Caption := ACaption;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TfrmEditHotkey.SetCommand(NewCommand: String);
|
||||
begin
|
||||
FCommand := NewCommand;
|
||||
|
|
@ -381,7 +483,7 @@ begin
|
|||
edtParameters.HelpKeyword := '/cmds.html#' + FCommand;
|
||||
end;
|
||||
|
||||
procedure TfrmEditHotkey.SetControls(NewControls: TDynamicStringArray);
|
||||
procedure TfrmEditHotkey.SetControls(const NewControls: TDynamicStringArray);
|
||||
var
|
||||
sControl: String;
|
||||
i: Integer;
|
||||
|
|
@ -408,17 +510,17 @@ procedure TfrmEditHotkey.SetHotkey(Hotkey: THotkey);
|
|||
begin
|
||||
if Assigned(Hotkey) then
|
||||
begin
|
||||
SetShortcut(Hotkey.Shortcut);
|
||||
SetShortcuts(Hotkey.Shortcuts);
|
||||
SetParameters(Hotkey.Params);
|
||||
end
|
||||
else
|
||||
begin
|
||||
SetShortcut(EmptyStr);
|
||||
SetShortcuts(nil);
|
||||
SetParameters(nil);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TfrmEditHotkey.SetParameters(NewParameters: TDynamicStringArray);
|
||||
procedure TfrmEditHotkey.SetParameters(const NewParameters: TDynamicStringArray);
|
||||
var
|
||||
Param: String;
|
||||
begin
|
||||
|
|
@ -427,9 +529,27 @@ begin
|
|||
edtParameters.Lines.Add(Param);
|
||||
end;
|
||||
|
||||
procedure TfrmEditHotkey.SetShortcut(NewShortcut: String);
|
||||
procedure TfrmEditHotkey.SetShortcuts(const NewShortcuts: TDynamicStringArray);
|
||||
var
|
||||
Index: Integer;
|
||||
EditControl: TEdit;
|
||||
Shortcut: String;
|
||||
begin
|
||||
edtHotKey.Text := NewShortcut;
|
||||
if Assigned(NewShortcuts) then
|
||||
begin
|
||||
while pnlShortcuts.ControlCount < Length(NewShortcuts) do
|
||||
AddShortcutEditor;
|
||||
while pnlShortcuts.ControlCount > Length(NewShortcuts) do
|
||||
RemoveLastShortcutEditor;
|
||||
|
||||
Index := 0;
|
||||
for Shortcut in NewShortcuts do
|
||||
begin
|
||||
EditControl := pnlShortcuts.Controls[Index] as TEdit;
|
||||
EditControl.Text := Shortcut;
|
||||
Inc(Index);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ type
|
|||
{en
|
||||
Return hotkeys assigned for command for the form and its controls.
|
||||
}
|
||||
procedure GetHotKeyList(HMForm: THMForm; Command: String; HotkeysList: TStringList);
|
||||
procedure GetHotKeyList(HMForm: THMForm; Command: String; HotkeysList: THotkeys);
|
||||
{en
|
||||
Fill hotkey grid with all hotkeys assigned to a command
|
||||
}
|
||||
|
|
@ -95,6 +95,7 @@ type
|
|||
Retrieves untranslated form name.
|
||||
}
|
||||
function GetSelectedForm: String;
|
||||
procedure SelectHotkey(Hotkey: THotkey);
|
||||
procedure ShowEditHotkeyForm(EditMode: Boolean; aHotkeyRow: Integer);
|
||||
procedure ShowEditHotkeyForm(EditMode: Boolean;
|
||||
const AForm: String;
|
||||
|
|
@ -142,30 +143,28 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
function StListToStr(separator:string; const lStList:TStringList; duplicates: boolean = true):string;
|
||||
//< convert stringlist to string
|
||||
// Converts hotkeys list to string.
|
||||
function HotkeysToString(const Hotkeys: THotkeys): String;
|
||||
var
|
||||
sLast: String;
|
||||
sCurrent: String;
|
||||
i: Integer;
|
||||
sList: TStringList;
|
||||
begin
|
||||
Result:='';
|
||||
if lStList.Count>0 then
|
||||
begin
|
||||
if not duplicates then
|
||||
lStList.Sort;
|
||||
|
||||
sLast := lStList[0];
|
||||
|
||||
Result:=lStList[0]+separator;
|
||||
for i:=1 to lStList.Count-1 do
|
||||
Result := '';
|
||||
sList := TStringList.Create;
|
||||
try
|
||||
sList.CaseSensitive := True;
|
||||
for i := 0 to Hotkeys.Count - 1 do
|
||||
begin
|
||||
if not duplicates and (lStList[i] = sLast) then
|
||||
continue;
|
||||
|
||||
sLast := lStList[i];
|
||||
|
||||
Result:=Result+lStList[i]+separator;
|
||||
sCurrent := ShortcutsToText(Hotkeys[i].Shortcuts);
|
||||
if sList.IndexOf(sCurrent) < 0 then
|
||||
begin
|
||||
sList.Add(sCurrent);
|
||||
AddStrWithSep(Result, sCurrent, ';');
|
||||
end;
|
||||
end;
|
||||
finally
|
||||
sList.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
|
@ -183,36 +182,38 @@ end;
|
|||
procedure TfrmOptionsHotkeys.btnDeleteHotKeyClick(Sender: TObject);
|
||||
var
|
||||
i: Integer;
|
||||
sShortCut: String;
|
||||
sCommand: String;
|
||||
HMForm: THMForm;
|
||||
HMControl: THMControl;
|
||||
hotkey: THotkey;
|
||||
HotkeyItem: PHotkeyItem;
|
||||
begin
|
||||
if lbxCategories.ItemIndex=-1 then Exit;
|
||||
sShortCut := stgHotkeys.Cells[0, stgHotkeys.Row];
|
||||
sCommand := GetSelectedCommand;
|
||||
HMForm := HotMan.Forms.Find(GetSelectedForm);
|
||||
if Assigned(HMForm) then
|
||||
if stgHotkeys.Row >= stgHotkeys.FixedRows then
|
||||
begin
|
||||
for i := 0 to HMForm.Controls.Count - 1 do
|
||||
HotkeyItem := PHotkeyItem(stgHotkeys.Objects[0, stgHotkeys.Row]);
|
||||
sCommand := GetSelectedCommand;
|
||||
HMForm := HotMan.Forms.Find(GetSelectedForm);
|
||||
if Assigned(HMForm) then
|
||||
begin
|
||||
HMControl := HMForm.Controls[i];
|
||||
if Assigned(HMControl) then
|
||||
for i := 0 to HMForm.Controls.Count - 1 do
|
||||
begin
|
||||
hotkey := HMControl.Hotkeys.Find(sShortCut);
|
||||
if Assigned(hotkey) and (hotkey.Command = sCommand) then
|
||||
HMControl.Hotkeys.Remove(hotkey);
|
||||
HMControl := HMForm.Controls[i];
|
||||
if Assigned(HMControl) then
|
||||
begin
|
||||
hotkey := HMControl.Hotkeys.FindByContents(HotkeyItem^.Hotkey);
|
||||
if Assigned(hotkey) then
|
||||
HMControl.Hotkeys.Remove(hotkey);
|
||||
end;
|
||||
end;
|
||||
|
||||
hotkey := HMForm.Hotkeys.FindByContents(HotkeyItem^.Hotkey);
|
||||
if Assigned(hotkey) then
|
||||
HMForm.Hotkeys.Remove(hotkey);
|
||||
|
||||
// refresh lists
|
||||
Self.UpdateHotkeys(HMForm);
|
||||
Self.FillHotkeyList(sCommand);
|
||||
end;
|
||||
|
||||
hotkey := HMForm.Hotkeys.Find(sShortCut);
|
||||
if Assigned(hotkey) and (hotkey.Command = sCommand) then
|
||||
HMForm.Hotkeys.Remove(hotkey);
|
||||
|
||||
// refresh lists
|
||||
Self.UpdateHotkeys(HMForm);
|
||||
Self.FillHotkeyList(sCommand);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
|
@ -343,12 +344,15 @@ end;
|
|||
|
||||
procedure TfrmOptionsHotkeys.UpdateHotkeysForCommand(HMForm: THMForm; RowNr: Integer);
|
||||
var
|
||||
lslHotKeys: TStringList;
|
||||
Hotkeys: THotkeys;
|
||||
begin
|
||||
lslHotKeys:=TStringList.Create;
|
||||
GetHotKeyList(HMForm, stgCommands.Cells[stgCmdCommandIndex,RowNr],lslHotKeys);
|
||||
stgCommands.Cells[stgCmdHotkeysIndex,RowNr]:=StListToStr(';',lslHotKeys,false);
|
||||
lslHotKeys.Free;
|
||||
Hotkeys := THotkeys.Create(False);
|
||||
try
|
||||
GetHotKeyList(HMForm, stgCommands.Cells[stgCmdCommandIndex,RowNr], Hotkeys);
|
||||
stgCommands.Cells[stgCmdHotkeysIndex, RowNr] := HotkeysToString(Hotkeys);
|
||||
finally
|
||||
Hotkeys.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TfrmOptionsHotkeys.FillSCFilesList;
|
||||
|
|
@ -368,7 +372,7 @@ begin
|
|||
FindCloseEx(SR);
|
||||
end;
|
||||
|
||||
procedure TfrmOptionsHotkeys.GetHotKeyList(HMForm: THMForm; Command: String; HotkeysList: TStringList);
|
||||
procedure TfrmOptionsHotkeys.GetHotKeyList(HMForm: THMForm; Command: String; HotkeysList: THotkeys);
|
||||
procedure AddHotkeys(hotkeys: THotkeys);
|
||||
var
|
||||
i: Integer;
|
||||
|
|
@ -376,7 +380,7 @@ procedure TfrmOptionsHotkeys.GetHotKeyList(HMForm: THMForm; Command: String; Hot
|
|||
for i := 0 to hotkeys.Count - 1 do
|
||||
begin
|
||||
if hotkeys[i].Command = Command then
|
||||
HotkeysList.AddObject(hotkeys[i].Shortcut, hotkeys[i]);
|
||||
HotkeysList.Add(hotkeys[i]);
|
||||
end;
|
||||
end;
|
||||
var
|
||||
|
|
@ -397,14 +401,6 @@ begin
|
|||
end;
|
||||
|
||||
procedure TfrmOptionsHotkeys.FillHotkeyList(sCommand: String);
|
||||
function GatherParams(const Params: array of String): String;
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
Result := '';
|
||||
for i := Low(Params) to High(Params) do
|
||||
AddStrWithSep(Result, Params[i], ' ');
|
||||
end;
|
||||
function SetObject(RowNr: Integer; AHotkey: THotkey): PHotkeyItem;
|
||||
var
|
||||
HotkeyItem: PHotkeyItem;
|
||||
|
|
@ -441,8 +437,8 @@ begin
|
|||
continue;
|
||||
|
||||
stgHotkeys.RowCount := stgHotkeys.RowCount + 1;
|
||||
stgHotkeys.Cells[0, stgHotkeys.RowCount - 1] := hotkey.ShortCut;
|
||||
stgHotkeys.Cells[1, stgHotkeys.RowCount - 1] := GatherParams(hotkey.Params);
|
||||
stgHotkeys.Cells[0, stgHotkeys.RowCount - 1] := ShortcutsToText(hotkey.Shortcuts);
|
||||
stgHotkeys.Cells[1, stgHotkeys.RowCount - 1] := ArrayToString(hotkey.Params);
|
||||
SetObject(stgHotkeys.RowCount - 1, hotkey);
|
||||
end;
|
||||
|
||||
|
|
@ -460,7 +456,9 @@ begin
|
|||
found := false;
|
||||
for iGrid := stgHotkeys.FixedRows to stgHotkeys.RowCount - 1 do
|
||||
begin
|
||||
if stgHotkeys.Cells[0, iGrid] = hotkey.ShortCut then
|
||||
HotkeyItem := PHotkeyItem(stgHotkeys.Objects[0, iGrid]);
|
||||
if HotkeyItem^.Hotkey.SameShortcuts(hotkey.Shortcuts) and
|
||||
HotkeyItem^.Hotkey.SameParams(hotkey.Params) then
|
||||
begin
|
||||
stgHotkeys.Cells[2, iGrid] := stgHotkeys.Cells[2, iGrid] + HMControl.Name + ';';
|
||||
HotkeyItem := PHotkeyItem(stgHotkeys.Objects[0, iGrid]);
|
||||
|
|
@ -474,8 +472,8 @@ begin
|
|||
if not found then
|
||||
begin
|
||||
stgHotkeys.RowCount := stgHotkeys.RowCount + 1;
|
||||
stgHotkeys.Cells[0, stgHotkeys.RowCount - 1] := hotkey.ShortCut;
|
||||
stgHotkeys.Cells[1, stgHotkeys.RowCount - 1] := GatherParams(hotkey.Params);
|
||||
stgHotkeys.Cells[0, stgHotkeys.RowCount - 1] := ShortcutsToText(hotkey.Shortcuts);
|
||||
stgHotkeys.Cells[1, stgHotkeys.RowCount - 1] := ArrayToString(hotkey.Params);
|
||||
stgHotkeys.Cells[2, stgHotkeys.RowCount - 1] := HMControl.Name + ';';
|
||||
HotkeyItem := SetObject(stgHotkeys.RowCount - 1, hotkey);
|
||||
AddString(HotkeyItem^.Controls, HMControl.Name);
|
||||
|
|
@ -498,7 +496,8 @@ end;
|
|||
procedure TfrmOptionsHotkeys.FillCommandList(Filter: String);
|
||||
//< fill stgCommands with commands and descriptions
|
||||
var
|
||||
slTmp, slAllCommands, slDescriptions, slHotKey: TStringList;
|
||||
slTmp: THotkeys;
|
||||
slAllCommands, slDescriptions, slHotKey: TStringList;
|
||||
slFiltered: TStringList = nil;
|
||||
lstr: String;
|
||||
i: Integer;
|
||||
|
|
@ -538,7 +537,7 @@ begin
|
|||
slAllCommands := TStringList.Create;
|
||||
slDescriptions := TStringList.Create;
|
||||
slHotKey := TStringList.Create;
|
||||
slTmp := TStringList.Create;
|
||||
slTmp := THotkeys.Create(False);
|
||||
HMForm := HotMan.Forms.Find(sForm);
|
||||
|
||||
CommandsIntf.GetCommandsList(slAllCommands);
|
||||
|
|
@ -573,7 +572,7 @@ begin
|
|||
begin
|
||||
slTmp.Clear;
|
||||
GetHotKeyList(HMForm, slFiltered.Strings[i], slTmp);
|
||||
slHotKey.Add(StListToStr(';', slTmp, false)); //add to hotkey list created string
|
||||
slHotKey.Add(HotkeysToString(slTmp)); //add to hotkey list created string
|
||||
end
|
||||
else
|
||||
slHotKey.Add('');
|
||||
|
|
@ -706,6 +705,22 @@ begin
|
|||
gNameSCFile := lbSCFilesList.Items[lbSCFilesList.ItemIndex];
|
||||
end;
|
||||
|
||||
procedure TfrmOptionsHotkeys.SelectHotkey(Hotkey: THotkey);
|
||||
var
|
||||
HotkeyItem: PHotkeyItem;
|
||||
i: Integer;
|
||||
begin
|
||||
for i := stgHotkeys.FixedRows to stgHotkeys.RowCount - 1 do
|
||||
begin
|
||||
HotkeyItem := PHotkeyItem(stgHotkeys.Objects[0, i]);
|
||||
if Assigned(HotkeyItem) and HotkeyItem^.Hotkey.SameAs(Hotkey) then
|
||||
begin
|
||||
stgHotkeys.Row := i;
|
||||
Break;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TfrmOptionsHotkeys.ShowEditHotkeyForm(EditMode: Boolean; aHotkeyRow: Integer);
|
||||
var
|
||||
HotkeyItem: PHotkeyItem;
|
||||
|
|
@ -727,6 +742,7 @@ procedure TfrmOptionsHotkeys.ShowEditHotkeyForm(
|
|||
const AControls: TDynamicStringArray);
|
||||
var
|
||||
HMForm: THMForm;
|
||||
Hotkey: THotkey = nil;
|
||||
begin
|
||||
if AForm <> EmptyStr then
|
||||
begin
|
||||
|
|
@ -741,8 +757,13 @@ begin
|
|||
Self.UpdateHotkeys(HMForm);
|
||||
Self.FillHotkeyList(ACommand);
|
||||
|
||||
// Select the new shortcut in the hotkeys table.
|
||||
stgHotkeys.Row := stgHotkeys.Cols[0].IndexOf(FEditForm.NewShortcut);
|
||||
Hotkey := FEditForm.CloneNewHotkey;
|
||||
try
|
||||
// Select the new shortcut in the hotkeys table.
|
||||
SelectHotkey(Hotkey);
|
||||
finally
|
||||
Hotkey.Free;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
|
@ -764,7 +785,7 @@ procedure TfrmOptionsHotkeys.AddDeleteWithShiftHotkey(UseTrash: Boolean);
|
|||
var
|
||||
ShiftState: TShiftState;
|
||||
begin
|
||||
Shortcut := TextToShortCutEx(Hotkey.Shortcut);
|
||||
Shortcut := TextToShortCutEx(Hotkey.Shortcuts[0]);
|
||||
ShiftState := ShortcutToShiftEx(Shortcut);
|
||||
if ssShift in ShiftState then
|
||||
ShiftState := ShiftState - [ssShift]
|
||||
|
|
@ -782,7 +803,7 @@ procedure TfrmOptionsHotkeys.AddDeleteWithShiftHotkey(UseTrash: Boolean);
|
|||
begin
|
||||
if Contains(Hotkey.Params, OldTrashParam) or NewTrashParam then
|
||||
begin
|
||||
Result := ConfirmFix(Hotkey, Format(rsOptHotkeysDeleteTrashCanOverrides, [Hotkey.Shortcut]));
|
||||
Result := ConfirmFix(Hotkey, Format(rsOptHotkeysDeleteTrashCanOverrides, [Hotkey.Shortcuts[0]]));
|
||||
if Result then
|
||||
begin
|
||||
DeleteString(Hotkey.Params, OldTrashParam);
|
||||
|
|
@ -808,7 +829,7 @@ procedure TfrmOptionsHotkeys.AddDeleteWithShiftHotkey(UseTrash: Boolean);
|
|||
begin
|
||||
if ContainsOneOf(Hotkey.Params, ParamsToDelete) or
|
||||
(HasTrashCan and (TrashStr <> NewTrashParam)) then
|
||||
if not ConfirmFix(Hotkey, Format(rsOptHotkeysDeleteTrashCanParameterExists, [Hotkey.Shortcut, NonReversedHotkey.Shortcut])) then
|
||||
if not ConfirmFix(Hotkey, Format(rsOptHotkeysDeleteTrashCanParameterExists, [Hotkey.Shortcuts[0], NonReversedHotkey.Shortcuts[0]])) then
|
||||
Exit;
|
||||
|
||||
for sDelete in ParamsToDelete do
|
||||
|
|
@ -834,93 +855,104 @@ procedure TfrmOptionsHotkeys.AddDeleteWithShiftHotkey(UseTrash: Boolean);
|
|||
for i := 0 to CountBeforeAdded - 1 do
|
||||
begin
|
||||
if (Hotkeys[i].Command = 'cm_Delete') and
|
||||
not Contains(CheckedShortcuts, Hotkeys[i].Shortcut) then
|
||||
(Length(Hotkeys[i].Shortcuts) > 0) then
|
||||
begin
|
||||
ReversedHotkey := nil;
|
||||
SetShortcut := True;
|
||||
ReverseShift(Hotkeys[i], Shortcut, TextShortcut);
|
||||
AddString(CheckedShortcuts, TextShortcut);
|
||||
|
||||
// Check if shortcut with reversed shift already exists.
|
||||
for j := 0 to CountBeforeAdded - 1 do
|
||||
if Length(Hotkeys[i].Shortcuts) > 1 then
|
||||
begin
|
||||
if Hotkeys[j].Shortcut = TextShortcut then
|
||||
begin
|
||||
if Hotkeys[j].Command <> Hotkeys[i].Command then
|
||||
begin
|
||||
if QuestionDlg(rsOptHotkeysCannotSetShortcut,
|
||||
Format(rsOptHotkeysShortcutForDeleteAlreadyAssigned,
|
||||
[Hotkeys[i].Shortcut, TextShortcut, Hotkeys[j].Command]),
|
||||
mtConfirmation, [mrYes, rsOptHotkeysChangeShortcut, 'isdefault', mrCancel], 0) = mrYes then
|
||||
begin
|
||||
Hotkeys[j].Command := Hotkeys[i].Command;
|
||||
end
|
||||
else
|
||||
SetShortcut := False;
|
||||
end;
|
||||
|
||||
ReversedHotkey := Hotkeys[j];
|
||||
Break;
|
||||
end;
|
||||
MessageDlg(rsOptHotkeysCannotSetShortcut,
|
||||
Format(rsOptHotkeysShortcutForDeleteIsSequence, [ShortcutsToText(Hotkeys[i].Shortcuts)]),
|
||||
mtWarning, [mbOK], 0);
|
||||
Continue;
|
||||
end;
|
||||
|
||||
if not SetShortcut then
|
||||
Continue;
|
||||
|
||||
// Fix parameters of original hotkey if needed.
|
||||
HasTrashCan := GetParamValue(Hotkeys[i].Params, 'trashcan', TrashStr);
|
||||
HasTrashBool := HasTrashCan and GetBoolValue(TrashStr, TrashBoolValue);
|
||||
if not FixOverrides(Hotkeys[i], 'recycle', HasTrashBool and TrashBoolValue, UseTrash) then
|
||||
Continue;
|
||||
if not FixOverrides(Hotkeys[i], 'norecycle', HasTrashBool and not TrashBoolValue, not UseTrash) then
|
||||
Continue;
|
||||
|
||||
// Reverse trash setting for reversed hotkey.
|
||||
NewParams := Copy(Hotkeys[i].Params);
|
||||
HasTrashCan := GetParamValue(NewParams, 'trashcan', TrashStr); // Could have been added above so check again
|
||||
if Contains(NewParams, 'recyclesettingrev') then
|
||||
if not Contains(CheckedShortcuts, Hotkeys[i].Shortcuts[0]) then
|
||||
begin
|
||||
DeleteString(NewParams, 'recyclesettingrev');
|
||||
NormalTrashSetting := True;
|
||||
end
|
||||
else if Contains(NewParams, 'recyclesetting') then
|
||||
begin
|
||||
DeleteString(NewParams, 'recyclesetting');
|
||||
NormalTrashSetting := False;
|
||||
end
|
||||
else if HasTrashCan and (TrashStr = 'reversesetting') then
|
||||
NormalTrashSetting := True
|
||||
else
|
||||
NormalTrashSetting := False;
|
||||
ReversedHotkey := nil;
|
||||
SetShortcut := True;
|
||||
ReverseShift(Hotkeys[i], Shortcut, TextShortcut);
|
||||
AddString(CheckedShortcuts, TextShortcut);
|
||||
|
||||
if Assigned(ReversedHotkey) then
|
||||
begin
|
||||
HasTrashCan := GetParamValue(ReversedHotkey.Params, 'trashcan', TrashStr);
|
||||
|
||||
if NormalTrashSetting then
|
||||
// Check if shortcut with reversed shift already exists.
|
||||
for j := 0 to CountBeforeAdded - 1 do
|
||||
begin
|
||||
FixReversedShortcut(ReversedHotkey, Hotkeys[i],
|
||||
['recyclesettingrev', 'recycle', 'norecycle'],
|
||||
'recyclesetting', 'setting', HasTrashCan, TrashStr);
|
||||
end
|
||||
else
|
||||
begin
|
||||
FixReversedShortcut(ReversedHotkey, Hotkeys[i],
|
||||
['recyclesetting', 'recycle', 'norecycle'],
|
||||
'recyclesettingrev', 'reversesetting', HasTrashCan, TrashStr);
|
||||
if ArrBegins(Hotkeys[j].Shortcuts, [TextShortcut], False) then
|
||||
begin
|
||||
if Hotkeys[j].Command <> Hotkeys[i].Command then
|
||||
begin
|
||||
if QuestionDlg(rsOptHotkeysCannotSetShortcut,
|
||||
Format(rsOptHotkeysShortcutForDeleteAlreadyAssigned,
|
||||
[Hotkeys[i].Shortcuts[0], TextShortcut, Hotkeys[j].Command]),
|
||||
mtConfirmation, [mrYes, rsOptHotkeysChangeShortcut, 'isdefault', mrCancel], 0) = mrYes then
|
||||
begin
|
||||
Hotkeys[j].Command := Hotkeys[i].Command;
|
||||
end
|
||||
else
|
||||
SetShortcut := False;
|
||||
end;
|
||||
|
||||
ReversedHotkey := Hotkeys[j];
|
||||
Break;
|
||||
end;
|
||||
end;
|
||||
end
|
||||
else if QuestionDlg(rsOptHotkeysSetDeleteShortcut,
|
||||
Format(rsOptHotkeysAddDeleteShortcutLong, [TextShortcut]),
|
||||
mtConfirmation, [mrYes, rsOptHotkeysAddShortcutButton, 'isdefault', mrCancel], 0) = mrYes then
|
||||
begin
|
||||
if NormalTrashSetting then
|
||||
TrashStr := 'setting'
|
||||
else
|
||||
TrashStr := 'reversesetting';
|
||||
SetValue(NewParams, 'trashcan', TrashStr);
|
||||
|
||||
Hotkeys.Add(TextShortcut, Hotkeys[i].Command, NewParams);
|
||||
if not SetShortcut then
|
||||
Continue;
|
||||
|
||||
// Fix parameters of original hotkey if needed.
|
||||
HasTrashCan := GetParamValue(Hotkeys[i].Params, 'trashcan', TrashStr);
|
||||
HasTrashBool := HasTrashCan and GetBoolValue(TrashStr, TrashBoolValue);
|
||||
if not FixOverrides(Hotkeys[i], 'recycle', HasTrashBool and TrashBoolValue, UseTrash) then
|
||||
Continue;
|
||||
if not FixOverrides(Hotkeys[i], 'norecycle', HasTrashBool and not TrashBoolValue, not UseTrash) then
|
||||
Continue;
|
||||
|
||||
// Reverse trash setting for reversed hotkey.
|
||||
NewParams := Copy(Hotkeys[i].Params);
|
||||
HasTrashCan := GetParamValue(NewParams, 'trashcan', TrashStr); // Could have been added above so check again
|
||||
if Contains(NewParams, 'recyclesettingrev') then
|
||||
begin
|
||||
DeleteString(NewParams, 'recyclesettingrev');
|
||||
NormalTrashSetting := True;
|
||||
end
|
||||
else if Contains(NewParams, 'recyclesetting') then
|
||||
begin
|
||||
DeleteString(NewParams, 'recyclesetting');
|
||||
NormalTrashSetting := False;
|
||||
end
|
||||
else if HasTrashCan and (TrashStr = 'reversesetting') then
|
||||
NormalTrashSetting := True
|
||||
else
|
||||
NormalTrashSetting := False;
|
||||
|
||||
if Assigned(ReversedHotkey) then
|
||||
begin
|
||||
HasTrashCan := GetParamValue(ReversedHotkey.Params, 'trashcan', TrashStr);
|
||||
|
||||
if NormalTrashSetting then
|
||||
begin
|
||||
FixReversedShortcut(ReversedHotkey, Hotkeys[i],
|
||||
['recyclesettingrev', 'recycle', 'norecycle'],
|
||||
'recyclesetting', 'setting', HasTrashCan, TrashStr);
|
||||
end
|
||||
else
|
||||
begin
|
||||
FixReversedShortcut(ReversedHotkey, Hotkeys[i],
|
||||
['recyclesetting', 'recycle', 'norecycle'],
|
||||
'recyclesettingrev', 'reversesetting', HasTrashCan, TrashStr);
|
||||
end;
|
||||
end
|
||||
else if QuestionDlg(rsOptHotkeysSetDeleteShortcut,
|
||||
Format(rsOptHotkeysAddDeleteShortcutLong, [TextShortcut]),
|
||||
mtConfirmation, [mrYes, rsOptHotkeysAddShortcutButton, 'isdefault', mrCancel], 0) = mrYes then
|
||||
begin
|
||||
if NormalTrashSetting then
|
||||
TrashStr := 'setting'
|
||||
else
|
||||
TrashStr := 'reversesetting';
|
||||
SetValue(NewParams, 'trashcan', TrashStr);
|
||||
|
||||
Hotkeys.Add([TextShortcut], NewParams, Hotkeys[i].Command);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
|
|
|||
|
|
@ -422,6 +422,23 @@ procedure UpdateColor(Control: TControl; Checked: Boolean);
|
|||
procedure EnableControl(Control: TControl; Enabled: Boolean);
|
||||
|
||||
procedure AddString(var anArray: TDynamicStringArray; const sToAdd: String);
|
||||
{en
|
||||
Checks if the second array is the beginning of first.
|
||||
If BothWays is @true then also checks the other way around,
|
||||
if the first array is the beginning of second.
|
||||
For Array1=[1,2] Array2=[1,2] returns @true.
|
||||
For Array1=[1,2,...] Array2=[1,2] returns @true.
|
||||
For Array1=[1,3,...] Array2=[1,2] returns @false.
|
||||
If BothWays = True then also
|
||||
For Array1=[1] Array2=[1,2] returns @true.
|
||||
For Array1=[1] Array2=[2] returns @false.
|
||||
}
|
||||
function ArrBegins(const Array1, Array2: array of String; BothWays: Boolean): Boolean;
|
||||
function ArrayToString(const anArray: TDynamicStringArray; const Separator: Char = ' '): String;
|
||||
{en
|
||||
Compares length and contents of the arrays.
|
||||
If lengths differ or individual elements differ returns @false, otherwise @true.
|
||||
}
|
||||
function Compare(const Array1, Array2: array of String): Boolean;
|
||||
{en
|
||||
Copies open array to dynamic array.
|
||||
|
|
@ -436,6 +453,7 @@ procedure DeleteString(var anArray: TDynamicStringArray; const sToDelete: String
|
|||
}
|
||||
procedure SetValue(var anArray: TDynamicStringArray; Key, NewValue: String);
|
||||
procedure SetValue(var anArray: TDynamicStringArray; Key: String; NewValue: Boolean);
|
||||
function ShortcutsToText(const Shortcuts: TDynamicStringArray): String;
|
||||
|
||||
implementation
|
||||
|
||||
|
|
@ -1784,6 +1802,35 @@ begin
|
|||
anArray[Len] := sToAdd;
|
||||
end;
|
||||
|
||||
function ArrBegins(const Array1, Array2: array of String; BothWays: Boolean): Boolean;
|
||||
var
|
||||
Len1, Len2: Integer;
|
||||
i: Integer;
|
||||
begin
|
||||
Len1 := Length(Array1);
|
||||
Len2 := Length(Array2);
|
||||
if not BothWays and (Len1 < Len2) then
|
||||
Result := False
|
||||
else
|
||||
begin
|
||||
if Len1 > Len2 then
|
||||
Len1 := Len2;
|
||||
for i := 0 to Len1 - 1 do
|
||||
if Array1[i] <> Array2[i] then
|
||||
Exit(False);
|
||||
Result := True;
|
||||
end;
|
||||
end;
|
||||
|
||||
function ArrayToString(const anArray: TDynamicStringArray; const Separator: Char): String;
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
Result := '';
|
||||
for i := Low(anArray) to High(anArray) do
|
||||
AddStrWithSep(Result, anArray[i], Separator);
|
||||
end;
|
||||
|
||||
function Compare(const Array1, Array2: array of String): Boolean;
|
||||
var
|
||||
Len1, Len2: Integer;
|
||||
|
|
@ -1876,5 +1923,10 @@ begin
|
|||
SetValue(anArray, Key, 'false');
|
||||
end;
|
||||
|
||||
function ShortcutsToText(const Shortcuts: TDynamicStringArray): String;
|
||||
begin
|
||||
Result := ArrayToString(Shortcuts, ' ');
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
|
|
|
|||
150
src/uglobs.pas
150
src/uglobs.pas
|
|
@ -90,7 +90,7 @@ type
|
|||
|
||||
const
|
||||
{ Default hotkey list version number }
|
||||
hkVersion = 9;
|
||||
hkVersion = 10;
|
||||
|
||||
// Previously existing names if reused must check for ConfigVersion >= X.
|
||||
// History:
|
||||
|
|
@ -389,95 +389,95 @@ begin
|
|||
HMForm := HotMan.Forms.FindOrCreate('Main');
|
||||
with HMForm.Hotkeys do
|
||||
begin
|
||||
AddIfNotExists('F1','cm_About',[]);
|
||||
AddIfNotExists('F2','cm_RenameOnly',[]);
|
||||
AddIfNotExists('F3','cm_View',[]);
|
||||
AddIfNotExists('F4','cm_Edit',[]);
|
||||
AddIfNotExists('F5','cm_Copy',[]);
|
||||
AddIfNotExists('F6','cm_Rename',[]);
|
||||
AddIfNotExists('F7','cm_MakeDir',[]);
|
||||
AddIfNotExists(['F8','',
|
||||
'Shift+F8','trashcan=reversesetting',''], 'cm_Delete');
|
||||
AddIfNotExists('F9','cm_RunTerm',[]);
|
||||
AddIfNotExists('Ctrl+7','cm_ShowCmdLineHistory',[]);
|
||||
AddIfNotExists('Ctrl+D','cm_DirHotList',[]);
|
||||
AddIfNotExists('Ctrl+F','cm_QuickFilter',[]);
|
||||
AddIfNotExists('Ctrl+H','cm_DirHistory',[]);
|
||||
AddIfNotExists('Ctrl+L','cm_CalculateSpace',[]);
|
||||
AddIfNotExists('Ctrl+M','cm_MultiRename',[]);
|
||||
AddIfNotExists('Ctrl+P','cm_AddPathToCmdLine',[]);
|
||||
AddIfNotExists('Ctrl+Q','cm_QuickView',[]);
|
||||
AddIfNotExists('Ctrl+S','cm_QuickSearch',[]);
|
||||
AddIfNotExists('Ctrl+R','cm_Refresh',[]);
|
||||
AddIfNotExists('Ctrl+T','cm_NewTab',[]);
|
||||
AddIfNotExists('Ctrl+U','cm_Exchange',[]);
|
||||
AddIfNotExists('Ctrl+W','cm_RemoveTab',[]);
|
||||
AddIfNotExists('Ctrl+Z','cm_EditComment',[]);
|
||||
AddIfNotExists('Ctrl+F3','cm_SortByName',[]);
|
||||
AddIfNotExists('Ctrl+F4','cm_SortByExt',[]);
|
||||
AddIfNotExists('Ctrl+F5','cm_SortByDate',[]);
|
||||
AddIfNotExists('Ctrl+F6','cm_SortBySize',[]);
|
||||
AddIfNotExists('Ctrl+Down','cm_ShowCmdLineHistory',[]);
|
||||
AddIfNotExists('Ctrl+Enter','cm_AddFilenameToCmdLine',[]);
|
||||
AddIfNotExists('Ctrl+PgDn','cm_OpenArchive',[]);
|
||||
AddIfNotExists('Ctrl+PgUp','cm_ChangeDirToParent',[]);
|
||||
AddIfNotExists('Ctrl+Shift+C','cm_CopyFullNamesToClip',[]);
|
||||
AddIfNotExists('Ctrl+Shift+H','cm_HorizontalFilePanels',[]);
|
||||
AddIfNotExists('Ctrl+Shift+X','cm_CopyNamesToClip',[]);
|
||||
AddIfNotExists('Ctrl+Shift+Enter','cm_AddPathAndFilenameToCmdLine',[]);
|
||||
AddIfNotExists('Ctrl+Shift+Tab','cm_PrevTab',[]);
|
||||
AddIfNotExists('Ctrl+Tab','cm_NextTab',[]);
|
||||
AddIfNotExists('Ctrl+Up','cm_OpenDirInNewTab',[]);
|
||||
AddIfNotExists('Ctrl+\','cm_ChangeDirToRoot',[]);
|
||||
AddIfNotExists('Ctrl+.','cm_ShowSysFiles',[]);
|
||||
AddIfNotExists('Shift+F2','cm_FocusCmdLine',[]);
|
||||
AddIfNotExists('Shift+F4','cm_EditNew',[]);
|
||||
AddIfNotExists('Shift+F5','cm_CopySamePanel',[]);
|
||||
AddIfNotExists('Shift+F6','cm_RenameOnly',[]);
|
||||
AddIfNotExists('Shift+F10','cm_ContextMenu',[]);
|
||||
AddIfNotExists('Alt+V','cm_OperationsViewer',[]);
|
||||
AddIfNotExists('Alt+X','cm_Exit',[]);
|
||||
AddIfNotExists('Alt+Z','cm_TargetEqualSource',[]);
|
||||
AddIfNotExists('Alt+F1','cm_LeftOpenDrives',[]);
|
||||
AddIfNotExists('Alt+F2','cm_RightOpenDrives',[]);
|
||||
AddIfNotExists('Alt+F5','cm_PackFiles',[]);
|
||||
AddIfNotExists('Alt+F7','cm_Search',[]);
|
||||
AddIfNotExists('Alt+F9','cm_ExtractFiles',[]);
|
||||
AddIfNotExists('Alt+Del','cm_Wipe',[]);
|
||||
AddIfNotExists('Alt+Down','cm_DirHistory',[]);
|
||||
AddIfNotExists('Alt+Enter','cm_FileProperties',[]);
|
||||
AddIfNotExists('Alt+Left','cm_ViewHistoryPrev',[]);
|
||||
AddIfNotExists('Alt+Right','cm_ViewHistoryNext',[]);
|
||||
AddIfNotExists('Alt+Shift+Enter','cm_CountDirContent',[]);
|
||||
AddIfNotExists('Alt+Shift+F9','cm_TestArchive',[]);
|
||||
AddIfNotExists(['F1'],[],'cm_About');
|
||||
AddIfNotExists(['F2'],[],'cm_RenameOnly');
|
||||
AddIfNotExists(['F3'],[],'cm_View');
|
||||
AddIfNotExists(['F4'],[],'cm_Edit');
|
||||
AddIfNotExists(['F5'],[],'cm_Copy');
|
||||
AddIfNotExists(['F6'],[],'cm_Rename');
|
||||
AddIfNotExists(['F7'],[],'cm_MakeDir');
|
||||
AddIfNotExists(['F8','','',
|
||||
'Shift+F8','','trashcan=reversesetting',''], 'cm_Delete');
|
||||
AddIfNotExists(['F9'],[],'cm_RunTerm');
|
||||
AddIfNotExists(['Ctrl+7'],[],'cm_ShowCmdLineHistory');
|
||||
AddIfNotExists(['Ctrl+D'],[],'cm_DirHotList');
|
||||
AddIfNotExists(['Ctrl+F'],[],'cm_QuickFilter');
|
||||
AddIfNotExists(['Ctrl+H'],[],'cm_DirHistory');
|
||||
AddIfNotExists(['Ctrl+L'],[],'cm_CalculateSpace');
|
||||
AddIfNotExists(['Ctrl+M'],[],'cm_MultiRename');
|
||||
AddIfNotExists(['Ctrl+P'],[],'cm_AddPathToCmdLine');
|
||||
AddIfNotExists(['Ctrl+Q'],[],'cm_QuickView');
|
||||
AddIfNotExists(['Ctrl+S'],[],'cm_QuickSearch');
|
||||
AddIfNotExists(['Ctrl+R'],[],'cm_Refresh');
|
||||
AddIfNotExists(['Ctrl+T'],[],'cm_NewTab');
|
||||
AddIfNotExists(['Ctrl+U'],[],'cm_Exchange');
|
||||
AddIfNotExists(['Ctrl+W'],[],'cm_RemoveTab');
|
||||
AddIfNotExists(['Ctrl+Z'],[],'cm_EditComment');
|
||||
AddIfNotExists(['Ctrl+F3'],[],'cm_SortByName');
|
||||
AddIfNotExists(['Ctrl+F4'],[],'cm_SortByExt');
|
||||
AddIfNotExists(['Ctrl+F5'],[],'cm_SortByDate');
|
||||
AddIfNotExists(['Ctrl+F6'],[],'cm_SortBySize');
|
||||
AddIfNotExists(['Ctrl+Down'],[],'cm_ShowCmdLineHistory');
|
||||
AddIfNotExists(['Ctrl+Enter'],[],'cm_AddFilenameToCmdLine');
|
||||
AddIfNotExists(['Ctrl+PgDn'],[],'cm_OpenArchive');
|
||||
AddIfNotExists(['Ctrl+PgUp'],[],'cm_ChangeDirToParent');
|
||||
AddIfNotExists(['Ctrl+Shift+C'],[],'cm_CopyFullNamesToClip');
|
||||
AddIfNotExists(['Ctrl+Shift+H'],[],'cm_HorizontalFilePanels');
|
||||
AddIfNotExists(['Ctrl+Shift+X'],[],'cm_CopyNamesToClip');
|
||||
AddIfNotExists(['Ctrl+Shift+Enter'],[],'cm_AddPathAndFilenameToCmdLine');
|
||||
AddIfNotExists(['Ctrl+Shift+Tab'],[],'cm_PrevTab');
|
||||
AddIfNotExists(['Ctrl+Tab'],[],'cm_NextTab');
|
||||
AddIfNotExists(['Ctrl+Up'],[],'cm_OpenDirInNewTab');
|
||||
AddIfNotExists(['Ctrl+\'],[],'cm_ChangeDirToRoot');
|
||||
AddIfNotExists(['Ctrl+.'],[],'cm_ShowSysFiles');
|
||||
AddIfNotExists(['Shift+F2'],[],'cm_FocusCmdLine');
|
||||
AddIfNotExists(['Shift+F4'],[],'cm_EditNew');
|
||||
AddIfNotExists(['Shift+F5'],[],'cm_CopySamePanel');
|
||||
AddIfNotExists(['Shift+F6'],[],'cm_RenameOnly');
|
||||
AddIfNotExists(['Shift+F10'],[],'cm_ContextMenu');
|
||||
AddIfNotExists(['Alt+V'],[],'cm_OperationsViewer');
|
||||
AddIfNotExists(['Alt+X'],[],'cm_Exit');
|
||||
AddIfNotExists(['Alt+Z'],[],'cm_TargetEqualSource');
|
||||
AddIfNotExists(['Alt+F1'],[],'cm_LeftOpenDrives');
|
||||
AddIfNotExists(['Alt+F2'],[],'cm_RightOpenDrives');
|
||||
AddIfNotExists(['Alt+F5'],[],'cm_PackFiles');
|
||||
AddIfNotExists(['Alt+F7'],[],'cm_Search');
|
||||
AddIfNotExists(['Alt+F9'],[],'cm_ExtractFiles');
|
||||
AddIfNotExists(['Alt+Del'],[],'cm_Wipe');
|
||||
AddIfNotExists(['Alt+Down'],[],'cm_DirHistory');
|
||||
AddIfNotExists(['Alt+Enter'],[],'cm_FileProperties');
|
||||
AddIfNotExists(['Alt+Left'],[],'cm_ViewHistoryPrev');
|
||||
AddIfNotExists(['Alt+Right'],[],'cm_ViewHistoryNext');
|
||||
AddIfNotExists(['Alt+Shift+Enter'],[],'cm_CountDirContent');
|
||||
AddIfNotExists(['Alt+Shift+F9'],[],'cm_TestArchive');
|
||||
end;
|
||||
|
||||
HMControl := HMForm.Controls.FindOrCreate('Files Panel');
|
||||
with HMControl.Hotkeys do
|
||||
begin
|
||||
AddIfNotExists(['Del','',
|
||||
'Shift+Del','trashcan=reversesetting',''], 'cm_Delete');
|
||||
AddIfNotExists('Ctrl+A','cm_MarkMarkAll',[]);
|
||||
AddIfNotExists('Ctrl+C','cm_CopyToClipboard',[]);
|
||||
AddIfNotExists('Ctrl+V','cm_PasteFromClipboard',[]);
|
||||
AddIfNotExists('Ctrl+X','cm_CutToClipboard',[]);
|
||||
AddIfNotExists('Ctrl+Left','cm_TransferLeft',[]);
|
||||
AddIfNotExists('Ctrl+Right','cm_TransferRight',[]);
|
||||
AddIfNotExists(['Del','','',
|
||||
'Shift+Del','','trashcan=reversesetting',''], 'cm_Delete');
|
||||
AddIfNotExists(['Ctrl+A'],[],'cm_MarkMarkAll');
|
||||
AddIfNotExists(['Ctrl+C'],[],'cm_CopyToClipboard');
|
||||
AddIfNotExists(['Ctrl+V'],[],'cm_PasteFromClipboard');
|
||||
AddIfNotExists(['Ctrl+X'],[],'cm_CutToClipboard');
|
||||
AddIfNotExists(['Ctrl+Left'],[],'cm_TransferLeft');
|
||||
AddIfNotExists(['Ctrl+Right'],[],'cm_TransferRight');
|
||||
end;
|
||||
|
||||
HMForm := HotMan.Forms.FindOrCreate('Viewer');
|
||||
with HMForm.Hotkeys do
|
||||
begin
|
||||
AddIfNotExists('F1','cm_About',[]);
|
||||
AddIfNotExists('F2','cm_Reload',[]);
|
||||
AddIfNotExists('N','cm_LoadNextFile',[]);
|
||||
AddIfNotExists('P','cm_LoadPrevFile',[]);
|
||||
AddIfNotExists(['F1'],[],'cm_About');
|
||||
AddIfNotExists(['F2'],[],'cm_Reload');
|
||||
AddIfNotExists(['N'],[],'cm_LoadNextFile');
|
||||
AddIfNotExists(['P'],[],'cm_LoadPrevFile');
|
||||
end;
|
||||
|
||||
HMForm := HotMan.Forms.FindOrCreate('Copy/Move Dialog');
|
||||
with HMForm.Hotkeys do
|
||||
begin
|
||||
AddIfNotExists('F2','cm_AddToQueue',[]);
|
||||
AddIfNotExists(['F2'],[],'cm_AddToQueue');
|
||||
end;
|
||||
|
||||
if not mbFileExists(gpCfgDir + gNameSCFile) then
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ interface
|
|||
|
||||
uses
|
||||
Classes, SysUtils, Controls, LCLProc, LCLType, LCLIntf, Forms, ActnList,
|
||||
uClassesEx, fgl, contnrs, uXmlConfig;
|
||||
uClassesEx, fgl, contnrs, uXmlConfig, uTypes;
|
||||
|
||||
type
|
||||
generic THMObjectInstance<InstanceClass> = class
|
||||
|
|
@ -45,13 +45,15 @@ type
|
|||
{ THotkey }
|
||||
|
||||
THotkey = class
|
||||
Shortcut: String;
|
||||
Shortcuts: array of String;
|
||||
Command: String;
|
||||
Params: array of String;
|
||||
function Clone: THotkey;
|
||||
function HasParam(const aParam: String): Boolean; overload;
|
||||
function HasParam(const aParams: array of String): Boolean; overload;
|
||||
function SameAs(Hotkey: THotkey): Boolean;
|
||||
function SameParams(const aParams: array of String): Boolean;
|
||||
function SameShortcuts(const aShortcuts: array of String): Boolean;
|
||||
end;
|
||||
|
||||
TBaseHotkeysList = specialize TFPGObjectList<THotkey>;
|
||||
|
|
@ -79,22 +81,29 @@ type
|
|||
procedure DoOnChange(hotkey: THotkey; operation: THotkeyOperation);
|
||||
public
|
||||
constructor Create(AFreeObjects: Boolean = True); reintroduce;
|
||||
function Add(Shortcut: String; Command: String; const Params: array of String): THotkey; overload;
|
||||
function AddIfNotExists(Shortcut: String; Command: String; const Params: array of String): THotkey; overload;
|
||||
function Add(const Shortcuts, Params: array of String; Command: String): THotkey; overload;
|
||||
function AddIfNotExists(const Shortcuts, Params: array of String; Command: String): THotkey; overload;
|
||||
{en
|
||||
Adds multiple shortcuts to the same command.
|
||||
@param(ShortcutsWithParams
|
||||
Array of shortcuts followed by any number of parameters.
|
||||
Each shortcut+parameters needs to end with an empty string.
|
||||
[Shortcut1, S1Param1, '', Shortcut2, S2Param1, S2Param2, '', ...])
|
||||
Each shortcuts array must end with an empty string,
|
||||
and similarly each parameters must end with an empty string.
|
||||
[Shortcut1A, Shortcut1B, '', S1ParamA, '',
|
||||
Shortcut2, '', S2ParamA, S2ParamB, '', ...])
|
||||
@param(Command
|
||||
Command to which the shortcuts should be added.)
|
||||
}
|
||||
procedure AddIfNotExists(const ShortcutsWithParams: array of String; Command: String);
|
||||
procedure Clear;
|
||||
procedure Delete(Shortcut: String); reintroduce;
|
||||
procedure Clear; reintroduce;
|
||||
procedure Remove(var hotkey: THotkey); reintroduce;
|
||||
function Find(Shortcut: String): THotkey; overload;
|
||||
function Find(const Shortcuts: TDynamicStringArray): THotkey;
|
||||
{en
|
||||
Find hotkey which shortcuts begin with Shortcuts parameter.
|
||||
If BothWays=@true then also looks for shortcuts which are the beginning
|
||||
of Shortcuts parameter.
|
||||
}
|
||||
function FindByBeginning(const Shortcuts: TDynamicStringArray; BothWays: Boolean): THotkey;
|
||||
function FindByCommand(Command: String): THotkey;
|
||||
function FindByContents(Hotkey: THotkey): THotkey;
|
||||
property OnChange: THotkeyEvent read FOnChange write FOnChange;
|
||||
|
|
@ -169,6 +178,9 @@ type
|
|||
THotKeyManager = class
|
||||
private
|
||||
FForms: THMForms;
|
||||
FLastShortcutTime: Double; // When last shortcut was received (used for sequences of shortcuts)
|
||||
FSequenceStep: Integer; // Which hotkey we are waiting for (from 0)
|
||||
FShortcutsSequence: TDynamicStringArray; // Sequence of shortcuts that has been processed since last key event
|
||||
FVersion: Integer;
|
||||
//---------------------
|
||||
procedure ClearAllHotkeys;
|
||||
|
|
@ -176,7 +188,7 @@ type
|
|||
procedure KeyDownHandler(Sender: TObject; var Key: Word; Shift: TShiftState);
|
||||
//---------------------
|
||||
//This function is called from KeyDownHandler to find registered hotkey and execute assigned action
|
||||
function HotKeyEvent(Form: TCustomForm; Shortcut: String; Hotkeys: THotkeys): Boolean;
|
||||
function HotKeyEvent(Form: TCustomForm; Hotkeys: THotkeys): Boolean;
|
||||
//---------------------
|
||||
function RegisterForm(AFormName: String): THMForm;
|
||||
function RegisterControl(AFormName: String; AControlName: String): THMControl;
|
||||
|
|
@ -208,12 +220,15 @@ uses
|
|||
XMLRead, uKeyboard, uGlobs, uDebug, uOSUtils, uDCUtils, uDCVersion,
|
||||
uFormCommands;
|
||||
|
||||
const
|
||||
MaxShortcutSequenceInterval = 1000; // in ms
|
||||
|
||||
{ THotkey }
|
||||
|
||||
function THotkey.Clone: THotkey;
|
||||
begin
|
||||
Result := THotkey.Create;
|
||||
Result.Shortcut := Shortcut;
|
||||
Result.Shortcuts := Copy(Shortcuts);
|
||||
Result.Command := Command;
|
||||
Result.Params := Copy(Params);
|
||||
end;
|
||||
|
|
@ -228,11 +243,23 @@ begin
|
|||
Result := Contains(Params, aParam);
|
||||
end;
|
||||
|
||||
function THotkey.SameAs(Hotkey: THotkey): Boolean;
|
||||
begin
|
||||
Result := (Command = Hotkey.Command) and
|
||||
(SameShortcuts(Hotkey.Shortcuts)) and
|
||||
(SameParams(Hotkey.Params));
|
||||
end;
|
||||
|
||||
function THotkey.SameParams(const aParams: array of String): Boolean;
|
||||
begin
|
||||
Result := Compare(Params, aParams);
|
||||
end;
|
||||
|
||||
function THotkey.SameShortcuts(const aShortcuts: array of String): Boolean;
|
||||
begin
|
||||
Result := Compare(Shortcuts, aShortcuts);
|
||||
end;
|
||||
|
||||
{ TFreeNotifier }
|
||||
|
||||
procedure TFreeNotifier.Notification(AComponent: TComponent; Operation: TOperation);
|
||||
|
|
@ -250,56 +277,77 @@ begin
|
|||
inherited Create(AFreeObjects);
|
||||
end;
|
||||
|
||||
function THotkeys.Add(Shortcut: String; Command: String; const Params: array of String): THotkey;
|
||||
function THotkeys.Add(const Shortcuts, Params: array of String; Command: String): THotkey;
|
||||
begin
|
||||
Result := THotkey.Create;
|
||||
Result.Shortcut := Shortcut;
|
||||
Result.Command := Command;
|
||||
Result.Params := CopyArray(Params);
|
||||
Add(Result);
|
||||
DoOnChange(Result, hopAdd);
|
||||
if (Command <> EmptyStr) and (Length(Shortcuts) > 0) then
|
||||
begin
|
||||
Result := THotkey.Create;
|
||||
Result.Shortcuts := CopyArray(Shortcuts);
|
||||
Result.Params := CopyArray(Params);
|
||||
Result.Command := Command;
|
||||
Add(Result);
|
||||
DoOnChange(Result, hopAdd);
|
||||
end
|
||||
else
|
||||
Result := nil;
|
||||
end;
|
||||
|
||||
function THotkeys.AddIfNotExists(Shortcut: String; Command: String; const Params: array of String): THotkey;
|
||||
function THotkeys.AddIfNotExists(const Shortcuts, Params: array of String; Command: String): THotkey;
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
// Check if the shortcut isn't already assigned to a different command
|
||||
// Check if the shortcuts aren't already assigned to a different command
|
||||
// or if a different shortcut isn't already assigned to the command.
|
||||
// Also check if the shortucts aren't a partial match to another shortcuts.
|
||||
for i := 0 to Count - 1 do
|
||||
begin
|
||||
if (Items[i].Shortcut = Shortcut) or (Items[i].Command = Command) then
|
||||
if ArrBegins(Items[i].Shortcuts, Shortcuts, True) or (Items[i].Command = Command) then
|
||||
Exit(nil);
|
||||
end;
|
||||
Result := Add(Shortcut, Command, Params);
|
||||
Result := Add(Shortcuts, Params, Command);
|
||||
end;
|
||||
|
||||
procedure THotkeys.AddIfNotExists(const ShortcutsWithParams: array of String; Command: String);
|
||||
var
|
||||
s: String;
|
||||
ShortCut: String = '';
|
||||
Params: array of String = nil;
|
||||
StartIndex: Integer;
|
||||
|
||||
function GetArray: TDynamicStringArray;
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
Result := nil;
|
||||
for i := StartIndex to High(ShortcutsWithParams) do
|
||||
begin
|
||||
s := ShortcutsWithParams[i];
|
||||
if s <> '' then
|
||||
AddString(Result, s)
|
||||
else
|
||||
Break;
|
||||
end;
|
||||
Inc(StartIndex);
|
||||
end;
|
||||
var
|
||||
Shortcuts, Params: array of String;
|
||||
begin
|
||||
// Check if a different shortcut isn't already assigned to the command.
|
||||
if Assigned(FindByCommand(Command)) then
|
||||
Exit;
|
||||
|
||||
for s in ShortcutsWithParams do
|
||||
StartIndex := Low(ShortcutsWithParams);
|
||||
while True do
|
||||
begin
|
||||
if s = '' then
|
||||
Shortcuts := GetArray;
|
||||
Params := GetArray;
|
||||
|
||||
if Length(Shortcuts) > 0 then
|
||||
begin
|
||||
// Check if the shortcut isn't already assigned to a different command.
|
||||
if not Assigned(Find(ShortCut)) then
|
||||
Add(ShortCut, Command, Params);
|
||||
ShortCut := '';
|
||||
SetLength(Params, 0);
|
||||
// Check if the shortcuts aren't already assigned to a different command.
|
||||
if not Assigned(FindByBeginning(Shortcuts, True)) then
|
||||
Add(Shortcuts, Params, Command);
|
||||
end
|
||||
else if ShortCut = '' then
|
||||
ShortCut := s
|
||||
else
|
||||
begin
|
||||
AddString(Params, s);
|
||||
end;
|
||||
Break;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
|
@ -314,19 +362,6 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
procedure THotkeys.Delete(Shortcut: String);
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
for i := 0 to Count - 1 do
|
||||
if Items[i].ShortCut = Shortcut then
|
||||
begin
|
||||
DoOnChange(Items[i], hopRemove);
|
||||
inherited Delete(i);
|
||||
Exit;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure THotkeys.Remove(var hotkey: THotkey);
|
||||
begin
|
||||
if Assigned(hotkey) then
|
||||
|
|
@ -338,12 +373,22 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
function THotkeys.Find(Shortcut: String): THotkey;
|
||||
function THotkeys.Find(const Shortcuts: TDynamicStringArray): THotkey;
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
for i := 0 to Count - 1 do
|
||||
if Items[i].ShortCut = Shortcut then
|
||||
if Items[i].SameShortcuts(Shortcuts) then
|
||||
Exit(Items[i]);
|
||||
Result := nil;
|
||||
end;
|
||||
|
||||
function THotkeys.FindByBeginning(const Shortcuts: TDynamicStringArray; BothWays: Boolean): THotkey;
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
for i := 0 to Count - 1 do
|
||||
if ArrBegins(Items[i].Shortcuts, Shortcuts, BothWays) then
|
||||
Exit(Items[i]);
|
||||
Result := nil;
|
||||
end;
|
||||
|
|
@ -365,9 +410,7 @@ begin
|
|||
for i := 0 to Count - 1 do
|
||||
begin
|
||||
Result := Items[i];
|
||||
if (Result.ShortCut = Hotkey.Shortcut) and
|
||||
(Result.Command = Hotkey.Command) and
|
||||
(Result.SameParams(Hotkey.Params)) then
|
||||
if Result.SameAs(Hotkey) then
|
||||
Exit;
|
||||
end;
|
||||
Result := nil;
|
||||
|
|
@ -461,7 +504,7 @@ var
|
|||
i, j: Integer;
|
||||
shortcut, newShortcut: TShortCut;
|
||||
begin
|
||||
shortcut := TextToShortCutEx(hotkey.Shortcut);
|
||||
shortcut := TextToShortCutEx(hotkey.Shortcuts[0]);
|
||||
for i := 0 to FActionLists.Count - 1 do
|
||||
begin
|
||||
action := GetActionByCommand(FActionLists[i], hotkey.Command);
|
||||
|
|
@ -477,7 +520,7 @@ begin
|
|||
for j := 0 to hotkeys.Count - 1 do
|
||||
if (hotkeys[j].Command = hotkey.Command) and (hotkeys[j] <> hotkey) then
|
||||
begin
|
||||
newShortcut := TextToShortCutEx(hotkeys[j].Shortcut);
|
||||
newShortcut := TextToShortCutEx(hotkeys[j].Shortcuts[0]);
|
||||
Break;
|
||||
end;
|
||||
end;
|
||||
|
|
@ -494,7 +537,7 @@ var
|
|||
i: Integer;
|
||||
shortcut: TShortCut;
|
||||
begin
|
||||
shortcut := TextToShortCutEx(hotkey.Shortcut);
|
||||
shortcut := TextToShortCutEx(hotkey.Shortcuts[0]);
|
||||
for i := 0 to FActionLists.Count - 1 do
|
||||
begin
|
||||
action := GetActionByCommand(FActionLists[i], hotkey.Command);
|
||||
|
|
@ -651,6 +694,7 @@ end;
|
|||
constructor THotKeyManager.Create;
|
||||
begin
|
||||
FForms := THMForms.Create(True);
|
||||
FSequenceStep := 0;
|
||||
end;
|
||||
|
||||
destructor THotKeyManager.Destroy;
|
||||
|
|
@ -724,8 +768,9 @@ var
|
|||
begin
|
||||
HotkeyNode := Config.AddNode(Node, 'Hotkey');
|
||||
|
||||
Config.SetAttr(HotkeyNode, 'Key', Hotkeys[i].Shortcut);
|
||||
Config.SetValue(HotkeyNode, 'Command', Hotkeys[i].Command);
|
||||
for j := Low(Hotkeys[i].Shortcuts) to High(Hotkeys[i].Shortcuts) do
|
||||
Config.AddValue(HotkeyNode, 'Shortcut', Hotkeys[i].Shortcuts[j]);
|
||||
Config.AddValue(HotkeyNode, 'Command', Hotkeys[i].Command);
|
||||
for j := Low(Hotkeys[i].Params) to High(Hotkeys[i].Params) do
|
||||
Config.AddValue(HotkeyNode, 'Param', Hotkeys[i].Params[j]);
|
||||
|
||||
|
|
@ -775,55 +820,75 @@ procedure THotKeyManager.Load(Config: TXmlConfig; Root: TXmlNode);
|
|||
var
|
||||
Form: THMForm;
|
||||
|
||||
procedure AddIfNotEmpty(var Arr: TDynamicStringArray; const Value: String);
|
||||
begin
|
||||
if Value <> '' then
|
||||
AddString(Arr, Value);
|
||||
end;
|
||||
procedure LoadHotkey(Hotkeys: THotkeys; Node: TXmlNode);
|
||||
var
|
||||
Shortcut, Command, Param: String;
|
||||
Shortcuts: array of String = nil;
|
||||
Params: array of String = nil;
|
||||
Controls: array of String = nil;
|
||||
HMControl: THMControl;
|
||||
i: Integer;
|
||||
begin
|
||||
if (Config.TryGetAttr(Node, 'Key', Shortcut)) and
|
||||
(((FVersion <= 1) and Config.TryGetAttr(Node, 'Command', Command)) or
|
||||
Config.TryGetValue(Node, 'Command', Command)) and
|
||||
(Shortcut <> EmptyStr) and
|
||||
(Command <> EmptyStr) then
|
||||
// These checks for version may be removed after 0.5.5 release because
|
||||
// the XML format for hotkeys has only been added in development version 0.5.5.
|
||||
// Only Command needs to be retrieved here.
|
||||
if FVersion <= 1 then
|
||||
Command := Config.GetAttr(Node, 'Command', '')
|
||||
else
|
||||
Command := Config.GetValue(Node, 'Command', ''); // Leave only this
|
||||
if FVersion <= 1 then
|
||||
Param := Config.GetAttr(Node, 'Params', '')
|
||||
else if FVersion < 9 then
|
||||
Param := Config.GetValue(Node, 'Params', '');
|
||||
if FVersion < 10 then
|
||||
begin
|
||||
if FVersion <= 1 then
|
||||
Param := Config.GetAttr(Node, 'Params', '')
|
||||
else if FVersion < 9 then
|
||||
Param := Config.GetValue(Node, 'Params', '');
|
||||
if (FVersion < 9) and (Param <> '') then
|
||||
AddString(Params, Param);
|
||||
|
||||
Shortcut := NormalizeModifiers(Shortcut);
|
||||
|
||||
Node := Node.FirstChild;
|
||||
while Assigned(Node) do
|
||||
Shortcut := Config.GetAttr(Node, 'Key', '');
|
||||
if Shortcut <> '' then
|
||||
begin
|
||||
if Node.CompareName('Control') = 0 then
|
||||
AddString(Controls, Config.GetContent(Node))
|
||||
else if Node.CompareName('Param') = 0 then
|
||||
AddString(Params, Config.GetContent(Node));
|
||||
Node := Node.NextSibling;
|
||||
Shortcut := NormalizeModifiers(Shortcut);
|
||||
AddIfNotEmpty(Shortcuts, Shortcut);
|
||||
end;
|
||||
end;
|
||||
if (FVersion < 9) then
|
||||
AddIfNotEmpty(Params, Param);
|
||||
// Up to here may be deleted after 0.5.5 release.
|
||||
|
||||
Node := Node.FirstChild;
|
||||
while Assigned(Node) do
|
||||
begin
|
||||
if Node.CompareName('Shortcut') = 0 then
|
||||
AddIfNotEmpty(Shortcuts, NormalizeModifiers(Config.GetContent(Node)))
|
||||
else if Node.CompareName('Control') = 0 then
|
||||
AddIfNotEmpty(Controls, Config.GetContent(Node))
|
||||
else if Node.CompareName('Param') = 0 then
|
||||
AddIfNotEmpty(Params, Config.GetContent(Node));
|
||||
Node := Node.NextSibling;
|
||||
end;
|
||||
|
||||
if Length(Shortcuts) > 0 then
|
||||
begin
|
||||
if Length(Controls) = 0 then
|
||||
begin
|
||||
if (FVersion <= 3) and IsShortcutConflictingWithOS(Shortcut) then
|
||||
// This "if" block may also be deleted after 0.5.5 release.
|
||||
if (FVersion <= 3) and IsShortcutConflictingWithOS(Shortcuts[0]) then
|
||||
begin
|
||||
HMControl := Form.Controls.FindOrCreate('Files Panel');
|
||||
HMControl.Hotkeys.AddIfNotExists(Shortcut, Command, Params);
|
||||
HMControl.Hotkeys.AddIfNotExists(Shortcuts, Params, Command);
|
||||
end
|
||||
else
|
||||
Hotkeys.Add(Shortcut, Command, Params);
|
||||
Hotkeys.Add(Shortcuts, Params, Command); // Leave only this
|
||||
end
|
||||
else
|
||||
begin
|
||||
for i := Low(Controls) to High(Controls) do
|
||||
begin
|
||||
HMControl := Form.Controls.FindOrCreate(Controls[i]);
|
||||
HMControl.Hotkeys.Add(Shortcut, Command, Params);
|
||||
HMControl.Hotkeys.Add(Shortcuts, Params, Command);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
|
@ -873,6 +938,7 @@ var
|
|||
form: THMForm;
|
||||
control: THMControl;
|
||||
Command, Param, FormName, ControlName: String;
|
||||
Params: array of String = nil;
|
||||
|
||||
procedure RemoveFrmPrexif(var s: String);
|
||||
begin
|
||||
|
|
@ -890,36 +956,47 @@ begin
|
|||
begin
|
||||
section := st[i];
|
||||
shortCut := NormalizeModifiers(section);
|
||||
j := 0;
|
||||
while ini.ValueExists(section, 'Command' + IntToStr(j)) do
|
||||
if shortCut <> '' then
|
||||
begin
|
||||
Command := ini.ReadString(section, 'Command' + IntToStr(j), '');
|
||||
Param := ini.ReadString(section, 'Param' + IntToStr(j), '');
|
||||
ControlName := ini.ReadString(section, 'Object' + IntToStr(j), '');
|
||||
FormName := ini.ReadString(section, 'Form' + IntToStr(j), '');
|
||||
|
||||
RemoveFrmPrexif(FormName);
|
||||
RemoveFrmPrexif(ControlName);
|
||||
|
||||
form := FForms.FindOrCreate(FormName);
|
||||
|
||||
if IsShortcutConflictingWithOS(shortCut) then
|
||||
ControlName := 'Files Panel';
|
||||
|
||||
// Old config had FormName=ControlName for main form.
|
||||
if SameText(FormName, ControlName) then
|
||||
j := 0;
|
||||
while ini.ValueExists(section, 'Command' + IntToStr(j)) do
|
||||
begin
|
||||
hotkeys := form.Hotkeys;
|
||||
end
|
||||
else
|
||||
begin
|
||||
control := form.Controls.FindOrCreate(ControlName);
|
||||
hotkeys := control.Hotkeys;
|
||||
Command := ini.ReadString(section, 'Command' + IntToStr(j), '');
|
||||
Param := ini.ReadString(section, 'Param' + IntToStr(j), '');
|
||||
ControlName := ini.ReadString(section, 'Object' + IntToStr(j), '');
|
||||
FormName := ini.ReadString(section, 'Form' + IntToStr(j), '');
|
||||
|
||||
RemoveFrmPrexif(FormName);
|
||||
RemoveFrmPrexif(ControlName);
|
||||
|
||||
form := FForms.FindOrCreate(FormName);
|
||||
|
||||
if IsShortcutConflictingWithOS(shortCut) then
|
||||
ControlName := 'Files Panel';
|
||||
|
||||
// Old config had FormName=ControlName for main form.
|
||||
if SameText(FormName, ControlName) then
|
||||
begin
|
||||
hotkeys := form.Hotkeys;
|
||||
end
|
||||
else
|
||||
begin
|
||||
control := form.Controls.FindOrCreate(ControlName);
|
||||
hotkeys := control.Hotkeys;
|
||||
end;
|
||||
|
||||
if Param <> '' then
|
||||
begin
|
||||
SetLength(Params, 1);
|
||||
Params[0] := Param;
|
||||
end
|
||||
else
|
||||
Params := nil;
|
||||
|
||||
hotkeys.Add([shortcut], Params, Command);
|
||||
|
||||
j := j + 1;
|
||||
end;
|
||||
|
||||
hotkeys.Add(shortcut, Command, [Param]);
|
||||
|
||||
j := j + 1;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
|
@ -1090,17 +1167,28 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
function THotKeyManager.HotKeyEvent(Form: TCustomForm; Shortcut: String; Hotkeys: THotkeys): Boolean;
|
||||
function THotKeyManager.HotKeyEvent(Form: TCustomForm; Hotkeys: THotkeys): Boolean;
|
||||
var
|
||||
hotkey: THotkey;
|
||||
FormCommands: IFormCommands;
|
||||
begin
|
||||
hotkey := Hotkeys.Find(Shortcut);
|
||||
hotkey := Hotkeys.FindByBeginning(FShortcutsSequence, False);
|
||||
if Assigned(hotkey) then
|
||||
begin
|
||||
FormCommands := Form as IFormCommands;
|
||||
Result := Assigned(FormCommands) and
|
||||
(FormCommands.ExecuteCommand(hotkey.Command, hotkey.Params) = cfrSuccess);
|
||||
if High(hotkey.Shortcuts) > FSequenceStep then
|
||||
begin
|
||||
// There are more shortcuts to match.
|
||||
FLastShortcutTime := SysUtils.Now;
|
||||
Inc(FSequenceStep);
|
||||
Result := True;
|
||||
end
|
||||
else
|
||||
begin
|
||||
FSequenceStep := 0;
|
||||
FormCommands := Form as IFormCommands;
|
||||
Result := Assigned(FormCommands) and
|
||||
(FormCommands.ExecuteCommand(hotkey.Command, hotkey.Params) = cfrSuccess);
|
||||
end;
|
||||
end
|
||||
else
|
||||
Result := False;
|
||||
|
|
@ -1157,7 +1245,9 @@ begin
|
|||
Control := Form.ActiveControl;
|
||||
|
||||
// Don't execute hotkeys that coincide with key typing actions.
|
||||
if not (((GetKeyTypingAction(ShiftEx) <> ktaNone)
|
||||
if (TextShortcut <> '') and
|
||||
((FSequenceStep > 0) or
|
||||
(not (((GetKeyTypingAction(ShiftEx) <> ktaNone)
|
||||
{$IFDEF MSWINDOWS}
|
||||
// Don't execute hotkeys with Ctrl+Alt = AltGr on Windows.
|
||||
or ((ShiftEx * KeyModifiersShortcutNoText = [ssCtrl, ssAlt]) and
|
||||
|
|
@ -1165,8 +1255,17 @@ begin
|
|||
// Don't execute hotkeys with AltGr on Windows.
|
||||
or (ShiftEx = [ssAltGr])
|
||||
{$ENDIF}
|
||||
) and (Key in [VK_0..VK_9, VK_A..VK_Z])) then
|
||||
) and (Key in [VK_0..VK_9, VK_A..VK_Z])))) then
|
||||
begin
|
||||
// If too much time has passed reset sequence.
|
||||
if (FSequenceStep > 0) and (DateTimeToTimeStamp(SysUtils.Now - FLastShortcutTime).Time > MaxShortcutSequenceInterval) then
|
||||
FSequenceStep := 0;
|
||||
|
||||
// Add shortcut to sequence.
|
||||
if Length(FShortcutsSequence) <> FSequenceStep + 1 then
|
||||
SetLength(FShortcutsSequence, FSequenceStep + 1);
|
||||
FShortcutsSequence[FSequenceStep] := TextShortcut;
|
||||
|
||||
if Assigned(Control) then
|
||||
begin
|
||||
for i := 0 to HMForm.Controls.Count - 1 do
|
||||
|
|
@ -1175,7 +1274,7 @@ begin
|
|||
HMControlInstance := HMControl.Find(Control);
|
||||
if Assigned(HMControlInstance) then
|
||||
begin
|
||||
if HotKeyEvent(Form, TextShortcut, HMControl.Hotkeys) then
|
||||
if HotKeyEvent(Form, HMControl.Hotkeys) then
|
||||
begin
|
||||
Key := VK_UNKNOWN;
|
||||
Exit;
|
||||
|
|
@ -1188,11 +1287,13 @@ begin
|
|||
end;
|
||||
|
||||
// Hotkey for the whole form
|
||||
if HotKeyEvent(Form, TextShortcut, HMForm.Hotkeys) then
|
||||
if HotKeyEvent(Form, HMForm.Hotkeys) then
|
||||
begin
|
||||
Key := VK_UNKNOWN;
|
||||
Exit;
|
||||
end;
|
||||
|
||||
FSequenceStep := 0; // Hotkey was not matched - reset sequence.
|
||||
end;
|
||||
|
||||
if Key <> VK_UNKNOWN then
|
||||
|
|
|
|||
|
|
@ -416,6 +416,8 @@ resourcestring
|
|||
rsOptHotkeysSetDeleteShortcut = 'Set shortcut to delete file';
|
||||
rsOptHotkeysShortcutForDeleteAlreadyAssigned =
|
||||
'For this setting to work with shortcut %s, shortcut %s must be assigned to cm_Delete but it is already assigned to %s. Do you want to change it?';
|
||||
rsOptHotkeysShortcutForDeleteIsSequence =
|
||||
'Shortcut %s for cm_Delete is a sequence shortcut for which a hotkey with reversed Shift cannot be assigned. This setting might not work.';
|
||||
rsOptHotkeysCommand = 'Command';
|
||||
rsOptHotkeysDescription = 'Description';
|
||||
rsOptHotkeysFixParameter = 'Fix parameter';
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue