wcedit.pas 56 KB

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