mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-05-01 16:43:43 +02:00
SynEdit, SourceEdtior: Decouple UndoBlock from UpdateBlock
git-svn-id: trunk@28602 -
This commit is contained in:
parent
d1792391e0
commit
ba8f8d4e90
@ -1592,6 +1592,7 @@ begin
|
||||
if F.CurrentEditor is TCustomSynEdit then
|
||||
with TCustomSynEdit(F.CurrentEditor) do begin
|
||||
BeginUndoBlock;
|
||||
BeginUpdate;
|
||||
LogCaret:=PhysicalToLogicalPos(CaretXY);
|
||||
NewBlockBegin:=LogCaret;
|
||||
CurLine:=Lines[NewBlockBegin.Y - 1];
|
||||
@ -1627,6 +1628,7 @@ begin
|
||||
TCustomSynEdit(F.CurrentEditor).SetFocus;
|
||||
end;
|
||||
end;
|
||||
EndUpdate;
|
||||
EndUndoBlock;
|
||||
end;
|
||||
end;
|
||||
|
@ -597,6 +597,8 @@ type
|
||||
procedure DestroyMarkList;
|
||||
procedure RemoveHandlers(ALines: TSynEditStrings = nil);
|
||||
procedure ExtraLineCharsChanged(Sender: TObject);
|
||||
procedure InternalBeginUndoBlock(aList: TSynEditUndoList = nil); // includes paintlock
|
||||
procedure InternalEndUndoBlock(aList: TSynEditUndoList = nil);
|
||||
protected
|
||||
procedure CreateHandle; override;
|
||||
procedure CreateParams(var Params: TCreateParams); override;
|
||||
@ -738,7 +740,7 @@ type
|
||||
procedure AddKey(Command: TSynEditorCommand; Key1: word; SS1: TShiftState;
|
||||
Key2: word; SS2: TShiftState);
|
||||
procedure AfterLoadFromFile;
|
||||
procedure BeginUndoBlock(aList: TSynEditUndoList = nil);
|
||||
procedure BeginUndoBlock;
|
||||
procedure BeginUpdate;
|
||||
function CaretXPix: Integer;
|
||||
function CaretYPix: Integer;
|
||||
@ -755,7 +757,7 @@ type
|
||||
destructor Destroy; override;
|
||||
procedure DoCopyToClipboard(SText: string; FoldInfo: String = '');
|
||||
procedure DragDrop(Source: TObject; X, Y: Integer); override;
|
||||
procedure EndUndoBlock(aList: TSynEditUndoList = nil);
|
||||
procedure EndUndoBlock;
|
||||
procedure EndUpdate;
|
||||
procedure EnsureCursorPosVisible;
|
||||
{$IFDEF SYN_COMPILER_4_UP}
|
||||
@ -4009,7 +4011,7 @@ var
|
||||
PasteAction: TSynCopyPasteAction;
|
||||
begin
|
||||
Result := False;
|
||||
BeginUndoBlock;
|
||||
InternalBeginUndoBlock;
|
||||
try
|
||||
PTxt := ClipHelper.TextP;
|
||||
PMode := ClipHelper.SelectionMode;
|
||||
@ -4050,7 +4052,7 @@ begin
|
||||
end;
|
||||
end;
|
||||
finally
|
||||
EndUndoBlock;
|
||||
InternalEndUndoBlock;
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -4296,11 +4298,11 @@ end;
|
||||
procedure TCustomSynEdit.SetSelTextExternal(const Value: string);
|
||||
begin
|
||||
// undo entry added
|
||||
BeginUndoBlock;
|
||||
InternalBeginUndoBlock;
|
||||
try
|
||||
FBlockSelection.SelText := Value;
|
||||
finally
|
||||
EndUndoBlock;
|
||||
InternalEndUndoBlock;
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -5016,7 +5018,7 @@ begin
|
||||
FTheLinesView.IsRedoing := True;
|
||||
Item := Group.Pop;
|
||||
if Item <> nil then begin
|
||||
BeginUndoBlock;
|
||||
InternalBeginUndoBlock;
|
||||
fUndoList.CurrentGroup.Reason := Group.Reason;
|
||||
fUndoList.IsInsideRedo := True;
|
||||
try
|
||||
@ -5025,7 +5027,7 @@ begin
|
||||
Item := Group.Pop;
|
||||
until (Item = nil);
|
||||
finally
|
||||
EndUndoBlock;
|
||||
InternalEndUndoBlock;
|
||||
end;
|
||||
end;
|
||||
FTheLinesView.IsRedoing := False;
|
||||
@ -5125,7 +5127,7 @@ begin
|
||||
FTheLinesView.IsUndoing := True;
|
||||
Item := Group.Pop;
|
||||
if Item <> nil then begin
|
||||
BeginUndoBlock(fRedoList);
|
||||
InternalBeginUndoBlock(fRedoList);
|
||||
fRedoList.CurrentGroup.Reason := Group.Reason;
|
||||
fUndoList.Lock;
|
||||
try
|
||||
@ -5137,7 +5139,7 @@ begin
|
||||
// Todo: Decide what do to, If there are any trimable spaces.
|
||||
FTrimmedLinesView.ForceTrim;
|
||||
fUndoList.UnLock;
|
||||
EndUndoBlock(fRedoList);
|
||||
InternalEndUndoBlock(fRedoList);
|
||||
end;
|
||||
end;
|
||||
FTheLinesView.IsUndoing := False;
|
||||
@ -5490,21 +5492,21 @@ end;
|
||||
procedure TCustomSynEdit.SetTextBetweenPoints(aStartPoint, aEndPoint: TPoint;
|
||||
const AValue: String);
|
||||
begin
|
||||
BeginUndoBlock;
|
||||
InternalBeginUndoBlock;
|
||||
try
|
||||
FInternalBlockSelection.SelectionMode := smNormal;
|
||||
FInternalBlockSelection.StartLineBytePos := aStartPoint;
|
||||
FInternalBlockSelection.EndLineBytePos := aEndPoint;
|
||||
FInternalBlockSelection.SelText := AValue;
|
||||
finally
|
||||
EndUndoBlock;
|
||||
InternalEndUndoBlock;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TCustomSynEdit.SetTextBetweenPointsEx(aStartPoint, aEndPoint: TPoint;
|
||||
aCaretMode: TSynCaretAdjustMode; const AValue: String);
|
||||
begin
|
||||
BeginUndoBlock;
|
||||
InternalBeginUndoBlock;
|
||||
try
|
||||
if aCaretMode = scamAdjust then
|
||||
FCaret.IncAutoMoveOnEdit;
|
||||
@ -5519,7 +5521,7 @@ begin
|
||||
finally
|
||||
if aCaretMode = scamAdjust then
|
||||
FCaret.DecAutoMoveOnEdit;
|
||||
EndUndoBlock;
|
||||
InternalEndUndoBlock;
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -5666,7 +5668,7 @@ begin
|
||||
or ((NewCaret.Y = BB.Y) and (NewCaret.X < BB.X));
|
||||
end;
|
||||
if DoDrop then begin
|
||||
BeginUndoBlock; //mh 2000-11-20
|
||||
InternalBeginUndoBlock; //mh 2000-11-20
|
||||
try
|
||||
DragDropText := TCustomSynEdit(Source).SelText;
|
||||
BlockSel := TCustomSynEdit(Source).FBlockSelection;
|
||||
@ -5714,7 +5716,7 @@ begin
|
||||
BlockEnd := {$IFDEF SYN_LAZARUS}PhysicalToLogicalPos(CaretXY)
|
||||
{$ELSE}CaretXY{$ENDIF};
|
||||
finally
|
||||
EndUndoBlock;
|
||||
InternalEndUndoBlock;
|
||||
end;
|
||||
end;
|
||||
finally
|
||||
@ -5996,7 +5998,7 @@ begin
|
||||
DoOnProcessCommand(Command, AChar, Data);
|
||||
if Command <> ecNone then begin
|
||||
try
|
||||
BeginUndoBlock;
|
||||
InternalBeginUndoBlock;
|
||||
FBeautifyStartLineIdx := -1;
|
||||
FBeautifyEndLineIdx := -1;
|
||||
if assigned(FBeautifier) then begin
|
||||
@ -6024,7 +6026,7 @@ begin
|
||||
FBeautifyStartLineIdx+1, FBeautifyEndLineIdx+1);
|
||||
end;
|
||||
finally
|
||||
EndUndoBlock;
|
||||
InternalEndUndoBlock;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
@ -6629,10 +6631,10 @@ end;
|
||||
procedure TCustomSynEdit.ClearAll;
|
||||
begin
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
BeginUndoBlock;
|
||||
InternalBeginUndoBlock;
|
||||
SelectAll;
|
||||
SelText:='';
|
||||
EndUndoBlock;
|
||||
InternalEndUndoBlock;
|
||||
{$ELSE}
|
||||
Lines.Clear;
|
||||
{$ENDIF}
|
||||
@ -6654,8 +6656,7 @@ begin
|
||||
fBlockSelection.ActiveSelectionMode := Value;
|
||||
end;
|
||||
|
||||
{begin} //sbs 2000-11-19
|
||||
procedure TCustomSynEdit.BeginUndoBlock(aList: TSynEditUndoList = nil);
|
||||
procedure TCustomSynEdit.InternalBeginUndoBlock(aList: TSynEditUndoList);
|
||||
begin
|
||||
if aList = nil then aList := fUndoList;
|
||||
aList.OnNeedCaretUndo := {$IFDEF FPC}@{$ENDIF}GetCaretUndo;
|
||||
@ -6663,15 +6664,8 @@ begin
|
||||
IncPaintLock;
|
||||
FFoldedLinesView.Lock;
|
||||
end;
|
||||
{end} //sbs 2000-11-19
|
||||
|
||||
procedure TCustomSynEdit.BeginUpdate;
|
||||
begin
|
||||
IncPaintLock;
|
||||
end;
|
||||
|
||||
{begin} //sbs 2000-11-19
|
||||
procedure TCustomSynEdit.EndUndoBlock(aList: TSynEditUndoList = nil);
|
||||
procedure TCustomSynEdit.InternalEndUndoBlock(aList: TSynEditUndoList);
|
||||
begin
|
||||
if aList = nil then aList := fUndoList;
|
||||
// Write all trimming info to the end of the undo block,
|
||||
@ -6682,7 +6676,28 @@ begin
|
||||
DecPaintLock;
|
||||
aList.EndBlock; // Todo: Doing this after DecPaintLock, can cause duplicate calls to StatusChanged(scModified)
|
||||
end;
|
||||
{end} //sbs 2000-11-19
|
||||
|
||||
procedure TCustomSynEdit.BeginUndoBlock;
|
||||
begin
|
||||
fUndoList.OnNeedCaretUndo := {$IFDEF FPC}@{$ENDIF}GetCaretUndo;
|
||||
fUndoList.BeginBlock;
|
||||
////FFoldedLinesView.Lock;
|
||||
//FTrimmedLinesView.Lock;
|
||||
end;
|
||||
|
||||
procedure TCustomSynEdit.BeginUpdate;
|
||||
begin
|
||||
IncPaintLock;
|
||||
end;
|
||||
|
||||
procedure TCustomSynEdit.EndUndoBlock;
|
||||
begin
|
||||
// Write all trimming info to the end of the undo block,
|
||||
// so it will be undone first, and other UndoItems do see the expected spaces
|
||||
//FTrimmedLinesView.UnLock;
|
||||
////FFoldedLinesView.UnLock;
|
||||
fUndoList.EndBlock;
|
||||
end;
|
||||
|
||||
procedure TCustomSynEdit.EndUpdate;
|
||||
begin
|
||||
@ -7565,7 +7580,7 @@ begin
|
||||
exit;
|
||||
end;
|
||||
|
||||
BeginUndoBlock;
|
||||
InternalBeginUndoBlock;
|
||||
try
|
||||
i := 0;
|
||||
OldCaretX := CaretX;
|
||||
@ -7609,7 +7624,7 @@ begin
|
||||
CaretX := OldCaretX + i;
|
||||
//debugln('TCustomSynEdit.DoTabKey StartOfBlock=',dbgs(StartOfBlock),' fBlockEnd=',dbgs(fBlockEnd),' Spaces="',Spaces,'"');
|
||||
finally
|
||||
EndUndoBlock;
|
||||
InternalEndUndoBlock;
|
||||
end;
|
||||
EnsureCursorPosVisible;
|
||||
end;
|
||||
|
@ -17,7 +17,7 @@ or between two empty lines
|
||||
|
||||
uses
|
||||
Classes, SysUtils, Forms, testregistry, TestBase, LCLProc, LCLType,
|
||||
SynEdit, SynEditKeyCmds;
|
||||
SynEdit, SynEditKeyCmds, SynEditTextTrimmer;
|
||||
|
||||
type
|
||||
|
||||
@ -43,6 +43,7 @@ type
|
||||
procedure TrimUndoRedo;
|
||||
procedure TrimUndoRedoEc;
|
||||
procedure NoTrimUndoRedo;
|
||||
procedure TestInUndoBlock;
|
||||
end;
|
||||
|
||||
implementation
|
||||
@ -63,14 +64,14 @@ begin
|
||||
AssertEquals(FTName+' ('+ASubName+') Caret X', AExpX, SynEdit.CaretX);
|
||||
AssertEquals(FTName+' ('+ASubName+') Caret Y', AExpY, SynEdit.CaretY);
|
||||
end;
|
||||
debugln(['done ',ASubName]);
|
||||
//debugln(['done ',ASubName]);
|
||||
end;
|
||||
|
||||
procedure TTestTrimSpace.test_start(AName, Txt: String);
|
||||
begin
|
||||
FTName := AName;
|
||||
SynEdit.Text := Txt;
|
||||
debugln(['----- START ',AName]);
|
||||
//debugln(['----- START ',AName]);
|
||||
end;
|
||||
|
||||
|
||||
@ -525,6 +526,74 @@ begin
|
||||
|
||||
end;
|
||||
|
||||
procedure TTestTrimSpace.TestInUndoBlock;
|
||||
type TUpdateMode = (umNone, umOuter, umInner);
|
||||
var UpdateMode: TUpdateMode;
|
||||
|
||||
procedure BeginUndoBlock;
|
||||
begin
|
||||
if UpdateMode = umOuter then SynEdit.BeginUpdate;
|
||||
SynEdit.BeginUndoBlock;
|
||||
if UpdateMode = umInner then SynEdit.BeginUpdate;
|
||||
end;
|
||||
|
||||
procedure EndUndoBlock;
|
||||
begin
|
||||
if UpdateMode = umInner then SynEdit.EndUpdate;
|
||||
SynEdit.EndUndoBlock;
|
||||
if UpdateMode = umOuter then SynEdit.EndUpdate;
|
||||
end;
|
||||
|
||||
procedure DoTestInUndoBlock;
|
||||
begin
|
||||
ReCreateEdit;
|
||||
SynEdit.Options := [eoTrimTrailingSpaces, eoAutoIndent, eoScrollPastEol]; // eoGroupUndo
|
||||
SynEdit.TrimSpaceType := settLeaveLine;
|
||||
SetLines(['abc d', 'mno', 'xyz', '']);
|
||||
SetCaret(1,1);
|
||||
// need to add space later, so it is regocnized as trailing
|
||||
|
||||
BeginUndoBlock;
|
||||
SynEdit.TextBetweenPointsEx[point(5,1), point(6,1), scamEnd] := ''; // delete d
|
||||
SynEdit.TextBetweenPointsEx[point(4,2), point(4,2), scamEnd] := ' '; // add space
|
||||
EndUndoBlock;
|
||||
TestIsFullText ('modified after block', ['abc', 'mno ', 'xyz', '']);
|
||||
TestIsCaret('modified after block', 5,2);
|
||||
|
||||
SynEdit.Undo;
|
||||
TestIsFullText ('Undone', ['abc d', 'mno', 'xyz', '']);
|
||||
TestIsCaret('UnDone', 1,1);
|
||||
|
||||
SynEdit.Redo;
|
||||
TestIsFullText ('Redone', ['abc', 'mno ', 'xyz', '']);
|
||||
TestIsCaret('Redone', 5,2);
|
||||
|
||||
SynEdit.Undo;
|
||||
TestIsFullText ('Undone 2', ['abc d', 'mno', 'xyz', '']);
|
||||
TestIsCaret('UnDone 2', 1,1);
|
||||
|
||||
SynEdit.Redo;
|
||||
TestIsFullText ('Redone 2', ['abc', 'mno ', 'xyz', '']);
|
||||
TestIsCaret('Redone 2', 5,2);
|
||||
|
||||
end;
|
||||
|
||||
begin
|
||||
UpdateMode := umNone;
|
||||
PushBaseName('Without BeginUpdate');
|
||||
DoTestInUndoBlock;
|
||||
|
||||
UpdateMode := umInner;
|
||||
PushBaseName('With BeginUpdate inside');
|
||||
DoTestInUndoBlock;
|
||||
|
||||
UpdateMode := umOuter;
|
||||
PushBaseName('With BeginUpdate outside');
|
||||
DoTestInUndoBlock;
|
||||
|
||||
PopBaseName;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
initialization
|
||||
|
@ -2170,6 +2170,7 @@ begin
|
||||
CodeToolsInSync:=not NeedsUpdateCodeBuffer;
|
||||
if SrcLogEntry<>nil then begin
|
||||
SynEditor.BeginUndoBlock;
|
||||
SynEditor.BeginUpdate;
|
||||
SynEditor.TemplateEdit.IncExternalEditLock;
|
||||
SynEditor.SyncroEdit.IncExternalEditLock;
|
||||
try
|
||||
@ -2202,6 +2203,7 @@ begin
|
||||
finally
|
||||
SynEditor.SyncroEdit.DecExternalEditLock;
|
||||
SynEditor.TemplateEdit.DecExternalEditLock;
|
||||
SynEditor.EndUpdate;
|
||||
SynEditor.EndUndoBlock;
|
||||
end;
|
||||
end else begin
|
||||
@ -3384,7 +3386,6 @@ var
|
||||
P: TPoint;
|
||||
begin
|
||||
if ReadOnly then exit;
|
||||
FEditor.BeginUpdate;
|
||||
FEditor.BeginUndoBlock;
|
||||
if not EditorComponent.SelAvail then begin
|
||||
P.Y := FEditor.CaretY;
|
||||
@ -3398,9 +3399,9 @@ begin
|
||||
i:=EditorOpts.HighlighterList.FindByHighlighter(FEditor.Highlighter);
|
||||
if i>=0 then
|
||||
IsPascal := EditorOpts.HighlighterList[i].DefaultCommentType <> comtCPP;
|
||||
// will show modal dialog - must not be in Editor.BeginUpdate block, or painting will not work
|
||||
FEditor.SelText:=AddConditional(EditorComponent.SelText,IsPascal);
|
||||
FEditor.EndUndoBlock;
|
||||
FEditor.EndUpdate;
|
||||
end;
|
||||
|
||||
procedure TSourceEditor.SortSelection;
|
||||
@ -3884,9 +3885,11 @@ begin
|
||||
// user typed 'begin'
|
||||
if not LazarusIDE.SaveSourceEditorChangesToCodeCache(self) then exit;
|
||||
FEditor.BeginUndoBlock;
|
||||
FEditor.BeginUpdate;
|
||||
try
|
||||
if not CodeToolBoss.CompleteBlock(CodeBuffer,p.X,p.Y,true) then exit;
|
||||
finally
|
||||
FEditor.EndUpdate;
|
||||
FEditor.EndUndoBlock;
|
||||
end;
|
||||
end;
|
||||
@ -3901,6 +3904,7 @@ begin
|
||||
if not LazarusIDE.SaveSourceEditorChangesToCodeCache(self) then exit;
|
||||
XY:=FEditor.LogicalCaretXY;
|
||||
FEditor.BeginUndoBlock;
|
||||
FEditor.BeginUpdate;
|
||||
try
|
||||
if not CodeToolBoss.CompleteBlock(CodeBuffer,XY.X,XY.Y,false,
|
||||
NewCode,NewX,NewY,NewTopLine) then exit;
|
||||
@ -3913,6 +3917,7 @@ begin
|
||||
FEditor.LogicalCaretXY:=XY;
|
||||
end;
|
||||
finally
|
||||
FEditor.EndUpdate;
|
||||
FEditor.EndUndoBlock;
|
||||
end;
|
||||
end;
|
||||
|
Loading…
Reference in New Issue
Block a user