diff --git a/Plugins/org.mitk.gui.qt.common/src/QmitkAbstractNodeSelectionWidget.cpp b/Plugins/org.mitk.gui.qt.common/src/QmitkAbstractNodeSelectionWidget.cpp index 87daa45a43..5c1fd9476b 100644 --- a/Plugins/org.mitk.gui.qt.common/src/QmitkAbstractNodeSelectionWidget.cpp +++ b/Plugins/org.mitk.gui.qt.common/src/QmitkAbstractNodeSelectionWidget.cpp @@ -1,161 +1,178 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "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() { if (!m_DataStorage.IsExpired()) { auto dataStorage = m_DataStorage.Lock(); // remove Listener for the data storage itself dataStorage->RemoveObserver(m_DataStorageDeletedTag); - // remove listener from data storage + // remove "add node listener" from data storage + dataStorage->AddNodeEvent.RemoveListener( + mitk::MessageDelegate1(this, &QmitkAbstractNodeSelectionWidget::NodeAddedToStorage)); + + // remove "remove node listener" from data storage dataStorage->RemoveNodeEvent.RemoveListener( mitk::MessageDelegate1(this, &QmitkAbstractNodeSelectionWidget::NodeRemovedFromStorage)); } } void QmitkAbstractNodeSelectionWidget::SetDataStorage(mitk::DataStorage* dataStorage) { if (m_DataStorage == dataStorage) { return; } if (!m_DataStorage.IsExpired()) { auto oldStorage = m_DataStorage.Lock(); // remove Listener for the data storage itself oldStorage->RemoveObserver(m_DataStorageDeletedTag); - // remove listener from old data storage + // remove "add node listener" from old data storage + oldStorage->AddNodeEvent.RemoveListener( + mitk::MessageDelegate1(this, &QmitkAbstractNodeSelectionWidget::NodeAddedToStorage)); + + // remove "remove node listener" from old data storage oldStorage->RemoveNodeEvent.RemoveListener( mitk::MessageDelegate1(this, &QmitkAbstractNodeSelectionWidget::NodeRemovedFromStorage)); } m_DataStorage = dataStorage; if (!m_DataStorage.IsExpired()) { auto newStorage = m_DataStorage.Lock(); // add Listener for the data storage itself auto command = itk::SimpleMemberCommand::New(); command->SetCallbackFunction(this, &QmitkAbstractNodeSelectionWidget::SetDataStorageDeleted); m_DataStorageDeletedTag = newStorage->AddObserver(itk::DeleteEvent(), command); - // add listener for new data storage + // add "add node listener" for new data storage + newStorage->AddNodeEvent.AddListener( + mitk::MessageDelegate1(this, &QmitkAbstractNodeSelectionWidget::NodeAddedToStorage)); + + // add remove node listener for new data storage newStorage->RemoveNodeEvent.AddListener( mitk::MessageDelegate1(this, &QmitkAbstractNodeSelectionWidget::NodeRemovedFromStorage)); } // update model if the data storage has been changed m_DataStorage = dataStorage; this->OnDataStorageChanged(); this->UpdateInfo(); } void QmitkAbstractNodeSelectionWidget::SetNodePredicate(const mitk::NodePredicateBase* nodePredicate) { if (m_NodePredicate != nodePredicate) { m_NodePredicate = nodePredicate; this->OnNodePredicateChanged(nodePredicate); this->UpdateInfo(); } } const 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 = info; this->UpdateInfo(); } void QmitkAbstractNodeSelectionWidget::SetEmptyInfo(QString info) { m_EmptyInfo = info; 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(); } void QmitkAbstractNodeSelectionWidget::SetDataStorageDeleted() { this->SetDataStorage(nullptr); } + +void QmitkAbstractNodeSelectionWidget::NodeAddedToStorage(const mitk::DataNode* node) +{ + //default implementation does nothing; +} \ No newline at end of file diff --git a/Plugins/org.mitk.gui.qt.common/src/QmitkAbstractNodeSelectionWidget.h b/Plugins/org.mitk.gui.qt.common/src/QmitkAbstractNodeSelectionWidget.h index 8ff2e58afd..017cd17b6e 100644 --- a/Plugins/org.mitk.gui.qt.common/src/QmitkAbstractNodeSelectionWidget.h +++ b/Plugins/org.mitk.gui.qt.common/src/QmitkAbstractNodeSelectionWidget.h @@ -1,157 +1,166 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef QMITK_ABSTRACT_NODE_SELECTION_WIDGET_H #define QMITK_ABSTRACT_NODE_SELECTION_WIDGET_H #include #include #include #include "org_mitk_gui_qt_common_Export.h" #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); ~QmitkAbstractNodeSelectionWidget() override; /** * @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(const mitk::NodePredicateBase* nodePredicate); const 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); 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 * * @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'). * * @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*/ 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*/ 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*/ 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*/ 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.*/ void SetSelectionIsOptional(bool isOptional); protected: /**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(const mitk::NodePredicateBase* newPredicate) = 0; /**Member is called if the data storage has changed. Thus the selection might change to.*/ virtual void OnDataStorageChanged() = 0; + /**Member is called when a node is added to the storage. Default implementation does nothing. + Derived widgets can override the method if they want to react on new nodes in the storage.*/ + virtual void NodeAddedToStorage(const mitk::DataNode* node); + + /**Member is called when a node is removed from the storage. The removed node is passed as + variable. Derived classes have to implement this method to react on the fact that there selection + might change, because the removed node is part of there selection. */ virtual void NodeRemovedFromStorage(const mitk::DataNode* node) = 0; mitk::WeakPointer m_DataStorage; mitk::NodePredicateBase::ConstPointer m_NodePredicate; QString m_InvalidInfo; QString m_EmptyInfo; QString m_PopUpTitel; QString m_PopUpHint; + /** See documentation of SetSelectOnlyVisibleNodes for details*/ bool m_IsOptional; + /** See documentation of SetSelectionIsOptional for details*/ bool m_SelectOnlyVisibleNodes; private: /** Helper triggered on the storage delete event */ void SetDataStorageDeleted(); unsigned long m_DataStorageDeletedTag; }; #endif // QmitkAbstractNodeSelectionWidget_H diff --git a/Plugins/org.mitk.gui.qt.common/src/QmitkSingleNodeSelectionWidget.cpp b/Plugins/org.mitk.gui.qt.common/src/QmitkSingleNodeSelectionWidget.cpp index 2689d07b5f..4903728a49 100644 --- a/Plugins/org.mitk.gui.qt.common/src/QmitkSingleNodeSelectionWidget.cpp +++ b/Plugins/org.mitk.gui.qt.common/src/QmitkSingleNodeSelectionWidget.cpp @@ -1,258 +1,336 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "QmitkSingleNodeSelectionWidget.h" #include #include #include "QmitkNodeSelectionDialog.h" #include "QmitkNodeDetailsDialog.h" -QmitkSingleNodeSelectionWidget::QmitkSingleNodeSelectionWidget(QWidget* parent) : QmitkAbstractNodeSelectionWidget(parent) +QmitkSingleNodeSelectionWidget::QmitkSingleNodeSelectionWidget(QWidget* parent) : QmitkAbstractNodeSelectionWidget(parent), m_AutoSelectNewNodes(false) { 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) + if (m_DataStorage.IsExpired()) { - bool valid = true; - if (m_NodePredicate.IsNotNull()) - { - valid = m_NodePredicate->CheckNode(node); - } - if (valid) + auto storage = m_DataStorage.Lock(); + + for (auto node : nodes) { - result = node; - break; + bool valid = storage->Exists(node); + if (valid && 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(const mitk::NodePredicateBase* /*newPredicate*/) { + auto lastEmission = this->CompileEmitSelection(); + if (m_NodePredicate.IsNotNull() && m_SelectedNode.IsNotNull() && !m_NodePredicate->CheckNode(m_SelectedNode)) { m_SelectedNode = nullptr; } - if (m_SelectedNode.IsNull()) { m_SelectedNode = this->ExtractCurrentValidSelection(m_ExternalSelection); } + + this->DoAutoSelectIfNeeded(); + + this->EmitAndUpdateIfNeeded(lastEmission); }; void QmitkSingleNodeSelectionWidget::OnDataStorageChanged() { + auto lastEmission = this->CompileEmitSelection(); + + if (m_DataStorage.IsExpired()) + { + m_SelectedNode = nullptr; + } + else if (m_SelectedNode.IsNotNull()) + { + auto storage = m_DataStorage.Lock(); + + if (!storage->Exists(m_SelectedNode)) + { + m_SelectedNode = nullptr; + } + } + + if (m_SelectedNode.IsNull()) + { + m_SelectedNode = this->ExtractCurrentValidSelection(m_ExternalSelection); + } + + this->DoAutoSelectIfNeeded(); + + this->EmitAndUpdateIfNeeded(lastEmission); }; 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) { if (this->isEnabled()) { 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(); - } + this->EmitAndUpdateIfNeeded(lastEmission); } 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.btnSelect->SetSelectionIsOptional(m_IsOptional); 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; + this->EmitAndUpdateIfNeeded(lastEmission); +}; + +void QmitkSingleNodeSelectionWidget::DoAutoSelectIfNeeded() +{ + if (m_SelectedNode.IsNull() && m_AutoSelectNewNodes && !m_DataStorage.IsExpired()) + { + auto storage = m_DataStorage.Lock(); + if (m_NodePredicate.IsNotNull()) + { + m_SelectedNode = storage->GetNode(m_NodePredicate); + } + else + { + m_SelectedNode = nullptr; + auto nodes = storage->GetAll(); + if (!nodes->empty()) + { + m_SelectedNode = nodes->front(); + } + } + } +} + +void QmitkSingleNodeSelectionWidget::EmitAndUpdateIfNeeded(const NodeList& lastEmission) +{ auto newEmission = this->CompileEmitSelection(); if (!EqualNodeSelections(lastEmission, newEmission)) { - emit CurrentSelectionChanged(newEmission); this->UpdateInfo(); + emit CurrentSelectionChanged(newEmission); } }; + void QmitkSingleNodeSelectionWidget::SetCurrentSelection(NodeList selectedNodes) { auto lastEmission = this->CompileEmitSelection(); m_ExternalSelection = selectedNodes; m_SelectedNode = this->ExtractCurrentValidSelection(selectedNodes); - auto newEmission = this->CompileEmitSelection(); + this->DoAutoSelectIfNeeded(); - if (!EqualNodeSelections(lastEmission, newEmission)) + this->EmitAndUpdateIfNeeded(lastEmission); +}; + +void QmitkSingleNodeSelectionWidget::NodeAddedToStorage(const mitk::DataNode* node) +{ + if (m_SelectedNode.IsNull() && m_AutoSelectNewNodes && !m_DataStorage.IsExpired()) { - this->UpdateInfo(); - emit CurrentSelectionChanged(newEmission); + auto lastEmission = this->CompileEmitSelection(); + + this->DoAutoSelectIfNeeded(); + + this->EmitAndUpdateIfNeeded(lastEmission); } -}; +} void QmitkSingleNodeSelectionWidget::NodeRemovedFromStorage(const mitk::DataNode* node) { if (m_SelectedNode == node && node != nullptr) { m_SelectedNode = nullptr; + + this->DoAutoSelectIfNeeded(); + auto newEmission = this->CompileEmitSelection(); emit CurrentSelectionChanged(newEmission); this->UpdateInfo(); } } + +bool QmitkSingleNodeSelectionWidget::GetAutoSelectNewNodes() const +{ + return m_AutoSelectNewNodes; +} + +void QmitkSingleNodeSelectionWidget::SetAutoSelectNewNodes(bool autoSelect) +{ + m_AutoSelectNewNodes = autoSelect; + NodeAddedToStorage(nullptr); +} diff --git a/Plugins/org.mitk.gui.qt.common/src/QmitkSingleNodeSelectionWidget.h b/Plugins/org.mitk.gui.qt.common/src/QmitkSingleNodeSelectionWidget.h index ced9c700f0..8df76ec2d3 100644 --- a/Plugins/org.mitk.gui.qt.common/src/QmitkSingleNodeSelectionWidget.h +++ b/Plugins/org.mitk.gui.qt.common/src/QmitkSingleNodeSelectionWidget.h @@ -1,72 +1,87 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef 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 +* \brief Widget that represents a node selection of (max) one node. 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() override; mitk::DataNode::Pointer GetSelectedNode() const; + bool GetAutoSelectNewNodes() const; using NodeList = QmitkAbstractNodeSelectionWidget::NodeList; public Q_SLOTS: void SetSelectOnlyVisibleNodes(bool selectOnlyVisibleNodes) override; void SetCurrentSelection(NodeList selectedNodes) override; + /** Sets the auto selection mode (Default is false). + If auto select is true and the following conditions are fullfilled, the widget will + select a node automatically from the data storage: + - a data storage is set + - data storage contains at least one node that matches the given predicate + - no selection is set.*/ + void SetAutoSelectNewNodes(bool autoSelect); + protected Q_SLOTS: virtual void OnClearSelection(); protected: mitk::DataNode::Pointer ExtractCurrentValidSelection(const NodeList& nodes) const; NodeList CompileEmitSelection() const; bool eventFilter(QObject *obj, QEvent *ev) override; void EditSelection(); void UpdateInfo() override; void OnNodePredicateChanged(const mitk::NodePredicateBase* newPredicate) override; void OnDataStorageChanged() override; + void NodeAddedToStorage(const mitk::DataNode* node) override; void NodeRemovedFromStorage(const mitk::DataNode* node) override; + void DoAutoSelectIfNeeded(); + void EmitAndUpdateIfNeeded(const NodeList& lastEmission); + NodeList m_ExternalSelection; mitk::DataNode::Pointer m_SelectedNode; + /** See documentation of SetAutoSelectNewNodes for details*/ + bool m_AutoSelectNewNodes; Ui_QmitkSingleNodeSelectionWidget m_Controls; }; #endif // QmitkSingleNodeSelectionWidget_H diff --git a/Plugins/org.mitk.gui.qt.datastorageviewertest/src/internal/QmitkDataStorageViewerTestControls.ui b/Plugins/org.mitk.gui.qt.datastorageviewertest/src/internal/QmitkDataStorageViewerTestControls.ui index f6e396042d..52adcb5c86 100644 --- a/Plugins/org.mitk.gui.qt.datastorageviewertest/src/internal/QmitkDataStorageViewerTestControls.ui +++ b/Plugins/org.mitk.gui.qt.datastorageviewertest/src/internal/QmitkDataStorageViewerTestControls.ui @@ -1,193 +1,200 @@ QmitkDataStorageViewerTestControls 0 0 945 456 0 0 Data storage viewer test - - + + - Allow only images -(using NodePredicate feature and general invalid message) + Set as selection provider - - + + + + + - Set as selection listner + Only valid nodes - - + + Set as selection listener - - + + - Set as selection listner + Only valid nodes - - + + - Only valid nodes + Allow only images + + + + + + + Is Optional Set as selection provider - - - - - + + - Is Optional + Is Enabled + + + true - - - - - + + - Set as selection listener + Set as selection provider - - + + - Set as selection provider + Set as selection listener - - + + - Only valid nodes + Allow only uneven selection count +(using check funcktion feature) - - + + - Is Optional + Set as selection listner - - + + - Set as selection provider + Is Optional - - + + + + + - Allow only images + Set as selection listner 0 0 0 40 - - - - - + + - Allow only uneven selection count -(using check funcktion feature) + Is Enabled + + + true - - + + - Set as selection provider + Allow only images +(using NodePredicate feature and general invalid message) - - + + + + + - Is Enabled - - - true + Set as selection provider - - + + - Is Enabled - - - true + Auto select node QmitkSingleNodeSelectionWidget QWidget
QmitkSingleNodeSelectionWidget.h
1
QmitkMultiNodeSelectionWidget QWidget
QmitkMultiNodeSelectionWidget.h
1
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 1501292067..7ab9404e83 100644 --- a/Plugins/org.mitk.gui.qt.datastorageviewertest/src/internal/QmitkDataStorageViewerTestView.cpp +++ b/Plugins/org.mitk.gui.qt.datastorageviewertest/src/internal/QmitkDataStorageViewerTestView.cpp @@ -1,276 +1,277 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ // 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(QStringLiteral("EmptyInfo: Set this to display info in empty state")); m_Controls.singleSlot->SetInvalidInfo(QStringLiteral("InvalidInfo: is displayed for invalid states")); m_Controls.singleSlot->SetPopUpTitel(QStringLiteral("This is the definable caption. Choose your data now!")); m_Controls.singleSlot->SetPopUpHint(QStringLiteral("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(QStringLiteral("EmptyInfo: Set this to display info in empty state")); m_Controls.multiSlot->SetInvalidInfo(QStringLiteral("InvalidInfo: is displayed for invalid states")); m_Controls.multiSlot->SetPopUpTitel(QStringLiteral("This is the definable caption. Choose your data now!")); m_Controls.multiSlot->SetPopUpHint(QStringLiteral("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.checkAuto, SIGNAL(toggled(bool)), m_Controls.singleSlot, SLOT(SetAutoSelectNewNodes(bool))); connect(m_Controls.checkOnlyImages, SIGNAL(toggled(bool)), this, SLOT(OnOnlyImages(bool))); connect(m_Controls.checkEnabled, SIGNAL(toggled(bool)), m_Controls.singleSlot, SLOT(setEnabled(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))); connect(m_Controls.checkEnabled_2, SIGNAL(toggled(bool)), m_Controls.multiSlot, SLOT(setEnabled(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(QStringLiteral("InvalidInfo: is displayed for invalid states. Only images allowed!")); } else { m_Controls.multiSlot->SetNodePredicate(nullptr); m_Controls.multiSlot->SetInvalidInfo(QStringLiteral("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 uneven! 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); } };