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.

908 lines
35 KiB

17 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
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
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
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
18 years ago
18 years ago
  1. /**************************************************/
  2. /* onrightclick.cpp: Right mouse button functions */
  3. /**************************************************/
  4. #include "fctsys.h"
  5. #include "gr_basic.h"
  6. #include "macros.h"
  7. #include "common.h"
  8. #include "class_drawpanel.h"
  9. #include "confirm.h"
  10. #include "pcbnew.h"
  11. #include "wxPcbStruct.h"
  12. #include "class_board_design_settings.h"
  13. #include "pcbnew_id.h"
  14. #include "hotkeys.h"
  15. #include "collectors.h"
  16. /* Bitmaps */
  17. #include "bitmaps.h"
  18. static wxMenu* Append_Track_Width_List( BOARD* aBoard );
  19. /******************************************************************************/
  20. bool WinEDA_PcbFrame::OnRightClick( const wxPoint& aMousePos, wxMenu* aPopMenu )
  21. /******************************************************************************/
  22. {
  23. wxString msg;
  24. int flags = 0;
  25. bool locate_track = FALSE;
  26. bool BlockActive = (GetScreen()->m_BlockLocate.m_Command != BLOCK_IDLE);
  27. wxClientDC dc( DrawPanel );
  28. BOARD_ITEM* item = GetCurItem();
  29. DrawPanel->m_CanStartBlock = -1; // Avoid to start a block coomand when clicking on menu
  30. // If a command or a block is in progress:
  31. // Put the Cancel command (if needed) and the End command
  32. if( BlockActive )
  33. {
  34. createPopUpBlockMenu( aPopMenu );
  35. aPopMenu->AppendSeparator();
  36. return true;
  37. }
  38. DrawPanel->CursorOff( &dc );
  39. if( m_ID_current_state )
  40. {
  41. if( item && item->m_Flags )
  42. {
  43. ADD_MENUITEM( aPopMenu, ID_POPUP_CANCEL_CURRENT_COMMAND,
  44. _( "Cancel" ), cancel_xpm );
  45. }
  46. else
  47. {
  48. ADD_MENUITEM( aPopMenu, ID_POPUP_CLOSE_CURRENT_TOOL,
  49. _( "End Tool" ), cancel_tool_xpm );
  50. }
  51. aPopMenu->AppendSeparator();
  52. }
  53. else
  54. {
  55. if( item && item->m_Flags )
  56. {
  57. ADD_MENUITEM( aPopMenu, ID_POPUP_CANCEL_CURRENT_COMMAND,
  58. _( "Cancel" ), cancel_xpm );
  59. aPopMenu->AppendSeparator();
  60. }
  61. }
  62. /* Select a proper item */
  63. wxPoint cursorPos = GetScreen()->m_Curseur;
  64. wxPoint selectPos = m_Collector->GetRefPos();
  65. PutOnGrid( &selectPos );
  66. /* We can reselect another item only if there are no item being edited
  67. * because ALL moving functions use GetCurItem(), therefore GetCurItem()
  68. * must return the same item during moving. We know an item is moving
  69. * if( item && (item->m_Flags != 0)) is true and after calling
  70. * PcbGeneralLocateAndDisplay(), GetCurItem() is any arbitrary BOARD_ITEM,
  71. * not the current item being edited. In such case we cannot call
  72. * PcbGeneralLocateAndDisplay().
  73. */
  74. if( !item || (item->m_Flags == 0) )
  75. {
  76. // show "item selector" menu only if no item now or selected item was not
  77. // previously picked at this position
  78. if( !item || cursorPos != selectPos )
  79. {
  80. DrawPanel->m_AbortRequest = false;
  81. item = PcbGeneralLocateAndDisplay();
  82. if( DrawPanel->m_AbortRequest )
  83. {
  84. DrawPanel->CursorOn( &dc );
  85. return false;
  86. }
  87. }
  88. }
  89. item = GetCurItem();
  90. if( item )
  91. flags = item->m_Flags;
  92. else
  93. flags = 0;
  94. if( item )
  95. {
  96. switch( item->Type() )
  97. {
  98. case TYPE_MODULE:
  99. createPopUpMenuForFootprints( (MODULE*) item, aPopMenu );
  100. if( m_HTOOL_current_state == ID_TOOLBARH_PCB_MODE_MODULE )
  101. {
  102. aPopMenu->AppendSeparator();
  103. if( !( (MODULE*) item )->IsLocked() )
  104. {
  105. msg = AddHotkeyName( _(
  106. "Lock Module" ), s_Board_Editor_Hokeys_Descr,
  107. HK_LOCK_UNLOCK_FOOTPRINT );
  108. ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_AUTOPLACE_FIXE_MODULE, msg,
  109. locked_xpm );
  110. }
  111. else
  112. {
  113. msg = AddHotkeyName( _(
  114. "Unlock Module" ), s_Board_Editor_Hokeys_Descr,
  115. HK_LOCK_UNLOCK_FOOTPRINT );
  116. ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_AUTOPLACE_FREE_MODULE, msg,
  117. unlocked_xpm );
  118. }
  119. if( !flags )
  120. aPopMenu->Append( ID_POPUP_PCB_AUTOPLACE_CURRENT_MODULE,
  121. _( "Auto Place Module" ) );
  122. }
  123. if( m_HTOOL_current_state == ID_TOOLBARH_PCB_MODE_TRACKS )
  124. {
  125. if( !flags )
  126. aPopMenu->Append( ID_POPUP_PCB_AUTOROUTE_MODULE, _( "Autoroute Module" ) );
  127. }
  128. break;
  129. case TYPE_PAD:
  130. createPopUpMenuForFpPads( (D_PAD*) item, aPopMenu );
  131. break;
  132. case TYPE_TEXTE_MODULE:
  133. createPopUpMenuForFpTexts( (TEXTE_MODULE*) item, aPopMenu );
  134. break;
  135. case TYPE_DRAWSEGMENT: // Some graphic items on technical layers
  136. if( (flags & IS_NEW) )
  137. {
  138. ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_STOP_CURRENT_DRAWING,
  139. _( "End Drawing" ), apply_xpm );
  140. }
  141. if( !flags )
  142. {
  143. msg = AddHotkeyName( _( "Move Drawing" ), s_Board_Editor_Hokeys_Descr, HK_MOVE_ITEM );
  144. ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_MOVE_DRAWING_REQUEST,
  145. msg, move_xpm );
  146. ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_EDIT_DRAWING, _( "Edit Drawing" ), edit_xpm );
  147. ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_DELETE_DRAWING, _(
  148. "Delete Drawing" ), delete_xpm );
  149. if( item->GetLayer() > LAST_COPPER_LAYER )
  150. ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_DELETE_DRAWING_LAYER,
  151. _( "Delete All Drawing on Layer" ), delete_body_xpm );
  152. }
  153. break;
  154. case TYPE_ZONE: // Item used to fill a zone
  155. ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_DELETE_ZONE,
  156. _( "Delete Zone Filling" ), delete_xpm );
  157. break;
  158. case TYPE_ZONE_CONTAINER: // Item used to handle a zone area (outlines, holes ...)
  159. if( flags & IS_NEW )
  160. {
  161. ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_STOP_CURRENT_EDGE_ZONE,
  162. _( "Close Zone Outline" ), apply_xpm );
  163. ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_DELETE_ZONE_LAST_CREATED_CORNER,
  164. _( "Delete Last Corner" ), delete_xpm );
  165. }
  166. else
  167. createPopUpMenuForZones( (ZONE_CONTAINER*) item, aPopMenu );
  168. break;
  169. case TYPE_TEXTE:
  170. createPopUpMenuForTexts( (TEXTE_PCB*) item, aPopMenu );
  171. break;
  172. case TYPE_TRACK:
  173. case TYPE_VIA:
  174. locate_track = true;
  175. createPopupMenuForTracks( (TRACK*) item, aPopMenu );
  176. break;
  177. case TYPE_MARKER_PCB:
  178. createPopUpMenuForMarkers( (MARKER_PCB*) item, aPopMenu );
  179. break;
  180. case TYPE_DIMENSION:
  181. if( !flags )
  182. {
  183. msg = AddHotkeyName( _( "Edit Dimension" ), s_Board_Editor_Hokeys_Descr, HK_EDIT_ITEM );
  184. ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_EDIT_DIMENSION,
  185. msg, edit_xpm );
  186. ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_DELETE_DIMENSION,
  187. _( "Delete Dimension" ), delete_xpm );
  188. }
  189. break;
  190. case TYPE_MIRE:
  191. if( !flags )
  192. {
  193. msg = AddHotkeyName( _( "Move Target" ), s_Board_Editor_Hokeys_Descr, HK_MOVE_ITEM );
  194. ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_MOVE_MIRE_REQUEST, msg, move_xpm );
  195. msg = AddHotkeyName( _( "Edit Target" ), s_Board_Editor_Hokeys_Descr, HK_EDIT_ITEM );
  196. ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_EDIT_MIRE,
  197. msg, edit_xpm );
  198. ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_DELETE_MIRE,
  199. _( "Delete Target" ), delete_xpm );
  200. }
  201. break;
  202. case TYPE_EDGE_MODULE:
  203. case TYPE_SCREEN:
  204. case TYPE_NOT_INIT:
  205. case TYPE_PCB:
  206. msg.Printf(
  207. wxT( "WinEDA_PcbFrame::OnRightClick() Error: unexpected DrawType %d" ),
  208. item->Type() );
  209. DisplayError( this, msg );
  210. SetCurItem( NULL );
  211. break;
  212. default:
  213. msg.Printf(
  214. wxT( "WinEDA_PcbFrame::OnRightClick() Error: unknown DrawType %d" ),
  215. item->Type() );
  216. DisplayError( this, msg );
  217. // Attempt to clear error (but should no occurs )
  218. if( item->Type() >= MAX_STRUCT_TYPE_ID )
  219. SetCurItem( NULL );
  220. break;
  221. }
  222. aPopMenu->AppendSeparator();
  223. }
  224. if( !flags )
  225. {
  226. msg = AddHotkeyName( _( "Get and Move Footprint" ),
  227. s_Board_Editor_Hokeys_Descr, HK_GET_AND_MOVE_FOOTPRINT );
  228. ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_GET_AND_MOVE_MODULE_REQUEST,
  229. msg, move_module_xpm );
  230. }
  231. /* Display context sensitive comands: */
  232. switch( m_ID_current_state )
  233. {
  234. case ID_PCB_ZONES_BUTT:
  235. if( GetBoard()->m_ZoneDescriptorList.size() > 0 )
  236. {
  237. aPopMenu->AppendSeparator();
  238. ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_FILL_ALL_ZONES,
  239. _( "Fill or Refill All Zones" ), fill_zone_xpm );
  240. ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_REMOVE_FILLED_AREAS_IN_ALL_ZONES,
  241. _( "Remove Filled Areas in All Zones" ), fill_zone_xpm );
  242. aPopMenu->AppendSeparator();
  243. }
  244. ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_SELECT_LAYER,
  245. _( "Select Working Layer" ), select_w_layer_xpm );
  246. aPopMenu->AppendSeparator();
  247. break;
  248. case ID_TRACK_BUTT:
  249. if ( ! locate_track ) // This menu is already added when a track is located
  250. ADD_MENUITEM_WITH_SUBMENU( aPopMenu, Append_Track_Width_List( GetBoard() ),
  251. ID_POPUP_PCB_SELECT_WIDTH,
  252. _( "Select Track Width" ), width_track_xpm );
  253. ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_SELECT_CU_LAYER,
  254. _( "Select Working Layer" ), select_w_layer_xpm );
  255. ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_SELECT_LAYER_PAIR,
  256. _( "Select Layer Pair for Vias" ), select_layer_pair_xpm );
  257. aPopMenu->AppendSeparator();
  258. break;
  259. case ID_PCB_CIRCLE_BUTT:
  260. case ID_PCB_ARC_BUTT:
  261. case ID_PCB_ADD_TEXT_BUTT:
  262. case ID_PCB_ADD_LINE_BUTT:
  263. case ID_PCB_DIMENSION_BUTT:
  264. ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_SELECT_NO_CU_LAYER,
  265. _( "Select Working Layer" ), select_w_layer_xpm );
  266. aPopMenu->AppendSeparator();
  267. break;
  268. case ID_COMPONENT_BUTT:
  269. ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_DISPLAY_FOOTPRINT_DOC,
  270. _( "Footprint Documentation" ), book_xpm );
  271. aPopMenu->AppendSeparator();
  272. break;
  273. case 0:
  274. if( m_HTOOL_current_state == ID_TOOLBARH_PCB_MODE_MODULE )
  275. {
  276. wxMenu* commands = new wxMenu;
  277. ADD_MENUITEM_WITH_SUBMENU( aPopMenu, commands,
  278. ID_POPUP_PCB_AUTOPLACE_COMMANDS, _(
  279. "Glob Move and Place" ), move_xpm );
  280. ADD_MENUITEM( commands, ID_POPUP_PCB_AUTOPLACE_FREE_ALL_MODULES,
  281. _( "Unlock All Modules" ), unlocked_xpm );
  282. ADD_MENUITEM( commands, ID_POPUP_PCB_AUTOPLACE_FIXE_ALL_MODULES,
  283. _( "Lock All Modules" ), locked_xpm );
  284. commands->AppendSeparator();
  285. ADD_MENUITEM( commands, ID_POPUP_PCB_AUTOMOVE_ALL_MODULES,
  286. _( "Move All Modules" ), move_xpm );
  287. commands->Append( ID_POPUP_PCB_AUTOMOVE_NEW_MODULES, _( "Move New Modules" ) );
  288. commands->AppendSeparator();
  289. commands->Append( ID_POPUP_PCB_AUTOPLACE_ALL_MODULES, _( "Autoplace All Modules" ) );
  290. commands->Append( ID_POPUP_PCB_AUTOPLACE_NEW_MODULES, _( "Autoplace New Modules" ) );
  291. commands->Append( ID_POPUP_PCB_AUTOPLACE_NEXT_MODULE, _( "Autoplace Next Module" ) );
  292. commands->AppendSeparator();
  293. ADD_MENUITEM( commands, ID_POPUP_PCB_REORIENT_ALL_MODULES,
  294. _( "Orient All Modules" ), rotate_module_pos_xpm );
  295. aPopMenu->AppendSeparator();
  296. }
  297. if( m_HTOOL_current_state == ID_TOOLBARH_PCB_MODE_TRACKS )
  298. {
  299. wxMenu* commands = new wxMenu;
  300. aPopMenu->Append( ID_POPUP_PCB_AUTOROUTE_COMMANDS, _( "Autoroute" ), commands );
  301. ADD_MENUITEM( commands, ID_POPUP_PCB_SELECT_LAYER_PAIR,
  302. _( "Select Layer Pair" ), select_layer_pair_xpm );
  303. commands->AppendSeparator();
  304. commands->Append( ID_POPUP_PCB_AUTOROUTE_ALL_MODULES, _( "Autoroute All Modules" ) );
  305. commands->AppendSeparator();
  306. commands->Append( ID_POPUP_PCB_AUTOROUTE_RESET_UNROUTED, _( "Reset Unrouted" ) );
  307. aPopMenu->AppendSeparator();
  308. }
  309. if( locate_track )
  310. ADD_MENUITEM_WITH_SUBMENU( aPopMenu, Append_Track_Width_List( GetBoard() ),
  311. ID_POPUP_PCB_SELECT_WIDTH, _( "Select Track Width" ),
  312. width_track_xpm );
  313. ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_SELECT_LAYER,
  314. _( "Select Working Layer" ), select_w_layer_xpm );
  315. aPopMenu->AppendSeparator();
  316. break;
  317. }
  318. DrawPanel->CursorOn( &dc );
  319. return true;
  320. }
  321. /*********************************************************/
  322. void WinEDA_PcbFrame::createPopUpBlockMenu( wxMenu* menu )
  323. /*********************************************************/
  324. /* Create Pop sub menu for block commands
  325. */
  326. {
  327. ADD_MENUITEM( menu, ID_POPUP_CANCEL_CURRENT_COMMAND,
  328. _( "Cancel Block" ), cancel_xpm );
  329. ADD_MENUITEM( menu, ID_POPUP_ZOOM_BLOCK,
  330. _( "Zoom Block" ), zoom_selected_xpm );
  331. menu->AppendSeparator();
  332. ADD_MENUITEM( menu, ID_POPUP_PLACE_BLOCK,
  333. _( "Place Block" ), apply_xpm );
  334. ADD_MENUITEM( menu, ID_POPUP_COPY_BLOCK,
  335. _( "Copy Block" ), copyblock_xpm );
  336. ADD_MENUITEM( menu, ID_POPUP_FLIP_BLOCK,
  337. _( "Flip Block" ), invert_module_xpm );
  338. ADD_MENUITEM( menu, ID_POPUP_ROTATE_BLOCK,
  339. _( "Rotate Block" ), rotate_pos_xpm );
  340. ADD_MENUITEM( menu, ID_POPUP_DELETE_BLOCK,
  341. _( "Delete Block" ), delete_xpm );
  342. }
  343. /******************************************************************************/
  344. void WinEDA_PcbFrame::createPopupMenuForTracks( TRACK* Track, wxMenu* PopMenu )
  345. /******************************************************************************/
  346. /* Create command lines for a popup menu, for track and via editing
  347. * also update Netclass selection
  348. */
  349. {
  350. wxPoint cursorPosition = GetScreen()->m_Curseur;
  351. wxString msg;
  352. GetBoard()->SetCurrentNetClass( Track->GetNetClassName() );
  353. m_TrackAndViasSizesList_Changed = true;
  354. AuxiliaryToolBar_Update_UI();
  355. int flags = Track->m_Flags;
  356. if( flags == 0 )
  357. {
  358. if( Track->Type() == TYPE_VIA )
  359. {
  360. ADD_MENUITEM( PopMenu, ID_POPUP_PCB_MOVE_TRACK_NODE, _( "Drag Via" ), move_xpm );
  361. }
  362. else
  363. {
  364. if( Track->IsPointOnEnds( cursorPosition, -1 ) != 0 )
  365. {
  366. msg = AddHotkeyName( _( "Move Node" ), s_Board_Editor_Hokeys_Descr, HK_MOVE_ITEM );
  367. ADD_MENUITEM( PopMenu, ID_POPUP_PCB_MOVE_TRACK_NODE,
  368. msg, move_xpm );
  369. }
  370. else
  371. {
  372. ADD_MENUITEM( PopMenu, ID_POPUP_PCB_DRAG_TRACK_SEGMENT_KEEP_SLOPE,
  373. _( "Drag Segments, Keep Slope" ), drag_segment_withslope_xpm );
  374. msg = AddHotkeyName( _( "Drag Segment" ), s_Board_Editor_Hokeys_Descr, HK_DRAG_ITEM );
  375. ADD_MENUITEM( PopMenu, ID_POPUP_PCB_DRAG_TRACK_SEGMENT,
  376. msg, drag_track_segment_xpm );
  377. ADD_MENUITEM( PopMenu, ID_POPUP_PCB_BREAK_TRACK,
  378. _( "Break Track" ), break_line_xpm );
  379. }
  380. }
  381. }
  382. else if( flags & IS_DRAGGED ) // Drag via or node in progress
  383. {
  384. ADD_MENUITEM( PopMenu, ID_POPUP_PCB_PLACE_MOVED_TRACK_NODE,
  385. _( "Place Node" ), apply_xpm );
  386. return;
  387. }
  388. else // Edition in progress
  389. {
  390. if( flags & IS_NEW )
  391. {
  392. msg = AddHotkeyName( _( "End Track" ), s_Board_Editor_Hokeys_Descr, HK_END_TRACK );
  393. ADD_MENUITEM( PopMenu, ID_POPUP_PCB_END_TRACK, msg, apply_xpm );
  394. }
  395. msg = AddHotkeyName( _( "Place Via" ), s_Board_Editor_Hokeys_Descr, HK_ADD_VIA );
  396. PopMenu->Append( ID_POPUP_PCB_PLACE_VIA, msg );
  397. msg = AddHotkeyName( _( "Switch Track Posture" ), s_Board_Editor_Hokeys_Descr, HK_SWITCH_TRACK_POSTURE );
  398. PopMenu->Append( ID_POPUP_PCB_SWITCH_TRACK_POSTURE, msg );
  399. // See if we can place a Micro Via (4 or more layers, and start from an external layer):
  400. if( IsMicroViaAcceptable() )
  401. {
  402. msg = AddHotkeyName( _(
  403. "Place Micro Via" ), s_Board_Editor_Hokeys_Descr,
  404. HK_ADD_MICROVIA );
  405. PopMenu->Append( ID_POPUP_PCB_PLACE_MICROVIA, msg );
  406. }
  407. }
  408. // track Width control :
  409. if( !flags )
  410. {
  411. if( Track->Type() == TYPE_VIA )
  412. {
  413. ADD_MENUITEM( PopMenu, ID_POPUP_PCB_EDIT_TRACKSEG, _(
  414. "Change Via Size and Drill" ), width_segment_xpm );
  415. }
  416. else
  417. {
  418. msg = AddHotkeyName( _( "Change Segment Width" ), s_Board_Editor_Hokeys_Descr, HK_EDIT_ITEM );
  419. ADD_MENUITEM( PopMenu, ID_POPUP_PCB_EDIT_TRACKSEG,
  420. msg, width_segment_xpm );
  421. ADD_MENUITEM( PopMenu, ID_POPUP_PCB_EDIT_TRACK,
  422. _( "Change Track Width" ), width_track_xpm );
  423. }
  424. ADD_MENUITEM_WITH_SUBMENU( PopMenu, Append_Track_Width_List( GetBoard() ),
  425. ID_POPUP_PCB_SELECT_WIDTH,
  426. _( "Select Track Width" ), width_track_xpm );
  427. }
  428. else // Allows switching to an other track/via size when routing
  429. {
  430. ADD_MENUITEM_WITH_SUBMENU( PopMenu, Append_Track_Width_List( GetBoard() ),
  431. ID_POPUP_PCB_SELECT_WIDTH,
  432. _( "Select Track Width" ), width_track_xpm );
  433. }
  434. // Delete control:
  435. PopMenu->AppendSeparator();
  436. wxMenu* track_mnu = new wxMenu;
  437. ADD_MENUITEM_WITH_SUBMENU( PopMenu, track_mnu,
  438. ID_POPUP_PCB_DELETE_TRACK_MNU, _( "Delete" ), delete_xpm );
  439. msg = AddHotkeyName( Track->Type()==TYPE_VIA ?
  440. _( "Delete Via" ) : _( "Delete Segment" ),
  441. s_Board_Editor_Hokeys_Descr, HK_BACK_SPACE );
  442. ADD_MENUITEM( track_mnu, ID_POPUP_PCB_DELETE_TRACKSEG,
  443. msg, delete_line_xpm );
  444. if( !flags )
  445. {
  446. msg = AddHotkeyName( _( "Delete Track" ), s_Board_Editor_Hokeys_Descr, HK_DELETE );
  447. ADD_MENUITEM( track_mnu, ID_POPUP_PCB_DELETE_TRACK,
  448. msg, delete_track_xpm );
  449. ADD_MENUITEM( track_mnu, ID_POPUP_PCB_DELETE_TRACKNET,
  450. _( "Delete Net" ), delete_net_xpm );
  451. }
  452. // Add global edition command
  453. if( !flags )
  454. {
  455. PopMenu->AppendSeparator();
  456. ADD_MENUITEM( PopMenu, ID_POPUP_PCB_EDIT_ALL_VIAS_AND_TRACK_SIZE,
  457. _( "Global Tracks and Vias Edition" ), width_track_via_xpm );
  458. }
  459. // Add lock/unlock flags menu:
  460. track_mnu = new wxMenu;
  461. ADD_MENUITEM_WITH_SUBMENU( PopMenu, track_mnu,
  462. ID_POPUP_PCB_SETFLAGS_TRACK_MNU, _( "Set Flags" ), flag_xpm );
  463. track_mnu->Append( ID_POPUP_PCB_LOCK_ON_TRACKSEG, _( "Locked: Yes" ), wxEmptyString, true );
  464. track_mnu->Append( ID_POPUP_PCB_LOCK_OFF_TRACKSEG, _( "Locked: No" ), wxEmptyString, true );
  465. if( Track->GetState( SEGM_FIXE ) )
  466. track_mnu->Check( ID_POPUP_PCB_LOCK_ON_TRACKSEG, true );
  467. else
  468. track_mnu->Check( ID_POPUP_PCB_LOCK_OFF_TRACKSEG, true );
  469. if( !flags )
  470. {
  471. track_mnu->Append( ID_POPUP_PCB_LOCK_ON_TRACK, _( "Track Locked: Yes" ) );
  472. track_mnu->Append( ID_POPUP_PCB_LOCK_OFF_TRACK, _( "Track Locked: No" ) );
  473. track_mnu->AppendSeparator();
  474. track_mnu->Append( ID_POPUP_PCB_LOCK_ON_NET, _( "Net Locked: Yes" ) );
  475. track_mnu->Append( ID_POPUP_PCB_LOCK_OFF_NET, _( "Net Locked: No" ) );
  476. }
  477. }
  478. /********************************************************************************************/
  479. void WinEDA_PcbFrame::createPopUpMenuForZones( ZONE_CONTAINER* edge_zone, wxMenu* aPopMenu )
  480. /********************************************************************************************/
  481. /* Create the wxMenuitem list for zone outlines editing and zone filling
  482. */
  483. {
  484. wxString msg;
  485. if( edge_zone->m_Flags == IS_DRAGGED )
  486. {
  487. ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_PLACE_DRAGGED_ZONE_OUTLINE_SEGMENT,
  488. _( "Place Edge Outline" ), apply_xpm );
  489. }
  490. else if( edge_zone->m_Flags )
  491. {
  492. if( (edge_zone->m_Flags & IN_EDIT ) )
  493. ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_PLACE_ZONE_CORNER,
  494. _( "Place Corner" ), apply_xpm );
  495. else
  496. ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_PLACE_ZONE_OUTLINES,
  497. _( "Place Zone" ), apply_xpm );
  498. }
  499. else
  500. {
  501. wxMenu* zones_menu = new wxMenu();
  502. ADD_MENUITEM_WITH_SUBMENU( aPopMenu, zones_menu,
  503. -1, _( "Zones" ), add_zone_xpm );
  504. int index;
  505. if( ( index = edge_zone->HitTestForCorner( GetScreen()->RefPos( true ) ) ) >= 0 )
  506. {
  507. ADD_MENUITEM( zones_menu, ID_POPUP_PCB_MOVE_ZONE_CORNER,
  508. _( "Move Corner" ), move_xpm );
  509. ADD_MENUITEM( zones_menu, ID_POPUP_PCB_DELETE_ZONE_CORNER,
  510. _( "Delete Corner" ), delete_xpm );
  511. }
  512. else if( ( index = edge_zone->HitTestForEdge( GetScreen()->RefPos( true ) ) ) >= 0 )
  513. {
  514. ADD_MENUITEM( zones_menu, ID_POPUP_PCB_ADD_ZONE_CORNER,
  515. _( "Create Corner" ), add_corner_xpm );
  516. msg = AddHotkeyName( _( "Drag Outline Segment" ), s_Board_Editor_Hokeys_Descr, HK_DRAG_ITEM );
  517. ADD_MENUITEM( zones_menu, ID_POPUP_PCB_DRAG_ZONE_OUTLINE_SEGMENT,
  518. msg, drag_outline_segment_xpm );
  519. }
  520. zones_menu->AppendSeparator();
  521. ADD_MENUITEM( zones_menu, ID_POPUP_PCB_ZONE_ADD_SIMILAR_ZONE,
  522. _( "Add Similar Zone" ), add_zone_xpm );
  523. ADD_MENUITEM( zones_menu, ID_POPUP_PCB_ZONE_ADD_CUTOUT_ZONE,
  524. _( "Add Cutout Area" ), add_zone_cutout );
  525. zones_menu->AppendSeparator();
  526. ADD_MENUITEM( zones_menu, ID_POPUP_PCB_FILL_ZONE,
  527. _( "Fill Zone" ), fill_zone_xpm );
  528. if( edge_zone->m_FilledPolysList.size() > 0 )
  529. {
  530. ADD_MENUITEM( zones_menu, ID_POPUP_PCB_REMOVE_FILLED_AREAS_IN_CURRENT_ZONE,
  531. _( "Remove Filled Areas in Zone" ), fill_zone_xpm );
  532. }
  533. msg = AddHotkeyName( _( "Move Zone" ), s_Board_Editor_Hokeys_Descr, HK_MOVE_ITEM );
  534. ADD_MENUITEM( zones_menu, ID_POPUP_PCB_MOVE_ZONE_OUTLINES,
  535. msg, move_xpm );
  536. msg = AddHotkeyName( _( "Edit Zone Params" ), s_Board_Editor_Hokeys_Descr, HK_EDIT_ITEM );
  537. ADD_MENUITEM( zones_menu, ID_POPUP_PCB_EDIT_ZONE_PARAMS,
  538. msg, edit_xpm );
  539. zones_menu->AppendSeparator();
  540. if( index >= 0 && edge_zone->m_Poly->IsCutoutContour( edge_zone->m_CornerSelection ) )
  541. ADD_MENUITEM( zones_menu, ID_POPUP_PCB_DELETE_ZONE_CUTOUT,
  542. _( "Delete Cutout" ), delete_xpm );
  543. ADD_MENUITEM( zones_menu, ID_POPUP_PCB_DELETE_ZONE_CONTAINER,
  544. _( "Delete Zone Outline" ), delete_xpm );
  545. }
  546. }
  547. /*********************************************************************************/
  548. void WinEDA_PcbFrame::createPopUpMenuForFootprints( MODULE* aModule, wxMenu* menu )
  549. /*********************************************************************************/
  550. /* Create the wxMenuitem list for footprint editing
  551. */
  552. {
  553. wxMenu* sub_menu_footprint;
  554. int flags = aModule->m_Flags;
  555. wxString msg;
  556. sub_menu_footprint = new wxMenu;
  557. msg = aModule->MenuText( GetBoard() );
  558. ADD_MENUITEM_WITH_SUBMENU( menu, sub_menu_footprint, -1, msg, module_xpm );
  559. if( !flags )
  560. {
  561. msg = AddHotkeyName( _( "Move" ), s_Board_Editor_Hokeys_Descr, HK_MOVE_ITEM );
  562. ADD_MENUITEM( sub_menu_footprint, ID_POPUP_PCB_MOVE_MODULE_REQUEST,
  563. msg, move_module_xpm );
  564. msg = AddHotkeyName( _( "Drag" ), s_Board_Editor_Hokeys_Descr, HK_DRAG_ITEM );
  565. ADD_MENUITEM( sub_menu_footprint, ID_POPUP_PCB_DRAG_MODULE_REQUEST,
  566. msg, drag_module_xpm );
  567. }
  568. msg = AddHotkeyName( _( "Rotate +" ), s_Board_Editor_Hokeys_Descr, HK_ROTATE_ITEM );
  569. ADD_MENUITEM( sub_menu_footprint, ID_POPUP_PCB_ROTATE_MODULE_COUNTERCLOCKWISE,
  570. msg, rotate_module_pos_xpm );
  571. ADD_MENUITEM( sub_menu_footprint, ID_POPUP_PCB_ROTATE_MODULE_CLOCKWISE,
  572. _( "Rotate -" ), rotate_module_neg_xpm );
  573. msg = AddHotkeyName( _( "Flip" ), s_Board_Editor_Hokeys_Descr, HK_FLIP_FOOTPRINT );
  574. ADD_MENUITEM( sub_menu_footprint, ID_POPUP_PCB_CHANGE_SIDE_MODULE,
  575. msg, invert_module_xpm );
  576. if( !flags )
  577. {
  578. msg = AddHotkeyName( _( "Edit" ), s_Board_Editor_Hokeys_Descr, HK_EDIT_ITEM );
  579. ADD_MENUITEM( sub_menu_footprint, ID_POPUP_PCB_EDIT_MODULE,
  580. msg, edit_module_xpm );
  581. sub_menu_footprint->AppendSeparator();
  582. ADD_MENUITEM( sub_menu_footprint, ID_POPUP_PCB_DELETE_MODULE,
  583. _( "Delete Module" ), delete_module_xpm );
  584. }
  585. }
  586. /********************************************************************/
  587. void WinEDA_PcbFrame::createPopUpMenuForFpTexts( TEXTE_MODULE* FpText, wxMenu* menu )
  588. /********************************************************************/
  589. /* Create the wxMenuitem list for editing texts on footprints
  590. */
  591. {
  592. wxMenu* sub_menu_Fp_text;
  593. int flags = FpText->m_Flags;
  594. wxString msg = FpText->MenuText( GetBoard() );
  595. sub_menu_Fp_text = new wxMenu;
  596. ADD_MENUITEM_WITH_SUBMENU( menu, sub_menu_Fp_text, -1, msg, footprint_text_xpm );
  597. if( !flags )
  598. {
  599. msg = AddHotkeyName( _( "Move" ), s_Board_Editor_Hokeys_Descr, HK_MOVE_ITEM );
  600. ADD_MENUITEM( sub_menu_Fp_text, ID_POPUP_PCB_MOVE_TEXTMODULE_REQUEST,
  601. msg, move_field_xpm );
  602. }
  603. msg = AddHotkeyName( _( "Rotate" ), s_Board_Editor_Hokeys_Descr, HK_ROTATE_ITEM );
  604. ADD_MENUITEM( sub_menu_Fp_text, ID_POPUP_PCB_ROTATE_TEXTMODULE,
  605. msg, rotate_field_xpm );
  606. if( !flags )
  607. {
  608. msg = AddHotkeyName( _( "Edit" ), s_Board_Editor_Hokeys_Descr, HK_EDIT_ITEM );
  609. ADD_MENUITEM( sub_menu_Fp_text, ID_POPUP_PCB_EDIT_TEXTMODULE,
  610. msg, edit_text_xpm );
  611. }
  612. if( !flags && FpText->m_Type == TEXT_is_DIVERS ) // Graphic texts can be deleted only if are not currently edited
  613. {
  614. ADD_MENUITEM( sub_menu_Fp_text, ID_POPUP_PCB_DELETE_TEXTMODULE,
  615. _( "Delete" ), delete_xpm );
  616. }
  617. if( !flags )
  618. {
  619. MODULE* module = (MODULE*) FpText->GetParent();
  620. if( module )
  621. {
  622. menu->AppendSeparator();
  623. createPopUpMenuForFootprints( module, menu );
  624. }
  625. }
  626. }
  627. /************************************************************************/
  628. void WinEDA_PcbFrame::createPopUpMenuForFpPads( D_PAD* Pad, wxMenu* menu )
  629. /************************************************************************/
  630. /* Create pop menu for pads
  631. * also update Netclass selection
  632. */
  633. {
  634. wxMenu* sub_menu_Pad;
  635. int flags = Pad->m_Flags;
  636. if( flags ) // Currently in edit, no others commands possible
  637. return;
  638. GetBoard()->SetCurrentNetClass( Pad->GetNetClassName() );
  639. m_TrackAndViasSizesList_Changed = true;
  640. AuxiliaryToolBar_Update_UI();
  641. wxString msg = Pad->MenuText( GetBoard() );
  642. sub_menu_Pad = new wxMenu;
  643. ADD_MENUITEM_WITH_SUBMENU( menu, sub_menu_Pad, -1, msg, pad_xpm );
  644. ADD_MENUITEM( sub_menu_Pad, ID_POPUP_PCB_MOVE_PAD_REQUEST,
  645. _( "Move" ), move_pad_xpm );
  646. ADD_MENUITEM( sub_menu_Pad, ID_POPUP_PCB_DRAG_PAD_REQUEST,
  647. _( "Drag" ), drag_pad_xpm );
  648. ADD_MENUITEM( sub_menu_Pad, ID_POPUP_PCB_EDIT_PAD,
  649. _( "Edit" ), options_pad_xpm );
  650. sub_menu_Pad->AppendSeparator();
  651. ADD_MENUITEM_WITH_HELP( sub_menu_Pad, ID_POPUP_PCB_IMPORT_PAD_SETTINGS,
  652. _( "Copy Current Settings to this Pad" ),
  653. wxEmptyString,
  654. options_new_pad_xpm );
  655. ADD_MENUITEM_WITH_HELP( sub_menu_Pad, ID_POPUP_PCB_EXPORT_PAD_SETTINGS,
  656. _( "Copy this Pad Settings to Current Settings" ),
  657. wxEmptyString,
  658. export_options_pad_xpm );
  659. ADD_MENUITEM_WITH_HELP( sub_menu_Pad, ID_POPUP_PCB_GLOBAL_IMPORT_PAD_SETTINGS,
  660. _( "Global Pads Edition" ),
  661. _( "Copy this pad settings to all pads in this footprint (or similar footprints)" ),
  662. global_options_pad_xpm );
  663. sub_menu_Pad->AppendSeparator();
  664. ADD_MENUITEM( sub_menu_Pad, ID_POPUP_PCB_DELETE_PAD,
  665. _( "Delete" ), delete_pad_xpm );
  666. if( m_HTOOL_current_state == ID_TOOLBARH_PCB_MODE_TRACKS )
  667. {
  668. menu->Append( ID_POPUP_PCB_AUTOROUTE_PAD, _( "Autoroute Pad" ) );
  669. menu->Append( ID_POPUP_PCB_AUTOROUTE_NET, _( "Autoroute Net" ) );
  670. }
  671. MODULE* module = (MODULE*) Pad->GetParent();
  672. if( module )
  673. {
  674. menu->AppendSeparator();
  675. createPopUpMenuForFootprints( module, menu );
  676. }
  677. }
  678. /*****************************************************************************/
  679. void WinEDA_PcbFrame::createPopUpMenuForTexts( TEXTE_PCB* Text, wxMenu* menu )
  680. /*****************************************************************************/
  681. /* Create pop menu for pcb texts */
  682. {
  683. wxMenu* sub_menu_Text;
  684. int flags = Text->m_Flags;
  685. wxString msg = Text->MenuText( GetBoard() );
  686. sub_menu_Text = new wxMenu;
  687. ADD_MENUITEM_WITH_SUBMENU( menu, sub_menu_Text, -1, msg, add_text_xpm );
  688. if( !flags )
  689. {
  690. msg = AddHotkeyName( _( "Move" ), s_Board_Editor_Hokeys_Descr, HK_MOVE_ITEM );
  691. ADD_MENUITEM( sub_menu_Text, ID_POPUP_PCB_MOVE_TEXTEPCB_REQUEST,
  692. msg, move_text_xpm );
  693. }
  694. msg = AddHotkeyName( _( "Rotate" ), s_Board_Editor_Hokeys_Descr, HK_ROTATE_ITEM );
  695. ADD_MENUITEM( sub_menu_Text, ID_POPUP_PCB_ROTATE_TEXTEPCB,
  696. msg, rotate_pos_xpm );
  697. msg = AddHotkeyName( _( "Edit" ), s_Board_Editor_Hokeys_Descr, HK_EDIT_ITEM );
  698. ADD_MENUITEM( sub_menu_Text, ID_POPUP_PCB_EDIT_TEXTEPCB,
  699. msg, edit_text_xpm );
  700. sub_menu_Text->AppendSeparator();
  701. ADD_MENUITEM( sub_menu_Text, ID_POPUP_PCB_DELETE_TEXTEPCB,
  702. _( "Delete" ), delete_text_xpm );
  703. }
  704. /**********************************************************************/
  705. void WinEDA_PcbFrame::createPopUpMenuForMarkers( MARKER_PCB* aMarker, wxMenu* aPopMenu )
  706. /**********************************************************************/
  707. {
  708. ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_DELETE_MARKER, _( "Delete Marker" ), delete_xpm );
  709. ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_GETINFO_MARKER, _( "Marker Error Info" ), info_xpm );
  710. }
  711. /*******************************************************/
  712. static wxMenu* Append_Track_Width_List( BOARD* aBoard )
  713. /*******************************************************/
  714. /** function Append_Track_Width_List
  715. * creates a wxMenu * which shows the last used track widths and via diameters
  716. * @return a pointeur to the menu
  717. */
  718. {
  719. wxString msg;
  720. wxMenu* trackwidth_menu;
  721. wxString value;
  722. trackwidth_menu = new wxMenu;
  723. trackwidth_menu->Append( ID_POPUP_PCB_SELECT_AUTO_WIDTH,
  724. _( "Auto Width" ),
  725. _(
  726. "Use the track width when starting on a track, otherwise the current track width" ),
  727. true );
  728. if( aBoard->GetBoardDesignSettings()->m_UseConnectedTrackWidth )
  729. trackwidth_menu->Check( ID_POPUP_PCB_SELECT_AUTO_WIDTH, true );
  730. if( aBoard->m_ViaSizeSelector != 0
  731. || aBoard->m_TrackWidthSelector != 0
  732. || aBoard->GetBoardDesignSettings()->m_UseConnectedTrackWidth )
  733. trackwidth_menu->Append( ID_POPUP_PCB_SELECT_USE_NETCLASS_VALUES,
  734. _( "Use Netclass Values" ),
  735. _( "Use track and via sizes from their Netclass values" ),
  736. true );
  737. for( unsigned ii = 0; ii < aBoard->m_TrackWidthList.size(); ii++ )
  738. {
  739. value = ReturnStringFromValue( g_UserUnit, aBoard->m_TrackWidthList[ii],
  740. PCB_INTERNAL_UNIT, true );
  741. msg.Printf( _( "Track %s" ), GetChars( value ) );
  742. if( ii == 0 )
  743. msg << _( " (use NetClass)" );
  744. trackwidth_menu->Append( ID_POPUP_PCB_SELECT_WIDTH1 + ii, msg, wxEmptyString, true );
  745. }
  746. if( aBoard->GetBoardDesignSettings()->m_UseConnectedTrackWidth )
  747. trackwidth_menu->Check( ID_POPUP_PCB_SELECT_AUTO_WIDTH, true );
  748. else
  749. {
  750. if( aBoard->m_TrackWidthSelector < aBoard->m_TrackWidthList.size() )
  751. trackwidth_menu->Check( ID_POPUP_PCB_SELECT_WIDTH1 + aBoard->m_TrackWidthSelector,
  752. true );
  753. }
  754. trackwidth_menu->AppendSeparator();
  755. for( unsigned ii = 0; ii < aBoard->m_ViasDimensionsList.size(); ii++ )
  756. {
  757. value = ReturnStringFromValue( g_UserUnit, aBoard->m_ViasDimensionsList[ii].m_Diameter,
  758. PCB_INTERNAL_UNIT, true );
  759. wxString drill = ReturnStringFromValue( g_UserUnit,
  760. aBoard->m_ViasDimensionsList[ii].m_Drill,
  761. PCB_INTERNAL_UNIT, true );
  762. if( aBoard->m_ViasDimensionsList[ii].m_Drill <= 0 )
  763. msg.Printf( _( "Via %s" ), GetChars( value ) );
  764. else
  765. {
  766. msg.Printf( _( "Via %s; (drl %s)" ), GetChars( value ), GetChars( drill ) );
  767. }
  768. if( ii == 0 )
  769. msg << _( " (use NetClass)" );
  770. trackwidth_menu->Append( ID_POPUP_PCB_SELECT_VIASIZE1 + ii, msg, wxEmptyString, true );
  771. }
  772. if( aBoard->m_ViaSizeSelector < aBoard->m_ViasDimensionsList.size() )
  773. trackwidth_menu->Check( ID_POPUP_PCB_SELECT_VIASIZE1 + aBoard->m_ViaSizeSelector, true );
  774. return trackwidth_menu;
  775. }