diff --git a/Documentation/development/tool-framework.md b/Documentation/development/tool-framework.md index 7aae89401d..6211debb08 100644 --- a/Documentation/development/tool-framework.md +++ b/Documentation/development/tool-framework.md @@ -446,18 +446,6 @@ The last step is to register the tool in the tool manager. This is done by adding a new instance of the tool to the `registerAllTools()` function in `pcbnew/tools/tools_common.cpp`. -Note - because the `RegisterTool()` function calls the tool's `Init()` -function, any _tools_ that your tools refers to in the init function -must already be registered so that your tool can access it via the -tool manager. Equally, if your tool is referenced by another in its -`Init()` function, your tool must be registered. In general, "top -level" tools go first, and other tools add items to their menus later. -If you register _actions_, that's OK, by the time the menu is invoked, -the tools will all be ready and bound to actions. - -In our case, it doesn't matter as our menu is not touched by anyone -else, we only add an _action_. - // add your tool header #include diff --git a/common/tool/tool_manager.cpp b/common/tool/tool_manager.cpp index 899cf214df..78221e7c4f 100644 --- a/common/tool/tool_manager.cpp +++ b/common/tool/tool_manager.cpp @@ -233,23 +233,6 @@ void TOOL_MANAGER::RegisterTool( TOOL_BASE* aTool ) m_toolTypes[typeid( *aTool ).name()] = st->theTool; aTool->attachManager( this ); - - if( !aTool->Init() ) - { - std::string msg = StrPrintf( "Initialization of the %s tool failed", - aTool->GetName().c_str() ); - - DisplayError( NULL, wxString::FromUTF8( msg.c_str() ) ); - - // Unregister the tool - m_toolState.erase( aTool ); - m_toolNameIndex.erase( aTool->GetName() ); - m_toolIdIndex.erase( aTool->GetId() ); - m_toolTypes.erase( typeid( *aTool ).name() ); - - delete st; - delete aTool; - } } @@ -424,12 +407,14 @@ TOOL_BASE* TOOL_MANAGER::FindTool( const std::string& aName ) const return NULL; } + void TOOL_MANAGER::DeactivateTool() { TOOL_EVENT evt( TC_COMMAND, TA_ACTIVATE, "" ); // deactivate the active tool ProcessEvent( evt ); } + void TOOL_MANAGER::ResetTools( TOOL_BASE::RESET_REASON aReason ) { DeactivateTool(); @@ -442,6 +427,34 @@ void TOOL_MANAGER::ResetTools( TOOL_BASE::RESET_REASON aReason ) } +void TOOL_MANAGER::InitTools() +{ + for( auto it = m_toolState.begin(); it != m_toolState.end(); /* iteration in the loop */ ) + { + TOOL_BASE* tool = it->first; + TOOL_STATE* state = it->second; + ++it; // keep the iterator valid if the element is going to be erased + + if( !tool->Init() ) + { + DisplayError( nullptr, + wxString::Format( "Initialization of tool '%s' failed", tool->GetName() ) ); + + // Unregister the tool + m_toolState.erase( tool ); + m_toolNameIndex.erase( tool->GetName() ); + m_toolIdIndex.erase( tool->GetId() ); + m_toolTypes.erase( typeid( *tool ).name() ); + + delete state; + delete tool; + } + } + + ResetTools( TOOL_BASE::RUN ); +} + + int TOOL_MANAGER::GetPriority( int aToolId ) const { int priority = 0; diff --git a/include/tool/tool_manager.h b/include/tool/tool_manager.h index e56542e63d..b8add965f0 100644 --- a/include/tool/tool_manager.h +++ b/include/tool/tool_manager.h @@ -198,6 +198,14 @@ public: */ void ResetTools( TOOL_BASE::RESET_REASON aReason ); + /** + * Function InitTools() + * Initializes all registered tools. If a tool fails during the initialization, it is + * deactivated and becomes unavailable for further use. Initialization should be done + * only once. + */ + void InitTools(); + /** * Propagates an event to tools that requested events of matching type(s). * @param aEvent is the event to be processed. diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index 3402bbf91b..8e5d33217d 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -568,8 +568,7 @@ void PCB_EDIT_FRAME::setupTools() // Register tools registerAllTools( m_toolManager ); - - m_toolManager->ResetTools( TOOL_BASE::RUN ); + m_toolManager->InitTools(); // Run the selection tool, it is supposed to be always active m_toolManager->InvokeTool( "pcbnew.InteractiveSelection" ); diff --git a/pcbnew/tools/tools_common.cpp b/pcbnew/tools/tools_common.cpp index fd727ff932..0e08778854 100644 --- a/pcbnew/tools/tools_common.cpp +++ b/pcbnew/tools/tools_common.cpp @@ -42,7 +42,7 @@ #include #include -void registerAllTools( TOOL_MANAGER *aToolManager ) +void registerAllTools( TOOL_MANAGER* aToolManager ) { aToolManager->RegisterTool( new SELECTION_TOOL ); aToolManager->RegisterTool( new ZOOM_TOOL ); @@ -56,5 +56,4 @@ void registerAllTools( TOOL_MANAGER *aToolManager ) aToolManager->RegisterTool( new PCBNEW_CONTROL ); aToolManager->RegisterTool( new PCB_EDITOR_CONTROL ); aToolManager->RegisterTool( new PLACEMENT_TOOL ); - }