2
0

fpcodtmp.pas 17 KB

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