diff --git a/Plugins/org.mitk.gui.qt.viewnavigator/src/QmitkPerspectiveItem.h b/Plugins/org.mitk.gui.qt.viewnavigator/src/QmitkPerspectiveItem.h index 84eea69df3..10ecc84c24 100644 --- a/Plugins/org.mitk.gui.qt.viewnavigator/src/QmitkPerspectiveItem.h +++ b/Plugins/org.mitk.gui.qt.viewnavigator/src/QmitkPerspectiveItem.h @@ -1,38 +1,38 @@ /*============================================================================ 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 QMITKPERSPECTIVEITEM_H #define QMITKPERSPECTIVEITEM_H #include #include class QmitkPerspectiveItem : public QStandardItem { public: - QmitkPerspectiveItem(QString string) + QmitkPerspectiveItem(const QString& string) : QStandardItem(string) { } - QmitkPerspectiveItem(const QIcon &icon, QString string) + QmitkPerspectiveItem(const QIcon& icon, const QString& string) : QStandardItem(icon, string) { } - berry::IPerspectiveDescriptor::Pointer m_Perspective; + berry::IPerspectiveDescriptor::Pointer m_ItemDescriptor; QStringList m_Tags; QString m_Description; }; #endif // QMITKPERSPECTIVEITEM_H diff --git a/Plugins/org.mitk.gui.qt.viewnavigator/src/QmitkViewItem.h b/Plugins/org.mitk.gui.qt.viewnavigator/src/QmitkViewItem.h index ac7464f384..26dd93c9c5 100644 --- a/Plugins/org.mitk.gui.qt.viewnavigator/src/QmitkViewItem.h +++ b/Plugins/org.mitk.gui.qt.viewnavigator/src/QmitkViewItem.h @@ -1,38 +1,38 @@ /*============================================================================ 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 QMITKVIEWITEM_H #define QMITKVIEWITEM_H #include #include class QmitkViewItem : public QStandardItem { public: - QmitkViewItem(QString string) + QmitkViewItem(const QString& string) : QStandardItem(string) { } - QmitkViewItem(const QIcon& icon, QString string) + QmitkViewItem(const QIcon& icon, const QString& string) : QStandardItem(icon, string) { } - berry::IViewDescriptor::Pointer m_View; + berry::IViewDescriptor::Pointer m_ItemDescriptor; QStringList m_Tags; QString m_Description; }; #endif // QMITKVIEWITEM_H diff --git a/Plugins/org.mitk.gui.qt.viewnavigator/src/QmitkViewNavigatorWidget.cpp b/Plugins/org.mitk.gui.qt.viewnavigator/src/QmitkViewNavigatorWidget.cpp index c0007c727a..1b378a4c41 100644 --- a/Plugins/org.mitk.gui.qt.viewnavigator/src/QmitkViewNavigatorWidget.cpp +++ b/Plugins/org.mitk.gui.qt.viewnavigator/src/QmitkViewNavigatorWidget.cpp @@ -1,738 +1,699 @@ /*============================================================================ 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. ============================================================================*/ // View navigator plugin #include #include #include // Blueberry #include #include #include #include #include #include #include #include // MITK #include // Qt #include #include #include #include class KeywordRegistry { public: KeywordRegistry() { berry::IExtensionRegistry* extensionPointService = berry::Platform::GetExtensionRegistry(); auto keywordExts = extensionPointService->GetConfigurationElementsFor("org.blueberry.ui.keywords"); for (auto keywordExtsIt = keywordExts.begin(); keywordExtsIt != keywordExts.end(); ++keywordExtsIt) { QString keywordId = (*keywordExtsIt)->GetAttribute("id"); QString keywordLabels = (*keywordExtsIt)->GetAttribute("label"); m_Keywords[keywordId].push_back(keywordLabels); } } QStringList GetKeywords(const QString& id) { return m_Keywords[id]; } QStringList GetKeywords(const QStringList& ids) { QStringList result; for (const auto& id : ids) { result.append(this->GetKeywords(id)); } return result; } private: QHash m_Keywords; }; class ClassFilterProxyModel : public QSortFilterProxyModel { public: ClassFilterProxyModel(QObject* parent = nullptr) : QSortFilterProxyModel(parent) { } bool filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const override { QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent); return hasToBeDisplayed(index); } private: bool displayElement(const QModelIndex index) const { QString type = sourceModel()->data(index, Qt::DisplayRole).toString(); QStandardItem* item = dynamic_cast(sourceModel())->itemFromIndex(index); if (type.contains(filterRegExp())) { return true; } QmitkViewItem* viewItem = dynamic_cast(item); if (nullptr != viewItem) { for (const auto& tag : viewItem->m_Tags) { if (tag.contains(filterRegExp())) { return true; } } if (viewItem->m_Description.contains(filterRegExp())) { return true; } } QmitkPerspectiveItem* perspectiveItem = dynamic_cast(item); if (nullptr != perspectiveItem) { for (const auto& tag : perspectiveItem->m_Tags) { if (tag.contains(filterRegExp())) { return true; } } if (perspectiveItem->m_Description.contains(filterRegExp())) { return true; } } return false; } bool hasToBeDisplayed(const QModelIndex index) const { bool result = false; if (sourceModel()->rowCount(index) > 0) { for (int i = 0; i < sourceModel()->rowCount(index); i++) { QModelIndex childIndex = sourceModel()->index(i, 0, index); if (!childIndex.isValid()) { break; } result = hasToBeDisplayed(childIndex); result |= displayElement(index); if (result) { break; } } } else { result = displayElement(index); } return result; } }; class ViewNavigatorPerspectiveListener: public berry::IPerspectiveListener { public: ViewNavigatorPerspectiveListener(QmitkViewNavigatorWidget* parent) : m_ParentWidget(parent) { } Events::Types GetPerspectiveEventTypes() const override { return Events::ACTIVATED | Events::SAVED_AS | Events::DEACTIVATED // remove the following line when command framework is finished | Events::CLOSED | Events::OPENED | Events::PART_CHANGED; } void PerspectiveActivated(const berry::IWorkbenchPage::Pointer& /*page*/, const berry::IPerspectiveDescriptor::Pointer& perspective) override { m_ParentWidget->m_ActivePerspective = perspective; m_ParentWidget->UpdateTreeList(); } void PerspectiveSavedAs(const berry::IWorkbenchPage::Pointer& /*page*/, const berry::IPerspectiveDescriptor::Pointer& /*oldPerspective*/, const berry::IPerspectiveDescriptor::Pointer& newPerspective) override { m_ParentWidget->m_ActivePerspective = newPerspective; m_ParentWidget->UpdateTreeList(); } void PerspectiveDeactivated(const berry::IWorkbenchPage::Pointer& /*page*/, const berry::IPerspectiveDescriptor::Pointer& /*perspective*/) override { m_ParentWidget->m_ActivePerspective = nullptr; } void PerspectiveOpened(const berry::IWorkbenchPage::Pointer& /*page*/, const berry::IPerspectiveDescriptor::Pointer& /*perspective*/) override { m_ParentWidget->UpdateTreeList(); } void PerspectiveClosed(const berry::IWorkbenchPage::Pointer& /*page*/, const berry::IPerspectiveDescriptor::Pointer& /*perspective*/) override { m_ParentWidget->m_ActivePerspective = nullptr; } using IPerspectiveListener::PerspectiveChanged; void PerspectiveChanged(const berry::IWorkbenchPage::Pointer& /*page*/, const berry::IPerspectiveDescriptor::Pointer& /*perspective*/, const berry::IWorkbenchPartReference::Pointer& partRef, const std::string& changeId) { if (changeId == "viewHide" && partRef->GetId() == "org.mitk.views.viewnavigator") berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->RemovePerspectiveListener(m_ParentWidget->m_PerspectiveListener.data()); else m_ParentWidget->UpdateTreeList(); } private: QmitkViewNavigatorWidget* m_ParentWidget; }; class ViewNavigatorViewListener: public berry::IPartListener { public: ViewNavigatorViewListener(QmitkViewNavigatorWidget* parent) : m_ParentWidget(parent) { } Events::Types GetPartEventTypes() const override { return Events::OPENED | Events::CLOSED; } void PartOpened(const berry::IWorkbenchPartReference::Pointer& partRef) override { if (partRef->GetId() != "org.mitk.views.viewnavigator") { m_ParentWidget->UpdateTreeList((partRef->GetPart(false)).GetPointer()); } else { m_ParentWidget->FillTreeList(); m_ParentWidget->UpdateTreeList(); } } void PartClosed(const berry::IWorkbenchPartReference::Pointer& partRef) override { if (partRef->GetId() != "org.mitk.views.viewnavigator") { m_ParentWidget->UpdateTreeList(); } } private: QmitkViewNavigatorWidget* m_ParentWidget; }; bool compareViews(const berry::IViewDescriptor::Pointer& a, const berry::IViewDescriptor::Pointer& b) { if (a.IsNull() || b.IsNull()) { return false; } return a->GetLabel().compare(b->GetLabel()) < 0; } bool comparePerspectives(const berry::IPerspectiveDescriptor::Pointer& a, const berry::IPerspectiveDescriptor::Pointer& b) { if (a.IsNull() || b.IsNull()) { return false; } return a->GetLabel().compare(b->GetLabel()) < 0; } bool compareQStandardItems(const QStandardItem* a, const QStandardItem* b) { if (nullptr == a || nullptr== b) { return false; } return a->text().compare(b->text()) < 0; } QmitkViewNavigatorWidget::QmitkViewNavigatorWidget(berry::IWorkbenchWindow::Pointer window, QWidget* parent, Qt::WindowFlags) : QWidget(parent) , m_Window(window) { this->CreateQtPartControl(this); } QmitkViewNavigatorWidget::~QmitkViewNavigatorWidget() { m_Window->RemovePerspectiveListener(m_PerspectiveListener.data()); m_Window->GetPartService()->RemovePartListener(m_ViewPartListener.data()); } void QmitkViewNavigatorWidget::SetFocus() { m_Controls.lineEdit->setFocus(); } void QmitkViewNavigatorWidget::UpdateTreeList(berry::IWorkbenchPart* workbenchPart) { berry::IWorkbenchPage::Pointer page = m_Window->GetActivePage(); if (page.IsNull()) { return; } berry::IPerspectiveDescriptor::Pointer currentPerspective = page->GetPerspective(); QList viewParts = page->GetViews(); // iterate over all tree items for (const auto& item : m_TreeModel->findItems("*", Qt::MatchWildcard | Qt::MatchRecursive)) { QFont font; // check if the item is a view item and if it is equal to any opened view QmitkViewItem* viewItem = dynamic_cast(item); if (nullptr != viewItem) { - if (nullptr != workbenchPart && workbenchPart->GetPartName() == viewItem->m_View->GetLabel()) + if (nullptr != workbenchPart && workbenchPart->GetPartName() == viewItem->m_ItemDescriptor->GetLabel()) { font.setBold(true); } else { for (const auto& viewPart : viewParts) { - if (viewPart->GetPartName() == viewItem->m_View->GetLabel()) + if (viewPart->GetPartName() == viewItem->m_ItemDescriptor->GetLabel()) { font.setBold(true); break; } } } viewItem->setFont(font); } else { // check if the item is a perspective item and if it is equal to the current perspective QmitkPerspectiveItem* perspectiveItem = dynamic_cast(item); if (nullptr != perspectiveItem) { - if (currentPerspective.IsNotNull() && currentPerspective->GetId() == perspectiveItem->m_Perspective->GetId()) + if (currentPerspective.IsNotNull() && currentPerspective->GetId() == perspectiveItem->m_ItemDescriptor->GetId()) { font.setBold(true); } perspectiveItem->setFont(font); } } } } bool QmitkViewNavigatorWidget::FillTreeList() { // initialize tree model m_TreeModel->clear(); - QStandardItem* treeRootItem = m_TreeModel->invisibleRootItem(); - - // get all available perspectives - berry::IPerspectiveRegistry* perspRegistry = berry::PlatformUI::GetWorkbench()->GetPerspectiveRegistry(); - QList perspectiveDescriptors(perspRegistry->GetPerspectives()); - qSort(perspectiveDescriptors.begin(), perspectiveDescriptors.end(), comparePerspectives); - - KeywordRegistry keywordRegistry; - berry::IPerspectiveDescriptor::Pointer currentPersp = page->GetPerspective(); - std::vector< QStandardItem* > categoryItems; - QStandardItem *perspectiveRootItem = new QStandardItem("Perspectives"); - perspectiveRootItem->setEditable(false); - perspectiveRootItem->setFont(QFont("", 12, QFont::Normal)); - treeRootItem->appendRow(perspectiveRootItem); - - for (const auto& perspectiveDescriptor : perspectiveDescriptors) - { - QmitkPerspectiveItem* perspectiveItem = new QmitkPerspectiveItem(perspectiveDescriptor->GetLabel()); - perspectiveItem->m_Perspective = perspectiveDescriptor; - perspectiveItem->m_Description = perspectiveDescriptor->GetDescription(); - QStringList keylist = perspectiveDescriptor->GetKeywordReferences(); - perspectiveItem->m_Tags = keywordRegistry.GetKeywords(keylist); - perspectiveItem->setEditable(false); - - QFont font; - font.setBold(true); - if (currentPersp.IsNotNull() && currentPersp->GetId() == perspectiveDescriptor->GetId()) - perspectiveItem->setFont(font); - - QStringList catPath = perspectiveDescriptor->GetCategoryPath(); - if (catPath.isEmpty()) - { - perspectiveRootItem->appendRow(perspectiveItem); - } - else - { - QStandardItem* categoryItem = nullptr; - for (const auto& currentCategoryItem : categoryItems) - { - if (currentCategoryItem->text() == catPath.front()) - { - categoryItem = currentCategoryItem; - break; - } - } - - if (nullptr == categoryItem) - { - categoryItem = new QStandardItem(QIcon(), catPath.front()); - categoryItems.push_back(categoryItem); - } - categoryItem->setEditable(false); - categoryItem->appendRow(perspectiveItem); - categoryItem->setFont(QFont("", 12, QFont::Normal)); - } - } - - std::sort(categoryItems.begin(), categoryItems.end(), compareQStandardItems); - for (const auto& categoryItem : categoryItems) - { - perspectiveRootItem->appendRow(categoryItem); - } - - // get all available views - berry::IViewRegistry* viewRegistry = berry::PlatformUI::GetWorkbench()->GetViewRegistry(); - QList viewDescriptors(viewRegistry->GetViews()); - QList viewParts(page->GetViews()); - qSort(viewDescriptors.begin(), viewDescriptors.end(), compareViews); - auto emptyItem = new QStandardItem(); - emptyItem->setFlags(Qt::ItemIsEnabled); - treeRootItem->appendRow(emptyItem); - //QStringList viewExcludeList = berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetViewExcludeList(); - - // There currently is no way to get the list of excluded views at application start - QStringList viewExcludeList; - // internal view used for the intro screen, will crash when opened directly, see T22352 - viewExcludeList.append(QString("org.blueberry.ui.internal.introview")); - viewExcludeList.append(QString("org.mitk.views.controlvisualizationpropertiesview")); - viewExcludeList.append(QString("org.mitk.views.modules")); - viewExcludeList.append(QString("org.mitk.views.viewnavigator")); - - QStandardItem* viewRootItem = new QStandardItem(QIcon(), "Views"); - viewRootItem->setFont(QFont("", 12, QFont::Normal)); - viewRootItem->setEditable(false); - treeRootItem->appendRow(viewRootItem); - - categoryItems.clear(); - QStandardItem* noCategoryItem = new QStandardItem(QIcon(), "Miscellaneous"); - noCategoryItem->setEditable(false); - noCategoryItem->setFont(QFont("", 12, QFont::Normal)); - - for (const auto& viewDescriptor : viewDescriptors) - { - bool skipView = false; - for (const auto& viewExcludeElement : viewExcludeList) - { - if(viewExcludeElement == viewDescriptor->GetId()) - { - skipView = true; - break; - } - } - - if (skipView) - continue; - - QStringList catPath = viewDescriptor->GetCategoryPath(); - - QIcon icon = viewDescriptor->GetImageDescriptor(); - QmitkViewItem* viewItem = new QmitkViewItem(icon, viewDescriptor->GetLabel()); - viewItem->m_View = viewDescriptor; - viewItem->setToolTip(viewDescriptor->GetDescription()); - viewItem->m_Description = viewDescriptor->GetDescription(); - - QStringList keylist = viewDescriptor->GetKeywordReferences(); - viewItem->m_Tags = keywordRegistry.GetKeywords(keylist); - viewItem->setEditable(false); - - for (const auto& viewPart : viewParts) - { - if (viewPart->GetPartName() == viewDescriptor->GetLabel()) - { - QFont font; - font.setBold(true); - viewItem->setFont(font); - break; - } - } - - if (catPath.empty()) - noCategoryItem->appendRow(viewItem); - else - { - QStandardItem* categoryItem = nullptr; - for (const auto& currentCategoryItem : categoryItems) - { - if (currentCategoryItem->text() == catPath.front()) - { - categoryItem = currentCategoryItem; - break; - } - } - - if (nullptr == categoryItem) - { - categoryItem = new QStandardItem(QIcon(),catPath.front()); - categoryItems.push_back(categoryItem); - } - categoryItem->setEditable(false); - categoryItem->appendRow(viewItem); - categoryItem->setFont(QFont("", 12, QFont::Normal)); - } - } - - std::sort(categoryItems.begin(), categoryItems.end(), compareQStandardItems); - for (const auto& categoryItem : categoryItems) - { - viewRootItem->appendRow(categoryItem); - } + // add all available perspectives + this->AddPerspectivesToTree(); - if (noCategoryItem->hasChildren()) - viewRootItem->appendRow(noCategoryItem); + // add all available views + this->AddViewsToTree(); m_Controls.m_PluginTreeView->expandAll(); return true; } void QmitkViewNavigatorWidget::FilterChanged() { QString filterString = m_Controls.lineEdit->text(); m_Controls.m_PluginTreeView->expandAll(); Qt::CaseSensitivity caseSensitivity = Qt::CaseInsensitive; QString strPattern = "^*" + filterString; QRegExp regExp(strPattern, caseSensitivity); m_FilterProxyModel->setFilterRegExp(regExp); } void QmitkViewNavigatorWidget::ItemClicked(const QModelIndex &index) { QStandardItem* item = m_TreeModel->itemFromIndex(m_FilterProxyModel->mapToSource(index)); QmitkPerspectiveItem* perspectiveItem = dynamic_cast(item); if (nullptr != perspectiveItem) { try { berry::PlatformUI::GetWorkbench()->ShowPerspective( - perspectiveItem->m_Perspective->GetId(), berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()); + perspectiveItem->m_ItemDescriptor->GetId(), berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()); } catch (...) { QMessageBox::critical(nullptr, "Opening Perspective Failed", QString("The requested perspective could not be opened.\nSee the log for details.")); } return; } QmitkViewItem* viewItem = dynamic_cast(item); if (nullptr != viewItem) { berry::IWorkbenchPage::Pointer page = berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage(); if (page.IsNotNull()) { try { - page->ShowView(viewItem->m_View->GetId()); + page->ShowView(viewItem->m_ItemDescriptor->GetId()); } catch (const berry::PartInitException& e) { BERRY_ERROR << "Error: " << e.what() << std::endl; } } } } void QmitkViewNavigatorWidget::SaveCurrentPerspectiveAs() { berry::IHandlerService* handlerService = m_Window->GetService(); try { handlerService->ExecuteCommand(berry::IWorkbenchCommandConstants::WINDOW_SAVE_PERSPECTIVE_AS, berry::UIElement::Pointer()); FillTreeList(); } catch(const berry::NotHandledException&) { } catch(const berry::CommandException& e) { MITK_ERROR << e.what(); } } void QmitkViewNavigatorWidget::ResetCurrentPerspective() { if (QMessageBox::Yes == QMessageBox(QMessageBox::Question, "Please confirm", "Do you really want to reset the current perspective?", QMessageBox::Yes | QMessageBox::No).exec()) { berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage()->ResetPerspective(); } } void QmitkViewNavigatorWidget::ClosePerspective() { if (QMessageBox::Yes == QMessageBox(QMessageBox::Question, "Please confirm", "Do you really want to close the current perspective?", QMessageBox::Yes | QMessageBox::No).exec()) { berry::IWorkbenchPage::Pointer page = m_Window->GetActivePage(); page->ClosePerspective(page->GetPerspective(), true, true); } } void QmitkViewNavigatorWidget::CloseAllPerspectives() { if (QMessageBox::Yes == QMessageBox(QMessageBox::Question, "Please confirm", "Do you really want to close all perspectives?", QMessageBox::Yes | QMessageBox::No).exec()) { berry::IWorkbenchPage::Pointer page = berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage(); page->CloseAllPerspectives(true, true); } } void QmitkViewNavigatorWidget::ExpandAll() { m_Controls.m_PluginTreeView->expandAll(); } void QmitkViewNavigatorWidget::CollapseAll() { m_Controls.m_PluginTreeView->collapseAll(); } void QmitkViewNavigatorWidget::CustomMenuRequested(QPoint pos) { QModelIndex index = m_Controls.m_PluginTreeView->indexAt(pos); QStandardItem* item = m_TreeModel->itemFromIndex(m_FilterProxyModel->mapToSource(index)); if (nullptr == m_ContextMenu) return; m_ContextMenu->clear(); QmitkPerspectiveItem* perspectiveItem = dynamic_cast(item); if (nullptr != perspectiveItem) { - berry::IPerspectiveDescriptor::Pointer perspectiveDescriptor = perspectiveItem->m_Perspective; + berry::IPerspectiveDescriptor::Pointer perspectiveDescriptor = perspectiveItem->m_ItemDescriptor; if (this->m_ActivePerspective.IsNotNull() && this->m_ActivePerspective == perspectiveDescriptor) { QAction* saveAsAction = new QAction("Save As...", this); m_ContextMenu->addAction(saveAsAction); connect(saveAsAction, SIGNAL(triggered()), SLOT(SaveCurrentPerspectiveAs())); m_ContextMenu->addSeparator(); } } QAction* resetAction = new QAction("Reset current perspective", this); m_ContextMenu->addAction(resetAction); connect(resetAction, SIGNAL(triggered()), SLOT(ResetCurrentPerspective())); QAction* closeAction = new QAction("Close perspective", this); m_ContextMenu->addAction(closeAction); connect(closeAction, SIGNAL(triggered()), SLOT(ClosePerspective())); QAction* closeAllAction = new QAction("Close all perspectives", this); m_ContextMenu->addAction(closeAllAction); connect(closeAllAction, SIGNAL(triggered()), SLOT(CloseAllPerspectives())); m_ContextMenu->addSeparator(); QAction* expandAction = new QAction("Expand tree", this); m_ContextMenu->addAction(expandAction); connect(expandAction, SIGNAL(triggered()), SLOT(ExpandAll())); QAction* collapseAction = new QAction("Collapse tree", this); m_ContextMenu->addAction(collapseAction); connect(collapseAction, SIGNAL(triggered()), SLOT(CollapseAll())); m_ContextMenu->popup(m_Controls.m_PluginTreeView->viewport()->mapToGlobal(pos)); } void QmitkViewNavigatorWidget::CreateQtPartControl(QWidget* parent) { // active workbench window available? if (m_Window.IsNull()) { return; } m_Parent = parent; m_Controls.setupUi(parent); connect(m_Controls.m_PluginTreeView, SIGNAL(customContextMenuRequested(QPoint)), SLOT(CustomMenuRequested(QPoint))); connect(m_Controls.m_PluginTreeView, SIGNAL(doubleClicked(const QModelIndex&)), SLOT(ItemClicked(const QModelIndex&))); connect(m_Controls.lineEdit, SIGNAL(textChanged(QString)), SLOT(FilterChanged())); m_ContextMenu = new QMenu(m_Controls.m_PluginTreeView); m_Controls.m_PluginTreeView->setContextMenuPolicy(Qt::CustomContextMenu); // Create a new TreeModel for the data m_TreeModel = new QStandardItemModel(); m_FilterProxyModel = new ClassFilterProxyModel(this); m_FilterProxyModel->setSourceModel(m_TreeModel); m_Controls.m_PluginTreeView->setModel(m_FilterProxyModel); m_PerspectiveListener.reset(new ViewNavigatorPerspectiveListener(this)); m_Window->AddPerspectiveListener(m_PerspectiveListener.data()); m_ViewPartListener.reset(new ViewNavigatorViewListener(this)); m_Window->GetPartService()->AddPartListener(m_ViewPartListener.data()); } + +void QmitkViewNavigatorWidget::AddPerspectivesToTree() +{ + berry::IPerspectiveRegistry* perspRegistry = berry::PlatformUI::GetWorkbench()->GetPerspectiveRegistry(); + QList perspectiveDescriptors(perspRegistry->GetPerspectives()); + qSort(perspectiveDescriptors.begin(), perspectiveDescriptors.end(), comparePerspectives); + + QStandardItem* perspectiveRootItem = new QStandardItem("Perspectives"); + perspectiveRootItem->setFont(QFont("", 12, QFont::Normal)); + perspectiveRootItem->setEditable(false); + QStandardItem* treeRootItem = m_TreeModel->invisibleRootItem(); + treeRootItem->appendRow(perspectiveRootItem); + + this->AddItemsToTree, QmitkPerspectiveItem>( + perspectiveDescriptors, perspectiveRootItem); +} + +void QmitkViewNavigatorWidget::AddViewsToTree() +{ + berry::IViewRegistry* viewRegistry = berry::PlatformUI::GetWorkbench()->GetViewRegistry(); + QList viewDescriptors(viewRegistry->GetViews()); + qSort(viewDescriptors.begin(), viewDescriptors.end(), compareViews); + + QStandardItem* viewRootItem = new QStandardItem("Views"); + viewRootItem->setFont(QFont("", 12, QFont::Normal)); + viewRootItem->setEditable(false); + QStandardItem* treeRootItem = m_TreeModel->invisibleRootItem(); + treeRootItem->appendRow(viewRootItem); + + QStandardItem* miscellaneousCategoryItem = new QStandardItem("Miscellaneous"); + miscellaneousCategoryItem->setFont(QFont("", 12, QFont::Normal)); + miscellaneousCategoryItem->setEditable(false); + + QStringList viewExcludeList; + // internal view used for the intro screen, will crash when opened directly, see T22352 + viewExcludeList.append(QString("org.blueberry.ui.internal.introview")); + viewExcludeList.append(QString("org.mitk.views.controlvisualizationpropertiesview")); + viewExcludeList.append(QString("org.mitk.views.modules")); + viewExcludeList.append(QString("org.mitk.views.viewnavigator")); + + this->AddItemsToTree, QmitkViewItem>( + viewDescriptors, viewRootItem, miscellaneousCategoryItem, viewExcludeList); +} + +template +void QmitkViewNavigatorWidget::AddItemsToTree(D itemDescriptors, QStandardItem* rootItem, + QStandardItem* miscellaneousItem, const QStringList& itemExcludeList) +{ + KeywordRegistry keywordRegistry; + std::vector categoryItems; + + for (const auto& itemDescriptor : itemDescriptors) + { + bool excludeView = itemExcludeList.contains(itemDescriptor->GetId()); + if (excludeView) + { + continue; + } + + QIcon icon = itemDescriptor->GetImageDescriptor(); + I* item = new I(icon, itemDescriptor->GetLabel()); + item->m_ItemDescriptor = itemDescriptor; + item->m_Description = itemDescriptor->GetDescription(); + item->setToolTip(itemDescriptor->GetDescription()); + + QStringList keylist = itemDescriptor->GetKeywordReferences(); + item->m_Tags = keywordRegistry.GetKeywords(keylist); + item->setEditable(false); + + QStringList categoryPath = itemDescriptor->GetCategoryPath(); + if (categoryPath.empty()) + { + // If a root item for general / non-categorized item views is given, use it. + // Otherwise put the non-categorized item views into the top root item. + if (nullptr != miscellaneousItem) + { + miscellaneousItem->appendRow(item); + } + else + { + rootItem->appendRow(item); + } + } + else + { + QStandardItem* categoryItem = nullptr; + for (const auto& currentCategoryItem : categoryItems) + { + if (currentCategoryItem->text() == categoryPath.front()) + { + categoryItem = currentCategoryItem; + break; + } + } + + if (nullptr == categoryItem) + { + categoryItem = new QStandardItem(QIcon(), categoryPath.front()); + categoryItems.push_back(categoryItem); + } + + categoryItem->setFont(QFont("", 12, QFont::Normal)); + categoryItem->setEditable(false); + categoryItem->appendRow(item); + } + } + + std::sort(categoryItems.begin(), categoryItems.end(), compareQStandardItems); + for (const auto& categoryItem : categoryItems) + { + rootItem->appendRow(categoryItem); + } + + if (nullptr != miscellaneousItem && miscellaneousItem->hasChildren()) + { + rootItem->appendRow(miscellaneousItem); + } +} diff --git a/Plugins/org.mitk.gui.qt.viewnavigator/src/QmitkViewNavigatorWidget.h b/Plugins/org.mitk.gui.qt.viewnavigator/src/QmitkViewNavigatorWidget.h index 607fbbfbac..d55bcedba4 100644 --- a/Plugins/org.mitk.gui.qt.viewnavigator/src/QmitkViewNavigatorWidget.h +++ b/Plugins/org.mitk.gui.qt.viewnavigator/src/QmitkViewNavigatorWidget.h @@ -1,81 +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 QMIKVIEWNAVIGATORWIDGET_H #define QMIKVIEWNAVIGATORWIDGET_H #include "ui_QmitkViewNavigatorWidgetControls.h" //QT headers #include #include #include #include #include #include class ClassFilterProxyModel; /** * @brief * */ class QmitkViewNavigatorWidget : public QWidget { Q_OBJECT public: QmitkViewNavigatorWidget(berry::IWorkbenchWindow::Pointer window, QWidget* parent = nullptr, Qt::WindowFlags f = nullptr); ~QmitkViewNavigatorWidget() override; void SetFocus(); public Q_SLOTS: void FilterChanged(); void ItemClicked(const QModelIndex& index); void SaveCurrentPerspectiveAs(); void ResetCurrentPerspective(); void ClosePerspective(); void CloseAllPerspectives(); void ExpandAll(); void CollapseAll(); void CustomMenuRequested(QPoint pos); protected: friend class ViewNavigatorPerspectiveListener; friend class ViewNavigatorViewListener; Ui::QmitkViewNavigatorWidgetControls m_Controls; QWidget* m_Parent; QStandardItemModel* m_TreeModel; ClassFilterProxyModel* m_FilterProxyModel; QMenu* m_ContextMenu; berry::IPerspectiveDescriptor::Pointer m_ActivePerspective; private: void CreateQtPartControl(QWidget* parent); bool FillTreeList(); void UpdateTreeList(berry::IWorkbenchPart* workbenchPart = nullptr); + void AddPerspectivesToTree(); + void AddViewsToTree(); + template + void AddItemsToTree(D itemDescriptors, QStandardItem* rootItem, + QStandardItem* miscellaneousItem = nullptr, const QStringList& itemExcludeList = QStringList()); + QScopedPointer m_PerspectiveListener; QScopedPointer m_ViewPartListener; berry::IWorkbenchWindow::Pointer m_Window; }; #endif // QMIKVIEWNAVIGATORWIDGET_H