wcedit.pas 56 KB

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