wcedit.pas 56 KB

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