wcedit.pas 54 KB

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