mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-18 04:49:43 +02:00
SynEdit: Refactor SynPlugin / Make SynCompletion a SynPlugin
git-svn-id: trunk@35493 -
This commit is contained in:
parent
7a3dbe9f15
commit
9c9f699f61
@ -43,7 +43,7 @@ interface
|
||||
uses
|
||||
LCLProc, LCLIntf, LCLType, LMessages, Classes, Graphics, Forms,
|
||||
Controls, StdCtrls, ExtCtrls, Menus, SysUtils,
|
||||
SynEditMiscProcs, SynEditKeyCmds, SynEdit, SynEditTypes;
|
||||
SynEditMiscProcs, SynEditKeyCmds, SynEdit, SynEditTypes, SynEditPlugins;
|
||||
|
||||
type
|
||||
TSynBaseCompletionPaintItem =
|
||||
@ -141,7 +141,6 @@ type
|
||||
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
|
||||
procedure KeyPress(var Key: char); override;
|
||||
procedure Paint; override;
|
||||
function Focused: Boolean; override;
|
||||
procedure AppDeactivated(Sender: TObject); // Because Form.Deactivate isn't called
|
||||
procedure Deactivate; override;
|
||||
procedure SelectPrec;
|
||||
@ -162,7 +161,7 @@ type
|
||||
procedure FontChanged(Sender: TObject); override;
|
||||
procedure WMMouseWheel(var Msg: TLMMouseEvent); message LM_MOUSEWHEEL;
|
||||
private
|
||||
fCurrentEditor: TComponent;
|
||||
FCurrentEditor: TCustomSynEdit; // Must only be set via TSynCompletion.SetEditor
|
||||
FDoubleClickSelects: Boolean;
|
||||
FDrawBorderWidth: Integer;
|
||||
FOnDragResized: TNotifyEvent;
|
||||
@ -170,12 +169,14 @@ type
|
||||
FOnPositionChanged: TNotifyEvent;
|
||||
FShowSizeDrag: Boolean;
|
||||
FHintLock: Integer;
|
||||
procedure SetCurrentEditor(const AValue: TComponent);
|
||||
procedure SetCurrentEditor(const AValue: TCustomSynEdit);
|
||||
procedure SetDrawBorderWidth(const AValue: Integer);
|
||||
procedure SetLongLineHintTime(const AValue: Integer);
|
||||
procedure EditorStatusChanged(Sender: TObject; Changes: TSynStatusChanges);
|
||||
procedure SetShowSizeDrag(const AValue: Boolean);
|
||||
protected
|
||||
procedure RegisterHandlers(EditOnly: Boolean = False);
|
||||
procedure UnRegisterHandlers(EditOnly: Boolean = False);
|
||||
procedure SetVisible(Value: Boolean); override;
|
||||
property DrawBorderWidth: Integer read FDrawBorderWidth write SetDrawBorderWidth;
|
||||
procedure IncHintLock;
|
||||
@ -184,8 +185,11 @@ type
|
||||
public
|
||||
constructor Create(AOwner: Tcomponent); override;
|
||||
destructor Destroy; override;
|
||||
function Focused: Boolean; override;
|
||||
procedure ShowItemHint(AIndex: Integer);
|
||||
procedure OnHintTimer(Sender: TObject);
|
||||
// Must only be set via TSynCompletion.SetEditor
|
||||
property CurrentEditor: TCustomSynEdit read FCurrentEditor;
|
||||
published
|
||||
property CurrentString: string read FCurrentString write SetCurrentString;
|
||||
property OnKeyPress: TKeyPressEvent read FOnKeyPress write FOnKeyPress;
|
||||
@ -202,7 +206,6 @@ type
|
||||
write SetNbLinesInWindow;
|
||||
property ClSelect: TColor read FClSelect write FClSelect;
|
||||
property CaseSensitive: boolean read FCaseSensitive write FCaseSensitive;
|
||||
property CurrentEditor: TComponent read fCurrentEditor write SetCurrentEditor;
|
||||
property FontHeight:integer read FFontHeight;
|
||||
property OnSearchPosition:TSynBaseCompletionSearchPosition
|
||||
read FOnSearchPosition write FOnSearchPosition;
|
||||
@ -225,7 +228,7 @@ type
|
||||
|
||||
{ TSynBaseCompletion }
|
||||
|
||||
TSynBaseCompletion = class(TComponent)
|
||||
TSynBaseCompletion = class(TLazSynMultiEditPlugin)
|
||||
private
|
||||
Form: TSynBaseCompletionForm;
|
||||
FAddedPersistentCaret: boolean;
|
||||
@ -281,7 +284,6 @@ type
|
||||
procedure SetOnKeyPrevChar(const AValue: TNotifyEvent);
|
||||
public
|
||||
constructor Create(AOwner: TComponent); override;
|
||||
destructor Destroy; override;
|
||||
procedure Execute(s: string; x, y: integer); overload;
|
||||
procedure Execute(s: string; TopLeft: TPoint); overload;
|
||||
procedure Execute(s: string; TokenRect: TRect); overload; // Excute below or above the token // may be extended to adjust left corner too
|
||||
@ -333,47 +335,45 @@ type
|
||||
TSynCompletion = class(TSynBaseCompletion)
|
||||
private
|
||||
FShortCut: TShortCut;
|
||||
fEditors: TList;
|
||||
fEditstuffs: TList;
|
||||
FExecCommandID: TSynEditorCommand;
|
||||
FEndOfTokenChr: string;
|
||||
FOnCodeCompletion: TCodeCompletionEvent;
|
||||
procedure SetEditor(const Value: TCustomSynEdit);
|
||||
procedure backspace(Sender: TObject);
|
||||
procedure Cancel(Sender: TObject);
|
||||
procedure Validate(Sender: TObject; KeyChar: TUTF8Char; Shift: TShiftState);
|
||||
procedure UTF8KeyPress(Sender: TObject; var Key: TUTF8Char);
|
||||
procedure EditorKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
|
||||
procedure EditorKeyPress(Sender: TObject; var Key: char);
|
||||
procedure EditorUTF8KeyPress(Sender: TObject; var UTF8Key: TUTF8Char);
|
||||
procedure UTF8KeyPress(Sender: TObject; var Key: TUTF8Char); // called by the form
|
||||
function GetPreviousToken(FEditor: TCustomSynEdit): string;
|
||||
function GetFEditor: TCustomSynEdit;
|
||||
function GetEditor(i: integer): TCustomSynEdit;
|
||||
protected
|
||||
procedure OnFormPaint(Sender: TObject);
|
||||
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
|
||||
procedure SetEditor(const Value: TCustomSynEdit); override;
|
||||
procedure DoEditorAdded(AValue: TCustomSynEdit); override;
|
||||
procedure DoEditorRemoving(AValue: TCustomSynEdit); override; /////////////
|
||||
procedure SetShortCut(Value: TShortCut);
|
||||
procedure TranslateKey(Sender: TObject; Code: word; SState: TShiftState;
|
||||
var Data: pointer; var IsStartOfCombo: boolean; var Handled: boolean;
|
||||
var Command: TSynEditorCommand; FinishComboOnly: Boolean;
|
||||
var ComboKeyStrokes: TSynEditKeyStrokes);
|
||||
procedure ProcessSynCommand(Sender: TObject; AfterProcessing: boolean;
|
||||
var Handled: boolean; var Command: TSynEditorCommand;
|
||||
var AChar: TUTF8Char; Data: pointer; HandlerData: pointer);
|
||||
public
|
||||
constructor Create(AOwner: TComponent); override;
|
||||
destructor Destroy; override;
|
||||
property Editors[i: integer]: TCustomSynEdit read GetEditor;
|
||||
procedure AddEditor(aEditor: TCustomSynEdit);
|
||||
function RemoveEditor(aEditor: TCustomSynEdit): boolean;
|
||||
function EditorsCount: integer;
|
||||
function EditorsCount: integer; deprecated; // use EditorCount
|
||||
published
|
||||
property ShortCut: TShortCut read FShortCut write SetShortCut;
|
||||
property Editor: TCustomSynEdit read GetFEditor write SetEditor;
|
||||
property EndOfTokenChr: string read FEndOfTokenChr write FEndOfTokenChr;
|
||||
property OnCodeCompletion: TCodeCompletionEvent
|
||||
read FOnCodeCompletion write FOnCodeCompletion;
|
||||
property ExecCommandID: TSynEditorCommand read FExecCommandID write FExecCommandID;
|
||||
end;
|
||||
|
||||
{ TSynAutoComplete }
|
||||
|
||||
TSynAutoComplete = class(TComponent)
|
||||
private
|
||||
fEditstuffs: TList;
|
||||
FShortCut: TShortCut;
|
||||
fEditors: TList;
|
||||
fEditstuffs: TList;
|
||||
fAutoCompleteList: TStrings;
|
||||
FEndOfTokenChr: string;
|
||||
procedure SetAutoCompleteList(List: TStrings);
|
||||
@ -410,9 +410,16 @@ type
|
||||
|
||||
procedure PrettyTextOut(c: TCanvas; x, y: integer; s: string);
|
||||
|
||||
const
|
||||
ecSynCompletionExecute = ecPluginFirst + 0;
|
||||
|
||||
ecSynCompletionCount = 1;
|
||||
|
||||
implementation
|
||||
|
||||
var
|
||||
KeyOffset: integer;
|
||||
|
||||
{ TSynBaseCompletionFormSizeDrag }
|
||||
|
||||
procedure TSynBaseCompletionFormSizeDrag.MouseDown(Button: TMouseButton; Shift: TShiftState;
|
||||
@ -588,6 +595,7 @@ end;
|
||||
|
||||
destructor TSynBaseCompletionForm.Destroy;
|
||||
begin
|
||||
UnRegisterHandlers;
|
||||
FreeAndNil(Scroll);
|
||||
FreeAndNil(SizeDrag);
|
||||
FItemList.Free;
|
||||
@ -1069,15 +1077,30 @@ begin
|
||||
SizeDrag.Visible := AValue;
|
||||
end;
|
||||
|
||||
procedure TSynBaseCompletionForm.SetCurrentEditor(const AValue: TComponent);
|
||||
procedure TSynBaseCompletionForm.RegisterHandlers(EditOnly: Boolean);
|
||||
begin
|
||||
if fCurrentEditor = AValue then exit;
|
||||
if fCurrentEditor <> nil then
|
||||
TCustomSynEdit(fCurrentEditor).UnRegisterStatusChangedHandler({$IFDEF FPC}@{$ENDIF}EditorStatusChanged);
|
||||
fCurrentEditor := AValue;
|
||||
if (fCurrentEditor <> nil) and Visible then
|
||||
TCustomSynEdit(fCurrentEditor).RegisterStatusChangedHandler({$IFDEF FPC}@{$ENDIF}EditorStatusChanged,
|
||||
[scTopLine]);
|
||||
if FCurrentEditor <> nil then
|
||||
FCurrentEditor.RegisterStatusChangedHandler
|
||||
({$IFDEF FPC}@{$ENDIF}EditorStatusChanged, [scTopLine]);
|
||||
if not EditOnly then
|
||||
Application.AddOnDeactivateHandler({$IFDEF FPC}@{$ENDIF}AppDeactivated);
|
||||
end;
|
||||
|
||||
procedure TSynBaseCompletionForm.UnRegisterHandlers(EditOnly: Boolean);
|
||||
begin
|
||||
if FCurrentEditor <> nil then
|
||||
FCurrentEditor.UnRegisterStatusChangedHandler({$IFDEF FPC}@{$ENDIF}EditorStatusChanged);
|
||||
if not EditOnly then
|
||||
Application.RemoveOnDeactivateHandler({$IFDEF FPC}@{$ENDIF}AppDeactivated);
|
||||
end;
|
||||
|
||||
procedure TSynBaseCompletionForm.SetCurrentEditor(const AValue: TCustomSynEdit);
|
||||
begin
|
||||
if FCurrentEditor = AValue then exit;
|
||||
UnRegisterHandlers(True);
|
||||
FCurrentEditor := AValue;
|
||||
if Visible then
|
||||
RegisterHandlers(True);
|
||||
end;
|
||||
|
||||
procedure TSynBaseCompletionForm.SetDrawBorderWidth(const AValue: Integer);
|
||||
@ -1099,17 +1122,11 @@ procedure TSynBaseCompletionForm.SetVisible(Value: Boolean);
|
||||
begin
|
||||
if Visible = Value then exit;;
|
||||
inherited SetVisible(Value);
|
||||
if (fCurrentEditor <> nil) then begin
|
||||
if Visible then
|
||||
TCustomSynEdit(fCurrentEditor).RegisterStatusChangedHandler({$IFDEF FPC}@{$ENDIF}EditorStatusChanged,
|
||||
[scTopLine])
|
||||
else
|
||||
TCustomSynEdit(fCurrentEditor).UnRegisterStatusChangedHandler({$IFDEF FPC}@{$ENDIF}EditorStatusChanged);
|
||||
end;
|
||||
|
||||
if Value then
|
||||
Application.AddOnDeactivateHandler({$IFDEF FPC}@{$ENDIF}AppDeactivated)
|
||||
RegisterHandlers
|
||||
else
|
||||
Application.RemoveOnDeactivateHandler({$IFDEF FPC}@{$ENDIF}AppDeactivated);
|
||||
UnRegisterHandlers;
|
||||
end;
|
||||
|
||||
procedure TSynBaseCompletionForm.IncHintLock;
|
||||
@ -1186,12 +1203,6 @@ begin
|
||||
Form.Width := FWidth;
|
||||
end;
|
||||
|
||||
destructor TSynBaseCompletion.Destroy;
|
||||
begin
|
||||
Form.Free;
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
function TSynBaseCompletion.GetOnUTF8KeyPress: TUTF8KeyPressEvent;
|
||||
begin
|
||||
Result:=Form.OnUTF8KeyPress;
|
||||
@ -1683,21 +1694,6 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TSynCompletion.SetEditor(const Value: TCustomSynEdit);
|
||||
begin
|
||||
AddEditor(Value);
|
||||
Form.FCurrentEditor:=Value;
|
||||
end;
|
||||
|
||||
procedure TSynCompletion.Notification(AComponent: TComponent;
|
||||
Operation: TOperation);
|
||||
begin
|
||||
inherited Notification(AComponent, Operation);
|
||||
if (Operation = opRemove) and (fEditors <> nil) then
|
||||
if (fEditors.IndexOf(AComponent) > -1) then
|
||||
RemoveEditor(AComponent as TCustomSynEdit);
|
||||
end;
|
||||
|
||||
constructor TSynCompletion.Create(AOwner: TComponent);
|
||||
begin
|
||||
inherited Create(AOwner);
|
||||
@ -1707,9 +1703,8 @@ begin
|
||||
Form.OnCancel := {$IFDEF FPC}@{$ENDIF}Cancel;
|
||||
Form.OnPaint:=@OnFormPaint;
|
||||
FEndOfTokenChr := '()[].';
|
||||
fEditors := TList.Create;
|
||||
fEditstuffs := TList.Create;
|
||||
fShortCut := Menus.ShortCut(Ord(' '), [ssCtrl]);
|
||||
FExecCommandID := KeyOffset + ecSynCompletionExecute;
|
||||
end;
|
||||
|
||||
procedure TSynCompletion.SetShortCut(Value: TShortCut);
|
||||
@ -1717,39 +1712,50 @@ begin
|
||||
FShortCut := Value;
|
||||
end;
|
||||
|
||||
procedure TSynCompletion.EditorKeyDown(Sender: TObject;
|
||||
var Key: Word; Shift: TShiftState);
|
||||
procedure TSynCompletion.TranslateKey(Sender: TObject; Code: word; SState: TShiftState;
|
||||
var Data: pointer; var IsStartOfCombo: boolean; var Handled: boolean;
|
||||
var Command: TSynEditorCommand; FinishComboOnly: Boolean;
|
||||
var ComboKeyStrokes: TSynEditKeyStrokes);
|
||||
var
|
||||
p: TPoint;
|
||||
i: integer;
|
||||
ShortCutKey: Word;
|
||||
ShortCutShift: TShiftState;
|
||||
begin
|
||||
if Key=VK_UNKNOWN then exit;
|
||||
//debugln('TSynCompletion.EditorKeyDown A ',dbgs(Key));
|
||||
if (Form<>nil) and Form.Visible then begin
|
||||
// completion form is visible, but the synedit got a key
|
||||
// -> redirect to form
|
||||
Form.KeyDown(Key,Shift);
|
||||
//debugln('TSynCompletion.EditorKeyDown B ',dbgs(Key));
|
||||
if (Code = VK_UNKNOWN) or Handled or FinishComboOnly or (FExecCommandID = ecNone) then exit;
|
||||
|
||||
i := IndexOfEditor(Sender as TCustomSynEdit);
|
||||
if i >= 0 then begin
|
||||
ShortCutToKey(FShortCut, ShortCutKey, ShortCutShift);
|
||||
if (SState = ShortCutShift) and (Code = ShortCutKey) then begin
|
||||
Command := FExecCommandID;
|
||||
Handled := True;
|
||||
end;
|
||||
end;
|
||||
|
||||
i := fEditors.IndexOf(Sender);
|
||||
if i <> -1 then begin
|
||||
ShortCutToKey(FShortCut, ShortCutKey, ShortCutShift);
|
||||
if (Shift = ShortCutShift) and (Key = ShortCutKey) then
|
||||
end;
|
||||
|
||||
procedure TSynCompletion.ProcessSynCommand(Sender: TObject; AfterProcessing: boolean;
|
||||
var Handled: boolean; var Command: TSynEditorCommand; var AChar: TUTF8Char; Data: pointer;
|
||||
HandlerData: pointer);
|
||||
var
|
||||
p: TPoint;
|
||||
i: integer;
|
||||
begin
|
||||
if Handled or (Command <> FExecCommandID) then
|
||||
exit;
|
||||
|
||||
i := IndexOfEditor(Sender as TCustomSynEdit);
|
||||
if i >= 0 then begin
|
||||
with sender as TCustomSynEdit do begin
|
||||
if not ReadOnly and (Shift = ShortCutShift) and (Key = ShortCutKey) then begin
|
||||
if not ReadOnly then begin
|
||||
p := ClientToScreen(Point(CaretXPix, CaretYPix + LineHeight + 1));
|
||||
Form.CurrentEditor := Sender as TCustomSynEdit;
|
||||
Editor := Sender as TCustomSynEdit; // Will set Form.SetCurrentEditor
|
||||
Execute(GetPreviousToken(Sender as TCustomSynEdit), p.x, p.y);
|
||||
// eat it
|
||||
Key := VK_UNKNOWN;
|
||||
Handled := True;
|
||||
end;
|
||||
end;
|
||||
if Assigned(TRecordUsedToStoreEachEditorVars(fEditstuffs[i]^).KeyDown) then
|
||||
TRecordUsedToStoreEachEditorVars(fEditstuffs[i]^).KeyDown(sender, key, shift);
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
function TSynCompletion.GetPreviousToken(FEditor: TCustomSynEdit): string;
|
||||
@ -1774,95 +1780,35 @@ begin
|
||||
result := '';
|
||||
end;
|
||||
|
||||
procedure TSynCompletion.EditorKeyPress(Sender: TObject; var Key: char);
|
||||
procedure TSynCompletion.DoEditorAdded(AValue: TCustomSynEdit);
|
||||
begin
|
||||
inherited DoEditorAdded(AValue);
|
||||
|
||||
AValue.RegisterCommandHandler(@ProcessSynCommand, nil);
|
||||
AValue.RegisterKeyTranslationHandler(@TranslateKey);
|
||||
end;
|
||||
|
||||
procedure TSynCompletion.DoEditorRemoving(AValue: TCustomSynEdit);
|
||||
var
|
||||
i: integer;
|
||||
i: Integer;
|
||||
begin
|
||||
//debugln(['TSynCompletion.EditorKeyPress ']);
|
||||
i := fEditors.IndexOf(Sender);
|
||||
if i <> -1 then begin
|
||||
if assigned(TRecordUsedToStoreEachEditorVars(fEditstuffs[i]^).KeyPress) then
|
||||
TRecordUsedToStoreEachEditorVars(fEditstuffs[i]^).KeyPress(sender, key);
|
||||
end;
|
||||
inherited DoEditorRemoving(AValue);
|
||||
if Form.CurrentEditor = AValue then
|
||||
Form.SetCurrentEditor(nil);
|
||||
|
||||
AValue.UnregisterCommandHandler(@ProcessSynCommand);
|
||||
AValue.UnRegisterKeyTranslationHandler(@TranslateKey);
|
||||
end;
|
||||
|
||||
procedure TSynCompletion.EditorUTF8KeyPress(Sender: TObject;
|
||||
var UTF8Key: TUTF8Char);
|
||||
var
|
||||
i: integer;
|
||||
procedure TSynCompletion.SetEditor(const Value: TCustomSynEdit);
|
||||
begin
|
||||
//debugln(['TSynCompletion.EditorUTF8KeyPress ']);
|
||||
i := fEditors.IndexOf(Sender);
|
||||
if i <> -1 then begin
|
||||
if assigned(TRecordUsedToStoreEachEditorVars(fEditstuffs[i]^).UTF8KeyPress) then
|
||||
TRecordUsedToStoreEachEditorVars(fEditstuffs[i]^).UTF8KeyPress(sender,UTF8Key);
|
||||
end;
|
||||
end;
|
||||
|
||||
destructor TSynCompletion.Destroy;
|
||||
begin
|
||||
// necessary to get Notification called before fEditors is freed
|
||||
Form.Free;
|
||||
Form := nil;
|
||||
while fEditors.Count <> 0 do
|
||||
RemoveEditor(TCustomSynEdit(fEditors.last));
|
||||
FreeAndNil(fEditors);
|
||||
FreeAndNil(fEditstuffs);
|
||||
inherited;
|
||||
end;
|
||||
|
||||
function TSynCompletion.GetFEditor: TCustomSynEdit;
|
||||
begin
|
||||
Result:=TCustomSynEdit(Form.fCurrentEditor);
|
||||
end;
|
||||
|
||||
procedure TSynCompletion.AddEditor(aEditor: TCustomSynEdit);
|
||||
var
|
||||
p: PRecordUsedToStoreEachEditorVars;
|
||||
begin
|
||||
if fEditors.IndexOf(aEditor) = -1 then begin
|
||||
fEditors.Add(aEditor);
|
||||
new(p);
|
||||
p^.KeyPress := aEditor.OnKeyPress;
|
||||
p^.UTF8KeyPress := aEditor.OnUTF8KeyPress;
|
||||
p^.KeyDown := aEditor.OnKeyDown;
|
||||
fEditstuffs.add(p);
|
||||
aEditor.FreeNotification(self);
|
||||
if not (csDesigning in ComponentState) then begin
|
||||
aEditor.OnKeyDown := {$IFDEF FPC}@{$ENDIF}EditorKeyDown;
|
||||
aEditor.OnKeyPress := {$IFDEF FPC}@{$ENDIF}EditorKeyPress;
|
||||
aEditor.OnUTF8KeyPress := {$IFDEF FPC}@{$ENDIF}EditorUTF8KeyPress;
|
||||
end;
|
||||
end;
|
||||
inherited SetEditor(Value);
|
||||
Form.SetCurrentEditor(Value);
|
||||
end;
|
||||
|
||||
function TSynCompletion.EditorsCount: integer;
|
||||
begin
|
||||
result := fEditors.count;
|
||||
end;
|
||||
|
||||
function TSynCompletion.GetEditor(i: integer): TCustomSynEdit;
|
||||
begin
|
||||
if (i < 0) or (i >= EditorsCount) then
|
||||
result := nil
|
||||
else
|
||||
result := TCustomSynEdit(fEditors[i]);
|
||||
end;
|
||||
|
||||
function TSynCompletion.RemoveEditor(aEditor: TCustomSynEdit): boolean;
|
||||
var
|
||||
i: integer;
|
||||
P : PRecordUsedToStoreEachEditorVars;
|
||||
begin
|
||||
i := fEditors.Remove(aEditor);
|
||||
result := i <> -1;
|
||||
if result then
|
||||
begin
|
||||
p := fEditStuffs[i]; //shane
|
||||
dispose(p); //shane
|
||||
// dispose(fEditstuffs[i]); //commented out by shane
|
||||
fEditstuffs.delete(i);
|
||||
end;
|
||||
result := EditorCount;
|
||||
end;
|
||||
|
||||
{ TSynAutoComplete }
|
||||
@ -2184,5 +2130,8 @@ begin
|
||||
Result := Rect(0, 0, Canvas.TextWidth(AHint) + 4, FCompletionForm.FontHeight);
|
||||
end;
|
||||
|
||||
initialization
|
||||
KeyOffset := AllocatePluginKeyRange(ecSynCompletionCount, True);
|
||||
|
||||
end.
|
||||
|
||||
|
@ -359,6 +359,8 @@ type
|
||||
|
||||
TLazSynEditPlugin = class(TSynEditFriend)
|
||||
protected
|
||||
procedure BeforeEditorChange; virtual;
|
||||
procedure AfterEditorChange; virtual;
|
||||
procedure RegisterToEditor(AValue: TCustomSynEdit);
|
||||
procedure UnRegisterFromEditor(AValue: TCustomSynEdit);
|
||||
procedure SetEditor(const AValue: TCustomSynEdit); virtual;
|
||||
@ -366,8 +368,8 @@ type
|
||||
function OwnedByEditor: Boolean; virtual; // if true, this will be destroyed by synedit
|
||||
procedure DoEditorDestroyed(const AValue: TCustomSynEdit); virtual;
|
||||
|
||||
procedure DoAddEditor(AValue: TCustomSynEdit); virtual;
|
||||
procedure DoRemoveEditor(AValue: TCustomSynEdit); virtual;
|
||||
procedure DoEditorAdded(AValue: TCustomSynEdit); virtual;
|
||||
procedure DoEditorRemoving(AValue: TCustomSynEdit); virtual;
|
||||
public
|
||||
constructor Create(AOwner: TComponent); override;
|
||||
destructor Destroy; override;
|
||||
@ -8670,6 +8672,22 @@ begin
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
procedure TLazSynEditPlugin.BeforeEditorChange;
|
||||
begin
|
||||
if (Editor <> nil) then begin
|
||||
DoEditorRemoving(Editor);
|
||||
UnRegisterFromEditor(Editor);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TLazSynEditPlugin.AfterEditorChange;
|
||||
begin
|
||||
if Editor <> nil then begin
|
||||
RegisterToEditor(Editor);
|
||||
DoEditorAdded(Editor);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TLazSynEditPlugin.RegisterToEditor(AValue: TCustomSynEdit);
|
||||
begin
|
||||
if AValue.fPlugins <> nil then
|
||||
@ -8686,17 +8704,9 @@ procedure TLazSynEditPlugin.SetEditor(const AValue: TCustomSynEdit);
|
||||
begin
|
||||
if AValue = FriendEdit then exit;
|
||||
|
||||
if (FriendEdit <> nil) then begin
|
||||
DoRemoveEditor(Editor);
|
||||
UnRegisterFromEditor(Editor);
|
||||
end;
|
||||
|
||||
BeforeEditorChange;
|
||||
FriendEdit := AValue;
|
||||
|
||||
if FriendEdit <> nil then begin
|
||||
RegisterToEditor(Editor);
|
||||
DoAddEditor(Editor);
|
||||
end;
|
||||
AfterEditorChange;
|
||||
end;
|
||||
|
||||
function TLazSynEditPlugin.GetEditor: TCustomSynEdit;
|
||||
@ -8718,12 +8728,12 @@ begin
|
||||
Editor := nil;
|
||||
end;
|
||||
|
||||
procedure TLazSynEditPlugin.DoAddEditor(AValue: TCustomSynEdit);
|
||||
procedure TLazSynEditPlugin.DoEditorAdded(AValue: TCustomSynEdit);
|
||||
begin
|
||||
//
|
||||
end;
|
||||
|
||||
procedure TLazSynEditPlugin.DoRemoveEditor(AValue: TCustomSynEdit);
|
||||
procedure TLazSynEditPlugin.DoEditorRemoving(AValue: TCustomSynEdit);
|
||||
begin
|
||||
//
|
||||
end;
|
||||
|
@ -50,16 +50,27 @@ type
|
||||
|
||||
TLazSynMultiEditPlugin = class(TLazSynEditPlugin)
|
||||
private
|
||||
FEditors: TList;
|
||||
FEditorWasAdded: Boolean;
|
||||
function GetEditorCount: integer;
|
||||
function GetEditors(aIndex: integer): TCustomSynEdit;
|
||||
protected
|
||||
FEditors: TList;
|
||||
procedure SetEditor(const AValue: TCustomSynEdit); override;
|
||||
procedure DoEditorDestroyed(const AValue: TCustomSynEdit); override;
|
||||
function IndexOfEditor(const AValue: TCustomSynEdit): integer;
|
||||
procedure BeforeEditorChange; override;
|
||||
procedure AfterEditorChange; override;
|
||||
function DoRemoveEditor(AValue: TCustomSynEdit): integer;
|
||||
procedure DoEditorDestroyed(const AValue: TCustomSynEdit); override;
|
||||
public
|
||||
destructor Destroy; override;
|
||||
(* Add/RemoveEditor versus Editor
|
||||
Unless stated otherwise Plugins inherting from TLazSynMultiEditPlugin can
|
||||
either use Add/RemoveEditor or Editor (single-editor-property).
|
||||
If Editors are added via AddEditor, then an Editor only set via "Editor:="
|
||||
may be lost/ignored.
|
||||
If using AddEditor, the "Editor" property may be used to set/read the
|
||||
current Editor (out of those in the list). This does however depend on the
|
||||
inherited class.
|
||||
*)
|
||||
function AddEditor(AValue: TCustomSynEdit): integer;
|
||||
function RemoveEditor(AValue: TCustomSynEdit): integer;
|
||||
property Editors[aIndex: integer]: TCustomSynEdit read GetEditors;
|
||||
@ -92,8 +103,8 @@ type
|
||||
fCurrentEditor: TCustomSynEdit;
|
||||
fShortCut: TShortCut;
|
||||
class function DefaultShortCut: TShortCut; virtual;
|
||||
procedure DoAddEditor(aEditor: TCustomSynEdit); override;
|
||||
procedure DoRemoveEditor(aEditor: TCustomSynEdit); override;
|
||||
procedure DoEditorAdded(aEditor: TCustomSynEdit); override;
|
||||
procedure DoEditorRemoving(aEditor: TCustomSynEdit); override;
|
||||
{}
|
||||
procedure DoExecute; virtual; abstract;
|
||||
procedure DoAccept; virtual; abstract;
|
||||
@ -165,40 +176,6 @@ begin
|
||||
Result := TCustomSynEdit(FEditors[aIndex]);
|
||||
end;
|
||||
|
||||
procedure TLazSynMultiEditPlugin.SetEditor(const AValue: TCustomSynEdit);
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
if AValue = FriendEdit then exit;
|
||||
|
||||
if (not FEditorWasAdded) and (Editor <> nil) then
|
||||
RemoveEditor(Editor);
|
||||
|
||||
FEditorWasAdded := False;
|
||||
i := IndexOfEditor(AValue);
|
||||
|
||||
if (i < 0) then
|
||||
inherited SetEditor(nil)
|
||||
else
|
||||
FriendEdit := nil; // keep registered / do not call EditorRemoved
|
||||
|
||||
if AValue = nil then
|
||||
exit;
|
||||
|
||||
FEditorWasAdded := i >= 0;
|
||||
|
||||
if not FEditorWasAdded then
|
||||
inherited SetEditor(AValue)
|
||||
else
|
||||
FriendEdit := AValue; // alreade registered / do not call EditorAdded
|
||||
end;
|
||||
|
||||
procedure TLazSynMultiEditPlugin.DoEditorDestroyed(const AValue: TCustomSynEdit);
|
||||
begin
|
||||
RemoveEditor(AValue);
|
||||
inherited DoEditorDestroyed(AValue);
|
||||
end;
|
||||
|
||||
function TLazSynMultiEditPlugin.IndexOfEditor(const AValue: TCustomSynEdit): integer;
|
||||
begin
|
||||
if FEditors = nil then
|
||||
@ -207,6 +184,48 @@ begin
|
||||
Result := FEditors.IndexOf(AValue);
|
||||
end;
|
||||
|
||||
procedure TLazSynMultiEditPlugin.BeforeEditorChange;
|
||||
begin
|
||||
if (Editor = nil) or FEditorWasAdded then
|
||||
exit;
|
||||
|
||||
// Current Editor was not explicitly added by user via "AddEditor"
|
||||
DoRemoveEditor(Editor);
|
||||
end;
|
||||
|
||||
procedure TLazSynMultiEditPlugin.AfterEditorChange;
|
||||
begin
|
||||
if (Editor = nil) then
|
||||
exit;
|
||||
FEditorWasAdded := IndexOfEditor(Editor) >= 0;
|
||||
if FEditorWasAdded then
|
||||
exit;
|
||||
|
||||
// Current Editor was not explicitly added by user via "AddEditor"
|
||||
// Temporary add it
|
||||
AddEditor(Editor);
|
||||
FEditorWasAdded := False; // Reset Flag, after AddEditor
|
||||
end;
|
||||
|
||||
function TLazSynMultiEditPlugin.DoRemoveEditor(AValue: TCustomSynEdit): integer;
|
||||
begin
|
||||
if IndexOfEditor(AValue) < 0 then begin
|
||||
Result := -1;
|
||||
Exit;
|
||||
end;
|
||||
|
||||
DoEditorRemoving(AValue);
|
||||
UnRegisterFromEditor(AValue);
|
||||
Result := FEditors.Remove(AValue);
|
||||
end;
|
||||
|
||||
procedure TLazSynMultiEditPlugin.DoEditorDestroyed(const AValue: TCustomSynEdit);
|
||||
begin
|
||||
RemoveEditor(AValue);
|
||||
if EditorCount = 0 then
|
||||
inherited DoEditorDestroyed(nil); // Editor is nil now, so pass nil as param too
|
||||
end;
|
||||
|
||||
function TLazSynMultiEditPlugin.AddEditor(AValue: TCustomSynEdit): integer;
|
||||
begin
|
||||
if AValue = Editor then
|
||||
@ -219,28 +238,17 @@ begin
|
||||
|
||||
if FEditors = nil then
|
||||
FEditors := TList.Create;
|
||||
|
||||
Result := FEditors.Add(AValue);
|
||||
RegisterToEditor(AValue);
|
||||
DoAddEditor( AValue );
|
||||
DoEditorAdded(AValue);
|
||||
end;
|
||||
|
||||
function TLazSynMultiEditPlugin.RemoveEditor(AValue: TCustomSynEdit): integer;
|
||||
begin
|
||||
if AValue = Editor then
|
||||
FEditorWasAdded := False;
|
||||
|
||||
if IndexOfEditor(AValue) < 0 then begin
|
||||
Result := -1;
|
||||
Exit;
|
||||
end;
|
||||
Editor := nil;
|
||||
|
||||
DoRemoveEditor(AValue);
|
||||
UnRegisterFromEditor(AValue);
|
||||
Result := FEditors.Remove( AValue );
|
||||
|
||||
if AValue = Editor then
|
||||
FriendEdit := nil;
|
||||
end;
|
||||
|
||||
destructor TLazSynMultiEditPlugin.Destroy;
|
||||
@ -355,7 +363,7 @@ begin
|
||||
inherited;
|
||||
end;
|
||||
|
||||
procedure TAbstractSynSingleHookPlugin.DoAddEditor(
|
||||
procedure TAbstractSynSingleHookPlugin.DoEditorAdded(
|
||||
aEditor: TCustomSynEdit);
|
||||
begin
|
||||
if ShortCut <> 0 then
|
||||
@ -388,7 +396,7 @@ begin
|
||||
Result := fShortCut <> DefaultShortCut;
|
||||
end;
|
||||
|
||||
procedure TAbstractSynSingleHookPlugin.DoRemoveEditor(aEditor: TCustomSynEdit);
|
||||
procedure TAbstractSynSingleHookPlugin.DoEditorRemoving(aEditor: TCustomSynEdit);
|
||||
begin
|
||||
if ShortCut <> 0 then
|
||||
UnHookEditor( aEditor, CommandID, ShortCut );
|
||||
|
@ -202,8 +202,8 @@ type
|
||||
procedure SetShortCut(const Index: Integer; const Value: TShortCut);
|
||||
function GetIsEmpty: boolean;
|
||||
procedure StateChanged;
|
||||
procedure DoAddEditor(aEditor: TCustomSynEdit); override;
|
||||
procedure DoRemoveEditor(aEditor: TCustomSynEdit); override;
|
||||
procedure DoEditorAdded(aEditor: TCustomSynEdit); override;
|
||||
procedure DoEditorRemoving(aEditor: TCustomSynEdit); override;
|
||||
procedure OnCommand(Sender: TObject; AfterProcessing: boolean;
|
||||
var Handled: boolean; var Command: TSynEditorCommand;
|
||||
var aChar: TUTF8Char;
|
||||
@ -431,7 +431,7 @@ begin
|
||||
inherited;
|
||||
end;
|
||||
|
||||
procedure TCustomSynMacroRecorder.DoAddEditor(aEditor: TCustomSynEdit);
|
||||
procedure TCustomSynMacroRecorder.DoEditorAdded(aEditor: TCustomSynEdit);
|
||||
begin
|
||||
if (RecordCommandID <> ecNone) and (RecordShortCut <> 0) then
|
||||
HookEditor( aEditor, RecordCommandID, 0, RecordShortCut, []);
|
||||
@ -443,7 +443,7 @@ begin
|
||||
aEditor.RegisterCommandHandler( {$IFDEF FPC}@{$ENDIF}OnFinishCommand, Self, [hcfFinish]);
|
||||
end;
|
||||
|
||||
procedure TCustomSynMacroRecorder.DoRemoveEditor(aEditor: TCustomSynEdit);
|
||||
procedure TCustomSynMacroRecorder.DoEditorRemoving(aEditor: TCustomSynEdit);
|
||||
begin
|
||||
if RecordCommandID <> ecNone then
|
||||
UnHookEditor( aEditor, RecordCommandID, RecordShortCut );
|
||||
@ -779,7 +779,7 @@ var
|
||||
c: TSynEditorCommand;
|
||||
begin
|
||||
c := GetCommandIDs(ord(ACmd));
|
||||
if (not Assigned(fEditors)) or (c = ecNone) then
|
||||
if (c = ecNone) then
|
||||
exit;
|
||||
|
||||
if fShortCuts[ACmd] = 0 then begin
|
||||
@ -787,7 +787,7 @@ begin
|
||||
exit;
|
||||
end;
|
||||
|
||||
for cEditor := 0 to fEditors.Count -1 do
|
||||
for cEditor := 0 to EditorCount -1 do
|
||||
HookEditor(Editors[cEditor], c, AnOldShortCut, fShortCuts[ACmd], []);
|
||||
end;
|
||||
|
||||
@ -797,10 +797,10 @@ var
|
||||
cEditor: Integer;
|
||||
begin
|
||||
c := GetCommandIDs(ord(ACmd));
|
||||
if (not Assigned(fEditors)) or (c = ecNone) then
|
||||
if (c = ecNone) then
|
||||
exit;
|
||||
|
||||
for cEditor := 0 to fEditors.Count -1 do
|
||||
for cEditor := 0 to EditorCount -1 do
|
||||
UnHookEditor(Editors[cEditor], c, fShortCuts[ACmd]);
|
||||
end;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user