mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-11-21 01:00:09 +01:00
SynEdit: Refactor SynMarks
git-svn-id: trunk@27037 -
This commit is contained in:
parent
206d235bd0
commit
8dae7aa8b1
@ -634,7 +634,7 @@ type
|
|||||||
procedure SetTopView(const AValue : Integer);
|
procedure SetTopView(const AValue : Integer);
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
procedure Loaded; override;
|
procedure Loaded; override;
|
||||||
procedure MarkListChange(Sender: TObject);
|
procedure MarkListChange(Sender: TSynEditMark; Changes: TSynEditMarkChangeReasons);
|
||||||
{$IFDEF SYN_MBCSSUPPORT}
|
{$IFDEF SYN_MBCSSUPPORT}
|
||||||
procedure MBCSGetSelRangeInLineWhenColumnSelectionMode(const s: string;
|
procedure MBCSGetSelRangeInLineWhenColumnSelectionMode(const s: string;
|
||||||
var ColFrom, ColTo: Integer);
|
var ColFrom, ColTo: Integer);
|
||||||
@ -1118,26 +1118,11 @@ const
|
|||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
{ TSynStatusChangedHandlerList }
|
TSynStatusChangedHandlerList = Class(TSynFilteredMethodList)
|
||||||
|
|
||||||
TStatusChangeEventHandlerListEntry = record
|
|
||||||
FHandler: TStatusChangeEvent;
|
|
||||||
FChanges: TSynStatusChanges;
|
|
||||||
end;
|
|
||||||
|
|
||||||
TSynStatusChangedHandlerList = Class
|
|
||||||
private
|
|
||||||
FCount: Integer;
|
|
||||||
FItems: Array of TStatusChangeEventHandlerListEntry;
|
|
||||||
protected
|
|
||||||
function IndexOf(AHandler: TStatusChangeEvent): Integer;
|
|
||||||
function NextDownIndex(var Index: integer): boolean;
|
|
||||||
public
|
public
|
||||||
constructor Create;
|
|
||||||
procedure Add(AHandler: TStatusChangeEvent; Changes: TSynStatusChanges);
|
procedure Add(AHandler: TStatusChangeEvent; Changes: TSynStatusChanges);
|
||||||
procedure Remove(AHandler: TStatusChangeEvent);
|
procedure Remove(AHandler: TStatusChangeEvent);
|
||||||
procedure CallStatusChangedHandlers(Sender: TObject; Changes: TSynStatusChanges);
|
procedure CallStatusChangedHandlers(Sender: TObject; Changes: TSynStatusChanges);
|
||||||
property Count: Integer read FCount;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TSynEditUndoCaret }
|
{ TSynEditUndoCaret }
|
||||||
@ -1745,7 +1730,8 @@ begin
|
|||||||
FMouseActionExecHandlerList := TSynEditMouseActionExecList.Create;
|
FMouseActionExecHandlerList := TSynEditMouseActionExecList.Create;
|
||||||
|
|
||||||
fMarkList := TSynEditMarkList.Create(self, FTheLinesView);
|
fMarkList := TSynEditMarkList.Create(self, FTheLinesView);
|
||||||
fMarkList.OnChange := {$IFDEF FPC}@{$ENDIF}MarkListChange;
|
fMarkList.RegisterChangeHandler({$IFDEF FPC}@{$ENDIF}MarkListChange,
|
||||||
|
[low(TSynEditMarkChangeReason)..high(TSynEditMarkChangeReason)]);
|
||||||
fRightEdgeColor := clSilver;
|
fRightEdgeColor := clSilver;
|
||||||
{$IFDEF SYN_MBCSSUPPORT}
|
{$IFDEF SYN_MBCSSUPPORT}
|
||||||
fImeCount := 0;
|
fImeCount := 0;
|
||||||
@ -6553,14 +6539,16 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ Called by FMarkList if change }
|
procedure TCustomSynEdit.MarkListChange(Sender: TSynEditMark; Changes: TSynEditMarkChangeReasons);
|
||||||
procedure TCustomSynEdit.MarkListChange(Sender: TObject);
|
|
||||||
begin
|
begin
|
||||||
{$IFDEF SYN_LAZARUS}
|
if (not Sender.Visible) and (not (smcrVisible in Changes)) then
|
||||||
Invalidate; // marks can have special line colors
|
exit;
|
||||||
{$ELSE}
|
if smcrLine in Changes then begin
|
||||||
InvalidateGutter;
|
InvalidateLine(Sender.OldLine);
|
||||||
{$ENDIF}
|
InvalidateGutterLines(Sender.OldLine, Sender.OldLine);
|
||||||
|
end;
|
||||||
|
InvalidateLine(Sender.Line);
|
||||||
|
InvalidateGutterLines(Sender.Line, Sender.Line);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{$IFDEF SYN_LAZARUS}
|
{$IFDEF SYN_LAZARUS}
|
||||||
@ -8715,60 +8703,15 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
{ TSynStatusChangedHandlerList }
|
{ TSynStatusChangedHandlerList }
|
||||||
|
|
||||||
function TSynStatusChangedHandlerList.IndexOf(AHandler: TStatusChangeEvent): Integer;
|
|
||||||
begin
|
|
||||||
Result := FCount - 1;
|
|
||||||
while (Result >= 0) and (FItems[Result].FHandler <> AHandler) do
|
|
||||||
dec(Result);
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TSynStatusChangedHandlerList.NextDownIndex(var Index: integer): boolean;
|
|
||||||
begin
|
|
||||||
if Self<>nil then begin
|
|
||||||
dec(Index);
|
|
||||||
if (Index>=FCount) then
|
|
||||||
Index:=FCount-1;
|
|
||||||
end else
|
|
||||||
Index:=-1;
|
|
||||||
Result:=(Index>=0);
|
|
||||||
end;
|
|
||||||
|
|
||||||
constructor TSynStatusChangedHandlerList.Create;
|
|
||||||
begin
|
|
||||||
FCount := 0;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TSynStatusChangedHandlerList.Add(AHandler: TStatusChangeEvent;
|
procedure TSynStatusChangedHandlerList.Add(AHandler: TStatusChangeEvent;
|
||||||
Changes: TSynStatusChanges);
|
Changes: TSynStatusChanges);
|
||||||
var
|
|
||||||
i: Integer;
|
|
||||||
begin
|
begin
|
||||||
i := IndexOf(AHandler);
|
AddBitFilter(TMethod(AHandler), Pointer(PtrUInt(Changes)));
|
||||||
if i >= 0 then
|
|
||||||
FItems[i].FChanges := FItems[i].FChanges + Changes
|
|
||||||
else begin
|
|
||||||
if FCount >= high(FItems) then
|
|
||||||
SetLength(FItems, Max(8, FCount * 2));
|
|
||||||
FItems[FCount].FHandler := AHandler;
|
|
||||||
FItems[FCount].FChanges := Changes;
|
|
||||||
inc(FCount);
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSynStatusChangedHandlerList.Remove(AHandler: TStatusChangeEvent);
|
procedure TSynStatusChangedHandlerList.Remove(AHandler: TStatusChangeEvent);
|
||||||
var
|
|
||||||
i: Integer;
|
|
||||||
begin
|
begin
|
||||||
i := IndexOf(AHandler);
|
inherited Remove(TMethod(AHandler));
|
||||||
if i < 0 then exit;
|
|
||||||
while i < FCount - 1 do begin
|
|
||||||
FItems[i] := FItems[i + 1];
|
|
||||||
inc(i);
|
|
||||||
end;
|
|
||||||
dec(FCount);
|
|
||||||
if length(FItems) > FCount * 4 then
|
|
||||||
SetLength(FItems, FCount * 2);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSynStatusChangedHandlerList.CallStatusChangedHandlers(Sender: TObject;
|
procedure TSynStatusChangedHandlerList.CallStatusChangedHandlers(Sender: TObject;
|
||||||
@ -8777,9 +8720,8 @@ var
|
|||||||
i: Integer;
|
i: Integer;
|
||||||
begin
|
begin
|
||||||
i:=Count;
|
i:=Count;
|
||||||
while NextDownIndex(i) do
|
while NextDownIndexBitFilter(i, Pointer(PtrUInt(Changes))) do
|
||||||
if FItems[i].FChanges * Changes <> [] then
|
TStatusChangeEvent(FItems[i].FHandler)(Sender, Changes);
|
||||||
FItems[i].FHandler(Sender, Changes);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
initialization
|
initialization
|
||||||
|
|||||||
@ -14,26 +14,56 @@ const
|
|||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
|
TSynEditMarkList = class;
|
||||||
|
TSynEditMark = class;
|
||||||
|
|
||||||
|
TSynEditMarkChangeReason = (smcrAdded, smcrRemoved, smcrLine, smcrVisible, smcrChanged);
|
||||||
|
TSynEditMarkChangeReasons = set of TSynEditMarkChangeReason;
|
||||||
|
|
||||||
|
TSynEditMarkChangeEvent = procedure(Sender: TSynEditMark; Changes: TSynEditMarkChangeReasons)
|
||||||
|
of object;
|
||||||
|
|
||||||
|
{ TSynEditMarkChangedHandlerList }
|
||||||
|
|
||||||
|
TSynEditMarkChangedHandlerList = Class(TSynFilteredMethodList)
|
||||||
|
public
|
||||||
|
procedure Add(AHandler: TSynEditMarkChangeEvent; Changes: TSynEditMarkChangeReasons);
|
||||||
|
procedure Remove(AHandler: TSynEditMarkChangeEvent);
|
||||||
|
procedure CallMarkChangedHandlers(Sender: TSynEditMark; Changes: TSynEditMarkChangeReasons);
|
||||||
|
end;
|
||||||
|
|
||||||
{ TSynEditMark }
|
{ TSynEditMark }
|
||||||
|
|
||||||
TSynEditMark = class
|
TSynEditMark = class
|
||||||
|
private
|
||||||
|
FOldLine: integer;
|
||||||
|
procedure SetMarkList(const AValue: TSynEditMarkList);
|
||||||
protected
|
protected
|
||||||
FLine, FColumn, FImage, FPriority: Integer;
|
FLine, FColumn, FImage, FPriority: Integer;
|
||||||
FEdit: TSynEditBase;
|
FEdit: TSynEditBase;
|
||||||
|
FMarkList: TSynEditMarkList;
|
||||||
FVisible: boolean;
|
FVisible: boolean;
|
||||||
FInternalImage: boolean;
|
FInternalImage: boolean;
|
||||||
FBookmarkNum: integer;
|
FBookmarkNum: integer;
|
||||||
function GetEdit: TSynEditBase; virtual;
|
FChangeLock: Integer;
|
||||||
|
FChanges: TSynEditMarkChangeReasons;
|
||||||
|
function GetEdit: TSynEditBase; virtual;
|
||||||
procedure SetColumn(const Value: Integer); virtual;
|
procedure SetColumn(const Value: Integer); virtual;
|
||||||
procedure SetImage(const Value: Integer); virtual;
|
procedure SetImage(const Value: Integer); virtual;
|
||||||
procedure SetLine(const Value: Integer); virtual;
|
procedure SetLine(const Value: Integer); virtual;
|
||||||
procedure SetPriority(const AValue: integer); virtual;
|
procedure SetPriority(const AValue: integer); virtual;
|
||||||
procedure SetVisible(const Value: boolean); virtual; //MWE: Laz needs to know when a line gets visible, so the editor color can be updated
|
procedure SetVisible(const Value: boolean); virtual;
|
||||||
procedure SetInternalImage(const Value: boolean);
|
procedure SetInternalImage(const Value: boolean);
|
||||||
function GetIsBookmark: boolean;
|
function GetIsBookmark: boolean;
|
||||||
|
procedure DoChange(AChanges: TSynEditMarkChangeReasons); virtual;
|
||||||
|
procedure ForceChange(AChanges: TSynEditMarkChangeReasons);
|
||||||
public
|
public
|
||||||
constructor Create(AOwner: TSynEditBase);
|
constructor Create(AOwner: TSynEditBase);
|
||||||
|
destructor Destroy; override;
|
||||||
|
procedure IncChangeLock;
|
||||||
|
procedure DecChangeLock;
|
||||||
property Line: integer read FLine write SetLine;
|
property Line: integer read FLine write SetLine;
|
||||||
|
property OldLine: integer read FOldLine;
|
||||||
property Column: integer read FColumn write SetColumn;
|
property Column: integer read FColumn write SetColumn;
|
||||||
property Priority: integer read FPriority write SetPriority;
|
property Priority: integer read FPriority write SetPriority;
|
||||||
property ImageIndex: integer read FImage write SetImage;
|
property ImageIndex: integer read FImage write SetImage;
|
||||||
@ -41,6 +71,7 @@ type
|
|||||||
property Visible: boolean read FVisible write SetVisible;
|
property Visible: boolean read FVisible write SetVisible;
|
||||||
property InternalImage: boolean read FInternalImage write SetInternalImage;
|
property InternalImage: boolean read FInternalImage write SetInternalImage;
|
||||||
property IsBookmark: boolean read GetIsBookmark;
|
property IsBookmark: boolean read GetIsBookmark;
|
||||||
|
property MarkList: TSynEditMarkList read FMarkList write SetMarkList;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
TPlaceMarkEvent = procedure(Sender: TObject; var Mark: TSynEditMark) of object;
|
TPlaceMarkEvent = procedure(Sender: TObject; var Mark: TSynEditMark) of object;
|
||||||
@ -57,7 +88,9 @@ type
|
|||||||
FEdit: TSynEditBase;
|
FEdit: TSynEditBase;
|
||||||
FLines: TSynEditStrings;
|
FLines: TSynEditStrings;
|
||||||
fOnChange: TNotifyEvent;
|
fOnChange: TNotifyEvent;
|
||||||
|
FChangeHandlers: TSynEditMarkChangedHandlerList;
|
||||||
procedure DoChange;
|
procedure DoChange;
|
||||||
|
procedure MarkChanged(Sender: TSynEditMark; AChanges: TSynEditMarkChangeReasons); virtual;
|
||||||
function Get(Index: Integer): TSynEditMark;
|
function Get(Index: Integer): TSynEditMark;
|
||||||
procedure Put(Index: Integer; Item: TSynEditMark);
|
procedure Put(Index: Integer; Item: TSynEditMark);
|
||||||
procedure DoLinesEdited(Sender: TSynEditStrings; aLinePos, aBytePos, aCount,
|
procedure DoLinesEdited(Sender: TSynEditStrings; aLinePos, aBytePos, aCount,
|
||||||
@ -74,6 +107,8 @@ type
|
|||||||
function Last: TSynEditMark;
|
function Last: TSynEditMark;
|
||||||
procedure Place(Mark: TSynEditMark);
|
procedure Place(Mark: TSynEditMark);
|
||||||
function Remove(Item: TSynEditMark): Integer;
|
function Remove(Item: TSynEditMark): Integer;
|
||||||
|
procedure RegisterChangeHandler(Handler: TSynEditMarkChangeEvent; Filter: TSynEditMarkChangeReasons);
|
||||||
|
procedure UnRegisterChangeHandler(Handler: TSynEditMarkChangeEvent);
|
||||||
public
|
public
|
||||||
property Items[Index: Integer]: TSynEditMark read Get write Put; default;
|
property Items[Index: Integer]: TSynEditMark read Get write Put; default;
|
||||||
property OnChange: TNotifyEvent read FOnChange write FOnChange;
|
property OnChange: TNotifyEvent read FOnChange write FOnChange;
|
||||||
@ -85,9 +120,6 @@ function DoMarksCompareBookmarksLast(Item1, Item2: Pointer): Integer;
|
|||||||
implementation
|
implementation
|
||||||
uses SynEdit;
|
uses SynEdit;
|
||||||
|
|
||||||
type // This is until InvalidateGutterLines, can be moved to an accessible place
|
|
||||||
SynEditAccess = Class(TCustomSynEdit);
|
|
||||||
|
|
||||||
function DoMarksCompareBookmarksFirst(Item1, Item2: Pointer): Integer;
|
function DoMarksCompareBookmarksFirst(Item1, Item2: Pointer): Integer;
|
||||||
var
|
var
|
||||||
Mark1: TSynEditMark absolute Item1;
|
Mark1: TSynEditMark absolute Item1;
|
||||||
@ -162,6 +194,17 @@ begin
|
|||||||
FPriority := AValue;
|
FPriority := AValue;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TSynEditMark.SetMarkList(const AValue: TSynEditMarkList);
|
||||||
|
begin
|
||||||
|
if AValue = nil then begin
|
||||||
|
DoChange([smcrRemoved]);
|
||||||
|
ForceChange(FChanges);
|
||||||
|
end;
|
||||||
|
FMarkList := AValue;
|
||||||
|
if FMarkList <> nil then
|
||||||
|
DoChange([smcrAdded]);
|
||||||
|
end;
|
||||||
|
|
||||||
function TSynEditMark.GetEdit: TSynEditBase;
|
function TSynEditMark.GetEdit: TSynEditBase;
|
||||||
begin
|
begin
|
||||||
if FEdit <> nil then try
|
if FEdit <> nil then try
|
||||||
@ -178,45 +221,61 @@ begin
|
|||||||
Result := (fBookmarkNum >= 0);
|
Result := (fBookmarkNum >= 0);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TSynEditMark.DoChange(AChanges: TSynEditMarkChangeReasons);
|
||||||
|
begin
|
||||||
|
if FChangeLock > 0 then begin
|
||||||
|
FChanges := FChanges + AChanges;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
ForceChange(AChanges);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TSynEditMark.ForceChange(AChanges: TSynEditMarkChangeReasons);
|
||||||
|
begin
|
||||||
|
if (FMarkList <> nil) and (AChanges <> []) then
|
||||||
|
FMarkList.MarkChanged(Self, AChanges);
|
||||||
|
FChanges := [];
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TSynEditMark.SetColumn(const Value: Integer);
|
procedure TSynEditMark.SetColumn(const Value: Integer);
|
||||||
begin
|
begin
|
||||||
|
if FColumn = Value then
|
||||||
|
exit;
|
||||||
FColumn := Value;
|
FColumn := Value;
|
||||||
|
DoChange([smcrChanged]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSynEditMark.SetImage(const Value: Integer);
|
procedure TSynEditMark.SetImage(const Value: Integer);
|
||||||
begin
|
begin
|
||||||
|
if FImage = Value then
|
||||||
|
exit;
|
||||||
FImage := Value;
|
FImage := Value;
|
||||||
if FVisible and Assigned(FEdit) then
|
DoChange([smcrChanged]);
|
||||||
SynEditAccess(Pointer(FEdit)).InvalidateGutterLines(FLine, FLine);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSynEditMark.SetInternalImage(const Value: boolean);
|
procedure TSynEditMark.SetInternalImage(const Value: boolean);
|
||||||
begin
|
begin
|
||||||
|
if FInternalImage = Value then
|
||||||
|
exit;
|
||||||
FInternalImage := Value;
|
FInternalImage := Value;
|
||||||
if FVisible and Assigned(FEdit) then
|
DoChange([smcrChanged]);
|
||||||
SynEditAccess(Pointer(FEdit)).InvalidateGutterLines(FLine, FLine);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSynEditMark.SetLine(const Value: Integer);
|
procedure TSynEditMark.SetLine(const Value: Integer);
|
||||||
begin
|
begin
|
||||||
if FVisible and Assigned(FEdit) then
|
if FLine = Value then
|
||||||
begin
|
exit;
|
||||||
if FLine > 0 then
|
FOldLine := FLine;
|
||||||
SynEditAccess(Pointer(FEdit)).InvalidateGutterLines(FLine, FLine);
|
FLine := Value;
|
||||||
FLine := Value;
|
DoChange([smcrLine]);
|
||||||
SynEditAccess(Pointer(FEdit)).InvalidateGutterLines(FLine, FLine);
|
|
||||||
end else
|
|
||||||
FLine := Value;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSynEditMark.SetVisible(const Value: boolean);
|
procedure TSynEditMark.SetVisible(const Value: boolean);
|
||||||
begin
|
begin
|
||||||
if FVisible <> Value then
|
if FVisible = Value then
|
||||||
begin
|
exit;
|
||||||
FVisible := Value;
|
FVisible := Value;
|
||||||
if Assigned(FEdit) then
|
DoChange([smcrVisible]);
|
||||||
SynEditAccess(Pointer(FEdit)).InvalidateGutterLines(FLine, FLine);
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
constructor TSynEditMark.Create(AOwner: TSynEditBase);
|
constructor TSynEditMark.Create(AOwner: TSynEditBase);
|
||||||
@ -227,10 +286,32 @@ begin
|
|||||||
FPriority := 0;
|
FPriority := 0;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
destructor TSynEditMark.Destroy;
|
||||||
|
begin
|
||||||
|
if FMarkList <> nil then begin
|
||||||
|
DoChange([smcrRemoved]);
|
||||||
|
FMarkList.Remove(self);
|
||||||
|
end;
|
||||||
|
inherited Destroy;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TSynEditMark.IncChangeLock;
|
||||||
|
begin
|
||||||
|
inc(FChangeLock);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TSynEditMark.DecChangeLock;
|
||||||
|
begin
|
||||||
|
dec(FChangeLock);
|
||||||
|
if (FChangeLock = 0) and (FChanges <> []) then
|
||||||
|
DoChange(FChanges);
|
||||||
|
end;
|
||||||
|
|
||||||
{ TSynEditMarkList }
|
{ TSynEditMarkList }
|
||||||
|
|
||||||
function TSynEditMarkList.Add(Item: TSynEditMark): Integer;
|
function TSynEditMarkList.Add(Item: TSynEditMark): Integer;
|
||||||
begin
|
begin
|
||||||
|
Item.MarkList := self;;
|
||||||
Result := inherited Add(Item);
|
Result := inherited Add(Item);
|
||||||
DoChange;
|
DoChange;
|
||||||
end;
|
end;
|
||||||
@ -245,6 +326,7 @@ end;
|
|||||||
|
|
||||||
constructor TSynEditMarkList.Create(AOwner: TSynEditBase; ALines: TSynEditStrings);
|
constructor TSynEditMarkList.Create(AOwner: TSynEditBase; ALines: TSynEditStrings);
|
||||||
begin
|
begin
|
||||||
|
FChangeHandlers := TSynEditMarkChangedHandlerList.Create;
|
||||||
inherited Create;
|
inherited Create;
|
||||||
FEdit := AOwner;
|
FEdit := AOwner;
|
||||||
FLines := ALines;
|
FLines := ALines;
|
||||||
@ -252,17 +334,17 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
destructor TSynEditMarkList.Destroy;
|
destructor TSynEditMarkList.Destroy;
|
||||||
var
|
|
||||||
i: integer;
|
|
||||||
begin
|
begin
|
||||||
FLines.RemoveEditHandler(@DoLinesEdited);
|
FLines.RemoveEditHandler(@DoLinesEdited);
|
||||||
for i := 0 to Pred(Count) do
|
while Count > 0 do
|
||||||
Get(i).Free;
|
Get(0).Free;
|
||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
|
FreeAndNil(FChangeHandlers);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSynEditMarkList.Delete(Index: Integer);
|
procedure TSynEditMarkList.Delete(Index: Integer);
|
||||||
begin
|
begin
|
||||||
|
Items[Index].MarkList := nil;
|
||||||
inherited Delete(Index);
|
inherited Delete(Index);
|
||||||
DoChange;
|
DoChange;
|
||||||
end;
|
end;
|
||||||
@ -273,6 +355,12 @@ begin
|
|||||||
FOnChange(Self);
|
FOnChange(Self);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TSynEditMarkList.MarkChanged(Sender: TSynEditMark;
|
||||||
|
AChanges: TSynEditMarkChangeReasons);
|
||||||
|
begin
|
||||||
|
FChangeHandlers.CallMarkChangedHandlers(Sender, AChanges);
|
||||||
|
end;
|
||||||
|
|
||||||
function TSynEditMarkList.First: TSynEditMark;
|
function TSynEditMarkList.First: TSynEditMark;
|
||||||
begin
|
begin
|
||||||
Result := TSynEditMark(inherited First);
|
Result := TSynEditMark(inherited First);
|
||||||
@ -311,6 +399,7 @@ end;
|
|||||||
|
|
||||||
procedure TSynEditMarkList.Insert(Index: Integer; Item: TSynEditMark);
|
procedure TSynEditMarkList.Insert(Index: Integer; Item: TSynEditMark);
|
||||||
begin
|
begin
|
||||||
|
Item.MarkList := Self;
|
||||||
inherited Insert(Index, Item);
|
inherited Insert(Index, Item);
|
||||||
DoChange;
|
DoChange;
|
||||||
end;
|
end;
|
||||||
@ -384,9 +473,44 @@ end;
|
|||||||
|
|
||||||
function TSynEditMarkList.Remove(Item: TSynEditMark): Integer;
|
function TSynEditMarkList.Remove(Item: TSynEditMark): Integer;
|
||||||
begin
|
begin
|
||||||
|
Item.MarkList := nil;
|
||||||
Result := inherited Remove(Item);
|
Result := inherited Remove(Item);
|
||||||
DoChange;
|
DoChange;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TSynEditMarkList.RegisterChangeHandler(Handler: TSynEditMarkChangeEvent;
|
||||||
|
Filter: TSynEditMarkChangeReasons);
|
||||||
|
begin
|
||||||
|
FChangeHandlers.Add(Handler, Filter);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TSynEditMarkList.UnRegisterChangeHandler(Handler: TSynEditMarkChangeEvent);
|
||||||
|
begin
|
||||||
|
FChangeHandlers.Remove(Handler);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TSynEditMarkChangedHandlerList }
|
||||||
|
|
||||||
|
procedure TSynEditMarkChangedHandlerList.Add(AHandler: TSynEditMarkChangeEvent;
|
||||||
|
Changes: TSynEditMarkChangeReasons);
|
||||||
|
begin
|
||||||
|
AddBitFilter(TMethod(AHandler), Pointer(PtrUInt(Changes)));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TSynEditMarkChangedHandlerList.Remove(AHandler: TSynEditMarkChangeEvent);
|
||||||
|
begin
|
||||||
|
inherited Remove(TMethod(AHandler));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TSynEditMarkChangedHandlerList.CallMarkChangedHandlers(Sender: TSynEditMark;
|
||||||
|
Changes: TSynEditMarkChangeReasons);
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
|
begin
|
||||||
|
i:=Count;
|
||||||
|
while NextDownIndexBitFilter(i, Pointer(PtrUInt(Changes))) do
|
||||||
|
TSynEditMarkChangeEvent(FItems[i].FHandler)(Sender, Changes);
|
||||||
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|||||||
@ -371,6 +371,35 @@ type
|
|||||||
read GetObjectItems write SetObjectItems; default;
|
read GetObjectItems write SetObjectItems; default;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
TSynFilteredMethodListEntry = record
|
||||||
|
FHandler: TMethod;
|
||||||
|
FFilter: Pointer;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TSynFilteredMethodList }
|
||||||
|
|
||||||
|
TSynFilteredMethodList = Class
|
||||||
|
private
|
||||||
|
FCount: Integer;
|
||||||
|
protected
|
||||||
|
FItems: Array of TSynFilteredMethodListEntry;
|
||||||
|
function IndexOf(AHandler: TMethod): Integer;
|
||||||
|
function IndexOf(AHandler: TMethod; AFilter: Pointer): Integer;
|
||||||
|
function NextDownIndex(var Index: integer): boolean;
|
||||||
|
function NextDownIndexNumFilter(var Index: integer; AFilter: Pointer): boolean;
|
||||||
|
function NextDownIndexBitFilter(var Index: integer; AFilter: Pointer): boolean;
|
||||||
|
procedure Delete(AIndex: Integer);
|
||||||
|
public
|
||||||
|
constructor Create;
|
||||||
|
procedure AddNumFilter(AHandler: TMethod; AFilter: Pointer); // Separate entries for same method with diff filter
|
||||||
|
procedure AddBitFilter(AHandler: TMethod; AFilter: Pointer); // Filter is bitmask
|
||||||
|
procedure Remove(AHandler: TMethod);
|
||||||
|
procedure Remove(AHandler: TMethod; AFilter: Pointer);
|
||||||
|
procedure CallNotifyEventsNumFilter(Sender: TObject; AFilter: Pointer);
|
||||||
|
procedure CallNotifyEventsBitFilter(Sender: TObject; AFilter: Pointer); // filter is Bitmask
|
||||||
|
property Count: Integer read FCount;
|
||||||
|
end;
|
||||||
|
|
||||||
const
|
const
|
||||||
synClipTagText = TSynClipboardStreamTag(1);
|
synClipTagText = TSynClipboardStreamTag(1);
|
||||||
synClipTagExtText = TSynClipboardStreamTag(2);
|
synClipTagExtText = TSynClipboardStreamTag(2);
|
||||||
@ -1242,5 +1271,131 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TSynFilteredMethodList }
|
||||||
|
|
||||||
|
function TSynFilteredMethodList.IndexOf(AHandler: TMethod): Integer;
|
||||||
|
begin
|
||||||
|
Result := FCount - 1;
|
||||||
|
while (Result >= 0) and
|
||||||
|
(FItems[Result].FHandler.Code <> AHandler.Code) and
|
||||||
|
(FItems[Result].FHandler.Data <> AHandler.Data)
|
||||||
|
do
|
||||||
|
dec(Result);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TSynFilteredMethodList.IndexOf(AHandler: TMethod; AFilter: Pointer): Integer;
|
||||||
|
begin
|
||||||
|
Result := FCount - 1;
|
||||||
|
while (Result >= 0) and
|
||||||
|
(FItems[Result].FHandler.Code <> AHandler.Code) and
|
||||||
|
(FItems[Result].FHandler.Data <> AHandler.Data) and
|
||||||
|
(FItems[Result].FFilter <> AFilter)
|
||||||
|
do
|
||||||
|
dec(Result);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TSynFilteredMethodList.NextDownIndex(var Index: integer): boolean;
|
||||||
|
begin
|
||||||
|
if Self<>nil then begin
|
||||||
|
dec(Index);
|
||||||
|
if (Index>=FCount) then
|
||||||
|
Index:=FCount-1;
|
||||||
|
end else
|
||||||
|
Index:=-1;
|
||||||
|
Result:=(Index>=0);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TSynFilteredMethodList.NextDownIndexNumFilter(var Index: integer;
|
||||||
|
AFilter: Pointer): boolean;
|
||||||
|
begin
|
||||||
|
Repeat
|
||||||
|
Result := NextDownIndex(Index);
|
||||||
|
until (not Result) or (FItems[Index].FFilter = AFilter);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TSynFilteredMethodList.NextDownIndexBitFilter(var Index: integer;
|
||||||
|
AFilter: Pointer): boolean;
|
||||||
|
begin
|
||||||
|
Repeat
|
||||||
|
Result := NextDownIndex(Index);
|
||||||
|
until (not Result) or (PtrUInt(FItems[Index].FFilter) and PtrUInt(AFilter) <> 0);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TSynFilteredMethodList.Delete(AIndex: Integer);
|
||||||
|
begin
|
||||||
|
if AIndex < 0 then exit;
|
||||||
|
while AIndex < FCount - 1 do begin
|
||||||
|
FItems[AIndex] := FItems[AIndex + 1];
|
||||||
|
inc(AIndex);
|
||||||
|
end;
|
||||||
|
dec(FCount);
|
||||||
|
if length(FItems) > FCount * 4 then
|
||||||
|
SetLength(FItems, FCount * 2);
|
||||||
|
end;
|
||||||
|
|
||||||
|
constructor TSynFilteredMethodList.Create;
|
||||||
|
begin
|
||||||
|
FCount := 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TSynFilteredMethodList.AddNumFilter(AHandler: TMethod; AFilter: Pointer);
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
|
begin
|
||||||
|
i := IndexOf(AHandler, AFilter);
|
||||||
|
if i >= 0 then
|
||||||
|
raise Exception.Create('Duplicate');
|
||||||
|
|
||||||
|
if FCount >= high(FItems) then
|
||||||
|
SetLength(FItems, Max(8, FCount * 2));
|
||||||
|
FItems[FCount].FHandler := AHandler;
|
||||||
|
FItems[FCount].FFilter := AFilter;
|
||||||
|
inc(FCount);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TSynFilteredMethodList.AddBitFilter(AHandler: TMethod; AFilter: Pointer);
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
|
begin
|
||||||
|
i := IndexOf(AHandler);
|
||||||
|
if i >= 0 then
|
||||||
|
FItems[i].FFilter := Pointer( PtrUInt(FItems[i].FFilter) or PtrUInt(AFilter) )
|
||||||
|
else begin
|
||||||
|
if FCount >= high(FItems) then
|
||||||
|
SetLength(FItems, Max(8, FCount * 2));
|
||||||
|
FItems[FCount].FHandler := AHandler;
|
||||||
|
FItems[FCount].FFilter := AFilter;
|
||||||
|
inc(FCount);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TSynFilteredMethodList.Remove(AHandler: TMethod);
|
||||||
|
begin
|
||||||
|
Delete(IndexOf(AHandler));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TSynFilteredMethodList.Remove(AHandler: TMethod; AFilter: Pointer);
|
||||||
|
begin
|
||||||
|
Delete(IndexOf(AHandler, AFilter));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TSynFilteredMethodList.CallNotifyEventsNumFilter(Sender: TObject; AFilter: Pointer);
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
|
begin
|
||||||
|
i:=Count;
|
||||||
|
while NextDownIndexNumFilter(i, AFilter) do
|
||||||
|
TNotifyEvent(FItems[i].FHandler)(Sender);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TSynFilteredMethodList.CallNotifyEventsBitFilter(Sender: TObject; AFilter: Pointer);
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
|
begin
|
||||||
|
i:=Count;
|
||||||
|
while NextDownIndexBitFilter(i, AFilter) do
|
||||||
|
TNotifyEvent(FItems[i].FHandler)(Sender);
|
||||||
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|||||||
@ -253,7 +253,6 @@ end;
|
|||||||
procedure TSynGutterBase.RecalcBounds;
|
procedure TSynGutterBase.RecalcBounds;
|
||||||
var
|
var
|
||||||
NewTop, NewLeft, NewHeight: Integer;
|
NewTop, NewLeft, NewHeight: Integer;
|
||||||
i: Integer;
|
|
||||||
begin
|
begin
|
||||||
// gutters act as alLeft or alRight, so Width is not computed here
|
// gutters act as alLeft or alRight, so Width is not computed here
|
||||||
NewTop := 0;
|
NewTop := 0;
|
||||||
|
|||||||
@ -18,7 +18,6 @@ type
|
|||||||
private
|
private
|
||||||
FColor: TColor;
|
FColor: TColor;
|
||||||
FHeight: Integer;
|
FHeight: Integer;
|
||||||
FProviderList: TSynGutterLineOverviewProviderList;
|
|
||||||
FGutterPart: TSynGutterLineOverview;
|
FGutterPart: TSynGutterLineOverview;
|
||||||
FPriority: Integer;
|
FPriority: Integer;
|
||||||
FRGBColor: TColor;
|
FRGBColor: TColor;
|
||||||
@ -331,8 +330,6 @@ end;
|
|||||||
|
|
||||||
procedure TSynGutterLineOverview.LineCountChanged(Sender: TSynEditStrings; AIndex,
|
procedure TSynGutterLineOverview.LineCountChanged(Sender: TSynEditStrings; AIndex,
|
||||||
ACount: Integer);
|
ACount: Integer);
|
||||||
var
|
|
||||||
r: TRect;
|
|
||||||
begin
|
begin
|
||||||
if not SynEdit.HandleAllocated then exit;
|
if not SynEdit.HandleAllocated then exit;
|
||||||
FWinControl.Invalidate;
|
FWinControl.Invalidate;
|
||||||
|
|||||||
@ -53,20 +53,15 @@ type
|
|||||||
FSourceMark: TSourceMark;
|
FSourceMark: TSourceMark;
|
||||||
FSynEdit: TSynEdit;
|
FSynEdit: TSynEdit;
|
||||||
FOnChange: TNotifyEvent;
|
FOnChange: TNotifyEvent;
|
||||||
FChangeLock: Integer;
|
FChangeLock2: Integer;
|
||||||
protected
|
protected
|
||||||
procedure Changed;
|
procedure DoChange(AChanges: TSynEditMarkChangeReasons); override;
|
||||||
property OnChange: TNotifyEvent read FOnChange write FOnChange;
|
property OnChange: TNotifyEvent read FOnChange write FOnChange;
|
||||||
procedure Assign(Src: TSourceSynMark);
|
procedure Assign(Src: TSourceSynMark);
|
||||||
public
|
public
|
||||||
constructor Create(AOwner: TSourceMark; AEditor: TSourceEditorInterface);
|
constructor Create(AOwner: TSourceMark; AEditor: TSourceEditorInterface);
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
function GetEdit: TSynEdit; override;
|
function GetEdit: TSynEdit; override;
|
||||||
procedure SetColumn(const Value: Integer); override;
|
|
||||||
procedure SetImage(const Value: Integer); override;
|
|
||||||
procedure SetLine(const Value: Integer); override;
|
|
||||||
procedure SetPriority(const AValue: integer); override;
|
|
||||||
procedure SetVisible(const Value: boolean); override;
|
|
||||||
property SourceMark: TSourceMark read FSourceMark write FSourceMark;
|
property SourceMark: TSourceMark read FSourceMark write FSourceMark;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -315,16 +310,18 @@ begin
|
|||||||
Result := -AMark.CompareEditorAndLine(EditorAndLine^.EditorID, EditorAndLine^.Line);
|
Result := -AMark.CompareEditorAndLine(EditorAndLine^.EditorID, EditorAndLine^.Line);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSourceSynMark.Changed;
|
procedure TSourceSynMark.DoChange(AChanges: TSynEditMarkChangeReasons);
|
||||||
begin
|
begin
|
||||||
if FChangeLock > 0 then exit;
|
inherited DoChange(AChanges);
|
||||||
|
if FChangeLock2 > 0 then exit;
|
||||||
if assigned(FOnChange) then
|
if assigned(FOnChange) then
|
||||||
FOnChange(Self);
|
FOnChange(Self);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSourceSynMark.Assign(Src: TSourceSynMark);
|
procedure TSourceSynMark.Assign(Src: TSourceSynMark);
|
||||||
begin
|
begin
|
||||||
inc(FChangeLock);
|
inc(FChangeLock2);
|
||||||
|
IncChangeLock;
|
||||||
try
|
try
|
||||||
Line := Src.Line;
|
Line := Src.Line;
|
||||||
Column := Src.Column;
|
Column := Src.Column;
|
||||||
@ -334,9 +331,9 @@ begin
|
|||||||
InternalImage := Src.InternalImage;
|
InternalImage := Src.InternalImage;
|
||||||
BookmarkNumber := Src.BookmarkNumber;
|
BookmarkNumber := Src.BookmarkNumber;
|
||||||
finally
|
finally
|
||||||
dec(FChangeLock);
|
DecChangeLock;
|
||||||
|
dec(FChangeLock2);
|
||||||
end;
|
end;
|
||||||
Changed;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
constructor TSourceSynMark.Create(AOwner: TSourceMark; AEditor: TSourceEditorInterface);
|
constructor TSourceSynMark.Create(AOwner: TSourceMark; AEditor: TSourceEditorInterface);
|
||||||
@ -345,7 +342,7 @@ begin
|
|||||||
FSourceEditor := AEditor;
|
FSourceEditor := AEditor;
|
||||||
FSynEdit := TSynEdit(FSourceEditor.EditorControl);
|
FSynEdit := TSynEdit(FSourceEditor.EditorControl);
|
||||||
Inherited Create(FSynEdit);
|
Inherited Create(FSynEdit);
|
||||||
FChangeLock := 0;
|
FChangeLock2 := 0;
|
||||||
if FSynEdit <> nil then
|
if FSynEdit <> nil then
|
||||||
FSynEdit.Marks.Add(Self);
|
FSynEdit.Marks.Add(Self);
|
||||||
end;
|
end;
|
||||||
@ -495,36 +492,6 @@ begin
|
|||||||
Result := FSynEdit;
|
Result := FSynEdit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSourceSynMark.SetColumn(const Value: Integer);
|
|
||||||
begin
|
|
||||||
inherited SetColumn(Value);
|
|
||||||
Changed;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TSourceSynMark.SetImage(const Value: Integer);
|
|
||||||
begin
|
|
||||||
inherited SetImage(Value);
|
|
||||||
Changed;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TSourceSynMark.SetLine(const Value: Integer);
|
|
||||||
begin
|
|
||||||
inherited SetLine(Value);
|
|
||||||
Changed;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TSourceSynMark.SetPriority(const AValue: integer);
|
|
||||||
begin
|
|
||||||
inherited SetPriority(AValue);
|
|
||||||
Changed;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TSourceSynMark.SetVisible(const Value: boolean);
|
|
||||||
begin
|
|
||||||
inherited SetVisible(Value);
|
|
||||||
Changed;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ TSourceMark }
|
{ TSourceMark }
|
||||||
|
|
||||||
procedure TSourceMark.SetSourceMarks(const AValue: TSourceMarks);
|
procedure TSourceMark.SetSourceMarks(const AValue: TSourceMarks);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user