diff --git a/components/synedit/synedit.pp b/components/synedit/synedit.pp index b9d4dd08ef..46a3f3ab93 100644 --- a/components/synedit/synedit.pp +++ b/components/synedit/synedit.pp @@ -277,19 +277,18 @@ type TSynLineState = (slsNone, slsSaved, slsUnsaved); - TSynEditPlugin = class(TObject) + { TSynEditPlugin } + + TSynEditPlugin = class(TSynEditFriend) private - fOwner: TCustomSynEdit; + procedure SetSynedit(const AValue: TCustomSynEdit); + function GetSynEdit: TCustomSynEdit; protected - procedure AfterPaint(ACanvas: TCanvas; AClip: TRect; - FirstLine, LastLine: integer); virtual; abstract; - procedure LinesInserted(FirstLine, Count: integer); virtual; abstract; - procedure LinesDeleted(FirstLine, Count: integer); virtual; abstract; - protected - property Editor: TCustomSynEdit read fOwner; //mh 2000-11-10 + function OwnedByEditor: Boolean; virtual; // if true, this will be destroyed by synedit public - constructor Create(AOwner: TCustomSynEdit); + constructor Create(AOwner: TComponent); override; destructor Destroy; override; + property Editor: TCustomSynEdit read GetSynEdit write SetSynedit; end; TSynMouseLinkEvent = procedure ( @@ -511,8 +510,6 @@ type {$ENDIF} procedure MoveCaretHorz(DX: integer; SelectionCommand: boolean); procedure MoveCaretVert(DY: integer; SelectionCommand: boolean); - procedure PluginsAfterPaint(ACanvas: TCanvas; AClip: TRect; - FirstLine, LastLine: integer); {$IFDEF SYN_LAZARUS} procedure PrimarySelectionRequest(const RequestedFormatID: TClipboardFormat; Data: TStream); @@ -1753,7 +1750,8 @@ begin end; if fPlugins <> nil then begin for i := fPlugins.Count - 1 downto 0 do - TSynEditPlugin(fPlugins[i]).Free; + if TSynEditPlugin(fPlugins[i]).OwnedByEditor then + TSynEditPlugin(fPlugins[i]).Free; fPlugins.Free; end; {$IFNDEF SYN_LAZARUS} @@ -2784,7 +2782,6 @@ begin rcDraw.Left := Max(rcDraw.Left, fGutterWidth); PaintTextLines(rcDraw, nL1, nL2, nC1, nC2); end; - PluginsAfterPaint(Canvas, rcDraw, nL1, nL2); // If there is a custom paint handler call it. DoOnPaint; finally @@ -5572,7 +5569,6 @@ procedure TCustomSynEdit.CommandProcessor(Command: TSynEditorCommand; Data: pointer); var InitialCmd: TSynEditorCommand; - CaretBefore: TPoint; begin {$IFDEF VerboseKeys} DebugLn(['[TCustomSynEdit.CommandProcessor] ',Command @@ -5586,7 +5582,6 @@ begin BeginUndoBlock; FBeautifyStartLineIdx := -1; FBeautifyEndLineIdx := -1; - CaretBefore := FCaret.LineCharPos; if assigned(FBeautifier) then begin FBeautifier.AutoIndent := (eoAutoIndent in FOptions); FBeautifier.BeforeCommand(self, FTheLinesView, FCaret, Command, InitialCmd); @@ -5610,8 +5605,6 @@ begin FBeautifier.AfterCommand(self, FTheLinesView, FCaret, Command, InitialCmd, FBeautifyStartLineIdx+1, FBeautifyEndLineIdx+1); end; - if not FCaret.IsAtLineChar(CaretBefore) then - EnsureCursorPosVisible; finally EndUndoBlock; end; @@ -8692,11 +8685,6 @@ begin else if Marks[i].Line > FirstLine then Marks[i].Line := FirstLine; end; - // plugins - if fPlugins <> nil then begin - for i := 0 to fPlugins.Count - 1 do - TSynEditPlugin(fPlugins[i]).LinesDeleted(FirstLine, Count); - end; end; procedure TCustomSynEdit.DoLinesInserted(FirstLine, Count: integer); @@ -8708,23 +8696,6 @@ begin if Marks[i].Line >= FirstLine then Marks[i].Line := Marks[i].Line + Count; end; - // plugins - if fPlugins <> nil then begin - for i := 0 to fPlugins.Count - 1 do - TSynEditPlugin(fPlugins[i]).LinesInserted(FirstLine, Count); - end; -end; - -procedure TCustomSynEdit.PluginsAfterPaint(ACanvas: TCanvas; AClip: TRect; - FirstLine, LastLine: integer); -var - i: integer; -begin - if fPlugins <> nil then - for i := 0 to fPlugins.Count - 1 do begin - TSynEditPlugin(fPlugins[i]).AfterPaint(ACanvas, AClip, FirstLine, - LastLine); - end; end; {$IFDEF SYN_LAZARUS} @@ -8775,24 +8746,45 @@ end; { TSynEditPlugin } -constructor TSynEditPlugin.Create(AOwner: TCustomSynEdit); +constructor TSynEditPlugin.Create(AOwner: TComponent); begin - inherited Create; - if AOwner <> nil then begin - fOwner := AOwner; - if fOwner.fPlugins = nil then - fOwner.fPlugins := TList.Create; - fOwner.fPlugins.Add(Self); - end; + if AOwner is TCustomSynEdit then begin + inherited Create(nil); + Editor := TCustomSynEdit(AOwner); + end + else + inherited Create(AOwner); end; destructor TSynEditPlugin.Destroy; begin - if fOwner <> nil then - fOwner.fPlugins.Remove(Self); + Editor := nil; inherited Destroy; end; +procedure TSynEditPlugin.SetSynedit(const AValue: TCustomSynEdit); +begin + if AValue = FriendEdit then exit; + if (FriendEdit <> nil) and (Editor.fPlugins <> nil) then + Editor.fPlugins.Remove(FriendEdit); + FriendEdit := AValue; + if FriendEdit <> nil then begin + if Editor.fPlugins = nil then + Editor.fPlugins := TList.Create; + Editor.fPlugins.Add(Self); + end; +end; + +function TSynEditPlugin.GetSynEdit: TCustomSynEdit; +begin + Result := FriendEdit as TSynEdit; +end; + +function TSynEditPlugin.OwnedByEditor: Boolean; +begin + Result := False; +end; + procedure Register; begin RegisterClasses([TSynGutterPartList, TSynGutterSeparator, TSynGutterCodeFolding, diff --git a/components/synedit/syneditmiscclasses.pp b/components/synedit/syneditmiscclasses.pp index a62419d588..aa116729e6 100644 --- a/components/synedit/syneditmiscclasses.pp +++ b/components/synedit/syneditmiscclasses.pp @@ -63,12 +63,27 @@ type procedure SetLines(Value: TStrings); virtual; abstract; function GetViewedTextBuffer: TSynEditStrings; virtual; abstract; function GetTextBuffer: TSynEditStrings; virtual; abstract; + property ViewedTextBuffer: TSynEditStrings read GetViewedTextBuffer; // As viewed internally (with uncommited spaces / TODO: expanded tabs, folds). This may change, use with care property TextBuffer: TSynEditStrings read GetTextBuffer; // No uncommited (trailing/trimmable) spaces public property Lines: TStrings read GetLines write SetLines; end; + { TSynEditPluginBase } + + { TSynEditFriend } + + TSynEditFriend = class(TComponent) + private + FFriendEdit: TSynEditBase; + function GetViewedTextBuffer: TSynEditStrings; + protected + property FriendEdit: TSynEditBase read FFriendEdit write FFriendEdit; + property ViewedTextBuffer: TSynEditStrings read GetViewedTextBuffer; // As viewed internally (with uncommited spaces / TODO: expanded tabs, folds). This may change, use with care + end; + + TSynObjectListItem = class; { TSynObjectList } @@ -318,6 +333,13 @@ const implementation +{ TSynEditFriend } + +function TSynEditFriend.GetViewedTextBuffer: TSynEditStrings; +begin + Result := FFriendEdit.ViewedTextBuffer; +end; + { TSynSelectedColor } constructor TSynSelectedColor.Create; diff --git a/ide/sourceeditor.pp b/ide/sourceeditor.pp index bff419b765..e7074811cd 100644 --- a/ide/sourceeditor.pp +++ b/ide/sourceeditor.pp @@ -51,6 +51,7 @@ uses SynEditStrConst, SynEditTypes, SynEdit, SynRegExpr, SynEditHighlighter, SynEditAutoComplete, SynEditKeyCmds, SynCompletion, SynEditMiscClasses, SynEditMarkupHighAll, SynGutterLineNumber, SynEditMarks, SynBeautifier, + SynEditTextBase, // IDE interface MacroIntf, ProjectIntf, SrcEditorIntf, MenuIntf, LazIDEIntf, PackageIntf, IDEDialogs, IDEHelpIntf, IDEWindowIntf, IDEImagesIntf, @@ -80,22 +81,23 @@ type TOnLinesInsertedDeleted = procedure(Sender : TObject; FirstLine,Count : Integer) of Object; + { TSynEditPlugin1 } + TSynEditPlugin1 = class(TSynEditPlugin) private FOnLinesInserted : TOnLinesInsertedDeleted; FOnLinesDeleted : TOnLinesInsertedDeleted; protected - procedure AfterPaint(ACanvas: TCanvas; AClip: TRect; - FirstLine, LastLine: integer); override; - procedure LinesInserted(FirstLine, Count: integer); override; - procedure LinesDeleted(FirstLine, Count: integer); override; + Procedure LineCountChanged(Sender: TSynEditStrings; AIndex, ACount : Integer); + function OwnedByEditor: Boolean; override; public property OnLinesInserted : TOnLinesInsertedDeleted read FOnLinesinserted write FOnLinesInserted; property OnLinesDeleted : TOnLinesInsertedDeleted read FOnLinesDeleted write FOnLinesDeleted; - constructor Create(AOwner: TCustomSynEdit); + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; end; @@ -7015,27 +7017,32 @@ end; { TSynEditPlugin1 } -constructor TSynEditPlugin1.Create(AOwner: TCustomSynEdit); +constructor TSynEditPlugin1.Create(AOwner: TComponent); Begin inherited Create(AOwner); + ViewedTextBuffer.AddChangeHandler(senrLineCount, {$IFDEF FPC}@{$ENDIF}LineCountChanged); end; -procedure TSynEditPlugin1.AfterPaint(ACanvas: TCanvas; AClip: TRect; FirstLine, - LastLine: integer); +destructor TSynEditPlugin1.Destroy; begin - //don't do anything + ViewedTextBuffer.RemoveChangeHandler(senrLineCount, {$IFDEF FPC}@{$ENDIF}LineCountChanged); + inherited Destroy; end; -procedure TSynEditPlugin1.LinesDeleted(FirstLine, Count: integer); +procedure TSynEditPlugin1.LineCountChanged(Sender: TSynEditStrings; AIndex, ACount: Integer); begin - if Assigned(OnLinesDeleted) then - OnLinesDeleted(self,Firstline,Count); + if ACount < 0 then begin + if Assigned(OnLinesDeleted) then + OnLinesDeleted(self, AIndex+1, -ACount); + end else begin + if Assigned(OnLinesInserted) then + OnLinesInserted(self, AIndex+1, ACount); + end; end; -procedure TSynEditPlugin1.LinesInserted(FirstLine, Count: integer); +function TSynEditPlugin1.OwnedByEditor: Boolean; begin - if Assigned(OnLinesInserted) then - OnLinesInserted(self,Firstline,Count); + Result := True; end; //-----------------------------------------------------------------------------