SynEdit: Added Copy and paste with ability to keep folded text

git-svn-id: trunk@20587 -
This commit is contained in:
martin 2009-06-11 23:00:44 +00:00
parent 47b8c987cb
commit 9d97223c5c
10 changed files with 606 additions and 246 deletions

View File

@ -85,7 +85,11 @@ uses
{$ENDIF}
SynEditMiscClasses, SynEditTextBuffer, SynEditHighlighter, SynTextDrawer,
SynEditLines,
LResources;
LResources, Clipbrd
{$IFDEF SYN_COMPILER_4_UP}
, StdActns
{$ENDIF}
;
const
DIGIT = ['0'..'9'];
@ -124,13 +128,6 @@ const
// maximum scroll range
MAX_SCROLL = 32767;
SYNEDIT_CLIPBOARD_FORMAT = 'SynEdit Control Block Type';
{$IFNDEF SYN_LAZARUS}
var
SynEditClipboardFormat: UINT;
{$ENDIF}
{$IFDEF SYN_MBCSSUPPORT}
{$IFNDEF SYN_COMPILER_4_UP}
{Windows.pas in D4}
@ -155,8 +152,6 @@ type
TSynEditMarkupClass = SynEditMarkup.TSynEditMarkupClass;
TSynReplaceAction = (raCancel, raSkip, raReplace, raReplaceAll);
ESynEditError = class(Exception);
TSynDropFilesEvent = procedure(Sender: TObject; X, Y: integer; AFiles: TStrings)
of object;
@ -232,7 +227,8 @@ type
TSynEditorOption2 = (
eoCaretSkipsSelection, // Caret skips selection on VK_LEFT/VK_RIGHT
eoAlwaysVisibleCaret, // Move caret to be always visible when scrolling
eoEnhanceEndKey // end key jumps to visual/hard line end whichever is nearer
eoEnhanceEndKey, // end key jumps to visual/hard line end whichever is nearer
eoFoldedCopyPaste // Remember folds in copy/paste operations
);
TSynEditorOptions2 = set of TSynEditorOption2;
{$ENDIF}
@ -254,6 +250,7 @@ const
{$IFDEF SYN_LAZARUS}
SYNEDIT_DEFAULT_OPTIONS2 = [
eoFoldedCopyPaste
];
{$ENDIF}
@ -604,6 +601,7 @@ type
function GetViewedTextBuffer: TSynEditStrings; override;
function GetTextBuffer: TSynEditStrings; override;
procedure SetLines(Value: TStrings); override;
procedure ScanFromAfterLock;
procedure DecPaintLock;
procedure DestroyWnd; override;
procedure DragOver(Source: TObject; X, Y: Integer;
@ -699,6 +697,7 @@ type
property TextView : TSynEditFoldedView read FFoldedLinesView;
property TopView: Integer read GetTopView write SetTopView; // TopLine converted into Visible(View) lines
{$ENDIF}
function PasteFromClipboardEx(ClipHelper: TSynClipboardStream): Boolean;
public
procedure FindMatchingBracket; virtual;
{$IFDEF SYN_LAZARUS}
@ -732,7 +731,7 @@ type
constructor Create(AOwner: TComponent); override;
procedure CutToClipboard;
destructor Destroy; override;
procedure DoCopyToClipboard(const SText: string);
procedure DoCopyToClipboard(const SText: string; FoldInfo: String = '');
procedure DragDrop(Source: TObject; X, Y: Integer); override;
procedure EndUndoBlock(aList: TSynEditUndoList = nil);
procedure EndUpdate;
@ -1105,25 +1104,12 @@ type
property OnStatusChange;
end;
{$IFDEF SYN_LAZARUS}
function SynEditClipboardFormat: TClipboardFormat;
{$ENDIF}
procedure Register;
implementation
// { $R SynEdit.res}
uses
{$IFDEF SYN_COMPILER_4_UP}
StdActns,
{$ENDIF}
{$IFNDEF SYN_LAZARUS}
// ToDo ShellAPI
ShellAPI, SynEditStrConst,
{$ENDIF}
Clipbrd;
type
{ TSynEditUndoCaret }
@ -1174,6 +1160,9 @@ type
function PerformUndo(Caller: TObject): Boolean; override;
end;
var
SynDefaultBeautifier: TSynCustomBeautifier;
{ TSynEditUndoCaret }
function TSynEditUndoCaret.IsEqualContent(AnItem: TSynEditUndoItem): Boolean;
@ -1268,24 +1257,6 @@ begin
Result := False;
end;
{$IFDEF SYN_LAZARUS}
var
SynDefaultBeautifier: TSynCustomBeautifier;
const
fSynEditClipboardFormat: TClipboardFormat = 0;
function SynEditClipboardFormat: TClipboardFormat;
begin
if fSynEditClipboardFormat=0 then
fSynEditClipboardFormat := ClipboardRegisterFormat(SYNEDIT_CLIPBOARD_FORMAT);
Result:=fSynEditClipboardFormat;
end;
{$ENDIF}
function Roundoff(X: Extended): Longint;
begin
if (x >= 0) then begin
@ -1327,13 +1298,14 @@ end;
procedure TCustomSynEdit.AquirePrimarySelection;
var
FormatList: TClipboardFormat;
FormatList: Array [0..1] of TClipboardFormat;
begin
if (not SelAvail)
or (PrimarySelection.OnRequest=@PrimarySelectionRequest) then exit;
FormatList:=CF_TEXT;
FormatList[0] := CF_TEXT;
FormatList[1] := TSynClipboardStream.ClipboardFormatId;
try
PrimarySelection.SetSupportedFormats(1,@FormatList);
PrimarySelection.SetSupportedFormats(2, @FormatList[0]);
PrimarySelection.OnRequest:=@PrimarySelectionRequest;
except
end;
@ -1438,111 +1410,49 @@ begin
CaretXY := PixelsToRowColumn(Point(X,Y));
end;
procedure TCustomSynEdit.DoCopyToClipboard(const SText: string);
procedure TCustomSynEdit.DoCopyToClipboard(const SText: string; FoldInfo: String = '');
var
{$IFDEF SYN_LAZARUS}
Buf: Pointer;
BufSize: integer;
{$ELSE}
Mem: HGLOBAL;
Failed: boolean;
{$ENDIF}
P: PChar;
SLen: integer;
ClipHelper: TSynClipboardStream;
begin
if SText = '' then exit;
SLen := Length(SText);
{$IFDEF SYN_LAZARUS}
Clipboard.Clear;
Clipboard.AsText:=SText;
if not Clipboard.HasFormat(CF_TEXT) then
raise ESynEditError.Create('Clipboard copy operation failed: HasFormat');
// Copy it in our custom format so we know what kind of block it is.
// That effects how it is pasted in.
BufSize:=SLen+SizeOf(TSynSelectionMode)+1;
GetMem(Buf,BufSize);
if Buf = nil then
raise ESynEditError.Create('Clipboard copy operation failed: GetMem');
ClipHelper := TSynClipboardStream.Create;
try
P:=PChar(Buf);
// Our format: TSynSelectionMode value followed by text.
PSynSelectionMode(P)^ := SelectionMode;
inc(P, SizeOf(TSynSelectionMode));
if SLen>0 then begin
Move(SText[1], P^, SLen);
inc(P,SLen);
end;
P[0]:=#0;
if not Clipboard.AddFormat(SynEditClipboardFormat,Buf^,BufSize) then
ClipHelper.Text := SText;
ClipHelper.SelectionMode := SelectionMode;
// Fold
if length(FoldInfo) > 0 then
ClipHelper.AddTag(synClipTagFold, @FoldInfo[1], length(FoldInfo));
if not ClipHelper.WriteToClipboard(Clipboard) then
raise ESynEditError.Create('Clipboard copy operation failed: AddFormat');
finally
FreeMem(Buf);
ClipHelper.Free;
end;
{$ELSE}
Failed := true; // assume the worst.
// Open and Close are the only TClipboard methods we use because TClipboard
// is very hard (impossible) to work with if you want to put more than one
// format on it at a time.
Clipboard.Open;
try
// Clear anything already on the clipboard.
EmptyClipboard;
// Put it on the clipboard as normal text format so it can be pasted into
// things like notepad or Delphi.
Mem := GlobalAlloc(GMEM_MOVEABLE or GMEM_DDESHARE, SLen + 1);
if Mem <> 0 then begin
P := GlobalLock(Mem);
try
if P <> nil then begin
Move(PChar(SText)^, P^, SLen + 1);
// Put it on the clipboard in text format
Failed := SetClipboardData(CF_TEXT, Mem) = 0;
end;
finally
GlobalUnlock(Mem);
end;
end;
// Don't free Mem! It belongs to the clipboard now, and it will free it
// when it is done with it.
if not Failed then begin
// Copy it in our custom format so we know what kind of block it is.
// That effects how it is pasted in.
Mem := GlobalAlloc(GMEM_MOVEABLE or GMEM_DDESHARE, SLen +
SizeOf(TSynSelectionMode) + 1);
P := GlobalLock(Mem);
try
if P <> nil then begin
// Our format: TSynSelectionMode value followed by text.
PSynSelectionMode(P)^ := SelectionMode;
inc(P, SizeOf(TSynSelectionMode));
Move(PChar(SText)^, P^, SLen + 1);
Failed := SetClipboardData(SynEditClipboardFormat, Mem) = 0;
end;
finally
GlobalUnlock(Mem);
end;
// Don't free Mem! It belongs to the clipboard now, and it will free it
// when it is done with it.
end;
finally
Clipboard.Close;
if Failed then
raise ESynEditError.Create('Clipboard copy operation failed');
end;
{$ENDIF}
end;
procedure TCustomSynEdit.CopyToClipboard;
var
FInfo: String;
begin
if SelAvail then begin
DoCopyToClipboard(SelText);
if eoFoldedCopyPaste in fOptions2 then
FInfo := FFoldedLinesView.GetFoldDescription(
FBlockSelection.FirstLineBytePos.Y - 1, FBlockSelection.FirstLineBytePos.X,
FBlockSelection.LastLineBytePos.Y - 1, FBlockSelection.LastLineBytePos.X);
DoCopyToClipboard(SelText, FInfo);
end;
end;
procedure TCustomSynEdit.CutToClipboard;
var
FInfo: String;
begin
if SelAvail then begin
DoCopyToClipboard(SelText);
if eoFoldedCopyPaste in fOptions2 then
FInfo := FFoldedLinesView.GetFoldDescription(
FBlockSelection.FirstLineBytePos.Y - 1, FBlockSelection.FirstLineBytePos.X,
FBlockSelection.LastLineBytePos.Y - 1, FBlockSelection.LastLineBytePos.X);
DoCopyToClipboard(SelText, FInfo);
SetSelTextExternal('');
end;
end;
@ -1764,12 +1674,10 @@ begin
end;
end;
procedure TCustomSynEdit.DecPaintLock;
procedure TCustomSynEdit.ScanFromAfterLock;
var
LastLineChanged: LongInt;
begin
if (fPaintLock=1) and HandleAllocated then begin
{$IFDEF SYN_LAZARUS}
if fHighlighterNeedsUpdateStartLine>0 then begin
//DebugLn('TCustomSynEdit.DecPaintLock ',dbgs(fHighlighterNeedsUpdateStartLine),'-',dbgs(fHighlighterNeedsUpdateEndLine));
if fHighlighterNeedsUpdateStartLine<=FTheLinesView.Count then begin
@ -1789,7 +1697,12 @@ begin
fHighlighterNeedsUpdateStartLine:=0;
fHighlighterNeedsUpdateEndLine:=0;
end;
{$ENDIF}
end;
procedure TCustomSynEdit.DecPaintLock;
begin
if (fPaintLock=1) and HandleAllocated then begin
ScanFromAfterLock;
end;
FCaret.Unlock; // Maybe after FFoldedLinesView;
FTrimmedLinesView.UnLock; // Must be unlocked after caret
@ -2380,10 +2293,10 @@ var
end;
var
PrimarySelText: String;
ACommand: TSynEditorMouseCommand;
Handled: Boolean;
AnAction: TSynEditMouseAction;
ClipHelper: TSynClipboardStream;
begin
AnAction := nil;
Result := False;
@ -2459,15 +2372,19 @@ begin
end;
emcPasteSelection:
begin
MoveCaret;
PrimarySelText := PrimarySelection.AsText;
if ((PrimarySelText<>'') or SelAvail) then begin
FBlockSelection.StartLineBytePos := AnInfo.NewCaret.LineBytePos;
FBlockSelection.EndLineBytePos := AnInfo.NewCaret.LineBytePos;
SelText:=PrimarySelText;
end
else
Result :=False;
ClipHelper := TSynClipboardStream.Create;
try
ClipHelper.ReadFromClipboard(PrimarySelection);
if ClipHelper.TextP <> nil then begin
MoveCaret;
FBlockSelection.StartLineBytePos := FCaret.LineBytePos;
Result := PasteFromClipboardEx(ClipHelper);
end
else
Result := False;
finally
ClipHelper.Free;
end;
end;
emcMouseLink:
begin
@ -3706,63 +3623,45 @@ end;
procedure TCustomSynEdit.PasteFromClipboard;
var
{$IFDEF SYN_LAZARUS}
MemStream: TMemoryStream;
Buf: Pointer;
BufSize: integer;
{$ELSE}
Mem: HGLOBAL;
{$ENDIF}
PasteMode: TSynSelectionMode;
P: PChar;
ClipHelper: TSynClipboardStream;
begin
BeginUndoBlock; //mh 2000-11-20
ClipHelper := TSynClipboardStream.Create;
try
// Check for our special format first.
if Clipboard.HasFormat(SynEditClipboardFormat) then begin
{$IFDEF SYN_LAZARUS}
MemStream:=TMemoryStream.Create;
Buf:=nil;
try
Clipboard.GetFormat(SynEditClipboardFormat,MemStream);
BufSize:=integer(MemStream.Size);
if BufSize>=SizeOf(TSynSelectionMode)+1 then begin
GetMem(Buf,BufSize+1);
MemStream.Position:=0;
MemStream.Read(Buf^,BufSize);
P:=PChar(Buf);
P[BufSize]:=#0;
{$ELSE}
Clipboard.Open;
try
Mem := Clipboard.GetAsHandle(SynEditClipboardFormat);
P := GlobalLock(Mem);
if P <> nil then begin
{$ENDIF}
// Our format: SelectionMode value followed by text.
// See CopyToClipboard
PasteMode := PSynSelectionMode(P)^;
inc(P, SizeOf(TSynSelectionMode));
SetSelTextPrimitive(PasteMode, P, true);
end else
raise ESynEditError.Create('Clipboard paste operation failed.');
finally
{$IFDEF SYN_LAZARUS}
MemStream.Free;
if Buf<>nil then FreeMem(Buf);
{$ELSE}
Clipboard.Close;
{$ENDIF}
ClipHelper.ReadFromClipboard(Clipboard);
PasteFromClipboardEx(ClipHelper);
finally
ClipHelper.Free;
end;
end;
function TCustomSynEdit.PasteFromClipboardEx(ClipHelper: TSynClipboardStream) : Boolean;
var
PTxt: PChar;
InsStart: TPoint;
begin
Result := False;
BeginUndoBlock;
try
if ClipHelper.TextP = nil then
exit;
Result := True;
InsStart := FBlockSelection.StartLineBytePos;
SetSelTextPrimitive(ClipHelper.SelectionMode, ClipHelper.TextP, true);
if eoFoldedCopyPaste in fOptions2 then begin
PTxt := ClipHelper.GetTagPointer(synClipTagFold);
if PTxt <> nil then begin
ScanFromAfterLock;
FFoldedLinesView.ApplyFoldDescription(InsStart.Y -1, InsStart.X,
FBlockSelection.StartLinePos-1, FBlockSelection.StartBytePos,
PTxt, ClipHelper.GetTagLen(synClipTagFold));
end;
// If our special format isn't there, check for regular text format.
end else if Clipboard.HasFormat(CF_TEXT) then begin
// Normal text is much easier...
SelText := Clipboard.AsText;
end;
finally
EndUndoBlock; //mh 2000-11-20
EndUndoBlock;
EnsureCursorPosVisible;
end;
EnsureCursorPosVisible;
end;
procedure TCustomSynEdit.SelectAll;
@ -4838,7 +4737,7 @@ end;
function TCustomSynEdit.GetCanPaste:Boolean;
begin
Result := Clipboard.HasFormat(CF_TEXT)
or Clipboard.HasFormat(SynEditClipboardFormat)
or Clipboard.HasFormat(TSynClipboardStream.ClipboardFormatId)
end;
procedure TCustomSynEdit.InsertBlock(BB: TPoint; ChangeStr: PChar);
@ -5198,6 +5097,8 @@ var
BB, BE: TPoint;
DragDropText: string;
Adjust: integer;
FoldInfo: String;
BlockSel: TSynEditSelection;
begin
if not ReadOnly and (Source is TCustomSynEdit)
and TCustomSynEdit(Source).SelAvail
@ -5226,6 +5127,11 @@ begin
BeginUndoBlock; //mh 2000-11-20
try
DragDropText := TCustomSynEdit(Source).SelText;
BlockSel := TCustomSynEdit(Source).FBlockSelection;
if eoFoldedCopyPaste in fOptions2 then
FoldInfo := TCustomSynEdit(Source).FFoldedLinesView.GetFoldDescription(
BlockSel.FirstLineBytePos.Y - 1, BlockSel.FirstLineBytePos.X,
BlockSel.LastLineBytePos.Y - 1, BlockSel.LastLineBytePos.X);
// delete the selected text if necessary
if DropMove then begin
if Source <> Self then
@ -5250,10 +5156,13 @@ begin
try
CaretXY := NewCaret;
BlockBegin := NewCaret;
if Source = Self then
SetSelTextPrimitive(smNormal, PChar(DragDropText), true)
else
SetSelTextPrimitive(smNormal, PChar(DragDropText), true);
SetSelTextPrimitive(smNormal, PChar(DragDropText), true);
if FoldInfo <> '' then begin
ScanFromAfterLock;
FFoldedLinesView.ApplyFoldDescription(NewCaret.Y -1, NewCaret.X,
FBlockSelection.StartLinePos-1, FBlockSelection.StartBytePos,
PChar(FoldInfo), length(FoldInfo));
end;
finally
FCaret.DecForcePastEOL;
end;
@ -8876,12 +8785,36 @@ end;
{$IFDEF SYN_LAZARUS}
procedure TCustomSynEdit.PrimarySelectionRequest(
const RequestedFormatID: TClipboardFormat; Data: TStream);
var s: string;
var
s: string;
ClipHelper: TSynClipboardStream;
begin
if (not SelAvail) or (RequestedFormatID<>CF_TEXT) then exit;
if (not SelAvail) then exit;
s:=SelText;
if s<>'' then
if s = '' then
exit;
if RequestedFormatID = CF_TEXT then begin
Data.Write(s[1],length(s));
end
else
if RequestedFormatID = TSynClipboardStream.ClipboardFormatId then begin
ClipHelper := TSynClipboardStream.Create;
try
ClipHelper.SelectionMode := SelectionMode;
// InternalText, so we don't need a 2nd call for CF_TEXT
ClipHelper.InternalText := s;
// Fold
if eoFoldedCopyPaste in fOptions2 then
s := FFoldedLinesView.GetFoldDescription(
FBlockSelection.FirstLineBytePos.Y - 1, FBlockSelection.FirstLineBytePos.X,
FBlockSelection.LastLineBytePos.Y - 1, FBlockSelection.LastLineBytePos.X);
if length(s) > 0 then
ClipHelper.AddTag(synClipTagFold, @s[1], length(s));
Data.Write(ClipHelper.Memory^, ClipHelper.Size);
finally
ClipHelper.Free;
end;
end;
end;
{$ENDIF}
@ -8942,9 +8875,6 @@ begin
end;
initialization
{$IFNDEF SYN_LAZARUS}
SynEditClipboardFormat := RegisterClipboardFormat(SYNEDIT_CLIPBOARD_FORMAT);
{$ENDIF}
SynDefaultBeautifier := TSynBeautifier.Create(Application);
Register;

View File

@ -289,6 +289,14 @@ type
Previous: Boolean = False): Integer;
procedure CollapseDefaultFolds;
// Load/Save folds to string
// AStartIndex, AEndIndex: (0 based) First/last line (EndIndex = -1 = open end)
// AStartCol, AEndCol: (1 based) Logical text pos in Line. (AEndCol = -1 = full line)
function GetFoldDescription(AStartIndex, AStartCol, AEndIndex,
AEndCol: Integer) :String;
procedure ApplyFoldDescription(AStartIndex, AStartCol, AEndIndex,
AEndCol: Integer; FoldDesc: PChar;
FoldDescLen: Integer);
procedure UnfoldAll;
procedure FoldAll(StartLevel : Integer = 0; IgnoreNested : Boolean = False);
@ -315,6 +323,12 @@ type
implementation
type
TFoldExportEntry = Record
Line, LogX, LogX2, ELine, ELogX, ELogX2, FType: Integer;
end;
{ TSynTextFoldAVLNodeData }
function TSynTextFoldAVLNodeData.TreeDepth : integer;
@ -1850,12 +1864,12 @@ begin
hl := TSynCustomFoldHighlighter(FHighLighter);
// AStartIndex is 0-based
// FoldTree is 1-based AND first line remains visble
c := hl.FoldNodeInfoCount[AStartIndex];
c := hl.FoldNodeInfoCount[AStartIndex, []];
if c = 0 then
exit(-1);
i := 0;
while i < c do begin
nd := hl.FoldNodeInfo[aStartIndex, i];
nd := hl.FoldNodeInfo[aStartIndex, i, []];
if sfaOpen in nd.FoldAction then begin
if (nd.LogXStart >= LogX) then begin
dec(i);
@ -1887,10 +1901,10 @@ begin
// Currently PascalHl Type 2 = Region
c := hl.FoldOpenCount(i, 2);
if c > 0 then begin
c := hl.FoldNodeInfoCount[i];
c := hl.FoldNodeInfoCount[i, []];
j := 0;
while j < c do begin
nd := hl.FoldNodeInfo[i, j];
nd := hl.FoldNodeInfo[i, j, []];
if (sfaDefaultCollapsed in nd.FoldAction) and
(not IsFoldedAtTextIndex(i, j))
then
@ -1902,6 +1916,149 @@ begin
end;
end;
function TSynEditFoldedView.GetFoldDescription(AStartIndex, AStartCol, AEndIndex,
AEndCol: Integer): String;
var
node: TSynTextFoldAVLNode;
hl: TSynCustomFoldHighlighter;
ndinfo, ndinfo2: TSynFoldNodeInfo;
EndIndex: Integer;
c, i, x: Integer;
entry: TFoldExportEntry;
begin
Result := '';
if not(assigned(FHighLighter) and (FHighLighter is TSynCustomFoldHighlighter))
then exit;
hl := TSynCustomFoldHighlighter(FHighLighter);
node := fFoldTree.FindFoldForLine(AStartIndex + 1, True);
if not node.IsInFold then
exit;
// Node.startline is first hidden line
while (node.StartLine = AStartIndex + 2) and (AStartCol > 1) do begin
ndinfo := hl.FoldNodeInfo[aStartIndex, node.FoldIndex, [sfaOpen]];
if (sfaInvalid in ndinfo.FoldAction) or (ndinfo.LogXStart >= AStartIndex)
then break;
node := node.Next;
if not node.IsInFold then
exit;
end;
while node.IsInFold and
((AEndIndex < 0) or (node.StartLine-2 <= AEndIndex)) do
begin
if (node.StartLine > AStartIndex + 2) then
AStartCol := 0;
EndIndex := node.StartLine-2 + node.LineCount;
if (AEndIndex >= 0) and (EndIndex > AEndIndex) then begin
node := node.Next;
continue;
end;
ndinfo := hl.FoldNodeInfo[node.StartLine-2, node.FoldIndex, [sfaOpen]];
c := hl.FoldNodeInfoCount[EndIndex, [sfaClose]];
i := 0;
while i < c do begin
ndinfo2 := hl.FoldNodeInfo[EndIndex, i, [sfaClose]];
if ndinfo2.FoldLvlStart = ndinfo.FoldLvlEnd then break;
inc(i);
end;
if (i = c) or (sfaInvalid in ndinfo2.FoldAction) or
((AEndIndex = EndIndex) and (AEndCol > 0) and (ndinfo2.LogXEnd > AEndCol))
then begin
node := node.Next;
continue;
end;
// Add the fold
x := ndinfo.LogXStart;
if AStartCol > 0 then
x := x - AStartCol + 1;
with entry do begin
LogX := x;
LogX2 := ndinfo.LogXEnd - ndinfo.LogXStart + x;
Line := node.StartLine - 2 - AStartIndex;
ELogX := ndinfo2.LogXStart;
ELogX2 := ndinfo2.LogXEnd;
ELine := node.StartLine - 2 - AStartIndex + node.LineCount;
FType := PtrUInt(ndinfo.FoldType);
end;
i := length(Result);
SetLength(Result, i + SizeOf(TFoldExportEntry));
System.Move(entry, Result[i+1], sizeof(TFoldExportEntry));
node := node.Next;
end;
end;
procedure TSynEditFoldedView.ApplyFoldDescription(AStartIndex, AStartCol, AEndIndex,
AEndCol: Integer; FoldDesc: PChar; FoldDescLen: Integer);
var
c, i, j: Integer;
Line, Line2: Integer;
entry: TFoldExportEntry;
hl: TSynCustomFoldHighlighter;
ndinfo, ndinfo2: TSynFoldNodeInfo;
FoldDescEnd: PChar;
begin
if not(assigned(FHighLighter) and (FHighLighter is TSynCustomFoldHighlighter))
then exit;
hl := TSynCustomFoldHighlighter(FHighLighter);
FoldDescEnd := FoldDesc + FoldDescLen;
if AStartCol > 0 then
dec(AStartCol);
while true do begin
if FoldDesc + sizeof(TFoldExportEntry) > FoldDescEnd then
exit;
System.Move(FoldDesc^, entry, sizeof(TFoldExportEntry));
inc(FoldDesc, sizeof(TFoldExportEntry));
if entry.Line > 0 then
AStartCol := 0;
Line := AStartIndex + entry.Line;
if Line >= FLines.Count then
continue;
c := hl.FoldNodeInfoCount[Line, [sfaOpen]];
j := 0;
while j < c do begin
ndinfo := hl.FoldNodeInfo[Line, j, [sfaOpen]];
if ndinfo.LogXStart >= entry.LogX + AStartCol then
break;
inc(j);
end;
if (sfaInvalid in ndinfo.FoldAction) or
(ndinfo.LogXStart <> entry.LogX + AStartCol) or
(ndinfo.LogXEnd <> entry.LogX2 + AStartCol) or
//(ndinfo.FoldType <> entry.FType) or
(entry.ELine - entry.Line <> LengthForFoldAtTextIndex(Line, j))
then
continue;
Line2 := AStartIndex + entry.ELine;
if Line2 >= FLines.Count then
continue;
c := hl.FoldNodeInfoCount[Line2, [sfaClose]];
i := 0;
while i < c do begin
ndinfo2 := hl.FoldNodeInfo[Line2, i, [sfaClose]];
if ndinfo2.FoldLvlStart = ndinfo.FoldLvlEnd then break;
inc(i);
end;
if (sfaInvalid in ndinfo2.FoldAction) or
(ndinfo2.LogXStart <> entry.ELogX) or
(ndinfo2.LogXEnd <> entry.ELogX2)
then
continue;
FoldAtTextIndex(Line, j);
end;
end;
procedure TSynEditFoldedView.FoldAtTextIndex(AStartIndex : Integer;
ColIndex : Integer = -1; ColCount : Integer = 1; Skip: Boolean = False);
var
@ -2281,8 +2438,8 @@ begin
(hl.FoldCloseCount(aStartIndex) > 0) then begin
o := hl.FoldOpenCount(AStartIndex);
n := o;
for i := hl.FoldNodeInfoCount[aStartIndex] - 1 downto 0 do begin
nd := hl.FoldNodeInfo[aStartIndex, i];
for i := hl.FoldNodeInfoCount[aStartIndex, []] - 1 downto 0 do begin
nd := hl.FoldNodeInfo[aStartIndex, i, []];
if not(sfaFold in nd.FoldAction) then
continue;
t := nd.FoldGroup;

