diff --git a/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeContextMenu.cpp b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeContextMenu.cpp index d8167fd46d..43c2a17b82 100644 --- a/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeContextMenu.cpp +++ b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeContextMenu.cpp @@ -1,549 +1,541 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "QmitkDataNodeContextMenu.h" // mitk gui qt application plugin #include "mitkIContextMenuAction.h" #include "QmitkFileSaveAction.h" // mitk gui common plugin #include // qt widgets module #include #include // berry #include #include #include #include #include QmitkDataNodeContextMenu::QmitkDataNodeContextMenu(berry::IWorkbenchPartSite::Pointer workbenchPartSite, QWidget* parent) : QMenu(parent) { m_Parent = parent; m_WorkbenchPartSite = workbenchPartSite; InitNodeDescriptors(); InitDefaultActions(); InitExtensionPointActions(); } QmitkDataNodeContextMenu::~QmitkDataNodeContextMenu() { // remove the registered actions from each descriptor for (DescriptorActionListType::const_iterator it = m_DescriptorActionList.begin(); it != m_DescriptorActionList.end(); ++it) { (it->first)->RemoveAction(it->second); } } void QmitkDataNodeContextMenu::SetDataStorage(mitk::DataStorage* dataStorage) { // set the new data storage - also for all actions m_DataStorage = dataStorage; for (DescriptorActionListType::const_iterator it = m_DescriptorActionList.begin(); it != m_DescriptorActionList.end(); ++it) { QmitkAbstractDataNodeAction *abstractDataNodeAction = dynamic_cast(it->second); if (nullptr != abstractDataNodeAction) { abstractDataNodeAction->SetDataStorage(m_DataStorage.Lock()); } } } void QmitkDataNodeContextMenu::SetBaseRenderer(mitk::BaseRenderer *baseRenderer) { // set the new base renderer - also for all actions m_BaseRenderer = baseRenderer; for (DescriptorActionListType::const_iterator it = m_DescriptorActionList.begin(); it != m_DescriptorActionList.end(); ++it) { QmitkAbstractDataNodeAction *abstractDataNodeAction = dynamic_cast(it->second); if (nullptr != abstractDataNodeAction) { abstractDataNodeAction->SetBaseRenderer(m_BaseRenderer.Lock()); } } } void QmitkDataNodeContextMenu::SetSurfaceDecimation(bool surfaceDecimation) { m_SurfaceDecimation = surfaceDecimation; } void QmitkDataNodeContextMenu::InitNodeDescriptors() { m_UnknownDataNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetUnknownDataNodeDescriptor(); m_ImageDataNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("Image"); m_MultiComponentImageDataNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("MultiComponentImage"); m_DiffusionImageDataNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("DiffusionImage"); m_FiberBundleDataNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("FiberBundle"); m_PeakImageDataNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("PeakImage"); m_SegmentDataNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("Segment"); m_SurfaceDataNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("Surface"); m_PointSetNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("PointSet"); m_PlanarLineNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("PlanarLine"); m_PlanarCircleNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("PlanarCircle"); m_PlanarEllipseNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("PlanarEllipse"); m_PlanarAngleNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("PlanarAngle"); m_PlanarFourPointAngleNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("PlanarFourPointAngle"); m_PlanarRectangleNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("PlanarRectangle"); m_PlanarPolygonNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("PlanarPolygon"); m_PlanarPathNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("PlanarPath"); m_PlanarDoubleEllipseNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("PlanarDoubleEllipse"); m_PlanarBezierCurveNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("PlanarBezierCurve"); m_PlanarSubdivisionPolygonNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("PlanarSubdivisionPolygon"); } void QmitkDataNodeContextMenu::InitDefaultActions() { m_GlobalReinitAction = new QmitkDataNodeGlobalReinitAction(m_Parent, m_WorkbenchPartSite.Lock()); m_GlobalReinitAction->setIcon(QIcon(":/org.mitk.gui.qt.datamanager/Refresh_48.png")); m_UnknownDataNodeDescriptor->AddAction(m_GlobalReinitAction, true); m_DescriptorActionList.push_back(std::make_pair(m_UnknownDataNodeDescriptor, m_GlobalReinitAction)); m_ReinitAction = new QmitkDataNodeReinitAction(m_Parent, m_WorkbenchPartSite.Lock()); m_ReinitAction->setIcon(QIcon(":/org.mitk.gui.qt.datamanager/Refresh_48.png")); m_UnknownDataNodeDescriptor->AddAction(m_ReinitAction, true); m_DescriptorActionList.push_back(std::make_pair(m_UnknownDataNodeDescriptor, m_ReinitAction)); QAction* saveAction = new QmitkFileSaveAction(QIcon(":/org.mitk.gui.qt.datamanager/Save_48.png"), m_WorkbenchPartSite.Lock()->GetWorkbenchWindow()); m_UnknownDataNodeDescriptor->AddAction(saveAction, true); m_DescriptorActionList.push_back(std::make_pair(m_UnknownDataNodeDescriptor, saveAction)); m_RemoveAction = new QmitkDataNodeRemoveAction(m_Parent, m_WorkbenchPartSite.Lock()); m_RemoveAction->setIcon(QIcon(":/org.mitk.gui.qt.datamanager/Remove_48.png")); m_UnknownDataNodeDescriptor->AddAction(m_RemoveAction, true); m_DescriptorActionList.push_back(std::make_pair(m_UnknownDataNodeDescriptor, m_RemoveAction)); m_ShowSelectedNodesAction = new QmitkDataNodeShowSelectedNodesAction(m_Parent, m_WorkbenchPartSite.Lock()); m_RemoveAction->setIcon(QIcon(":/org.mitk.gui.qt.datamanager/ShowSelectedNode_48.png")); m_UnknownDataNodeDescriptor->AddAction(m_ShowSelectedNodesAction, true); m_DescriptorActionList.push_back(std::make_pair(m_UnknownDataNodeDescriptor, m_ShowSelectedNodesAction)); m_ToggleVisibilityAction = new QmitkDataNodeToggleVisibilityAction(m_Parent, m_WorkbenchPartSite.Lock()); m_ToggleVisibilityAction->setIcon(QIcon(":/org.mitk.gui.qt.datamanager/InvertShowSelectedNode_48.png")); m_UnknownDataNodeDescriptor->AddAction(m_ToggleVisibilityAction, true); m_DescriptorActionList.push_back(std::make_pair(m_UnknownDataNodeDescriptor, m_ToggleVisibilityAction)); m_ShowDetailsAction = new QmitkDataNodeShowDetailsAction(m_Parent, m_WorkbenchPartSite.Lock()); m_ShowDetailsAction->setIcon(QIcon(":/org.mitk.gui.qt.datamanager/ShowDataInfo_48.png")); m_UnknownDataNodeDescriptor->AddAction(m_ShowDetailsAction, true); m_DescriptorActionList.push_back(std::make_pair(m_UnknownDataNodeDescriptor, m_ShowDetailsAction)); // default widget actions m_OpacityAction = new QmitkDataNodeOpacityAction(m_Parent, m_WorkbenchPartSite.Lock()); // not used for batch actions (no multi-selection action) m_UnknownDataNodeDescriptor->AddAction(m_OpacityAction, false); m_DescriptorActionList.push_back(std::make_pair(m_UnknownDataNodeDescriptor, m_OpacityAction)); m_ColorAction = new QmitkDataNodeColorAction(m_Parent, m_WorkbenchPartSite.Lock()); AddColorAction(m_ColorAction); m_ColormapAction = new QmitkDataNodeColorMapAction(m_Parent, m_WorkbenchPartSite.Lock()); // not used for batch actions (no multi-selection action) m_ImageDataNodeDescriptor->AddAction(m_ColormapAction, false); m_DescriptorActionList.push_back(std::make_pair(m_ImageDataNodeDescriptor, m_ColormapAction)); if (m_DiffusionImageDataNodeDescriptor != nullptr) { // not used for batch actions (no multi-selection action) m_DiffusionImageDataNodeDescriptor->AddAction(m_ColormapAction, false); m_DescriptorActionList.push_back(std::make_pair(m_DiffusionImageDataNodeDescriptor, m_ColormapAction)); } m_ComponentAction = new QmitkDataNodeComponentAction(m_Parent, m_WorkbenchPartSite.Lock()); // not used for batch actions (no multi-selection action) m_MultiComponentImageDataNodeDescriptor->AddAction(m_ComponentAction, false); m_DescriptorActionList.push_back(std::make_pair(m_MultiComponentImageDataNodeDescriptor, m_ComponentAction)); if (m_DiffusionImageDataNodeDescriptor != nullptr) { // not used for batch actions (no multi-selection action) m_DiffusionImageDataNodeDescriptor->AddAction(m_ComponentAction, false); m_DescriptorActionList.push_back(std::make_pair(m_DiffusionImageDataNodeDescriptor, m_ComponentAction)); } m_TextureInterpolationAction = new QmitkDataNodeTextureInterpolationAction(m_Parent, m_WorkbenchPartSite.Lock()); // not used for batch actions (no multi-selection action) m_ImageDataNodeDescriptor->AddAction(m_TextureInterpolationAction, false); m_DescriptorActionList.push_back(std::make_pair(m_ImageDataNodeDescriptor, m_TextureInterpolationAction)); if (m_DiffusionImageDataNodeDescriptor != nullptr) { // not used for batch actions (no multi-selection action) m_DiffusionImageDataNodeDescriptor->AddAction(m_TextureInterpolationAction, false); m_DescriptorActionList.push_back(std::make_pair(m_DiffusionImageDataNodeDescriptor, m_TextureInterpolationAction)); } if (m_SegmentDataNodeDescriptor != nullptr) { // not used for batch actions (no multi-selection action) m_SegmentDataNodeDescriptor->AddAction(m_TextureInterpolationAction, false); m_DescriptorActionList.push_back(std::make_pair(m_SegmentDataNodeDescriptor, m_TextureInterpolationAction)); } m_SurfaceRepresentationAction = new QmitkDataNodeSurfaceRepresentationAction(m_Parent, m_WorkbenchPartSite.Lock()); // not used for batch actions (no multi-selection action) m_SurfaceDataNodeDescriptor->AddAction(m_SurfaceRepresentationAction, false); m_DescriptorActionList.push_back(std::make_pair(m_SurfaceDataNodeDescriptor, m_SurfaceRepresentationAction)); } void QmitkDataNodeContextMenu::InitExtensionPointActions() { // find contextMenuAction extension points and add them to the node descriptor berry::IExtensionRegistry* extensionPointService = berry::Platform::GetExtensionRegistry(); QList customMenuConfigs = extensionPointService->GetConfigurationElementsFor("org.mitk.gui.qt.datamanager.contextMenuActions"); // prepare all custom QActions m_ConfigElements.clear(); DescriptorActionListType descriptorActionList; for (const auto& customMenuConfig : customMenuConfigs) { QString actionNodeDescriptorName = customMenuConfig->GetAttribute("nodeDescriptorName"); QString actionLabel = customMenuConfig->GetAttribute("label"); QString actionClass = customMenuConfig->GetAttribute("class"); if (actionNodeDescriptorName.isEmpty() || actionLabel.isEmpty() || actionClass.isEmpty()) { // no properties found for the current extension point continue; } // find matching descriptor auto nodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor(actionNodeDescriptorName); if (nullptr == nodeDescriptor) { MITK_WARN << "Cannot add action \"" << actionLabel << "\" because descriptor " << actionNodeDescriptorName << " does not exist."; continue; } // create action with or without icon QAction* contextMenuAction; QString actionIconName = customMenuConfig->GetAttribute("icon"); if (!actionIconName.isEmpty()) { QIcon actionIcon; if (QFile::exists(actionIconName)) { actionIcon = QIcon(actionIconName); } else { actionIcon = berry::AbstractUICTKPlugin::ImageDescriptorFromPlugin(customMenuConfig->GetContributor()->GetName(), actionIconName); } contextMenuAction = new QAction(actionIcon, actionLabel, m_Parent); } else { contextMenuAction = new QAction(actionLabel, m_Parent); } // connect action trigger connect(contextMenuAction, static_cast(&QAction::triggered), this, &QmitkDataNodeContextMenu::OnExtensionPointActionTriggered); // mark configuration element into lookup list for context menu handler m_ConfigElements[contextMenuAction] = customMenuConfig; // mark new action in sortable list for addition to descriptor descriptorActionList.emplace_back(nodeDescriptor, contextMenuAction); } AddDescriptorActionList(descriptorActionList); } void QmitkDataNodeContextMenu::InitServiceActions() { } void QmitkDataNodeContextMenu::OnContextMenuRequested(const QPoint& pos) { if (m_WorkbenchPartSite.Expired()) { return; } berry::ISelection::ConstPointer selection = m_WorkbenchPartSite.Lock()->GetWorkbenchWindow()->GetSelectionService()->GetSelection(); mitk::DataNodeSelection::ConstPointer currentSelection = selection.Cast(); if (currentSelection.IsNull() || currentSelection->IsEmpty()) { return; } m_SelectedNodes = QList::fromStdList(currentSelection->GetSelectedDataNodes()); if (!m_SelectedNodes.isEmpty()) { clear(); QList actions; if (m_SelectedNodes.size() == 1) { // no batch action; should only contain a single node actions = GetActions(m_SelectedNodes.front()); } else { // batch action actions = GetActions(m_SelectedNodes); } // initialize abstract data node actions for (auto& action : actions) { QmitkAbstractDataNodeAction* abstractDataNodeAction = dynamic_cast(action); if (nullptr != abstractDataNodeAction) { // use the first selected node to initialize the data node actions abstractDataNodeAction->InitializeWithDataNode(m_SelectedNodes.front()); } } - /* - if (!m_ShowInActions.isEmpty()) - { - QMenu* showInMenu = m_NodeMenu->addMenu(tr("Show In")); - showInMenu->addActions(m_ShowInActions); - } - */ - addActions(actions); popup(QCursor::pos()); } } void QmitkDataNodeContextMenu::OnExtensionPointActionTriggered(bool) { QAction* action = qobject_cast(sender()); ConfigurationElementsType::const_iterator it = m_ConfigElements.find(action); if (it == m_ConfigElements.end()) { MITK_WARN << "Associated configuration element for action " << action->text().toStdString() << " not found."; return; } berry::IConfigurationElement::Pointer confElem = it->second; mitk::IContextMenuAction* contextMenuAction = confElem->CreateExecutableExtension("class"); QString className = confElem->GetAttribute("class"); QString smoothed = confElem->GetAttribute("smoothed"); if (!m_DataStorage.IsExpired()) { auto dataStorage = m_DataStorage.Lock(); contextMenuAction->SetDataStorage(dataStorage); } if (className == "QmitkCreatePolygonModelAction") { if (smoothed == "false") { contextMenuAction->SetSmoothed(false); } else { contextMenuAction->SetSmoothed(true); } contextMenuAction->SetDecimated(m_SurfaceDecimation); } contextMenuAction->Run(m_SelectedNodes); } void QmitkDataNodeContextMenu::AddColorAction(QWidgetAction* colorAction) { bool colorActionCanBatch = true; if (nullptr != m_ImageDataNodeDescriptor) { m_ImageDataNodeDescriptor->AddAction(colorAction, colorActionCanBatch); m_DescriptorActionList.push_back(std::make_pair(m_ImageDataNodeDescriptor, colorAction)); } if (nullptr != m_MultiComponentImageDataNodeDescriptor) { m_MultiComponentImageDataNodeDescriptor->AddAction(colorAction, colorActionCanBatch); m_DescriptorActionList.push_back(std::make_pair(m_MultiComponentImageDataNodeDescriptor, colorAction)); } if (nullptr != m_DiffusionImageDataNodeDescriptor) { m_DiffusionImageDataNodeDescriptor->AddAction(colorAction, colorActionCanBatch); m_DescriptorActionList.push_back(std::make_pair(m_DiffusionImageDataNodeDescriptor, colorAction)); } if (nullptr != m_FiberBundleDataNodeDescriptor) { m_FiberBundleDataNodeDescriptor->AddAction(colorAction, false); m_DescriptorActionList.push_back(std::make_pair(m_FiberBundleDataNodeDescriptor, colorAction)); } if (nullptr != m_PeakImageDataNodeDescriptor) { m_PeakImageDataNodeDescriptor->AddAction(colorAction, false); m_DescriptorActionList.push_back(std::make_pair(m_PeakImageDataNodeDescriptor, colorAction)); } if (nullptr != m_SegmentDataNodeDescriptor) { m_SegmentDataNodeDescriptor->AddAction(colorAction, false); m_DescriptorActionList.push_back(std::make_pair(m_SegmentDataNodeDescriptor, colorAction)); } if (nullptr != m_SurfaceDataNodeDescriptor) { m_SurfaceDataNodeDescriptor->AddAction(colorAction, colorActionCanBatch); m_DescriptorActionList.push_back(std::make_pair(m_SurfaceDataNodeDescriptor, colorAction)); } if (nullptr != m_PointSetNodeDescriptor) { m_PointSetNodeDescriptor->AddAction(colorAction, colorActionCanBatch); m_DescriptorActionList.push_back(std::make_pair(m_PointSetNodeDescriptor, colorAction)); } if (nullptr != m_PlanarLineNodeDescriptor) { m_PlanarLineNodeDescriptor->AddAction(colorAction, colorActionCanBatch); m_DescriptorActionList.push_back(std::make_pair(m_PlanarLineNodeDescriptor, colorAction)); } if (nullptr != m_PlanarCircleNodeDescriptor) { m_PlanarCircleNodeDescriptor->AddAction(colorAction, colorActionCanBatch); m_DescriptorActionList.push_back(std::make_pair(m_PlanarCircleNodeDescriptor, colorAction)); } if (nullptr != m_PlanarEllipseNodeDescriptor) { m_PlanarEllipseNodeDescriptor->AddAction(colorAction, colorActionCanBatch); m_DescriptorActionList.push_back(std::make_pair(m_PlanarEllipseNodeDescriptor, colorAction)); } if (nullptr != m_PlanarAngleNodeDescriptor) { m_PlanarAngleNodeDescriptor->AddAction(colorAction, colorActionCanBatch); m_DescriptorActionList.push_back(std::make_pair(m_PlanarAngleNodeDescriptor, colorAction)); } if (nullptr != m_PlanarFourPointAngleNodeDescriptor) { m_PlanarFourPointAngleNodeDescriptor->AddAction(colorAction, colorActionCanBatch); m_DescriptorActionList.push_back(std::make_pair(m_PlanarFourPointAngleNodeDescriptor, colorAction)); } if (nullptr != m_PlanarRectangleNodeDescriptor) { m_PlanarRectangleNodeDescriptor->AddAction(colorAction, colorActionCanBatch); m_DescriptorActionList.push_back(std::make_pair(m_PlanarRectangleNodeDescriptor, colorAction)); } if (nullptr != m_PlanarPolygonNodeDescriptor) { m_PlanarPolygonNodeDescriptor->AddAction(colorAction, colorActionCanBatch); m_DescriptorActionList.push_back(std::make_pair(m_PlanarPolygonNodeDescriptor, colorAction)); } if (nullptr != m_PlanarPathNodeDescriptor) { m_PlanarPathNodeDescriptor->AddAction(colorAction, colorActionCanBatch); m_DescriptorActionList.push_back(std::make_pair(m_PlanarPathNodeDescriptor, colorAction)); } if (nullptr != m_PlanarDoubleEllipseNodeDescriptor) { m_PlanarDoubleEllipseNodeDescriptor->AddAction(colorAction, colorActionCanBatch); m_DescriptorActionList.push_back(std::make_pair(m_PlanarDoubleEllipseNodeDescriptor, colorAction)); } if (nullptr != m_PlanarBezierCurveNodeDescriptor) { m_PlanarBezierCurveNodeDescriptor->AddAction(colorAction, colorActionCanBatch); m_DescriptorActionList.push_back(std::make_pair(m_PlanarBezierCurveNodeDescriptor, colorAction)); } if (nullptr != m_PlanarSubdivisionPolygonNodeDescriptor) { m_PlanarSubdivisionPolygonNodeDescriptor->AddAction(colorAction, colorActionCanBatch); m_DescriptorActionList.push_back(std::make_pair(m_PlanarSubdivisionPolygonNodeDescriptor, colorAction)); } } void QmitkDataNodeContextMenu::AddDescriptorActionList(DescriptorActionListType& descriptorActionList) { // sort all custom QActions by their texts using ListEntryType = std::pair; std::sort(descriptorActionList.begin(), descriptorActionList.end(), [](const ListEntryType& left, const ListEntryType& right) -> bool { assert(left.second != nullptr && right.second != nullptr); // unless we messed up above return left.second->text() < right.second->text(); }); // add custom QActions in sorted order for (auto& descriptorActionPair : descriptorActionList) { auto& nodeDescriptor = descriptorActionPair.first; auto& contextMenuAction = descriptorActionPair.second; // add action to the descriptor nodeDescriptor->AddAction(contextMenuAction); // mark new action into list of descriptors to remove in destructor m_DescriptorActionList.push_back(descriptorActionPair); } } QList QmitkDataNodeContextMenu::GetActions(const mitk::DataNode* node) { QList actions; for (DescriptorActionListType::const_iterator it = m_DescriptorActionList.begin(); it != m_DescriptorActionList.end(); ++it) { if ((it->first)->CheckNode(node) || it->first->GetNameOfClass() == "Unknown") { actions.append(it->second); } } return actions; } QList QmitkDataNodeContextMenu::GetActions(const QList& nodes) { QList actions; for (DescriptorActionListType::const_iterator it = m_DescriptorActionList.begin(); it != m_DescriptorActionList.end(); ++it) { for (const auto& node : nodes) { if ((it->first)->CheckNode(node) || it->first->GetNameOfClass() == "Unknown") { const auto& batchActions = (it->first)->GetBatchActions(); if (std::find(batchActions.begin(), batchActions.end(), it->second) != batchActions.end()) { // current descriptor action is a batch action actions.append(it->second); } break; // only add action once; goto next descriptor action } } } return actions; } diff --git a/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.cpp b/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.cpp index 99646505a1..f05b1152a2 100644 --- a/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.cpp +++ b/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.cpp @@ -1,281 +1,253 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "QmitkDataManagerView.h" // mitk gui qt datamanager #include "src/internal/QmitkDataManagerItemDelegate.h" // mitk core #include #include #include #include #include #include #include #include #include #include #include #include #include #include // qt widgets module #include #include #include #include #include // beery plugins #include -#include -#include -#include -#include #include #include #include #include // mitk core services plugin #include #include // mitk gui common plugin #include -#include #include // mitk gui qt application plugin #include #include // mitk gui qt common plugin #include // qt #include #include #include #include #include #include #include #include #include -#include const QString QmitkDataManagerView::VIEW_ID = "org.mitk.views.datamanager"; QmitkDataManagerView::QmitkDataManagerView() : m_ItemDelegate(nullptr) { } QmitkDataManagerView::~QmitkDataManagerView() { // nothing here } void QmitkDataManagerView::CreateQtPartControl(QWidget* parent) { m_CurrentRowCount = 0; m_Parent = parent; //# Preferences berry::IPreferencesService* prefService = berry::Platform::GetPreferencesService(); berry::IBerryPreferences::Pointer prefs = (prefService->GetSystemPreferences()->Node(VIEW_ID)).Cast(); assert(prefs); prefs->OnChanged.AddListener(berry::MessageDelegate1(this, &QmitkDataManagerView::OnPreferencesChanged)); //# GUI m_NodeTreeModel = new QmitkDataStorageTreeModel(GetDataStorage(), prefs->GetBool("Place new nodes on top", true)); m_NodeTreeModel->setParent(parent); m_NodeTreeModel->SetAllowHierarchyChange(prefs->GetBool("Allow changing of parent node", false)); m_SurfaceDecimation = prefs->GetBool("Use surface decimation", false); // Prepare filters m_HelperObjectFilterPredicate = mitk::NodePredicateOr::New( mitk::NodePredicateProperty::New("helper object", mitk::BoolProperty::New(true)), mitk::NodePredicateProperty::New("hidden object", mitk::BoolProperty::New(true))); m_NodeWithNoDataFilterPredicate = mitk::NodePredicateData::New(nullptr); m_FilterModel = new QmitkDataStorageFilterProxyModel(); m_FilterModel->setSourceModel(m_NodeTreeModel); m_FilterModel->AddFilterPredicate(m_HelperObjectFilterPredicate); m_FilterModel->AddFilterPredicate(m_NodeWithNoDataFilterPredicate); //# Tree View (experimental) m_NodeTreeView = new QTreeView; m_NodeTreeView->setHeaderHidden(true); m_NodeTreeView->setSelectionMode(QAbstractItemView::ExtendedSelection); m_NodeTreeView->setSelectionBehavior(QAbstractItemView::SelectRows); m_NodeTreeView->setAlternatingRowColors(true); m_NodeTreeView->setDragEnabled(true); m_NodeTreeView->setDropIndicatorShown(true); m_NodeTreeView->setAcceptDrops(true); m_NodeTreeView->setContextMenuPolicy(Qt::CustomContextMenu); m_NodeTreeView->setModel(m_FilterModel); m_NodeTreeView->setTextElideMode(Qt::ElideMiddle); m_ItemDelegate = new QmitkDataManagerItemDelegate(m_NodeTreeView); m_NodeTreeView->setItemDelegate(m_ItemDelegate); connect(m_NodeTreeModel, SIGNAL(rowsInserted(const QModelIndex&, int, int)), this, SLOT(NodeTreeViewRowsInserted(const QModelIndex&, int, int))); connect(m_NodeTreeModel, SIGNAL(rowsRemoved(const QModelIndex&, int, int)), this, SLOT(NodeTreeViewRowsRemoved(const QModelIndex&, int, int))); connect(m_NodeTreeView->selectionModel(), SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)), this, SLOT(NodeSelectionChanged(const QItemSelection &, const QItemSelection &))); connect(m_NodeTreeModel, &QmitkDataStorageTreeModel::nodeVisibilityChanged, this, &QmitkDataManagerView::OnNodeVisibilityChanged); // data node context menu and menu actions m_DataNodeContextMenu = new QmitkDataNodeContextMenu(GetSite(), m_NodeTreeView); m_DataNodeContextMenu->SetDataStorage(GetDataStorage()); m_DataNodeContextMenu->SetSurfaceDecimation(m_SurfaceDecimation); connect(m_NodeTreeView, SIGNAL(customContextMenuRequested(const QPoint&)), m_DataNodeContextMenu, SLOT(OnContextMenuRequested(const QPoint&))); - berry::IEditorRegistry* editorRegistry = berry::PlatformUI::GetWorkbench()->GetEditorRegistry(); - QList editors = editorRegistry->GetEditors("*.mitk"); - if (editors.size() > 1) - { - m_ShowInMapper = new QSignalMapper(this); - foreach(berry::IEditorDescriptor::Pointer descriptor, editors) - { - QAction* action = new QAction(descriptor->GetLabel(), this); - m_ShowInActions << action; - m_ShowInMapper->connect(action, SIGNAL(triggered()), m_ShowInMapper, SLOT(map())); - m_ShowInMapper->setMapping(action, descriptor->GetId()); - } - connect(m_ShowInMapper, SIGNAL(mapped(QString)), this, SLOT(ShowIn(QString))); - } - QGridLayout* dndFrameWidgetLayout = new QGridLayout; dndFrameWidgetLayout->addWidget(m_NodeTreeView, 0, 0); dndFrameWidgetLayout->setContentsMargins(0, 0, 0, 0); m_DnDFrameWidget = new QmitkDnDFrameWidget(m_Parent); m_DnDFrameWidget->setLayout(dndFrameWidgetLayout); QVBoxLayout* layout = new QVBoxLayout(parent); layout->addWidget(m_DnDFrameWidget); layout->setContentsMargins(0, 0, 0, 0); m_Parent->setLayout(layout); } void QmitkDataManagerView::SetFocus() { } void QmitkDataManagerView::NodeChanged(const mitk::DataNode* /*node*/) { // m_FilterModel->invalidate(); // fix as proposed by R. Khlebnikov in the mitk-users mail from 02.09.2014 QMetaObject::invokeMethod(m_FilterModel, "invalidate", Qt::QueuedConnection); } void QmitkDataManagerView::OnPreferencesChanged(const berry::IBerryPreferences* prefs) { if (m_NodeTreeModel->GetPlaceNewNodesOnTopFlag() != prefs->GetBool("Place new nodes on top", true)) { m_NodeTreeModel->SetPlaceNewNodesOnTop(!m_NodeTreeModel->GetPlaceNewNodesOnTopFlag()); } bool hideHelperObjects = !prefs->GetBool("Show helper objects", false); if (m_FilterModel->HasFilterPredicate(m_HelperObjectFilterPredicate) != hideHelperObjects) { if (hideHelperObjects) { m_FilterModel->AddFilterPredicate(m_HelperObjectFilterPredicate); } else { m_FilterModel->RemoveFilterPredicate(m_HelperObjectFilterPredicate); } } bool hideNodesWithNoData = !prefs->GetBool("Show nodes containing no data", false); if (m_FilterModel->HasFilterPredicate(m_NodeWithNoDataFilterPredicate) != hideNodesWithNoData) { if (hideNodesWithNoData) { m_FilterModel->AddFilterPredicate(m_NodeWithNoDataFilterPredicate); } else { m_FilterModel->RemoveFilterPredicate(m_NodeWithNoDataFilterPredicate); } } m_NodeTreeView->expandAll(); m_SurfaceDecimation = prefs->GetBool("Use surface decimation", false); m_DataNodeContextMenu->SetSurfaceDecimation(m_SurfaceDecimation); m_NodeTreeModel->SetAllowHierarchyChange(prefs->GetBool("Allow changing of parent node", false)); GlobalReinitAction::Run(GetSite(), GetDataStorage()); } ////////////////////////////////////////////////////////////////////////// // Node tree modification ////////////////////////////////////////////////////////////////////////// void QmitkDataManagerView::NodeTreeViewRowsInserted(const QModelIndex& parent, int /*start*/, int /*end*/) { QModelIndex viewIndex = m_FilterModel->mapFromSource(parent); m_NodeTreeView->setExpanded(viewIndex, true); // a new row was inserted if (m_CurrentRowCount == 0 && m_NodeTreeModel->rowCount() == 1) { mitk::WorkbenchUtil::OpenRenderWindowPart(GetSite()->GetPage()); m_CurrentRowCount = m_NodeTreeModel->rowCount(); } } void QmitkDataManagerView::NodeTreeViewRowsRemoved(const QModelIndex& /*parent*/, int /*start*/, int /*end*/) { m_CurrentRowCount = m_NodeTreeModel->rowCount(); } void QmitkDataManagerView::NodeSelectionChanged(const QItemSelection& /*selected*/, const QItemSelection& /*deselected*/) { auto selectedNodes = GetCurrentSelection(); auto nodeSet = m_NodeTreeModel->GetNodeSet(); for (auto node : nodeSet) { if (node.IsNotNull()) { node->SetSelected(selectedNodes.contains(node)); } } } void QmitkDataManagerView::OnNodeVisibilityChanged() { ToggleVisibilityAction::Run(GetSite(), GetDataStorage()); } -void QmitkDataManagerView::ShowIn(const QString& editorId) -{ - berry::IWorkbenchPage::Pointer page = GetSite()->GetPage(); - berry::IEditorInput::Pointer input(new mitk::DataStorageEditorInput(GetDataStorageReference())); - page->OpenEditor(input, editorId, false, berry::IWorkbenchPage::MATCH_ID); -} - QItemSelectionModel* QmitkDataManagerView::GetDataNodeSelectionModel() const { return m_NodeTreeView->selectionModel(); } diff --git a/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.h b/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.h index 2be976e22a..95a3cb21dd 100644 --- a/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.h +++ b/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.h @@ -1,142 +1,132 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef QMITKDATAMANAGERVIEW_H_ #define QMITKDATAMANAGERVIEW_H_ #include // mitk core #include // berry plugin #include // mitk gui qt common plugin #include // mitk gui qt application #include // qt #include // forward declarations class QAction; class QModelIndex; class QTreeView; -class QSignalMapper; class QmitkDnDFrameWidget; class QmitkDataStorageTreeModel; class QmitkDataManagerItemDelegate; class QmitkDataStorageFilterProxyModel; /** * @brief A view that shows all data nodes of the data storage in a qt tree view. * */ class MITK_QT_DATAMANAGER QmitkDataManagerView : public QmitkAbstractView { Q_OBJECT public: static const QString VIEW_ID; // = "org.mitk.views.datamanager" QmitkDataManagerView(); ~QmitkDataManagerView() override; public Q_SLOTS: // invoked when the berry preferences were changed void OnPreferencesChanged(const berry::IBerryPreferences* prefs) override; ////////////////////////////////////////////////////////////////////////// // Slots for Qt node tree signals ////////////////////////////////////////////////////////////////////////// /// When rows are inserted auto expand them void NodeTreeViewRowsInserted(const QModelIndex& parent, int start, int end); /// will setup m_CurrentRowCount void NodeTreeViewRowsRemoved(const QModelIndex& parent, int start, int end); /// Whenever the selection changes set the "selected" property respectively void NodeSelectionChanged(const QItemSelection& selected, const QItemSelection& deselected); void OnNodeVisibilityChanged(); - /// Opens the editor with the given id using the current data storage - void ShowIn(const QString& editorId); - protected: void CreateQtPartControl(QWidget* parent) override; void SetFocus() override; /// /// React to node changes. Overridden from QmitkAbstractView. /// void NodeChanged(const mitk::DataNode* node) override; protected: QWidget* m_Parent; QmitkDnDFrameWidget* m_DnDFrameWidget; /// /// \brief A plain widget as the base pane. /// QmitkDataStorageTreeModel* m_NodeTreeModel; QmitkDataStorageFilterProxyModel* m_FilterModel; mitk::NodePredicateBase::Pointer m_HelperObjectFilterPredicate; mitk::NodePredicateBase::Pointer m_NodeWithNoDataFilterPredicate; /// /// Holds the preferences for the data manager. /// berry::IBerryPreferences::Pointer m_DataManagerPreferencesNode; /// /// \brief The Table view to show the selected nodes. /// QTreeView* m_NodeTreeView; /// /// \brief The context menu that shows up when right clicking on a node. /// QmitkDataNodeContextMenu* m_DataNodeContextMenu; /// /// \brief flag indicating whether a surface created from a selected decimation is decimated with vtkQuadricDecimation or not /// bool m_SurfaceDecimation; - /// Maps "Show in" actions to editor ids - QSignalMapper* m_ShowInMapper; - - /// A list of "Show in" actions - QList m_ShowInActions; - /// saves the current amount of rows shown in the data manager size_t m_CurrentRowCount; QmitkDataManagerItemDelegate* m_ItemDelegate; private: QItemSelectionModel* GetDataNodeSelectionModel() const override; }; #endif // QMITKDATAMANAGERVIEW_H_