diff --git a/Modules/RenderWindowManager/files.cmake b/Modules/RenderWindowManager/files.cmake index 5e95f08b7a..8d8bb99f84 100644 --- a/Modules/RenderWindowManager/files.cmake +++ b/Modules/RenderWindowManager/files.cmake @@ -1,19 +1,11 @@ set(H_FILES - include/QmitkRenderWindowDataModel.h - include/mitkRenderWindowLayerController.h - include/mitkRenderWindowViewDirectionController.h - include/mitkRenderWindowLayerUtilities.h + include/mitkRenderWindowViewDirectionController.h + include/mitkRenderWindowLayerUtilities.h ) set(CPP_FILES - QmitkRenderWindowDataModel.cpp - - mitkRenderWindowLayerController.cpp - mitkRenderWindowViewDirectionController.cpp - mitkRenderWindowLayerUtilities.cpp -) - -set(MOC_H_FILES - include/QmitkRenderWindowDataModel.h + mitkRenderWindowLayerController.cpp + mitkRenderWindowViewDirectionController.cpp + mitkRenderWindowLayerUtilities.cpp ) diff --git a/Modules/RenderWindowManager/include/QmitkRenderWindowDataModel.h b/Modules/RenderWindowManager/include/QmitkRenderWindowDataModel.h deleted file mode 100644 index b96a518bc2..0000000000 --- a/Modules/RenderWindowManager/include/QmitkRenderWindowDataModel.h +++ /dev/null @@ -1,69 +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 QMITKRENDERWINDOWDATAMODEL_H -#define QMITKRENDERWINDOWDATAMODEL_H - -// render window manager module -#include "MitkRenderWindowManagerExports.h" -#include "mitkRenderWindowLayerUtilities.h" - -//mitk core -#include -#include - -// qt -#include - -/* -* @brief This class extends the 'QAbstractTableModel' to meet the specific requirements of the QmitkRenderWindowDataModel. -*/ -class MITKRENDERWINDOWMANAGER_EXPORT QmitkRenderWindowDataModel : public QAbstractTableModel -{ - Q_OBJECT - -public: - - QmitkRenderWindowDataModel(QObject* parent = nullptr); - ~QmitkRenderWindowDataModel() override; - - ////////////////////////////////////////////////////////////////////////// - /// overridden functions from QAbstractItemModel - ////////////////////////////////////////////////////////////////////////// - Qt::ItemFlags flags(const QModelIndex &index) const override; - QVariant data(const QModelIndex &index, int role) const override; - QVariant headerData(int section, Qt::Orientation orientation, int role) const override; - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - int columnCount(const QModelIndex &parent = QModelIndex()) const override; - bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; - ////////////////////////////////////////////////////////////////////////// - /// end override - ///////////////////////////////////////////////////////////////////////// - - void SetDataStorage(mitk::DataStorage::Pointer dataStorage); - void SetCurrentRenderer(std::string rendererName); - mitk::BaseRenderer* GetCurrentRenderer() const { return m_BaseRenderer.GetPointer(); } - void DataChanged(const mitk::DataNode* dataNode); - -private: - - mitk::DataStorage::Pointer m_DataStorage; - mitk::BaseRenderer::Pointer m_BaseRenderer; - RenderWindowLayerUtilities::LayerStack m_TempLayerStack; - -}; - -#endif // QMITKRENDERWINDOWDATAMODEL_H diff --git a/Modules/RenderWindowManager/src/QmitkRenderWindowDataModel.cpp b/Modules/RenderWindowManager/src/QmitkRenderWindowDataModel.cpp deleted file mode 100644 index a8888f8042..0000000000 --- a/Modules/RenderWindowManager/src/QmitkRenderWindowDataModel.cpp +++ /dev/null @@ -1,208 +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. - -===================================================================*/ - -// render window manager UI module -#include "QmitkRenderWindowDataModel.h" - -#include "QmitkCustomVariants.h" - -QmitkRenderWindowDataModel::QmitkRenderWindowDataModel(QObject* parent /*= nullptr*/) - : QAbstractTableModel(parent) -{ - // nothing here -} - -QmitkRenderWindowDataModel::~QmitkRenderWindowDataModel() -{ - if (m_DataStorage.IsNotNull()) - { - m_DataStorage->ChangedNodeEvent.RemoveListener(mitk::MessageDelegate1(this, &QmitkRenderWindowDataModel::DataChanged)); - m_DataStorage->RemoveNodeEvent.RemoveListener(mitk::MessageDelegate1(this, &QmitkRenderWindowDataModel::DataChanged)); - } -} - -int QmitkRenderWindowDataModel::rowCount(const QModelIndex &parent /*= QModelIndex()*/) const -{ - if (parent.isValid()) - { - return 0; - } - - return static_cast(m_TempLayerStack.size()); -} - -int QmitkRenderWindowDataModel::columnCount(const QModelIndex &parent /*= QModelIndex()*/) const -{ - if (parent.isValid()) - { - return 0; - } - - return 2; -} - -QVariant QmitkRenderWindowDataModel::data(const QModelIndex &index, int role) const -{ - if (!index.isValid()) - { - return QVariant(); - } - - if ((index.row()) < static_cast(m_TempLayerStack.size())) - { - RenderWindowLayerUtilities::LayerStack::const_iterator layerStackIt = m_TempLayerStack.begin(); - std::advance(layerStackIt, index.row()); - mitk::DataNode* dataNode = layerStackIt->second; - if (Qt::CheckStateRole == role && 0 == index.column()) - { - bool visibility = false; - dataNode->GetVisibility(visibility, m_BaseRenderer); - if (visibility) - { - return Qt::Checked; - } - else - { - return Qt::Unchecked; - } - } - else if (Qt::DisplayRole == role && 1 == index.column()) - { - return QVariant(QString::fromStdString(dataNode->GetName())); - } - else if (Qt::ToolTipRole == role) - { - if (0 == index.column()) - { - return QVariant("Show/hide data node."); - } - else if (1 == index.column()) - { - return QVariant("Name of the data node."); - } - } - else if (Qt::UserRole == role) - { - // user role always returns a reference to the data node, - // which can be used to modify the data node in the data storage - return QVariant::fromValue(dataNode); - } - } - return QVariant(); -} - -Qt::ItemFlags QmitkRenderWindowDataModel::flags(const QModelIndex &index) const -{ - Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable; - if (0 == index.column()) - { - flags |= Qt::ItemIsUserCheckable; - } - - return flags; -} - -QVariant QmitkRenderWindowDataModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if (Qt::Horizontal == orientation && Qt::DisplayRole == role) - { - if (0 == section) - { - return QVariant("Visibility"); - } - else if (1 == section) - { - return QVariant("Data node"); - } - } - return QVariant(); -} - -bool QmitkRenderWindowDataModel::setData(const QModelIndex &index, const QVariant &value, int role /*= Qt::EditRole*/) -{ - if (!index.isValid()) - { - return false; - } - - if ((index.row()) < static_cast(m_TempLayerStack.size())) - { - RenderWindowLayerUtilities::LayerStack::const_iterator layerStackIt = m_TempLayerStack.begin(); - std::advance(layerStackIt, index.row()); - mitk::DataNode* dataNode = layerStackIt->second; - if (Qt::CheckStateRole == role) - { - Qt::CheckState newCheckState = static_cast(value.toInt()); - - if (Qt::PartiallyChecked == newCheckState || Qt::Checked == newCheckState) - { - dataNode->SetVisibility(true, m_BaseRenderer); - } - else - { - dataNode->SetVisibility(false, m_BaseRenderer); - } - emit dataChanged(index, index); - mitk::RenderingManager::GetInstance()->RequestUpdate(m_BaseRenderer->GetRenderWindow()); - return true; - } - } - return false; -} - -void QmitkRenderWindowDataModel::SetDataStorage(mitk::DataStorage::Pointer dataStorage) -{ - if (m_DataStorage != dataStorage) - { - // given data storage is a new data storage - if (m_DataStorage.IsNotNull()) - { - // remove listener from old data storage - m_DataStorage->ChangedNodeEvent.RemoveListener(mitk::MessageDelegate1(this, &QmitkRenderWindowDataModel::DataChanged)); - m_DataStorage->RemoveNodeEvent.RemoveListener(mitk::MessageDelegate1(this, &QmitkRenderWindowDataModel::DataChanged)); - } - // set the new data storage - m_DataStorage = dataStorage; - // register new data storage listener - if (m_DataStorage.IsNotNull()) - { - m_DataStorage->ChangedNodeEvent.AddListener(mitk::MessageDelegate1(this, &QmitkRenderWindowDataModel::DataChanged)); - m_DataStorage->RemoveNodeEvent.AddListener(mitk::MessageDelegate1(this, &QmitkRenderWindowDataModel::DataChanged)); - } - DataChanged(nullptr); - } -} - -void QmitkRenderWindowDataModel::SetCurrentRenderer(std::string renderWindowName) -{ - m_BaseRenderer = mitk::BaseRenderer::GetByName(renderWindowName); - if (m_DataStorage.IsNotNull()) - { - DataChanged(nullptr); - } -} - -void QmitkRenderWindowDataModel::DataChanged(const mitk::DataNode* /*dataNode*/) -{ - if (m_BaseRenderer.IsNotNull()) - { - // update the model, so that the table will be filled with the nodes information of the new data storage - beginResetModel(); - // get the current layer stack of the given base renderer - m_TempLayerStack = RenderWindowLayerUtilities::GetLayerStack(m_DataStorage, m_BaseRenderer, true); - endResetModel(); - } -} diff --git a/Modules/RenderWindowManagerUI/files.cmake b/Modules/RenderWindowManagerUI/files.cmake index a998c3cf7f..a350cab98c 100644 --- a/Modules/RenderWindowManagerUI/files.cmake +++ b/Modules/RenderWindowManagerUI/files.cmake @@ -1,15 +1,18 @@ set(H_FILES include/QmitkRenderWindowManipulatorWidget.h + include/QmitkDataStorageLayerStackModel.h ) set(CPP_FILES QmitkRenderWindowManipulatorWidget.cpp + QmitkDataStorageLayerStackModel.cpp ) set(MOC_H_FILES include/QmitkRenderWindowManipulatorWidget.h + include/QmitkDataStorageLayerStackModel.h ) set(UI_FILES src/QmitkRenderWindowManipulatorWidget.ui ) \ No newline at end of file diff --git a/Modules/RenderWindowManagerUI/include/QmitkDataStorageLayerStackModel.h b/Modules/RenderWindowManagerUI/include/QmitkDataStorageLayerStackModel.h new file mode 100644 index 0000000000..d106d23db8 --- /dev/null +++ b/Modules/RenderWindowManagerUI/include/QmitkDataStorageLayerStackModel.h @@ -0,0 +1,93 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical Image Computing. +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 QMITKDATASTORAGELAYERSTACKMODEL_H +#define QMITKDATASTORAGELAYERSTACKMODEL_H + +// render window manager UI module +#include "MitkRenderWindowManagerUIExports.h" + +// render window manager module +#include "mitkRenderWindowLayerUtilities.h" + +// qt widgets module +#include + +/** +* @brief The 'QmitkDataStorageLayerStackModel' is a customized table model, derived from the 'QmitkAbstractDataStorageModel'. +* It provides functions to accept a data storage and a node predicate in order to customize the model data nodes. +* Furthermore it overrides the functions of 'QAbstractItemModel' to create a customized qt table model. +* This model can be used in conjunction with a 'QmitkDataStorageSelectionConnector'. +*/ +class MITKRENDERWINDOWMANAGERUI_EXPORT QmitkDataStorageLayerStackModel : public QmitkAbstractDataStorageModel +{ + Q_OBJECT + +public: + + QmitkDataStorageLayerStackModel(QObject* parent = nullptr); + + // override from 'QmitkAbstractDataStorageModel' + /* + * @brief See 'QmitkAbstractDataStorageModel' + */ + void DataStorageChanged() override; + /* + * @brief See 'QmitkAbstractDataStorageModel' + */ + void NodePredicateChanged() override; + /* + * @brief See 'QmitkAbstractDataStorageModel' + */ + void NodeAdded(const mitk::DataNode* node) override; + /* + * @brief See 'QmitkAbstractDataStorageModel' + */ + void NodeChanged(const mitk::DataNode* node) override; + /* + * @brief See 'QmitkAbstractDataStorageModel' + */ + void NodeRemoved(const mitk::DataNode* node) override; + + void SetCurrentRenderer(const std::string& rendererName); + + mitk::BaseRenderer* GetCurrentRenderer() const; + + ////////////////////////////////////////////////////////////////////////// + /// overridden functions from QAbstractItemModel + ////////////////////////////////////////////////////////////////////////// + QModelIndex index(int row, int column, const QModelIndex& parent) const; + QModelIndex parent(const QModelIndex& child) const; + Qt::ItemFlags flags(const QModelIndex& index) const override; + QVariant headerData(int section, Qt::Orientation orientation, int role) const override; + int rowCount(const QModelIndex& parent = QModelIndex()) const override; + int columnCount(const QModelIndex& parent = QModelIndex()) const override; + QVariant data(const QModelIndex& index, int role) const override; + bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override; + ////////////////////////////////////////////////////////////////////////// + /// end override + ///////////////////////////////////////////////////////////////////////// + +private: + + void UpdateModelData(); + + mitk::WeakPointer m_BaseRenderer; + RenderWindowLayerUtilities::LayerStack m_TempLayerStack; + +}; + +#endif // QMITKDATASTORAGELAYERSTACKMODEL_H diff --git a/Modules/RenderWindowManagerUI/include/QmitkRenderWindowManipulatorWidget.h b/Modules/RenderWindowManagerUI/include/QmitkRenderWindowManipulatorWidget.h index e08edafbce..c863b88052 100644 --- a/Modules/RenderWindowManagerUI/include/QmitkRenderWindowManipulatorWidget.h +++ b/Modules/RenderWindowManagerUI/include/QmitkRenderWindowManipulatorWidget.h @@ -1,108 +1,114 @@ /*=================================================================== 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 QMITKRENDERWINDOWMANIPULATORWIDGET_H #define QMITKRENDERWINDOWMANIPULATORWIDGET_H // render window manager UI module #include "MitkRenderWindowManagerUIExports.h" #include "ui_QmitkRenderWindowManipulatorWidget.h" +#include // render window manager module #include #include -#include // qt #include /** * The QmitkRenderWindowManipulatorWidget offers a GUI to manipulate the base renderer / render windows of the MITK workbench. * The widgets supports adding a layer to an active render window, moving layers up and down, removing layers, * resetting layers (hiding them) or removing all layers at once. * * In order to use this widget, a (e.g.) plugin has to set the controlled renderer, which will be forwarded to * a render window layer controller and a render window view direction controller. * The plugin also has to provide a Q_SLOT that is connected to the 'AddLayerButtonClicked'-Q_SIGNAL of this widget. * This allows for a customized add-layer functionality. */ class MITKRENDERWINDOWMANAGERUI_EXPORT QmitkRenderWindowManipulatorWidget : public QWidget { Q_OBJECT public: QmitkRenderWindowManipulatorWidget(mitk::DataStorage::Pointer dataStorage, QWidget* parent = nullptr); /** + * @brief Get the table view that displays the layer stack inside this widget + */ + QTableView* GetLayerStackTableView(); + /** * @brief Set the controlled base renderer. */ void SetControlledRenderer(RenderWindowLayerUtilities::RendererVector controlledRenderer); /** * @brief Set the currently selected render window * * @param renderWindowId the text inside the combo box */ void SetActiveRenderWindow(const QString &renderWindowId); /** * @brief Use the RenderWindowLayerController to insert the given data node into the currently active render window. * The new node is placed on top of all existing layer nodes in that render window. * * @param dataNode The data node that should be inserted. */ void AddLayer(mitk::DataNode* dataNode); /** * @brief Use the RenderWindowLayerController to insert the given data node into all controlled render windows. * The new node is placed on top of all existing layer nodes in the render window. * * @param dataNode The data node that should be inserted. */ void AddLayerToAllRenderer(mitk::DataNode* dataNode); /** * @brief Use the RenderWindowLayerController to hide the given data node in the currently active render window. * * @param dataNode The data node that should be hid. */ void HideDataNodeInAllRenderer(const mitk::DataNode* dataNode); Q_SIGNALS: + void AddLayerButtonClicked(); private Q_SLOTS: void RemoveLayer(); void SetAsBaseLayer(); void MoveLayer(const QString &direction); void ResetRenderer(); void ClearRenderer(); void ChangeViewDirection(const QString &viewDirection); private: void Init(); void SetUpConnections(); Ui::QmitkRenderWindowManipulatorWidget m_Controls; mitk::DataStorage::Pointer m_DataStorage; - std::unique_ptr m_RenderWindowDataModel; std::unique_ptr m_RenderWindowLayerController; std::unique_ptr m_RenderWindowViewDirectionController; + + QmitkDataStorageLayerStackModel* m_StorageModel; }; #endif // QMITKRENDERWINDOWMANIPULATORWIDGET_H diff --git a/Modules/RenderWindowManagerUI/src/QmitkDataStorageLayerStackModel.cpp b/Modules/RenderWindowManagerUI/src/QmitkDataStorageLayerStackModel.cpp new file mode 100644 index 0000000000..e4f627fffc --- /dev/null +++ b/Modules/RenderWindowManagerUI/src/QmitkDataStorageLayerStackModel.cpp @@ -0,0 +1,238 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical Image Computing. +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 + +// qt widgets module +#include "QmitkCustomVariants.h" +#include "QmitkEnums.h" + +QmitkDataStorageLayerStackModel::QmitkDataStorageLayerStackModel(QObject* parent/* = nullptr*/) + : QmitkAbstractDataStorageModel(parent) +{ + // nothing here +} + +void QmitkDataStorageLayerStackModel::DataStorageChanged() +{ + UpdateModelData(); +} + +void QmitkDataStorageLayerStackModel::NodePredicateChanged() +{ + UpdateModelData(); +} + +void QmitkDataStorageLayerStackModel::NodeAdded(const mitk::DataNode* /*node*/) +{ + // nothing here; layers (nodes) are only added after button click +} + +void QmitkDataStorageLayerStackModel::NodeChanged(const mitk::DataNode* /*node*/) +{ + UpdateModelData(); +} + +void QmitkDataStorageLayerStackModel::NodeRemoved(const mitk::DataNode* /*node*/) +{ + UpdateModelData(); +} + +void QmitkDataStorageLayerStackModel::SetCurrentRenderer(const std::string& renderWindowName) +{ + if (!m_DataStorage.IsExpired()) + { + m_BaseRenderer = mitk::BaseRenderer::GetByName(renderWindowName); + UpdateModelData(); + } +} + +mitk::BaseRenderer* QmitkDataStorageLayerStackModel::GetCurrentRenderer() const +{ + return m_BaseRenderer.Lock(); +} + +QModelIndex QmitkDataStorageLayerStackModel::index(int row, int column, const QModelIndex& parent) const +{ + bool hasIndex = this->hasIndex(row, column, parent); + if (hasIndex) + { + return this->createIndex(row, column); + } + + return QModelIndex(); +} + +QModelIndex QmitkDataStorageLayerStackModel::parent(const QModelIndex& /*child*/) const +{ + return QModelIndex(); +} + +Qt::ItemFlags QmitkDataStorageLayerStackModel::flags(const QModelIndex& index) const +{ + Qt::ItemFlags flags = Qt::NoItemFlags; + if (index.isValid() && index.model() == this) + { + flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable; + if (0 == index.column()) + { + flags |= Qt::ItemIsUserCheckable; + } + } + + return flags; +} + +QVariant QmitkDataStorageLayerStackModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (Qt::Horizontal == orientation && Qt::DisplayRole == role) + { + if (0 == section) + { + return QVariant("Visibility"); + } + else if (1 == section) + { + return QVariant("Data node"); + } + } + return QVariant(); +} + +int QmitkDataStorageLayerStackModel::rowCount(const QModelIndex& parent/* = QModelIndex()*/) const +{ + if (parent.isValid()) + { + return 0; + } + + return static_cast(m_TempLayerStack.size()); +} + +int QmitkDataStorageLayerStackModel::columnCount(const QModelIndex& parent/* = QModelIndex()*/) const +{ + if (parent.isValid()) + { + return 0; + } + + return 2; +} + +QVariant QmitkDataStorageLayerStackModel::data(const QModelIndex& index, int role) const +{ + if (!index.isValid() || index.model() != this) + { + return QVariant(); + } + + if ((index.row()) < 0 || index.row() >= static_cast(m_TempLayerStack.size())) + { + return QVariant(); + } + + RenderWindowLayerUtilities::LayerStack::const_iterator layerStackIt = m_TempLayerStack.begin(); + std::advance(layerStackIt, index.row()); + mitk::DataNode* dataNode = layerStackIt->second; + if (Qt::CheckStateRole == role && 0 == index.column()) + { + bool visibility = false; + dataNode->GetVisibility(visibility, m_BaseRenderer.Lock()); + if (visibility) + { + return Qt::Checked; + } + else + { + return Qt::Unchecked; + } + } + else if (Qt::DisplayRole == role && 1 == index.column()) + { + return QVariant(QString::fromStdString(dataNode->GetName())); + } + else if (Qt::ToolTipRole == role) + { + if (0 == index.column()) + { + return QVariant("Show/hide data node."); + } + else if (1 == index.column()) + { + return QVariant("Name of the data node."); + } + } + else if (QmitkDataNodeRole == role) + { + return QVariant::fromValue(mitk::DataNode::Pointer(dataNode)); + } + else if (QmitkDataNodeRawPointerRole == role) + { + return QVariant::fromValue(dataNode); + } + + return QVariant(); +} + +bool QmitkDataStorageLayerStackModel::setData(const QModelIndex &index, const QVariant &value, int role /*= Qt::EditRole*/) +{ + if (!index.isValid() || index.model() != this) + { + return false; + } + + if ((index.row()) < 0 || index.row() >= static_cast(m_TempLayerStack.size())) + { + return false; + } + + if (!m_BaseRenderer.IsExpired()) + { + auto baseRenderer = m_BaseRenderer.Lock(); + + RenderWindowLayerUtilities::LayerStack::const_iterator layerStackIt = m_TempLayerStack.begin(); + std::advance(layerStackIt, index.row()); + mitk::DataNode* dataNode = layerStackIt->second; + if (Qt::CheckStateRole == role) + { + Qt::CheckState newCheckState = static_cast(value.toInt()); + + if (Qt::PartiallyChecked == newCheckState || Qt::Checked == newCheckState) + { + dataNode->SetVisibility(true, baseRenderer); + } + else + { + dataNode->SetVisibility(false, baseRenderer); + } + emit dataChanged(index, index); + mitk::RenderingManager::GetInstance()->RequestUpdate(baseRenderer->GetRenderWindow()); + return true; + } + } + + return false; +} + +void QmitkDataStorageLayerStackModel::UpdateModelData() +{ + // update the model, so that the table will be filled with the nodes according to the current + // data storage and base renderer + beginResetModel(); + // get the current layer stack of the given base renderer + m_TempLayerStack = RenderWindowLayerUtilities::GetLayerStack(m_DataStorage.Lock(), m_BaseRenderer.Lock(), true); + endResetModel(); +} diff --git a/Modules/RenderWindowManagerUI/src/QmitkRenderWindowManipulatorWidget.cpp b/Modules/RenderWindowManagerUI/src/QmitkRenderWindowManipulatorWidget.cpp index c8ecd4bee7..cb8ad4eb8e 100644 --- a/Modules/RenderWindowManagerUI/src/QmitkRenderWindowManipulatorWidget.cpp +++ b/Modules/RenderWindowManagerUI/src/QmitkRenderWindowManipulatorWidget.cpp @@ -1,216 +1,272 @@ /*=================================================================== 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. ===================================================================*/ // render window manager UI module #include "QmitkRenderWindowManipulatorWidget.h" +// qt widgets module #include "QmitkCustomVariants.h" +#include "QmitkEnums.h" // mitk core #include // qt #include QmitkRenderWindowManipulatorWidget::QmitkRenderWindowManipulatorWidget(mitk::DataStorage::Pointer dataStorage, QWidget* parent /*=nullptr*/) : QWidget(parent) , m_DataStorage(dataStorage) + , m_StorageModel(nullptr) { Init(); } void QmitkRenderWindowManipulatorWidget::Init() { - // create GUI from the Qt Designer's .ui file m_Controls.setupUi(this); // initialize the render window layer controller and the render window view direction controller // and set the controller renderer (in constructor) and the data storage m_RenderWindowLayerController = std::make_unique(); m_RenderWindowViewDirectionController = std::make_unique(); m_RenderWindowLayerController->SetDataStorage(m_DataStorage); m_RenderWindowViewDirectionController->SetDataStorage(m_DataStorage); - // create a new model - m_RenderWindowDataModel = std::make_unique(this); - m_RenderWindowDataModel->SetDataStorage(m_DataStorage); + m_Controls.layerStackTableView->setEditTriggers(QAbstractItemView::NoEditTriggers); + m_Controls.layerStackTableView->horizontalHeader()->setStretchLastSection(true); + m_Controls.layerStackTableView->setSelectionBehavior(QAbstractItemView::SelectRows); + m_Controls.layerStackTableView->setSelectionMode(QAbstractItemView::SingleSelection); - m_Controls.renderWindowTableView->setModel(m_RenderWindowDataModel.get()); - m_Controls.renderWindowTableView->setEditTriggers(QAbstractItemView::NoEditTriggers); - m_Controls.renderWindowTableView->horizontalHeader()->setStretchLastSection(true); - m_Controls.renderWindowTableView->setSelectionBehavior(QAbstractItemView::SelectRows); - m_Controls.renderWindowTableView->setSelectionMode(QAbstractItemView::SingleSelection); + m_StorageModel = new QmitkDataStorageLayerStackModel(this); + m_StorageModel->SetDataStorage(m_DataStorage); + + m_Controls.layerStackTableView->setModel(m_StorageModel); SetUpConnections(); } void QmitkRenderWindowManipulatorWidget::SetUpConnections() { // signal to signal connection connect(m_Controls.pushButtonAddLayer, SIGNAL(clicked()), this, SIGNAL(AddLayerButtonClicked())); connect(m_Controls.pushButtonRemoveLayer, SIGNAL(clicked()), this, SLOT(RemoveLayer())); connect(m_Controls.pushButtonSetAsBaseLayer, SIGNAL(clicked()), this, SLOT(SetAsBaseLayer())); QSignalMapper* udSignalMapper = new QSignalMapper(this); udSignalMapper->setMapping(m_Controls.pushButtonMoveUp, QString("up")); udSignalMapper->setMapping(m_Controls.pushButtonMoveDown, QString("down")); connect(udSignalMapper, SIGNAL(mapped(const QString&)), this, SLOT(MoveLayer(const QString&))); connect(m_Controls.pushButtonMoveUp, SIGNAL(clicked()), udSignalMapper, SLOT(map())); connect(m_Controls.pushButtonMoveDown, SIGNAL(clicked()), udSignalMapper, SLOT(map())); connect(m_Controls.pushButtonResetRenderer, SIGNAL(clicked()), this, SLOT(ResetRenderer())); connect(m_Controls.pushButtonClearRenderer, SIGNAL(clicked()), this, SLOT(ClearRenderer())); QSignalMapper* changeViewDirectionSignalMapper = new QSignalMapper(this); changeViewDirectionSignalMapper->setMapping(m_Controls.radioButtonAxial, QString("axial")); changeViewDirectionSignalMapper->setMapping(m_Controls.radioButtonCoronal, QString("coronal")); changeViewDirectionSignalMapper->setMapping(m_Controls.radioButtonSagittal, QString("sagittal")); connect(changeViewDirectionSignalMapper, SIGNAL(mapped(const QString&)), this, SLOT(ChangeViewDirection(const QString&))); connect(m_Controls.radioButtonAxial, SIGNAL(clicked()), changeViewDirectionSignalMapper, SLOT(map())); connect(m_Controls.radioButtonCoronal, SIGNAL(clicked()), changeViewDirectionSignalMapper, SLOT(map())); connect(m_Controls.radioButtonSagittal, SIGNAL(clicked()), changeViewDirectionSignalMapper, SLOT(map())); } +QTableView* QmitkRenderWindowManipulatorWidget::GetLayerStackTableView() +{ + return m_Controls.layerStackTableView; +} + void QmitkRenderWindowManipulatorWidget::SetControlledRenderer(RenderWindowLayerUtilities::RendererVector controlledRenderer) { m_RenderWindowLayerController->SetControlledRenderer(controlledRenderer); m_RenderWindowViewDirectionController->SetControlledRenderer(controlledRenderer); } void QmitkRenderWindowManipulatorWidget::SetActiveRenderWindow(const QString &renderWindowId) { + if (nullptr == m_StorageModel) + { + return; + } + std::string currentRendererName = renderWindowId.toStdString(); - m_RenderWindowDataModel->SetCurrentRenderer(currentRendererName); + m_StorageModel->SetCurrentRenderer(currentRendererName); mitk::BaseRenderer* selectedRenderer = mitk::BaseRenderer::GetByName(currentRendererName); if (nullptr == selectedRenderer) { return; } mitk::SliceNavigationController::ViewDirection viewDirection = selectedRenderer->GetSliceNavigationController()->GetDefaultViewDirection(); switch (viewDirection) { case mitk::SliceNavigationController::Axial: m_Controls.radioButtonAxial->setChecked(true); break; case mitk::SliceNavigationController::Frontal: m_Controls.radioButtonCoronal->setChecked(true); break; case mitk::SliceNavigationController::Sagittal: m_Controls.radioButtonSagittal->setChecked(true); break; default: break; } } void QmitkRenderWindowManipulatorWidget::AddLayer(mitk::DataNode* dataNode) { - m_RenderWindowLayerController->InsertLayerNode(dataNode, -1, m_RenderWindowDataModel->GetCurrentRenderer()); + if (nullptr == m_StorageModel) + { + return; + } + + m_RenderWindowLayerController->InsertLayerNode(dataNode, -1, m_StorageModel->GetCurrentRenderer()); } void QmitkRenderWindowManipulatorWidget::AddLayerToAllRenderer(mitk::DataNode* dataNode) { m_RenderWindowLayerController->InsertLayerNode(dataNode, -1, nullptr); } void QmitkRenderWindowManipulatorWidget::HideDataNodeInAllRenderer(const mitk::DataNode* dataNode) { m_RenderWindowLayerController->HideDataNodeInAllRenderer(dataNode); } void QmitkRenderWindowManipulatorWidget::RemoveLayer() { - QModelIndex selectedIndex = m_Controls.renderWindowTableView->currentIndex(); + if (nullptr == m_StorageModel) + { + return; + } + + QModelIndex selectedIndex = m_Controls.layerStackTableView->currentIndex(); if (selectedIndex.isValid()) { - QVariant qvariantDataNode = m_RenderWindowDataModel->data(selectedIndex, Qt::UserRole); + QVariant qvariantDataNode = m_StorageModel->data(selectedIndex, QmitkDataNodeRawPointerRole); if (qvariantDataNode.canConvert()) { mitk::DataNode* dataNode = qvariantDataNode.value(); - m_RenderWindowLayerController->RemoveLayerNode(dataNode, m_RenderWindowDataModel->GetCurrentRenderer()); - m_Controls.renderWindowTableView->clearSelection(); + m_RenderWindowLayerController->RemoveLayerNode(dataNode, m_StorageModel->GetCurrentRenderer()); + m_Controls.layerStackTableView->clearSelection(); } } } void QmitkRenderWindowManipulatorWidget::SetAsBaseLayer() { - QModelIndex selectedIndex = m_Controls.renderWindowTableView->currentIndex(); + if (nullptr == m_StorageModel) + { + return; + } + + QModelIndex selectedIndex = m_Controls.layerStackTableView->currentIndex(); if (selectedIndex.isValid()) { - QVariant qvariantDataNode = m_RenderWindowDataModel->data(selectedIndex, Qt::UserRole); + QVariant qvariantDataNode = m_StorageModel->data(selectedIndex, QmitkDataNodeRawPointerRole); if (qvariantDataNode.canConvert()) { mitk::DataNode* dataNode = qvariantDataNode.value(); - m_RenderWindowLayerController->SetBaseDataNode(dataNode, m_RenderWindowDataModel->GetCurrentRenderer()); - m_Controls.renderWindowTableView->clearSelection(); + m_RenderWindowLayerController->SetBaseDataNode(dataNode, m_StorageModel->GetCurrentRenderer()); + m_Controls.layerStackTableView->clearSelection(); } } } void QmitkRenderWindowManipulatorWidget::MoveLayer(const QString &direction) { - QModelIndex selectedIndex = m_Controls.renderWindowTableView->currentIndex(); + if (nullptr == m_StorageModel) + { + return; + } + + QModelIndex selectedIndex = m_Controls.layerStackTableView->currentIndex(); if (selectedIndex.isValid()) { - QVariant qvariantDataNode = m_RenderWindowDataModel->data(selectedIndex, Qt::UserRole); + QVariant qvariantDataNode = m_StorageModel->data(selectedIndex, QmitkDataNodeRawPointerRole); if (qvariantDataNode.canConvert()) { mitk::DataNode* dataNode = qvariantDataNode.value(); - const mitk::BaseRenderer* selectedRenderer = m_RenderWindowDataModel->GetCurrentRenderer(); + const mitk::BaseRenderer* selectedRenderer = m_StorageModel->GetCurrentRenderer(); bool success = false; if ("up" == direction) { success = m_RenderWindowLayerController->MoveNodeUp(dataNode, selectedRenderer); if (success) { // node has been successfully moved up - m_Controls.renderWindowTableView->selectRow(selectedIndex.row() - 1); + QTableView* tableView = dynamic_cast(m_Controls.layerStackTableView); + if (nullptr != tableView) + { + tableView->selectRow(selectedIndex.row() - 1); + } } } else { success = m_RenderWindowLayerController->MoveNodeDown(dataNode, selectedRenderer); if (success) { // node has been successfully moved down - m_Controls.renderWindowTableView->selectRow(selectedIndex.row() + 1); + QTableView* tableView = dynamic_cast(m_Controls.layerStackTableView); + if (nullptr != tableView) + { + tableView->selectRow(selectedIndex.row() + 1); + } } } } } } void QmitkRenderWindowManipulatorWidget::ResetRenderer() { - m_RenderWindowLayerController->ResetRenderer(true, m_RenderWindowDataModel->GetCurrentRenderer()); - m_Controls.renderWindowTableView->clearSelection(); + if (nullptr == m_StorageModel) + { + return; + } + + m_RenderWindowLayerController->ResetRenderer(true, m_StorageModel->GetCurrentRenderer()); + m_Controls.layerStackTableView->clearSelection(); } void QmitkRenderWindowManipulatorWidget::ClearRenderer() { - m_RenderWindowLayerController->ResetRenderer(false, m_RenderWindowDataModel->GetCurrentRenderer()); - m_Controls.renderWindowTableView->clearSelection(); + if (nullptr == m_StorageModel) + { + return; + } + + m_RenderWindowLayerController->ResetRenderer(false, m_StorageModel->GetCurrentRenderer()); + m_Controls.layerStackTableView->clearSelection(); } void QmitkRenderWindowManipulatorWidget::ChangeViewDirection(const QString &viewDirection) { - m_RenderWindowViewDirectionController->SetViewDirectionOfRenderer(viewDirection.toStdString(), m_RenderWindowDataModel->GetCurrentRenderer()); + if (nullptr == m_StorageModel) + { + return; + + } + + m_RenderWindowViewDirectionController->SetViewDirectionOfRenderer(viewDirection.toStdString(), m_StorageModel->GetCurrentRenderer()); } diff --git a/Modules/RenderWindowManagerUI/src/QmitkRenderWindowManipulatorWidget.ui b/Modules/RenderWindowManagerUI/src/QmitkRenderWindowManipulatorWidget.ui index 01e6a1b05f..b0db32738a 100644 --- a/Modules/RenderWindowManagerUI/src/QmitkRenderWindowManipulatorWidget.ui +++ b/Modules/RenderWindowManagerUI/src/QmitkRenderWindowManipulatorWidget.ui @@ -1,120 +1,120 @@ QmitkRenderWindowManipulatorWidget 0 0 308 246 0 0 0 0 Render window manager Render window overview - + Add Layer Remove layer Set as base layer Move up Move down Reset render window Clear render window Axial true Coronal Sagittal diff --git a/Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkRenderWindowManagerView.cpp b/Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkRenderWindowManagerView.cpp index 1307b4045e..99ef6fcaf9 100644 --- a/Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkRenderWindowManagerView.cpp +++ b/Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkRenderWindowManagerView.cpp @@ -1,114 +1,156 @@ /*=================================================================== 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. ===================================================================*/ // render window manager plugin #include "QmitkRenderWindowManagerView.h" // blueberry #include #include // mitk core #include #include +// org.mitk.gui.qt.common +#include + const std::string QmitkRenderWindowManagerView::VIEW_ID = "org.mitk.views.renderwindowmanager"; void QmitkRenderWindowManagerView::SetFocus() { // nothing here } void QmitkRenderWindowManagerView::CreateQtPartControl(QWidget* parent) { + m_Parent = parent; // create GUI widgets m_Controls.setupUi(parent); // add custom render window manager UI widget to the 'renderWindowManagerTab' m_RenderWindowManipulatorWidget = new QmitkRenderWindowManipulatorWidget(GetDataStorage(), parent); m_RenderWindowManipulatorWidget->setObjectName(QStringLiteral("m_RenderWindowManipulatorWidget")); m_Controls.verticalLayout->addWidget(m_RenderWindowManipulatorWidget); SetControlledRenderer(); for (const auto& renderer : m_ControlledRenderer) { m_Controls.comboBoxRenderWindowSelection->addItem(renderer->GetName()); } + SetUpConnections(); + OnRenderWindowSelectionChanged(m_Controls.comboBoxRenderWindowSelection->itemText(0)); +} +void QmitkRenderWindowManagerView::SetUpConnections() +{ connect(m_Controls.comboBoxRenderWindowSelection, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(OnRenderWindowSelectionChanged(const QString&))); connect(m_RenderWindowManipulatorWidget, SIGNAL(AddLayerButtonClicked()), this, SLOT(OnAddLayerButtonClicked())); + + m_ModelViewSelectionConnector = std::make_unique(); + try + { + m_ModelViewSelectionConnector->SetView(m_RenderWindowManipulatorWidget->GetLayerStackTableView()); + } + catch (mitk::Exception& e) + { + mitkReThrow(e) << "Cannot connect the model-view pair signals and slots."; + } + m_SelectionServiceConnector = std::make_unique(); } void QmitkRenderWindowManagerView::SetControlledRenderer() { const mitk::RenderingManager::RenderWindowVector allRegisteredRenderWindows = mitk::RenderingManager::GetInstance()->GetAllRegisteredRenderWindows(); mitk::BaseRenderer* baseRenderer = nullptr; for (const auto &renderWindow : allRegisteredRenderWindows) { baseRenderer = mitk::BaseRenderer::GetInstance(renderWindow); if (nullptr != baseRenderer) { m_ControlledRenderer.push_back(baseRenderer); } } m_RenderWindowManipulatorWidget->SetControlledRenderer(m_ControlledRenderer); } void QmitkRenderWindowManagerView::OnRenderWindowSelectionChanged(const QString &renderWindowId) { m_RenderWindowManipulatorWidget->SetActiveRenderWindow(renderWindowId); } void QmitkRenderWindowManagerView::OnAddLayerButtonClicked() { - QList nodes = GetDataManagerSelection(); - for (mitk::DataNode* dataNode : nodes) + QmitkNodeSelectionDialog* dialog = new QmitkNodeSelectionDialog(m_Parent, "Select nodes to add to the render window", ""); + dialog->SetDataStorage(GetDataStorage()); + dialog->SetSelectOnlyVisibleNodes(true); + dialog->SetSelectionMode(QAbstractItemView::MultiSelection); + + if (QDialog::Accepted == dialog->exec()) { - if (nullptr != dataNode) + auto nodes = dialog->GetSelectedNodes(); + for (mitk::DataNode* dataNode : nodes) { - m_RenderWindowManipulatorWidget->AddLayer(dataNode); - - // get child nodes of the current node - mitk::DataStorage::SetOfObjects::ConstPointer derivedNodes = GetDataStorage()->GetDerivations(dataNode, nullptr, false); - for (mitk::DataStorage::SetOfObjects::ConstIterator it = derivedNodes->Begin(); it != derivedNodes->End(); ++it) + if (nullptr != dataNode) { - m_RenderWindowManipulatorWidget->AddLayer(it->Value()); + m_RenderWindowManipulatorWidget->AddLayer(dataNode); + + // get child nodes of the current node + mitk::DataStorage::SetOfObjects::ConstPointer derivedNodes = GetDataStorage()->GetDerivations(dataNode, nullptr, false); + for (mitk::DataStorage::SetOfObjects::ConstIterator it = derivedNodes->Begin(); it != derivedNodes->End(); ++it) + { + m_RenderWindowManipulatorWidget->AddLayer(it->Value()); + } } } } + + delete dialog; +} + +void QmitkRenderWindowManagerView::SetSelectionProvider() +{ + m_SelectionProvider = QmitkDataNodeSelectionProvider::Pointer(new QmitkDataNodeSelectionProvider); + m_SelectionProvider->SetItemSelectionModel(m_RenderWindowManipulatorWidget->GetLayerStackTableView()->selectionModel()); + GetSite()->SetSelectionProvider(berry::ISelectionProvider::Pointer(m_SelectionProvider)); + + // This function is called during the creation of the GUI. It is overridden in this class to create a custom selection provider. + // This view is used as a selection provider (not used as a selection listener) + m_SelectionServiceConnector->SetAsSelectionProvider(m_SelectionProvider.GetPointer()); + connect(m_ModelViewSelectionConnector.get(), SIGNAL(CurrentSelectionChanged(QList)), m_SelectionServiceConnector.get(), SLOT(ChangeServiceSelection(QList))); } void QmitkRenderWindowManagerView::NodeAdded(const mitk::DataNode* node) { bool global = false; node->GetBoolProperty("globalObject_RWM", global); if (global) { // initially insert new point set node into the node list of all render windows // the node object of a new point set won't be visible due to its "helper object" property set to true m_RenderWindowManipulatorWidget->AddLayerToAllRenderer(const_cast(node)); } else { // initially set new node as invisible in all render windows // this way, each single renderer overwrites the common renderer and the node is invisible // until it is inserted into the node list of a render windows m_RenderWindowManipulatorWidget->HideDataNodeInAllRenderer(node); } } diff --git a/Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkRenderWindowManagerView.h b/Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkRenderWindowManagerView.h index ba9743fb77..3d3968f752 100644 --- a/Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkRenderWindowManagerView.h +++ b/Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkRenderWindowManagerView.h @@ -1,82 +1,93 @@ /*=================================================================== 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 QMITKRENDERWINDOWMANAGERVIEW_H #define QMITKRENDERWINDOWMANAGERVIEW_H // render window manager plugin #include "ui_QmitkRenderWindowManagerControls.h" // render window manager UI module #include // blueberry #include -// qt +// mitk gui qt common plugin #include +#include "QmitkModelViewSelectionConnector.h" +#include "QmitkSelectionServiceConnector.h" /** * @brief RenderWindowManager */ class QmitkRenderWindowManagerView : public QmitkAbstractView { Q_OBJECT public: static const std::string VIEW_ID; protected: virtual void SetFocus() override; virtual void CreateQtPartControl(QWidget* parent) override; private Q_SLOTS: /** * @brief Called when the user changes the render window selection in the combo box. * * @param renderWindowId The text inside the combo box. */ void OnRenderWindowSelectionChanged(const QString &renderWindowId); /** * @brief Called when the 'AddLayer'-button of he render window manipulator widget has been pushed. */ void OnAddLayerButtonClicked(); private: + void SetUpConnections(); void SetControlledRenderer(); + /** + * @brief see QmitkAbstractView + */ + void SetSelectionProvider() override; /** * @brief Reacts to a node that has been added to the data storage. * 1. Insert new node into the node list of all render windows, if it is an "globalObject_RWM"-node. * or else * 2. Set data node invisible in all render windows, as soon as the node is added to the data storage. */ void NodeAdded(const mitk::DataNode* node) override; // the Qt parent of our GUI QWidget* m_Parent; Ui::QmitkRenderWindowManagerControls m_Controls; QmitkRenderWindowManipulatorWidget* m_RenderWindowManipulatorWidget; + std::unique_ptr m_ModelViewSelectionConnector; + std::unique_ptr m_SelectionServiceConnector; + QmitkDataNodeSelectionProvider::Pointer m_SelectionProvider; + RenderWindowLayerUtilities::RendererVector m_ControlledRenderer; }; #endif // QMITKRENDERWINDOWMANAGERVIEW_H