wcedit.pas 55 KB

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