fpkeys.pas 8.2 KB

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