You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

521 lines
18 KiB

  1. /***************/
  2. /* hotkeys.cpp */
  3. /***************/
  4. #include "fctsys.h"
  5. #include "gr_basic.h"
  6. #include "common.h"
  7. #include "program.h"
  8. #include "libcmp.h"
  9. #include "general.h"
  10. #include "id.h"
  11. #include "hotkeys.h"
  12. #include "protos.h"
  13. /* How to add a new hotkey:
  14. * add a new id in the enum hotkey_id_commnand like MY_NEW_ID_FUNCTION (see hotkeys.h).
  15. * add a new Ki_HotkeyInfo entry like:
  16. * static Ki_HotkeyInfo HkMyNewEntry(wxT("Command Label"), MY_NEW_ID_FUNCTION, default key value);
  17. * "Command Label" is the name used in hotkey list display, and the identifier in the hotkey list file
  18. * MY_NEW_ID_FUNCTION is an equivalent id function used in the switch in OnHotKey() function.
  19. * default key value is the default hotkey for this command. Can be overrided by the user hotkey list file
  20. * add the HkMyNewEntry pointer in the s_Schematic_Hotkey_List list or the s_LibEdit_Hotkey_List list
  21. * ( or s_Common_Hotkey_List if the same command is added both in eeschema and libedit)
  22. * Add the new code in the switch in OnHotKey() function.
  23. * when the variable ItemInEdit is true, an item is currently edited.
  24. * This can be usefull if the new function cannot be executed while an item is currently being edited
  25. * ( For example, one cannot start a new wire when a component is moving.)
  26. *
  27. * Note: If an hotkey is a special key be sure the corresponding wxWidget keycode (WXK_XXXX)
  28. * is handled in the hotkey_name_descr s_Hotkey_Name_List list (see hotkeys_basic.cpp)
  29. * and see this list for some ascii keys (space ...)
  30. * Key modifier are: GR_KB_CTRL GR_KB_ALT
  31. */
  32. /* local variables */
  33. /* Hotkey list: */
  34. // Common commands
  35. static Ki_HotkeyInfo HkZoomCenter( wxT( "Zoom Center" ), HK_ZOOM_CENTER, WXK_F4 );
  36. static Ki_HotkeyInfo HkZoomRedraw( wxT( "Zoom Redraw" ), HK_ZOOM_REDRAW, WXK_F3 );
  37. static Ki_HotkeyInfo HkZoomOut( wxT( "Zoom Out" ), HK_ZOOM_OUT, WXK_F2 );
  38. static Ki_HotkeyInfo HkZoomIn( wxT( "Zoom In" ), HK_ZOOM_IN, WXK_F1 );
  39. static Ki_HotkeyInfo HkHelp( wxT( "Help: this message" ), HK_HELP, '?' );
  40. static Ki_HotkeyInfo HkResetLocalCoord( wxT( "Reset local coord." ), HK_RESET_LOCAL_COORD, ' ' );
  41. static Ki_HotkeyInfo HkUndo( wxT( "Undo" ), HK_UNDO, GR_KB_CTRL + 'Z', (int)ID_SCHEMATIC_UNDO );
  42. static Ki_HotkeyInfo HkRedo( wxT( "Redo" ), HK_REDO, GR_KB_CTRL + 'Y', (int)ID_SCHEMATIC_REDO );
  43. // Schematic editor
  44. static Ki_HotkeyInfo HkBeginWire( wxT( "begin Wire" ), HK_BEGIN_WIRE, 'W' );
  45. static Ki_HotkeyInfo HkAddComponent( wxT( "Add Component" ), HK_ADD_NEW_COMPONENT, 'A' );
  46. static Ki_HotkeyInfo HkMirrorYComponent( wxT(
  47. "Mirror Y Component" ), HK_MIRROR_Y_COMPONENT, 'Y' );
  48. static Ki_HotkeyInfo HkMirrorXComponent( wxT(
  49. "Mirror X Component" ), HK_MIRROR_X_COMPONENT, 'X' );
  50. static Ki_HotkeyInfo HkOrientNormalComponent( wxT(
  51. "Orient Normal Component" ),
  52. HK_ORIENT_NORMAL_COMPONENT, 'N' );
  53. static Ki_HotkeyInfo HkRotateComponent( wxT( "Rotate Component" ), HK_ROTATE_COMPONENT, 'R' );
  54. static Ki_HotkeyInfo HkEditComponentValue( wxT( "Edit Component Value" ), HK_EDIT_COMPONENT_VALUE, 'V' );
  55. static Ki_HotkeyInfo HkEditComponentFootprint( wxT( "Edit Component Footprint" ), HK_EDIT_COMPONENT_FOOTPRINT, 'F' );
  56. static Ki_HotkeyInfo HkMoveComponent( wxT( "Move Component" ), HK_MOVE_COMPONENT, 'M', ID_POPUP_SCH_MOVE_CMP_REQUEST );
  57. static Ki_HotkeyInfo HkDragComponent( wxT( "Drag Component" ), HK_DRAG_COMPONENT, 'G', ID_POPUP_SCH_DRAG_CMP_REQUEST );
  58. static Ki_HotkeyInfo HkMove2Drag( wxT(
  59. "Switch move block to drag block" ),
  60. HK_MOVEBLOCK_TO_DRAGBLOCK, '\t' );
  61. static Ki_HotkeyInfo HkInsert( wxT( "Repeat Last Item" ), HK_REPEAT_LAST, WXK_INSERT );
  62. static Ki_HotkeyInfo HkDelete( wxT( "Delete Item" ), HK_DELETE, WXK_DELETE );
  63. static Ki_HotkeyInfo HkNextSearch( wxT( "Next Search" ), HK_NEXT_SEARCH, WXK_F5 );
  64. // Library editor:
  65. static Ki_HotkeyInfo HkInsertPin( wxT( "Repeat Pin" ), HK_REPEAT_LAST, WXK_INSERT );
  66. static Ki_HotkeyInfo HkEditPin( wxT( "Edit Pin" ), HK_EDIT_PIN, 'E' );
  67. static Ki_HotkeyInfo HkMovePin( wxT( "Move Pin" ), HK_MOVE_PIN, 'M' );
  68. static Ki_HotkeyInfo HkDeletePin( wxT( "Delete Pin" ), HK_DELETE_PIN, WXK_DELETE );
  69. // List of common hotkey descriptors
  70. Ki_HotkeyInfo* s_Common_Hotkey_List[] =
  71. {
  72. &HkHelp,
  73. &HkZoomIn, &HkZoomOut, &HkZoomRedraw, &HkZoomCenter,
  74. &HkResetLocalCoord,
  75. &HkUndo, &HkRedo,
  76. NULL
  77. };
  78. // List of hotkey descriptors for schematic
  79. Ki_HotkeyInfo* s_Schematic_Hotkey_List[] = {
  80. &HkNextSearch,
  81. &HkDelete, &HkInsert, &HkMove2Drag,
  82. &HkMoveComponent, &HkDragComponent, &HkAddComponent,
  83. &HkRotateComponent, &HkMirrorXComponent, &HkMirrorYComponent, &HkOrientNormalComponent,
  84. &HkEditComponentValue, &HkEditComponentFootprint,
  85. &HkBeginWire,
  86. NULL
  87. };
  88. // List of hotkey descriptors for libray editor
  89. Ki_HotkeyInfo* s_LibEdit_Hotkey_List[] =
  90. {
  91. &HkInsertPin,
  92. &HkEditPin,
  93. &HkMovePin,
  94. &HkDeletePin,
  95. NULL
  96. };
  97. // list of sections and corresponding hotkey list for eeschema (used to create an hotkey config file)
  98. struct Ki_HotkeyInfoSectionDescriptor s_Eeschema_Hokeys_Descr[] =
  99. {
  100. { &g_CommonSectionTag, s_Common_Hotkey_List, "Common keys" },
  101. { &g_SchematicSectionTag, s_Schematic_Hotkey_List, "Schematic editor keys" },
  102. { &g_LibEditSectionTag, s_LibEdit_Hotkey_List, "library editor keys" },
  103. { NULL, NULL }
  104. };
  105. // list of sections and corresponding hotkey list for the schematic editor (used to list current hotkeys)
  106. struct Ki_HotkeyInfoSectionDescriptor s_Schematic_Hokeys_Descr[] =
  107. {
  108. { &g_CommonSectionTag, s_Common_Hotkey_List, NULL },
  109. { &g_SchematicSectionTag, s_Schematic_Hotkey_List, NULL },
  110. { NULL, NULL, NULL }
  111. };
  112. // list of sections and corresponding hotkey list for the component editor (used to list current hotkeys)
  113. struct Ki_HotkeyInfoSectionDescriptor s_Libedit_Hokeys_Descr[] =
  114. {
  115. { &g_CommonSectionTag, s_Common_Hotkey_List, NULL },
  116. { &g_LibEditSectionTag, s_LibEdit_Hotkey_List, NULL },
  117. { NULL, NULL, NULL }
  118. };
  119. /***********************************************************/
  120. void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey,
  121. EDA_BaseStruct* DrawStruct )
  122. /***********************************************************/
  123. /* Hot keys. Some commands are relative to the item under the mouse cursor
  124. * Commands are case insensitive
  125. */
  126. {
  127. bool ItemInEdit = GetScreen()->GetCurItem()
  128. && GetScreen()->GetCurItem()->m_Flags;
  129. bool RefreshToolBar = FALSE; // We must refresh tool bar when the undo/redo tool state is modified
  130. if( hotkey == 0 )
  131. return;
  132. wxPoint MousePos = GetScreen()->m_MousePosition;
  133. // Remap the control key Ctrl A (0x01) to GR_KB_CTRL + 'A' (easier to handle...)
  134. if( (hotkey & GR_KB_CTRL) != 0 )
  135. hotkey += 'A' - 1;
  136. /* Convert lower to upper case (the usual toupper function has problem with non ascii codes like function keys */
  137. if( (hotkey >= 'a') && (hotkey <= 'z') )
  138. hotkey += 'A' - 'a';
  139. // Search command from key :
  140. Ki_HotkeyInfo * HK_Descr = GetDescriptorFromHotkey( hotkey, s_Common_Hotkey_List );
  141. if( HK_Descr == NULL )
  142. HK_Descr = GetDescriptorFromHotkey( hotkey, s_Schematic_Hotkey_List );
  143. if( HK_Descr == NULL ) return;
  144. switch( HK_Descr->m_Idcommand )
  145. {
  146. default:
  147. case HK_NOT_FOUND:
  148. return;
  149. break;
  150. case HK_HELP: // Display Current hotkey list
  151. DisplayHotkeyList( this, s_Schematic_Hokeys_Descr );
  152. break;
  153. case HK_RESET_LOCAL_COORD: /* Reset the relative coord */
  154. GetScreen()->m_O_Curseur = GetScreen()->m_Curseur;
  155. break;
  156. case HK_ZOOM_IN:
  157. OnZoom( ID_ZOOM_IN_KEY );
  158. break;
  159. case HK_ZOOM_OUT:
  160. OnZoom( ID_ZOOM_OUT_KEY );
  161. break;
  162. case HK_ZOOM_REDRAW:
  163. OnZoom( ID_ZOOM_REDRAW_KEY );
  164. break;
  165. case HK_ZOOM_CENTER:
  166. OnZoom( ID_ZOOM_CENTER_KEY );
  167. break;
  168. case HK_UNDO:
  169. case HK_REDO:
  170. if( ItemInEdit )
  171. break;
  172. {
  173. wxCommandEvent event( wxEVT_COMMAND_TOOL_CLICKED, HK_Descr->m_IdMenuEvent );
  174. wxPostEvent( this, event );
  175. }
  176. break;
  177. case HK_MOVEBLOCK_TO_DRAGBLOCK: // Switch to drag mode, when block moving
  178. HandleBlockEndByPopUp( BLOCK_DRAG, DC );
  179. break;
  180. case HK_DELETE:
  181. if( ItemInEdit )
  182. break;
  183. RefreshToolBar = LocateAndDeleteItem( this, DC );
  184. GetScreen()->SetModify();
  185. GetScreen()->SetCurItem( NULL );
  186. TestDanglingEnds( GetScreen()->EEDrawList, DC );
  187. break;
  188. case HK_REPEAT_LAST:
  189. if( ItemInEdit )
  190. break;
  191. if( g_ItemToRepeat && (g_ItemToRepeat->m_Flags == 0) )
  192. {
  193. RepeatDrawItem( DC );
  194. }
  195. break;
  196. case HK_NEXT_SEARCH:
  197. if( ItemInEdit )
  198. break;
  199. if( g_LastSearchIsMarker )
  200. WinEDA_SchematicFrame::FindMarker( 1 );
  201. else
  202. FindSchematicItem( wxEmptyString, 2 );
  203. break;
  204. case HK_ADD_NEW_COMPONENT: // Add component
  205. if( ItemInEdit )
  206. break;
  207. // switch to m_ID_current_state = ID_COMPONENT_BUTT;
  208. if( m_ID_current_state != ID_COMPONENT_BUTT )
  209. SetToolID( ID_COMPONENT_BUTT, wxCURSOR_PENCIL, _( "Add Component" ) );
  210. OnLeftClick( DC, MousePos );
  211. break;
  212. case HK_BEGIN_WIRE: // Add wire
  213. if( DrawStruct ) // An item is selected. If edited and not a wire, a new command is not possible
  214. {
  215. if( DrawStruct->m_Flags ) // Item selected and edition in progress
  216. {
  217. if( DrawStruct->Type() == DRAW_SEGMENT_STRUCT_TYPE )
  218. {
  219. EDA_DrawLineStruct* segment = (EDA_DrawLineStruct*) DrawStruct;
  220. if( segment->GetLayer() != LAYER_WIRE )
  221. break;
  222. }
  223. else
  224. break;
  225. }
  226. }
  227. // switch to m_ID_current_state = ID_WIRE_BUTT;
  228. if( m_ID_current_state != ID_WIRE_BUTT )
  229. SetToolID( ID_WIRE_BUTT, wxCURSOR_PENCIL, _( "Add Wire" ) );
  230. OnLeftClick( DC, MousePos );
  231. break;
  232. case HK_ROTATE_COMPONENT: // Component Rotation
  233. if( DrawStruct == NULL )
  234. {
  235. DrawStruct = PickStruct( GetScreen()->m_Curseur,
  236. GetScreen(), LIBITEM | TEXTITEM | LABELITEM );
  237. if( DrawStruct == NULL )
  238. break;
  239. if( DrawStruct->Type() == TYPE_SCH_COMPONENT )
  240. DrawStruct = LocateSmallestComponent( GetScreen() );
  241. if( DrawStruct == NULL )
  242. break;
  243. }
  244. switch( DrawStruct->Type() )
  245. {
  246. case TYPE_SCH_COMPONENT:
  247. if( DrawStruct->m_Flags == 0 )
  248. {
  249. SaveCopyInUndoList( (SCH_ITEM*) DrawStruct, IS_CHANGED );
  250. RefreshToolBar = TRUE;
  251. }
  252. CmpRotationMiroir(
  253. (SCH_COMPONENT*) DrawStruct, DC, CMP_ROTATE_COUNTERCLOCKWISE );
  254. break;
  255. case TYPE_SCH_TEXT:
  256. case TYPE_SCH_LABEL:
  257. case TYPE_SCH_GLOBALLABEL:
  258. case TYPE_SCH_HIERLABEL:
  259. if( DrawStruct->m_Flags == 0 )
  260. {
  261. SaveCopyInUndoList( (SCH_ITEM*) DrawStruct, IS_CHANGED );
  262. RefreshToolBar = TRUE;
  263. }
  264. ChangeTextOrient( (SCH_TEXT*) DrawStruct, DC );
  265. break;
  266. default:
  267. ;
  268. }
  269. break;
  270. case HK_MIRROR_Y_COMPONENT: // Mirror Y (Component)
  271. if( DrawStruct == NULL )
  272. DrawStruct = LocateSmallestComponent( (SCH_SCREEN*)GetScreen() );
  273. if( DrawStruct )
  274. {
  275. if( DrawStruct->m_Flags == 0 )
  276. {
  277. SaveCopyInUndoList( (SCH_ITEM*) DrawStruct, IS_CHANGED );
  278. RefreshToolBar = TRUE;
  279. }
  280. CmpRotationMiroir( (SCH_COMPONENT*) DrawStruct, DC, CMP_MIROIR_Y );
  281. }
  282. break;
  283. case HK_MIRROR_X_COMPONENT: // Mirror X (Component)
  284. if( DrawStruct == NULL )
  285. DrawStruct = LocateSmallestComponent( GetScreen() );
  286. if( DrawStruct )
  287. {
  288. if( DrawStruct->m_Flags == 0 )
  289. {
  290. SaveCopyInUndoList( (SCH_ITEM*) DrawStruct, IS_CHANGED );
  291. RefreshToolBar = TRUE;
  292. }
  293. CmpRotationMiroir(
  294. (SCH_COMPONENT*) DrawStruct, DC, CMP_MIROIR_X );
  295. }
  296. break;
  297. case HK_ORIENT_NORMAL_COMPONENT: // Orient 0, no mirror (Component)
  298. if( DrawStruct == NULL )
  299. DrawStruct = LocateSmallestComponent( GetScreen() );
  300. if( DrawStruct )
  301. {
  302. if( DrawStruct->m_Flags == 0 )
  303. {
  304. SaveCopyInUndoList( (SCH_ITEM*) DrawStruct, IS_CHANGED );
  305. RefreshToolBar = TRUE;
  306. }
  307. CmpRotationMiroir( (SCH_COMPONENT*) DrawStruct, DC, CMP_NORMAL );
  308. TestDanglingEnds( GetScreen()->EEDrawList, DC );
  309. }
  310. break;
  311. case HK_DRAG_COMPONENT: // Start drag Component
  312. case HK_MOVE_COMPONENT: // Start move Component
  313. if( ItemInEdit )
  314. break;
  315. if( DrawStruct == NULL )
  316. DrawStruct = LocateSmallestComponent( GetScreen() );
  317. if( DrawStruct && (DrawStruct->m_Flags ==0) )
  318. {
  319. GetScreen()->SetCurItem( (SCH_ITEM*) DrawStruct );
  320. wxCommandEvent event( wxEVT_COMMAND_TOOL_CLICKED, HK_Descr->m_IdMenuEvent );
  321. wxPostEvent( this, event );
  322. }
  323. break;
  324. case HK_EDIT_COMPONENT_VALUE:
  325. if( ItemInEdit )
  326. break;
  327. if( DrawStruct == NULL )
  328. DrawStruct = LocateSmallestComponent( GetScreen() );
  329. if(DrawStruct)
  330. {
  331. EditComponentValue(
  332. (SCH_COMPONENT*) DrawStruct, DC );
  333. }
  334. break;
  335. case HK_EDIT_COMPONENT_FOOTPRINT:
  336. if( ItemInEdit )
  337. break;
  338. if( DrawStruct == NULL )
  339. DrawStruct = LocateSmallestComponent( GetScreen() );
  340. if(DrawStruct)
  341. {
  342. EditComponentFootprint(
  343. (SCH_COMPONENT*) DrawStruct, DC );
  344. }
  345. break;
  346. }
  347. if( RefreshToolBar )
  348. SetToolbars();
  349. }
  350. /***********************************************************/
  351. void WinEDA_LibeditFrame::OnHotKey( wxDC* DC, int hotkey,
  352. EDA_BaseStruct* DrawStruct )
  353. /***********************************************************/
  354. /* Hot keys for the component editor. Some commands are relatives to the item under the mouse cursor
  355. * Commands are case insensitive
  356. */
  357. {
  358. bool ItemInEdit = GetScreen()->GetCurItem()
  359. && GetScreen()->GetCurItem()->m_Flags;
  360. bool RefreshToolBar = FALSE; // We must refresh tool bar when the undo/redo tool state is modified
  361. if( hotkey == 0 )
  362. return;
  363. wxPoint MousePos = GetScreen()->m_MousePosition;
  364. LibEDA_BaseStruct* DrawEntry = LocateItemUsingCursor();
  365. // Remap the control key Ctrl A (0x01) to GR_KB_CTRL + 'A' (easier to handle...)
  366. if( (hotkey & GR_KB_CTRL) != 0 )
  367. hotkey += 'A' - 1;
  368. /* Convert lower to upper case (the usual toupper function has problem with non ascii codes like function keys */
  369. if( (hotkey >= 'a') && (hotkey <= 'z') )
  370. hotkey += 'A' - 'a';
  371. Ki_HotkeyInfo * HK_Descr = GetDescriptorFromHotkey( hotkey, s_Common_Hotkey_List );
  372. if( HK_Descr == NULL )
  373. HK_Descr = GetDescriptorFromHotkey( hotkey, s_LibEdit_Hotkey_List );
  374. if( HK_Descr == NULL ) return;
  375. switch( HK_Descr->m_Idcommand )
  376. {
  377. default:
  378. case HK_NOT_FOUND:
  379. return;
  380. break;
  381. case HK_HELP: // Display Current hotkey list
  382. DisplayHotkeyList( this, s_Libedit_Hokeys_Descr );
  383. break;
  384. case HK_RESET_LOCAL_COORD: /* Reset the relative coord */
  385. GetScreen()->m_O_Curseur = GetScreen()->m_Curseur;
  386. break;
  387. case HK_ZOOM_IN:
  388. OnZoom( ID_ZOOM_IN_KEY );
  389. break;
  390. case HK_ZOOM_OUT:
  391. OnZoom( ID_ZOOM_OUT_KEY );
  392. break;
  393. case HK_ZOOM_REDRAW:
  394. OnZoom( ID_ZOOM_REDRAW_KEY );
  395. break;
  396. case HK_ZOOM_CENTER:
  397. OnZoom( ID_ZOOM_CENTER_KEY );
  398. break;
  399. case HK_UNDO:
  400. case HK_REDO:
  401. if( ItemInEdit )
  402. break;
  403. {
  404. wxCommandEvent event( wxEVT_COMMAND_TOOL_CLICKED, HK_Descr->m_IdMenuEvent );
  405. wxPostEvent( this, event );
  406. }
  407. break;
  408. case HK_REPEAT_LAST:
  409. if( LibItemToRepeat && (LibItemToRepeat->m_Flags == 0)
  410. && (LibItemToRepeat->Type() == COMPONENT_PIN_DRAW_TYPE) )
  411. {
  412. RepeatPinItem( DC, (LibDrawPin*) LibItemToRepeat );
  413. }
  414. else
  415. wxBell();
  416. break;
  417. case HK_EDIT_PIN:
  418. if(DrawEntry)
  419. CurrentDrawItem = DrawEntry;
  420. if(CurrentDrawItem)
  421. {
  422. if(CurrentDrawItem->Type() == COMPONENT_PIN_DRAW_TYPE)
  423. InstallPineditFrame( this, DC, MousePos );
  424. }
  425. break;
  426. case HK_DELETE_PIN:
  427. if(DrawEntry)
  428. CurrentDrawItem = DrawEntry;
  429. if(CurrentDrawItem)
  430. {
  431. wxCommandEvent evt;
  432. evt.SetId(ID_POPUP_LIBEDIT_DELETE_ITEM);
  433. Process_Special_Functions(evt);
  434. }
  435. break;
  436. case HK_MOVE_PIN:
  437. if(DrawEntry)
  438. CurrentDrawItem = DrawEntry;
  439. if(CurrentDrawItem)
  440. {
  441. wxCommandEvent evt;
  442. evt.SetId(ID_POPUP_LIBEDIT_MOVE_ITEM_REQUEST);
  443. Process_Special_Functions(evt);
  444. }
  445. break;
  446. }
  447. if( RefreshToolBar )
  448. SetToolbars();
  449. }