SynEdit, Refactor: Moved Modified/ChangStamp completely to TextBuffer (shred editors share this state)

git-svn-id: trunk@24633 -
This commit is contained in:
martin 2010-04-15 18:42:04 +00:00
parent 622b9e77e6
commit 261424827b
4 changed files with 126 additions and 157 deletions

View File

@ -413,7 +413,6 @@ type
FMouseActions, FMouseSelActions: TSynEditMouseActions; FMouseActions, FMouseSelActions: TSynEditMouseActions;
FMouseActionSearchHandlerList: TSynEditMouseActionSearchList; FMouseActionSearchHandlerList: TSynEditMouseActionSearchList;
FMouseActionExecHandlerList: TSynEditMouseActionExecList; FMouseActionExecHandlerList: TSynEditMouseActionExecList;
fModified: Boolean;
fMarkList: TSynEditMarkList; fMarkList: TSynEditMarkList;
fExtraLineSpacing: integer; fExtraLineSpacing: integer;
FUseUTF8: boolean; FUseUTF8: boolean;
@ -447,16 +446,15 @@ type
fOnReplaceText: TReplaceTextEvent; fOnReplaceText: TReplaceTextEvent;
fOnSpecialLineColors: TSpecialLineColorsEvent;// needed, because bug fpc 11926 fOnSpecialLineColors: TSpecialLineColorsEvent;// needed, because bug fpc 11926
fOnStatusChange: TStatusChangeEvent; fOnStatusChange: TStatusChangeEvent;
{$IFDEF SYN_LAZARUS}
FOnSpecialLineMarkup: TSpecialLineMarkupEvent;// needed, because bug fpc 11926 FOnSpecialLineMarkup: TSpecialLineMarkupEvent;// needed, because bug fpc 11926
FOnClickLink: TMouseEvent; FOnClickLink: TMouseEvent;
FOnMouseLink: TSynMouseLinkEvent; FOnMouseLink: TSynMouseLinkEvent;
fChangeStamp: int64;
{$ENDIF}
procedure AquirePrimarySelection; procedure AquirePrimarySelection;
function GetChangeStamp: int64;
function GetDefSelectionMode: TSynSelectionMode; function GetDefSelectionMode: TSynSelectionMode;
function GetFoldState: String; function GetFoldState: String;
function GetModified: Boolean;
function GetPaintLockOwner: TSynEditBase; function GetPaintLockOwner: TSynEditBase;
function GetPlugin(Index: Integer): TSynEditPlugin; function GetPlugin(Index: Integer): TSynEditPlugin;
function GetTextBetweenPoints(aStartPoint, aEndPoint: TPoint): String; function GetTextBetweenPoints(aStartPoint, aEndPoint: TPoint): String;
@ -571,8 +569,8 @@ type
procedure SetParagraphBlock(Value: TPoint); procedure SetParagraphBlock(Value: TPoint);
procedure SizeOrFontChanged(bFont: boolean); procedure SizeOrFontChanged(bFont: boolean);
procedure StatusChanged(AChanges: TSynStatusChanges); procedure StatusChanged(AChanges: TSynStatusChanges);
procedure UpdateModified;
procedure UndoRedoAdded(Sender: TObject); procedure UndoRedoAdded(Sender: TObject);
procedure ModifiedChanged(Sender: TObject);
procedure UnlockUndo; procedure UnlockUndo;
procedure UpdateCaret(IgnorePaintLock: Boolean = False); procedure UpdateCaret(IgnorePaintLock: Boolean = False);
procedure UpdateScrollBars; procedure UpdateScrollBars;
@ -600,7 +598,6 @@ type
procedure Resize; override; procedure Resize; override;
function RealGetText: TCaption; override; function RealGetText: TCaption; override;
procedure RealSetText(const Value: TCaption); override; procedure RealSetText(const Value: TCaption); override;
procedure IncreaseChangeStamp;
function GetLines: TStrings; override; function GetLines: TStrings; override;
function GetViewedTextBuffer: TSynEditStrings; override; function GetViewedTextBuffer: TSynEditStrings; override;
function GetTextBuffer: TSynEditStrings; override; function GetTextBuffer: TSynEditStrings; override;
@ -870,7 +867,7 @@ type
property Marks: TSynEditMarkList read fMarkList; property Marks: TSynEditMarkList read fMarkList;
property MaxLeftChar: integer read fMaxLeftChar write SetMaxLeftChar property MaxLeftChar: integer read fMaxLeftChar write SetMaxLeftChar
default 1024; default 1024;
property Modified: Boolean read fModified write SetModified; property Modified: Boolean read GetModified write SetModified;
property PaintLock: Integer read fPaintLock; property PaintLock: Integer read fPaintLock;
property ReadOnly: Boolean read GetReadOnly write SetReadOnly default FALSE; property ReadOnly: Boolean read GetReadOnly write SetReadOnly default FALSE;
property SelAvail: Boolean read GetSelAvail; property SelAvail: Boolean read GetSelAvail;
@ -885,7 +882,7 @@ type
property UseUTF8: boolean read FUseUTF8; property UseUTF8: boolean read FUseUTF8;
procedure Update; override; procedure Update; override;
procedure Invalidate; override; procedure Invalidate; override;
property ChangeStamp: int64 read fChangeStamp; property ChangeStamp: int64 read GetChangeStamp;
{$ENDIF} {$ENDIF}
procedure ShareTextBufferFrom(AShareEditor: TCustomSynEdit); procedure ShareTextBufferFrom(AShareEditor: TCustomSynEdit);
procedure UnShareTextBuffer; procedure UnShareTextBuffer;
@ -1318,6 +1315,11 @@ begin
end; end;
end; end;
function TCustomSynEdit.GetChangeStamp: int64;
begin
Result := TSynEditStringList(FLines).TextChangeStamp;
end;
function TCustomSynEdit.GetDefSelectionMode: TSynSelectionMode; function TCustomSynEdit.GetDefSelectionMode: TSynSelectionMode;
begin begin
Result := FBlockSelection.SelectionMode; Result := FBlockSelection.SelectionMode;
@ -1328,6 +1330,11 @@ begin
Result := FFoldedLinesView.GetFoldDescription(0, 0, -1, -1, True); Result := FFoldedLinesView.GetFoldDescription(0, 0, -1, -1, True);
end; end;
function TCustomSynEdit.GetModified: Boolean;
begin
Result := TSynEditStringList(FLines).Modified;
end;
function TCustomSynEdit.GetPaintLockOwner: TSynEditBase; function TCustomSynEdit.GetPaintLockOwner: TSynEditBase;
begin begin
Result := TSynEditStringList(FLines).PaintLockOwner; Result := TSynEditStringList(FLines).PaintLockOwner;
@ -1536,7 +1543,7 @@ begin
FTheLinesView := FTabbedLinesView; FTheLinesView := FTabbedLinesView;
FTopLinesView := FTrimmedLinesView; FTopLinesView := FTrimmedLinesView;
// External Accessor // External Accessor
FStrings := TSynEditLines.Create(FLines, {$IFDEF FPC}@{$ENDIF}MarkTextAsSaved); FStrings := TSynEditLines.Create(TSynEditStringList(FLines), {$IFDEF FPC}@{$ENDIF}MarkTextAsSaved);
FCaret.Lines := FTheLinesView; FCaret.Lines := FTheLinesView;
FInternalCaret.Lines := FTheLinesView; FInternalCaret.Lines := FTheLinesView;
@ -1549,7 +1556,8 @@ begin
AddNotifyHandler(senrBeginUpdate, {$IFDEF FPC}@{$ENDIF}LinesChanging); AddNotifyHandler(senrBeginUpdate, {$IFDEF FPC}@{$ENDIF}LinesChanging);
AddNotifyHandler(senrEndUpdate, {$IFDEF FPC}@{$ENDIF}LinesChanged); AddNotifyHandler(senrEndUpdate, {$IFDEF FPC}@{$ENDIF}LinesChanged);
AddNotifyHandler(senrCleared, {$IFDEF FPC}@{$ENDIF}ListCleared); AddNotifyHandler(senrCleared, {$IFDEF FPC}@{$ENDIF}ListCleared);
AddNotifyHandler(senrUndoRedoAdded, {$IFDEF FPC}@{$ENDIF}UndoRedoAdded); AddNotifyHandler(senrUndoRedoAdded, {$IFDEF FPC}@{$ENDIF}Self.UndoRedoAdded);
AddNotifyHandler(senrModifiedChanged, {$IFDEF FPC}@{$ENDIF}ModifiedChanged);
end; end;
FUndoList := TSynEditStringList(fLines).UndoList; FUndoList := TSynEditStringList(fLines).UndoList;
@ -4108,14 +4116,6 @@ begin
FLines.Text := Value; // Do not trim FLines.Text := Value; // Do not trim
end; end;
procedure TCustomSynEdit.IncreaseChangeStamp;
begin
if fChangeStamp=High(fChangeStamp) then
fChangeStamp:=Low(fChangeStamp)
else
inc(fChangeStamp);
end;
function TCustomSynEdit.CurrentMaxTopLine: Integer; function TCustomSynEdit.CurrentMaxTopLine: Integer;
begin begin
if (eoScrollPastEof in Options) then if (eoScrollPastEof in Options) then
@ -4593,7 +4593,6 @@ procedure TCustomSynEdit.LineCountChanged(Sender: TSynEditStrings;
AIndex, ACount: Integer); AIndex, ACount: Integer);
begin begin
{$IFDEF SYNFOLDDEBUG}debugln(['FOLD-- LineCountChanged Aindex', AIndex, ' ACount=', ACount]);{$ENDIF} {$IFDEF SYNFOLDDEBUG}debugln(['FOLD-- LineCountChanged Aindex', AIndex, ' ACount=', ACount]);{$ENDIF}
IncreaseChangeStamp;
if (AIndex < FBeautifyStartLineIdx) or (FBeautifyStartLineIdx < 0) then if (AIndex < FBeautifyStartLineIdx) or (FBeautifyStartLineIdx < 0) then
FBeautifyStartLineIdx := AIndex; FBeautifyStartLineIdx := AIndex;
if ACount > 0 then begin if ACount > 0 then begin
@ -4628,7 +4627,6 @@ procedure TCustomSynEdit.LineTextChanged(Sender: TSynEditStrings;
AIndex, ACount: Integer); AIndex, ACount: Integer);
begin begin
{$IFDEF SYNFOLDDEBUG}debugln(['FOLD-- LineTextChanged Aindex', AIndex, ' ACount=', ACount]);{$ENDIF} {$IFDEF SYNFOLDDEBUG}debugln(['FOLD-- LineTextChanged Aindex', AIndex, ' ACount=', ACount]);{$ENDIF}
IncreaseChangeStamp;
if (AIndex < FBeautifyStartLineIdx) or (FBeautifyStartLineIdx < 0) then if (AIndex < FBeautifyStartLineIdx) or (FBeautifyStartLineIdx < 0) then
FBeautifyStartLineIdx := AIndex; FBeautifyStartLineIdx := AIndex;
if (AIndex + ACount - 1 > FBeautifyEndLineIdx) then if (AIndex + ACount - 1 > FBeautifyEndLineIdx) then
@ -5062,7 +5060,7 @@ begin
// Recreate te public access to FLines // Recreate te public access to FLines
FreeAndNil(FStrings); FreeAndNil(FStrings);
FStrings := TSynEditLines.Create(FLines, {$IFDEF FPC}@{$ENDIF}MarkTextAsSaved); FStrings := TSynEditLines.Create(TSynEditStringList(FLines), {$IFDEF FPC}@{$ENDIF}MarkTextAsSaved);
// Attach Highlighter // Attach Highlighter
if FHighlighter <> nil then if FHighlighter <> nil then
@ -7630,21 +7628,7 @@ end;
procedure TCustomSynEdit.SetModified(Value: boolean); procedure TCustomSynEdit.SetModified(Value: boolean);
begin begin
if Value then TSynEditStringList(FLines).Modified := Value;
IncreaseChangeStamp;
if Value <> fModified then
begin
fModified := Value;
{$IFDEF SYN_LAZARUS}
if not fModified then
begin
// the current state should be the unmodified state.
fUndoList.MarkTopAsUnmodified;
fRedoList.MarkTopAsUnmodified;
end;
{$ENDIF}
StatusChanged([scModified]);
end;
end; end;
{$IFNDEF SYN_LAZARUS} {$IFNDEF SYN_LAZARUS}
@ -8398,28 +8382,18 @@ begin
end; end;
end; end;
procedure TCustomSynEdit.UpdateModified;
begin
if fUndoList.UnModifiedMarkerExists then
Modified:=not fUndoList.IsTopMarkedAsUnmodified
else if fRedoList.UnModifiedMarkerExists then
Modified:=not fRedoList.IsTopMarkedAsUnmodified
else
Modified := fUndoList.CanUndo or fUndoList.FullUndoImpossible; //mh 2000-10-03
end;
procedure TCustomSynEdit.UndoRedoAdded(Sender: TObject); procedure TCustomSynEdit.UndoRedoAdded(Sender: TObject);
begin begin
IncreaseChangeStamp; // Todo: Check Paintlock, otherwise move to LinesChanged, LineCountChanged
UpdateModified;
// we have to clear the redo information, since adding undo info removes
// the necessary context to undo earlier edit actions
if (Sender = fUndoList) and not (fUndoList.IsInsideRedo) then //mh 2000-10-30
fRedoList.Clear;
if Assigned(fOnChange) then if Assigned(fOnChange) then
fOnChange(Self); fOnChange(Self);
end; end;
procedure TCustomSynEdit.ModifiedChanged(Sender: TObject);
begin
StatusChanged([scModified]);
end;
function TCustomSynEdit.LogicalToPhysicalPos(const p: TPoint): TPoint; function TCustomSynEdit.LogicalToPhysicalPos(const p: TPoint): TPoint;
begin begin
Result := FTheLinesView.LogicalToPhysicalPos(p); Result := FTheLinesView.LogicalToPhysicalPos(p);

