fpcodcmp.pas 19 KB

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