diff --git a/Plugins/org.mitk.gui.qt.semanticrelations/files.cmake b/Plugins/org.mitk.gui.qt.semanticrelations/files.cmake index 2191a732b8..5e270d6953 100644 --- a/Plugins/org.mitk.gui.qt.semanticrelations/files.cmake +++ b/Plugins/org.mitk.gui.qt.semanticrelations/files.cmake @@ -1,59 +1,58 @@ set(SRC_CPP_FILES QmitkDataNodeAddToSemanticRelationsAction.cpp ) set(INTERNAL_CPP_FILES mitkPluginActivator.cpp - QmitkAbstractSemanticRelationsAction.cpp QmitkDataNodeRemoveFromSemanticRelationsAction.cpp QmitkDataNodeUnlinkFromLesionAction.cpp QmitkDataNodeSetControlPointAction.cpp QmitkDataNodeSetInformationTypeAction.cpp QmitkDataSetOpenInAction.cpp QmitkFocusOnLesionAction.cpp QmitkLabelSetJumpToAction.cpp QmitkLesionInfoWidget.cpp QmitkSemanticRelationsContextMenu.cpp QmitkSemanticRelationsNodeSelectionDialog.cpp QmitkSemanticRelationsStatisticsView.cpp QmitkSemanticRelationsView.cpp ) set(UI_FILES src/internal/QmitkLesionInfoWidgetControls.ui src/internal/QmitkSemanticRelationsControls.ui src/internal/QmitkSemanticRelationsStatisticsControls.ui ) set(MOC_H_FILES src/QmitkDataNodeAddToSemanticRelationsAction.h src/internal/mitkPluginActivator.h src/internal/QmitkDataNodeRemoveFromSemanticRelationsAction.h src/internal/QmitkDataNodeUnlinkFromLesionAction.h src/internal/QmitkDataNodeSetControlPointAction.h src/internal/QmitkDataNodeSetInformationTypeAction.h src/internal/QmitkDataSetOpenInAction.h src/internal/QmitkFocusOnLesionAction.h src/internal/QmitkLabelSetJumpToAction.h src/internal/QmitkLesionInfoWidget.h src/internal/QmitkSemanticRelationsContextMenu.h src/internal/QmitkSemanticRelationsNodeSelectionDialog.h src/internal/QmitkSemanticRelationsStatisticsView.h src/internal/QmitkSemanticRelationsView.h ) set(CACHED_RESOURCE_FILES resources/SemanticRelations_48.png resources/SemanticRelationsStatistics_48.png plugin.xml ) set(QRC_FILES ) foreach(file ${SRC_CPP_FILES}) set(CPP_FILES ${CPP_FILES} src/${file}) endforeach(file ${SRC_CPP_FILES}) foreach(file ${INTERNAL_CPP_FILES}) set(CPP_FILES ${CPP_FILES} src/internal/${file}) endforeach(file ${INTERNAL_CPP_FILES}) diff --git a/Plugins/org.mitk.gui.qt.semanticrelations/src/QmitkDataNodeAddToSemanticRelationsAction.cpp b/Plugins/org.mitk.gui.qt.semanticrelations/src/QmitkDataNodeAddToSemanticRelationsAction.cpp index 04c81dcffe..5e03cbfc62 100644 --- a/Plugins/org.mitk.gui.qt.semanticrelations/src/QmitkDataNodeAddToSemanticRelationsAction.cpp +++ b/Plugins/org.mitk.gui.qt.semanticrelations/src/QmitkDataNodeAddToSemanticRelationsAction.cpp @@ -1,275 +1,251 @@ /*=================================================================== 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. ===================================================================*/ // semantic relations plugin #include "QmitkDataNodeAddToSemanticRelationsAction.h" #include "internal/QmitkDataNodeRemoveFromSemanticRelationsAction.h" // semantic relations module #include #include #include #include -#include #include +#include +#include #include #include // mitk gui common plugin #include // mitk core #include // qt #include // namespace that contains the concrete action namespace AddToSemanticRelationsAction { - void Run(mitk::SemanticRelationsIntegration* semanticRelationsIntegration, mitk::DataStorage* dataStorage, const mitk::DataNode* dataNode) + void Run(mitk::DataStorage* dataStorage, const mitk::DataNode* dataNode) { - if (nullptr == dataNode) + if (nullptr == dataStorage + || nullptr == dataNode) { return; } if (mitk::NodePredicates::GetImagePredicate()->CheckNode(dataNode)) { - AddImage(semanticRelationsIntegration, dataStorage, dataNode); + try + { + AddImage(dataStorage, dataNode); + } + catch (mitk::SemanticRelationException& e) + { + mitkReThrow(e); + } } else if (mitk::NodePredicates::GetSegmentationPredicate()->CheckNode(dataNode)) { - AddSegmentation(semanticRelationsIntegration, dataStorage, dataNode); + try + { + AddSegmentation(dataStorage, dataNode); + } + catch (mitk::SemanticRelationException& e) + { + mitkReThrow(e); + } } } - void AddImage(mitk::SemanticRelationsIntegration* semanticRelationsIntegration, mitk::DataStorage* dataStorage, const mitk::DataNode* image) + void AddImage(mitk::DataStorage* dataStorage, const mitk::DataNode* image) { - if (nullptr == image) - { - return; - } - mitk::SemanticTypes::InformationType informationType; mitk::SemanticTypes::ExaminationPeriod examinationPeriod; mitk::SemanticRelationsDataStorageAccess::DataNodeVector allSpecificImages; try { mitk::SemanticTypes::CaseID caseID = GetCaseIDFromDataNode(image); informationType = GetDICOMModalityFromDataNode(image); // see if the examination period - information type cell is already taken examinationPeriod = FindFittingExaminationPeriod(image); auto semanticRelationsDataStorageAccess = mitk::SemanticRelationsDataStorageAccess(dataStorage); try { allSpecificImages = semanticRelationsDataStorageAccess.GetAllSpecificImages(caseID, informationType, examinationPeriod); } catch (const mitk::SemanticRelationException&) { // just continue since an exception means that there is no specific image } } - catch (const mitk::SemanticRelationException& e) + catch (mitk::SemanticRelationException& e) { - std::stringstream exceptionMessage; exceptionMessage << e; - QMessageBox msgBox(QMessageBox::Warning, - "Could not add the selected image.", - "The program wasn't able to correctly add the selected images.\n" - "Reason:\n" + QString::fromStdString(exceptionMessage.str() + "\n")); - msgBox.exec(); + mitkReThrow(e); } if (!allSpecificImages.empty()) { // examination period - information type cell is already taken // ask if cell should be overwritten QMessageBox::StandardButton answerButton = QMessageBox::question(nullptr, "Specific image already exists.", QString::fromStdString("Force overwriting existing image " + informationType + " at " + examinationPeriod.name + "?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); if (answerButton == QMessageBox::Yes) { try { // remove already existent images at specific cell for (const auto& specificImage : allSpecificImages) { - RemoveFromSemanticRelationsAction::Run(semanticRelationsIntegration, dataStorage, specificImage); + RemoveFromSemanticRelationsAction::Run(dataStorage, specificImage); } } - catch (const mitk::SemanticRelationException& e) + catch (mitk::SemanticRelationException& e) { - std::stringstream exceptionMessage; exceptionMessage << e; - QMessageBox msgBox(QMessageBox::Warning, - "Could not add the selected image.", - "The program wasn't able to correctly add the selected images.\n" - "Reason:\n" + QString::fromStdString(exceptionMessage.str() + "\n")); - msgBox.exec(); + mitkReThrow(e); + return; } } else { // else case is: no overwriting return; } } // specific image does not exist or has been removed; adding the image should work + mitk::SemanticRelationsIntegration semanticRelationsIntegration; try { - semanticRelationsIntegration->AddImage(image); + semanticRelationsIntegration.AddImage(image); } - catch (const mitk::SemanticRelationException& e) + catch (mitk::SemanticRelationException& e) { - std::stringstream exceptionMessage; exceptionMessage << e; - QMessageBox msgBox(QMessageBox::Warning, - "Could not add the selected image.", - "The program wasn't able to correctly add the selected images.\n" - "Reason:\n" + QString::fromStdString(exceptionMessage.str() + "\n")); - msgBox.exec(); + mitkReThrow(e); } } - void AddSegmentation(mitk::SemanticRelationsIntegration* semanticRelationsIntegration, mitk::DataStorage* dataStorage, const mitk::DataNode* segmentation) + void AddSegmentation(mitk::DataStorage* dataStorage, const mitk::DataNode* segmentation) { if (nullptr == segmentation) { return; } mitk::BaseData* baseData = segmentation->GetData(); if (nullptr == baseData) { return; } // continue with valid segmentation data // get parent node of the current segmentation node with the node predicate mitk::DataStorage::SetOfObjects::ConstPointer parentNodes = dataStorage->GetSources(segmentation, mitk::NodePredicates::GetImagePredicate(), false); if (parentNodes->empty()) { // segmentation without corresponding image will not be added QMessageBox msgBox(QMessageBox::Warning, "Could not add the selected segmentation.", "The program wasn't able to correctly add the selected segmentation.\n" "Reason: No parent image found"); msgBox.exec(); return; } // check for already existing, identifying base properties auto caseIDPropertyName = mitk::GetCaseIDDICOMProperty(); auto nodeIDPropertyName = mitk::GetNodeIDDICOMProperty(); mitk::BaseProperty* caseIDProperty = baseData->GetProperty(caseIDPropertyName.c_str()); mitk::BaseProperty* nodeIDProperty = baseData->GetProperty(nodeIDPropertyName.c_str()); if (nullptr == caseIDProperty || nullptr == nodeIDProperty) { MITK_INFO << "No DICOM tags for case and node identification found. Transferring DICOM tags from the parent node to the selected segmentation node."; mitk::SemanticTypes::CaseID caseID; mitk::SemanticTypes::ID nodeID; try { caseID = mitk::GetCaseIDFromDataNode(parentNodes->front()); nodeID = mitk::GetIDFromDataNode(parentNodes->front()); } - catch (const mitk::SemanticRelationException& e) + catch (mitk::SemanticRelationException& e) { - std::stringstream exceptionMessage; exceptionMessage << e; - QMessageBox msgBox(QMessageBox::Warning, - "Could not add the selected segmentation.", - "The program wasn't able to correctly add the selected segmentation.\n" - "Reason:\n" + QString::fromStdString(exceptionMessage.str())); - msgBox.exec(); + mitkReThrow(e); return; } // transfer DICOM tags to the segmentation node - baseData->SetProperty(caseIDPropertyName, - mitk::TemporoSpatialStringProperty::New(caseID)); + baseData->SetProperty(caseIDPropertyName, mitk::TemporoSpatialStringProperty::New(caseID)); // add UID to distinguish between different segmentations of the same parent node - baseData->SetProperty(nodeIDPropertyName, - mitk::TemporoSpatialStringProperty::New(nodeID + mitk::UIDGeneratorBoost::GenerateUID())); + baseData->SetProperty(nodeIDPropertyName, mitk::TemporoSpatialStringProperty::New(nodeID + mitk::UIDGeneratorBoost::GenerateUID())); } // add the parent node if not already existent if (!mitk::SemanticRelationsInference::InstanceExists(parentNodes->front())) { - AddImage(semanticRelationsIntegration, dataStorage, parentNodes->front()); + AddImage(dataStorage, parentNodes->front()); } + mitk::SemanticRelationsIntegration semanticRelationsIntegration; try { // add the segmentation with its parent image to the semantic relations storage - semanticRelationsIntegration->AddSegmentation(segmentation, parentNodes->front()); + semanticRelationsIntegration.AddSegmentation(segmentation, parentNodes->front()); } - catch (const mitk::SemanticRelationException& e) + catch (mitk::SemanticRelationException& e) { - std::stringstream exceptionMessage; exceptionMessage << e; - QMessageBox msgBox(QMessageBox::Warning, - "Could not add the selected segmentation.", - "The program wasn't able to correctly add the selected segmentation.\n" - "Reason:\n" + QString::fromStdString(exceptionMessage.str())); - msgBox.exec(); - return; + mitkReThrow(e); } } } QmitkDataNodeAddToSemanticRelationsAction::QmitkDataNodeAddToSemanticRelationsAction(QWidget* parent, berry::IWorkbenchPartSite::Pointer workbenchPartSite) : QAction(parent) - , QmitkAbstractSemanticRelationsAction(workbenchPartSite) + , QmitkAbstractDataNodeAction(workbenchPartSite) { setText(tr("Add to semantic relations")); InitializeAction(); } QmitkDataNodeAddToSemanticRelationsAction::QmitkDataNodeAddToSemanticRelationsAction(QWidget* parent, berry::IWorkbenchPartSite* workbenchPartSite) : QAction(parent) - , QmitkAbstractSemanticRelationsAction(berry::IWorkbenchPartSite::Pointer(workbenchPartSite)) + , QmitkAbstractDataNodeAction(berry::IWorkbenchPartSite::Pointer(workbenchPartSite)) { setText(tr("Add to semantic relations")); InitializeAction(); } -QmitkDataNodeAddToSemanticRelationsAction::~QmitkDataNodeAddToSemanticRelationsAction() -{ - // nothing here -} - void QmitkDataNodeAddToSemanticRelationsAction::InitializeAction() { connect(this, &QAction::triggered, this, &QmitkDataNodeAddToSemanticRelationsAction::OnActionTriggered); } void QmitkDataNodeAddToSemanticRelationsAction::OnActionTriggered(bool /*checked*/) { - if (nullptr == m_SemanticRelationsIntegration) - { - return; - } - if (m_DataStorage.IsExpired()) { return; } auto dataNode = GetSelectedNode(); - AddToSemanticRelationsAction::Run(m_SemanticRelationsIntegration.get(), m_DataStorage.Lock(), dataNode); + AddToSemanticRelationsAction::Run(m_DataStorage.Lock(), dataNode); } diff --git a/Plugins/org.mitk.gui.qt.semanticrelations/src/QmitkDataNodeAddToSemanticRelationsAction.h b/Plugins/org.mitk.gui.qt.semanticrelations/src/QmitkDataNodeAddToSemanticRelationsAction.h index 94acc3a444..cdb4f94585 100644 --- a/Plugins/org.mitk.gui.qt.semanticrelations/src/QmitkDataNodeAddToSemanticRelationsAction.h +++ b/Plugins/org.mitk.gui.qt.semanticrelations/src/QmitkDataNodeAddToSemanticRelationsAction.h @@ -1,57 +1,73 @@ /*=================================================================== 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 QMITKDATANODEADDTOSEMANTICRELATIONSACTION_H #define QMITKDATANODEADDTOSEMANTICRELATIONSACTION_H #include // mitk gui qt application plugin -#include "internal/QmitkAbstractSemanticRelationsAction.h" +#include // qt #include namespace AddToSemanticRelationsAction { - MITK_GUI_SEMANTICRELATIONS_EXPORT void Run(mitk::SemanticRelationsIntegration* semanticRelationsIntegration, mitk::DataStorage* dataStorage, const mitk::DataNode* image); + /** + * @brief The function checks whether the given node is an image or a segmentation and calls the corresponding add function. + * The corresponding add functions will add the data node to the semantic relations storage. + * If an image is added, the 'AddImage' function will check if another image at the fitting control-point - information type cell + * already exists. If so, the user is prompted to overwrite the existing image or abort the process. + * If the user wants to overwrite the existing image, the image and it's corresponding segmentation nodes will be removed from the semantic relations storage. + * If a segmentation is added, the parent image node will also be to the semantic relations storage. If the segmentation does not contain the required DICOM information, + * the DICOM information of the parent data will be transfered to the segmentation data. + * + * @pre The given dataStorage has to be valid (!nullptr). + * @pre The given dataNode has to be valid (!nullptr). + * The function simply returns if the preconditions are not met. + * + * @throw SemanticRelationException re-thrown. + * + * @param dataStorage The data storage to use for to remove the existing image and to check for the parent image node of a segmentation. + * @param dataNode The data node to add. + */ + MITK_GUI_SEMANTICRELATIONS_EXPORT void Run(mitk::DataStorage* dataStorage, const mitk::DataNode* image); - void AddImage(mitk::SemanticRelationsIntegration* semanticRelationsIntegration, mitk::DataStorage* dataStorage, const mitk::DataNode* image); - void AddSegmentation(mitk::SemanticRelationsIntegration* semanticRelationsIntegration, mitk::DataStorage* dataStorage, const mitk::DataNode* segmentation); + void AddImage(mitk::DataStorage* dataStorage, const mitk::DataNode* image); + void AddSegmentation(mitk::DataStorage* dataStorage, const mitk::DataNode* segmentation); } -class MITK_GUI_SEMANTICRELATIONS_EXPORT QmitkDataNodeAddToSemanticRelationsAction : public QAction, public QmitkAbstractSemanticRelationsAction +class MITK_GUI_SEMANTICRELATIONS_EXPORT QmitkDataNodeAddToSemanticRelationsAction : public QAction, public QmitkAbstractDataNodeAction { Q_OBJECT public: QmitkDataNodeAddToSemanticRelationsAction(QWidget* parent, berry::IWorkbenchPartSite::Pointer workbenchPartSite); QmitkDataNodeAddToSemanticRelationsAction(QWidget* parent, berry::IWorkbenchPartSite* workbenchPartSite); - virtual ~QmitkDataNodeAddToSemanticRelationsAction() override; - private Q_SLOTS: void OnActionTriggered(bool); protected: virtual void InitializeAction() override; }; #endif // QMITKDATANODEADDTOSEMANTICRELATIONSACTION_H diff --git a/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkAbstractSemanticRelationsAction.cpp b/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkAbstractSemanticRelationsAction.cpp deleted file mode 100644 index 43699e88fd..0000000000 --- a/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkAbstractSemanticRelationsAction.cpp +++ /dev/null @@ -1,30 +0,0 @@ -/*=================================================================== - -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. - -===================================================================*/ - -// semantic relations plugin -#include "QmitkAbstractSemanticRelationsAction.h" - -QmitkAbstractSemanticRelationsAction::QmitkAbstractSemanticRelationsAction(berry::IWorkbenchPartSite::Pointer workbenchPartSite) - : QmitkAbstractDataNodeAction(workbenchPartSite) -{ - m_SemanticRelationsIntegration = std::make_unique(); -} - -QmitkAbstractSemanticRelationsAction::QmitkAbstractSemanticRelationsAction(berry::IWorkbenchPartSite* workbenchPartSite) - : QmitkAbstractDataNodeAction(berry::IWorkbenchPartSite::Pointer(workbenchPartSite)) -{ - // nothing here -} diff --git a/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkAbstractSemanticRelationsAction.h b/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkAbstractSemanticRelationsAction.h deleted file mode 100644 index 0cef975cb7..0000000000 --- a/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkAbstractSemanticRelationsAction.h +++ /dev/null @@ -1,39 +0,0 @@ -/*=================================================================== - -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 QMITKABSTRACTSEMANTICRELATIONSACTION_H -#define QMITKABSTRACTSEMANTICRELATIONSACTION_H - -// mitk gui qt application plugin -#include - -// semantic relations module -#include - -class QmitkAbstractSemanticRelationsAction : public QmitkAbstractDataNodeAction -{ - -public: - - QmitkAbstractSemanticRelationsAction(berry::IWorkbenchPartSite::Pointer workbenchPartSite); - QmitkAbstractSemanticRelationsAction(berry::IWorkbenchPartSite* workbenchPartSite); - -protected: - - std::unique_ptr m_SemanticRelationsIntegration; -}; - -#endif // QMITKABSTRACTSEMANTICRELATIONSACTION_H diff --git a/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkDataNodeRemoveFromSemanticRelationsAction.cpp b/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkDataNodeRemoveFromSemanticRelationsAction.cpp index 86ae166272..30ac801473 100644 --- a/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkDataNodeRemoveFromSemanticRelationsAction.cpp +++ b/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkDataNodeRemoveFromSemanticRelationsAction.cpp @@ -1,147 +1,131 @@ /*=================================================================== 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. ===================================================================*/ // semantic relations plugin #include "QmitkDataNodeRemoveFromSemanticRelationsAction.h" // semantic relations module #include #include +#include // mitk gui common plugin #include // qt #include // namespace that contains the concrete action namespace RemoveFromSemanticRelationsAction { - void Run(mitk::SemanticRelationsIntegration* semanticRelationsIntegration, mitk::DataStorage* dataStorage, const mitk::DataNode* dataNode) + void Run(mitk::DataStorage* dataStorage, const mitk::DataNode* dataNode) { - if (nullptr == dataNode) + if (nullptr == dataStorage + || nullptr == dataNode) { return; } if (mitk::NodePredicates::GetImagePredicate()->CheckNode(dataNode)) { - RemoveImage(semanticRelationsIntegration, dataStorage, dataNode); + try + { + RemoveImage(dataStorage, dataNode); + } + catch (mitk::SemanticRelationException& e) + { + mitkReThrow(e); + } } else if (mitk::NodePredicates::GetSegmentationPredicate()->CheckNode(dataNode)) { - RemoveSegmentation(semanticRelationsIntegration, dataNode); + try + { + RemoveSegmentation(dataNode); + } + catch (mitk::SemanticRelationException& e) + { + mitkReThrow(e); + } } } - void RemoveImage(mitk::SemanticRelationsIntegration* semanticRelationsIntegration, mitk::DataStorage* dataStorage, const mitk::DataNode* image) + void RemoveImage(mitk::DataStorage* dataStorage, const mitk::DataNode* image) { - if (nullptr == image) - { - return; - } - + mitk::SemanticRelationsIntegration semanticRelationsIntegration; try { // remove each corresponding segmentation from the semantic relations storage mitk::DataStorage::SetOfObjects::ConstPointer childNodes = dataStorage->GetDerivations(image, mitk::NodePredicates::GetSegmentationPredicate(), false); for (auto it = childNodes->Begin(); it != childNodes->End(); ++it) { - RemoveSegmentation(semanticRelationsIntegration, it->Value()); + RemoveSegmentation(it->Value()); } // remove the image from the semantic relations storage - semanticRelationsIntegration->RemoveImage(image); + semanticRelationsIntegration.RemoveImage(image); } - catch (const mitk::SemanticRelationException& e) + catch (mitk::SemanticRelationException& e) { - std::stringstream exceptionMessage; exceptionMessage << e; - QMessageBox msgBox; - msgBox.setWindowTitle("Could not remove the selected image."); - msgBox.setText("The program wasn't able to correctly remove the selected image.\n" - "Reason:\n" + QString::fromStdString(exceptionMessage.str())); - msgBox.setIcon(QMessageBox::Warning); - msgBox.exec(); - return; + mitkReThrow(e); } } - void RemoveSegmentation(mitk::SemanticRelationsIntegration* semanticRelationsIntegration, const mitk::DataNode* segmentation) + void RemoveSegmentation(const mitk::DataNode* segmentation) { - if (nullptr == segmentation) - { - return; - } - + mitk::SemanticRelationsIntegration semanticRelationsIntegration; try { // remove the segmentation from the semantic relations storage - semanticRelationsIntegration->RemoveSegmentation(segmentation); + semanticRelationsIntegration.RemoveSegmentation(segmentation); } - catch (const mitk::SemanticRelationException& e) + catch (mitk::SemanticRelationException& e) { - std::stringstream exceptionMessage; exceptionMessage << e; - QMessageBox msgBox; - msgBox.setWindowTitle("Could not remove the selected segmentation."); - msgBox.setText("The program wasn't able to correctly remove the selected segmentation.\n" - "Reason:\n" + QString::fromStdString(exceptionMessage.str())); - msgBox.setIcon(QMessageBox::Warning); - msgBox.exec(); - return; + mitkReThrow(e); } } } QmitkDataNodeRemoveFromSemanticRelationsAction::QmitkDataNodeRemoveFromSemanticRelationsAction(QWidget* parent, berry::IWorkbenchPartSite::Pointer workbenchPartSite) : QAction(parent) - , QmitkAbstractSemanticRelationsAction(workbenchPartSite) + , QmitkAbstractDataNodeAction(workbenchPartSite) { setText(tr("Remove from semantic relations")); InitializeAction(); } QmitkDataNodeRemoveFromSemanticRelationsAction::QmitkDataNodeRemoveFromSemanticRelationsAction(QWidget* parent, berry::IWorkbenchPartSite* workbenchPartSite) : QAction(parent) - , QmitkAbstractSemanticRelationsAction(berry::IWorkbenchPartSite::Pointer(workbenchPartSite)) + , QmitkAbstractDataNodeAction(berry::IWorkbenchPartSite::Pointer(workbenchPartSite)) { setText(tr("Remove from semantic relations")); InitializeAction(); } -QmitkDataNodeRemoveFromSemanticRelationsAction::~QmitkDataNodeRemoveFromSemanticRelationsAction() -{ - // nothing here -} - void QmitkDataNodeRemoveFromSemanticRelationsAction::InitializeAction() { connect(this, &QAction::triggered, this, &QmitkDataNodeRemoveFromSemanticRelationsAction::OnActionTriggered); } void QmitkDataNodeRemoveFromSemanticRelationsAction::OnActionTriggered(bool /*checked*/) { - if (nullptr == m_SemanticRelationsIntegration) - { - return; - } - if (m_DataStorage.IsExpired()) { return; } auto dataNode = GetSelectedNode(); - RemoveFromSemanticRelationsAction::Run(m_SemanticRelationsIntegration.get(), m_DataStorage.Lock(),dataNode); + RemoveFromSemanticRelationsAction::Run(m_DataStorage.Lock(),dataNode); } diff --git a/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkDataNodeRemoveFromSemanticRelationsAction.h b/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkDataNodeRemoveFromSemanticRelationsAction.h index 4aebf291f7..2ac42add53 100644 --- a/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkDataNodeRemoveFromSemanticRelationsAction.h +++ b/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkDataNodeRemoveFromSemanticRelationsAction.h @@ -1,57 +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 QMITKDATANODEREMOVEFROMSEMANTICRELATIONSACTION_H #define QMITKDATANODEREMOVEFROMSEMANTICRELATIONSACTION_H #include // mitk gui qt application plugin -#include "QmitkAbstractSemanticRelationsAction.h" +#include // qt #include namespace RemoveFromSemanticRelationsAction { - MITK_GUI_SEMANTICRELATIONS_EXPORT void Run(mitk::SemanticRelationsIntegration* semanticRelationsIntegration, mitk::DataStorage* dataStorage, const mitk::DataNode* dataNode); - - void RemoveImage(mitk::SemanticRelationsIntegration* semanticRelationsIntegration, mitk::DataStorage* dataStorage, const mitk::DataNode* image); - void RemoveSegmentation(mitk::SemanticRelationsIntegration* semanticRelationsIntegration, const mitk::DataNode* segmentation); + /** + * @brief The function checks whether the given node is an image or a segmentation and calls the corresponding remove function. + * The corresponding remove functions will remove the data node from the semantic relations storage. + * If an image is removed, the child segmentation nodes will also be removed from the semantic relations storage. + * + * @pre The given dataStorage has to be valid (!nullptr). + * @pre The given dataNode has to be valid (!nullptr). + * The function simply returns if the preconditions are not met. + * + * @throw SemanticRelationException re-thrown. + * + * @param dataStorage The data storage to use to check for the child segmentation nodes of an image. + * @param dataNode The data node to remove. + */ + MITK_GUI_SEMANTICRELATIONS_EXPORT void Run(mitk::DataStorage* dataStorage, const mitk::DataNode* dataNode); + + void RemoveImage(mitk::DataStorage* dataStorage, const mitk::DataNode* image); + void RemoveSegmentation(const mitk::DataNode* segmentation); } -class MITK_GUI_SEMANTICRELATIONS_EXPORT QmitkDataNodeRemoveFromSemanticRelationsAction : public QAction, public QmitkAbstractSemanticRelationsAction +class MITK_GUI_SEMANTICRELATIONS_EXPORT QmitkDataNodeRemoveFromSemanticRelationsAction : public QAction, public QmitkAbstractDataNodeAction { Q_OBJECT public: QmitkDataNodeRemoveFromSemanticRelationsAction(QWidget* parent, berry::IWorkbenchPartSite::Pointer workbenchPartSite); QmitkDataNodeRemoveFromSemanticRelationsAction(QWidget* parent, berry::IWorkbenchPartSite* workbenchPartSite); - virtual ~QmitkDataNodeRemoveFromSemanticRelationsAction() override; - private Q_SLOTS: void OnActionTriggered(bool); protected: virtual void InitializeAction() override; }; #endif // QMITKDATANODEREMOVEFROMSEMANTICRELATIONSACTION_H diff --git a/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkDataNodeSetControlPointAction.cpp b/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkDataNodeSetControlPointAction.cpp index 37c192b029..070da81ebb 100644 --- a/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkDataNodeSetControlPointAction.cpp +++ b/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkDataNodeSetControlPointAction.cpp @@ -1,180 +1,174 @@ /*=================================================================== 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. ===================================================================*/ // semantic relations plugin #include "QmitkDataNodeSetControlPointAction.h" #include "QmitkDataNodeRemoveFromSemanticRelationsAction.h" // semantic relations module #include #include -#include #include +#include #include +#include #include // semantic relations UI module #include "QmitkControlPointDialog.h" // qt #include #include QmitkDataNodeSetControlPointAction::QmitkDataNodeSetControlPointAction(QWidget* parent, berry::IWorkbenchPartSite::Pointer workbenchPartSite) : QAction(parent) - , QmitkAbstractSemanticRelationsAction(workbenchPartSite) + , QmitkAbstractDataNodeAction(workbenchPartSite) { setText(tr("Set control point")); m_Parent = parent; InitializeAction(); } QmitkDataNodeSetControlPointAction::QmitkDataNodeSetControlPointAction(QWidget* parent, berry::IWorkbenchPartSite* workbenchPartSite) : QAction(parent) - , QmitkAbstractSemanticRelationsAction(berry::IWorkbenchPartSite::Pointer(workbenchPartSite)) + , QmitkAbstractDataNodeAction(berry::IWorkbenchPartSite::Pointer(workbenchPartSite)) { setText(tr("Set control point")); m_Parent = parent; InitializeAction(); } -QmitkDataNodeSetControlPointAction::~QmitkDataNodeSetControlPointAction() -{ - // nothing here -} - void QmitkDataNodeSetControlPointAction::InitializeAction() { connect(this, &QAction::triggered, this, &QmitkDataNodeSetControlPointAction::OnActionTriggered); } void QmitkDataNodeSetControlPointAction::OnActionTriggered(bool /*checked*/) { - if (nullptr == m_SemanticRelationsIntegration) - { - return; - } - if (m_DataStorage.IsExpired()) { return; } + auto dataStorage = m_DataStorage.Lock(); + auto dataNode = GetSelectedNode(); if (dataNode.IsNull()) { return; } QmitkControlPointDialog* inputDialog = new QmitkControlPointDialog(m_Parent); inputDialog->setWindowTitle("Set control point"); inputDialog->SetCurrentDate(mitk::SemanticRelationsInference::GetControlPointOfImage(dataNode)); int dialogReturnValue = inputDialog->exec(); if (QDialog::Rejected == dialogReturnValue) { return; } const QDate& userSelectedDate = inputDialog->GetCurrentDate(); mitk::SemanticTypes::ControlPoint controlPoint; controlPoint.UID = mitk::UIDGeneratorBoost::GenerateUID(); controlPoint.date = boost::gregorian::date(userSelectedDate.year(), userSelectedDate.month(), userSelectedDate.day()); mitk::SemanticTypes::InformationType informationType; mitk::SemanticTypes::ExaminationPeriod examinationPeriod; mitk::SemanticRelationsDataStorageAccess::DataNodeVector allSpecificImages; try { mitk::SemanticTypes::CaseID caseID = mitk::GetCaseIDFromDataNode(dataNode); informationType = mitk::SemanticRelationsInference::GetInformationTypeOfImage(dataNode); // see if the examination period - information type cell is already taken examinationPeriod = mitk::FindFittingExaminationPeriod(caseID, controlPoint); - auto semanticRelationsDataStorageAccess = mitk::SemanticRelationsDataStorageAccess(m_DataStorage.Lock()); + auto semanticRelationsDataStorageAccess = mitk::SemanticRelationsDataStorageAccess(dataStorage); try { allSpecificImages = semanticRelationsDataStorageAccess.GetAllSpecificImages(caseID, informationType, examinationPeriod); } catch (const mitk::SemanticRelationException&) { // just continue since an exception means that there is no specific image } } catch (const mitk::SemanticRelationException& e) { std::stringstream exceptionMessage; exceptionMessage << e; QMessageBox msgBox(QMessageBox::Warning, "Could not set the control point.", "The program wasn't able to correctly set the control point.\n" "Reason:\n" + QString::fromStdString(exceptionMessage.str() + "\n")); msgBox.exec(); } if (!allSpecificImages.empty()) { // examination period - information type cell is already taken // ask if cell should be overwritten QMessageBox::StandardButton answerButton = QMessageBox::question(nullptr, "Specific image already exists.", QString::fromStdString("Force overwriting existing image " + informationType + " at " + examinationPeriod.name + "?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); if (answerButton == QMessageBox::Yes) { try { // remove already existent images at specific cell for (const auto& specificImage : allSpecificImages) { - RemoveFromSemanticRelationsAction::Run(m_SemanticRelationsIntegration.get(), m_DataStorage.Lock(), specificImage); + RemoveFromSemanticRelationsAction::Run(dataStorage, specificImage); } } catch (const mitk::SemanticRelationException& e) { std::stringstream exceptionMessage; exceptionMessage << e; QMessageBox msgBox(QMessageBox::Warning, "Could not set the control point.", "The program wasn't able to correctly set the control point.\n" "Reason:\n" + QString::fromStdString(exceptionMessage.str() + "\n")); msgBox.exec(); } } else { // else case is: no overwriting return; } } // specific image does not exist or has been removed; setting the control point should work + mitk::SemanticRelationsIntegration semanticRelationsIntegration; try { - m_SemanticRelationsIntegration->UnlinkImageFromControlPoint(dataNode); - m_SemanticRelationsIntegration->SetControlPointOfImage(dataNode, controlPoint); + semanticRelationsIntegration.UnlinkImageFromControlPoint(dataNode); + semanticRelationsIntegration.SetControlPointOfImage(dataNode, controlPoint); } catch (const mitk::SemanticRelationException& e) { std::stringstream exceptionMessage; exceptionMessage << e; QMessageBox msgBox(QMessageBox::Warning, "Could not set the control point.", "The program wasn't able to correctly set the control point.\n" "Reason:\n" + QString::fromStdString(exceptionMessage.str() + "\n")); msgBox.exec(); } } diff --git a/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkDataNodeSetControlPointAction.h b/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkDataNodeSetControlPointAction.h index 625e707e92..b11eddbb9b 100644 --- a/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkDataNodeSetControlPointAction.h +++ b/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkDataNodeSetControlPointAction.h @@ -1,49 +1,47 @@ /*=================================================================== 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 QMITKDATANODESETCONTROLPOINTACTION_H #define QMITKDATANODESETCONTROLPOINTACTION_H -// mitk gui qt semanticrelations plugin -#include "QmitkAbstractSemanticRelationsAction.h" +// mitk gui qt application plugin +#include // qt #include -class QmitkDataNodeSetControlPointAction : public QAction, public QmitkAbstractSemanticRelationsAction +class QmitkDataNodeSetControlPointAction : public QAction, public QmitkAbstractDataNodeAction { Q_OBJECT public: QmitkDataNodeSetControlPointAction(QWidget* parent, berry::IWorkbenchPartSite::Pointer workbenchPartSite); QmitkDataNodeSetControlPointAction(QWidget* parent, berry::IWorkbenchPartSite* workbenchPartSite); - virtual ~QmitkDataNodeSetControlPointAction() override; - private Q_SLOTS: void OnActionTriggered(bool); protected: virtual void InitializeAction() override; QWidget* m_Parent; }; #endif // QMITKDATANODESETCONTROLPOINTACTION_H diff --git a/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkDataNodeSetInformationTypeAction.cpp b/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkDataNodeSetInformationTypeAction.cpp index 4075650f6f..f5fc1816fe 100644 --- a/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkDataNodeSetInformationTypeAction.cpp +++ b/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkDataNodeSetInformationTypeAction.cpp @@ -1,171 +1,165 @@ /*=================================================================== 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. ===================================================================*/ // semantic relations plugin #include "QmitkDataNodeSetInformationTypeAction.h" #include "QmitkDataNodeRemoveFromSemanticRelationsAction.h" // semantic relations module #include #include -#include #include +#include #include +#include // qt #include #include QmitkDataNodeSetInformationTypeAction::QmitkDataNodeSetInformationTypeAction(QWidget* parent, berry::IWorkbenchPartSite::Pointer workbenchPartSite) : QAction(parent) - , QmitkAbstractSemanticRelationsAction(workbenchPartSite) + , QmitkAbstractDataNodeAction(workbenchPartSite) { setText(tr("Set information type")); m_Parent = parent; InitializeAction(); } QmitkDataNodeSetInformationTypeAction::QmitkDataNodeSetInformationTypeAction(QWidget* parent, berry::IWorkbenchPartSite* workbenchPartSite) : QAction(parent) - , QmitkAbstractSemanticRelationsAction(berry::IWorkbenchPartSite::Pointer(workbenchPartSite)) + , QmitkAbstractDataNodeAction(berry::IWorkbenchPartSite::Pointer(workbenchPartSite)) { setText(tr("Set information type")); m_Parent = parent; InitializeAction(); } -QmitkDataNodeSetInformationTypeAction::~QmitkDataNodeSetInformationTypeAction() -{ - // nothing here -} - void QmitkDataNodeSetInformationTypeAction::InitializeAction() { connect(this, &QAction::triggered, this, &QmitkDataNodeSetInformationTypeAction::OnActionTriggered); } void QmitkDataNodeSetInformationTypeAction::OnActionTriggered(bool /*checked*/) { - if (nullptr == m_SemanticRelationsIntegration) - { - return; - } - if (m_DataStorage.IsExpired()) { return; } + auto dataStorage = m_DataStorage.Lock(); + auto dataNode = GetSelectedNode(); if (dataNode.IsNull()) { return; } QInputDialog* inputDialog = new QInputDialog(m_Parent); inputDialog->setWindowTitle(tr("Set information type of selected node")); inputDialog->setLabelText(tr("Information type:")); inputDialog->setTextValue(QString::fromStdString(mitk::SemanticRelationsInference::GetInformationTypeOfImage(dataNode))); inputDialog->setMinimumSize(250, 100); int dialogReturnValue = inputDialog->exec(); if (QDialog::Rejected == dialogReturnValue) { return; } mitk::SemanticTypes::InformationType informationType = inputDialog->textValue().toStdString(); mitk::SemanticTypes::ExaminationPeriod examinationPeriod; mitk::SemanticTypes::ControlPoint controlPoint; mitk::SemanticRelationsDataStorageAccess::DataNodeVector allSpecificImages; try { mitk::SemanticTypes::CaseID caseID = mitk::GetCaseIDFromDataNode(dataNode); controlPoint = mitk::SemanticRelationsInference::GetControlPointOfImage(dataNode); // see if the examination period - information type cell is already taken examinationPeriod = mitk::FindFittingExaminationPeriod(caseID, controlPoint); - auto semanticRelationsDataStorageAccess = mitk::SemanticRelationsDataStorageAccess(m_DataStorage.Lock()); + auto semanticRelationsDataStorageAccess = mitk::SemanticRelationsDataStorageAccess(dataStorage); try { allSpecificImages = semanticRelationsDataStorageAccess.GetAllSpecificImages(caseID, informationType, examinationPeriod); } catch (const mitk::SemanticRelationException&) { // just continue since an exception means that there is no specific image } } catch (const mitk::SemanticRelationException& e) { std::stringstream exceptionMessage; exceptionMessage << e; QMessageBox msgBox(QMessageBox::Warning, "Could not set the information type.", "The program wasn't able to correctly set the information type.\n" "Reason:\n" + QString::fromStdString(exceptionMessage.str() + "\n")); msgBox.exec(); } if (!allSpecificImages.empty()) { // examination period - information type cell is already taken // ask if cell should be overwritten QMessageBox::StandardButton answerButton = QMessageBox::question(nullptr, "Specific image already exists.", QString::fromStdString("Force overwriting existing image " + informationType + " at " + examinationPeriod.name + "?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); if (answerButton == QMessageBox::Yes) { try { // remove already existent images at specific cell for (const auto& specificImage : allSpecificImages) { - RemoveFromSemanticRelationsAction::Run(m_SemanticRelationsIntegration.get(), m_DataStorage.Lock(), specificImage); + RemoveFromSemanticRelationsAction::Run(dataStorage, specificImage); } } catch (const mitk::SemanticRelationException& e) { std::stringstream exceptionMessage; exceptionMessage << e; QMessageBox msgBox(QMessageBox::Warning, "Could not set the information type.", "The program wasn't able to correctly set the information type.\n" "Reason:\n" + QString::fromStdString(exceptionMessage.str() + "\n")); msgBox.exec(); } } else { // else case is: no overwriting return; } } + mitk::SemanticRelationsIntegration semanticRelationsIntegration; try { - m_SemanticRelationsIntegration->SetInformationType(dataNode, informationType); + semanticRelationsIntegration.SetInformationType(dataNode, informationType); } catch (const mitk::SemanticRelationException& e) { std::stringstream exceptionMessage; exceptionMessage << e; QMessageBox msgBox(QMessageBox::Warning, "Could not set the information type.", "The program wasn't able to correctly set the information type.\n" "Reason:\n" + QString::fromStdString(exceptionMessage.str() + "\n")); msgBox.exec(); } } diff --git a/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkDataNodeSetInformationTypeAction.h b/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkDataNodeSetInformationTypeAction.h index 618b5d7f55..472def3765 100644 --- a/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkDataNodeSetInformationTypeAction.h +++ b/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkDataNodeSetInformationTypeAction.h @@ -1,49 +1,47 @@ /*=================================================================== 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 QMITKDATANODESETINFORMATIONTYPEACTION_H #define QMITKDATANODESETINFORMATIONTYPEACTION_H // mitk gui qt application plugin -#include "QmitkAbstractSemanticRelationsAction.h" +#include // qt #include -class QmitkDataNodeSetInformationTypeAction : public QAction, public QmitkAbstractSemanticRelationsAction +class QmitkDataNodeSetInformationTypeAction : public QAction, public QmitkAbstractDataNodeAction { Q_OBJECT public: QmitkDataNodeSetInformationTypeAction(QWidget* parent, berry::IWorkbenchPartSite::Pointer workbenchPartSite); QmitkDataNodeSetInformationTypeAction(QWidget* parent, berry::IWorkbenchPartSite* workbenchPartSite); - virtual ~QmitkDataNodeSetInformationTypeAction() override; - private Q_SLOTS: void OnActionTriggered(bool); protected: virtual void InitializeAction() override; QWidget* m_Parent; }; #endif // QMITKDATANODESETINFORMATIONTYPEACTION_H diff --git a/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkDataNodeUnlinkFromLesionAction.cpp b/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkDataNodeUnlinkFromLesionAction.cpp index c01e1301b0..3c1619e8f3 100644 --- a/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkDataNodeUnlinkFromLesionAction.cpp +++ b/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkDataNodeUnlinkFromLesionAction.cpp @@ -1,102 +1,94 @@ /*=================================================================== 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. ===================================================================*/ // semantic relations plugin #include "QmitkDataNodeUnlinkFromLesionAction.h" // semantic relations module #include #include +#include #include // mitk gui common plugin #include // qt #include // namespace that contains the concrete action namespace UnlinkFromLesionAction { - void Run(mitk::SemanticRelationsIntegration* semanticRelationsIntegration, const mitk::DataNode* dataNode) + void Run(const mitk::DataNode* dataNode) { if (nullptr == dataNode) { return; } if (mitk::NodePredicates::GetSegmentationPredicate()->CheckNode(dataNode)) { + mitk::SemanticRelationsIntegration semanticRelationsIntegration; try { - semanticRelationsIntegration->UnlinkSegmentationFromLesion(dataNode); + semanticRelationsIntegration.UnlinkSegmentationFromLesion(dataNode); } catch (const mitk::SemanticRelationException& e) { std::stringstream exceptionMessage; exceptionMessage << e; QMessageBox msgBox(QMessageBox::Warning, "Could not unlink the selected segmentation.", "The program wasn't able to correctly unlink the selected segmentation.\n" "Reason:\n" + QString::fromStdString(exceptionMessage.str())); msgBox.exec(); } } else { QMessageBox msgBox(QMessageBox::Warning, "Could not unlink the selected data node.", "Please chose a valid segmentation to unlink from its represented lesion!"); msgBox.exec(); } } } QmitkDataNodeUnlinkFromLesionAction::QmitkDataNodeUnlinkFromLesionAction(QWidget* parent, berry::IWorkbenchPartSite::Pointer workbenchPartSite) : QAction(parent) - , QmitkAbstractSemanticRelationsAction(workbenchPartSite) + , QmitkAbstractDataNodeAction(workbenchPartSite) { setText(tr("Unlink from lesion")); InitializeAction(); } QmitkDataNodeUnlinkFromLesionAction::QmitkDataNodeUnlinkFromLesionAction(QWidget* parent, berry::IWorkbenchPartSite* workbenchPartSite) : QAction(parent) - , QmitkAbstractSemanticRelationsAction(berry::IWorkbenchPartSite::Pointer(workbenchPartSite)) + , QmitkAbstractDataNodeAction(berry::IWorkbenchPartSite::Pointer(workbenchPartSite)) { setText(tr("Unlink from lesion")); InitializeAction(); } -QmitkDataNodeUnlinkFromLesionAction::~QmitkDataNodeUnlinkFromLesionAction() -{ - // nothing here -} - void QmitkDataNodeUnlinkFromLesionAction::InitializeAction() { connect(this, &QAction::triggered, this, &QmitkDataNodeUnlinkFromLesionAction::OnActionTriggered); } void QmitkDataNodeUnlinkFromLesionAction::OnActionTriggered(bool /*checked*/) { - if (nullptr == m_SemanticRelationsIntegration) - { - return; - } - auto dataNode = GetSelectedNode(); - UnlinkFromLesionAction::Run(m_SemanticRelationsIntegration.get(), dataNode); + UnlinkFromLesionAction::Run(dataNode); } diff --git a/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkDataNodeUnlinkFromLesionAction.h b/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkDataNodeUnlinkFromLesionAction.h index 452d8b39fa..b9e0bf9d18 100644 --- a/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkDataNodeUnlinkFromLesionAction.h +++ b/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkDataNodeUnlinkFromLesionAction.h @@ -1,54 +1,52 @@ /*=================================================================== 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 QMITKDATANODEUNLINKFROMLESIONACTION_H #define QMITKDATANODEUNLINKFROMLESIONACTION_H #include -// mitk gui qt semanticrelations plugin -#include "QmitkAbstractSemanticRelationsAction.h" +// mitk gui qt application plugin +#include // qt #include namespace UnlinkFromLesionAction { - MITK_GUI_SEMANTICRELATIONS_EXPORT void Run(const mitk::DataNode* dataNode, mitk::SemanticRelationsIntegration* semanticRelationsIntegration); + MITK_GUI_SEMANTICRELATIONS_EXPORT void Run(const mitk::DataNode* dataNode); } -class MITK_GUI_SEMANTICRELATIONS_EXPORT QmitkDataNodeUnlinkFromLesionAction : public QAction, public QmitkAbstractSemanticRelationsAction +class MITK_GUI_SEMANTICRELATIONS_EXPORT QmitkDataNodeUnlinkFromLesionAction : public QAction, public QmitkAbstractDataNodeAction { Q_OBJECT public: QmitkDataNodeUnlinkFromLesionAction(QWidget* parent, berry::IWorkbenchPartSite::Pointer workbenchPartSite); QmitkDataNodeUnlinkFromLesionAction(QWidget* parent, berry::IWorkbenchPartSite* workbenchPartSite); - virtual ~QmitkDataNodeUnlinkFromLesionAction() override; - private Q_SLOTS: void OnActionTriggered(bool); protected: virtual void InitializeAction() override; }; #endif // QMITKDATANODEUNLINKFROMLESIONACTION_H diff --git a/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkFocusOnLesionAction.cpp b/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkFocusOnLesionAction.cpp index 33d0a622ce..bd507fdd94 100644 --- a/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkFocusOnLesionAction.cpp +++ b/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkFocusOnLesionAction.cpp @@ -1,127 +1,126 @@ /*=================================================================== 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. ===================================================================*/ // semantic relations plugin #include "QmitkFocusOnLesionAction.h" #include "QmitkLabelSetJumpToAction.h" // mitk core #include #include // render window manager module #include #include // semantic relations module #include -#include #include // qt #include #include QmitkFocusOnLesionAction::QmitkFocusOnLesionAction(QWidget* parent, berry::IWorkbenchPartSite::Pointer workbenchPartSite) : QAction(parent) , QmitkAbstractDataNodeAction(workbenchPartSite) { setText(tr("Focus on lesion")); InitializeAction(); } QmitkFocusOnLesionAction::QmitkFocusOnLesionAction(QWidget* parent, berry::IWorkbenchPartSite* workbenchPartSite) : QAction(parent) , QmitkAbstractDataNodeAction(berry::IWorkbenchPartSite::Pointer(workbenchPartSite)) { setText(tr("Focus on lesion")); InitializeAction(); } void QmitkFocusOnLesionAction::SetSelectedLesion(mitk::SemanticTypes::Lesion selectedLesion) { m_Lesion = selectedLesion; } void QmitkFocusOnLesionAction::InitializeAction() { setCheckable(true); connect(this, &QAction::triggered, this, &QmitkFocusOnLesionAction::OnActionTriggered); SetControlledRenderer(); } void QmitkFocusOnLesionAction::OnActionTriggered(bool /*checked*/) { if (m_WorkbenchPartSite.Expired()) { return; } if (m_DataStorage.IsExpired()) { return; } auto dataStorage = m_DataStorage.Lock(); auto renderWindowLayerController = std::make_unique(); renderWindowLayerController->SetDataStorage(dataStorage); // check each renderer to see if it contains a segmentation represented by the currently selected lesion for (const auto& renderer : m_ControlledRenderer) { // get currently fixed layer nodes of the specified renderer auto layerStack = mitk::RenderWindowLayerUtilities::GetLayerStack(dataStorage, renderer, true); // check each node to see if it is a segmentation represented by the currently selected lesion for (const auto& layer : layerStack) { auto dataNode = layer.second; bool isVisible = false; if (dataNode.IsNotNull()) { dataNode->GetBoolProperty("visible", isVisible, renderer); } // only focus in renderer where the segmentation is visible if (!isVisible) { continue; } auto currentLesion = mitk::SemanticRelationsInference::GetLesionOfSegmentation(dataNode); if (currentLesion.UID == m_Lesion.UID) { // jump to this lesion in the specified renderer LabelSetJumpToAction::Run(m_WorkbenchPartSite.Lock(), dataNode, renderer); } } } } void QmitkFocusOnLesionAction::SetControlledRenderer() { const mitk::RenderingManager::RenderWindowVector allRegisteredRenderWindows = mitk::RenderingManager::GetInstance()->GetAllRegisteredRenderWindows(); mitk::BaseRenderer *baseRenderer = nullptr; m_ControlledRenderer.clear(); for (const auto& renderWindow : allRegisteredRenderWindows) { baseRenderer = mitk::BaseRenderer::GetInstance(renderWindow); if (nullptr != baseRenderer) { m_ControlledRenderer.push_back(baseRenderer); } } } diff --git a/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkFocusOnLesionAction.h b/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkFocusOnLesionAction.h index d7e7b13efc..7f01b292fb 100644 --- a/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkFocusOnLesionAction.h +++ b/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkFocusOnLesionAction.h @@ -1,55 +1,56 @@ /*=================================================================== 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 QMITKLESIONSHOWINACTION_H #define QMITKLESIONSHOWINACTION_H -#include "QmitkAbstractDataNodeAction.h" +// mitk gui qt application plugin +#include // semantic relations module #include // qt #include class QmitkFocusOnLesionAction : public QAction, public QmitkAbstractDataNodeAction { Q_OBJECT public: typedef std::vector RendererVector; QmitkFocusOnLesionAction(QWidget* parent, berry::IWorkbenchPartSite::Pointer workbenchPartSite); QmitkFocusOnLesionAction(QWidget* parent, berry::IWorkbenchPartSite* workbenchPartSite); void SetSelectedLesion(mitk::SemanticTypes::Lesion selectedLesion); private Q_SLOTS: void OnActionTriggered(bool); protected: virtual void InitializeAction() override; void SetControlledRenderer(); RendererVector m_ControlledRenderer; mitk::SemanticTypes::Lesion m_Lesion; }; #endif // QMITKLESIONSHOWINACTION_H diff --git a/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkLesionInfoWidget.cpp b/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkLesionInfoWidget.cpp index 3bdf03580b..910b6cefaa 100644 --- a/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkLesionInfoWidget.cpp +++ b/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkLesionInfoWidget.cpp @@ -1,449 +1,461 @@ /*=================================================================== 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. ===================================================================*/ // semantic relations plugin #include "QmitkLesionInfoWidget.h" #include "QmitkDataNodeAddToSemanticRelationsAction.h" #include "QmitkFocusOnLesionAction.h" #include "QmitkSemanticRelationsNodeSelectionDialog.h" // semantic relations UI module #include // semantic relations module #include #include #include #include #include // registration ontology module //#include // qt #include #include #include #include #include QmitkLesionInfoWidget::QmitkLesionInfoWidget(mitk::DataStorage* dataStorage, berry::IWorkbenchPartSite::Pointer workbenchPartSite, QWidget* parent /*= nullptr*/) : QWidget(parent) , m_DataStorage(dataStorage) , m_WorkbenchPartSite(workbenchPartSite) , m_SemanticRelationsDataStorageAccess(std::make_unique(dataStorage)) , m_SemanticRelationsIntegration(std::make_unique()) { Initialize(); } void QmitkLesionInfoWidget::Initialize() { m_Controls.setupUi(this); m_Controls.lesionTreeView->setAlternatingRowColors(true); m_Controls.lesionTreeView->setSelectionMode(QAbstractItemView::SingleSelection); m_Controls.lesionTreeView->setSelectionBehavior(QAbstractItemView::SelectRows); m_Controls.lesionTreeView->setContextMenuPolicy(Qt::CustomContextMenu); m_StorageModel = new QmitkLesionTreeModel(m_Controls.lesionTreeView); if (m_DataStorage.IsExpired()) { return; } auto dataStorage = m_DataStorage.Lock(); m_StorageModel->SetDataStorage(dataStorage); m_Controls.lesionTreeView->setModel(m_StorageModel); SetUpConnections(); } void QmitkLesionInfoWidget::SetUpConnections() { connect(m_StorageModel, &QmitkLesionTreeModel::ModelUpdated, this, &QmitkLesionInfoWidget::OnModelUpdated); connect(m_Controls.addLesionPushButton, &QPushButton::clicked, this, &QmitkLesionInfoWidget::OnAddLesionButtonClicked); connect(m_Controls.lesionTreeView->selectionModel(), &QItemSelectionModel::currentChanged, this, &QmitkLesionInfoWidget::OnSelectionChanged); connect(m_Controls.lesionTreeView, &QTreeView::customContextMenuRequested, this, &QmitkLesionInfoWidget::OnLesionListContextMenuRequested); } void QmitkLesionInfoWidget::SetCaseID(const mitk::SemanticTypes::CaseID& caseID) { m_CaseID = caseID; m_StorageModel->SetCaseID(caseID); } void QmitkLesionInfoWidget::SetDataNodeSelection(const QList& dataNodeSelection) { m_StorageModel->SetDataNodeSelection(dataNodeSelection); } ////////////////////////////////////////////////////////////////////////// // Implementation of the QT_SLOTS ////////////////////////////////////////////////////////////////////////// void QmitkLesionInfoWidget::OnModelUpdated() { m_Controls.lesionTreeView->expandAll(); int columns = m_Controls.lesionTreeView->model()->columnCount(); for (int i = 0; i < columns; ++i) { m_Controls.lesionTreeView->resizeColumnToContents(i); } } void QmitkLesionInfoWidget::OnAddLesionButtonClicked() { if (m_CaseID.empty()) { QMessageBox msgBox(QMessageBox::Warning, "No case ID set.", "In order to add a lesion, please specify the current case / patient."); msgBox.exec(); return; } mitk::SemanticTypes::Lesion newLesion = mitk::GenerateNewLesion(); try { m_SemanticRelationsIntegration->AddLesion(m_CaseID, newLesion); } catch (mitk::SemanticRelationException& e) { MITK_INFO << "Could not add a new lesion. " << e; } } void QmitkLesionInfoWidget::OnSelectionChanged(const QModelIndex& current, const QModelIndex& /*previous*/) { // only the UID is needed to identify a representing lesion QVariant data = m_StorageModel->data(current, Qt::UserRole); if (!data.canConvert()) { return; } auto lesion = data.value()->GetData().GetLesion(); if (false == mitk::SemanticRelationsInference::InstanceExists(m_CaseID, lesion)) { // no UID of a existing lesion found; cannot create a lesion return; } // if selected data nodes are set, reset to empty list to // hide "selected data nodes presence background highlighting" in the model if (!m_StorageModel->GetSelectedDataNodes().isEmpty()) { m_StorageModel->SetDataNodeSelection(QList()); } emit LesionSelectionChanged(lesion); } void QmitkLesionInfoWidget::OnLesionListContextMenuRequested(const QPoint& pos) { if (nullptr == m_SemanticRelationsIntegration) { return; } if (m_CaseID.empty()) { QMessageBox msgBox(QMessageBox::Warning, "No case ID set.", "In order to access the context menu entries a case ID has to be set."); msgBox.exec(); return; } QModelIndex index = m_Controls.lesionTreeView->indexAt(pos); if (!index.isValid()) { // no item clicked; cannot retrieve the current lesion return; } QVariant data = m_StorageModel->data(index, Qt::UserRole); mitk::SemanticTypes::Lesion selectedLesion; if (data.canConvert()) { selectedLesion = data.value()->GetData().GetLesion(); } else { return; } QMenu* menu = new QMenu(m_Controls.lesionTreeView); QAction* linkToSegmentation = new QAction("Link to segmentation", this); linkToSegmentation->setEnabled(true); connect(linkToSegmentation, &QAction::triggered, [this, selectedLesion] { OnLinkToSegmentation(selectedLesion); }); menu->addAction(linkToSegmentation); QAction* setLesionName = new QAction("Set lesion name", this); setLesionName->setEnabled(true); connect(setLesionName, &QAction::triggered, [this, selectedLesion] { OnSetLesionName(selectedLesion); }); menu->addAction(setLesionName); QAction* setLesionClass = new QAction("Set lesion class", this); setLesionClass->setEnabled(true); connect(setLesionClass, &QAction::triggered, [this, selectedLesion] { OnSetLesionClass(selectedLesion); }); menu->addAction(setLesionClass); QAction* propageLesionToImage = new QAction("Propagate lesion to image", this); propageLesionToImage->setEnabled(true); connect(propageLesionToImage, &QAction::triggered, [this, selectedLesion] { OnPropagateLesion(selectedLesion); }); menu->addAction(propageLesionToImage); QAction* removeLesion = new QAction("Remove lesion", this); removeLesion->setEnabled(true); connect(removeLesion, &QAction::triggered, [this, selectedLesion] { OnRemoveLesion(selectedLesion); }); menu->addAction(removeLesion); if (!m_WorkbenchPartSite.Expired()) { QmitkFocusOnLesionAction* focusOnLesion = new QmitkFocusOnLesionAction(this, m_WorkbenchPartSite.Lock()); focusOnLesion->SetDataStorage(m_DataStorage.Lock()); focusOnLesion->SetSelectedLesion(selectedLesion); menu->addAction(focusOnLesion); } menu->popup(QCursor::pos()); } void QmitkLesionInfoWidget::OnLinkToSegmentation(mitk::SemanticTypes::Lesion selectedLesion) { if (m_DataStorage.IsExpired()) { return; } auto dataStorage = m_DataStorage.Lock(); QmitkSemanticRelationsNodeSelectionDialog* dialog = new QmitkSemanticRelationsNodeSelectionDialog(this, "Select segmentation to link to the selected lesion.", ""); dialog->setWindowTitle("Select segmentation node"); dialog->SetDataStorage(dataStorage); dialog->SetNodePredicate(mitk::NodePredicates::GetSegmentationPredicate()); dialog->SetSelectOnlyVisibleNodes(true); dialog->SetCaseID(m_CaseID); // set the last added segmentation node as pre-selected data node const mitk::DataNode* lastSegmentation = m_StorageModel->GetLastSegmentation(); QList selectedDataNodes; if (nullptr != lastSegmentation) { selectedDataNodes.push_back(const_cast(lastSegmentation)); dialog->SetCurrentSelection(selectedDataNodes); } int dialogReturnValue = dialog->exec(); if (QDialog::Rejected == dialogReturnValue) { return; } mitk::DataNode::Pointer selectedDataNode = nullptr; selectedDataNodes = dialog->GetSelectedNodes(); if (!selectedDataNodes.isEmpty()) { // only single selection allowed selectedDataNode = selectedDataNodes.front(); } if (nullptr == selectedDataNode || false == mitk::NodePredicates::GetSegmentationPredicate()->CheckNode(selectedDataNode)) { QMessageBox msgBox(QMessageBox::Warning, "No valid segmentation node selected.", "In order to link the selected lesion to a segmentation, please specify a valid segmentation node."); msgBox.exec(); return; } mitk::BaseData* baseData = selectedDataNode->GetData(); if (nullptr == baseData) { QMessageBox msgBox(QMessageBox::Warning, "No valid base data.", "In order to link the selected lesion to a segmentation, please specify a valid segmentation node."); msgBox.exec(); return; } // if the segmentation is not contained in the semantic relations, add it if (!mitk::SemanticRelationsInference::InstanceExists(selectedDataNode)) { - AddToSemanticRelationsAction::Run(m_SemanticRelationsIntegration.get(), dataStorage, selectedDataNode); + try + { + AddToSemanticRelationsAction::Run(dataStorage, selectedDataNode); + } + catch (const mitk::SemanticRelationException& e) + { + std::stringstream exceptionMessage; exceptionMessage << e; + QMessageBox msgBox(QMessageBox::Warning, + "Could not link the selected lesion.", + "The program wasn't able to correctly link the selected lesion with the selected segmentation.\n" + "Reason:\n" + QString::fromStdString(exceptionMessage.str() + "\n")); + msgBox.exec(); + } } // link the segmentation try { m_SemanticRelationsIntegration->LinkSegmentationToLesion(selectedDataNode, selectedLesion); } catch (const mitk::SemanticRelationException& e) { std::stringstream exceptionMessage; exceptionMessage << e; QMessageBox msgBox(QMessageBox::Warning, "Could not link the selected lesion.", "The program wasn't able to correctly link the selected lesion with the selected segmentation.\n" "Reason:\n" + QString::fromStdString(exceptionMessage.str())); msgBox.exec(); } } void QmitkLesionInfoWidget::OnSetLesionName(mitk::SemanticTypes::Lesion selectedLesion) { // use the lesion information to set the input text for the dialog QmitkLesionTextDialog* inputDialog = new QmitkLesionTextDialog(this); inputDialog->setWindowTitle("Set lesion name"); inputDialog->SetLineEditText(selectedLesion.name); int dialogReturnValue = inputDialog->exec(); if (QDialog::Rejected == dialogReturnValue) { return; } selectedLesion.name = inputDialog->GetLineEditText().toStdString(); m_SemanticRelationsIntegration->OverwriteLesion(m_CaseID, selectedLesion); } void QmitkLesionInfoWidget::OnSetLesionClass(mitk::SemanticTypes::Lesion selectedLesion) { // use the lesion information to set the input text for the dialog QmitkLesionTextDialog* inputDialog = new QmitkLesionTextDialog(this); inputDialog->setWindowTitle("Set lesion class"); inputDialog->SetLineEditText(selectedLesion.lesionClass.classType); // prepare the completer for the dialogs input text field mitk::LesionClassVector allLesionClasses = mitk::SemanticRelationsInference::GetAllLesionClassesOfCase(m_CaseID); QStringList wordList; for (const auto& lesionClass : allLesionClasses) { wordList << QString::fromStdString(lesionClass.classType); } QCompleter* completer = new QCompleter(wordList, this); completer->setCaseSensitivity(Qt::CaseInsensitive); inputDialog->GetLineEdit()->setCompleter(completer); int dialogReturnValue = inputDialog->exec(); if (QDialog::Rejected == dialogReturnValue) { return; } // retrieve the new input lesion class type and check for an already existing lesion class types std::string newLesionClassType = inputDialog->GetLineEditText().toStdString(); mitk::SemanticTypes::LesionClass existingLesionClass = mitk::FindExistingLesionClass(newLesionClassType, allLesionClasses); if (existingLesionClass.UID.empty()) { // could not find lesion class information for the new lesion class type // create a new lesion class for the selected lesion existingLesionClass = mitk::GenerateNewLesionClass(newLesionClassType); } selectedLesion.lesionClass = existingLesionClass; m_SemanticRelationsIntegration->OverwriteLesion(m_CaseID, selectedLesion); } void QmitkLesionInfoWidget::OnPropagateLesion(mitk::SemanticTypes::Lesion selectedLesion) { if (m_DataStorage.IsExpired()) { return; } auto dataStorage = m_DataStorage.Lock(); QmitkSemanticRelationsNodeSelectionDialog* dialog = new QmitkSemanticRelationsNodeSelectionDialog(this, "Select data node to propagate the selected lesion.", ""); dialog->setWindowTitle("Select image node"); dialog->SetDataStorage(dataStorage); dialog->SetNodePredicate(mitk::NodePredicates::GetImagePredicate()); dialog->SetSelectOnlyVisibleNodes(true); dialog->SetCaseID(m_CaseID); dialog->SetLesion(selectedLesion); int dialogReturnValue = dialog->exec(); if (QDialog::Rejected == dialogReturnValue) { return; } auto nodes = dialog->GetSelectedNodes(); mitk::DataNode::Pointer selectedDataNode = nullptr; if (!nodes.isEmpty()) { // only single selection allowed selectedDataNode = nodes.front(); } if (nullptr == selectedDataNode || false == mitk::NodePredicates::GetImagePredicate()->CheckNode(selectedDataNode)) { QMessageBox msgBox(QMessageBox::Warning, "No valid image node selected.", "In order to propagate the selected lesion to an image, please specify a valid image node."); msgBox.exec(); return; } mitk::BaseData* baseData = selectedDataNode->GetData(); if (nullptr == baseData) { QMessageBox msgBox(QMessageBox::Warning, "No valid base data.", "In order to propagate the selected lesion to an image, please specify a valid image node."); msgBox.exec(); return; } try { /* auto allSegmentationsOfLesion = m_SemanticRelationsDataStorageAccess->GetAllSegmentationsOfLesion(m_CaseID, selectedLesion); mitk::FindClosestSegmentationMask(); */ } catch (const mitk::SemanticRelationException& e) { std::stringstream exceptionMessage; exceptionMessage << e; QMessageBox msgBox(QMessageBox::Warning, "Could not propagate the selected lesion.", "The program wasn't able to correctly propagate the selected lesion to the selected image.\n" "Reason:\n" + QString::fromStdString(exceptionMessage.str())); msgBox.exec(); } } void QmitkLesionInfoWidget::OnRemoveLesion(mitk::SemanticTypes::Lesion selectedLesion) { try { m_SemanticRelationsIntegration->RemoveLesion(m_CaseID, selectedLesion); } catch (const mitk::SemanticRelationException& e) { std::stringstream exceptionMessage; exceptionMessage << e; QMessageBox msgBox(QMessageBox::Warning, "Could not remove the selected lesion.", "The program wasn't able to correctly remove the selected lesion from the semantic relations model.\n" "Reason:\n" + QString::fromStdString(exceptionMessage.str())); msgBox.exec(); } } diff --git a/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkSemanticRelationsView.cpp b/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkSemanticRelationsView.cpp index 56787f9e4e..19c4b7c8ba 100644 --- a/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkSemanticRelationsView.cpp +++ b/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkSemanticRelationsView.cpp @@ -1,263 +1,285 @@ /*=================================================================== 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. ===================================================================*/ // semantic relations plugin #include "QmitkSemanticRelationsView.h" #include "QmitkDataNodeAddToSemanticRelationsAction.h" #include "QmitkDataNodeRemoveFromSemanticRelationsAction.h" #include "QmitkLabelSetJumpToAction.h" // semantic relations module #include #include +#include #include #include // mitk core #include // mitk qt widgets module #include #include // berry #include #include // qt #include +#include #include const std::string QmitkSemanticRelationsView::VIEW_ID = "org.mitk.views.semanticrelations"; void QmitkSemanticRelationsView::SetFocus() { // nothing here } void QmitkSemanticRelationsView::RenderWindowPartActivated(mitk::IRenderWindowPart* renderWindowPart) { if (m_RenderWindowPart != renderWindowPart) { m_RenderWindowPart = renderWindowPart; SetControlledRenderer(); } } void QmitkSemanticRelationsView::RenderWindowPartDeactivated(mitk::IRenderWindowPart* renderWindowPart) { if (m_RenderWindowPart == renderWindowPart) { m_RenderWindowPart = nullptr; SetControlledRenderer(); } } void QmitkSemanticRelationsView::RenderWindowPartInputChanged(mitk::IRenderWindowPart* renderWindowPart) { if (m_RenderWindowPart == renderWindowPart) { SetControlledRenderer(); } } void QmitkSemanticRelationsView::CreateQtPartControl(QWidget* parent) { // create GUI widgets m_Controls.setupUi(parent); m_LesionInfoWidget = new QmitkLesionInfoWidget(GetDataStorage(), GetSite(), parent); m_Controls.gridLayout->addWidget(m_LesionInfoWidget); m_PatientTableInspector = new QmitkPatientTableInspector(parent); m_PatientTableInspector->SetDataStorage(GetDataStorage()); m_Controls.gridLayout->addWidget(m_PatientTableInspector); QGridLayout* dndDataNodeWidgetLayout = new QGridLayout; dndDataNodeWidgetLayout->addWidget(m_PatientTableInspector, 0, 0); dndDataNodeWidgetLayout->setContentsMargins(0, 0, 0, 0); m_DnDDataNodeWidget = new QmitkDnDDataNodeWidget(parent); m_DnDDataNodeWidget->setLayout(dndDataNodeWidgetLayout); m_Controls.gridLayout->addWidget(m_DnDDataNodeWidget); m_ContextMenu = new QmitkSemanticRelationsContextMenu(GetSite(), m_PatientTableInspector); m_ContextMenu->SetDataStorage(GetDataStorage()); mitk::IRenderWindowPart* renderWindowPart = GetRenderWindowPart(); if (nullptr != renderWindowPart) { RenderWindowPartActivated(renderWindowPart); } SetUpConnections(); const auto& allCaseIDs = mitk::RelationStorage::GetAllCaseIDs(); for (const auto& caseID : allCaseIDs) { AddToComboBox(caseID); } } void QmitkSemanticRelationsView::SetUpConnections() { connect(m_Controls.caseIDComboBox, static_cast(&QComboBox::currentIndexChanged), this, &QmitkSemanticRelationsView::OnCaseIDSelectionChanged); connect(m_LesionInfoWidget, &QmitkLesionInfoWidget::LesionSelectionChanged, this, &QmitkSemanticRelationsView::OnLesionSelectionChanged); connect(m_PatientTableInspector, &QmitkPatientTableInspector::CurrentSelectionChanged, this, &QmitkSemanticRelationsView::OnDataNodeSelectionChanged); connect(m_PatientTableInspector, &QmitkPatientTableInspector::DataNodeDoubleClicked, this, &QmitkSemanticRelationsView::OnDataNodeDoubleClicked); connect(m_DnDDataNodeWidget, &QmitkDnDDataNodeWidget::NodesDropped, this, &QmitkSemanticRelationsView::OnNodesAdded); connect(m_PatientTableInspector, &QmitkPatientTableInspector::OnContextMenuRequested, m_ContextMenu, &QmitkSemanticRelationsContextMenu::OnContextMenuRequested); connect(m_PatientTableInspector, &QmitkPatientTableInspector::OnNodeRemoved, this, &QmitkSemanticRelationsView::NodeRemoved); } QItemSelectionModel* QmitkSemanticRelationsView::GetDataNodeSelectionModel() const { return m_PatientTableInspector->GetSelectionModel(); } void QmitkSemanticRelationsView::NodeRemoved(const mitk::DataNode* dataNode) { if (nullptr == dataNode) { return; } if (mitk::SemanticRelationsInference::InstanceExists(dataNode)) { - // no observer needed for the integration; simply use a temporary instance for removing - mitk::SemanticRelationsIntegration semanticRelationsIntegration; - RemoveFromSemanticRelationsAction::Run(&semanticRelationsIntegration, GetDataStorage(), dataNode); - mitk::SemanticTypes::CaseID caseID = mitk::GetCaseIDFromDataNode(dataNode); - RemoveFromComboBox(caseID); + try + { + RemoveFromSemanticRelationsAction::Run(GetDataStorage(), dataNode); + mitk::SemanticTypes::CaseID caseID = mitk::GetCaseIDFromDataNode(dataNode); + RemoveFromComboBox(caseID); + } + catch (const mitk::SemanticRelationException& e) + { + std::stringstream exceptionMessage; exceptionMessage << e; + QMessageBox msgBox(QMessageBox::Warning, + "Could not remove the data node(s).", + "The program wasn't able to correctly remove the selected data node(s).\n" + "Reason:\n" + QString::fromStdString(exceptionMessage.str() + "\n")); + msgBox.exec(); + } } } void QmitkSemanticRelationsView::OnLesionSelectionChanged(const mitk::SemanticTypes::Lesion& lesion) { m_PatientTableInspector->SetLesion(lesion); } void QmitkSemanticRelationsView::OnDataNodeSelectionChanged(const QList& dataNodeSelection) { m_LesionInfoWidget->SetDataNodeSelection(dataNodeSelection); } void QmitkSemanticRelationsView::OnDataNodeDoubleClicked(const mitk::DataNode* dataNode) { if (nullptr == dataNode) { return; } if (mitk::NodePredicates::GetImagePredicate()->CheckNode(dataNode)) { OpenInEditor(dataNode); } else if (mitk::NodePredicates::GetSegmentationPredicate()->CheckNode(dataNode)) { LabelSetJumpToAction::Run(GetSite(), dataNode); } } void QmitkSemanticRelationsView::OnCaseIDSelectionChanged(const QString& caseID) { m_LesionInfoWidget->SetCaseID(caseID.toStdString()); m_PatientTableInspector->SetCaseID(caseID.toStdString()); } void QmitkSemanticRelationsView::OnNodesAdded(std::vector nodes) { mitk::SemanticTypes::CaseID caseID = ""; for (mitk::DataNode* dataNode : nodes) { - // no observer needed for the integration; simply use a temporary instance for adding - mitk::SemanticRelationsIntegration semanticRelationsIntegration; - AddToSemanticRelationsAction::Run(&semanticRelationsIntegration, GetDataStorage(), dataNode); - caseID = mitk::GetCaseIDFromDataNode(dataNode); - AddToComboBox(caseID); + try + { + AddToSemanticRelationsAction::Run(GetDataStorage(), dataNode); + caseID = mitk::GetCaseIDFromDataNode(dataNode); + AddToComboBox(caseID); + } + catch (const mitk::SemanticRelationException& e) + { + std::stringstream exceptionMessage; exceptionMessage << e; + QMessageBox msgBox(QMessageBox::Warning, + "Could not add the data node(s).", + "The program wasn't able to correctly add the selected data node(s).\n" + "Reason:\n" + QString::fromStdString(exceptionMessage.str() + "\n")); + msgBox.exec(); + } } } void QmitkSemanticRelationsView::OnNodeRemoved(const mitk::DataNode* dataNode) { NodeRemoved(dataNode); } void QmitkSemanticRelationsView::AddToComboBox(const mitk::SemanticTypes::CaseID& caseID) { int foundIndex = m_Controls.caseIDComboBox->findText(QString::fromStdString(caseID)); if (-1 == foundIndex) { // add the caseID to the combo box, as it is not already contained m_Controls.caseIDComboBox->addItem(QString::fromStdString(caseID)); } } void QmitkSemanticRelationsView::RemoveFromComboBox(const mitk::SemanticTypes::CaseID& caseID) { std::vector allControlPoints = mitk::RelationStorage::GetAllControlPointsOfCase(caseID); int foundIndex = m_Controls.caseIDComboBox->findText(QString::fromStdString(caseID)); if (allControlPoints.empty() && -1 != foundIndex) { // caseID does not contain any control points and therefore no data // remove the caseID, if it is still contained m_Controls.caseIDComboBox->removeItem(foundIndex); } } void QmitkSemanticRelationsView::OpenInEditor(const mitk::DataNode* dataNode) { auto renderWindowPart = GetRenderWindowPart(); if (nullptr == renderWindowPart) { renderWindowPart = GetRenderWindowPart(mitk::WorkbenchUtil::IRenderWindowPartStrategy::BRING_TO_FRONT | mitk::WorkbenchUtil::IRenderWindowPartStrategy::OPEN); if (nullptr == renderWindowPart) { // no render window available return; } } auto image = dynamic_cast(dataNode->GetData()); if (nullptr != image) { mitk::RenderingManager::GetInstance()->InitializeViews(image->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true); } } void QmitkSemanticRelationsView::SetControlledRenderer() { QHash renderWindows; if (m_RenderWindowPart != nullptr) { renderWindows = m_RenderWindowPart->GetQmitkRenderWindows(); } mitk::RenderWindowLayerUtilities::RendererVector controlledRenderer; mitk::BaseRenderer* baseRenderer = nullptr; for (const auto& renderWindow : renderWindows.values()) { baseRenderer = mitk::BaseRenderer::GetInstance(renderWindow->GetVtkRenderWindow()); if (nullptr != baseRenderer) { controlledRenderer.push_back(baseRenderer); } } m_ContextMenu->SetControlledRenderer(controlledRenderer); }