2
0

wcedit.pas 57 KB

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