mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-08 18:39:30 +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;
|
||||
Code: word; SState: TShiftState; var Data: pointer;
|
||||
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;
|
||||
|
||||
TSynMouseLinkEvent = procedure (
|
||||
@ -488,7 +491,8 @@ type
|
||||
fHideSelection: boolean;
|
||||
fOverwriteCaret: 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;
|
||||
FMouseActionSearchHandlerList: TSynEditMouseActionSearchList;
|
||||
FMouseActionExecHandlerList: TSynEditMouseActionExecList;
|
||||
@ -1989,7 +1993,7 @@ begin
|
||||
fInsertCaret := ctVerticalLine;
|
||||
fOverwriteCaret := ctBlock;
|
||||
FKeystrokes := TSynEditKeyStrokes.Create(Self);
|
||||
FLastKeyStrokes := nil;
|
||||
FCurrentComboKeyStrokes := nil;
|
||||
if assigned(Owner) and not (csLoading in Owner.ComponentState) then begin
|
||||
SetDefaultKeystrokes;
|
||||
end;
|
||||
@ -2597,28 +2601,65 @@ begin
|
||||
inherited;
|
||||
if assigned(fMarkupCtrlMouse) then
|
||||
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;
|
||||
C := #0;
|
||||
try
|
||||
IsStartOfCombo := False;
|
||||
Handled := False;
|
||||
// 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.
|
||||
if FLastKeyStrokes = FKeyStrokes then begin
|
||||
Cmd := KeyStrokes.FindKeycodeEx(Key, Shift, Data, IsStartOfCombo, True);
|
||||
Handled := Cmd <> ecNone;
|
||||
end;
|
||||
// Hooked
|
||||
if not Handled then
|
||||
IsStartOfCombo := False;
|
||||
Handled := False;
|
||||
|
||||
// Check 2nd stroke in SynEdit.KeyStrokes
|
||||
if FCurrentComboKeyStrokes <> nil then begin
|
||||
// Run hooked first, it might want to "steal" the key(s)
|
||||
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
|
||||
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);
|
||||
if IsStartOfCombo then
|
||||
FLastKeyStrokes := FKeyStrokes;
|
||||
FCurrentComboKeyStrokes := FKeyStrokes;
|
||||
end;
|
||||
|
||||
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);
|
||||
LastMouseCaret := Point(-1,-1); // includes update cursor
|
||||
//DebugLn(['[TCustomSynEdit.KeyDown] key translated ',cmd]);
|
||||
@ -8722,16 +8763,18 @@ procedure TSynHookedKeyTranslationList.CallHookedKeyTranslationHandlers(Sender:
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
// Finish Combo ?
|
||||
for i := 0 to Count - 1 do
|
||||
THookedKeyTranslationEvent(Items[i])(Sender, Code, SState, Data,
|
||||
IsStartOfCombo, Handled, Command, True, ComboKeyStrokes);
|
||||
if Handled then
|
||||
exit;
|
||||
// New Stroke ?
|
||||
for i := 0 to Count - 1 do
|
||||
THookedKeyTranslationEvent(Items[i])(Sender, Code, SState, Data,
|
||||
IsStartOfCombo, Handled, Command, False, ComboKeyStrokes);
|
||||
if ComboKeyStrokes <> nil then begin
|
||||
// Finish Combo
|
||||
for i := 0 to Count - 1 do
|
||||
THookedKeyTranslationEvent(Items[i])(Sender, Code, SState, Data,
|
||||
IsStartOfCombo, Handled, Command, True, ComboKeyStrokes);
|
||||
end
|
||||
else begin
|
||||
// New Stroke
|
||||
for i := 0 to Count - 1 do
|
||||
THookedKeyTranslationEvent(Items[i])(Sender, Code, SState, Data,
|
||||
IsStartOfCombo, Handled, Command, False, ComboKeyStrokes);
|
||||
end;
|
||||
end;
|
||||
|
||||
{ TSynStatusChangedHandlerList }
|
||||
|
@ -357,7 +357,8 @@ type
|
||||
function FindKeycode(Code: word; SS: TShiftState): integer;
|
||||
function FindKeycodeEx(Code: word; SS: TShiftState; var Data: pointer;
|
||||
out IsStartOfCombo: boolean;
|
||||
FinishComboOnly: Boolean = False): TSynEditorCommand;
|
||||
FinishComboOnly: Boolean = False;
|
||||
ComboStart: TSynEditKeyStrokes = nil): TSynEditorCommand;
|
||||
procedure ResetKeyCombo;
|
||||
function FindShortcut(SC: TShortcut): integer;
|
||||
function FindShortcut2(SC, SC2: TShortcut): integer;
|
||||
@ -921,34 +922,70 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function TSynEditKeyStrokes.FindKeycodeEx(Code: word; SS: TShiftState; var Data: pointer; out
|
||||
IsStartOfCombo: boolean; FinishComboOnly: Boolean = False): TSynEditorCommand;
|
||||
function TSynEditKeyStrokes.FindKeycodeEx(Code: word; SS: TShiftState; var Data: pointer;
|
||||
out IsStartOfCombo: boolean;
|
||||
FinishComboOnly: Boolean; ComboStart: TSynEditKeyStrokes): TSynEditorCommand;
|
||||
var
|
||||
i: integer;
|
||||
LK: Word;
|
||||
LS: TShiftState;
|
||||
CurComboStart: TSynEditKeyStrokes;
|
||||
{$IFNDEF SYN_COMPILER_3_UP}
|
||||
const
|
||||
VK_ACCEPT = $30;
|
||||
{$ENDIF}
|
||||
begin
|
||||
i := FindKeycode2(fLastKey, fLastShiftState, Code, SS);
|
||||
if (i < 0) and not FinishComboOnly then
|
||||
i := FindKeycode(Code, SS);
|
||||
if i >= 0 then
|
||||
Result := Items[i].Command
|
||||
else
|
||||
Result := ecNone;
|
||||
(* if FinishComboOnly=True then ComboStart are the KeyStrokes, which have the
|
||||
already received keys.
|
||||
If several TSynEditKeyStrokes have combos, starting with the same key(s)
|
||||
only one needs to keep the info. The others chek, if they have a matching combo
|
||||
*)
|
||||
|
||||
if (Result = ecNone) and (Code >= VK_ACCEPT) and (Code <= VK_SCROLL) and
|
||||
(FindKeycode2Start(Code, SS) >= 0) and not FinishComboOnly then
|
||||
Result := ecNone;
|
||||
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
|
||||
fLastKey := Code;
|
||||
fLastShiftState := SS;
|
||||
IsStartOfCombo := True;
|
||||
end else begin
|
||||
fLastKey := 0;
|
||||
fLastShiftState := [];
|
||||
IsStartOfCombo := False;
|
||||
end;
|
||||
// Now this is the start of combo
|
||||
if (ComboStart <> nil) and (ComboStart <> self) then
|
||||
ComboStart.ResetKeyCombo;
|
||||
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;
|
||||
|
||||
procedure TSynEditKeyStrokes.ResetKeyCombo;
|
||||
|
@ -1326,38 +1326,30 @@ begin
|
||||
exit;
|
||||
|
||||
keys := nil;
|
||||
|
||||
if Mode = spseSelecting then
|
||||
keys := FKeystrokesSelecting;
|
||||
|
||||
if Mode = spseEditing then begin
|
||||
if CurrentCell < 0 then begin
|
||||
keys := FKeyStrokesOffCell;
|
||||
FKeyStrokes.ResetKeyCombo;
|
||||
end
|
||||
else begin
|
||||
if CurrentCell < 0 then
|
||||
keys := FKeyStrokesOffCell
|
||||
else
|
||||
keys := FKeyStrokes;
|
||||
FKeyStrokesOffCell.ResetKeyCombo;
|
||||
end;
|
||||
end;
|
||||
if keys = nil then exit;
|
||||
|
||||
if (FinishComboOnly and (ComboKeyStrokes <> keys)) then begin
|
||||
keys.ResetKeyCombo;
|
||||
exit;
|
||||
end;
|
||||
|
||||
IsStartOfCombo := False;
|
||||
try
|
||||
keys.UsePluginOffset := True;
|
||||
Command := keys.FindKeycodeEx(Code, SState, Data, IsStartOfCombo,
|
||||
FinishComboOnly);
|
||||
if not FinishComboOnly then
|
||||
keys.ResetKeyCombo;
|
||||
Command := keys.FindKeycodeEx(Code, SState, Data, IsStartOfCombo, FinishComboOnly, ComboKeyStrokes);
|
||||
finally
|
||||
keys.UsePluginOffset := False;
|
||||
end;
|
||||
|
||||
Handled := (Command <> ecNone) or IsStartOfCombo;
|
||||
if Handled then begin
|
||||
if IsStartOfCombo then
|
||||
ComboKeyStrokes := keys;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TSynPluginSyncroEdit.ProcessSynCommand(Sender: TObject; AfterProcessing: boolean;
|
||||
|
@ -199,32 +199,23 @@ begin
|
||||
if (not Active) or Handled then
|
||||
exit;
|
||||
|
||||
if CurrentCell < 0 then begin
|
||||
keys := FKeyStrokesOffCell;
|
||||
FKeyStrokes.ResetKeyCombo;
|
||||
end
|
||||
else begin
|
||||
if CurrentCell < 0 then
|
||||
keys := FKeyStrokesOffCell
|
||||
else
|
||||
keys := FKeyStrokes;
|
||||
FKeyStrokesOffCell.ResetKeyCombo;
|
||||
end;
|
||||
|
||||
if (FinishComboOnly and (ComboKeyStrokes <> keys)) then begin
|
||||
keys.ResetKeyCombo;
|
||||
exit;
|
||||
end;
|
||||
|
||||
IsStartOfCombo := False;
|
||||
try
|
||||
keys.UsePluginOffset := True;
|
||||
Command := keys.FindKeycodeEx(Code, SState, Data, IsStartOfCombo,
|
||||
FinishComboOnly);
|
||||
if not FinishComboOnly then
|
||||
keys.ResetKeyCombo;
|
||||
Command := keys.FindKeycodeEx(Code, SState, Data, IsStartOfCombo, FinishComboOnly, ComboKeyStrokes);
|
||||
finally
|
||||
keys.UsePluginOffset := False;
|
||||
end;
|
||||
|
||||
Handled := (Command <> ecNone) or IsStartOfCombo;
|
||||
if Handled then begin
|
||||
if IsStartOfCombo then
|
||||
ComboKeyStrokes := keys;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TSynPluginTemplateEdit.ProcessSynCommand(Sender: TObject; AfterProcessing: boolean;
|
||||
|
Loading…
Reference in New Issue
Block a user