fpcodtmp.pas 17 KB

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