diff --git a/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeContextMenu.cpp b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeContextMenu.cpp index e10ca0235c..de2ccb87e7 100644 --- a/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeContextMenu.cpp +++ b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeContextMenu.cpp @@ -1,552 +1,480 @@ /*============================================================================ 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 "QmitkDataNodeContextMenu.h" +#include -// mitk gui qt application plugin -#include "mitkIContextMenuAction.h" -#include "QmitkFileSaveAction.h" - -// mitk gui common plugin -#include - -// qt widgets module #include +#include #include -// berry +#include +#include + #include #include #include #include #include QmitkDataNodeContextMenu::QmitkDataNodeContextMenu(berry::IWorkbenchPartSite::Pointer workbenchPartSite, QWidget* parent) - : QMenu(parent) + : QMenu(parent), + m_Parent(parent), + m_WorkbenchPartSite(workbenchPartSite) { - m_Parent = parent; - m_WorkbenchPartSite = workbenchPartSite; - - InitNodeDescriptors(); - InitDefaultActions(); - InitExtensionPointActions(); + this->InitNodeDescriptors(); + this->InitDefaultActions(); + this->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); - } + for (auto& descriptorActionPair : m_DescriptorActionList) + descriptorActionPair.first->RemoveAction(descriptorActionPair.second); } void QmitkDataNodeContextMenu::SetDataStorage(mitk::DataStorage* dataStorage) { - if (m_DataStorage != dataStorage) + m_DataStorage = dataStorage; + + for (auto& descriptorActionPair : m_DescriptorActionList) { - // 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()); - } - } - } + auto dataNodeAction = dynamic_cast(descriptorActionPair.second); + + if (nullptr != dataNodeAction) + dataNodeAction->SetDataStorage(dataStorage); + } } void QmitkDataNodeContextMenu::SetBaseRenderer(mitk::BaseRenderer* baseRenderer) { - if (m_BaseRenderer != baseRenderer) + m_BaseRenderer = baseRenderer; + + for (auto& descriptorActionPair : m_DescriptorActionList) { - // 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()); - } - } + auto dataNodeAction = dynamic_cast(descriptorActionPair.second); + + if (nullptr != dataNodeAction) + dataNodeAction->SetBaseRenderer(baseRenderer); } } void QmitkDataNodeContextMenu::SetSurfaceDecimation(bool surfaceDecimation) { m_SurfaceDecimation = surfaceDecimation; } void QmitkDataNodeContextMenu::SetSelectedNodes(const QList& selectedNodes) { m_SelectedNodes = selectedNodes; } 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"); + auto nodeDescriptorManager = QmitkNodeDescriptorManager::GetInstance(); + + m_UnknownDataNodeDescriptor = nodeDescriptorManager->GetUnknownDataNodeDescriptor(); + m_ImageDataNodeDescriptor = nodeDescriptorManager->GetDescriptor("Image"); + m_MultiComponentImageDataNodeDescriptor = nodeDescriptorManager->GetDescriptor("MultiComponentImage"); + m_DiffusionImageDataNodeDescriptor = nodeDescriptorManager->GetDescriptor("DiffusionImage"); + m_FiberBundleDataNodeDescriptor = nodeDescriptorManager->GetDescriptor("FiberBundle"); + m_PeakImageDataNodeDescriptor = nodeDescriptorManager->GetDescriptor("PeakImage"); + m_SegmentDataNodeDescriptor = nodeDescriptorManager->GetDescriptor("Segment"); + m_SurfaceDataNodeDescriptor = nodeDescriptorManager->GetDescriptor("Surface"); + m_PointSetNodeDescriptor = nodeDescriptorManager->GetDescriptor("PointSet"); + m_PlanarLineNodeDescriptor = nodeDescriptorManager->GetDescriptor("PlanarLine"); + m_PlanarCircleNodeDescriptor = nodeDescriptorManager->GetDescriptor("PlanarCircle"); + m_PlanarEllipseNodeDescriptor = nodeDescriptorManager->GetDescriptor("PlanarEllipse"); + m_PlanarAngleNodeDescriptor = nodeDescriptorManager->GetDescriptor("PlanarAngle"); + m_PlanarFourPointAngleNodeDescriptor = nodeDescriptorManager->GetDescriptor("PlanarFourPointAngle"); + m_PlanarRectangleNodeDescriptor = nodeDescriptorManager->GetDescriptor("PlanarRectangle"); + m_PlanarPolygonNodeDescriptor = nodeDescriptorManager->GetDescriptor("PlanarPolygon"); + m_PlanarPathNodeDescriptor = nodeDescriptorManager->GetDescriptor("PlanarPath"); + m_PlanarDoubleEllipseNodeDescriptor = nodeDescriptorManager->GetDescriptor("PlanarDoubleEllipse"); + m_PlanarBezierCurveNodeDescriptor = nodeDescriptorManager->GetDescriptor("PlanarBezierCurve"); + m_PlanarSubdivisionPolygonNodeDescriptor = nodeDescriptorManager->GetDescriptor("PlanarSubdivisionPolygon"); } void QmitkDataNodeContextMenu::InitDefaultActions() { - m_GlobalReinitAction = new QmitkDataNodeGlobalReinitAction(m_Parent, m_WorkbenchPartSite.Lock()); + auto workbenchPartSite = m_WorkbenchPartSite.Lock(); + + m_GlobalReinitAction = new QmitkDataNodeGlobalReinitAction(m_Parent, workbenchPartSite); 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 = new QmitkDataNodeReinitAction(m_Parent, workbenchPartSite); 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()); + QAction* saveAction = new QmitkFileSaveAction(QIcon(":/org.mitk.gui.qt.datamanager/Save_48.png"), workbenchPartSite->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 = new QmitkDataNodeRemoveAction(m_Parent, workbenchPartSite); 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_ShowSelectedNodesAction = new QmitkDataNodeShowSelectedNodesAction(m_Parent, workbenchPartSite); 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 = new QmitkDataNodeToggleVisibilityAction(m_Parent, workbenchPartSite); 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 = new QmitkDataNodeShowDetailsAction(m_Parent, workbenchPartSite); 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_OpacityAction = new QmitkDataNodeOpacityAction(m_Parent, workbenchPartSite); 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_ColorAction = new QmitkDataNodeColorAction(m_Parent, workbenchPartSite); + this->AddColorAction(m_ColorAction); - m_ColormapAction = new QmitkDataNodeColorMapAction(m_Parent, m_WorkbenchPartSite.Lock()); - // used for batch actions + m_ColormapAction = new QmitkDataNodeColorMapAction(m_Parent, workbenchPartSite); m_ImageDataNodeDescriptor->AddAction(m_ColormapAction); m_DescriptorActionList.push_back(std::make_pair(m_ImageDataNodeDescriptor, m_ColormapAction)); - if (m_DiffusionImageDataNodeDescriptor != nullptr) + if (nullptr != m_DiffusionImageDataNodeDescriptor) { - // 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_ComponentAction = new QmitkDataNodeComponentAction(m_Parent, workbenchPartSite); m_MultiComponentImageDataNodeDescriptor->AddAction(m_ComponentAction, false); m_DescriptorActionList.push_back(std::make_pair(m_MultiComponentImageDataNodeDescriptor, m_ComponentAction)); - if (m_DiffusionImageDataNodeDescriptor != nullptr) + if (nullptr != m_DiffusionImageDataNodeDescriptor) { - // 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_TextureInterpolationAction = new QmitkDataNodeTextureInterpolationAction(m_Parent, workbenchPartSite); m_ImageDataNodeDescriptor->AddAction(m_TextureInterpolationAction, false); m_DescriptorActionList.push_back(std::make_pair(m_ImageDataNodeDescriptor, m_TextureInterpolationAction)); - if (m_DiffusionImageDataNodeDescriptor != nullptr) + if (nullptr != m_DiffusionImageDataNodeDescriptor) { - // 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) + if (nullptr != m_SegmentDataNodeDescriptor) { - // 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_SurfaceRepresentationAction = new QmitkDataNodeSurfaceRepresentationAction(m_Parent, workbenchPartSite); 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"); + auto extensionPointService = berry::Platform::GetExtensionRegistry(); + auto customMenuConfigs = extensionPointService->GetConfigurationElementsFor("org.mitk.gui.qt.datamanager.contextMenuActions"); - // prepare all custom QActions - m_ConfigElements.clear(); DescriptorActionListType descriptorActionList; + m_ConfigElements.clear(); + for (const auto& customMenuConfig : customMenuConfigs) { - QString actionNodeDescriptorName = customMenuConfig->GetAttribute("nodeDescriptorName"); - QString actionLabel = customMenuConfig->GetAttribute("label"); - QString actionClass = customMenuConfig->GetAttribute("class"); + auto descriptorName = customMenuConfig->GetAttribute("nodeDescriptorName"); + auto actionLabel = customMenuConfig->GetAttribute("label"); + auto actionClass = customMenuConfig->GetAttribute("class"); - if (actionNodeDescriptorName.isEmpty() || actionLabel.isEmpty() || actionClass.isEmpty()) - { - // no properties found for the current extension point + if (descriptorName.isEmpty() || actionLabel.isEmpty() || actionClass.isEmpty()) continue; - } - // find matching descriptor - auto nodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor(actionNodeDescriptorName); - if (nullptr == nodeDescriptor) + auto descriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor(descriptorName); + + if (nullptr == descriptor) { - MITK_WARN << "Cannot add action \"" << actionLabel << "\" because descriptor " << actionNodeDescriptorName << " does not exist."; + MITK_WARN << "Cannot add action \"" << actionLabel << "\" to non-existent descriptor \"" << descriptorName << "\"."; continue; } - // create action with or without icon - QAction* contextMenuAction; - QString actionIconName = customMenuConfig->GetAttribute("icon"); - if (!actionIconName.isEmpty()) + QAction* action = nullptr; + auto actionIcon = customMenuConfig->GetAttribute("icon"); + + if (!actionIcon.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); + QIcon icon = !QFile::exists(actionIcon) + ? berry::AbstractUICTKPlugin::ImageDescriptorFromPlugin(customMenuConfig->GetContributor()->GetName(), actionIcon) + : QIcon(actionIcon); + + action = new QAction(icon, actionLabel, m_Parent); } else { - contextMenuAction = new QAction(actionLabel, m_Parent); + action = new QAction(actionLabel, m_Parent); } - // connect action trigger - connect(contextMenuAction, static_cast(&QAction::triggered), this, &QmitkDataNodeContextMenu::OnExtensionPointActionTriggered); + if (nullptr != action) + { + // See T26938. We do not know why but without the lambda function indirection, the + // connection is lost after the content menu was shown for the first time. + connect(action, &QAction::triggered, [action, this]() + { + this->OnExtensionPointActionTriggered(action); + }); - // 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); + m_ConfigElements[action] = customMenuConfig; + descriptorActionList.push_back(std::make_pair(descriptor, action)); + } } - AddDescriptorActionList(descriptorActionList); + this->AddDescriptorActionList(descriptorActionList); } void QmitkDataNodeContextMenu::InitServiceActions() { } void QmitkDataNodeContextMenu::OnContextMenuRequested(const QPoint& /*pos*/) { if (m_WorkbenchPartSite.Expired()) - { return; - } - if (m_SelectedNodes.isEmpty()) - { - // no selection set - retrieve selection from the workbench selection service - m_SelectedNodes = AbstractDataNodeAction::GetSelectedNodes(m_WorkbenchPartSite.Lock()); - } - - // if either a selection was set or a selection could be retrieved from the workbench selection service - berry::ISelection::ConstPointer selection = m_WorkbenchPartSite.Lock()->GetWorkbenchWindow()->GetSelectionService()->GetSelection(); - mitk::DataNodeSelection::ConstPointer currentSelection = selection.Cast(); + auto selection = m_WorkbenchPartSite.Lock()->GetWorkbenchWindow()->GetSelectionService()->GetSelection() + .Cast(); - if (currentSelection.IsNull() || currentSelection->IsEmpty()) - { + if (selection.IsNull() || selection->IsEmpty()) return; - } - m_SelectedNodes = QList::fromStdList(currentSelection->GetSelectedDataNodes()); + m_SelectedNodes = QList::fromStdList(selection->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); - } + this->clear(); + + auto actions = m_SelectedNodes.size() == 1 + ? this->GetActions(m_SelectedNodes.front()) + : this->GetActions(m_SelectedNodes); - // initialize abstract data node actions for (auto& action : actions) { - QmitkAbstractDataNodeAction* abstractDataNodeAction = dynamic_cast(action); - if (nullptr != abstractDataNodeAction) - { - abstractDataNodeAction->SetSelectedNodes(m_SelectedNodes); - } + auto dataNodeAction = dynamic_cast(action); + + if (nullptr != dataNodeAction) + dataNodeAction->SetSelectedNodes(m_SelectedNodes); } - addActions(actions); - popup(QCursor::pos()); + + this->addActions(actions); + this->popup(QCursor::pos()); } } -void QmitkDataNodeContextMenu::OnExtensionPointActionTriggered(bool) +void QmitkDataNodeContextMenu::OnExtensionPointActionTriggered(QAction* action) { - QAction* action = qobject_cast(sender()); - ConfigurationElementsType::const_iterator it = m_ConfigElements.find(action); - if (it == m_ConfigElements.end()) + auto configElementIter = m_ConfigElements.find(action); + + if (m_ConfigElements.end() == configElementIter) { - MITK_WARN << "Associated configuration element for action " << action->text().toStdString() << " not found."; + MITK_WARN << "Associated configuration element for action \"" << action->text() << "\" 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"); + auto configElement = configElementIter->second; + auto contextMenuAction = configElement->CreateExecutableExtension("class"); if (!m_DataStorage.IsExpired()) - { - auto dataStorage = m_DataStorage.Lock(); - contextMenuAction->SetDataStorage(dataStorage); - } + contextMenuAction->SetDataStorage(m_DataStorage.Lock()); - if (className == "QmitkCreatePolygonModelAction") + if ("QmitkCreatePolygonModelAction" == configElement->GetAttribute("class")) { - if (smoothed == "false") - { - contextMenuAction->SetSmoothed(false); - } - else - { - contextMenuAction->SetSmoothed(true); - } + contextMenuAction->SetSmoothed("true" == configElement->GetAttribute("smoothed")); 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_ImageDataNodeDescriptor->AddAction(colorAction, true); m_DescriptorActionList.push_back(std::make_pair(m_ImageDataNodeDescriptor, colorAction)); } if (nullptr != m_MultiComponentImageDataNodeDescriptor) { - m_MultiComponentImageDataNodeDescriptor->AddAction(colorAction, colorActionCanBatch); + m_MultiComponentImageDataNodeDescriptor->AddAction(colorAction, true); m_DescriptorActionList.push_back(std::make_pair(m_MultiComponentImageDataNodeDescriptor, colorAction)); } if (nullptr != m_DiffusionImageDataNodeDescriptor) { - m_DiffusionImageDataNodeDescriptor->AddAction(colorAction, colorActionCanBatch); + m_DiffusionImageDataNodeDescriptor->AddAction(colorAction, true); 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_SurfaceDataNodeDescriptor->AddAction(colorAction, true); m_DescriptorActionList.push_back(std::make_pair(m_SurfaceDataNodeDescriptor, colorAction)); } if (nullptr != m_PointSetNodeDescriptor) { - m_PointSetNodeDescriptor->AddAction(colorAction, colorActionCanBatch); + m_PointSetNodeDescriptor->AddAction(colorAction, true); m_DescriptorActionList.push_back(std::make_pair(m_PointSetNodeDescriptor, colorAction)); } if (nullptr != m_PlanarLineNodeDescriptor) { - m_PlanarLineNodeDescriptor->AddAction(colorAction, colorActionCanBatch); + m_PlanarLineNodeDescriptor->AddAction(colorAction, true); m_DescriptorActionList.push_back(std::make_pair(m_PlanarLineNodeDescriptor, colorAction)); } if (nullptr != m_PlanarCircleNodeDescriptor) { - m_PlanarCircleNodeDescriptor->AddAction(colorAction, colorActionCanBatch); + m_PlanarCircleNodeDescriptor->AddAction(colorAction, true); m_DescriptorActionList.push_back(std::make_pair(m_PlanarCircleNodeDescriptor, colorAction)); } if (nullptr != m_PlanarEllipseNodeDescriptor) { - m_PlanarEllipseNodeDescriptor->AddAction(colorAction, colorActionCanBatch); + m_PlanarEllipseNodeDescriptor->AddAction(colorAction, true); m_DescriptorActionList.push_back(std::make_pair(m_PlanarEllipseNodeDescriptor, colorAction)); } if (nullptr != m_PlanarAngleNodeDescriptor) { - m_PlanarAngleNodeDescriptor->AddAction(colorAction, colorActionCanBatch); + m_PlanarAngleNodeDescriptor->AddAction(colorAction, true); m_DescriptorActionList.push_back(std::make_pair(m_PlanarAngleNodeDescriptor, colorAction)); } if (nullptr != m_PlanarFourPointAngleNodeDescriptor) { - m_PlanarFourPointAngleNodeDescriptor->AddAction(colorAction, colorActionCanBatch); + m_PlanarFourPointAngleNodeDescriptor->AddAction(colorAction, true); m_DescriptorActionList.push_back(std::make_pair(m_PlanarFourPointAngleNodeDescriptor, colorAction)); } if (nullptr != m_PlanarRectangleNodeDescriptor) { - m_PlanarRectangleNodeDescriptor->AddAction(colorAction, colorActionCanBatch); + m_PlanarRectangleNodeDescriptor->AddAction(colorAction, true); m_DescriptorActionList.push_back(std::make_pair(m_PlanarRectangleNodeDescriptor, colorAction)); } if (nullptr != m_PlanarPolygonNodeDescriptor) { - m_PlanarPolygonNodeDescriptor->AddAction(colorAction, colorActionCanBatch); + m_PlanarPolygonNodeDescriptor->AddAction(colorAction, true); m_DescriptorActionList.push_back(std::make_pair(m_PlanarPolygonNodeDescriptor, colorAction)); } if (nullptr != m_PlanarPathNodeDescriptor) { - m_PlanarPathNodeDescriptor->AddAction(colorAction, colorActionCanBatch); + m_PlanarPathNodeDescriptor->AddAction(colorAction, true); m_DescriptorActionList.push_back(std::make_pair(m_PlanarPathNodeDescriptor, colorAction)); } if (nullptr != m_PlanarDoubleEllipseNodeDescriptor) { - m_PlanarDoubleEllipseNodeDescriptor->AddAction(colorAction, colorActionCanBatch); + m_PlanarDoubleEllipseNodeDescriptor->AddAction(colorAction, true); m_DescriptorActionList.push_back(std::make_pair(m_PlanarDoubleEllipseNodeDescriptor, colorAction)); } if (nullptr != m_PlanarBezierCurveNodeDescriptor) { - m_PlanarBezierCurveNodeDescriptor->AddAction(colorAction, colorActionCanBatch); + m_PlanarBezierCurveNodeDescriptor->AddAction(colorAction, true); m_DescriptorActionList.push_back(std::make_pair(m_PlanarBezierCurveNodeDescriptor, colorAction)); } if (nullptr != m_PlanarSubdivisionPolygonNodeDescriptor) { - m_PlanarSubdivisionPolygonNodeDescriptor->AddAction(colorAction, colorActionCanBatch); + m_PlanarSubdivisionPolygonNodeDescriptor->AddAction(colorAction, true); 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 + using ListItem = std::pair; + + std::sort(descriptorActionList.begin(), descriptorActionList.end(), [](const ListItem& left, const ListItem& 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 + descriptorActionPair.first->AddAction(descriptorActionPair.second); 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) + + for(const auto& descriptorActionPair : m_DescriptorActionList) { - if ((it->first)->CheckNode(node) || - it->first->GetNameOfClass() == "Unknown") - { - actions.append(it->second); - } + if (descriptorActionPair.first->CheckNode(node) || "Unknown" == descriptorActionPair.first->GetNameOfClass()) + actions.append(descriptorActionPair.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& descriptorActionPair : m_DescriptorActionList) { for (const auto& node : nodes) { - if ((it->first)->CheckNode(node) || - it->first->GetNameOfClass() == "Unknown") + if (descriptorActionPair.first->CheckNode(node) || "Unknown" == descriptorActionPair.first->GetNameOfClass()) { - 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 + auto batchActions = descriptorActionPair.first->GetBatchActions(); + + if (std::find(batchActions.begin(), batchActions.end(), descriptorActionPair.second) != batchActions.end()) + actions.append(descriptorActionPair.second); + + break; } } } return actions; } diff --git a/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeContextMenu.h b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeContextMenu.h index 764a40b498..2dcf8ba901 100644 --- a/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeContextMenu.h +++ b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeContextMenu.h @@ -1,136 +1,136 @@ /*============================================================================ 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 QMITKDATANODECONTEXTMENU_H #define QMITKDATANODECONTEXTMENU_H #include // qt widgets module #include "QmitkDataNodeGlobalReinitAction.h" #include "QmitkDataNodeReinitAction.h" #include "QmitkDataNodeRemoveAction.h" #include "QmitkDataNodeShowSelectedNodesAction.h" #include "QmitkDataNodeToggleVisibilityAction.h" #include "QmitkDataNodeShowDetailsAction.h" #include "QmitkDataNodeOpacityAction.h" #include "QmitkDataNodeColorAction.h" #include "QmitkDataNodeColorMapAction.h" #include "QmitkDataNodeComponentAction.h" #include "QmitkDataNodeTextureInterpolationAction.h" #include "QmitkDataNodeSurfaceRepresentationAction.h" #include "QmitkNodeDescriptor.h" // mitk core #include #include #include // blueberry ui qt plugin #include #include // qt #include class MITK_QT_APP QmitkDataNodeContextMenu : public QMenu { Q_OBJECT public: QmitkDataNodeContextMenu(berry::IWorkbenchPartSite::Pointer workbenchPartSite, QWidget* parent = nullptr); ~QmitkDataNodeContextMenu() override; void SetDataStorage(mitk::DataStorage* dataStorage); void SetBaseRenderer(mitk::BaseRenderer* baseRenderer); void SetSurfaceDecimation(bool surfaceDecimation); void SetSelectedNodes(const QList& selectedNodes); public Q_SLOTS: void OnContextMenuRequested(const QPoint& pos); - void OnExtensionPointActionTriggered(bool); + void OnExtensionPointActionTriggered(QAction* action); private: using DescriptorActionListType = std::vector>; using ConfigurationElementsType = std::map; void InitNodeDescriptors(); void InitDefaultActions(); void InitExtensionPointActions(); void InitServiceActions(); void AddColorAction(QWidgetAction* colorAction); void AddDescriptorActionList(DescriptorActionListType& descriptorActionList); QList GetActions(const mitk::DataNode* node); QList GetActions(const QList& nodes); QWidget* m_Parent; berry::IWorkbenchPartSite::WeakPtr m_WorkbenchPartSite; mitk::WeakPointer m_DataStorage; mitk::WeakPointer m_BaseRenderer; QList m_SelectedNodes; // store a list of all actions to remove them on menu destruction DescriptorActionListType m_DescriptorActionList; // stores the configuration elements for the context menu actions from extension points ConfigurationElementsType m_ConfigElements; QmitkNodeDescriptor* m_UnknownDataNodeDescriptor; QmitkNodeDescriptor* m_ImageDataNodeDescriptor; QmitkNodeDescriptor* m_MultiComponentImageDataNodeDescriptor; QmitkNodeDescriptor* m_DiffusionImageDataNodeDescriptor; QmitkNodeDescriptor* m_FiberBundleDataNodeDescriptor; QmitkNodeDescriptor* m_PeakImageDataNodeDescriptor; QmitkNodeDescriptor* m_SegmentDataNodeDescriptor; QmitkNodeDescriptor* m_SurfaceDataNodeDescriptor; QmitkNodeDescriptor* m_PointSetNodeDescriptor; QmitkNodeDescriptor* m_PlanarLineNodeDescriptor; QmitkNodeDescriptor* m_PlanarCircleNodeDescriptor; QmitkNodeDescriptor* m_PlanarEllipseNodeDescriptor; QmitkNodeDescriptor* m_PlanarAngleNodeDescriptor; QmitkNodeDescriptor* m_PlanarFourPointAngleNodeDescriptor; QmitkNodeDescriptor* m_PlanarRectangleNodeDescriptor; QmitkNodeDescriptor* m_PlanarPolygonNodeDescriptor; QmitkNodeDescriptor* m_PlanarPathNodeDescriptor; QmitkNodeDescriptor* m_PlanarDoubleEllipseNodeDescriptor; QmitkNodeDescriptor* m_PlanarBezierCurveNodeDescriptor; QmitkNodeDescriptor* m_PlanarSubdivisionPolygonNodeDescriptor; ////////////////////////////////////////////////////////////////////////// // default actions ////////////////////////////////////////////////////////////////////////// QmitkDataNodeGlobalReinitAction* m_GlobalReinitAction; QmitkDataNodeReinitAction* m_ReinitAction; QmitkDataNodeRemoveAction* m_RemoveAction; QmitkDataNodeShowSelectedNodesAction* m_ShowSelectedNodesAction; QmitkDataNodeToggleVisibilityAction* m_ToggleVisibilityAction; QmitkDataNodeShowDetailsAction* m_ShowDetailsAction; QmitkDataNodeOpacityAction* m_OpacityAction; QmitkDataNodeColorAction* m_ColorAction; QmitkDataNodeColorMapAction* m_ColormapAction; QmitkDataNodeComponentAction* m_ComponentAction; QmitkDataNodeTextureInterpolationAction* m_TextureInterpolationAction; QmitkDataNodeSurfaceRepresentationAction* m_SurfaceRepresentationAction; bool m_SurfaceDecimation; }; #endif // QMITKDATANODECONTEXTMENU_H