~ubuntu-branches/ubuntu/saucy/lazarus/saucy

« back to all changes in this revision

Viewing changes to components/synedit/synedittextbase.pas

  • Committer: Package Import Robot
  • Author(s): Paul Gevers, Abou Al Montacir, Bart Martens, Paul Gevers
  • Date: 2013-06-08 14:12:17 UTC
  • mfrom: (1.1.9)
  • Revision ID: package-import@ubuntu.com-20130608141217-7k0cy9id8ifcnutc
Tags: 1.0.8+dfsg-1
[ Abou Al Montacir ]
* New upstream major release and multiple maintenace release offering many
  fixes and new features marking a new milestone for the Lazarus development
  and its stability level.
  - The detailed list of changes can be found here:
    http://wiki.lazarus.freepascal.org/Lazarus_1.0_release_notes
    http://wiki.lazarus.freepascal.org/Lazarus_1.0_fixes_branch
* LCL changes:
  - LCL is now a normal package.
      + Platform independent parts of the LCL are now in the package LCLBase
      + LCL is automatically recompiled when switching the target platform,
        unless pre-compiled binaries for this target are already installed.
      + No impact on existing projects.
      + Linker options needed by LCL are no more added to projects that do
        not use the LCL package.
  - Minor changes in LCL basic classes behaviour
      + TCustomForm.Create raises an exception if a form resource is not
        found.
      + TNotebook and TPage: a new implementation of these classes was added.
      + TDBNavigator: It is now possible to have focusable buttons by setting
        Options = [navFocusableButtons] and TabStop = True, useful for
        accessibility and for devices with neither mouse nor touch screen.
      + Names of TControlBorderSpacing.GetSideSpace and GetSpace were swapped
        and are now consistent. GetSideSpace = Around + GetSpace.
      + TForm.WindowState=wsFullscreen was added
      + TCanvas.TextFitInfo was added to calculate how many characters will
        fit into a specified Width. Useful for word-wrapping calculations.
      + TControl.GetColorResolvingParent and
        TControl.GetRGBColorResolvingParent were added, simplifying the work
        to obtain the final color of the control while resolving clDefault
        and the ParentColor.
      + LCLIntf.GetTextExtentExPoint now has a good default implementation
        which works in any platform not providing a specific implementation.
        However, Widgetset specific implementation is better, when available.
      + TTabControl was reorganized. Now it has the correct class hierarchy
        and inherits from TCustomTabControl as it should.
  - New unit in the LCL:
      + lazdialogs.pas: adds non-native versions of various native dialogs,
        for example TLazOpenDialog, TLazSaveDialog, TLazSelectDirectoryDialog.
        It is used by widgetsets which either do not have a native dialog, or
        do not wish to use it because it is limited. These dialogs can also be
        used by user applications directly.
      + lazdeviceapis.pas: offers an interface to more hardware devices such
        as the accelerometer, GPS, etc. See LazDeviceAPIs
      + lazcanvas.pas: provides a TFPImageCanvas descendent implementing
        drawing in a LCL-compatible way, but 100% in Pascal.
      + lazregions.pas. LazRegions is a wholly Pascal implementation of
        regions for canvas clipping, event clipping, finding in which control
        of a region tree one an event should reach, for drawing polygons, etc.
      + customdrawncontrols.pas, customdrawndrawers.pas,
        customdrawn_common.pas, customdrawn_android.pas and
        customdrawn_winxp.pas: are the Lazarus Custom Drawn Controls -controls
        which imitate the standard LCL ones, but with the difference that they
        are non-native and support skinning.
  - New APIs added to the LCL to improve support of accessibility software
    such as screen readers.
* IDE changes:
  - Many improvments.
  - The detailed list of changes can be found here:
    http://wiki.lazarus.freepascal.org/New_IDE_features_since#v1.0_.282012-08-29.29
    http://wiki.lazarus.freepascal.org/Lazarus_1.0_release_notes#IDE_Changes
* Debugger / Editor changes:
  - Added pascal sources and breakpoints to the disassembler
  - Added threads dialog.
