LazEdit: fix TEditor.MarkSelection.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7256 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
lazarus-bart
2020-01-09 17:41:12 +00:00
parent f9403bf32f
commit 887e07f476

View File

@ -723,23 +723,62 @@ end;
procedure TEditor.MarkSelection(const Pre, Post: String); procedure TEditor.MarkSelection(const Pre, Post: String);
var var
SLen: Integer; BB, BE, LC: TPoint;
OldSelMode: TSynSelectionMode; BackwardsSel, HadSelection: Boolean;
begin begin
//this only works with SelectionMode := scNormal //Putting all this in BeginUpdate/EndUpdate ensures that all actions taken here
OldSelMode := SelectionMode; //can be undone in one undo operation (otherwise it would take 2 or 3)
SelectionMode := smNormal; BeginUpdate;
//Using SelEnd - SelStart doesn't work correctly when selecting across lines try
//SynEdit internally works with byte positions, therefore use Length(), not Utf8Length() //Using SetTextBetweenPoints is faster (and according to Martin Friebe) more reliable
SLen := {Utf8}Length(Seltext); //SelStart - SelEnd; //than using SelStart and SelLength (like the old code did)
SelText := Pre + SelText + Post; BB := BlockBegin;
//SelStart now is after Post, place it before the original selection BE := BlockEnd;
SelStart := SelStart - {Utf8}Length(Post) - SLen; BackwardsSel := IsBackwardSel;
SelEnd := SelStart + SLen; //In an newly create TSynEdit without any text SetTextBetweenPoints does not
SelectionMode := OldSelMode; //adjust BlockBegin/BlockEnd at all, so force a line and set the caret at the top
if (Lines.Count = 0) then //fixed in trunk, remove after 2.2 release
begin
Lines.Add('');
LogicalCaretXY := Point(1,1);
end;
HadSelection := SelAvail;
//BB is always before BE even if IsBackwardSel=TRUE
//move caret to the end of the selection
LogicalCaretXY := BlockEnd;
//SetLogicalCaret clears the selection, so restore it
BlockBegin := BB;
BlockEnd := BE;
//Insert Pre at blockbegin, so in front of the selection: block moves to the right, blockbegin.x and blockend.x will increase
//scamAdjust: move the cursor with the block
SetTextBetweenPoints(BB, BB, Pre, [setMoveBlock], scamAdjust{scamIgnore}, smaMoveUp, smNormal);
//if not text was selected SetTextBetweenPoints adjusts BlockEnd, but it does not move BlockBegin and since these point to the same point:
if not HadSelection then //fixed in trunk, remove after 2.2 release
BlockBegin := BlockEnd;
BB := BlockBegin;
BE := BlockEnd;
//Insert Post at blockend, the block does NOT move, so this should NOT affect the value of blockbegin or blockend
SetTextBetweenPoints(BE, BE, Post, [setMoveBlock], scamIgnore, smaMoveUp, smNormal);
//if no text was selected SetTextBetweenPoints adjusts BlockEnd, but it should not have done so, the block is not moved at all,
//so restore:
if not HadSelection then //fixed in trunk, remove after 2.2 release
begin
BlockBegin := BB;
BlockEnd := BB;
end;
finally
EndUpdate;
end;
SetFocus; SetFocus;
end; end;
constructor TEditor.Create(TheOwner: TComponent); constructor TEditor.Create(TheOwner: TComponent);
begin begin
inherited Create(TheOwner); inherited Create(TheOwner);