mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-09 01:48:03 +02:00
SynEdit: Improved Syncro-Edit (see note on issue #14813)
git-svn-id: trunk@25247 -
This commit is contained in:
parent
2fb19534f3
commit
9b27609bab
@ -385,7 +385,6 @@ type
|
||||
|
||||
FPaintLock: Integer;
|
||||
FPaintLockOwnerCnt: Integer;
|
||||
FStoredCaredAutoAdjust: Boolean;
|
||||
fReadOnly: Boolean;
|
||||
fRightEdge: Integer;
|
||||
fRightEdgeColor: TColor;
|
||||
@ -607,10 +606,10 @@ type
|
||||
function GetCaretObj: TSynEditCaret; override;
|
||||
procedure IncPaintLock;
|
||||
procedure DecPaintLock;
|
||||
procedure DoIncPaintLock;
|
||||
procedure DoDecPaintLock;
|
||||
procedure DoIncForeignPaintLock;
|
||||
procedure DoDecForeignPaintLock;
|
||||
procedure DoIncPaintLock(Sender: TObject);
|
||||
procedure DoDecPaintLock(Sender: TObject);
|
||||
procedure DoIncForeignPaintLock(Sender: TObject);
|
||||
procedure DoDecForeignPaintLock(Sender: TObject);
|
||||
procedure DestroyWnd; override;
|
||||
procedure DragOver(Source: TObject; X, Y: Integer;
|
||||
State: TDragState; var Accept: Boolean); override;
|
||||
@ -1559,6 +1558,10 @@ begin
|
||||
AddNotifyHandler(senrCleared, {$IFDEF FPC}@{$ENDIF}ListCleared);
|
||||
AddNotifyHandler(senrUndoRedoAdded, {$IFDEF FPC}@{$ENDIF}Self.UndoRedoAdded);
|
||||
AddNotifyHandler(senrModifiedChanged, {$IFDEF FPC}@{$ENDIF}ModifiedChanged);
|
||||
AddNotifyHandler(senrIncPaintLock, {$IFDEF FPC}@{$ENDIF}DoIncPaintLock);
|
||||
AddNotifyHandler(senrDecPaintLock, {$IFDEF FPC}@{$ENDIF}DoDecPaintLock);
|
||||
AddNotifyHandler(senrIncOwnedPaintLock, {$IFDEF FPC}@{$ENDIF}DoIncForeignPaintLock);
|
||||
AddNotifyHandler(senrDecOwnedPaintLock, {$IFDEF FPC}@{$ENDIF}DoDecForeignPaintLock);
|
||||
end;
|
||||
|
||||
FUndoList := TSynEditStringList(fLines).UndoList;
|
||||
@ -1729,49 +1732,46 @@ begin
|
||||
end;
|
||||
|
||||
procedure TCustomSynEdit.IncPaintLock;
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
if (PaintLockOwner = nil) then begin
|
||||
PaintLockOwner := Self;
|
||||
for i := 0 to TSynEditStringList(FLines).AttachedSynEditCount - 1 do
|
||||
if TSynEditStringList(FLines).AttachedSynEdits[i] <> Self then
|
||||
TCustomSynEdit(TSynEditStringList(FLines).AttachedSynEdits[i]).DoIncForeignPaintLock;
|
||||
FLines.SendNotification(senrIncOwnedPaintLock, Self); // DoIncForeignPaintLock
|
||||
end;
|
||||
inc(FPaintLockOwnerCnt);
|
||||
for i := 0 to TSynEditStringList(FLines).AttachedSynEditCount - 1 do
|
||||
TCustomSynEdit(TSynEditStringList(FLines).AttachedSynEdits[i]).DoIncPaintLock;
|
||||
if FPaintLockOwnerCnt = 1 then begin
|
||||
FLines.SendNotification(senrIncPaintLock, Self); // DoIncPaintLock
|
||||
FLines.SendNotification(senrAfterIncPaintLock, Self);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TCustomSynEdit.DecPaintLock;
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
for i := 0 to TSynEditStringList(FLines).AttachedSynEditCount - 1 do
|
||||
TCustomSynEdit(TSynEditStringList(FLines).AttachedSynEdits[i]).DoDecPaintLock;
|
||||
if FPaintLockOwnerCnt = 1 then begin
|
||||
FLines.SendNotification(senrBeforeDecPaintLock, Self);
|
||||
FLines.SendNotification(senrDecPaintLock, Self); // DoDecPaintLock
|
||||
end;
|
||||
dec(FPaintLockOwnerCnt);
|
||||
if (PaintLockOwner = Self) and (FPaintLockOwnerCnt = 0) then begin
|
||||
for i := 0 to TSynEditStringList(FLines).AttachedSynEditCount - 1 do
|
||||
if TSynEditStringList(FLines).AttachedSynEdits[i] <> Self then
|
||||
TCustomSynEdit(TSynEditStringList(FLines).AttachedSynEdits[i]).DoDecForeignPaintLock;
|
||||
FLines.SendNotification(senrDecOwnedPaintLock, Self); // DoDecForeignPaintLock
|
||||
PaintLockOwner := nil;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TCustomSynEdit.DoIncForeignPaintLock;
|
||||
procedure TCustomSynEdit.DoIncForeignPaintLock(Sender: TObject);
|
||||
begin
|
||||
FStoredCaredAutoAdjust := FCaret.AutoMoveOnEdit;
|
||||
FCaret.AutoMoveOnEdit := True;
|
||||
if Sender = Self then exit;
|
||||
FCaret.IncAutoMoveOnEdit;
|
||||
FBlockSelection.IncPersistentLock;
|
||||
end;
|
||||
|
||||
procedure TCustomSynEdit.DoDecForeignPaintLock;
|
||||
procedure TCustomSynEdit.DoDecForeignPaintLock(Sender: TObject);
|
||||
begin
|
||||
if Sender = Self then exit;
|
||||
FBlockSelection.DecPersistentLock;
|
||||
FCaret.AutoMoveOnEdit := FStoredCaredAutoAdjust;
|
||||
FCaret.DecAutoMoveOnEdit;
|
||||
end;
|
||||
|
||||
procedure TCustomSynEdit.DoIncPaintLock;
|
||||
procedure TCustomSynEdit.DoIncPaintLock(Sender: TObject);
|
||||
begin
|
||||
if FPaintLock = 0 then begin
|
||||
FOldTopLine := FTopLine;
|
||||
@ -1783,7 +1783,7 @@ begin
|
||||
FCaret.Lock;
|
||||
end;
|
||||
|
||||
procedure TCustomSynEdit.DoDecPaintLock;
|
||||
procedure TCustomSynEdit.DoDecPaintLock(Sender: TObject);
|
||||
begin
|
||||
if (FPaintLock=1) and HandleAllocated then begin
|
||||
ScanRanges;
|
||||
@ -2737,7 +2737,7 @@ begin
|
||||
// changes to line / column in one go
|
||||
if sfIsDragging in fStateFlags then
|
||||
FBlockSelection.IncPersistentLock;
|
||||
DoIncPaintLock; // No editing is taking place
|
||||
DoIncPaintLock(Self); // No editing is taking place
|
||||
try
|
||||
GetCursorPos(CurMousePos);
|
||||
CurMousePos:=ScreenToClient(CurMousePos);
|
||||
@ -2792,7 +2792,7 @@ begin
|
||||
SetBlockEnd(PhysicalToLogicalPos(CaretXY));
|
||||
end;
|
||||
finally
|
||||
DoDecPaintLock;
|
||||
DoDecPaintLock(Self);
|
||||
if sfIsDragging in fStateFlags then
|
||||
FBlockSelection.DecPersistentLock;
|
||||
end;
|
||||
@ -3876,7 +3876,7 @@ procedure TCustomSynEdit.SelectAll;
|
||||
var
|
||||
LastPt: TPoint;
|
||||
begin
|
||||
DoIncPaintLock; // No editing is taking place
|
||||
DoIncPaintLock(Self); // No editing is taking place
|
||||
LastPt := Point(1, FTheLinesView.Count);
|
||||
if LastPt.y > 0 then
|
||||
Inc(LastPt.x, Length(FTheLinesView[LastPt.y - 1]))
|
||||
@ -3884,7 +3884,7 @@ begin
|
||||
LastPt.y := 1;
|
||||
SetCaretAndSelection(LogicalToPhysicalPos(LastPt), Point(1, 1), LastPt);
|
||||
FBlockSelection.ActiveSelectionMode := smNormal;
|
||||
DoDecPaintLock;
|
||||
DoDecPaintLock(Self);
|
||||
end;
|
||||
|
||||
procedure TCustomSynEdit.SetHighlightSearch(const ASearch : String; AOptions : TSynSearchOptions);
|
||||
@ -4726,13 +4726,13 @@ begin
|
||||
if Value.X < 0 then
|
||||
exit;
|
||||
|
||||
DoIncPaintLock; // No editing is taking place
|
||||
DoIncPaintLock(Self); // No editing is taking place
|
||||
FBlockSelection.StartLineBytePos := Value;
|
||||
Value.X := WordBreaker.NextWordEnd(TempString, Value.X);
|
||||
FBlockSelection.EndLineBytePos := Value;
|
||||
FBlockSelection.ActiveSelectionMode := smNormal;
|
||||
FCaret.LineBytePos := Value;
|
||||
DoDecPaintLock;
|
||||
DoDecPaintLock(Self);
|
||||
end;
|
||||
|
||||
procedure TCustomSynEdit.SetLineBlock(Value: TPoint; WithLeadSpaces: Boolean = True);
|
||||
@ -4740,7 +4740,7 @@ var
|
||||
ALine: string;
|
||||
x, x2: Integer;
|
||||
begin
|
||||
DoIncPaintLock; // No editing is taking place
|
||||
DoIncPaintLock(Self); // No editing is taking place
|
||||
FBlockSelection.StartLineBytePos := Point(1,MinMax(Value.y, 1, FTheLinesView.Count));
|
||||
FBlockSelection.EndLineBytePos := Point(1,MinMax(Value.y+1, 1, FTheLinesView.Count));
|
||||
if (FBlockSelection.StartLinePos >= 1)
|
||||
@ -4760,7 +4760,7 @@ begin
|
||||
FBlockSelection.ActiveSelectionMode := smNormal;
|
||||
CaretXY := FTheLinesView.LogicalToPhysicalPos(FBlockSelection.EndLineBytePos);
|
||||
//DebugLn(' FFF2 ',Value.X,',',Value.Y,' BlockBegin=',BlockBegin.X,',',BlockBegin.Y,' BlockEnd=',BlockEnd.X,',',BlockEnd.Y);
|
||||
DoDecPaintLock;
|
||||
DoDecPaintLock(Self);
|
||||
end;
|
||||
|
||||
procedure TCustomSynEdit.SetParagraphBlock(Value: TPoint);
|
||||
@ -4768,7 +4768,7 @@ var
|
||||
ParagraphStartLine, ParagraphEndLine, ParagraphEndX: integer;
|
||||
|
||||
begin
|
||||
DoIncPaintLock; // No editing is taking place
|
||||
DoIncPaintLock(Self); // No editing is taking place
|
||||
ParagraphStartLine := MinMax(Value.y, 1, FTheLinesView.Count);
|
||||
ParagraphEndLine := MinMax(Value.y+1, 1, FTheLinesView.Count);
|
||||
ParagraphEndX := 1;
|
||||
@ -4789,7 +4789,7 @@ begin
|
||||
FBlockSelection.ActiveSelectionMode := smNormal;
|
||||
CaretXY := FBlockSelection.EndLineBytePos;
|
||||
//DebugLn(' FFF3 ',Value.X,',',Value.Y,' BlockBegin=',BlockBegin.X,',',BlockBegin.Y,' BlockEnd=',BlockEnd.X,',',BlockEnd.Y);
|
||||
DoDecPaintLock;
|
||||
DoDecPaintLock(Self);
|
||||
end;
|
||||
|
||||
function TCustomSynEdit.GetCanUndo: Boolean;
|
||||
@ -5152,7 +5152,7 @@ begin
|
||||
BeginUndoBlock;
|
||||
try
|
||||
if aCaretMode = scamAdjust then
|
||||
FCaret.AutoMoveOnEdit := True;
|
||||
FCaret.IncAutoMoveOnEdit;
|
||||
FInternalBlockSelection.SelectionMode := smNormal;
|
||||
FInternalBlockSelection.StartLineBytePos := aStartPoint;
|
||||
FInternalBlockSelection.EndLineBytePos := aEndPoint;
|
||||
@ -5163,7 +5163,7 @@ begin
|
||||
FCaret.LineBytePos := FInternalBlockSelection.StartLineBytePos;
|
||||
finally
|
||||
if aCaretMode = scamAdjust then
|
||||
FCaret.AutoMoveOnEdit := False;
|
||||
FCaret.DecAutoMoveOnEdit;
|
||||
EndUndoBlock;
|
||||
end;
|
||||
end;
|
||||
@ -5200,11 +5200,11 @@ begin
|
||||
then begin
|
||||
NewCaret:=Point(fBookMarks[BookMark].Column, fBookMarks[BookMark].Line);
|
||||
LogCaret:=PhysicalToLogicalPos(NewCaret);
|
||||
DoIncPaintLock; // No editing is taking place
|
||||
DoIncPaintLock(Self); // No editing is taking place
|
||||
FCaret.LineCharPos := NewCaret;
|
||||
SetBlockEnd(LogCaret);
|
||||
SetBlockBegin(LogCaret);
|
||||
DoDecPaintLock;
|
||||
DoDecPaintLock(Self);
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -5606,7 +5606,7 @@ begin
|
||||
exit;
|
||||
end;
|
||||
exclude(fStateFlags, sfEnsureCursorPos);
|
||||
DoIncPaintLock; // No editing is taking place
|
||||
DoIncPaintLock(Self); // No editing is taking place
|
||||
try
|
||||
// Make sure X is visible
|
||||
//DebugLn('[TCustomSynEdit.EnsureCursorPosVisible] A CaretX=',CaretX,' LeftChar=',LeftChar,' CharsInWindow=',CharsInWindow,' ClientWidth=',ClientWidth);
|
||||
@ -5651,7 +5651,7 @@ begin
|
||||
else
|
||||
TopLine := TopLine; //mh 2000-10-19
|
||||
finally
|
||||
DoDecPaintLock;
|
||||
DoDecPaintLock(Self);
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -7167,7 +7167,7 @@ begin
|
||||
NewCaret.Y := FFoldedLinesView.TextPosAddLines(NewCaret.Y, +1);
|
||||
end;
|
||||
end;
|
||||
DoIncPaintLock; // No editing is taking place
|
||||
DoIncPaintLock(Self); // No editing is taking place
|
||||
FCaret.IncForcePastEOL;
|
||||
if DX > 0 then
|
||||
FCaret.IncForceAdjustToNextChar;
|
||||
@ -7175,7 +7175,7 @@ begin
|
||||
FCaret.DecForcePastEOL;
|
||||
if DX > 0 then
|
||||
FCaret.DecForceAdjustToNextChar;
|
||||
DoDecPaintLock;
|
||||
DoDecPaintLock(Self);
|
||||
end;
|
||||
|
||||
procedure TCustomSynEdit.MoveCaretVert(DY: integer);
|
||||
@ -7187,9 +7187,9 @@ begin
|
||||
OldCaret:=CaretXY;
|
||||
NewCaret:=OldCaret;
|
||||
NewCaret.Y:=FFoldedLinesView.TextPosAddLines(NewCaret.Y, DY);
|
||||
DoIncPaintLock; // No editing is taking place
|
||||
DoIncPaintLock(Self); // No editing is taking place
|
||||
FCaret.LinePos := NewCaret.Y;
|
||||
DoDecPaintLock;
|
||||
DoDecPaintLock(Self);
|
||||
end;
|
||||
|
||||
procedure TCustomSynEdit.SetCaretAndSelection(const ptCaret, ptBefore,
|
||||
@ -7197,14 +7197,14 @@ procedure TCustomSynEdit.SetCaretAndSelection(const ptCaret, ptBefore,
|
||||
// caret is physical (screen)
|
||||
// Before, After is logical (byte)
|
||||
begin
|
||||
DoIncPaintLock; // No editing is taking place
|
||||
DoIncPaintLock(Self); // No editing is taking place
|
||||
CaretXY := ptCaret;
|
||||
SetBlockBegin(ptBefore);
|
||||
SetBlockEnd(ptAfter);
|
||||
if Mode <> smCurrent then
|
||||
FBlockSelection.ActiveSelectionMode := Mode;
|
||||
AquirePrimarySelection;
|
||||
DoDecPaintLock;
|
||||
DoDecPaintLock(Self);
|
||||
end;
|
||||
|
||||
procedure TCustomSynEdit.RecalcCharExtent;
|
||||
|
@ -167,7 +167,7 @@ type
|
||||
TSynEditCaret = class(TSynEditPointBase)
|
||||
private
|
||||
FAllowPastEOL: Boolean;
|
||||
FAutoMoveOnEdit: Boolean;
|
||||
FAutoMoveOnEdit: Integer;
|
||||
FForcePastEOL: Integer;
|
||||
FForceAdjustToNextChar: Integer;
|
||||
FKeepCaretX: Boolean;
|
||||
@ -215,6 +215,8 @@ type
|
||||
procedure DecForcePastEOL;
|
||||
procedure IncForceAdjustToNextChar;
|
||||
procedure DecForceAdjustToNextChar;
|
||||
procedure IncAutoMoveOnEdit;
|
||||
procedure DecAutoMoveOnEdit;
|
||||
procedure ChangeOnTouch;
|
||||
function IsAtLineChar(aPoint: TPoint): Boolean;
|
||||
function IsAtLineByte(aPoint: TPoint): Boolean;
|
||||
@ -239,7 +241,6 @@ type
|
||||
property AllowPastEOL: Boolean read FAllowPastEOL write SetAllowPastEOL;
|
||||
property KeepCaretX: Boolean read FKeepCaretX write SetKeepCaretX;
|
||||
property MaxLeftChar: PInteger write FMaxLeftChar;
|
||||
property AutoMoveOnEdit: Boolean read FAutoMoveOnEdit write FAutoMoveOnEdit;
|
||||
end;
|
||||
|
||||
implementation
|
||||
@ -315,6 +316,7 @@ begin
|
||||
fCharPos:= 1;
|
||||
FAllowPastEOL := True;
|
||||
FForcePastEOL := 0;
|
||||
FAutoMoveOnEdit := 0;
|
||||
if FLines <> nil then
|
||||
FLines.AddEditHandler(@DoLinesEdited);
|
||||
end;
|
||||
@ -360,6 +362,16 @@ begin
|
||||
Dec(FForceAdjustToNextChar);
|
||||
end;
|
||||
|
||||
procedure TSynEditCaret.IncAutoMoveOnEdit;
|
||||
begin
|
||||
inc(FAutoMoveOnEdit);
|
||||
end;
|
||||
|
||||
procedure TSynEditCaret.DecAutoMoveOnEdit;
|
||||
begin
|
||||
dec(FAutoMoveOnEdit);
|
||||
end;
|
||||
|
||||
procedure TSynEditCaret.ChangeOnTouch;
|
||||
begin
|
||||
FChangeOnTouch := True;
|
||||
@ -619,7 +631,7 @@ procedure TSynEditCaret.DoLinesEdited(Sender: TSynEditStrings; aLinePos, aBytePo
|
||||
end;
|
||||
|
||||
begin
|
||||
if FAutoMoveOnEdit then begin
|
||||
if FAutoMoveOnEdit > 0 then begin
|
||||
IncForcePastEOL;
|
||||
LineBytePos := AdjustPoint(LineBytePos);
|
||||
DecForcePastEOL;
|
||||
|
@ -47,7 +47,14 @@ type
|
||||
senrBeginUpdate, senrEndUpdate,
|
||||
senrCleared,
|
||||
senrUndoRedoAdded,
|
||||
senrModifiedChanged // The modified flag was changed
|
||||
senrModifiedChanged, // The modified flag was changed
|
||||
// Paintlocks are managed by SynEdit, but need distribution to shared edits
|
||||
senrIncOwnedPaintLock, // Inform other SynEdits (ForeignPaintLock)
|
||||
senrDecOwnedPaintLock,
|
||||
senrIncPaintLock, // Actual PaintLock
|
||||
senrDecPaintLock,
|
||||
senrAfterIncPaintLock, // For plugins, etc...
|
||||
senrBeforeDecPaintLock
|
||||
);
|
||||
|
||||
TPhysicalCharWidths = Array of Shortint;
|
||||
@ -148,10 +155,6 @@ type
|
||||
function GetIsUndoing: Boolean; virtual; abstract;
|
||||
procedure SetIsRedoing(const AValue: Boolean); virtual; abstract;
|
||||
function GetIsRedoing: Boolean; virtual; abstract;
|
||||
procedure SendNotification(AReason: TSynEditNotifyReason;
|
||||
ASender: TSynEditStrings; aIndex, aCount: Integer;
|
||||
aBytePos: Integer = -1; aLen: Integer = 0;
|
||||
aTxt: String = ''); virtual; abstract;
|
||||
procedure IgnoreSendNotification(AReason: TSynEditNotifyReason;
|
||||
ReEnable: Boolean); virtual; abstract;
|
||||
public
|
||||
@ -181,6 +184,12 @@ type
|
||||
procedure AddEditHandler(AHandler: TStringListLineEditEvent);
|
||||
procedure RemoveEditHandler(AHandler: TStringListLineEditEvent);
|
||||
procedure SendHighlightChanged(aIndex, aCount: Integer); override;
|
||||
procedure SendNotification(AReason: TSynEditNotifyReason;
|
||||
ASender: TSynEditStrings; aIndex, aCount: Integer;
|
||||
aBytePos: Integer = -1; aLen: Integer = 0;
|
||||
aTxt: String = ''); virtual; abstract;
|
||||
procedure SendNotification(AReason: TSynEditNotifyReason;
|
||||
ASender: TObject); virtual; abstract;
|
||||
public
|
||||
function GetPhysicalCharWidths(Index: Integer): TPhysicalCharWidths;
|
||||
function GetPhysicalCharWidths(const Line: String; Index: Integer): TPhysicalCharWidths; virtual; abstract;
|
||||
@ -230,10 +239,6 @@ type
|
||||
function GetExpandedString(Index: integer): string; override;
|
||||
function GetLengthOfLongestLine: integer; override;
|
||||
|
||||
procedure SendNotification(AReason: TSynEditNotifyReason;
|
||||
ASender: TSynEditStrings; aIndex, aCount: Integer;
|
||||
aBytePos: Integer = -1; aLen: Integer = 0;
|
||||
aTxt: String = ''); override;
|
||||
procedure IgnoreSendNotification(AReason: TSynEditNotifyReason;
|
||||
IncIgnore: Boolean); override;
|
||||
function GetUndoList: TSynEditUndoList; override;
|
||||
@ -273,6 +278,12 @@ type
|
||||
AHandler: TMethod); override;
|
||||
procedure RemoveGenericHandler(AReason: TSynEditNotifyReason;
|
||||
AHandler: TMethod); override;
|
||||
procedure SendNotification(AReason: TSynEditNotifyReason;
|
||||
ASender: TSynEditStrings; aIndex, aCount: Integer;
|
||||
aBytePos: Integer = -1; aLen: Integer = 0;
|
||||
aTxt: String = ''); override;
|
||||
procedure SendNotification(AReason: TSynEditNotifyReason;
|
||||
ASender: TObject); override;
|
||||
|
||||
function GetPhysicalCharWidths(const Line: String; Index: Integer): TPhysicalCharWidths; override;
|
||||
property NextLines: TSynEditStrings read fSynStrings write fSynStrings;
|
||||
@ -810,6 +821,12 @@ begin
|
||||
fSynStrings.SendNotification(AReason, ASender, aIndex, aCount, aBytePos, aLen, aTxt);
|
||||
end;
|
||||
|
||||
procedure TSynEditStringsLinked.SendNotification(AReason: TSynEditNotifyReason;
|
||||
ASender: TObject);
|
||||
begin
|
||||
fSynStrings.SendNotification(AReason, ASender);
|
||||
end;
|
||||
|
||||
procedure TSynEditStringsLinked.IgnoreSendNotification(AReason: TSynEditNotifyReason;
|
||||
IncIgnore: Boolean);
|
||||
begin
|
||||
@ -1215,6 +1232,7 @@ end;
|
||||
|
||||
function TSynEditStorageMem.GetItemPointer(Index: Integer): Pointer;
|
||||
begin
|
||||
//if (Index >= FCount) or (FCount > FCapacity) then raise Exception.Create('Bad Index');
|
||||
Result := Pointer(FMem + Index * ItemSize);
|
||||
end;
|
||||
|
||||
|
@ -157,9 +157,6 @@ type
|
||||
procedure SetIsRedoing(const AValue: Boolean); override;
|
||||
function GetIsRedoing: Boolean; override;
|
||||
procedure UndoRedoAdded(Sender: TObject);
|
||||
procedure SendNotification(AReason: TSynEditNotifyReason;
|
||||
ASender: TSynEditStrings; aIndex, aCount: Integer;
|
||||
aBytePos: Integer = -1; aLen: Integer = 0; aTxt: String = ''); override;
|
||||
procedure IgnoreSendNotification(AReason: TSynEditNotifyReason;
|
||||
IncIgnore: Boolean); override;
|
||||
|
||||
@ -199,6 +196,11 @@ type
|
||||
AHandler: TMethod); override;
|
||||
procedure RemoveGenericHandler(AReason: TSynEditNotifyReason;
|
||||
AHandler: TMethod); override;
|
||||
procedure SendNotification(AReason: TSynEditNotifyReason;
|
||||
ASender: TSynEditStrings; aIndex, aCount: Integer;
|
||||
aBytePos: Integer = -1; aLen: Integer = 0; aTxt: String = ''); override;
|
||||
procedure SendNotification(AReason: TSynEditNotifyReason;
|
||||
ASender: TObject); override;
|
||||
function GetPhysicalCharWidths(const Line: String; Index: Integer): TPhysicalCharWidths; override;
|
||||
// For Textbuffersharing
|
||||
procedure AttachSynEdit(AEdit: TSynEditBase);
|
||||
@ -422,15 +424,15 @@ begin
|
||||
FIsRedoing := False;
|
||||
FModified := False;
|
||||
|
||||
FNotifyLists[senrLineCount] := TLineRangeNotificationList.Create;
|
||||
FNotifyLists[senrLineChange] := TLineRangeNotificationList.Create;
|
||||
FNotifyLists[senrHighlightChanged] := TLineRangeNotificationList.Create;
|
||||
FNotifyLists[senrEditAction] := TLineEditNotificationList.Create;
|
||||
FNotifyLists[senrBeginUpdate] := TSynMethodList.Create;
|
||||
FNotifyLists[senrEndUpdate] := TSynMethodList.Create;
|
||||
FNotifyLists[senrCleared] := TSynMethodList.Create;
|
||||
FNotifyLists[senrUndoRedoAdded] := TSynMethodList.Create;
|
||||
FNotifyLists[senrModifiedChanged] := TSynMethodList.Create;
|
||||
for r := low(TSynEditNotifyReason) to high(TSynEditNotifyReason)
|
||||
do case r of
|
||||
senrLineCount, senrLineChange, senrHighlightChanged:
|
||||
FNotifyLists[r] := TLineRangeNotificationList.Create;
|
||||
senrEditAction:
|
||||
FNotifyLists[r] := TLineEditNotificationList.Create;
|
||||
else
|
||||
FNotifyLists[r] := TSynMethodList.Create;
|
||||
end;
|
||||
|
||||
for r := low(TSynEditNotifyReason) to high(TSynEditNotifyReason) do
|
||||
FIgnoreSendNotification[r] := 0;
|
||||
@ -1082,11 +1084,19 @@ begin
|
||||
.CallRangeNotifyEvents(ASender, aIndex, aCount);
|
||||
senrEditAction:
|
||||
// aindex is mis-named (linepos) for edit action
|
||||
TLineEditNotificationList(FNotifyLists[senrEditAction])
|
||||
TLineEditNotificationList(FNotifyLists[AReason])
|
||||
.CallRangeNotifyEvents(ASender, aIndex, aBytePos, aLen, aCount, aTxt);
|
||||
else
|
||||
raise Exception.Create('Invalid');
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TSynEditStringList.SendNotification(AReason: TSynEditNotifyReason;
|
||||
ASender: TObject);
|
||||
begin
|
||||
FNotifyLists[AReason].CallNotifyEvents(ASender);
|
||||
end;
|
||||
|
||||
procedure TSynEditStringList.IgnoreSendNotification(AReason: TSynEditNotifyReason;
|
||||
IncIgnore: Boolean);
|
||||
begin
|
||||
|
@ -215,7 +215,7 @@ type
|
||||
procedure DoSelectionChanged(Sender: TObject);
|
||||
procedure DoScanSelection(Data: PtrInt);
|
||||
procedure DoOnDeactivate; override;
|
||||
procedure DoBeforeEdit(aX, aY: Integer; aUndoRedo: Boolean); override;
|
||||
procedure DoBeforeEdit(aX, aY, aCount, aLineBrkCnt: Integer; aUndoRedo: Boolean); override;
|
||||
|
||||
function MaybeHandleMouseAction(var AnInfo: TSynEditMouseActionInfo;
|
||||
HandleActionProc: TSynEditMouseActionHandler): Boolean;
|
||||
@ -1212,7 +1212,7 @@ begin
|
||||
inherited DoOnDeactivate;
|
||||
end;
|
||||
|
||||
procedure TSynPluginSyncroEdit.DoBeforeEdit(aX, aY: Integer; aUndoRedo: Boolean);
|
||||
procedure TSynPluginSyncroEdit.DoBeforeEdit(aX, aY, aCount, aLineBrkCnt: Integer; aUndoRedo: Boolean);
|
||||
begin
|
||||
if (FMode = spseSelecting) then begin
|
||||
FWordIndex.Clear;
|
||||
@ -1220,7 +1220,7 @@ begin
|
||||
FMode := spseInvalid;
|
||||
end
|
||||
else
|
||||
inherited DoBeforeEdit(aX, aY, aUndoRedo);
|
||||
inherited DoBeforeEdit(aX, aY, aCount, aLineBrkCnt, aUndoRedo);
|
||||
end;
|
||||
|
||||
function TSynPluginSyncroEdit.MaybeHandleMouseAction(var AnInfo: TSynEditMouseActionInfo;
|
||||
|
@ -26,9 +26,9 @@ unit SynPluginSyncronizedEditBase;
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, math, Graphics,
|
||||
Classes, SysUtils, math, Graphics, LCLProc,
|
||||
SynEditMiscClasses, SynEdit, SynEditMarkup, SynEditMiscProcs, SynEditTextBase,
|
||||
SynEditTextTrimmer;
|
||||
SynEditTextTrimmer, SynEditKeyCmds;
|
||||
|
||||
type
|
||||
|
||||
@ -134,6 +134,30 @@ type
|
||||
property CellGroupForArea: Integer read FCellIdForArea write FCellIdForArea;
|
||||
end;
|
||||
|
||||
{ TSynPluginSyncronizedEditChangeAction }
|
||||
|
||||
TSynPluginSyncronizedEditChangeAction = record
|
||||
CellIndex: Integer;
|
||||
cLinePos, cBytePos, Count, LineBrkCount: Integer;
|
||||
Text: String;
|
||||
end;
|
||||
|
||||
{ TSynPluginSyncronizedEditChangeList }
|
||||
|
||||
TSynPluginSyncronizedEditChangeList = class
|
||||
private
|
||||
FList: array of TSynPluginSyncronizedEditChangeAction;
|
||||
FCount: Integer;
|
||||
function GetItems(Index: Integer): TSynPluginSyncronizedEditChangeAction;
|
||||
public
|
||||
procedure Clear;
|
||||
procedure Add(aCellIndex, aLinePos, aBytePos, aCount, aLineBrkCnt: Integer;
|
||||
aText: String);
|
||||
property Count: Integer read FCount;
|
||||
property Items[Index: Integer]: TSynPluginSyncronizedEditChangeAction
|
||||
read GetItems; default;
|
||||
end;
|
||||
|
||||
{ TSynPluginSyncronizedEditBase }
|
||||
|
||||
TSynPluginSyncronizedEditBase = class(TSynEditPlugin)
|
||||
@ -141,10 +165,13 @@ type
|
||||
FActive: Boolean;
|
||||
FCells: TSynPluginSyncronizedEditList;
|
||||
FCurrentCell: Integer;
|
||||
FChangeList: TSynPluginSyncronizedEditChangeList;
|
||||
FAreaMarkupEnabled: Boolean;
|
||||
FMarkupEnabled: Boolean;
|
||||
FEnabled: Boolean;
|
||||
FEditing: Boolean;
|
||||
FPaintLock: Integer;
|
||||
FOwnPaintLock: Integer;
|
||||
|
||||
fMarkupInfo: TSynSelectedColor;
|
||||
fMarkupInfoSync: TSynSelectedColor;
|
||||
@ -167,11 +194,16 @@ type
|
||||
procedure SetEditor(const AValue: TCustomSynEdit); override;
|
||||
procedure DoLinesEdited(Sender: TSynEditStrings; aLinePos, aBytePos, aCount,
|
||||
aLineBrkCnt: Integer; aText: String);
|
||||
procedure DoBeforeEdit(aX, aY: Integer; aUndoRedo: Boolean); virtual;
|
||||
procedure ApplyChangeList;
|
||||
procedure DoBeforeEdit(aX, aY, aCount, aLineBrkCnt: Integer; aUndoRedo: Boolean); virtual;
|
||||
procedure DoAfterEdit(aX, aY: Integer; aUndoRedo: Boolean); virtual;
|
||||
procedure DoPaintLockStarted; virtual;
|
||||
procedure DoPaintLockEnded; virtual;
|
||||
procedure DoClear; virtual;
|
||||
procedure DoOnActivate; virtual;
|
||||
procedure DoOnDeactivate; virtual;
|
||||
procedure DoIncPaintLock(Sender: TObject);
|
||||
procedure DoDecPaintLock(Sender: TObject);
|
||||
property CurrentCell: Integer read FCurrentCell write SetCurrentCell;
|
||||
property Cells: TSynPluginSyncronizedEditList read FCells;
|
||||
property Markup: TSynPluginSyncronizedEditMarkup read FMarkup;
|
||||
@ -207,15 +239,17 @@ type
|
||||
FUndoRealCount, FRedoRealCount: Integer;
|
||||
FRedoList: TSynEditUndoList;
|
||||
FUndoList: TSynEditUndoList;
|
||||
FExternalEditLock: Integer;
|
||||
protected
|
||||
procedure SetUndoStart; // Handle undo/redo stuff
|
||||
procedure SetEditor(const AValue: TCustomSynEdit); override;
|
||||
procedure DoOnActivate; override;
|
||||
procedure DoOnDeactivate; override;
|
||||
procedure DoBeforeEdit(aX, aY: Integer; aUndoRedo: Boolean); override;
|
||||
procedure DoBeforeEdit(aX, aY, aCount, aLineBrkCnt: Integer; aUndoRedo: Boolean); override;
|
||||
procedure DoAfterEdit(aX, aY: Integer; aUndoRedo: Boolean); override;
|
||||
procedure DoPaintLockStarted; override;
|
||||
procedure DoPaintLockEnded; override;
|
||||
procedure UpdateCurrentCell;
|
||||
procedure UpdateCurrentCell(aLogX, aLogY: Integer);
|
||||
procedure DoCaretChanged(Sender: TObject);
|
||||
property LastCell: Integer read FLastCell;
|
||||
protected
|
||||
@ -225,8 +259,10 @@ type
|
||||
procedure CellCaretHome;
|
||||
procedure CellCaretEnd;
|
||||
public
|
||||
//constructor Create(AOwner: TComponent); override;
|
||||
constructor Create(AOwner: TComponent); override;
|
||||
//destructor Destroy; override;
|
||||
procedure IncExternalEditLock;
|
||||
procedure DecExternalEditLock;
|
||||
end;
|
||||
|
||||
implementation
|
||||
@ -605,6 +641,34 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
{ TSynPluginSyncronizedEditChangeList }
|
||||
|
||||
function TSynPluginSyncronizedEditChangeList.GetItems(Index: Integer): TSynPluginSyncronizedEditChangeAction;
|
||||
begin
|
||||
Result := FList[Index];
|
||||
end;
|
||||
|
||||
procedure TSynPluginSyncronizedEditChangeList.Clear;
|
||||
begin
|
||||
FList := nil;
|
||||
FCount := 0;
|
||||
end;
|
||||
|
||||
procedure TSynPluginSyncronizedEditChangeList.Add(aCellIndex, aLinePos, aBytePos,
|
||||
aCount, aLineBrkCnt: Integer; aText: String);
|
||||
begin
|
||||
if length(FList) <= FCount then
|
||||
SetLength(FList, FCount + 4);
|
||||
|
||||
FList[FCount].CellIndex := aCellIndex;
|
||||
FList[FCount].cLinePos := aLinePos;
|
||||
FList[FCount].cBytePos := aBytePos;
|
||||
FList[FCount].Count := aCount;
|
||||
FList[FCount].LineBrkCount := aLineBrkCnt;
|
||||
FList[FCount].Text := aText;
|
||||
inc(FCount);
|
||||
end;
|
||||
|
||||
{ TSynPluginSyncronizedEditBase }
|
||||
|
||||
constructor TSynPluginSyncronizedEditBase.Create(AOwner: TComponent);
|
||||
@ -636,6 +700,7 @@ begin
|
||||
|
||||
FCells := TSynPluginSyncronizedEditList.Create;
|
||||
CurrentCell := -1;
|
||||
FChangeList := TSynPluginSyncronizedEditChangeList.Create;
|
||||
AreaMarkupEnabled := False;
|
||||
MarkupEnabled := True;
|
||||
inherited Create(AOwner);
|
||||
@ -654,6 +719,7 @@ begin
|
||||
FreeAndNil(fMarkupInfoSync);
|
||||
FreeAndNil(fMarkupInfoCurrent);
|
||||
FreeAndNil(fMarkupInfoArea);
|
||||
FreeAndNil(FChangeList);
|
||||
inherited;
|
||||
end;
|
||||
|
||||
@ -671,6 +737,8 @@ begin
|
||||
Active := False;
|
||||
if Editor <> nil then begin
|
||||
ViewedTextBuffer.RemoveEditHandler(@DoLinesEdited);
|
||||
ViewedTextBuffer.RemoveNotifyHandler(senrAfterIncPaintLock, @DoIncPaintLock);
|
||||
ViewedTextBuffer.RemoveNotifyHandler(senrBeforeDecPaintLock, @DoDecPaintLock);
|
||||
if FMarkup <> nil then begin
|
||||
TSynEditMarkupManager(MarkupMgr).RemoveMarkUp(FMarkup);
|
||||
FreeAndNil(FMarkup);
|
||||
@ -693,6 +761,8 @@ begin
|
||||
TSynEditMarkupManager(MarkupMgr).AddMarkUp(FMarkupArea, True);
|
||||
MarkupChanged(nil);
|
||||
ViewedTextBuffer.AddEditHandler(@DoLinesEdited);
|
||||
ViewedTextBuffer.AddNotifyHandler(senrAfterIncPaintLock, @DoIncPaintLock);
|
||||
ViewedTextBuffer.AddNotifyHandler(senrBeforeDecPaintLock, @DoDecPaintLock);
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -812,17 +882,15 @@ var
|
||||
var
|
||||
i, a: Integer;
|
||||
CurCell: TSynPluginSyncronizedEditCell;
|
||||
Y2, X2: Integer;
|
||||
chg: Boolean;
|
||||
edit: Boolean;
|
||||
CaretPos: TPoint;
|
||||
CellAtPos: Integer;
|
||||
begin
|
||||
if not Active then exit;
|
||||
Pos := Point(aBytePos, aLinePos);
|
||||
Pos2 := Pos;
|
||||
if not FEditing then
|
||||
DoBeforeEdit(Pos.x, Pos.y, IsUndoing or IsRedoing);
|
||||
DoBeforeEdit(Pos.x, Pos.y, aCount, aLineBrkCnt, IsUndoing or IsRedoing);
|
||||
CellAtPos := Cells.IndexOf(Pos.x, Pos.y, True);
|
||||
|
||||
// Todo: need do add undo info (start/stop flag),
|
||||
@ -846,85 +914,85 @@ begin
|
||||
(CompareCarets(Pos, FCells[CellAtPos].LogStart) <= 0) and
|
||||
(CompareCarets(Pos, FCells[CellAtPos].LogEnd) >= 0)
|
||||
then begin
|
||||
ViewedTextBuffer.BeginUpdate;
|
||||
try
|
||||
FEditing := True;
|
||||
CaretPos := CaretObj.LineBytePos;
|
||||
CurCell := FCells[CellAtPos];
|
||||
a := CurCell.Group;
|
||||
Pos.Y := Pos.Y - CurCell.LogStart.y;
|
||||
if Pos.y = 0
|
||||
then Pos.X := Pos.X - CurCell.LogStart.x
|
||||
else dec(Pos.x);
|
||||
for i := 0 to FCells.Count - 1 do begin
|
||||
if FCells[i].LogStart.Y = FCells[i].LogEnd.Y
|
||||
then x2 := FCells[i].LogStart.X + Pos.X
|
||||
else x2 := 1 + Pos.X;
|
||||
if (i <> CellAtPos) and (FCells[i].Group = a) and
|
||||
( (FCells[i].LogStart.Y + Pos.Y < FCells[i].LogEnd.Y) or
|
||||
( (FCells[i].LogStart.Y + Pos.Y = FCells[i].LogEnd.Y) and
|
||||
(x2 <= FCells[i].LogEnd.X) )
|
||||
)
|
||||
then begin
|
||||
Y2 := FCells[i].LogStart.Y + Pos.Y;
|
||||
X2 := Pos.X;
|
||||
if Pos.Y = 0
|
||||
then X2 := X2 + FCells[i].LogStart.X
|
||||
else inc(X2);
|
||||
if aLineBrkCnt = -1 then begin
|
||||
ViewedTextBuffer.EditLineJoin(Y2);
|
||||
if (CaretPos.y > Y2) then begin
|
||||
dec(CaretPos.y);
|
||||
if (CaretPos.y = Y2) then
|
||||
inc(CaretPos.x, X2 - 1);
|
||||
end;
|
||||
end
|
||||
else if aLineBrkCnt < -1 then begin
|
||||
ViewedTextBuffer.EditLinesDelete(Y2, -aLineBrkCnt);
|
||||
if (CaretPos.y > Y2) then
|
||||
inc(CaretPos.y, aLineBrkCnt);
|
||||
end
|
||||
else if aLineBrkCnt = 1 then begin
|
||||
ViewedTextBuffer.EditLineBreak(X2, Y2);
|
||||
if (CaretPos.y > Y2) then
|
||||
inc(CaretPos.y);
|
||||
if (CaretPos.y = Y2) and (CaretPos.x > X2) then begin
|
||||
inc(CaretPos.y);
|
||||
dec(CaretPos.x, X2 - 1);
|
||||
end;
|
||||
end
|
||||
else if aLineBrkCnt > 1 then begin
|
||||
ViewedTextBuffer.EditLinesInsert(Y2, aLineBrkCnt);
|
||||
if (CaretPos.y > Y2) then
|
||||
inc(CaretPos.y, aLineBrkCnt);
|
||||
end
|
||||
else if aCount < 0 then begin
|
||||
ViewedTextBuffer.EditDelete(X2, Y2, -aCount);
|
||||
if (CaretPos.y = Y2) and (CaretPos.X > X2) then
|
||||
inc(CaretPos.X, aCount);
|
||||
end
|
||||
else if aCount > 0 then begin
|
||||
ViewedTextBuffer.EditInsert(X2, Y2, aText);
|
||||
if (CaretPos.y = Y2) and (CaretPos.X > X2) then
|
||||
inc(CaretPos.X, aCount);
|
||||
end;
|
||||
end;
|
||||
end
|
||||
finally
|
||||
ViewedTextBuffer.EndUpdate;
|
||||
end;
|
||||
CaretObj.LineBytePos := CaretPos;
|
||||
FEditing := False;
|
||||
CurCell := FCells[CellAtPos];
|
||||
Pos.Y := Pos.Y - CurCell.LogStart.y;
|
||||
if Pos.y = 0 then
|
||||
pos2.x := pos.x + CurCell.LogStart.x;
|
||||
Pos2.y := Pos.y + CurCell.LogStart.y;
|
||||
Pos.X := Pos.X - CurCell.LogStart.x
|
||||
else
|
||||
dec(Pos.x);
|
||||
FChangeList.Add(CellAtPos, Pos.Y, Pos.X, aCount, aLineBrkCnt, aText);
|
||||
end;
|
||||
|
||||
if not FEditing then
|
||||
DoAfterEdit(Pos2.x, Pos2.y, IsUndoing or IsRedoing);
|
||||
if (not FEditing) and (FPaintLock = 0) then
|
||||
DoPaintLockEnded;
|
||||
end;
|
||||
|
||||
procedure TSynPluginSyncronizedEditBase.DoBeforeEdit(aX, aY: Integer; aUndoRedo: Boolean);
|
||||
procedure TSynPluginSyncronizedEditBase.ApplyChangeList;
|
||||
var
|
||||
Action: TSynPluginSyncronizedEditChangeAction;
|
||||
a, i: Integer;
|
||||
Group, Y2, X2: Integer;
|
||||
Cell: TSynPluginSyncronizedEditCell;
|
||||
begin
|
||||
if FChangeList.Count = 0 then
|
||||
exit;
|
||||
FEditing := True;
|
||||
ViewedTextBuffer.BeginUpdate;
|
||||
CaretObj.IncAutoMoveOnEdit;
|
||||
try
|
||||
for a := 0 to FChangeList.Count - 1 do begin
|
||||
Action := FChangeList[a];
|
||||
Group := FCells[Action.CellIndex].Group;
|
||||
for i := 0 to FCells.Count - 1 do begin
|
||||
Cell := FCells[i];
|
||||
if (i = Action.CellIndex) or (Cell.Group <> Group) then
|
||||
continue;
|
||||
|
||||
if Cell.LogStart.Y = Cell.LogEnd.Y then
|
||||
X2 := Cell.LogStart.X + Action.cBytePos
|
||||
else
|
||||
X2 := 1 + Action.cBytePos;
|
||||
if (Cell.LogStart.Y + Action.cLinePos < Cell.LogEnd.Y) or
|
||||
( (Cell.LogStart.Y + Action.cLinePos = Cell.LogEnd.Y) and
|
||||
(X2 <= Cell.LogEnd.X) )
|
||||
then begin
|
||||
Y2 := Cell.LogStart.Y + Action.cLinePos;
|
||||
if Action.cLinePos = 0 then
|
||||
X2 := Cell.LogStart.X + Action.cBytePos
|
||||
else
|
||||
X2 := 1 + Action.cBytePos;
|
||||
|
||||
if Action.LineBrkCount = -1 then
|
||||
ViewedTextBuffer.EditLineJoin(Y2)
|
||||
else
|
||||
if Action.LineBrkCount < -1 then
|
||||
ViewedTextBuffer.EditLinesDelete(Y2, -Action.LineBrkCount)
|
||||
else
|
||||
if Action.LineBrkCount = 1 then
|
||||
ViewedTextBuffer.EditLineBreak(X2, Y2)
|
||||
else
|
||||
if Action.LineBrkCount > 1 then
|
||||
ViewedTextBuffer.EditLinesInsert(Y2, Action.LineBrkCount)
|
||||
else
|
||||
if Action.Count < 0 then
|
||||
ViewedTextBuffer.EditDelete(X2, Y2, -Action.Count)
|
||||
else
|
||||
if Action.Count > 0 then
|
||||
ViewedTextBuffer.EditInsert(X2, Y2, Action.Text);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
finally
|
||||
FEditing := False;
|
||||
CaretObj.DecAutoMoveOnEdit;
|
||||
ViewedTextBuffer.EndUpdate;
|
||||
end;
|
||||
FChangeList.Clear;
|
||||
end;
|
||||
|
||||
procedure TSynPluginSyncronizedEditBase.DoBeforeEdit(aX, aY, aCount, aLineBrkCnt: Integer; aUndoRedo: Boolean);
|
||||
begin
|
||||
(* Do Nothing *);
|
||||
end;
|
||||
@ -934,6 +1002,16 @@ begin
|
||||
(* Do Nothing *);
|
||||
end;
|
||||
|
||||
procedure TSynPluginSyncronizedEditBase.DoPaintLockStarted;
|
||||
begin
|
||||
(* Do Nothing *);
|
||||
end;
|
||||
|
||||
procedure TSynPluginSyncronizedEditBase.DoPaintLockEnded;
|
||||
begin
|
||||
(* Do Nothing *);
|
||||
end;
|
||||
|
||||
procedure TSynPluginSyncronizedEditBase.DoClear;
|
||||
begin
|
||||
(* Do Nothing *);
|
||||
@ -951,6 +1029,24 @@ begin
|
||||
FOnDeactivate(self);
|
||||
end;
|
||||
|
||||
procedure TSynPluginSyncronizedEditBase.DoIncPaintLock(Sender: TObject);
|
||||
begin
|
||||
if FPaintLock = 0 then
|
||||
DoPaintLockStarted;
|
||||
inc(FPaintLock);
|
||||
if Sender = Editor then
|
||||
inc(FOwnPaintLock);
|
||||
end;
|
||||
|
||||
procedure TSynPluginSyncronizedEditBase.DoDecPaintLock(Sender: TObject);
|
||||
begin
|
||||
dec(FPaintLock);
|
||||
if Sender = Editor then
|
||||
dec(FOwnPaintLock);
|
||||
if FPaintLock = 0 then
|
||||
DoPaintLockEnded;
|
||||
end;
|
||||
|
||||
{ TSynPluginSyncronizedEditCell }
|
||||
|
||||
procedure TSynPluginSyncronizedEditCell.Assign(Src: TSynPluginSyncronizedEditCell);
|
||||
@ -1018,7 +1114,10 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TSynPluginCustomSyncroEdit.DoBeforeEdit(aX, aY: Integer; aUndoRedo: Boolean);
|
||||
procedure TSynPluginCustomSyncroEdit.DoBeforeEdit(aX, aY, aCount, aLineBrkCnt: Integer;
|
||||
aUndoRedo: Boolean);
|
||||
var
|
||||
c1, c2: Integer;
|
||||
begin
|
||||
inherited;
|
||||
if IsUndoing and (FUndoRealCount >= 0) and (FUndoList.RealCount < FUndoRealCount)
|
||||
@ -1036,10 +1135,30 @@ begin
|
||||
- User edit outside a cell (both locations will be outside the cell => deactivate
|
||||
TODO: Hook SynEdits Lock, and check Caret before locking only
|
||||
*)
|
||||
UpdateCurrentCell(aX, aY);
|
||||
if CurrentCell < 0 then
|
||||
UpdateCurrentCell;
|
||||
if CurrentCell < 0 then begin
|
||||
c1 := Cells.IndexOf(aX, aY, True);
|
||||
if aLineBrkCnt < 0 then
|
||||
c2 := Cells.IndexOf(1, aY-aLineBrkCnt, True)
|
||||
else if aCount < 0 then
|
||||
c2 := Cells.IndexOf(aX - aCount, aY, True)
|
||||
else
|
||||
c2 := c1;
|
||||
debugln(['----- c1=',c1,' c2=',c2,' ay=',ay,' ax=',ax,' aLineBrkCnt=',aLineBrkCnt,' aCount=',aCount,' FExternalEditLock=',FExternalEditLock,' FPaintLock=', FPaintLock,' FOwnPaintLock=',FOwnPaintLock]);
|
||||
// allow edit outside cell? (only if not partly cell / part cell updates are not allowed at all)
|
||||
// Todo, could be just on the edge of a cell !
|
||||
if (c1 = c2) and (FExternalEditLock > 0) then begin
|
||||
debugln(['exit for external']);
|
||||
exit;
|
||||
end;
|
||||
// shared editor, outside cells
|
||||
if (FPaintLock > 0) and (FOwnPaintLock = 0) then begin
|
||||
if (c1 < 0) and (c2 < 0) then
|
||||
exit;
|
||||
c1 := -1; // shared Eitor in cell => deactivate
|
||||
debugln(['deactivate for shared']);
|
||||
end;
|
||||
|
||||
if (CurrentCell < 0) or (c1 < 0) or (c2 <> c1) then begin
|
||||
debugln(['deactivate']);
|
||||
Clear;
|
||||
Active := False;
|
||||
end;
|
||||
@ -1048,19 +1167,28 @@ end;
|
||||
procedure TSynPluginCustomSyncroEdit.DoAfterEdit(aX, aY: Integer; aUndoRedo: Boolean);
|
||||
begin
|
||||
inherited DoAfterEdit(aX, aY, aUndoRedo);
|
||||
if FPaintLock = 0 then
|
||||
UpdateCurrentCell;
|
||||
end;
|
||||
|
||||
procedure TSynPluginCustomSyncroEdit.DoPaintLockStarted;
|
||||
begin
|
||||
inherited DoPaintLockStarted;
|
||||
end;
|
||||
|
||||
procedure TSynPluginCustomSyncroEdit.DoPaintLockEnded;
|
||||
begin
|
||||
inherited DoPaintLockEnded;
|
||||
ApplyChangeList;
|
||||
UpdateCurrentCell;
|
||||
end;
|
||||
|
||||
procedure TSynPluginCustomSyncroEdit.UpdateCurrentCell;
|
||||
begin
|
||||
UpdateCurrentCell(CaretObj.BytePos, CaretObj.LinePos);
|
||||
end;
|
||||
|
||||
procedure TSynPluginCustomSyncroEdit.UpdateCurrentCell(aLogX, aLogY: Integer);
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
i := Cells.IndexOf(aLogX, aLogY, True);
|
||||
debugln(['update current cell pl=',FPaintLock]);
|
||||
i := Cells.IndexOf(CaretObj.BytePos, CaretObj.LinePos, True);
|
||||
if (i <> CurrentCell) and (CurrentCell >= 0) then
|
||||
FLastCell := CurrentCell;
|
||||
CurrentCell := i;
|
||||
@ -1185,5 +1313,22 @@ begin
|
||||
Editor.BlockBegin := Cells[CurrentCell].LogEnd;
|
||||
end;
|
||||
|
||||
constructor TSynPluginCustomSyncroEdit.Create(AOwner: TComponent);
|
||||
begin
|
||||
FPaintLock := 0;
|
||||
FExternalEditLock := 0;
|
||||
inherited Create(AOwner);
|
||||
end;
|
||||
|
||||
procedure TSynPluginCustomSyncroEdit.IncExternalEditLock;
|
||||
begin
|
||||
inc(FExternalEditLock);
|
||||
end;
|
||||
|
||||
procedure TSynPluginCustomSyncroEdit.DecExternalEditLock;
|
||||
begin
|
||||
dec(FExternalEditLock);
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
|
@ -2093,34 +2093,41 @@ begin
|
||||
if SrcLogEntry<>nil then begin
|
||||
SynEditor.BeginUpdate;
|
||||
SynEditor.BeginUndoBlock;
|
||||
case SrcLogEntry.Operation of
|
||||
sleoInsert:
|
||||
begin
|
||||
Sender.AbsoluteToLineCol(SrcLogEntry.Position,StartPos.Y,StartPos.X);
|
||||
if StartPos.Y>=1 then
|
||||
SynEditor.TextBetweenPointsEx[StartPos, StartPos, scamAdjust] := SrcLogEntry.Txt;
|
||||
end;
|
||||
sleoDelete:
|
||||
begin
|
||||
Sender.AbsoluteToLineCol(SrcLogEntry.Position,StartPos.Y,StartPos.X);
|
||||
Sender.AbsoluteToLineCol(SrcLogEntry.Position+SrcLogEntry.Len,
|
||||
EndPos.Y,EndPos.X);
|
||||
if (StartPos.Y>=1) and (EndPos.Y>=1) then
|
||||
SynEditor.TextBetweenPointsEx[StartPos, EndPos, scamAdjust] := '';
|
||||
end;
|
||||
sleoMove:
|
||||
begin
|
||||
Sender.AbsoluteToLineCol(SrcLogEntry.Position,StartPos.Y,StartPos.X);
|
||||
Sender.AbsoluteToLineCol(SrcLogEntry.Position+SrcLogEntry.Len,
|
||||
EndPos.Y,EndPos.X);
|
||||
Sender.AbsoluteToLineCol(SrcLogEntry.MoveTo,MoveToPos.Y,MoveToPos.X);
|
||||
if (StartPos.Y>=1) and (EndPos.Y>=1) and (MoveToPos.Y>=1) then
|
||||
MoveTxt(StartPos, EndPos, MoveToPos,
|
||||
SrcLogEntry.Position<SrcLogEntry.MoveTo);
|
||||
end;
|
||||
SynEditor.TemplateEdit.IncExternalEditLock;
|
||||
SynEditor.SyncroEdit.IncExternalEditLock;
|
||||
try
|
||||
case SrcLogEntry.Operation of
|
||||
sleoInsert:
|
||||
begin
|
||||
Sender.AbsoluteToLineCol(SrcLogEntry.Position,StartPos.Y,StartPos.X);
|
||||
if StartPos.Y>=1 then
|
||||
SynEditor.TextBetweenPointsEx[StartPos, StartPos, scamAdjust] := SrcLogEntry.Txt;
|
||||
end;
|
||||
sleoDelete:
|
||||
begin
|
||||
Sender.AbsoluteToLineCol(SrcLogEntry.Position,StartPos.Y,StartPos.X);
|
||||
Sender.AbsoluteToLineCol(SrcLogEntry.Position+SrcLogEntry.Len,
|
||||
EndPos.Y,EndPos.X);
|
||||
if (StartPos.Y>=1) and (EndPos.Y>=1) then
|
||||
SynEditor.TextBetweenPointsEx[StartPos, EndPos, scamAdjust] := '';
|
||||
end;
|
||||
sleoMove:
|
||||
begin
|
||||
Sender.AbsoluteToLineCol(SrcLogEntry.Position,StartPos.Y,StartPos.X);
|
||||
Sender.AbsoluteToLineCol(SrcLogEntry.Position+SrcLogEntry.Len,
|
||||
EndPos.Y,EndPos.X);
|
||||
Sender.AbsoluteToLineCol(SrcLogEntry.MoveTo,MoveToPos.Y,MoveToPos.X);
|
||||
if (StartPos.Y>=1) and (EndPos.Y>=1) and (MoveToPos.Y>=1) then
|
||||
MoveTxt(StartPos, EndPos, MoveToPos,
|
||||
SrcLogEntry.Position<SrcLogEntry.MoveTo);
|
||||
end;
|
||||
end;
|
||||
finally
|
||||
SynEditor.SyncroEdit.DecExternalEditLock;
|
||||
SynEditor.TemplateEdit.DecExternalEditLock;
|
||||
SynEditor.EndUndoBlock;
|
||||
SynEditor.EndUpdate;
|
||||
end;
|
||||
SynEditor.EndUndoBlock;
|
||||
SynEditor.EndUpdate;
|
||||
end else begin
|
||||
{$IFDEF VerboseSrcEditBufClean}
|
||||
debugln(['TSourceEditor.OnCodeBufferChanged clean up ',TCodeBuffer(Sender).FileName,' ',Sender=CodeBuffer,' ',Filename]);
|
||||
@ -2219,10 +2226,13 @@ begin
|
||||
//DebugLn(['TSourceEditor.UpdateCodeBuffer ',FCodeBuffer.FileName]);
|
||||
IncreaseIgnoreCodeBufferLock;
|
||||
SynEditor.BeginUpdate;
|
||||
FCodeBuffer.Assign(SynEditor.Lines);
|
||||
FEditorStampCommitedToCodetools:=(SynEditor.Lines as TSynEditLines).TextChangeStamp;
|
||||
SynEditor.EndUpdate;
|
||||
DecreaseIgnoreCodeBufferLock;
|
||||
try
|
||||
FCodeBuffer.Assign(SynEditor.Lines);
|
||||
FEditorStampCommitedToCodetools:=(SynEditor.Lines as TSynEditLines).TextChangeStamp;
|
||||
finally
|
||||
SynEditor.EndUpdate;
|
||||
DecreaseIgnoreCodeBufferLock;
|
||||
end;
|
||||
end;
|
||||
|
||||
constructor TSourceEditorSharedValues.Create;
|
||||
@ -3738,8 +3748,6 @@ var
|
||||
NewName: string;
|
||||
i: integer;
|
||||
bmp: TCustomBitmap;
|
||||
TemplateEdit: TSynPluginTemplateEdit;
|
||||
SyncroEdit: TSynPluginSyncroEdit;
|
||||
Begin
|
||||
{$IFDEF IDE_DEBUG}
|
||||
writeln('TSourceEditor.CreateEditor A ');
|
||||
@ -3786,15 +3794,14 @@ Begin
|
||||
end;
|
||||
Manager.CodeTemplateModul.AddEditor(FEditor);
|
||||
Manager.NewEditorCreated(self);
|
||||
TemplateEdit:=TSynPluginTemplateEdit.Create(FEditor);
|
||||
TemplateEdit.OnActivate := @EditorActivateSyncro;
|
||||
TemplateEdit.OnDeactivate := @EditorDeactivateSyncro;
|
||||
SyncroEdit := TSynPluginSyncroEdit.Create(FEditor);
|
||||
FEditor.TemplateEdit.OnActivate := @EditorActivateSyncro;
|
||||
FEditor.TemplateEdit.OnDeactivate := @EditorDeactivateSyncro;
|
||||
bmp := CreateBitmapFromLazarusResource('tsynsyncroedit');
|
||||
SyncroEdit.GutterGlyph.Assign(bmp);
|
||||
FEditor.SyncroEdit.GutterGlyph.Assign(bmp);
|
||||
bmp.Free;
|
||||
SyncroEdit.OnActivate := @EditorActivateSyncro;
|
||||
SyncroEdit.OnDeactivate := @EditorDeactivateSyncro;
|
||||
FEditor.SyncroEdit.OnActivate := @EditorActivateSyncro;
|
||||
FEditor.SyncroEdit.OnDeactivate := @EditorDeactivateSyncro;
|
||||
|
||||
RefreshEditorSettings;
|
||||
FEditor.EndUpdate;
|
||||
end else begin
|
||||
|
@ -39,7 +39,8 @@ interface
|
||||
uses
|
||||
Classes, SysUtils, LCLProc, Graphics, SynEdit, SynEditMiscClasses, SynGutter,
|
||||
SynGutterLineNumber, SynGutterCodeFolding, SynGutterMarks, SynGutterChanges,
|
||||
SynEditTextBuffer, SynEditFoldedView, SynTextDrawer, SynEditTextBase;
|
||||
SynEditTextBuffer, SynEditFoldedView, SynTextDrawer, SynEditTextBase,
|
||||
SynPluginTemplateEdit, SynPluginSyncroEdit;
|
||||
|
||||
type
|
||||
|
||||
@ -49,15 +50,20 @@ type
|
||||
|
||||
TIDESynEditor = class(TSynEdit)
|
||||
private
|
||||
FSyncroEdit: TSynPluginSyncroEdit;
|
||||
FTemplateEdit: TSynPluginTemplateEdit;
|
||||
function GetIDEGutterMarks: TIDESynGutterMarks;
|
||||
protected
|
||||
function CreateGutter(AOwner : TSynEditBase; AFoldedLinesView: TSynEditFoldedView;
|
||||
ATextDrawer: TheTextDrawer): TSynGutter; override;
|
||||
public
|
||||
constructor Create(AOwner: TComponent); override;
|
||||
function TextIndexToViewPos(aTextIndex : Integer) : Integer;
|
||||
property IDEGutterMarks: TIDESynGutterMarks read GetIDEGutterMarks;
|
||||
property TopView;
|
||||
property TextBuffer;
|
||||
property TemplateEdit: TSynPluginTemplateEdit read FTemplateEdit;
|
||||
property SyncroEdit: TSynPluginSyncroEdit read FSyncroEdit;
|
||||
end;
|
||||
|
||||
{ TIDESynGutter }
|
||||
@ -120,6 +126,13 @@ begin
|
||||
Result := TIDESynGutter.Create(AOwner, AFoldedLinesView, ATextDrawer);
|
||||
end;
|
||||
|
||||
constructor TIDESynEditor.Create(AOwner: TComponent);
|
||||
begin
|
||||
inherited Create(AOwner);
|
||||
FTemplateEdit:=TSynPluginTemplateEdit.Create(Self);
|
||||
FSyncroEdit := TSynPluginSyncroEdit.Create(Self);
|
||||
end;
|
||||
|
||||
function TIDESynEditor.TextIndexToViewPos(aTextIndex: Integer): Integer;
|
||||
begin
|
||||
Result := TextView.TextIndexToViewPos(aTextIndex - 1);
|
||||
|
Loading…
Reference in New Issue
Block a user