* Components changes:
  - TAChart: many fixes and new features
  - CodeTool: support Delphi style generics and new syntax extensions.
  - AggPas: removed to honor free licencing. (Closes: Bug#708695)
[Bart Martens]
* New debian/watch file fixing issues with upstream RC release.
[Abou Al Montacir]
* Avoid changing files in .pc hidden directory, these are used by quilt for
  internal purpose and could lead to surprises during build.
[Paul Gevers]
* Updated get-orig-source target and it compinion script orig-tar.sh so that they
  repack the source file, allowing bug 708695 to be fixed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
unit SynEditTextBase;
23
23
 
24
24
{$I synedit.inc}
 
25
{$IFOPT C+}
 
26
  {$DEFINE AssertSynMemIndex}
 
27
{$ENDIF}
 
28
{$IFDEF SynAssert}
 
29
  {$DEFINE AssertSynMemIndex}
 
30
{$ENDIF}
 
31
{$IFDEF SynUndoDebug}
 
32
  {$Define SynUndoDebugItems}
 
33
  {$Define SynUndoDebugCalls}
 
34
{$ENDIF}
 
35
 
25
36
 
26
37
interface
27
38
 
29
40
  Classes, SysUtils, LCLProc, SynEditMiscProcs, SynEditKeyCmds;
30
41
 
31
42
type
32
 
  TSynEditStrings = class;
33
 
 
34
 
  TStringListLineCountEvent = procedure(Sender: TSynEditStrings;
35
 
                                        Index, Count: Integer) of object;
36
 
  TStringListLineEditEvent = procedure(Sender: TSynEditStrings;
37
 
                                       LinePos, BytePos, Count, LineBrkCnt: Integer;
38
 
                                       Text: String) of object;
39
 
 
40
 
  TSynEditNotifyReason = ( // TStringListLineCountEvent
41
 
                           senrLineCount,        // Lines Inserted or Deleted (if not empty, they will trigger senrLineChange too)
42
 
                           senrLineChange,       // Lines modified (also triggered by senrEditAction)
43
 
                           senrHighlightChanged, // used by Highlighter (invalidate and fold checks needed)
44
 
                           // TStringListLineEditEvent
45
 
                           senrEditAction,       // EditInsert, EditDelete, EditLineBreak, ...
46
 
                           // TNotifyEvent
47
 
                           senrCleared,
48
 
                           senrUndoRedoAdded,
49
 
                           senrModifiedChanged,  // The modified flag was changed
50
 
                           // Paintlocks are managed by SynEdit, but need distribution to shared edits
51
 
                           senrIncOwnedPaintLock, // Inform other SynEdits (ForeignPaintLock)
52
 
                           senrDecOwnedPaintLock,
53
 
                           senrIncPaintLock,      // Actual PaintLock
54
 
                           senrDecPaintLock,
55
 
                           senrAfterIncPaintLock, // For plugins, etc...
56
 
                           senrBeforeDecPaintLock,
57
 
                           senrTextBufferChanging, // About to change
58
 
                           senrTextBufferChanged
59
 
                          );
60
 
 
61
 
  TPhysicalCharWidths = Array of Shortint;
62
 
  TPhysicalCharWidth = ShortInt;
63
 
  PPhysicalCharWidth = ^TPhysicalCharWidth;
64
43
 
65
44
  TSynEditUndoList = class;
66
45
  TSynEditUndoItem = class;
129
108
             read GetStorageMems write SetStorageMems; default;
130
109
  end;
131
110
 
132
 
  { TSynLogicalPhysicalConvertor }
133
 
const
134
 
  SYN_LP_MIN_ALLOC = 1024; // Keep at least n*SizeOf(TPhysicalCharWidths) allocated
135
 
type
136
 
  TSynLogicalPhysicalConvertor = class
137
 
  private
138
 
    FLines: TSynEditStrings;
139
 
    FCurrentWidths: TPhysicalCharWidths;
140
 
    FCurrentWidthsLen, FCurrentWidthsAlloc: Integer;
141
 
    FCurrentLine: Integer;
142
 
    FTextChangeStamp, FViewChangeStamp: Int64;
143
 
    // TODOtab-width
144
 
    procedure PrepareWidthsForLine(AIndex: Integer; AForce: Boolean = False);
145
 
  public
146
 
    constructor Create(ALines: TSynEditStrings);
147
 
    destructor Destroy; override;
148
 
    // Line is 0-based // Column is 1-based
149
 
    function PhysicalToLogical(AIndex, AColumn: Integer): Integer;
150
 
    function PhysicalToLogical(AIndex, AColumn: Integer; out AColOffset: Integer): Integer;
151
 
    // ACharPos 1=before 1st char
152
 
    function LogicalToPhysical(AIndex, ABytePos: Integer): Integer;
153
 
    function LogicalToPhysical(AIndex, ABytePos: Integer; var AColOffset: Integer): Integer;
154
 
  end;
155
 
 
156
111
  { TSynEditStringsBase }
157
112
 
158
113
  TSynEditStringsBase = class(TStrings)
166
121
    property Ranges[Index: Pointer]: TSynManagedStorageMem read GetRange write PutRange;
167
122
  end;
168
123
 
169
 
  { TSynEditStrings }
170
 
 
171
 
  TSynEditStrings = class(TSynEditStringsBase)
172
 
  private
173
 
    FSenderUpdateCount: Integer;
174
 
    FLogPhysConvertor :TSynLogicalPhysicalConvertor;
175
 
  protected
176
 
    FIsUtf8: Boolean;
177
 
    function  GetIsUtf8 : Boolean; virtual;
178
 
    procedure SetIsUtf8(const AValue : Boolean); virtual;
179
 
 
180
 
    function GetExpandedString(Index: integer): string; virtual; abstract;
181
 
    function GetLengthOfLongestLine: integer; virtual; abstract;
182
 
    procedure SetTextStr(const Value: string); override;
183
 
    function GetTextChangeStamp: int64; virtual; abstract;
184
 
    function GetViewChangeStamp: int64; virtual;
185
 
 
186
 
    function GetUndoList: TSynEditUndoList; virtual; abstract;
187
 
    function GetRedoList: TSynEditUndoList; virtual; abstract;
188
 
    function GetCurUndoList: TSynEditUndoList; virtual; abstract;
189
 
    procedure SetIsUndoing(const AValue: Boolean); virtual; abstract;
190
 
    function  GetIsUndoing: Boolean; virtual; abstract;
191
 
    procedure SetIsRedoing(const AValue: Boolean); virtual; abstract;
192
 
    function  GetIsRedoing: Boolean; virtual; abstract;
193
 
    procedure IgnoreSendNotification(AReason: TSynEditNotifyReason;
194
 
                                     ReEnable: Boolean); virtual; abstract;
195
 
 
196
 
    procedure SetUpdateState(Updating: Boolean); override;
197
 
    procedure SetUpdateState(Updating: Boolean; Sender: TObject); virtual; abstract;
198
 
 
199
 
    procedure DoGetPhysicalCharWidths(Line: PChar; LineLen, Index: Integer; PWidths: PPhysicalCharWidth); virtual; abstract;
200
 
  public
201
 
    constructor Create;
202
 
    destructor Destroy; override;
203
 
    procedure BeginUpdate(Sender: TObject); overload;
204
 
    procedure EndUpdate(Sender: TObject); overload;
205
 
    function  IsUpdating: Boolean;
206
 
    procedure DeleteLines(Index, NumLines: integer); virtual; abstract;
207
 
    procedure InsertLines(Index, NumLines: integer); virtual; abstract;
208
 
    procedure InsertStrings(Index: integer; NewStrings: TStrings); virtual; abstract;
209
 
 
210
 
    procedure AddGenericHandler(AReason: TSynEditNotifyReason;
211
 
                AHandler: TMethod); virtual; abstract;
212
 
    procedure AddChangeHandler(AReason: TSynEditNotifyReason;
213
 
                AHandler: TStringListLineCountEvent);
214
 
    procedure AddNotifyHandler(AReason: TSynEditNotifyReason;
215
 
                AHandler: TNotifyEvent);
216
 
 
217
 
    procedure RemoveGenericHandler(AReason: TSynEditNotifyReason;
218
 
                AHandler: TMethod); virtual; abstract;
219
 
    procedure RemoveChangeHandler(AReason: TSynEditNotifyReason;
220
 
                AHandler: TStringListLineCountEvent);
221
 
    procedure RemoveNotifyHandler(AReason: TSynEditNotifyReason;
222
 
                AHandler: TNotifyEvent);
223
 
 
224
 
    procedure AddEditHandler(AHandler: TStringListLineEditEvent);
225
 
    procedure RemoveEditHandler(AHandler: TStringListLineEditEvent);
226
 
    procedure SendHighlightChanged(aIndex, aCount: Integer); override;
227
 
    procedure SendNotification(AReason: TSynEditNotifyReason;
228
 
                ASender: TSynEditStrings; aIndex, aCount: Integer;
229
 
                aBytePos: Integer = -1; aLen: Integer = 0;
230
 
                aTxt: String = ''); virtual; abstract;
231
 
    procedure SendNotification(AReason: TSynEditNotifyReason;
232
 
                ASender: TObject); virtual; abstract;
233
 
   procedure FlushNotificationCache; virtual; abstract;
234
 
  public
235
 
    function GetPhysicalCharWidths(Index: Integer): TPhysicalCharWidths;
236
 
    function GetPhysicalCharWidths(Line: PChar; LineLen, Index: Integer): TPhysicalCharWidths;
237
 
    // Byte to Char
238
 
    function LogicalToPhysicalPos(const p: TPoint): TPoint;
239
 
    function LogicalToPhysicalCol(const Line: String;
240
 
                                  Index, LogicalPos: integer): integer; virtual;
241
 
    // Char to Byte
242
 
    function PhysicalToLogicalPos(const p: TPoint): TPoint;
243
 
    function PhysicalToLogicalCol(const Line: string;
244
 
                                  Index, PhysicalPos: integer): integer; virtual;
245
 
    property LogPhysConvertor :TSynLogicalPhysicalConvertor read FLogPhysConvertor;
246
 
  public
247
 
    procedure EditInsert(LogX, LogY: Integer; AText: String); virtual; abstract;
248
 
    function  EditDelete(LogX, LogY, ByteLen: Integer): String; virtual; abstract;
249
 
    procedure EditLineBreak(LogX, LogY: Integer); virtual; abstract;
250
 
    procedure EditLineJoin(LogY: Integer; FillText: String = ''); virtual; abstract;
251
 
    procedure EditLinesInsert(LogY, ACount: Integer; AText: String = ''); virtual; abstract;
252
 
    procedure EditLinesDelete(LogY, ACount: Integer); virtual; abstract;
253
 
    procedure EditUndo(Item: TSynEditUndoItem); virtual; abstract;
254
 
    procedure EditRedo(Item: TSynEditUndoItem); virtual; abstract;
255
 
    property UndoList: TSynEditUndoList read GetUndoList;
256
 
    property RedoList: TSynEditUndoList read GetRedoList;
257
 
    property CurUndoList: TSynEditUndoList read GetCurUndoList; // Re or Undo (Redo while undoing)
258
 
    property IsUndoing: Boolean read GetIsUndoing write SetIsUndoing;
259
 
    property IsRedoing: Boolean read GetIsRedoing write SetIsRedoing;
260
 
  public
261
 
    property TextChangeStamp: int64 read GetTextChangeStamp;
262
 
    property ViewChangeStamp: int64 read GetViewChangeStamp; // tabs-size, trailing-spaces, ...
263
 
    property ExpandedStrings[Index: integer]: string read GetExpandedString;
264
 
    property LengthOfLongestLine: integer read GetLengthOfLongestLine;
265
 
    property IsUtf8: Boolean read GetIsUtf8 write SetIsUtf8;
266
 
  end;
267
 
 
268
 
  { TSynEditStringsLinked }
269
 
 
270
 
  TSynEditStringsLinked = class(TSynEditStrings)
271
 
  protected
272
 
    fSynStrings: TSynEditStrings;
273
 
 
274
 
    function  GetIsUtf8 : Boolean;  override;
275
 
    procedure SetIsUtf8(const AValue : Boolean);  override;
276
 
    function GetTextChangeStamp: int64; override;
277
 
    function GetViewChangeStamp: int64; override;
278
 
 
279
 
    function GetRange(Index: Pointer): TSynManagedStorageMem; override;
280
 
    procedure PutRange(Index: Pointer; const ARange: TSynManagedStorageMem); override;
281
 
 
282
 
    function GetExpandedString(Index: integer): string; override;
283
 
    function GetLengthOfLongestLine: integer; override;
284
 
 
285
 
    procedure IgnoreSendNotification(AReason: TSynEditNotifyReason;
286
 
                                     IncIgnore: Boolean); override;
287
 
    function GetUndoList: TSynEditUndoList; override;
288
 
    function GetRedoList: TSynEditUndoList; override;
289
 
    function GetCurUndoList: TSynEditUndoList; override;
290
 
    procedure SetIsUndoing(const AValue: Boolean); override;
291
 
    function  GetIsUndoing: Boolean; override;
292
 
    procedure SetIsRedoing(const AValue: Boolean); override;
293
 
    function  GetIsRedoing: Boolean; override;
294
 
  protected
295
 
    function GetCount: integer; override;
296
 
    function GetCapacity: integer;
297
 
      {$IFDEF SYN_COMPILER_3_UP} override; {$ELSE} virtual; {$ENDIF}
298
 
    procedure SetCapacity(NewCapacity: integer);
299
 
      {$IFDEF SYN_COMPILER_3_UP} override; {$ELSE} virtual; {$ENDIF}
300
 
    function  Get(Index: integer): string; override;
301
 
    function  GetObject(Index: integer): TObject; override;
302
 
    procedure Put(Index: integer; const S: string); override;
303
 
    procedure PutObject(Index: integer; AObject: TObject); override;
304
 
 
305
 
    procedure SetUpdateState(Updating: Boolean; Sender: TObject); override;
306
 
    procedure DoGetPhysicalCharWidths(Line: PChar; LineLen, Index: Integer; PWidths: PPhysicalCharWidth); override;
307
 
  public
308
 
    constructor Create(ASynStringSource: TSynEditStrings);
309
 
 
310
 
    function Add(const S: string): integer; override;
311
 
    procedure AddStrings(AStrings: TStrings); override;
312
 
    procedure Clear; override;
313
 
    procedure Delete(Index: integer); override;
314
 
    procedure DeleteLines(Index, NumLines: integer);  override;
315
 
    procedure Insert(Index: integer; const S: string); override;
316
 
    procedure InsertLines(Index, NumLines: integer); override;
317
 
    procedure InsertStrings(Index: integer; NewStrings: TStrings); override;
318
 
    function  GetPChar(ALineIndex: Integer; out ALen: Integer): PChar; override; // experimental
319
 
 
320
 
    procedure AddGenericHandler(AReason: TSynEditNotifyReason;
321
 
                AHandler: TMethod); override;
322
 
    procedure RemoveGenericHandler(AReason: TSynEditNotifyReason;
323
 
                AHandler: TMethod); override;
324
 
    procedure SendNotification(AReason: TSynEditNotifyReason;
325
 
                ASender: TSynEditStrings; aIndex, aCount: Integer;
326
 
                aBytePos: Integer = -1; aLen: Integer = 0;
327
 
                aTxt: String = ''); override;
328
 
    procedure SendNotification(AReason: TSynEditNotifyReason;
329
 
                ASender: TObject); override;
330
 
   procedure FlushNotificationCache; override;
331
 
 
332
 
    //function GetPhysicalCharWidths(Line: PChar; LineLen, Index: Integer): TPhysicalCharWidths; override;
333
 
    property NextLines: TSynEditStrings read fSynStrings write fSynStrings;
334
 
  public
335
 
    // LogX, LogY are 1-based
336
 
    procedure EditInsert(LogX, LogY: Integer; AText: String); override;
337
 
    function  EditDelete(LogX, LogY, ByteLen: Integer): String; override;
338
 
    procedure EditLineBreak(LogX, LogY: Integer); override;
339
 
    procedure EditLineJoin(LogY: Integer; FillText: String = ''); override;
340
 
    procedure EditLinesInsert(LogY, ACount: Integer; AText: String = ''); override;
341
 
    procedure EditLinesDelete(LogY, ACount: Integer); override;
342
 
    procedure EditUndo(Item: TSynEditUndoItem); override;
343
 
    procedure EditRedo(Item: TSynEditUndoItem); override;
344
 
  end;
345
 
 
346
124
  { TSynEditUndoItem }
347
125
 
348
126
  TSynEditUndoItem = class(TObject)
411
189
    procedure SetCurrentReason(const AValue: TSynEditorCommand);
412
190
    procedure SetMaxUndoActions(Value: integer);
413
191
  public
 
192
    {$IFDEF SynUndoDebugCalls}
 
193
    DebugName: string;
 
194
    {$ENDIF}
414
195
    constructor Create;
415
196
    destructor Destroy; override;
416
197
    procedure AddChange(AChange: TSynEditUndoItem);
427
208
    function RealCount: Integer;
428
209
    function IsTopMarkedAsUnmodified: boolean;
429
210
    function UnModifiedMarkerExists: boolean;
 
211
    {$IFDEF SynUndoDebugBeginEnd}
 
212
    property InGroupCount: integer read FInGroupCount;
 
213
    {$ENDIF}
430
214
  public
431
215
    property CanUndo: boolean read GetCanUndo;
432
216
    property FullUndoImpossible: boolean read fFullUndoImposible;
463
247
  raise ESynEditStorageMem.CreateFmt(SListIndexOutOfBounds, [Index]);
464
248
end;
465
249
 
466
 
{ TSynLogicalPhysicalConvertor }
467
 
 
468
 
procedure TSynLogicalPhysicalConvertor.PrepareWidthsForLine(AIndex: Integer;
469
 
  AForce: Boolean);
470
 
var
471
 
  LineLen: Integer;
472
 
  Line: PChar;
473
 
//const dbg_cnt: integer = 0;
474
 
begin
475
 
  if (not AForce) and (FCurrentLine = AIndex) and
476
 
     (FLines.TextChangeStamp = FTextChangeStamp) and (FLines.ViewChangeStamp = FViewChangeStamp)
477
 
  then begin
478
 
    //debugln(['**************** RE-USING widths: ', AIndex,' (',dbgs(Pointer(self)),')']);
479
 
    //dbg_cnt := dbg_cnt + 1;
480
 
    exit;
481
 
  end;
482
 
 
483
 
  if (AIndex < 0) or (AIndex >= FLines.Count) then begin
484
 
    FCurrentWidthsLen := 0;
485
 
    FViewChangeStamp := FLines.ViewChangeStamp;
486
 
    FTextChangeStamp := FLines.TextChangeStamp;
487
 
    exit;
488
 
  end;
489
 
 
490
 
  Line := FLines.GetPChar(AIndex, LineLen);
491
 
  if LineLen > FCurrentWidthsAlloc then begin
492
 
    //debugln(['**************** COMPUTING widths (grow): ', AIndex,' (',dbgs(Pointer(self)),') old-alloc=', FCurrentWidthsAlloc, '  new-len=',LineLen]);
493
 
    SetLength(FCurrentWidths, LineLen);
494
 
    FCurrentWidthsAlloc := LineLen;
495
 
  end
496
 
  else if FCurrentWidthsAlloc > Max(Max(LineLen, FCurrentWidthsLen)*4, SYN_LP_MIN_ALLOC) then begin
497
 
    //debugln(['**************** COMPUTING widths (shrink): ', AIndex,' (',dbgs(Pointer(self)),') old-alloc=', FCurrentWidthsAlloc, '  new-len=',LineLen]);
498
 
    FCurrentWidthsAlloc := Max(Max(LineLen, FCurrentWidthsLen), SYN_LP_MIN_ALLOC) ;
499
 
    SetLength(FCurrentWidths, FCurrentWidthsAlloc);
500
 
  //end
501
 
  //else begin
502
 
  //  debugln(['**************** COMPUTING widths: ', AIndex,' (',dbgs(Pointer(self)),') alloc=',FCurrentWidthsAlloc]);
503
 
  end;
504
 
  //debugln(['**************** NEW for index:: ', AIndex,' (',dbgs(Pointer(self)),') after index: ', FCurrentLine, ' used ', dbg_cnt,' times // old-alloc=', FCurrentWidthsAlloc, '  new-len=',LineLen, '  viewchg:',dbgs(not(FViewChangeStamp=FLines.ViewChangeStamp)),' txtchg:',dbgs(not(FTextChangeStamp=FLines.TextChangeStamp))]); dbg_cnt := 0;
505
 
 
506
 
  FCurrentWidthsLen := LineLen;
507
 
  if LineLen > 0 then
508
 
    FLines.DoGetPhysicalCharWidths(Line, LineLen, AIndex, @FCurrentWidths[0]);
509
 
  FViewChangeStamp := FLines.ViewChangeStamp;
510
 
  FTextChangeStamp := FLines.TextChangeStamp;
511
 
  FCurrentLine := AIndex;
512
 
end;
513
 
 
514
 
constructor TSynLogicalPhysicalConvertor.Create(ALines: TSynEditStrings);
515
 
begin
516
 
  FLines := ALines;
517
 
  FCurrentLine := -1;
518
 
  FCurrentWidths := nil;
519
 
  FCurrentWidthsLen := 0;
520
 
  FCurrentWidthsAlloc := 0;
521
 
end;
522
 
 
523
 
destructor TSynLogicalPhysicalConvertor.Destroy;
524
 
begin
525
 
  SetLength(FCurrentWidths, 0);
526
 
  inherited Destroy;
527
 
end;
528
 
 
529
 
function TSynLogicalPhysicalConvertor.PhysicalToLogical(AIndex,
530
 
  AColumn: Integer): Integer;
531
 
var
532
 
  ColOffs: Integer;
533
 
begin
534
 
  Result := PhysicalToLogical(AIndex, AColumn, ColOffs);
535
 
end;
536
 
 
537
 
function TSynLogicalPhysicalConvertor.PhysicalToLogical(AIndex, AColumn: Integer;
538
 
  out AColOffset: Integer): Integer;
539
 
var
540
 
  BytePos, ScreenPos, ScreenPosOld: integer;
541
 
begin
542
 
  PrepareWidthsForLine(AIndex);
543
 
 
544
 
  ScreenPos := 1;
545
 
  BytePos := 0;
546
 
  while BytePos < FCurrentWidthsLen do begin
547
 
    ScreenPosOld := ScreenPos;
548
 
    ScreenPos := ScreenPos + FCurrentWidths[BytePos];
549
 
    inc(BytePos);
550
 
    if ScreenPos > AColumn then begin
551
 
      AColOffset := AColumn - ScreenPosOld;
552
 
      exit(BytePos);
553
 
    end;
554
 
  end;
555
 
 
556
 
  // Column at/past end of line
557
 
  AColOffset := 0;
558
 
  Result := BytePos + 1 + AColumn - ScreenPos;
559
 
end;
560
 
 
561
 
function TSynLogicalPhysicalConvertor.LogicalToPhysical(AIndex,
562
 
  ABytePos: Integer): Integer;
563
 
var
564
 
  ColOffs: Integer;
565
 
begin
566
 
  ColOffs := 0;
567
 
  Result := LogicalToPhysical(AIndex, ABytePos, ColOffs);
568
 
end;
569
 
 
570
 
function TSynLogicalPhysicalConvertor.LogicalToPhysical(AIndex, ABytePos: Integer;
571
 
  var AColOffset: Integer): Integer;
572
 
var
573
 
  i: integer;
574
 
  CharWidths: TPhysicalCharWidths;
575
 
begin
576
 
  {$IFDEF AssertSynMemIndex}
577
 
  if (ABytePos <= 0) then
578
 
    raise Exception.Create(Format('Bad Bytpos for PhystoLogical BytePos=%d ColOffs= %d idx= %d',[ABytePos, AColOffset, AIndex]));
579
 
  {$ENDIF}
580
 
  if (ABytePos = 0) or ((ABytePos = 1) and (AColOffset=0)) then
581
 
    exit(ABytePos);
582
 
  PrepareWidthsForLine(AIndex);
583
 
 
584
 
  dec(ABytePos);
585
 
  if ABytePos >= FCurrentWidthsLen then begin
586
 
    Result := 1 + ABytePos - FCurrentWidthsLen;
587
 
    ABytePos := FCurrentWidthsLen;
588
 
    AColOffset := 0;
589
 
  end
590
 
  else begin
591
 
    AColOffset := Min(AColOffset, FCurrentWidths[ABytePos]-1);
592
 
    Result := 1 + AColOffset;
593
 
  end;
594
 
 
595
 
  for i := 0 to ABytePos - 1 do
596
 
    Result := Result + FCurrentWidths[i];
597
 
end;
598
 
 
599
250
{ TSynEditStringsBase }
600
251
 
601
252
function TSynEditStringsBase.GetPChar(ALineIndex: Integer): PChar;
605
256
  Result := GetPChar(ALineIndex, l);
606
257
end;
607
258
 
608
 
{ TSynEditStrings }
609
 
 
610
 
constructor TSynEditStrings.Create;
611
 
begin
612
 
  FLogPhysConvertor := TSynLogicalPhysicalConvertor.Create(self);
613
 
  inherited Create;
614
 
  IsUtf8 := True;
615
 
end;
616
 
 
617
 
destructor TSynEditStrings.Destroy;
618
 
begin
619
 
  FreeAndNil(FLogPhysConvertor);
620
 
  inherited Destroy;
621
 
end;
622
 
 
623
 
procedure TSynEditStrings.BeginUpdate(Sender: TObject);
624
 
begin
625
 
  if FSenderUpdateCount = 0 then
626
 
    SetUpdateState(true, Sender);
627
 
  inc(FSenderUpdateCount);
628
 
end;
629
 
 
630
 
procedure TSynEditStrings.EndUpdate(Sender: TObject);
631
 
begin
632
 
  If FSenderUpdateCount>0 then
633
 
    Dec(FSenderUpdateCount);
634
 
  if FSenderUpdateCount=0 then
635
 
    SetUpdateState(False, Sender);
636
 
end;
637
 
 
638
 
function TSynEditStrings.IsUpdating: Boolean;
639
 
begin
640
 
  Result := (FSenderUpdateCount > 0) or (UpdateCount > 0);
641
 
end;
642
 
 
643
 
procedure TSynEditStrings.AddChangeHandler(AReason: TSynEditNotifyReason;
644
 
  AHandler: TStringListLineCountEvent);
645
 
begin
646
 
  AddGenericHandler(AReason, TMethod(AHandler));
647
 
end;
648
 
 
649
 
procedure TSynEditStrings.AddNotifyHandler(AReason: TSynEditNotifyReason;
650
 
  AHandler: TNotifyEvent);
651
 
begin
652
 
  AddGenericHandler(AReason, TMethod(AHandler));
653
 
end;
654
 
 
655
 
procedure TSynEditStrings.RemoveChangeHandler(AReason: TSynEditNotifyReason;
656
 
  AHandler: TStringListLineCountEvent);
657
 
begin
658
 
  RemoveGenericHandler(AReason, TMethod(AHandler));
659
 
end;
660
 
 
661
 
procedure TSynEditStrings.RemoveNotifyHandler(AReason: TSynEditNotifyReason;
662
 
  AHandler: TNotifyEvent);
663
 
begin
664
 
  RemoveGenericHandler(AReason, TMethod(AHandler));
665
 
end;
666
 
 
667
 
procedure TSynEditStrings.AddEditHandler(AHandler: TStringListLineEditEvent);
668
 
begin
669
 
  AddGenericHandler(senrEditAction, TMethod(AHandler));
670
 
end;
671
 
 
672
 
procedure TSynEditStrings.RemoveEditHandler(AHandler: TStringListLineEditEvent);
673
 
begin
674
 
  RemoveGenericHandler(senrEditAction, TMethod(AHandler));
675
 
end;
676
 
 
677
 
procedure TSynEditStrings.SendHighlightChanged(aIndex, aCount: Integer);
678
 
begin
679
 
  SendNotification(senrHighlightChanged, Self, aIndex, aCount);
680
 
end;
681
 
 
682
 
function TSynEditStrings.GetPhysicalCharWidths(Index: Integer): TPhysicalCharWidths;
683
 
var
684
 
  s: string;
685
 
begin
686
 
  s := Strings[Index];
687
 
  Result := GetPhysicalCharWidths(PChar(s), length(s), Index);
688
 
end;
689
 
 
690
 
function TSynEditStrings.GetPhysicalCharWidths(Line: PChar; LineLen,
691
 
  Index: Integer): TPhysicalCharWidths;
692
 
begin
693
 
  SetLength(Result, LineLen);
694
 
  if LineLen = 0 then
695
 
    exit;
696
 
  DoGetPhysicalCharWidths(Line, LineLen, Index, @Result[0]);
697
 
end;
698
 
 
699
 
function TSynEditStrings.GetIsUtf8 : Boolean;
700
 
begin
701
 
  Result := FIsUtf8;
702
 
end;
703
 
 
704
 
procedure TSynEditStrings.SetIsUtf8(const AValue : Boolean);
705
 
begin
706
 
  FIsUtf8 := AValue;
707
 
end;
708
 
 
709
 
procedure TSynEditStrings.SetTextStr(const Value : string);
710
 
var
711
 
  StartPos: PChar;
712
 
  p: PChar;
713
 
  Last: PChar;
714
 
  sl: TStringList;
715
 
  s: string;
716
 
begin
717
 
  if Value='' then begin
718
 
    Clear;
719
 
    exit;
720
 
  end;
721
 
  BeginUpdate;
722
 
  sl:=TStringList.Create;
723
 
  try
724
 
    Clear;
725
 
    p:=PChar(Value);
726
 
    StartPos:=p;
727
 
    Last:=p+length(Value);
728
 
    while p<Last do begin
729
 
      if not (p^ in [#10,#13]) then begin
730
 
        inc(p);
731
 
      end else begin
732
 
        SetLength(s,p-StartPos);
733
 
        if s<>'' then
734
 
          System.Move(StartPos^,s[1],length(s));
735
 
        sl.Add(s);
736
 
        if (p[1] in [#10,#13]) and (p[1]<>p^) then
737
 
          inc(p);
738
 
        inc(p);
739
 
        StartPos:=p;
740
 
      end;
741
 
    end;
742
 
    if StartPos<Last then begin
743
 
      SetLength(s,Last-StartPos);
744
 
      if s<>'' then
745
 
        System.Move(StartPos^,s[1],length(s));
746
 
      sl.Add(s);
747
 
    end;
748
 
    AddStrings(sl);
749
 
  finally
750
 
    sl.Free;
751
 
    EndUpdate;
752
 
  end;
753
 
end;
754
 
 
755
 
function TSynEditStrings.GetViewChangeStamp: int64;
756
 
begin
757
 
  Result := 0;
758
 
end;
759
 
 
760
 
procedure TSynEditStrings.SetUpdateState(Updating: Boolean);
761
 
begin
762
 
  // Update/check "FSenderUpdateCount", to avoid extra locking/unlocking
763
 
  if Updating then
764
 
    BeginUpdate(nil)
765
 
  else
766
 
    EndUpdate(nil);
767
 
end;
768
 
 
769
 
function TSynEditStrings.LogicalToPhysicalPos(const p : TPoint) : TPoint;
770
 
begin
771
 
  Result := p;
772
 
  Result.X := FLogPhysConvertor.LogicalToPhysical(p.y - 1, p.x);
773
 
//  if Result.Y - 1 < Count then
774
 
//    Result.X:=LogicalToPhysicalCol(self[Result.Y - 1], Result.Y, Result.X);
775
 
end;
776
 
 
777
 
function TSynEditStrings.LogicalToPhysicalCol(const Line : String;
778
 
  Index, LogicalPos: integer) : integer;
779
 
var
780
 
  i, ByteLen: integer;
781
 
  CharWidths: TPhysicalCharWidths;
782
 
begin
783
 
  CharWidths := GetPhysicalCharWidths(Pchar(Line), length(Line), Index);
784
 
  ByteLen := length(Line);
785
 
  dec(LogicalPos);
786
 
 
787
 
  if LogicalPos > ByteLen then begin
788
 
    Result := 1 + LogicalPos - ByteLen;
789
 
    LogicalPos := ByteLen;
790
 
  end
791
 
  else
792
 
    Result := 1;
793
 
 
794
 
  for i := 0 to LogicalPos - 1 do
795
 
    Result := Result + CharWidths[i];
796
 
end;
797
 
 
798
 
function TSynEditStrings.PhysicalToLogicalPos(const p : TPoint) : TPoint;
799
 
begin
800
 
  Result := p;
801
 
  Result.X := FLogPhysConvertor.PhysicalToLogical(p.y - 1, p.x);
802
 
//  if (Result.Y>=1) and (Result.Y <= Count) then
803
 
//    Result.X:=PhysicalToLogicalCol(self[Result.Y - 1], Result.Y - 1, Result.X);
804
 
end;
805
 
 
806
 
function TSynEditStrings.PhysicalToLogicalCol(const Line : string;
807
 
  Index, PhysicalPos : integer) : integer;
808
 
var
809
 
  BytePos, ByteLen: integer;
810
 
  ScreenPos: integer;
811
 
  CharWidths: TPhysicalCharWidths;
812
 
begin
813
 
  CharWidths := GetPhysicalCharWidths(PChar(Line), length(Line), Index);
814
 
  ByteLen := Length(Line);
815
 
  ScreenPos := 1;
816
 
  BytePos := 0;
817
 
 
818
 
  while BytePos < ByteLen do begin
819
 
    if ScreenPos + CharWidths[BytePos] > PhysicalPos then
820
 
      exit(BytePos+1);
821
 
    ScreenPos := ScreenPos + CharWidths[BytePos];
822
 
    inc(BytePos);
823
 
  end;
824
 
 
825
 
  Result := BytePos + 1 + PhysicalPos - ScreenPos;
826
 
end;
827
 
 
828
 
{ TSynEditStringsLinked }
829
 
 
830
 
constructor TSynEditStringsLinked.Create(ASynStringSource: TSynEditStrings);
831
 
begin
832
 
  fSynStrings := ASynStringSource;
833
 
  Inherited Create;
834
 
end;
835
 
 
836
 
function TSynEditStringsLinked.Add(const S: string): integer;
837
 
begin
838
 
  Result := fSynStrings.Add(S);
839
 
end;
840
 
 
841
 
procedure TSynEditStringsLinked.AddStrings(AStrings: TStrings);
842
 
begin
843
 
  fSynStrings.AddStrings(AStrings);
844
 
end;
845
 
 
846
 
procedure TSynEditStringsLinked.Clear;
847
 
begin
848
 
  fSynStrings.Clear;
849
 
end;
850
 
 
851
 
procedure TSynEditStringsLinked.Delete(Index: integer);
852
 
begin
853
 
  fSynStrings.Delete(Index);
854
 
end;
855
 
 
856
 
procedure TSynEditStringsLinked.DeleteLines(Index, NumLines: integer);
857
 
begin
858
 
  fSynStrings.DeleteLines(Index, NumLines);
859
 
end;
860
 
 
861
 
procedure TSynEditStringsLinked.Insert(Index: integer; const S: string);
862
 
begin
863
 
  fSynStrings.Insert(Index, S);
864
 
end;
865
 
 
866
 
procedure TSynEditStringsLinked.InsertLines(Index, NumLines: integer);
867
 
begin
868
 
  fSynStrings.InsertLines(Index, NumLines);
869
 
end;
870
 
 
871
 
procedure TSynEditStringsLinked.InsertStrings(Index: integer; NewStrings: TStrings);
872
 
begin
873
 
  fSynStrings.InsertStrings(Index, NewStrings);
874
 
end;
875
 
 
876
 
function TSynEditStringsLinked.GetPChar(ALineIndex: Integer; out ALen: Integer): PChar;
877
 
begin
878
 
  Result := fSynStrings.GetPChar(ALineIndex, ALen);
879
 
end;
880
 
 
881
 
procedure TSynEditStringsLinked.SetIsUndoing(const AValue: Boolean);
882
 
begin
883
 
  fSynStrings.IsUndoing := AValue;
884
 
end;
885
 
 
886
 
function TSynEditStringsLinked.GetIsUndoing: Boolean;
887
 
begin
888
 
  Result := fSynStrings.IsUndoing;
889
 
end;
890
 
 
891
 
procedure TSynEditStringsLinked.SetIsRedoing(const AValue: Boolean);
892
 
begin
893
 
  fSynStrings.IsRedoing := AValue;
894
 
end;
895
 
 
896
 
function TSynEditStringsLinked.GetIsRedoing: Boolean;
897
 
begin
898
 
  Result := fSynStrings.IsRedoing;
899
 
end;
900
 
 
901
 
function TSynEditStringsLinked.GetIsUtf8: Boolean;
902
 
begin
903
 
  Result := FSynStrings.IsUtf8;
904
 
end;
905
 
 
906
 
procedure TSynEditStringsLinked.SetIsUtf8(const AValue: Boolean);
907
 
begin
908
 
  FSynStrings.IsUtf8 := AValue;
909
 
end;
910
 
 
911
 
function TSynEditStringsLinked.GetTextChangeStamp: int64;
912
 
begin
913
 
  Result := fSynStrings.GetTextChangeStamp;
914
 
end;
915
 
 
916
 
function TSynEditStringsLinked.GetViewChangeStamp: int64;
917
 
begin
918
 
  Result := fSynStrings.GetViewChangeStamp;
919
 
end;
920
 
 
921
 
//Ranges
922
 
function TSynEditStringsLinked.GetRange(Index: Pointer): TSynManagedStorageMem;
923
 
begin
924
 
  Result:= fSynStrings.Ranges[Index];
925
 
end;
926
 
 
927
 
procedure TSynEditStringsLinked.PutRange(Index: Pointer; const ARange: TSynManagedStorageMem);
928
 
begin
929
 
  fSynStrings.Ranges[Index] := ARange;
930
 
end;
931
 
 
932
 
function TSynEditStringsLinked.GetExpandedString(Index: integer): string;
933
 
begin
934
 
  Result:= fSynStrings.GetExpandedString(Index);
935
 
end;
936
 
 
937
 
function TSynEditStringsLinked.GetLengthOfLongestLine: integer;
938
 
begin
939
 
  Result:= fSynStrings.GetLengthOfLongestLine;
940
 
end;
941
 
 
942
 
function TSynEditStringsLinked.GetRedoList: TSynEditUndoList;
943
 
begin
944
 
  Result := fSynStrings.GetRedoList;
945
 
end;
946
 
 
947
 
function TSynEditStringsLinked.GetUndoList: TSynEditUndoList;
948
 
begin
949
 
  Result := fSynStrings.GetUndoList;
950
 
end;
951
 
 
952
 
function TSynEditStringsLinked.GetCurUndoList: TSynEditUndoList;
953
 
begin
954
 
  Result := fSynStrings.GetCurUndoList;
955
 
end;
956
 
 
957
 
procedure TSynEditStringsLinked.AddGenericHandler(AReason: TSynEditNotifyReason; AHandler: TMethod);
958
 
begin
959
 
  fSynStrings.AddGenericHandler(AReason, AHandler);
960
 
end;
961
 
 
962
 
procedure TSynEditStringsLinked.RemoveGenericHandler(AReason: TSynEditNotifyReason; AHandler: TMethod);
963
 
begin
964
 
  fSynStrings.RemoveGenericHandler(AReason, AHandler);
965
 
end;
966
 
 
967
 
// Count
968
 
function TSynEditStringsLinked.GetCount: integer;
969
 
begin
970
 
  Result:= fSynStrings.Count;
971
 
end;
972
 
 
973
 
function TSynEditStringsLinked.GetCapacity: integer;
974
 
begin
975
 
  Result:= fSynStrings.Capacity;
976
 
end;
977
 
 
978
 
procedure TSynEditStringsLinked.SetCapacity(NewCapacity: integer);
979
 
begin
980
 
  fSynStrings.Capacity := NewCapacity;
981
 
end;
982
 
 
983
 
function TSynEditStringsLinked.Get(Index: integer): string;
984
 
begin
985
 
  Result:= fSynStrings.Get(Index);
986
 
end;
987
 
 
988
 
function TSynEditStringsLinked.GetObject(Index: integer): TObject;
989
 
begin
990
 
  Result:= fSynStrings.GetObject(Index);
991
 
end;
992
 
 
993
 
procedure TSynEditStringsLinked.Put(Index: integer; const S: string);
994
 
begin
995
 
  fSynStrings.Put(Index, S);
996
 
end;
997
 
 
998
 
procedure TSynEditStringsLinked.PutObject(Index: integer; AObject: TObject);
999
 
begin
1000
 
  fSynStrings.PutObject(Index, AObject);
1001
 
end;
1002
 
 
1003
 
//function TSynEditStringsLinked.GetPhysicalCharWidths(Line: PChar; LineLen, Index: Integer): TPhysicalCharWidths;
1004
 
//begin
1005
 
//  Result := fSynStrings.GetPhysicalCharWidths(Line, LineLen, Index);
1006
 
//end;
1007
 
 
1008
 
procedure TSynEditStringsLinked.SetUpdateState(Updating: Boolean; Sender: TObject);
1009
 
begin
1010
 
  // Update/check "FSenderUpdateCount" in linked lists too (avoid extra locking/unlocking)
1011
 
  if Updating then
1012
 
    fSynStrings.BeginUpdate(Sender)
1013
 
  else
1014
 
    fSynStrings.EndUpdate(Sender);
1015
 
end;
1016
 
 
1017
 
procedure TSynEditStringsLinked.DoGetPhysicalCharWidths(Line: PChar;
1018
 
  LineLen, Index: Integer; PWidths: PPhysicalCharWidth);
1019
 
begin
1020
 
  fSynStrings.DoGetPhysicalCharWidths(Line, LineLen, Index, PWidths);
1021
 
end;
1022
 
 
1023
 
procedure TSynEditStringsLinked.EditInsert(LogX, LogY: Integer; AText: String);
1024
 
begin
1025
 
  fSynStrings.EditInsert(LogX, LogY, AText);
1026
 
end;
1027
 
 
1028
 
function TSynEditStringsLinked.EditDelete(LogX, LogY, ByteLen: Integer): String;
1029
 
begin
1030
 
  Result := fSynStrings.EditDelete(LogX, LogY, ByteLen);
1031
 
end;
1032
 
 
1033
 
procedure TSynEditStringsLinked.EditLineBreak(LogX, LogY: Integer);
1034
 
begin
1035
 
  fSynStrings.EditLineBreak(LogX, LogY);
1036
 
end;
1037
 
 
1038
 
procedure TSynEditStringsLinked.EditLineJoin(LogY: Integer;
1039
 
  FillText: String = '');
1040
 
begin
1041
 
  fSynStrings.EditLineJoin(LogY, FillText);
1042
 
end;
1043
 
 
1044
 
procedure TSynEditStringsLinked.EditLinesInsert(LogY, ACount: Integer; AText: String = '');
1045
 
begin
1046
 
  fSynStrings.EditLinesInsert(LogY, ACount, AText);
1047
 
end;
1048
 
 
1049
 
procedure TSynEditStringsLinked.EditLinesDelete(LogY, ACount: Integer);
1050
 
begin
1051
 
  fSynStrings.EditLinesDelete(LogY, ACount);
1052
 
end;
1053
 
 
1054
 
procedure TSynEditStringsLinked.EditUndo(Item: TSynEditUndoItem);
1055
 
begin
1056
 
  fSynStrings.EditUndo(Item);
1057
 
end;
1058
 
 
1059
 
procedure TSynEditStringsLinked.EditRedo(Item: TSynEditUndoItem);
1060
 
begin
1061
 
  fSynStrings.EditRedo(Item);
1062
 
end;
1063
 
 
1064
 
procedure TSynEditStringsLinked.SendNotification(AReason: TSynEditNotifyReason;
1065
 
  ASender: TSynEditStrings; aIndex, aCount: Integer;
1066
 
  aBytePos: Integer = -1; aLen: Integer = 0; aTxt: String = '');
1067
 
begin
1068
 
  fSynStrings.SendNotification(AReason, ASender, aIndex, aCount, aBytePos, aLen, aTxt);
1069
 
end;
1070
 
 
1071
 
procedure TSynEditStringsLinked.SendNotification(AReason: TSynEditNotifyReason;
1072
 
  ASender: TObject);
1073
 
begin
1074
 
  fSynStrings.SendNotification(AReason, ASender);
1075
 
end;
1076
 
 
1077
 
procedure TSynEditStringsLinked.FlushNotificationCache;
1078
 
begin
1079
 
  fSynStrings.FlushNotificationCache;
1080
 
end;
1081
 
 
1082
 
procedure TSynEditStringsLinked.IgnoreSendNotification(AReason: TSynEditNotifyReason;
1083
 
  IncIgnore: Boolean);
1084
 
begin
1085
 
  fSynStrings.IgnoreSendNotification(AReason, IncIgnore);
1086
 
end;
1087
 
 
1088
259
{ TSynEditUndoList }
1089
260
 
1090
261
constructor TSynEditUndoList.Create;
1155
326
    FUndoGroup.Clear;
1156
327
    if assigned(FOnNeedCaretUndo) then
1157
328
      FUndoGroup.add(FOnNeedCaretUndo());
1158
 
  end
 
329
  end;
 
330
  {$IFDEF SynUndoDebugCalls}
 
331
  DebugLnEnter(['>> TSynEditUndoList.BeginBlock ', DebugName, ' ', DbgSName(self), ' ', dbgs(Self), ' fLockCount=', fLockCount, ' Cnt=', fItems.Count, ' FInGroupCount=', FInGroupCount, ' fUnModifiedItem=', fUnModifiedItem]);
 
332
  {$ENDIF}
1159
333
end;
1160
334
 
1161
335
procedure TSynEditUndoList.Clear;
1162
336
var
1163
337
  i: integer;
1164
338
begin
 
339
  {$IFDEF SynUndoDebugCalls}
 
340
  DebugLn(['>> TSynEditUndoList.Clear ', DebugName, ' ', DbgSName(self), ' ', dbgs(Self), ' fLockCount=', fLockCount, ' Cnt=', fItems.Count, ' FInGroupCount=', FInGroupCount]);
 
341
  {$ENDIF}
1165
342
  for i := 0 to fItems.Count - 1 do
1166
343
    TSynEditUndoGroup(fItems[i]).Free;
1167
344
  fItems.Clear;
1197
374
      FIsInsideRedo := False;
1198
375
      FForceGroupEnd := False;
1199
376
    end;
 
377
    {$IFDEF SynUndoDebugCalls}
 
378
    DebugLnExit(['<< TSynEditUndoList.EndBlock ', DebugName, ' ', DbgSName(self), ' ', dbgs(Self), ' fLockCount=', fLockCount, ' Cnt=', fItems.Count, ' FInGroupCount=', FInGroupCount, ' fUnModifiedItem=', fUnModifiedItem]);
 
379
  end else begin
 
380
    DebugLn(['** EXTRA TSynEditUndoList.EndBlock ', DebugName, ' ', DbgSName(self), ' ', dbgs(Self), ' fLockCount=', fLockCount, ' Cnt=', fItems.Count, ' FInGroupCount=', FInGroupCount, ' fUnModifiedItem=', fUnModifiedItem]);
 
381
    {$ENDIF}
1200
382
  end;
1201
383
end;
1202
384
 
1239
421
procedure TSynEditUndoList.Lock;
1240
422
begin
1241
423
  Inc(fLockCount);
 
424
  {$IFDEF SynUndoDebugCalls}
 
425
  DebugLnEnter(['>> TSynEditUndoList.Lock ', DebugName, ' ', DbgSName(self), ' ', dbgs(Self), ' fLockCount=', fLockCount, ' Cnt=', fItems.Count, ' FInGroupCount=', FInGroupCount]);
 
426
  {$ENDIF}
1242
427
end;
1243
428
 
1244
429
function TSynEditUndoList.PopItem: TSynEditUndoGroup;
1276
461
begin
1277
462
  if fLockCount > 0 then
1278
463
    Dec(fLockCount);
 
464
  {$IFDEF SynUndoDebugCalls}
 
465
  DebugLnExit(['<< TSynEditUndoList.UnLock ', DebugName, ' ', DbgSName(self), ' ', dbgs(Self), ' fLockCount=', fLockCount, ' Cnt=', fItems.Count, ' FInGroupCount=', FInGroupCount]);
 
466
  {$ENDIF}
1279
467
end;
1280
468
 
1281
469
function TSynEditUndoList.IsLocked: Boolean;