fpcodcmp.pas 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649
  1. {
  2. $Id$
  3. This file is part of the Free Pascal Integrated Development Environment
  4. Copyright (c) 1998 by Berczi Gabor
  5. Code Complete 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 FPCodCmp; { CodeComplete }
  13. interface
  14. uses Objects,Drivers,Dialogs,
  15. WUtils,WViews;
  16. type
  17. PCodeCompleteWordList = ^TCodeCompleteWordList;
  18. TCodeCompleteWordList = object(TTextCollection)
  19. end;
  20. PCodeCompleteDialog = ^TCodeCompleteDialog;
  21. TCodeCompleteDialog = object(TCenterDialog)
  22. constructor Init;
  23. function Execute: Word; virtual;
  24. procedure HandleEvent(var Event: TEvent); virtual;
  25. private
  26. CodeCompleteLB : PAdvancedListBox;
  27. RB : PRadioButtons;
  28. CB : PCheckBoxes;
  29. MinInputL,InputL : PInputLine;
  30. procedure Add;
  31. procedure Edit;
  32. procedure Delete;
  33. end;
  34. function FPCompleteCodeWord(const WordS: string; var Text: string): boolean;
  35. procedure InitCodeComplete;
  36. function LoadCodeComplete(var S: TStream): boolean;
  37. procedure AddStandardUnitsToCodeComplete;
  38. procedure AddAvailableUnitsToCodeComplete(OnlyStandard : boolean);
  39. function StoreCodeComplete(var S: TStream): boolean;
  40. procedure DoneCodeComplete;
  41. const CodeCompleteWords : PCodeCompleteWordList = nil;
  42. type
  43. TCodeCompleteCase = (ccc_unchanged, ccc_lower, ccc_upper, ccc_mixed);
  44. const
  45. CodeCompleteCase : TCodeCompleteCase = ccc_unchanged;
  46. UnitsCodeCompleteWords : PCodeCompleteWordList = nil;
  47. procedure RegisterCodeComplete;
  48. implementation
  49. uses App,Views,MsgBox,Validate,
  50. {$ifdef FVISION}
  51. FVConsts,
  52. {$else}
  53. Commands,
  54. {$endif}
  55. systems, BrowCol,
  56. WEditor, FPSwitch,
  57. FPCompil, FPVars, FPSymbol,
  58. FPConst,FPString,FPViews;
  59. {$ifndef NOOBJREG}
  60. const
  61. RCodeCompleteWordList: TStreamRec = (
  62. ObjType: 14401;
  63. VmtLink: Ofs(TypeOf(TCodeCompleteWordList)^);
  64. Load: @TCodeCompleteWordList.Load;
  65. Store: @TCodeCompleteWordList.Store
  66. );
  67. {$endif}
  68. function FPCompleteCodeWord(const WordS: string; var Text: string): boolean;
  69. var OK: boolean;
  70. CIndex, Index, i : sw_integer;
  71. St, UpWordS : string;
  72. begin
  73. if ShowOnlyUnique then
  74. UpWordS:=UpCaseStr(WordS);
  75. OK:=Assigned(CodeCompleteWords);
  76. if OK then
  77. begin
  78. Text:=CodeCompleteWords^.Lookup(WordS,CIndex);
  79. OK:=(CIndex<>-1) and (length(Text)<>length(WordS));
  80. if OK and ShowOnlyUnique and (CIndex<CodeCompleteWords^.Count-1) then
  81. begin
  82. St:=PString(CodeCompleteWords^.At(CIndex+1))^;
  83. if (UpCaseStr(Copy(St,1,length(WordS)))=UpWordS) then
  84. begin
  85. {if UpCase(st[Length(UpWordS)+1])<>Upcase(Text[Length(UpWordS)+1]) then}
  86. begin
  87. Text:='';
  88. FPCompleteCodeWord:=false;
  89. exit;
  90. (* end
  91. else
  92. { only give the common part }
  93. begin
  94. i:=Length(UpWordS)+1;
  95. while (i<=length(st)) and (i<=length(text)) and (UpCase(st[i])=Upcase(Text[i])) do
  96. inc(i);
  97. SetLength(Text,i-1); *)
  98. end;
  99. end;
  100. end;
  101. end;
  102. if (ShowOnlyUnique or not OK) and Assigned(UnitsCodeCompleteWords) then
  103. begin
  104. Text:=UnitsCodeCompleteWords^.Lookup(WordS,Index);
  105. OK:=(Index<>-1) and (length(Text)<>length(WordS));
  106. if ShowOnlyUnique and (Index<UnitsCodeCompleteWords^.Count-1) then
  107. begin
  108. St:=PString(UnitsCodeCompleteWords^.At(Index+1))^;
  109. if UpCaseStr(Copy(St,1,length(WordS)))=UpWordS then
  110. begin
  111. {if UpCase(st[Length(UpWordS)+1])<>Upcase(Text[Length(UpWordS)+1]) then}
  112. begin
  113. Text:='';
  114. FPCompleteCodeWord:=false;
  115. exit;
  116. (* end
  117. else
  118. { only give the common part }
  119. begin
  120. i:=Length(UpWordS)+1;
  121. while (i<=length(st)) and (i<=length(text)) and (UpCase(st[i])=Upcase(Text[i])) do
  122. inc(i);
  123. SetLength(Text,i-1); *)
  124. end;
  125. end;
  126. end;
  127. end;
  128. if ShowOnlyUnique and (Index<>-1) and (CIndex<>-1) then
  129. begin
  130. St:=PString(CodeCompleteWords^.At(CIndex+1))^;
  131. {if UpCase(st[Length(UpWordS)+1])<>Upcase(Text[Length(UpWordS)+1]) then}
  132. begin
  133. Text:='';
  134. FPCompleteCodeWord:=false;
  135. exit;
  136. (* end
  137. else
  138. { only give the common part }
  139. begin
  140. i:=Length(UpWordS)+1;
  141. while (i<=length(st)) and (i<=length(text)) and (UpCase(st[i])=Upcase(Text[i])) do
  142. inc(i);
  143. SetLength(Text,i-1); *)
  144. end;
  145. end;
  146. if OK=false then Text:=''
  147. else case CodeCompleteCase of
  148. ccc_upper : Text:=UpcaseStr(Text);
  149. ccc_lower : Text:=LowcaseStr(Text);
  150. ccc_mixed : Text:=UpCase(Text[1])+LowCaseStr(Copy(Text,2,High(Text)));
  151. end;
  152. FPCompleteCodeWord:=OK;
  153. end;
  154. procedure InitCodeComplete;
  155. var I:integer;
  156. S: string;
  157. begin
  158. if Assigned(CodeCompleteWords) then
  159. Dispose(CodeCompleteWords, Done);
  160. New(CodeCompleteWords, Init(10,10));
  161. for I:=0 to GetReservedWordCount-1 do
  162. begin
  163. S:=LowCaseStr(GetReservedWord(I));
  164. if length(S)>=CodeCompleteMinLen then
  165. CodeCompleteWords^.Insert(NewStr(S));
  166. end;
  167. {
  168. there should be also a user front-end for customizing CodeComplete !
  169. any volunteers to implement? ;) - Gabor
  170. }
  171. end;
  172. procedure AddAvailableUnitsToCodeComplete(OnlyStandard : boolean);
  173. var
  174. I : sw_integer;
  175. Overflow: boolean;
  176. Level : longint;
  177. UpStandardUnits : string;
  178. procedure InsertInS(P: PSymbol); {$ifndef FPC}far;{$endif}
  179. procedure InsertItemsInS(P: PSymbolCollection);
  180. var I: Sw_integer;
  181. begin
  182. for I:=0 to P^.Count-1 do
  183. InsertInS(P^.At(I));
  184. end;
  185. Var
  186. st : string;
  187. begin
  188. Inc(level);
  189. if UnitsCodeCompleteWords^.Count=MaxCollectionSize then
  190. begin Overflow:=true; Exit; end;
  191. st:=P^.GetName;
  192. if Length(st)>=CodeCompleteMinLen then
  193. if not ((level=1) and OnlyStandard and (st=UpCaseStr(CodeCompleteUnitName))) then
  194. UnitsCodeCompleteWords^.Insert(NewStr(Lowcasestr(st)));
  195. { this is wrong because it inserted args or locals of proc
  196. in the globals list !! PM}
  197. if (P^.Items<>nil) and (level=1) and
  198. ((not OnlyStandard or (Pos(P^.GetName+',',UpStandardUnits)>0) or
  199. { don't exclude system unit ... }
  200. (Pos('SYS',P^.GetName)>0))) then
  201. InsertItemsInS(P^.Items);
  202. Dec(level);
  203. end;
  204. begin
  205. if OnlyStandard then
  206. UpStandardunits:=UpCaseStr(StandardUnits)+',';
  207. if IsSymbolInfoAvailable then
  208. begin
  209. if Assigned(UnitsCodeCompleteWords) then
  210. begin
  211. Dispose(UnitsCodeCompleteWords,done);
  212. UnitsCodeCompleteWords:=nil;
  213. end;
  214. New(UnitsCodeCompleteWords, Init(10,10));
  215. level:=0;
  216. Overflow:=false;
  217. BrowCol.Modules^.ForEach(@InsertInS);
  218. { if Overflow then
  219. WarningBox(msg_toomanysymbolscantdisplayall,nil); }
  220. end;
  221. end;
  222. procedure AddStandardUnitsToCodeComplete;
  223. var
  224. HiddenSource : PSourceWindow;
  225. R : TRect;
  226. StoreBrowserSwitchesConfig : string;
  227. begin
  228. Desktop^.GetExtent(R);
  229. New(HiddenSource,init(R,'*'));
  230. HiddenSource^.NoNameCount:=0;
  231. HiddenSource^.UpdateTitle;
  232. HiddenSource^.Hide;
  233. CompilingHiddenFile:=HiddenSource;
  234. { compile a dummy file to get symbol info }
  235. with HiddenSource^.Editor^ do
  236. begin
  237. FileName:=CodeCompleteUnitName+'.pp';
  238. Addline('unit '+CodeCompleteUnitName+';');
  239. Addline('interface');
  240. if StandardUnits<>'' then
  241. begin
  242. AddLine('uses');
  243. Addline(StandardUnits);
  244. Addline(' ;');
  245. end;
  246. Addline('implementation');
  247. Addline('end.');
  248. SetModified(true);
  249. // SaveFile;
  250. end;
  251. StoreBrowserSwitchesConfig:=BrowserSwitches^.GetCurrSelParam;
  252. BrowserSwitches^.ReadItemsCfg('+');
  253. DoCompile(cCompile);
  254. BrowserSwitches^.SetCurrSelParam(StoreBrowserSwitchesConfig);
  255. AddAvailableUnitsToCodeComplete(true);
  256. { Now add the interface declarations to the Code Complete list }
  257. CompilingHiddenFile:=nil;
  258. Dispose(HiddenSource,Done);
  259. end;
  260. function LoadCodeComplete(var S: TStream): boolean;
  261. var C: PCodeCompleteWordList;
  262. OK: boolean;
  263. NewCodeCompleteMinLen : byte;
  264. NewUseStandardUnitsInCodeComplete,
  265. NewUseAllUnitsInCodeComplete,
  266. NewShowOnlyUnique : boolean;
  267. NewCodeCompleteCase : TCodeCompleteCase;
  268. StPtr : PString;
  269. begin
  270. New(C, Load(S));
  271. OK:=Assigned(C) and (S.Status=stOk);
  272. if OK then
  273. begin
  274. if Assigned(CodeCompleteWords) then Dispose(CodeCompleteWords, Done);
  275. CodeCompleteWords:=C;
  276. S.Read(NewCodeCompleteCase,Sizeof(TCodeCompleteCase));
  277. OK:=(S.Status=stOk);
  278. if OK then
  279. CodeCompleteCase:=NewCodeCompleteCase;
  280. { Old version of Code complete, also OK PM }
  281. if not OK or (S.getPos=S.getSize) then
  282. begin
  283. LoadCodeComplete:=OK;
  284. exit;
  285. end;
  286. if S.Status=stOK then
  287. S.Read(NewUseStandardUnitsInCodeComplete,Sizeof(UseStandardUnitsInCodeComplete));
  288. if S.Status=stOK then
  289. UseStandardUnitsInCodeComplete:=NewUseStandardUnitsInCodeComplete;
  290. if S.Status=stOK then
  291. S.Read(NewUseAllUnitsInCodeComplete,Sizeof(UseAllUnitsInCodeComplete));
  292. if S.Status=stOK then
  293. UseAllUnitsInCodeComplete:=NewUseAllUnitsInCodeComplete;
  294. if S.Status=stOK then
  295. S.Read(NewShowOnlyUnique,Sizeof(ShowOnlyUnique));
  296. if S.Status=stOK then
  297. ShowOnlyUnique:=NewShowOnlyUnique;
  298. if S.Status=stOK then
  299. S.Read(NewCodeCompleteMinLen,Sizeof(CodeCompleteMinLen));
  300. if S.Status=stOK then
  301. CodeCompleteMinLen:=NewCodeCompleteMinLen;
  302. if S.Status=stOK then
  303. StPtr:=S.ReadStr
  304. else
  305. StPtr:=nil;
  306. if (S.Status=stOK) then
  307. StandardUnits:=GetStr(StPtr);
  308. if assigned(StPtr) then
  309. FreeMem(StPtr,Length(StandardUnits)+1);
  310. OK:=S.Status=stOK;
  311. end
  312. else
  313. if Assigned(C) then
  314. Dispose(C, Done);
  315. LoadCodeComplete:=OK;
  316. end;
  317. function StoreCodeComplete(var S: TStream): boolean;
  318. var OK: boolean;
  319. begin
  320. OK:=Assigned(CodeCompleteWords);
  321. if OK then
  322. begin
  323. CodeCompleteWords^.Store(S);
  324. S.Write(CodeCompleteCase,Sizeof(TCodeCompleteCase));
  325. { New fields added }
  326. S.Write(UseStandardUnitsInCodeComplete,Sizeof(UseStandardUnitsInCodeComplete));
  327. S.Write(UseAllUnitsInCodeComplete,Sizeof(UseAllUnitsInCodeComplete));
  328. S.Write(ShowOnlyUnique,Sizeof(ShowOnlyUnique));
  329. S.Write(CodeCompleteMinLen,Sizeof(CodeCompleteMinLen));
  330. S.WriteStr(@StandardUnits);
  331. OK:=OK and (S.Status=stOK);
  332. end;
  333. StoreCodeComplete:=OK;
  334. end;
  335. procedure DoneCodeComplete;
  336. begin
  337. if Assigned(CodeCompleteWords) then
  338. begin
  339. Dispose(CodeCompleteWords, Done);
  340. CodeCompleteWords:=nil;
  341. end;
  342. if Assigned(UnitsCodeCompleteWords) then
  343. begin
  344. Dispose(UnitsCodeCompleteWords,done);
  345. UnitsCodeCompleteWords:=nil;
  346. end;
  347. end;
  348. constructor TCodeCompleteDialog.Init;
  349. var R,R2,R3: TRect;
  350. Items: PSItem;
  351. SB: PScrollBar;
  352. begin
  353. R.Assign(0,0,50,22);
  354. inherited Init(R,dialog_codecomplete);
  355. HelpCtx:=hcCodeCompleteOptions;
  356. { name list dialog }
  357. GetExtent(R); R.Grow(-3,-2); Inc(R.A.Y); R3.Copy(R); Dec(R.B.X,12);
  358. Dec(R.B.Y,7);
  359. R2.Copy(R); R2.Move(1,0); R2.A.X:=R2.B.X-1;
  360. New(SB, Init(R2)); Insert(SB);
  361. New(CodeCompleteLB, Init(R,1,SB));
  362. Insert(CodeCompleteLB);
  363. R2.Copy(R); R2.Move(0,-1); R2.B.Y:=R2.A.Y+1; Dec(R2.A.X);
  364. Insert(New(PLabel, Init(R2, label_codecomplete_keywords, CodeCompleteLB)));
  365. { Case choice }
  366. R.Copy(R3); Dec(R.B.Y,2); R.A.Y:=R.B.Y-4; Inc(R.A.X); R.B.X:=R.A.X+15;
  367. Items:=NewSItem('Unc~h~anged',
  368. NewSItem('~L~ower',
  369. NewSItem('~U~pper',
  370. NewSItem('~M~ixed',nil))));
  371. RB:=New(PRadioButtons,Init(R,Items));
  372. RB^.SetData(ord(CodeCompleteCase));
  373. R2.Copy(R); R2.Move(0,-1); R2.B.Y:=R2.A.Y+1; Dec(R2.A.X);
  374. Insert(New(PLabel, Init(R2, 'Case handling', RB)));
  375. Insert(RB);
  376. { Mininum length inputline }
  377. R.Copy(R3); R.A.Y:=R.B.Y-7;R.B.Y:=R.A.Y+1; Dec(R.B.X); R.A.X:=R.B.X -5;
  378. New(MinInputL, Init(R,5));
  379. MinInputL^.SetValidator(New(PRangeValidator, Init(1,255)));
  380. Insert(MinInputL);
  381. R2.Copy(R); R2.A.X:=20;Dec(R2.B.X,5);
  382. Insert(New(PLabel, Init(R2, 'Min. length', MinInputL)));
  383. { Standard/all units booleans }
  384. Items:=nil;
  385. Items:=NewSItem('Add standard units', Items);
  386. Items:=NewSItem('Add all units', Items);
  387. Items:=NewSItem('Show only unique', Items);
  388. R.Copy(R3); R.A.Y:=R.B.Y-5;R.B.Y:=R.A.Y+3; Inc(R.A.X,18); Dec(R.B.X);
  389. New(CB, Init(R, Items));
  390. Insert(CB);
  391. R2.Copy(R); R2.Move(0,-1); R2.B.Y:=R2.A.Y+1; Dec(R2.A.X);
  392. Insert(New(PLabel, Init(R2, 'Unit handling', CB)));
  393. R2.Copy(R); R2.Move(0,-1); R2.B.Y:=R2.A.Y+1;
  394. If ShowOnlyUnique then
  395. CB^.Press(0);
  396. If UseAllUnitsInCodeComplete then
  397. CB^.Press(1);
  398. If UseStandardUnitsInCodeComplete then
  399. CB^.Press(2);
  400. { Standard unit name boolean }
  401. R.Copy(R3); R.A.Y:=R.B.Y-1; Inc(R.A.X); Dec(R.B.X);
  402. New(InputL,Init(R,255));
  403. Insert(InputL);
  404. InputL^.SetValidator(New(PFilterValidator,Init(NumberChars+AlphaChars+[','])));
  405. R2.Copy(R); R2.Move(0,-1); R2.B.Y:=R2.A.Y+1; Dec(R2.A.X);R2.B.X:=R2.A.X+25;
  406. Insert(New(PLabel, Init(R2, '~S~tandard unit list', InputL)));
  407. R.Copy(R3); R.A.X:=R.B.X-10; R.B.Y:=R.A.Y+2;
  408. Insert(New(PButton, Init(R, button_OK, cmOK, bfNormal)));
  409. R.Move(0,2);
  410. Insert(New(PButton, Init(R, button_Edit, cmEditItem, bfDefault)));
  411. R.Move(0,2);
  412. Insert(New(PButton, Init(R, button_New, cmAddItem, bfNormal)));
  413. R.Move(0,2);
  414. Insert(New(PButton, Init(R, button_Delete, cmDeleteItem, bfNormal)));
  415. R.Move(0,2);
  416. Insert(New(PButton, Init(R, button_Cancel, cmCancel, bfNormal)));
  417. SelectNext(false);
  418. end;
  419. procedure TCodeCompleteDialog.HandleEvent(var Event: TEvent);
  420. var DontClear: boolean;
  421. begin
  422. case Event.What of
  423. evKeyDown :
  424. begin
  425. DontClear:=false;
  426. case Event.KeyCode of
  427. kbIns :
  428. Message(@Self,evCommand,cmAddItem,nil);
  429. kbDel :
  430. Message(@Self,evCommand,cmDeleteItem,nil);
  431. else DontClear:=true;
  432. end;
  433. if DontClear=false then ClearEvent(Event);
  434. end;
  435. evBroadcast :
  436. case Event.Command of
  437. cmListItemSelected :
  438. if Event.InfoPtr=pointer(CodeCompleteLB) then
  439. Message(@Self,evCommand,cmEditItem,nil);
  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 TCodeCompleteDialog.Execute: Word;
  456. var R: word;
  457. C: PCodeCompleteWordList;
  458. NewVal, I: integer;
  459. NewValStr : string;
  460. begin
  461. New(C, Init(10,20));
  462. if Assigned(CodeCompleteWords) then
  463. for I:=0 to CodeCompleteWords^.Count-1 do
  464. C^.Insert(NewStr(GetStr(CodeCompleteWords^.At(I))));
  465. CodeCompleteLB^.NewList(C);
  466. InputL^.SetData(StandardUnits);
  467. NewValStr:=IntToStr(CodeCompleteMinLen);
  468. MinInputL^.SetData(NewValStr);
  469. R:=inherited Execute;
  470. if R=cmOK then
  471. begin
  472. if Assigned(CodeCompleteWords) then Dispose(CodeCompleteWords, Done);
  473. CodeCompleteWords:=C;
  474. CodeCompleteCase:=TCodeCompleteCase(RB^.Value);
  475. MinInputL^.GetData(NewValStr);
  476. NewVal:=StrToInt(NewValStr);
  477. if (NewVal>0) and (NewVal<>CodeCompleteMinLen) then
  478. begin
  479. CodeCompleteMinLen:=NewVal;
  480. InitCodeComplete;
  481. end;
  482. ShowOnlyUnique:=CB^.Mark(0);
  483. UseAllUnitsInCodeComplete:=CB^.Mark(1);
  484. UseStandardUnitsInCodeComplete:=CB^.Mark(2);
  485. if UseStandardUnitsInCodeComplete and (not UseAllUnitsInCodeComplete or not assigned(UnitsCodeCompleteWords)) and
  486. ((StandardUnits<>GetStr(InputL^.Data)) or not assigned(UnitsCodeCompleteWords)) then
  487. begin
  488. InputL^.GetData(StandardUnits);
  489. AddStandardUnitsToCodeComplete;
  490. end
  491. else
  492. InputL^.GetData(StandardUnits);
  493. end
  494. else
  495. Dispose(C, Done);
  496. Execute:=R;
  497. end;
  498. procedure TCodeCompleteDialog.Add;
  499. var IC: boolean;
  500. S: string;
  501. P: PString;
  502. Cmd: word;
  503. CanExit: boolean;
  504. I: sw_integer;
  505. begin
  506. IC:=CodeCompleteLB^.Range=0;
  507. if IC=false then
  508. S:=GetStr(CodeCompleteLB^.List^.At(CodeCompleteLB^.Focused))
  509. else
  510. S:='';
  511. repeat
  512. Cmd:=InputBox(dialog_codecomplete_add,label_codecomplete_add_keyword,S,255);
  513. CanExit:=Cmd<>cmOK;
  514. if CanExit=false then
  515. begin
  516. CanExit:=PCodeCompleteWordList(CodeCompleteLB^.List)^.Search(@S,I)=false;
  517. if CanExit=false then
  518. begin
  519. ClearFormatParams; AddFormatParamStr(S);
  520. ErrorBox(msg_codecomplete_alreadyinlist,@FormatParams);
  521. end;
  522. end;
  523. until CanExit;
  524. if Cmd=cmOK then
  525. begin
  526. P:=NewStr(S);
  527. with CodeCompleteLB^ do
  528. begin
  529. List^.Insert(P);
  530. SetRange(List^.Count);
  531. SetFocusedItem(P);
  532. end;
  533. ReDraw;
  534. end;
  535. end;
  536. procedure TCodeCompleteDialog.Edit;
  537. var S: string;
  538. I,T: sw_integer;
  539. Cmd: word;
  540. CanExit: boolean;
  541. P: PString;
  542. begin
  543. if CodeCompleteLB^.Range=0 then Exit;
  544. I:=CodeCompleteLB^.Focused;
  545. S:=GetStr(CodeCompleteLB^.List^.At(I));
  546. repeat
  547. Cmd:=InputBox(dialog_codecomplete_edit,label_codecomplete_edit_keyword,S,255);
  548. CanExit:=Cmd<>cmOK;
  549. if CanExit=false then
  550. begin
  551. CanExit:=PCodeCompleteWordList(CodeCompleteLB^.List)^.Search(@S,T)=false;
  552. CanExit:=CanExit or (T=I);
  553. if CanExit=false then
  554. begin
  555. ClearFormatParams; AddFormatParamStr(S);
  556. ErrorBox(msg_codecomplete_alreadyinlist,@FormatParams);
  557. end;
  558. end;
  559. until CanExit;
  560. if Cmd=cmOK then
  561. begin
  562. P:=NewStr(S);
  563. with CodeCompleteLB^ do
  564. begin
  565. List^.AtFree(I);
  566. List^.Insert(P);
  567. SetFocusedItem(P);
  568. end;
  569. ReDraw;
  570. end;
  571. end;
  572. procedure TCodeCompleteDialog.Delete;
  573. begin
  574. if CodeCompleteLB^.Range=0 then Exit;
  575. CodeCompleteLB^.List^.AtFree(CodeCompleteLB^.Focused);
  576. CodeCompleteLB^.SetRange(CodeCompleteLB^.List^.Count);
  577. ReDraw;
  578. end;
  579. procedure RegisterCodeComplete;
  580. begin
  581. {$ifndef NOOBJREG}
  582. RegisterType(RCodeCompleteWordList);
  583. {$endif}
  584. end;
  585. END.
  586. {
  587. $Log$
  588. Revision 1.10 2002-09-11 13:12:42 pierre
  589. * fix CodeComplete loading and use a unit for standard units code complete
  590. Revision 1.9 2002/09/09 06:53:54 pierre
  591. * avoid to save file used by codecomplete
  592. Revision 1.8 2002/09/09 06:22:45 pierre
  593. * get it to load old and new desktops
  594. }