fpcodtmp.pas 14 KB

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