wcedit.pas 56 KB

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