synedit: better handle line changes

git-svn-id: trunk@17720 -
This commit is contained in:
paul 2008-12-08 06:54:59 +00:00
parent 13a160ad52
commit d094e7acee
3 changed files with 67 additions and 53 deletions

View File

@ -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

View File

@ -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 }

View File

@ -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);