diff --git a/Plugins/org.mitk.gui.qt.common/src/QmitkNodeSelectionDialog.cpp b/Plugins/org.mitk.gui.qt.common/src/QmitkNodeSelectionDialog.cpp index aa8adaac9f..56e426b8bf 100644 --- a/Plugins/org.mitk.gui.qt.common/src/QmitkNodeSelectionDialog.cpp +++ b/Plugins/org.mitk.gui.qt.common/src/QmitkNodeSelectionDialog.cpp @@ -1,278 +1,287 @@ /*============================================================================ 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 "QmitkNodeSelectionDialog.h" #include #include #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) { m_Controls.setupUi(this); m_CheckFunction = [](const NodeList &) { return ""; }; auto providers = mitk::DataStorageInspectorGenerator::GetProviders(); auto visibleProviders = mitk::GetVisibleDataStorageInspectors(); auto preferredID = mitk::GetPreferredDataStorageInspector(); 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)); ++order; } } int preferredIndex = 0; bool preferredFound = false; for (auto proIter : visibleProviders) { auto finding = providers.find(proIter.second); if (finding != providers.end()) { if (finding->second->GetInspectorID() != QmitkDataStorageFavoriteNodesInspector::INSPECTOR_ID() && finding->second->GetInspectorID() != QmitkDataStorageSelectionHistoryInspector::INSPECTOR_ID()) { auto provider = finding->second; this->AddPanel(provider, preferredID, preferredFound, preferredIndex); } } else { MITK_DEBUG << "No provider registered for inspector that is defined as visible in the preferences. Illegal inspector ID: " << proIter.second; } } if (mitk::GetShowFavoritesInspector()) { auto favoritesPorvider = mitk::DataStorageInspectorGenerator::GetProvider(QmitkDataStorageFavoriteNodesInspector::INSPECTOR_ID()); if (favoritesPorvider != nullptr) { this->AddPanel(favoritesPorvider, preferredID, preferredFound, preferredIndex); } } if (mitk::GetShowHistoryInspector()) { auto historyPorvider = mitk::DataStorageInspectorGenerator::GetProvider(QmitkDataStorageSelectionHistoryInspector::INSPECTOR_ID()); if (historyPorvider != nullptr) { this->AddPanel(historyPorvider, preferredID, preferredFound, preferredIndex); } } m_Controls.tabWidget->setCurrentIndex(preferredIndex); this->setWindowTitle(title); this->setToolTip(hint); m_Controls.hint->setText(hint); m_Controls.hint->setVisible(!hint.isEmpty()); if(hint.isEmpty()) { m_Controls.layoutHint->setContentsMargins(0, 0, 0, 0); } else { m_Controls.layoutHint->setContentsMargins(6, 6, 6, 6); } this->SetErrorText(""); m_Controls.btnAddToFav->setIcon(berry::QtStyleManager::ThemeIcon(QStringLiteral(":/Qmitk/favorite_add.svg"))); connect(m_Controls.btnAddToFav, &QPushButton::clicked, this, &QmitkNodeSelectionDialog::OnFavoriteNodesButtonClicked); connect(m_Controls.buttonBox, &QDialogButtonBox::accepted, this, &QmitkNodeSelectionDialog::OnOK); connect(m_Controls.buttonBox, &QDialogButtonBox::rejected, this, &QmitkNodeSelectionDialog::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(const mitk::NodePredicateBase* nodePredicate) { if (m_NodePredicate != nodePredicate) { m_NodePredicate = nodePredicate; for (auto panel : m_Panels) { panel->SetNodePredicate(m_NodePredicate); } } } const mitk::NodePredicateBase* QmitkNodeSelectionDialog::GetNodePredicate() const { return m_NodePredicate; } QmitkNodeSelectionDialog::NodeList QmitkNodeSelectionDialog::GetSelectedNodes() const { return m_SelectedNodes; } void QmitkNodeSelectionDialog::SetSelectionCheckFunction(const SelectionCheckFunctionType &checkFunction) { m_CheckFunction = checkFunction; auto checkResponse = m_CheckFunction(m_SelectedNodes); SetErrorText(checkResponse); m_Controls.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(checkResponse.empty()); } void QmitkNodeSelectionDialog::SetErrorText(const std::string& checkResponse) { m_Controls.error->setText(QString::fromStdString(checkResponse)); m_Controls.error->setVisible(!checkResponse.empty()); if (checkResponse.empty()) { m_Controls.layoutError->setContentsMargins(0, 0, 0, 0); } else { m_Controls.layoutError->setContentsMargins(6, 6, 6, 6); } } bool QmitkNodeSelectionDialog::GetSelectOnlyVisibleNodes() const { return m_SelectOnlyVisibleNodes; } void QmitkNodeSelectionDialog::SetSelectionMode(SelectionMode mode) { m_SelectionMode = mode; for (auto panel : m_Panels) { panel->SetSelectionMode(mode); } } QmitkNodeSelectionDialog::SelectionMode QmitkNodeSelectionDialog::GetSelectionMode() const { return m_SelectionMode; } 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; auto checkResponse = m_CheckFunction(m_SelectedNodes); SetErrorText(checkResponse); m_Controls.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(checkResponse.empty()); for (auto panel : m_Panels) { panel->SetCurrentSelection(selectedNodes); } } void QmitkNodeSelectionDialog::OnSelectionChanged(NodeList selectedNodes) { SetCurrentSelection(selectedNodes); emit CurrentSelectionChanged(selectedNodes); } void QmitkNodeSelectionDialog::OnFavoriteNodesButtonClicked() { for (auto node : m_SelectedNodes) { node->SetBoolProperty("org.mitk.selection.favorite", true); } } void QmitkNodeSelectionDialog::OnOK() { for (auto node : m_SelectedNodes) { QmitkDataStorageSelectionHistoryInspector::AddNodeToHistory(node); } this->accept(); } void QmitkNodeSelectionDialog::OnCancel() { this->reject(); } void QmitkNodeSelectionDialog::AddPanel(const mitk::IDataStorageInspectorProvider * provider, const mitk::IDataStorageInspectorProvider::InspectorIDType& preferredID, bool &preferredFound, int &preferredIndex) { auto inspector = provider->CreateInspector(); QString name = QString::fromStdString(provider->GetInspectorDisplayName()); QString desc = QString::fromStdString(provider->GetInspectorDescription()); inspector->setParent(this); inspector->SetSelectionMode(m_SelectionMode); auto tabPanel = new QWidget(); tabPanel->setObjectName(QString("tab_") + name); tabPanel->setToolTip(desc); auto verticalLayout = new QVBoxLayout(tabPanel); verticalLayout->setSpacing(0); verticalLayout->setContentsMargins(0, 0, 0, 0); verticalLayout->addWidget(inspector); auto panelPos = m_Controls.tabWidget->insertTab(m_Controls.tabWidget->count(), tabPanel, name); auto icon = provider->GetInspectorIcon(); if (!icon.isNull()) { m_Controls.tabWidget->setTabIcon(panelPos, icon); } m_Panels.push_back(inspector); connect(inspector, &QmitkAbstractDataStorageInspector::CurrentSelectionChanged, this, &QmitkNodeSelectionDialog::OnSelectionChanged); + connect(inspector->GetView(), &QAbstractItemView::doubleClicked, this, &QmitkNodeSelectionDialog::OnDoubleClicked); preferredFound = preferredFound || provider->GetInspectorID() == preferredID; if (!preferredFound) { ++preferredIndex; } } + +void QmitkNodeSelectionDialog::OnDoubleClicked(const QModelIndex& /*index*/) +{ + if (!m_SelectedNodes.empty()) + { + this->OnOK(); + } +} diff --git a/Plugins/org.mitk.gui.qt.common/src/QmitkNodeSelectionDialog.h b/Plugins/org.mitk.gui.qt.common/src/QmitkNodeSelectionDialog.h index 91bafa3581..25ccda870d 100644 --- a/Plugins/org.mitk.gui.qt.common/src/QmitkNodeSelectionDialog.h +++ b/Plugins/org.mitk.gui.qt.common/src/QmitkNodeSelectionDialog.h @@ -1,142 +1,143 @@ /*============================================================================ 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_NODE_SELECTION_DIALOG_H #define QMITK_NODE_SELECTION_DIALOG_H #include #include #include #include "mitkIDataStorageInspectorProvider.h" #include #include "org_mitk_gui_qt_common_Export.h" #include "ui_QmitkNodeSelectionDialog.h" #include #include /** * \class QmitkNodeSelectionDialog * \brief Widget that allows to show and edit the content of an mitk::IsoDoseLevel instance. */ 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. * * @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. * * @param nodePredicate A pointer to node predicate. */ virtual void SetNodePredicate(const mitk::NodePredicateBase* nodePredicate); const mitk::NodePredicateBase* GetNodePredicate() const; using NodeList = QList; NodeList GetSelectedNodes() const; /** * @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. */ using SelectionCheckFunctionType = std::function; /** * @brief A selection check function can be set. If set the dialog uses this function to check the made/set selection. * If the selection is valid, everything is fine. * If the selection is indicated as invalid, the dialog will display the selection check function error message. */ void SetSelectionCheckFunction(const SelectionCheckFunctionType &checkFunction); bool GetSelectOnlyVisibleNodes() const; using SelectionMode = QAbstractItemView::SelectionMode; 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 * * @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'). * * @param nodes A list of data nodes that should be newly selected. */ void SetCurrentSelection(NodeList selectedNodes); protected Q_SLOTS: void OnSelectionChanged(NodeList selectedNodes); void OnFavoriteNodesButtonClicked(); void OnOK(); void OnCancel(); + void OnDoubleClicked(const QModelIndex& index); protected: void SetErrorText(const std::string& checkResponse); void AddPanel(const mitk::IDataStorageInspectorProvider* provider, const mitk::IDataStorageInspectorProvider::InspectorIDType &preferredID, bool &preferredFound, int &preferredIndex); mitk::WeakPointer m_DataStorage; mitk::NodePredicateBase::ConstPointer m_NodePredicate; bool m_SelectOnlyVisibleNodes; NodeList m_SelectedNodes; SelectionCheckFunctionType m_CheckFunction; SelectionMode m_SelectionMode; using PanelVectorType = std::vector; PanelVectorType m_Panels; QPushButton* m_FavoriteNodesButton; Ui_QmitkNodeSelectionDialog m_Controls; }; #endif // QMITK_NODE_SELECTION_DIALOG_H