View File

@ -34,7 +34,7 @@ unit SynEditLines;
interface interface
uses uses
Classes, SysUtils, FileUtil, FPCAdds, SynEditTextBase; Classes, SysUtils, FileUtil, FPCAdds, SynEditTextBuffer;
type type
@ -45,7 +45,7 @@ type
TSynEditLines = class(TStrings) TSynEditLines = class(TStrings)
private private
fDosFileFormat: boolean; fDosFileFormat: boolean;
FTextBuffer: TSynEditStrings; FTextBuffer: TSynEditStringList;
FOnSaved: TSavedNotification; FOnSaved: TSavedNotification;
function GetTextChangeStamp: int64; function GetTextChangeStamp: int64;
protected protected
@ -60,7 +60,7 @@ type
{$IFDEF SYN_COMPILER_3_UP} override; {$ENDIF} {$IFDEF SYN_COMPILER_3_UP} override; {$ENDIF}
procedure SetUpdateState(Updating: Boolean); override; procedure SetUpdateState(Updating: Boolean); override;
public public
constructor Create(ATextBuffer: TSynEditStrings; OnSaved: TSavedNotification); constructor Create(ATextBuffer: TSynEditStringList; OnSaved: TSavedNotification);
function Add(const S: string): integer; override; function Add(const S: string): integer; override;
procedure AddStrings(AStrings: TStrings); override; procedure AddStrings(AStrings: TStrings); override;
procedure Clear; override; procedure Clear; override;
@ -70,7 +70,7 @@ type
procedure LoadFromFile(const FileName: string); override; procedure LoadFromFile(const FileName: string); override;
procedure SaveToFile(const FileName: string); override; procedure SaveToFile(const FileName: string); override;
property DosFileFormat: boolean read fDosFileFormat write fDosFileFormat; property DosFileFormat: boolean read fDosFileFormat write fDosFileFormat;
property TextChangeStamp: int64 read GetTextChangeStamp; property TextChangeStamp: int64 read GetTextChangeStamp; deprecated '#############';
end; end;
implementation implementation
@ -273,7 +273,7 @@ end;
{ TSynEditLines } { TSynEditLines }
constructor TSynEditLines.Create(ATextBuffer: TSynEditStrings; OnSaved: TSavedNotification); constructor TSynEditLines.Create(ATextBuffer: TSynEditStringList; OnSaved: TSavedNotification);
begin begin
inherited Create; inherited Create;
FTextBuffer := ATextBuffer; FTextBuffer := ATextBuffer;

