diff --git a/Modules/Segmentation/Controllers/mitkToolManager.cpp b/Modules/Segmentation/Controllers/mitkToolManager.cpp index c019e28930..2ff9e68aac 100644 --- a/Modules/Segmentation/Controllers/mitkToolManager.cpp +++ b/Modules/Segmentation/Controllers/mitkToolManager.cpp @@ -1,540 +1,542 @@ /*=================================================================== 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" #include "mitkDisplayInteractor.h" #include "mitkSegTool2D.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(mitk::GlobalInteraction::GetInstance()->IsInitialized()) { - if ( Tool* tool = dynamic_cast( iter->GetPointer() ) ) + // 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 ) { - 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 ); + 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); } 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 if (dynamic_cast(m_ActiveTool)) GlobalInteraction::GetInstance()->SetEventNotificationPolicy(GlobalInteraction::INFORM_ONE); } } } 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()); //} } diff --git a/Modules/SegmentationUI/Qmitk/QmitkToolSelectionBox.cpp b/Modules/SegmentationUI/Qmitk/QmitkToolSelectionBox.cpp index fc346636ed..cb6928bea4 100755 --- a/Modules/SegmentationUI/Qmitk/QmitkToolSelectionBox.cpp +++ b/Modules/SegmentationUI/Qmitk/QmitkToolSelectionBox.cpp @@ -1,697 +1,699 @@ /*=================================================================== 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. ===================================================================*/ //#define MBILOG_ENABLE_DEBUG 1 #include "QmitkToolSelectionBox.h" #include "QmitkToolGUI.h" #include "mitkBaseRenderer.h" #include #include #include #include #include #include #include #include #include "mitkModuleResource.h" #include "mitkModuleResourceStream.h" +#include "mitkToolManagerProvider.h" + QmitkToolSelectionBox::QmitkToolSelectionBox(QWidget* parent, mitk::DataStorage* storage) :QWidget(parent), m_SelfCall(false), m_DisplayedGroups("default"), m_LayoutColumns(2), m_ShowNames(true), m_AutoShowNamesWidth(0), m_GenerateAccelerators(false), m_ToolGUIWidget(NULL), m_LastToolGUI(NULL), m_ToolButtonGroup(NULL), m_ButtonLayout(NULL), m_EnabledMode(EnabledWithReferenceAndWorkingDataVisible) { QFont currentFont = QWidget::font(); currentFont.setBold(true); QWidget::setFont( currentFont ); - m_ToolManager = mitk::ToolManager::New( storage ); + m_ToolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager(); // muellerm // QButtonGroup m_ToolButtonGroup = new QButtonGroup(this); // some features of QButtonGroup m_ToolButtonGroup->setExclusive( false ); // mutually exclusive toggle buttons RecreateButtons(); QWidget::setContentsMargins(0, 0, 0, 0); if ( layout() != NULL ) { layout()->setContentsMargins(0, 0, 0, 0); } // reactions to signals connect( m_ToolButtonGroup, SIGNAL(buttonClicked(int)), this, SLOT(toolButtonClicked(int)) ); // reactions to ToolManager events m_ToolManager->ActiveToolChanged += mitk::MessageDelegate( this, &QmitkToolSelectionBox::OnToolManagerToolModified ); m_ToolManager->ReferenceDataChanged += mitk::MessageDelegate( this, &QmitkToolSelectionBox::OnToolManagerReferenceDataModified ); m_ToolManager->WorkingDataChanged += mitk::MessageDelegate( this, &QmitkToolSelectionBox::OnToolManagerWorkingDataModified ); // show active tool SetOrUnsetButtonForActiveTool(); QWidget::setEnabled( false ); } QmitkToolSelectionBox::~QmitkToolSelectionBox() { m_ToolManager->ActiveToolChanged -= mitk::MessageDelegate( this, &QmitkToolSelectionBox::OnToolManagerToolModified ); m_ToolManager->ReferenceDataChanged -= mitk::MessageDelegate( this, &QmitkToolSelectionBox::OnToolManagerReferenceDataModified ); m_ToolManager->WorkingDataChanged -= mitk::MessageDelegate( this, &QmitkToolSelectionBox::OnToolManagerWorkingDataModified ); } void QmitkToolSelectionBox::SetEnabledMode(EnabledMode mode) { m_EnabledMode = mode; SetGUIEnabledAccordingToToolManagerState(); } mitk::ToolManager* QmitkToolSelectionBox::GetToolManager() { return m_ToolManager; } void QmitkToolSelectionBox::SetToolManager(mitk::ToolManager& newManager) // no NULL pointer allowed here, a manager is required { // say bye to the old manager m_ToolManager->ActiveToolChanged -= mitk::MessageDelegate( this, &QmitkToolSelectionBox::OnToolManagerToolModified ); m_ToolManager->ReferenceDataChanged -= mitk::MessageDelegate( this, &QmitkToolSelectionBox::OnToolManagerReferenceDataModified ); m_ToolManager->WorkingDataChanged -= mitk::MessageDelegate( this, &QmitkToolSelectionBox::OnToolManagerWorkingDataModified ); if ( QWidget::isEnabled() ) { m_ToolManager->UnregisterClient(); } m_ToolManager = &newManager; RecreateButtons(); // greet the new one m_ToolManager->ActiveToolChanged += mitk::MessageDelegate( this, &QmitkToolSelectionBox::OnToolManagerToolModified ); m_ToolManager->ReferenceDataChanged += mitk::MessageDelegate( this, &QmitkToolSelectionBox::OnToolManagerReferenceDataModified ); m_ToolManager->WorkingDataChanged += mitk::MessageDelegate( this, &QmitkToolSelectionBox::OnToolManagerWorkingDataModified ); if ( QWidget::isEnabled() ) { m_ToolManager->RegisterClient(); } // ask the new one what the situation is like SetOrUnsetButtonForActiveTool(); } void QmitkToolSelectionBox::toolButtonClicked(int id) { if ( !QWidget::isEnabled() ) return; // this method could be triggered from the constructor, when we are still disabled MITK_DEBUG << "toolButtonClicked(" << id << "): id translates to tool ID " << m_ToolIDForButtonID[id]; //QToolButton* toolButton = dynamic_cast( Q3ButtonGroup::find(id) ); QToolButton* toolButton = dynamic_cast( m_ToolButtonGroup->buttons().at(id) ); if (toolButton) { if ( (m_ButtonIDForToolID.find( m_ToolManager->GetActiveToolID() ) != m_ButtonIDForToolID.end()) // if we have this tool in our box && (m_ButtonIDForToolID[ m_ToolManager->GetActiveToolID() ] == id) ) // the tool corresponding to this button is already active { // disable this button, disable all tools // mmueller toolButton->setChecked(false); m_ToolManager->ActivateTool(-1); // disable everything } else { // enable the corresponding tool m_SelfCall = true; m_ToolManager->ActivateTool( m_ToolIDForButtonID[id] ); m_SelfCall = false; } } } void QmitkToolSelectionBox::OnToolManagerToolModified() { SetOrUnsetButtonForActiveTool(); } void QmitkToolSelectionBox::SetOrUnsetButtonForActiveTool() { // we want to emit a signal in any case, whether we selected ourselves or somebody else changes "our" tool manager. --> emit before check on m_SelfCall int id = m_ToolManager->GetActiveToolID(); // don't emit signal for shape model tools bool emitSignal = true; mitk::Tool* tool = m_ToolManager->GetActiveTool(); if(tool && std::string(tool->GetGroup()) == "organ_segmentation") emitSignal = false; if(emitSignal) emit ToolSelected(id); // delete old GUI (if any) if ( m_LastToolGUI && m_ToolGUIWidget ) { if (m_ToolGUIWidget->layout()) { m_ToolGUIWidget->layout()->removeWidget(m_LastToolGUI); } //m_LastToolGUI->reparent(NULL, QPoint(0,0)); // TODO: reparent <-> setParent, Daniel fragen m_LastToolGUI->setParent(0); delete m_LastToolGUI; // will hopefully notify parent and layouts m_LastToolGUI = NULL; QLayout* layout = m_ToolGUIWidget->layout(); if (layout) { layout->activate(); } } QToolButton* toolButton(NULL); //mitk::Tool* tool = m_ToolManager->GetActiveTool(); if (m_ButtonIDForToolID.find(id) != m_ButtonIDForToolID.end()) // if this tool is in our box { //toolButton = dynamic_cast( Q3ButtonGroup::find( m_ButtonIDForToolID[id] ) ); toolButton = dynamic_cast( m_ToolButtonGroup->buttons().at( m_ButtonIDForToolID[id] ) ); } if ( toolButton ) { // mmueller // uncheck all other buttons QAbstractButton* tmpBtn = 0; QList::iterator it; for(int i=0; i < m_ToolButtonGroup->buttons().size(); ++i) { tmpBtn = m_ToolButtonGroup->buttons().at(i); if(tmpBtn != toolButton) dynamic_cast( tmpBtn )->setChecked(false); } toolButton->setChecked(true); if (m_ToolGUIWidget && tool) { // create and reparent new GUI (if any) itk::Object::Pointer possibleGUI = tool->GetGUI("Qmitk", "GUI").GetPointer(); // prefix and postfix QmitkToolGUI* gui = dynamic_cast( possibleGUI.GetPointer() ); //! m_LastToolGUI = gui; if (gui) { gui->SetTool( tool ); // mmueller //gui->reparent(m_ToolGUIWidget, gui->geometry().topLeft(), true ); gui->setParent(m_ToolGUIWidget); gui->move(gui->geometry().topLeft()); gui->show(); QLayout* layout = m_ToolGUIWidget->layout(); if (!layout) { layout = new QVBoxLayout( m_ToolGUIWidget ); } if (layout) { // mmueller layout->addWidget( gui ); //layout->add( gui ); layout->activate(); } } } } else { // disable all buttons QToolButton* selectedToolButton = dynamic_cast( m_ToolButtonGroup->checkedButton() ); //QToolButton* selectedToolButton = dynamic_cast( Q3ButtonGroup::find( Q3ButtonGroup::selectedId() ) ); if (selectedToolButton) { // mmueller selectedToolButton->setChecked(false); //selectedToolButton->setOn(false); } } } void QmitkToolSelectionBox::OnToolManagerReferenceDataModified() { if (m_SelfCall) return; MITK_DEBUG << "OnToolManagerReferenceDataModified()"; SetGUIEnabledAccordingToToolManagerState(); } void QmitkToolSelectionBox::OnToolManagerWorkingDataModified() { if (m_SelfCall) return; MITK_DEBUG << "OnToolManagerWorkingDataModified()"; SetGUIEnabledAccordingToToolManagerState(); } /** Implementes the logic, which decides, when tools are activated/deactivated. */ void QmitkToolSelectionBox::SetGUIEnabledAccordingToToolManagerState() { mitk::DataNode* referenceNode = m_ToolManager->GetReferenceData(0); mitk::DataNode* workingNode = m_ToolManager->GetWorkingData(0); //MITK_DEBUG << this->name() << ": SetGUIEnabledAccordingToToolManagerState: referenceNode " << (void*)referenceNode << " workingNode " << (void*)workingNode << " isVisible() " << isVisible(); bool enabled = true; switch ( m_EnabledMode ) { default: case EnabledWithReferenceAndWorkingDataVisible: enabled = referenceNode && workingNode && referenceNode->IsVisible(mitk::BaseRenderer::GetInstance( mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget1"))) && workingNode->IsVisible(mitk::BaseRenderer::GetInstance( mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget1"))) && isVisible(); break; case EnabledWithReferenceData: enabled = referenceNode && isVisible(); break; case EnabledWithWorkingData: enabled = workingNode && isVisible(); break; case AlwaysEnabled: enabled = isVisible(); break; } if ( QWidget::isEnabled() == enabled ) return; // nothing to change QWidget::setEnabled( enabled ); if (enabled) { m_ToolManager->RegisterClient(); int id = m_ToolManager->GetActiveToolID(); emit ToolSelected(id); } else { m_ToolManager->ActivateTool(-1); m_ToolManager->UnregisterClient(); emit ToolSelected(-1); } } /** External enableization... */ void QmitkToolSelectionBox::setEnabled( bool enable ) { QWidget::setEnabled(enable); SetGUIEnabledAccordingToToolManagerState(); } void QmitkToolSelectionBox::RecreateButtons() { if (m_ToolManager.IsNull()) return; /* // remove all buttons that are there QObjectList *l = Q3ButtonGroup::queryList( "QButton" ); QObjectListIt it( *l ); // iterate over all buttons QObject *obj; while ( (obj = it.current()) != 0 ) { ++it; QButton* button = dynamic_cast(obj); if (button) { Q3ButtonGroup::remove(button); delete button; } } delete l; // delete the list, not the objects */ // mmueller Qt4 impl QList l = m_ToolButtonGroup->buttons(); // remove all buttons that are there QList::iterator it; QAbstractButton * btn; for(it=l.begin(); it!=l.end();++it) { btn = *it; m_ToolButtonGroup->removeButton(btn); //this->removeChild(btn); delete btn; } // end mmueller Qt4 impl mitk::ToolManager::ToolVectorTypeConst allPossibleTools = m_ToolManager->GetTools(); mitk::ToolManager::ToolVectorTypeConst allTools; typedef std::pair< std::string::size_type, const mitk::Tool* > SortPairType; typedef std::priority_queue< SortPairType > SortedToolQueueType; SortedToolQueueType toolPositions; // clear and sort all tools // step one: find name/group of all tools in m_DisplayedGroups string. remember these positions for all tools. for ( mitk::ToolManager::ToolVectorTypeConst::const_iterator iter = allPossibleTools.begin(); iter != allPossibleTools.end(); ++iter) { const mitk::Tool* tool = *iter; std::string::size_type namePos = m_DisplayedGroups.find( std::string("'") + tool->GetName() + "'" ); std::string::size_type groupPos = m_DisplayedGroups.find( std::string("'") + tool->GetGroup() + "'" ); if ( !m_DisplayedGroups.empty() && namePos == std::string::npos && groupPos == std::string::npos ) continue; // skip if ( m_DisplayedGroups.empty() && std::string(tool->GetName()).length() > 0 ) { namePos = static_cast (tool->GetName()[0]); } SortPairType thisPair = std::make_pair( namePos < groupPos ? namePos : groupPos, *iter ); toolPositions.push( thisPair ); } // step two: sort tools according to previously found positions in m_DisplayedGroups MITK_DEBUG << "Sorting order of tools (lower number --> earlier in button group)"; while ( !toolPositions.empty() ) { SortPairType thisPair = toolPositions.top(); MITK_DEBUG << "Position " << thisPair.first << " : " << thisPair.second->GetName(); allTools.push_back( thisPair.second ); toolPositions.pop(); } std::reverse( allTools.begin(), allTools.end() ); MITK_DEBUG << "Sorted tools:"; for ( mitk::ToolManager::ToolVectorTypeConst::const_iterator iter = allTools.begin(); iter != allTools.end(); ++iter) { MITK_DEBUG << (*iter)->GetName(); } // try to change layout... bad? //Q3GroupBox::setColumnLayout ( m_LayoutColumns, Qt::Horizontal ); // mmueller using gridlayout instead of Q3GroupBox //this->setLayout(0); if(m_ButtonLayout == NULL) m_ButtonLayout = new QGridLayout; /*else delete m_ButtonLayout;*/ int row(0); int column(-1); int currentButtonID(0); m_ButtonIDForToolID.clear(); m_ToolIDForButtonID.clear(); QToolButton* button = 0; MITK_DEBUG << "Creating buttons for tools"; // fill group box with buttons for ( mitk::ToolManager::ToolVectorTypeConst::const_iterator iter = allTools.begin(); iter != allTools.end(); ++iter) { const mitk::Tool* tool = *iter; int currentToolID( m_ToolManager->GetToolID( tool ) ); ++column; // new line if we are at the maximum columns if(column == m_LayoutColumns) { ++row; column = 0; } button = new QToolButton; button->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum)); // add new button to the group MITK_DEBUG << "Adding button with ID " << currentToolID; m_ToolButtonGroup->addButton(button, currentButtonID); // ... and to the layout MITK_DEBUG << "Adding button in row/column " << row << "/" << column; m_ButtonLayout->addWidget(button, row, column); if (m_LayoutColumns == 1) { //button->setTextPosition( QToolButton::BesideIcon ); // mmueller button->setToolButtonStyle( Qt::ToolButtonTextBesideIcon ); } else { //button->setTextPosition( QToolButton::BelowIcon ); // mmueller button->setToolButtonStyle( Qt::ToolButtonTextUnderIcon ); } //button->setToggleButton( true ); // mmueller button->setCheckable ( true ); if(currentToolID == m_ToolManager->GetActiveToolID()) button->setChecked(true); QString label; if (m_GenerateAccelerators) { label += "&"; } label += tool->GetName(); QString tooltip = tool->GetName(); MITK_DEBUG << tool->GetName() << ", " << label.toLocal8Bit().constData() << ", '" << tooltip.toLocal8Bit().constData(); if ( m_ShowNames ) { /* button->setUsesTextLabel(true); button->setTextLabel( label ); // a label QToolTip::add( button, tooltip ); */ // mmueller Qt4 button->setText( label ); // a label button->setToolTip( tooltip ); // mmueller QFont currentFont = button->font(); currentFont.setBold(false); button->setFont( currentFont ); } mitk::ModuleResource iconResource = tool->GetIconResource(); if (!iconResource.IsValid()) { button->setIcon(QIcon(QPixmap(tool->GetXPM()))); } else { mitk::ModuleResourceStream resourceStream(iconResource, std::ios::binary); resourceStream.seekg(0, std::ios::end); std::ios::pos_type length = resourceStream.tellg(); resourceStream.seekg(0, std::ios::beg); char* data = new char[length]; resourceStream.read(data, length); QPixmap pixmap; pixmap.loadFromData(QByteArray::fromRawData(data, length)); QIcon* icon = new QIcon(pixmap); delete[] data; button->setIcon(*icon); if (m_ShowNames) { if (m_LayoutColumns == 1) button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); else button->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); button->setIconSize(QSize(24, 24)); } else { button->setToolButtonStyle(Qt::ToolButtonIconOnly); button->setIconSize(QSize(32,32)); button->setToolTip(tooltip); } } if (m_GenerateAccelerators) { QString firstLetter = QString( tool->GetName() ); firstLetter.truncate( 1 ); button->setShortcut( firstLetter ); // a keyboard shortcut (just the first letter of the given name w/o any CTRL or something) } m_ButtonIDForToolID[currentToolID] = currentButtonID; m_ToolIDForButtonID[currentButtonID] = currentToolID; MITK_DEBUG << "m_ButtonIDForToolID[" << currentToolID << "] == " << currentButtonID; MITK_DEBUG << "m_ToolIDForButtonID[" << currentButtonID << "] == " << currentToolID; tool->GUIProcessEventsMessage += mitk::MessageDelegate( this, &QmitkToolSelectionBox::OnToolGUIProcessEventsMessage ); // will never add a listener twice, so we don't have to check here tool->ErrorMessage += mitk::MessageDelegate1( this, &QmitkToolSelectionBox::OnToolErrorMessage ); // will never add a listener twice, so we don't have to check here tool->GeneralMessage += mitk::MessageDelegate1( this, &QmitkToolSelectionBox::OnGeneralToolMessage ); ++currentButtonID; } // setting grid layout for this groupbox this->setLayout(m_ButtonLayout); //this->update(); } void QmitkToolSelectionBox::OnToolGUIProcessEventsMessage() { qApp->processEvents(); } void QmitkToolSelectionBox::OnToolErrorMessage(std::string s) { QMessageBox::critical(this, "MITK", QString( s.c_str() ), QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton); } void QmitkToolSelectionBox::OnGeneralToolMessage(std::string s) { QMessageBox::information(this, "MITK", QString( s.c_str() ), QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton); } void QmitkToolSelectionBox::SetDisplayedToolGroups(const std::string& toolGroups) { if (m_DisplayedGroups != toolGroups) { QString q_DisplayedGroups = toolGroups.c_str(); // quote all unquoted single words q_DisplayedGroups = q_DisplayedGroups.replace( QRegExp("\\b(\\w+)\\b|'([^']+)'"), "'\\1\\2'" ); MITK_DEBUG << "m_DisplayedGroups was \"" << toolGroups << "\""; m_DisplayedGroups = q_DisplayedGroups.toLocal8Bit().constData(); MITK_DEBUG << "m_DisplayedGroups is \"" << m_DisplayedGroups << "\""; RecreateButtons(); SetOrUnsetButtonForActiveTool(); } } void QmitkToolSelectionBox::SetLayoutColumns(int columns) { if (columns > 0 && columns != m_LayoutColumns) { m_LayoutColumns = columns; RecreateButtons(); } } void QmitkToolSelectionBox::SetShowNames(bool show) { if (show != m_ShowNames) { m_ShowNames = show; RecreateButtons(); } } void QmitkToolSelectionBox::SetAutoShowNamesWidth(int width) { width = std::max(0, width); if (m_AutoShowNamesWidth != width) { m_AutoShowNamesWidth = width; if (width != 0) this->SetShowNames(this->width() >= m_AutoShowNamesWidth); else this->SetShowNames(true); } } void QmitkToolSelectionBox::SetGenerateAccelerators(bool accel) { if (accel != m_GenerateAccelerators) { m_GenerateAccelerators = accel; RecreateButtons(); } } void QmitkToolSelectionBox::SetToolGUIArea( QWidget* parentWidget ) { m_ToolGUIWidget = parentWidget; } void QmitkToolSelectionBox::setTitle( const QString& /*title*/ ) { } void QmitkToolSelectionBox::showEvent( QShowEvent* e ) { QWidget::showEvent(e); SetGUIEnabledAccordingToToolManagerState(); } void QmitkToolSelectionBox::hideEvent( QHideEvent* e ) { QWidget::hideEvent(e); SetGUIEnabledAccordingToToolManagerState(); } void QmitkToolSelectionBox::resizeEvent( QResizeEvent* e ) { QWidget::resizeEvent(e); if (m_AutoShowNamesWidth != 0) this->SetShowNames(e->size().width() >= m_AutoShowNamesWidth); } diff --git a/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationView.cpp b/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationView.cpp index b34e611f13..677f6e93a3 100644 --- a/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationView.cpp +++ b/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationView.cpp @@ -1,1145 +1,1147 @@ /*=================================================================== 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 "mitkProperties.h" #include "mitkSegTool2D.h" #include "QmitkStdMultiWidget.h" #include "QmitkNewSegmentationDialog.h" #include #include #include "QmitkSegmentationView.h" #include "QmitkSegmentationOrganNamesHandling.cpp" #include #include "mitkVtkResliceInterpolationProperty.h" #include "mitkGetModuleContext.h" #include "mitkModule.h" #include "mitkModuleRegistry.h" #include "mitkModuleResource.h" #include "mitkStatusBar.h" #include "mitkApplicationCursor.h" #include "mitkSegmentationObjectFactory.h" +//micro service to get the ToolManager instance +#include "mitkToolManagerProvider.h" + const std::string QmitkSegmentationView::VIEW_ID = "org.mitk.views.segmentation"; // public methods QmitkSegmentationView::QmitkSegmentationView() :m_Parent(NULL) ,m_Controls(NULL) ,m_MultiWidget(NULL) ,m_DataSelectionChanged(false) ,m_MouseCursorSet(false) { RegisterSegmentationObjectFactory(); mitk::NodePredicateDataType::Pointer isDwi = mitk::NodePredicateDataType::New("DiffusionImage"); mitk::NodePredicateDataType::Pointer isDti = mitk::NodePredicateDataType::New("TensorImage"); mitk::NodePredicateDataType::Pointer isQbi = mitk::NodePredicateDataType::New("QBallImage"); mitk::NodePredicateOr::Pointer isDiffusionImage = mitk::NodePredicateOr::New(isDwi, isDti); isDiffusionImage = mitk::NodePredicateOr::New(isDiffusionImage, isQbi); m_IsOfTypeImagePredicate = mitk::NodePredicateOr::New(isDiffusionImage, mitk::TNodePredicateDataType::New()); m_IsBinaryPredicate = mitk::NodePredicateProperty::New("binary", mitk::BoolProperty::New(true)); m_IsNotBinaryPredicate = mitk::NodePredicateNot::New( m_IsBinaryPredicate ); m_IsNotABinaryImagePredicate = mitk::NodePredicateAnd::New( m_IsOfTypeImagePredicate, m_IsNotBinaryPredicate ); m_IsABinaryImagePredicate = mitk::NodePredicateAnd::New( m_IsOfTypeImagePredicate, m_IsBinaryPredicate); } QmitkSegmentationView::~QmitkSegmentationView() { delete m_Controls; } void QmitkSegmentationView::NewNodesGenerated() { MITK_WARN<<"Use of deprecated function: NewNodesGenerated!! This function is empty and will be removed in the next time!"; } void QmitkSegmentationView::NewNodeObjectsGenerated(mitk::ToolManager::DataVectorType* nodes) { if (!nodes) return; - mitk::ToolManager* toolManager = m_Controls->m_ManualToolSelectionBox2D->GetToolManager(); + mitk::ToolManager* toolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager(); if (!toolManager) return; for (mitk::ToolManager::DataVectorType::iterator iter = nodes->begin(); iter != nodes->end(); ++iter) { this->FireNodeSelected( *iter ); // only last iteration meaningful, multiple generated objects are not taken into account here } } void QmitkSegmentationView::Visible() { if (m_DataSelectionChanged) { this->OnSelectionChanged(this->GetDataManagerSelection()); } } void QmitkSegmentationView::Activated() { // should be moved to ::BecomesVisible() or similar if( m_Controls ) { //m_Controls->m_ManualToolSelectionBox2D->SetAutoShowNamesWidth(m_Controls->m_ManualToolSelectionBox2D->minimumSizeHint().width()+1); m_Controls->m_ManualToolSelectionBox2D->SetAutoShowNamesWidth(250); m_Controls->m_ManualToolSelectionBox2D->setEnabled( true ); //m_Controls->m_ManualToolSelectionBox3D->SetAutoShowNamesWidth(m_Controls->m_ManualToolSelectionBox3D->minimumSizeHint().width()+1); m_Controls->m_ManualToolSelectionBox3D->SetAutoShowNamesWidth(260); m_Controls->m_ManualToolSelectionBox3D->setEnabled( true ); // m_Controls->m_OrganToolSelectionBox->setEnabled( true ); // m_Controls->m_LesionToolSelectionBox->setEnabled( true ); // m_Controls->m_SlicesInterpolator->Enable3DInterpolation( m_Controls->widgetStack->currentWidget() == m_Controls->pageManual ); mitk::DataStorage::SetOfObjects::ConstPointer segmentations = this->GetDefaultDataStorage()->GetSubset( m_IsABinaryImagePredicate ); mitk::DataStorage::SetOfObjects::ConstPointer image = this->GetDefaultDataStorage()->GetSubset( m_IsNotABinaryImagePredicate ); if (!image->empty()) { OnSelectionChanged(*image->begin()); } for ( mitk::DataStorage::SetOfObjects::const_iterator iter = segmentations->begin(); iter != segmentations->end(); ++iter) { mitk::DataNode* node = *iter; itk::SimpleMemberCommand::Pointer command = itk::SimpleMemberCommand::New(); command->SetCallbackFunction(this, &QmitkSegmentationView::OnWorkingNodeVisibilityChanged); m_WorkingDataObserverTags.insert( std::pair( node, node->GetProperty("visible")->AddObserver( itk::ModifiedEvent(), command ) ) ); itk::SimpleMemberCommand::Pointer command2 = itk::SimpleMemberCommand::New(); command2->SetCallbackFunction(this, &QmitkSegmentationView::OnBinaryPropertyChanged); m_BinaryPropertyObserverTags.insert( std::pair( node, node->GetProperty("binary")->AddObserver( itk::ModifiedEvent(), command2 ) ) ); } } this->SetToolManagerSelection(m_Controls->patImageSelector->GetSelectedNode(), m_Controls->segImageSelector->GetSelectedNode()); } void QmitkSegmentationView::Deactivated() { if( m_Controls ) { m_Controls->m_ManualToolSelectionBox2D->setEnabled( false ); m_Controls->m_ManualToolSelectionBox3D->setEnabled( false ); //deactivate all tools - m_Controls->m_ManualToolSelectionBox2D->GetToolManager()->ActivateTool(-1); + mitk::ToolManagerProvider::GetInstance()->GetToolManager()->ActivateTool(-1); // m_Controls->m_OrganToolSelectionBox->setEnabled( false ); // m_Controls->m_LesionToolSelectionBox->setEnabled( false ); m_Controls->m_SlicesInterpolator->EnableInterpolation( false ); //Removing all observers for ( NodeTagMapType::iterator dataIter = m_WorkingDataObserverTags.begin(); dataIter != m_WorkingDataObserverTags.end(); ++dataIter ) { (*dataIter).first->GetProperty("visible")->RemoveObserver( (*dataIter).second ); } m_WorkingDataObserverTags.clear(); for ( NodeTagMapType::iterator dataIter = m_BinaryPropertyObserverTags.begin(); dataIter != m_BinaryPropertyObserverTags.end(); ++dataIter ) { (*dataIter).first->GetProperty("binary")->RemoveObserver( (*dataIter).second ); } m_BinaryPropertyObserverTags.clear(); // gets the context of the "Mitk" (Core) module (always has id 1) // TODO Workaround until CTK plugincontext is available mitk::ModuleContext* context = mitk::ModuleRegistry::GetModule(1)->GetModuleContext(); // Workaround end mitk::ServiceReference serviceRef = context->GetServiceReference(); mitk::PlanePositionManagerService* service = dynamic_cast(context->GetService(serviceRef)); service->RemoveAllPlanePositions(); } } void QmitkSegmentationView::StdMultiWidgetAvailable( QmitkStdMultiWidget& stdMultiWidget ) { SetMultiWidget(&stdMultiWidget); } void QmitkSegmentationView::StdMultiWidgetNotAvailable() { SetMultiWidget(NULL); } void QmitkSegmentationView::StdMultiWidgetClosed( QmitkStdMultiWidget& /*stdMultiWidget*/ ) { SetMultiWidget(NULL); } void QmitkSegmentationView::SetMultiWidget(QmitkStdMultiWidget* multiWidget) { // save the current multiwidget as the working widget m_MultiWidget = multiWidget; if (m_Parent) { m_Parent->setEnabled(m_MultiWidget); } // tell the interpolation about toolmanager and multiwidget (and data storage) if (m_Controls && m_MultiWidget) { - mitk::ToolManager* toolManager = m_Controls->m_ManualToolSelectionBox2D->GetToolManager(); + mitk::ToolManager* toolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager(); m_Controls->m_SlicesInterpolator->SetDataStorage( this->GetDefaultDataStorage()); QList controllers; controllers.push_back(m_MultiWidget->GetRenderWindow1()->GetSliceNavigationController()); controllers.push_back(m_MultiWidget->GetRenderWindow2()->GetSliceNavigationController()); controllers.push_back(m_MultiWidget->GetRenderWindow3()->GetSliceNavigationController()); m_Controls->m_SlicesInterpolator->Initialize( toolManager, controllers ); } } void QmitkSegmentationView::OnPreferencesChanged(const berry::IBerryPreferences* prefs) { m_AutoSelectionEnabled = prefs->GetBool("auto selection", false); } void QmitkSegmentationView::CreateNewSegmentation() { - mitk::DataNode::Pointer node = m_Controls->m_ManualToolSelectionBox2D->GetToolManager()->GetReferenceData(0); + mitk::DataNode::Pointer node = mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetReferenceData(0); if (node.IsNotNull()) { mitk::Image::Pointer image = dynamic_cast( node->GetData() ); if (image.IsNotNull()) { if (image->GetDimension()>1) { // ask about the name and organ type of the new segmentation QmitkNewSegmentationDialog* dialog = new QmitkNewSegmentationDialog( m_Parent ); // needs a QWidget as parent, "this" is not QWidget QString storedList = QString::fromStdString( this->GetPreferences()->GetByteArray("Organ-Color-List","") ); QStringList organColors; if (storedList.isEmpty()) { organColors = GetDefaultOrganColorString(); } else { /* a couple of examples of how organ names are stored: a simple item is built up like 'name#AABBCC' where #AABBCC is the hexadecimal notation of a color as known from HTML items are stored separated by ';' this makes it necessary to escape occurrences of ';' in name. otherwise the string "hugo;ypsilon#AABBCC;eugen#AABBCC" could not be parsed as two organs but we would get "hugo" and "ypsilon#AABBCC" and "eugen#AABBCC" so the organ name "hugo;ypsilon" is stored as "hugo\;ypsilon" and must be unescaped after loading the following lines could be one split with Perl's negative lookbehind */ // recover string list from BlueBerry view's preferences QString storedString = QString::fromStdString( this->GetPreferences()->GetByteArray("Organ-Color-List","") ); MITK_DEBUG << "storedString: " << storedString.toStdString(); // match a string consisting of any number of repetitions of either "anything but ;" or "\;". This matches everything until the next unescaped ';' QRegExp onePart("(?:[^;]|\\\\;)*"); MITK_DEBUG << "matching " << onePart.pattern().toStdString(); int count = 0; int pos = 0; while( (pos = onePart.indexIn( storedString, pos )) != -1 ) { ++count; int length = onePart.matchedLength(); if (length == 0) break; QString matchedString = storedString.mid(pos, length); MITK_DEBUG << " Captured length " << length << ": " << matchedString.toStdString(); pos += length + 1; // skip separating ';' // unescape possible occurrences of '\;' in the string matchedString.replace("\\;", ";"); // add matched string part to output list organColors << matchedString; } MITK_DEBUG << "Captured " << count << " organ name/colors"; } dialog->SetSuggestionList( organColors ); int dialogReturnValue = dialog->exec(); if ( dialogReturnValue == QDialog::Rejected ) return; // user clicked cancel or pressed Esc or something similar // ask the user about an organ type and name, add this information to the image's (!) propertylist // create a new image of the same dimensions and smallest possible pixel type - mitk::ToolManager* toolManager = m_Controls->m_ManualToolSelectionBox2D->GetToolManager(); + mitk::ToolManager* toolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager(); mitk::Tool* firstTool = toolManager->GetToolById(0); if (firstTool) { try { std::string newNodeName = dialog->GetSegmentationName().toStdString(); if(newNodeName.empty()) newNodeName = "no_name"; mitk::DataNode::Pointer emptySegmentation = firstTool->CreateEmptySegmentationNode( image, newNodeName, dialog->GetColor() ); // initialize showVolume to false to prevent recalculating the volume while working on the segmentation emptySegmentation->SetProperty( "showVolume", mitk::BoolProperty::New( false ) ); if (!emptySegmentation) return; // could be aborted by user UpdateOrganList( organColors, dialog->GetSegmentationName(), dialog->GetColor() ); /* escape ';' here (replace by '\;'), see longer comment above */ std::string stringForStorage = organColors.replaceInStrings(";","\\;").join(";").toStdString(); MITK_DEBUG << "Will store: " << stringForStorage; this->GetPreferences()->PutByteArray("Organ-Color-List", stringForStorage ); this->GetPreferences()->Flush(); - if(m_Controls->m_ManualToolSelectionBox2D->GetToolManager()->GetWorkingData(0)) + if(mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetWorkingData(0)) { - m_Controls->m_ManualToolSelectionBox2D->GetToolManager()->GetWorkingData(0)->SetSelected(false); + mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetWorkingData(0)->SetSelected(false); } emptySegmentation->SetSelected(true); this->GetDefaultDataStorage()->Add( emptySegmentation, node ); // add as a child, because the segmentation "derives" from the original itk::SimpleMemberCommand::Pointer command = itk::SimpleMemberCommand::New(); command->SetCallbackFunction(this, &QmitkSegmentationView::OnWorkingNodeVisibilityChanged); m_WorkingDataObserverTags.insert( std::pair( emptySegmentation, emptySegmentation->GetProperty("visible")->AddObserver( itk::ModifiedEvent(), command ) ) ); itk::SimpleMemberCommand::Pointer command2 = itk::SimpleMemberCommand::New(); command2->SetCallbackFunction(this, &QmitkSegmentationView::OnBinaryPropertyChanged); m_BinaryPropertyObserverTags.insert( std::pair( emptySegmentation, emptySegmentation->GetProperty("binary")->AddObserver( itk::ModifiedEvent(), command2 ) ) ); this->ApplyDisplayOptions( emptySegmentation ); this->FireNodeSelected( emptySegmentation ); this->OnSelectionChanged( emptySegmentation ); m_Controls->segImageSelector->SetSelectedNode(emptySegmentation); } catch (std::bad_alloc) { QMessageBox::warning(NULL,"Create new segmentation","Could not allocate memory for new segmentation"); } } } else { QMessageBox::information(NULL,"Segmentation","Segmentation is currently not supported for 2D images"); } } } else { MITK_ERROR << "'Create new segmentation' button should never be clickable unless a patient image is selected..."; } } void QmitkSegmentationView::OnWorkingNodeVisibilityChanged() { mitk::DataNode* selectedNode = m_Controls->segImageSelector->GetSelectedNode(); bool selectedNodeIsVisible = selectedNode->IsVisible(mitk::BaseRenderer::GetInstance( mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget1"))); if (m_Controls->tab2DTools->isVisible() && !selectedNodeIsVisible) { m_Controls->m_ManualToolSelectionBox2D->setEnabled(false); this->UpdateWarningLabel("The selected segmentation is currently not visible!"); m_Controls->m_SlicesInterpolator->Show3DInterpolationResult(false); - m_Controls->m_ManualToolSelectionBox2D->GetToolManager()->ActivateTool(-1); + mitk::ToolManagerProvider::GetInstance()->GetToolManager()->ActivateTool(-1); } else { m_Controls->m_ManualToolSelectionBox2D->setEnabled(true); this->UpdateWarningLabel(""); //Trigger 3d interpolation is selected segmentation is visible again mitk::SurfaceInterpolationController::GetInstance()->Modified(); } } void QmitkSegmentationView::OnBinaryPropertyChanged() { mitk::DataStorage::SetOfObjects::ConstPointer patImages = m_Controls->patImageSelector->GetNodes(); bool isBinary(false); for (mitk::DataStorage::SetOfObjects::ConstIterator it = patImages->Begin(); it != patImages->End(); ++it) { const mitk::DataNode* node = it->Value(); node->GetBoolProperty("binary", isBinary); if(isBinary) { m_Controls->patImageSelector->RemoveNode(node); m_Controls->segImageSelector->AddNode(node); this->SetToolManagerSelection(NULL,NULL); return; } } mitk::DataStorage::SetOfObjects::ConstPointer segImages = m_Controls->segImageSelector->GetNodes(); isBinary = true; for (mitk::DataStorage::SetOfObjects::ConstIterator it = segImages->Begin(); it != segImages->End(); ++it) { const mitk::DataNode* node = it->Value(); node->GetBoolProperty("binary", isBinary); if(!isBinary) { m_Controls->segImageSelector->RemoveNode(node); m_Controls->patImageSelector->AddNode(node); - if (m_Controls->m_ManualToolSelectionBox2D->GetToolManager()->GetWorkingData(0) == node) - m_Controls->m_ManualToolSelectionBox2D->GetToolManager()->SetWorkingData(NULL); + if (mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetWorkingData(0) == node) + mitk::ToolManagerProvider::GetInstance()->GetToolManager()->SetWorkingData(NULL); return; } } } void QmitkSegmentationView::NodeAdded(const mitk::DataNode *node) { bool isBinary (false); bool isHelperObject (false); node->GetBoolProperty("binary", isBinary); node->GetBoolProperty("helper object", isHelperObject); if (m_AutoSelectionEnabled) { if (!isBinary && dynamic_cast(node->GetData())) { FireNodeSelected(const_cast(node)); } } if (isBinary && !isHelperObject) { itk::SimpleMemberCommand::Pointer command = itk::SimpleMemberCommand::New(); command->SetCallbackFunction(this, &QmitkSegmentationView::OnWorkingNodeVisibilityChanged); m_WorkingDataObserverTags.insert( std::pair( const_cast(node), node->GetProperty("visible")->AddObserver( itk::ModifiedEvent(), command ) ) ); itk::SimpleMemberCommand::Pointer command2 = itk::SimpleMemberCommand::New(); command2->SetCallbackFunction(this, &QmitkSegmentationView::OnBinaryPropertyChanged); m_BinaryPropertyObserverTags.insert( std::pair( const_cast(node), node->GetProperty("binary")->AddObserver( itk::ModifiedEvent(), command2 ) ) ); this->ApplyDisplayOptions( const_cast(node) ); } } void QmitkSegmentationView::NodeRemoved(const mitk::DataNode* node) { bool isSeg(false); bool isHelperObject(false); node->GetBoolProperty("helper object", isHelperObject); node->GetBoolProperty("binary", isSeg); mitk::Image* image = dynamic_cast(node->GetData()); if(isSeg && !isHelperObject && image) { //First of all remove all possible contour markers of the segmentation mitk::DataStorage::SetOfObjects::ConstPointer allContourMarkers = this->GetDataStorage()->GetDerivations(node, mitk::NodePredicateProperty::New("isContourMarker" , mitk::BoolProperty::New(true))); // gets the context of the "Mitk" (Core) module (always has id 1) // TODO Workaround until CTK plugincontext is available mitk::ModuleContext* context = mitk::ModuleRegistry::GetModule(1)->GetModuleContext(); // Workaround end mitk::ServiceReference serviceRef = context->GetServiceReference(); mitk::PlanePositionManagerService* service = dynamic_cast(context->GetService(serviceRef)); for (mitk::DataStorage::SetOfObjects::ConstIterator it = allContourMarkers->Begin(); it != allContourMarkers->End(); ++it) { std::string nodeName = node->GetName(); unsigned int t = nodeName.find_last_of(" "); unsigned int id = atof(nodeName.substr(t+1).c_str())-1; service->RemovePlanePosition(id); this->GetDataStorage()->Remove(it->Value()); } - if ((m_Controls->m_ManualToolSelectionBox2D->GetToolManager()->GetWorkingData(0) == node) && m_Controls->patImageSelector->GetSelectedNode().IsNotNull()) + if ((mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetWorkingData(0) == node) && m_Controls->patImageSelector->GetSelectedNode().IsNotNull()) { - this->SetToolManagerSelection(m_Controls->m_ManualToolSelectionBox2D->GetToolManager()->GetReferenceData(0), NULL); + this->SetToolManagerSelection(mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetReferenceData(0), NULL); this->UpdateWarningLabel("Select or create a segmentation!"); } mitk::SurfaceInterpolationController::GetInstance()->RemoveSegmentationFromContourList(image); } mitk::DataNode* tempNode = const_cast(node); //Since the binary property could be changed during runtime by the user if (image && !isHelperObject) { node->GetProperty("visible")->RemoveObserver( m_WorkingDataObserverTags[tempNode] ); m_WorkingDataObserverTags.erase(tempNode); node->GetProperty("binary")->RemoveObserver( m_BinaryPropertyObserverTags[tempNode] ); m_BinaryPropertyObserverTags.erase(tempNode); } - if((m_Controls->m_ManualToolSelectionBox2D->GetToolManager()->GetReferenceData(0) == node)) + if((mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetReferenceData(0) == node)) { //as we don't know which node was actually removed e.g. our reference node, disable 'New Segmentation' button. //consider the case that there is no more image in the datastorage this->SetToolManagerSelection(NULL, NULL); } } //void QmitkSegmentationView::CreateSegmentationFromSurface() //{ // mitk::DataNode::Pointer surfaceNode = // m_Controls->MaskSurfaces->GetSelectedNode(); // mitk::Surface::Pointer surface(0); // if(surfaceNode.IsNotNull()) // surface = dynamic_cast ( surfaceNode->GetData() ); // if(surface.IsNull()) // { // this->HandleException( "No surface selected.", m_Parent, true); // return; // } // mitk::DataNode::Pointer imageNode -// = m_Controls->m_ManualToolSelectionBox2D->GetToolManager()->GetReferenceData(0); +// = mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetReferenceData(0); // mitk::Image::Pointer image(0); // if (imageNode.IsNotNull()) // image = dynamic_cast( imageNode->GetData() ); // if(image.IsNull()) // { // this->HandleException( "No image selected.", m_Parent, true); // return; // } // mitk::SurfaceToImageFilter::Pointer s2iFilter // = mitk::SurfaceToImageFilter::New(); // s2iFilter->MakeOutputBinaryOn(); // s2iFilter->SetInput(surface); // s2iFilter->SetImage(image); // s2iFilter->Update(); // mitk::DataNode::Pointer resultNode = mitk::DataNode::New(); // std::string nameOfResultImage = imageNode->GetName(); // nameOfResultImage.append(surfaceNode->GetName()); // resultNode->SetProperty("name", mitk::StringProperty::New(nameOfResultImage) ); // resultNode->SetProperty("binary", mitk::BoolProperty::New(true) ); // resultNode->SetData( s2iFilter->GetOutput() ); // this->GetDataStorage()->Add(resultNode, imageNode); //} //void QmitkSegmentationView::ToolboxStackPageChanged(int id) //{ // // interpolation only with manual tools visible // m_Controls->m_SlicesInterpolator->EnableInterpolation( id == 0 ); // if( id == 0 ) // { -// mitk::DataNode::Pointer workingData = m_Controls->m_ManualToolSelectionBox2D->GetToolManager()->GetWorkingData(0); +// mitk::DataNode::Pointer workingData = mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetWorkingData(0); // if( workingData.IsNotNull() ) // { // m_Controls->segImageSelector->setCurrentIndex( m_Controls->segImageSelector->Find(workingData) ); // } // } // // this is just a workaround, should be removed when all tools support 3D+t // if (id==2) // lesions // { -// mitk::DataNode::Pointer node = m_Controls->m_ManualToolSelectionBox2D->GetToolManager()->GetReferenceData(0); +// mitk::DataNode::Pointer node = mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetReferenceData(0); // if (node.IsNotNull()) // { // mitk::Image::Pointer image = dynamic_cast( node->GetData() ); // if (image.IsNotNull()) // { // if (image->GetDimension()>3) // { // m_Controls->widgetStack->setCurrentIndex(0); // QMessageBox::information(NULL,"Segmentation","Lesion segmentation is currently not supported for 4D images"); // } // } // } // } //} // protected void QmitkSegmentationView::OnPatientComboBoxSelectionChanged( const mitk::DataNode* node ) { //mitk::DataNode* selectedNode = const_cast(node); if( node != NULL ) { this->UpdateWarningLabel(""); mitk::DataNode* segNode = m_Controls->segImageSelector->GetSelectedNode(); if (segNode) { mitk::DataStorage::SetOfObjects::ConstPointer possibleParents = this->GetDefaultDataStorage()->GetSources( segNode, m_IsNotABinaryImagePredicate ); bool isSourceNode(false); for (mitk::DataStorage::SetOfObjects::ConstIterator it = possibleParents->Begin(); it != possibleParents->End(); it++) { if (it.Value() == node) isSourceNode = true; } if ( !isSourceNode && (!this->CheckForSameGeometry(segNode, node) || possibleParents->Size() > 0 )) { this->SetToolManagerSelection(node, NULL); this->UpdateWarningLabel("The selected patient image does not\nmatch with the selected segmentation!"); } else if ((!isSourceNode && this->CheckForSameGeometry(segNode, node)) || isSourceNode ) { this->SetToolManagerSelection(node, segNode); //Doing this we can assure that the segmenation is always visible if the segmentation and the patient image are //loaded separately int layer(10); node->GetIntProperty("layer", layer); layer++; segNode->SetProperty("layer", mitk::IntProperty::New(layer)); this->UpdateWarningLabel(""); } } else { this->SetToolManagerSelection(node, NULL); this->UpdateWarningLabel("Select or create a segmentation"); } } else { this->UpdateWarningLabel("Please load an image!"); } } void QmitkSegmentationView::OnSegmentationComboBoxSelectionChanged(const mitk::DataNode *node) { if ( node == 0) return; mitk::DataNode* refNode = m_Controls->patImageSelector->GetSelectedNode(); if (m_AutoSelectionEnabled) { this->OnSelectionChanged(const_cast(node)); } else { mitk::DataStorage::SetOfObjects::ConstPointer possibleParents = this->GetDefaultDataStorage()->GetSources( node, m_IsNotABinaryImagePredicate ); if ( possibleParents->Size() == 1 ) { mitk::DataNode* parentNode = possibleParents->ElementAt(0); if (parentNode != refNode) { this->UpdateWarningLabel("The selected segmentation does not\nmatch with the selected patient image!"); this->SetToolManagerSelection(NULL, node); } else { this->UpdateWarningLabel(""); this->SetToolManagerSelection(refNode, node); } } else if (refNode && this->CheckForSameGeometry(node, refNode)) { this->UpdateWarningLabel(""); this->SetToolManagerSelection(refNode, node); } else if (!refNode || !this->CheckForSameGeometry(node, refNode)) { this->UpdateWarningLabel("Please select or load the according patient image!"); } } if (!node->IsVisible(mitk::BaseRenderer::GetInstance( mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget1")))) this->UpdateWarningLabel("The selected segmentation is currently not visible!"); } void QmitkSegmentationView::OnShowMarkerNodes (bool state) { mitk::SegTool2D::Pointer manualSegmentationTool; - unsigned int numberOfExistingTools = m_Controls->m_ManualToolSelectionBox2D->GetToolManager()->GetTools().size(); + unsigned int numberOfExistingTools = mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetTools().size(); for(unsigned int i = 0; i < numberOfExistingTools; i++) { - manualSegmentationTool = dynamic_cast(m_Controls->m_ManualToolSelectionBox2D->GetToolManager()->GetToolById(i)); + manualSegmentationTool = dynamic_cast(mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetToolById(i)); if (manualSegmentationTool) { if(state == true) { manualSegmentationTool->SetShowMarkerNodes( true ); } else { manualSegmentationTool->SetShowMarkerNodes( false ); } } } } void QmitkSegmentationView::OnSelectionChanged(mitk::DataNode* node) { std::vector nodes; nodes.push_back( node ); this->OnSelectionChanged( nodes ); } //void QmitkSegmentationView::OnSurfaceSelectionChanged() //{ // // if Image and Surface are selected, enable button // if ( (m_Controls->patImageSelector->GetSelectedNode().IsNull()) || // (m_Controls->MaskSurfaces->GetSelectedNode().IsNull())) // m_Controls->CreateSegmentationFromSurface->setEnabled(false); // else // m_Controls->CreateSegmentationFromSurface->setEnabled(true); //} void QmitkSegmentationView::OnSelectionChanged(std::vector nodes) { if (nodes.size() != 0) { std::string markerName = "Position"; unsigned int numberOfNodes = nodes.size(); std::string nodeName = nodes.at( 0 )->GetName(); if ( ( numberOfNodes == 1 ) && ( nodeName.find( markerName ) == 0) ) { this->OnContourMarkerSelected( nodes.at( 0 ) ); return; } } if (m_AutoSelectionEnabled && this->IsActivated()) { if (nodes.size() == 0 && m_Controls->patImageSelector->GetSelectedNode().IsNull()) { SetToolManagerSelection(NULL,NULL); } else if (nodes.size() == 1) { mitk::DataNode::Pointer selectedNode = nodes.at(0); if(selectedNode.IsNull()) { return; } mitk::Image::Pointer selectedImage = dynamic_cast(selectedNode->GetData()); if (selectedImage.IsNull()) { SetToolManagerSelection(NULL,NULL); return; } else { bool isASegmentation(false); selectedNode->GetBoolProperty("binary", isASegmentation); if (isASegmentation) { //If a segmentation is selected find a possible reference image: mitk::DataStorage::SetOfObjects::ConstPointer sources = this->GetDataStorage()->GetSources(selectedNode, m_IsNotABinaryImagePredicate); mitk::DataNode::Pointer refNode; if (sources->Size() != 0) { refNode = sources->ElementAt(0); refNode->SetVisibility(true); selectedNode->SetVisibility(true); SetToolManagerSelection(refNode,selectedNode); mitk::DataStorage::SetOfObjects::ConstPointer otherSegmentations = this->GetDataStorage()->GetSubset(m_IsABinaryImagePredicate); for(mitk::DataStorage::SetOfObjects::const_iterator iter = otherSegmentations->begin(); iter != otherSegmentations->end(); ++iter) { mitk::DataNode* node = *iter; if (dynamic_cast(node->GetData()) != selectedImage.GetPointer()) node->SetVisibility(false); } mitk::DataStorage::SetOfObjects::ConstPointer otherPatientImages = this->GetDataStorage()->GetSubset(m_IsNotABinaryImagePredicate); for(mitk::DataStorage::SetOfObjects::const_iterator iter = otherPatientImages->begin(); iter != otherPatientImages->end(); ++iter) { mitk::DataNode* node = *iter; if (dynamic_cast(node->GetData()) != dynamic_cast(refNode->GetData())) node->SetVisibility(false); } } else { mitk::DataStorage::SetOfObjects::ConstPointer possiblePatientImages = this->GetDataStorage()->GetSubset(m_IsNotABinaryImagePredicate); for (mitk::DataStorage::SetOfObjects::ConstIterator it = possiblePatientImages->Begin(); it != possiblePatientImages->End(); it++) { refNode = it->Value(); if (this->CheckForSameGeometry(selectedNode, it->Value())) { refNode->SetVisibility(true); selectedNode->SetVisibility(true); mitk::DataStorage::SetOfObjects::ConstPointer otherSegmentations = this->GetDataStorage()->GetSubset(m_IsABinaryImagePredicate); for(mitk::DataStorage::SetOfObjects::const_iterator iter = otherSegmentations->begin(); iter != otherSegmentations->end(); ++iter) { mitk::DataNode* node = *iter; if (dynamic_cast(node->GetData()) != selectedImage.GetPointer()) node->SetVisibility(false); } mitk::DataStorage::SetOfObjects::ConstPointer otherPatientImages = this->GetDataStorage()->GetSubset(m_IsNotABinaryImagePredicate); for(mitk::DataStorage::SetOfObjects::const_iterator iter = otherPatientImages->begin(); iter != otherPatientImages->end(); ++iter) { mitk::DataNode* node = *iter; if (dynamic_cast(node->GetData()) != dynamic_cast(refNode->GetData())) node->SetVisibility(false); } this->SetToolManagerSelection(refNode, selectedNode); //Doing this we can assure that the segmenation is always visible if the segmentation and the patient image are at the //same level in the datamanager int layer(10); refNode->GetIntProperty("layer", layer); layer++; selectedNode->SetProperty("layer", mitk::IntProperty::New(layer)); return; } } this->SetToolManagerSelection(NULL, selectedNode); } } else { - if (m_Controls->m_ManualToolSelectionBox2D->GetToolManager()->GetReferenceData(0) != selectedNode) + if (mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetReferenceData(0) != selectedNode) { SetToolManagerSelection(selectedNode, NULL); //May be a bug in the selection services. A node which is deselected will be passed as selected node to the OnSelectionChanged function if (!selectedNode->IsVisible(mitk::BaseRenderer::GetInstance( mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget1")))) selectedNode->SetVisibility(true); this->UpdateWarningLabel("The selected patient image does not\nmatchwith the selected segmentation!"); } } } } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkSegmentationView::OnContourMarkerSelected(const mitk::DataNode *node) { QmitkRenderWindow* selectedRenderWindow = 0; QmitkRenderWindow* RenderWindow1 = this->GetActiveStdMultiWidget()->GetRenderWindow1(); QmitkRenderWindow* RenderWindow2 = this->GetActiveStdMultiWidget()->GetRenderWindow2(); QmitkRenderWindow* RenderWindow3 = this->GetActiveStdMultiWidget()->GetRenderWindow3(); QmitkRenderWindow* RenderWindow4 = this->GetActiveStdMultiWidget()->GetRenderWindow4(); bool PlanarFigureInitializedWindow = false; // find initialized renderwindow if (node->GetBoolProperty("PlanarFigureInitializedWindow", PlanarFigureInitializedWindow, RenderWindow1->GetRenderer())) { selectedRenderWindow = RenderWindow1; } if (!selectedRenderWindow && node->GetBoolProperty( "PlanarFigureInitializedWindow", PlanarFigureInitializedWindow, RenderWindow2->GetRenderer())) { selectedRenderWindow = RenderWindow2; } if (!selectedRenderWindow && node->GetBoolProperty( "PlanarFigureInitializedWindow", PlanarFigureInitializedWindow, RenderWindow3->GetRenderer())) { selectedRenderWindow = RenderWindow3; } if (!selectedRenderWindow && node->GetBoolProperty( "PlanarFigureInitializedWindow", PlanarFigureInitializedWindow, RenderWindow4->GetRenderer())) { selectedRenderWindow = RenderWindow4; } // make node visible if (selectedRenderWindow) { std::string nodeName = node->GetName(); unsigned int t = nodeName.find_last_of(" "); unsigned int id = atof(nodeName.substr(t+1).c_str())-1; // gets the context of the "Mitk" (Core) module (always has id 1) // TODO Workaround until CTL plugincontext is available mitk::ModuleContext* context = mitk::ModuleRegistry::GetModule(1)->GetModuleContext(); // Workaround end mitk::ServiceReference serviceRef = context->GetServiceReference(); mitk::PlanePositionManagerService* service = dynamic_cast(context->GetService(serviceRef)); selectedRenderWindow->GetSliceNavigationController()->ExecuteOperation(service->GetPlanePosition(id)); selectedRenderWindow->GetRenderer()->GetDisplayGeometry()->Fit(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkSegmentationView::OnTabWidgetChanged(int id) { + //always disable tools on tab changed + mitk::ToolManagerProvider::GetInstance()->GetToolManager()->ActivateTool(-1); + //2D Tab ID = 0 //3D Tab ID = 1 if (id == 0) { //Hide 3D selection box, show 2D selection box m_Controls->m_ManualToolSelectionBox3D->hide(); m_Controls->m_ManualToolSelectionBox2D->show(); //Deactivate possible active tool - m_Controls->m_ManualToolSelectionBox3D->GetToolManager()->ActivateTool(-1); //TODO Remove possible visible interpolations -> Maybe changes in SlicesInterpolator } else { //Hide 3D selection box, show 2D selection box m_Controls->m_ManualToolSelectionBox2D->hide(); m_Controls->m_ManualToolSelectionBox3D->show(); //Deactivate possible active tool - m_Controls->m_ManualToolSelectionBox2D->GetToolManager()->ActivateTool(-1); } } void QmitkSegmentationView::SetToolManagerSelection(const mitk::DataNode* referenceData, const mitk::DataNode* workingData) { // called as a result of new BlueBerry selections // tells the ToolManager for manual segmentation about new selections // updates GUI information about what the user should select - mitk::ToolManager* toolManager = m_Controls->m_ManualToolSelectionBox2D->GetToolManager(); + mitk::ToolManager* toolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager(); toolManager->SetReferenceData(const_cast(referenceData)); toolManager->SetWorkingData( const_cast(workingData)); // check original image m_Controls->btnNewSegmentation->setEnabled(referenceData != NULL); if (referenceData) { this->UpdateWarningLabel(""); disconnect( m_Controls->patImageSelector, SIGNAL( OnSelectionChanged( const mitk::DataNode* ) ), this, SLOT( OnPatientComboBoxSelectionChanged( const mitk::DataNode* ) ) ); m_Controls->patImageSelector->setCurrentIndex( m_Controls->patImageSelector->Find(referenceData) ); connect( m_Controls->patImageSelector, SIGNAL( OnSelectionChanged( const mitk::DataNode* ) ), this, SLOT( OnPatientComboBoxSelectionChanged( const mitk::DataNode* ) ) ); } // check segmentation if (referenceData) { if (workingData) { this->FireNodeSelected(const_cast(workingData)); // mitk::RenderingManager::GetInstance()->InitializeViews(workingData->GetData()->GetTimeSlicedGeometry(), // mitk::RenderingManager::REQUEST_UPDATE_ALL, true ); // if( m_Controls->widgetStack->currentIndex() == 0 ) // { disconnect( m_Controls->segImageSelector, SIGNAL( OnSelectionChanged( const mitk::DataNode* ) ), this, SLOT( OnSegmentationComboBoxSelectionChanged( const mitk::DataNode* ) ) ); m_Controls->segImageSelector->setCurrentIndex(m_Controls->segImageSelector->Find(workingData)); connect( m_Controls->segImageSelector, SIGNAL( OnSelectionChanged( const mitk::DataNode* ) ), this, SLOT( OnSegmentationComboBoxSelectionChanged(const mitk::DataNode*)) ); // } } } } void QmitkSegmentationView::ApplyDisplayOptions(mitk::DataNode* node) { if (!node) return; bool isBinary(false); node->GetPropertyValue("binary", isBinary); if (isBinary) { node->SetProperty( "outline binary", mitk::BoolProperty::New( this->GetPreferences()->GetBool("draw outline", true)) ); node->SetProperty( "outline width", mitk::FloatProperty::New( 2.0 ) ); node->SetProperty( "opacity", mitk::FloatProperty::New( this->GetPreferences()->GetBool("draw outline", true) ? 1.0 : 0.3 ) ); node->SetProperty( "volumerendering", mitk::BoolProperty::New( this->GetPreferences()->GetBool("volume rendering", false) ) ); } } bool QmitkSegmentationView::CheckForSameGeometry(const mitk::DataNode *node1, const mitk::DataNode *node2) const { bool isSameGeometry(true); mitk::Image* image1 = dynamic_cast(node1->GetData()); mitk::Image* image2 = dynamic_cast(node2->GetData()); if (image1 && image2) { mitk::Geometry3D* geo1 = image1->GetGeometry(); mitk::Geometry3D* geo2 = image2->GetGeometry(); isSameGeometry = isSameGeometry && mitk::Equal(geo1->GetOrigin(), geo2->GetOrigin()); isSameGeometry = isSameGeometry && mitk::Equal(geo1->GetExtent(0), geo2->GetExtent(0)); isSameGeometry = isSameGeometry && mitk::Equal(geo1->GetExtent(1), geo2->GetExtent(1)); isSameGeometry = isSameGeometry && mitk::Equal(geo1->GetExtent(2), geo2->GetExtent(2)); isSameGeometry = isSameGeometry && mitk::Equal(geo1->GetSpacing(), geo2->GetSpacing()); isSameGeometry = isSameGeometry && mitk::MatrixEqualElementWise(geo1->GetIndexToWorldTransform()->GetMatrix(), geo2->GetIndexToWorldTransform()->GetMatrix()); return isSameGeometry; } else { return false; } } void QmitkSegmentationView::UpdateWarningLabel(QString text) { if (text.size() == 0) m_Controls->lblSegmentationWarnings->hide(); else m_Controls->lblSegmentationWarnings->show(); m_Controls->lblSegmentationWarnings->setText(text); } void QmitkSegmentationView::CreateQtPartControl(QWidget* parent) { // setup the basic GUI of this view m_Parent = parent; m_Controls = new Ui::QmitkSegmentationControls; m_Controls->setupUi(parent); m_Controls->patImageSelector->SetDataStorage(this->GetDefaultDataStorage()); m_Controls->patImageSelector->SetPredicate(m_IsNotABinaryImagePredicate); this->UpdateWarningLabel("Please load an image"); if( m_Controls->patImageSelector->GetSelectedNode().IsNotNull() ) this->UpdateWarningLabel("Select or create a new segmentation"); m_Controls->segImageSelector->SetDataStorage(this->GetDefaultDataStorage()); m_Controls->segImageSelector->SetPredicate(m_IsABinaryImagePredicate); if( m_Controls->segImageSelector->GetSelectedNode().IsNotNull() ) this->UpdateWarningLabel(""); - mitk::ToolManager* toolManager = m_Controls->m_ManualToolSelectionBox2D->GetToolManager(); + mitk::ToolManager* toolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager(); toolManager->SetDataStorage( *(this->GetDefaultDataStorage()) ); assert ( toolManager ); - //use the same ToolManager instance for our 3D Tools - m_Controls->m_ManualToolSelectionBox3D->SetToolManager(*toolManager); // all part of open source MITK m_Controls->m_ManualToolSelectionBox2D->SetGenerateAccelerators(true); m_Controls->m_ManualToolSelectionBox2D->SetToolGUIArea( m_Controls->m_ManualToolGUIContainer2D ); m_Controls->m_ManualToolSelectionBox2D->SetDisplayedToolGroups("Add Subtract Correction Paint Wipe 'Region Growing' Fill Erase 'Live Wire' 'FastMarching2D'"); m_Controls->m_ManualToolSelectionBox2D->SetLayoutColumns(3); m_Controls->m_ManualToolSelectionBox2D->SetEnabledMode( QmitkToolSelectionBox::EnabledWithReferenceAndWorkingDataVisible ); connect( m_Controls->m_ManualToolSelectionBox2D, SIGNAL(ToolSelected(int)), this, SLOT(OnManualTool2DSelected(int)) ); //setup 3D Tools m_Controls->m_ManualToolSelectionBox3D->SetGenerateAccelerators(true); m_Controls->m_ManualToolSelectionBox3D->SetToolGUIArea( m_Controls->m_ManualToolGUIContainer3D ); //specify tools to be added to 3D Tool area m_Controls->m_ManualToolSelectionBox3D->SetDisplayedToolGroups("Threshold 'Two Thresholds' Otsu FastMarching3D RegionGrowing Watershed"); m_Controls->m_ManualToolSelectionBox3D->SetLayoutColumns(3); m_Controls->m_ManualToolSelectionBox3D->SetEnabledMode( QmitkToolSelectionBox::EnabledWithReferenceAndWorkingDataVisible ); //Hide 3D selection box, show 2D selection box m_Controls->m_ManualToolSelectionBox3D->hide(); m_Controls->m_ManualToolSelectionBox2D->show(); toolManager->NewNodesGenerated += mitk::MessageDelegate( this, &QmitkSegmentationView::NewNodesGenerated ); // update the list of segmentations toolManager->NewNodeObjectsGenerated += mitk::MessageDelegate1( this, &QmitkSegmentationView::NewNodeObjectsGenerated ); // update the list of segmentations // create signal/slot connections connect( m_Controls->patImageSelector, SIGNAL( OnSelectionChanged( const mitk::DataNode* ) ), this, SLOT( OnPatientComboBoxSelectionChanged( const mitk::DataNode* ) ) ); connect( m_Controls->segImageSelector, SIGNAL( OnSelectionChanged( const mitk::DataNode* ) ), this, SLOT( OnSegmentationComboBoxSelectionChanged( const mitk::DataNode* ) ) ); connect( m_Controls->btnNewSegmentation, SIGNAL(clicked()), this, SLOT(CreateNewSegmentation()) ); // connect( m_Controls->CreateSegmentationFromSurface, SIGNAL(clicked()), this, SLOT(CreateSegmentationFromSurface()) ); // connect( m_Controls->widgetStack, SIGNAL(currentChanged(int)), this, SLOT(ToolboxStackPageChanged(int)) ); connect( m_Controls->tabWidgetSegmentationTools, SIGNAL(currentChanged(int)), this, SLOT(OnTabWidgetChanged(int))); // connect(m_Controls->MaskSurfaces, SIGNAL( OnSelectionChanged( const mitk::DataNode* ) ), // this, SLOT( OnSurfaceSelectionChanged( ) ) ); connect(m_Controls->m_SlicesInterpolator, SIGNAL(SignalShowMarkerNodes(bool)), this, SLOT(OnShowMarkerNodes(bool))); connect(m_Controls->m_SlicesInterpolator, SIGNAL(Signal3DInterpolationEnabled(bool)), this, SLOT(On3DInterpolationEnabled(bool))); // m_Controls->MaskSurfaces->SetDataStorage(this->GetDefaultDataStorage()); // m_Controls->MaskSurfaces->SetPredicate(mitk::NodePredicateDataType::New("Surface")); } void QmitkSegmentationView::OnManualTool2DSelected(int id) { if (id >= 0) { std::string text = "Active Tool: \""; - mitk::ToolManager* toolManager = m_Controls->m_ManualToolSelectionBox2D->GetToolManager(); + mitk::ToolManager* toolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager(); text += toolManager->GetToolById(id)->GetName(); text += "\""; mitk::StatusBar::GetInstance()->DisplayText(text.c_str()); mitk::ModuleResource resource = toolManager->GetToolById(id)->GetCursorIconResource(); this->SetMouseCursor(resource, 0, 0); } else { this->ResetMouseCursor(); mitk::StatusBar::GetInstance()->DisplayText(""); } } void QmitkSegmentationView::ResetMouseCursor() { if ( m_MouseCursorSet ) { mitk::ApplicationCursor::GetInstance()->PopCursor(); m_MouseCursorSet = false; } } void QmitkSegmentationView::SetMouseCursor( const mitk::ModuleResource resource, int hotspotX, int hotspotY ) { // Remove previously set mouse cursor if ( m_MouseCursorSet ) { mitk::ApplicationCursor::GetInstance()->PopCursor(); } mitk::ApplicationCursor::GetInstance()->PushCursor( resource, hotspotX, hotspotY ); m_MouseCursorSet = true; } // ATTENTION some methods for handling the known list of (organ names, colors) are defined in QmitkSegmentationOrganNamesHandling.cpp