fpcodcmp.pas 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. unit FPCodCmp; { CodeComplete }
  2. interface
  3. uses Objects,Drivers,
  4. WUtils,WViews;
  5. type
  6. PCodeCompleteWordList = ^TCodeCompleteWordList;
  7. TCodeCompleteWordList = object(TTextCollection)
  8. end;
  9. PCodeCompleteDialog = ^TCodeCompleteDialog;
  10. TCodeCompleteDialog = object(TCenterDialog)
  11. constructor Init;
  12. function Execute: Word; virtual;
  13. procedure HandleEvent(var Event: TEvent); virtual;
  14. private
  15. CodeCompleteLB : PAdvancedListBox;
  16. procedure Add;
  17. procedure Edit;
  18. procedure Delete;
  19. end;
  20. function FPCompleteCodeWord(const WordS: string; var Text: string): boolean;
  21. procedure InitCodeComplete;
  22. function LoadCodeComplete(var S: TStream): boolean;
  23. function StoreCodeComplete(var S: TStream): boolean;
  24. procedure DoneCodeComplete;
  25. const CodeCompleteWords : PCodeCompleteWordList = nil;
  26. procedure RegisterCodeComplete;
  27. implementation
  28. uses Views,Dialogs,MsgBox,
  29. {$ifdef FVISION}
  30. FVConsts,
  31. {$else}
  32. Commands,
  33. {$endif}
  34. WEditor,
  35. FPConst,FPString,FPViews;
  36. {$ifndef NOOBJREG}
  37. const
  38. RCodeCompleteWordList: TStreamRec = (
  39. ObjType: 14401;
  40. VmtLink: Ofs(TypeOf(TCodeCompleteWordList)^);
  41. Load: @TCodeCompleteWordList.Load;
  42. Store: @TCodeCompleteWordList.Store
  43. );
  44. {$endif}
  45. function FPCompleteCodeWord(const WordS: string; var Text: string): boolean;
  46. var OK: boolean;
  47. Index: sw_integer;
  48. begin
  49. OK:=Assigned(CodeCompleteWords);
  50. if OK then
  51. begin
  52. Text:=CodeCompleteWords^.Lookup(WordS,Index);
  53. OK:=(Index<>-1) and (length(Text)<>length(WordS));
  54. end;
  55. if OK=false then Text:='';
  56. FPCompleteCodeWord:=OK;
  57. end;
  58. procedure InitCodeComplete;
  59. var I:integer;
  60. S: string;
  61. begin
  62. if Assigned(CodeCompleteWords) then Exit;
  63. New(CodeCompleteWords, Init(10,10));
  64. for I:=0 to GetReservedWordCount-1 do
  65. begin
  66. S:=LowCaseStr(GetReservedWord(I));
  67. if length(S)>=CodeCompleteMinLen then
  68. CodeCompleteWords^.Insert(NewStr(S));
  69. end;
  70. {
  71. there should be also a user front-end for customizing CodeComplete !
  72. any volunteers to implement? ;) - Gabor
  73. }
  74. end;
  75. function LoadCodeComplete(var S: TStream): boolean;
  76. var C: PCodeCompleteWordList;
  77. OK: boolean;
  78. begin
  79. New(C, Load(S));
  80. OK:=Assigned(C) and (S.Status=stOk);
  81. if OK then
  82. begin
  83. if Assigned(CodeCompleteWords) then Dispose(CodeCompleteWords, Done);
  84. CodeCompleteWords:=C;
  85. end
  86. else
  87. if Assigned(C) then
  88. Dispose(C, Done);
  89. LoadCodeComplete:=OK;
  90. end;
  91. function StoreCodeComplete(var S: TStream): boolean;
  92. var OK: boolean;
  93. begin
  94. OK:=Assigned(CodeCompleteWords);
  95. if OK then
  96. begin
  97. CodeCompleteWords^.Store(S);
  98. OK:=OK and (S.Status=stOK);
  99. end;
  100. StoreCodeComplete:=OK;
  101. end;
  102. procedure DoneCodeComplete;
  103. begin
  104. if Assigned(CodeCompleteWords) then Dispose(CodeCompleteWords, Done);
  105. CodeCompleteWords:=nil;
  106. end;
  107. constructor TCodeCompleteDialog.Init;
  108. var R,R2,R3: TRect;
  109. SB: PScrollBar;
  110. begin
  111. R.Assign(0,0,46,16);
  112. inherited Init(R,dialog_codecomplete);
  113. HelpCtx:=hcCodeCompleteOptions;
  114. GetExtent(R); R.Grow(-3,-2); Inc(R.A.Y); R3.Copy(R); Dec(R.B.X,12);
  115. R2.Copy(R); R2.Move(1,0); R2.A.X:=R2.B.X-1;
  116. New(SB, Init(R2)); Insert(SB);
  117. New(CodeCompleteLB, Init(R,1,SB));
  118. Insert(CodeCompleteLB);
  119. R2.Copy(R); R2.Move(0,-1); R2.B.Y:=R2.A.Y+1; Dec(R2.A.X);
  120. Insert(New(PLabel, Init(R2, label_codecomplete_keywords, CodeCompleteLB)));
  121. R.Copy(R3); R.A.X:=R.B.X-10; R.B.Y:=R.A.Y+2;
  122. Insert(New(PButton, Init(R, button_OK, cmOK, bfNormal)));
  123. R.Move(0,2);
  124. Insert(New(PButton, Init(R, button_Edit, cmEditItem, bfDefault)));
  125. R.Move(0,2);
  126. Insert(New(PButton, Init(R, button_New, cmAddItem, bfNormal)));
  127. R.Move(0,2);
  128. Insert(New(PButton, Init(R, button_Delete, cmDeleteItem, bfNormal)));
  129. R.Move(0,2);
  130. Insert(New(PButton, Init(R, button_Cancel, cmCancel, bfNormal)));
  131. SelectNext(false);
  132. end;
  133. procedure TCodeCompleteDialog.HandleEvent(var Event: TEvent);
  134. var DontClear: boolean;
  135. begin
  136. case Event.What of
  137. evKeyDown :
  138. begin
  139. DontClear:=false;
  140. case Event.KeyCode of
  141. kbIns :
  142. Message(@Self,evCommand,cmAddItem,nil);
  143. kbDel :
  144. Message(@Self,evCommand,cmDeleteItem,nil);
  145. else DontClear:=true;
  146. end;
  147. if DontClear=false then ClearEvent(Event);
  148. end;
  149. evBroadcast :
  150. case Event.Command of
  151. cmListItemSelected :
  152. if Event.InfoPtr=pointer(CodeCompleteLB) then
  153. Message(@Self,evCommand,cmEditItem,nil);
  154. end;
  155. evCommand :
  156. begin
  157. DontClear:=false;
  158. case Event.Command of
  159. cmAddItem : Add;
  160. cmDeleteItem : Delete;
  161. cmEditItem : Edit;
  162. else DontClear:=true;
  163. end;
  164. if DontClear=false then ClearEvent(Event);
  165. end;
  166. end;
  167. inherited HandleEvent(Event);
  168. end;
  169. function TCodeCompleteDialog.Execute: Word;
  170. var R: word;
  171. C: PCodeCompleteWordList;
  172. I: integer;
  173. begin
  174. New(C, Init(10,20));
  175. if Assigned(CodeCompleteWords) then
  176. for I:=0 to CodeCompleteWords^.Count-1 do
  177. C^.Insert(NewStr(GetStr(CodeCompleteWords^.At(I))));
  178. CodeCompleteLB^.NewList(C);
  179. R:=inherited Execute;
  180. if R=cmOK then
  181. begin
  182. if Assigned(CodeCompleteWords) then Dispose(CodeCompleteWords, Done);
  183. CodeCompleteWords:=C;
  184. end
  185. else
  186. Dispose(C, Done);
  187. Execute:=R;
  188. end;
  189. procedure TCodeCompleteDialog.Add;
  190. var IC: boolean;
  191. S: string;
  192. P: PString;
  193. Cmd: word;
  194. CanExit: boolean;
  195. I: sw_integer;
  196. begin
  197. IC:=CodeCompleteLB^.Range=0;
  198. if IC=false then
  199. S:=GetStr(CodeCompleteLB^.List^.At(CodeCompleteLB^.Focused))
  200. else
  201. S:='';
  202. repeat
  203. Cmd:=InputBox(dialog_codecomplete_add,label_codecomplete_add_keyword,S,255);
  204. CanExit:=Cmd<>cmOK;
  205. if CanExit=false then
  206. begin
  207. CanExit:=PCodeCompleteWordList(CodeCompleteLB^.List)^.Search(@S,I)=false;
  208. if CanExit=false then
  209. begin
  210. ClearFormatParams; AddFormatParamStr(S);
  211. ErrorBox(msg_codecomplete_alreadyinlist,@FormatParams);
  212. end;
  213. end;
  214. until CanExit;
  215. if Cmd=cmOK then
  216. begin
  217. P:=NewStr(S);
  218. with CodeCompleteLB^ do
  219. begin
  220. List^.Insert(P);
  221. SetRange(List^.Count);
  222. SetFocusedItem(P);
  223. end;
  224. ReDraw;
  225. end;
  226. end;
  227. procedure TCodeCompleteDialog.Edit;
  228. var S: string;
  229. I,T: sw_integer;
  230. Cmd: word;
  231. CanExit: boolean;
  232. P: PString;
  233. begin
  234. if CodeCompleteLB^.Range=0 then Exit;
  235. I:=CodeCompleteLB^.Focused;
  236. S:=GetStr(CodeCompleteLB^.List^.At(I));
  237. repeat
  238. Cmd:=InputBox(dialog_codecomplete_edit,label_codecomplete_edit_keyword,S,255);
  239. CanExit:=Cmd<>cmOK;
  240. if CanExit=false then
  241. begin
  242. CanExit:=PCodeCompleteWordList(CodeCompleteLB^.List)^.Search(@S,T)=false;
  243. CanExit:=CanExit or (T=I);
  244. if CanExit=false then
  245. begin
  246. ClearFormatParams; AddFormatParamStr(S);
  247. ErrorBox(msg_codecomplete_alreadyinlist,@FormatParams);
  248. end;
  249. end;
  250. until CanExit;
  251. if Cmd=cmOK then
  252. begin
  253. P:=NewStr(S);
  254. with CodeCompleteLB^ do
  255. begin
  256. List^.AtFree(I);
  257. List^.Insert(P);
  258. SetFocusedItem(P);
  259. end;
  260. ReDraw;
  261. end;
  262. end;
  263. procedure TCodeCompleteDialog.Delete;
  264. begin
  265. if CodeCompleteLB^.Range=0 then Exit;
  266. CodeCompleteLB^.List^.AtFree(CodeCompleteLB^.Focused);
  267. CodeCompleteLB^.SetRange(CodeCompleteLB^.List^.Count);
  268. ReDraw;
  269. end;
  270. procedure RegisterCodeComplete;
  271. begin
  272. {$ifndef NOOBJREG}
  273. RegisterType(RCodeCompleteWordList);
  274. {$endif}
  275. end;
  276. END.