From def53707d52bb18376028f309a0675dce2f36cce Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 14 May 2014 16:29:53 +0200 Subject: [PATCH] TOOL_MANAGER is no longer static. Reworked autoregistration of TOOL_ACTIONs. --- common/tool/action_manager.cpp | 4 ++++ common/tool/context_menu.cpp | 15 ++++++--------- common/tool/tool_manager.cpp | 9 +-------- include/tool/tool_action.h | 17 +++++++++++++---- include/tool/tool_manager.h | 27 ++++++++++++++------------- include/wxBasePcbFrame.h | 2 +- pcbnew/basepcbframe.cpp | 4 ++-- pcbnew/board_undo_redo.cpp | 4 ++-- pcbnew/edit.cpp | 6 +++--- pcbnew/pcbframe.cpp | 10 +++++----- pcbnew/tools/pcb_tools.cpp | 34 ++++++++++++++++++++-------------- 11 files changed, 71 insertions(+), 61 deletions(-) diff --git a/common/tool/action_manager.cpp b/common/tool/action_manager.cpp index 51c85aa273..444143b0fb 100644 --- a/common/tool/action_manager.cpp +++ b/common/tool/action_manager.cpp @@ -50,6 +50,7 @@ void ACTION_MANAGER::RegisterAction( TOOL_ACTION* aAction ) // action name without specifying at least toolName is not valid assert( aAction->GetName().find( '.', 0 ) != std::string::npos ); + // TOOL_ACTIONs must have unique names & ids assert( m_actionNameIndex.find( aAction->m_name ) == m_actionNameIndex.end() ); assert( m_actionIdIndex.find( aAction->m_id ) == m_actionIdIndex.end() ); @@ -60,6 +61,8 @@ void ACTION_MANAGER::RegisterAction( TOOL_ACTION* aAction ) if( aAction->HasHotKey() ) m_actionHotKeys[aAction->m_currentHotKey].push_back( aAction ); + + aAction->setActionMgr( this ); } @@ -69,6 +72,7 @@ void ACTION_MANAGER::UnregisterAction( TOOL_ACTION* aAction ) m_actionIdIndex.erase( aAction->m_id ); // Indicate that the ACTION_MANAGER no longer care about the object + aAction->setActionMgr( NULL ); aAction->setId( -1 ); if( aAction->HasHotKey() ) diff --git a/common/tool/context_menu.cpp b/common/tool/context_menu.cpp index 7413761ed3..b6277e16a7 100644 --- a/common/tool/context_menu.cpp +++ b/common/tool/context_menu.cpp @@ -73,14 +73,8 @@ CONTEXT_MENU::CONTEXT_MENU( const CONTEXT_MENU& aMenu ) : void CONTEXT_MENU::setupEvents() { - Connect( wxEVT_MENU_HIGHLIGHT, wxEventHandler( CONTEXT_MENU::onMenuEvent ), - NULL, this ); - Connect( wxEVT_COMMAND_MENU_SELECTED, wxEventHandler( CONTEXT_MENU::onMenuEvent ), - NULL, this ); - - // Workaround for the case when mouse cursor never reaches menu (it hangs up tools using menu) - wxMenuEvent menuEvent( wxEVT_MENU_HIGHLIGHT, -1, this ); - AddPendingEvent( menuEvent ); + Connect( wxEVT_MENU_HIGHLIGHT, wxEventHandler( CONTEXT_MENU::onMenuEvent ), NULL, this ); + Connect( wxEVT_COMMAND_MENU_SELECTED, wxEventHandler( CONTEXT_MENU::onMenuEvent ), NULL, this ); } @@ -191,8 +185,11 @@ void CONTEXT_MENU::onMenuEvent( wxEvent& aEvent ) } } + assert( m_tool ); // without tool & tool manager we cannot handle events + // forward the action/update event to the TOOL_MANAGER - TOOL_MANAGER::Instance().ProcessEvent( *evt ); + if( evt && m_tool ) + m_tool->GetManager()->ProcessEvent( *evt ); } diff --git a/common/tool/tool_manager.cpp b/common/tool/tool_manager.cpp index dd77425a0c..a0bba9c51f 100644 --- a/common/tool/tool_manager.cpp +++ b/common/tool/tool_manager.cpp @@ -103,14 +103,6 @@ TOOL_MANAGER::TOOL_MANAGER() : TOOL_MANAGER::~TOOL_MANAGER() -{ - DeleteAll(); - - delete m_actionMgr; -} - - -void TOOL_MANAGER::DeleteAll() { std::map::iterator it, it_end; @@ -122,6 +114,7 @@ void TOOL_MANAGER::DeleteAll() } m_toolState.clear(); + delete m_actionMgr; } diff --git a/include/tool/tool_action.h b/include/tool/tool_action.h index 8fb81e5d8d..4097fd2f7f 100644 --- a/include/tool/tool_action.h +++ b/include/tool/tool_action.h @@ -52,12 +52,12 @@ public: m_currentHotKey( aDefaultHotKey ), m_menuItem( aMenuItem ), m_menuDescription( aMenuDesc ), m_id( -1 ) { - TOOL_MANAGER::Instance().RegisterAction( this ); + TOOL_MANAGER::GetActionList().push_back( this ); } ~TOOL_ACTION() { - TOOL_MANAGER::Instance().UnregisterAction( this ); + TOOL_MANAGER::GetActionList().remove( this ); } bool operator==( const TOOL_ACTION& aRhs ) const @@ -195,6 +195,12 @@ private: m_id = aId; } + /// Assigns ACTION_MANAGER object that handles the TOOL_ACTION. + void setActionMgr( ACTION_MANAGER* aManager ) + { + m_actionMgr = aManager; + } + /// Name of the action (convention is: app.[tool.]action.name) std::string m_name; @@ -219,11 +225,14 @@ private: /// Unique ID for fast matching. Assigned by ACTION_MANAGER. int m_id; + /// Action manager that handles this TOOL_ACTION. + ACTION_MANAGER* m_actionMgr; + /// Origin of the action -// const TOOL_BASE* m_origin; + // const TOOL_BASE* m_origin; /// Originating UI object -// wxWindow* m_uiOrigin; + // wxWindow* m_uiOrigin; }; #endif diff --git a/include/tool/tool_manager.h b/include/tool/tool_manager.h index 1e4563a7e0..c8861c7ff1 100644 --- a/include/tool/tool_manager.h +++ b/include/tool/tool_manager.h @@ -48,20 +48,10 @@ class wxWindow; class TOOL_MANAGER { public: - static TOOL_MANAGER& Instance() - { - static TOOL_MANAGER manager; - - return manager; - } + TOOL_MANAGER(); ~TOOL_MANAGER(); - /** - * Deletes all the tools that were registered in the TOOL_MANAGER. - */ - void DeleteAll(); - /** * Generates an unique ID from for a tool with given name. */ @@ -251,9 +241,20 @@ public: m_passEvent = true; } -private: - TOOL_MANAGER(); + /** + * Returns list of TOOL_ACTIONs. TOOL_ACTIONs add themselves to the list upon their + * creation. + * @return List of TOOL_ACTIONs. + */ + static std::list& GetActionList() + { + // TODO I am afraid this approach won't work when we reach multitab version of kicad. + static std::list actionList; + return actionList; + } + +private: struct TOOL_STATE; typedef std::pair TRANSITION; diff --git a/include/wxBasePcbFrame.h b/include/wxBasePcbFrame.h index b2ce7d9a23..19d66214ac 100644 --- a/include/wxBasePcbFrame.h +++ b/include/wxBasePcbFrame.h @@ -90,7 +90,7 @@ protected: /// main window. wxAuiToolBar* m_auxiliaryToolBar; - TOOL_MANAGER& m_toolManager; + TOOL_MANAGER* m_toolManager; TOOL_DISPATCHER* m_toolDispatcher; void updateGridSelectBox(); diff --git a/pcbnew/basepcbframe.cpp b/pcbnew/basepcbframe.cpp index caa1194fc8..5577650436 100644 --- a/pcbnew/basepcbframe.cpp +++ b/pcbnew/basepcbframe.cpp @@ -133,10 +133,10 @@ END_EVENT_TABLE() PCB_BASE_FRAME::PCB_BASE_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrameType, const wxString& aTitle, const wxPoint& aPos, const wxSize& aSize, long aStyle, const wxString & aFrameName ) : - EDA_DRAW_FRAME( aKiway, aParent, aFrameType, aTitle, aPos, aSize, aStyle, aFrameName ), - m_toolManager( TOOL_MANAGER::Instance() ) + EDA_DRAW_FRAME( aKiway, aParent, aFrameType, aTitle, aPos, aSize, aStyle, aFrameName ) { m_Pcb = NULL; + m_toolManager = NULL; m_toolDispatcher = NULL; m_DisplayPadFill = true; // How to draw pads diff --git a/pcbnew/board_undo_redo.cpp b/pcbnew/board_undo_redo.cpp index db51056d02..56b5ca63d2 100644 --- a/pcbnew/board_undo_redo.cpp +++ b/pcbnew/board_undo_redo.cpp @@ -637,7 +637,7 @@ void PCB_EDIT_FRAME::GetBoardFromUndoList( wxCommandEvent& aEvent ) // Inform tools that undo command was issued TOOL_EVENT event( TC_MESSAGE, TA_UNDO_REDO, AS_GLOBAL ); - m_toolManager.ProcessEvent( event ); + m_toolManager->ProcessEvent( event ); /* Get the old list */ PICKED_ITEMS_LIST* List = GetScreen()->PopCommandFromUndoList(); @@ -660,7 +660,7 @@ void PCB_EDIT_FRAME::GetBoardFromRedoList( wxCommandEvent& aEvent ) // Inform tools that redo command was issued TOOL_EVENT event( TC_MESSAGE, TA_UNDO_REDO, AS_GLOBAL ); - m_toolManager.ProcessEvent( event ); + m_toolManager->ProcessEvent( event ); /* Get the old list */ PICKED_ITEMS_LIST* List = GetScreen()->PopCommandFromRedoList(); diff --git a/pcbnew/edit.cpp b/pcbnew/edit.cpp index 51de425839..7c2a02804f 100644 --- a/pcbnew/edit.cpp +++ b/pcbnew/edit.cpp @@ -1391,15 +1391,15 @@ void PCB_EDIT_FRAME::OnSelectTool( wxCommandEvent& aEvent ) // Cancel the current tool // TODO while sending a lot of cancel events works for sure, it is not the most // elegant way to cancel a tool, this should be probably done another way - while( m_toolManager.GetCurrentTool()->GetName() != "pcbnew.InteractiveSelection" && + while( m_toolManager->GetCurrentTool()->GetName() != "pcbnew.InteractiveSelection" && trials++ < MAX_TRIALS ) { TOOL_EVENT cancel( TC_ANY, TA_CANCEL_TOOL ); - m_toolManager.ProcessEvent( cancel ); + m_toolManager->ProcessEvent( cancel ); } if( !actionName.empty() ) - m_toolManager.RunAction( actionName ); + m_toolManager->RunAction( actionName ); } } else diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index b873ef95f7..d04541e200 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -495,9 +495,9 @@ void PCB_EDIT_FRAME::SetBoard( BOARD* aBoard ) ViewReloadBoard( aBoard ); // update the tool manager with the new board and its view. - m_toolManager.SetEnvironment( aBoard, GetGalCanvas()->GetView(), - GetGalCanvas()->GetViewControls(), this ); - m_toolManager.ResetTools( TOOL_BASE::MODEL_RELOAD ); + m_toolManager->SetEnvironment( aBoard, GetGalCanvas()->GetView(), + GetGalCanvas()->GetViewControls(), this ); + m_toolManager->ResetTools( TOOL_BASE::MODEL_RELOAD ); } } @@ -677,9 +677,9 @@ void PCB_EDIT_FRAME::UseGalCanvas( bool aEnable ) ViewReloadBoard( m_Pcb ); GetGalCanvas()->GetView()->RecacheAllItems(); - m_toolManager.SetEnvironment( m_Pcb, GetGalCanvas()->GetView(), + m_toolManager->SetEnvironment( m_Pcb, GetGalCanvas()->GetView(), GetGalCanvas()->GetViewControls(), this ); - m_toolManager.ResetTools( TOOL_BASE::MODEL_RELOAD ); + m_toolManager->ResetTools( TOOL_BASE::MODEL_RELOAD ); GetGalCanvas()->StartDrawing(); } diff --git a/pcbnew/tools/pcb_tools.cpp b/pcbnew/tools/pcb_tools.cpp index 0decc244d7..eaefa97678 100644 --- a/pcbnew/tools/pcb_tools.cpp +++ b/pcbnew/tools/pcb_tools.cpp @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -45,8 +46,8 @@ void PCB_EDIT_FRAME::setupTools() { // Create the manager and dispatcher & route draw panel events to the dispatcher - m_toolManager = TOOL_MANAGER::Instance(); - m_toolDispatcher = new TOOL_DISPATCHER( &m_toolManager, this ); + m_toolManager = new TOOL_MANAGER; + m_toolDispatcher = new TOOL_DISPATCHER( m_toolManager, this ); GetGalCanvas()->SetEventDispatcher( m_toolDispatcher ); // Connect handlers to toolbar buttons @@ -59,26 +60,31 @@ void PCB_EDIT_FRAME::setupTools() wxCommandEventHandler( PCB_EDIT_FRAME::onGenericCommand ), NULL, this ); #endif - // Register tools - m_toolManager.RegisterTool( new SELECTION_TOOL ); - m_toolManager.RegisterTool( new ROUTER_TOOL ); - m_toolManager.RegisterTool( new EDIT_TOOL ); - m_toolManager.RegisterTool( new DRAWING_TOOL ); - m_toolManager.RegisterTool( new POINT_EDITOR ); - m_toolManager.RegisterTool( new PCBNEW_CONTROL ); + // Register actions + std::list& actionList = m_toolManager->GetActionList(); + BOOST_FOREACH( TOOL_ACTION* action, actionList ) + m_toolManager->RegisterAction( action ); - m_toolManager.SetEnvironment( NULL, GetGalCanvas()->GetView(), - GetGalCanvas()->GetViewControls(), this ); - m_toolManager.ResetTools( TOOL_BASE::RUN ); + // Register tools + m_toolManager->RegisterTool( new SELECTION_TOOL ); + m_toolManager->RegisterTool( new ROUTER_TOOL ); + m_toolManager->RegisterTool( new EDIT_TOOL ); + m_toolManager->RegisterTool( new DRAWING_TOOL ); + m_toolManager->RegisterTool( new POINT_EDITOR ); + m_toolManager->RegisterTool( new PCBNEW_CONTROL ); + + m_toolManager->SetEnvironment( NULL, GetGalCanvas()->GetView(), + GetGalCanvas()->GetViewControls(), this ); + m_toolManager->ResetTools( TOOL_BASE::RUN ); // Run the selection tool, it is supposed to be always active - m_toolManager.InvokeTool( "pcbnew.InteractiveSelection" ); + m_toolManager->InvokeTool( "pcbnew.InteractiveSelection" ); } void PCB_EDIT_FRAME::destroyTools() { - m_toolManager.DeleteAll(); + delete m_toolManager; delete m_toolDispatcher; }