mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-06-01 10:32:37 +02:00
synedit: better handle line changes
git-svn-id: trunk@17720 -
This commit is contained in:
parent
13a160ad52
commit
d094e7acee
@ -5824,13 +5824,14 @@ end;
|
||||
|
||||
function TCustomSynEdit.GetLineState(ALine: Integer): TSynLineState;
|
||||
begin
|
||||
if fUndoList.IsLineExists(ALine, False) then
|
||||
Result := slsUnsaved
|
||||
else
|
||||
if fUndoList.IsLineExists(ALine, True) then
|
||||
Result := slsSaved
|
||||
else
|
||||
Result := slsNone;
|
||||
with TSynEditStringList(fLines) do
|
||||
if [sfModified, sfSaved] * Flags[ALine] = [sfModified] then
|
||||
Result := slsUnsaved
|
||||
else
|
||||
if [sfModified, sfSaved] * Flags[ALine] = [sfModified, sfSaved] then
|
||||
Result := slsSaved
|
||||
else
|
||||
Result := slsNone;
|
||||
end;
|
||||
|
||||
procedure TCustomSynEdit.UndoItem;
|
||||
@ -9429,6 +9430,7 @@ begin
|
||||
// the current state should be the unmodified state.
|
||||
fUndoList.MarkTopAsUnmodified;
|
||||
fRedoList.MarkTopAsUnmodified;
|
||||
TSynEditStringList(fLines).MarkSaved;
|
||||
if fGutter.Visible and fGutter.ShowChanges then
|
||||
InvalidateGutter;
|
||||
end;
|
||||
@ -10037,9 +10039,15 @@ begin
|
||||
end;
|
||||
|
||||
procedure TCustomSynEdit.UndoRedoAdded(Sender: TObject);
|
||||
var
|
||||
Item: TSynEditUndoItem;
|
||||
begin
|
||||
// Modified := TRUE;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
Item := TSynEditUndoList(Sender).PeekItem;
|
||||
if Item <> nil then
|
||||
TSynEditStringList(fLines).MarkModified(Item.ChangeStartPos.y - 1,
|
||||
Item.ChangeEndPos.y - 1, Sender = fUndoList, Item.fChangeReason);
|
||||
if fUndoList.UnModifiedMarkerExists then
|
||||
Modified:=not fUndoList.IsTopMarkedAsUnmodified
|
||||
else if fRedoList.UnModifiedMarkerExists then
|
||||
|
@ -56,10 +56,23 @@ type
|
||||
TSynEditRange = pointer;
|
||||
{$ENDIF}
|
||||
|
||||
{begin} //mh 2000-10-19
|
||||
TSynEditStringFlag = (sfHasTabs, sfHasNoTabs, sfExpandedLengthUnknown);
|
||||
TSynEditStringFlag = (
|
||||
sfHasTabs, //
|
||||
sfHasNoTabs, //
|
||||
sfExpandedLengthUnknown, //
|
||||
sfModified, // a line is modified and not saved after
|
||||
sfSaved // a line is modified and saved after
|
||||
);
|
||||
TSynEditStringFlags = set of TSynEditStringFlag;
|
||||
{end} //mh 2000-10-19
|
||||
|
||||
TSynChangeReason = (crInsert, crPaste, crDragDropInsert,
|
||||
// Note: crSelDelete and crDragDropDelete have been deleted, because
|
||||
// several undo entries can be chained together now via the ChangeNumber
|
||||
// see also TCustomSynEdit.[Begin|End]UndoBlock methods
|
||||
crDeleteAfterCursor, crDelete, {crSelDelete, crDragDropDelete, } //mh 2000-11-20
|
||||
crLineBreak, crIndent, crUnindent,
|
||||
crSilentDelete, crSilentDeleteAfterCursor, //mh 2000-10-30
|
||||
crNothing {$IFDEF SYN_LAZARUS}, crTrimSpace {$ENDIF});
|
||||
|
||||
PSynEditStringRec = ^TSynEditStringRec;
|
||||
TSynEditStringRec = record
|
||||
@ -116,6 +129,7 @@ type
|
||||
function ExpandedString(Index: integer): string;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
function ExpandedStringLength(Index: integer): integer;
|
||||
function GetFlags(Index: Integer): TSynEditStringFlags;
|
||||
{$ENDIF}
|
||||
{$IFNDEF SYN_LAZARUS} // protected in SynLazarus
|
||||
function GetExpandedString(Index: integer): string;
|
||||
@ -171,6 +185,8 @@ type
|
||||
procedure SaveToFile(const FileName: string); override;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
procedure ClearRanges(ARange: TSynEditRange); override;
|
||||
procedure MarkModified(AFirst, ALast: Integer; AUndo: Boolean; AReason: TSynChangeReason);
|
||||
procedure MarkSaved;
|
||||
{$ENDIF}
|
||||
public
|
||||
property DosFileFormat: boolean read fDosFileFormat write fDosFileFormat;
|
||||
@ -194,21 +210,13 @@ type
|
||||
write SetFoldMinLevel;
|
||||
property FoldEndLevel[Index: integer]: integer read GetFoldEndLevel
|
||||
write SetFoldEndLevel;
|
||||
property Flags[Index: Integer]: TSynEditStringFlags read GetFlags;
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
ESynEditStringList = class(Exception);
|
||||
{end} //mh 2000-10-10
|
||||
|
||||
TSynChangeReason = (crInsert, crPaste, crDragDropInsert,
|
||||
// Note: crSelDelete and crDragDropDelete have been deleted, because
|
||||
// several undo entries can be chained together now via the ChangeNumber
|
||||
// see also TCustomSynEdit.[Begin|End]UndoBlock methods
|
||||
crDeleteAfterCursor, crDelete, {crSelDelete, crDragDropDelete, } //mh 2000-11-20
|
||||
crLineBreak, crIndent, crUnindent,
|
||||
crSilentDelete, crSilentDeleteAfterCursor, //mh 2000-10-30
|
||||
crNothing {$IFDEF SYN_LAZARUS}, crTrimSpace {$ENDIF});
|
||||
|
||||
{ TSynEditUndoItem }
|
||||
|
||||
TSynEditUndoItem = class(TObject)
|
||||
@ -225,6 +233,8 @@ type
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
{ TSynEditUndoList }
|
||||
|
||||
TSynEditUndoList = class(TObject)
|
||||
private
|
||||
fBlockChangeNumber: integer; //sbs 2000-11-19
|
||||
@ -259,7 +269,6 @@ type
|
||||
procedure MarkTopAsUnmodified;
|
||||
function IsTopMarkedAsUnmodified: boolean;
|
||||
function UnModifiedMarkerExists: boolean;
|
||||
function IsLineExists(ALine: Integer; InUnmodified: Boolean): Boolean;
|
||||
{$ENDIF}
|
||||
public
|
||||
property BlockChangeNumber: integer read fBlockChangeNumber //sbs 2000-11-19
|
||||
@ -730,6 +739,14 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function TSynEditStringList.GetFlags(Index: Integer): TSynEditStringFlags;
|
||||
begin
|
||||
if (Index >= 0) and (Index < fCount) then
|
||||
Result := fList^[Index].fFlags
|
||||
else
|
||||
Result := [];
|
||||
end;
|
||||
|
||||
function TSynEditStringList.GetFoldEndLevel(Index: integer): integer;
|
||||
begin
|
||||
if (Index >= 0) and (Index < fCount) then
|
||||
@ -1040,6 +1057,27 @@ begin
|
||||
fList^[Index].fRange := ARange;
|
||||
end;
|
||||
|
||||
procedure TSynEditStringList.MarkModified(AFirst, ALast: Integer;
|
||||
AUndo: Boolean; AReason: TSynChangeReason);
|
||||
var
|
||||
Index: Integer;
|
||||
begin
|
||||
// AUndo = True => this change is also pushed to the undo list, False => to the redo list
|
||||
// AReason - a reason of change
|
||||
|
||||
for Index := AFirst to ALast do
|
||||
if (Index >= 0) and (Index < Count) then
|
||||
fList^[Index].fFlags := fList^[Index].fFlags + [sfModified] - [sfSaved];
|
||||
end;
|
||||
|
||||
procedure TSynEditStringList.MarkSaved;
|
||||
var
|
||||
Index: Integer;
|
||||
begin
|
||||
for Index := 0 to fCount - 1 do
|
||||
if sfModified in fList^[Index].fFlags then
|
||||
include(fList^[Index].fFlags, sfSaved);
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
procedure TSynEditStringList.SetCapacity(NewCapacity: integer);
|
||||
@ -1273,38 +1311,6 @@ begin
|
||||
Result:=fUnModifiedItem>=0;
|
||||
end;
|
||||
|
||||
function TSynEditUndoList.IsLineExists(ALine: Integer; InUnmodified: Boolean): Boolean;
|
||||
var
|
||||
I, Start, Stop: Integer;
|
||||
Item: TSynEditUndoItem;
|
||||
begin
|
||||
Result := False;
|
||||
if InUnmodified then
|
||||
begin
|
||||
Start := 0;
|
||||
Stop := fUnModifiedItem - 1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
Start := fUnModifiedItem;
|
||||
Stop := fItems.Count - 1;
|
||||
if Stop < 0 then
|
||||
Exit;
|
||||
if Start < 0 then
|
||||
Start := 0;
|
||||
end;
|
||||
|
||||
for I := Start to Stop do
|
||||
begin
|
||||
Item := TSynEditUndoItem(FItems[I]);
|
||||
if (ALine >= Item.ChangeStartPos.y) and (ALine <= Item.ChangeEndPos.y) then
|
||||
begin
|
||||
Result := True;
|
||||
Exit;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
{$ENDIF}
|
||||
|
||||
{ TSynEditUndoItem }
|
||||
|
@ -103,7 +103,7 @@ begin
|
||||
rcLine.Bottom := FirstLine * LineHeight;
|
||||
for i := FirstLine to LastLine do
|
||||
begin
|
||||
iLine := FFoldView.DisplayNumber[i];
|
||||
iLine := FFoldView.TextIndex[i];
|
||||
// next line rect
|
||||
rcLine.Top := rcLine.Bottom;
|
||||
Inc(rcLine.Bottom, LineHeight);
|
||||
|
Loading…
Reference in New Issue
Block a user