fpcodcmp.pas 19 KB

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