wcedit.pas 56 KB

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