SynEdit: fixed utf-8/tab issue for column mode selections

git-svn-id: trunk@21035 -
This commit is contained in:
martin 2009-07-31 20:58:14 +00:00
parent 4a22e85af6
commit 11cefe2883

View File

@ -632,19 +632,14 @@ function TSynEditSelection.GetSelText : string;
end; end;
const
sLineBreak = {$IFDEF SYN_LAZARUS}LineEnding{$ELSE}#$0D#$0A{$ENDIF};
var var
First, Last, TotalLen: Integer; First, Last, TotalLen: Integer;
ColFrom, ColTo: Integer; ColFrom, ColTo: Integer;
I: Integer; I: Integer;
{$IFDEF SYN_MBCSSUPPORT}
l, r: Integer;
s: string;
{$ELSE}
ColLen: integer;
{$ENDIF}
P: PChar; P: PChar;
C1, C2: Integer;
Col, Len: array of Integer;
begin begin
if not SelAvail then if not SelAvail then
Result := '' Result := ''
@ -681,54 +676,38 @@ begin
CopyAndForward(FLines[i], 1, MaxInt, P); CopyAndForward(FLines[i], 1, MaxInt, P);
CopyAndForward(sLineBreak, 1, MaxInt, P); CopyAndForward(sLineBreak, 1, MaxInt, P);
end; end;
{$IFDEF SYN_LAZARUS}
CopyPaddedAndForward(FLines[Last], 1, ColTo - 1, P); CopyPaddedAndForward(FLines[Last], 1, ColTo - 1, P);
{$ELSE}
CopyAndForward(FLines[Last], 1, ColTo - 1, P);
{$ENDIF}
end; end;
smColumn: smColumn:
begin begin
if ColFrom > ColTo then // Calculate the byte positions for each line
SwapInt(ColFrom, ColTo); SetLength(Col, Last - First + 1);
// step1: calclate total length of result string SetLength(Len, Last - First + 1);
{$IFNDEF SYN_MBCSSUPPORT} FInternalCaret.AllowPastEOL := True;
ColLen := ColTo - ColFrom; FInternalCaret.LineBytePos := FirstLineBytePos;
TotalLen := ColLen + (ColLen + Length(sLineBreak)) * (Last - First); C1 := FInternalCaret.CharPos;
// step2: build up result string FInternalCaret.LineBytePos := LastLineBytePos;
C2 := FInternalCaret.CharPos;
if C1 > C2 then
SwapInt(C1, C2);
TotalLen := 0;
for i := First to Last do begin
FInternalCaret.LineCharPos := Point(C1, i + 1);
Col[i - First] := FInternalCaret.BytePos;
FInternalCaret.LineCharPos := Point(C2, i + 1);
Len[i - First] := Max(0, FInternalCaret.BytePos - Col[i - First]);
Inc(TotalLen, Len[i - First]);
end;
Inc(TotalLen, Length(LineEnding) * (Last - First));
// build up result string
SetLength(Result, TotalLen); SetLength(Result, TotalLen);
P := PChar(Pointer(Result)); P := PChar(Pointer(Result));
for i := First to Last - 1 do begin
CopyPaddedAndForward(FLines[i], ColFrom, ColLen, P);
CopyAndForward(sLineBreak, 1, MaxInt, P);
end;
CopyPaddedAndForward(FLines[Last], ColFrom, ColLen, P);
{$ELSE} //SYN_MBCSSUPPORT
for i := First to Last do begin for i := First to Last do begin
s := FLines[i]; CopyPaddedAndForward(FLines[i], Col[i-First], Len[i-First], P);
l := ColFrom; if i < Last then
r := ColTo; CopyAndForward(LineEnding, 1, MaxInt, P);
MBCSGetSelRangeInLineWhenColumnActiveSelectionMode(s, l, r);
Inc(TotalLen, r - l);
end; end;
Inc(TotalLen, Length(sLineBreak) * (Last - First));
// step2: build up result string
SetLength(Result, TotalLen);
P := PChar(Result);
for i := First to Last - 1 do begin
s := FLines[i];
l := ColFrom;
r := ColTo;
MBCSGetSelRangeInLineWhenColumnActiveSelectionMode(s, l, r);
CopyPaddedAndForward(s, l, r - l, P);
CopyAndForward(sLineBreak, 1, MaxInt, P);
end;
s := FLines[Last];
l := ColFrom;
r := ColTo;
MBCSGetSelRangeInLineWhenColumnActiveSelectionMode(s, l, r);
CopyPaddedAndForward(FLines[Last], l, r - l, P);
{$ENDIF}
end; end;
smLine: smLine:
begin begin
@ -736,19 +715,19 @@ begin
// line break code(s) of the last line will not be added. // line break code(s) of the last line will not be added.
// step1: calclate total length of result string // step1: calclate total length of result string
for i := First to Last do for i := First to Last do
Inc(TotalLen, Length(FLines[i]) + Length(sLineBreak)); Inc(TotalLen, Length(FLines[i]) + Length(LineEnding));
if Last = FLines.Count - 1 then if Last = FLines.Count - 1 then
Dec(TotalLen, Length(sLineBreak)); Dec(TotalLen, Length(LineEnding));
// step2: build up result string // step2: build up result string
SetLength(Result, TotalLen); SetLength(Result, TotalLen);
P := PChar(Pointer(Result)); P := PChar(Pointer(Result));
for i := First to Last - 1 do begin for i := First to Last - 1 do begin
CopyAndForward(FLines[i], 1, MaxInt, P); CopyAndForward(FLines[i], 1, MaxInt, P);
CopyAndForward(sLineBreak, 1, MaxInt, P); CopyAndForward(LineEnding, 1, MaxInt, P);
end; end;
CopyAndForward(FLines[Last], 1, MaxInt, P); CopyAndForward(FLines[Last], 1, MaxInt, P);
if Last < FLines.Count - 1 then if Last < FLines.Count - 1 then
CopyAndForward(sLineBreak, 1, MaxInt, P); CopyAndForward(LineEnding, 1, MaxInt, P);
end; end;
end; end;
end; end;