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.

934 lines
32 KiB

11 years ago
11 years ago
11 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
  5. * Copyright (C) 2008 Wayne Stambaugh <stambaughw@verizon.net>
  6. * Copyright (C) 2004-2017 KiCad Developers, see AUTHORS.txt for contributors.
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License
  10. * as published by the Free Software Foundation; either version 2
  11. * of the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, you may find one here:
  20. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  21. * or you may search the http://www.gnu.org website for the version 2 license,
  22. * or you may write to the Free Software Foundation, Inc.,
  23. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  24. */
  25. /**
  26. * @file eeschema/hotkeys.cpp
  27. */
  28. #include <fctsys.h>
  29. #include <eeschema_id.h>
  30. #include <hotkeys.h>
  31. #include <sch_edit_frame.h>
  32. #include <class_drawpanel.h>
  33. #include <general.h>
  34. #include <lib_edit_frame.h>
  35. #include <viewlib_frame.h>
  36. #include <class_libentry.h>
  37. #include <sch_junction.h>
  38. #include <sch_line.h>
  39. #include <sch_component.h>
  40. #include <sch_sheet.h>
  41. #include <dialogs/dialog_schematic_find.h>
  42. // Remark: the hotkey message info is used as keyword in hotkey config files and
  43. // as comments in help windows, therefore translated only when displayed
  44. // they are marked _HKI to be extracted by translation tools
  45. // See hotkeys_basic.h for more info
  46. /* How to add a new hotkey:
  47. * add a new id in the enum hotkey_id_command like MY_NEW_ID_FUNCTION (see
  48. * hotkeys.h).
  49. * add a new EDA_HOTKEY entry like:
  50. * static EDA_HOTKEY HkMyNewEntry(_HKI("Command Label"), MY_NEW_ID_FUNCTION,
  51. * default key value);
  52. * _HKI("Command Label") is the name used in hotkey list display, and the
  53. * identifier in the hotkey list file
  54. * MY_NEW_ID_FUNCTION is an equivalent id function used in the switch in
  55. * OnHotKey() function.
  56. * default key value is the default hotkey for this command. Can be overridden
  57. * by the user hotkey list file
  58. * add the HkMyNewEntry pointer in the schematic_Hotkey_List list or the
  59. * libEdit_Hotkey_List list or common_Hotkey_List if the same command is
  60. * added both in Eeschema and libedit)
  61. * Add the new code in the switch in OnHotKey() function.
  62. * when the variable itemInEdit is true, an item is currently edited.
  63. * This can be useful if the new function cannot be executed while an item is
  64. * currently being edited
  65. * ( For example, one cannot start a new wire when a component is moving.)
  66. *
  67. * Note: If an hotkey is a special key be sure the corresponding wxWidget
  68. * keycode (WXK_XXXX) is handled in the hotkey_name_descr
  69. * s_Hotkey_Name_List list (see hotkeys_basic.cpp) and see this list
  70. * for some ascii keys (space ...)
  71. *
  72. * Key modifier are: GR_KB_CTRL GR_KB_ALT
  73. */
  74. // Common commands
  75. // Fit on Screen
  76. #if !defined( __WXMAC__ )
  77. static EDA_HOTKEY HkZoomAuto( _HKI( "Fit on Screen" ), HK_ZOOM_AUTO, WXK_HOME, ID_ZOOM_PAGE );
  78. #else
  79. static EDA_HOTKEY HkZoomAuto( _HKI( "Zoom Auto" ), HK_ZOOM_AUTO, GR_KB_CTRL + '0',
  80. ID_ZOOM_PAGE );
  81. #endif
  82. static EDA_HOTKEY HkZoomCenter( _HKI( "Zoom Center" ), HK_ZOOM_CENTER, WXK_F4,
  83. ID_POPUP_ZOOM_CENTER );
  84. // Refresh Screen
  85. #if !defined( __WXMAC__ )
  86. static EDA_HOTKEY HkZoomRedraw( _HKI( "Zoom Redraw" ), HK_ZOOM_REDRAW, WXK_F3, ID_ZOOM_REDRAW );
  87. #else
  88. static EDA_HOTKEY HkZoomRedraw( _HKI( "Zoom Redraw" ), HK_ZOOM_REDRAW, GR_KB_CTRL + 'R',
  89. ID_ZOOM_REDRAW );
  90. #endif
  91. // Zoom In
  92. #if !defined( __WXMAC__ )
  93. static EDA_HOTKEY HkZoomIn( _HKI( "Zoom In" ), HK_ZOOM_IN, WXK_F1, ID_KEY_ZOOM_IN );
  94. #else
  95. static EDA_HOTKEY HkZoomIn( _HKI( "Zoom In" ), HK_ZOOM_IN, GR_KB_CTRL + '+', ID_KEY_ZOOM_IN );
  96. #endif
  97. // Zoom Out
  98. #if !defined( __WXMAC__ )
  99. static EDA_HOTKEY HkZoomOut( _HKI( "Zoom Out" ), HK_ZOOM_OUT, WXK_F2, ID_KEY_ZOOM_OUT );
  100. #else
  101. static EDA_HOTKEY HkZoomOut( _HKI( "Zoom Out" ), HK_ZOOM_OUT, GR_KB_CTRL + '-', ID_KEY_ZOOM_OUT );
  102. #endif
  103. static EDA_HOTKEY HkHelp( _HKI( "Help (this window)" ), HK_HELP, '?' );
  104. static EDA_HOTKEY HkResetLocalCoord( _HKI( "Reset Local Coordinates" ), HK_RESET_LOCAL_COORD, ' ' );
  105. static EDA_HOTKEY HkLeaveSheet( _HKI( "Leave Sheet" ), HK_LEAVE_SHEET, GR_KB_ALT + WXK_BACK,
  106. ID_POPUP_SCH_LEAVE_SHEET );
  107. // Undo
  108. static EDA_HOTKEY HkUndo( _HKI( "Undo" ), HK_UNDO, GR_KB_CTRL + 'Z', (int) wxID_UNDO );
  109. // Redo
  110. #if !defined( __WXMAC__ )
  111. static EDA_HOTKEY HkRedo( _HKI( "Redo" ), HK_REDO, GR_KB_CTRL + 'Y', (int) wxID_REDO );
  112. #else
  113. static EDA_HOTKEY HkRedo( _HKI( "Redo" ), HK_REDO, GR_KB_SHIFT + GR_KB_CTRL + 'Z',
  114. (int) wxID_REDO );
  115. #endif
  116. // mouse click command:
  117. static EDA_HOTKEY HkMouseLeftClick( _HKI( "Mouse Left Click" ), HK_LEFT_CLICK, WXK_RETURN, 0 );
  118. static EDA_HOTKEY HkMouseLeftDClick( _HKI( "Mouse Left Double Click" ), HK_LEFT_DCLICK, WXK_END, 0 );
  119. // Schematic editor
  120. static EDA_HOTKEY HkBeginWire( _HKI( "Begin Wire" ), HK_BEGIN_WIRE, 'W', ID_WIRE_BUTT );
  121. static EDA_HOTKEY HkBeginBus( _HKI( "Begin Bus" ), HK_BEGIN_BUS, 'B', ID_BUS_BUTT );
  122. static EDA_HOTKEY HkEndLineWireBus( _HKI( "End Line Wire Bus" ), HK_END_CURR_LINEWIREBUS, 'K',
  123. ID_POPUP_END_LINE );
  124. static EDA_HOTKEY HkAddLabel( _HKI( "Add Label" ), HK_ADD_LABEL, 'L', ID_LABEL_BUTT );
  125. static EDA_HOTKEY HkAddHierarchicalLabel( _HKI( "Add Hierarchical Label" ), HK_ADD_HLABEL, 'H',
  126. ID_HIERLABEL_BUTT );
  127. static EDA_HOTKEY HkAddGlobalLabel( _HKI( "Add Global Label" ), HK_ADD_GLABEL, GR_KB_CTRL + 'H',
  128. ID_GLABEL_BUTT );
  129. static EDA_HOTKEY HkAddJunction( _HKI( "Add Junction" ), HK_ADD_JUNCTION, 'J', ID_JUNCTION_BUTT );
  130. static EDA_HOTKEY HkAddComponent( _HKI( "Add Symbol" ), HK_ADD_NEW_COMPONENT, 'A',
  131. ID_SCH_PLACE_COMPONENT );
  132. static EDA_HOTKEY HkAddPower( _HKI( "Add Power" ), HK_ADD_NEW_POWER, 'P',
  133. ID_PLACE_POWER_BUTT );
  134. static EDA_HOTKEY HkAddNoConn( _HKI( "Add No Connect Flag" ), HK_ADD_NOCONN_FLAG, 'Q',
  135. ID_NOCONN_BUTT );
  136. static EDA_HOTKEY HkAddHierSheet( _HKI( "Add Sheet" ), HK_ADD_HIER_SHEET, 'S',
  137. ID_SHEET_SYMBOL_BUTT );
  138. static EDA_HOTKEY HkAddBusEntry( _HKI( "Add Bus Entry" ), HK_ADD_BUS_ENTRY, '/',
  139. ID_BUSTOBUS_ENTRY_BUTT );
  140. static EDA_HOTKEY HkAddWireEntry( _HKI( "Add Wire Entry" ), HK_ADD_WIRE_ENTRY, 'Z',
  141. ID_WIRETOBUS_ENTRY_BUTT );
  142. static EDA_HOTKEY HkAddGraphicPolyLine( _HKI( "Add Graphic PolyLine" ), HK_ADD_GRAPHIC_POLYLINE,
  143. 'I', ID_LINE_COMMENT_BUTT );
  144. static EDA_HOTKEY HkAddGraphicText( _HKI( "Add Graphic Text" ), HK_ADD_GRAPHIC_TEXT, 'T',
  145. ID_TEXT_COMMENT_BUTT );
  146. static EDA_HOTKEY HkMirrorY( _HKI( "Mirror Y" ), HK_MIRROR_Y, 'Y',
  147. ID_SCH_MIRROR_Y );
  148. static EDA_HOTKEY HkMirrorX( _HKI( "Mirror X" ), HK_MIRROR_X, 'X',
  149. ID_SCH_MIRROR_X );
  150. static EDA_HOTKEY HkOrientNormalComponent( _HKI( "Orient Normal Component" ),
  151. HK_ORIENT_NORMAL_COMPONENT, 'N', ID_SCH_ORIENT_NORMAL );
  152. static EDA_HOTKEY HkRotate( _HKI( "Rotate Item" ), HK_ROTATE, 'R', ID_SCH_ROTATE_CLOCKWISE );
  153. static EDA_HOTKEY HkEdit( _HKI( "Edit Item" ), HK_EDIT, 'E', ID_SCH_EDIT_ITEM );
  154. static EDA_HOTKEY HkEditComponentValue( _HKI( "Edit Symbol Value" ),
  155. HK_EDIT_COMPONENT_VALUE, 'V',
  156. ID_SCH_EDIT_COMPONENT_VALUE );
  157. static EDA_HOTKEY HkEditComponentReference( _HKI( "Edit Symbol Reference" ),
  158. HK_EDIT_COMPONENT_REFERENCE, 'U',
  159. ID_SCH_EDIT_COMPONENT_REFERENCE );
  160. static EDA_HOTKEY HkEditComponentFootprint( _HKI( "Edit Symbol Footprint" ),
  161. HK_EDIT_COMPONENT_FOOTPRINT, 'F',
  162. ID_SCH_EDIT_COMPONENT_FOOTPRINT );
  163. static EDA_HOTKEY HkEditComponentWithLibedit( _HKI( "Edit with Symbol Editor" ),
  164. HK_EDIT_COMPONENT_WITH_LIBEDIT,
  165. 'E' + GR_KB_CTRL,
  166. ID_POPUP_SCH_CALL_LIBEDIT_AND_LOAD_CMP );
  167. static EDA_HOTKEY HkMove( _HKI( "Move Schematic Item" ),
  168. HK_MOVE_COMPONENT_OR_ITEM, 'M',
  169. ID_SCH_MOVE_ITEM );
  170. static EDA_HOTKEY HkDuplicateItem( _HKI( "Duplicate Symbol or Label" ),
  171. HK_DUPLICATE_ITEM, 'C',
  172. ID_POPUP_SCH_DUPLICATE_ITEM );
  173. static EDA_HOTKEY HkDrag( _HKI( "Drag Item" ), HK_DRAG, 'G', ID_SCH_DRAG_ITEM );
  174. static EDA_HOTKEY HkCopyBlock( _HKI( "Copy Block" ), HK_COPY_BLOCK, 'C' + GR_KB_CTRL, wxID_COPY );
  175. static EDA_HOTKEY HkPasteBlock( _HKI( "Paste Block" ), HK_PASTE_BLOCK, 'V' + GR_KB_CTRL, wxID_PASTE );
  176. static EDA_HOTKEY HkCutBlock( _HKI( "Cut Block" ), HK_CUT_BLOCK, 'X' + GR_KB_CTRL, wxID_CUT );
  177. static EDA_HOTKEY HkMove2Drag( _HKI( "Move Block -> Drag Block" ),
  178. HK_MOVEBLOCK_TO_DRAGBLOCK, '\t', ID_POPUP_DRAG_BLOCK );
  179. static EDA_HOTKEY HkInsert( _HKI( "Repeat Last Item" ), HK_REPEAT_LAST, WXK_INSERT );
  180. static EDA_HOTKEY HkDelete( _HKI( "Delete Item" ), HK_DELETE, WXK_DELETE );
  181. static EDA_HOTKEY HkDeleteNode( _HKI( "Delete Node" ), HK_DELETE_NODE, WXK_BACK,
  182. ID_POPUP_SCH_DELETE_NODE );
  183. static EDA_HOTKEY HkFindItem( _HKI( "Find Item" ), HK_FIND_ITEM, 'F' + GR_KB_CTRL, ID_FIND_ITEMS );
  184. static EDA_HOTKEY HkFindNextItem( _HKI( "Find Next Item" ), HK_FIND_NEXT_ITEM, WXK_F5,
  185. wxEVT_COMMAND_FIND );
  186. static EDA_HOTKEY HkFindReplace( _HKI( "Find and Replace" ), HK_FIND_REPLACE,
  187. 'F' + GR_KB_CTRL + GR_KB_ALT, wxID_REPLACE );
  188. static EDA_HOTKEY HkFindNextDrcMarker( _HKI( "Find Next DRC Marker" ), HK_FIND_NEXT_DRC_MARKER,
  189. WXK_F5 + GR_KB_SHIFT, EVT_COMMAND_FIND_DRC_MARKER );
  190. static EDA_HOTKEY HkZoomSelection( _HKI( "Zoom to Selection" ), HK_ZOOM_SELECTION, '@', ID_ZOOM_SELECTION );
  191. // Special keys for library editor:
  192. static EDA_HOTKEY HkCreatePin( _HKI( "Create Pin" ), HK_LIBEDIT_CREATE_PIN, 'P' );
  193. static EDA_HOTKEY HkInsertPin( _HKI( "Repeat Pin" ), HK_REPEAT_LAST, WXK_INSERT );
  194. static EDA_HOTKEY HkMoveLibItem( _HKI( "Move Library Item" ), HK_LIBEDIT_MOVE_GRAPHIC_ITEM, 'M' );
  195. // Load/save files
  196. static EDA_HOTKEY HkSaveAllLib( _HKI( "Save All Libraries" ), HK_SAVE_ALL_LIBS, 'S' + GR_KB_CTRL, ID_LIBEDIT_SAVE_ALL_LIBS );
  197. static EDA_HOTKEY HkSaveSchematic( _HKI( "Save Schematic" ), HK_SAVE_SCH, 'S' + GR_KB_CTRL );
  198. static EDA_HOTKEY HkLoadSchematic( _HKI( "Load Schematic" ), HK_LOAD_SCH, 'L' + GR_KB_CTRL );
  199. // Autoplace fields
  200. static EDA_HOTKEY HkAutoplaceFields( _HKI( "Autoplace Fields" ), HK_AUTOPLACE_FIELDS, 'O',
  201. ID_AUTOPLACE_FIELDS );
  202. static EDA_HOTKEY HkUpdatePcbFromSch( _HKI( "Update PCB from Schematic" ), HK_UPDATE_PCB_FROM_SCH,
  203. WXK_F8 );
  204. // Higtlight connection
  205. static EDA_HOTKEY HkHighlightConnection( _HKI( "Highlight Connection" ), ID_HOTKEY_HIGHLIGHT,
  206. 'B' + GR_KB_CTRL );
  207. // List of common hotkey descriptors
  208. static EDA_HOTKEY* common_Hotkey_List[] =
  209. {
  210. &HkHelp,
  211. &HkZoomIn,
  212. &HkZoomOut,
  213. &HkZoomRedraw,
  214. &HkZoomCenter,
  215. &HkZoomAuto,
  216. &HkZoomSelection,
  217. &HkResetLocalCoord,
  218. &HkEdit,
  219. &HkDelete,
  220. &HkRotate,
  221. &HkDrag,
  222. &HkUndo,
  223. &HkRedo,
  224. &HkMouseLeftClick,
  225. &HkMouseLeftDClick,
  226. NULL
  227. };
  228. // List of common hotkey descriptors, for the library vierwer
  229. static EDA_HOTKEY* common_basic_Hotkey_List[] =
  230. {
  231. &HkHelp,
  232. &HkZoomIn,
  233. &HkZoomOut,
  234. &HkZoomRedraw,
  235. &HkZoomCenter,
  236. &HkZoomAuto,
  237. &HkResetLocalCoord,
  238. &HkMouseLeftClick,
  239. &HkMouseLeftDClick,
  240. NULL
  241. };
  242. // List of hotkey descriptors for schematic
  243. static EDA_HOTKEY* schematic_Hotkey_List[] =
  244. {
  245. &HkSaveSchematic,
  246. &HkLoadSchematic,
  247. &HkFindItem,
  248. &HkFindNextItem,
  249. &HkFindNextDrcMarker,
  250. &HkFindReplace,
  251. &HkInsert,
  252. &HkMove2Drag,
  253. &HkCopyBlock,
  254. &HkPasteBlock,
  255. &HkCutBlock,
  256. &HkMove,
  257. &HkDuplicateItem,
  258. &HkAddComponent,
  259. &HkAddPower,
  260. &HkMirrorX,
  261. &HkMirrorY,
  262. &HkOrientNormalComponent,
  263. &HkEditComponentValue,
  264. &HkEditComponentReference,
  265. &HkEditComponentFootprint,
  266. &HkEditComponentWithLibedit,
  267. &HkBeginWire,
  268. &HkBeginBus,
  269. &HkEndLineWireBus,
  270. &HkAddLabel,
  271. &HkAddHierarchicalLabel,
  272. &HkAddGlobalLabel,
  273. &HkAddJunction,
  274. &HkAddNoConn,
  275. &HkAddHierSheet,
  276. &HkAddWireEntry,
  277. &HkAddBusEntry,
  278. &HkAddGraphicPolyLine,
  279. &HkAddGraphicText,
  280. &HkUpdatePcbFromSch,
  281. &HkAutoplaceFields,
  282. &HkLeaveSheet,
  283. &HkDeleteNode,
  284. &HkHighlightConnection,
  285. NULL
  286. };
  287. // List of hotkey descriptors for library editor
  288. static EDA_HOTKEY* libEdit_Hotkey_List[] =
  289. {
  290. &HkSaveAllLib,
  291. &HkCreatePin,
  292. &HkInsertPin,
  293. &HkMoveLibItem,
  294. &HkMirrorX,
  295. &HkMirrorY,
  296. &HkCopyBlock,
  297. &HkPasteBlock,
  298. &HkCutBlock,
  299. NULL
  300. };
  301. // List of hotkey descriptors for library viewer (currently empty
  302. static EDA_HOTKEY* viewlib_Hotkey_List[] =
  303. {
  304. NULL
  305. };
  306. // Keyword Identifiers (tags) in key code configuration file (section names)
  307. // (.m_SectionTag member of a EDA_HOTKEY_CONFIG)
  308. static wxString schematicSectionTag( wxT( "[eeschema]" ) );
  309. static wxString libEditSectionTag( wxT( "[libedit]" ) );
  310. // Titles for hotkey editor and hotkey display
  311. static wxString commonSectionTitle( _HKI( "Common" ) );
  312. static wxString schematicSectionTitle( _HKI( "Schematic Editor" ) );
  313. static wxString libEditSectionTitle( _HKI( "Library Editor" ) );
  314. // list of sections and corresponding hotkey list for Eeschema (used to create
  315. // an hotkey config file)
  316. struct EDA_HOTKEY_CONFIG g_Eeschema_Hokeys_Descr[] =
  317. {
  318. { &g_CommonSectionTag, common_Hotkey_List, &commonSectionTitle },
  319. { &schematicSectionTag, schematic_Hotkey_List, &schematicSectionTitle },
  320. { &libEditSectionTag, libEdit_Hotkey_List, &libEditSectionTitle },
  321. { NULL, NULL, NULL }
  322. };
  323. // list of sections and corresponding hotkey list for the schematic editor
  324. // (used to list current hotkeys)
  325. struct EDA_HOTKEY_CONFIG g_Schematic_Hokeys_Descr[] =
  326. {
  327. { &g_CommonSectionTag, common_Hotkey_List, &commonSectionTitle },
  328. { &schematicSectionTag, schematic_Hotkey_List, &schematicSectionTitle },
  329. { NULL, NULL, NULL }
  330. };
  331. // list of sections and corresponding hotkey list for the component editor
  332. // (used to list current hotkeys)
  333. struct EDA_HOTKEY_CONFIG g_Libedit_Hokeys_Descr[] =
  334. {
  335. { &g_CommonSectionTag, common_Hotkey_List, &commonSectionTitle },
  336. { &libEditSectionTag, libEdit_Hotkey_List, &libEditSectionTitle },
  337. { NULL, NULL, NULL }
  338. };
  339. // list of sections and corresponding hotkey list for the component browser
  340. // (used to list current hotkeys)
  341. struct EDA_HOTKEY_CONFIG g_Viewlib_Hokeys_Descr[] =
  342. {
  343. { &g_CommonSectionTag, common_basic_Hotkey_List, &commonSectionTitle },
  344. { NULL, NULL, NULL }
  345. };
  346. EDA_HOTKEY* SCH_EDIT_FRAME::GetHotKeyDescription( int aCommand ) const
  347. {
  348. EDA_HOTKEY* HK_Descr = GetDescriptorFromCommand( aCommand, common_Hotkey_List );
  349. if( HK_Descr == NULL )
  350. HK_Descr = GetDescriptorFromCommand( aCommand, schematic_Hotkey_List );
  351. return HK_Descr;
  352. }
  353. /*
  354. * Hot keys. Some commands are relative to the item under the mouse cursor
  355. * Commands are case insensitive
  356. */
  357. bool SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition, EDA_ITEM* aItem )
  358. {
  359. if( aHotKey == 0 )
  360. return false;
  361. wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED );
  362. SCH_SCREEN* screen = GetScreen();
  363. // itemInEdit == false means no item currently edited. We can ask for editing a new item
  364. bool itemInEdit = screen->GetCurItem() && screen->GetCurItem()->GetFlags();
  365. // blocInProgress == false means no block in progress.
  366. // Because a drag command uses a drag block, false means also no drag in progress
  367. // If false, we can ask for editing a new item
  368. bool blocInProgress = screen->m_BlockLocate.GetState() != STATE_NO_BLOCK;
  369. // notBusy == true means no item currently edited and no other command in progress
  370. // We can change active tool and ask for editing a new item
  371. bool notBusy = (!itemInEdit) && (!blocInProgress);
  372. /* Convert lower to upper case (the usual toupper function has problem
  373. * with non ascii codes like function keys */
  374. if( (aHotKey >= 'a') && (aHotKey <= 'z') )
  375. aHotKey += 'A' - 'a';
  376. // Search command from key :
  377. EDA_HOTKEY* hotKey = GetDescriptorFromHotkey( aHotKey, common_Hotkey_List );
  378. if( hotKey == NULL )
  379. hotKey = GetDescriptorFromHotkey( aHotKey, schematic_Hotkey_List );
  380. if( hotKey == NULL )
  381. return false;
  382. switch( hotKey->m_Idcommand )
  383. {
  384. default:
  385. case HK_NOT_FOUND:
  386. return false;
  387. case HK_HELP: // Display Current hotkey list
  388. DisplayHotkeyList( this, g_Schematic_Hokeys_Descr );
  389. break;
  390. case HK_RESET_LOCAL_COORD: // Reset the relative coord
  391. GetScreen()->m_O_Curseur = GetCrossHairPosition();
  392. break;
  393. case ID_HOTKEY_HIGHLIGHT:
  394. if( notBusy )
  395. HighlightConnectionAtPosition( GetCrossHairPosition() );
  396. break;
  397. case HK_LEFT_CLICK:
  398. case HK_LEFT_DCLICK: // Simulate a double left click: generate 2 events
  399. if( screen->m_BlockLocate.GetState() == STATE_BLOCK_MOVE )
  400. {
  401. GetCanvas()->SetAutoPanRequest( false );
  402. HandleBlockPlace( aDC );
  403. }
  404. else if( screen->m_BlockLocate.GetState() == STATE_NO_BLOCK )
  405. {
  406. OnLeftClick( aDC, aPosition );
  407. if( hotKey->m_Idcommand == HK_LEFT_DCLICK )
  408. OnLeftDClick( aDC, aPosition );
  409. }
  410. break;
  411. case HK_ZOOM_IN:
  412. case HK_ZOOM_OUT:
  413. case HK_ZOOM_REDRAW:
  414. case HK_ZOOM_CENTER:
  415. case HK_ZOOM_AUTO:
  416. case HK_ZOOM_SELECTION:
  417. case HK_MOVEBLOCK_TO_DRAGBLOCK: // Switch to drag mode, when block moving
  418. case HK_PASTE_BLOCK:
  419. case HK_COPY_BLOCK: // Copy block to paste buffer.
  420. case HK_CUT_BLOCK:
  421. cmd.SetId( hotKey->m_IdMenuEvent );
  422. GetEventHandler()->ProcessEvent( cmd );
  423. break;
  424. case HK_DELETE:
  425. if( blocInProgress )
  426. {
  427. cmd.SetId( ID_POPUP_DELETE_BLOCK );
  428. GetEventHandler()->ProcessEvent( cmd );
  429. }
  430. else if( notBusy )
  431. DeleteItemAtCrossHair( aDC );
  432. break;
  433. case HK_REPEAT_LAST:
  434. if( notBusy )
  435. RepeatDrawItem( aDC );
  436. break;
  437. case HK_END_CURR_LINEWIREBUS:
  438. // this key terminates a new line/bus/wire in progress
  439. if( aItem && aItem->IsNew() &&
  440. aItem->Type() == SCH_LINE_T )
  441. {
  442. cmd.SetId( hotKey->m_IdMenuEvent );
  443. GetEventHandler()->ProcessEvent( cmd );
  444. }
  445. break;
  446. case HK_UNDO: // Hot keys that map to command IDs that cannot be called
  447. case HK_REDO: // while busy performing another command.
  448. case HK_FIND_ITEM:
  449. case HK_FIND_REPLACE:
  450. case HK_DELETE_NODE:
  451. case HK_LEAVE_SHEET:
  452. if( notBusy )
  453. {
  454. cmd.SetId( hotKey->m_IdMenuEvent );
  455. GetEventHandler()->ProcessEvent( cmd );
  456. }
  457. break;
  458. case HK_FIND_NEXT_ITEM:
  459. case HK_FIND_NEXT_DRC_MARKER:
  460. if( notBusy )
  461. {
  462. wxFindDialogEvent event( hotKey->m_IdMenuEvent, GetId() );
  463. event.SetEventObject( this );
  464. event.SetFlags( m_findReplaceData->GetFlags() );
  465. event.SetFindString( m_findReplaceData->GetFindString() );
  466. GetEventHandler()->ProcessEvent( event );
  467. }
  468. break;
  469. case HK_ADD_NEW_COMPONENT: // Add component
  470. case HK_ADD_NEW_POWER: // Add power component
  471. case HK_ADD_LABEL:
  472. case HK_ADD_HLABEL:
  473. case HK_ADD_GLABEL:
  474. case HK_ADD_JUNCTION:
  475. case HK_ADD_WIRE_ENTRY:
  476. case HK_ADD_BUS_ENTRY:
  477. case HK_ADD_HIER_SHEET:
  478. case HK_ADD_GRAPHIC_TEXT:
  479. case HK_ADD_GRAPHIC_POLYLINE:
  480. case HK_ADD_NOCONN_FLAG: // Add a no connected flag
  481. case HK_BEGIN_BUS:
  482. case HK_BEGIN_WIRE:
  483. if( notBusy )
  484. {
  485. EDA_HOTKEY_CLIENT_DATA data( aPosition );
  486. cmd.SetInt( aHotKey );
  487. cmd.SetClientObject( &data );
  488. cmd.SetId( hotKey->m_IdMenuEvent );
  489. GetEventHandler()->ProcessEvent( cmd );
  490. }
  491. else if( aItem && aItem->IsNew() )
  492. {
  493. // If the item is a bus or a wire, a begin command is not possible.
  494. if( (GetToolId() == ID_BUS_BUTT) && (aItem->Type() == SCH_LINE_T) )
  495. {
  496. SCH_LINE* segment = (SCH_LINE*) aItem;
  497. if( segment->GetLayer() != LAYER_BUS )
  498. break;
  499. // Bus in progress:
  500. OnLeftClick( aDC, aPosition );
  501. }
  502. else if( (GetToolId() == ID_WIRE_BUTT ) && (aItem->Type() == SCH_LINE_T) )
  503. {
  504. SCH_LINE* segment = (SCH_LINE*) aItem;
  505. if( segment->GetLayer() != LAYER_WIRE )
  506. break;
  507. // Wire in progress:
  508. OnLeftClick( aDC, aPosition );
  509. }
  510. }
  511. break;
  512. case HK_DUPLICATE_ITEM: // Duplicate component or text/label
  513. if( itemInEdit )
  514. break;
  515. if( aItem == NULL )
  516. {
  517. aItem = LocateAndShowItem( aPosition, SCH_COLLECTOR::CopyableItems );
  518. if( aItem == NULL )
  519. break;
  520. }
  521. cmd.SetId( hotKey->m_IdMenuEvent );
  522. wxPostEvent( this, cmd );
  523. break;
  524. case HK_DRAG: // Start drag
  525. case HK_MOVE_COMPONENT_OR_ITEM: // Start move schematic item.
  526. if( ! notBusy )
  527. break;
  528. // Fall through
  529. case HK_EDIT:
  530. // Edit schematic item. Do not allow sheet edition when mowing
  531. // Because a sheet edition can be complex.
  532. if( itemInEdit && screen->GetCurItem()->Type() == SCH_SHEET_T )
  533. break;
  534. // Fall through
  535. case HK_EDIT_COMPONENT_VALUE: // Edit component value field.
  536. case HK_EDIT_COMPONENT_REFERENCE: // Edit component value reference.
  537. case HK_EDIT_COMPONENT_FOOTPRINT: // Edit component footprint field.
  538. case HK_MIRROR_Y: // Mirror Y
  539. case HK_MIRROR_X: // Mirror X
  540. case HK_ORIENT_NORMAL_COMPONENT: // Orient 0, no mirror (Component)
  541. case HK_ROTATE: // Rotate schematic item.
  542. case HK_EDIT_COMPONENT_WITH_LIBEDIT: // Call Libedit and load the current component
  543. case HK_AUTOPLACE_FIELDS: // Autoplace all fields around component
  544. {
  545. // force a new item search on hot keys at current position,
  546. // if there is no currently edited item,
  547. // to avoid using a previously selected item
  548. if( ! itemInEdit )
  549. screen->SetCurItem( NULL );
  550. EDA_HOTKEY_CLIENT_DATA data( aPosition );
  551. cmd.SetInt( hotKey->m_Idcommand );
  552. cmd.SetClientObject( &data );
  553. cmd.SetId( hotKey->m_IdMenuEvent );
  554. GetEventHandler()->ProcessEvent( cmd );
  555. }
  556. break;
  557. }
  558. // Hot key handled.
  559. return true;
  560. }
  561. EDA_HOTKEY* LIB_EDIT_FRAME::GetHotKeyDescription( int aCommand ) const
  562. {
  563. EDA_HOTKEY* HK_Descr = GetDescriptorFromCommand( aCommand, common_Hotkey_List );
  564. if( HK_Descr == NULL )
  565. HK_Descr = GetDescriptorFromCommand( aCommand, libEdit_Hotkey_List );
  566. return HK_Descr;
  567. }
  568. bool LIB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition, EDA_ITEM* aItem )
  569. {
  570. if( aHotKey == 0 )
  571. return false;
  572. wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED );
  573. cmd.SetEventObject( this );
  574. /* Convert lower to upper case (the usual toupper function has problem
  575. * with non ascii codes like function keys */
  576. if( (aHotKey >= 'a') && (aHotKey <= 'z') )
  577. aHotKey += 'A' - 'a';
  578. EDA_HOTKEY* hotKey = GetDescriptorFromHotkey( aHotKey, common_Hotkey_List );
  579. if( hotKey == NULL )
  580. hotKey = GetDescriptorFromHotkey( aHotKey, libEdit_Hotkey_List );
  581. if( hotKey == NULL )
  582. return false;
  583. // itemInEdit == false means no item currently edited. We can ask for editing a new item
  584. bool itemInEdit = IsEditingDrawItem();
  585. bool blocInProgress = GetScreen()->m_BlockLocate.GetState() != STATE_NO_BLOCK;
  586. switch( hotKey->m_Idcommand )
  587. {
  588. default:
  589. case HK_NOT_FOUND:
  590. return false;
  591. case HK_HELP: // Display Current hotkey list
  592. DisplayHotkeyList( this, g_Libedit_Hokeys_Descr );
  593. break;
  594. case HK_RESET_LOCAL_COORD: // Reset the relative coord
  595. GetScreen()->m_O_Curseur = GetCrossHairPosition();
  596. break;
  597. case HK_LEFT_CLICK:
  598. OnLeftClick( aDC, aPosition );
  599. break;
  600. case HK_LEFT_DCLICK: // Simulate a double left click: generate 2 events
  601. OnLeftClick( aDC, aPosition );
  602. OnLeftDClick( aDC, aPosition );
  603. break;
  604. case HK_ZOOM_IN:
  605. case HK_ZOOM_OUT:
  606. case HK_ZOOM_REDRAW:
  607. case HK_ZOOM_CENTER:
  608. case HK_ZOOM_AUTO:
  609. case HK_PASTE_BLOCK:
  610. case HK_COPY_BLOCK:
  611. case HK_CUT_BLOCK:
  612. cmd.SetId( hotKey->m_IdMenuEvent );
  613. GetEventHandler()->ProcessEvent( cmd );
  614. break;
  615. case HK_UNDO:
  616. case HK_REDO:
  617. if( !itemInEdit )
  618. {
  619. cmd.SetId( hotKey->m_IdMenuEvent );
  620. GetEventHandler()->ProcessEvent( cmd );
  621. }
  622. break;
  623. case HK_REPEAT_LAST:
  624. if( ! itemInEdit )
  625. {
  626. if( m_lastDrawItem && !m_lastDrawItem->InEditMode() &&
  627. ( m_lastDrawItem->Type() == LIB_PIN_T ) )
  628. RepeatPinItem( aDC, (LIB_PIN*) m_lastDrawItem );
  629. }
  630. break;
  631. case HK_EDIT:
  632. if ( !itemInEdit )
  633. SetDrawItem( LocateItemUsingCursor( aPosition ) );
  634. if( GetDrawItem() )
  635. {
  636. switch( GetDrawItem()->Type() )
  637. {
  638. case LIB_PIN_T:
  639. cmd.SetId( ID_LIBEDIT_EDIT_PIN );
  640. GetEventHandler()->ProcessEvent( cmd );
  641. break;
  642. case LIB_ARC_T:
  643. case LIB_CIRCLE_T:
  644. case LIB_RECTANGLE_T:
  645. case LIB_POLYLINE_T:
  646. case LIB_TEXT_T:
  647. cmd.SetId( ID_POPUP_LIBEDIT_BODY_EDIT_ITEM );
  648. GetEventHandler()->ProcessEvent( cmd );
  649. break;
  650. case LIB_FIELD_T:
  651. cmd.SetId( ID_POPUP_LIBEDIT_FIELD_EDIT_ITEM );
  652. GetEventHandler()->ProcessEvent( cmd );
  653. break;
  654. default:
  655. break;
  656. }
  657. }
  658. break;
  659. case HK_ROTATE:
  660. if( blocInProgress )
  661. {
  662. GetScreen()->m_BlockLocate.SetCommand( BLOCK_ROTATE );
  663. HandleBlockPlace( aDC );
  664. }
  665. else
  666. {
  667. if ( !itemInEdit )
  668. SetDrawItem( LocateItemUsingCursor( aPosition ) );
  669. if( GetDrawItem() )
  670. {
  671. cmd.SetId( ID_LIBEDIT_ROTATE_ITEM );
  672. GetEventHandler()->ProcessEvent( cmd );
  673. }
  674. }
  675. break;
  676. case HK_LIBEDIT_CREATE_PIN:
  677. if( ! itemInEdit )
  678. {
  679. SetToolID( ID_LIBEDIT_PIN_BUTT, wxCURSOR_PENCIL, _( "Add Pin" ) );
  680. OnLeftClick( aDC, aPosition );
  681. }
  682. break;
  683. case HK_DELETE:
  684. if ( !itemInEdit )
  685. SetDrawItem( LocateItemUsingCursor( aPosition ) );
  686. if( GetDrawItem() )
  687. {
  688. cmd.SetId( ID_POPUP_LIBEDIT_DELETE_ITEM );
  689. Process_Special_Functions( cmd );
  690. }
  691. break;
  692. case HK_LIBEDIT_MOVE_GRAPHIC_ITEM:
  693. if( !itemInEdit )
  694. {
  695. SetDrawItem( LocateItemUsingCursor( aPosition ) );
  696. if( GetDrawItem() )
  697. {
  698. cmd.SetId( ID_POPUP_LIBEDIT_MOVE_ITEM_REQUEST );
  699. Process_Special_Functions( cmd );
  700. }
  701. }
  702. break;
  703. case HK_DRAG:
  704. if( !itemInEdit )
  705. {
  706. SetDrawItem( LocateItemUsingCursor( aPosition ) );
  707. if( GetDrawItem() )
  708. {
  709. cmd.SetId( ID_POPUP_LIBEDIT_MODIFY_ITEM );
  710. Process_Special_Functions( cmd );
  711. }
  712. }
  713. break;
  714. case HK_MIRROR_Y: // Mirror Y
  715. if( !itemInEdit )
  716. SetDrawItem( LocateItemUsingCursor( aPosition ) );
  717. cmd.SetId( ID_LIBEDIT_MIRROR_Y );
  718. GetEventHandler()->ProcessEvent( cmd );
  719. break;
  720. case HK_MIRROR_X: // Mirror X
  721. if( !itemInEdit )
  722. SetDrawItem( LocateItemUsingCursor( aPosition ) );
  723. cmd.SetId( ID_LIBEDIT_MIRROR_X );
  724. GetEventHandler()->ProcessEvent( cmd );
  725. break;
  726. }
  727. // Hot key handled.
  728. return true;
  729. }
  730. EDA_HOTKEY* LIB_VIEW_FRAME::GetHotKeyDescription( int aCommand ) const
  731. {
  732. EDA_HOTKEY* HK_Descr = GetDescriptorFromCommand( aCommand, common_Hotkey_List );
  733. if( HK_Descr == NULL )
  734. HK_Descr = GetDescriptorFromCommand( aCommand, viewlib_Hotkey_List );
  735. return HK_Descr;
  736. }
  737. bool LIB_VIEW_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition, EDA_ITEM* aItem )
  738. {
  739. if( aHotKey == 0 )
  740. return false;
  741. wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED );
  742. cmd.SetEventObject( this );
  743. /* Convert lower to upper case (the usual toupper function has problem with non ascii
  744. * codes like function keys */
  745. if( (aHotKey >= 'a') && (aHotKey <= 'z') )
  746. aHotKey += 'A' - 'a';
  747. EDA_HOTKEY* HK_Descr = GetDescriptorFromHotkey( aHotKey, common_basic_Hotkey_List );
  748. if( HK_Descr == NULL )
  749. HK_Descr = GetDescriptorFromHotkey( aHotKey, viewlib_Hotkey_List );
  750. if( HK_Descr == NULL )
  751. return false;
  752. switch( HK_Descr->m_Idcommand )
  753. {
  754. default:
  755. case HK_NOT_FOUND:
  756. return false;
  757. case HK_HELP: // Display Current hotkey list
  758. DisplayHotkeyList( this, g_Viewlib_Hokeys_Descr );
  759. break;
  760. case HK_RESET_LOCAL_COORD: // set local (relative) coordinate origin
  761. GetScreen()->m_O_Curseur = GetCrossHairPosition();
  762. break;
  763. case HK_LEFT_CLICK:
  764. OnLeftClick( aDC, aPosition );
  765. break;
  766. case HK_LEFT_DCLICK: // Simulate a double left click: generate 2 events
  767. OnLeftClick( aDC, aPosition );
  768. OnLeftDClick( aDC, aPosition );
  769. break;
  770. case HK_ZOOM_IN:
  771. cmd.SetId( ID_KEY_ZOOM_IN );
  772. GetEventHandler()->ProcessEvent( cmd );
  773. break;
  774. case HK_ZOOM_OUT:
  775. cmd.SetId( ID_KEY_ZOOM_OUT );
  776. GetEventHandler()->ProcessEvent( cmd );
  777. break;
  778. case HK_ZOOM_REDRAW:
  779. cmd.SetId( ID_ZOOM_REDRAW );
  780. GetEventHandler()->ProcessEvent( cmd );
  781. break;
  782. case HK_ZOOM_CENTER:
  783. cmd.SetId( ID_POPUP_ZOOM_CENTER );
  784. GetEventHandler()->ProcessEvent( cmd );
  785. break;
  786. case HK_ZOOM_AUTO:
  787. cmd.SetId( ID_ZOOM_PAGE );
  788. GetEventHandler()->ProcessEvent( cmd );
  789. break;
  790. }
  791. return true;
  792. }