fpcodcmp.pas 19 KB

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