wcedit.pas 55 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081
  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); 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: PStream): 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); 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. end;
  213. PFileEditor = ^TFileEditor;
  214. TFileEditor = object(TCodeEditor)
  215. FileName: string;
  216. constructor Init(var Bounds: TRect; AHScrollBar, AVScrollBar:
  217. PScrollBar; AIndicator: PIndicator; ACore: PCodeEditorCore; const AFileName: string);
  218. function Save: Boolean; virtual;
  219. function SaveAs: Boolean; virtual;
  220. function SaveAsk(Force: boolean): Boolean; virtual;
  221. function LoadFile: boolean; virtual;
  222. function ReloadFile: boolean; virtual;
  223. function SaveFile: boolean; virtual;
  224. function Valid(Command: Word): Boolean; virtual;
  225. procedure HandleEvent(var Event: TEvent); virtual;
  226. function ShouldSave: boolean; virtual;
  227. function IsChangedOnDisk : boolean;
  228. public
  229. procedure BindingsChanged; virtual;
  230. private
  231. OnDiskLoadTime : longint;
  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));
  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);
  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))
  636. then
  637. begin
  638. pa^.EndPos:=AEndPos;
  639. S:=GetStr(pa^.text);
  640. if S<>'' then
  641. DisposeStr(pa^.text);
  642. if (AAction=eaDeleteText) and
  643. (AStartPos.X>AEndPos.X) then
  644. pa^.text:=NewStr(AText+S)
  645. else
  646. pa^.text:=NewStr(S+AText);
  647. ActionIntegrated:=true;
  648. end;
  649. end;
  650. if not ActionIntegrated then
  651. begin
  652. UndoList^.Insert(New(PEditorAction,Init(AAction,AStartPos,AEndPos,AText)));
  653. if assigned(UndoList^.CurrentGroupedAction) then
  654. Inc(UndoList^.CurrentGroupedAction^.actionCount);
  655. UpdateUndoRedo(cmUndo,AAction);
  656. end;
  657. if UndoList^.count>0 then
  658. begin
  659. UpdateUndoRedo(cmRedo,0);
  660. RedoList^.FreeAll;
  661. end;
  662. end;
  663. procedure TCodeEditorCore.AddGroupedAction(AAction : byte);
  664. begin
  665. if Assigned(UndoList^.CurrentGroupedAction) then
  666. inc(UndoList^.GroupLevel)
  667. else
  668. begin
  669. UndoList^.CurrentGroupedAction:=New(PEditorAction,Init_group(AAction));
  670. UndoList^.GroupLevel:=1;
  671. end;
  672. end;
  673. procedure TCodeEditorCore.CloseGroupedAction(AAction : byte);
  674. begin
  675. dec(UndoList^.GroupLevel);
  676. if UndoList^.GroupLevel=0 then
  677. begin
  678. UndoList^.Insert(UndoList^.CurrentGroupedAction);
  679. UndoList^.CurrentGroupedAction:=nil;
  680. UpdateUndoRedo(cmUndo,AAction);
  681. end;
  682. end;
  683. function TCodeEditorCore.GetUndoActionCount: sw_integer;
  684. begin
  685. GetUndoActionCount:=UndoList^.Count;
  686. end;
  687. function TCodeEditorCore.GetRedoActionCount: sw_integer;
  688. begin
  689. GetRedoActionCount:=RedoList^.Count;
  690. end;
  691. destructor TCodeEditorCore.Done;
  692. begin
  693. inherited Done;
  694. if Assigned(Lines) then Dispose(Lines, Done); Lines:=nil;
  695. if Assigned(RedoList) then Dispose(RedoList, Done); RedoList:=nil;
  696. if Assigned(UndoList) then Dispose(UndoList, Done); UndoList:=nil;
  697. end;
  698. constructor TIndicator.Init(var Bounds: TRect);
  699. begin
  700. inherited Init(Bounds);
  701. GrowMode := gfGrowLoY + gfGrowHiY;
  702. end;
  703. procedure TIndicator.Draw;
  704. var
  705. Color: Byte;
  706. Frame: Char;
  707. L: array[0..1] of Longint;
  708. S: String[15];
  709. B: TDrawBuffer;
  710. begin
  711. if assigned(CodeOwner) and
  712. (CodeOwner^.ELockFlag>0) then
  713. begin
  714. CodeOwner^.IndicatorDrawCalled:=true;
  715. exit;
  716. end;
  717. if (State and sfDragging = 0) and (State and sfActive <> 0) then
  718. begin
  719. Color := GetColor(1);
  720. Frame := #205;
  721. end
  722. else
  723. begin
  724. if (State and sfDragging)<>0 then
  725. Color := GetColor(2)
  726. else
  727. Color := GetColor(3);
  728. Frame := #196;
  729. end;
  730. MoveChar(B, Frame, Color, Size.X);
  731. if State and sfActive<>0 then
  732. begin
  733. if Modified then
  734. WordRec (B[0]).Lo := ord('*');
  735. {$ifdef debug}
  736. if StoreUndo then
  737. WordRec (B[1]).Lo := ord('S');
  738. if SyntaxComplete then
  739. WordRec(B[2]).lo := ord('C');
  740. if UseTabs then
  741. WordRec(B[3]).lo := ord('T');
  742. {$endif debug}
  743. L[0] := Location.Y + 1;
  744. L[1] := Location.X + 1;
  745. FormatStr(S, '%d:%d ', L);
  746. MoveStr(B[8 - Pos(':', S)], S, Color);
  747. end;
  748. WriteBuf(0, 0, Size.X, 1, B);
  749. end;
  750. function TIndicator.GetPalette: PPalette;
  751. const
  752. P: string[Length(CIndicator)] = CIndicator;
  753. begin
  754. GetPalette := @P;
  755. end;
  756. procedure TIndicator.SetState(AState: Word; Enable: Boolean);
  757. begin
  758. inherited SetState(AState, Enable);
  759. if (AState = sfDragging) or (AState=sfActive) then
  760. DrawView;
  761. end;
  762. procedure TIndicator.SetValue(ALocation: TPoint; AModified: Boolean);
  763. begin
  764. if (Location.X<>ALocation.X) or
  765. (Location.Y<>ALocation.Y) or
  766. (Modified <> AModified) then
  767. begin
  768. Location := ALocation;
  769. Modified := AModified;
  770. DrawView;
  771. end;
  772. end;
  773. {constructor TIndicator.Load(var S: TStream);
  774. begin
  775. inherited Load(S);
  776. S.Read(Location,SizeOf(Location));
  777. S.Read(Modified,SizeOf(Modified));
  778. end;
  779. procedure TIndicator.Store(var S: TStream);
  780. begin
  781. inherited Store(S);
  782. S.Write(Location,SizeOf(Location));
  783. S.Write(Modified,SizeOf(Modified));
  784. end;}
  785. {*****************************************************************************
  786. TCodeEditor
  787. *****************************************************************************}
  788. constructor TCodeEditor.Init(var Bounds: TRect; AHScrollBar, AVScrollBar:
  789. PScrollBar; AIndicator: PIndicator; ACore: PCodeEditorCore);
  790. begin
  791. inherited Init(Bounds,AHScrollBar,AVScrollBar);
  792. New(Folds, Init(100,100));
  793. if ACore=nil then ACore:=New(PCodeEditorCore, Init);
  794. Core:=ACore;
  795. Core^.BindEditor(@Self);
  796. SetState(sfCursorVis,true);
  797. SetFlags(DefaultCodeEditorFlags);
  798. SetCurPtr(0,0);
  799. Indicator:=AIndicator;
  800. if assigned(Indicator) then
  801. Indicator^.CodeOwner:=@Self;
  802. UpdateIndicator;
  803. LimitsChanged;
  804. end;
  805. function TCodeEditor.GetFlags: longint;
  806. begin
  807. GetFlags:=Flags;
  808. end;
  809. procedure TCodeEditor.SetFlags(AFlags: longint);
  810. var OFlags: longint;
  811. begin
  812. if AFlags<>Flags then
  813. begin
  814. OFlags:=Flags;
  815. Flags:=AFlags;
  816. FlagsChanged(OFlags);
  817. end;
  818. end;
  819. function TCodeEditor.GetModified: boolean;
  820. begin
  821. GetModified:=Core^.GetModified;
  822. end;
  823. procedure TCodeEditor.SetModified(AModified: boolean);
  824. begin
  825. Core^.SetModified(AModified);
  826. end;
  827. function TCodeEditor.GetStoreUndo: boolean;
  828. begin
  829. GetStoreUndo:=Core^.GetStoreUndo;
  830. end;
  831. procedure TCodeEditor.SetStoreUndo(AStore: boolean);
  832. begin
  833. Core^.SetStoreUndo(AStore);
  834. end;
  835. procedure TCodeEditor.ClearUndoList;
  836. begin
  837. Core^.UndoList^.FreeAll;
  838. Core^.RedoList^.FreeAll;
  839. end;
  840. function TCodeEditor.GetSyntaxCompleted: boolean;
  841. begin
  842. GetSyntaxCompleted:=Core^.GetSyntaxCompleted;
  843. end;
  844. procedure TCodeEditor.SetSyntaxCompleted(SC : boolean);
  845. begin
  846. Core^.SetSyntaxCompleted(SC);
  847. UpdateIndicator;
  848. end;
  849. function TCodeEditor.GetLastSyntaxedLine: sw_integer;
  850. begin
  851. GetLastSyntaxedLine:=Core^.GetLastSyntaxedLine;
  852. end;
  853. procedure TCodeEditor.SetLastSyntaxedLine(ALine: sw_integer);
  854. begin
  855. Core^.SetLastSyntaxedLine(ALine);
  856. end;
  857. function TCodeEditor.GetTabSize: integer;
  858. begin
  859. GetTabSize:=Core^.GetTabSize;
  860. end;
  861. procedure TCodeEditor.SetTabSize(ATabSize: integer);
  862. begin
  863. Core^.SetTabSize(ATabSize);
  864. end;
  865. function TCodeEditor.GetIndentSize: integer;
  866. begin
  867. GetIndentSize:=Core^.GetIndentSize;
  868. end;
  869. procedure TCodeEditor.SetIndentSize(AIndentSize: integer);
  870. begin
  871. Core^.SetIndentSize(AIndentSize);
  872. end;
  873. function TCodeEditor.IsReadOnly: boolean;
  874. begin
  875. IsReadOnly:=ReadOnly or (Core^.ReadOnly);
  876. end;
  877. function TCodeEditor.IsClipboard: Boolean;
  878. begin
  879. IsClipboard:=Core^.IsClipboard;
  880. end;
  881. function TCodeEditor.GetErrorMessage: string;
  882. begin
  883. GetErrorMessage:=GetStr(ErrorMessage);
  884. end;
  885. procedure TCodeEditor.SetErrorMessage(const S: string);
  886. begin
  887. SetStr(ErrorMessage,S);
  888. DrawView;
  889. end;
  890. function TCodeEditor.GetLineCount: sw_integer;
  891. begin
  892. GetLineCount:=Core^.GetLineCount;
  893. end;
  894. function TCodeEditor.GetLine(LineNo: sw_integer): PCustomLine;
  895. begin
  896. GetLine:=Core^.GetLine(LineNo);
  897. end;
  898. function TCodeEditor.CharIdxToLinePos(Line,CharIdx: sw_integer): sw_integer;
  899. begin
  900. CharIdxToLinePos:=Core^.CharIdxToLinePos(Line,CharIdx);
  901. end;
  902. function TCodeEditor.LinePosToCharIdx(Line,X: sw_integer): sw_integer;
  903. begin
  904. LinePosToCharIdx:=Core^.LinePosToCharIdx(Line,X);
  905. end;
  906. function TCodeEditor.GetLineText(I: sw_integer): string;
  907. begin
  908. GetLineText:=Core^.GetLineText(I);
  909. end;
  910. procedure TCodeEditor.SetDisplayText(I: sw_integer;const S: string);
  911. begin
  912. Core^.SetDisplayText(I,S);
  913. end;
  914. function TCodeEditor.GetDisplayText(I: sw_integer): string;
  915. begin
  916. GetDisplayText:=Core^.GetDisplayText(I);
  917. end;
  918. procedure TCodeEditor.SetLineText(I: sw_integer;const S: string);
  919. begin
  920. Core^.SetLineText(I,S);
  921. end;
  922. procedure TCodeEditor.GetDisplayTextFormat(I: sw_integer;var DT,DF:string);
  923. begin
  924. Core^.GetDisplayTextFormat(@Self,I,DT,DF);
  925. end;
  926. function TCodeEditor.GetLineFormat(I: sw_integer): string;
  927. begin
  928. GetLineFormat:=Core^.GetLineFormat(@Self,I);
  929. end;
  930. procedure TCodeEditor.SetLineFormat(I: sw_integer;const S: string);
  931. begin
  932. Core^.SetLineFormat(@Self,I,S);
  933. end;
  934. procedure TCodeEditor.DeleteAllLines;
  935. begin
  936. Core^.DeleteAllLines;
  937. end;
  938. procedure TCodeEditor.DeleteLine(I: sw_integer);
  939. begin
  940. Core^.DeleteLine(I);
  941. end;
  942. function TCodeEditor.InsertLine(LineNo: sw_integer; const S: string): PCustomLine;
  943. begin
  944. InsertLine:=Core^.InsertLine(LineNo,S);
  945. end;
  946. procedure TCodeEditor.AddLine(const S: string);
  947. begin
  948. Core^.AddLine(S);
  949. end;
  950. function TCodeEditor.GetMaxFoldLevel: sw_integer;
  951. begin
  952. GetMaxFoldLevel:=MaxFoldLevel;
  953. end;
  954. procedure TCodeEditor.RegisterFold(AFold: PFold);
  955. var L: sw_integer;
  956. begin
  957. if Assigned(Folds) then
  958. begin
  959. Folds^.Insert(AFold);
  960. L:=AFold^.GetLevel+1;
  961. if L>MaxFoldLevel then MaxFoldLevel:=L;
  962. end;
  963. end;
  964. procedure TCodeEditor.UnRegisterFold(AFold: PFold);
  965. begin
  966. if Assigned(Folds) then
  967. begin
  968. Folds^.Delete(AFold);
  969. if Folds^.Count=0 then
  970. MaxFoldLevel:=0
  971. else
  972. MaxFoldLevel:=inherited GetMaxFoldLevel+1;
  973. end;
  974. end;
  975. function TCodeEditor.GetFoldCount: sw_integer;
  976. begin
  977. GetFoldCount:=Folds^.Count;
  978. end;
  979. function TCodeEditor.GetFold(Index: sw_integer): PFold;
  980. begin
  981. GetFold:=Folds^.At(Index);
  982. end;
  983. {function TCodeEditor.GetLineTextPos(Line,X: integer): integer;
  984. var
  985. S: string;
  986. rx,i : Sw_integer;
  987. begin
  988. S:=GetLineText(Line);
  989. i:=0; rx:=0;
  990. while (RX<X) and (i<Length(s)) do
  991. begin
  992. inc(i);
  993. inc(rx);
  994. if s[i]=#9 then
  995. inc(rx,TabSize-(rx mod tabsize));
  996. end;
  997. if RX<X then Inc(I,X-RX);
  998. GetLineTextPos:=i;
  999. end;
  1000. function TCodeEditor.GetDisplayTextPos(Line,X: integer): integer;
  1001. var
  1002. S: string;
  1003. L: PCustomLine;
  1004. rx,i : Sw_integer;
  1005. begin
  1006. S:='';
  1007. if Line<Lines^.Count then
  1008. begin
  1009. L:=Lines^.At(Line);
  1010. if assigned(L^.Text) then
  1011. S:=L^.Text^;
  1012. end;
  1013. i:=0;
  1014. rx:=0;
  1015. while (i<X) and (i<Length(s)) do
  1016. begin
  1017. inc(i);
  1018. inc(rx);
  1019. if s[i]=#9 then
  1020. inc(rx,TabSize-(rx mod tabsize));
  1021. end;
  1022. GetDisplayTextPos:=rx;
  1023. end;}
  1024. procedure TCodeEditor.GetContent(ALines: PUnsortedStringCollection);
  1025. begin
  1026. Core^.GetContent(ALines);
  1027. end;
  1028. procedure TCodeEditor.SetContent(ALines: PUnsortedStringCollection);
  1029. begin
  1030. Lock;
  1031. TextStart; HideSelect;
  1032. Core^.SetContent(ALines);
  1033. LimitsChanged;
  1034. if IsFlagSet(efSyntaxHighlight) then
  1035. Core^.UpdateAttrsRange(0,Min(Delta.Y+Size.Y,GetLineCount-1),
  1036. attrAll
  1037. {$ifndef TEST_PARTIAL_SYNTAX}
  1038. +attrForceFull
  1039. {$endif TEST_PARTIAL_SYNTAX}
  1040. );
  1041. TextStart;
  1042. UnLock;
  1043. end;
  1044. function TCodeEditor.GetCodeCompleteFrag: string;
  1045. begin
  1046. GetCodeCompleteFrag:=GetStr(CodeCompleteFrag);
  1047. end;
  1048. procedure TCodeEditor.SetCodeCompleteFrag(const S: string);
  1049. begin
  1050. SetStr(CodeCompleteFrag,S);
  1051. end;
  1052. function TCodeEditor.GetCompleteState: TCompleteState;
  1053. begin
  1054. GetCompleteState:=CompleteState;
  1055. end;
  1056. procedure TCodeEditor.SetCompleteState(AState: TCompleteState);
  1057. begin
  1058. if AState<>CompleteState then
  1059. begin
  1060. CompleteState:=AState;
  1061. if CompleteState<>csOffering then
  1062. ClearCodeCompleteWord;
  1063. end;
  1064. end;
  1065. function TCodeEditor.GetCodeCompleteWord: string;
  1066. begin
  1067. GetCodeCompleteWord:=GetStr(CodeCompleteWord);
  1068. end;
  1069. procedure TCodeEditor.SetCodeCompleteWord(const S: string);
  1070. begin
  1071. if Assigned(CodeCompleteWord) then DisposeStr(CodeCompleteWord);
  1072. CodeCompleteWord:=NewStr(S);
  1073. inherited SetCodeCompleteWord(S);
  1074. end;
  1075. procedure TCodeEditor.DrawIndicator;
  1076. begin
  1077. if Assigned(Indicator) then
  1078. Indicator^.DrawView;
  1079. end;
  1080. procedure TCodeEditor.Lock;
  1081. begin
  1082. inherited Lock;
  1083. Core^.Lock(@Self);
  1084. end;
  1085. procedure TCodeEditor.UnLock;
  1086. begin
  1087. Core^.UnLock(@Self);
  1088. inherited UnLock;
  1089. If (ELockFlag=0) and IndicatorDrawCalled then
  1090. begin
  1091. DrawIndicator;
  1092. IndicatorDrawCalled:=false;
  1093. end;
  1094. end;
  1095. procedure TCodeEditor.UpdateIndicator;
  1096. begin
  1097. if Indicator<>nil then
  1098. begin
  1099. Indicator^.Location:=CurPos;
  1100. Indicator^.Modified:=GetModified;
  1101. {$ifdef debug}
  1102. Indicator^.StoreUndo:=GetStoreUndo;
  1103. {$ifdef TEST_PARTIAL_SYNTAX}
  1104. Indicator^.SyntaxComplete:=GetSyntaxCompleted and IsFlagSet(efSyntaxHighlight);
  1105. {$endif TEST_PARTIAL_SYNTAX}
  1106. Indicator^.UseTabs:=IsFlagSet(efUseTabCharacters);
  1107. {$endif debug}
  1108. if Elockflag>0 then
  1109. IndicatorDrawCalled:=true
  1110. else
  1111. Indicator^.DrawView;
  1112. end;
  1113. end;
  1114. procedure TCodeEditor.LimitsChanged;
  1115. begin
  1116. Core^.LimitsChanged;
  1117. end;
  1118. procedure TCodeEditor.ModifiedChanged;
  1119. begin
  1120. UpdateIndicator;
  1121. end;
  1122. procedure TCodeEditor.PositionChanged;
  1123. begin
  1124. UpdateIndicator;
  1125. end;
  1126. procedure TCodeEditor.JumpToLastCursorPos;
  1127. var
  1128. pa : PEditorAction;
  1129. begin
  1130. if (Core^.UndoList^.count>0) and (Core^.RedoList^.count=0) then
  1131. begin
  1132. { Or should we just call Undo ?? PM }
  1133. pa:=Core^.UndoList^.At(Core^.UndoList^.count-1);
  1134. if (pa^.action=eaMoveCursor) then
  1135. SetCurPtr(pa^.StartPos.X,pa^.StartPos.Y);
  1136. end;
  1137. end;
  1138. procedure TCodeEditor.Undo;
  1139. var
  1140. Temp,Idx,Last,Count : Longint;
  1141. WasInserting,Is_grouped,Had_efNoIndent : boolean;
  1142. MaxY,MinY : sw_integer;
  1143. Line : String;
  1144. procedure SetMinMax(y : sw_integer);
  1145. begin
  1146. if MinY=-1 then
  1147. MinY:=Y;
  1148. if Y<MinY then
  1149. MinY:=Y;
  1150. if MaxY=-1 then
  1151. MaxY:=Y;
  1152. if Y>MaxY then
  1153. MaxY:=Y;
  1154. end;
  1155. begin
  1156. Core^.SetStoreUndo(False);
  1157. Lock;
  1158. MinY:=-1;
  1159. MaxY:=-1;
  1160. if Core^.UndoList^.count > 0 then
  1161. begin
  1162. Last:=Core^.UndoList^.count-1;
  1163. if Core^.UndoList^.At(Last)^.Is_grouped_action then
  1164. begin
  1165. Count:=Core^.UndoList^.At(Last)^.ActionCount;
  1166. Dec(Last);
  1167. Is_grouped:=true;
  1168. end
  1169. else
  1170. begin
  1171. Count:=1;
  1172. Is_grouped:=false;
  1173. end;
  1174. for Idx:=Last downto Last-Count+1 do
  1175. with Core^.UndoList^.At(Idx)^ do
  1176. begin
  1177. case action of
  1178. eaMoveCursor :
  1179. begin
  1180. { move cursor back to original position }
  1181. SetCurPtr(startpos.x,startpos.y);
  1182. end;
  1183. eaInsertText :
  1184. begin
  1185. SetCurPtr(StartPos.X,StartPos.Y);
  1186. if assigned(text) then
  1187. for Temp := 1 to length(Text^) do
  1188. DelChar;
  1189. SetMinMax(StartPos.Y);
  1190. end;
  1191. eaDeleteText :
  1192. begin
  1193. { reinsert deleted text }
  1194. SetCurPtr(EndPos.X,EndPos.Y);
  1195. if assigned(text) then
  1196. for Temp := 1 to length(Text^) do
  1197. AddChar(Text^[Temp]);
  1198. SetMinMax(EndPos.Y);
  1199. SetCurPtr(StartPos.X,StartPos.Y);
  1200. end;
  1201. eaOverwriteText :
  1202. begin
  1203. SetCurPtr(StartPos.X,StartPos.Y);
  1204. Line:=GetDisplayText(StartPos.Y);
  1205. WasInserting:=GetInsertMode;
  1206. SetInsertMode(false);
  1207. if assigned(text) then
  1208. for Temp := 1 to length(Text^) do
  1209. begin
  1210. AddChar(Text^[Temp]);
  1211. if StartPos.X+Temp>Length(Line) then
  1212. Text^[Temp]:=' '
  1213. else
  1214. Text^[Temp]:=Line[StartPos.X+Temp];
  1215. end;
  1216. SetInsertMode(WasInserting);
  1217. SetMinMax(EndPos.Y);
  1218. SetCurPtr(StartPos.X,StartPos.Y);
  1219. end;
  1220. eaInsertLine :
  1221. begin
  1222. SetCurPtr(EndPos.X,EndPos.Y);
  1223. SetDisplayText(EndPos.Y,Copy(GetDisplayText(EndPos.Y),EndPos.X+1,255));
  1224. SetMinMax(EndPos.Y);
  1225. SetCurPtr(0,EndPos.Y);
  1226. BackSpace;
  1227. SetCurPtr(StartPos.X,StartPos.Y);
  1228. SetMinMax(StartPos.Y);
  1229. end;
  1230. eaDeleteLine :
  1231. begin
  1232. SetCurPtr(EndPos.X,EndPos.Y);
  1233. SetMinMax(EndPos.Y);
  1234. Had_efNoIndent:=(GetFlags and efNoIndent)<>0;
  1235. SetFlags(GetFlags or efNoIndent);
  1236. InsertNewLine;
  1237. if not Had_efNoIndent then
  1238. SetFlags(GetFlags and not efNoIndent);
  1239. {DelEnd; wrong for eaCut at least }
  1240. SetCurPtr(StartPos.X,StartPos.Y);
  1241. SetLineText(StartPos.Y,Copy(GetDisplayText(StartPos.Y),1,StartPos.X)+GetStr(Text));
  1242. SetMinMax(StartPos.Y);
  1243. end;
  1244. eaSelectionChanged :
  1245. begin
  1246. { move cursor to end of last set selection }
  1247. end;
  1248. else
  1249. { what the 'ell's an undefined action doing round 'ere mate! }
  1250. ;
  1251. end; { once this lot is done paste into redo and modify to suit needs }
  1252. { move item to redo stack }
  1253. Core^.RedoList^.Insert(Core^.UndoList^.At(Idx));
  1254. UpdateUndoRedo(cmRedo,Core^.UndoList^.At(Idx)^.Action);
  1255. Core^.UndoList^.atDelete(Idx);
  1256. If Idx>0 then
  1257. UpdateUndoRedo(cmUndo,Core^.UndoList^.At(Idx-1)^.Action)
  1258. else
  1259. UpdateUndoRedo(cmUndo,0);
  1260. end;{Idx loop for grouped actions }
  1261. if is_grouped then
  1262. begin
  1263. Idx:=Core^.UndoList^.Count-1;
  1264. Core^.RedoList^.Insert(Core^.UndoList^.At(Idx));
  1265. UpdateUndoRedo(cmRedo,Core^.UndoList^.At(Idx)^.Action);
  1266. Core^.UndoList^.atDelete(Idx);
  1267. If Idx>0 then
  1268. UpdateUndoRedo(cmUndo,Core^.UndoList^.At(Idx-1)^.Action)
  1269. else
  1270. UpdateUndoRedo(cmUndo,0);
  1271. end;
  1272. if Core^.UndoList^.count=0 then
  1273. SetCmdState(UndoCmd,false);
  1274. SetCmdState(RedoCmd,true);
  1275. Message(Application,evBroadcast,cmCommandSetChanged,nil);
  1276. if MinY<>-1 then
  1277. UpdateAttrsRange(MinY,MaxY,attrAll);
  1278. DrawView;
  1279. end;
  1280. Core^.SetStoreUndo(True);
  1281. Unlock;
  1282. end;
  1283. procedure TCodeEditor.Redo;
  1284. var
  1285. Temp,Idx,Last,Count : Longint;
  1286. WasInserting,Is_grouped,Had_efNoIndent : boolean;
  1287. Line : String;
  1288. begin
  1289. Core^.SetStoreUndo(False);
  1290. Lock;
  1291. if Core^.RedoList^.count <> 0 then
  1292. begin
  1293. Last:=Core^.RedoList^.count-1;
  1294. if Core^.RedoList^.At(Last)^.Is_grouped_action then
  1295. begin
  1296. Count:=Core^.RedoList^.At(Last)^.ActionCount;
  1297. Dec(Last);
  1298. Is_grouped:=true;
  1299. end
  1300. else
  1301. begin
  1302. Count:=1;
  1303. Is_grouped:=false;
  1304. end;
  1305. for Idx:=Last downto Last-Count+1 do
  1306. with Core^.RedoList^.At(Idx)^ do
  1307. begin
  1308. case action of
  1309. eaMoveCursor :
  1310. begin
  1311. { move cursor back to original position }
  1312. SetCurPtr(EndPos.X,EndPos.Y);
  1313. end;
  1314. eaInsertText :
  1315. begin
  1316. SetCurPtr(startpos.x,startpos.y);
  1317. InsertText(GetStr(Text));
  1318. end;
  1319. eaDeleteText :
  1320. begin
  1321. SetCurPtr(EndPos.X,EndPos.Y);
  1322. for Temp := 1 to length(GetStr(Text)) do
  1323. DelChar;
  1324. end;
  1325. eaOverwriteText :
  1326. begin
  1327. SetCurPtr(StartPos.X,StartPos.Y);
  1328. Line:=GetDisplayText(StartPos.Y);
  1329. WasInserting:=GetInsertMode;
  1330. SetInsertMode(false);
  1331. if assigned(text) then
  1332. for Temp := 1 to length(Text^) do
  1333. begin
  1334. AddChar(Text^[Temp]);
  1335. if StartPos.X+Temp>Length(Line) then
  1336. Text^[Temp]:=' '
  1337. else
  1338. Text^[Temp]:=Line[StartPos.X+Temp];
  1339. end;
  1340. SetInsertMode(WasInserting);
  1341. SetCurPtr(EndPos.X,EndPos.Y);
  1342. end;
  1343. eaInsertLine :
  1344. begin
  1345. SetCurPtr(StartPos.X,StartPos.Y);
  1346. Had_efNoIndent:=(GetFlags and efNoIndent)<>0;
  1347. SetFlags(GetFlags or efNoIndent);
  1348. InsertNewLine;
  1349. SetCurPtr(StartPos.X,StartPos.Y);
  1350. InsertText(GetStr(Text));
  1351. if not Had_efNoIndent then
  1352. SetFlags(GetFlags and not efNoIndent);
  1353. SetCurPtr(EndPos.X,EndPos.Y);
  1354. end;
  1355. eaDeleteLine :
  1356. begin
  1357. SetCurPtr(StartPos.X,StartPos.Y);
  1358. DeleteLine(StartPos.Y);
  1359. SetCurPtr(EndPos.X,EndPos.Y);
  1360. if EndPos.Y=StartPos.Y-1 then
  1361. SetDisplayText(EndPos.Y,RExpand(
  1362. copy(GetDisplayText(EndPos.Y),1,EndPos.X),EndPos.X)
  1363. +GetStr(Text));
  1364. SetCurPtr(EndPos.X,EndPos.Y);
  1365. end;
  1366. eaSelectionChanged :
  1367. begin
  1368. { move cursor to end of last set test selection }
  1369. end;
  1370. else
  1371. { what the 'ell's an undefined action doing round 'ere mate! }
  1372. ;
  1373. end; { once this lot is done paste back into undo and modify to suit needs }
  1374. { move item to undo stack }
  1375. Core^.UndoList^.Insert(Core^.RedoList^.At(Idx));
  1376. UpdateUndoRedo(cmUndo,Core^.RedoList^.At(Idx)^.Action);
  1377. If Idx>0 then
  1378. UpdateUndoRedo(cmRedo,Core^.RedoList^.At(Idx-1)^.Action)
  1379. else
  1380. UpdateUndoRedo(cmRedo,0);
  1381. Core^.RedoList^.atDelete(Idx);
  1382. end;{ Idx loop for grouped action }
  1383. If is_grouped then
  1384. begin
  1385. Idx:=Core^.RedoList^.count-1;
  1386. Core^.UndoList^.Insert(Core^.RedoList^.At(Idx));
  1387. UpdateUndoRedo(cmUndo,Core^.RedoList^.At(Idx)^.Action);
  1388. If Idx>0 then
  1389. UpdateUndoRedo(cmRedo,Core^.RedoList^.At(Idx-1)^.Action)
  1390. else
  1391. UpdateUndoRedo(cmRedo,0);
  1392. Core^.RedoList^.atDelete(Idx);
  1393. end;
  1394. if Core^.RedoList^.count=0 then
  1395. SetCmdState(RedoCmd,false);
  1396. SetCmdState(UndoCmd,true);
  1397. DrawView;
  1398. Message(Application,evBroadcast,cmCommandSetChanged,nil);
  1399. end;
  1400. Core^.SetStoreUndo(True);
  1401. Unlock;
  1402. end;
  1403. (*constructor TCodeEditor.Load(var S: TStream);
  1404. var TS: PSubStream;
  1405. TSize: longint;
  1406. begin
  1407. inherited Load(S);
  1408. New(UndoList,init(500,1000));
  1409. New(RedoList,init(500,1000));
  1410. New(Lines, Init(500,1000));
  1411. { we have always need at least 1 line }
  1412. LinesInsert(New(PLine, Init('',0)));
  1413. GetPeerViewPtr(S,Indicator);
  1414. S.Read(Flags,SizeOf(Flags));
  1415. S.Read(TabSize,SizeOf(TabSize));
  1416. if IsFlagSet(efStoreContent) then
  1417. begin
  1418. S.Read(TSize,SizeOf(TSize));
  1419. New(TS, Init(@S,S.GetPos,TSize));
  1420. {$ifdef TEST_PARTIAL_SYNTAX}
  1421. Core^.SearchBinding(Editor)^.SyntaxComplete:=false;
  1422. { Idle necessary }
  1423. EventMask:=EventMask or evIdle;
  1424. {$endif TEST_PARTIAL_SYNTAX}
  1425. LoadFromStream(TS);
  1426. Dispose(TS, Done);
  1427. end;
  1428. S.Read(SelStart,SizeOf(SelStart));
  1429. S.Read(SelEnd,SizeOf(SelEnd));
  1430. S.Read(Highlight,SizeOf(Highlight));
  1431. S.Read(CurPos,SizeOf(CurPos));
  1432. S.Read(StoreUndo,SizeOf(StoreUndo));
  1433. S.Read(IsReadOnly,SizeOf(IsReadOnly));
  1434. S.Read(NoSelect,SizeOf(NoSelect));
  1435. S.Read(HighlightRow,SizeOf(HighlightRow));
  1436. SetDebuggerRow(-1);
  1437. LimitsChanged;
  1438. SelectionChanged; HighlightChanged;
  1439. UpdateIndicator;
  1440. end;
  1441. procedure TCodeEditor.Store(var S: TStream);
  1442. var {NS: TNulStream;}
  1443. TSizePos,TSize,EndPos: longint;
  1444. begin
  1445. inherited Store(S);
  1446. PutPeerViewPtr(S,Indicator);
  1447. S.Write(Flags,SizeOf(Flags));
  1448. S.Write(TabSize,SizeOf(TabSize));
  1449. if IsFlagSet(efStoreContent) then
  1450. begin
  1451. { NS.Init;
  1452. SaveToStream(@NS);
  1453. TSize:=NS.GetSize;
  1454. NS.Done;
  1455. This is waste of time PM
  1456. use Seek instead !! }
  1457. { yep. and this won't work for serial streams. - Gabor }
  1458. TSize:=0;
  1459. TSizePos:=S.GetPos;
  1460. S.Write(TSize,SizeOf(TSize));
  1461. SaveToStream(@S);
  1462. EndPos:=S.GetPos;
  1463. TSize:=EndPos-TSizePos-SizeOf(TSize);
  1464. S.Seek(TSizePos);
  1465. S.Write(TSize,SizeOf(TSize));
  1466. S.Seek(EndPos);
  1467. end;
  1468. S.Write(SelStart,SizeOf(SelStart));
  1469. S.Write(SelEnd,SizeOf(SelEnd));
  1470. S.Write(Highlight,SizeOf(Highlight));
  1471. S.Write(CurPos,SizeOf(CurPos));
  1472. S.Write(StoreUndo,SizeOf(StoreUndo));
  1473. S.Write(IsReadOnly,SizeOf(IsReadOnly));
  1474. S.Write(NoSelect,SizeOf(NoSelect));
  1475. S.Write(HighlightRow,SizeOf(HighlightRow));
  1476. end;*)
  1477. function TCodeEditor.LoadFromStream(Stream: PStream): boolean;
  1478. var OK: boolean;
  1479. begin
  1480. OK:=Core^.LoadFromStream(@Self,Stream);
  1481. if IsFlagSet(efSyntaxHighlight) then
  1482. UpdateAttrsRange(0,Min(Delta.Y+Size.Y,GetLineCount-1),
  1483. attrAll
  1484. {$ifndef TEST_PARTIAL_SYNTAX}
  1485. +attrForceFull
  1486. {$endif TEST_PARTIAL_SYNTAX}
  1487. );
  1488. TextStart;
  1489. LoadFromStream:=OK;
  1490. end;
  1491. function TCodeEditor.SaveToStream(Stream: PStream): boolean;
  1492. begin
  1493. SaveToStream:=Core^.SaveToStream(@Self,Stream);
  1494. end;
  1495. function TCodeEditor.SaveAreaToStream(Stream: PStream; StartP,EndP: TPoint): boolean;
  1496. begin
  1497. SaveAreaToStream:=Core^.SaveAreaToStream(@Self,Stream,StartP,EndP);
  1498. end;
  1499. function TCodeEditor.UpdateAttrs(FromLine: sw_integer; Attrs: byte): sw_integer;
  1500. begin
  1501. UpdateAttrs:=Core^.UpdateAttrs(FromLine,Attrs);
  1502. end;
  1503. function TCodeEditor.UpdateAttrsRange(FromLine, ToLine: sw_integer; Attrs: byte): sw_integer;
  1504. begin
  1505. UpdateAttrsRange:=Core^.UpdateAttrsRange(FromLine,ToLine,Attrs);
  1506. end;
  1507. procedure TCodeEditor.AddAction(AAction: byte; AStartPos, AEndPos: TPoint; AText: string);
  1508. begin
  1509. Core^.AddAction(AAction,AStartPos,AEndPos,AText);
  1510. end;
  1511. procedure TCodeEditor.AddGroupedAction(AAction : byte);
  1512. begin
  1513. Core^.AddGroupedAction(AAction);
  1514. end;
  1515. procedure TCodeEditor.CloseGroupedAction(AAction : byte);
  1516. begin
  1517. Core^.CloseGroupedAction(AAction);
  1518. end;
  1519. function TCodeEditor.GetUndoActionCount: sw_integer;
  1520. begin
  1521. GetUndoActionCount:=Core^.GetUndoActionCount;
  1522. end;
  1523. function TCodeEditor.GetRedoActionCount: sw_integer;
  1524. begin
  1525. GetRedoActionCount:=Core^.GetRedoActionCount;
  1526. end;
  1527. destructor TCodeEditor.Done;
  1528. begin
  1529. inherited Done;
  1530. if Assigned(Core) then
  1531. begin
  1532. Core^.UnBindEditor(@Self);
  1533. if Core^.CanDispose then
  1534. Dispose(Core, Done);
  1535. end;
  1536. Core:=nil;
  1537. if Assigned(CodeCompleteFrag) then
  1538. DisposeStr(CodeCompleteFrag);
  1539. if Assigned(CodeCompleteWord) then
  1540. DisposeStr(CodeCompleteWord);
  1541. if Assigned(ErrorMessage) then
  1542. DisposeStr(ErrorMessage);
  1543. if Assigned(Folds) then
  1544. Dispose(Folds, Done);
  1545. Folds:=nil;
  1546. end;
  1547. constructor TFileEditor.Init(var Bounds: TRect; AHScrollBar, AVScrollBar:
  1548. PScrollBar; AIndicator: PIndicator;ACore: PCodeEditorCore; const AFileName: string);
  1549. begin
  1550. inherited Init(Bounds,AHScrollBAr,AVScrollBAr,AIndicator,ACore);
  1551. FileName:=AFileName;
  1552. UpdateIndicator;
  1553. Message(@Self,evBroadcast,cmFileNameChanged,@Self);
  1554. OnDiskLoadTime:=-1;
  1555. end;
  1556. function TFileEditor.LoadFile: boolean;
  1557. var OK: boolean;
  1558. PA : Array[1..2] of pointer;
  1559. begin
  1560. OK:=LoadFromFile(FileName);
  1561. if GetModified and (Core^.GetBindingCount=1) then
  1562. begin
  1563. PA[1]:=@FileName;
  1564. longint(PA[2]):=Core^.GetChangedLine;
  1565. EditorDialog(edChangedOnloading,@PA);
  1566. end;
  1567. OnDiskLoadTime:=GetFileTime(FileName);
  1568. LoadFile:=OK;
  1569. end;
  1570. function TFileEditor.IsChangedOnDisk : boolean;
  1571. begin
  1572. IsChangedOnDisk:=(OnDiskLoadTime<>GetFileTime(FileName)) and (OnDiskLoadTime<>-1);
  1573. end;
  1574. function TFileEditor.SaveFile: boolean;
  1575. var OK: boolean;
  1576. BAKName: string;
  1577. f: text;
  1578. begin
  1579. If IsChangedOnDisk then
  1580. begin
  1581. if EditorDialog(edFileOnDiskChanged, @FileName) <> cmYes then
  1582. begin
  1583. SaveFile:=false;
  1584. exit;
  1585. end;
  1586. end;
  1587. {$I-}
  1588. if IsFlagSet(efBackupFiles) and ExistsFile(FileName) then
  1589. begin
  1590. BAKName:=DirAndNameOf(FileName)+'.bak';
  1591. Assign(f,BAKName);
  1592. Erase(f);
  1593. EatIO;
  1594. Assign(f,FileName);
  1595. Rename(F,BAKName);
  1596. EatIO;
  1597. end;
  1598. {$I+}
  1599. OK:=SaveToFile(FileName);
  1600. if OK then
  1601. SetModified(false)
  1602. { Restore the original }
  1603. else if IsFlagSet(efBackupFiles) and ExistsFile(BakName) then
  1604. begin
  1605. {$I-}
  1606. Assign(f,BakName);
  1607. Rename(F,FileName);
  1608. EatIO;
  1609. {$I+}
  1610. end;
  1611. { don't forget to update the OnDiskLoadTime value }
  1612. if OK then
  1613. OnDiskLoadTime:=GetFileTime(FileName);
  1614. if not OK then
  1615. EditorDialog(edSaveError,@FileName);
  1616. SaveFile:=OK;
  1617. end;
  1618. function TFileEditor.ReloadFile: boolean;
  1619. var OK,WasModified: boolean;
  1620. BAKName: string;
  1621. f: text;
  1622. begin
  1623. If not IsChangedOnDisk then
  1624. begin
  1625. ReloadFile:=false;
  1626. exit;
  1627. end;
  1628. WasModified:=GetModified;
  1629. if not WasModified then
  1630. OK:=EditorDialog(edreloaddiskmodifiedfile, @FileName)=cmYes
  1631. else
  1632. OK:=EditorDialog(edreloaddiskandidemodifiedfile, @FileName)=cmYes;
  1633. if not OK then
  1634. begin
  1635. ReloadFile:=false;
  1636. exit;
  1637. end;
  1638. { avoid wrong message }
  1639. if WasModified then
  1640. SetModified(false);
  1641. OK:=LoadFile;
  1642. if OK then
  1643. begin
  1644. SetModified(false);
  1645. ClearUndoList;
  1646. { don't forget to update the OnDiskLoadTime value }
  1647. OnDiskLoadTime:=GetFileTime(FileName);
  1648. DrawView;
  1649. end
  1650. else
  1651. begin
  1652. if WasModified then
  1653. SetModified(true);
  1654. EditorDialog(edReadError,@FileName);
  1655. end;
  1656. ReloadFile:=OK;
  1657. end;
  1658. function TFileEditor.ShouldSave: boolean;
  1659. begin
  1660. ShouldSave:=GetModified{ or (FileName='')};
  1661. end;
  1662. function TFileEditor.Save: Boolean;
  1663. begin
  1664. if ShouldSave=false then begin Save:=true; Exit; end;
  1665. if FileName = '' then Save := SaveAs else Save := SaveFile;
  1666. end;
  1667. function TFileEditor.SaveAs: Boolean;
  1668. var
  1669. SavedName : String;
  1670. SavedDiskLoadTime : longint;
  1671. begin
  1672. SaveAs := False;
  1673. SavedName:=FileName;
  1674. SavedDiskLoadTime:=OnDiskLoadTime;
  1675. if EditorDialog(edSaveAs, @FileName) <> cmCancel then
  1676. begin
  1677. FileName:=FExpand(FileName);
  1678. Message(Owner, evBroadcast, cmUpdateTitle, @Self);
  1679. { if we rename the file the OnDiskLoadTime is wrong so we reset it }
  1680. OnDiskLoadTime:=-1;
  1681. if SaveFile then
  1682. begin
  1683. SaveAs := true;
  1684. end
  1685. else
  1686. begin
  1687. FileName:=SavedName;
  1688. OnDiskLoadTime:=SavedDiskLoadTime;
  1689. Message(Owner, evBroadcast, cmUpdateTitle, @Self);
  1690. end;
  1691. if IsClipboard then FileName := '';
  1692. Message(Application,evBroadcast,cmFileNameChanged,@Self);
  1693. end;
  1694. end;
  1695. function TFileEditor.SaveAsk(Force: boolean): boolean;
  1696. var OK: boolean;
  1697. D: Sw_integer;
  1698. begin
  1699. if Force then
  1700. begin
  1701. if GetModified then
  1702. OK:=Save
  1703. else
  1704. OK:=true;
  1705. end
  1706. else
  1707. begin
  1708. OK:=(GetModified=false);
  1709. if (OK=false) and (Core^.GetBindingCount>1) then
  1710. OK:=true;
  1711. if OK=false then
  1712. begin
  1713. if FileName = '' then D := edSaveUntitled else D := edSaveModify;
  1714. case EditorDialog(D, @FileName) of
  1715. cmYes : OK := Save;
  1716. cmNo : begin
  1717. { the file should be still marked as modified! (FK) }
  1718. { SetModified(False); }
  1719. OK:=true;
  1720. end;
  1721. cmCancel : begin
  1722. OK := False;
  1723. Message(Application,evBroadcast,cmSaveCancelled,@Self);
  1724. end;
  1725. end;
  1726. end;
  1727. end;
  1728. SaveAsk:=OK;
  1729. end;
  1730. procedure TFileEditor.BindingsChanged;
  1731. begin
  1732. Message(Application,evBroadcast,cmUpdateTitle,@Self);
  1733. end;
  1734. procedure TFileEditor.HandleEvent(var Event: TEvent);
  1735. var SH,B: boolean;
  1736. begin
  1737. case Event.What of
  1738. evBroadcast :
  1739. case Event.Command of
  1740. cmFileNameChanged :
  1741. if (Event.InfoPtr=nil) or (Event.InfoPtr=@Self) then
  1742. begin
  1743. B:=IsFlagSet(efSyntaxHighlight);
  1744. SH:=UseSyntaxHighlight(@Self);
  1745. if SH<>B then
  1746. if SH then
  1747. SetFlags(Flags or efSyntaxHighlight)
  1748. else
  1749. SetFlags(Flags and not efSyntaxHighlight);
  1750. if UseTabsPattern(@Self) then
  1751. SetFlags(Flags or efUseTabCharacters);
  1752. end;
  1753. end;
  1754. end;
  1755. inherited HandleEvent(Event);
  1756. end;
  1757. function TFileEditor.Valid(Command: Word): Boolean;
  1758. var OK: boolean;
  1759. begin
  1760. OK:=inherited Valid(Command);
  1761. if OK and (Command=cmClose) then
  1762. if IsClipboard=false then
  1763. OK:=SaveAsk(false);
  1764. Valid:=OK;
  1765. end;
  1766. (* constructor TFileEditor.Load(var S: TStream);
  1767. var P: PString;
  1768. SSP,SEP,CP,DP: TPoint;
  1769. HR: TRect;
  1770. PA : Array[1..2] of pointer;
  1771. HoldUndo : boolean;
  1772. begin
  1773. inherited Load(S);
  1774. HoldUndo:=GetStoreUndo;
  1775. SetStoreUndo(False);
  1776. P:=S.ReadStr;
  1777. FileName:=GetStr(P);
  1778. if P<>nil then DisposeStr(P);
  1779. UpdateIndicator;
  1780. { Message(@Self,evBroadcast,cmFileNameChanged,@Self);}
  1781. SSP:=SelStart; SEP:=SelEnd;
  1782. CP:=CurPos;
  1783. HR:=Highlight;
  1784. DP:=Delta;
  1785. if FileName<>'' then
  1786. LoadFile;
  1787. { if GetModified then
  1788. begin
  1789. PA[1]:=@FileName;
  1790. longint(PA[2]):=ChangedLine;
  1791. EditorDialog(edChangedOnloading,@PA);
  1792. end;}
  1793. SetHighlight(HR.A,HR.B);
  1794. SetSelection(SSP,SEP);
  1795. SetCurPtr(CP.X,CP.Y);
  1796. ScrollTo(DP.X,DP.Y);
  1797. SetModified(false);
  1798. LimitsChanged;
  1799. SetStoreUndo(HoldUndo);
  1800. end;
  1801. procedure TFileEditor.Store(var S: TStream);
  1802. begin
  1803. inherited Store(S);
  1804. S.WriteStr(@FileName);
  1805. end;
  1806. *)
  1807. function DefUseSyntaxHighlight(Editor: PFileEditor): boolean;
  1808. begin
  1809. DefUseSyntaxHighlight:=Editor^.IsFlagSet(efSyntaxHighlight);
  1810. end;
  1811. function DefUseTabsPattern(Editor: PFileEditor): boolean;
  1812. begin
  1813. DefUseTabsPattern:=Editor^.IsFlagSet(efUseTabCharacters);
  1814. end;
  1815. procedure RegisterWCEdit;
  1816. begin
  1817. {$ifndef NOOBJREG}
  1818. RegisterType(RIndicator);
  1819. RegisterType(RCodeEditor);
  1820. RegisterType(RFileEditor);
  1821. {$endif}
  1822. end;
  1823. END.
  1824. {
  1825. $Log$
  1826. Revision 1.6 2001-10-10 23:34:54 pierre
  1827. * fix bug 1632
  1828. Revision 1.5 2001/09/27 22:32:24 pierre
  1829. * avoid to get unnecessary warnings about modified files if file already open
  1830. Revision 1.4 2001/09/14 23:47:08 pierre
  1831. + more regexp, options now in Find/Replace dialogs
  1832. Revision 1.3 2001/09/14 16:33:06 pierre
  1833. * several small changes
  1834. Revision 1.2 2001/08/05 02:01:48 peter
  1835. * FVISION define to compile with fvision units
  1836. Revision 1.1 2001/08/04 11:30:25 peter
  1837. * ide works now with both compiler versions
  1838. Revision 1.1.2.20 2001/06/07 16:41:12 jonas
  1839. * updated for stricter checking of @ for procvars
  1840. Revision 1.1.2.19 2001/03/20 00:20:43 pierre
  1841. * fix some memory leaks + several small enhancements
  1842. Revision 1.1.2.18 2001/03/12 17:34:57 pierre
  1843. + Disassembly window started
  1844. Revision 1.1.2.17 2001/03/06 22:04:53 pierre
  1845. * Avoid cursor updates when editor window is locked
  1846. Revision 1.1.2.16 2001/02/19 10:40:51 pierre
  1847. * Check for changed files after Running tool or shell
  1848. Revision 1.1.2.15 2001/02/13 16:04:00 pierre
  1849. * fixes for bugs 1280
  1850. Revision 1.1.2.14 2001/02/05 12:58:26 pierre
  1851. * fix several Undo bugs
  1852. Revision 1.1.2.13 2000/12/30 22:44:37 peter
  1853. * autosave editor files fixed
  1854. Revision 1.1.2.12 2000/12/23 23:08:42 florian
  1855. * better message for unsaved files
  1856. Revision 1.1.2.11 2000/12/09 17:41:20 florian
  1857. * IndentSize is stored in the .INI file now
  1858. Revision 1.1.2.10 2000/11/29 12:04:37 pierre
  1859. * remove unwanted Indicator changes
  1860. Revision 1.1.2.9 2000/11/29 11:26:01 pierre
  1861. + TFPDlgWindow that handles cmSearchWindow
  1862. Revision 1.1.2.8 2000/11/27 12:06:50 pierre
  1863. New bunch of Gabor fixes
  1864. Revision 1.1.2.7 2000/11/14 23:41:32 pierre
  1865. * fix for bug 1234
  1866. Revision 1.1.2.6 2000/11/03 15:49:26 pierre
  1867. * more Undo fixes
  1868. Revision 1.1.2.5 2000/11/03 13:31:33 pierre
  1869. + more Undo stuff and smarter indent/unindent
  1870. Revision 1.1.2.4 2000/10/24 23:06:30 pierre
  1871. * some Undo/redo fixes
  1872. Revision 1.1.2.3 2000/09/18 13:20:55 pierre
  1873. New bunch of Gabor changes
  1874. }