View File

@ -38,13 +38,16 @@ type
Text: String) of object; Text: String) of object;
TSynEditNotifyReason = ( // TStringListLineCountEvent TSynEditNotifyReason = ( // TStringListLineCountEvent
senrLineCount, senrLineChange, senrEditAction, senrLineCount, // Lines Inserted or Deleted (if not empty, they will trigger senrLineChange too)
senrHighlightChanged, // used by Highlighter senrLineChange, // Lines modified (also triggered by senrEditAction)
senrHighlightChanged, // used by Highlighter (invalidate and fold checks needed)
// TStringListLineEditEvent // TStringListLineEditEvent
senrTextEdit, senrEditAction, // EditInsert, EditDelete, EditLineBreak, ...
// TNotifyEvent // TNotifyEvent
senrBeginUpdate, senrEndUpdate, senrCleared, senrBeginUpdate, senrEndUpdate,
senrUndoRedoAdded senrCleared,
senrUndoRedoAdded,
senrModifiedChanged // The modified flag was changed
); );
TPhysicalCharWidths = Array of Shortint; TPhysicalCharWidths = Array of Shortint;
@ -84,7 +87,6 @@ type
TSynEditStrings = class(TStrings) TSynEditStrings = class(TStrings)
protected protected
FTextChangeStamp: int64;
FIsUtf8: Boolean; FIsUtf8: Boolean;
function GetIsUtf8 : Boolean; virtual; function GetIsUtf8 : Boolean; virtual;
procedure SetIsUtf8(const AValue : Boolean); virtual; procedure SetIsUtf8(const AValue : Boolean); virtual;
@ -161,14 +163,12 @@ type
property CurUndoList: TSynEditUndoList read GetCurUndoList; // Re or Undo (Redo while undoing) property CurUndoList: TSynEditUndoList read GetCurUndoList; // Re or Undo (Redo while undoing)
property IsUndoing: Boolean read GetIsUndoing write SetIsUndoing; property IsUndoing: Boolean read GetIsUndoing write SetIsUndoing;
property IsRedoing: Boolean read GetIsRedoing write SetIsRedoing; property IsRedoing: Boolean read GetIsRedoing write SetIsRedoing;
procedure IncreaseTextChangeStamp;
procedure SendHighlightChanged(aIndex, aCount: Integer); procedure SendHighlightChanged(aIndex, aCount: Integer);
public public
property ExpandedStrings[Index: integer]: string read GetExpandedString; property ExpandedStrings[Index: integer]: string read GetExpandedString;
property LengthOfLongestLine: integer read GetLengthOfLongestLine; property LengthOfLongestLine: integer read GetLengthOfLongestLine;
property IsUtf8: Boolean read GetIsUtf8 write SetIsUtf8; property IsUtf8: Boolean read GetIsUtf8 write SetIsUtf8;
property Ranges[Index: TClass]: TSynEditStorageMem read GetRange write PutRange; property Ranges[Index: TClass]: TSynEditStorageMem read GetRange write PutRange;
property TextChangeStamp: int64 read FTextChangeStamp;
end; end;
{ TSynEditStringsLinked } { TSynEditStringsLinked }
@ -401,12 +401,12 @@ end;
procedure TSynEditStrings.AddEditHandler(AHandler: TStringListLineEditEvent); procedure TSynEditStrings.AddEditHandler(AHandler: TStringListLineEditEvent);
begin begin
AddGenericHandler(senrTextEdit, TMethod(AHandler)); AddGenericHandler(senrEditAction, TMethod(AHandler));
end; end;
procedure TSynEditStrings.RemoveEditHandler(AHandler: TStringListLineEditEvent); procedure TSynEditStrings.RemoveEditHandler(AHandler: TStringListLineEditEvent);
begin begin
RemoveGenericHandler(senrTextEdit, TMethod(AHandler)); RemoveGenericHandler(senrEditAction, TMethod(AHandler));
end; end;
function TSynEditStrings.GetPhysicalCharWidths(Index: Integer): TPhysicalCharWidths; function TSynEditStrings.GetPhysicalCharWidths(Index: Integer): TPhysicalCharWidths;
@ -527,14 +527,6 @@ begin
Result := BytePos + 1 + PhysicalPos - ScreenPos; Result := BytePos + 1 + PhysicalPos - ScreenPos;
end; end;
procedure TSynEditStrings.IncreaseTextChangeStamp;
begin
if fTextChangeStamp=High(fTextChangeStamp) then
fTextChangeStamp:=Low(fTextChangeStamp)
else
inc(fTextChangeStamp);
end;
procedure TSynEditStrings.SendHighlightChanged(aIndex, aCount: Integer); procedure TSynEditStrings.SendHighlightChanged(aIndex, aCount: Integer);
begin begin
SendNotification(senrHighlightChanged, Self, aIndex, aCount); SendNotification(senrHighlightChanged, Self, aIndex, aCount);

