diff --git a/Core/Code/Interactions/mitkDispatcher.cpp b/Core/Code/Interactions/mitkDispatcher.cpp index 4207d4dbca..a90637e3d8 100644 --- a/Core/Code/Interactions/mitkDispatcher.cpp +++ b/Core/Code/Interactions/mitkDispatcher.cpp @@ -1,233 +1,230 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkDispatcher.h" #include "mitkInteractionEvent.h" #include "mitkInternalEvent.h" // MicroServices #include "mitkGetModuleContext.h" #include "mitkModule.h" #include "mitkModuleRegistry.h" #include "mitkInteractionEventObserver.h" mitk::Dispatcher::Dispatcher() : m_ProcessingMode(REGULAR) { m_EventObserverTracker = new mitk::ServiceTracker(GetModuleContext()); m_EventObserverTracker->Open(); } void mitk::Dispatcher::AddDataInteractor(const DataNode* dataNode) { RemoveDataInteractor(dataNode); RemoveOrphanedInteractors(); DataInteractor::Pointer dataInteractor = dataNode->GetDataInteractor(); if (dataInteractor.IsNotNull()) { m_Interactors.push_back(dataInteractor); } } /* * Note: One DataInteractor can only have one DataNode and vice versa, * BUT the m_Interactors list may contain another DataInteractor that is still connected to this DataNode, * in this case we have to remove >1 DataInteractor. (Some special case of switching DataNodes between DataInteractors and registering a * DataNode to a DataStorage after assigning it to an DataInteractor) */ void mitk::Dispatcher::RemoveDataInteractor(const DataNode* dataNode) { for (ListInteractorType::iterator it = m_Interactors.begin(); it != m_Interactors.end();) { if ((*it)->GetDataNode() == dataNode) { it = m_Interactors.erase(it); } else { ++it; } } } size_t mitk::Dispatcher::GetNumberOfInteractors() { return m_Interactors.size(); } mitk::Dispatcher::~Dispatcher() { m_EventObserverTracker->Close(); delete m_EventObserverTracker; } bool mitk::Dispatcher::ProcessEvent(InteractionEvent* event) { InteractionEvent::Pointer p = event; //MITK_INFO << event->GetEventClass(); bool eventIsHandled = false; /* Filter out and handle Internal Events separately */ InternalEvent* internalEvent = dynamic_cast(event); if (internalEvent != NULL) { eventIsHandled = HandleInternalEvent(internalEvent); // InternalEvents that are handled are not sent to the listeners if (eventIsHandled) { return true; } } switch (m_ProcessingMode) { case CONNECTEDMOUSEACTION: // finished connected mouse action if (p->GetEventClass() == "MouseReleaseEvent") { m_ProcessingMode = REGULAR; eventIsHandled = m_SelectedInteractor->HandleEvent(event, m_SelectedInteractor->GetDataNode()); } // give event to selected interactor if (eventIsHandled == false) { eventIsHandled = m_SelectedInteractor->HandleEvent(event, m_SelectedInteractor->GetDataNode()); } break; case GRABINPUT: eventIsHandled = m_SelectedInteractor->HandleEvent(event, m_SelectedInteractor->GetDataNode()); SetEventProcessingMode(m_SelectedInteractor); break; case PREFERINPUT: if (m_SelectedInteractor->HandleEvent(event, m_SelectedInteractor->GetDataNode()) == true) { SetEventProcessingMode(m_SelectedInteractor); eventIsHandled = true; } break; case REGULAR: break; } // Standard behavior. Is executed in STANDARD mode and PREFERINPUT mode, if preferred interactor rejects event. if (m_ProcessingMode == REGULAR || (m_ProcessingMode == PREFERINPUT && eventIsHandled == false)) { m_Interactors.sort(cmp()); // sorts interactors by layer (descending); for (std::list::iterator it = m_Interactors.begin(); it != m_Interactors.end(); ++it) { // explicit copy of pointer because HandleEvent function causes the m_Interactors list to be updated, // which in turn invalidates the iterator. DataInteractor::Pointer dataInteractor = *it; if (dataInteractor->HandleEvent(event, dataInteractor->GetDataNode())) { // if an event is handled several properties are checked, in order to determine the processing mode of the dispatcher SetEventProcessingMode(dataInteractor); if (p->GetEventClass() == "MousePressEvent" && m_ProcessingMode == REGULAR) { m_SelectedInteractor = dataInteractor; m_ProcessingMode = CONNECTEDMOUSEACTION; } eventIsHandled = true; break; } } } /* Notify InteractionEventObserver */ std::list listEventObserver; m_EventObserverTracker->GetServiceReferences(listEventObserver); for (std::list::iterator it = listEventObserver.begin(); it != listEventObserver.end(); ++it) { - - Any patternName = it->GetProperty("org.mitk.statemachinepattern"); - - //if (!patternName.Empty() || patternName.ToString() == "") - //{ - InteractionEventObserver* interactionEventObserver = m_EventObserverTracker->GetService(*it); - if (interactionEventObserver != NULL) + InteractionEventObserver* interactionEventObserver = m_EventObserverTracker->GetService(*it); + if (interactionEventObserver != NULL) + { + if (interactionEventObserver->IsEnabled()) { interactionEventObserver->Notify(event, eventIsHandled); } - //} + } } // Process event queue if (!m_QueuedEvents.empty()) { InteractionEvent::Pointer e = m_QueuedEvents.front(); m_QueuedEvents.pop_front(); ProcessEvent(e); } return eventIsHandled; } /* * Checks if DataNodes associated with DataInteractors point back to them. * If not remove the DataInteractors. (This can happen when s.o. tries to set DataNodes to multiple DataInteractors) */ void mitk::Dispatcher::RemoveOrphanedInteractors() { for (ListInteractorType::iterator it = m_Interactors.begin(); it != m_Interactors.end();) { DataNode::Pointer dn = (*it)->GetDataNode(); if (dn.IsNull()) { it = m_Interactors.erase(it); } else { DataInteractor::Pointer interactor = dn->GetDataInteractor(); if (interactor != it->GetPointer()) { it = m_Interactors.erase(it); } else { ++it; } } } } void mitk::Dispatcher::QueueEvent(InteractionEvent* event) { m_QueuedEvents.push_back(event); } void mitk::Dispatcher::SetEventProcessingMode(DataInteractor::Pointer dataInteractor) { m_ProcessingMode = dataInteractor->GetMode(); if (dataInteractor->GetMode() != REGULAR) { m_SelectedInteractor = dataInteractor; } } bool mitk::Dispatcher::HandleInternalEvent(InternalEvent* internalEvent) { if (internalEvent->GetSignalName() == IntDeactivateMe && internalEvent->GetTargetInteractor() != NULL) { internalEvent->GetTargetInteractor()->GetDataNode()->SetDataInteractor(NULL); internalEvent->GetTargetInteractor()->SetDataNode(NULL); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); return true; } return false; } diff --git a/Core/Code/Interactions/mitkMouseModeSwitcher.cpp b/Core/Code/Interactions/mitkMouseModeSwitcher.cpp index 2c8169dfb4..f7a5f24a4b 100644 --- a/Core/Code/Interactions/mitkMouseModeSwitcher.cpp +++ b/Core/Code/Interactions/mitkMouseModeSwitcher.cpp @@ -1,110 +1,113 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkMouseModeSwitcher.h" // us #include "mitkGetModuleContext.h" #include "mitkModule.h" #include "mitkModuleRegistry.h" #include "mitkInteractionEventObserver.h" mitk::MouseModeSwitcher::MouseModeSwitcher() : m_ActiveInteractionScheme(MITK), m_ActiveMouseMode(MousePointer), m_CurrentObserver(NULL) { this->InitializeListeners(); this->SetInteractionScheme(m_ActiveInteractionScheme); } mitk::MouseModeSwitcher::~MouseModeSwitcher() { m_ServiceRegistration.Unregister(); } void mitk::MouseModeSwitcher::InitializeListeners() { if (m_CurrentObserver.IsNull()) { m_CurrentObserver = mitk::DisplayInteractor::New(); m_CurrentObserver->LoadStateMachine("DisplayInteraction.xml"); m_CurrentObserver->LoadEventConfig("DisplayConfigMITK.xml"); // Register as listener via micro services + ServiceProperties props; + props["name"] = std::string("DisplayInteractor"); m_ServiceRegistration = GetModuleContext()->RegisterService( - m_CurrentObserver.GetPointer()); + m_CurrentObserver.GetPointer(),props); + } } void mitk::MouseModeSwitcher::SetInteractionScheme(InteractionScheme scheme) { switch (scheme) { case MITK: { m_CurrentObserver->LoadEventConfig("DisplayConfigMITK.xml"); } break; case PACS: { m_CurrentObserver->LoadEventConfig("DisplayConfigPACS.xml"); } break; } m_ActiveInteractionScheme = scheme; this->InvokeEvent(MouseModeChangedEvent()); } void mitk::MouseModeSwitcher::SelectMouseMode(MouseMode mode) { if (m_ActiveInteractionScheme != PACS) return; switch (mode) { case MousePointer: { m_CurrentObserver->LoadEventConfig("DisplayConfigPACS.xml"); break; } // case 0 case Scroll: { m_CurrentObserver->AddEventConfig("DisplayConfigPACSScroll.xml"); break; } case LevelWindow: { m_CurrentObserver->AddEventConfig("DisplayConfigPACSLevelWindow.xml"); break; } case Zoom: { m_CurrentObserver->AddEventConfig("DisplayConfigPACSZoom.xml"); break; } case Pan: { m_CurrentObserver->AddEventConfig("DisplayConfigPACSPan.xml"); break; } } // end switch (mode) m_ActiveMouseMode = mode; this->InvokeEvent(MouseModeChangedEvent()); } mitk::MouseModeSwitcher::MouseMode mitk::MouseModeSwitcher::GetCurrentMouseMode() const { return m_ActiveMouseMode; } diff --git a/Core/Code/Interfaces/mitkInteractionEventObserver.cpp b/Core/Code/Interfaces/mitkInteractionEventObserver.cpp index 785f1ef263..cb98786e3f 100644 --- a/Core/Code/Interfaces/mitkInteractionEventObserver.cpp +++ b/Core/Code/Interfaces/mitkInteractionEventObserver.cpp @@ -1,22 +1,41 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkInteractionEventObserver.h" +mitk::InteractionEventObserver::InteractionEventObserver() : m_IsEnabled(true) +{ +} + mitk::InteractionEventObserver::~InteractionEventObserver() { } + +void mitk::InteractionEventObserver::Disable() +{ + m_IsEnabled = false; +} + +void mitk::InteractionEventObserver::Enable() +{ + m_IsEnabled = true; +} + +bool mitk::InteractionEventObserver::IsEnabled() +{ + return m_IsEnabled; +} diff --git a/Core/Code/Interfaces/mitkInteractionEventObserver.h b/Core/Code/Interfaces/mitkInteractionEventObserver.h index 49f44208fc..de1cee1fe0 100644 --- a/Core/Code/Interfaces/mitkInteractionEventObserver.h +++ b/Core/Code/Interfaces/mitkInteractionEventObserver.h @@ -1,62 +1,69 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef InteractionEventObserver_h #define InteractionEventObserver_h #include #include "mitkServiceInterface.h" #include "mitkInteractionEvent.h" namespace mitk { /** * \class InteractionEventObserver * \brief Base class to implement InteractionEventObservers. * * This class also provides state machine infrastructure, * but usage thereof is optional. See the Notify method for more information. */ struct MITK_CORE_EXPORT InteractionEventObserver { + InteractionEventObserver(); virtual ~InteractionEventObserver(); /** * By this method all registered EventObersers are notified about every InteractionEvent, * the isHandled flag indicates if a DataInteractor has already handled that event. * InteractionEventObserver that trigger an action when observing an event may consider * this in order to not confuse the user by, triggering several independent action with one * single user event (such as a mouse click) * * If you want to use the InteractionEventObserver as a state machine give the event to the state machine by implementing, e.g. \code void mitk::InteractionEventObserver::Notify(InteractionEvent::Pointer interactionEvent, bool isHandled) { if (!isHandled) { this->HandleEvent(interactionEvent, NULL); } } \endcode * This overwrites the FilterEvents function of the EventStateMachine to ignore the DataNode, since InteractionEventObservers are not associated with one. virtual bool FilterEvents(InteractionEvent* interactionEvent, DataNode* dataNode); */ virtual void Notify(InteractionEvent* interactionEvent,bool isHandled) = 0; + + void Disable(); + void Enable(); + bool IsEnabled(); + private: + bool m_IsEnabled; }; } /* namespace mitk */ US_DECLARE_SERVICE_INTERFACE(mitk::InteractionEventObserver, "org.mitk.InteractionEventObserver") #endif /* InteractionEventObserver_h */ diff --git a/Modules/MitkExt/Controllers/mitkToolManager.cpp b/Modules/MitkExt/Controllers/mitkToolManager.cpp index 74650a2092..da81a44c03 100644 --- a/Modules/MitkExt/Controllers/mitkToolManager.cpp +++ b/Modules/MitkExt/Controllers/mitkToolManager.cpp @@ -1,528 +1,567 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkToolManager.h" #include "mitkGlobalInteraction.h" #include "mitkCoreObjectFactory.h" #include #include #include +#include "mitkInteractionEventObserver.h" +// MicroServices +#include "mitkGetModuleContext.h" +#include "mitkModule.h" +#include "mitkModuleRegistry.h" + + mitk::ToolManager::ToolManager(DataStorage* storage) :m_ActiveTool(NULL), m_ActiveToolID(-1), m_RegisteredClients(0), m_DataStorage(storage) { CoreObjectFactory::GetInstance(); // to make sure a CoreObjectFactory was instantiated (and in turn, possible tools are registered) - bug 1029 // get a list of all known mitk::Tools std::list thingsThatClaimToBeATool = itk::ObjectFactoryBase::CreateAllInstance("mitkTool"); // remember these tools for ( std::list::iterator iter = thingsThatClaimToBeATool.begin(); iter != thingsThatClaimToBeATool.end(); ++iter ) { if ( Tool* tool = dynamic_cast( iter->GetPointer() ) ) { tool->SetToolManager(this); // important to call right after instantiation tool->ErrorMessage += MessageDelegate1( this, &ToolManager::OnToolErrorMessage ); tool->GeneralMessage += MessageDelegate1( this, &ToolManager::OnGeneralToolMessage ); m_Tools.push_back( tool ); } } //ActivateTool(0); // first one is default } mitk::ToolManager::~ToolManager() { for (DataVectorType::iterator dataIter = m_WorkingData.begin(); dataIter != m_WorkingData.end(); ++dataIter) (*dataIter)->RemoveObserver(m_WorkingDataObserverTags[(*dataIter)]); if(this->GetDataStorage() != NULL) this->GetDataStorage()->RemoveNodeEvent.RemoveListener( mitk::MessageDelegate1 ( this, &ToolManager::OnNodeRemoved )); if (m_ActiveTool) { m_ActiveTool->Deactivated(); GlobalInteraction::GetInstance()->RemoveListener( m_ActiveTool ); m_ActiveTool = NULL; m_ActiveToolID = -1; // no tool active ActiveToolChanged.Send(); } for ( NodeTagMapType::iterator observerTagMapIter = m_ReferenceDataObserverTags.begin(); observerTagMapIter != m_ReferenceDataObserverTags.end(); ++observerTagMapIter ) { observerTagMapIter->first->RemoveObserver( observerTagMapIter->second ); } } void mitk::ToolManager::OnToolErrorMessage(std::string s) { this->ToolErrorMessage(s); } void mitk::ToolManager::OnGeneralToolMessage(std::string s) { this->GeneralToolMessage(s); } const mitk::ToolManager::ToolVectorTypeConst mitk::ToolManager::GetTools() { ToolVectorTypeConst resultList; for ( ToolVectorType::iterator iter = m_Tools.begin(); iter != m_Tools.end(); ++iter ) { resultList.push_back( iter->GetPointer() ); } return resultList; } mitk::Tool* mitk::ToolManager::GetToolById(int id) { try { return m_Tools.at(id); } catch(std::exception&) { return NULL; } } bool mitk::ToolManager::ActivateTool(int id) { if(this->GetDataStorage()) { this->GetDataStorage()->RemoveNodeEvent.AddListener( mitk::MessageDelegate1 ( this, &ToolManager::OnNodeRemoved ) ); } //MITK_INFO << "ToolManager::ActivateTool("<SetEventNotificationPolicy(GlobalInteraction::INFORM_MULTIPLE); + // Re-enabling InteractionEventObservers that have been previously disabled for legacy handling of Tools + // in new interaction framework + std::list listEventObserver; + ServiceTracker* eventObserverTracker= new ServiceTracker(GetModuleContext()); + eventObserverTracker->Open(); + eventObserverTracker->GetServiceReferences(listEventObserver); // query all registered interaction event observer + for (std::list::iterator it = listEventObserver.begin(); it != listEventObserver.end(); ++it) + { + InteractionEventObserver* interactionEventObserver = eventObserverTracker->GetService(*it); + if (interactionEventObserver != NULL) { + interactionEventObserver->Enable(); // re-enable the interaction + } + } + eventObserverTracker->Close(); + delete eventObserverTracker; + } if ( GetToolById( id ) == m_ActiveTool ) return true; // no change needed static int nextTool = -1; nextTool = id; //MITK_INFO << "ToolManager::ActivateTool("<Deactivated(); GlobalInteraction::GetInstance()->RemoveListener( m_ActiveTool ); } m_ActiveTool = GetToolById( nextTool ); m_ActiveToolID = m_ActiveTool ? nextTool : -1; // current ID if tool is valid, otherwise -1 ActiveToolChanged.Send(); if (m_ActiveTool) { if (m_RegisteredClients > 0) { m_ActiveTool->Activated(); GlobalInteraction::GetInstance()->AddListener( m_ActiveTool ); //If a tool is activated set event notification policy to one GlobalInteraction::GetInstance()->SetEventNotificationPolicy(GlobalInteraction::INFORM_ONE); + // As a legacy solution the display interaction of the new interaction framework is disabled here to avoid conflicts with tools + // Note: this only affects InteractionEventObservers (formerly known as Listeners) all DataNode specific interaction will still be enabled + std::list listEventObserver; + ServiceTracker* eventObserverTracker= new ServiceTracker(GetModuleContext()); + eventObserverTracker->Open(); + eventObserverTracker->GetServiceReferences(listEventObserver); + for (std::list::iterator it = listEventObserver.begin(); it != listEventObserver.end(); ++it) + { + InteractionEventObserver* interactionEventObserver = eventObserverTracker->GetService(*it); + if (interactionEventObserver != NULL) { + interactionEventObserver->Disable(); // disable the interaction + } + } + eventObserverTracker->Close(); + delete eventObserverTracker; } } } inActivateTool = false; return (m_ActiveTool != NULL); } void mitk::ToolManager::SetReferenceData(DataVectorType data) { if (data != m_ReferenceData) { // remove observers from old nodes for ( DataVectorType::iterator dataIter = m_ReferenceData.begin(); dataIter != m_ReferenceData.end(); ++dataIter ) { NodeTagMapType::iterator searchIter = m_ReferenceDataObserverTags.find( *dataIter ); if ( searchIter != m_ReferenceDataObserverTags.end() ) { //MITK_INFO << "Stopping observation of " << (void*)(*dataIter) << std::endl; (*dataIter)->RemoveObserver( searchIter->second ); } } m_ReferenceData = data; // TODO tell active tool? // attach new observers m_ReferenceDataObserverTags.clear(); for ( DataVectorType::iterator dataIter = m_ReferenceData.begin(); dataIter != m_ReferenceData.end(); ++dataIter ) { //MITK_INFO << "Observing " << (void*)(*dataIter) << std::endl; itk::MemberCommand::Pointer command = itk::MemberCommand::New(); command->SetCallbackFunction( this, &ToolManager::OnOneOfTheReferenceDataDeleted ); command->SetCallbackFunction( this, &ToolManager::OnOneOfTheReferenceDataDeletedConst ); m_ReferenceDataObserverTags.insert( std::pair( (*dataIter), (*dataIter)->AddObserver( itk::DeleteEvent(), command ) ) ); } ReferenceDataChanged.Send(); } } void mitk::ToolManager::OnOneOfTheReferenceDataDeletedConst(const itk::Object* caller, const itk::EventObject& e) { OnOneOfTheReferenceDataDeleted( const_cast(caller), e ); } void mitk::ToolManager::OnOneOfTheReferenceDataDeleted(itk::Object* caller, const itk::EventObject& itkNotUsed(e)) { //MITK_INFO << "Deleted: " << (void*)caller << " Removing from reference data list." << std::endl; DataVectorType v; for (DataVectorType::iterator dataIter = m_ReferenceData.begin(); dataIter != m_ReferenceData.end(); ++dataIter ) { //MITK_INFO << " In list: " << (void*)(*dataIter); if ( (void*)(*dataIter) != (void*)caller ) { v.push_back( *dataIter ); //MITK_INFO << " kept" << std::endl; } else { //MITK_INFO << " removed" << std::endl; m_ReferenceDataObserverTags.erase( *dataIter ); // no tag to remove anymore } } this->SetReferenceData( v ); } void mitk::ToolManager::SetReferenceData(DataNode* data) { //MITK_INFO << "ToolManager::SetReferenceData(" << (void*)data << ")" << std::endl; DataVectorType v; if (data) { v.push_back(data); } SetReferenceData(v); } void mitk::ToolManager::SetWorkingData(DataVectorType data) { if ( data != m_WorkingData ) { // remove observers from old nodes for ( DataVectorType::iterator dataIter = m_WorkingData.begin(); dataIter != m_WorkingData.end(); ++dataIter ) { NodeTagMapType::iterator searchIter = m_WorkingDataObserverTags.find( *dataIter ); if ( searchIter != m_WorkingDataObserverTags.end() ) { //MITK_INFO << "Stopping observation of " << (void*)(*dataIter) << std::endl; (*dataIter)->RemoveObserver( searchIter->second ); } } m_WorkingData = data; // TODO tell active tool? // attach new observers m_WorkingDataObserverTags.clear(); for ( DataVectorType::iterator dataIter = m_WorkingData.begin(); dataIter != m_WorkingData.end(); ++dataIter ) { //MITK_INFO << "Observing " << (void*)(*dataIter) << std::endl; itk::MemberCommand::Pointer command = itk::MemberCommand::New(); command->SetCallbackFunction( this, &ToolManager::OnOneOfTheWorkingDataDeleted ); command->SetCallbackFunction( this, &ToolManager::OnOneOfTheWorkingDataDeletedConst ); m_WorkingDataObserverTags.insert( std::pair( (*dataIter), (*dataIter)->AddObserver( itk::DeleteEvent(), command ) ) ); } WorkingDataChanged.Send(); } } void mitk::ToolManager::OnOneOfTheWorkingDataDeletedConst(const itk::Object* caller, const itk::EventObject& e) { OnOneOfTheWorkingDataDeleted( const_cast(caller), e ); } void mitk::ToolManager::OnOneOfTheWorkingDataDeleted(itk::Object* caller, const itk::EventObject& itkNotUsed(e)) { //MITK_INFO << "Deleted: " << (void*)caller << " Removing from reference data list." << std::endl; DataVectorType v; for (DataVectorType::iterator dataIter = m_WorkingData.begin(); dataIter != m_WorkingData.end(); ++dataIter ) { //MITK_INFO << " In list: " << (void*)(*dataIter); if ( (void*)(*dataIter) != (void*)caller ) { v.push_back( *dataIter ); //MITK_INFO << " kept" << std::endl; } else { //MITK_INFO << " removed" << std::endl; m_WorkingDataObserverTags.erase( *dataIter ); // no tag to remove anymore } } this->SetWorkingData( v ); } void mitk::ToolManager::SetWorkingData(DataNode* data) { DataVectorType v; if (data) // don't allow for NULL nodes { v.push_back(data); } SetWorkingData(v); } void mitk::ToolManager::SetRoiData(DataVectorType data) { if (data != m_RoiData) { // remove observers from old nodes for ( DataVectorType::iterator dataIter = m_RoiData.begin(); dataIter != m_RoiData.end(); ++dataIter ) { NodeTagMapType::iterator searchIter = m_RoiDataObserverTags.find( *dataIter ); if ( searchIter != m_RoiDataObserverTags.end() ) { //MITK_INFO << "Stopping observation of " << (void*)(*dataIter) << std::endl; (*dataIter)->RemoveObserver( searchIter->second ); } } m_RoiData = data; // TODO tell active tool? // attach new observers m_RoiDataObserverTags.clear(); for ( DataVectorType::iterator dataIter = m_RoiData.begin(); dataIter != m_RoiData.end(); ++dataIter ) { //MITK_INFO << "Observing " << (void*)(*dataIter) << std::endl; itk::MemberCommand::Pointer command = itk::MemberCommand::New(); command->SetCallbackFunction( this, &ToolManager::OnOneOfTheRoiDataDeleted ); command->SetCallbackFunction( this, &ToolManager::OnOneOfTheRoiDataDeletedConst ); m_RoiDataObserverTags.insert( std::pair( (*dataIter), (*dataIter)->AddObserver( itk::DeleteEvent(), command ) ) ); } RoiDataChanged.Send(); } } void mitk::ToolManager::SetRoiData(DataNode* data) { DataVectorType v; if(data) { v.push_back(data); } this->SetRoiData(v); } void mitk::ToolManager::OnOneOfTheRoiDataDeletedConst(const itk::Object* caller, const itk::EventObject& e) { OnOneOfTheRoiDataDeleted( const_cast(caller), e ); } void mitk::ToolManager::OnOneOfTheRoiDataDeleted(itk::Object* caller, const itk::EventObject& itkNotUsed(e)) { //MITK_INFO << "Deleted: " << (void*)caller << " Removing from roi data list." << std::endl; DataVectorType v; for (DataVectorType::iterator dataIter = m_RoiData.begin(); dataIter != m_RoiData.end(); ++dataIter ) { //MITK_INFO << " In list: " << (void*)(*dataIter); if ( (void*)(*dataIter) != (void*)caller ) { v.push_back( *dataIter ); //MITK_INFO << " kept" << std::endl; } else { //MITK_INFO << " removed" << std::endl; m_RoiDataObserverTags.erase( *dataIter ); // no tag to remove anymore } } this->SetRoiData( v ); } mitk::ToolManager::DataVectorType mitk::ToolManager::GetReferenceData() { return m_ReferenceData; } mitk::DataNode* mitk::ToolManager::GetReferenceData(int idx) { try { return m_ReferenceData.at(idx); } catch(std::exception&) { return NULL; } } mitk::ToolManager::DataVectorType mitk::ToolManager::GetWorkingData() { return m_WorkingData; } mitk::ToolManager::DataVectorType mitk::ToolManager::GetRoiData() { return m_RoiData; } mitk::DataNode* mitk::ToolManager::GetRoiData(int idx) { try { return m_RoiData.at(idx); } catch(std::exception&) { return NULL; } } mitk::DataStorage* mitk::ToolManager::GetDataStorage() { if ( m_DataStorage.IsNotNull() ) { return m_DataStorage; } else { return NULL; } } void mitk::ToolManager::SetDataStorage(DataStorage& storage) { m_DataStorage = &storage; } mitk::DataNode* mitk::ToolManager::GetWorkingData(int idx) { try { return m_WorkingData.at(idx); } catch(std::exception&) { return NULL; } } int mitk::ToolManager::GetActiveToolID() { return m_ActiveToolID; } mitk::Tool* mitk::ToolManager::GetActiveTool() { return m_ActiveTool; } void mitk::ToolManager::RegisterClient() { if ( m_RegisteredClients < 1 ) { if ( m_ActiveTool ) { m_ActiveTool->Activated(); GlobalInteraction::GetInstance()->AddListener( m_ActiveTool ); } } ++m_RegisteredClients; } void mitk::ToolManager::UnregisterClient() { if ( m_RegisteredClients < 1) return; --m_RegisteredClients; if ( m_RegisteredClients < 1 ) { if ( m_ActiveTool ) { m_ActiveTool->Deactivated(); GlobalInteraction::GetInstance()->RemoveListener( m_ActiveTool ); } } } int mitk::ToolManager::GetToolID( const Tool* tool ) { int id(0); for ( ToolVectorType::iterator iter = m_Tools.begin(); iter != m_Tools.end(); ++iter, ++id ) { if ( tool == iter->GetPointer() ) { return id; } } return -1; } void mitk::ToolManager::OnNodeRemoved(const mitk::DataNode* node) { //check if the data of the node is typeof Image /*if(dynamic_cast(node->GetData())) {*/ //check all storage vectors OnOneOfTheReferenceDataDeleted(const_cast(node), itk::DeleteEvent()); OnOneOfTheRoiDataDeleted(const_cast(node),itk::DeleteEvent()); OnOneOfTheWorkingDataDeleted(const_cast(node),itk::DeleteEvent()); //} }