uEditor.pas 11 KB

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