diff --git a/Modules/QtWidgets/include/QmitkDataStorageSimpleTreeModel.h b/Modules/QtWidgets/include/QmitkDataStorageSimpleTreeModel.h index e2dd6b31f9..3296b98483 100644 --- a/Modules/QtWidgets/include/QmitkDataStorageSimpleTreeModel.h +++ b/Modules/QtWidgets/include/QmitkDataStorageSimpleTreeModel.h @@ -1,105 +1,105 @@ /*=================================================================== 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 QMITKDATASTORAGESIMPLETREEMODEL_H #define QMITKDATASTORAGESIMPLETREEMODEL_H #include // qt widgets module #include class QmitkDataStorageTreeModelInternalItem; /** * @brief The 'QmitkDataStorageSimpleTreeModel' is a basic tree 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 simple qt list model.* * This model can be used in conjunction with a 'QmitkDataStorageSelectionConnector'. * This model is a "light" version of the classic QmitkDataStorgageTreeModel. The differences between both are the following: * - This class currently does not support DragNDrop. -* - This class does not have the ability to change hirarchy or changes the layer property -*of nodes. This was skipped on purpose, because that is not the job of the storage model. -* - If a tree item A is removed this class does not attach children of A to the parent -*of A. Instead the complete tree representation is updated. This was changed on purpose -*because otherwise the internal representation of the model would not reflect the data storage graph anymore. +* - This class does not have the ability to change hierarchy or changes the layer property of nodes. +* This was skipped on purpose, because that is not the job of the storage model. +* - If a tree item A is removed this class does not attach children of A to the parent of A. +* Instead the complete tree representation is updated. This was changed on purpose because otherwise the internal +* representation of the model would not reflect the data storage graph anymore. */ class MITKQTWIDGETS_EXPORT QmitkDataStorageSimpleTreeModel : public QmitkAbstractDataStorageModel { Q_OBJECT public: QmitkDataStorageSimpleTreeModel(QObject *parent); virtual ~QmitkDataStorageSimpleTreeModel(); // 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 pure virtual from 'QAbstractItemModel' QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; QModelIndex parent(const QModelIndex &child) 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 = Qt::DisplayRole) const override; bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; Qt::ItemFlags flags(const QModelIndex &index) const override; protected: using TreeItem = QmitkDataStorageTreeModelInternalItem; private: void UpdateModelData(); void AddNodeInternal(const mitk::DataNode *node); mitk::DataNode *GetParentNode(const mitk::DataNode *node) const; TreeItem *TreeItemFromIndex(const QModelIndex &index) const; QModelIndex IndexFromTreeItem(TreeItem *item) const; void ResetTree(); TreeItem *m_Root; - /**helper structure to check, if a tree item is realy part of the model. + /**helper structure to check, if a tree item is really part of the model. Prefered over iterating over the tree by hand because we can use std::find.*/ std::list m_TreeItems; }; -#endif // QmitkDataStorageSimpleTreeModel_H +#endif // QMITKDATASTORAGESIMPLETREEMODEL_H diff --git a/Modules/QtWidgets/src/QmitkAbstractDataStorageInspector.cpp b/Modules/QtWidgets/src/QmitkAbstractDataStorageInspector.cpp index d42d6846f8..ecbdf25949 100644 --- a/Modules/QtWidgets/src/QmitkAbstractDataStorageInspector.cpp +++ b/Modules/QtWidgets/src/QmitkAbstractDataStorageInspector.cpp @@ -1,83 +1,83 @@ /*=================================================================== 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 QmitkAbstractDataStorageInspector::QmitkAbstractDataStorageInspector(QWidget* parent/* = nullptr*/) : QWidget(parent) , m_NodePredicate(nullptr) { m_Connector = std::make_unique(); connect(m_Connector.get(), &QmitkModelViewSelectionConnector::CurrentSelectionChanged, this, &QmitkAbstractDataStorageInspector::OnSelectionChanged); } QmitkAbstractDataStorageInspector::~QmitkAbstractDataStorageInspector() { } void QmitkAbstractDataStorageInspector::SetDataStorage(mitk::DataStorage* dataStorage) { if (m_DataStorage != dataStorage) { m_DataStorage = dataStorage; if (!m_DataStorage.IsExpired()) { this->Initialize(); } } } void QmitkAbstractDataStorageInspector::SetNodePredicate(mitk::NodePredicateBase* nodePredicate) { if (m_NodePredicate != nodePredicate) { m_NodePredicate = nodePredicate; this->Initialize(); } } mitk::NodePredicateBase* QmitkAbstractDataStorageInspector::GetNodePredicate() const { return m_NodePredicate; } QmitkAbstractDataStorageInspector::NodeList QmitkAbstractDataStorageInspector::GetSelectedNodes() const { return m_Connector->GetSelectedNodes(); -}; +} bool QmitkAbstractDataStorageInspector::GetSelectOnlyVisibleNodes() const { return m_Connector->GetSelectOnlyVisibleNodes(); -}; +} void QmitkAbstractDataStorageInspector::SetSelectOnlyVisibleNodes(bool selectOnlyVisibleNodes) { m_Connector->SetSelectOnlyVisibleNodes(selectOnlyVisibleNodes); -}; +} void QmitkAbstractDataStorageInspector::SetCurrentSelection(NodeList selectedNodes) { m_Connector->SetCurrentSelection(selectedNodes); -}; +} void QmitkAbstractDataStorageInspector::OnSelectionChanged(NodeList selectedNodes) { emit CurrentSelectionChanged(selectedNodes); -}; +} diff --git a/Modules/QtWidgets/src/QmitkDataStorageDefaultListModel.cpp b/Modules/QtWidgets/src/QmitkDataStorageDefaultListModel.cpp index 6f3a9db5ad..89ab5d902c 100644 --- a/Modules/QtWidgets/src/QmitkDataStorageDefaultListModel.cpp +++ b/Modules/QtWidgets/src/QmitkDataStorageDefaultListModel.cpp @@ -1,172 +1,173 @@ /*=================================================================== 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" #include "QmitkNodeDescriptorManager.h" -QmitkDataStorageDefaultListModel::QmitkDataStorageDefaultListModel(QObject *parent) : QmitkAbstractDataStorageModel(parent) +QmitkDataStorageDefaultListModel::QmitkDataStorageDefaultListModel(QObject *parent) + : QmitkAbstractDataStorageModel(parent) { } void QmitkDataStorageDefaultListModel::DataStorageChanged() { UpdateModelData(); } void QmitkDataStorageDefaultListModel::NodePredicateChanged() { UpdateModelData(); } void QmitkDataStorageDefaultListModel::NodeAdded(const mitk::DataNode* /*node*/) { UpdateModelData(); } void QmitkDataStorageDefaultListModel::NodeChanged(const mitk::DataNode* /*node*/) { // nothing here, since the "'NodeChanged'-event is currently sent far too often //UpdateModelData(); } void QmitkDataStorageDefaultListModel::NodeRemoved(const mitk::DataNode* /*node*/) { UpdateModelData(); } QModelIndex QmitkDataStorageDefaultListModel::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 QmitkDataStorageDefaultListModel::parent(const QModelIndex &/*child*/) const { return QModelIndex(); } int QmitkDataStorageDefaultListModel::rowCount(const QModelIndex &parent) const { if (parent.isValid()) { return 0; } return m_DataNodes.size(); } int QmitkDataStorageDefaultListModel::columnCount(const QModelIndex &parent) const { if (parent.isValid()) { return 0; } return 1; } QVariant QmitkDataStorageDefaultListModel::data(const QModelIndex &index, int role) const { if (!index.isValid() || index.model() != this) { return QVariant(); } if(index.row() < 0 || index.row() >= static_cast(m_DataNodes.size())) { return QVariant(); } mitk::DataNode::Pointer dataNode = m_DataNodes.at(index.row()); QString nodeName = QString::fromStdString(dataNode->GetName()); if (nodeName.isEmpty()) nodeName = "unnamed"; if (role == Qt::DisplayRole) return nodeName; else if (role == Qt::ToolTipRole) return nodeName; else if (role == Qt::DecorationRole) { QmitkNodeDescriptor *nodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor(dataNode); return nodeDescriptor->GetIcon(dataNode); } else if (role == QmitkDataNodeRole) { return QVariant::fromValue(mitk::DataNode::Pointer(dataNode)); } else if (role == QmitkDataNodeRawPointerRole) { return QVariant::fromValue(dataNode); } return QVariant(); } QVariant QmitkDataStorageDefaultListModel::headerData(int /*section*/, Qt::Orientation /*orientation*/, int /*role*/) const { return QVariant(tr("Nodes")); } Qt::ItemFlags QmitkDataStorageDefaultListModel::flags(const QModelIndex &index) const { if (index.isValid() && index.model() == this) { return Qt::ItemIsEnabled | Qt::ItemIsSelectable; } return Qt::NoItemFlags; } void QmitkDataStorageDefaultListModel::UpdateModelData() { mitk::DataStorage::SetOfObjects::ConstPointer dataNodes; if (!m_DataStorage.IsExpired()) { auto dataStorage = m_DataStorage.Lock(); if (m_NodePredicate.IsNotNull()) { dataNodes = dataStorage->GetSubset(m_NodePredicate); } else { dataNodes = dataStorage->GetAll(); } } // update the model, so that it will be filled with the nodes of the new data storage beginResetModel(); m_DataNodes.clear(); // add all (filtered) nodes to the vector of nodes if (dataNodes != nullptr) { for (auto& node : *dataNodes) { m_DataNodes.push_back(node); } } endResetModel(); } diff --git a/Modules/QtWidgets/src/QmitkDataStorageListInspector.cpp b/Modules/QtWidgets/src/QmitkDataStorageListInspector.cpp index a5d3182d1f..37e57944f5 100644 --- a/Modules/QtWidgets/src/QmitkDataStorageListInspector.cpp +++ b/Modules/QtWidgets/src/QmitkDataStorageListInspector.cpp @@ -1,61 +1,61 @@ /*=================================================================== 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 #include QmitkDataStorageListInspector::QmitkDataStorageListInspector(QWidget* parent/* = nullptr*/) : QmitkAbstractDataStorageInspector(parent) { m_Controls.setupUi(this); m_Controls.view->setSelectionMode(QAbstractItemView::ExtendedSelection); m_Controls.view->setSelectionBehavior(QAbstractItemView::SelectRows); m_Controls.view->setAlternatingRowColors(true); m_StorageModel = new QmitkDataStorageDefaultListModel(this); m_Controls.view->setModel(m_StorageModel); } QAbstractItemView* QmitkDataStorageListInspector::GetView() { return m_Controls.view; -}; +} const QAbstractItemView* QmitkDataStorageListInspector::GetView() const { return m_Controls.view; -}; +} void QmitkDataStorageListInspector::Initialize() { m_StorageModel->SetDataStorage(m_DataStorage.Lock()); m_StorageModel->SetNodePredicate(m_NodePredicate); m_Connector->SetView(m_Controls.view); } void QmitkDataStorageListInspector::SetSelectionMode(SelectionMode mode) { m_Controls.view->setSelectionMode(mode); } QmitkDataStorageListInspector::SelectionMode QmitkDataStorageListInspector::GetSelectionMode() const { return m_Controls.view->selectionMode(); -}; +} diff --git a/Modules/QtWidgets/src/QmitkDataStorageListModel.cpp b/Modules/QtWidgets/src/QmitkDataStorageListModel.cpp index 93aeeaa827..9cd825427d 100755 --- a/Modules/QtWidgets/src/QmitkDataStorageListModel.cpp +++ b/Modules/QtWidgets/src/QmitkDataStorageListModel.cpp @@ -1,333 +1,336 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "QmitkDataStorageListModel.h" //# Own includes // mitk #include "mitkStringProperty.h" //# Toolkit includes // itk #include "itkCommand.h" QmitkDataStorageListModel::QmitkDataStorageListModel(mitk::DataStorage *dataStorage, mitk::NodePredicateBase::Pointer pred, QObject *parent) - : QAbstractListModel(parent), m_NodePredicate(nullptr), m_DataStorage(nullptr), m_BlockEvents(false) + : QAbstractListModel(parent) + , m_NodePredicate(nullptr) + , m_DataStorage(nullptr) + , m_BlockEvents(false) { this->SetPredicate(pred); this->SetDataStorage(dataStorage); } QmitkDataStorageListModel::~QmitkDataStorageListModel() { // set data storage to nullptr so that the event listener gets removed this->SetDataStorage(nullptr); } void QmitkDataStorageListModel::SetDataStorage(mitk::DataStorage::Pointer dataStorage) { if (m_DataStorage == dataStorage) { return; } // remove old listeners if (m_DataStorage != nullptr) { m_DataStorage->AddNodeEvent.RemoveListener( mitk::MessageDelegate1( this, &QmitkDataStorageListModel::OnDataStorageNodeAdded)); m_DataStorage->RemoveNodeEvent.RemoveListener( mitk::MessageDelegate1( this, &QmitkDataStorageListModel::OnDataStorageNodeRemoved)); m_DataStorage->RemoveObserver(m_DataStorageDeleteObserverTag); m_DataStorageDeleteObserverTag = 0; } m_DataStorage = dataStorage; if (m_DataStorage != nullptr) { // subscribe for node added/removed events m_DataStorage->AddNodeEvent.AddListener(mitk::MessageDelegate1( this, &QmitkDataStorageListModel::OnDataStorageNodeAdded)); m_DataStorage->RemoveNodeEvent.AddListener( mitk::MessageDelegate1( this, &QmitkDataStorageListModel::OnDataStorageNodeRemoved)); // add ITK delete listener on data storage itk::MemberCommand::Pointer deleteCommand = itk::MemberCommand::New(); deleteCommand->SetCallbackFunction(this, &QmitkDataStorageListModel::OnDataStorageDeleted); m_DataStorageDeleteObserverTag = m_DataStorage->AddObserver(itk::DeleteEvent(), deleteCommand); } // reset/rebuild model reset(); } Qt::ItemFlags QmitkDataStorageListModel::flags(const QModelIndex &) const { return Qt::ItemIsEnabled | Qt::ItemIsSelectable; } QVariant QmitkDataStorageListModel::data(const QModelIndex &index, int role) const { if (role == Qt::DisplayRole && index.isValid()) { const mitk::DataNode *node = std::get(m_NodesAndObserverTags.at(index.row())); return QVariant(QString::fromStdString(node->GetName())); } else { return QVariant(); } } QVariant QmitkDataStorageListModel::headerData(int /*section*/, Qt::Orientation /*orientation*/, int /*role*/) const { return QVariant(tr("Nodes")); } int QmitkDataStorageListModel::rowCount(const QModelIndex & /*parent*/) const { return m_NodesAndObserverTags.size(); } std::vector QmitkDataStorageListModel::GetDataNodes() const { auto size = m_NodesAndObserverTags.size(); std::vector result(size); for (std::size_t i = 0; i < size; ++i) { result[i] = std::get(m_NodesAndObserverTags[i]); } return result; } mitk::DataStorage *QmitkDataStorageListModel::GetDataStorage() const { return m_DataStorage; } void QmitkDataStorageListModel::SetPredicate(mitk::NodePredicateBase *pred) { m_NodePredicate = pred; // in a prior implementation the call to beginResetModel() been after reset(). // Should this actually be the better order of calls, please document! QAbstractListModel::beginResetModel(); reset(); QAbstractListModel::endResetModel(); } mitk::NodePredicateBase *QmitkDataStorageListModel::GetPredicate() const { return m_NodePredicate; } void QmitkDataStorageListModel::reset() { mitk::DataStorage::SetOfObjects::ConstPointer modelNodes; if (m_DataStorage != nullptr) { if (m_NodePredicate != nullptr) { modelNodes = m_DataStorage->GetSubset(m_NodePredicate); } else { modelNodes = m_DataStorage->GetAll(); } } ClearInternalNodeList(); // add all filtered nodes to our list if (modelNodes != nullptr) { for (auto &node : *modelNodes) { AddNodeToInternalList(node); } } } void QmitkDataStorageListModel::AddNodeToInternalList(mitk::DataNode *node) { if (m_DataStorage != nullptr) { itk::MemberCommand::Pointer nodeModifiedCommand; // add modified observer nodeModifiedCommand = itk::MemberCommand::New(); nodeModifiedCommand->SetCallbackFunction(this, &QmitkDataStorageListModel::OnDataNodeModified); unsigned long nodeObserverTag = node->AddObserver(itk::ModifiedEvent(), nodeModifiedCommand); itk::MemberCommand::Pointer dataModifiedCommand; unsigned long dataObserverTag = 0; // add modified observer if (node->GetData() != nullptr) { dataModifiedCommand = itk::MemberCommand::New(); dataModifiedCommand->SetCallbackFunction(this, &QmitkDataStorageListModel::OnDataModified); dataObserverTag = node->GetData()->AddObserver(itk::ModifiedEvent(), dataModifiedCommand); } m_NodesAndObserverTags.push_back(std::make_tuple(node, nodeObserverTag, dataObserverTag)); } } void QmitkDataStorageListModel::ClearInternalNodeList() { for (auto &iter : m_NodesAndObserverTags) { auto node = std::get(iter); if (node != nullptr) { node->RemoveObserver(std::get(iter)); if (node->GetData() != nullptr) { node->GetData()->RemoveObserver(std::get(iter)); } } } m_NodesAndObserverTags.clear(); } void QmitkDataStorageListModel::RemoveNodeFromInternalList(mitk::DataNode *node) { for (auto iter = m_NodesAndObserverTags.begin(); iter != m_NodesAndObserverTags.end(); ++iter) { if (std::get(*iter) == node) { node->RemoveObserver(std::get(*iter)); if (node->GetData() != nullptr) { node->GetData()->RemoveObserver(std::get(*iter)); } m_NodesAndObserverTags.erase(iter); // invalidate iter break; } } } void QmitkDataStorageListModel::OnDataStorageNodeAdded(const mitk::DataNode *node) { // guarantee no recursions when a new node event is thrown if (!m_BlockEvents) { m_BlockEvents = true; // check if node should be added to the model bool addNode = true; if (m_NodePredicate && !m_NodePredicate->CheckNode(node)) addNode = false; if (addNode) { int newIndex = m_NodesAndObserverTags.size(); beginInsertRows(QModelIndex(), newIndex, newIndex); AddNodeToInternalList(const_cast(node)); endInsertRows(); } m_BlockEvents = false; } } void QmitkDataStorageListModel::OnDataStorageNodeRemoved(const mitk::DataNode *node) { // guarantee no recursions when a new node event is thrown if (!m_BlockEvents) { m_BlockEvents = true; int row = 0; for (auto iter = m_NodesAndObserverTags.begin(); iter != m_NodesAndObserverTags.end(); ++iter, ++row) { if (std::get(*iter) == node) { // node found, remove it beginRemoveRows(QModelIndex(), row, row); RemoveNodeFromInternalList(std::get(*iter)); endRemoveRows(); break; } } } m_BlockEvents = false; } void QmitkDataStorageListModel::OnDataNodeModified(const itk::Object *caller, const itk::EventObject & /*event*/) { if (m_BlockEvents) return; const mitk::DataNode *modifiedNode = dynamic_cast(caller); if (modifiedNode) { QModelIndex changedIndex = getIndex(modifiedNode); if (changedIndex.isValid()) { emit dataChanged(changedIndex, changedIndex); } } } void QmitkDataStorageListModel::OnDataModified(const itk::Object *caller, const itk::EventObject &event) { OnDataNodeModified(caller, event); // until different implementation } void QmitkDataStorageListModel::OnDataStorageDeleted(const itk::Object *, const itk::EventObject &) { if (m_BlockEvents) return; this->SetDataStorage(nullptr); } mitk::DataNode::Pointer QmitkDataStorageListModel::getNode(const QModelIndex &index) const { if (index.isValid()) { return std::get(m_NodesAndObserverTags.at(index.row())); } else { return nullptr; } } QModelIndex QmitkDataStorageListModel::getIndex(const mitk::DataNode *node) const { int row = 0; for (auto iter = m_NodesAndObserverTags.begin(); iter != m_NodesAndObserverTags.end(); ++iter, ++row) { if (std::get(*iter) == node) { return index(row); } } return QModelIndex(); } diff --git a/Modules/QtWidgets/src/QmitkDataStorageSimpleTreeModel.cpp b/Modules/QtWidgets/src/QmitkDataStorageSimpleTreeModel.cpp index 0189f5df4d..8036c18934 100644 --- a/Modules/QtWidgets/src/QmitkDataStorageSimpleTreeModel.cpp +++ b/Modules/QtWidgets/src/QmitkDataStorageSimpleTreeModel.cpp @@ -1,370 +1,371 @@ /*=================================================================== 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 #include #include // qt widgets module #include "QmitkCustomVariants.h" #include "QmitkEnums.h" QmitkDataStorageSimpleTreeModel::QmitkDataStorageSimpleTreeModel(QObject *parent) - : QmitkAbstractDataStorageModel(parent), m_Root(nullptr) + : QmitkAbstractDataStorageModel(parent) + , m_Root(nullptr) { ResetTree(); } QmitkDataStorageSimpleTreeModel::~QmitkDataStorageSimpleTreeModel() { m_Root->Delete(); m_Root = nullptr; -}; +} void QmitkDataStorageSimpleTreeModel::ResetTree() { mitk::DataNode::Pointer rootDataNode = mitk::DataNode::New(); rootDataNode->SetName("Data Storage"); m_Root = new TreeItem(rootDataNode, 0); } void QmitkDataStorageSimpleTreeModel::DataStorageChanged() { if (m_Root) { m_Root->Delete(); } ResetTree(); UpdateModelData(); } void QmitkDataStorageSimpleTreeModel::NodePredicateChanged() { ResetTree(); UpdateModelData(); } void QmitkDataStorageSimpleTreeModel::NodeAdded(const mitk::DataNode *node) { if (node == nullptr || m_DataStorage.IsExpired() || !m_DataStorage.Lock()->Exists(node) || m_Root->Find(node) != nullptr) return; this->AddNodeInternal(node); } void QmitkDataStorageSimpleTreeModel::NodeChanged(const mitk::DataNode *node) { TreeItem *treeItem = m_Root->Find(node); if (treeItem) { TreeItem *parentTreeItem = treeItem->GetParent(); // as the root node should not be removed one should always have a parent item if (!parentTreeItem) return; QModelIndex index = this->createIndex(treeItem->GetIndex(), 0, treeItem); // now emit the dataChanged signal emit dataChanged(index, index); } } void QmitkDataStorageSimpleTreeModel::NodeRemoved(const mitk::DataNode *node) { if (node == nullptr || !m_Root) return; TreeItem *treeItem = m_Root->Find(node); if (!treeItem) return; // return because there is no treeitem containing this node TreeItem *parentTreeItem = treeItem->GetParent(); QModelIndex parentIndex = this->IndexFromTreeItem(parentTreeItem); // emit beginRemoveRows event (QModelIndex is empty because we dont have a tree model) this->beginRemoveRows(parentIndex, treeItem->GetIndex(), treeItem->GetIndex()); // remove node std::vector children = treeItem->GetChildren(); m_TreeItems.remove(treeItem); delete treeItem; //delete in tree if (!children.empty()) { //if not empty we have to rebuild the whole representation, //because the children could be now top level, or at another //source/parent. this->UpdateModelData(); } } QModelIndex QmitkDataStorageSimpleTreeModel::index(int row, int column, const QModelIndex &parent) const { TreeItem *parentItem; if (!parent.isValid() || parent.model() != this) parentItem = m_Root; else parentItem = static_cast(parent.internalPointer()); if (parentItem) { TreeItem *childItem = parentItem->GetChild(row); if (childItem) return createIndex(row, column, childItem); } return QModelIndex(); } QModelIndex QmitkDataStorageSimpleTreeModel::parent(const QModelIndex &child) const { if (!child.isValid() || !m_Root || child.model() != this) return QModelIndex(); TreeItem *childItem = this->TreeItemFromIndex(child); if (!childItem) return QModelIndex(); TreeItem *parentItem = childItem->GetParent(); if (parentItem == m_Root) return QModelIndex(); return this->createIndex(parentItem->GetIndex(), 0, parentItem); } QmitkDataStorageSimpleTreeModel::TreeItem *QmitkDataStorageSimpleTreeModel::TreeItemFromIndex( const QModelIndex &index) const { if (index.isValid() && index.model() == this) { auto item = static_cast(index.internalPointer()); auto finding = std::find(std::begin(m_TreeItems), std::end(m_TreeItems), item); if (finding == std::end(m_TreeItems)) { return nullptr; } return item; } else return m_Root; } int QmitkDataStorageSimpleTreeModel::rowCount(const QModelIndex &parent) const { TreeItem *parentTreeItem = this->TreeItemFromIndex(parent); if (parentTreeItem) return parentTreeItem->GetChildCount(); else return 0; } int QmitkDataStorageSimpleTreeModel::columnCount(const QModelIndex &/*parent*/) const { return 1; } QVariant QmitkDataStorageSimpleTreeModel::data(const QModelIndex &index, int role) const { if (!index.isValid() || index.model() != this) { return QVariant(); } auto treeItem = this->TreeItemFromIndex(index); if (!treeItem) return QVariant(); mitk::DataNode *dataNode = treeItem->GetDataNode(); QString nodeName = QString::fromStdString(dataNode->GetName()); if (nodeName.isEmpty()) { nodeName = "unnamed"; } if (role == Qt::DisplayRole) return nodeName; else if (role == Qt::ToolTipRole) return nodeName; else if (role == Qt::DecorationRole) { QmitkNodeDescriptor *nodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor(dataNode); return nodeDescriptor->GetIcon(dataNode); } else if (role == QmitkDataNodeRole) { return QVariant::fromValue(mitk::DataNode::Pointer(dataNode)); } else if (role == QmitkDataNodeRawPointerRole) { return QVariant::fromValue(dataNode); } return QVariant(); } bool QmitkDataStorageSimpleTreeModel::setData(const QModelIndex &index, const QVariant &value, int role) { if (!index.isValid() || index.model() != this) return false; auto treeItem = this->TreeItemFromIndex(index); if (!treeItem) return false; mitk::DataNode *dataNode = treeItem->GetDataNode(); if (!dataNode) return false; if (role == Qt::EditRole && !value.toString().isEmpty()) { dataNode->SetName(value.toString().toStdString().c_str()); } else if (role == Qt::CheckStateRole) { // Please note: value.toInt() returns 2, independentely from the actual checkstate of the index element. // Therefore the checkstate is being estimated again here. QVariant qcheckstate = index.data(Qt::CheckStateRole); int checkstate = qcheckstate.toInt(); bool isVisible = bool(checkstate); dataNode->SetVisibility(!isVisible); } // inform listeners about changes emit dataChanged(index, index); return true; } QVariant QmitkDataStorageSimpleTreeModel::headerData(int /*section*/, Qt::Orientation orientation, int role) const { if (orientation == Qt::Horizontal && role == Qt::DisplayRole && m_Root) return QString::fromStdString(m_Root->GetDataNode()->GetName()); return QVariant(); } Qt::ItemFlags QmitkDataStorageSimpleTreeModel::flags(const QModelIndex &index) const { if (index.isValid() && index.model() == this) { auto treeItem = this->TreeItemFromIndex(index); if (!treeItem) return Qt::NoItemFlags; const auto dataNode = treeItem->GetDataNode(); if (m_NodePredicate.IsNull() || m_NodePredicate->CheckNode(dataNode)) { return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable; } else { return Qt::NoItemFlags; } } return Qt::NoItemFlags; } mitk::DataNode *QmitkDataStorageSimpleTreeModel::GetParentNode(const mitk::DataNode *node) const { mitk::DataNode *dataNode = nullptr; mitk::DataStorage::SetOfObjects::ConstPointer _Sources = m_DataStorage.Lock()->GetSources(node); if (_Sources->Size() > 0) dataNode = _Sources->front(); return dataNode; } void QmitkDataStorageSimpleTreeModel::AddNodeInternal(const mitk::DataNode *node) { if (node == nullptr || m_DataStorage.IsExpired() || !m_DataStorage.Lock()->Exists(node) || m_Root->Find(node) != 0) return; // find out if we have a root node TreeItem *parentTreeItem = m_Root; QModelIndex index; mitk::DataNode *parentDataNode = this->GetParentNode(node); if (parentDataNode) // no top level data node { parentTreeItem = m_Root->Find(parentDataNode); // find the corresponding tree item if (!parentTreeItem) { this->NodeAdded(parentDataNode); parentTreeItem = m_Root->Find(parentDataNode); if (!parentTreeItem) return; } // get the index of this parent with the help of the grand parent index = this->createIndex(parentTreeItem->GetIndex(), 0, parentTreeItem); } int firstRowWithASiblingBelow = 0; int nodeLayer = -1; node->GetIntProperty("layer", nodeLayer); for (TreeItem *siblingTreeItem : parentTreeItem->GetChildren()) { int siblingLayer = -1; if (mitk::DataNode *siblingNode = siblingTreeItem->GetDataNode()) { siblingNode->GetIntProperty("layer", siblingLayer); } if (nodeLayer > siblingLayer) { break; } ++firstRowWithASiblingBelow; } beginInsertRows(index, firstRowWithASiblingBelow, firstRowWithASiblingBelow); auto newNode = new TreeItem(const_cast(node)); parentTreeItem->InsertChild(newNode, firstRowWithASiblingBelow); m_TreeItems.push_back(newNode); endInsertRows(); } QModelIndex QmitkDataStorageSimpleTreeModel::IndexFromTreeItem(TreeItem *item) const { if (item == m_Root) return QModelIndex(); else return this->createIndex(item->GetIndex(), 0, item); } void QmitkDataStorageSimpleTreeModel::UpdateModelData() { if (!m_DataStorage.IsExpired()) { auto nodeset = m_DataStorage.Lock()->GetAll(); if (m_NodePredicate != nullptr) { nodeset = m_DataStorage.Lock()->GetSubset(m_NodePredicate); } for (const auto& node : *nodeset) { this->AddNodeInternal(node); } } } diff --git a/Modules/QtWidgets/src/QmitkDataStorageTreeInspector.cpp b/Modules/QtWidgets/src/QmitkDataStorageTreeInspector.cpp index c8bb5c952b..4d6c466bcb 100644 --- a/Modules/QtWidgets/src/QmitkDataStorageTreeInspector.cpp +++ b/Modules/QtWidgets/src/QmitkDataStorageTreeInspector.cpp @@ -1,65 +1,65 @@ /*=================================================================== 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 #include QmitkDataStorageTreeInspector::QmitkDataStorageTreeInspector(QWidget* parent/* = nullptr*/) : QmitkAbstractDataStorageInspector(parent) { m_Controls.setupUi(this); m_Controls.view->setSelectionMode(QAbstractItemView::ExtendedSelection); m_Controls.view->setSelectionBehavior(QAbstractItemView::SelectRows); m_Controls.view->setAlternatingRowColors(true); m_Controls.view->setHeaderHidden(true); m_Controls.view->setTextElideMode(Qt::ElideMiddle); m_StorageModel = new QmitkDataStorageSimpleTreeModel(this); m_Controls.view->setModel(m_StorageModel); } QAbstractItemView* QmitkDataStorageTreeInspector::GetView() { return m_Controls.view; -}; +} const QAbstractItemView* QmitkDataStorageTreeInspector::GetView() const { return m_Controls.view; -}; +} void QmitkDataStorageTreeInspector::Initialize() { m_StorageModel->SetDataStorage(m_DataStorage.Lock()); m_StorageModel->SetNodePredicate(m_NodePredicate); m_Connector->SetView(m_Controls.view); m_Controls.view->expandAll(); } void QmitkDataStorageTreeInspector::SetSelectionMode(SelectionMode mode) { m_Controls.view->setSelectionMode(mode); } QmitkDataStorageTreeInspector::SelectionMode QmitkDataStorageTreeInspector::GetSelectionMode() const { return m_Controls.view->selectionMode(); -}; +} diff --git a/Plugins/org.mitk.gui.qt.common/src/QmitkAbstractNodeSelectionWidget.cpp b/Plugins/org.mitk.gui.qt.common/src/QmitkAbstractNodeSelectionWidget.cpp index c97a3f6016..604808efd9 100644 --- a/Plugins/org.mitk.gui.qt.common/src/QmitkAbstractNodeSelectionWidget.cpp +++ b/Plugins/org.mitk.gui.qt.common/src/QmitkAbstractNodeSelectionWidget.cpp @@ -1,113 +1,116 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ - #include "QmitkAbstractNodeSelectionWidget.h" -QmitkAbstractNodeSelectionWidget::QmitkAbstractNodeSelectionWidget(QWidget* parent) : QWidget(parent), m_InvalidInfo("Error. Select data."), -m_EmptyInfo("Empty. Make a selection."), m_PopUpTitel("Select a data node"), m_PopUpHint(""), -m_IsOptional(false), m_SelectOnlyVisibleNodes(true) +QmitkAbstractNodeSelectionWidget::QmitkAbstractNodeSelectionWidget(QWidget* parent) + : QWidget(parent) + , m_InvalidInfo("Error. Select data.") + , m_EmptyInfo("Empty. Make a selection.") + , m_PopUpTitel("Select a data node") + , m_PopUpHint("") + , m_IsOptional(false) + , m_SelectOnlyVisibleNodes(true) { } void QmitkAbstractNodeSelectionWidget::SetDataStorage(mitk::DataStorage* dataStorage) { if (m_DataStorage != dataStorage) { m_DataStorage = dataStorage; this->OnDataStorageChanged(); this->UpdateInfo(); } -}; +} void QmitkAbstractNodeSelectionWidget::SetNodePredicate(mitk::NodePredicateBase* nodePredicate) { if (m_NodePredicate != nodePredicate) { m_NodePredicate = nodePredicate; - - this->OnNodePredicateChanged(nodePredicate); + this->OnNodePredicateChanged(); this->UpdateInfo(); } -}; +} mitk::NodePredicateBase* QmitkAbstractNodeSelectionWidget::GetNodePredicate() const { return m_NodePredicate; } QString QmitkAbstractNodeSelectionWidget::GetInvalidInfo() const { return m_InvalidInfo; -}; +} QString QmitkAbstractNodeSelectionWidget::GetEmptyInfo() const { return m_EmptyInfo; -}; +} QString QmitkAbstractNodeSelectionWidget::GetPopUpTitel() const { return m_PopUpTitel; -}; +} QString QmitkAbstractNodeSelectionWidget::GetPopUpHint() const { return m_PopUpHint; -}; +} bool QmitkAbstractNodeSelectionWidget::GetSelectionIsOptional() const { return m_IsOptional; -}; +} bool QmitkAbstractNodeSelectionWidget::GetSelectOnlyVisibleNodes() const { return m_SelectOnlyVisibleNodes; -}; +} void QmitkAbstractNodeSelectionWidget::SetSelectOnlyVisibleNodes(bool selectOnlyVisibleNodes) { m_SelectOnlyVisibleNodes = selectOnlyVisibleNodes; -}; +} void QmitkAbstractNodeSelectionWidget::SetInvalidInfo(QString info) { m_InvalidInfo = QString("")+info+QString(""); this->UpdateInfo(); -}; +} void QmitkAbstractNodeSelectionWidget::SetEmptyInfo(QString info) { m_EmptyInfo = QString("")+info+QString(""); this->UpdateInfo(); -}; +} void QmitkAbstractNodeSelectionWidget::SetPopUpTitel(QString info) { m_PopUpTitel = info; -}; +} void QmitkAbstractNodeSelectionWidget::SetPopUpHint(QString info) { m_PopUpHint = info; -}; +} void QmitkAbstractNodeSelectionWidget::SetSelectionIsOptional(bool isOptional) { m_IsOptional = isOptional; this->UpdateInfo(); -}; +} diff --git a/Plugins/org.mitk.gui.qt.common/src/QmitkAbstractNodeSelectionWidget.h b/Plugins/org.mitk.gui.qt.common/src/QmitkAbstractNodeSelectionWidget.h index 4ec7267eb2..38423870b7 100644 --- a/Plugins/org.mitk.gui.qt.common/src/QmitkAbstractNodeSelectionWidget.h +++ b/Plugins/org.mitk.gui.qt.common/src/QmitkAbstractNodeSelectionWidget.h @@ -1,151 +1,148 @@ /*=================================================================== 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 QMITK_ABSTRACT_NODE_SELECTION_WIDGET_H #define QMITK_ABSTRACT_NODE_SELECTION_WIDGET_H +#include "org_mitk_gui_qt_common_Export.h" + +// mitk core #include #include #include -#include "org_mitk_gui_qt_common_Export.h" - +// qt #include class QmitkAbstractDataStorageModel; class QAbstractItemVew; /** * \class QmitkAbstractNodeSelectionWidget * \brief Abstract base class for the selection of data from a data storage. */ class MITK_QT_COMMON QmitkAbstractNodeSelectionWidget : public QWidget { Q_OBJECT public: explicit QmitkAbstractNodeSelectionWidget(QWidget* parent = nullptr); /** - * @brief Sets the data storage that will be used /monitored by widget. + * @brief Sets the data storage that will be used / monitored by widget. * * @par dataStorage A pointer to the data storage to set. */ void SetDataStorage(mitk::DataStorage* dataStorage); /** * Sets the node predicate and updates the widget, according to the node predicate. * Implement OnNodePredicateChange() for custom actualization of a derived widget class. * * @par nodePredicate A pointer to node predicate. */ void SetNodePredicate(mitk::NodePredicateBase* nodePredicate); mitk::NodePredicateBase* GetNodePredicate() const; QString GetInvalidInfo() const; QString GetEmptyInfo() const; QString GetPopUpTitel() const; QString GetPopUpHint() const; bool GetSelectionIsOptional() const; bool GetSelectOnlyVisibleNodes() const; using NodeList = QList; Q_SIGNALS: - /* + /** * @brief A signal that will be emitted if the selected node has changed. * * @par nodes A list of data nodes that are newly selected. */ - void CurrentSelectionChanged(QList nodes); + void CurrentSelectionChanged(NodeList nodes); public Q_SLOTS: - /* - * @brief Change the selection modus of the item view's selection model. - * - * If true, an incoming selection will be filtered (reduced) to only those nodes that are visible by the current view. - * An outgoing selection can then at most contain the filtered nodes. - * If false, the incoming non-visible selection will be stored and later added to the outgoing selection, - * to include the original selection that could not be modified. - * The part of the original selection, that is non-visible are the nodes that are not + /** + * @brief Set the selection modus to (not) include invisible nodes in the selection. + * In order to customize a widget's behavior this virtual function can be overridden. + * After a widget has set its selection modus the CurrentSelectionChanged(NodeList nodes)-signal should be emitted. * * @par selectOnlyVisibleNodes The bool value to define the selection modus. */ virtual void SetSelectOnlyVisibleNodes(bool selectOnlyVisibleNodes); - /* - * @brief Transform a list of data nodes into a model selection and set this as a new selection of the - * selection model of the private member item view. - * - * The function filters the given list of nodes according to the 'm_SelectOnlyVisibleNodes' member variable. If - * necessary, the non-visible nodes are stored. This is done if 'm_SelectOnlyVisibleNodes' is false: In this case - * the selection may be filtered and only a subset of the selected nodes may be visible and therefore (de-)selectable - * in the data storage viewer. By storing the non-visible nodes it is possible to send the new, modified selection - * but also include the selected nodes from the original selection that could not be modified (see 'SetSelectOnlyVisibleNodes'). + /** + * @brief Transform a given list of data nodes (a selection) into a new selection of a concrete node selection widget. + * In order to customize a widget's behavior this function needs to be overridden. + * After a widget has set its current selection the CurrentSelectionChanged(NodeList nodes)-signal should be emitted. * * @par nodes A list of data nodes that should be newly selected. */ virtual void SetCurrentSelection(NodeList selectedNodes) = 0; /** Set the info text that should be displayed if no (valid) node is selected, - * but a selection is mandatory. - * The string can contain HTML code. if wanted*/ + * but a selection is mandatory. + * The string can contain HTML code, if desired. + */ void SetInvalidInfo(QString info); /** Set the info text that should be displayed if no (valid) node is selected, - * but a selection is optional. - * The string can contain HTML code. if wanted*/ + * but a selection is optional. + * The string can contain HTML code, if desired. + */ void SetEmptyInfo(QString info); /** Set the caption of the popup that is displayed to alter the selection. - * The string can contain HTML code. if wanted*/ + * The string can contain HTML code, if desired. + */ void SetPopUpTitel(QString info); /** Set the hint text of the popup that is displayed to alter the selection. - * The string can contain HTML code. if wanted*/ + * The string can contain HTML code, if desired. + */ void SetPopUpHint(QString info); /** Set the widget into an optional mode. Optional means that the selection of no valid - node does not mean an invalid state. Thus no node is a valid "node" selection too.*/ + * node does not mean an invalid state. Thus no node is a valid "node" selection, too. + */ void SetSelectionIsOptional(bool isOptional); protected: - /**Member is called if the display of the selected nodes should be updated.*/ + /** Member is called if the display of the selected nodes should be updated. */ virtual void UpdateInfo() = 0; - /**Member is called if the predicate has changed. Thus the selection might change to. The new (changed) predicate - is passed with the function call. It is the same like this->GetNodePredicate() called in the function call.*/ - virtual void OnNodePredicateChanged(mitk::NodePredicateBase* newPredicate) = 0; + /** Member is called if the predicate has changed. Thus the selection might change, too. */ + virtual void OnNodePredicateChanged() = 0; - /**Member is called if the data storage has changed. Thus the selection might change to.*/ + /** Member is called if the data storage has changed. Thus the selection might change, too. */ virtual void OnDataStorageChanged() = 0; mitk::WeakPointer m_DataStorage; mitk::NodePredicateBase::Pointer m_NodePredicate; QString m_InvalidInfo; QString m_EmptyInfo; QString m_PopUpTitel; QString m_PopUpHint; bool m_IsOptional; bool m_SelectOnlyVisibleNodes; }; -#endif // QmitkAbstractNodeSelectionWidget_H + +#endif // QMITK_ABSTRACT_NODE_SELECTION_WIDGET_H diff --git a/Plugins/org.mitk.gui.qt.common/src/QmitkMultiNodeSelectionWidget.cpp b/Plugins/org.mitk.gui.qt.common/src/QmitkMultiNodeSelectionWidget.cpp index 26102b6d3e..2bb5b88cc0 100644 --- a/Plugins/org.mitk.gui.qt.common/src/QmitkMultiNodeSelectionWidget.cpp +++ b/Plugins/org.mitk.gui.qt.common/src/QmitkMultiNodeSelectionWidget.cpp @@ -1,244 +1,242 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ - #include "QmitkMultiNodeSelectionWidget.h" #include #include "QmitkNodeSelectionDialog.h" #include "QmitkCustomVariants.h" #include "internal/QmitkNodeSelectionListItemWidget.h" -QmitkMultiNodeSelectionWidget::QmitkMultiNodeSelectionWidget(QWidget* parent) : QmitkAbstractNodeSelectionWidget(parent) +QmitkMultiNodeSelectionWidget::QmitkMultiNodeSelectionWidget(QWidget* parent) + : QmitkAbstractNodeSelectionWidget(parent) { m_Controls.setupUi(this); m_Overlay = new QmitkSimpleTextOverlayWidget(m_Controls.list); m_Overlay->setVisible(false); m_CheckFunction = [](const NodeList &) { return ""; }; this->UpdateList(); this->UpdateInfo(); connect(m_Controls.btnChange, SIGNAL(clicked(bool)), this, SLOT(OnEditSelection())); } QmitkMultiNodeSelectionWidget::NodeList QmitkMultiNodeSelectionWidget::CompileEmitSelection() const { NodeList result; for (int i = 0; i < m_Controls.list->count(); ++i) { QListWidgetItem* item = m_Controls.list->item(i); auto node = item->data(Qt::UserRole).value(); result.append(node); } if (!m_SelectOnlyVisibleNodes) { for (auto node : m_CurrentSelection) { if (!result.contains(node)) { result.append(node); } } } return result; } -void QmitkMultiNodeSelectionWidget::OnNodePredicateChanged(mitk::NodePredicateBase* /*newPredicate*/) +void QmitkMultiNodeSelectionWidget::OnNodePredicateChanged() { - this->UpdateInfo(); this->UpdateList(); -}; +} void QmitkMultiNodeSelectionWidget::OnDataStorageChanged() { - this->UpdateInfo(); this->UpdateList(); -}; +} QmitkMultiNodeSelectionWidget::NodeList QmitkMultiNodeSelectionWidget::GetSelectedNodes() const { return m_CurrentSelection; -}; +} void QmitkMultiNodeSelectionWidget::SetSelectionCheckFunction(const SelectionCheckFunctionType &checkFunction) { m_CheckFunction = checkFunction; auto newEmission = this->CompileEmitSelection(); auto newCheckResponse = m_CheckFunction(newEmission); if (newCheckResponse.empty() && !m_CheckResponse.empty()) { emit CurrentSelectionChanged(newEmission); } m_CheckResponse = newCheckResponse; this->UpdateInfo(); -}; +} void QmitkMultiNodeSelectionWidget::OnEditSelection() { QmitkNodeSelectionDialog* dialog = new QmitkNodeSelectionDialog(this, m_PopUpTitel, m_PopUpHint); dialog->SetDataStorage(m_DataStorage.Lock()); dialog->SetNodePredicate(m_NodePredicate); dialog->SetCurrentSelection(this->CompileEmitSelection()); dialog->SetSelectOnlyVisibleNodes(m_SelectOnlyVisibleNodes); dialog->SetSelectionMode(QAbstractItemView::MultiSelection); m_Controls.btnChange->setChecked(true); if (dialog->exec()) { auto lastEmission = this->CompileEmitSelection(); m_CurrentSelection = dialog->GetSelectedNodes(); this->UpdateList(); auto newEmission = this->CompileEmitSelection(); m_CheckResponse = m_CheckFunction(newEmission); this->UpdateInfo(); if (!EqualNodeSelections(lastEmission, newEmission)) { if (m_CheckResponse.empty()) { emit CurrentSelectionChanged(newEmission); } } } m_Controls.btnChange->setChecked(false); delete dialog; -}; +} void QmitkMultiNodeSelectionWidget::UpdateInfo() { if (!m_Controls.list->count()) { if (m_IsOptional) { m_Overlay->SetOverlayText(m_EmptyInfo); } else { m_Overlay->SetOverlayText(m_InvalidInfo); } } else { if (!m_CheckResponse.empty()) { m_Overlay->SetOverlayText(QString::fromStdString(m_CheckResponse)); } } m_Overlay->setVisible(m_Controls.list->count() == 0 || !m_CheckResponse.empty()); for (auto i = 0; i < m_Controls.list->count(); ++i) { auto item = m_Controls.list->item(i); auto widget = qobject_cast(m_Controls.list->itemWidget(item)); widget->SetClearAllowed(m_IsOptional || m_CurrentSelection.size() > 1); } -}; +} void QmitkMultiNodeSelectionWidget::UpdateList() { m_Controls.list->clear(); for (auto node : m_CurrentSelection) { if (m_NodePredicate.IsNull() || m_NodePredicate->CheckNode(node)) { QListWidgetItem *newItem = new QListWidgetItem; newItem->setSizeHint(QSize(0, 40)); QmitkNodeSelectionListItemWidget* widget = new QmitkNodeSelectionListItemWidget; widget->SetSelectedNode(node); widget->SetClearAllowed(m_IsOptional || m_CurrentSelection.size() > 1); connect(widget, SIGNAL(ClearSelection(mitk::DataNode*)), this, SLOT(OnClearSelection(mitk::DataNode*))); newItem->setData(Qt::UserRole, QVariant::fromValue(node)); m_Controls.list->addItem(newItem); m_Controls.list->setItemWidget(newItem, widget); } } -}; +} void QmitkMultiNodeSelectionWidget::SetSelectOnlyVisibleNodes(bool selectOnlyVisibleNodes) { auto lastEmission = this->CompileEmitSelection(); m_SelectOnlyVisibleNodes = selectOnlyVisibleNodes; auto newEmission = this->CompileEmitSelection(); if (!EqualNodeSelections(lastEmission, newEmission)) { m_CheckResponse = m_CheckFunction(newEmission); if (m_CheckResponse.empty()) { emit CurrentSelectionChanged(newEmission); } this->UpdateList(); this->UpdateInfo(); } -}; +} void QmitkMultiNodeSelectionWidget::SetCurrentSelection(NodeList selectedNodes) { auto lastEmission = this->CompileEmitSelection(); m_CurrentSelection = selectedNodes; this->UpdateList(); auto newEmission = this->CompileEmitSelection(); if (!EqualNodeSelections(lastEmission, newEmission)) { m_CheckResponse = m_CheckFunction(newEmission); if (m_CheckResponse.empty()) { emit CurrentSelectionChanged(newEmission); } this->UpdateInfo(); } -}; +} void QmitkMultiNodeSelectionWidget::OnClearSelection(mitk::DataNode* node) { auto finding = std::find(std::begin(m_CurrentSelection), std::end(m_CurrentSelection), node); m_CurrentSelection.erase(finding); this->UpdateList(); auto newEmission = this->CompileEmitSelection(); m_CheckResponse = m_CheckFunction(newEmission); if (m_CheckResponse.empty()) { emit CurrentSelectionChanged(newEmission); } this->UpdateInfo(); -}; +} diff --git a/Plugins/org.mitk.gui.qt.common/src/QmitkMultiNodeSelectionWidget.h b/Plugins/org.mitk.gui.qt.common/src/QmitkMultiNodeSelectionWidget.h index 28cc17ed33..2fff9c1ca8 100644 --- a/Plugins/org.mitk.gui.qt.common/src/QmitkMultiNodeSelectionWidget.h +++ b/Plugins/org.mitk.gui.qt.common/src/QmitkMultiNodeSelectionWidget.h @@ -1,88 +1,92 @@ /*=================================================================== 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 QMITK_MULTI_NODE_SELECTION_WIDGET_H #define QMITK_MULTI_NODE_SELECTION_WIDGET_H #include #include #include #include "QmitkSimpleTextOverlayWidget.h" #include "org_mitk_gui_qt_common_Export.h" #include "ui_QmitkMultiNodeSelectionWidget.h" #include class QmitkAbstractDataStorageModel; class QAbstractItemVew; /** -* \class QmitkMultiNodeSelectionWidget -* \brief Widget that allows to perform and represents a multiple node selection. +* @class QmitkMultiNodeSelectionWidget +* @brief Widget that allows to perform and represents a multiple node selection. */ class MITK_QT_COMMON QmitkMultiNodeSelectionWidget : public QmitkAbstractNodeSelectionWidget { Q_OBJECT public: explicit QmitkMultiNodeSelectionWidget(QWidget* parent = nullptr); using NodeList = QmitkAbstractNodeSelectionWidget::NodeList; NodeList GetSelectedNodes() const; - /**Helper function that is used to check the given selection for consistency. - Returning an empty string assumes that everything is alright and the selection - is valid. If the string is not empty, the content of the string will be used - as error message in the overlay to indicate the problem.*/ + /** + * @brief Helper function that is used to check the given selection for consistency. + * Returning an empty string assumes that everything is alright and the selection + * is valid. If the string is not empty, the content of the string will be used + * as error message in the overlay to indicate the problem. + */ using SelectionCheckFunctionType = std::function; - /**A selection check function can be set. If set the widget uses this function to - check the made/set selection. If the selection is valid, everything is fine. - If selection is indicated as invalid, it will not be communicated by the widget - (no signal emission.*/ + /** + * @brief A selection check function can be set. If set the widget uses this function to + * check the made/set selection. If the selection is valid, everything is fine. + * If selection is indicated as invalid, it will not be communicated by the widget + * (no signal emission). + */ void SetSelectionCheckFunction(const SelectionCheckFunctionType &checkFunction); public Q_SLOTS: virtual void SetSelectOnlyVisibleNodes(bool selectOnlyVisibleNodes) override; virtual void SetCurrentSelection(NodeList selectedNodes) override; void OnEditSelection(); protected Q_SLOTS: void OnClearSelection(mitk::DataNode* node); protected: NodeList CompileEmitSelection() const; virtual void UpdateInfo() override; virtual void UpdateList(); - virtual void OnNodePredicateChanged(mitk::NodePredicateBase* newPredicate) override; + virtual void OnNodePredicateChanged() override; virtual void OnDataStorageChanged() override; NodeList m_CurrentSelection; QmitkSimpleTextOverlayWidget* m_Overlay; SelectionCheckFunctionType m_CheckFunction; std::string m_CheckResponse; Ui_QmitkMultiNodeSelectionWidget m_Controls; }; -#endif // QmitkMultiNodeSelectionWidget_H + +#endif // QMITK_MULTI_NODE_SELECTION_WIDGET_H diff --git a/Plugins/org.mitk.gui.qt.common/src/QmitkNodeSelectionButton.cpp b/Plugins/org.mitk.gui.qt.common/src/QmitkNodeSelectionButton.cpp index 08bb6248cf..c141732f90 100644 --- a/Plugins/org.mitk.gui.qt.common/src/QmitkNodeSelectionButton.cpp +++ b/Plugins/org.mitk.gui.qt.common/src/QmitkNodeSelectionButton.cpp @@ -1,181 +1,181 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ - #include "QmitkNodeSelectionButton.h" -// berry includes -#include -#include - -#include "QPainter" -#include "QTextDocument" - -#include -#include - // mitk core #include -#include #include #include #include #include +// mitk qt widgets module +#include + +// berry includes +#include +#include + // vtk #include +// qt +#include +#include + QPixmap GetPixmapFromImageNode(const mitk::DataNode* dataNode, int height) { if (nullptr == dataNode) { return QPixmap(); } const mitk::Image* image = dynamic_cast(dataNode->GetData()); if ((nullptr == image || !image->IsInitialized()) || // -> must be an image (image->GetPixelType().GetNumberOfComponents() != 1)) // -> for now only single component are allowed { auto descManager = QmitkNodeDescriptorManager::GetInstance(); auto desc = descManager->GetDescriptor(dataNode); auto icon = desc->GetIcon(dataNode); auto fallBackMap = icon.pixmap(height, height); return fallBackMap; } mitk::PlaneGeometry::Pointer planeGeometry = mitk::PlaneGeometry::New(); int sliceNumber = image->GetDimension(2) / 2; planeGeometry->InitializeStandardPlane(image->GetGeometry(), mitk::PlaneGeometry::Axial, sliceNumber); mitk::ExtractSliceFilter::Pointer extractSliceFilter = mitk::ExtractSliceFilter::New(); extractSliceFilter->SetInput(image); extractSliceFilter->SetInterpolationMode(mitk::ExtractSliceFilter::RESLICE_CUBIC); extractSliceFilter->SetResliceTransformByGeometry(image->GetGeometry()); extractSliceFilter->SetWorldGeometry(planeGeometry); extractSliceFilter->SetOutputDimensionality(2); extractSliceFilter->SetVtkOutputRequest(true); extractSliceFilter->Update(); vtkImageData* imageData = extractSliceFilter->GetVtkOutput(); mitk::LevelWindow levelWindow; dataNode->GetLevelWindow(levelWindow); vtkSmartPointer lookupTable = vtkSmartPointer::New(); lookupTable->SetRange(levelWindow.GetLowerWindowBound(), levelWindow.GetUpperWindowBound()); lookupTable->SetSaturationRange(0.0, 0.0); lookupTable->SetValueRange(0.0, 1.0); lookupTable->SetHueRange(0.0, 0.0); lookupTable->SetRampToLinear(); vtkSmartPointer levelWindowFilter = vtkSmartPointer::New(); levelWindowFilter->SetLookupTable(lookupTable); levelWindowFilter->SetInputData(imageData); levelWindowFilter->SetMinOpacity(0.0); levelWindowFilter->SetMaxOpacity(1.0); int dims[3]; imageData->GetDimensions(dims); double clippingBounds[] = { 0.0, static_cast(dims[0]), 0.0, static_cast(dims[1]) }; levelWindowFilter->SetClippingBounds(clippingBounds); levelWindowFilter->Update(); imageData = levelWindowFilter->GetOutput(); QImage thumbnailImage(reinterpret_cast(imageData->GetScalarPointer()), dims[0], dims[1], QImage::Format_ARGB32); thumbnailImage = thumbnailImage.scaledToHeight(height,Qt::SmoothTransformation).rgbSwapped(); return QPixmap::fromImage(thumbnailImage); } QmitkNodeSelectionButton::QmitkNodeSelectionButton(QWidget *parent) - : QPushButton(parent), m_OutDatedThumpNail(true) -{ } + : QPushButton(parent) + , m_OutdatedThumbnail(true) +{ +} QmitkNodeSelectionButton::~QmitkNodeSelectionButton() { this->m_SelectedNode = nullptr; } mitk::DataNode::Pointer QmitkNodeSelectionButton::GetSelectedNode() const { return m_SelectedNode; } void QmitkNodeSelectionButton::SetSelectedNode(mitk::DataNode* node) { if (m_SelectedNode != node) { this->m_SelectedNode = node; - this->m_OutDatedThumpNail = true; + this->m_OutdatedThumbnail = true; } this->update(); -}; +} void QmitkNodeSelectionButton::SetNodeInfo(QString info) { this->m_Info = info; this->update(); -}; +} void QmitkNodeSelectionButton::paintEvent(QPaintEvent *p) { QString stylesheet; ctkPluginContext* context = berry::WorkbenchPlugin::GetDefault()->GetPluginContext(); ctkServiceReference styleManagerRef = context->getServiceReference(); if (styleManagerRef) { auto styleManager = context->getService(styleManagerRef); stylesheet = styleManager->GetStylesheet(); } QPushButton::paintEvent(p); QPainter painter(this); QTextDocument td(this); td.setDefaultStyleSheet(stylesheet); auto widgetSize = this->size(); QPoint origin = QPoint(5, 5); if (this->m_SelectedNode) { auto iconLength = widgetSize.height() - 10; auto node = this->m_SelectedNode; - if (this->m_OutDatedThumpNail) + if (this->m_OutdatedThumbnail) { - this->m_ThumpNail = GetPixmapFromImageNode(node, iconLength); - this->m_OutDatedThumpNail = false; + this->m_Thumbnail = GetPixmapFromImageNode(node, iconLength); + this->m_OutdatedThumbnail = false; } - painter.drawPixmap(origin, m_ThumpNail); + painter.drawPixmap(origin, m_Thumbnail); origin.setX(origin.x() + iconLength + 5); td.setHtml(QString::fromStdString(""+node->GetName()+"")); } else { td.setHtml(m_Info); } auto textSize = td.size(); origin.setY( (widgetSize.height() - textSize.height()) / 2.); painter.translate(origin); td.drawContents(&painter); - } diff --git a/Plugins/org.mitk.gui.qt.common/src/QmitkNodeSelectionButton.h b/Plugins/org.mitk.gui.qt.common/src/QmitkNodeSelectionButton.h index a8d78302ce..ac689640e6 100644 --- a/Plugins/org.mitk.gui.qt.common/src/QmitkNodeSelectionButton.h +++ b/Plugins/org.mitk.gui.qt.common/src/QmitkNodeSelectionButton.h @@ -1,58 +1,58 @@ /*=================================================================== 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 QMITK_NODE_SELECTION_BUTTON_H #define QMITK_NODE_SELECTION_BUTTON_H -#include -#include - #include "org_mitk_gui_qt_common_Export.h" -#include "QPushButton" -#include "QPixmap" +// mitk core +#include +// qt +#include +#include -/** Button class that can be used to display informations about a passed node. - * If the passed node is a null ptr the node info text will be shown. - * In difference to the normal push button text property. The node info can - * be formated text (e.g. HTML code; like the tooltip text).*/ +/** +* @class QmitkNodeSelectionButton +* @brief Button class that can be used to display informations about a given node. +* If the given node is a nullptr the node info text will be shown. +* The node info can be formated text (e.g. HTML code; like the tooltip text). +*/ class MITK_QT_COMMON QmitkNodeSelectionButton : public QPushButton { Q_OBJECT public: explicit QmitkNodeSelectionButton(QWidget *parent = nullptr); ~QmitkNodeSelectionButton(); mitk::DataNode::Pointer GetSelectedNode() const; -public Q_SLOTS : +public Q_SLOTS: virtual void SetSelectedNode(mitk::DataNode* node); virtual void SetNodeInfo(QString info); protected: void paintEvent(QPaintEvent *p) override; mitk::DataNode::Pointer m_SelectedNode; QString m_Info; - bool m_OutDatedThumpNail; - QPixmap m_ThumpNail; + bool m_OutdatedThumbnail; + QPixmap m_Thumbnail; }; - -#endif // QmitkSingleNodeSelectionWidget_H +#endif // QMITK_NODE_SELECTION_BUTTON_H diff --git a/Plugins/org.mitk.gui.qt.common/src/QmitkNodeSelectionDialog.cpp b/Plugins/org.mitk.gui.qt.common/src/QmitkNodeSelectionDialog.cpp index cdba488356..6d07796ad8 100644 --- a/Plugins/org.mitk.gui.qt.common/src/QmitkNodeSelectionDialog.cpp +++ b/Plugins/org.mitk.gui.qt.common/src/QmitkNodeSelectionDialog.cpp @@ -1,186 +1,189 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ - #include "QmitkNodeSelectionDialog.h" #include #include #include -QmitkNodeSelectionDialog::QmitkNodeSelectionDialog(QWidget* parent, QString title, QString hint) : QDialog(parent), - m_NodePredicate(nullptr), m_SelectOnlyVisibleNodes(false), m_SelectedNodes(NodeList()), m_SelectionMode(QAbstractItemView::SingleSelection) +QmitkNodeSelectionDialog::QmitkNodeSelectionDialog(QWidget* parent, QString title, QString hint) + : QDialog(parent) + , m_NodePredicate(nullptr) + , m_SelectOnlyVisibleNodes(false) + , m_SelectedNodes(NodeList()) + , m_SelectionMode(QAbstractItemView::SingleSelection) { m_Controls.setupUi(this); auto providers = mitk::DataStorageInspectorGenerator::GetProviders(); auto visibleProviders = mitk::GetVisibleDataStorageInspectors(); auto favoriteID = mitk::GetFavoriteDataStorageInspector(); if (visibleProviders.empty()) { MITK_DEBUG << "No presets for visible node selection inspectors available. Use fallback (show all available inspectors)"; unsigned int order = 0; for (auto proIter : providers) { visibleProviders.insert(std::make_pair(order, proIter.first)); } } int favIndex = 0; bool favoriteFound = false; for (auto proIter : visibleProviders) { auto finding = providers.find(proIter.second); if (finding != providers.end()) { auto inspector = finding->second->CreateInspector(); QString name = QString::fromStdString(finding->second->GetInspectorDisplayName()); QString desc = QString::fromStdString(finding->second->GetInspectorDescription()); AddPanel(inspector, name, desc); favoriteFound = favoriteFound || proIter.second == favoriteID; if (!favoriteFound) { ++favIndex; } } else { MITK_DEBUG << "No provider registered for inspector that is defined as visible in the preferences. Illegal inspector ID: " << proIter.second; } } m_Controls.tabWidget->setCurrentIndex(favIndex); this->setWindowTitle(title); this->setToolTip(hint); m_Controls.hint->setText(hint); m_Controls.hint->setVisible(!hint.isEmpty()); connect(m_Controls.buttonBox, SIGNAL(accepted()), this, SLOT(OnOK())); connect(m_Controls.buttonBox, SIGNAL(rejected()), this, SLOT(OnCancel())); } void QmitkNodeSelectionDialog::SetDataStorage(mitk::DataStorage* dataStorage) { if (m_DataStorage != dataStorage) { m_DataStorage = dataStorage; if (!m_DataStorage.IsExpired()) { for (auto panel : m_Panels) { panel->SetDataStorage(dataStorage); } } } -}; +} void QmitkNodeSelectionDialog::SetNodePredicate(mitk::NodePredicateBase* nodePredicate) { if (m_NodePredicate != nodePredicate) { m_NodePredicate = nodePredicate; for (auto panel : m_Panels) { panel->SetNodePredicate(m_NodePredicate); } } -}; +} mitk::NodePredicateBase* QmitkNodeSelectionDialog::GetNodePredicate() const { return m_NodePredicate; } QmitkNodeSelectionDialog::NodeList QmitkNodeSelectionDialog::GetSelectedNodes() const { return m_SelectedNodes; -}; +} void QmitkNodeSelectionDialog::SetSelectOnlyVisibleNodes(bool selectOnlyVisibleNodes) { if (m_SelectOnlyVisibleNodes != selectOnlyVisibleNodes) { m_SelectOnlyVisibleNodes = selectOnlyVisibleNodes; for (auto panel : m_Panels) { panel->SetSelectOnlyVisibleNodes(m_SelectOnlyVisibleNodes); } } -}; +} void QmitkNodeSelectionDialog::SetCurrentSelection(NodeList selectedNodes) { m_SelectedNodes = selectedNodes; for (auto panel : m_Panels) { panel->SetCurrentSelection(selectedNodes); } -}; +} void QmitkNodeSelectionDialog::OnSelectionChanged(NodeList selectedNodes) { SetCurrentSelection(selectedNodes); emit CurrentSelectionChanged(selectedNodes); -}; +} void QmitkNodeSelectionDialog::AddPanel(QmitkAbstractDataStorageInspector* view, QString name, QString desc) { view->setParent(this); view->SetSelectionMode(m_SelectionMode); auto tabPanel = new QWidget(); tabPanel->setObjectName(QString("tab_")+name); tabPanel->setToolTip(desc); m_Controls.tabWidget->insertTab(m_Controls.tabWidget->count(), tabPanel, name); auto verticalLayout = new QVBoxLayout(tabPanel); verticalLayout->setSpacing(0); verticalLayout->setContentsMargins(0, 0, 0, 0); verticalLayout->addWidget(view); m_Panels.push_back(view); connect(view, &QmitkAbstractDataStorageInspector::CurrentSelectionChanged, this, &QmitkNodeSelectionDialog::OnSelectionChanged); -}; +} void QmitkNodeSelectionDialog::OnOK() { this->accept(); -}; +} void QmitkNodeSelectionDialog::OnCancel() { this->reject(); -}; +} void QmitkNodeSelectionDialog::SetSelectionMode(SelectionMode mode) { m_SelectionMode = mode; for (auto panel : m_Panels) { panel->SetSelectionMode(mode); } -}; +} QmitkNodeSelectionDialog::SelectionMode QmitkNodeSelectionDialog::GetSelectionMode() const { return m_SelectionMode; } diff --git a/Plugins/org.mitk.gui.qt.common/src/QmitkNodeSelectionDialog.h b/Plugins/org.mitk.gui.qt.common/src/QmitkNodeSelectionDialog.h index 02f828bcc5..62a9a6c271 100644 --- a/Plugins/org.mitk.gui.qt.common/src/QmitkNodeSelectionDialog.h +++ b/Plugins/org.mitk.gui.qt.common/src/QmitkNodeSelectionDialog.h @@ -1,127 +1,131 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ - #ifndef QMITK_NODE_SELECTION_DIALOG_H #define QMITK_NODE_SELECTION_DIALOG_H +#include "org_mitk_gui_qt_common_Export.h" + +#include "ui_QmitkNodeSelectionDialog.h" +// mitk core #include #include #include +// mitk qt widgets module #include -#include "org_mitk_gui_qt_common_Export.h" - -#include "ui_QmitkNodeSelectionDialog.h" - +// qt #include /** -* \class QmitkNodeSelectionDialog -* \brief Widget that allows to show and edit the content of an mitk::IsoDoseLevel instance. +* @class QmitkNodeSelectionDialog +* @brief A customized QDialog that displays different concrete data storage inspectors and allows to +* set and get a current selection by selecting data nodes in the data storage inspectors. */ class MITK_QT_COMMON QmitkNodeSelectionDialog : public QDialog { Q_OBJECT public: explicit QmitkNodeSelectionDialog(QWidget* parent = nullptr, QString caption = "", QString hint = ""); - /* - * @brief Sets the data storage that will be used /monitored by widget. + /** + * @brief Set the data storage that will be used. + * The function iterates over the dialog's panels and sets the data storage of each panel accordingly. + * Each panel is a concrete data storage inspector. * * @param dataStorage A pointer to the data storage to set. */ void SetDataStorage(mitk::DataStorage* dataStorage); - /* - * @brief Sets the node predicate and updates the widget, according to the node predicate. + /** + * @brief Set the node predicate that will be used. + * The function iterates over the dialog's panels and sets the node predicate of each panel accordingly. + * Each panel is a concrete data storage inspector. * * @param nodePredicate A pointer to node predicate. */ virtual void SetNodePredicate(mitk::NodePredicateBase* nodePredicate); mitk::NodePredicateBase* GetNodePredicate() const; using NodeList = QList; NodeList GetSelectedNodes() const; bool GetSelectOnlyVisibleNodes() const; using SelectionMode = QAbstractItemView::SelectionMode; + /** + * @brief Set the Qt selection mode (e.g. Single selection, multi selection). + * The function iterates over the dialog's panels and sets the Qt selection mode of each panel accordingly. + * Each panel is a concrete data storage inspector. + * + * @param mode The QAbstractItemView::SelectionMode to define the selection mode. + */ void SetSelectionMode(SelectionMode mode); SelectionMode GetSelectionMode() const; Q_SIGNALS: - /* + /** * @brief A signal that will be emitted if the selected node has changed. * * @param nodes A list of data nodes that are newly selected. */ void CurrentSelectionChanged(NodeList nodes); public Q_SLOTS: - /* - * @brief Change the selection modus of the item view's selection model. - * - * If true, an incoming selection will be filtered (reduced) to only those nodes that are visible by the current view. - * An outgoing selection can then at most contain the filtered nodes. - * If false, the incoming non-visible selection will be stored and later added to the outgoing selection, - * to include the original selection that could not be modified. - * The part of the original selection, that is non-visible are the nodes that are not + /** + * @brief Set the selection modus to (not) include invisible nodes in the selection. + * The function iterates over the dialog's panels and sets the selection modus of each panel accordingly. + * Each panel is a concrete data storage inspector. * * @param selectOnlyVisibleNodes The bool value to define the selection modus. */ void SetSelectOnlyVisibleNodes(bool selectOnlyVisibleNodes); - - /* - * @brief Transform a list of data nodes into a model selection and set this as a new selection of the - * selection model of the private member item view. - * - * The function filters the given list of nodes according to the 'm_SelectOnlyVisibleNodes' member variable. If - * necessary, the non-visible nodes are stored. This is done if 'm_SelectOnlyVisibleNodes' is false: In this case - * the selection may be filtered and only a subset of the selected nodes may be visible and therefore (de-)selectable - * in the data storage viewer. By storing the non-visible nodes it is possible to send the new, modified selection - * but also include the selected nodes from the original selection that could not be modified (see 'SetSelectOnlyVisibleNodes'). + /** + * @brief Set the currently selected nodes given a list of data nodes. + * The function iterates over the dialog's panels and sets the current selection of each panel accordingly. + * Each panel is a concrete data storage inspector. * * @param nodes A list of data nodes that should be newly selected. */ void SetCurrentSelection(NodeList selectedNodes); protected Q_SLOTS: void OnSelectionChanged(NodeList selectedNodes); void OnOK(); void OnCancel(); protected: void AddPanel(QmitkAbstractDataStorageInspector* view, QString name, QString desc); mitk::WeakPointer m_DataStorage; mitk::NodePredicateBase::Pointer m_NodePredicate; bool m_SelectOnlyVisibleNodes; NodeList m_SelectedNodes; SelectionMode m_SelectionMode; using PanelVectorType = std::vector; PanelVectorType m_Panels; Ui_QmitkNodeSelectionDialog m_Controls; }; -#endif // QmitkNodeSelectionDialog_H + +#endif // QMITK_NODE_SELECTION_DIALOG_H diff --git a/Plugins/org.mitk.gui.qt.common/src/QmitkSingleNodeSelectionWidget.cpp b/Plugins/org.mitk.gui.qt.common/src/QmitkSingleNodeSelectionWidget.cpp index 4083d5511e..7be35be60d 100644 --- a/Plugins/org.mitk.gui.qt.common/src/QmitkSingleNodeSelectionWidget.cpp +++ b/Plugins/org.mitk.gui.qt.common/src/QmitkSingleNodeSelectionWidget.cpp @@ -1,237 +1,237 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ - #include "QmitkSingleNodeSelectionWidget.h" #include #include #include "QmitkNodeSelectionDialog.h" #include "QmitkNodeDetailsDialog.h" -QmitkSingleNodeSelectionWidget::QmitkSingleNodeSelectionWidget(QWidget* parent) : QmitkAbstractNodeSelectionWidget(parent) +QmitkSingleNodeSelectionWidget::QmitkSingleNodeSelectionWidget(QWidget* parent) + : QmitkAbstractNodeSelectionWidget(parent) { m_Controls.setupUi(this); m_Controls.btnSelect->installEventFilter(this); m_Controls.btnSelect->setVisible(true); m_Controls.btnClear->setVisible(false); m_Controls.btnClear->setIcon(berry::QtStyleManager::ThemeIcon(QStringLiteral(":/org.mitk.gui.qt.common/times.svg"))); this->UpdateInfo(); connect(m_Controls.btnClear, SIGNAL(clicked(bool)), this, SLOT(OnClearSelection())); } QmitkSingleNodeSelectionWidget::~QmitkSingleNodeSelectionWidget() { } mitk::DataNode::Pointer QmitkSingleNodeSelectionWidget::ExtractCurrentValidSelection(const NodeList& nodes) const { mitk::DataNode::Pointer result = nullptr; for (auto node : nodes) { bool valid = true; if (m_NodePredicate.IsNotNull()) { valid = m_NodePredicate->CheckNode(node); } if (valid) { result = node; break; } } return result; } QmitkSingleNodeSelectionWidget::NodeList QmitkSingleNodeSelectionWidget::CompileEmitSelection() const { NodeList result; if (!m_SelectOnlyVisibleNodes) { result = m_ExternalSelection; } if (m_SelectedNode.IsNotNull() && !result.contains(m_SelectedNode)) { result.append(m_SelectedNode); } return result; } -void QmitkSingleNodeSelectionWidget::OnNodePredicateChanged(mitk::NodePredicateBase* /*newPredicate*/) +void QmitkSingleNodeSelectionWidget::OnNodePredicateChanged() { m_SelectedNode = this->ExtractCurrentValidSelection(m_ExternalSelection); -}; +} void QmitkSingleNodeSelectionWidget::OnDataStorageChanged() { -}; +} void QmitkSingleNodeSelectionWidget::OnClearSelection() { if (m_IsOptional) { NodeList emptyList; this->SetCurrentSelection(emptyList); } this->UpdateInfo(); } mitk::DataNode::Pointer QmitkSingleNodeSelectionWidget::GetSelectedNode() const { return m_SelectedNode; -}; +} bool QmitkSingleNodeSelectionWidget::eventFilter(QObject *obj, QEvent *ev) { if (obj == m_Controls.btnSelect) { if (ev->type() == QEvent::MouseButtonRelease) { auto mouseEv = dynamic_cast(ev); if (!mouseEv) { return false; } if (mouseEv->button() == Qt::LeftButton) { this->EditSelection(); return true; } else { auto selection = this->CompileEmitSelection(); if (!selection.empty()) { QmitkNodeDetailsDialog infoDialog(selection, this); infoDialog.exec(); return true; } } } } return false; } void QmitkSingleNodeSelectionWidget::EditSelection() { QmitkNodeSelectionDialog* dialog = new QmitkNodeSelectionDialog(this, m_PopUpTitel, m_PopUpHint); dialog->SetDataStorage(m_DataStorage.Lock()); dialog->SetNodePredicate(m_NodePredicate); NodeList list; if (m_SelectedNode.IsNotNull()) { list.append(m_SelectedNode); } dialog->SetCurrentSelection(list); dialog->SetSelectOnlyVisibleNodes(m_SelectOnlyVisibleNodes); dialog->SetSelectionMode(QAbstractItemView::SingleSelection); m_Controls.btnSelect->setChecked(true); if (dialog->exec()) { auto lastEmission = this->CompileEmitSelection(); auto nodes = dialog->GetSelectedNodes(); if (nodes.empty()) { m_SelectedNode = nullptr; } else { m_SelectedNode = nodes.first(); } auto newEmission = this->CompileEmitSelection(); if (!EqualNodeSelections(lastEmission, newEmission)) { emit CurrentSelectionChanged(newEmission); this->UpdateInfo(); } } m_Controls.btnSelect->setChecked(false); delete dialog; -}; +} void QmitkSingleNodeSelectionWidget::UpdateInfo() { if (m_SelectedNode.IsNull()) { if (m_IsOptional) { m_Controls.btnSelect->SetNodeInfo(m_EmptyInfo); } else { m_Controls.btnSelect->SetNodeInfo(m_InvalidInfo); } m_Controls.btnClear->setVisible(false); } else { m_Controls.btnClear->setVisible(m_IsOptional); } m_Controls.btnSelect->SetSelectedNode(m_SelectedNode); -}; +} void QmitkSingleNodeSelectionWidget::SetSelectOnlyVisibleNodes(bool selectOnlyVisibleNodes) { auto lastEmission = this->CompileEmitSelection(); m_SelectOnlyVisibleNodes = selectOnlyVisibleNodes; auto newEmission = this->CompileEmitSelection(); if (!EqualNodeSelections(lastEmission, newEmission)) { emit CurrentSelectionChanged(newEmission); this->UpdateInfo(); } -}; +} void QmitkSingleNodeSelectionWidget::SetCurrentSelection(NodeList selectedNodes) { auto lastEmission = this->CompileEmitSelection(); m_ExternalSelection = selectedNodes; m_SelectedNode = this->ExtractCurrentValidSelection(selectedNodes); auto newEmission = this->CompileEmitSelection(); if (!EqualNodeSelections(lastEmission, newEmission)) { emit CurrentSelectionChanged(newEmission); this->UpdateInfo(); } -}; +} diff --git a/Plugins/org.mitk.gui.qt.common/src/QmitkSingleNodeSelectionWidget.h b/Plugins/org.mitk.gui.qt.common/src/QmitkSingleNodeSelectionWidget.h index 4f67d11568..2794a7be96 100644 --- a/Plugins/org.mitk.gui.qt.common/src/QmitkSingleNodeSelectionWidget.h +++ b/Plugins/org.mitk.gui.qt.common/src/QmitkSingleNodeSelectionWidget.h @@ -1,76 +1,75 @@ /*=================================================================== 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 QMITK_SINGLE_NODE_SELECTION_WIDGET_H #define QMITK_SINGLE_NODE_SELECTION_WIDGET_H #include #include #include #include "org_mitk_gui_qt_common_Export.h" #include "ui_QmitkSingleNodeSelectionWidget.h" #include #include class QmitkAbstractDataStorageModel; /** -* \class QmitkSingleNodeSelectionWidget -* \brief Widget that represents a node selection. It acts like a button. Clicking on it -* allows to change the selection. +* @class QmitkSingleNodeSelectionWidget +* @brief Widget that represents a node selection. It acts like a button. Clicking on it +* allows to change the selection. */ class MITK_QT_COMMON QmitkSingleNodeSelectionWidget : public QmitkAbstractNodeSelectionWidget { Q_OBJECT public: explicit QmitkSingleNodeSelectionWidget(QWidget* parent = nullptr); ~QmitkSingleNodeSelectionWidget(); mitk::DataNode::Pointer GetSelectedNode() const; using NodeList = QmitkAbstractNodeSelectionWidget::NodeList; public Q_SLOTS: virtual void SetSelectOnlyVisibleNodes(bool selectOnlyVisibleNodes) override; virtual void SetCurrentSelection(NodeList selectedNodes) override; protected Q_SLOTS: virtual void OnClearSelection(); protected: mitk::DataNode::Pointer ExtractCurrentValidSelection(const NodeList& nodes) const; NodeList CompileEmitSelection() const; virtual bool eventFilter(QObject *obj, QEvent *ev) override; void EditSelection(); virtual void UpdateInfo() override; - virtual void OnNodePredicateChanged(mitk::NodePredicateBase* newPredicate) override; + virtual void OnNodePredicateChanged() override; virtual void OnDataStorageChanged() override; NodeList m_ExternalSelection; mitk::DataNode::Pointer m_SelectedNode; Ui_QmitkSingleNodeSelectionWidget m_Controls; }; -#endif // QmitkSingleNodeSelectionWidget_H +#endif // QMITK_SINGLE_NODE_SELECTION_WIDGET_H diff --git a/Plugins/org.mitk.gui.qt.datastorageviewertest/src/internal/QmitkDataStorageViewerTestView.cpp b/Plugins/org.mitk.gui.qt.datastorageviewertest/src/internal/QmitkDataStorageViewerTestView.cpp index 3fe521c862..75b1e89291 100644 --- a/Plugins/org.mitk.gui.qt.datastorageviewertest/src/internal/QmitkDataStorageViewerTestView.cpp +++ b/Plugins/org.mitk.gui.qt.datastorageviewertest/src/internal/QmitkDataStorageViewerTestView.cpp @@ -1,278 +1,278 @@ /*=================================================================== 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. ===================================================================*/ // data storage viewer test plugin #include "QmitkDataStorageViewerTestView.h" #include "mitkNodePredicateDataType.h" // berry #include // qt #include const std::string QmitkDataStorageViewerTestView::VIEW_ID = "org.mitk.views.datastorageviewertest"; void QmitkDataStorageViewerTestView::SetFocus() { // nothing here } void QmitkDataStorageViewerTestView::CreateQtPartControl(QWidget* parent) { // create GUI widgets m_Controls.setupUi(parent); m_DataStorageDefaultListModel = new QmitkDataStorageDefaultListModel(this); m_DataStorageDefaultListModel->SetDataStorage(GetDataStorage()); m_Controls.selectionListView->setSelectionMode(QAbstractItemView::ExtendedSelection); m_Controls.selectionListView->setSelectionBehavior(QAbstractItemView::SelectRows); m_Controls.selectionListView->setAlternatingRowColors(true); m_Controls.selectionListView->setModel(m_DataStorageDefaultListModel); m_DataStorageDefaultListModel2 = new QmitkDataStorageDefaultListModel(this); m_DataStorageDefaultListModel2->SetDataStorage(GetDataStorage()); m_Controls.selectionListView2->setSelectionMode(QAbstractItemView::ExtendedSelection); m_Controls.selectionListView2->setSelectionBehavior(QAbstractItemView::SelectRows); m_Controls.selectionListView2->setAlternatingRowColors(true); m_Controls.selectionListView2->setModel(m_DataStorageDefaultListModel2); m_Controls.singleSlot->SetDataStorage(GetDataStorage()); m_Controls.singleSlot->SetEmptyInfo(QString("EmptyInfo: Set this to display info in empty state")); m_Controls.singleSlot->SetInvalidInfo(QString("InvalidInfo: is displayed for invalid states")); m_Controls.singleSlot->SetPopUpTitel(QString("This is the definable caption. Choose your data now!")); m_Controls.singleSlot->SetPopUpHint(QString("I am an optional hint, that can be set by the developer

If not set the widget is invisible.")); m_Controls.multiSlot->SetDataStorage(GetDataStorage()); m_Controls.multiSlot->SetEmptyInfo(QString("EmptyInfo: Set this to display info in empty state")); m_Controls.multiSlot->SetInvalidInfo(QString("InvalidInfo: is displayed for invalid states")); m_Controls.multiSlot->SetPopUpTitel(QString("This is the definable caption. Choose your data now!")); m_Controls.multiSlot->SetPopUpHint(QString("I am an optional hint, that can be set by the developer

If not set the widget is invisible.")); m_ModelViewSelectionConnector = std::make_unique(); try { m_ModelViewSelectionConnector->SetView(m_Controls.selectionListView); } catch (mitk::Exception& e) { mitkReThrow(e) << "Cannot connect the model-view pair signals and slots."; } m_SelectionServiceConnector = std::make_unique(); m_ModelViewSelectionConnector2 = std::make_unique(); try { m_ModelViewSelectionConnector2->SetView(m_Controls.selectionListView2); } catch (mitk::Exception& e) { mitkReThrow(e) << "Cannot connect the model-view pair signals and slots."; } m_SelectionServiceConnector2 = std::make_unique(); m_SelectionServiceConnector3 = std::make_unique(); m_SelectionServiceConnector4 = std::make_unique(); connect(m_Controls.selectionProviderCheckBox, SIGNAL(toggled(bool)), this, SLOT(SetAsSelectionProvider1(bool))); connect(m_Controls.selectionProviderCheckBox2, SIGNAL(toggled(bool)), this, SLOT(SetAsSelectionProvider2(bool))); connect(m_Controls.selectionListenerCheckBox, SIGNAL(toggled(bool)), this, SLOT(SetAsSelectionListener1(bool))); connect(m_Controls.selectionListenerCheckBox2, SIGNAL(toggled(bool)), this, SLOT(SetAsSelectionListener2(bool))); connect(m_Controls.selectionProviderCheckBox3, SIGNAL(toggled(bool)), this, SLOT(SetAsSelectionProvider3(bool))); connect(m_Controls.selectionListenerCheckBox3, SIGNAL(toggled(bool)), this, SLOT(SetAsSelectionListener3(bool))); connect(m_Controls.checkOnlyVisible, SIGNAL(toggled(bool)), m_Controls.singleSlot, SLOT(SetSelectOnlyVisibleNodes(bool))); connect(m_Controls.checkOptional, SIGNAL(toggled(bool)), m_Controls.singleSlot, SLOT(SetSelectionIsOptional(bool))); connect(m_Controls.checkOnlyImages, SIGNAL(toggled(bool)), this, SLOT(OnOnlyImages(bool))); connect(m_Controls.selectionProviderCheckBox4, SIGNAL(toggled(bool)), this, SLOT(SetAsSelectionProvider4(bool))); connect(m_Controls.selectionListenerCheckBox4, SIGNAL(toggled(bool)), this, SLOT(SetAsSelectionListener4(bool))); connect(m_Controls.checkOnlyVisible_2, SIGNAL(toggled(bool)), m_Controls.multiSlot, SLOT(SetSelectOnlyVisibleNodes(bool))); connect(m_Controls.checkOptional_2, SIGNAL(toggled(bool)), m_Controls.multiSlot, SLOT(SetSelectionIsOptional(bool))); connect(m_Controls.checkOnlyImages_2, SIGNAL(toggled(bool)), this, SLOT(OnOnlyImages2(bool))); connect(m_Controls.checkOnlyUneven, SIGNAL(toggled(bool)), this, SLOT(OnOnlyUneven(bool))); } void QmitkDataStorageViewerTestView::SetAsSelectionProvider1(bool checked) { if (checked) { m_SelectionServiceConnector->SetAsSelectionProvider(GetSite()->GetSelectionProvider().Cast().GetPointer()); connect(m_ModelViewSelectionConnector.get(), SIGNAL(CurrentSelectionChanged(QList)), m_SelectionServiceConnector.get(), SLOT(ChangeServiceSelection(QList))); } else { m_SelectionServiceConnector->RemoveAsSelectionProvider(); disconnect(m_ModelViewSelectionConnector.get(), SIGNAL(CurrentSelectionChanged(QList)), m_SelectionServiceConnector.get(), SLOT(ChangeServiceSelection(QList))); } } void QmitkDataStorageViewerTestView::SetAsSelectionListener1(bool checked) { if (checked) { m_SelectionServiceConnector->AddPostSelectionListener(GetSite()->GetWorkbenchWindow()->GetSelectionService()); connect(m_SelectionServiceConnector.get(), SIGNAL(ServiceSelectionChanged(QList)), m_ModelViewSelectionConnector.get(), SLOT(SetCurrentSelection(QList))); } else { m_SelectionServiceConnector->RemovePostSelectionListener(); disconnect(m_SelectionServiceConnector.get(), SIGNAL(ServiceSelectionChanged(QList)), m_ModelViewSelectionConnector.get(), SLOT(SetCurrentSelection(QList))); } } void QmitkDataStorageViewerTestView::SetAsSelectionProvider2(bool checked) { if (checked) { m_SelectionServiceConnector2->SetAsSelectionProvider(GetSite()->GetSelectionProvider().Cast().GetPointer()); connect(m_ModelViewSelectionConnector2.get(), SIGNAL(CurrentSelectionChanged(QList)), m_SelectionServiceConnector2.get(), SLOT(ChangeServiceSelection(QList))); } else { m_SelectionServiceConnector2->RemoveAsSelectionProvider(); disconnect(m_ModelViewSelectionConnector2.get(), SIGNAL(CurrentSelectionChanged(QList)), m_SelectionServiceConnector2.get(), SLOT(ChangeServiceSelection(QList))); } } void QmitkDataStorageViewerTestView::SetAsSelectionListener2(bool checked) { if (checked) { m_SelectionServiceConnector2->AddPostSelectionListener(GetSite()->GetWorkbenchWindow()->GetSelectionService()); connect(m_SelectionServiceConnector2.get(), SIGNAL(ServiceSelectionChanged(QList)), m_ModelViewSelectionConnector2.get(), SLOT(SetCurrentSelection(QList))); } else { m_SelectionServiceConnector2->RemovePostSelectionListener(); disconnect(m_SelectionServiceConnector2.get(), SIGNAL(ServiceSelectionChanged(QList)), m_ModelViewSelectionConnector2.get(), SLOT(SetCurrentSelection(QList))); } } void QmitkDataStorageViewerTestView::SetAsSelectionProvider3(bool checked) { if (checked) { m_SelectionServiceConnector3->SetAsSelectionProvider(GetSite()->GetSelectionProvider().Cast().GetPointer()); connect(m_Controls.singleSlot, SIGNAL(CurrentSelectionChanged(QList)), m_SelectionServiceConnector3.get(), SLOT(ChangeServiceSelection(QList))); } else { m_SelectionServiceConnector3->RemoveAsSelectionProvider(); disconnect(m_Controls.singleSlot, SIGNAL(CurrentSelectionChanged(QList)), m_SelectionServiceConnector3.get(), SLOT(ChangeServiceSelection(QList))); } } void QmitkDataStorageViewerTestView::SetAsSelectionListener3(bool checked) { if (checked) { m_SelectionServiceConnector3->AddPostSelectionListener(GetSite()->GetWorkbenchWindow()->GetSelectionService()); connect(m_SelectionServiceConnector3.get(), &QmitkSelectionServiceConnector::ServiceSelectionChanged, m_Controls.singleSlot, &QmitkSingleNodeSelectionWidget::SetCurrentSelection); } else { m_SelectionServiceConnector3->RemovePostSelectionListener(); disconnect(m_SelectionServiceConnector3.get(), &QmitkSelectionServiceConnector::ServiceSelectionChanged, m_Controls.singleSlot, &QmitkSingleNodeSelectionWidget::SetCurrentSelection); } } void QmitkDataStorageViewerTestView::SetAsSelectionProvider4(bool checked) { if (checked) { m_SelectionServiceConnector4->SetAsSelectionProvider(GetSite()->GetSelectionProvider().Cast().GetPointer()); connect(m_Controls.multiSlot, SIGNAL(CurrentSelectionChanged(QList)), m_SelectionServiceConnector4.get(), SLOT(ChangeServiceSelection(QList))); } else { m_SelectionServiceConnector4->RemoveAsSelectionProvider(); disconnect(m_Controls.multiSlot, SIGNAL(CurrentSelectionChanged(QList)), m_SelectionServiceConnector4.get(), SLOT(ChangeServiceSelection(QList))); } } void QmitkDataStorageViewerTestView::SetAsSelectionListener4(bool checked) { if (checked) { m_SelectionServiceConnector4->AddPostSelectionListener(GetSite()->GetWorkbenchWindow()->GetSelectionService()); connect(m_SelectionServiceConnector4.get(), &QmitkSelectionServiceConnector::ServiceSelectionChanged, m_Controls.multiSlot, &QmitkMultiNodeSelectionWidget::SetCurrentSelection); } else { m_SelectionServiceConnector4->RemovePostSelectionListener(); disconnect(m_SelectionServiceConnector4.get(), &QmitkSelectionServiceConnector::ServiceSelectionChanged, m_Controls.multiSlot, &QmitkMultiNodeSelectionWidget::SetCurrentSelection); } } void QmitkDataStorageViewerTestView::OnOnlyImages(bool checked) { if (checked) { m_Controls.singleSlot->SetNodePredicate(mitk::NodePredicateDataType::New("Image")); } else { m_Controls.singleSlot->SetNodePredicate(nullptr); } -}; +} void QmitkDataStorageViewerTestView::OnOnlyImages2(bool checked) { if (checked) { m_Controls.multiSlot->SetNodePredicate(mitk::NodePredicateDataType::New("Image")); m_Controls.multiSlot->SetInvalidInfo(QString("InvalidInfo: is displayed for invalid states. Only images allowed!")); } else { m_Controls.multiSlot->SetNodePredicate(nullptr); m_Controls.multiSlot->SetInvalidInfo(QString("InvalidInfo: is displayed for invalid states")); } }; void QmitkDataStorageViewerTestView::OnOnlyUneven(bool checked) { if (checked) { auto checkFunction = [](const QmitkMultiNodeSelectionWidget::NodeList & nodes) { if (!(nodes.size() % 2)) { std::stringstream ss; ss << "

Invalid selection.

The number of selected nodes must be even! the current number is " << nodes.size() << ".

"; return ss.str(); } return std::string(); }; m_Controls.multiSlot->SetSelectionCheckFunction(checkFunction); } else { auto checkFunction = [](const QmitkMultiNodeSelectionWidget::NodeList & /*nodes*/) { return std::string(); }; m_Controls.multiSlot->SetSelectionCheckFunction(checkFunction); } -}; +}