fpcodtmp.pas 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638
  1. {
  2. This file is part of the Free Pascal Integrated Development Environment
  3. Copyright (c) 1998 by Berczi Gabor
  4. Code Template routines
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. unit FPCodTmp; { Code Templates }
  12. interface
  13. uses Objects,Drivers,Dialogs,
  14. WUtils,WViews,WEditor,
  15. FPViews;
  16. type
  17. PCodeTemplate = ^TCodeTemplate;
  18. TCodeTemplate = object(TObject)
  19. constructor Init(const AShortCut: string; AText: PUnsortedStringCollection);
  20. function GetShortCut: string;
  21. procedure GetText(AList: PUnsortedStringCollection);
  22. procedure SetShortCut(const AShortCut: string);
  23. procedure SetText(AList: PUnsortedStringCollection);
  24. procedure GetParams(var AShortCut: string; Lines: PUnsortedStringCollection);
  25. procedure SetParams(const AShortCut: string; Lines: PUnsortedStringCollection);
  26. constructor Load(var S: TStream);
  27. procedure Store(var S: TStream);
  28. destructor Done; virtual;
  29. private
  30. ShortCut: PString;
  31. Text: PUnsortedStringCollection;
  32. end;
  33. PCodeTemplateCollection = ^TCodeTemplateCollection;
  34. TCodeTemplateCollection = object(TSortedCollection)
  35. function Compare(Key1, Key2: Pointer): sw_Integer; virtual;
  36. function SearchByShortCut(const ShortCut: string): PCodeTemplate; virtual;
  37. function LookUp(const S: string; AcceptMulti: boolean; var Idx: sw_integer): string; virtual;
  38. end;
  39. PCodeTemplateListBox = ^TCodeTemplateListBox;
  40. TCodeTemplateListBox = object(TAdvancedListBox)
  41. function GetText(Item,MaxLen: Sw_Integer): String; virtual;
  42. end;
  43. PCodeTemplateDialog = ^TCodeTemplateDialog;
  44. TCodeTemplateDialog = object(TCenterDialog)
  45. constructor Init(const ATitle: string; ATemplate: PCodeTemplate);
  46. function Execute: Word; virtual;
  47. private
  48. Template : PCodeTemplate;
  49. ShortcutIL : PInputLine;
  50. CodeMemo : PFPCodeMemo;
  51. end;
  52. PCodeTemplatesDialog = ^TCodeTemplatesDialog;
  53. TCodeTemplatesDialog = object(TCenterDialog)
  54. SelMode: boolean;
  55. constructor Init(ASelMode: boolean;const AShortCut : string);
  56. function Execute: Word; virtual;
  57. procedure HandleEvent(var Event: TEvent); virtual;
  58. function GetSelectedShortCut: string;
  59. private
  60. CodeTemplatesLB : PCodeTemplateListBox;
  61. TemplateViewer : PFPCodeMemo;
  62. StartIdx : sw_integer;
  63. procedure Add;
  64. procedure Edit;
  65. procedure Delete;
  66. procedure Update;
  67. end;
  68. const CodeTemplates : PCodeTemplateCollection = nil;
  69. function FPTranslateCodeTemplate(var Shortcut: string; ALines: PUnsortedStringCollection): boolean;
  70. procedure InitCodeTemplates;
  71. function LoadCodeTemplates(var S: TStream): boolean;
  72. function StoreCodeTemplates(var S: TStream): boolean;
  73. procedure DoneCodeTemplates;
  74. procedure RegisterCodeTemplates;
  75. implementation
  76. uses Views,App,Validate,
  77. FVConsts,
  78. FPConst,FPString;
  79. {$ifndef NOOBJREG}
  80. const
  81. RCodeTemplate: TStreamRec = (
  82. ObjType: 14501;
  83. VmtLink: Ofs(TypeOf(TCodeTemplate)^);
  84. Load: @TCodeTemplate.Load;
  85. Store: @TCodeTemplate.Store
  86. );
  87. RCodeTemplateCollection: TStreamRec = (
  88. ObjType: 14502;
  89. VmtLink: Ofs(TypeOf(TCodeTemplateCollection)^);
  90. Load: @TCodeTemplateCollection.Load;
  91. Store: @TCodeTemplateCollection.Store
  92. );
  93. {$endif}
  94. constructor TCodeTemplate.Init(const AShortCut: string; AText: PUnsortedStringCollection);
  95. procedure CopyIt(P: PString); {$ifndef FPC}far;{$endif}
  96. begin
  97. Text^.Insert(NewStr(GetStr(P)));
  98. end;
  99. begin
  100. inherited Init;
  101. ShortCut:=NewStr(AShortCut);
  102. SetText(AText);
  103. end;
  104. function TCodeTemplate.GetShortCut: string;
  105. begin
  106. GetShortCut:=GetStr(ShortCut);
  107. end;
  108. procedure TCodeTemplate.GetText(AList: PUnsortedStringCollection);
  109. procedure CopyIt(P: PString); {$ifndef FPC}far;{$endif}
  110. begin
  111. AList^.Insert(NewStr(GetStr(P)));
  112. end;
  113. begin
  114. if Assigned(AList) and Assigned(Text) then
  115. Text^.ForEach(@CopyIt);
  116. end;
  117. procedure TCodeTemplate.SetShortCut(const AShortCut: string);
  118. begin
  119. if Assigned(ShortCut) then DisposeStr(ShortCut);
  120. ShortCut:=NewStr(AShortCut);
  121. end;
  122. procedure TCodeTemplate.SetText(AList: PUnsortedStringCollection);
  123. begin
  124. if Assigned(Text) then Dispose(Text, Done);
  125. New(Text, CreateFrom(AList));
  126. end;
  127. procedure TCodeTemplate.GetParams(var AShortCut: string; Lines: PUnsortedStringCollection);
  128. begin
  129. AShortCut:=GetShortCut;
  130. GetText(Lines);
  131. end;
  132. procedure TCodeTemplate.SetParams(const AShortCut: string; Lines: PUnsortedStringCollection);
  133. begin
  134. SetShortCut(AShortCut);
  135. SetText(Lines);
  136. end;
  137. constructor TCodeTemplate.Load(var S: TStream);
  138. begin
  139. ShortCut:=S.ReadStr;
  140. New(Text, Load(S));
  141. end;
  142. procedure TCodeTemplate.Store(var S: TStream);
  143. begin
  144. S.WriteStr(ShortCut);
  145. Text^.Store(S);
  146. end;
  147. destructor TCodeTemplate.Done;
  148. begin
  149. if Assigned(ShortCut) then DisposeStr(ShortCut); ShortCut:=nil;
  150. if Assigned(Text) then Dispose(Text, Done); Text:=nil;
  151. inherited Done;
  152. end;
  153. function TCodeTemplateCollection.Compare(Key1, Key2: Pointer): sw_Integer;
  154. var K1: PCodeTemplate absolute Key1;
  155. K2: PCodeTemplate absolute Key2;
  156. R: Sw_integer;
  157. S1,S2: string;
  158. begin
  159. S1:=UpCaseStr(K1^.GetShortCut);
  160. S2:=UpCaseStr(K2^.GetShortCut);
  161. if S1<S2 then R:=-1 else
  162. if S1>S2 then R:=1 else
  163. R:=0;
  164. Compare:=R;
  165. end;
  166. function TCodeTemplateCollection.SearchByShortCut(const ShortCut: string): PCodeTemplate;
  167. var T: TCodeTemplate;
  168. Index: sw_integer;
  169. P: PCodeTemplate;
  170. begin
  171. T.Init(ShortCut,nil);
  172. if Search(@T,Index)=false then P:=nil else
  173. P:=At(Index);
  174. T.Done;
  175. SearchByShortCut:=P;
  176. end;
  177. function TCodeTemplateCollection.LookUp(const S: string; AcceptMulti: boolean; var Idx: sw_integer): string;
  178. var OLI,ORI,Left,Right,Mid: sw_integer;
  179. MidP: PCodeTemplate;
  180. MidS: string;
  181. FoundS: string;
  182. UpS : string;
  183. begin
  184. Idx:=-1; FoundS:='';
  185. Left:=0; Right:=Count-1;
  186. UpS:=UpCaseStr(S);
  187. while Left<=Right do
  188. begin
  189. OLI:=Left; ORI:=Right;
  190. Mid:=Left+(Right-Left) div 2;
  191. MidP:=At(Mid);
  192. MidS:=UpCaseStr(MidP^.GetShortCut);
  193. if copy(MidS,1,length(UpS))=UpS then
  194. begin
  195. if (Idx<>-1) and (Idx<>Mid) and not AcceptMulti then
  196. begin
  197. { several solutions possible, return nothing }
  198. Idx:=-1;
  199. FoundS:='';
  200. break;
  201. end
  202. else if Idx=-1 then
  203. begin
  204. Idx:=Mid;
  205. FoundS:=MidP^.GetShortCut;
  206. end;
  207. end;
  208. if UpS<MidS then
  209. Right:=Mid
  210. else
  211. Left:=Mid;
  212. if (OLI=Left) and (ORI=Right) then
  213. begin
  214. if (Left<Right) then
  215. Left:=Right
  216. else
  217. Break;
  218. end;
  219. end;
  220. { check if next also fits...
  221. return '' in that case }
  222. if (Idx<>-1) and (Idx<Count-1) and not AcceptMulti then
  223. begin
  224. MidP:=At(Idx+1);
  225. MidS:=UpCaseStr(MidP^.GetShortCut);
  226. if copy(MidS,1,length(UpS))=UpS then
  227. begin
  228. Idx:=-1;
  229. FoundS:='';
  230. end;
  231. end;
  232. LookUp:=FoundS;
  233. end;
  234. function FPTranslateCodeTemplate(var Shortcut: string; ALines: PUnsortedStringCollection): boolean;
  235. var OK: boolean;
  236. P: PCodeTemplate;
  237. CompleteName: String;
  238. Idx : sw_integer;
  239. begin
  240. OK:=Assigned(CodeTemplates);
  241. if OK then
  242. begin
  243. P:=CodeTemplates^.SearchByShortCut(ShortCut);
  244. if not assigned(P) then
  245. begin
  246. CompleteName:=CodeTemplates^.Lookup(ShortCut,false,Idx);
  247. if Idx<>-1 then
  248. begin
  249. P:=CodeTemplates^.At(Idx);
  250. ShortCut:=CompleteName;
  251. end;
  252. end;
  253. OK:=Assigned(P);
  254. if OK then
  255. P^.GetText(ALines);
  256. end;
  257. FPTranslateCodeTemplate:=OK;
  258. end;
  259. procedure InitCodeTemplates;
  260. begin
  261. if Assigned(CodeTemplates) then Exit;
  262. New(CodeTemplates, Init(10,10));
  263. end;
  264. function LoadCodeTemplates(var S: TStream): boolean;
  265. var C: PCodeTemplateCollection;
  266. OK: boolean;
  267. begin
  268. New(C, Load(S));
  269. OK:=Assigned(C) and (S.Status=stOk);
  270. if OK then
  271. begin
  272. if Assigned(CodeTemplates) then Dispose(CodeTemplates, Done);
  273. CodeTemplates:=C;
  274. end
  275. else
  276. if Assigned(C) then
  277. Dispose(C, Done);
  278. LoadCodeTemplates:=OK;
  279. end;
  280. function StoreCodeTemplates(var S: TStream): boolean;
  281. var OK: boolean;
  282. begin
  283. OK:=Assigned(CodeTemplates);
  284. if OK then
  285. begin
  286. CodeTemplates^.Store(S);
  287. OK:=OK and (S.Status=stOK);
  288. end;
  289. StoreCodeTemplates:=OK;
  290. end;
  291. procedure DoneCodeTemplates;
  292. begin
  293. if Assigned(CodeTemplates) then Dispose(CodeTemplates, Done);
  294. CodeTemplates:=nil;
  295. end;
  296. function TCodeTemplateListBox.GetText(Item,MaxLen: Sw_Integer): String;
  297. var P: PCodeTemplate;
  298. begin
  299. P:=List^.At(Item);
  300. GetText:=P^.GetShortCut;
  301. end;
  302. constructor TCodeTemplateDialog.Init(const ATitle: string; ATemplate: PCodeTemplate);
  303. var R,R2,R3: TRect;
  304. begin
  305. R.Assign(0,0,52,15);
  306. inherited Init(R,ATitle);
  307. Template:=ATemplate;
  308. GetExtent(R); R.Grow(-3,-2); R3.Copy(R);
  309. Inc(R.A.Y); R.B.Y:=R.A.Y+1; R.B.X:=R.A.X+46;
  310. New(ShortCutIL, Init(R, 128)); Insert(ShortcutIL);
  311. ShortCutIL^.SetValidator(New(PFilterValidator,Init(NumberChars+AlphaChars)));
  312. R2.Copy(R); R2.Move(-1,-1);
  313. Insert(New(PLabel, Init(R2, label_codetemplate_shortcut, ShortcutIL)));
  314. R.Move(0,3); R.B.Y:=R.A.Y+8;
  315. New(CodeMemo, Init(R, nil,nil,nil{,4096 does not compile !! }));
  316. Insert(CodeMemo);
  317. R2.Copy(R); R2.Move(-1,-1); R2.B.Y:=R2.A.Y+1;
  318. Insert(New(PLabel, Init(R2, label_codetemplate_content, CodeMemo)));
  319. InsertButtons(@Self);
  320. ShortcutIL^.Select;
  321. end;
  322. function TCodeTemplateDialog.Execute: Word;
  323. var R: word;
  324. S: string;
  325. L: PUnsortedStringCollection;
  326. begin
  327. New(L, Init(10,10));
  328. S:=Template^.GetShortCut;
  329. Template^.GetText(L);
  330. ShortcutIL^.SetData(S);
  331. CodeMemo^.SetContent(L);
  332. R:=inherited Execute;
  333. if R=cmOK then
  334. begin
  335. L^.FreeAll;
  336. ShortcutIL^.GetData(S);
  337. CodeMemo^.GetContent(L);
  338. Template^.SetShortcut(S);
  339. Template^.SetText(L);
  340. end;
  341. Execute:=R;
  342. end;
  343. constructor TCodeTemplatesDialog.Init(ASelMode: boolean;const AShortCut : string);
  344. function B2I(B: boolean; I1,I2: longint): longint;
  345. begin
  346. if B then B2I:=I1 else B2I:=I2;
  347. end;
  348. var R,R2,R3: TRect;
  349. SB: PScrollBar;
  350. begin
  351. R.Assign(0,0,46,20);
  352. inherited Init(R,'Code Templates');
  353. HelpCtx:=hcCodeTemplateOptions;
  354. SelMode:=ASelMode;
  355. GetExtent(R); R.Grow(-3,-2); Inc(R.A.Y); R.B.Y:=R.A.Y+10;
  356. R3.Copy(R); Dec(R.B.X,12);
  357. R2.Copy(R); R2.Move(1,0); R2.A.X:=R2.B.X-1;
  358. New(SB, Init(R2)); Insert(SB);
  359. New(CodeTemplatesLB, Init(R,1,SB));
  360. Insert(CodeTemplatesLB);
  361. if AShortCut<>'' then
  362. begin
  363. If assigned(CodeTemplates) then
  364. CodeTemplates^.Lookup(AShortCut,true,StartIdx)
  365. else
  366. StartIdx:=-1;
  367. end
  368. else
  369. StartIdx:=-1;
  370. R2.Copy(R); R2.Move(0,-1); R2.B.Y:=R2.A.Y+1; Dec(R2.A.X);
  371. Insert(New(PLabel, Init(R2, label_codetemplate_templates, CodeTemplatesLB)));
  372. GetExtent(R); R.Grow(-2,-2); Inc(R.A.Y,12);
  373. R2.Copy(R); R2.Move(1,0); R2.A.X:=R2.B.X-1;
  374. New(SB, Init(R2)); Insert(SB);
  375. New(TemplateViewer, Init(R,nil,SB,nil{,4096 does not compile }));
  376. with TemplateViewer^ do
  377. begin
  378. ReadOnly:=true;
  379. AlwaysShowScrollBars:=true;
  380. end;
  381. Insert(TemplateViewer);
  382. R.Copy(R3); R.A.X:=R.B.X-10; R.B.Y:=R.A.Y+2;
  383. Insert(New(PButton, Init(R, button_OK, cmOK, B2I(SelMode,bfDefault,bfNormal))));
  384. R.Move(0,2);
  385. Insert(New(PButton, Init(R, button_Edit, cmEditItem, B2I(SelMode,bfNormal,bfDefault) )));
  386. R.Move(0,2);
  387. Insert(New(PButton, Init(R, button_New, cmAddItem, bfNormal)));
  388. R.Move(0,2);
  389. Insert(New(PButton, Init(R, button_Delete, cmDeleteItem, bfNormal)));
  390. R.Move(0,2);
  391. Insert(New(PButton, Init(R, button_Cancel, cmCancel, bfNormal)));
  392. SelectNext(false);
  393. end;
  394. procedure TCodeTemplatesDialog.Update;
  395. var C: PUnsortedStringCollection;
  396. begin
  397. if CodeTemplatesLB^.Range=0 then C:=nil else
  398. C:=PCodeTemplate(CodeTemplatesLB^.GetFocusedItem)^.Text;
  399. TemplateViewer^.SetContent(C);
  400. ReDraw;
  401. end;
  402. function TCodeTemplatesDialog.GetSelectedShortCut: string;
  403. var S: string;
  404. begin
  405. if CodeTemplatesLB^.Range=0 then S:='' else
  406. S:=GetStr(PCodeTemplate(CodeTemplatesLB^.GetFocusedItem)^.ShortCut);
  407. GetSelectedShortCut:=S;
  408. end;
  409. procedure TCodeTemplatesDialog.HandleEvent(var Event: TEvent);
  410. var DontClear: boolean;
  411. begin
  412. case Event.What of
  413. evKeyDown :
  414. begin
  415. DontClear:=false;
  416. case Event.KeyCode of
  417. kbIns :
  418. Message(@Self,evCommand,cmAddItem,nil);
  419. kbDel :
  420. Message(@Self,evCommand,cmDeleteItem,nil);
  421. else DontClear:=true;
  422. end;
  423. if DontClear=false then ClearEvent(Event);
  424. end;
  425. evBroadcast :
  426. case Event.Command of
  427. cmListItemSelected :
  428. if Event.InfoPtr=pointer(CodeTemplatesLB) then
  429. Message(@Self,evCommand,cmEditItem,nil);
  430. cmListFocusChanged :
  431. if Event.InfoPtr=pointer(CodeTemplatesLB) then
  432. Message(@Self,evBroadcast,cmUpdate,nil);
  433. cmUpdate :
  434. Update;
  435. end;
  436. evCommand :
  437. begin
  438. DontClear:=false;
  439. case Event.Command of
  440. cmAddItem : Add;
  441. cmDeleteItem : Delete;
  442. cmEditItem : Edit;
  443. else DontClear:=true;
  444. end;
  445. if DontClear=false then ClearEvent(Event);
  446. end;
  447. end;
  448. inherited HandleEvent(Event);
  449. end;
  450. function TCodeTemplatesDialog.Execute: Word;
  451. var R: word;
  452. P: PCodeTemplate;
  453. C: PCodeTemplateCollection;
  454. L: PUnsortedStringCollection;
  455. I: integer;
  456. begin
  457. New(C, Init(10,20));
  458. if Assigned(CodeTemplates) then
  459. for I:=0 to CodeTemplates^.Count-1 do
  460. begin
  461. P:=CodeTemplates^.At(I);
  462. New(L, Init(10,50));
  463. P^.GetText(L);
  464. C^.Insert(New(PCodeTemplate, Init(P^.GetShortCut,L)));
  465. Dispose(L, Done);
  466. end;
  467. CodeTemplatesLB^.NewList(C);
  468. if StartIdx<>-1 then
  469. CodeTemplatesLB^.SetFocusedItem(CodeTemplates^.At(StartIdx));
  470. Update;
  471. R:=inherited Execute;
  472. if R=cmOK then
  473. begin
  474. if Assigned(CodeTemplates) then Dispose(CodeTemplates, Done);
  475. CodeTemplates:=C;
  476. end
  477. else
  478. Dispose(C, Done);
  479. Execute:=R;
  480. end;
  481. procedure TCodeTemplatesDialog.Add;
  482. var P,P2: PCodeTemplate;
  483. IC: boolean;
  484. S: string;
  485. L: PUnsortedStringCollection;
  486. Cmd: word;
  487. CanExit: boolean;
  488. begin
  489. New(L, Init(10,10));
  490. IC:=CodeTemplatesLB^.Range=0;
  491. if IC=false then
  492. begin
  493. P:=CodeTemplatesLB^.List^.At(CodeTemplatesLB^.Focused);
  494. P^.GetParams(S,L);
  495. end
  496. else
  497. begin
  498. S:='';
  499. end;
  500. New(P, Init(S,L));
  501. repeat
  502. Cmd:=Application^.ExecuteDialog(New(PCodeTemplateDialog, Init(dialog_newtemplate,P)), nil);
  503. CanExit:=(Cmd<>cmOK);
  504. if CanExit=false then
  505. begin
  506. P2:=PCodeTemplateCollection(CodeTemplatesLB^.List)^.SearchByShortCut(P^.GetShortCut);
  507. CanExit:=(Assigned(P2)=false);
  508. if CanExit=false then
  509. begin
  510. ClearFormatParams; AddFormatParamStr(P^.GetShortCut);
  511. ErrorBox(msg_codetemplate_alreadyinlist,@FormatParams);
  512. end;
  513. end;
  514. until CanExit;
  515. if Cmd=cmOK then
  516. begin
  517. CodeTemplatesLB^.List^.Insert(P);
  518. CodeTemplatesLB^.SetRange(CodeTemplatesLB^.List^.Count);
  519. CodeTemplatesLB^.SetFocusedItem(P);
  520. Update;
  521. end
  522. else
  523. Dispose(P, Done);
  524. Dispose(L, Done);
  525. end;
  526. procedure TCodeTemplatesDialog.Edit;
  527. var P,O,P2: PCodeTemplate;
  528. I: sw_integer;
  529. S: string;
  530. L: PUnsortedStringCollection;
  531. Cmd: word;
  532. CanExit: boolean;
  533. begin
  534. if CodeTemplatesLB^.Range=0 then Exit;
  535. New(L, Init(10,10));
  536. I:=CodeTemplatesLB^.Focused;
  537. O:=CodeTemplatesLB^.List^.At(I);
  538. O^.GetParams(S,L);
  539. P:=New(PCodeTemplate, Init(S, L));
  540. repeat
  541. Cmd:=Application^.ExecuteDialog(New(PCodeTemplateDialog, Init(dialog_modifytemplate,P)), nil);
  542. CanExit:=(Cmd<>cmOK);
  543. if CanExit=false then
  544. begin
  545. P2:=PCodeTemplateCollection(CodeTemplatesLB^.List)^.SearchByShortCut(P^.GetShortCut);
  546. CanExit:=(Assigned(P2)=false) or (CodeTemplatesLB^.List^.IndexOf(P2)=I);
  547. if CanExit=false then
  548. begin
  549. ClearFormatParams; AddFormatParamStr(P^.GetShortCut);
  550. ErrorBox(msg_codetemplate_alreadyinlist,@FormatParams);
  551. end;
  552. end;
  553. until CanExit;
  554. if Cmd=cmOK then
  555. begin
  556. with CodeTemplatesLB^ do
  557. begin
  558. List^.AtFree(I); O:=nil;
  559. List^.Insert(P);
  560. SetFocusedItem(P);
  561. end;
  562. Update;
  563. end;
  564. Dispose(L, Done);
  565. end;
  566. procedure TCodeTemplatesDialog.Delete;
  567. begin
  568. if CodeTemplatesLB^.Range=0 then Exit;
  569. CodeTemplatesLB^.List^.AtFree(CodeTemplatesLB^.Focused);
  570. CodeTemplatesLB^.SetRange(CodeTemplatesLB^.List^.Count);
  571. Update;
  572. end;
  573. procedure RegisterCodeTemplates;
  574. begin
  575. {$ifndef NOOBJREG}
  576. RegisterType(RCodeTemplate);
  577. RegisterType(RCodeTemplateCollection);
  578. {$endif}
  579. end;
  580. END.