View File

@ -127,8 +127,8 @@ type
function GetFoldConfigCount: Integer; virtual;
procedure SetFoldConfig(Index: Integer; const AValue: Boolean); virtual;
function GetFoldNodeInfo(Line, Index: Integer): TSynFoldNodeInfo; virtual;
function GetFoldNodeInfoCount(Line: Integer): Integer; virtual;
function GetFoldNodeInfo(Line, Index: Integer; Filter: TSynFoldActions): TSynFoldNodeInfo; virtual;
function GetFoldNodeInfoCount(Line: Integer; Filter: TSynFoldActions): Integer; virtual;
property CodeFoldRange: TSynCustomHighlighterRange read FCodeFoldRange;
function GetRangeClass: TSynCustomHighlighterRangeClass; virtual;
function TopCodeFoldBlockType(DownIndex: Integer = 0): Pointer;
@ -161,8 +161,8 @@ type
function FoldLineLength(ALineIndex, FoldIndex: Integer): integer; virtual;
// All fold-nodes
property FoldNodeInfo[Line, Index: Integer]: TSynFoldNodeInfo read GetFoldNodeInfo;
property FoldNodeInfoCount[Line: Integer]: Integer read GetFoldNodeInfoCount;
property FoldNodeInfo[Line, Index: Integer; Filter: TSynFoldActions]: TSynFoldNodeInfo read GetFoldNodeInfo;
property FoldNodeInfoCount[Line: Integer; Filter: TSynFoldActions]: Integer read GetFoldNodeInfoCount;
procedure SetRange(Value: Pointer); override;
procedure ResetRange; override;
@ -337,7 +337,8 @@ begin
result := 0;
end;
function TSynCustomFoldHighlighter.GetFoldNodeInfoCount(Line: Integer): Integer;
function TSynCustomFoldHighlighter.GetFoldNodeInfoCount(Line: Integer;
Filter: TSynFoldActions): Integer;
begin
Result := 0;
end;
@ -356,7 +357,8 @@ procedure TSynCustomFoldHighlighter.SetFoldConfig(Index: Integer; const AValue:
begin
end;
function TSynCustomFoldHighlighter.GetFoldNodeInfo(Line, Index: Integer): TSynFoldNodeInfo;
function TSynCustomFoldHighlighter.GetFoldNodeInfo(Line, Index: Integer;
Filter: TSynFoldActions): TSynFoldNodeInfo;
begin
Result.FoldAction := [sfaInvalid];
end;

View File

@ -117,7 +117,7 @@ var
begin
repeat
inc(NIndex);
Result := HL.FoldNodeInfo[YIndex, NIndex];
Result := HL.FoldNodeInfo[YIndex, NIndex, []];
until (sfaInvalid in Result.FoldAction) or
(Result.FoldLvlEnd <= StartNode.FoldLvlStart);
if not (sfaInvalid in Result.FoldAction) then
@ -133,7 +133,7 @@ var
NIndex := -1;
repeat
inc(NIndex);
Result:= HL.FoldNodeInfo[YIndex, NIndex];
Result:= HL.FoldNodeInfo[YIndex, NIndex, []];
until (sfaInvalid in Result.FoldAction) or
(Result.FoldLvlEnd <= StartNode.FoldLvlStart);
if (Result.LogXEnd = 0) then
@ -145,7 +145,7 @@ var
begin
repeat
dec(NIndex);
Result := HL.FoldNodeInfo[YIndex, NIndex];
Result := HL.FoldNodeInfo[YIndex, NIndex, []];
until (sfaInvalid in Result.FoldAction) or
(Result.FoldLvlStart <= EndNode.FoldLvlEnd);
if not(sfaInvalid in Result.FoldAction) then
@ -156,10 +156,10 @@ var
dec(YIndex);
if YIndex < 0 then
exit;
NIndex := HL.FoldNodeInfoCount[YIndex];
NIndex := HL.FoldNodeInfoCount[YIndex, []];
repeat
dec(NIndex);
Result:= HL.FoldNodeInfo[YIndex, NIndex];
Result:= HL.FoldNodeInfo[YIndex, NIndex, []];
until (sfaInvalid in Result.FoldAction) or
(Result.FoldLvlStart <= EndNode.FoldLvlEnd);
end;
@ -172,7 +172,7 @@ var
i := NIndex;
repeat
dec(NIndex);
Result := HL.FoldNodeInfo[YIndex, NIndex];
Result := HL.FoldNodeInfo[YIndex, NIndex, []];
if (sfaMarkup in Result.FoldAction) and
(Result.LogXStart = OrigNode.LogXStart) and (Result.LogXEnd > 0)
then
@ -181,7 +181,7 @@ var
NIndex := i;
repeat
inc(NIndex);
Result := HL.FoldNodeInfo[YIndex, NIndex];
Result := HL.FoldNodeInfo[YIndex, NIndex, []];
if (sfaMarkup in Result.FoldAction) and
(Result.LogXStart = OrigNode.LogXStart) and (Result.LogXEnd > 0)
then
@ -212,14 +212,14 @@ begin
HL.CurrentLines := Lines;
i := 0;
repeat
Node1 := HL.FoldNodeInfo[y, i];
Node1 := HL.FoldNodeInfo[y, i, []];
inc(i);
until (sfaInvalid in Node1.FoldAction) or
((Node1.LogXEnd >= LogCaretXY.X - 1) and (Node1.LogXEnd > 0));
while not(Node1.FoldAction * [sfaInvalid, sfaMarkup] <> [])
and (Node1.LogXStart <= LogCaretXY.X - 1) do
begin
Node1 := HL.FoldNodeInfo[y, i];
Node1 := HL.FoldNodeInfo[y, i, []];
inc(i);
end;
if (Node1.LogXStart > LogCaretXY.X - 1) or not(sfaMarkup in Node1.FoldAction) then

View File

@ -47,8 +47,8 @@ uses
{$ELSE}
Windows,
{$ENDIF}
Classes, Graphics, Controls, SysUtils, SynEditMiscProcs, SynEditTypes,
SynEditTextBase;
Classes, Graphics, Controls, SysUtils, Clipbrd,
SynEditMiscProcs, SynEditTypes, SynEditTextBase;
type
@ -261,6 +261,58 @@ type
property Options: TSynSearchOptions write SetOptions;
end;
TSynClipboardStreamTag = type word;
{ TSynClipboardStream }
TSynClipboardStream = class
private
FMemStream: TMemoryStream;
FText: String;
FTextP: PChar;
FIsPlainText: Boolean;
function GetMemory: Pointer;
function GetSize: LongInt;
function GetSelectionMode: TSynSelectionMode;
procedure SetSelectionMode(const AValue: TSynSelectionMode);
procedure SetInternalText(const AValue: String);
procedure SetText(const AValue: String);
public
constructor Create;
destructor Destroy; override;
class function ClipboardFormatId: TClipboardFormat;
function CanReadFromClipboard(AClipboard: TClipboard): Boolean;
function ReadFromClipboard(AClipboard: TClipboard): Boolean;
function WriteToClipboard(AClipboard: TClipboard): Boolean;
procedure Clear;
function HasTag(ATag: TSynClipboardStreamTag): Boolean;
function GetTagPointer(ATag: TSynClipboardStreamTag): Pointer;
function GetTagLen(ATag: TSynClipboardStreamTag): Integer;
// No check for duplicates
Procedure AddTag(ATag: TSynClipboardStreamTag; Location: Pointer; Len: Integer);
// Currently Each method (or each method of a pair) must be assigned only ONCE
property TextP: PChar read FTextP;
property Text: String write SetText;
property InternalText: String write SetInternalText;
property SelectionMode: TSynSelectionMode read GetSelectionMode write SetSelectionMode;
property Memory: Pointer read GetMemory;
property Size: LongInt read GetSize;
end;
const
synClipTagText = TSynClipboardStreamTag(1);
synClipTagExtText = TSynClipboardStreamTag(2);
synClipTagMode = TSynClipboardStreamTag(3);
synClipTagFold = TSynClipboardStreamTag(4);
implementation
{ TSynSelectedColor }
@ -746,5 +798,181 @@ begin
FOwner.Delete(FOwner.IndexOf(self));
end;
{ TSynClipboardStream }
function TSynClipboardStream.GetMemory: Pointer;
begin
Result := FMemStream.Memory;
end;
function TSynClipboardStream.GetSize: LongInt;
begin
Result := FMemStream.Size;
end;
procedure TSynClipboardStream.SetInternalText(const AValue: String);
begin
FIsPlainText := False;
// Text, if we don't need CF_TEXT // Must include a zero byte
AddTag(synClipTagText, @AValue[1], length(AValue) + 1);
end;
function TSynClipboardStream.GetSelectionMode: TSynSelectionMode;
var
PasteMode: ^TSynSelectionMode;
begin
PasteMode := GetTagPointer(synClipTagMode);
if PasteMode = nil then
Result := smNormal
else
Result := PasteMode^;
end;
procedure TSynClipboardStream.SetSelectionMode(const AValue: TSynSelectionMode);
begin
AddTag(synClipTagMode, @AValue, SizeOf(TSynSelectionMode));
end;
procedure TSynClipboardStream.SetText(const AValue: String);
var
SLen: Integer;
begin
FIsPlainText := True;
FText := AValue;
SLen := length(FText);
AddTag(synClipTagExtText, @SLen, SizeOf(Integer));
end;
constructor TSynClipboardStream.Create;
begin
FMemStream := TMemoryStream.Create;
end;
destructor TSynClipboardStream.Destroy;
begin
FreeAndNil(FMemStream);
inherited Destroy;
end;
class function TSynClipboardStream.ClipboardFormatId: TClipboardFormat;
const
SYNEDIT_CLIPBOARD_FORMAT_TAGGED = 'Application/X-Laz-SynEdit-Tagged';
Format: UINT = 0;
begin
if Format = 0 then
Format := ClipboardRegisterFormat(SYNEDIT_CLIPBOARD_FORMAT_TAGGED);
Result := Format;
end;
function TSynClipboardStream.CanReadFromClipboard(AClipboard: TClipboard): Boolean;
begin
Result := AClipboard.HasFormat(ClipboardFormatId);
end;
function TSynClipboardStream.ReadFromClipboard(AClipboard: TClipboard): Boolean;
var
ip: PInteger;
len: LongInt;
begin
Clear;
Result := AClipboard.GetFormat(ClipboardFormatId, FMemStream);
// Check for embedded text
FTextP := GetTagPointer(synClipTagText);
if FTextP <> nil then begin
len := GetTagLen(synClipTagText);
if len > 0 then
(FTextP + len - 1)^ := #0
else
FTextP := nil;
end;
// Normal text
if (FTextP = nil) and AClipboard.HasFormat(CF_TEXT) then begin
FText:= AClipboard.AsText;
if FText <> '' then begin
FTextP := @FText[1];
ip := GetTagPointer(synClipTagExtText);
if (length(FText) = 0) or (ip = nil) or (length(FText) <> ip^) then
FIsPlainText := True;
end;
end;
end;
function TSynClipboardStream.WriteToClipboard(AClipboard: TClipboard): Boolean;
begin
if FIsPlainText and (FText <> '') then begin
Clipboard.AsText:= FText;
if not Clipboard.HasFormat(CF_TEXT) then
raise ESynEditError.Create('Clipboard copy operation failed: HasFormat');
end;
Result := AClipboard.AddFormat(ClipboardFormatId, FMemStream.Memory^, FMemStream.Size);
end;
procedure TSynClipboardStream.Clear;
begin
FMemStream.Clear;
FIsPlainText := False;
end;
function TSynClipboardStream.HasTag(ATag: TSynClipboardStreamTag): Boolean;
begin
Result := GetTagPointer(ATag) <> nil;
end;
function TSynClipboardStream.GetTagPointer(ATag: TSynClipboardStreamTag): Pointer;
var
ctag, mend: Pointer;
begin
Result := nil;
if FIsPlainText then
exit;
ctag := FMemStream.Memory;
mend := ctag + FMemStream.Size;
while (result = nil) and
(ctag + SizeOf(TSynClipboardStreamTag) + SizeOf(Integer) <= mend) do
begin
if TSynClipboardStreamTag(ctag^) = ATag then begin
Result := ctag + SizeOf(TSynClipboardStreamTag) + SizeOf(Integer)
end else begin
inc(ctag, SizeOf(TSynClipboardStreamTag));
inc(ctag, PInteger(ctag)^);
inc(ctag, SizeOf(Integer));
end;
end;
if (Result <> nil) and
(ctag + Integer((ctag + SizeOf(TSynClipboardStreamTag))^) > mend) then
begin
Result := nil;
raise ESynEditError.Create('Clipboard read operation failed, data corrupt');
end;
end;
function TSynClipboardStream.GetTagLen(ATag: TSynClipboardStreamTag): Integer;
var
p: PInteger;
begin
Result := 0;
p := GetTagPointer(ATag);
if p = nil then
exit;
dec(p, 1);
Result := p^;
end;
procedure TSynClipboardStream.AddTag(ATag: TSynClipboardStreamTag; Location: Pointer;
Len: Integer);
var
msize: Int64;
mpos: Pointer;
begin
msize := FMemStream.Size;
FMemStream.Size := msize + Len + SizeOf(TSynClipboardStreamTag) + SizeOf(Integer);
mpos := FMemStream.Memory + msize;
TSynClipboardStreamTag(mpos^) := ATag;
inc(mpos, SizeOf(TSynClipboardStreamTag));
Integer(mpos^) := Len;
inc(mpos, SizeOf(Integer));
System.Move(Location^, mpos^, Len);
end;
end.

View File

@ -40,6 +40,8 @@ unit SynEditTypes;
{$I synedit.inc}
interface
uses
SysUtils;
const
TSynSpecialChars = [#128..#255]; // MG: special chars. Meaning depends on system encoding/codepage.
@ -49,6 +51,8 @@ const
')', '{', '}', '@', '^', '-', '=', '+', '*', '/', '\', '|','<','>'];
type
ESynEditError = class(Exception);
TSynIdentChars = set of char;
{$IFDEF SYN_LAZARUS}

View File

@ -418,8 +418,8 @@ type
procedure StartCustomCodeFoldBlock(ABlockType: TPascalCodeFoldBlockType);
procedure EndCustomCodeFoldBlock(ABlockType: TPascalCodeFoldBlockType);
function GetFoldNodeInfo(Line, Index: Integer): TSynFoldNodeInfo; override;
function GetFoldNodeInfoCount(Line: Integer): Integer; override;
function GetFoldNodeInfo(Line, Index: Integer; Filter: TSynFoldActions): TSynFoldNodeInfo; override;
function GetFoldNodeInfoCount(Line: Integer; Filter: TSynFoldActions): Integer; override;
property PasCodeFoldRange: TSynPasSynRange read GetPasCodeFoldRange;
function TopPascalCodeFoldBlockType
@ -2555,11 +2555,11 @@ begin
CompilerMode := PasCodeFoldRange.Mode;
fRange := TRangeStates(Integer(PtrUInt(CodeFoldRange.RangeType)));
FNodeInfoLine := -1;
FSynPasRangeInfo := TSynHighlighterPasRangeList(CurrentRanges).PasRangeInfo[LineIndex-1];
end;
procedure TSynPasSyn.StartAtLineIndex(LineNumber: Integer);
begin
FSynPasRangeInfo := TSynHighlighterPasRangeList(CurrentRanges).PasRangeInfo[LineNumber];
inherited StartAtLineIndex(LineNumber);
end;
@ -2671,10 +2671,10 @@ var
i, j: LongInt;
act: TSynFoldActions;
begin
j := GetFoldNodeInfoCount(ALineIndex);
j := GetFoldNodeInfoCount(ALineIndex, []);
i := 0;
while (i < j) and (FoldIndex > 0) do begin
act := GetFoldNodeInfo(ALineIndex, i).FoldAction;
act := GetFoldNodeInfo(ALineIndex, i, []).FoldAction;
if (UseCloseNodes and (sfaClose in act)) or
((not UseCloseNodes) and (sfaOpen in act)) then
dec(FoldIndex);
@ -2683,7 +2683,7 @@ begin
if i = j then
exit(-1);
// 0 is used for "all"
case TPascalCodeFoldBlockType(PtrUInt(GetFoldNodeInfo(ALineIndex, i).FoldType)) of
case TPascalCodeFoldBlockType(PtrUInt(GetFoldNodeInfo(ALineIndex, i, []).FoldType)) of
cfbtRegion:
Result := 2;
cfbtIfDef:
@ -2834,12 +2834,22 @@ begin
Node.FoldType := Pointer(PtrInt(ABlockType));
case ABlockType of
cfbtRegion:
node.FoldGroup := 2;
begin
node.FoldGroup := 2;
Node.FoldLvlStart := FSynPasRangeInfo.EndLevelRegion;
end;
cfbtIfDef:
node.FoldGroup := 3;
begin
node.FoldGroup := 3;
Node.FoldLvlStart := FSynPasRangeInfo.EndLevelIfDef;
end;
else
node.FoldGroup := 1;
begin
node.FoldGroup := 1;
Node.FoldLvlStart := CurrentCodeFoldBlockLevel;
end;
end;
Node.FoldLvlEnd := Node.FoldLvlStart + EndOffs;
if ABlockType in PascalWordTrippletRanges then
Node.FoldAction := [sfaMarkup]
else
@ -2869,7 +2879,7 @@ begin
if not FFoldConfig[ABlockType] then exit;
if FCatchNodeInfo then begin // exclude subblocks, because they do not increase the foldlevel yet
GrowNodeInfoList;
InitNode(FNodeInfoList[FNodeInfoCount], +1, ABlockType);
InitNode(FNodeInfoList[FNodeInfoCount], -1, ABlockType);
FNodeInfoList[FNodeInfoCount].FoldAction :=
FNodeInfoList[FNodeInfoCount].FoldAction + [sfaClose, sfaFold];
inc(FNodeInfoCount);
@ -3214,7 +3224,8 @@ begin
- ord(low(TSynPasDividerDrawLocation)) + 1;
end;
function TSynPasSyn.GetFoldNodeInfo(Line, Index: Integer): TSynFoldNodeInfo;
function TSynPasSyn.GetFoldNodeInfo(Line, Index: Integer;
Filter: TSynFoldActions): TSynFoldNodeInfo;
var
i: LongInt;
begin
@ -3234,16 +3245,31 @@ begin
end;
if (index < 0) or (index >= FNodeInfoCount) then
Result := inherited GetFoldNodeInfo(Line, Index)
Result := inherited GetFoldNodeInfo(Line, Index, [])
else
Result := FNodeInfoList[Index];
if Filter = [] then
Result := FNodeInfoList[Index]
else
for i := 0 to FNodeInfoCount - 1 do
if FNodeInfoList[i].FoldAction * Filter = Filter then begin
Result := FNodeInfoList[i];
if Index = 0 then break;
dec(Index);
end;
end;
function TSynPasSyn.GetFoldNodeInfoCount(Line: Integer): Integer;
function TSynPasSyn.GetFoldNodeInfoCount(Line: Integer;
Filter: TSynFoldActions): Integer;
var
i: Integer;
begin
if FNodeInfoLine <> Line then
GetFoldNodeInfo(Line, 0);
GetFoldNodeInfo(Line, 0, []);
Result := FNodeInfoCount;
if Filter <> [] then
for i := 0 to FNodeInfoCount - 1 do
if FNodeInfoList[i].FoldAction * Filter <> Filter then
dec(Result);
end;
function TSynPasSyn.GetRangeClass: TSynCustomHighlighterRangeClass;

View File

@ -2052,6 +2052,8 @@ begin
SynEditOptName := 'AlwaysVisibleCaret';
eoEnhanceEndKey:
SynEditOptName := 'EnhanceEndKey';
eoFoldedCopyPaste:
SynEditOptName := 'FoldedCopyPaste';
else
SynEditOptName := '';
end;
@ -2302,6 +2304,8 @@ begin
SynEditOptName := 'AlwaysVisibleCaret';
eoEnhanceEndKey:
SynEditOptName := 'EnhanceEndKey';
eoFoldedCopyPaste:
SynEditOptName := 'FoldedCopyPaste';
else
SynEditOptName := '';
end;

View File

@ -74,6 +74,7 @@ begin
// copying
Items.Add(dlgFindTextatCursor);
Items.Add(dlgCopyWordAtCursorOnCopyNone);
Items.Add(dlgCopyPasteKeepFolds);
end;
EditorTrimSpaceTypeCheckBox.Items.Add(dlgTrimSpaceTypeLeaveLine);
EditorTrimSpaceTypeCheckBox.Items.Add(dlgTrimSpaceTypeEditLine);
@ -94,6 +95,7 @@ begin
Checked[Items.IndexOf(dlgShowGutterHints)] := ShowGutterHints;
Checked[Items.IndexOf(dlgFindTextatCursor)] := FindTextAtCursor;
Checked[Items.IndexOf(dlgCopyWordAtCursorOnCopyNone)] := CopyWordAtCursorOnCopyNone;
Checked[Items.IndexOf(dlgCopyPasteKeepFolds)] := eoFoldedCopyPaste in SynEditOptions2;
end;
EditorTrimSpaceTypeCheckBox.ItemIndex := ord(TrimSpaceType);
end;
@ -127,6 +129,12 @@ begin
ShowGutterHints := CheckGroupItemChecked(EditorOptionsGroupBox, dlgShowGutterHints);
FindTextAtCursor := CheckGroupItemChecked(EditorOptionsGroupBox, dlgFindTextatCursor);
TrimSpaceType := TSynEditStringTrimmingType(EditorTrimSpaceTypeCheckBox.ItemIndex);
if EditorOptionsGroupBox.Checked[EditorOptionsGroupBox.Items.IndexOf
(dlgCopyPasteKeepFolds)]
then
SynEditOptions2 := SynEditOptions2 + [eoFoldedCopyPaste]
else
SynEditOptions2 := SynEditOptions2 - [eoFoldedCopyPaste];
end;
end;

View File

@ -1237,6 +1237,7 @@ resourcestring
dlgTrimSpaceTypeEditLine = 'Line Edited';
dlgTrimSpaceTypeCaretMove = 'Caret or Edit';
dlgTrimSpaceTypePosOnly = 'Position Only';
dlgCopyPasteKeepFolds = 'Copy/Paste with fold info';
dlgUndoLimit = 'Undo limit';
dlgTabWidths = 'Tab widths';
dlgMarginGutter = 'Margin and gutter';