View File

@ -42,9 +42,8 @@ unit SynEditTextBuffer;
interface interface
uses uses
Classes, SysUtils, SynEditTextBase, Classes, SysUtils, LCLProc, LCLIntf, LCLType,
FileUtil, LCLProc, LCLIntf, LCLType, SynEditTextBase, SynEditTypes, SynEditMiscProcs, SynEditMiscClasses;
SynEditTypes, SynEditMiscProcs, SynEditMiscClasses;
const const
NullRange = TSynEditRange(nil); NullRange = TSynEditRange(nil);
@ -139,14 +138,7 @@ type
FAttributeList: Array of TSynEditStringAttribute; FAttributeList: Array of TSynEditStringAttribute;
FAttachedSynEditList: TFPList; FAttachedSynEditList: TFPList;
FLineRangeNotificationList: TLineRangeNotificationList; // LineCount FNotifyLists: Array [TSynEditNotifyReason] of TSynMethodList;
FLineChangeNotificationList: TLineRangeNotificationList; // ContentChange (not called on add...)
FLineInvalidateNotificationList: TLineRangeNotificationList; // senrHighlightChanged
FLineEditNotificationList: TLineEditNotificationList;
FUndoRedoAddedNotificationList: TSynMethodList;
FOnChangeList: TSynMethodList;
FOnChangingList: TSynMethodList;
FOnClearedList: TSynMethodList;
FIgnoreSendNotification: array [TSynEditNotifyReason] of Integer; FIgnoreSendNotification: array [TSynEditNotifyReason] of Integer;
fDosFileFormat: boolean; fDosFileFormat: boolean;
@ -155,6 +147,9 @@ type
FUndoList: TSynEditUndoList; FUndoList: TSynEditUndoList;
FIsUndoing, FIsRedoing: Boolean; FIsUndoing, FIsRedoing: Boolean;
FModified: Boolean;
FTextChangeStamp: int64;
function GetAttachedSynEdits(Index: Integer): TSynEditBase; function GetAttachedSynEdits(Index: Integer): TSynEditBase;
function GetFlags(Index: Integer): TSynEditStringFlags; function GetFlags(Index: Integer): TSynEditStringFlags;
procedure Grow; procedure Grow;
@ -162,6 +157,7 @@ type
function ClassIndexForAttribute(AttrIndex: TClass): Integer; function ClassIndexForAttribute(AttrIndex: TClass): Integer;
Procedure SetAttributeSize(NewSize: Integer); Procedure SetAttributeSize(NewSize: Integer);
procedure SetFlags(Index: Integer; const AValue: TSynEditStringFlags); procedure SetFlags(Index: Integer; const AValue: TSynEditStringFlags);
procedure SetModified(const AValue: Boolean);
protected protected
function GetExpandedString(Index: integer): string; override; function GetExpandedString(Index: integer): string; override;
function GetLengthOfLongestLine: integer; override; function GetLengthOfLongestLine: integer; override;
@ -197,6 +193,7 @@ type
procedure SetUpdateState(Updating: Boolean); override; procedure SetUpdateState(Updating: Boolean); override;
procedure UndoEditLinesDelete(LogY, ACount: Integer); procedure UndoEditLinesDelete(LogY, ACount: Integer);
procedure IncreaseTextChangeStamp;
public public
constructor Create; constructor Create;
destructor Destroy; override; destructor Destroy; override;
@ -228,6 +225,8 @@ type
property LengthOfLongestLine: integer read GetLengthOfLongestLine; property LengthOfLongestLine: integer read GetLengthOfLongestLine;
property Flags[Index: Integer]: TSynEditStringFlags read GetFlags property Flags[Index: Integer]: TSynEditStringFlags read GetFlags
write SetFlags; write SetFlags;
property Modified: Boolean read FModified write SetModified;
property TextChangeStamp: int64 read FTextChangeStamp;
public public
property UndoList: TSynEditUndoList read GetUndoList write fUndoList; property UndoList: TSynEditUndoList read GetUndoList write fUndoList;
property RedoList: TSynEditUndoList read GetRedoList write fRedoList; property RedoList: TSynEditUndoList read GetRedoList write fRedoList;
@ -434,15 +433,17 @@ begin
fRedoList.OnAddedUndo := {$IFDEF FPC}@{$ENDIF}UndoRedoAdded; fRedoList.OnAddedUndo := {$IFDEF FPC}@{$ENDIF}UndoRedoAdded;
FIsUndoing := False; FIsUndoing := False;
FIsRedoing := False; FIsRedoing := False;
FModified := False;
FLineRangeNotificationList := TLineRangeNotificationList.Create; FNotifyLists[senrLineCount] := TLineRangeNotificationList.Create;
FLineChangeNotificationList := TLineRangeNotificationList.Create; FNotifyLists[senrLineChange] := TLineRangeNotificationList.Create;
FLineInvalidateNotificationList := TLineRangeNotificationList.Create; FNotifyLists[senrHighlightChanged] := TLineRangeNotificationList.Create;
FLineEditNotificationList := TLineEditNotificationList.Create; FNotifyLists[senrEditAction] := TLineEditNotificationList.Create;
FUndoRedoAddedNotificationList := TLineEditNotificationList.Create; FNotifyLists[senrBeginUpdate] := TSynMethodList.Create;
FOnChangeList := TSynMethodList.Create; FNotifyLists[senrEndUpdate] := TSynMethodList.Create;
FOnChangingList := TSynMethodList.Create; FNotifyLists[senrCleared] := TSynMethodList.Create;
FOnClearedList := TSynMethodList.Create; FNotifyLists[senrUndoRedoAdded] := TSynMethodList.Create;
FNotifyLists[senrModifiedChanged] := TSynMethodList.Create;
for r := low(TSynEditNotifyReason) to high(TSynEditNotifyReason) do for r := low(TSynEditNotifyReason) to high(TSynEditNotifyReason) do
FIgnoreSendNotification[r] := 0; FIgnoreSendNotification[r] := 0;
@ -456,19 +457,15 @@ begin
end; end;
destructor TSynEditStringList.Destroy; destructor TSynEditStringList.Destroy;
var
i: TSynEditNotifyReason;
begin begin
fAttributeList := nil; fAttributeList := nil;
inherited Destroy; inherited Destroy;
SetCount(0); SetCount(0);
SetCapacity(0); SetCapacity(0);
FreeAndNil(FLineRangeNotificationList); for i := low(TSynEditNotifyReason) to high(TSynEditNotifyReason) do
FreeAndNil(FLineChangeNotificationList); FreeAndNil(FNotifyLists[i]);
FreeAndNil(FLineInvalidateNotificationList);
FreeAndNil(FLineEditNotificationList);
FreeAndNil(FUndoRedoAddedNotificationList);
FreeAndNil(FOnChangeList);
FreeAndNil(FOnChangingList);
FreeAndNil(FOnClearedList);
FreeAndNil(FUndoList); FreeAndNil(FUndoList);
FreeAndNil(FRedoList); FreeAndNil(FRedoList);
FreeAndNil(FAttachedSynEditList); FreeAndNil(FAttachedSynEditList);
@ -481,7 +478,7 @@ begin
BeginUpdate; BeginUpdate;
Result := Count; Result := Count;
InsertItem(Result, S); InsertItem(Result, S);
FLineRangeNotificationList.CallRangeNotifyEvents(self, Result, Count - Result); SendNotification(senrLineCount, self, Result, Count - Result);
EndUpdate; EndUpdate;
end; end;
@ -506,7 +503,7 @@ begin
end; end;
Flags[Count-1] := []; Flags[Count-1] := [];
end; end;
FLineRangeNotificationList.CallRangeNotifyEvents(self, FirstAdded, Count - FirstAdded); SendNotification(senrLineCount, self, FirstAdded, Count - FirstAdded);
finally finally
EndUpdate; EndUpdate;
end; end;
@ -523,8 +520,8 @@ begin
BeginUpdate; BeginUpdate;
SetCount(0); SetCount(0);
SetCapacity(0); SetCapacity(0);
FOnClearedList.CallNotifyEvents(Self); FNotifyLists[senrCleared].CallNotifyEvents(Self);
FLineRangeNotificationList.CallRangeNotifyEvents(self, 0, -c); SendNotification(senrLineCount, self, 0, -c);
EndUpdate; EndUpdate;
end; end;
fIndexOfLongestLine := -1; fIndexOfLongestLine := -1;
@ -538,7 +535,7 @@ begin
BeginUpdate; BeginUpdate;
FList.DeleteRows(Index, 1); FList.DeleteRows(Index, 1);
fIndexOfLongestLine := -1; fIndexOfLongestLine := -1;
FLineRangeNotificationList.CallRangeNotifyEvents(self, Index, -1); SendNotification(senrLineCount, self, Index, -1);
EndUpdate; EndUpdate;
end; end;
@ -550,7 +547,7 @@ begin
ListIndexOutOfBounds(Index); ListIndexOutOfBounds(Index);
BeginUpdate; BeginUpdate;
FList.DeleteRows(Index, NumLines); FList.DeleteRows(Index, NumLines);
FLineRangeNotificationList.CallRangeNotifyEvents(self, Index, -NumLines); SendNotification(senrLineCount, self, Index, -NumLines);
EndUpdate; EndUpdate;
end; end;
end; end;
@ -663,7 +660,18 @@ end;
procedure TSynEditStringList.UndoRedoAdded(Sender: TObject); procedure TSynEditStringList.UndoRedoAdded(Sender: TObject);
begin begin
FUndoRedoAddedNotificationList.CallNotifyEvents(Sender); // we have to clear the redo information, since adding undo info removes
// the necessary context to undo earlier edit actions
if (Sender = fUndoList) and not (fUndoList.IsInsideRedo) then
fRedoList.Clear;
if fUndoList.UnModifiedMarkerExists then
Modified := not fUndoList.IsTopMarkedAsUnmodified
else if fRedoList.UnModifiedMarkerExists then
Modified := not fRedoList.IsTopMarkedAsUnmodified
else
Modified := fUndoList.CanUndo or fUndoList.FullUndoImpossible;
FNotifyLists[senrUndoRedoAdded].CallNotifyEvents(Sender);
end; end;
// Maps the Physical Width (ScreenCells) to each character // Maps the Physical Width (ScreenCells) to each character
@ -737,7 +745,7 @@ begin
BeginUpdate; BeginUpdate;
OldCnt:=Count; OldCnt:=Count;
InsertItem(Index, S); InsertItem(Index, S);
FLineRangeNotificationList.CallRangeNotifyEvents(self, Index, Count - OldCnt); SendNotification(senrLineCount, self, Index, Count - OldCnt);
EndUpdate; EndUpdate;
end; end;
@ -769,7 +777,7 @@ begin
if Capacity<Count + NumLines then if Capacity<Count + NumLines then
SetCapacity(Count + NumLines); SetCapacity(Count + NumLines);
FList.InsertRows(Index, NumLines); FList.InsertRows(Index, NumLines);
FLineRangeNotificationList.CallRangeNotifyEvents(self, Index, NumLines); SendNotification(senrLineCount, self, Index, NumLines);
finally finally
EndUpdate; EndUpdate;
end; end;
@ -894,6 +902,21 @@ begin
SetAttribute(TSynEditFlagsClass, Index, Pointer(PtrUInt(Integer(AValue)))); SetAttribute(TSynEditFlagsClass, Index, Pointer(PtrUInt(Integer(AValue))));
end; end;
procedure TSynEditStringList.SetModified(const AValue: Boolean);
begin
if AValue then
IncreaseTextChangeStamp;
if FModified = AValue then exit;
FModified := AValue;
if not FModified then
begin
// the current state should be the unmodified state.
FUndoList.MarkTopAsUnmodified;
FRedoList.MarkTopAsUnmodified;
end;
FNotifyLists[senrModifiedChanged].CallNotifyEvents(Self);
end;
procedure TSynEditStringList.MarkModified(AFirst, ALast: Integer); procedure TSynEditStringList.MarkModified(AFirst, ALast: Integer);
var var
Index: Integer; Index: Integer;
@ -914,54 +937,28 @@ end;
procedure TSynEditStringList.AddGenericHandler(AReason: TSynEditNotifyReason; AHandler: TMethod); procedure TSynEditStringList.AddGenericHandler(AReason: TSynEditNotifyReason; AHandler: TMethod);
begin begin
case AReason of FNotifyLists[AReason].Add(AHandler);
senrLineChange : FLineChangeNotificationList.Add(AHandler);
senrLineCount : FLineRangeNotificationList.Add(AHandler);
senrTextEdit: FLineEditNotificationList.Add(TMethod(AHandler));
senrHighlightChanged: FLineInvalidateNotificationList.Add(TMethod(AHandler));
senrBeginUpdate : FOnChangingList.Add(AHandler);
senrEndUpdate : FOnChangeList.Add(AHandler);
senrCleared : FOnClearedList.Add(AHandler);
senrUndoRedoAdded : FUndoRedoAddedNotificationList.Add(AHandler);
end;
end; end;
procedure TSynEditStringList.RemoveGenericHandler(AReason: TSynEditNotifyReason; AHandler: TMethod); procedure TSynEditStringList.RemoveGenericHandler(AReason: TSynEditNotifyReason; AHandler: TMethod);
begin begin
case AReason of FNotifyLists[AReason].Remove(AHandler);
senrLineChange : FLineChangeNotificationList.Remove(AHandler);
senrLineCount : FLineRangeNotificationList.Remove(AHandler);
senrTextEdit: FLineEditNotificationList.Remove(TMethod(AHandler));
senrHighlightChanged: FLineInvalidateNotificationList.Remove(TMethod(AHandler));
senrBeginUpdate : FOnChangingList.Remove(AHandler);
senrEndUpdate : FOnChangeList.Remove(AHandler);
senrCleared : FOnClearedList.Remove(AHandler);
senrUndoRedoAdded : FUndoRedoAddedNotificationList.Remove(AHandler);
end;
end; end;
procedure TSynEditStringList.CopyHanlders(OtherLines: TSynEditStringList; AOwner: TObject = nil); procedure TSynEditStringList.CopyHanlders(OtherLines: TSynEditStringList; AOwner: TObject = nil);
var
i: TSynEditNotifyReason;
begin begin
FLineRangeNotificationList.AddCopyFrom(OtherLines.FLineRangeNotificationList, AOwner); for i := low(TSynEditNotifyReason) to high(TSynEditNotifyReason) do
FLineChangeNotificationList.AddCopyFrom(OtherLines.FLineChangeNotificationList, AOwner); FNotifyLists[i].AddCopyFrom(OtherLines.FNotifyLists[i], AOwner);
FLineEditNotificationList.AddCopyFrom(OtherLines.FLineEditNotificationList, AOwner);
FLineInvalidateNotificationList.AddCopyFrom(OtherLines.FLineInvalidateNotificationList, AOwner);
FUndoRedoAddedNotificationList.AddCopyFrom(OtherLines.FUndoRedoAddedNotificationList, AOwner);
FOnChangeList.AddCopyFrom(OtherLines.FOnChangeList, AOwner);
FOnChangingList.AddCopyFrom(OtherLines.FOnChangingList, AOwner);
FOnClearedList.AddCopyFrom(OtherLines.FOnClearedList, AOwner);
end; end;
procedure TSynEditStringList.RemoveHanlders(AOwner: TObject); procedure TSynEditStringList.RemoveHanlders(AOwner: TObject);
var
i: TSynEditNotifyReason;
begin begin
FLineRangeNotificationList.RemoveAllMethodsOfObject(AOwner); for i := low(TSynEditNotifyReason) to high(TSynEditNotifyReason) do
FLineChangeNotificationList.RemoveAllMethodsOfObject(AOwner); FNotifyLists[i].RemoveAllMethodsOfObject(AOwner);
FLineEditNotificationList.RemoveAllMethodsOfObject(AOwner);
FLineInvalidateNotificationList.RemoveAllMethodsOfObject(AOwner);
FUndoRedoAddedNotificationList.RemoveAllMethodsOfObject(AOwner);
FOnChangeList.RemoveAllMethodsOfObject(AOwner);
FOnChangingList.RemoveAllMethodsOfObject(AOwner);
FOnClearedList.RemoveAllMethodsOfObject(AOwner);
end; end;
procedure TSynEditStringList.SetCapacity(NewCapacity: integer); procedure TSynEditStringList.SetCapacity(NewCapacity: integer);
@ -972,9 +969,9 @@ end;
procedure TSynEditStringList.SetUpdateState(Updating: Boolean); procedure TSynEditStringList.SetUpdateState(Updating: Boolean);
begin begin
if Updating then begin if Updating then begin
FOnChangingList.CallNotifyEvents(Self); FNotifyLists[senrBeginUpdate].CallNotifyEvents(Self);
end else begin end else begin
FOnChangeList.CallNotifyEvents(Self); FNotifyLists[senrEndUpdate].CallNotifyEvents(Self);
end; end;
end; end;
@ -1070,6 +1067,14 @@ begin
SendNotification(senrEditAction, self, LogY, -ACount, 1, 0, ''); SendNotification(senrEditAction, self, LogY, -ACount, 1, 0, '');
end; end;
procedure TSynEditStringList.IncreaseTextChangeStamp;
begin
if FTextChangeStamp=High(FTextChangeStamp) then
FTextChangeStamp:=Low(FTextChangeStamp)
else
inc(FTextChangeStamp);
end;
procedure TSynEditStringList.EditRedo(Item: TSynEditUndoItem); procedure TSynEditStringList.EditRedo(Item: TSynEditUndoItem);
begin begin
Item.PerformUndo(self); Item.PerformUndo(self);
@ -1081,15 +1086,13 @@ procedure TSynEditStringList.SendNotification(AReason: TSynEditNotifyReason;
begin begin
if FIgnoreSendNotification[AReason] > 0 then exit; if FIgnoreSendNotification[AReason] > 0 then exit;
case AReason of case AReason of
senrLineChange: senrLineChange, senrLineCount, senrHighlightChanged:
FLineChangeNotificationList.CallRangeNotifyEvents(ASender, aIndex, aCount); TLineRangeNotificationList(FNotifyLists[AReason])
senrLineCount: .CallRangeNotifyEvents(ASender, aIndex, aCount);
FLineRangeNotificationList.CallRangeNotifyEvents(ASender, aIndex, aCount);
senrEditAction: senrEditAction:
FLineEditNotificationList.CallRangeNotifyEvents(ASender, aIndex, // aindex is mis-named (linepos) for edit action // aindex is mis-named (linepos) for edit action
aBytePos, aLen, aCount, aTxt); TLineEditNotificationList(FNotifyLists[senrEditAction])
senrHighlightChanged: .CallRangeNotifyEvents(ASender, aIndex, aBytePos, aLen, aCount, aTxt);
FLineInvalidateNotificationList.CallRangeNotifyEvents(ASender, aIndex, aCount);
end; end;
end; end;