wcedit.pas 56 KB

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