fpkeys.pas 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. {
  2. This file is part of the Free Pascal Integrated Development Environment
  3. Copyright (c) 1998-2000 by Pierre Muller
  4. Learn keys routines for the IDE
  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 fpkeys;
  12. {$H-}
  13. interface
  14. uses
  15. keyboard, Objects, Drivers, Dialogs, App,
  16. FPViews, WViews;
  17. procedure LearnKeysDialog;
  18. Const
  19. NumWantedKeys = 24;
  20. WantedKeys : Array[1..NumWantedKeys] of word =
  21. (kbF1,kbF2,kbF3,kbF4,
  22. kbF5,kbF6,kbF7,kbF8,
  23. kbF9,kbF10,kbF11,kbF12,
  24. kbLeft,kbRight,kbUp,kbDown,
  25. kbPgUp,kbPgDn,kbIns,kbDel,
  26. kbEnd,kbHome,kbBack,kbShiftTab);
  27. type
  28. PKeyDialog = ^TKeyDialog;
  29. TKeyDialog = object(TCenterDialog)
  30. PSTL : Array [1..NumWantedKeys] of PLabel;
  31. PL : Array [1..NumWantedKeys] of PInputLine;
  32. KeyOK : Array [1..NumWantedKeys] of boolean;
  33. PST,PST2 : PAdvancedStaticText;
  34. Constructor Init(Const ATitle : String);
  35. {Procedure HandleEvent(var E : TEvent);virtual;}
  36. function Execute : Word;Virtual;
  37. end;
  38. Procedure LoadKeys(var S : TStream);
  39. Procedure StoreKeys(var S : TStream);
  40. Procedure SetKnownKeys;
  41. implementation
  42. uses
  43. FVConsts,
  44. WUtils;
  45. {$ifndef NotUseTree}
  46. function GetKey(Const St : String) : word;
  47. var
  48. AChar,AScan : byte;
  49. begin
  50. If FindSequence(St,AChar,Ascan) then
  51. GetKey:=Ascan*$100+AChar
  52. else
  53. GetKey:=0;
  54. end;
  55. Procedure SetKey(Const St : String;key :word);
  56. var
  57. AChar,AScan : byte;
  58. begin
  59. AChar:=key and $ff;
  60. AScan:=key shr 8;
  61. AddSequence(St,AChar,Ascan);
  62. end;
  63. {$endif not NotUseTree}
  64. Const
  65. WantedKeysLabels : Array[1..NumWantedKeys] of String[5] =
  66. ('F1 ','F2 ','F3 ','F4 ',
  67. 'F5 ','F6 ','F7 ','F8 ',
  68. 'F9 ','F10 ','F11 ','F12 ',
  69. 'Left ','Right','Up ','Down ',
  70. 'PgUp ','PgDn ','Ins ','Del ',
  71. 'End ','Home ','Back ','ShTab');
  72. var
  73. KeyEscape : Array[1..NumWantedKeys] of String[10];
  74. Procedure StoreKeys(var S : TStream);
  75. var
  76. i,index : longint;
  77. l : byte;
  78. begin
  79. for i:=1 to NumWantedKeys do
  80. if KeyEscape[i]<>'' then
  81. begin
  82. { need temporary local var, because write has var argument }
  83. index:=i;
  84. S.Write(index,Sizeof(index));
  85. l:=Length(KeyEscape[i]);
  86. S.Write(l,sizeof(l));
  87. S.Write(KeyEscape[i][1],l);
  88. end;
  89. end;
  90. Procedure LoadKeys(var S : TStream);
  91. var
  92. i : longint;
  93. l : byte;
  94. begin
  95. While S.GetPos<S.GetSize do
  96. begin
  97. S.Read(i,Sizeof(i));
  98. S.Read(l,Sizeof(l));
  99. S.Read(KeyEscape[i][1],l);
  100. KeyEscape[i][0]:=chr(l);
  101. end;
  102. SetKnownKeys;
  103. end;
  104. Procedure SetKnownKeys;
  105. var
  106. i : longint;
  107. begin
  108. {$ifndef NotUseTree}
  109. for i:=1 to NumWantedKeys do
  110. if KeyEscape[i]<>'' then
  111. SetKey(KeyEscape[i],WantedKeys[i]);
  112. {$endif not NotUseTree}
  113. end;
  114. function NiceEscape(Const St : String) : String;
  115. var
  116. s : string;
  117. i : longint;
  118. begin
  119. s:='';
  120. for i:=1 to length(St) do
  121. case ord(St[i]) of
  122. 1..26 : s:=s+'^'+chr(ord('A')-1+Ord(St[i]));
  123. 27 : s:=s+'Esc';
  124. 0,28..31,127..255 : s:=s+'"#'+IntToStr(ord(St[i]))+'"';
  125. else
  126. s:=s+St[i];
  127. end;
  128. NiceEscape:=s;
  129. end;
  130. constructor TKeyDialog.Init(Const ATitle : String);
  131. var
  132. St : String;
  133. D : PCenterDialog;
  134. R : TRect;
  135. E : TEvent;
  136. i,hight,key : longint;
  137. begin
  138. Hight:=(NumWantedKeys + 2) div 3;
  139. R.Assign(0,0,63 + 4,Hight + 4);
  140. Inherited Init(R,ATitle);
  141. for i:=1 to NumWantedKeys do
  142. begin
  143. GetExtent(R);
  144. R.Grow(-1,-1);
  145. R.A.Y:=R.A.Y + ((i-1) mod Hight);
  146. R.A.X:=R.A.X + 21 * ((i-1) div Hight);
  147. R.B.Y:=R.A.Y+1;
  148. R.B.X:=R.A.X + 10;
  149. St:=WantedKeysLabels[i]+' key';
  150. KeyOK[i]:=false;
  151. New(PSTL[i],Init(R,St,nil));
  152. Insert(PSTL[i]);
  153. R.A.X:=R.B.X+1;
  154. R.B.X:=R.B.X+11;
  155. New(PL[i],Init(R,20));
  156. St:=NiceEscape(KeyEscape[i]);
  157. PL[i]^.SetData(St);
  158. Insert(PL[i]);
  159. PSTL[i]^.Link:=PL[i];
  160. end;
  161. GetExtent(R);
  162. R.Grow(-1,-1);
  163. Dec(R.B.Y);
  164. R.A.Y:=R.B.Y-1;
  165. New(PST,init(R,'Press all listed keys'));
  166. Insert(PST);
  167. GetExtent(R);
  168. R.Grow(-1,-1);
  169. R.A.Y:=R.B.Y-1;
  170. New(PST2,init(R,'Alt prefix "'+NiceEscape(chr(AltPrefix))+'" Shift prefix = "'+
  171. NiceEscape(chr(ShiftPrefix))+'" Ctrl prefix = "'+NiceEscape(chr(CtrlPrefix))+'"'));
  172. Insert(PST2);
  173. InsertButtons(@Self);
  174. end;
  175. function TKeyDialog.Execute : Word;
  176. var
  177. APL : PInputLine;
  178. i,j : longint;
  179. St : String;
  180. E : TEvent;
  181. OldKey : word;
  182. keyfound : boolean;
  183. begin
  184. {$ifndef NotUseTree}
  185. repeat
  186. EndState := 0;
  187. repeat
  188. if TypeOf(Current^)=Typeof(TInputLine) then
  189. APL:=PInputLine(Current)
  190. else if TypeOf(Current^)=Typeof(TLabel) then
  191. APL:=PInputLine(Plabel(Current)^.Link)
  192. else
  193. APL:=nil;
  194. FillChar(E,SizeOf(E),#0);
  195. if Keyboard.KeyPressed then
  196. St:=RawReadString
  197. else
  198. begin
  199. St:='';
  200. Application^.GetEvent(E);
  201. end;
  202. if E.What= evNothing then
  203. begin
  204. if St<>'' then
  205. begin
  206. if GetKey(St)<>0 then
  207. begin
  208. E.What:=evKeyDown;
  209. E.KeyCode:=GetKey(St);
  210. end
  211. else if St=#9 then
  212. begin
  213. E.What:=evKeyDown;
  214. E.KeyCode:=kbTab;
  215. end
  216. else if St=#27 then
  217. begin
  218. E.What:=evKeyDown;
  219. E.KeyCode:=kbEsc;
  220. end
  221. else if St=#13 then
  222. begin
  223. E.What:=evKeyDown;
  224. E.KeyCode:=kbEnter;
  225. end;
  226. end;
  227. end;
  228. keyFound:=false;
  229. if (E.What=evKeyDown) and not assigned(APL) then
  230. begin
  231. for i:=1 to NumWantedKeys do
  232. if E.Keycode=WantedKeys[i] then
  233. begin
  234. DisposeStr(PSTL[i]^.Text);
  235. PSTL[i]^.Text:=NewStr(WantedKeysLabels[i]+' OK ');
  236. keyFound:=true;
  237. keyOK[i]:=true;
  238. KeyEscape[i]:=St;
  239. St:=NiceEscape(St);
  240. PL[i]^.SetData(St);
  241. ClearEvent(E);
  242. ReDraw;
  243. end;
  244. end;
  245. if (St<>'') and not keyfound and
  246. ((E.What<>evKeyDown) or
  247. ((E.KeyCode<>kbTab) and (E.Keycode<>kbEnter) and (E.Keycode<>kbEsc))) then
  248. begin
  249. PST^.SetText('"'+NiceEscape(St)+'"');
  250. if Assigned(APL) then
  251. begin
  252. j:=-1;
  253. for i:=1 to NumWantedKeys do
  254. if APL=PL[i] then
  255. j:=i;
  256. if (j>0) and (j<=NumWantedKeys) then
  257. begin
  258. OldKey:=GetKey(St);
  259. if OldKey<>0 then
  260. begin
  261. for i:=1 to NumWantedKeys do
  262. if (OldKey=WantedKeys[i]) and (i<>j) then
  263. begin
  264. If ConfirmBox('"'+St+'" is used for'+#13+
  265. 'key $'+hexstr(oldKey,4)+' '+WantedKeysLabels[i]+#13+
  266. 'Change it to '+WantedKeysLabels[j],nil,true)=cmYes then
  267. begin
  268. KeyEscape[i]:='';
  269. PL[i]^.SetData(KeyEscape[i]);
  270. end
  271. else
  272. begin
  273. St:='';
  274. end;
  275. end;
  276. end;
  277. if St<>'' then
  278. Begin
  279. SetKey(St,WantedKeys[j]);
  280. KeyEscape[j]:=St;
  281. St:=NiceEscape(St);
  282. APL^.SetData(St);
  283. end;
  284. end;
  285. ClearEvent(E);
  286. end;
  287. end;
  288. if (E.What<>evNothing) then
  289. HandleEvent(E);
  290. if E.What <> evNothing then EventError(E);
  291. until EndState <> 0;
  292. until Valid(EndState);
  293. Execute := EndState;
  294. {$else NotUseTree}
  295. Execute:=cmCancel;
  296. {$endif NotUseTree}
  297. end;
  298. procedure LearnKeysDialog;
  299. var
  300. D : PKeyDialog;
  301. begin
  302. {$ifdef NotUseTree}
  303. NotImplemented;
  304. {$else not NotUseTree}
  305. New(D,Init('Learn keys'));
  306. Application^.ExecuteDialog(D,nil);
  307. {$endif not NotUseTree}
  308. end;
  309. end.