diff --git a/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkPropertyTreeView.cpp b/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkPropertyTreeView.cpp index e243416aa3..ad4cf8c67b 100644 --- a/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkPropertyTreeView.cpp +++ b/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkPropertyTreeView.cpp @@ -1,394 +1,405 @@ /*============================================================================ 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 "QmitkAddNewPropertyDialog.h" #include "QmitkPropertyItemDelegate.h" #include "QmitkPropertyItemModel.h" #include "QmitkPropertyItemSortFilterProxyModel.h" #include "QmitkPropertyTreeView.h" #include #include #include #include #include #include #include namespace { QmitkAbstractNodeSelectionWidget::NodeList GetInitialSelection(berry::ISelection::ConstPointer selection) { if (selection.IsNotNull() && !selection->IsEmpty()) { auto* dataNodeSelection = dynamic_cast(selection.GetPointer()); if (nullptr != dataNodeSelection) { auto firstSelectedDataNode = dataNodeSelection->GetSelectedDataNodes().front(); if (firstSelectedDataNode.IsNotNull()) { QmitkAbstractNodeSelectionWidget::NodeList initialSelection; initialSelection.push_back(firstSelectedDataNode); return initialSelection; } } } return QmitkAbstractNodeSelectionWidget::NodeList(); } } const std::string QmitkPropertyTreeView::VIEW_ID = "org.mitk.views.properties"; QmitkPropertyTreeView::QmitkPropertyTreeView() : m_PropertyAliases(mitk::CoreServices::GetPropertyAliases(nullptr), nullptr), m_PropertyDescriptions(mitk::CoreServices::GetPropertyDescriptions(nullptr), nullptr), m_PropertyPersistence(mitk::CoreServices::GetPropertyPersistence(nullptr), nullptr), m_ProxyModel(nullptr), m_Model(nullptr), m_Delegate(nullptr), m_Renderer(nullptr) { } QmitkPropertyTreeView::~QmitkPropertyTreeView() { } void QmitkPropertyTreeView::SetFocus() { m_Controls.filterLineEdit->setFocus(); } -void QmitkPropertyTreeView::RenderWindowPartActivated(mitk::IRenderWindowPart* renderWindowPart) +void QmitkPropertyTreeView::ResetRenderWindowComboBox() { - if (m_Controls.propertyListComboBox->count() == 2) - { - QHash renderWindows = renderWindowPart->GetQmitkRenderWindows(); + m_Controls.propertyListComboBox->clear(); + m_Controls.propertyListComboBox->addItem("Data node: common"); + m_Controls.propertyListComboBox->addItem("Base data"); +} - Q_FOREACH(QString renderWindow, renderWindows.keys()) - { - m_Controls.propertyListComboBox->insertItem(m_Controls.propertyListComboBox->count() - 1, QString("Data node: ") + renderWindow); - } +void QmitkPropertyTreeView::UpdateRenderWindowComboBox(mitk::IRenderWindowPart* renderWindowPart) +{ + this->ResetRenderWindowComboBox(); + + QHash renderWindows = renderWindowPart->GetQmitkRenderWindows(); + + for (auto renderWindowName : renderWindows.keys()) + { + m_Controls.propertyListComboBox->insertItem(m_Controls.propertyListComboBox->count() - 1, QString("Data node: ") + renderWindowName); } } +void QmitkPropertyTreeView::RenderWindowPartActivated(mitk::IRenderWindowPart* renderWindowPart) +{ + this->UpdateRenderWindowComboBox(renderWindowPart); +} + +void QmitkPropertyTreeView::RenderWindowPartInputChanged(mitk::IRenderWindowPart* renderWindowPart) +{ + this->UpdateRenderWindowComboBox(renderWindowPart); +} + void QmitkPropertyTreeView::RenderWindowPartDeactivated(mitk::IRenderWindowPart*) { - if (m_Controls.propertyListComboBox->count() > 2) - { - m_Controls.propertyListComboBox->clear(); - m_Controls.propertyListComboBox->addItem("Data node: common"); - m_Controls.propertyListComboBox->addItem("Base data"); - } + this->ResetRenderWindowComboBox(); } void QmitkPropertyTreeView::CreateQtPartControl(QWidget* parent) { m_Controls.setupUi(parent); m_Controls.propertyListComboBox->addItem("Data node: common"); mitk::IRenderWindowPart* renderWindowPart = this->GetRenderWindowPart(); if (renderWindowPart != nullptr) { QHash renderWindows = renderWindowPart->GetQmitkRenderWindows(); for(const auto& renderWindow : renderWindows.keys()) { m_Controls.propertyListComboBox->addItem(QString("Data node: ") + renderWindow); } } m_Controls.propertyListComboBox->addItem("Base data"); m_Controls.newButton->setEnabled(false); this->HideAllIcons(); m_ProxyModel = new QmitkPropertyItemSortFilterProxyModel(m_Controls.treeView); m_Model = new QmitkPropertyItemModel(m_ProxyModel); m_ProxyModel->setSourceModel(m_Model); m_ProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive); m_ProxyModel->setSortCaseSensitivity(Qt::CaseInsensitive); m_ProxyModel->setDynamicSortFilter(true); m_Delegate = new QmitkPropertyItemDelegate(m_Controls.treeView); m_Controls.singleSlot->SetDataStorage(GetDataStorage()); m_Controls.singleSlot->SetSelectionIsOptional(true); m_Controls.singleSlot->SetEmptyInfo(QString("Please select a data node")); m_Controls.singleSlot->SetPopUpTitel(QString("Select data node")); m_SelectionServiceConnector = std::make_unique(); SetAsSelectionListener(true); m_Controls.filterLineEdit->setClearButtonEnabled(true); m_Controls.treeView->setItemDelegateForColumn(1, m_Delegate); m_Controls.treeView->setModel(m_ProxyModel); m_Controls.treeView->setColumnWidth(0, 160); m_Controls.treeView->sortByColumn(0, Qt::AscendingOrder); m_Controls.treeView->setSelectionBehavior(QAbstractItemView::SelectRows); m_Controls.treeView->setSelectionMode(QAbstractItemView::SingleSelection); m_Controls.treeView->setEditTriggers(QAbstractItemView::SelectedClicked | QAbstractItemView::DoubleClicked); const int ICON_SIZE = 32; auto icon = berry::QtStyleManager::ThemeIcon(QStringLiteral(":/org_mitk_icons/icons/awesome/scalable/tags.svg")); m_Controls.tagsLabel->setPixmap(icon.pixmap(ICON_SIZE)); icon = berry::QtStyleManager::ThemeIcon(QStringLiteral(":/org_mitk_icons/icons/awesome/scalable/tag.svg")); m_Controls.tagLabel->setPixmap(icon.pixmap(ICON_SIZE)); icon = berry::QtStyleManager::ThemeIcon(QStringLiteral(":/org_mitk_icons/icons/awesome/scalable/actions/document-save.svg")); m_Controls.saveLabel->setPixmap(icon.pixmap(ICON_SIZE)); connect(m_Controls.singleSlot, &QmitkSingleNodeSelectionWidget::CurrentSelectionChanged, this, &QmitkPropertyTreeView::OnCurrentSelectionChanged); connect(m_Controls.filterLineEdit, &QLineEdit::textChanged, this, &QmitkPropertyTreeView::OnFilterTextChanged); connect(m_Controls.propertyListComboBox, static_cast(&QComboBox::currentIndexChanged), this, &QmitkPropertyTreeView::OnPropertyListChanged); connect(m_Controls.newButton, &QPushButton::clicked, this, &QmitkPropertyTreeView::OnAddNewProperty); connect(m_Controls.treeView->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &QmitkPropertyTreeView::OnCurrentRowChanged); connect(m_Model, &QmitkPropertyItemModel::modelReset, this, &QmitkPropertyTreeView::OnModelReset); auto selection = this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->GetSelection(); auto currentSelection = GetInitialSelection(selection); if (!currentSelection.isEmpty()) m_Controls.singleSlot->SetCurrentSelection(currentSelection); } void QmitkPropertyTreeView::SetAsSelectionListener(bool checked) { if (checked) { m_SelectionServiceConnector->AddPostSelectionListener(GetSite()->GetWorkbenchWindow()->GetSelectionService()); connect(m_SelectionServiceConnector.get(), &QmitkSelectionServiceConnector::ServiceSelectionChanged, m_Controls.singleSlot, &QmitkSingleNodeSelectionWidget::SetCurrentSelection); } else { m_SelectionServiceConnector->RemovePostSelectionListener(); disconnect(m_SelectionServiceConnector.get(), &QmitkSelectionServiceConnector::ServiceSelectionChanged, m_Controls.singleSlot, &QmitkSingleNodeSelectionWidget::SetCurrentSelection); } } QString QmitkPropertyTreeView::GetPropertyNameOrAlias(const QModelIndex& index) { QString propertyName; if (index.isValid()) { QModelIndex current = index; while (current.isValid()) { QString name = m_ProxyModel->data(m_ProxyModel->index(current.row(), 0, current.parent())).toString(); propertyName.prepend(propertyName.isEmpty() ? name : name.append('.')); current = current.parent(); } } return propertyName; } void QmitkPropertyTreeView::OnCurrentSelectionChanged(QList nodes) { if (nodes.empty() || nodes.front().IsNull()) { m_SelectedNode = nullptr; this->SetPartName("Properties"); m_Model->SetPropertyList(nullptr); m_Delegate->SetPropertyList(nullptr); m_Controls.newButton->setEnabled(false); return; } // node is selected, create tree with node properties m_SelectedNode = nodes.front(); mitk::PropertyList* propertyList = m_Model->GetPropertyList(); if (m_Renderer == nullptr && m_Controls.propertyListComboBox->currentText() == "Base data") { propertyList = m_SelectedNode->GetData() != nullptr ? m_SelectedNode->GetData()->GetPropertyList() : nullptr; } else { propertyList = m_SelectedNode->GetPropertyList(m_Renderer); } QString selectionClassName = m_SelectedNode->GetData() != nullptr ? m_SelectedNode->GetData()->GetNameOfClass() : ""; m_SelectionClassName = selectionClassName.toStdString(); m_Model->SetPropertyList(propertyList, selectionClassName); m_Delegate->SetPropertyList(propertyList); m_Controls.newButton->setEnabled(true); m_Controls.treeView->expandAll(); } void QmitkPropertyTreeView::HideAllIcons() { m_Controls.tagLabel->hide(); m_Controls.tagsLabel->hide(); m_Controls.saveLabel->hide(); } void QmitkPropertyTreeView::OnCurrentRowChanged(const QModelIndex& current, const QModelIndex&) { if (current.isValid()) { QString name = this->GetPropertyNameOrAlias(current); if (!name.isEmpty()) { QString alias; bool isTrueName = true; std::string trueName = m_PropertyAliases->GetPropertyName(name.toStdString()); if (trueName.empty() && !m_SelectionClassName.empty()) trueName = m_PropertyAliases->GetPropertyName(name.toStdString(), m_SelectionClassName); if (!trueName.empty()) { alias = name; name = QString::fromStdString(trueName); isTrueName = false; } QString description = QString::fromStdString(m_PropertyDescriptions->GetDescription(name.toStdString())); std::vector aliases; if (!isTrueName) { aliases = m_PropertyAliases->GetAliases(name.toStdString(), m_SelectionClassName); if (aliases.empty() && !m_SelectionClassName.empty()) aliases = m_PropertyAliases->GetAliases(name.toStdString()); } bool isPersistent = m_PropertyPersistence->HasInfo(name.toStdString()); if (!description.isEmpty() || !aliases.empty() || isPersistent) { QString customizedDescription; if (!aliases.empty()) { customizedDescription = "

" + name + "

"; std::size_t numAliases = aliases.size(); std::size_t lastAlias = numAliases - 1; for (std::size_t i = 0; i < numAliases; ++i) { customizedDescription += i != lastAlias ? "
" : "
"; customizedDescription += QString::fromStdString(aliases[i]) + "
"; } } else { customizedDescription = "

" + name + "

"; } if (!description.isEmpty()) customizedDescription += "

" + description + "

"; m_Controls.tagsLabel->setVisible(!aliases.empty() && aliases.size() > 1); m_Controls.tagLabel->setVisible(!aliases.empty() && aliases.size() == 1); m_Controls.saveLabel->setVisible(isPersistent); m_Controls.descriptionLabel->setText(customizedDescription); m_Controls.descriptionLabel->show(); return; } } } m_Controls.descriptionLabel->hide(); this->HideAllIcons(); } void QmitkPropertyTreeView::OnPropertyListChanged(int index) { if (index == -1) return; QString renderer = m_Controls.propertyListComboBox->itemText(index); if (renderer.startsWith("Data node: ")) renderer = QString::fromStdString(renderer.toStdString().substr(11)); m_Renderer = nullptr; if (renderer != "common" && renderer != "Base data") { auto* renderWindowPart = this->GetRenderWindowPart(); if (nullptr != renderWindowPart) m_Renderer = renderWindowPart->GetQmitkRenderWindow(renderer)->GetRenderer(); } QList nodes; if (m_SelectedNode.IsNotNull()) nodes << m_SelectedNode; this->OnCurrentSelectionChanged(nodes); } void QmitkPropertyTreeView::OnAddNewProperty() { std::unique_ptr dialog(m_Controls.propertyListComboBox->currentText() != "Base data" ? new QmitkAddNewPropertyDialog(m_SelectedNode, m_Renderer) : new QmitkAddNewPropertyDialog(m_SelectedNode->GetData())); if (dialog->exec() == QDialog::Accepted) this->m_Model->Update(); } void QmitkPropertyTreeView::OnFilterTextChanged(const QString& filter) { m_ProxyModel->setFilterWildcard(filter); m_Controls.treeView->expandAll(); } void QmitkPropertyTreeView::OnModelReset() { m_Controls.treeView->expandAll(); m_Controls.descriptionLabel->hide(); this->HideAllIcons(); } diff --git a/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkPropertyTreeView.h b/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkPropertyTreeView.h index 7750155927..6156185679 100644 --- a/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkPropertyTreeView.h +++ b/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkPropertyTreeView.h @@ -1,95 +1,98 @@ /*============================================================================ 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 QmitkPropertyTreeView_h #define QmitkPropertyTreeView_h #include // mitk core module #include #include // mitk gui common plugin #include // mitk gui qt common plugin #include #include "QmitkSelectionServiceConnector.h" class QmitkPropertyItemDelegate; class QmitkPropertyItemModel; class QmitkPropertyItemSortFilterProxyModel; namespace mitk { class IPropertyAliases; class IPropertyDescriptions; class IPropertyPersistence; } class QmitkPropertyTreeView : public QmitkAbstractView, public mitk::IRenderWindowPartListener { Q_OBJECT public: static const std::string VIEW_ID; berryObjectMacro(QmitkPropertyTreeView); QmitkPropertyTreeView(); ~QmitkPropertyTreeView() override; void SetFocus() override; void RenderWindowPartActivated(mitk::IRenderWindowPart* renderWindowPart) override; + void RenderWindowPartInputChanged(mitk::IRenderWindowPart*) override; void RenderWindowPartDeactivated(mitk::IRenderWindowPart*) override; protected: void CreateQtPartControl(QWidget* parent) override; private: + void ResetRenderWindowComboBox(); + void UpdateRenderWindowComboBox(mitk::IRenderWindowPart* renderWindowPart); void SetAsSelectionListener(bool checked); QString GetPropertyNameOrAlias(const QModelIndex& index); void OnCurrentSelectionChanged(QList nodes); void HideAllIcons(); private Q_SLOTS: void OnCurrentRowChanged(const QModelIndex& current, const QModelIndex& previous); void OnPropertyListChanged(int index); void OnAddNewProperty(); void OnFilterTextChanged(const QString& filter); void OnModelReset(); private: std::string m_SelectionClassName; mitk::CoreServicePointer m_PropertyAliases; mitk::CoreServicePointer m_PropertyDescriptions; mitk::CoreServicePointer m_PropertyPersistence; Ui::QmitkPropertyTreeView m_Controls; QmitkPropertyItemSortFilterProxyModel* m_ProxyModel; QmitkPropertyItemModel* m_Model; QmitkPropertyItemDelegate* m_Delegate; mitk::DataNode::Pointer m_SelectedNode; mitk::BaseRenderer* m_Renderer; std::unique_ptr m_SelectionServiceConnector; }; #endif