wcedit.pas 55 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067
  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(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+
  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,
  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: Char;
  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,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. if assigned(text) then
  1209. for Temp := 1 to length(Text^) do
  1210. AddChar(Text^[Temp]);
  1211. SetInsertMode(WasInserting);
  1212. SetMinMax(EndPos.Y);
  1213. SetCurPtr(StartPos.X,StartPos.Y);
  1214. end;
  1215. eaOverwriteText :
  1216. begin
  1217. SetCurPtr(StartPos.X,StartPos.Y);
  1218. Line:=GetDisplayText(StartPos.Y);
  1219. WasInserting:=GetInsertMode;
  1220. SetInsertMode(false);
  1221. if assigned(text) then
  1222. for Temp := 1 to length(Text^) do
  1223. begin
  1224. AddChar(Text^[Temp]);
  1225. if StartPos.X+Temp>Length(Line) then
  1226. Text^[Temp]:=' '
  1227. else
  1228. Text^[Temp]:=Line[StartPos.X+Temp];
  1229. end;
  1230. SetInsertMode(WasInserting);
  1231. SetMinMax(EndPos.Y);
  1232. SetCurPtr(StartPos.X,StartPos.Y);
  1233. end;
  1234. eaInsertLine :
  1235. begin
  1236. SetCurPtr(EndPos.X,EndPos.Y);
  1237. Line:=Copy(GetDisplayText(StartPos.Y),1,StartPos.X);
  1238. If Length(Line)<StartPos.X then
  1239. Line:=Line+CharStr(' ',StartPos.X-length(Line))+GetStr(Text);
  1240. SetDisplayText(StartPos.Y,Line+Copy(GetDisplayText(EndPos.Y),EndPos.X+1,255));
  1241. SetMinMax(EndPos.Y);
  1242. SetCurPtr(0,EndPos.Y);
  1243. DeleteLine(EndPos.Y);
  1244. SetCurPtr(StartPos.X,StartPos.Y);
  1245. SetMinMax(StartPos.Y);
  1246. end;
  1247. eaDeleteLine :
  1248. begin
  1249. HadefNoIndent:=(GetFlags and efNoIndent)<>0;
  1250. WasInserting:=GetInsertMode;
  1251. SetInsertMode(true);
  1252. SetFlags(GetFlags or efNoIndent);
  1253. InsertLine(StartPos.Y,'');
  1254. SetInsertMode(WasInserting);
  1255. if not HadefNoIndent then
  1256. SetFlags(GetFlags and not efNoIndent);
  1257. {DelEnd; wrong for eaCut at least }
  1258. SetCurPtr(StartPos.X,StartPos.Y);
  1259. SetLineText(StartPos.Y,Copy(GetDisplayText(StartPos.Y),1,StartPos.X)+GetStr(Text));
  1260. SetMinMax(StartPos.Y);
  1261. end;
  1262. eaSelectionChanged :
  1263. begin
  1264. { move cursor to end of last set selection }
  1265. end;
  1266. else
  1267. { what the 'ell's an undefined action doing round 'ere mate! }
  1268. ;
  1269. end; { once this lot is done paste into redo and modify to suit needs }
  1270. { move item to redo stack }
  1271. Core^.RedoList^.Insert(Core^.UndoList^.At(Idx));
  1272. UpdateUndoRedo(cmRedo,Core^.UndoList^.At(Idx)^.Action);
  1273. Core^.UndoList^.atDelete(Idx);
  1274. If Idx>0 then
  1275. UpdateUndoRedo(cmUndo,Core^.UndoList^.At(Idx-1)^.Action)
  1276. else
  1277. UpdateUndoRedo(cmUndo,0);
  1278. end;{Idx loop for grouped actions }
  1279. if IsGrouped then
  1280. begin
  1281. Idx:=Core^.UndoList^.Count-1;
  1282. Core^.RedoList^.Insert(Core^.UndoList^.At(Idx));
  1283. UpdateUndoRedo(cmRedo,Core^.UndoList^.At(Idx)^.Action);
  1284. Core^.UndoList^.atDelete(Idx);
  1285. If Idx>0 then
  1286. UpdateUndoRedo(cmUndo,Core^.UndoList^.At(Idx-1)^.Action)
  1287. else
  1288. UpdateUndoRedo(cmUndo,0);
  1289. end;
  1290. if Core^.UndoList^.count=0 then
  1291. SetCmdState(UndoCmd,false);
  1292. if (Core^.UndoList^.count=0) or
  1293. ((Core^.UndoList^.count=1) and
  1294. (Core^.UndoList^.At(0)^.Action=eaMoveCursor)) then
  1295. begin
  1296. SetCmdState(UndoCmd,false);
  1297. if (UndoTime>=Core^.SystemLoadTime) or (Core^.SystemLoadTime=0) then
  1298. SetModified(false);
  1299. end;
  1300. SetCmdState(RedoCmd,true);
  1301. Message(Application,evBroadcast,cmCommandSetChanged,nil);
  1302. if MinY<>-1 then
  1303. UpdateAttrsRange(MinY,MaxY,attrAll);
  1304. DrawView;
  1305. end;
  1306. Core^.SetStoreUndo(True);
  1307. Unlock;
  1308. end;
  1309. procedure TCodeEditor.Redo;
  1310. var
  1311. Temp,Idx,i,Last,Count : Longint;
  1312. StoredFlags : longint;
  1313. WasInserting,IsGrouped,ShouldInsertText : boolean;
  1314. Line : String;
  1315. MaxY,MinY : sw_integer;
  1316. procedure SetMinMax(y : sw_integer);
  1317. begin
  1318. if MinY=-1 then
  1319. MinY:=Y;
  1320. if Y<MinY then
  1321. MinY:=Y;
  1322. if MaxY=-1 then
  1323. MaxY:=Y;
  1324. if Y>MaxY then
  1325. MaxY:=Y;
  1326. end;
  1327. begin
  1328. Core^.SetStoreUndo(False);
  1329. Lock;
  1330. MinY:=-1;
  1331. MaxY:=-1;
  1332. if Core^.RedoList^.count <> 0 then
  1333. begin
  1334. Last:=Core^.RedoList^.count-1;
  1335. if Core^.RedoList^.At(Last)^.Is_grouped_action then
  1336. begin
  1337. Count:=Core^.RedoList^.At(Last)^.ActionCount;
  1338. Dec(Last);
  1339. IsGrouped:=true;
  1340. end
  1341. else
  1342. begin
  1343. Count:=1;
  1344. IsGrouped:=false;
  1345. end;
  1346. for Idx:=Last downto Last-Count+1 do
  1347. with Core^.RedoList^.At(Idx)^ do
  1348. begin
  1349. case action of
  1350. eaMoveCursor :
  1351. begin
  1352. { move cursor back to original position }
  1353. SetCurPtr(EndPos.X,EndPos.Y);
  1354. end;
  1355. eaInsertText :
  1356. begin
  1357. SetCurPtr(startpos.x,startpos.y);
  1358. InsertText(GetStr(Text));
  1359. SetMinMax(StartPos.Y);
  1360. end;
  1361. eaDeleteText :
  1362. begin
  1363. SetCurPtr(EndPos.X,EndPos.Y);
  1364. for Temp := 1 to length(GetStr(Text)) do
  1365. DelChar;
  1366. SetMinMax(EndPos.Y);
  1367. end;
  1368. eaOverwriteText :
  1369. begin
  1370. SetCurPtr(StartPos.X,StartPos.Y);
  1371. Line:=GetDisplayText(StartPos.Y);
  1372. WasInserting:=GetInsertMode;
  1373. SetInsertMode(false);
  1374. if assigned(text) then
  1375. for Temp := 1 to length(Text^) do
  1376. begin
  1377. AddChar(Text^[Temp]);
  1378. if StartPos.X+Temp>Length(Line) then
  1379. Text^[Temp]:=' '
  1380. else
  1381. Text^[Temp]:=Line[StartPos.X+Temp];
  1382. end;
  1383. SetInsertMode(WasInserting);
  1384. SetCurPtr(EndPos.X,EndPos.Y);
  1385. SetMinMax(StartPos.Y);
  1386. end;
  1387. eaInsertLine :
  1388. begin
  1389. SetCurPtr(StartPos.X,StartPos.Y);
  1390. StoredFlags:=GetFlags;
  1391. SetFlags(Flags);
  1392. InsertNewLine;
  1393. SetCurPtr(0,EndPos.Y);
  1394. Line:=GetStr(Text);
  1395. ShouldInsertText:=false;
  1396. for I:=1 to Length(Line) do
  1397. if Line[I]<>' ' then
  1398. ShouldInsertText:=true;
  1399. If ShouldInsertText then
  1400. InsertText(Line);
  1401. SetFlags(StoredFlags);
  1402. SetCurPtr(EndPos.X,EndPos.Y);
  1403. SetMinMax(StartPos.Y);
  1404. end;
  1405. eaDeleteLine :
  1406. begin
  1407. SetCurPtr(StartPos.X,StartPos.Y);
  1408. DeleteLine(StartPos.Y);
  1409. SetCurPtr(EndPos.X,EndPos.Y);
  1410. if EndPos.Y=StartPos.Y-1 then
  1411. SetDisplayText(EndPos.Y,RExpand(
  1412. copy(GetDisplayText(EndPos.Y),1,EndPos.X),EndPos.X)
  1413. +GetStr(Text));
  1414. SetCurPtr(EndPos.X,EndPos.Y);
  1415. SetMinMax(StartPos.Y);
  1416. SetMinMax(EndPos.Y);
  1417. end;
  1418. eaSelectionChanged :
  1419. begin
  1420. { move cursor to end of last set test selection }
  1421. end;
  1422. else
  1423. { what the 'ell's an undefined action doing round 'ere mate! }
  1424. ;
  1425. end; { once this lot is done paste back into undo and modify to suit needs }
  1426. { move item to undo stack }
  1427. Core^.UndoList^.Insert(Core^.RedoList^.At(Idx));
  1428. UpdateUndoRedo(cmUndo,Core^.RedoList^.At(Idx)^.Action);
  1429. If Idx>0 then
  1430. UpdateUndoRedo(cmRedo,Core^.RedoList^.At(Idx-1)^.Action)
  1431. else
  1432. UpdateUndoRedo(cmRedo,0);
  1433. Core^.RedoList^.atDelete(Idx);
  1434. end;{ Idx loop for grouped action }
  1435. If IsGrouped then
  1436. begin
  1437. Idx:=Core^.RedoList^.count-1;
  1438. Core^.UndoList^.Insert(Core^.RedoList^.At(Idx));
  1439. UpdateUndoRedo(cmUndo,Core^.RedoList^.At(Idx)^.Action);
  1440. If Idx>0 then
  1441. UpdateUndoRedo(cmRedo,Core^.RedoList^.At(Idx-1)^.Action)
  1442. else
  1443. UpdateUndoRedo(cmRedo,0);
  1444. Core^.RedoList^.atDelete(Idx);
  1445. end;
  1446. if Core^.RedoList^.count=0 then
  1447. SetCmdState(RedoCmd,false);
  1448. SetCmdState(UndoCmd,true);
  1449. Message(Application,evBroadcast,cmCommandSetChanged,nil);
  1450. if MinY<>-1 then
  1451. UpdateAttrsRange(MinY,MaxY,attrAll);
  1452. DrawView;
  1453. end;
  1454. Core^.SetStoreUndo(True);
  1455. Unlock;
  1456. end;
  1457. (*constructor TCodeEditor.Load(var S: TStream);
  1458. var TS: PSubStream;
  1459. TSize: longint;
  1460. begin
  1461. inherited Load(S);
  1462. New(UndoList,init(500,1000));
  1463. New(RedoList,init(500,1000));
  1464. New(Lines, Init(500,1000));
  1465. { we have always need at least 1 line }
  1466. LinesInsert(New(PLine, Init('',0)));
  1467. GetPeerViewPtr(S,Indicator);
  1468. S.Read(Flags,SizeOf(Flags));
  1469. S.Read(TabSize,SizeOf(TabSize));
  1470. if IsFlagSet(efStoreContent) then
  1471. begin
  1472. S.Read(TSize,SizeOf(TSize));
  1473. New(TS, Init(@S,S.GetPos,TSize));
  1474. {$ifdef TEST_PARTIAL_SYNTAX}
  1475. Core^.SearchBinding(Editor)^.SyntaxComplete:=false;
  1476. { Idle necessary }
  1477. EventMask:=EventMask or evIdle;
  1478. {$endif TEST_PARTIAL_SYNTAX}
  1479. LoadFromStream(TS);
  1480. Dispose(TS, Done);
  1481. end;
  1482. S.Read(SelStart,SizeOf(SelStart));
  1483. S.Read(SelEnd,SizeOf(SelEnd));
  1484. S.Read(Highlight,SizeOf(Highlight));
  1485. S.Read(CurPos,SizeOf(CurPos));
  1486. S.Read(StoreUndo,SizeOf(StoreUndo));
  1487. S.Read(IsReadOnly,SizeOf(IsReadOnly));
  1488. S.Read(NoSelect,SizeOf(NoSelect));
  1489. S.Read(HighlightRow,SizeOf(HighlightRow));
  1490. SetDebuggerRow(-1);
  1491. LimitsChanged;
  1492. SelectionChanged; HighlightChanged;
  1493. UpdateIndicator;
  1494. end;
  1495. procedure TCodeEditor.Store(var S: TStream);
  1496. var {NS: TNulStream;}
  1497. TSizePos,TSize,EndPos: longint;
  1498. begin
  1499. inherited Store(S);
  1500. PutPeerViewPtr(S,Indicator);
  1501. S.Write(Flags,SizeOf(Flags));
  1502. S.Write(TabSize,SizeOf(TabSize));
  1503. if IsFlagSet(efStoreContent) then
  1504. begin
  1505. { NS.Init;
  1506. SaveToStream(@NS);
  1507. TSize:=NS.GetSize;
  1508. NS.Done;
  1509. This is waste of time PM
  1510. use Seek instead !! }
  1511. { yep. and this won't work for serial streams. - Gabor }
  1512. TSize:=0;
  1513. TSizePos:=S.GetPos;
  1514. S.Write(TSize,SizeOf(TSize));
  1515. SaveToStream(@S);
  1516. EndPos:=S.GetPos;
  1517. TSize:=EndPos-TSizePos-SizeOf(TSize);
  1518. S.Seek(TSizePos);
  1519. S.Write(TSize,SizeOf(TSize));
  1520. S.Seek(EndPos);
  1521. end;
  1522. S.Write(SelStart,SizeOf(SelStart));
  1523. S.Write(SelEnd,SizeOf(SelEnd));
  1524. S.Write(Highlight,SizeOf(Highlight));
  1525. S.Write(CurPos,SizeOf(CurPos));
  1526. S.Write(StoreUndo,SizeOf(StoreUndo));
  1527. S.Write(IsReadOnly,SizeOf(IsReadOnly));
  1528. S.Write(NoSelect,SizeOf(NoSelect));
  1529. S.Write(HighlightRow,SizeOf(HighlightRow));
  1530. end;*)
  1531. function TCodeEditor.LoadFromStream(Stream: PFastBufStream): boolean;
  1532. var OK: boolean;
  1533. begin
  1534. OK:=Core^.LoadFromStream(@Self,Stream);
  1535. if IsFlagSet(efSyntaxHighlight) then
  1536. UpdateAttrsRange(0,Min(Delta.Y+Size.Y,GetLineCount-1),
  1537. attrAll
  1538. {$ifndef TEST_PARTIAL_SYNTAX}
  1539. +attrForceFull
  1540. {$endif TEST_PARTIAL_SYNTAX}
  1541. );
  1542. TextStart;
  1543. LoadFromStream:=OK;
  1544. end;
  1545. function TCodeEditor.SaveToStream(Stream: PStream): boolean;
  1546. begin
  1547. SaveToStream:=Core^.SaveToStream(@Self,Stream);
  1548. end;
  1549. function TCodeEditor.SaveAreaToStream(Stream: PStream; StartP,EndP: TPoint): boolean;
  1550. begin
  1551. SaveAreaToStream:=Core^.SaveAreaToStream(@Self,Stream,StartP,EndP);
  1552. end;
  1553. function TCodeEditor.UpdateAttrs(FromLine: sw_integer; Attrs: byte): sw_integer;
  1554. begin
  1555. UpdateAttrs:=Core^.UpdateAttrs(FromLine,Attrs);
  1556. end;
  1557. function TCodeEditor.UpdateAttrsRange(FromLine, ToLine: sw_integer; Attrs: byte): sw_integer;
  1558. begin
  1559. UpdateAttrsRange:=Core^.UpdateAttrsRange(FromLine,ToLine,Attrs);
  1560. end;
  1561. procedure TCodeEditor.AddAction(AAction: byte; AStartPos, AEndPos: TPoint; AText: string;AFlags : longint);
  1562. begin
  1563. Core^.AddAction(AAction,AStartPos,AEndPos,AText,AFlags);
  1564. end;
  1565. procedure TCodeEditor.AddGroupedAction(AAction : byte);
  1566. begin
  1567. Core^.AddGroupedAction(AAction);
  1568. end;
  1569. procedure TCodeEditor.CloseGroupedAction(AAction : byte);
  1570. begin
  1571. Core^.CloseGroupedAction(AAction);
  1572. end;
  1573. function TCodeEditor.GetUndoActionCount: sw_integer;
  1574. begin
  1575. GetUndoActionCount:=Core^.GetUndoActionCount;
  1576. end;
  1577. function TCodeEditor.GetRedoActionCount: sw_integer;
  1578. begin
  1579. GetRedoActionCount:=Core^.GetRedoActionCount;
  1580. end;
  1581. destructor TCodeEditor.Done;
  1582. begin
  1583. inherited Done;
  1584. if Assigned(Core) then
  1585. begin
  1586. Core^.UnBindEditor(@Self);
  1587. if Core^.CanDispose then
  1588. Dispose(Core, Done);
  1589. end;
  1590. Core:=nil;
  1591. if Assigned(CodeCompleteFrag) then
  1592. DisposeStr(CodeCompleteFrag);
  1593. if Assigned(CodeCompleteWord) then
  1594. DisposeStr(CodeCompleteWord);
  1595. if Assigned(ErrorMessage) then
  1596. DisposeStr(ErrorMessage);
  1597. if Assigned(Folds) then
  1598. Dispose(Folds, Done);
  1599. Folds:=nil;
  1600. end;
  1601. constructor TFileEditor.Init(var Bounds: TRect; AHScrollBar, AVScrollBar:
  1602. PScrollBar; AIndicator: PIndicator;ACore: PCodeEditorCore; const AFileName: string);
  1603. begin
  1604. inherited Init(Bounds,AHScrollBAr,AVScrollBAr,AIndicator,ACore);
  1605. FileName:=AFileName;
  1606. UpdateIndicator;
  1607. Message(@Self,evBroadcast,cmFileNameChanged,@Self);
  1608. end;
  1609. function TFileEditor.LoadFile: boolean;
  1610. var OK: boolean;
  1611. PA : Array[1..2] of pointer;
  1612. begin
  1613. OK:=LoadFromFile(FileName);
  1614. if GetModified and (Core^.GetBindingCount=1) then
  1615. begin
  1616. PA[1]:=@FileName;
  1617. Ptrint(PA[2]):=Core^.GetChangedLine;
  1618. EditorDialog(edChangedOnloading,@PA);
  1619. end;
  1620. Core^.OnDiskLoadTime:=Cardinal(GetFileTime(FileName));
  1621. Core^.SystemLoadTime:=Core^.OnDiskLoadTime;
  1622. LoadFile:=OK;
  1623. end;
  1624. function TFileEditor.IsChangedOnDisk : boolean;
  1625. begin
  1626. IsChangedOnDisk:=(Core^.OnDiskLoadTime<>Cardinal(GetFileTime(FileName))) and
  1627. (Core^.OnDiskLoadTime<>0);
  1628. end;
  1629. function TFileEditor.SaveFile: boolean;
  1630. var OK: boolean;
  1631. BAKName: string;
  1632. f: text;
  1633. SaveTime : cardinal;
  1634. begin
  1635. If IsChangedOnDisk then
  1636. begin
  1637. if EditorDialog(edFileOnDiskChanged, @FileName) <> cmYes then
  1638. begin
  1639. SaveFile:=false;
  1640. exit;
  1641. end;
  1642. end;
  1643. {$I-}
  1644. if IsFlagSet(efBackupFiles) and ExistsFile(FileName) then
  1645. begin
  1646. BAKName:=DirAndNameOf(FileName)+'.bak';
  1647. Assign(f,BAKName);
  1648. Erase(f);
  1649. EatIO;
  1650. Assign(f,FileName);
  1651. Rename(F,BAKName);
  1652. EatIO;
  1653. end;
  1654. {$I+}
  1655. SaveTime:=cardinal(now);
  1656. OK:=SaveToFile(FileName);
  1657. if OK then
  1658. SetModified(false)
  1659. { Restore the original }
  1660. else if IsFlagSet(efBackupFiles) and ExistsFile(BakName) then
  1661. begin
  1662. {$I-}
  1663. Assign(f,BakName);
  1664. Rename(F,FileName);
  1665. EatIO;
  1666. {$I+}
  1667. end;
  1668. { don't forget to update the OnDiskLoadTime value }
  1669. if OK then
  1670. begin
  1671. Core^.OnDiskLoadTime:=Cardinal(GetFileTime(FileName));
  1672. Core^.SystemLoadTime:=SaveTime;
  1673. end;
  1674. if not OK then
  1675. EditorDialog(edSaveError,@FileName);
  1676. SaveFile:=OK;
  1677. end;
  1678. function TFileEditor.ReloadFile: boolean;
  1679. var OK,WasModified: boolean;
  1680. BAKName: string;
  1681. f: text;
  1682. begin
  1683. If not IsChangedOnDisk then
  1684. begin
  1685. ReloadFile:=false;
  1686. exit;
  1687. end;
  1688. WasModified:=GetModified;
  1689. if not WasModified then
  1690. OK:=EditorDialog(edreloaddiskmodifiedfile, @FileName)=cmYes
  1691. else
  1692. OK:=EditorDialog(edreloaddiskandidemodifiedfile, @FileName)=cmYes;
  1693. if not OK then
  1694. begin
  1695. ReloadFile:=false;
  1696. exit;
  1697. end;
  1698. { avoid wrong message }
  1699. if WasModified then
  1700. SetModified(false);
  1701. OK:=LoadFile;
  1702. if OK then
  1703. begin
  1704. SetModified(false);
  1705. ClearUndoList;
  1706. { don't forget to update the OnDiskLoadTime value }
  1707. Core^.OnDiskLoadTime:=Cardinal(GetFileTime(FileName));
  1708. Core^.SystemLoadTime:=Core^.OnDiskLoadTime;
  1709. DrawView;
  1710. end
  1711. else
  1712. begin
  1713. if WasModified then
  1714. SetModified(true);
  1715. EditorDialog(edReadError,@FileName);
  1716. end;
  1717. ReloadFile:=OK;
  1718. end;
  1719. function TFileEditor.ShouldSave: boolean;
  1720. begin
  1721. ShouldSave:=GetModified{ or (FileName='')};
  1722. end;
  1723. function TFileEditor.Save: Boolean;
  1724. begin
  1725. if ShouldSave=false then begin Save:=true; Exit; end;
  1726. if FileName = '' then Save := SaveAs else Save := SaveFile;
  1727. end;
  1728. function TFileEditor.SaveAs: Boolean;
  1729. var
  1730. SavedName : String;
  1731. SavedDiskLoadTime : cardinal;
  1732. begin
  1733. SaveAs := False;
  1734. SavedName:=FileName;
  1735. SavedDiskLoadTime:=Core^.OnDiskLoadTime;
  1736. if EditorDialog(edSaveAs, @FileName) <> cmCancel then
  1737. begin
  1738. FileName:=FExpand(FileName);
  1739. Message(Owner, evBroadcast, cmUpdateTitle, @Self);
  1740. { if we rename the file the OnDiskLoadTime is wrong so we reset it }
  1741. Core^.OnDiskLoadTime:=0;
  1742. if SaveFile then
  1743. begin
  1744. SaveAs := true;
  1745. end
  1746. else
  1747. begin
  1748. FileName:=SavedName;
  1749. Core^.OnDiskLoadTime:=SavedDiskLoadTime;
  1750. Message(Owner, evBroadcast, cmUpdateTitle, @Self);
  1751. end;
  1752. if IsClipboard then FileName := '';
  1753. Message(Application,evBroadcast,cmFileNameChanged,@Self);
  1754. end;
  1755. end;
  1756. function TFileEditor.SaveAsk(Force: boolean): boolean;
  1757. var OK: boolean;
  1758. D: Sw_integer;
  1759. begin
  1760. if Force then
  1761. begin
  1762. if GetModified then
  1763. OK:=Save
  1764. else
  1765. OK:=true;
  1766. end
  1767. else
  1768. begin
  1769. OK:=(GetModified=false);
  1770. if (OK=false) and (Core^.GetBindingCount>1) then
  1771. OK:=true;
  1772. if OK=false then
  1773. begin
  1774. if FileName = '' then D := edSaveUntitled else D := edSaveModify;
  1775. case EditorDialog(D, @FileName) of
  1776. cmYes : OK := Save;
  1777. cmNo : begin
  1778. { the file should be still marked as modified! (FK) }
  1779. { SetModified(False); }
  1780. OK:=true;
  1781. end;
  1782. cmCancel : begin
  1783. OK := False;
  1784. Message(Application,evBroadcast,cmSaveCancelled,@Self);
  1785. end;
  1786. end;
  1787. end;
  1788. end;
  1789. SaveAsk:=OK;
  1790. end;
  1791. procedure TFileEditor.BindingsChanged;
  1792. begin
  1793. Message(Application,evBroadcast,cmUpdateTitle,@Self);
  1794. end;
  1795. procedure TFileEditor.HandleEvent(var Event: TEvent);
  1796. var SH,B: boolean;
  1797. begin
  1798. case Event.What of
  1799. evBroadcast :
  1800. case Event.Command of
  1801. cmFileNameChanged :
  1802. if (Event.InfoPtr=nil) or (Event.InfoPtr=@Self) then
  1803. begin
  1804. B:=IsFlagSet(efSyntaxHighlight);
  1805. SH:=UseSyntaxHighlight(@Self);
  1806. if SH<>B then
  1807. if SH then
  1808. SetFlags(Flags or efSyntaxHighlight)
  1809. else
  1810. SetFlags(Flags and not efSyntaxHighlight);
  1811. if UseTabsPattern(@Self) then
  1812. SetFlags(Flags or efUseTabCharacters);
  1813. end;
  1814. end;
  1815. end;
  1816. inherited HandleEvent(Event);
  1817. end;
  1818. function TFileEditor.Valid(Command: Word): Boolean;
  1819. var OK: boolean;
  1820. begin
  1821. OK:=inherited Valid(Command);
  1822. if OK and (Command=cmClose) then
  1823. if IsClipboard=false then
  1824. OK:=SaveAsk(false);
  1825. Valid:=OK;
  1826. end;
  1827. (* constructor TFileEditor.Load(var S: TStream);
  1828. var P: PString;
  1829. SSP,SEP,CP,DP: TPoint;
  1830. HR: TRect;
  1831. PA : Array[1..2] of pointer;
  1832. HoldUndo : boolean;
  1833. begin
  1834. inherited Load(S);
  1835. HoldUndo:=GetStoreUndo;
  1836. SetStoreUndo(False);
  1837. P:=S.ReadStr;
  1838. FileName:=GetStr(P);
  1839. if P<>nil then DisposeStr(P);
  1840. UpdateIndicator;
  1841. { Message(@Self,evBroadcast,cmFileNameChanged,@Self);}
  1842. SSP:=SelStart; SEP:=SelEnd;
  1843. CP:=CurPos;
  1844. HR:=Highlight;
  1845. DP:=Delta;
  1846. if FileName<>'' then
  1847. LoadFile;
  1848. { if GetModified then
  1849. begin
  1850. PA[1]:=@FileName;
  1851. longint(PA[2]):=ChangedLine;
  1852. EditorDialog(edChangedOnloading,@PA);
  1853. end;}
  1854. SetHighlight(HR.A,HR.B);
  1855. SetSelection(SSP,SEP);
  1856. SetCurPtr(CP.X,CP.Y);
  1857. ScrollTo(DP.X,DP.Y);
  1858. SetModified(false);
  1859. LimitsChanged;
  1860. SetStoreUndo(HoldUndo);
  1861. end;
  1862. procedure TFileEditor.Store(var S: TStream);
  1863. begin
  1864. inherited Store(S);
  1865. S.WriteStr(@FileName);
  1866. end;
  1867. *)
  1868. function DefUseSyntaxHighlight(Editor: PFileEditor): boolean;
  1869. begin
  1870. DefUseSyntaxHighlight:=Editor^.IsFlagSet(efSyntaxHighlight);
  1871. end;
  1872. function DefUseTabsPattern(Editor: PFileEditor): boolean;
  1873. begin
  1874. DefUseTabsPattern:=Editor^.IsFlagSet(efUseTabCharacters);
  1875. end;
  1876. procedure RegisterWCEdit;
  1877. begin
  1878. {$ifndef NOOBJREG}
  1879. RegisterType(RIndicator);
  1880. RegisterType(RCodeEditor);
  1881. RegisterType(RFileEditor);
  1882. {$endif}
  1883. end;
  1884. end.