fpcodtmp.pas 14 KB

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