Don't allow reentrancy into PlaceFootprint.

Fixes https://gitlab.com/kicad/code/kicad/issues/9269
This commit is contained in:
Jeff Young 2021-09-29 16:39:43 +01:00
parent 9cf9abbd66
commit 0438a45176
4 changed files with 36 additions and 6 deletions

View File

@ -35,6 +35,7 @@
#include <dialogs/dialog_text_entry.h>
#include <tool/tool_manager.h>
#include <tools/pcb_actions.h>
#include <tools/board_editor_control.h>
#include <board.h>
#include <footprint.h>
#include <board_commit.h>
@ -869,6 +870,7 @@ bool FOOTPRINT_EDIT_FRAME::SaveFootprintToBoard( bool aAddNew )
// update footprint in the current board,
// not just add it to the board with total disregard for the netlist...
PCB_EDIT_FRAME* pcbframe = (PCB_EDIT_FRAME*) Kiway().Player( FRAME_PCB_EDITOR, false );
TOOL_MANAGER* toolMgr = pcbframe->GetToolManager();
if( pcbframe == nullptr ) // happens when the board editor is not active (or closed)
{
@ -902,8 +904,14 @@ bool FOOTPRINT_EDIT_FRAME::SaveFootprintToBoard( bool aAddNew )
return false;
}
if( aAddNew && toolMgr->GetTool<BOARD_EDITOR_CONTROL>()->PlacingFootprint() )
{
DisplayError( this, _( "Previous footprint placement still in progress." ) );
return false;
}
m_toolManager->RunAction( PCB_ACTIONS::selectionClear, true );
pcbframe->GetToolManager()->RunAction( PCB_ACTIONS::selectionClear, true );
toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
BOARD_COMMIT commit( pcbframe );
// Create a copy for the board, first using Clone() to keep existing Uuids, and then either
@ -950,7 +958,7 @@ bool FOOTPRINT_EDIT_FRAME::SaveFootprintToBoard( bool aAddNew )
commit.Push( wxT( "Insert footprint" ) );
pcbframe->Raise();
pcbframe->GetToolManager()->RunAction( PCB_ACTIONS::placeFootprint, true, newFootprint );
toolMgr->RunAction( PCB_ACTIONS::placeFootprint, true, newFootprint );
}
newFootprint->ClearFlags();

View File

@ -54,6 +54,7 @@
#include <tools/pcb_control.h>
#include <tools/pcb_picker_tool.h>
#include <tools/pcb_selection_tool.h>
#include <tools/board_editor_control.h>
#include <wildcards_and_files_ext.h>
#include <wx/listbox.h>
#include <wx/srchctrl.h>
@ -712,7 +713,15 @@ void FOOTPRINT_VIEWER_FRAME::AddFootprintToPCB( wxCommandEvent& aEvent )
return;
}
pcbframe->GetToolManager()->RunAction( PCB_ACTIONS::selectionClear, true );
TOOL_MANAGER* toolMgr = pcbframe->GetToolManager();
if( toolMgr->GetTool<BOARD_EDITOR_CONTROL>()->PlacingFootprint() )
{
DisplayError( this, _( "Previous footprint placement still in progress." ) );
return;
}
toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
BOARD_COMMIT commit( pcbframe );
// Create the "new" footprint
@ -748,7 +757,7 @@ void FOOTPRINT_VIEWER_FRAME::AddFootprintToPCB( wxCommandEvent& aEvent )
commit.Push( wxT( "Insert footprint" ) );
pcbframe->Raise();
pcbframe->GetToolManager()->RunAction( PCB_ACTIONS::placeFootprint, true, newFootprint );
toolMgr->RunAction( PCB_ACTIONS::placeFootprint, true, newFootprint );
newFootprint->ClearFlags();
}

View File

@ -965,6 +965,7 @@ int BOARD_EDITOR_CONTROL::PlaceFootprint( const TOOL_EVENT& aEvent )
// Prime the pump
if( fp )
{
m_placingFootprint = true;
fp->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) );
m_toolMgr->RunAction( PCB_ACTIONS::selectItem, true, fp );
m_toolMgr->RunAction( ACTIONS::refreshPreview );
@ -1002,12 +1003,15 @@ int BOARD_EDITOR_CONTROL::PlaceFootprint( const TOOL_EVENT& aEvent )
}
fp = nullptr;
m_placingFootprint = false;
};
if( evt->IsCancelInteractive() )
{
if( fp )
{
cleanup();
}
else
{
m_frame->PopTool( tool );
@ -1040,6 +1044,8 @@ int BOARD_EDITOR_CONTROL::PlaceFootprint( const TOOL_EVENT& aEvent )
if( fp == nullptr )
continue;
m_placingFootprint = true;
fp->SetLink( niluuid );
fp->SetFlags(IS_NEW ); // whatever
@ -1072,6 +1078,7 @@ int BOARD_EDITOR_CONTROL::PlaceFootprint( const TOOL_EVENT& aEvent )
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
commit.Push( _( "Place a footprint" ) );
fp = nullptr; // to indicate that there is no footprint that we currently modify
m_placingFootprint = false;
}
}
else if( evt->IsClick( BUT_RIGHT ) )

View File

@ -102,6 +102,11 @@ public:
*/
int PlaceFootprint( const TOOL_EVENT& aEvent );
/**
* Re-entrancy checker for above.
*/
bool PlacingFootprint() const { return m_placingFootprint; }
///< Toggle 'lock' property for selected items.
int ToggleLockSelected( const TOOL_EVENT& aEvent );
@ -129,8 +134,9 @@ private:
private:
PCB_EDIT_FRAME* m_frame;
bool m_inPlaceFootprint; // Re-entrancy guard.
bool m_inPlaceTarget; // Re-entrancy guard.
bool m_inPlaceFootprint; // Re-entrancy guard for tool.
bool m_placingFootprint; // Re-entrancy guard for placement loop.
bool m_inPlaceTarget; // Re-entrancy guard.
std::unique_ptr<KIGFX::ORIGIN_VIEWITEM> m_placeOrigin;