fpcodtmp.pas 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520
  1. unit FPCodTmp; { Code Templates }
  2. interface
  3. uses Objects,Drivers,Dialogs,
  4. WUtils,WViews,WEditor,
  5. FPViews;
  6. type
  7. PCodeTemplate = ^TCodeTemplate;
  8. TCodeTemplate = object(TObject)
  9. constructor Init(const AShortCut: string; AText: PUnsortedStringCollection);
  10. function GetShortCut: string;
  11. procedure GetText(AList: PUnsortedStringCollection);
  12. procedure SetShortCut(const AShortCut: string);
  13. procedure SetText(AList: PUnsortedStringCollection);
  14. procedure GetParams(var AShortCut: string; Lines: PUnsortedStringCollection);
  15. procedure SetParams(const AShortCut: string; Lines: PUnsortedStringCollection);
  16. constructor Load(var S: TStream);
  17. procedure Store(var S: TStream);
  18. destructor Done; virtual;
  19. private
  20. ShortCut: PString;
  21. Text: PUnsortedStringCollection;
  22. end;
  23. PCodeTemplateCollection = ^TCodeTemplateCollection;
  24. TCodeTemplateCollection = object(TSortedCollection)
  25. function Compare(Key1, Key2: Pointer): sw_Integer; virtual;
  26. function SearchByShortCut(const ShortCut: string): PCodeTemplate; virtual;
  27. end;
  28. PCodeTemplateListBox = ^TCodeTemplateListBox;
  29. TCodeTemplateListBox = object(TAdvancedListBox)
  30. function GetText(Item,MaxLen: Sw_Integer): String; virtual;
  31. end;
  32. PCodeTemplateDialog = ^TCodeTemplateDialog;
  33. TCodeTemplateDialog = object(TCenterDialog)
  34. constructor Init(const ATitle: string; ATemplate: PCodeTemplate);
  35. function Execute: Word; virtual;
  36. private
  37. Template : PCodeTemplate;
  38. ShortcutIL : PInputLine;
  39. CodeMemo : PFPCodeMemo;
  40. end;
  41. PCodeTemplatesDialog = ^TCodeTemplatesDialog;
  42. TCodeTemplatesDialog = object(TCenterDialog)
  43. constructor Init;
  44. function Execute: Word; virtual;
  45. procedure HandleEvent(var Event: TEvent); virtual;
  46. private
  47. CodeTemplatesLB : PCodeTemplateListBox;
  48. TemplateViewer : PFPCodeMemo;
  49. procedure Add;
  50. procedure Edit;
  51. procedure Delete;
  52. procedure Update;
  53. end;
  54. const CodeTemplates : PCodeTemplateCollection = nil;
  55. function FPTranslateCodeTemplate(const Shortcut: string; ALines: PUnsortedStringCollection): boolean;
  56. procedure InitCodeTemplates;
  57. function LoadCodeTemplates(var S: TStream): boolean;
  58. function StoreCodeTemplates(var S: TStream): boolean;
  59. procedure DoneCodeTemplates;
  60. procedure RegisterCodeTemplates;
  61. implementation
  62. uses Commands,Views,App,
  63. FPConst,FPString;
  64. {$ifndef NOOBJREG}
  65. const
  66. RCodeTemplate: TStreamRec = (
  67. ObjType: 14501;
  68. VmtLink: Ofs(TypeOf(TCodeTemplate)^);
  69. Load: @TCodeTemplate.Load;
  70. Store: @TCodeTemplate.Store
  71. );
  72. RCodeTemplateCollection: TStreamRec = (
  73. ObjType: 14502;
  74. VmtLink: Ofs(TypeOf(TCodeTemplateCollection)^);
  75. Load: @TCodeTemplateCollection.Load;
  76. Store: @TCodeTemplateCollection.Store
  77. );
  78. {$endif}
  79. constructor TCodeTemplate.Init(const AShortCut: string; AText: PUnsortedStringCollection);
  80. procedure CopyIt(P: PString); {$ifndef FPC}far;{$endif}
  81. begin
  82. Text^.Insert(NewStr(GetStr(P)));
  83. end;
  84. begin
  85. inherited Init;
  86. ShortCut:=NewStr(AShortCut);
  87. SetText(AText);
  88. end;
  89. function TCodeTemplate.GetShortCut: string;
  90. begin
  91. GetShortCut:=GetStr(ShortCut);
  92. end;
  93. procedure TCodeTemplate.GetText(AList: PUnsortedStringCollection);
  94. procedure CopyIt(P: PString); {$ifndef FPC}far;{$endif}
  95. begin
  96. AList^.Insert(NewStr(GetStr(P)));
  97. end;
  98. begin
  99. if Assigned(AList) and Assigned(Text) then
  100. Text^.ForEach(@CopyIt);
  101. end;
  102. procedure TCodeTemplate.SetShortCut(const AShortCut: string);
  103. begin
  104. if Assigned(ShortCut) then DisposeStr(ShortCut);
  105. ShortCut:=NewStr(AShortCut);
  106. end;
  107. procedure TCodeTemplate.SetText(AList: PUnsortedStringCollection);
  108. begin
  109. if Assigned(Text) then Dispose(Text, Done);
  110. New(Text, CreateFrom(AList));
  111. end;
  112. procedure TCodeTemplate.GetParams(var AShortCut: string; Lines: PUnsortedStringCollection);
  113. begin
  114. AShortCut:=GetShortCut;
  115. GetText(Lines);
  116. end;
  117. procedure TCodeTemplate.SetParams(const AShortCut: string; Lines: PUnsortedStringCollection);
  118. begin
  119. SetShortCut(AShortCut);
  120. SetText(Lines);
  121. end;
  122. constructor TCodeTemplate.Load(var S: TStream);
  123. begin
  124. ShortCut:=S.ReadStr;
  125. New(Text, Load(S));
  126. end;
  127. procedure TCodeTemplate.Store(var S: TStream);
  128. begin
  129. S.WriteStr(ShortCut);
  130. Text^.Store(S);
  131. end;
  132. destructor TCodeTemplate.Done;
  133. begin
  134. if Assigned(ShortCut) then DisposeStr(ShortCut); ShortCut:=nil;
  135. if Assigned(Text) then Dispose(Text, Done); Text:=nil;
  136. inherited Done;
  137. end;
  138. function TCodeTemplateCollection.Compare(Key1, Key2: Pointer): sw_Integer;
  139. var K1: PCodeTemplate absolute Key1;
  140. K2: PCodeTemplate absolute Key2;
  141. R: Sw_integer;
  142. S1,S2: string;
  143. begin
  144. S1:=UpCaseStr(K1^.GetShortCut);
  145. S2:=UpCaseStr(K2^.GetShortCut);
  146. if S1<S2 then R:=-1 else
  147. if S1>S2 then R:=1 else
  148. R:=0;
  149. Compare:=R;
  150. end;
  151. function TCodeTemplateCollection.SearchByShortCut(const ShortCut: string): PCodeTemplate;
  152. var T: TCodeTemplate;
  153. Index: sw_integer;
  154. P: PCodeTemplate;
  155. begin
  156. T.Init(ShortCut,nil);
  157. if Search(@T,Index)=false then P:=nil else
  158. P:=At(Index);
  159. T.Done;
  160. SearchByShortCut:=P;
  161. end;
  162. function FPTranslateCodeTemplate(const Shortcut: string; ALines: PUnsortedStringCollection): boolean;
  163. var OK: boolean;
  164. P: PCodeTemplate;
  165. begin
  166. OK:=Assigned(CodeTemplates);
  167. if OK then
  168. begin
  169. P:=CodeTemplates^.SearchByShortCut(ShortCut);
  170. OK:=Assigned(P);
  171. if OK then
  172. P^.GetText(ALines);
  173. end;
  174. FPTranslateCodeTemplate:=OK;
  175. end;
  176. procedure InitCodeTemplates;
  177. begin
  178. if Assigned(CodeTemplates) then Exit;
  179. New(CodeTemplates, Init(10,10));
  180. end;
  181. function LoadCodeTemplates(var S: TStream): boolean;
  182. var C: PCodeTemplateCollection;
  183. OK: boolean;
  184. begin
  185. New(C, Load(S));
  186. OK:=Assigned(C) and (S.Status=stOk);
  187. if OK then
  188. begin
  189. if Assigned(CodeTemplates) then Dispose(CodeTemplates, Done);
  190. CodeTemplates:=C;
  191. end
  192. else
  193. if Assigned(C) then
  194. Dispose(C, Done);
  195. LoadCodeTemplates:=OK;
  196. end;
  197. function StoreCodeTemplates(var S: TStream): boolean;
  198. var OK: boolean;
  199. begin
  200. OK:=Assigned(CodeTemplates);
  201. if OK then
  202. begin
  203. CodeTemplates^.Store(S);
  204. OK:=OK and (S.Status=stOK);
  205. end;
  206. StoreCodeTemplates:=OK;
  207. end;
  208. procedure DoneCodeTemplates;
  209. begin
  210. if Assigned(CodeTemplates) then Dispose(CodeTemplates, Done);
  211. CodeTemplates:=nil;
  212. end;
  213. function TCodeTemplateListBox.GetText(Item,MaxLen: Sw_Integer): String;
  214. var P: PCodeTemplate;
  215. begin
  216. P:=List^.At(Item);
  217. GetText:=P^.GetShortCut;
  218. end;
  219. constructor TCodeTemplateDialog.Init(const ATitle: string; ATemplate: PCodeTemplate);
  220. var R,R2,R3: TRect;
  221. begin
  222. R.Assign(0,0,52,15);
  223. inherited Init(R,ATitle);
  224. Template:=ATemplate;
  225. GetExtent(R); R.Grow(-3,-2); R3.Copy(R);
  226. Inc(R.A.Y); R.B.Y:=R.A.Y+1; R.B.X:=R.A.X+46;
  227. New(ShortCutIL, Init(R, 128)); Insert(ShortcutIL);
  228. R2.Copy(R); R2.Move(-1,-1); Insert(New(PLabel, Init(R2, label_codetemplate_shortcut, ShortcutIL)));
  229. R.Move(0,3); R.B.Y:=R.A.Y+8;
  230. New(CodeMemo, Init(R, nil,nil,nil{,4096 does not compile !! })); Insert(CodeMemo);
  231. R2.Copy(R); R2.Move(-1,-1); R2.B.Y:=R2.A.Y+1; Insert(New(PLabel, Init(R2, label_codetemplate_content, CodeMemo)));
  232. InsertButtons(@Self);
  233. ShortcutIL^.Select;
  234. end;
  235. function TCodeTemplateDialog.Execute: Word;
  236. var R: word;
  237. S: string;
  238. L: PUnsortedStringCollection;
  239. begin
  240. New(L, Init(10,10));
  241. S:=Template^.GetShortCut;
  242. Template^.GetText(L);
  243. ShortcutIL^.SetData(S);
  244. CodeMemo^.SetContent(L);
  245. R:=inherited Execute;
  246. if R=cmOK then
  247. begin
  248. L^.FreeAll;
  249. ShortcutIL^.GetData(S);
  250. CodeMemo^.GetContent(L);
  251. Template^.SetShortcut(S);
  252. Template^.SetText(L);
  253. end;
  254. Execute:=R;
  255. end;
  256. constructor TCodeTemplatesDialog.Init;
  257. var R,R2,R3: TRect;
  258. SB: PScrollBar;
  259. begin
  260. R.Assign(0,0,46,20);
  261. inherited Init(R,'CodeTemplates');
  262. GetExtent(R); R.Grow(-3,-2); Inc(R.A.Y); R.B.Y:=R.A.Y+10;
  263. R3.Copy(R); Dec(R.B.X,12);
  264. R2.Copy(R); R2.Move(1,0); R2.A.X:=R2.B.X-1;
  265. New(SB, Init(R2)); Insert(SB);
  266. New(CodeTemplatesLB, Init(R,1,SB));
  267. Insert(CodeTemplatesLB);
  268. R2.Copy(R); R2.Move(0,-1); R2.B.Y:=R2.A.Y+1; Dec(R2.A.X);
  269. Insert(New(PLabel, Init(R2, label_codetemplate_templates, CodeTemplatesLB)));
  270. GetExtent(R); R.Grow(-2,-2); Inc(R.A.Y,12);
  271. R2.Copy(R); R2.Move(1,0); R2.A.X:=R2.B.X-1;
  272. New(SB, Init(R2)); Insert(SB);
  273. New(TemplateViewer, Init(R,nil,SB,nil{,4096 does not compile }));
  274. with TemplateViewer^ do
  275. begin
  276. ReadOnly:=true;
  277. AlwaysShowScrollBars:=true;
  278. end;
  279. Insert(TemplateViewer);
  280. R.Copy(R3); R.A.X:=R.B.X-10; R.B.Y:=R.A.Y+2;
  281. Insert(New(PButton, Init(R, button_OK, cmOK, bfNormal)));
  282. R.Move(0,2);
  283. Insert(New(PButton, Init(R, button_Edit, cmEditItem, bfDefault)));
  284. R.Move(0,2);
  285. Insert(New(PButton, Init(R, button_New, cmAddItem, bfNormal)));
  286. R.Move(0,2);
  287. Insert(New(PButton, Init(R, button_Delete, cmDeleteItem, bfNormal)));
  288. R.Move(0,2);
  289. Insert(New(PButton, Init(R, button_Cancel, cmCancel, bfNormal)));
  290. SelectNext(false);
  291. end;
  292. procedure TCodeTemplatesDialog.Update;
  293. var C: PUnsortedStringCollection;
  294. begin
  295. if CodeTemplatesLB^.Range=0 then C:=nil else
  296. C:=PCodeTemplate(CodeTemplatesLB^.GetFocusedItem)^.Text;
  297. TemplateViewer^.SetContent(C);
  298. ReDraw;
  299. end;
  300. procedure TCodeTemplatesDialog.HandleEvent(var Event: TEvent);
  301. var DontClear: boolean;
  302. begin
  303. case Event.What of
  304. evKeyDown :
  305. begin
  306. DontClear:=false;
  307. case Event.KeyCode of
  308. kbIns :
  309. Message(@Self,evCommand,cmAddItem,nil);
  310. kbDel :
  311. Message(@Self,evCommand,cmDeleteItem,nil);
  312. else DontClear:=true;
  313. end;
  314. if DontClear=false then ClearEvent(Event);
  315. end;
  316. evBroadcast :
  317. case Event.Command of
  318. cmListItemSelected :
  319. if Event.InfoPtr=pointer(CodeTemplatesLB) then
  320. Message(@Self,evCommand,cmEditItem,nil);
  321. cmListFocusChanged :
  322. if Event.InfoPtr=pointer(CodeTemplatesLB) then
  323. Message(@Self,evBroadcast,cmUpdate,nil);
  324. cmUpdate :
  325. Update;
  326. end;
  327. evCommand :
  328. begin
  329. DontClear:=false;
  330. case Event.Command of
  331. cmAddItem : Add;
  332. cmDeleteItem : Delete;
  333. cmEditItem : Edit;
  334. else DontClear:=true;
  335. end;
  336. if DontClear=false then ClearEvent(Event);
  337. end;
  338. end;
  339. inherited HandleEvent(Event);
  340. end;
  341. function TCodeTemplatesDialog.Execute: Word;
  342. var R: word;
  343. P: PCodeTemplate;
  344. C: PCodeTemplateCollection;
  345. L: PUnsortedStringCollection;
  346. I: integer;
  347. begin
  348. New(C, Init(10,20));
  349. if Assigned(CodeTemplates) then
  350. for I:=0 to CodeTemplates^.Count-1 do
  351. begin
  352. P:=CodeTemplates^.At(I);
  353. New(L, Init(10,50));
  354. P^.GetText(L);
  355. C^.Insert(New(PCodeTemplate, Init(P^.GetShortCut,L)));
  356. Dispose(L, Done);
  357. end;
  358. CodeTemplatesLB^.NewList(C);
  359. Update;
  360. R:=inherited Execute;
  361. if R=cmOK then
  362. begin
  363. if Assigned(CodeTemplates) then Dispose(CodeTemplates, Done);
  364. CodeTemplates:=C;
  365. end
  366. else
  367. Dispose(C, Done);
  368. Execute:=R;
  369. end;
  370. procedure TCodeTemplatesDialog.Add;
  371. var P,P2: PCodeTemplate;
  372. IC: boolean;
  373. S: string;
  374. L: PUnsortedStringCollection;
  375. Cmd: word;
  376. CanExit: boolean;
  377. begin
  378. New(L, Init(10,10));
  379. IC:=CodeTemplatesLB^.Range=0;
  380. if IC=false then
  381. begin
  382. P:=CodeTemplatesLB^.List^.At(CodeTemplatesLB^.Focused);
  383. P^.GetParams(S,L);
  384. end
  385. else
  386. begin
  387. S:='';
  388. end;
  389. New(P, Init(S,L));
  390. repeat
  391. Cmd:=Application^.ExecuteDialog(New(PCodeTemplateDialog, Init(dialog_newtemplate,P)), nil);
  392. CanExit:=(Cmd<>cmOK);
  393. if CanExit=false then
  394. begin
  395. P2:=PCodeTemplateCollection(CodeTemplatesLB^.List)^.SearchByShortCut(P^.GetShortCut);
  396. CanExit:=(Assigned(P2)=false);
  397. if CanExit=false then
  398. begin
  399. ClearFormatParams; AddFormatParamStr(P^.GetShortCut);
  400. ErrorBox(msg_codetemplate_alreadyinlist,@FormatParams);
  401. end;
  402. end;
  403. until CanExit;
  404. if Cmd=cmOK then
  405. begin
  406. CodeTemplatesLB^.List^.Insert(P);
  407. CodeTemplatesLB^.SetRange(CodeTemplatesLB^.List^.Count);
  408. CodeTemplatesLB^.SetFocusedItem(P);
  409. Update;
  410. end
  411. else
  412. Dispose(P, Done);
  413. Dispose(L, Done);
  414. end;
  415. procedure TCodeTemplatesDialog.Edit;
  416. var P,O,P2: PCodeTemplate;
  417. I: sw_integer;
  418. S: string;
  419. L: PUnsortedStringCollection;
  420. Cmd: word;
  421. CanExit: boolean;
  422. begin
  423. if CodeTemplatesLB^.Range=0 then Exit;
  424. New(L, Init(10,10));
  425. I:=CodeTemplatesLB^.Focused;
  426. O:=CodeTemplatesLB^.List^.At(I);
  427. O^.GetParams(S,L);
  428. P:=New(PCodeTemplate, Init(S, L));
  429. repeat
  430. Cmd:=Application^.ExecuteDialog(New(PCodeTemplateDialog, Init(dialog_modifytemplate,P)), nil);
  431. CanExit:=(Cmd<>cmOK);
  432. if CanExit=false then
  433. begin
  434. P2:=PCodeTemplateCollection(CodeTemplatesLB^.List)^.SearchByShortCut(P^.GetShortCut);
  435. CanExit:=(Assigned(P2)=false) or (CodeTemplatesLB^.List^.IndexOf(P2)=I);
  436. if CanExit=false then
  437. begin
  438. ClearFormatParams; AddFormatParamStr(P^.GetShortCut);
  439. ErrorBox(msg_codetemplate_alreadyinlist,@FormatParams);
  440. end;
  441. end;
  442. until CanExit;
  443. if Cmd=cmOK then
  444. begin
  445. with CodeTemplatesLB^ do
  446. begin
  447. List^.AtFree(I); O:=nil;
  448. List^.Insert(P);
  449. SetFocusedItem(P);
  450. end;
  451. Update;
  452. end;
  453. Dispose(L, Done);
  454. end;
  455. procedure TCodeTemplatesDialog.Delete;
  456. begin
  457. if CodeTemplatesLB^.Range=0 then Exit;
  458. CodeTemplatesLB^.List^.AtFree(CodeTemplatesLB^.Focused);
  459. CodeTemplatesLB^.SetRange(CodeTemplatesLB^.List^.Count);
  460. Update;
  461. end;
  462. procedure RegisterCodeTemplates;
  463. begin
  464. {$ifndef NOOBJREG}
  465. RegisterType(RCodeTemplate);
  466. RegisterType(RCodeTemplateCollection);
  467. {$endif}
  468. end;
  469. END.