diff --git a/pcbnew/router/pns_tool_base.h b/pcbnew/router/pns_tool_base.h index d93b8e1f12..e885546059 100644 --- a/pcbnew/router/pns_tool_base.h +++ b/pcbnew/router/pns_tool_base.h @@ -67,6 +67,7 @@ protected: virtual void updateStartItem( const TOOL_EVENT& aEvent, bool aIgnorePads = false ); virtual void updateEndItem( const TOOL_EVENT& aEvent ); +protected: SIZES_SETTINGS m_savedSizes; // Stores sizes settings between router invocations ITEM* m_startItem; VECTOR2I m_startSnapPoint; diff --git a/pcbnew/router/router_tool.cpp b/pcbnew/router/router_tool.cpp index 6a007d21f2..56908c0988 100644 --- a/pcbnew/router/router_tool.cpp +++ b/pcbnew/router/router_tool.cpp @@ -239,7 +239,8 @@ ROUTER_TOOL::ROUTER_TOOL() : TOOL_BASE( "pcbnew.InteractiveRouter" ), m_lastTargetLayer( UNDEFINED_LAYER ), m_originalActiveLayer( UNDEFINED_LAYER ), - m_inRouterTool( false ) + m_inRouterTool( false ), + m_inRouteSelected( false ) { } @@ -530,6 +531,12 @@ bool ROUTER_TOOL::Init() return !m_router->RoutingInProgress(); }; + auto inRouteSelected = + [this]( const SELECTION& ) + { + return m_inRouteSelected; + }; + auto hasOtherEnd = [this]( const SELECTION& ) { @@ -548,6 +555,7 @@ bool ROUTER_TOOL::Init() }; menu.AddItem( ACTIONS::cancelInteractive, SELECTION_CONDITIONS::ShowAlways, 1 ); + menu.AddItem( PCB_ACTIONS::cancelCurrentItem, inRouteSelected, 1 ); menu.AddSeparator( 1 ); menu.AddItem( PCB_ACTIONS::clearHighlight, haveHighlight, 2 ); @@ -1583,10 +1591,11 @@ void ROUTER_TOOL::performRouting( VECTOR2D aStartPosition ) m_router->FixRoute( m_endSnapPoint, m_endItem, forceFinish, forceCommit ); break; } - else if( evt->IsCancelInteractive() || evt->IsActivate() + else if( evt->IsCancelInteractive() || evt->IsAction( &PCB_ACTIONS::cancelCurrentItem ) + || evt->IsActivate() || evt->IsAction( &PCB_ACTIONS::routerInlineDrag ) ) { - if( evt->IsCancelInteractive() && !m_router->RoutingInProgress() ) + if( evt->IsCancelInteractive() && ( m_inRouteSelected || !m_router->RoutingInProgress() ) ) m_cancelled = true; if( evt->IsActivate() && !evt->IsMoveTool() ) @@ -1739,6 +1748,8 @@ int ROUTER_TOOL::RouteSelected( const TOOL_EVENT& aEvent ) }; Activate(); + m_inRouteSelected = true; + // Must be done after Activate() so that it gets set into the correct context controls->ShowCursor( true ); controls->ForceCursorPosition( false ); @@ -1765,6 +1776,7 @@ int ROUTER_TOOL::RouteSelected( const TOOL_EVENT& aEvent ) // For putting sequential tracks that successfully autoroute into one undo commit bool groupStart = true; + m_cancelled = false; for( BOARD_CONNECTED_ITEM* item : itemList ) { @@ -1829,15 +1841,22 @@ int ROUTER_TOOL::RouteSelected( const TOOL_EVENT& aEvent ) // Start interactive routing. Will automatically finish if possible. performRouting( VECTOR2D() ); + if( m_cancelled ) + break; + // Route didn't complete automatically, need to a new undo commit // for the next line so those can group as far as they autoroute if( !autoRouted ) groupStart = true; } + + if( m_cancelled ) + break; } m_iface->SetCommitFlags( 0 ); frame->PopTool( pushedEvent ); + m_inRouteSelected = false; return 0; } @@ -2083,7 +2102,8 @@ void ROUTER_TOOL::performDragging( int aMode ) { m_menu->ShowContextMenu( selection() ); } - else if( evt->IsCancelInteractive() || evt->IsActivate() ) + else if( evt->IsCancelInteractive() || evt->IsAction( &PCB_ACTIONS::cancelCurrentItem ) + || evt->IsActivate() ) { if( evt->IsCancelInteractive() && !m_startItem ) m_cancelled = true; @@ -2517,7 +2537,8 @@ int ROUTER_TOOL::InlineDrag( const TOOL_EVENT& aEvent ) { setCursor(); - if( evt->IsCancelInteractive() || evt->IsActivate() ) + if( evt->IsCancelInteractive() || evt->IsAction( &PCB_ACTIONS::cancelCurrentItem ) + || evt->IsActivate() ) { if( wasLocked ) item->SetLocked( true ); diff --git a/pcbnew/router/router_tool.h b/pcbnew/router/router_tool.h index 0b7f6f23ef..15ad65ef7e 100644 --- a/pcbnew/router/router_tool.h +++ b/pcbnew/router/router_tool.h @@ -103,6 +103,7 @@ private: PCB_LAYER_ID m_originalActiveLayer; bool m_inRouterTool; // Re-entrancy guard + bool m_inRouteSelected; }; #endif diff --git a/pcbnew/tools/pcb_actions.cpp b/pcbnew/tools/pcb_actions.cpp index 98ecc44515..59b043545a 100644 --- a/pcbnew/tools/pcb_actions.cpp +++ b/pcbnew/tools/pcb_actions.cpp @@ -2670,6 +2670,12 @@ TOOL_ACTION PCB_ACTIONS::routerAutorouteSelected( TOOL_ACTION_ARGS() .Flags( AF_ACTIVATE ) .Parameter( PNS::PNS_MODE_ROUTE_SINGLE ) ); +TOOL_ACTION PCB_ACTIONS::cancelCurrentItem( TOOL_ACTION_ARGS() + .Name( "pcbnew.InteractiveRouter.CancelCurrentItem" ) + .Scope( AS_GLOBAL ) + .FriendlyName( _( "Cancel Current Item" ) ) + .Tooltip( _( "Skip current item and route next selected item." ) ) ); + TOOL_ACTION PCB_ACTIONS::breakTrack( TOOL_ACTION_ARGS() .Name( "pcbnew.InteractiveRouter.BreakTrack" ) .Scope( AS_GLOBAL ) diff --git a/pcbnew/tools/pcb_actions.h b/pcbnew/tools/pcb_actions.h index 5344270ca6..9e4c66aad2 100644 --- a/pcbnew/tools/pcb_actions.h +++ b/pcbnew/tools/pcb_actions.h @@ -270,6 +270,7 @@ public: static TOOL_ACTION routerRouteSelected; static TOOL_ACTION routerRouteSelectedFromEnd; static TOOL_ACTION routerAutorouteSelected; + static TOOL_ACTION cancelCurrentItem; /// Activation of the Push and Shove settings dialogs static TOOL_ACTION routerSettingsDialog;