1 {
2 This file is part of the Free Pascal Integrated Development Environment
3 Copyright (c) 1998-2000 by Berczi Gabor
4
5 Code editor template objects
6
7 See the file COPYING.FPC, included in this distribution,
8 for details about the copyright.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
14 **********************************************************************}
15 {$i globdir.inc}
16 unit WCEdit;
17
18 interface
19
20 uses Objects,Drivers,Views,
21 WUtils,WEditor;
22
23 type
24 PCodeEditor = ^TCodeEditor;
25
26 PIndicator = ^TIndicator;
27 TIndicator = object(TView)
28 Location: TPoint;
29 Modified : Boolean;
30 CodeOwner : PCodeEditor;
31 {$ifdef debug}
32 StoreUndo : Boolean;
33 SyntaxComplete : boolean;
34 UseTabs : Boolean;
35 {$endif debug}
36 constructor Init(var Bounds: TRect);
37 procedure Draw; virtual;
GetPalettenull38 function GetPalette: PPalette; virtual;
39 procedure SetState(AState: Word; Enable: Boolean); virtual;
40 procedure SetValue(ALocation: TPoint; AModified: Boolean);
41 end;
42
43 PLine = ^TLine;
44 TLine = object(TCustomLine)
45 public { internal use only! }
46 Text : PString;
47 DefaultEditorInfo : PEditorLineInfo;
48 EditorInfos : PEditorLineInfoCollection;
49 Flags : longint;
50 Owner : PCustomCodeEditorCore;
51 procedure AddEditorInfo(Index: sw_integer; AEditor: PCustomCodeEditor); virtual;
52 procedure RemoveEditorInfo(AEditor: PCustomCodeEditor); virtual;
53 public
54 constructor Init(AOwner: PCustomCodeEditorCore; const AText: string; AFlags: longint);
GetTextnull55 function GetText: string; virtual;
56 procedure SetText(const AText: string); virtual;
GetEditorInfonull57 function GetEditorInfo(Editor: PCustomCodeEditor): PEditorLineInfo; virtual;
GetFlagsnull58 function GetFlags: longint; virtual;
59 procedure SetFlags(AFlags: longint); virtual;
60 destructor Done; virtual;
61 end;
62
63 PCodeEditorCore = ^TCodeEditorCore;
64 TCodeEditorCore = object(TCustomCodeEditorCore)
65 protected
66 Lines : PLineCollection;
67 CanUndo : Boolean;
68 StoreUndo : boolean;
69 Modified : Boolean;
70 ReadOnly : Boolean;
71 TabSize : integer;
72 IndentSize : integer;
73 ModifiedTime : cardinal;
74 public
75 UndoList : PEditorActionCollection;
76 RedoList : PEditorActionCollection;
77 constructor Init;
78 destructor Done; virtual;
79 procedure ChangeLinesTo(ALines : PLineCollection); virtual;
GetModifiednull80 function GetModified: boolean; virtual;
81 procedure SetModified(AModified: boolean); virtual;
GetModifyTimenull82 function GetModifyTime: cardinal; virtual;
GetTabSizenull83 function GetTabSize: integer; virtual;
84 procedure SetTabSize(ATabSize: integer); virtual;
GetIndentSizenull85 function GetIndentSize: integer; virtual;
86 procedure SetIndentSize(AIndentSize: integer); virtual;
GetStoreUndonull87 function GetStoreUndo: boolean; virtual;
88 procedure SetStoreUndo(AStore: boolean); virtual;
GetSyntaxCompletednull89 function GetSyntaxCompleted: boolean; virtual;
90 procedure SetSyntaxCompleted(SC : boolean); virtual;
GetLastSyntaxedLinenull91 function GetLastSyntaxedLine: sw_integer; virtual;
92 procedure SetLastSyntaxedLine(ALine: sw_integer); virtual;
93 { Storage }
94 protected
95 { Text & info storage abstraction }
96 procedure ISetLineFlagState(Binding: PEditorBinding; LineNo: sw_integer; Flag: longint; ASet: boolean); virtual;
97 procedure IGetDisplayTextFormat(Binding: PEditorBinding; LineNo: sw_integer;var DT,DF:string); virtual;
IGetLineFormatnull98 function IGetLineFormat(Binding: PEditorBinding; LineNo: sw_integer): string; virtual;
99 procedure ISetLineFormat(Binding: PEditorBinding; LineNo: sw_integer;const S: string); virtual;
100 public
101 { Text & info storage abstraction }
GetLineCountnull102 function GetLineCount: sw_integer; virtual;
GetLinenull103 function GetLine(LineNo: sw_integer): PCustomLine; virtual;
GetLineTextnull104 function GetLineText(LineNo: sw_integer): string; virtual;
105 procedure SetDisplayText(I: sw_integer;const S: string); virtual;
GetDisplayTextnull106 function GetDisplayText(I: sw_integer): string; virtual;
107 procedure SetLineText(I: sw_integer;const S: string); virtual;
108 procedure DeleteAllLines; virtual;
109 procedure DeleteLine(I: sw_integer); virtual;
InsertLinenull110 function InsertLine(LineNo: sw_integer; const S: string): PCustomLine; virtual;
111 procedure AddLine(const S: string); virtual;
112 procedure GetContent(ALines: PUnsortedStringCollection); virtual;
113 procedure SetContent(ALines: PUnsortedStringCollection); virtual;
114 public
115 { Undo info storage }
116 procedure AddAction(AAction: byte; AStartPos, AEndPos: TPoint; AText: string;AFlags : longint); virtual;
117 procedure AddGroupedAction(AAction : byte); virtual;
118 procedure CloseGroupedAction(AAction : byte); virtual;
GetUndoActionCountnull119 function GetUndoActionCount: sw_integer; virtual;
GetRedoActionCountnull120 function GetRedoActionCount: sw_integer; virtual;
121 private
122 OnDiskLoadTime : cardinal;
123 SystemLoadTime : cardinal;
124 procedure LinesInsert(Idx: sw_integer; Line: PLine);
125 end;
126
127 TCodeEditor = object(TCustomCodeEditor)
128 Core : PCodeEditorCore;
129 Flags : longint;
130 Indicator : PIndicator;
131 HighlightRow: sw_integer;
132 DebuggerRow: sw_integer;
133 CodeCompleteFrag: PString;
134 CodeCompleteWord: PString;
135 ReadOnly : boolean;
136 CompleteState: TCompleteState;
137 ErrorMessage: PString;
138 IndicatorDrawCalled : boolean;
139 Folds : PFoldCollection;
140 MaxFoldLevel: sw_integer;
141 constructor Init(var Bounds: TRect; AHScrollBar, AVScrollBar:
142 PScrollBar; AIndicator: PIndicator; ACore: PCodeEditorCore);
143 public
144 procedure DrawIndicator; virtual;
145 public
GetFlagsnull146 function GetFlags: longint; virtual;
147 procedure SetFlags(AFlags: longint); virtual;
GetModifiednull148 function GetModified: boolean; virtual;
149 procedure SetModified(AModified: boolean); virtual;
GetStoreUndonull150 function GetStoreUndo: boolean; virtual;
151 procedure SetStoreUndo(AStore: boolean); virtual;
152 procedure ClearUndoList;
GetSyntaxCompletednull153 function GetSyntaxCompleted: boolean; virtual;
154 procedure SetSyntaxCompleted(SC : boolean); virtual;
GetLastSyntaxedLinenull155 function GetLastSyntaxedLine: sw_integer; virtual;
156 procedure SetLastSyntaxedLine(ALine: sw_integer); virtual;
GetTabSizenull157 function GetTabSize: integer; virtual;
158 procedure SetTabSize(ATabSize: integer); virtual;
GetIndentSizenull159 function GetIndentSize: integer; virtual;
160 procedure SetIndentSize(AIndentSize: integer); virtual;
IsReadOnlynull161 function IsReadOnly: boolean; virtual;
162 public
163 procedure UpdateIndicator; virtual;
164 procedure ModifiedChanged; virtual;
165 procedure PositionChanged; virtual;
166 procedure LimitsChanged; virtual;
IsClipboardnull167 function IsClipboard: Boolean; virtual;
LoadFromStreamnull168 function LoadFromStream(Stream: PFastBufStream): boolean; virtual;
SaveToStreamnull169 function SaveToStream(Stream: PStream): boolean; virtual;
SaveAreaToStreamnull170 function SaveAreaToStream(Stream: PStream; StartP,EndP: TPoint): boolean;virtual;
171 destructor Done; virtual;
172 public
173 { ChangedLine : sw_integer;}
174 { Text & info storage abstraction }
GetLineCountnull175 function GetLineCount: sw_integer; virtual;
GetLinenull176 function GetLine(LineNo: sw_integer): PCustomLine; virtual;
CharIdxToLinePosnull177 function CharIdxToLinePos(Line,CharIdx: sw_integer): sw_integer; virtual;
LinePosToCharIdxnull178 function LinePosToCharIdx(Line,X: sw_integer): sw_integer; virtual;
GetLineTextnull179 function GetLineText(I: sw_integer): string; virtual;
180 procedure SetDisplayText(I: sw_integer;const S: string); virtual;
GetDisplayTextnull181 function GetDisplayText(I: sw_integer): string; virtual;
182 procedure SetLineText(I: sw_integer;const S: string); virtual;
183 procedure GetDisplayTextFormat(I: sw_integer;var DT,DF:string); virtual;
GetLineFormatnull184 function GetLineFormat(I: sw_integer): string; virtual;
185 procedure SetLineFormat(I: sw_integer;const S: string); virtual;
186 procedure DeleteAllLines; virtual;
187 procedure DeleteLine(I: sw_integer); virtual;
InsertLinenull188 function InsertLine(LineNo: sw_integer; const S: string): PCustomLine; virtual;
189 procedure AddLine(const S: string); virtual;
GetErrorMessagenull190 function GetErrorMessage: string; virtual;
191 procedure SetErrorMessage(const S: string); virtual;
192 procedure GetContent(ALines: PUnsortedStringCollection); virtual;
193 procedure SetContent(ALines: PUnsortedStringCollection); virtual;
194 procedure Lock; virtual;
195 procedure UnLock; virtual;
196 public
197 { CodeComplete support }
GetCodeCompleteWordnull198 function GetCodeCompleteWord: string; virtual;
199 procedure SetCodeCompleteWord(const S: string); virtual;
GetCodeCompleteFragnull200 function GetCodeCompleteFrag: string; virtual;
201 procedure SetCodeCompleteFrag(const S: string); virtual;
GetCompleteStatenull202 function GetCompleteState: TCompleteState; virtual;
203 procedure SetCompleteState(AState: TCompleteState); virtual;
204 public
205 { Syntax highlight }
UpdateAttrsnull206 {a}function UpdateAttrs(FromLine: sw_integer; Attrs: byte): sw_integer; virtual;
UpdateAttrsRangenull207 {a}function UpdateAttrsRange(FromLine, ToLine: sw_integer; Attrs: byte): sw_integer; virtual;
208 public
209 { Undo info storage }
210 procedure AddAction(AAction: byte; AStartPos, AEndPos: TPoint; AText: string;AFlags : longint); virtual;
211 procedure AddGroupedAction(AAction : byte); virtual;
212 procedure CloseGroupedAction(AAction : byte); virtual;
GetUndoActionCountnull213 function GetUndoActionCount: sw_integer; virtual;
GetRedoActionCountnull214 function GetRedoActionCount: sw_integer; virtual;
215 procedure JumpToLastCursorPos; virtual;
216 procedure Undo; virtual;
217 procedure Redo; virtual;
218 { Fold support }
GetMaxFoldLevelnull219 function GetMaxFoldLevel: sw_integer; virtual;
GetFoldCountnull220 function GetFoldCount: sw_integer; virtual;
GetFoldnull221 function GetFold(Index: sw_integer): PFold; virtual;
222 procedure RegisterFold(AFold: PFold); virtual;
223 procedure UnRegisterFold(AFold: PFold); virtual;
224 end;
225
226 PFileEditor = ^TFileEditor;
227 TFileEditor = object(TCodeEditor)
228 FileName: string;
229 constructor Init(var Bounds: TRect; AHScrollBar, AVScrollBar:
230 PScrollBar; AIndicator: PIndicator; ACore: PCodeEditorCore; const AFileName: string);
Savenull231 function Save: Boolean; virtual;
SaveAsnull232 function SaveAs: Boolean; virtual;
SaveAsknull233 function SaveAsk(Force: boolean): Boolean; virtual;
LoadFilenull234 function LoadFile: boolean; virtual;
ReloadFilenull235 function ReloadFile: boolean; virtual;
SaveFilenull236 function SaveFile: boolean; virtual;
Validnull237 function Valid(Command: Word): Boolean; virtual;
238 procedure HandleEvent(var Event: TEvent); virtual;
ShouldSavenull239 function ShouldSave: boolean; virtual;
IsChangedOnDisknull240 function IsChangedOnDisk : boolean;
241 public
242 procedure BindingsChanged; virtual;
243 end;
244
DefUseSyntaxHighlightnull245 function DefUseSyntaxHighlight(Editor: PFileEditor): boolean;
DefUseTabsPatternnull246 function DefUseTabsPattern(Editor: PFileEditor): boolean;
247
248 const
249 DefaultCodeEditorFlags : longint =
250 efBackupFiles+efInsertMode+efAutoIndent+efPersistentBlocks+
251 {efUseTabCharacters+}efBackSpaceUnindents+efSyntaxHighlight+
252 efExpandAllTabs+efCodeComplete{+efFolds};
253 DefaultTabSize : integer = 8;
254 DefaultIndentSize : integer = 1;
ditornull255 UseSyntaxHighlight : function(Editor: PFileEditor): boolean = {$ifdef fpc}@{$endif}DefUseSyntaxHighlight;
ditornull256 UseTabsPattern : function(Editor: PFileEditor): boolean = {$ifdef fpc}@{$endif}DefUseTabsPattern;
257
258 procedure RegisterWCEdit;
259
260 implementation
261
262 uses Dos,
263 WConsts,
264 FVConsts,
265 App,WViews;
266
267 {$ifndef NOOBJREG}
268 const
269 RIndicator: TStreamRec = (
270 ObjType: 1100;
271 VmtLink: Ofs(TypeOf(TIndicator)^);
272 Load: @TIndicator.Load;
273 Store: @TIndicator.Store
274 );
275 RCodeEditor: TStreamRec = (
276 ObjType: 1101;
277 VmtLink: Ofs(TypeOf(TCodeEditor)^);
278 Load: @TCodeEditor.Load;
279 Store: @TCodeEditor.Store
280 );
281 RFileEditor: TStreamRec = (
282 ObjType: 1102;
283 VmtLink: Ofs(TypeOf(TFileEditor)^);
284 Load: @TFileEditor.Load;
285 Store: @TFileEditor.Store
286 );
287 {$endif}
288
289 constructor TLine.Init(AOwner: PCustomCodeEditorCore; const AText: string; AFlags: longint);
290 begin
291 inherited Init(AText,AFlags);
292 // New(EditorInfos, Init(10,10));
293 Owner:=AOwner;
294 end;
295
296 procedure TLine.AddEditorInfo(Index: sw_integer; AEditor: PCustomCodeEditor);
297 begin
298 if Index=0 then
299 begin
300 DefaultEditorInfo:=New(PEditorLineInfo, Init(AEditor));
301 exit;
302 end;
303 if not assigned(EditorInfos) then
304 begin
305 New(EditorInfos, Init(10,10));
306 EditorInfos^.AtInsert(0,DefaultEditorInfo);
307 DefaultEditorInfo:=nil;
308 end;
309 EditorInfos^.AtInsert(Index,New(PEditorLineInfo, Init(AEditor)));
310 end;
311
312 procedure TLine.RemoveEditorInfo(AEditor: PCustomCodeEditor);
313 var E: PEditorLineInfo;
314 begin
315 E:=GetEditorInfo(AEditor);
316 if Assigned(EditorInfos) then
317 EditorInfos^.Free(E);
318 end;
319
TLine.GetTextnull320 function TLine.GetText: string;
321 begin
322 GetText:=GetStr(Text);
323 end;
324
325 procedure TLine.SetText(const AText: string);
326 begin
327 SetStr(Text,AText);
328 end;
329
GetEditorInfonull330 function TLine.GetEditorInfo(Editor: PCustomCodeEditor): PEditorLineInfo;
Matchnull331 function Match(P: PEditorLineInfo): boolean;
332 begin
333 Match:=P^.Editor=Editor;
334 end;
335 begin
336 if not assigned(EditorInfos) then
337 GetEditorInfo:=DefaultEditorInfo
338 else
339 GetEditorInfo:=EditorInfos^.FirstThat(@Match);
340 end;
341
GetFlagsnull342 function TLine.GetFlags: longint;
343 begin
344 GetFlags:=Flags;
345 end;
346
347 procedure TLine.SetFlags(AFlags: longint);
348 begin
349 Flags:=AFlags;
350 if Assigned(Owner) then
351 Owner^.ContentsChanged;
352 end;
353
354 destructor TLine.Done;
355 begin
356 if Assigned(Text) then
357 DisposeStr(Text);
358 Text:=nil;
359 if Assigned(EditorInfos) then
360 Dispose(EditorInfos, Done);
361 EditorInfos:=nil;
362 if Assigned(DefaultEditorInfo) then
363 Dispose(DefaultEditorInfo, Done);
364 DefaultEditorInfo:=nil;
365 inherited Done;
366 end;
367
368 constructor TCodeEditorCore.Init;
369 begin
370 inherited Init;
371 StoreUndo:=true;
372 new(UndoList,init(500,1000));
373 new(RedoList,init(500,1000));
374 New(Lines, Init(500,1000));
375 TabSize:=DefaultTabSize;
376 IndentSize:=DefaultIndentSize;
377 OnDiskLoadTime:=0;
378 SystemLoadTime:=0;
379 end;
380
381 procedure TCodeEditorCore.ChangeLinesTo(ALines : PLineCollection);
382 begin
383 if assigned(lines) then
384 Dispose(Lines,Done);
385 Lines:=ALines;
386 end;
387
TCodeEditorCore.GetLineCountnull388 function TCodeEditorCore.GetLineCount: sw_integer;
389 begin
390 GetLineCount:=Lines^.Count;
391 end;
392
GetLinenull393 function TCodeEditorCore.GetLine(LineNo: sw_integer): PCustomLine;
394 begin
395 GetLine:=Lines^.At(LineNo);
396 end;
397
TCodeEditorCore.GetModifiednull398 function TCodeEditorCore.GetModified: boolean;
399 begin
400 GetModified:=Modified;
401 end;
402
TCodeEditorCore.GetModifyTimenull403 function TCodeEditorCore.GetModifyTime: cardinal;
404 begin
405 GetModifyTime:=ModifiedTime;
406 end;
407
408 procedure TCodeEditorCore.SetModified(AModified: boolean);
409 begin
410 if AModified<>Modified then
411 begin
412 Modified:=AModified;
413 ModifiedChanged;
414 end;
415 ModifiedTime:=cardinal(Now);
416 end;
417
TCodeEditorCore.GetStoreUndonull418 function TCodeEditorCore.GetStoreUndo: boolean;
419 begin
420 GetStoreUndo:=StoreUndo;
421 end;
422
423 procedure TCodeEditorCore.SetStoreUndo(AStore: boolean);
424 begin
425 if StoreUndo<>AStore then
426 begin
427 StoreUndo:=AStore;
428 StoreUndoChanged;
429 end;
430 end;
431
TCodeEditorCore.GetSyntaxCompletednull432 function TCodeEditorCore.GetSyntaxCompleted: boolean;
433 begin
434 {$ifdef TEST_PARTIAL_SYNTAX}
435 GetSyntaxCompleted:=SyntaxComplete;
436 {$else}
437 GetSyntaxCompleted:=true;
438 {$endif}
439 end;
440
441 procedure TCodeEditorCore.SetSyntaxCompleted(SC: boolean);
442 begin
443 {$ifdef TEST_PARTIAL_SYNTAX}
444 if SC<>SyntaxComplete then
445 begin
446 SyntaxComplete:=SC;
447 end;
448 {$endif}
449 end;
GetLastSyntaxedLinenull450 function TCodeEditorCore.GetLastSyntaxedLine: sw_integer;
451 begin
452 GetLastSyntaxedLine:=LastSyntaxedLine;
453 end;
454
455 procedure TCodeEditorCore.SetLastSyntaxedLine(ALine: sw_integer);
456 begin
457 LastSyntaxedLine:=ALine;
458 end;
459
460
461 procedure TCodeEditorCore.ISetLineFlagState(Binding: PEditorBinding; LineNo: sw_integer; Flag: longint; ASet: boolean);
462 var P: PCustomLine;
463 begin
464 if LineNo<GetLineCount then
465 begin
466 P:=GetLine(LineNo);
467 if assigned(P) then
468 P^.SetFlagState(Flag,ASet);
469 end;
470 end;
471
472 procedure TCodeEditorCore.GetContent(ALines: PUnsortedStringCollection);
473 procedure AddIt(P: PCustomLine);
474 begin
475 if Assigned(P) then
476 ALines^.Insert(NewStr(P^.GetText));
477 end;
478 begin
479 if Assigned(Lines) then
480 Lines^.ForEach(@AddIt);
481 end;
482
483 procedure TCodeEditorCore.SetContent(ALines: PUnsortedStringCollection);
484 procedure AddIt(P: PString);
485 begin
486 AddLine(GetStr(P));
487 end;
488 begin
489 DeleteAllLines;
490 if Assigned(ALines) then
491 ALines^.ForEach(@AddIt);
492 LimitsChanged;
493 end;
494
TCodeEditorCore.GetTabSizenull495 function TCodeEditorCore.GetTabSize: integer;
496 begin
497 GetTabSize:=TabSize;
498 end;
499
500 procedure TCodeEditorCore.SetTabSize(ATabSize: integer);
501 begin
502 if ATabSize<>TabSize then
503 begin
504 TabSize:=ATabSize;
505 TabSizeChanged;
506 end;
507 end;
508
GetIndentSizenull509 function TCodeEditorCore.GetIndentSize: integer;
510 begin
511 GetIndentSize:=IndentSize;
512 end;
513
514 procedure TCodeEditorCore.SetIndentSize(AIndentSize: integer);
515 begin
516 if AIndentSize<>IndentSize then
517 begin
518 IndentSize:=AIndentSize;
519 end;
520 end;
521
GetLineTextnull522 function TCodeEditorCore.GetLineText(LineNo: sw_integer): string;
523 var
524 L : PCustomLine;
525 begin
526 GetLineText:='';
527 if LineNo<Lines^.Count then
528 begin
529 L:=Lines^.At(LineNo);
530 GetLineText:=L^.GetText;
531 end;
532 end;
533
534 procedure TCodeEditorCore.LinesInsert(Idx: sw_integer; Line: PLine);
535 var I: sw_integer;
536 procedure RegLine(P: PEditorBinding);
537 begin
538 Line^.AddEditorInfo(I,P^.Editor);
539 Inc(I);
540 end;
541 begin
542 if Idx=-1 then Idx:=Lines^.Count;
543 I:=0;
544 Bindings^.ForEach(@RegLine);
545 Lines^.AtInsert(Idx,Line);
546 end;
547
548 procedure TCodeEditorCore.SetLineText(I: sw_integer;const S: string);
549 var
550 L : PCustomLine;
551 AddCount : Sw_Integer;
552 begin
553 AddCount:=0;
554 while (Lines^.Count<I+1) do
555 begin
556 LinesInsert(-1,New(PLine, Init(@Self,'',0)));
557 Inc(AddCount);
558 end;
559 if AddCount>0 then
560 LimitsChanged;
561 L:=Lines^.At(I);
562 L^.SetText(S);
563 ContentsChanged;
564 end;
565
GetDisplayTextnull566 function TCodeEditorCore.GetDisplayText(I: sw_integer): string;
567 begin
568 GetDisplayText:=ExtractTabs(GetLineText(I),GetTabSize);
569 end;
570
571 procedure TCodeEditorCore.SetDisplayText(I: sw_integer;const S: string);
572 begin
573 { I disagree here
574 I don't want the editor to change the position of the tabs
575 in my makefiles !! PM
576 if FlagSet(efUseTabCharacters) and (TabSize>0) then
577 SetLineText(I,CompressUsingTabs(S,TabSize))
578 else }
579 { ... then you better make this optional - Gabor }
580 SetLineText(I,S);
581 end;
582
583 procedure TCodeEditorCore.IGetDisplayTextFormat(Binding: PEditorBinding; LineNo: sw_integer;var DT,DF:string);
584 var
585 L : PCustomLine;
586 P,PAdd : SW_Integer;
587 begin
588 DF:='';
589 DT:='';
590 if (0<=LineNo) and (LineNo<GetLineCount) then
591 begin
592 L:=GetLine(LineNo);
593 if not assigned(L) then
594 exit;
595 DF:=IGetLineFormat(Binding,LineNo);
596 DT:=L^.GetText;
597 p:=0;
598 while p<length(DT) do
599 begin
600 inc(p);
601 if DT[p]=#9 then
602 begin
603 PAdd:=TabSize-((p-1) mod TabSize);
604 if DF<>'' then
605 DF:=copy(DF,1,P-1)+CharStr(DF[p],PAdd)+copy(DF,P+1,High(DF));
606 DT:=copy(DT,1,P-1)+CharStr(' ',PAdd)+copy(DT,P+1,High(DF));
607 inc(P,PAdd-1);
608 end;
609 end;
610 end;
611 end;
612
TCodeEditorCore.IGetLineFormatnull613 function TCodeEditorCore.IGetLineFormat(Binding: PEditorBinding; LineNo: sw_integer): string;
614 var P: PCustomLine;
615 LI: PEditorLineInfo;
616 S: string;
617 begin
618 if (0<=LineNo) and (LineNo<GetLineCount) then
619 P:=GetLine(LineNo)
620 else
621 P:=nil;
622 if P=nil then LI:=nil else
623 LI:=P^.GetEditorInfo(Binding^.Editor);
624 if LI=nil then S:='' else S:=LI^.GetFormat;
625 IGetLineFormat:=S;
626 end;
627
628 procedure TCodeEditorCore.ISetLineFormat(Binding: PEditorBinding; LineNo: sw_integer;const S: string);
629 var P: PCustomLine;
630 LI: PEditorLineInfo;
631 begin
632 if (LineNo<GetLineCount) then
633 begin
634 P:=GetLine(LineNo);
635 if P=nil then LI:=nil else LI:=P^.GetEditorInfo(Binding^.Editor);
636 if Assigned(LI) then LI^.SetFormat(S);
637 end;
638 end;
639
640 procedure TCodeEditorCore.DeleteAllLines;
641 begin
642 if Assigned(Lines) then
643 Lines^.FreeAll;
644 end;
645
646 procedure TCodeEditorCore.DeleteLine(I: sw_integer);
647 var
648 CP : Tpoint;
649 begin
650 if I<Lines^.Count then
651 begin
652 if StoreUndo then
653 begin
654 CP.X:=0;CP.Y:=I;
655 AddAction(eaDeleteLine,CP,CP,GetLineText(I),0);
656 end;
657 Lines^.AtFree(I);
658 end;
659 end;
660
InsertLinenull661 function TCodeEditorCore.InsertLine(LineNo: sw_integer; const S: string): PCustomLine;
662 var L: PLine;
663 begin
664 L:=New(PLine, Init(@Self,S,0));
665 LinesInsert(LineNo, L);
666 InsertLine:=L;
667 end;
668
669 procedure TCodeEditorCore.AddLine(const S: string);
670 begin
671 LinesInsert(-1,New(PLine, Init(@Self,S,0)));
672 end;
673
674 procedure TCodeEditorCore.AddAction(AAction: byte; AStartPos, AEndPos: TPoint; AText: string;AFlags : longint);
675 var
676 ActionIntegrated : boolean;
677 pa : PEditorAction;
678 S : String;
679 begin
680 if (UndoList=nil) or (not StoreUndo) then Exit;
681 ActionIntegrated:=false;
682 if UndoList^.count>0 then
683 begin
684 pa:=UndoList^.At(UndoList^.count-1);
685 if (pa^.action=AAction) and
686 (pa^.EndPos.X=AStartPos.X) and
687 (pa^.EndPos.Y=AStartPos.Y) and
688 { do not group InsertLine and DeleteLine !! }
689 ((AAction=eaMoveCursor) or
690 (AAction=eaInsertText) or
691 (AAction=eaOverwriteText) or
692 (AAction=eaDeleteText)) and
693 { do not group if a new grouped_action started }
694 (not assigned(UndoList^.CurrentGroupedAction) or
695 (UndoList^.CurrentGroupedAction^.ActionCount>0))
696 then
697 begin
698 pa^.EndPos:=AEndPos;
699 S:=GetStr(pa^.text);
700 if S<>'' then
701 DisposeStr(pa^.text);
702 if (AAction=eaDeleteText) and
703 (AStartPos.X>AEndPos.X) then
704 pa^.text:=NewStr(AText+S)
705 else
706 pa^.text:=NewStr(S+AText);
707 ActionIntegrated:=true;
708 end;
709 end;
710 if not ActionIntegrated then
711 begin
712 UndoList^.Insert(New(PEditorAction,Init(AAction,AStartPos,AEndPos,AText,AFlags)));
713 if assigned(UndoList^.CurrentGroupedAction) then
714 Inc(UndoList^.CurrentGroupedAction^.actionCount);
715 UpdateUndoRedo(cmUndo,AAction);
716 end;
717 if UndoList^.count>0 then
718 begin
719 UpdateUndoRedo(cmRedo,0);
720 RedoList^.FreeAll;
721 end;
722 end;
723
724 procedure TCodeEditorCore.AddGroupedAction(AAction : byte);
725 begin
726 if (UndoList=nil) or (not StoreUndo) then Exit;
727 if Assigned(UndoList^.CurrentGroupedAction) then
728 inc(UndoList^.GroupLevel)
729 else
730 begin
731 UndoList^.CurrentGroupedAction:=New(PEditorAction,Init_group(AAction));
732 UndoList^.GroupLevel:=1;
733 end;
734 end;
735
736 procedure TCodeEditorCore.CloseGroupedAction(AAction : byte);
737 begin
738 if (UndoList=nil) or (not StoreUndo) then Exit;
739 dec(UndoList^.GroupLevel);
740 if UndoList^.GroupLevel=0 then
741 begin
742 UndoList^.CurrentGroupedAction^.TimeStamp:=now;
743 UndoList^.Insert(UndoList^.CurrentGroupedAction);
744 UndoList^.CurrentGroupedAction:=nil;
745 UpdateUndoRedo(cmUndo,AAction);
746 end;
747 end;
748
TCodeEditorCore.GetUndoActionCountnull749 function TCodeEditorCore.GetUndoActionCount: sw_integer;
750 begin
751 GetUndoActionCount:=UndoList^.Count;
752 end;
753
TCodeEditorCore.GetRedoActionCountnull754 function TCodeEditorCore.GetRedoActionCount: sw_integer;
755 begin
756 GetRedoActionCount:=RedoList^.Count;
757 end;
758
759 destructor TCodeEditorCore.Done;
760 begin
761 inherited Done;
762 if Assigned(Lines) then Dispose(Lines, Done); Lines:=nil;
763 if Assigned(RedoList) then Dispose(RedoList, Done); RedoList:=nil;
764 if Assigned(UndoList) then Dispose(UndoList, Done); UndoList:=nil;
765 end;
766
767 constructor TIndicator.Init(var Bounds: TRect);
768 begin
769 inherited Init(Bounds);
770 GrowMode := gfGrowLoY + gfGrowHiY;
771 end;
772
773 procedure TIndicator.Draw;
774 var
775 Color: Byte;
776 Frame: Char;
777 L: array[0..1] of PtrInt;
778 S: String[15];
779 B: TDrawBuffer;
780 begin
781 if assigned(CodeOwner) and
782 (CodeOwner^.ELockFlag>0) then
783 begin
784 CodeOwner^.IndicatorDrawCalled:=true;
785 exit;
786 end;
787 if (State and sfDragging = 0) and (State and sfActive <> 0) then
788 begin
789 Color := GetColor(1);
790 Frame := #205;
791 end
792 else
793 begin
794 if (State and sfDragging)<>0 then
795 Color := GetColor(2)
796 else
797 Color := GetColor(3);
798 Frame := #196;
799 end;
800 MoveChar(B, Frame, Color, Size.X);
801 if State and sfActive<>0 then
802 begin
803 if Modified then
804 WordRec (B[0]).Lo := ord('*');
805 {$ifdef debug}
806 if StoreUndo then
807 WordRec (B[1]).Lo := ord('S');
808 if SyntaxComplete then
809 WordRec(B[2]).lo := ord('C');
810 if UseTabs then
811 WordRec(B[3]).lo := ord('T');
812 {$endif debug}
813 L[0] := Location.Y + 1;
814 L[1] := Location.X + 1;
815 FormatStr(S, ' %d:%d ', L);
816 MoveStr(B[8 - Pos(':', S)], S, Color);
817 end;
818 WriteBuf(0, 0, Size.X, 1, B);
819 end;
820
GetPalettenull821 function TIndicator.GetPalette: PPalette;
822 const
823 P: string[Length(CIndicator)] = CIndicator;
824 begin
825 GetPalette := @P;
826 end;
827
828 procedure TIndicator.SetState(AState: Word; Enable: Boolean);
829 begin
830 inherited SetState(AState, Enable);
831 if (AState = sfDragging) or (AState=sfActive) then
832 DrawView;
833 end;
834
835 procedure TIndicator.SetValue(ALocation: TPoint; AModified: Boolean);
836 begin
837 if (Location.X<>ALocation.X) or
838 (Location.Y<>ALocation.Y) or
839 (Modified <> AModified) then
840 begin
841 Location := ALocation;
842 Modified := AModified;
843 DrawView;
844 end;
845 end;
846
847 {constructor TIndicator.Load(var S: TStream);
848 begin
849 inherited Load(S);
850 S.Read(Location,SizeOf(Location));
851 S.Read(Modified,SizeOf(Modified));
852 end;
853
854 procedure TIndicator.Store(var S: TStream);
855 begin
856 inherited Store(S);
857 S.Write(Location,SizeOf(Location));
858 S.Write(Modified,SizeOf(Modified));
859 end;}
860
861 {*****************************************************************************
862 TCodeEditor
863 *****************************************************************************}
864
865 constructor TCodeEditor.Init(var Bounds: TRect; AHScrollBar, AVScrollBar:
866 PScrollBar; AIndicator: PIndicator; ACore: PCodeEditorCore);
867 begin
868 inherited Init(Bounds,AHScrollBar,AVScrollBar);
869 New(Folds, Init(100,100));
870 if ACore=nil then ACore:=New(PCodeEditorCore, Init);
871 Core:=ACore;
872 Core^.BindEditor(@Self);
873 SetState(sfCursorVis,true);
874 SetFlags(DefaultCodeEditorFlags);
875 SetCurPtr(0,0);
876 Indicator:=AIndicator;
877 if assigned(Indicator) then
878 Indicator^.CodeOwner:=@Self;
879 UpdateIndicator;
880 LimitsChanged;
881 end;
882
GetFlagsnull883 function TCodeEditor.GetFlags: longint;
884 begin
885 GetFlags:=Flags;
886 end;
887
888 procedure TCodeEditor.SetFlags(AFlags: longint);
889 var OFlags: longint;
890 begin
891 if AFlags<>Flags then
892 begin
893 OFlags:=Flags;
894 Flags:=AFlags;
895 FlagsChanged(OFlags);
896 end;
897 end;
898
TCodeEditor.GetModifiednull899 function TCodeEditor.GetModified: boolean;
900 begin
901 GetModified:=Core^.GetModified;
902 end;
903
904 procedure TCodeEditor.SetModified(AModified: boolean);
905 begin
906 Core^.SetModified(AModified);
907 end;
908
TCodeEditor.GetStoreUndonull909 function TCodeEditor.GetStoreUndo: boolean;
910 begin
911 GetStoreUndo:=Core^.GetStoreUndo;
912 end;
913
914 procedure TCodeEditor.SetStoreUndo(AStore: boolean);
915 begin
916 Core^.SetStoreUndo(AStore);
917 end;
918
919 procedure TCodeEditor.ClearUndoList;
920 begin
921 Core^.UndoList^.FreeAll;
922 Core^.RedoList^.FreeAll;
923 end;
924
GetSyntaxCompletednull925 function TCodeEditor.GetSyntaxCompleted: boolean;
926 begin
927 GetSyntaxCompleted:=Core^.GetSyntaxCompleted;
928 end;
929
930 procedure TCodeEditor.SetSyntaxCompleted(SC : boolean);
931 begin
932 Core^.SetSyntaxCompleted(SC);
933 UpdateIndicator;
934 end;
935
GetLastSyntaxedLinenull936 function TCodeEditor.GetLastSyntaxedLine: sw_integer;
937 begin
938 GetLastSyntaxedLine:=Core^.GetLastSyntaxedLine;
939 end;
940
941 procedure TCodeEditor.SetLastSyntaxedLine(ALine: sw_integer);
942 begin
943 Core^.SetLastSyntaxedLine(ALine);
944 end;
945
GetTabSizenull946 function TCodeEditor.GetTabSize: integer;
947 begin
948 GetTabSize:=Core^.GetTabSize;
949 end;
950
951 procedure TCodeEditor.SetTabSize(ATabSize: integer);
952 begin
953 Core^.SetTabSize(ATabSize);
954 end;
955
TCodeEditor.GetIndentSizenull956 function TCodeEditor.GetIndentSize: integer;
957 begin
958 GetIndentSize:=Core^.GetIndentSize;
959 end;
960
961 procedure TCodeEditor.SetIndentSize(AIndentSize: integer);
962 begin
963 Core^.SetIndentSize(AIndentSize);
964 end;
965
TCodeEditor.IsReadOnlynull966 function TCodeEditor.IsReadOnly: boolean;
967 begin
968 IsReadOnly:=ReadOnly or (Core^.ReadOnly);
969 end;
970
TCodeEditor.IsClipboardnull971 function TCodeEditor.IsClipboard: Boolean;
972 begin
973 IsClipboard:=Core^.IsClipboard;
974 end;
975
TCodeEditor.GetErrorMessagenull976 function TCodeEditor.GetErrorMessage: string;
977 begin
978 GetErrorMessage:=GetStr(ErrorMessage);
979 end;
980
981 procedure TCodeEditor.SetErrorMessage(const S: string);
982 begin
983 SetStr(ErrorMessage,S);
984 DrawView;
985 end;
986
TCodeEditor.GetLineCountnull987 function TCodeEditor.GetLineCount: sw_integer;
988 begin
989 GetLineCount:=Core^.GetLineCount;
990 end;
991
GetLinenull992 function TCodeEditor.GetLine(LineNo: sw_integer): PCustomLine;
993 begin
994 GetLine:=Core^.GetLine(LineNo);
995 end;
996
CharIdxToLinePosnull997 function TCodeEditor.CharIdxToLinePos(Line,CharIdx: sw_integer): sw_integer;
998 begin
999 CharIdxToLinePos:=Core^.CharIdxToLinePos(Line,CharIdx);
1000 end;
1001
TCodeEditor.LinePosToCharIdxnull1002 function TCodeEditor.LinePosToCharIdx(Line,X: sw_integer): sw_integer;
1003 begin
1004 LinePosToCharIdx:=Core^.LinePosToCharIdx(Line,X);
1005 end;
1006
TCodeEditor.GetLineTextnull1007 function TCodeEditor.GetLineText(I: sw_integer): string;
1008 begin
1009 GetLineText:=Core^.GetLineText(I);
1010 end;
1011
1012 procedure TCodeEditor.SetDisplayText(I: sw_integer;const S: string);
1013 begin
1014 Core^.SetDisplayText(I,S);
1015 end;
1016
GetDisplayTextnull1017 function TCodeEditor.GetDisplayText(I: sw_integer): string;
1018 begin
1019 GetDisplayText:=Core^.GetDisplayText(I);
1020 end;
1021
1022 procedure TCodeEditor.SetLineText(I: sw_integer;const S: string);
1023 begin
1024 Core^.SetLineText(I,S);
1025 end;
1026
1027 procedure TCodeEditor.GetDisplayTextFormat(I: sw_integer;var DT,DF:string);
1028 begin
1029 Core^.GetDisplayTextFormat(@Self,I,DT,DF);
1030 end;
1031
GetLineFormatnull1032 function TCodeEditor.GetLineFormat(I: sw_integer): string;
1033 begin
1034 GetLineFormat:=Core^.GetLineFormat(@Self,I);
1035 end;
1036
1037 procedure TCodeEditor.SetLineFormat(I: sw_integer;const S: string);
1038 begin
1039 Core^.SetLineFormat(@Self,I,S);
1040 end;
1041
1042 procedure TCodeEditor.DeleteAllLines;
1043 begin
1044 Core^.DeleteAllLines;
1045 end;
1046
1047 procedure TCodeEditor.DeleteLine(I: sw_integer);
1048 begin
1049 Core^.DeleteLine(I);
1050 end;
1051
TCodeEditor.InsertLinenull1052 function TCodeEditor.InsertLine(LineNo: sw_integer; const S: string): PCustomLine;
1053 begin
1054 InsertLine:=Core^.InsertLine(LineNo,S);
1055 end;
1056
1057 procedure TCodeEditor.AddLine(const S: string);
1058 begin
1059 Core^.AddLine(S);
1060 end;
1061
TCodeEditor.GetMaxFoldLevelnull1062 function TCodeEditor.GetMaxFoldLevel: sw_integer;
1063 begin
1064 GetMaxFoldLevel:=MaxFoldLevel;
1065 end;
1066
1067 procedure TCodeEditor.RegisterFold(AFold: PFold);
1068 var L: sw_integer;
1069 begin
1070 if Assigned(Folds) then
1071 begin
1072 Folds^.Insert(AFold);
1073 L:=AFold^.GetLevel+1;
1074 if L>MaxFoldLevel then MaxFoldLevel:=L;
1075 end;
1076 end;
1077
1078 procedure TCodeEditor.UnRegisterFold(AFold: PFold);
1079 begin
1080 if Assigned(Folds) then
1081 begin
1082 Folds^.Delete(AFold);
1083 if Folds^.Count=0 then
1084 MaxFoldLevel:=0
1085 else
1086 MaxFoldLevel:=inherited GetMaxFoldLevel+1;
1087 end;
1088 end;
1089
GetFoldCountnull1090 function TCodeEditor.GetFoldCount: sw_integer;
1091 begin
1092 GetFoldCount:=Folds^.Count;
1093 end;
1094
TCodeEditor.GetFoldnull1095 function TCodeEditor.GetFold(Index: sw_integer): PFold;
1096 begin
1097 GetFold:=Folds^.At(Index);
1098 end;
1099
1100 {function TCodeEditor.GetLineTextPos(Line,X: integer): integer;
1101 var
1102 S: string;
1103 rx,i : Sw_integer;
1104 begin
1105 S:=GetLineText(Line);
1106 i:=0; rx:=0;
1107 while (RX<X) and (i<Length(s)) do
1108 begin
1109 inc(i);
1110 inc(rx);
1111 if s[i]=#9 then
1112 inc(rx,TabSize-(rx mod tabsize));
1113 end;
1114 if RX<X then Inc(I,X-RX);
1115 GetLineTextPos:=i;
1116 end;
1117
GetDisplayTextPosnull1118 function TCodeEditor.GetDisplayTextPos(Line,X: integer): integer;
1119 var
1120 S: string;
1121 L: PCustomLine;
1122 rx,i : Sw_integer;
1123 begin
1124 S:='';
1125 if Line<Lines^.Count then
1126 begin
1127 L:=Lines^.At(Line);
1128 if assigned(L^.Text) then
1129 S:=L^.Text^;
1130 end;
1131 i:=0;
1132 rx:=0;
1133 while (i<X) and (i<Length(s)) do
1134 begin
1135 inc(i);
1136 inc(rx);
1137 if s[i]=#9 then
1138
1139
1140 inc(rx,TabSize-(rx mod tabsize));
1141 end;
1142 GetDisplayTextPos:=rx;
1143 end;}
1144
1145 procedure TCodeEditor.GetContent(ALines: PUnsortedStringCollection);
1146 begin
1147 Core^.GetContent(ALines);
1148 end;
1149
1150 procedure TCodeEditor.SetContent(ALines: PUnsortedStringCollection);
1151 begin
1152 Lock;
1153 TextStart; HideSelect;
1154 Core^.SetContent(ALines);
1155 LimitsChanged;
1156 if IsFlagSet(efSyntaxHighlight) then
1157 Core^.UpdateAttrsRange(0,Min(Delta.Y+Size.Y,GetLineCount-1),
1158 attrAll
1159 {$ifndef TEST_PARTIAL_SYNTAX}
1160 +attrForceFull
1161 {$endif TEST_PARTIAL_SYNTAX}
1162 );
1163 TextStart;
1164 UnLock;
1165 end;
1166
TCodeEditor.GetCodeCompleteFragnull1167 function TCodeEditor.GetCodeCompleteFrag: string;
1168 begin
1169 GetCodeCompleteFrag:=GetStr(CodeCompleteFrag);
1170 end;
1171
1172 procedure TCodeEditor.SetCodeCompleteFrag(const S: string);
1173 begin
1174 SetStr(CodeCompleteFrag,S);
1175 end;
1176
GetCompleteStatenull1177 function TCodeEditor.GetCompleteState: TCompleteState;
1178 begin
1179 GetCompleteState:=CompleteState;
1180 end;
1181
1182 procedure TCodeEditor.SetCompleteState(AState: TCompleteState);
1183 begin
1184 if AState<>CompleteState then
1185 begin
1186 CompleteState:=AState;
1187 if CompleteState<>csOffering then
1188 ClearCodeCompleteWord;
1189 end;
1190 end;
1191
TCodeEditor.GetCodeCompleteWordnull1192 function TCodeEditor.GetCodeCompleteWord: string;
1193 begin
1194 GetCodeCompleteWord:=GetStr(CodeCompleteWord);
1195 end;
1196
1197 procedure TCodeEditor.SetCodeCompleteWord(const S: string);
1198 begin
1199 if Assigned(CodeCompleteWord) then DisposeStr(CodeCompleteWord);
1200 CodeCompleteWord:=NewStr(S);
1201 inherited SetCodeCompleteWord(S);
1202 end;
1203
1204 procedure TCodeEditor.DrawIndicator;
1205 begin
1206 if Assigned(Indicator) then
1207 Indicator^.DrawView;
1208 end;
1209
1210 procedure TCodeEditor.Lock;
1211 begin
1212 inherited Lock;
1213 Core^.Lock(@Self);
1214 end;
1215
1216 procedure TCodeEditor.UnLock;
1217 begin
1218 Core^.UnLock(@Self);
1219 inherited UnLock;
1220 If (ELockFlag=0) and IndicatorDrawCalled then
1221 begin
1222 DrawIndicator;
1223 IndicatorDrawCalled:=false;
1224 end;
1225 end;
1226
1227 procedure TCodeEditor.UpdateIndicator;
1228 begin
1229 if Indicator<>nil then
1230 begin
1231 Indicator^.Location:=CurPos;
1232 Indicator^.Modified:=GetModified;
1233 {$ifdef debug}
1234 Indicator^.StoreUndo:=GetStoreUndo;
1235 {$ifdef TEST_PARTIAL_SYNTAX}
1236 Indicator^.SyntaxComplete:=GetSyntaxCompleted and IsFlagSet(efSyntaxHighlight);
1237 {$endif TEST_PARTIAL_SYNTAX}
1238 Indicator^.UseTabs:=IsFlagSet(efUseTabCharacters);
1239 {$endif debug}
1240 if Elockflag>0 then
1241 IndicatorDrawCalled:=true
1242 else
1243 Indicator^.DrawView;
1244 end;
1245 end;
1246
1247 procedure TCodeEditor.LimitsChanged;
1248 begin
1249 Core^.LimitsChanged;
1250 end;
1251
1252 procedure TCodeEditor.ModifiedChanged;
1253 begin
1254 UpdateIndicator;
1255 end;
1256
1257 procedure TCodeEditor.PositionChanged;
1258 begin
1259 UpdateIndicator;
1260 end;
1261
1262 procedure TCodeEditor.JumpToLastCursorPos;
1263 var
1264 pa : PEditorAction;
1265 begin
1266 if (Core^.UndoList^.count>0) and (Core^.RedoList^.count=0) then
1267 begin
1268 { Or should we just call Undo ?? PM }
1269 pa:=Core^.UndoList^.At(Core^.UndoList^.count-1);
1270 if (pa^.action=eaMoveCursor) then
1271 SetCurPtr(pa^.StartPos.X,pa^.StartPos.Y);
1272 end;
1273 end;
1274
1275 procedure TCodeEditor.Undo;
1276 var
1277 Temp,Idx,Last,Count : Longint;
1278 StoredFlags : longint;
1279 UndoTime : longint;
1280 WasInserting,IsGrouped,HadefNoIndent : boolean;
1281 MaxY,MinY : sw_integer;
1282 Line : String;
1283
1284 procedure SetMinMax(y : sw_integer);
1285 begin
1286 if MinY=-1 then
1287 MinY:=Y;
1288 if Y<MinY then
1289 MinY:=Y;
1290 if MaxY=-1 then
1291 MaxY:=Y;
1292 if Y>MaxY then
1293 MaxY:=Y;
1294 end;
1295 begin
1296 Core^.SetStoreUndo(False);
1297 Lock;
1298 MinY:=-1;
1299 MaxY:=-1;
1300 if Core^.UndoList^.count > 0 then
1301 begin
1302 Last:=Core^.UndoList^.count-1;
1303 if Core^.UndoList^.At(Last)^.Is_grouped_action then
1304 begin
1305 Count:=Core^.UndoList^.At(Last)^.ActionCount;
1306 UndoTime:=Core^.UndoList^.At(Last)^.TimeStamp;
1307 Dec(Last);
1308 IsGrouped:=true;
1309 end
1310 else
1311 begin
1312 Count:=1;
1313 IsGrouped:=false;
1314 end;
1315 for Idx:=Last downto Last-Count+1 do
1316 with Core^.UndoList^.At(Idx)^ do
1317 begin
1318 if not IsGrouped then
1319 UndoTime:=TimeStamp;
1320 case action of
1321 eaMoveCursor :
1322 begin
1323 { move cursor back to original position }
1324 SetCurPtr(startpos.x,startpos.y);
1325 end;
1326 eaInsertText :
1327 begin
1328 SetCurPtr(StartPos.X,StartPos.Y);
1329 if assigned(text) then
1330 for Temp := 1 to length(Text^) do
1331 DelChar;
1332 SetMinMax(StartPos.Y);
1333 end;
1334 eaDeleteText :
1335 begin
1336 { reinsert deleted text }
1337 SetCurPtr(EndPos.X,EndPos.Y);
1338 WasInserting:=GetInsertMode;
1339 SetInsertMode(true);
1340 if assigned(text) then
1341 for Temp := 1 to length(Text^) do
1342 AddChar(Text^[Temp]);
1343 SetInsertMode(WasInserting);
1344 SetMinMax(EndPos.Y);
1345 SetCurPtr(StartPos.X,StartPos.Y);
1346 end;
1347 eaOverwriteText :
1348 begin
1349 SetCurPtr(StartPos.X,StartPos.Y);
1350 Line:=GetDisplayText(StartPos.Y);
1351 WasInserting:=GetInsertMode;
1352 SetInsertMode(false);
1353 if assigned(text) then
1354 for Temp := 1 to length(Text^) do
1355 begin
1356 AddChar(Text^[Temp]);
1357 if StartPos.X+Temp>Length(Line) then
1358 Text^[Temp]:=' '
1359 else
1360 Text^[Temp]:=Line[StartPos.X+Temp];
1361 end;
1362 SetInsertMode(WasInserting);
1363 SetMinMax(EndPos.Y);
1364 SetCurPtr(StartPos.X,StartPos.Y);
1365 end;
1366 eaInsertLine :
1367 begin
1368 SetCurPtr(EndPos.X,EndPos.Y);
1369 Line:=Copy(GetDisplayText(StartPos.Y),1,StartPos.X);
1370 If Length(Line)<StartPos.X then
1371 Line:=Line+CharStr(' ',StartPos.X-length(Line))+GetStr(Text);
1372 SetDisplayText(StartPos.Y,Line+Copy(GetDisplayText(EndPos.Y),EndPos.X+1,255));
1373 SetMinMax(EndPos.Y);
1374 SetCurPtr(0,EndPos.Y);
1375 DeleteLine(EndPos.Y);
1376 SetCurPtr(StartPos.X,StartPos.Y);
1377 SetMinMax(StartPos.Y);
1378 end;
1379 eaDeleteLine :
1380 begin
1381 HadefNoIndent:=(GetFlags and efNoIndent)<>0;
1382 WasInserting:=GetInsertMode;
1383 SetInsertMode(true);
1384 SetFlags(GetFlags or efNoIndent);
1385 InsertLine(StartPos.Y,GetStr(Text));
1386 SetInsertMode(WasInserting);
1387 if not HadefNoIndent then
1388 SetFlags(GetFlags and not efNoIndent);
1389 {DelEnd; wrong for eaCut at least }
1390 SetCurPtr(StartPos.X,StartPos.Y);
1391 if StartPos.Y > EndPos.Y then
1392 SetLineText(EndPos.Y,Copy(GetDisplayText(EndPos.Y),1,EndPos.X));
1393 SetMinMax(StartPos.Y);
1394 end;
1395 eaSelectionChanged :
1396 begin
1397 { move cursor to end of last set selection }
1398 end;
1399 else
1400 { what the 'ell's an undefined action doing round 'ere mate! }
1401 ;
1402 end; { once this lot is done paste into redo and modify to suit needs }
1403 { move item to redo stack }
1404 Core^.RedoList^.Insert(Core^.UndoList^.At(Idx));
1405 UpdateUndoRedo(cmRedo,Core^.UndoList^.At(Idx)^.Action);
1406 Core^.UndoList^.atDelete(Idx);
1407 If Idx>0 then
1408 UpdateUndoRedo(cmUndo,Core^.UndoList^.At(Idx-1)^.Action)
1409 else
1410 UpdateUndoRedo(cmUndo,0);
1411 end;{Idx loop for grouped actions }
1412 if IsGrouped then
1413 begin
1414 Idx:=Core^.UndoList^.Count-1;
1415 Core^.RedoList^.Insert(Core^.UndoList^.At(Idx));
1416 UpdateUndoRedo(cmRedo,Core^.UndoList^.At(Idx)^.Action);
1417 Core^.UndoList^.atDelete(Idx);
1418 If Idx>0 then
1419 UpdateUndoRedo(cmUndo,Core^.UndoList^.At(Idx-1)^.Action)
1420 else
1421 UpdateUndoRedo(cmUndo,0);
1422 end;
1423 if Core^.UndoList^.count=0 then
1424 SetCmdState(UndoCmd,false);
1425 if (Core^.UndoList^.count=0) or
1426 ((Core^.UndoList^.count=1) and
1427 (Core^.UndoList^.At(0)^.Action=eaMoveCursor)) then
1428 begin
1429 SetCmdState(UndoCmd,false);
1430 if (UndoTime>=Core^.SystemLoadTime) or (Core^.SystemLoadTime=0) then
1431 SetModified(false);
1432 end;
1433 SetCmdState(RedoCmd,true);
1434 Message(Application,evBroadcast,cmCommandSetChanged,nil);
1435 if MinY<>-1 then
1436 UpdateAttrsRange(MinY,MaxY,attrAll);
1437 DrawView;
1438 end;
1439 Core^.SetStoreUndo(True);
1440 Unlock;
1441 end;
1442
1443 procedure TCodeEditor.Redo;
1444 var
1445 Temp,Idx,i,Last,Count : Longint;
1446 StoredFlags : longint;
1447 WasInserting,IsGrouped,ShouldInsertText : boolean;
1448 Line : String;
1449 MaxY,MinY : sw_integer;
1450 procedure SetMinMax(y : sw_integer);
1451 begin
1452 if MinY=-1 then
1453 MinY:=Y;
1454 if Y<MinY then
1455 MinY:=Y;
1456 if MaxY=-1 then
1457 MaxY:=Y;
1458 if Y>MaxY then
1459 MaxY:=Y;
1460 end;
1461 begin
1462 Core^.SetStoreUndo(False);
1463 Lock;
1464 MinY:=-1;
1465 MaxY:=-1;
1466 if Core^.RedoList^.count <> 0 then
1467 begin
1468 Last:=Core^.RedoList^.count-1;
1469 if Core^.RedoList^.At(Last)^.Is_grouped_action then
1470 begin
1471 Count:=Core^.RedoList^.At(Last)^.ActionCount;
1472 Dec(Last);
1473 IsGrouped:=true;
1474 end
1475 else
1476 begin
1477 Count:=1;
1478 IsGrouped:=false;
1479 end;
1480 for Idx:=Last downto Last-Count+1 do
1481 with Core^.RedoList^.At(Idx)^ do
1482 begin
1483 case action of
1484 eaMoveCursor :
1485 begin
1486 { move cursor back to original position }
1487 SetCurPtr(EndPos.X,EndPos.Y);
1488 end;
1489 eaInsertText :
1490 begin
1491 SetCurPtr(startpos.x,startpos.y);
1492 InsertText(GetStr(Text));
1493 SetMinMax(StartPos.Y);
1494 end;
1495 eaDeleteText :
1496 begin
1497 SetCurPtr(EndPos.X,EndPos.Y);
1498 for Temp := 1 to length(GetStr(Text)) do
1499 DelChar;
1500 SetMinMax(EndPos.Y);
1501 end;
1502 eaOverwriteText :
1503 begin
1504 SetCurPtr(StartPos.X,StartPos.Y);
1505 Line:=GetDisplayText(StartPos.Y);
1506 WasInserting:=GetInsertMode;
1507 SetInsertMode(false);
1508 if assigned(text) then
1509 for Temp := 1 to length(Text^) do
1510 begin
1511 AddChar(Text^[Temp]);
1512 if StartPos.X+Temp>Length(Line) then
1513 Text^[Temp]:=' '
1514 else
1515 Text^[Temp]:=Line[StartPos.X+Temp];
1516 end;
1517 SetInsertMode(WasInserting);
1518 SetCurPtr(EndPos.X,EndPos.Y);
1519 SetMinMax(StartPos.Y);
1520 end;
1521 eaInsertLine :
1522 begin
1523 SetCurPtr(StartPos.X,StartPos.Y);
1524 StoredFlags:=GetFlags;
1525 SetFlags(Flags);
1526 InsertNewLine;
1527 SetCurPtr(0,EndPos.Y);
1528 Line:=GetStr(Text);
1529 ShouldInsertText:=false;
1530 for I:=1 to Length(Line) do
1531 if Line[I]<>' ' then
1532 ShouldInsertText:=true;
1533 If ShouldInsertText then
1534 InsertText(Line);
1535 SetFlags(StoredFlags);
1536 SetCurPtr(EndPos.X,EndPos.Y);
1537 SetMinMax(StartPos.Y);
1538 end;
1539 eaDeleteLine :
1540 begin
1541 SetCurPtr(StartPos.X,StartPos.Y);
1542 DeleteLine(StartPos.Y);
1543 SetCurPtr(EndPos.X,EndPos.Y);
1544 if EndPos.Y=StartPos.Y-1 then
1545 SetDisplayText(EndPos.Y,RExpand(
1546 copy(GetDisplayText(EndPos.Y),1,EndPos.X),EndPos.X)
1547 +GetStr(Text));
1548 SetCurPtr(EndPos.X,EndPos.Y);
1549 SetMinMax(StartPos.Y);
1550 SetMinMax(EndPos.Y);
1551 end;
1552 eaSelectionChanged :
1553 begin
1554 { move cursor to end of last set test selection }
1555 end;
1556 else
1557 { what the 'ell's an undefined action doing round 'ere mate! }
1558 ;
1559 end; { once this lot is done paste back into undo and modify to suit needs }
1560 { move item to undo stack }
1561 Core^.UndoList^.Insert(Core^.RedoList^.At(Idx));
1562 UpdateUndoRedo(cmUndo,Core^.RedoList^.At(Idx)^.Action);
1563 If Idx>0 then
1564 UpdateUndoRedo(cmRedo,Core^.RedoList^.At(Idx-1)^.Action)
1565 else
1566 UpdateUndoRedo(cmRedo,0);
1567 Core^.RedoList^.atDelete(Idx);
1568 end;{ Idx loop for grouped action }
1569 If IsGrouped then
1570 begin
1571 Idx:=Core^.RedoList^.count-1;
1572 Core^.UndoList^.Insert(Core^.RedoList^.At(Idx));
1573 UpdateUndoRedo(cmUndo,Core^.RedoList^.At(Idx)^.Action);
1574 If Idx>0 then
1575 UpdateUndoRedo(cmRedo,Core^.RedoList^.At(Idx-1)^.Action)
1576 else
1577 UpdateUndoRedo(cmRedo,0);
1578 Core^.RedoList^.atDelete(Idx);
1579 end;
1580 if Core^.RedoList^.count=0 then
1581 SetCmdState(RedoCmd,false);
1582 SetCmdState(UndoCmd,true);
1583 Message(Application,evBroadcast,cmCommandSetChanged,nil);
1584 if MinY<>-1 then
1585 UpdateAttrsRange(MinY,MaxY,attrAll);
1586 DrawView;
1587 end;
1588 Core^.SetStoreUndo(True);
1589 Unlock;
1590 end;
1591
1592 (*constructor TCodeEditor.Load(var S: TStream);
1593 var TS: PSubStream;
1594 TSize: longint;
1595 begin
1596 inherited Load(S);
1597
1598 New(UndoList,init(500,1000));
1599 New(RedoList,init(500,1000));
1600
1601 New(Lines, Init(500,1000));
1602 { we have always need at least 1 line }
1603 LinesInsert(New(PLine, Init('',0)));
1604
1605 GetPeerViewPtr(S,Indicator);
1606 S.Read(Flags,SizeOf(Flags));
1607 S.Read(TabSize,SizeOf(TabSize));
1608
1609 if IsFlagSet(efStoreContent) then
1610 begin
1611 S.Read(TSize,SizeOf(TSize));
1612 New(TS, Init(@S,S.GetPos,TSize));
1613 {$ifdef TEST_PARTIAL_SYNTAX}
1614 Core^.SearchBinding(Editor)^.SyntaxComplete:=false;
1615 { Idle necessary }
1616 EventMask:=EventMask or evIdle;
1617 {$endif TEST_PARTIAL_SYNTAX}
1618 LoadFromStream(TS);
1619 Dispose(TS, Done);
1620 end;
1621
1622 S.Read(SelStart,SizeOf(SelStart));
1623 S.Read(SelEnd,SizeOf(SelEnd));
1624 S.Read(Highlight,SizeOf(Highlight));
1625 S.Read(CurPos,SizeOf(CurPos));
1626 S.Read(StoreUndo,SizeOf(StoreUndo));
1627 S.Read(IsReadOnly,SizeOf(IsReadOnly));
1628 S.Read(NoSelect,SizeOf(NoSelect));
1629 S.Read(HighlightRow,SizeOf(HighlightRow));
1630 SetDebuggerRow(-1);
1631
1632 LimitsChanged;
1633 SelectionChanged; HighlightChanged;
1634 UpdateIndicator;
1635 end;
1636
1637 procedure TCodeEditor.Store(var S: TStream);
1638 var {NS: TNulStream;}
1639 TSizePos,TSize,EndPos: longint;
1640 begin
1641 inherited Store(S);
1642
1643 PutPeerViewPtr(S,Indicator);
1644 S.Write(Flags,SizeOf(Flags));
1645 S.Write(TabSize,SizeOf(TabSize));
1646
1647 if IsFlagSet(efStoreContent) then
1648 begin
1649 { NS.Init;
1650 SaveToStream(@NS);
1651 TSize:=NS.GetSize;
1652 NS.Done;
1653 This is waste of time PM
1654 use Seek instead !! }
1655 { yep. and this won't work for serial streams. - Gabor }
1656 TSize:=0;
1657 TSizePos:=S.GetPos;
1658 S.Write(TSize,SizeOf(TSize));
1659 SaveToStream(@S);
1660 EndPos:=S.GetPos;
1661 TSize:=EndPos-TSizePos-SizeOf(TSize);
1662 S.Seek(TSizePos);
1663 S.Write(TSize,SizeOf(TSize));
1664 S.Seek(EndPos);
1665 end;
1666
1667 S.Write(SelStart,SizeOf(SelStart));
1668 S.Write(SelEnd,SizeOf(SelEnd));
1669 S.Write(Highlight,SizeOf(Highlight));
1670 S.Write(CurPos,SizeOf(CurPos));
1671 S.Write(StoreUndo,SizeOf(StoreUndo));
1672 S.Write(IsReadOnly,SizeOf(IsReadOnly));
1673 S.Write(NoSelect,SizeOf(NoSelect));
1674 S.Write(HighlightRow,SizeOf(HighlightRow));
1675 end;*)
1676
TCodeEditor.LoadFromStreamnull1677 function TCodeEditor.LoadFromStream(Stream: PFastBufStream): boolean;
1678 var OK: boolean;
1679 begin
1680 OK:=Core^.LoadFromStream(@Self,Stream);
1681 if IsFlagSet(efSyntaxHighlight) then
1682 UpdateAttrsRange(0,Min(Delta.Y+Size.Y,GetLineCount-1),
1683 attrAll
1684 {$ifndef TEST_PARTIAL_SYNTAX}
1685 +attrForceFull
1686 {$endif TEST_PARTIAL_SYNTAX}
1687 );
1688 TextStart;
1689 LoadFromStream:=OK;
1690 end;
1691
SaveToStreamnull1692 function TCodeEditor.SaveToStream(Stream: PStream): boolean;
1693 begin
1694 SaveToStream:=Core^.SaveToStream(@Self,Stream);
1695 end;
1696
SaveAreaToStreamnull1697 function TCodeEditor.SaveAreaToStream(Stream: PStream; StartP,EndP: TPoint): boolean;
1698 begin
1699 SaveAreaToStream:=Core^.SaveAreaToStream(@Self,Stream,StartP,EndP);
1700 end;
1701
TCodeEditor.UpdateAttrsnull1702 function TCodeEditor.UpdateAttrs(FromLine: sw_integer; Attrs: byte): sw_integer;
1703 begin
1704 UpdateAttrs:=Core^.UpdateAttrs(FromLine,Attrs);
1705 end;
1706
UpdateAttrsRangenull1707 function TCodeEditor.UpdateAttrsRange(FromLine, ToLine: sw_integer; Attrs: byte): sw_integer;
1708 begin
1709 UpdateAttrsRange:=Core^.UpdateAttrsRange(FromLine,ToLine,Attrs);
1710 end;
1711
1712 procedure TCodeEditor.AddAction(AAction: byte; AStartPos, AEndPos: TPoint; AText: string;AFlags : longint);
1713 begin
1714 Core^.AddAction(AAction,AStartPos,AEndPos,AText,AFlags);
1715 end;
1716
1717 procedure TCodeEditor.AddGroupedAction(AAction : byte);
1718 begin
1719 Core^.AddGroupedAction(AAction);
1720 end;
1721
1722 procedure TCodeEditor.CloseGroupedAction(AAction : byte);
1723 begin
1724 Core^.CloseGroupedAction(AAction);
1725 end;
1726
GetUndoActionCountnull1727 function TCodeEditor.GetUndoActionCount: sw_integer;
1728 begin
1729 GetUndoActionCount:=Core^.GetUndoActionCount;
1730 end;
1731
TCodeEditor.GetRedoActionCountnull1732 function TCodeEditor.GetRedoActionCount: sw_integer;
1733 begin
1734 GetRedoActionCount:=Core^.GetRedoActionCount;
1735 end;
1736
1737 destructor TCodeEditor.Done;
1738 begin
1739 inherited Done;
1740 if Assigned(Core) then
1741 begin
1742 Core^.UnBindEditor(@Self);
1743 if Core^.CanDispose then
1744 Dispose(Core, Done);
1745 end;
1746 Core:=nil;
1747 if Assigned(CodeCompleteFrag) then
1748 DisposeStr(CodeCompleteFrag);
1749 if Assigned(CodeCompleteWord) then
1750 DisposeStr(CodeCompleteWord);
1751 if Assigned(ErrorMessage) then
1752 DisposeStr(ErrorMessage);
1753 if Assigned(Folds) then
1754 Dispose(Folds, Done);
1755 Folds:=nil;
1756 end;
1757
1758 constructor TFileEditor.Init(var Bounds: TRect; AHScrollBar, AVScrollBar:
1759 PScrollBar; AIndicator: PIndicator;ACore: PCodeEditorCore; const AFileName: string);
1760 begin
1761 inherited Init(Bounds,AHScrollBAr,AVScrollBAr,AIndicator,ACore);
1762 FileName:=AFileName;
1763 UpdateIndicator;
1764 Message(@Self,evBroadcast,cmFileNameChanged,@Self);
1765 end;
1766
LoadFilenull1767 function TFileEditor.LoadFile: boolean;
1768 var OK: boolean;
1769 PA : Array[1..2] of pointer;
1770 begin
1771 OK:=LoadFromFile(FileName);
1772 if GetModified and (Core^.GetBindingCount=1) then
1773 begin
1774 PA[1]:=@FileName;
1775 Ptrint(PA[2]):=Core^.GetChangedLine;
1776 EditorDialog(edChangedOnloading,@PA);
1777 end;
1778 Core^.OnDiskLoadTime:=Cardinal(GetFileTime(FileName));
1779 Core^.SystemLoadTime:=Core^.OnDiskLoadTime;
1780 LoadFile:=OK;
1781 end;
1782
TFileEditor.IsChangedOnDisknull1783 function TFileEditor.IsChangedOnDisk : boolean;
1784 begin
1785 IsChangedOnDisk:=(Core^.OnDiskLoadTime<>Cardinal(GetFileTime(FileName))) and
1786 (Core^.OnDiskLoadTime<>0);
1787 end;
1788
SaveFilenull1789 function TFileEditor.SaveFile: boolean;
1790 var OK: boolean;
1791 BAKName: string;
1792 f: text;
1793 SaveTime : cardinal;
1794 begin
1795 If IsChangedOnDisk then
1796 begin
1797 if EditorDialog(edFileOnDiskChanged, @FileName) <> cmYes then
1798 begin
1799 SaveFile:=false;
1800 exit;
1801 end;
1802 end;
1803 {$I-}
1804 if IsFlagSet(efBackupFiles) and ExistsFile(FileName) then
1805 begin
1806 BAKName:=DirAndNameOf(FileName)+'.bak';
1807 Assign(f,BAKName);
1808 Erase(f);
1809 EatIO;
1810 Assign(f,FileName);
1811 Rename(F,BAKName);
1812 EatIO;
1813 end;
1814 {$I+}
1815 SaveTime:=cardinal(now);
1816 OK:=SaveToFile(FileName);
1817 if OK then
1818 SetModified(false)
1819 { Restore the original }
1820 else if IsFlagSet(efBackupFiles) and ExistsFile(BakName) then
1821 begin
1822 {$I-}
1823 Assign(f,BakName);
1824 Rename(F,FileName);
1825 EatIO;
1826 {$I+}
1827 end;
1828 { don't forget to update the OnDiskLoadTime value }
1829 if OK then
1830 begin
1831 Core^.OnDiskLoadTime:=Cardinal(GetFileTime(FileName));
1832 Core^.SystemLoadTime:=SaveTime;
1833 end;
1834 if not OK then
1835 EditorDialog(edSaveError,@FileName);
1836 SaveFile:=OK;
1837 end;
1838
ReloadFilenull1839 function TFileEditor.ReloadFile: boolean;
1840 var OK,WasModified: boolean;
1841 BAKName: string;
1842 f: text;
1843 begin
1844 If not IsChangedOnDisk then
1845 begin
1846 ReloadFile:=false;
1847 exit;
1848 end;
1849 WasModified:=GetModified;
1850 if not WasModified then
1851 OK:=EditorDialog(edreloaddiskmodifiedfile, @FileName)=cmYes
1852 else
1853 OK:=EditorDialog(edreloaddiskandidemodifiedfile, @FileName)=cmYes;
1854 if not OK then
1855 begin
1856 ReloadFile:=false;
1857 exit;
1858 end;
1859 { avoid wrong message }
1860 if WasModified then
1861 SetModified(false);
1862 OK:=LoadFile;
1863 if OK then
1864 begin
1865 SetModified(false);
1866 ClearUndoList;
1867 { don't forget to update the OnDiskLoadTime value }
1868 Core^.OnDiskLoadTime:=Cardinal(GetFileTime(FileName));
1869 Core^.SystemLoadTime:=Core^.OnDiskLoadTime;
1870 DrawView;
1871 end
1872 else
1873 begin
1874 if WasModified then
1875 SetModified(true);
1876 EditorDialog(edReadError,@FileName);
1877 end;
1878 ReloadFile:=OK;
1879 end;
1880
TFileEditor.ShouldSavenull1881 function TFileEditor.ShouldSave: boolean;
1882 begin
1883 ShouldSave:=GetModified{ or (FileName='')};
1884 end;
1885
TFileEditor.Savenull1886 function TFileEditor.Save: Boolean;
1887 begin
1888 if ShouldSave=false then begin Save:=true; Exit; end;
1889 if FileName = '' then Save := SaveAs else Save := SaveFile;
1890 end;
1891
TFileEditor.SaveAsnull1892 function TFileEditor.SaveAs: Boolean;
1893 var
1894 SavedName : String;
1895 SavedDiskLoadTime : cardinal;
1896 begin
1897 SaveAs := False;
1898 SavedName:=FileName;
1899 SavedDiskLoadTime:=Core^.OnDiskLoadTime;
1900 if EditorDialog(edSaveAs, @FileName) <> cmCancel then
1901 begin
1902 FileName:=FExpand(FileName);
1903 Message(Owner, evBroadcast, cmUpdateTitle, @Self);
1904 { if we rename the file the OnDiskLoadTime is wrong so we reset it }
1905 Core^.OnDiskLoadTime:=0;
1906 if SaveFile then
1907 begin
1908 SaveAs := true;
1909 end
1910 else
1911 begin
1912 FileName:=SavedName;
1913 Core^.OnDiskLoadTime:=SavedDiskLoadTime;
1914 Message(Owner, evBroadcast, cmUpdateTitle, @Self);
1915 end;
1916 if IsClipboard then FileName := '';
1917 Message(Application,evBroadcast,cmFileNameChanged,@Self);
1918 end;
1919 end;
1920
SaveAsknull1921 function TFileEditor.SaveAsk(Force: boolean): boolean;
1922 var OK: boolean;
1923 D: Sw_integer;
1924 begin
1925 if Force then
1926 begin
1927 if GetModified then
1928 OK:=Save
1929 else
1930 OK:=true;
1931 end
1932 else
1933 begin
1934 OK:=(GetModified=false);
1935 if (OK=false) and (Core^.GetBindingCount>1) then
1936 OK:=true;
1937 if OK=false then
1938 begin
1939 if FileName = '' then D := edSaveUntitled else D := edSaveModify;
1940 case EditorDialog(D, @FileName) of
1941 cmYes : OK := Save;
1942 cmNo : begin
1943 { the file should be still marked as modified! (FK) }
1944 { SetModified(False); }
1945 OK:=true;
1946 end;
1947 cmCancel : begin
1948 OK := False;
1949 Message(Application,evBroadcast,cmSaveCancelled,@Self);
1950 end;
1951 end;
1952 end;
1953 end;
1954 SaveAsk:=OK;
1955 end;
1956
1957 procedure TFileEditor.BindingsChanged;
1958 begin
1959 Message(Application,evBroadcast,cmUpdateTitle,@Self);
1960 end;
1961
1962 procedure TFileEditor.HandleEvent(var Event: TEvent);
1963 var SH,B: boolean;
1964 begin
1965 case Event.What of
1966 evBroadcast :
1967 case Event.Command of
1968 cmFileNameChanged :
1969 if (Event.InfoPtr=nil) or (Event.InfoPtr=@Self) then
1970 begin
1971 B:=IsFlagSet(efSyntaxHighlight);
1972 SH:=UseSyntaxHighlight(@Self);
1973 if SH<>B then
1974 if SH then
1975 SetFlags(Flags or efSyntaxHighlight)
1976 else
1977 SetFlags(Flags and not efSyntaxHighlight);
1978 if UseTabsPattern(@Self) then
1979 SetFlags(Flags or efUseTabCharacters);
1980 end;
1981 end;
1982 end;
1983 inherited HandleEvent(Event);
1984 end;
1985
TFileEditor.Validnull1986 function TFileEditor.Valid(Command: Word): Boolean;
1987 var OK: boolean;
1988 begin
1989 OK:=inherited Valid(Command);
1990 if OK and (Command=cmClose) then
1991 if IsClipboard=false then
1992 OK:=SaveAsk(false);
1993 Valid:=OK;
1994 end;
1995
1996 (* constructor TFileEditor.Load(var S: TStream);
1997 var P: PString;
1998 SSP,SEP,CP,DP: TPoint;
1999 HR: TRect;
2000 PA : Array[1..2] of pointer;
2001 HoldUndo : boolean;
2002 begin
2003 inherited Load(S);
2004 HoldUndo:=GetStoreUndo;
2005 SetStoreUndo(False);
2006 P:=S.ReadStr;
2007 FileName:=GetStr(P);
2008 if P<>nil then DisposeStr(P);
2009
2010 UpdateIndicator;
2011 { Message(@Self,evBroadcast,cmFileNameChanged,@Self);}
2012
2013 SSP:=SelStart; SEP:=SelEnd;
2014 CP:=CurPos;
2015 HR:=Highlight;
2016 DP:=Delta;
2017
2018 if FileName<>'' then
2019 LoadFile;
2020
2021 { if GetModified then
2022 begin
2023 PA[1]:=@FileName;
2024 longint(PA[2]):=ChangedLine;
2025 EditorDialog(edChangedOnloading,@PA);
2026 end;}
2027
2028 SetHighlight(HR.A,HR.B);
2029 SetSelection(SSP,SEP);
2030 SetCurPtr(CP.X,CP.Y);
2031 ScrollTo(DP.X,DP.Y);
2032 SetModified(false);
2033
2034 LimitsChanged;
2035 SetStoreUndo(HoldUndo);
2036 end;
2037
2038 procedure TFileEditor.Store(var S: TStream);
2039 begin
2040 inherited Store(S);
2041 S.WriteStr(@FileName);
2042 end;
2043 *)
2044
DefUseSyntaxHighlightnull2045 function DefUseSyntaxHighlight(Editor: PFileEditor): boolean;
2046 begin
2047 DefUseSyntaxHighlight:=Editor^.IsFlagSet(efSyntaxHighlight);
2048 end;
2049
DefUseTabsPatternnull2050 function DefUseTabsPattern(Editor: PFileEditor): boolean;
2051 begin
2052 DefUseTabsPattern:=Editor^.IsFlagSet(efUseTabCharacters);
2053 end;
2054
2055 procedure RegisterWCEdit;
2056 begin
2057 {$ifndef NOOBJREG}
2058 RegisterType(RIndicator);
2059 RegisterType(RCodeEditor);
2060 RegisterType(RFileEditor);
2061 {$endif}
2062 end;
2063
2064 end.
2065