mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-18 20:59:08 +02:00
EditorOpts: Fixed Keymaps, combo strokes in plugins
git-svn-id: trunk@35406 -
This commit is contained in:
parent
ce0c730b46
commit
a1ff712f8b
@ -381,7 +381,10 @@ type
|
|||||||
procedure CallHookedKeyTranslationHandlers(Sender: TObject;
|
procedure CallHookedKeyTranslationHandlers(Sender: TObject;
|
||||||
Code: word; SState: TShiftState; var Data: pointer;
|
Code: word; SState: TShiftState; var Data: pointer;
|
||||||
var IsStartOfCombo: boolean; var Handled: boolean;
|
var IsStartOfCombo: boolean; var Handled: boolean;
|
||||||
var Command: TSynEditorCommand; var ComboKeyStrokes: TSynEditKeyStrokes);
|
var Command: TSynEditorCommand;
|
||||||
|
// ComboKeyStrokes decides, either FinishComboOnly, or new stroke
|
||||||
|
var ComboKeyStrokes: TSynEditKeyStrokes
|
||||||
|
);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
TSynMouseLinkEvent = procedure (
|
TSynMouseLinkEvent = procedure (
|
||||||
@ -488,7 +491,8 @@ type
|
|||||||
fHideSelection: boolean;
|
fHideSelection: boolean;
|
||||||
fOverwriteCaret: TSynEditCaretType;
|
fOverwriteCaret: TSynEditCaretType;
|
||||||
fInsertCaret: TSynEditCaretType;
|
fInsertCaret: TSynEditCaretType;
|
||||||
FKeyStrokes, FLastKeyStrokes: TSynEditKeyStrokes;
|
FKeyStrokes: TSynEditKeyStrokes;
|
||||||
|
FCurrentComboKeyStrokes: TSynEditKeyStrokes; // Holding info about the keystroke(s) already received for a mult-stroke-combo
|
||||||
FMouseActions, FMouseSelActions, FMouseTextActions: TSynEditMouseInternalActions;
|
FMouseActions, FMouseSelActions, FMouseTextActions: TSynEditMouseInternalActions;
|
||||||
FMouseActionSearchHandlerList: TSynEditMouseActionSearchList;
|
FMouseActionSearchHandlerList: TSynEditMouseActionSearchList;
|
||||||
FMouseActionExecHandlerList: TSynEditMouseActionExecList;
|
FMouseActionExecHandlerList: TSynEditMouseActionExecList;
|
||||||
@ -1989,7 +1993,7 @@ begin
|
|||||||
fInsertCaret := ctVerticalLine;
|
fInsertCaret := ctVerticalLine;
|
||||||
fOverwriteCaret := ctBlock;
|
fOverwriteCaret := ctBlock;
|
||||||
FKeystrokes := TSynEditKeyStrokes.Create(Self);
|
FKeystrokes := TSynEditKeyStrokes.Create(Self);
|
||||||
FLastKeyStrokes := nil;
|
FCurrentComboKeyStrokes := nil;
|
||||||
if assigned(Owner) and not (csLoading in Owner.ComponentState) then begin
|
if assigned(Owner) and not (csLoading in Owner.ComponentState) then begin
|
||||||
SetDefaultKeystrokes;
|
SetDefaultKeystrokes;
|
||||||
end;
|
end;
|
||||||
@ -2597,28 +2601,65 @@ begin
|
|||||||
inherited;
|
inherited;
|
||||||
if assigned(fMarkupCtrlMouse) then
|
if assigned(fMarkupCtrlMouse) then
|
||||||
fMarkupCtrlMouse.UpdateCtrlState(Shift);
|
fMarkupCtrlMouse.UpdateCtrlState(Shift);
|
||||||
|
|
||||||
|
if Key in [VK_SHIFT, VK_CONTROL, VK_MENU,
|
||||||
|
VK_LSHIFT, VK_LCONTROL, VK_LMENU,
|
||||||
|
VK_RSHIFT, VK_RCONTROL, VK_RMENU,
|
||||||
|
VK_LWIN, VK_RWIN]
|
||||||
|
then
|
||||||
|
exit;
|
||||||
|
|
||||||
Data := nil;
|
Data := nil;
|
||||||
C := #0;
|
C := #0;
|
||||||
try
|
try
|
||||||
IsStartOfCombo := False;
|
|
||||||
Handled := False;
|
|
||||||
// If the translations requires Data, memory will be allocated for it via a
|
// If the translations requires Data, memory will be allocated for it via a
|
||||||
// GetMem call. The client must call FreeMem on Data if it is not NIL.
|
// GetMem call. The client must call FreeMem on Data if it is not NIL.
|
||||||
if FLastKeyStrokes = FKeyStrokes then begin
|
IsStartOfCombo := False;
|
||||||
Cmd := KeyStrokes.FindKeycodeEx(Key, Shift, Data, IsStartOfCombo, True);
|
Handled := False;
|
||||||
Handled := Cmd <> ecNone;
|
|
||||||
end;
|
// Check 2nd stroke in SynEdit.KeyStrokes
|
||||||
// Hooked
|
if FCurrentComboKeyStrokes <> nil then begin
|
||||||
if not Handled then
|
// Run hooked first, it might want to "steal" the key(s)
|
||||||
FHookedKeyTranslationList.CallHookedKeyTranslationHandlers(self,
|
FHookedKeyTranslationList.CallHookedKeyTranslationHandlers(self,
|
||||||
Key, Shift, Data, IsStartOfCombo, Handled, Cmd, FLastKeyStrokes);
|
Key, Shift, Data, IsStartOfCombo, Handled, Cmd, FCurrentComboKeyStrokes);
|
||||||
|
|
||||||
|
if not Handled then begin
|
||||||
|
Cmd := KeyStrokes.FindKeycodeEx(Key, Shift, Data, IsStartOfCombo, True, FCurrentComboKeyStrokes);
|
||||||
|
if IsStartOfCombo then
|
||||||
|
FCurrentComboKeyStrokes := FKeyStrokes;
|
||||||
|
Handled := (Cmd <> ecNone) or IsStartOfCombo;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if not IsStartOfCombo then begin
|
||||||
|
FCurrentComboKeyStrokes.ResetKeyCombo;
|
||||||
|
FCurrentComboKeyStrokes := nil;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
assert(Handled or (FCurrentComboKeyStrokes=nil), 'FCurrentComboKeyStrokes<>nil, should be handled');
|
||||||
|
|
||||||
|
// Check 1st/single stroke in Hooked KeyStrokes
|
||||||
if not Handled then begin
|
if not Handled then begin
|
||||||
|
FCurrentComboKeyStrokes := nil;
|
||||||
|
FHookedKeyTranslationList.CallHookedKeyTranslationHandlers(self,
|
||||||
|
Key, Shift, Data, IsStartOfCombo, Handled, Cmd, FCurrentComboKeyStrokes);
|
||||||
|
if (not IsStartOfCombo) and (FCurrentComboKeyStrokes <> nil) then
|
||||||
|
FCurrentComboKeyStrokes.ResetKeyCombo; // should not happen
|
||||||
|
end;
|
||||||
|
// Check 1st/single stroke in SynEdit.KeyStrokes
|
||||||
|
if not Handled then begin
|
||||||
|
FKeyStrokes.ResetKeyCombo;
|
||||||
Cmd := KeyStrokes.FindKeycodeEx(Key, Shift, Data, IsStartOfCombo);
|
Cmd := KeyStrokes.FindKeycodeEx(Key, Shift, Data, IsStartOfCombo);
|
||||||
if IsStartOfCombo then
|
if IsStartOfCombo then
|
||||||
FLastKeyStrokes := FKeyStrokes;
|
FCurrentComboKeyStrokes := FKeyStrokes;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if Cmd <> ecNone then begin
|
if Cmd <> ecNone then begin
|
||||||
|
// Reset FCurrentComboKeyStrokes => no open combo
|
||||||
|
assert(FCurrentComboKeyStrokes=nil, 'FCurrentComboKeyStrokes<>nil, should be ecNone');
|
||||||
|
if FCurrentComboKeyStrokes <> nil then
|
||||||
|
FCurrentComboKeyStrokes.ResetKeyCombo;
|
||||||
|
FCurrentComboKeyStrokes := nil;
|
||||||
|
|
||||||
Include(FStateFlags, sfHideCursor);
|
Include(FStateFlags, sfHideCursor);
|
||||||
LastMouseCaret := Point(-1,-1); // includes update cursor
|
LastMouseCaret := Point(-1,-1); // includes update cursor
|
||||||
//DebugLn(['[TCustomSynEdit.KeyDown] key translated ',cmd]);
|
//DebugLn(['[TCustomSynEdit.KeyDown] key translated ',cmd]);
|
||||||
@ -8722,16 +8763,18 @@ procedure TSynHookedKeyTranslationList.CallHookedKeyTranslationHandlers(Sender:
|
|||||||
var
|
var
|
||||||
i: Integer;
|
i: Integer;
|
||||||
begin
|
begin
|
||||||
// Finish Combo ?
|
if ComboKeyStrokes <> nil then begin
|
||||||
for i := 0 to Count - 1 do
|
// Finish Combo
|
||||||
THookedKeyTranslationEvent(Items[i])(Sender, Code, SState, Data,
|
for i := 0 to Count - 1 do
|
||||||
IsStartOfCombo, Handled, Command, True, ComboKeyStrokes);
|
THookedKeyTranslationEvent(Items[i])(Sender, Code, SState, Data,
|
||||||
if Handled then
|
IsStartOfCombo, Handled, Command, True, ComboKeyStrokes);
|
||||||
exit;
|
end
|
||||||
// New Stroke ?
|
else begin
|
||||||
for i := 0 to Count - 1 do
|
// New Stroke
|
||||||
THookedKeyTranslationEvent(Items[i])(Sender, Code, SState, Data,
|
for i := 0 to Count - 1 do
|
||||||
IsStartOfCombo, Handled, Command, False, ComboKeyStrokes);
|
THookedKeyTranslationEvent(Items[i])(Sender, Code, SState, Data,
|
||||||
|
IsStartOfCombo, Handled, Command, False, ComboKeyStrokes);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TSynStatusChangedHandlerList }
|
{ TSynStatusChangedHandlerList }
|
||||||
|
@ -357,7 +357,8 @@ type
|
|||||||
function FindKeycode(Code: word; SS: TShiftState): integer;
|
function FindKeycode(Code: word; SS: TShiftState): integer;
|
||||||
function FindKeycodeEx(Code: word; SS: TShiftState; var Data: pointer;
|
function FindKeycodeEx(Code: word; SS: TShiftState; var Data: pointer;
|
||||||
out IsStartOfCombo: boolean;
|
out IsStartOfCombo: boolean;
|
||||||
FinishComboOnly: Boolean = False): TSynEditorCommand;
|
FinishComboOnly: Boolean = False;
|
||||||
|
ComboStart: TSynEditKeyStrokes = nil): TSynEditorCommand;
|
||||||
procedure ResetKeyCombo;
|
procedure ResetKeyCombo;
|
||||||
function FindShortcut(SC: TShortcut): integer;
|
function FindShortcut(SC: TShortcut): integer;
|
||||||
function FindShortcut2(SC, SC2: TShortcut): integer;
|
function FindShortcut2(SC, SC2: TShortcut): integer;
|
||||||
@ -921,34 +922,70 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TSynEditKeyStrokes.FindKeycodeEx(Code: word; SS: TShiftState; var Data: pointer; out
|
function TSynEditKeyStrokes.FindKeycodeEx(Code: word; SS: TShiftState; var Data: pointer;
|
||||||
IsStartOfCombo: boolean; FinishComboOnly: Boolean = False): TSynEditorCommand;
|
out IsStartOfCombo: boolean;
|
||||||
|
FinishComboOnly: Boolean; ComboStart: TSynEditKeyStrokes): TSynEditorCommand;
|
||||||
var
|
var
|
||||||
i: integer;
|
i: integer;
|
||||||
|
LK: Word;
|
||||||
|
LS: TShiftState;
|
||||||
|
CurComboStart: TSynEditKeyStrokes;
|
||||||
{$IFNDEF SYN_COMPILER_3_UP}
|
{$IFNDEF SYN_COMPILER_3_UP}
|
||||||
const
|
const
|
||||||
VK_ACCEPT = $30;
|
VK_ACCEPT = $30;
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
begin
|
begin
|
||||||
i := FindKeycode2(fLastKey, fLastShiftState, Code, SS);
|
(* if FinishComboOnly=True then ComboStart are the KeyStrokes, which have the
|
||||||
if (i < 0) and not FinishComboOnly then
|
already received keys.
|
||||||
i := FindKeycode(Code, SS);
|
If several TSynEditKeyStrokes have combos, starting with the same key(s)
|
||||||
if i >= 0 then
|
only one needs to keep the info. The others chek, if they have a matching combo
|
||||||
Result := Items[i].Command
|
*)
|
||||||
else
|
|
||||||
Result := ecNone;
|
|
||||||
|
|
||||||
if (Result = ecNone) and (Code >= VK_ACCEPT) and (Code <= VK_SCROLL) and
|
Result := ecNone;
|
||||||
(FindKeycode2Start(Code, SS) >= 0) and not FinishComboOnly then
|
IsStartOfCombo := False;
|
||||||
|
|
||||||
|
if ComboStart = nil then
|
||||||
|
CurComboStart := self
|
||||||
|
else
|
||||||
|
CurComboStart := ComboStart;
|
||||||
|
|
||||||
|
if CurComboStart.fLastKey <> 0 then begin
|
||||||
|
// Try to finish the combo
|
||||||
|
i := FindKeycode2(CurComboStart.fLastKey, CurComboStart.fLastShiftState, Code, SS);
|
||||||
|
if (i >= 0) then begin
|
||||||
|
Result := Items[i].Command;
|
||||||
|
CurComboStart.ResetKeyCombo;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
if FinishComboOnly then
|
||||||
|
exit;
|
||||||
|
|
||||||
|
// Check for single stroke
|
||||||
|
i := FindKeycode(Code, SS);
|
||||||
|
if i >= 0 then begin
|
||||||
|
Result := Items[i].Command;
|
||||||
|
ResetKeyCombo;
|
||||||
|
if (ComboStart <> nil) and (ComboStart <> self) then
|
||||||
|
ComboStart.ResetKeyCombo;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if (FindKeycode2Start(Code, SS) >= 0) and not FinishComboOnly then
|
||||||
begin
|
begin
|
||||||
fLastKey := Code;
|
fLastKey := Code;
|
||||||
fLastShiftState := SS;
|
fLastShiftState := SS;
|
||||||
IsStartOfCombo := True;
|
IsStartOfCombo := True;
|
||||||
end else begin
|
// Now this is the start of combo
|
||||||
fLastKey := 0;
|
if (ComboStart <> nil) and (ComboStart <> self) then
|
||||||
fLastShiftState := [];
|
ComboStart.ResetKeyCombo;
|
||||||
IsStartOfCombo := False;
|
end
|
||||||
end;
|
else begin
|
||||||
|
// Nothing was found.
|
||||||
|
// Keep CurComboStart.fLastKey. It may be ued by another TSynEditKeyStrokes
|
||||||
|
if (ComboStart <> self) then
|
||||||
|
ResetKeyCombo; // reset self, if not CurComboStart
|
||||||
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSynEditKeyStrokes.ResetKeyCombo;
|
procedure TSynEditKeyStrokes.ResetKeyCombo;
|
||||||
|
@ -1326,38 +1326,30 @@ begin
|
|||||||
exit;
|
exit;
|
||||||
|
|
||||||
keys := nil;
|
keys := nil;
|
||||||
|
|
||||||
if Mode = spseSelecting then
|
if Mode = spseSelecting then
|
||||||
keys := FKeystrokesSelecting;
|
keys := FKeystrokesSelecting;
|
||||||
|
|
||||||
if Mode = spseEditing then begin
|
if Mode = spseEditing then begin
|
||||||
if CurrentCell < 0 then begin
|
if CurrentCell < 0 then
|
||||||
keys := FKeyStrokesOffCell;
|
keys := FKeyStrokesOffCell
|
||||||
FKeyStrokes.ResetKeyCombo;
|
else
|
||||||
end
|
|
||||||
else begin
|
|
||||||
keys := FKeyStrokes;
|
keys := FKeyStrokes;
|
||||||
FKeyStrokesOffCell.ResetKeyCombo;
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
if keys = nil then exit;
|
if keys = nil then exit;
|
||||||
|
|
||||||
if (FinishComboOnly and (ComboKeyStrokes <> keys)) then begin
|
|
||||||
keys.ResetKeyCombo;
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
|
|
||||||
IsStartOfCombo := False;
|
|
||||||
try
|
try
|
||||||
keys.UsePluginOffset := True;
|
keys.UsePluginOffset := True;
|
||||||
Command := keys.FindKeycodeEx(Code, SState, Data, IsStartOfCombo,
|
if not FinishComboOnly then
|
||||||
FinishComboOnly);
|
keys.ResetKeyCombo;
|
||||||
|
Command := keys.FindKeycodeEx(Code, SState, Data, IsStartOfCombo, FinishComboOnly, ComboKeyStrokes);
|
||||||
finally
|
finally
|
||||||
keys.UsePluginOffset := False;
|
keys.UsePluginOffset := False;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
Handled := (Command <> ecNone) or IsStartOfCombo;
|
Handled := (Command <> ecNone) or IsStartOfCombo;
|
||||||
if Handled then begin
|
if IsStartOfCombo then
|
||||||
ComboKeyStrokes := keys;
|
ComboKeyStrokes := keys;
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSynPluginSyncroEdit.ProcessSynCommand(Sender: TObject; AfterProcessing: boolean;
|
procedure TSynPluginSyncroEdit.ProcessSynCommand(Sender: TObject; AfterProcessing: boolean;
|
||||||
|
@ -199,32 +199,23 @@ begin
|
|||||||
if (not Active) or Handled then
|
if (not Active) or Handled then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
if CurrentCell < 0 then begin
|
if CurrentCell < 0 then
|
||||||
keys := FKeyStrokesOffCell;
|
keys := FKeyStrokesOffCell
|
||||||
FKeyStrokes.ResetKeyCombo;
|
else
|
||||||
end
|
|
||||||
else begin
|
|
||||||
keys := FKeyStrokes;
|
keys := FKeyStrokes;
|
||||||
FKeyStrokesOffCell.ResetKeyCombo;
|
|
||||||
end;
|
|
||||||
|
|
||||||
if (FinishComboOnly and (ComboKeyStrokes <> keys)) then begin
|
|
||||||
keys.ResetKeyCombo;
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
|
|
||||||
IsStartOfCombo := False;
|
|
||||||
try
|
try
|
||||||
keys.UsePluginOffset := True;
|
keys.UsePluginOffset := True;
|
||||||
Command := keys.FindKeycodeEx(Code, SState, Data, IsStartOfCombo,
|
if not FinishComboOnly then
|
||||||
FinishComboOnly);
|
keys.ResetKeyCombo;
|
||||||
|
Command := keys.FindKeycodeEx(Code, SState, Data, IsStartOfCombo, FinishComboOnly, ComboKeyStrokes);
|
||||||
finally
|
finally
|
||||||
keys.UsePluginOffset := False;
|
keys.UsePluginOffset := False;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
Handled := (Command <> ecNone) or IsStartOfCombo;
|
Handled := (Command <> ecNone) or IsStartOfCombo;
|
||||||
if Handled then begin
|
if IsStartOfCombo then
|
||||||
ComboKeyStrokes := keys;
|
ComboKeyStrokes := keys;
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSynPluginTemplateEdit.ProcessSynCommand(Sender: TObject; AfterProcessing: boolean;
|
procedure TSynPluginTemplateEdit.ProcessSynCommand(Sender: TObject; AfterProcessing: boolean;
|
||||||
|
Loading…
Reference in New Issue
Block a user