uEditor.pas 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510
  1. {
  2. TIGCC IDE
  3. Copyright (C) 2004 Fréderic Bour
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2, or (at your option)
  7. any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software Foundation,
  14. Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  15. }
  16. unit uEditor;
  17. interface
  18. uses
  19. Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  20. Dialogs, ExtCtrls, StdCtrls, Buttons, Grids, ValEdit, Menus, FileCtrl,
  21. ComCtrls, CodeCompletion, HtFormatting;
  22. const
  23. DefautCaption = 'Completion Editor';
  24. Cell_Left = ' Left';
  25. Cell_Right = ' Right';
  26. Cell_Name = ' Name';
  27. Cell_Desc = ' Description';
  28. Cell_Line = ' Line';
  29. SaveModif = 'Save modifications ?';
  30. SaveError = 'Error %s:'#13#10'%s';
  31. PreviewLBl = 'Preview:';
  32. BrowseHSF = 'Select Directory where HSF files are stored';
  33. LoadingError = 'Error while loading! (%s error: %s)';
  34. type
  35. TCEditorForm = class(TForm)
  36. MenuPnl: TPanel;
  37. NewBtn: TSpeedButton;
  38. SaveBtn: TSpeedButton;
  39. OpenBtn: TSpeedButton;
  40. OpenDialog: TOpenDialog;
  41. SaveDialog: TSaveDialog;
  42. ToolsBtn: TSpeedButton;
  43. ToolsMenu: TPopupMenu;
  44. ParseHSF: TMenuItem;
  45. MainPageControl: TPageControl;
  46. InfoTab: TTabSheet;
  47. ItemsTab: TTabSheet;
  48. ItemsLbl: TLabel;
  49. ItemsList: TListBox;
  50. ItemBox: TGroupBox;
  51. ItemEditor: TValueListEditor;
  52. ApplyBtn: TButton;
  53. UNameLbl: TLabel;
  54. UNameEdit: TEdit;
  55. IncludeLbl: TLabel;
  56. IncludeMemo: TMemo;
  57. DelBtn: TButton;
  58. ParseHeader: TMenuItem;
  59. OpenHeaderDialog: TOpenDialog;
  60. N1: TMenuItem;
  61. Batch1: TMenuItem;
  62. PreviewBox: TPaintBox;
  63. procedure NewBtnClick(Sender: TObject);
  64. procedure FormCreate(Sender: TObject);
  65. procedure FormDestroy(Sender: TObject);
  66. procedure ApplyBtnClick(Sender: TObject);
  67. procedure OpenBtnClick(Sender: TObject);
  68. procedure SaveBtnClick(Sender: TObject);
  69. procedure DelBtnClick(Sender: TObject);
  70. procedure ItemsListClick(Sender: TObject);
  71. procedure ItemEditorStringsChange(Sender: TObject);
  72. procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  73. procedure ToolsBtnClick(Sender: TObject);
  74. procedure ParseHSFClick(Sender: TObject);
  75. procedure ParseHeaderClick(Sender: TObject);
  76. procedure PreviewBoxPaint(Sender: TObject);
  77. procedure ItemsListData(Control: TWinControl; Index: Integer;
  78. var Data: string);
  79. procedure Batch1Click(Sender: TObject);
  80. procedure SetModified(Sender: TObject);
  81. private
  82. { Déclarations privées }
  83. public
  84. { Déclarations publiques }
  85. Filename: string;
  86. Locked, Modified: Boolean;
  87. Lst, LastHeader: TStringList;
  88. HSFDir: string;
  89. procedure UpdatePreview;
  90. procedure SetItem(const Name, Left, Right, Description: string; Line: Cardinal);
  91. // Stream methods
  92. procedure Clear;
  93. procedure LoadFromStream(F: TStream);
  94. procedure SaveToStream(F: TStream);
  95. // Tools Method
  96. function ParseH(const FileName: string): Boolean;
  97. // Add Symbol Line
  98. function GetLine(const Symbol: string): Integer;
  99. end;
  100. var
  101. CEditorForm: TCEditorForm;
  102. procedure ClearCompletion(Lst: TStrings);
  103. implementation
  104. {$R *.dfm}
  105. uses uHSFParser, Math, uBatch;
  106. procedure ClearCompletion(Lst: TStrings);
  107. var
  108. i: Integer;
  109. begin
  110. for i := 0 to Lst.Count - 1 do
  111. Lst.Objects[i].Free;
  112. Lst.Clear;
  113. end;
  114. procedure TCEditorForm.UpdatePreview;
  115. begin
  116. PreviewBox.Repaint;
  117. end;
  118. procedure TCEditorForm.NewBtnClick(Sender: TObject);
  119. begin
  120. Clear;
  121. end;
  122. procedure TCEditorForm.FormCreate(Sender: TObject);
  123. begin
  124. LastHeader := TStringList.Create;
  125. Lst := TStringList.Create;
  126. Lst.Sorted := True;
  127. ItemEditor.ColWidths[0] := 96;
  128. ItemEditor.Strings.Clear;
  129. ItemEditor.Strings.Add(Cell_Name + '=');
  130. ItemEditor.Strings.Add(Cell_Left + '=');
  131. ItemEditor.Strings.Add(Cell_Right + '=');
  132. ItemEditor.Strings.Add(Cell_Desc + '=');
  133. ItemEditor.Strings.Add(Cell_Line + '=');
  134. Modified := False;
  135. Clear;
  136. end;
  137. procedure TCEditorForm.FormDestroy(Sender: TObject);
  138. begin
  139. ClearCompletion(Lst);
  140. Lst.Free;
  141. LastHeader.Free;
  142. end;
  143. procedure TCEditorForm.ApplyBtnClick(Sender: TObject);
  144. begin
  145. SetItem(ItemEditor.Values[Cell_Name],
  146. ItemEditor.Values[Cell_Left],
  147. ItemEditor.Values[Cell_Right],
  148. ItemEditor.Values[Cell_Desc],
  149. StrToIntDef(ItemEditor.Values[Cell_Line], 0));
  150. end;
  151. procedure TCEditorForm.OpenBtnClick(Sender: TObject);
  152. var
  153. F: TFileStream;
  154. begin
  155. if CloseQuery and OpenDialog.Execute then
  156. try
  157. Lst.Clear;
  158. IncludeMemo.Clear;
  159. F := TFileStream.Create(OpenDialog.FileName, fmOpenRead);
  160. try
  161. LoadFromStream(F);
  162. Filename := OpenDialog.FileName;
  163. Caption := DefautCaption + ' - ' + ExtractFileName(Filename);
  164. finally
  165. F.Free;
  166. end;
  167. except
  168. on E: Exception do
  169. ShowMessageFmt(LoadingError, [E.ClassName, E.Message]);
  170. end;
  171. ItemsList.Count := Lst.Count;
  172. end;
  173. procedure TCEditorForm.SaveBtnClick(Sender: TObject);
  174. var
  175. F: TFileStream;
  176. begin
  177. if FileExists(Filename) or SaveDialog.Execute then
  178. try
  179. F := TFileStream.Create(SaveDialog.FileName, fmCreate);
  180. SaveToStream(F);
  181. F.Free;
  182. Filename := SaveDialog.FileName;
  183. Caption := DefautCaption + ' - ' + ExtractFileName(Filename);
  184. Modified := False;
  185. except
  186. on E: Exception do
  187. ShowMessageFmt(SaveError, [E.ClassName, E.Message]);
  188. end;
  189. end;
  190. procedure TCEditorForm.DelBtnClick(Sender: TObject);
  191. var
  192. i: Integer;
  193. begin
  194. for i := Lst.Count - 1 downto 0 do
  195. if ItemsList.Selected[i] then
  196. begin
  197. Lst.Objects[i].Free;
  198. Lst.Delete(i);
  199. end;
  200. ItemsList.Count := Lst.Count;
  201. end;
  202. procedure TCEditorForm.ItemsListClick(Sender: TObject);
  203. var
  204. i: Integer;
  205. O: TCompletionItem;
  206. begin
  207. if ItemsList.SelCount > 0 then
  208. begin
  209. i := ItemsList.ItemIndex;
  210. ItemEditor.Strings.BeginUpdate;
  211. ItemEditor.Values[Cell_Name] := Lst[i];
  212. O := TCompletionItem(Lst.Objects[i]);
  213. if Assigned(O) then
  214. begin
  215. ItemEditor.Values[Cell_Left] := O.Left;
  216. ItemEditor.Values[Cell_Right] := O.Right;
  217. ItemEditor.Values[Cell_Desc] := O.Description;
  218. ItemEditor.Values[Cell_Line] := IntToStr(O.Line);
  219. end;
  220. ItemEditor.Strings.EndUpdate;
  221. UpdatePreview;
  222. end;
  223. end;
  224. procedure TCEditorForm.ItemEditorStringsChange(Sender: TObject);
  225. begin
  226. UpdatePreview;
  227. SetModified(Sender);
  228. end;
  229. procedure TCEditorForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  230. begin
  231. CanClose := True;
  232. if Modified then
  233. case MessageDlg(SaveModif, mtConfirmation, mbYesNoCancel, 0) of
  234. mrYes: SaveBtn.Click;
  235. mrNo: ;
  236. else
  237. CanClose := False;
  238. end;
  239. end;
  240. procedure TCEditorForm.ToolsBtnClick(Sender: TObject);
  241. var
  242. P: TPoint;
  243. begin
  244. P := Point(0, ToolsBtn.Height);
  245. P := ToolsBtn.ClientToScreen(P);
  246. ToolsMenu.Popup(P.X, P.Y);
  247. end;
  248. procedure TCEditorForm.ParseHeaderClick(Sender: TObject);
  249. begin
  250. if OpenHeaderDialog.Execute then
  251. ParseH(OpenHeaderDialog.FileName);
  252. end;
  253. procedure TCEditorForm.ParseHSFClick(Sender: TObject);
  254. begin
  255. if SelectDirectory(BrowseHSF, '', HSFDir) then
  256. begin
  257. Locked := True;
  258. Lst.BeginUpdate;
  259. ImportDir(HSFDir, Self, GetLine);
  260. Lst.EndUpdate;
  261. Locked := False;
  262. ItemsList.Count := Lst.Count;
  263. end;
  264. end;
  265. procedure TCEditorForm.SetItem(const Name, Left, Right, Description: string; Line: Cardinal);
  266. var
  267. i: Integer;
  268. O: TCompletionItem;
  269. begin
  270. if (Name <> '') then
  271. begin
  272. i := Lst.IndexOf(Name);
  273. if i = -1 then
  274. begin
  275. O := TCompletionItem.Create;
  276. i := Lst.AddObject(Name, O);
  277. end
  278. else
  279. O := TCompletionItem(Lst.Objects[i]);
  280. O.Left := Left;
  281. O.Right := Right;
  282. O.Description := Description;
  283. O.Line := Line;
  284. if not Locked then
  285. begin
  286. ItemsList.Count := Lst.Count;
  287. ItemsList.ItemIndex := i;
  288. end;
  289. Modified := True;
  290. end;
  291. end;
  292. procedure TCEditorForm.LoadFromStream(F: TStream);
  293. var
  294. S: string;
  295. i, W: Word;
  296. C: TCompletionItem;
  297. B: Byte;
  298. begin
  299. if (F.Read(B, 1) = 1) and (B = CCFVersion) and ReadString(F, S) then
  300. begin
  301. // Set Unit Name
  302. UNameEdit.Text := S;
  303. if F.Read(W, 2) = 2 then
  304. begin
  305. // Load Includes List
  306. IncludeMemo.Lines.Clear;
  307. for i := 1 to W do
  308. begin
  309. if ReadString(F, S) then
  310. IncludeMemo.Lines.Add(S)
  311. else
  312. Break;
  313. end;
  314. // Load Symbols List
  315. while ReadString(F, S) do
  316. begin
  317. C := TCompletionItem.Create;
  318. C.ReadFromStream(F);
  319. Lst.AddObject(S, C);
  320. end;
  321. end;
  322. ItemsList.Count := Lst.Count;
  323. end;
  324. end;
  325. procedure TCEditorForm.PreviewBoxPaint(Sender: TObject);
  326. var
  327. H, W: Integer;
  328. C: TCanvas;
  329. R: TRect;
  330. begin
  331. C := PreviewBox.Canvas;
  332. R := PreviewBox.ClientRect;
  333. H := C.TextHeight(PreviewLbl) + 2;
  334. try
  335. C.FillRect(R);
  336. // Draw Preview
  337. C.TextRect(R, R.Left, R.Top, PreviewLbl);
  338. Inc(R.Top, H);
  339. // Draw Left
  340. DrawHtText(ItemEditor.Values[Cell_Left], R, C, W, False);
  341. Inc(R.Top, H);
  342. // Draw Name
  343. C.Font.Style := [fsBold];
  344. C.TextRect(R, R.Left, R.Top, ItemEditor.Values[Cell_Name]);
  345. C.Font.Style := [];
  346. Inc(R.Top, H);
  347. // Draw Right
  348. DrawHtText(ItemEditor.Values[Cell_Right], R, C, W, False);
  349. Inc(R.Top, H);
  350. // Draw Description
  351. C.TextRect(R, R.Left, R.Top, ItemEditor.Values[Cell_Desc]);
  352. Inc(R.Top, H);
  353. except
  354. C.Font.Style := [];
  355. end;
  356. end;
  357. procedure TCEditorForm.SaveToStream(F: TStream);
  358. var
  359. i: Integer;
  360. W: Word;
  361. begin
  362. try
  363. // Write CCF Version
  364. F.Write(CCFVersion, SizeOf(CCFVersion));
  365. // Write Unit Name
  366. WriteString(F, UNameEdit.Text);
  367. // Write Included Units
  368. W := IncludeMemo.Lines.Count;
  369. if F.Write(W, 2) = 2 then
  370. for i := 0 to W - 1 do
  371. if not WriteString(F, Trim(IncludeMemo.Lines[i])) then
  372. Break;
  373. // Write Symbols
  374. for i := 0 to Lst.Count - 1 do
  375. begin
  376. if WriteString(F, Lst[i]) then
  377. TCompletionItem(Lst.Objects[i]).WriteToStream(F)
  378. else
  379. Break;
  380. end;
  381. except
  382. end;
  383. end;
  384. function TCEditorForm.ParseH(const FileName: string): Boolean;
  385. var
  386. Src: TStringList;
  387. S: TStream;
  388. begin
  389. Src := TStringList.Create;
  390. try
  391. try
  392. Src.LoadFromFile(FileName);
  393. S := TStringStream.Create(MakeCCF_H(ExtractFileName(FileName), Src, LastHeader));
  394. try
  395. LoadFromStream(S);
  396. finally
  397. S.Free;
  398. end;
  399. finally
  400. Src.Free;
  401. end;
  402. Result := True;
  403. except
  404. Result := False;
  405. end;
  406. end;
  407. procedure TCEditorForm.Clear;
  408. begin
  409. if CloseQuery then
  410. begin
  411. LastHeader.Clear;
  412. Caption := DefautCaption;
  413. Filename := '';
  414. UNameEdit.Text := '';
  415. IncludeMemo.Text := '';
  416. ClearCompletion(Lst);
  417. ItemsList.Count := 0;
  418. end;
  419. end;
  420. procedure TCEditorForm.ItemsListData(Control: TWinControl; Index: Integer;
  421. var Data: string);
  422. begin
  423. if (Index >= 0) and (Index < Lst.Count) then
  424. Data := Lst[Index]
  425. else
  426. ItemsList.Count := Lst.Count;
  427. end;
  428. procedure TCEditorForm.Batch1Click(Sender: TObject);
  429. var
  430. B: TBatchEdit;
  431. begin
  432. Locked := True;
  433. B := TBatchEdit.Create(Self);
  434. B.Editor := Self;
  435. B.ShowModal;
  436. B.Free;
  437. Locked := False;
  438. end;
  439. procedure TCEditorForm.SetModified(Sender: TObject);
  440. begin
  441. Modified := True;
  442. end;
  443. function TCEditorForm.GetLine(const Symbol: string): Integer;
  444. var
  445. i, p: Integer;
  446. S: string;
  447. begin
  448. for i := 0 to LastHeader.Count - 1 do
  449. begin
  450. S := LastHeader[i];
  451. p := Pos(Symbol, S);
  452. if not ((p = 0) or ((p > 1) and (S[p - 1] in ['a'..'z', 'A'..'Z', '0'..'9', '$', '_']))) then
  453. if GetIdent(S, p) = Symbol then
  454. begin
  455. Result := i;
  456. Exit;
  457. end;
  458. end;
  459. Result := 0;
  460. end;
  461. end.