fpcodcmp.pas 19 KB

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