diff --git a/eeschema/tools/sch_drawing_tools.cpp b/eeschema/tools/sch_drawing_tools.cpp index d905150d84..e337857c87 100644 --- a/eeschema/tools/sch_drawing_tools.cpp +++ b/eeschema/tools/sch_drawing_tools.cpp @@ -353,11 +353,13 @@ int SCH_DRAWING_TOOLS::PlaceSymbol( const TOOL_EVENT& aEvent ) evt->SetPassEvent(); } - // Enable autopanning and cursor capture only when there is a footprint to be placed + // Enable autopanning and cursor capture only when there is a symbol to be placed getViewControls()->SetAutoPan( symbol != nullptr ); getViewControls()->CaptureCursor( symbol != nullptr ); } + getViewControls()->SetAutoPan( false ); + getViewControls()->CaptureCursor( false ); m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW ); m_inPlaceSymbol = false; return 0; @@ -569,11 +571,13 @@ int SCH_DRAWING_TOOLS::PlaceImage( const TOOL_EVENT& aEvent ) evt->SetPassEvent(); } - // Enable autopanning and cursor capture only when there is a footprint to be placed + // Enable autopanning and cursor capture only when there is an image to be placed getViewControls()->SetAutoPan( image != nullptr ); getViewControls()->CaptureCursor( image != nullptr ); } + getViewControls()->SetAutoPan( false ); + getViewControls()->CaptureCursor( false ); m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW ); m_inPlaceImage = false; return 0; @@ -1221,13 +1225,15 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent ) evt->SetPassEvent(); } - // Enable autopanning and cursor capture only when there is a footprint to be placed + // Enable autopanning and cursor capture only when there is an item to be placed controls->SetAutoPan( item != nullptr ); controls->CaptureCursor( item != nullptr ); } - m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW ); + controls->SetAutoPan( false ); + controls->CaptureCursor( false ); controls->ForceCursorPosition( false ); + m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW ); m_inTwoClickPlace = false; return 0; } @@ -1407,6 +1413,8 @@ int SCH_DRAWING_TOOLS::DrawSheet( const TOOL_EVENT& aEvent ) getViewControls()->CaptureCursor( sheet != nullptr ); } + getViewControls()->SetAutoPan( false ); + getViewControls()->CaptureCursor( false ); m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW ); m_inDrawSheet = false; return 0; diff --git a/eeschema/tools/sch_line_wire_bus_tool.cpp b/eeschema/tools/sch_line_wire_bus_tool.cpp index e1517e237f..21c1822800 100644 --- a/eeschema/tools/sch_line_wire_bus_tool.cpp +++ b/eeschema/tools/sch_line_wire_bus_tool.cpp @@ -771,6 +771,8 @@ int SCH_LINE_WIRE_BUS_TOOL::doDrawSegments( const std::string& aTool, int aType, controls->CaptureCursor( segment != nullptr ); } + controls->SetAutoPan( false ); + controls->CaptureCursor( false ); m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW ); controls->ForceCursorPosition( false ); return 0; diff --git a/eeschema/tools/symbol_editor_drawing_tools.cpp b/eeschema/tools/symbol_editor_drawing_tools.cpp index a01708fc8b..c1c888c749 100644 --- a/eeschema/tools/symbol_editor_drawing_tools.cpp +++ b/eeschema/tools/symbol_editor_drawing_tools.cpp @@ -253,6 +253,8 @@ int SYMBOL_EDITOR_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent ) getViewControls()->CaptureCursor( item != nullptr ); } + getViewControls()->SetAutoPan( false ); + getViewControls()->CaptureCursor( false ); m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW ); return 0; } @@ -414,6 +416,8 @@ int SYMBOL_EDITOR_DRAWING_TOOLS::DrawShape( const TOOL_EVENT& aEvent ) getViewControls()->CaptureCursor( item != nullptr ); } + getViewControls()->SetAutoPan( false ); + getViewControls()->CaptureCursor( false ); m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW ); return 0; } diff --git a/pagelayout_editor/tools/pl_drawing_tools.cpp b/pagelayout_editor/tools/pl_drawing_tools.cpp index b4a0456ac5..0b60fd7fd5 100644 --- a/pagelayout_editor/tools/pl_drawing_tools.cpp +++ b/pagelayout_editor/tools/pl_drawing_tools.cpp @@ -212,6 +212,8 @@ int PL_DRAWING_TOOLS::PlaceItem( const TOOL_EVENT& aEvent ) getViewControls()->CaptureCursor( item != nullptr ); } + getViewControls()->SetAutoPan( false ); + getViewControls()->CaptureCursor( false ); m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW ); return 0; } @@ -332,6 +334,8 @@ int PL_DRAWING_TOOLS::DrawShape( const TOOL_EVENT& aEvent ) getViewControls()->CaptureCursor( item != nullptr ); } + getViewControls()->SetAutoPan( false ); + getViewControls()->CaptureCursor( false ); m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW ); m_frame->PopTool( tool ); return 0; diff --git a/pcbnew/tools/board_editor_control.cpp b/pcbnew/tools/board_editor_control.cpp index d7a48cb31b..1c0b3ce2ba 100644 --- a/pcbnew/tools/board_editor_control.cpp +++ b/pcbnew/tools/board_editor_control.cpp @@ -177,7 +177,9 @@ protected: BOARD_EDITOR_CONTROL::BOARD_EDITOR_CONTROL() : PCB_TOOL_BASE( "pcbnew.EditorControl" ), - m_frame( nullptr ) + m_frame( nullptr ), + m_inPlaceFootprint( false ), + m_inPlaceTarget( false ) { m_placeOrigin = std::make_unique<KIGFX::ORIGIN_VIEWITEM>( KIGFX::COLOR4D( 0.8, 0.0, 0.0, 1.0 ), @@ -916,6 +918,11 @@ int BOARD_EDITOR_CONTROL::ViaSizeDec( const TOOL_EVENT& aEvent ) int BOARD_EDITOR_CONTROL::PlaceFootprint( const TOOL_EVENT& aEvent ) { + if( m_inPlaceFootprint ) + return 0; + else + m_inPlaceFootprint = true; + FOOTPRINT* fp = aEvent.Parameter<FOOTPRINT*>(); KIGFX::VIEW_CONTROLS* controls = getViewControls(); BOARD_COMMIT commit( m_frame ); @@ -1073,11 +1080,15 @@ int BOARD_EDITOR_CONTROL::PlaceFootprint( const TOOL_EVENT& aEvent ) } // Enable autopanning and cursor capture only when there is a footprint to be placed - controls->SetAutoPan( !!fp ); - controls->CaptureCursor( !!fp ); + controls->SetAutoPan( fp != nullptr ); + controls->CaptureCursor( fp != nullptr ); } + controls->SetAutoPan( false ); + controls->CaptureCursor( false ); m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW ); + + m_inPlaceFootprint = false; return 0; } @@ -1161,6 +1172,11 @@ int BOARD_EDITOR_CONTROL::modifyLockSelected( MODIFY_MODE aMode ) int BOARD_EDITOR_CONTROL::PlaceTarget( const TOOL_EVENT& aEvent ) { + if( m_inPlaceTarget ) + return 0; + else + m_inPlaceTarget = true; + KIGFX::VIEW* view = getView(); KIGFX::VIEW_CONTROLS* controls = getViewControls(); BOARD* board = getModel<BOARD>(); @@ -1267,6 +1283,8 @@ int BOARD_EDITOR_CONTROL::PlaceTarget( const TOOL_EVENT& aEvent ) view->Remove( &preview ); m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW ); + + m_inPlaceTarget = false; return 0; } diff --git a/pcbnew/tools/board_editor_control.h b/pcbnew/tools/board_editor_control.h index 76682725c1..bba1ebd02d 100644 --- a/pcbnew/tools/board_editor_control.h +++ b/pcbnew/tools/board_editor_control.h @@ -124,9 +124,12 @@ private: ///< Set up handlers for various events. void setTransitions() override; - PCB_EDIT_FRAME* m_frame; ///< Pointer to the currently used edit frame. +private: + PCB_EDIT_FRAME* m_frame; + bool m_inPlaceFootprint; // Re-entrancy guard. + bool m_inPlaceTarget; // Re-entrancy guard. - std::unique_ptr<KIGFX::ORIGIN_VIEWITEM> m_placeOrigin; ///< Place & drill origin marker + std::unique_ptr<KIGFX::ORIGIN_VIEWITEM> m_placeOrigin; static const int WIDTH_STEP; ///< How does line width change after one -/+ key press. }; diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index be13913d66..5ae65d2451 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -157,7 +157,8 @@ DRAWING_TOOL::DRAWING_TOOL() : m_board( nullptr ), m_frame( nullptr ), m_mode( MODE::NONE ), - m_lineWidth( 1 ) + m_lineWidth( 1 ), + m_inDrawingTool( false ) { } @@ -246,6 +247,11 @@ int DRAWING_TOOL::DrawLine( const TOOL_EVENT& aEvent ) if( m_isFootprintEditor && !m_frame->GetModel() ) return 0; + if( m_inDrawingTool ) + return 0; + else + m_inDrawingTool = true; + FOOTPRINT* parentFootprint = dynamic_cast<FOOTPRINT*>( m_frame->GetModel() ); PCB_SHAPE* line = m_isFootprintEditor ? new FP_SHAPE( parentFootprint ) : new PCB_SHAPE; BOARD_COMMIT commit( m_frame ); @@ -283,6 +289,7 @@ int DRAWING_TOOL::DrawLine( const TOOL_EVENT& aEvent ) line->SetFlags( IS_NEW ); } + m_inDrawingTool = false; return 0; } @@ -292,6 +299,11 @@ int DRAWING_TOOL::DrawRectangle( const TOOL_EVENT& aEvent ) if( m_isFootprintEditor && !m_frame->GetModel() ) return 0; + if( m_inDrawingTool ) + return 0; + else + m_inDrawingTool = true; + FOOTPRINT* parentFootprint = dynamic_cast<FOOTPRINT*>( m_frame->GetModel() ); PCB_SHAPE* rect = m_isFootprintEditor ? new FP_SHAPE( parentFootprint ) : new PCB_SHAPE; BOARD_COMMIT commit( m_frame ); @@ -329,6 +341,7 @@ int DRAWING_TOOL::DrawRectangle( const TOOL_EVENT& aEvent ) startingPoint = NULLOPT; } + m_inDrawingTool = false; return 0; } @@ -338,6 +351,11 @@ int DRAWING_TOOL::DrawCircle( const TOOL_EVENT& aEvent ) if( m_isFootprintEditor && !m_frame->GetModel() ) return 0; + if( m_inDrawingTool ) + return 0; + else + m_inDrawingTool = true; + FOOTPRINT* parentFootprint = dynamic_cast<FOOTPRINT*>( m_frame->GetModel() ); PCB_SHAPE* circle = m_isFootprintEditor ? new FP_SHAPE( parentFootprint ) : new PCB_SHAPE; BOARD_COMMIT commit( m_frame ); @@ -375,6 +393,7 @@ int DRAWING_TOOL::DrawCircle( const TOOL_EVENT& aEvent ) startingPoint = NULLOPT; } + m_inDrawingTool = false; return 0; } @@ -384,6 +403,11 @@ int DRAWING_TOOL::DrawArc( const TOOL_EVENT& aEvent ) if( m_isFootprintEditor && !m_frame->GetModel() ) return 0; + if( m_inDrawingTool ) + return 0; + else + m_inDrawingTool = true; + FOOTPRINT* parentFootprint = dynamic_cast<FOOTPRINT*>( m_frame->GetModel() ); PCB_SHAPE* arc = m_isFootprintEditor ? new FP_SHAPE( parentFootprint ) : new PCB_SHAPE; BOARD_COMMIT commit( m_frame ); @@ -416,6 +440,7 @@ int DRAWING_TOOL::DrawArc( const TOOL_EVENT& aEvent ) immediateMode = false; } + m_inDrawingTool = false; return 0; } @@ -425,6 +450,11 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent ) if( m_isFootprintEditor && !m_frame->GetModel() ) return 0; + if( m_inDrawingTool ) + return 0; + else + m_inDrawingTool = true; + BOARD_ITEM* text = NULL; const BOARD_DESIGN_SETTINGS& dsnSettings = m_frame->GetDesignSettings(); BOARD_COMMIT commit( m_frame ); @@ -637,8 +667,12 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent ) } } + m_controls->SetAutoPan( false ); + m_controls->CaptureCursor( false ); m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW ); m_frame->SetMsgPanel( board() ); + + m_inDrawingTool = false; return 0; } @@ -657,6 +691,11 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent ) if( m_isFootprintEditor && !m_frame->GetModel() ) return 0; + if( m_inDrawingTool ) + return 0; + else + m_inDrawingTool = true; + enum DIMENSION_STEPS { SET_ORIGIN = 0, @@ -1080,6 +1119,8 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent ) m_view->Remove( &preview ); m_frame->SetMsgPanel( board() ); + + m_inDrawingTool = false; return 0; } @@ -1089,6 +1130,11 @@ int DRAWING_TOOL::PlaceImportedGraphics( const TOOL_EVENT& aEvent ) if( !m_frame->GetModel() ) return 0; + if( m_inDrawingTool ) + return 0; + else + m_inDrawingTool = true; + // Note: PlaceImportedGraphics() will convert PCB_SHAPE_T and PCB_TEXT_T to footprint // items if needed DIALOG_IMPORT_GFX dlg( m_frame, m_isFootprintEditor ); @@ -1236,7 +1282,10 @@ int DRAWING_TOOL::PlaceImportedGraphics( const TOOL_EVENT& aEvent ) m_view->Remove( &preview ); m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW ); + + m_inDrawingTool = false; m_frame->PopTool( tool ); + return 0; } @@ -1248,6 +1297,11 @@ int DRAWING_TOOL::SetAnchor( const TOOL_EVENT& aEvent ) if( !m_frame->GetModel() ) return 0; + if( m_inDrawingTool ) + return 0; + else + m_inDrawingTool = true; + SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::ANCHOR ); PCB_GRID_HELPER grid( m_toolMgr, m_frame->GetMagneticItemsSettings() ); @@ -1312,6 +1366,8 @@ int DRAWING_TOOL::SetAnchor( const TOOL_EVENT& aEvent ) } m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW ); + + m_inDrawingTool = false; return 0; } diff --git a/pcbnew/tools/drawing_tool.h b/pcbnew/tools/drawing_tool.h index b46628e55e..41f61d02ae 100644 --- a/pcbnew/tools/drawing_tool.h +++ b/pcbnew/tools/drawing_tool.h @@ -269,6 +269,7 @@ private: BOARD* m_board; PCB_BASE_EDIT_FRAME* m_frame; MODE m_mode; + bool m_inDrawingTool; // Re-entrancy guard unsigned int m_lineWidth; // Current line width for multi-segment drawing static const unsigned int WIDTH_STEP; // Amount of width change for one -/+ key press