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.

1027 lines
40 KiB

18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 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) 2013 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
  6. * Copyright (C) 2007-2013 Wayne Stambaugh <stambaughw@verizon.net>
  7. * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
  8. *
  9. * This program is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU General Public License
  11. * as published by the Free Software Foundation; either version 2
  12. * of the License, or (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program; if not, you may find one here:
  21. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  22. * or you may search the http://www.gnu.org website for the version 2 license,
  23. * or you may write to the Free Software Foundation, Inc.,
  24. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  25. */
  26. /**
  27. * @file pcbnew/onrightclick.cpp
  28. * @brief Right mouse button functions.
  29. */
  30. #include <fctsys.h>
  31. #include <class_drawpanel.h>
  32. #include <macros.h>
  33. #include <base_units.h>
  34. #include <bitmaps.h>
  35. #include <class_board.h>
  36. #include <class_module.h>
  37. #include <class_track.h>
  38. #include <class_pcb_text.h>
  39. #include <class_zone.h>
  40. #include <pcbnew.h>
  41. #include <pcb_edit_frame.h>
  42. #include <pcbnew_id.h>
  43. #include <hotkeys.h>
  44. #include <collectors.h>
  45. #include <menus_helpers.h>
  46. static wxMenu* Append_Track_Width_List( BOARD* aBoard, EDA_UNITS_T aUnits );
  47. bool PCB_EDIT_FRAME::OnRightClick( const wxPoint& aMousePos, wxMenu* aPopMenu )
  48. {
  49. wxString msg;
  50. STATUS_FLAGS flags = 0;
  51. bool trackFound = false; // Flag set to true,
  52. // if a track is being the cursor, to avoid
  53. // to display menus relative to tracks twice
  54. bool blockActive = !GetScreen()->m_BlockLocate.IsIdle();
  55. BOARD_ITEM* item = GetCurItem();
  56. m_canvas->SetCanStartBlock( -1 ); // Avoid to start a block command when clicking on menu
  57. // If a command or a block is in progress:
  58. // Put the Cancel command (if needed) and the End command
  59. if( blockActive )
  60. {
  61. createPopUpBlockMenu( aPopMenu );
  62. aPopMenu->AppendSeparator();
  63. return true;
  64. }
  65. if( GetToolId() != ID_NO_TOOL_SELECTED && GetToolId() != ID_ZOOM_SELECTION )
  66. {
  67. if( item && item->GetFlags() )
  68. {
  69. AddMenuItem( aPopMenu, ID_POPUP_CANCEL_CURRENT_COMMAND, _( "Cancel" ),
  70. KiBitmap( cancel_xpm ) );
  71. }
  72. else
  73. {
  74. AddMenuItem( aPopMenu, ID_POPUP_CLOSE_CURRENT_TOOL,
  75. _( "End Tool" ), KiBitmap( cursor_xpm ) );
  76. }
  77. aPopMenu->AppendSeparator();
  78. }
  79. else
  80. {
  81. if( item && item->GetFlags() )
  82. {
  83. AddMenuItem( aPopMenu, ID_POPUP_CANCEL_CURRENT_COMMAND,
  84. _( "Cancel" ), KiBitmap( cancel_xpm ) );
  85. aPopMenu->AppendSeparator();
  86. }
  87. }
  88. // Select a proper item
  89. wxPoint cursorPos = GetCrossHairPosition();
  90. wxPoint selectPos = m_Collector->GetRefPos();
  91. selectPos = GetNearestGridPosition( selectPos );
  92. /* We can reselect another item only if there are no item being edited
  93. * because ALL moving functions use GetCurItem(), therefore GetCurItem()
  94. * must return the same item during moving. We know an item is moving
  95. * if( item && (item->m_Flags != 0)) is true and after calling
  96. * PcbGeneralLocateAndDisplay(), GetCurItem() is any arbitrary BOARD_ITEM,
  97. * not the current item being edited. In such case we cannot call
  98. * PcbGeneralLocateAndDisplay().
  99. */
  100. if( !item || (item->GetFlags() == 0) )
  101. {
  102. // show the "item selector" menu if no item selected or
  103. // if there is a selected item but the mouse has moved
  104. // (therefore a new item is perhaps under the cursor)
  105. if( !item || cursorPos != selectPos )
  106. {
  107. m_canvas->SetAbortRequest( false );
  108. PcbGeneralLocateAndDisplay();
  109. if( m_canvas->GetAbortRequest() )
  110. {
  111. return false;
  112. }
  113. }
  114. }
  115. item = GetCurItem();
  116. flags = item ? item->GetFlags() : 0;
  117. // Add the context menu, which depends on the picked item:
  118. if( item )
  119. {
  120. switch( item->Type() )
  121. {
  122. case PCB_MODULE_T:
  123. createPopUpMenuForFootprints( (MODULE*) item, aPopMenu );
  124. break;
  125. case PCB_PAD_T:
  126. createPopUpMenuForFpPads( static_cast<D_PAD*>( item ), aPopMenu );
  127. break;
  128. case PCB_MODULE_TEXT_T:
  129. createPopUpMenuForFpTexts( static_cast<TEXTE_MODULE*>( item ), aPopMenu );
  130. break;
  131. case PCB_LINE_T: // Some graphic items on technical layers
  132. if( (flags & IS_NEW) )
  133. {
  134. AddMenuItem( aPopMenu, ID_POPUP_PCB_STOP_CURRENT_DRAWING,
  135. _( "End Drawing" ), KiBitmap( checked_ok_xpm ) );
  136. }
  137. if( !flags )
  138. {
  139. msg = AddHotkeyName( _( "Move" ), g_Board_Editor_Hotkeys_Descr,
  140. HK_MOVE_ITEM );
  141. AddMenuItem( aPopMenu, ID_POPUP_PCB_MOVE_DRAWING_REQUEST,
  142. msg, KiBitmap( move_xpm ) );
  143. msg = AddHotkeyName( _( "Duplicate" ), g_Board_Editor_Hotkeys_Descr,
  144. HK_DUPLICATE_ITEM );
  145. AddMenuItem( aPopMenu, ID_POPUP_PCB_DUPLICATE_ITEM,
  146. msg, KiBitmap( duplicate_xpm ) );
  147. msg = AddHotkeyName( _("Move Exactly..." ), g_Board_Editor_Hotkeys_Descr,
  148. HK_MOVE_ITEM_EXACT );
  149. AddMenuItem( aPopMenu, ID_POPUP_PCB_MOVE_EXACT,
  150. msg, KiBitmap( move_exactly_xpm ) );
  151. msg = AddHotkeyName( _("Create Array..." ), g_Board_Editor_Hotkeys_Descr,
  152. HK_CREATE_ARRAY );
  153. AddMenuItem( aPopMenu, ID_POPUP_PCB_CREATE_ARRAY,
  154. msg, KiBitmap( array_xpm ) );
  155. msg = AddHotkeyName( _( "Edit..." ), g_Board_Editor_Hotkeys_Descr,
  156. HK_EDIT_ITEM );
  157. AddMenuItem( aPopMenu, ID_POPUP_PCB_EDIT_DRAWING,
  158. msg, KiBitmap( edit_xpm ) );
  159. AddMenuItem( aPopMenu, ID_POPUP_PCB_DELETE_DRAWING,
  160. _( "Delete" ), KiBitmap( delete_xpm ) );
  161. if( !IsCopperLayer( item->GetLayer() ) )
  162. AddMenuItem( aPopMenu, ID_POPUP_PCB_DELETE_DRAWING_LAYER,
  163. _( "Delete All Drawings on Layer" ), KiBitmap( delete_xpm ) );
  164. }
  165. break;
  166. case PCB_SEGZONE_T: // Item used to fill a zone
  167. AddMenuItem( aPopMenu, ID_POPUP_PCB_DELETE_ZONE,
  168. _( "Delete Zone Filling" ), KiBitmap( delete_xpm ) );
  169. break;
  170. case PCB_ZONE_AREA_T: // Item used to handle a zone area (outlines, holes ...)
  171. if( flags & IS_NEW )
  172. {
  173. AddMenuItem( aPopMenu, ID_POPUP_PCB_STOP_CURRENT_EDGE_ZONE,
  174. _( "Close Zone Outline" ), KiBitmap( checked_ok_xpm ) );
  175. AddMenuItem( aPopMenu, ID_POPUP_PCB_DELETE_ZONE_LAST_CREATED_CORNER,
  176. _( "Delete Last Corner" ), KiBitmap( delete_xpm ) );
  177. }
  178. else
  179. {
  180. createPopUpMenuForZones( (ZONE_CONTAINER*) item, aPopMenu );
  181. }
  182. break;
  183. case PCB_TEXT_T:
  184. createPopUpMenuForTexts( (TEXTE_PCB*) item, aPopMenu );
  185. break;
  186. case PCB_TRACE_T:
  187. case PCB_VIA_T:
  188. trackFound = true;
  189. createPopupMenuForTracks( (TRACK*) item, aPopMenu );
  190. break;
  191. case PCB_MARKER_T:
  192. createPopUpMenuForMarkers( (MARKER_PCB*) item, aPopMenu );
  193. break;
  194. case PCB_DIMENSION_T:
  195. if( !flags )
  196. {
  197. msg = AddHotkeyName( _( "Edit..." ), g_Board_Editor_Hotkeys_Descr,
  198. HK_EDIT_ITEM );
  199. AddMenuItem( aPopMenu, ID_POPUP_PCB_EDIT_DIMENSION, msg, KiBitmap( edit_xpm ) );
  200. msg = AddHotkeyName( _( "Move" ), g_Board_Editor_Hotkeys_Descr,
  201. HK_MOVE_ITEM );
  202. AddMenuItem( aPopMenu, ID_POPUP_PCB_MOVE_TEXT_DIMENSION_REQUEST,
  203. msg, KiBitmap( move_xpm ) );
  204. msg = AddHotkeyName( _( "Duplicate" ), g_Board_Editor_Hotkeys_Descr,
  205. HK_DUPLICATE_ITEM );
  206. AddMenuItem( aPopMenu, ID_POPUP_PCB_DUPLICATE_ITEM,
  207. msg, KiBitmap( duplicate_xpm ) );
  208. msg = AddHotkeyName( _("Move Exactly..." ), g_Board_Editor_Hotkeys_Descr,
  209. HK_MOVE_ITEM_EXACT );
  210. AddMenuItem( aPopMenu, ID_POPUP_PCB_MOVE_EXACT,
  211. msg, KiBitmap( move_exactly_xpm ) );
  212. msg = AddHotkeyName( _( "Delete" ), g_Board_Editor_Hotkeys_Descr,
  213. HK_DELETE );
  214. AddMenuItem( aPopMenu, ID_POPUP_PCB_DELETE_DIMENSION,
  215. msg, KiBitmap( delete_dimension_xpm ) );
  216. }
  217. break;
  218. case PCB_TARGET_T:
  219. if( !flags )
  220. {
  221. msg = AddHotkeyName( _( "Move" ), g_Board_Editor_Hotkeys_Descr,
  222. HK_MOVE_ITEM );
  223. AddMenuItem( aPopMenu, ID_POPUP_PCB_MOVE_PCB_TARGET_REQUEST,
  224. msg, KiBitmap( move_target_xpm ) );
  225. msg = AddHotkeyName( _("Move Exactly..." ), g_Board_Editor_Hotkeys_Descr,
  226. HK_MOVE_ITEM_EXACT );
  227. AddMenuItem( aPopMenu, ID_POPUP_PCB_MOVE_EXACT,
  228. msg, KiBitmap( move_exactly_xpm ) );
  229. msg = AddHotkeyName( _( "Duplicate" ), g_Board_Editor_Hotkeys_Descr,
  230. HK_DUPLICATE_ITEM );
  231. AddMenuItem( aPopMenu, ID_POPUP_PCB_DUPLICATE_ITEM,
  232. msg, KiBitmap( duplicate_xpm ) );
  233. msg = AddHotkeyName( _( "Edit..." ), g_Board_Editor_Hotkeys_Descr,
  234. HK_EDIT_ITEM );
  235. AddMenuItem( aPopMenu, ID_POPUP_PCB_EDIT_PCB_TARGET, msg, KiBitmap( edit_xpm ) );
  236. msg = AddHotkeyName( _( "Delete" ), g_Board_Editor_Hotkeys_Descr, HK_DELETE );
  237. AddMenuItem( aPopMenu, ID_POPUP_PCB_DELETE_PCB_TARGET,
  238. msg, KiBitmap( delete_xpm ) );
  239. }
  240. break;
  241. case PCB_MODULE_EDGE_T:
  242. case SCREEN_T:
  243. case TYPE_NOT_INIT:
  244. case PCB_T:
  245. wxLogDebug( wxT( "PCB_EDIT_FRAME::OnRightClick() Error: unexpected DrawType %d" ),
  246. item->Type() );
  247. SetCurItem( NULL );
  248. break;
  249. default:
  250. wxLogDebug( wxT( "PCB_EDIT_FRAME::OnRightClick() Error: unknown DrawType %d" ),
  251. item->Type() );
  252. // Attempt to clear error (but should no occurs )
  253. if( item->Type() >= MAX_STRUCT_TYPE_ID )
  254. SetCurItem( NULL );
  255. break;
  256. }
  257. aPopMenu->AppendSeparator();
  258. }
  259. if( !flags )
  260. {
  261. msg = AddHotkeyName( _( "Get and Move Footprint..." ),
  262. g_Board_Editor_Hotkeys_Descr, HK_GET_AND_MOVE_FOOTPRINT );
  263. AddMenuItem( aPopMenu, ID_POPUP_PCB_GET_AND_MOVE_MODULE_REQUEST,
  264. msg, KiBitmap( move_xpm ) );
  265. }
  266. // Display context sensitive commands:
  267. switch( GetToolId() )
  268. {
  269. case ID_PCB_ZONES_BUTT:
  270. if( GetBoard()->m_ZoneDescriptorList.size() > 0 )
  271. {
  272. aPopMenu->AppendSeparator();
  273. msg = AddHotkeyName( _( "Fill or Refill All Zones" ),
  274. g_Board_Editor_Hotkeys_Descr, HK_ZONE_FILL_OR_REFILL );
  275. AddMenuItem( aPopMenu, ID_POPUP_PCB_FILL_ALL_ZONES,
  276. msg, KiBitmap( fill_zone_xpm ) );
  277. msg = AddHotkeyName( _( "Remove Filled Areas in All Zones" ),
  278. g_Board_Editor_Hotkeys_Descr, HK_ZONE_REMOVE_FILLED );
  279. AddMenuItem( aPopMenu, ID_POPUP_PCB_REMOVE_FILLED_AREAS_IN_ALL_ZONES,
  280. msg, KiBitmap( zone_unfill_xpm ) );
  281. aPopMenu->AppendSeparator();
  282. }
  283. AddMenuItem( aPopMenu, ID_POPUP_PCB_SELECT_LAYER,
  284. _( "Select Working Layer..." ), KiBitmap( select_w_layer_xpm ) );
  285. aPopMenu->AppendSeparator();
  286. break;
  287. case ID_PCB_KEEPOUT_AREA_BUTT:
  288. AddMenuItem( aPopMenu, ID_POPUP_PCB_SELECT_LAYER,
  289. _( "Select Working Layer..." ), KiBitmap( select_w_layer_xpm ) );
  290. aPopMenu->AppendSeparator();
  291. break;
  292. case ID_TRACK_BUTT:
  293. if ( ! trackFound ) // This menu is already added when a track is located
  294. {
  295. aPopMenu->AppendSeparator();
  296. msg = AddHotkeyName( _( "Begin Track" ),
  297. g_Board_Editor_Hotkeys_Descr, HK_ADD_NEW_TRACK );
  298. AddMenuItem( aPopMenu, ID_POPUP_PCB_BEGIN_TRACK,
  299. msg, KiBitmap( add_tracks_xpm ) );
  300. AddMenuItem( aPopMenu, Append_Track_Width_List( GetBoard(), GetUserUnits() ),
  301. ID_POPUP_PCB_SELECT_WIDTH, _( "Select Track Width" ),
  302. KiBitmap( width_track_xpm ) );
  303. AddMenuItem( aPopMenu, ID_POPUP_PCB_SELECT_CU_LAYER,
  304. _( "Select Working Layer..." ), KiBitmap( select_w_layer_xpm ) );
  305. AddMenuItem( aPopMenu, ID_POPUP_PCB_SELECT_LAYER_PAIR,
  306. _( "Select Layer Pair for Vias..." ), KiBitmap( select_layer_pair_xpm ) );
  307. aPopMenu->AppendSeparator();
  308. }
  309. break;
  310. case ID_PCB_CIRCLE_BUTT:
  311. case ID_PCB_ARC_BUTT:
  312. case ID_PCB_ADD_TEXT_BUTT:
  313. case ID_PCB_ADD_LINE_BUTT:
  314. case ID_PCB_DIMENSION_BUTT:
  315. AddMenuItem( aPopMenu, ID_POPUP_PCB_SELECT_NO_CU_LAYER,
  316. _( "Select Working Layer..." ), KiBitmap( select_w_layer_xpm ) );
  317. aPopMenu->AppendSeparator();
  318. break;
  319. case ID_PCB_MODULE_BUTT:
  320. if( !flags )
  321. {
  322. AddMenuItem( aPopMenu, ID_POPUP_PCB_DISPLAY_FOOTPRINT_DOC,
  323. _( "Footprint Documentation" ), KiBitmap( book_xpm ) );
  324. aPopMenu->AppendSeparator();
  325. }
  326. break;
  327. case ID_NO_TOOL_SELECTED:
  328. {
  329. if( !trackFound )
  330. {
  331. msg = AddHotkeyName( _( "Begin Track" ), g_Board_Editor_Hotkeys_Descr, HK_ADD_NEW_TRACK );
  332. AddMenuItem( aPopMenu, ID_POPUP_PCB_BEGIN_TRACK, msg, KiBitmap( add_tracks_xpm ) );
  333. AddMenuItem( aPopMenu, Append_Track_Width_List( GetBoard(), GetUserUnits() ),
  334. ID_POPUP_PCB_SELECT_WIDTH, _( "Select Track Width" ),
  335. KiBitmap( width_track_xpm ) );
  336. AddMenuItem( aPopMenu, ID_POPUP_PCB_SELECT_LAYER,
  337. _( "Select Working Layer..." ), KiBitmap( select_w_layer_xpm ) );
  338. aPopMenu->AppendSeparator();
  339. }
  340. break;
  341. }
  342. }
  343. return true;
  344. }
  345. /* Create Pop sub menu for block commands
  346. */
  347. void PCB_EDIT_FRAME::createPopUpBlockMenu( wxMenu* menu )
  348. {
  349. AddMenuItem( menu, ID_POPUP_CANCEL_CURRENT_COMMAND, _( "Cancel Block" ),
  350. KiBitmap( cancel_xpm ) );
  351. AddMenuItem( menu, ID_POPUP_ZOOM_BLOCK, _( "Zoom Block" ), KiBitmap( zoom_area_xpm ) );
  352. menu->AppendSeparator();
  353. AddMenuItem( menu, ID_POPUP_PLACE_BLOCK, _( "Place Block" ), KiBitmap( checked_ok_xpm ) );
  354. AddMenuItem( menu, ID_POPUP_DUPLICATE_BLOCK, _( "Duplicate" ), KiBitmap( duplicate_xpm ) );
  355. AddMenuItem( menu, ID_POPUP_FLIP_BLOCK, _( "Flip" ), KiBitmap( mirror_v_xpm ) );
  356. AddMenuItem( menu, ID_POPUP_ROTATE_BLOCK, _( "Rotate Counterclockwise" ), KiBitmap( rotate_ccw_xpm ) );
  357. AddMenuItem( menu, ID_POPUP_DELETE_BLOCK, _( "Delete" ), KiBitmap( delete_xpm ) );
  358. }
  359. /* Create command lines for a popup menu, for track and via editing
  360. * also update Netclass selection
  361. */
  362. void PCB_EDIT_FRAME::createPopupMenuForTracks( TRACK* Track, wxMenu* PopMenu )
  363. {
  364. wxPoint cursorPosition = GetCrossHairPosition();
  365. wxString msg;
  366. SetCurrentNetClass( Track->GetNetClassName() );
  367. int flags = Track->GetFlags();
  368. if( flags == 0 )
  369. {
  370. msg = AddHotkeyName( _( "Begin Track" ),
  371. g_Board_Editor_Hotkeys_Descr, HK_ADD_NEW_TRACK );
  372. AddMenuItem( PopMenu, ID_POPUP_PCB_BEGIN_TRACK,
  373. msg, KiBitmap( add_tracks_xpm ) );
  374. if( Track->Type() == PCB_VIA_T )
  375. {
  376. msg = AddHotkeyName( _( "Drag Via" ), g_Board_Editor_Hotkeys_Descr,
  377. HK_DRAG_ITEM );
  378. AddMenuItem( PopMenu, ID_POPUP_PCB_MOVE_TRACK_NODE, msg,
  379. KiBitmap( move_xpm ) );
  380. }
  381. else
  382. {
  383. if( Track->IsPointOnEnds( cursorPosition, -1 ) != 0 )
  384. {
  385. msg = AddHotkeyName( _( "Move" ), g_Board_Editor_Hotkeys_Descr, HK_MOVE_ITEM );
  386. AddMenuItem( PopMenu, ID_POPUP_PCB_MOVE_TRACK_NODE,
  387. msg, KiBitmap( move_xpm ) );
  388. }
  389. else
  390. {
  391. msg = AddHotkeyName( _( "Drag Segments, Keep Slope" ), g_Board_Editor_Hotkeys_Descr,
  392. HK_DRAG_TRACK_KEEP_SLOPE );
  393. AddMenuItem( PopMenu, ID_POPUP_PCB_DRAG_TRACK_SEGMENT_KEEP_SLOPE,
  394. msg, KiBitmap( drag_segment_withslope_xpm ) );
  395. msg = AddHotkeyName( _( "Drag Segment" ), g_Board_Editor_Hotkeys_Descr,
  396. HK_DRAG_ITEM );
  397. AddMenuItem( PopMenu, ID_POPUP_PCB_DRAG_TRACK_SEGMENT,
  398. msg, KiBitmap( drag_xpm ) );
  399. msg = AddHotkeyName( _( "Duplicate" ), g_Board_Editor_Hotkeys_Descr,
  400. HK_DUPLICATE_ITEM );
  401. AddMenuItem( PopMenu, ID_POPUP_PCB_DUPLICATE_ITEM,
  402. msg, KiBitmap( duplicate_xpm ) );
  403. msg = AddHotkeyName( _("Move Exactly..." ), g_Board_Editor_Hotkeys_Descr,
  404. HK_MOVE_ITEM_EXACT );
  405. AddMenuItem( PopMenu, ID_POPUP_PCB_MOVE_EXACT,
  406. msg, KiBitmap( move_exactly_xpm ) );
  407. msg = AddHotkeyName( _("Create Track Array..." ), g_Board_Editor_Hotkeys_Descr,
  408. HK_CREATE_ARRAY );
  409. AddMenuItem( PopMenu, ID_POPUP_PCB_CREATE_ARRAY,
  410. msg, KiBitmap( array_xpm ) );
  411. AddMenuItem( PopMenu, ID_POPUP_PCB_BREAK_TRACK,
  412. _( "Break Track" ), KiBitmap( break_line_xpm ) );
  413. }
  414. }
  415. AddMenuItem( PopMenu, ID_POPUP_PCB_SELECT_CU_LAYER,
  416. _( "Select Working Layer..." ), KiBitmap( select_w_layer_xpm ) );
  417. }
  418. else if( flags & IS_DRAGGED ) // Drag via or node in progress
  419. {
  420. AddMenuItem( PopMenu, ID_POPUP_PCB_PLACE_MOVED_TRACK_NODE,
  421. _( "Place Node" ), KiBitmap( checked_ok_xpm ) );
  422. return;
  423. }
  424. else // Edit in progress
  425. {
  426. if( flags & IS_NEW )
  427. {
  428. msg = AddHotkeyName( _( "End Track" ), g_Board_Editor_Hotkeys_Descr, HK_LEFT_DCLICK );
  429. AddMenuItem( PopMenu, ID_POPUP_PCB_END_TRACK, msg, KiBitmap( checked_ok_xpm ) );
  430. }
  431. msg = AddHotkeyName( _( "Place Through Via" ), g_Board_Editor_Hotkeys_Descr, HK_ADD_THROUGH_VIA );
  432. AddMenuItem( PopMenu, ID_POPUP_PCB_PLACE_THROUGH_VIA, msg, KiBitmap( via_xpm ) );
  433. msg = AddHotkeyName( _( "Select Layer and Place Through Via..." ),
  434. g_Board_Editor_Hotkeys_Descr, HK_SEL_LAYER_AND_ADD_THROUGH_VIA );
  435. AddMenuItem( PopMenu, ID_POPUP_PCB_SELECT_CU_LAYER_AND_PLACE_THROUGH_VIA,
  436. msg, KiBitmap( select_w_layer_xpm ) );
  437. if( GetDesignSettings().m_BlindBuriedViaAllowed )
  438. {
  439. msg = AddHotkeyName( _( "Place Blind/Buried Via" ),
  440. g_Board_Editor_Hotkeys_Descr, HK_ADD_BLIND_BURIED_VIA );
  441. AddMenuItem( PopMenu, ID_POPUP_PCB_PLACE_BLIND_BURIED_VIA, msg, KiBitmap( via_buried_xpm ) );
  442. msg = AddHotkeyName( _( "Select Layer and Place Blind/Buried Via..." ),
  443. g_Board_Editor_Hotkeys_Descr, HK_SEL_LAYER_AND_ADD_BLIND_BURIED_VIA );
  444. AddMenuItem( PopMenu, ID_POPUP_PCB_SELECT_CU_LAYER_AND_PLACE_BLIND_BURIED_VIA,
  445. msg, KiBitmap( select_w_layer_xpm ) );
  446. }
  447. msg = AddHotkeyName( _( "Switch Track Posture" ), g_Board_Editor_Hotkeys_Descr,
  448. HK_SWITCH_TRACK_POSTURE );
  449. AddMenuItem( PopMenu, ID_POPUP_PCB_SWITCH_TRACK_POSTURE, msg,
  450. KiBitmap( change_entry_orient_xpm ) );
  451. // See if we can place a Micro Via (4 or more layers, and start from an external layer):
  452. if( IsMicroViaAcceptable() )
  453. {
  454. msg = AddHotkeyName( _( "Place Micro Via" ), g_Board_Editor_Hotkeys_Descr,
  455. HK_ADD_MICROVIA );
  456. AddMenuItem( PopMenu, ID_POPUP_PCB_PLACE_MICROVIA, msg, KiBitmap( via_microvia_xpm ) );
  457. }
  458. }
  459. // track Width control :
  460. if( !flags )
  461. {
  462. if( Track->Type() == PCB_VIA_T )
  463. {
  464. msg = AddHotkeyName( _( "Change Via Size and Drill" ), g_Board_Editor_Hotkeys_Descr,
  465. HK_EDIT_ITEM );
  466. AddMenuItem( PopMenu, ID_POPUP_PCB_EDIT_TRACKSEG, msg, KiBitmap( width_segment_xpm ) );
  467. }
  468. else
  469. {
  470. msg = AddHotkeyName( _( "Change Segment Width" ), g_Board_Editor_Hotkeys_Descr,
  471. HK_EDIT_ITEM );
  472. AddMenuItem( PopMenu, ID_POPUP_PCB_EDIT_TRACKSEG, msg, KiBitmap( width_segment_xpm ) );
  473. AddMenuItem( PopMenu, ID_POPUP_PCB_EDIT_TRACK,
  474. _( "Change Track Width" ), KiBitmap( width_track_xpm ) );
  475. }
  476. }
  477. // Allows switching to another track/via size when routing
  478. AddMenuItem( PopMenu, Append_Track_Width_List( GetBoard(), GetUserUnits() ),
  479. ID_POPUP_PCB_SELECT_WIDTH,
  480. _( "Select Track Width" ), KiBitmap( width_track_xpm ) );
  481. // Delete control:
  482. PopMenu->AppendSeparator();
  483. wxMenu* trackdel_mnu = new wxMenu;
  484. AddMenuItem( PopMenu, trackdel_mnu, ID_POPUP_PCB_DELETE_TRACK_MNU, _( "Delete" ),
  485. KiBitmap( delete_xpm ) );
  486. msg = AddHotkeyName( Track->Type()==PCB_VIA_T ?
  487. _( "Delete Via" ) : _( "Delete Segment" ),
  488. g_Board_Editor_Hotkeys_Descr, HK_BACK_SPACE );
  489. AddMenuItem( trackdel_mnu, ID_POPUP_PCB_DELETE_TRACKSEG, msg, KiBitmap( delete_line_xpm ) );
  490. if( !flags )
  491. {
  492. msg = AddHotkeyName( _( "Delete Track" ), g_Board_Editor_Hotkeys_Descr, HK_DELETE );
  493. AddMenuItem( trackdel_mnu, ID_POPUP_PCB_DELETE_TRACK, msg, KiBitmap( delete_track_xpm ) );
  494. AddMenuItem( trackdel_mnu, ID_POPUP_PCB_DELETE_TRACKNET, _( "Delete Net" ),
  495. KiBitmap( delete_net_xpm ) );
  496. }
  497. // Add global editing commands:
  498. if( !flags )
  499. {
  500. PopMenu->AppendSeparator();
  501. AddMenuItem( PopMenu, ID_POPUP_PCB_EDIT_ALL_VIAS_AND_TRACK_SIZE,
  502. _( "Set Track and Via Sizes..." ), KiBitmap( width_track_via_xpm ) );
  503. }
  504. // Add lock/unlock flags menu:
  505. wxMenu* trackflg_mnu = new wxMenu;
  506. AddMenuItem( PopMenu, trackflg_mnu, ID_POPUP_PCB_SETFLAGS_TRACK_MNU, _( "Set Flags" ),
  507. KiBitmap( flag_xpm ) );
  508. trackflg_mnu->Append( ID_POPUP_PCB_LOCK_ON_TRACKSEG, _( "Locked: Yes" ), wxEmptyString, true );
  509. trackflg_mnu->Append( ID_POPUP_PCB_LOCK_OFF_TRACKSEG, _( "Locked: No" ), wxEmptyString, true );
  510. if( Track->GetState( TRACK_LOCKED ) )
  511. trackflg_mnu->Check( ID_POPUP_PCB_LOCK_ON_TRACKSEG, true );
  512. else
  513. trackflg_mnu->Check( ID_POPUP_PCB_LOCK_OFF_TRACKSEG, true );
  514. if( !flags )
  515. {
  516. trackflg_mnu->Append( ID_POPUP_PCB_LOCK_ON_TRACK, _( "Track Locked: Yes" ) );
  517. trackflg_mnu->Append( ID_POPUP_PCB_LOCK_OFF_TRACK, _( "Track Locked: No" ) );
  518. trackflg_mnu->AppendSeparator();
  519. trackflg_mnu->Append( ID_POPUP_PCB_LOCK_ON_NET, _( "Net Locked: Yes" ) );
  520. trackflg_mnu->Append( ID_POPUP_PCB_LOCK_OFF_NET, _( "Net Locked: No" ) );
  521. }
  522. }
  523. /* Create the wxMenuitem list for zone outlines editing and zone filling
  524. */
  525. void PCB_EDIT_FRAME::createPopUpMenuForZones( ZONE_CONTAINER* edge_zone, wxMenu* aPopMenu )
  526. {
  527. wxString msg;
  528. GENERAL_COLLECTORS_GUIDE guide = GetCollectorsGuide();
  529. if( edge_zone->GetFlags() == IS_DRAGGED )
  530. {
  531. AddMenuItem( aPopMenu, ID_POPUP_PCB_PLACE_DRAGGED_ZONE_OUTLINE_SEGMENT,
  532. _( "Place Edge Outline" ), KiBitmap( checked_ok_xpm ) );
  533. }
  534. else if( edge_zone->GetFlags() )
  535. {
  536. if( (edge_zone->GetFlags() & IN_EDIT ) )
  537. AddMenuItem( aPopMenu, ID_POPUP_PCB_PLACE_ZONE_CORNER,
  538. _( "Place Corner" ), KiBitmap( checked_ok_xpm ) );
  539. else
  540. AddMenuItem( aPopMenu, ID_POPUP_PCB_PLACE_ZONE_OUTLINES,
  541. _( "Place Zone" ), KiBitmap( checked_ok_xpm ) );
  542. }
  543. else
  544. {
  545. wxMenu* zones_menu = new wxMenu();
  546. int accuracy = KiROUND( 5 * guide.OnePixelInIU() );
  547. AddMenuItem( aPopMenu, zones_menu, -1,
  548. edge_zone->GetIsKeepout() ? _("Keepout Area") : _( "Zones" ),
  549. KiBitmap( add_zone_xpm ) );
  550. if( edge_zone->HitTestForCorner( RefPos( true ), accuracy * 2 ) )
  551. {
  552. AddMenuItem( zones_menu, ID_POPUP_PCB_MOVE_ZONE_CORNER,
  553. _( "Move Corner" ), KiBitmap( move_xpm ) );
  554. AddMenuItem( zones_menu, ID_POPUP_PCB_DELETE_ZONE_CORNER,
  555. _( "Delete Corner" ), KiBitmap( delete_xpm ) );
  556. }
  557. else if( edge_zone->HitTestForEdge( RefPos( true ), accuracy ) )
  558. {
  559. AddMenuItem( zones_menu, ID_POPUP_PCB_ADD_ZONE_CORNER,
  560. _( "Create Corner" ), KiBitmap( add_corner_xpm ) );
  561. msg = AddHotkeyName( _( "Drag Outline Segment" ), g_Board_Editor_Hotkeys_Descr,
  562. HK_DRAG_ITEM );
  563. AddMenuItem( zones_menu, ID_POPUP_PCB_DRAG_ZONE_OUTLINE_SEGMENT,
  564. msg, KiBitmap( drag_outline_segment_xpm ) );
  565. }
  566. zones_menu->AppendSeparator();
  567. AddMenuItem( zones_menu, ID_POPUP_PCB_ZONE_ADD_SIMILAR_ZONE,
  568. _( "Add Similar Zone" ), KiBitmap( add_zone_xpm ) );
  569. AddMenuItem( zones_menu, ID_POPUP_PCB_ZONE_ADD_CUTOUT_ZONE,
  570. _( "Add Cutout Area" ), KiBitmap( add_zone_cutout_xpm ) );
  571. AddMenuItem( zones_menu, ID_POPUP_PCB_ZONE_DUPLICATE,
  572. _( "Duplicate Zone onto Layer..." ), KiBitmap( zone_duplicate_xpm ) );
  573. zones_menu->AppendSeparator();
  574. if( ! edge_zone->GetIsKeepout() )
  575. AddMenuItem( zones_menu, ID_POPUP_PCB_FILL_ZONE, _( "Fill Zone" ),
  576. KiBitmap( fill_zone_xpm ) );
  577. if( !edge_zone->GetFilledPolysList().IsEmpty() )
  578. {
  579. AddMenuItem( zones_menu, ID_POPUP_PCB_REMOVE_FILLED_AREAS_IN_CURRENT_ZONE,
  580. _( "Remove Filled Areas in Zone" ), KiBitmap( zone_unfill_xpm ) );
  581. }
  582. msg = AddHotkeyName( _( "Move Zone" ), g_Board_Editor_Hotkeys_Descr, HK_MOVE_ITEM );
  583. AddMenuItem( zones_menu, ID_POPUP_PCB_MOVE_ZONE_OUTLINES, msg, KiBitmap( move_xpm ) );
  584. msg = AddHotkeyName( _("Move Zone Exactly..." ), g_Board_Editor_Hotkeys_Descr,
  585. HK_MOVE_ITEM_EXACT );
  586. AddMenuItem( zones_menu, ID_POPUP_PCB_MOVE_EXACT,
  587. msg, KiBitmap( move_xpm ) );
  588. msg = AddHotkeyName( _( "Edit Zone Properties..." ), g_Board_Editor_Hotkeys_Descr,
  589. HK_EDIT_ITEM );
  590. AddMenuItem( zones_menu, ID_POPUP_PCB_EDIT_ZONE_PARAMS,
  591. msg, KiBitmap( edit_xpm ) );
  592. zones_menu->AppendSeparator();
  593. if( edge_zone->GetSelectedCorner() >= 0 &&
  594. edge_zone->Outline()->IsVertexInHole( edge_zone->GetSelectedCorner() ) )
  595. AddMenuItem( zones_menu, ID_POPUP_PCB_DELETE_ZONE_CUTOUT,
  596. _( "Delete Cutout" ), KiBitmap( delete_xpm ) );
  597. AddMenuItem( zones_menu, ID_POPUP_PCB_DELETE_ZONE_CONTAINER,
  598. _( "Delete Zone Outline" ), KiBitmap( delete_xpm ) );
  599. }
  600. }
  601. /* Create the wxMenuitem list for footprint editing
  602. */
  603. void PCB_EDIT_FRAME::createPopUpMenuForFootprints( MODULE* aModule, wxMenu* menu )
  604. {
  605. wxMenu* sub_menu_footprint;
  606. int flags = aModule->GetFlags();
  607. wxString msg;
  608. sub_menu_footprint = new wxMenu;
  609. msg = aModule->GetSelectMenuText( m_UserUnits );
  610. AddMenuItem( menu, sub_menu_footprint, -1, msg, KiBitmap( module_xpm ) );
  611. if( !flags )
  612. {
  613. msg = AddHotkeyName( _( "Move" ), g_Board_Editor_Hotkeys_Descr, HK_MOVE_ITEM );
  614. AddMenuItem( sub_menu_footprint, ID_POPUP_PCB_MOVE_MODULE_REQUEST,
  615. msg, KiBitmap( move_xpm ) );
  616. msg = AddHotkeyName( _( "Drag" ), g_Board_Editor_Hotkeys_Descr, HK_DRAG_ITEM );
  617. AddMenuItem( sub_menu_footprint, ID_POPUP_PCB_DRAG_MODULE_REQUEST,
  618. msg, KiBitmap( drag_xpm ) );
  619. }
  620. msg = AddHotkeyName( _( "Rotate Counterclockwise" ), g_Board_Editor_Hotkeys_Descr, HK_ROTATE_ITEM );
  621. AddMenuItem( sub_menu_footprint, ID_POPUP_PCB_ROTATE_MODULE_COUNTERCLOCKWISE,
  622. msg, KiBitmap( rotate_ccw_xpm ) );
  623. AddMenuItem( sub_menu_footprint, ID_POPUP_PCB_ROTATE_MODULE_CLOCKWISE,
  624. _( "Rotate Clockwise" ), KiBitmap( rotate_cw_xpm ) );
  625. msg = AddHotkeyName( _( "Flip" ), g_Board_Editor_Hotkeys_Descr, HK_FLIP_ITEM );
  626. AddMenuItem( sub_menu_footprint, ID_POPUP_PCB_CHANGE_SIDE_MODULE,
  627. msg, KiBitmap( mirror_v_xpm ) );
  628. if( !flags )
  629. {
  630. msg = AddHotkeyName( _( "Edit Parameters..." ),
  631. g_Board_Editor_Hotkeys_Descr, HK_EDIT_ITEM );
  632. AddMenuItem( sub_menu_footprint, ID_POPUP_PCB_EDIT_MODULE_PRMS, msg,
  633. KiBitmap( edit_module_xpm ) );
  634. msg = AddHotkeyName( _( "Edit with Footprint Editor" ),
  635. g_Board_Editor_Hotkeys_Descr, HK_EDIT_MODULE_WITH_MODEDIT );
  636. AddMenuItem( sub_menu_footprint, ID_POPUP_PCB_EDIT_MODULE_WITH_MODEDIT,
  637. msg, KiBitmap( module_editor_xpm ) );
  638. sub_menu_footprint->AppendSeparator();
  639. msg = AddHotkeyName( _( "Delete" ),
  640. g_Board_Editor_Hotkeys_Descr, HK_DELETE );
  641. AddMenuItem( sub_menu_footprint, ID_POPUP_PCB_DELETE_MODULE,
  642. msg, KiBitmap( delete_module_xpm ) );
  643. sub_menu_footprint->AppendSeparator();
  644. msg = AddHotkeyName( _("Move Exactly..." ), g_Board_Editor_Hotkeys_Descr,
  645. HK_MOVE_ITEM_EXACT );
  646. AddMenuItem( sub_menu_footprint, ID_POPUP_PCB_MOVE_EXACT,
  647. msg, KiBitmap( move_exactly_xpm ) );
  648. msg = AddHotkeyName( _( "Duplicate" ), g_Board_Editor_Hotkeys_Descr,
  649. HK_DUPLICATE_ITEM );
  650. AddMenuItem( sub_menu_footprint, ID_POPUP_PCB_DUPLICATE_ITEM,
  651. msg, KiBitmap( duplicate_xpm ) );
  652. msg = AddHotkeyName( _("Create Array..." ), g_Board_Editor_Hotkeys_Descr,
  653. HK_CREATE_ARRAY );
  654. AddMenuItem( sub_menu_footprint, ID_POPUP_PCB_CREATE_ARRAY,
  655. msg, KiBitmap( array_xpm ) );
  656. AddMenuItem( sub_menu_footprint, ID_POPUP_PCB_UPDATE_FOOTPRINTS,
  657. _( "Update Footprint..." ), KiBitmap( reload_xpm ) );
  658. AddMenuItem( sub_menu_footprint, ID_POPUP_PCB_EXCHANGE_FOOTPRINTS,
  659. _( "Change Footprint..." ), KiBitmap( exchange_xpm ) );
  660. }
  661. sub_menu_footprint->AppendSeparator();
  662. if( !aModule->IsLocked() )
  663. {
  664. }
  665. else
  666. {
  667. }
  668. }
  669. /* Create the wxMenuitem list for editing texts on footprints
  670. */
  671. void PCB_EDIT_FRAME::createPopUpMenuForFpTexts( TEXTE_MODULE* FpText, wxMenu* menu )
  672. {
  673. wxMenu* sub_menu_Fp_text;
  674. int flags = FpText->GetFlags();
  675. wxString msg = FpText->GetSelectMenuText( m_UserUnits );
  676. sub_menu_Fp_text = new wxMenu;
  677. AddMenuItem( menu, sub_menu_Fp_text, -1, msg, KiBitmap( footprint_text_xpm ) );
  678. if( !flags )
  679. {
  680. msg = AddHotkeyName( _( "Move" ), g_Board_Editor_Hotkeys_Descr, HK_MOVE_ITEM );
  681. AddMenuItem( sub_menu_Fp_text, ID_POPUP_PCB_MOVE_TEXTMODULE_REQUEST,
  682. msg, KiBitmap( move_xpm ) );
  683. msg = AddHotkeyName( _("Move Exactly..." ), g_Board_Editor_Hotkeys_Descr,
  684. HK_MOVE_ITEM_EXACT );
  685. AddMenuItem( sub_menu_Fp_text, ID_POPUP_PCB_MOVE_EXACT,
  686. msg, KiBitmap( move_exactly_xpm ) );
  687. }
  688. msg = AddHotkeyName( _( "Rotate Clockwise" ), g_Board_Editor_Hotkeys_Descr, HK_ROTATE_ITEM );
  689. AddMenuItem( sub_menu_Fp_text, ID_POPUP_PCB_ROTATE_TEXTMODULE,
  690. msg, KiBitmap( rotate_cw_xpm ) );
  691. if( !flags )
  692. {
  693. msg = AddHotkeyName( _( "Edit..." ), g_Board_Editor_Hotkeys_Descr, HK_EDIT_ITEM );
  694. AddMenuItem( sub_menu_Fp_text, ID_POPUP_PCB_EDIT_TEXTMODULE,
  695. msg, KiBitmap( edit_text_xpm ) );
  696. AddMenuItem( sub_menu_Fp_text, ID_POPUP_PCB_RESET_TEXT_SIZE,
  697. _( "Reset Size" ), KiBitmap( reset_text_xpm ) );
  698. }
  699. // Graphic texts can be deleted only if are not currently edited.
  700. if( !flags && FpText->GetType() == TEXTE_MODULE::TEXT_is_DIVERS )
  701. {
  702. AddMenuItem( sub_menu_Fp_text, ID_POPUP_PCB_DELETE_TEXTMODULE,
  703. _( "Delete" ), KiBitmap( delete_xpm ) );
  704. }
  705. if( !flags )
  706. {
  707. MODULE* module = (MODULE*) FpText->GetParent();
  708. if( module )
  709. {
  710. menu->AppendSeparator();
  711. createPopUpMenuForFootprints( module, menu );
  712. }
  713. }
  714. }
  715. /* Create pop menu for pads
  716. * also update Netclass selection
  717. */
  718. void PCB_EDIT_FRAME::createPopUpMenuForFpPads( D_PAD* Pad, wxMenu* menu )
  719. {
  720. wxMenu* sub_menu_Pad;
  721. int flags = Pad->GetFlags();
  722. if( flags ) // Currently in edit, no others commands possible
  723. return;
  724. SetCurrentNetClass( Pad->GetNetClassName() );
  725. wxString msg = Pad->GetSelectMenuText( m_UserUnits );
  726. sub_menu_Pad = new wxMenu;
  727. AddMenuItem( menu, sub_menu_Pad, -1, msg, KiBitmap( pad_xpm ) );
  728. AddMenuItem( sub_menu_Pad, ID_POPUP_PCB_MOVE_PAD_REQUEST, _( "Move Pad" ),
  729. KiBitmap( move_pad_xpm ) );
  730. AddMenuItem( sub_menu_Pad, ID_POPUP_PCB_DRAG_PAD_REQUEST, _( "Drag Pad" ),
  731. KiBitmap( drag_pad_xpm ) );
  732. msg = AddHotkeyName( _( "Edit Pad..." ), g_Board_Editor_Hotkeys_Descr, HK_EDIT_ITEM );
  733. AddMenuItem( sub_menu_Pad, ID_POPUP_PCB_EDIT_PAD, msg, KiBitmap( options_pad_xpm ) );
  734. sub_menu_Pad->AppendSeparator();
  735. AddMenuItem( sub_menu_Pad, ID_POPUP_PCB_COPY_PAD_SETTINGS,
  736. _( "Copy Pad Properties" ),
  737. wxEmptyString,
  738. KiBitmap( copy_pad_settings_xpm ) );
  739. AddMenuItem( sub_menu_Pad, ID_POPUP_PCB_APPLY_PAD_SETTINGS,
  740. _( "Paste Pad Properties" ),
  741. wxEmptyString,
  742. KiBitmap( apply_pad_settings_xpm ) );
  743. AddMenuItem( sub_menu_Pad, ID_POPUP_PCB_GLOBAL_IMPORT_PAD_SETTINGS,
  744. _( "Push Pad Properties..." ),
  745. _( "Copy this pad's properties to all pads in this footprint (or similar footprints)" ),
  746. KiBitmap( push_pad_settings_xpm ) );
  747. sub_menu_Pad->AppendSeparator();
  748. AddMenuItem( sub_menu_Pad, ID_POPUP_PCB_DELETE_PAD, _( "Delete" ), KiBitmap( delete_pad_xpm ) );
  749. MODULE* module = Pad->GetParent();
  750. if( module )
  751. {
  752. menu->AppendSeparator();
  753. createPopUpMenuForFootprints( module, menu );
  754. }
  755. }
  756. // Create pop menu for pcb texts
  757. void PCB_EDIT_FRAME::createPopUpMenuForTexts( TEXTE_PCB* Text, wxMenu* menu )
  758. {
  759. wxMenu* sub_menu_Text;
  760. int flags = Text->GetFlags();
  761. wxString msg = Text->GetSelectMenuText( m_UserUnits );
  762. sub_menu_Text = new wxMenu;
  763. AddMenuItem( menu, sub_menu_Text, -1, msg, KiBitmap( text_xpm ) );
  764. if( !flags )
  765. {
  766. msg = AddHotkeyName( _( "Move" ), g_Board_Editor_Hotkeys_Descr, HK_MOVE_ITEM );
  767. AddMenuItem( sub_menu_Text, ID_POPUP_PCB_MOVE_TEXTEPCB_REQUEST,
  768. msg, KiBitmap( move_xpm ) );
  769. msg = AddHotkeyName( _( "Copy" ), g_Board_Editor_Hotkeys_Descr, HK_COPY_ITEM );
  770. AddMenuItem( sub_menu_Text, ID_POPUP_PCB_COPY_TEXTEPCB,
  771. msg, KiBitmap( copy_xpm ) );
  772. }
  773. msg = AddHotkeyName( _( "Rotate" ), g_Board_Editor_Hotkeys_Descr, HK_ROTATE_ITEM );
  774. AddMenuItem( sub_menu_Text, ID_POPUP_PCB_ROTATE_TEXTEPCB, msg, KiBitmap( rotate_ccw_xpm ) );
  775. msg = AddHotkeyName( _( "Flip" ), g_Board_Editor_Hotkeys_Descr, HK_FLIP_ITEM );
  776. AddMenuItem( sub_menu_Text, ID_POPUP_PCB_FLIP_TEXTEPCB, msg, KiBitmap( mirror_h_xpm ) );
  777. msg = AddHotkeyName( _( "Edit..." ), g_Board_Editor_Hotkeys_Descr, HK_EDIT_ITEM );
  778. AddMenuItem( sub_menu_Text, ID_POPUP_PCB_EDIT_TEXTEPCB, msg, KiBitmap( edit_text_xpm ) );
  779. if( !flags )
  780. {
  781. AddMenuItem( sub_menu_Text, ID_POPUP_PCB_RESET_TEXT_SIZE,
  782. _( "Reset Size" ), KiBitmap( reset_text_xpm ) );
  783. sub_menu_Text->AppendSeparator();
  784. msg = AddHotkeyName( _( "Delete" ), g_Board_Editor_Hotkeys_Descr, HK_DELETE );
  785. AddMenuItem( sub_menu_Text, ID_POPUP_PCB_DELETE_TEXTEPCB, msg, KiBitmap( delete_xpm ) );
  786. }
  787. }
  788. void PCB_EDIT_FRAME::createPopUpMenuForMarkers( MARKER_PCB* aMarker, wxMenu* aPopMenu )
  789. {
  790. AddMenuItem( aPopMenu, ID_POPUP_PCB_DELETE_MARKER, _( "Delete Marker" ),
  791. KiBitmap( delete_xpm ) );
  792. AddMenuItem( aPopMenu, ID_POPUP_PCB_GETINFO_MARKER, _( "Marker Error Info" ),
  793. KiBitmap( info_xpm ) );
  794. }
  795. /**
  796. * Function Append_Track_Width_List
  797. * creates a wxMenu * which shows the last used track widths and via diameters
  798. * @return a pointer to the menu
  799. */
  800. static wxMenu* Append_Track_Width_List( BOARD* aBoard, EDA_UNITS_T aUnits )
  801. {
  802. wxString msg;
  803. wxMenu* trackwidth_menu;
  804. BOARD_DESIGN_SETTINGS& bds = aBoard->GetDesignSettings();
  805. trackwidth_menu = new wxMenu;
  806. trackwidth_menu->Append( ID_POPUP_PCB_SELECT_AUTO_WIDTH, _( "Auto Width" ),
  807. _( "Use the track width when starting on a track, otherwise the current track width" ),
  808. true );
  809. if( bds.m_UseConnectedTrackWidth )
  810. trackwidth_menu->Check( ID_POPUP_PCB_SELECT_AUTO_WIDTH, true );
  811. if( bds.GetViaSizeIndex() != 0 || bds.GetTrackWidthIndex() != 0 || bds.m_UseConnectedTrackWidth )
  812. trackwidth_menu->Append( ID_POPUP_PCB_SELECT_USE_NETCLASS_VALUES,
  813. _( "Use Netclass Values" ),
  814. _( "Use track and via sizes from their Netclass values" ),
  815. true );
  816. for( unsigned ii = 0; ii < bds.m_TrackWidthList.size(); ii++ )
  817. {
  818. wxString value = StringFromValue( aUnits, bds.m_TrackWidthList[ii], true );
  819. msg.Printf( _( "Track %s" ), GetChars( value ) );
  820. if( ii == 0 )
  821. msg << _( " uses NetClass" );
  822. trackwidth_menu->Append( ID_POPUP_PCB_SELECT_WIDTH1 + ii, msg, wxEmptyString, true );
  823. }
  824. trackwidth_menu->AppendSeparator();
  825. for( unsigned ii = 0; ii < bds.m_ViasDimensionsList.size(); ii++ )
  826. {
  827. wxString value = StringFromValue( aUnits, bds.m_ViasDimensionsList[ii].m_Diameter, true );
  828. wxString drill = StringFromValue( aUnits, bds.m_ViasDimensionsList[ii].m_Drill, true );
  829. if( bds.m_ViasDimensionsList[ii].m_Drill <= 0 )
  830. {
  831. msg.Printf( _( "Via %s" ), GetChars( value ) );
  832. }
  833. else
  834. {
  835. msg.Printf( _( "Via %s, drill %s" ), GetChars( value ), GetChars( drill ) );
  836. }
  837. if( ii == 0 )
  838. msg << _( " uses NetClass" );
  839. trackwidth_menu->Append( ID_POPUP_PCB_SELECT_VIASIZE1 + ii, msg, wxEmptyString, true );
  840. }
  841. return trackwidth_menu;
  842. }