diff --git a/Modules/QtWidgets/include/QmitkRenderWindowDataStorageTreeModel.h b/Modules/QtWidgets/include/QmitkRenderWindowDataStorageTreeModel.h index 6fae6f6630..b29ac1e636 100644 --- a/Modules/QtWidgets/include/QmitkRenderWindowDataStorageTreeModel.h +++ b/Modules/QtWidgets/include/QmitkRenderWindowDataStorageTreeModel.h @@ -1,132 +1,131 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef QmitkRenderWindowDataStorageTreeModel_h #define QmitkRenderWindowDataStorageTreeModel_h // render window manager UI model #include "MitkQtWidgetsExports.h" // render window manager module #include "mitkRenderWindowLayerController.h" #include "mitkRenderWindowLayerUtilities.h" //mitk core #include // qt widgets module #include #include /* * @brief The 'QmitkRenderWindowDataStorageTreeModel' is a tree model derived from the 'QmitkAbstractDataStorageModel'. */ class MITKQTWIDGETS_EXPORT QmitkRenderWindowDataStorageTreeModel : public QmitkAbstractDataStorageModel { Q_OBJECT public: QmitkRenderWindowDataStorageTreeModel(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; // override from 'QAbstractItemModel' QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const override; QModelIndex parent(const QModelIndex& parent) 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; Qt::ItemFlags flags(const QModelIndex& index) const override; Qt::DropActions supportedDropActions() const override; Qt::DropActions supportedDragActions() const override; QStringList mimeTypes() const override; QMimeData* mimeData(const QModelIndexList& indexes) const override; bool dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent) override; void SetControlledRenderer(mitk::RenderWindowLayerUtilities::RendererVector controlledRenderer); void SetCurrentRenderer(mitk::BaseRenderer* baseRenderer); mitk::BaseRenderer::Pointer GetCurrentRenderer() const; private: void ResetTree(); void UpdateModelData(); /** * @brief Adjust the layer property according to the current tree. * The function will set the "layer" property of each underlying data node so that it fits the * the actual hierarchy represented by the current tree. */ void AdjustLayerProperty(); /** * @brief Fill a vector of tree items in a depth-first order (child-first). */ void TreeToVector(QmitkDataStorageTreeModelInternalItem* parent, std::vector& treeAsVector) const; /** * @brief Add the given data node to the tree of the given renderer. * The given renderer specifies the "layer"-property that is used for adding the new tree item * to the tree. The "layer"-property may be different for each renderer resulting in a * different tree for each renderer. * * @param dataNode The data node that should be added. * @param renderer The base renderer to which the data node should be added. */ void AddNodeInternal(const mitk::DataNode* dataNode, const mitk::BaseRenderer* renderer); /** * @brief Remove the tree item that contains the given data node. Removing an item may * leave the child items of the removed item without a parent. In this case * the children have to be moved inside the tree so the tree has to be rebuild * according to the current status of the data storage. * * @param dataNode The data node that should be removed. */ void RemoveNodeInternal(const mitk::DataNode* dataNode); mitk::DataNode* GetParentNode(const mitk::DataNode* node) const; QmitkDataStorageTreeModelInternalItem* GetItemByIndex(const QModelIndex& index) const; QModelIndex GetIndexByItem(QmitkDataStorageTreeModelInternalItem* item) const; std::unique_ptr m_RenderWindowLayerController; - mitk::RenderWindowLayerUtilities::RendererVector m_ControlledRenderer; QmitkDataStorageTreeModelInternalItem* m_Root; mitk::WeakPointer m_BaseRenderer; }; #endif diff --git a/Modules/QtWidgets/include/mitkRenderWindowLayerController.h b/Modules/QtWidgets/include/mitkRenderWindowLayerController.h index c90a2c9b61..7df2a26072 100644 --- a/Modules/QtWidgets/include/mitkRenderWindowLayerController.h +++ b/Modules/QtWidgets/include/mitkRenderWindowLayerController.h @@ -1,115 +1,115 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef mitkRenderWindowLayerController_h #define mitkRenderWindowLayerController_h // qt widgets module #include "MitkQtWidgetsExports.h" #include "mitkRenderWindowLayerUtilities.h" // mitk core #include #include #include namespace mitk { /** - * The RenderWindowLayerController is used to manipulate the 'layer', 'fixedLayer' and 'visible' property of a given data node. + * The RenderWindowLayerController is used to manipulate the 'layer' and 'visible' property of a given data node. * The 'layer' property is used to denote the layer level of a data node. Data from nodes on higher layer level are rendered * on top of data from nodes on lower layer level. It can be changed using the 'MoveNode*'-functions. * * To view the data of a data node only in a specific renderer, the "InsertLayerNode'-function should be used. It inserts the * given node into the specified renderer and sets the corresponding properties. * Inserting and showing a data node in a specific renderer / render window, will overwrite the properties of the common renderer view. * * For more information about the data node properties for specific renderer, see mitk::DataNode- and mitk::PropertyList-classes. * * Functions with 'mitk::BaseRenderer* renderer' have 'nullptr' as their default argument. Using the nullptr * these functions operate on the general property list. * Giving a specific base renderer will modify the property list of the given renderer. */ class MITKQTWIDGETS_EXPORT RenderWindowLayerController { public: RenderWindowLayerController(); /** * @brief Set the data storage on which to work. */ void SetDataStorage(DataStorage::Pointer dataStorage); // wrapper functions to modify the layer order / visibility of render window data /** * @brief Insert the given data node at the specified layer for the given renderer. * * @param dataNode The data node that should be inserted. * @param layer The layer value for the "layer" property of the data node (insertion level). "layer = RenderWindowLayerUtilities::TOP_LAYER_INDEX" (default) inserts the given data node at the top of the node stack (topmost layer). * @param renderer Pointer to the renderer instance for which the data node should be inserted. * If it is a nullptr (default) all controlled renderer will be affected. * - * @post After a successful call, the "fixedLayer" and "visibility" property will be true and the "layer" property will be set correctly. + * @post After a successful call, the "visibility" property will be true and the "layer" property will be set correctly. */ void InsertLayerNode(DataNode* dataNode, int layer = RenderWindowLayerUtilities::TOP_LAYER_INDEX, const BaseRenderer* renderer = nullptr); /** * @brief Move the data node to the given layer. This will change only the "layer" property. * * @param dataNode The data node that should be moved. * @param layer The layer to which the data node should be moved. * @param renderer Pointer to the renderer instance for which the data node should be moved. * If it is a nullptr (default) all controlled renderer will be affected and the * common property list will be modified. */ bool MoveNodeToPosition(DataNode* dataNode, int layer, const BaseRenderer* renderer = nullptr); /** * @brief Set the node in the given renderer as the topmost layer. This will change only the "layer" property. * * @param dataNode The data node that should be moved. * @param renderer Pointer to the renderer instance for which the data node should be moved. * If it is a nullptr (default) all controlled renderer will be affected. */ bool MoveNodeToFront(DataNode* dataNode, const BaseRenderer* renderer = nullptr); /** * @brief Set the node in the given renderer as the lowermost layer. This will change only the "layer" property. * * @param dataNode The data node that should be moved. * @param renderer Pointer to the renderer instance for which the data node should be moved. * If it is a nullptr (default) all controlled renderer will be affected. */ bool MoveNodeToBack(DataNode* dataNode, const BaseRenderer* renderer = nullptr); /** * @brief Move the node in the given renderer one layer down. This will change only the "layer" property. * * @param dataNode The data node that should be moved. * @param renderer Pointer to the renderer instance for which the data node should be moved. * If it is a nullptr (default) all controlled renderer will be affected. */ bool MoveNodeUp(DataNode* dataNode, const BaseRenderer* renderer = nullptr); /** * @brief Move the node in the given renderer one layer up. This will change only the "layer" property. * * @param dataNode The data node that should be moved. * @param renderer Pointer to the renderer instance for which the data node should be moved. * If it is a nullptr (default) all controlled renderer will be affected. */ bool MoveNodeDown(DataNode* dataNode, const BaseRenderer* renderer = nullptr); private: DataStorage::Pointer m_DataStorage; }; } // namespace mitk #endif diff --git a/Modules/QtWidgets/include/mitkRenderWindowLayerUtilities.h b/Modules/QtWidgets/include/mitkRenderWindowLayerUtilities.h index 6c81c3b451..6bd6377467 100644 --- a/Modules/QtWidgets/include/mitkRenderWindowLayerUtilities.h +++ b/Modules/QtWidgets/include/mitkRenderWindowLayerUtilities.h @@ -1,77 +1,61 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef mitkRenderWindowLayerUtilities_h #define mitkRenderWindowLayerUtilities_h // qt widgets module #include "MitkQtWidgetsExports.h" // mitk core #include #include #include #include /** * @brief Render window layer helper functions to retrieve the currently valid layer stack */ namespace mitk { namespace RenderWindowLayerUtilities { typedef std::vector RendererVector; typedef std::map> LayerStack; - /** - * The base data node of a renderer is supposed to be on layer 0 (zero), which should be the lowest layer in a render window. - */ - const int BASE_LAYER_INDEX = 0; /** * The top layer index, denoting that no valid (positive) layer index is given and therefore the index should be resolved into the topmost layer index. */ const int TOP_LAYER_INDEX = -1; /** * @brief Return the stack of layers of the given renderer as std::map, which guarantees ordering of the layers. - * Stacked layers are only included if they have their "fixedLayer" property set to true and their "layer" property set. + * Stacked layers are only included if they have their "layer" property set. * * If "renderer" = nullptr: a layer stack won't be created and an empty "LayerStack" will be returned. - * If "withBaseNode" = true: include the base node in the layer stack, if existing. - * If "withBaseNode" = false: exclude the base node from the layer stack. * * @param dataStorage Pointer to a data storage instance whose data nodes should be checked and possibly be included. * @param renderer Pointer to the renderer instance for which the layer stack should be generated. - * @param withBaseNode Boolean to decide whether the base node should be included in or excluded from the layer stack. - */ - MITKQTWIDGETS_EXPORT LayerStack GetLayerStack(const DataStorage* dataStorage, const BaseRenderer* renderer, bool withBaseNode); - /** - * @brief Helper function to get a node predicate that can be used to filter render window specific data nodes. - * The data nodes must have set a 'fixed layer' property for the given renderer. - * - * @param renderer Pointer to the renderer instance for which the 'fixed layer' should be true. - * @return The node predicate to filter 'fixed layer' data nodes. */ - MITKQTWIDGETS_EXPORT NodePredicateBase::Pointer GetRenderWindowPredicate(const BaseRenderer* renderer); + MITKQTWIDGETS_EXPORT LayerStack GetLayerStack(const DataStorage* dataStorage, const BaseRenderer* renderer); /** * @brief Set renderer-specific properties to mark a data node as 'managed by the specific renderer'. - * In order for a renderer to manage a data node, the 'fixedLayer' property has to be set for the given renderer. - * Additionally, the 'visible' and the 'layer' property are set and allow to individually render a set of nodes - * with a specific renderer. + * In order for a renderer to manage a data node, the 'visible' and the 'layer' property are set and + * allow to individually render a set of nodes with a specific renderer. * The last two mentioned properties are set so that they initially have the same value as the corresponding * global property. */ MITKQTWIDGETS_EXPORT void SetRenderWindowProperties(mitk::DataNode* dataNode, const BaseRenderer* renderer); } // namespace RenderWindowLayerUtilities } // namespace mitk #endif diff --git a/Modules/QtWidgets/src/QmitkRenderWindowDataStorageTreeModel.cpp b/Modules/QtWidgets/src/QmitkRenderWindowDataStorageTreeModel.cpp index 8592a884a5..cebc96e009 100644 --- a/Modules/QtWidgets/src/QmitkRenderWindowDataStorageTreeModel.cpp +++ b/Modules/QtWidgets/src/QmitkRenderWindowDataStorageTreeModel.cpp @@ -1,627 +1,606 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ // render window manager UI module #include "QmitkRenderWindowDataStorageTreeModel.h" #include - -// mitk core -#include - // qt widgets module #include "QmitkCustomVariants.h" #include "QmitkEnums.h" #include "QmitkMimeTypes.h" #include "QmitkNodeDescriptorManager.h" QmitkRenderWindowDataStorageTreeModel::QmitkRenderWindowDataStorageTreeModel(QObject* parent /*= nullptr*/) : QmitkAbstractDataStorageModel(parent) , m_Root(nullptr) { m_RenderWindowLayerController = std::make_unique(); ResetTree(); } void QmitkRenderWindowDataStorageTreeModel::DataStorageChanged() { m_RenderWindowLayerController->SetDataStorage(m_DataStorage.Lock()); ResetTree(); UpdateModelData(); } void QmitkRenderWindowDataStorageTreeModel::NodePredicateChanged() { ResetTree(); UpdateModelData(); } void QmitkRenderWindowDataStorageTreeModel::NodeAdded(const mitk::DataNode* node) { - for (const auto renderer : m_ControlledRenderer) - { - // add the node to each render window - mitk::RenderWindowLayerUtilities::SetRenderWindowProperties(const_cast(node), renderer); - } - auto baseRenderer = m_BaseRenderer.Lock(); if (baseRenderer.IsNull()) { return; } - mitk::NodePredicateBase::Pointer renderWindowPredicate = mitk::RenderWindowLayerUtilities::GetRenderWindowPredicate(baseRenderer); - mitk::NodePredicateAnd::Pointer combinedNodePredicate = mitk::NodePredicateAnd::New(); - combinedNodePredicate->AddPredicate(renderWindowPredicate); if (m_NodePredicate.IsNotNull()) { - combinedNodePredicate->AddPredicate(m_NodePredicate); - } - if (combinedNodePredicate->CheckNode(node)) - { - AddNodeInternal(node, baseRenderer); + if (m_NodePredicate->CheckNode(node)) + { + AddNodeInternal(node, baseRenderer); + } } } void QmitkRenderWindowDataStorageTreeModel::NodeChanged(const mitk::DataNode* node) { auto item = m_Root->Find(node); if (nullptr != item) { auto parentItem = item->GetParent(); // as the root node should not be removed one should always have a parent item if (nullptr == parentItem) { return; } auto index = createIndex(item->GetIndex(), 0, item); emit dataChanged(index, index); } } void QmitkRenderWindowDataStorageTreeModel::NodeRemoved(const mitk::DataNode* node) { RemoveNodeInternal(node); } QModelIndex QmitkRenderWindowDataStorageTreeModel::index(int row, int column, const QModelIndex& parent) const { auto item = GetItemByIndex(parent); if (nullptr != item) { item = item->GetChild(row); } if (nullptr == item) { return QModelIndex(); } return createIndex(row, column, item); } QModelIndex QmitkRenderWindowDataStorageTreeModel::parent(const QModelIndex& parent) const { auto item = GetItemByIndex(parent); if (nullptr != item) { item = item->GetParent(); } if(nullptr == item) { return QModelIndex(); } if (item == m_Root) { return QModelIndex(); } return createIndex(item->GetIndex(), 0, item); } int QmitkRenderWindowDataStorageTreeModel::rowCount(const QModelIndex& parent /*= QModelIndex()*/) const { auto item = GetItemByIndex(parent); if (nullptr == item) { return 0; } return item->GetChildCount(); } int QmitkRenderWindowDataStorageTreeModel::columnCount(const QModelIndex&/* parent = QModelIndex()*/) const { if (0 == m_Root->GetChildCount()) { // no items stored, no need to display columns return 0; } return 1; } QVariant QmitkRenderWindowDataStorageTreeModel::data(const QModelIndex& index, int role) const { auto baseRenderer = m_BaseRenderer.Lock(); if (baseRenderer.IsNull()) { return QVariant(); } if (!index.isValid() || this != index.model()) { return QVariant(); } auto item = GetItemByIndex(index); if (nullptr == item) { return QVariant(); } auto dataNode = item->GetDataNode(); if (nullptr == dataNode) { return QVariant(); } if (Qt::CheckStateRole == role) { bool visibility = false; dataNode->GetVisibility(visibility, baseRenderer); if (visibility) { return Qt::Checked; } else { return Qt::Unchecked; } } else if (Qt::DisplayRole == role) { return QVariant(QString::fromStdString(dataNode->GetName())); } else if (Qt::ToolTipRole == role) { return QVariant("Name of the data node."); } else if (Qt::DecorationRole == role) { QmitkNodeDescriptor* nodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor(dataNode); return nodeDescriptor->GetIcon(dataNode); } else if (Qt::UserRole == role || QmitkDataNodeRawPointerRole == 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); } else if (QmitkDataNodeRole == role) { return QVariant::fromValue(mitk::DataNode::Pointer(dataNode)); } return QVariant(); } bool QmitkRenderWindowDataStorageTreeModel::setData(const QModelIndex& index, const QVariant& value, int role /*= Qt::EditRole*/) { auto baseRenderer = m_BaseRenderer.Lock(); if (baseRenderer.IsNull()) { return false; } if (!index.isValid() || this != index.model()) { return false; } auto item = GetItemByIndex(index); if (nullptr == item) { return false; } auto dataNode = item->GetDataNode(); if (nullptr == dataNode) { return false; } if (Qt::EditRole == role && !value.toString().isEmpty()) { dataNode->SetName(value.toString().toStdString().c_str()); emit dataChanged(index, index); return true; } if (Qt::CheckStateRole == role) { Qt::CheckState newCheckState = static_cast(value.toInt()); bool isVisible = newCheckState; dataNode->SetVisibility(isVisible, baseRenderer); emit dataChanged(index, index); mitk::RenderingManager::GetInstance()->RequestUpdate(baseRenderer->GetRenderWindow()); return true; } return false; } Qt::ItemFlags QmitkRenderWindowDataStorageTreeModel::flags(const QModelIndex& index) const { if (this != index.model()) { return Qt::NoItemFlags; } if (!index.isValid()) { return Qt::ItemIsDropEnabled; } auto item = GetItemByIndex(index); if (nullptr == item) { return Qt::NoItemFlags; } const auto dataNode = item->GetDataNode(); if (m_NodePredicate.IsNull() || m_NodePredicate->CheckNode(dataNode)) { return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled; } return Qt::NoItemFlags; } Qt::DropActions QmitkRenderWindowDataStorageTreeModel::supportedDropActions() const { return Qt::CopyAction | Qt::MoveAction; } Qt::DropActions QmitkRenderWindowDataStorageTreeModel::supportedDragActions() const { return Qt::CopyAction | Qt::MoveAction; } QStringList QmitkRenderWindowDataStorageTreeModel::mimeTypes() const { QStringList types = QAbstractItemModel::mimeTypes(); types << QmitkMimeTypes::DataNodePtrs; return types; } QMimeData* QmitkRenderWindowDataStorageTreeModel::mimeData(const QModelIndexList& indexes) const { QMimeData* mimeData = new QMimeData(); QByteArray encodedData; QDataStream stream(&encodedData, QIODevice::WriteOnly); for (const auto& index : indexes) { if (index.isValid()) { auto dataNode = data(index, QmitkDataNodeRawPointerRole).value(); stream << reinterpret_cast(dataNode); } } mimeData->setData(QmitkMimeTypes::DataNodePtrs, encodedData); return mimeData; } bool QmitkRenderWindowDataStorageTreeModel::dropMimeData(const QMimeData* data, Qt::DropAction action, int /*row*/, int /*column*/, const QModelIndex& parent) { auto baseRenderer = m_BaseRenderer.Lock(); if (baseRenderer.IsNull()) { return false; } if (action == Qt::IgnoreAction) { return true; } if (!data->hasFormat(QmitkMimeTypes::DataNodePtrs)) { return false; } if (!parent.isValid()) { return false; } int layer = -1; auto dataNode = this->data(parent, QmitkDataNodeRawPointerRole).value(); if (nullptr != dataNode) { dataNode->GetIntProperty("layer", layer, baseRenderer); } auto dataNodeList = QmitkMimeTypes::ToDataNodePtrList(data); for (const auto& dataNode : qAsConst(dataNodeList)) { m_RenderWindowLayerController->MoveNodeToPosition(dataNode, layer, baseRenderer); } ResetTree(); UpdateModelData(); AdjustLayerProperty(); return true; } void QmitkRenderWindowDataStorageTreeModel::SetControlledRenderer(mitk::RenderWindowLayerUtilities::RendererVector controlledRenderer) { - m_ControlledRenderer = controlledRenderer; - ResetTree(); auto dataStorage = m_DataStorage.Lock(); if (dataStorage.IsNull()) { return; } for (const auto& renderer : controlledRenderer) { if (nullptr == renderer) { continue; } auto allDataNodes = dataStorage->GetAll(); for (const auto& dataNode : *allDataNodes) { // add the node to each render window mitk::RenderWindowLayerUtilities::SetRenderWindowProperties(dataNode, renderer); } } } void QmitkRenderWindowDataStorageTreeModel::SetCurrentRenderer(mitk::BaseRenderer* baseRenderer) { if (m_BaseRenderer == baseRenderer) { return; } // base renderer changed // reset tree to build a new renderer-specific item hierarchy m_BaseRenderer = baseRenderer; ResetTree(); UpdateModelData(); } mitk::BaseRenderer::Pointer QmitkRenderWindowDataStorageTreeModel::GetCurrentRenderer() const { return m_BaseRenderer.Lock(); } void QmitkRenderWindowDataStorageTreeModel::ResetTree() { beginResetModel(); if (nullptr != m_Root) { m_Root->Delete(); } mitk::DataNode::Pointer rootDataNode = mitk::DataNode::New(); rootDataNode->SetName("Data Storage"); m_Root = new QmitkDataStorageTreeModelInternalItem(rootDataNode); endResetModel(); } void QmitkRenderWindowDataStorageTreeModel::UpdateModelData() { auto dataStorage = m_DataStorage.Lock(); if (dataStorage.IsNotNull()) { auto baseRenderer = m_BaseRenderer.Lock(); if (baseRenderer.IsNotNull()) { auto allDataNodes = dataStorage->GetAll(); for (const auto& dataNode : *allDataNodes) { // add the node to each render window mitk::RenderWindowLayerUtilities::SetRenderWindowProperties(dataNode, baseRenderer); } - mitk::NodePredicateBase::Pointer renderWindowPredicate = mitk::RenderWindowLayerUtilities::GetRenderWindowPredicate(baseRenderer); - mitk::NodePredicateAnd::Pointer combinedNodePredicate = mitk::NodePredicateAnd::New(); - combinedNodePredicate->AddPredicate(renderWindowPredicate); if (m_NodePredicate.IsNotNull()) { - combinedNodePredicate->AddPredicate(m_NodePredicate); - } - - auto filteredDataNodes = dataStorage->GetSubset(combinedNodePredicate); - for (const auto& dataNode : *filteredDataNodes) - { - AddNodeInternal(dataNode, baseRenderer); + auto filteredDataNodes = dataStorage->GetSubset(m_NodePredicate); + for (const auto& dataNode : *filteredDataNodes) + { + AddNodeInternal(dataNode, baseRenderer); + } } } } } void QmitkRenderWindowDataStorageTreeModel::AdjustLayerProperty() { auto baseRenderer = m_BaseRenderer.Lock(); if (baseRenderer.IsNull()) { return; } std::vector treeAsVector; TreeToVector(m_Root, treeAsVector); int i = treeAsVector.size() - 1; for (auto it = treeAsVector.begin(); it != treeAsVector.end(); ++it) { auto dataNode = (*it)->GetDataNode(); dataNode->SetIntProperty("layer", i, baseRenderer); --i; } } void QmitkRenderWindowDataStorageTreeModel::TreeToVector(QmitkDataStorageTreeModelInternalItem* parent, std::vector& treeAsVector) const { QmitkDataStorageTreeModelInternalItem* item; for (int i = 0; i < parent->GetChildCount(); ++i) { item = parent->GetChild(i); TreeToVector(item, treeAsVector); treeAsVector.push_back(item); } } void QmitkRenderWindowDataStorageTreeModel::AddNodeInternal(const mitk::DataNode* dataNode, const mitk::BaseRenderer* renderer) { if (nullptr == dataNode || m_DataStorage.IsExpired() || nullptr != m_Root->Find(dataNode)) { return; } // find out if we have a root node auto parentItem = m_Root; QModelIndex index; auto parentDataNode = GetParentNode(dataNode); if (nullptr != parentDataNode) // no top level data node { parentItem = m_Root->Find(parentDataNode); if (nullptr == parentItem) { // parent node not contained in the tree; add it NodeAdded(parentDataNode); parentItem = m_Root->Find(parentDataNode); if (nullptr == parentItem) { // could not find and add the parent tree; abort return; } } // get the index of this parent with the help of the grand parent index = createIndex(parentItem->GetIndex(), 0, parentItem); } int firstRowWithASiblingBelow = 0; int nodeLayer = -1; dataNode->GetIntProperty("layer", nodeLayer, renderer); for (const auto& siblingItem : parentItem->GetChildren()) { int siblingLayer = -1; auto siblingNode = siblingItem->GetDataNode(); if (nullptr != siblingNode) { siblingNode->GetIntProperty("layer", siblingLayer, renderer); } if (nodeLayer > siblingLayer) { break; } ++firstRowWithASiblingBelow; } beginInsertRows(index, firstRowWithASiblingBelow, firstRowWithASiblingBelow); auto newNode = new QmitkDataStorageTreeModelInternalItem(const_cast(dataNode)); parentItem->InsertChild(newNode, firstRowWithASiblingBelow); endInsertRows(); } void QmitkRenderWindowDataStorageTreeModel::RemoveNodeInternal(const mitk::DataNode* dataNode) { if (nullptr == dataNode || nullptr == m_Root) { return; } auto item = m_Root->Find(dataNode); if (nullptr == item) { return; } auto parentItem = item->GetParent(); auto parentIndex = GetIndexByItem(parentItem); auto children = item->GetChildren(); beginRemoveRows(parentIndex, item->GetIndex(), item->GetIndex()); parentItem->RemoveChild(item); delete item; endRemoveRows(); if (!children.empty()) { // rebuild tree because children could not be at the top level ResetTree(); UpdateModelData(); } } mitk::DataNode* QmitkRenderWindowDataStorageTreeModel::GetParentNode(const mitk::DataNode* node) const { mitk::DataNode* dataNode = nullptr; auto dataStorage = m_DataStorage.Lock(); if (dataStorage.IsNull()) { return dataNode; } auto sources = dataStorage->GetSources(node); if (sources->empty()) { return dataNode; } return sources->front(); } QmitkDataStorageTreeModelInternalItem* QmitkRenderWindowDataStorageTreeModel::GetItemByIndex(const QModelIndex& index) const { if (index.isValid()) { return static_cast(index.internalPointer()); } return m_Root; } QModelIndex QmitkRenderWindowDataStorageTreeModel::GetIndexByItem(QmitkDataStorageTreeModelInternalItem* item) const { if (item == m_Root) { return QModelIndex(); } return createIndex(item->GetIndex(), 0, item); } diff --git a/Modules/QtWidgets/src/mitkRenderWindowLayerUtilities.cpp b/Modules/QtWidgets/src/mitkRenderWindowLayerUtilities.cpp index e2e8c375ba..76bd2d2b06 100644 --- a/Modules/QtWidgets/src/mitkRenderWindowLayerUtilities.cpp +++ b/Modules/QtWidgets/src/mitkRenderWindowLayerUtilities.cpp @@ -1,82 +1,69 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ // render window manager module #include "mitkRenderWindowLayerUtilities.h" // mitk core #include -mitk::RenderWindowLayerUtilities::LayerStack mitk::RenderWindowLayerUtilities::GetLayerStack(const DataStorage* dataStorage, const BaseRenderer* renderer, bool withBaseNode) +mitk::RenderWindowLayerUtilities::LayerStack mitk::RenderWindowLayerUtilities::GetLayerStack(const DataStorage* dataStorage, const BaseRenderer* renderer) { LayerStack stackedLayers; - if (nullptr == dataStorage || nullptr == renderer) + if (nullptr == dataStorage) { - // no nodes to stack or no renderer selected + // no nodes to stack return stackedLayers; } int layer = -1; - NodePredicateBase::Pointer fixedLayerPredicate = GetRenderWindowPredicate(renderer); - DataStorage::SetOfObjects::ConstPointer filteredDataNodes = dataStorage->GetSubset(fixedLayerPredicate); - for (DataStorage::SetOfObjects::ConstIterator it = filteredDataNodes->Begin(); it != filteredDataNodes->End(); ++it) + + auto allDataNodes = dataStorage->GetAll(); + for (DataStorage::SetOfObjects::ConstIterator it = allDataNodes->Begin(); it != allDataNodes->End(); ++it) { DataNode::Pointer dataNode = it->Value(); if (dataNode.IsNull()) { continue; } bool layerFound = dataNode->GetIntProperty("layer", layer, renderer); if (layerFound) { - if (BASE_LAYER_INDEX != layer|| withBaseNode) - { - // data node is not on the base layer or the base layer should be included anyway - stackedLayers.insert(std::make_pair(layer, dataNode)); - } + stackedLayers.insert(std::make_pair(layer, dataNode)); } } return stackedLayers; } -mitk::NodePredicateBase::Pointer mitk::RenderWindowLayerUtilities::GetRenderWindowPredicate(const BaseRenderer* renderer) -{ - NodePredicateBase::Pointer fixedLayerPredicate = - NodePredicateProperty::New("fixedLayer", BoolProperty::New(true), renderer); - - return fixedLayerPredicate; -} - void mitk::RenderWindowLayerUtilities::SetRenderWindowProperties(mitk::DataNode* dataNode, const BaseRenderer* renderer) { - dataNode->SetBoolProperty("fixedLayer", true, renderer); // use visibility of existing renderer or common renderer // common renderer is used if renderer-specific property does not exist bool visible = false; bool visibilityProperty = dataNode->GetVisibility(visible, renderer); if (true == visibilityProperty) { // found a visibility property dataNode->SetVisibility(visible, renderer); } // use layer of existing renderer or common renderer // common renderer is used if renderer-specific property does not exist int layer = -1; bool layerProperty = dataNode->GetIntProperty("layer", layer, renderer); if (true == layerProperty) { // found a layer property dataNode->SetIntProperty("layer", layer, renderer); } } diff --git a/Modules/QtWidgets/src/mitkRenderWindowViewDirectionController.cpp b/Modules/QtWidgets/src/mitkRenderWindowViewDirectionController.cpp index 7410b0ec9d..21a70620e6 100644 --- a/Modules/QtWidgets/src/mitkRenderWindowViewDirectionController.cpp +++ b/Modules/QtWidgets/src/mitkRenderWindowViewDirectionController.cpp @@ -1,137 +1,134 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkRenderWindowViewDirectionController.h" // mitk core #include #include #include mitk::RenderWindowViewDirectionController::RenderWindowViewDirectionController() : m_DataStorage(nullptr) { // nothing here } void mitk::RenderWindowViewDirectionController::SetDataStorage(DataStorage::Pointer dataStorage) { if (m_DataStorage != dataStorage) { // set the new data storage m_DataStorage = dataStorage; } } void mitk::RenderWindowViewDirectionController::SetControlledRenderer(RenderWindowLayerUtilities::RendererVector controlledRenderer) { if (m_ControlledRenderer != controlledRenderer) { // set the new set of controlled renderer m_ControlledRenderer = controlledRenderer; } } void mitk::RenderWindowViewDirectionController::SetViewDirectionOfRenderer(const std::string& viewDirection, BaseRenderer* renderer/* =nullptr*/) { if (nullptr == renderer) { // set visibility of data node in all controlled renderer for (auto& renderer : m_ControlledRenderer) { if (nullptr != renderer) { SetViewDirectionOfRenderer(viewDirection, renderer); } } } else { mitk::SliceNavigationController* sliceNavigationController = renderer->GetSliceNavigationController(); if ("axial" == viewDirection) { sliceNavigationController->SetDefaultViewDirection(AnatomicalPlane::Axial); } else if ("coronal" == viewDirection) { sliceNavigationController->SetDefaultViewDirection(AnatomicalPlane::Coronal); } else if ("sagittal" == viewDirection) { sliceNavigationController->SetDefaultViewDirection(AnatomicalPlane::Sagittal); } if ("3D" == viewDirection) { renderer->SetMapperID(mitk::BaseRenderer::Standard3D); } else { renderer->SetMapperID(mitk::BaseRenderer::Standard2D); } // initialize the views to the bounding geometry InitializeViewByBoundingObjects(renderer); } } void mitk::RenderWindowViewDirectionController::SetViewDirectionOfRenderer(AnatomicalPlane viewDirection , BaseRenderer* renderer/* =nullptr*/) { if (nullptr == renderer) { // set visibility of data node in all controlled renderer for (auto& renderer : m_ControlledRenderer) { if (nullptr != renderer) { SetViewDirectionOfRenderer(viewDirection, renderer); } } } else { mitk::SliceNavigationController* sliceNavigationController = renderer->GetSliceNavigationController(); sliceNavigationController->SetDefaultViewDirection(viewDirection); // initialize the views to the bounding geometry InitializeViewByBoundingObjects(renderer); } } void mitk::RenderWindowViewDirectionController::InitializeViewByBoundingObjects(const BaseRenderer* renderer) { if (nullptr == m_DataStorage || nullptr == renderer) { return; } // get all nodes that have not set "includeInBoundingBox" to false mitk::NodePredicateProperty::Pointer includeInBoundingBox = mitk::NodePredicateProperty::New("includeInBoundingBox", mitk::BoolProperty::New(false)); mitk::NodePredicateNot::Pointer notIncludeInBoundingBox = mitk::NodePredicateNot::New(includeInBoundingBox); // get all non-helper objects mitk::NodePredicateProperty::Pointer helperObject = mitk::NodePredicateProperty::New("helper object", mitk::BoolProperty::New(true)); mitk::NodePredicateNot::Pointer notAHelperObject = mitk::NodePredicateNot::New(helperObject); - // get all nodes that have a fixed layer for the given renderer - mitk::NodePredicateProperty::Pointer fixedLayer = mitk::NodePredicateProperty::New("fixedLayer", mitk::BoolProperty::New(true), renderer); - // combine node predicates - mitk::NodePredicateAnd::Pointer combinedNodePredicate = mitk::NodePredicateAnd::New(notIncludeInBoundingBox, notAHelperObject, fixedLayer); + mitk::NodePredicateAnd::Pointer combinedNodePredicate = mitk::NodePredicateAnd::New(notIncludeInBoundingBox, notAHelperObject); mitk::DataStorage::SetOfObjects::ConstPointer filteredDataNodes = m_DataStorage->GetSubset(combinedNodePredicate); // calculate bounding geometry of these nodes auto bounds = m_DataStorage->ComputeBoundingGeometry3D(filteredDataNodes, "visible", renderer); // initialize the views to the bounding geometry mitk::RenderingManager::GetInstance()->InitializeView(renderer->GetRenderWindow(), bounds); } diff --git a/Modules/RenderWindowManagerUI/src/QmitkDataStorageLayerStackModel.cpp b/Modules/RenderWindowManagerUI/src/QmitkDataStorageLayerStackModel.cpp index 59232e7a5a..441c29e276 100644 --- a/Modules/RenderWindowManagerUI/src/QmitkDataStorageLayerStackModel.cpp +++ b/Modules/RenderWindowManagerUI/src/QmitkDataStorageLayerStackModel.cpp @@ -1,234 +1,234 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #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; } auto baseRenderer = m_BaseRenderer.Lock(); if (baseRenderer.IsNotNull()) { 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); + m_TempLayerStack = RenderWindowLayerUtilities::GetLayerStack(m_DataStorage.Lock(), m_BaseRenderer.Lock()); endResetModel(); } diff --git a/Modules/RenderWindowManagerUI/src/QmitkRenderWindowDataStorageListModel.cpp b/Modules/RenderWindowManagerUI/src/QmitkRenderWindowDataStorageListModel.cpp index 812b6356e3..efba98a992 100644 --- a/Modules/RenderWindowManagerUI/src/QmitkRenderWindowDataStorageListModel.cpp +++ b/Modules/RenderWindowManagerUI/src/QmitkRenderWindowDataStorageListModel.cpp @@ -1,350 +1,350 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ // render window manager UI module #include "QmitkRenderWindowDataStorageListModel.h" // qt widgets module #include "QmitkCustomVariants.h" #include "QmitkEnums.h" #include "QmitkMimeTypes.h" #include "QmitkNodeDescriptorManager.h" QmitkRenderWindowDataStorageListModel::QmitkRenderWindowDataStorageListModel(QObject* parent /*= nullptr*/) : QmitkAbstractDataStorageModel(parent) { m_RenderWindowLayerController = std::make_unique(); } void QmitkRenderWindowDataStorageListModel::DataStorageChanged() { m_RenderWindowLayerController->SetDataStorage(m_DataStorage.Lock()); UpdateModelData(); } void QmitkRenderWindowDataStorageListModel::NodePredicateChanged() { UpdateModelData(); } void QmitkRenderWindowDataStorageListModel::NodeAdded(const mitk::DataNode* node) { // add a node to each render window specific list (or to a global list initially) AddDataNodeToAllRenderer(const_cast(node)); UpdateModelData(); } void QmitkRenderWindowDataStorageListModel::NodeChanged(const mitk::DataNode* /*node*/) { // nothing here, since the "'NodeChanged'-event is currently sent far too often } void QmitkRenderWindowDataStorageListModel::NodeRemoved(const mitk::DataNode* /*node*/) { // update model data to create a new list without the removed data node UpdateModelData(); } QModelIndex QmitkRenderWindowDataStorageListModel::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 QmitkRenderWindowDataStorageListModel::parent(const QModelIndex& /*child*/) const { return QModelIndex(); } int QmitkRenderWindowDataStorageListModel::rowCount(const QModelIndex& parent /*= QModelIndex()*/) const { if (parent.isValid()) { return 0; } return static_cast(m_LayerStack.size()); } int QmitkRenderWindowDataStorageListModel::columnCount(const QModelIndex& parent /*= QModelIndex()*/) const { if (parent.isValid()) { return 0; } return 1; } QVariant QmitkRenderWindowDataStorageListModel::data(const QModelIndex& index, int role) const { auto baseRenderer = m_BaseRenderer.Lock(); if (baseRenderer.IsNull()) { return QVariant(); } if (!index.isValid() || this != index.model()) { return QVariant(); } if (index.row() < 0 || index.row() >= static_cast(m_LayerStack.size())) { return QVariant(); } mitk::RenderWindowLayerUtilities::LayerStack::const_iterator layerStackIt = m_LayerStack.begin(); std::advance(layerStackIt, index.row()); mitk::DataNode* dataNode = layerStackIt->second; if (Qt::CheckStateRole == role) { bool visibility = false; dataNode->GetVisibility(visibility, baseRenderer); if (visibility) { return Qt::Checked; } else { return Qt::Unchecked; } } else if (Qt::DisplayRole == role) { return QVariant(QString::fromStdString(dataNode->GetName())); } else if (Qt::ToolTipRole == role) { return QVariant("Name of the data node."); } else if (Qt::DecorationRole == role) { QmitkNodeDescriptor* nodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor(dataNode); return nodeDescriptor->GetIcon(dataNode); } else if (Qt::UserRole == role || QmitkDataNodeRawPointerRole == 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); } else if (QmitkDataNodeRole == role) { return QVariant::fromValue(mitk::DataNode::Pointer(dataNode)); } return QVariant(); } bool QmitkRenderWindowDataStorageListModel::setData(const QModelIndex& index, const QVariant& value, int role /*= Qt::EditRole*/) { auto baseRenderer = m_BaseRenderer.Lock(); if (baseRenderer.IsNull()) { return false; } if (!index.isValid() || this != index.model()) { return false; } if (index.row() < 0 || index.row() >= static_cast(m_LayerStack.size())) { return false; } mitk::RenderWindowLayerUtilities::LayerStack::const_iterator layerStackIt = m_LayerStack.begin(); std::advance(layerStackIt, index.row()); mitk::DataNode* dataNode = layerStackIt->second; if (Qt::CheckStateRole == role) { Qt::CheckState newCheckState = static_cast(value.toInt()); bool isVisible = newCheckState; dataNode->SetVisibility(isVisible, baseRenderer); emit dataChanged(index, index); mitk::RenderingManager::GetInstance()->RequestUpdate(baseRenderer->GetRenderWindow()); return true; } return false; } Qt::ItemFlags QmitkRenderWindowDataStorageListModel::flags(const QModelIndex &index) const { if (this != index.model()) { return Qt::NoItemFlags; } if (!index.isValid()) { return Qt::ItemIsDropEnabled; } return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled; } Qt::DropActions QmitkRenderWindowDataStorageListModel::supportedDropActions() const { return Qt::CopyAction | Qt::MoveAction; } Qt::DropActions QmitkRenderWindowDataStorageListModel::supportedDragActions() const { return Qt::CopyAction | Qt::MoveAction; } QStringList QmitkRenderWindowDataStorageListModel::mimeTypes() const { QStringList types = QAbstractItemModel::mimeTypes(); types << QmitkMimeTypes::DataNodePtrs; return types; } QMimeData* QmitkRenderWindowDataStorageListModel::mimeData(const QModelIndexList& indexes) const { QMimeData* mimeData = new QMimeData(); QByteArray encodedData; QDataStream stream(&encodedData, QIODevice::WriteOnly); for (const auto& index : indexes) { if (index.isValid()) { auto dataNode = data(index, QmitkDataNodeRawPointerRole).value(); stream << reinterpret_cast(dataNode); } } mimeData->setData(QmitkMimeTypes::DataNodePtrs, encodedData); return mimeData; } bool QmitkRenderWindowDataStorageListModel::dropMimeData(const QMimeData* data, Qt::DropAction action, int /*row*/, int column, const QModelIndex& parent) { auto baseRenderer = m_BaseRenderer.Lock(); if (baseRenderer.IsNull()) { return false; } if (action == Qt::IgnoreAction) { return true; } if (!data->hasFormat(QmitkMimeTypes::DataNodePtrs)) { return false; } if (column > 0) { return false; } if (parent.isValid()) { int layer = -1; auto dataNode = this->data(parent, QmitkDataNodeRawPointerRole).value(); if (nullptr != dataNode) { dataNode->GetIntProperty("layer", layer, baseRenderer); } auto dataNodeList = QmitkMimeTypes::ToDataNodePtrList(data); for (const auto& dataNode : qAsConst(dataNodeList)) { m_RenderWindowLayerController->MoveNodeToPosition(dataNode, layer, baseRenderer); } UpdateModelData(); return true; } return false; } -void QmitkRenderWindowDataStorageListModel::SetControlledRenderer(mitk::RenderWindowLayerUtilities::RendererVector controlledRenderer) +void QmitkRenderWindowDataStorageListModel::SetControlledRenderer(mitk::RenderWindowLayerUtilities::RendererVector /*controlledRenderer*/) { auto dataStorage = m_DataStorage.Lock(); if (dataStorage.IsNotNull()) { mitk::DataStorage::SetOfObjects::ConstPointer allDataNodes = dataStorage->GetAll(); for (mitk::DataStorage::SetOfObjects::ConstIterator it = allDataNodes->Begin(); it != allDataNodes->End(); ++it) { mitk::DataNode::Pointer dataNode = it->Value(); if (dataNode.IsNull()) { continue; } AddDataNodeToAllRenderer(dataNode); } } } void QmitkRenderWindowDataStorageListModel::SetCurrentRenderer(mitk::BaseRenderer* baseRenderer) { if (m_BaseRenderer == baseRenderer) { return; } m_BaseRenderer = baseRenderer; if (!m_BaseRenderer.IsExpired()) { UpdateModelData(); } } mitk::BaseRenderer::Pointer QmitkRenderWindowDataStorageListModel::GetCurrentRenderer() const { return m_BaseRenderer.Lock(); } void QmitkRenderWindowDataStorageListModel::AddDataNodeToAllRenderer(mitk::DataNode* dataNode) { m_RenderWindowLayerController->InsertLayerNode(dataNode); } void QmitkRenderWindowDataStorageListModel::UpdateModelData() { auto dataStorage = m_DataStorage.Lock(); if (dataStorage.IsNotNull()) { auto baseRenderer = m_BaseRenderer.Lock(); if (baseRenderer.IsNotNull()) { // update the model, so that it will be filled with the nodes of the new data storage beginResetModel(); // get the current layer stack of the given base renderer - m_LayerStack = mitk::RenderWindowLayerUtilities::GetLayerStack(dataStorage, baseRenderer, true); + m_LayerStack = mitk::RenderWindowLayerUtilities::GetLayerStack(dataStorage, baseRenderer); endResetModel(); } } } diff --git a/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkDataSetOpenInAction.cpp b/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkDataSetOpenInAction.cpp index 3156db0e06..73ac1edd38 100644 --- a/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkDataSetOpenInAction.cpp +++ b/Plugins/org.mitk.gui.qt.semanticrelations/src/internal/QmitkDataSetOpenInAction.cpp @@ -1,160 +1,156 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ // semantic relations plugin #include "QmitkDataSetOpenInAction.h" // mitk core #include #include // render window manager module #include #include // semantic relations module #include "mitkNodePredicates.h" // mitk gui qt application plugin #include // qt #include #include namespace OpenInAction { void Run(mitk::DataStorage::Pointer dataStorage, mitk::DataNode::Pointer imageNode, mitk::BaseRenderer* renderer /*= nullptr*/) { if (dataStorage.IsNull()) { return; } if (imageNode.IsNull()) { return; } auto renderWindowLayerController = std::make_unique(); renderWindowLayerController->SetDataStorage(dataStorage); - // get currently fixed layer nodes of the specified renderer + // get current layer stack of the specified renderer // remove them from the specified renderer - auto layerStack = mitk::RenderWindowLayerUtilities::GetLayerStack(dataStorage, renderer, true); - for (auto& fixedLayer : layerStack) + auto layerStack = mitk::RenderWindowLayerUtilities::GetLayerStack(dataStorage, renderer); + for (auto& layerNode : layerStack) { // hide all nodes of the specified renderer - fixedLayer.second->SetVisibility(false, renderer); - fixedLayer.second->Modified(); + layerNode.second->SetVisibility(false, renderer); + layerNode.second->Modified(); } - // add the selected data node to the specified renderer - // only needed in case the render window manager plugin is not used - imageNode->SetBoolProperty("fixedLayer", true, renderer); - // make is visible + // make the selected data node visible imageNode->SetVisibility(true, renderer); imageNode->Modified(); // move node to front, which also request a render update renderWindowLayerController->MoveNodeToFront(imageNode, renderer); QList visibleNodes; visibleNodes.push_back(imageNode); // get all corresponding segmentations of this node mitk::DataStorage::SetOfObjects::ConstPointer segmentationNodes = dataStorage->GetDerivations(imageNode, mitk::NodePredicates::GetSegmentationPredicate(), false); for (auto it = segmentationNodes->Begin(); it != segmentationNodes->End(); ++it) { auto segmentation = it->Value(); - segmentation->SetBoolProperty("fixedLayer", true, renderer); segmentation->SetVisibility(true, renderer); // move node to front, which also request a render update renderWindowLayerController->MoveNodeToFront(segmentation, renderer); visibleNodes.push_back(segmentation); } ReinitAction::Run(berry::IWorkbenchPartSite::Pointer(), dataStorage, visibleNodes, renderer); } } QmitkDataSetOpenInAction::QmitkDataSetOpenInAction(QWidget* parent, berry::IWorkbenchPartSite::Pointer workbenchPartSite) : QmitkDataNodeOpenInAction(parent, workbenchPartSite) { setText(tr("Open in")); InitializeAction(); } QmitkDataSetOpenInAction::QmitkDataSetOpenInAction(QWidget* parent, berry::IWorkbenchPartSite* workbenchPartSite) : QmitkDataNodeOpenInAction(parent, berry::IWorkbenchPartSite::Pointer(workbenchPartSite)) { setText(tr("Open in")); InitializeAction(); } void QmitkDataSetOpenInAction::InitializeAction() { setCheckable(true); setMenu(new QMenu); connect(menu(), &QMenu::aboutToShow, this, &QmitkDataSetOpenInAction::OnMenuAboutToShow); SetControlledRenderer(); } void QmitkDataSetOpenInAction::OnMenuAboutToShow() { menu()->clear(); QAction* action; QStringList rendererNames; for (const auto& renderer : m_ControlledRenderer) { rendererNames.append(renderer->GetName()); } rendererNames.sort(); for (const auto& rendererName : rendererNames) { action = menu()->addAction(rendererName); connect(action, &QAction::triggered, this, &QmitkDataSetOpenInAction::OnActionTriggered); } } void QmitkDataSetOpenInAction::OnActionTriggered(bool /*checked*/) { auto dataStorage = m_DataStorage.Lock(); if (dataStorage.IsNull()) { return; } auto dataNode = GetSelectedNode(); if (dataNode.IsNull()) { return; } QAction* senderAction = qobject_cast(QObject::sender()); if (nullptr == senderAction) { return; } std::string selectedRenderer = senderAction->text().toStdString(); mitk::BaseRenderer* renderer = mitk::BaseRenderer::GetByName(selectedRenderer); if (nullptr == renderer) { return; } OpenInAction::Run(dataStorage, dataNode, renderer); }