diff --git a/Plugins/org.mitk.gui.qt.common/files.cmake b/Plugins/org.mitk.gui.qt.common/files.cmake index 2564418383..4a2ae184c9 100755 --- a/Plugins/org.mitk.gui.qt.common/files.cmake +++ b/Plugins/org.mitk.gui.qt.common/files.cmake @@ -1,38 +1,40 @@ set(SRC_CPP_FILES QmitkAbstractRenderEditor.cpp QmitkAbstractView.cpp QmitkDataNodeSelectionProvider.cpp + QmitkDataStorageSelectionConnector.cpp QmitkDnDFrameWidget.cpp QmitkSliceNavigationListener.cpp ) set(INTERNAL_CPP_FILES QmitkCommonActivator.cpp QmitkDataNodeItemModel.cpp QmitkDataNodeSelection.cpp QmitkViewCoordinator.cpp ) set(MOC_H_FILES src/QmitkAbstractRenderEditor.h + src/QmitkDataStorageSelectionConnector.h src/QmitkDnDFrameWidget.h src/QmitkSliceNavigationListener.h src/internal/QmitkCommonActivator.h ) set(CACHED_RESOURCE_FILES ) set(QRC_FILES ) set(CPP_FILES ) foreach(file ${SRC_CPP_FILES}) set(CPP_FILES ${CPP_FILES} src/${file}) endforeach(file ${SRC_CPP_FILES}) foreach(file ${INTERNAL_CPP_FILES}) set(CPP_FILES ${CPP_FILES} src/internal/${file}) endforeach(file ${INTERNAL_CPP_FILES}) diff --git a/Plugins/org.mitk.gui.qt.common/src/QmitkDataStorageSelectionConnector.cpp b/Plugins/org.mitk.gui.qt.common/src/QmitkDataStorageSelectionConnector.cpp new file mode 100644 index 0000000000..e0adceb0b1 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.common/src/QmitkDataStorageSelectionConnector.cpp @@ -0,0 +1,128 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical Image Computing. +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. + +===================================================================*/ + +// mitk gui qt common plugin +#include "QmitkDataStorageSelectionConnector.h" +#include "internal/QmitkDataNodeSelection.h" + +// org.blueberry.ui.qt +#include + +QmitkDataStorageSelectionConnector::QmitkDataStorageSelectionConnector(QmitkDataStorageAbstractView* dataStorageAbstractView) + : m_DataStorageAbstractView(dataStorageAbstractView) + , m_SelectionService(nullptr) + , m_SelectionProvider(nullptr) +{ + m_DataNodeItemModel = std::make_shared(); + m_DataNodeSelectionModel = std::make_shared(m_DataNodeItemModel.get()); +} + +QmitkDataStorageSelectionConnector::~QmitkDataStorageSelectionConnector() +{ + RemovePostSelectionListener(); + RemoveAsSelectionProvider(); +} + +void QmitkDataStorageSelectionConnector::AddPostSelectionListener(berry::ISelectionService* selectionService) +{ + if (nullptr == selectionService) + { + return; + } + + m_SelectionService = selectionService; + m_BerrySelectionListener.reset(new berry::NullSelectionChangedAdapter(this, &QmitkDataStorageSelectionConnector::GlobalSelectionChanged)); + m_SelectionService->AddPostSelectionListener(m_BerrySelectionListener.get()); +} + +void QmitkDataStorageSelectionConnector::RemovePostSelectionListener() +{ + if (nullptr == m_SelectionService) + { + return; + } + + m_SelectionService->RemovePostSelectionListener(m_BerrySelectionListener.get()); + m_SelectionService = nullptr; +} + +void QmitkDataStorageSelectionConnector::SetAsSelectionProvider(QmitkDataNodeSelectionProvider* selectionProvider) +{ + m_SelectionProvider = selectionProvider; + connect(m_DataStorageAbstractView, SIGNAL(CurrentSelectionChanged(QList)), SLOT(FireGlobalSelectionChanged(QList))); +} + +void QmitkDataStorageSelectionConnector::RemoveAsSelectionProvider() +{ + disconnect(m_DataStorageAbstractView, SIGNAL(CurrentSelectionChanged(QList)), this, SLOT(FireGlobalSelectionChanged(QList))); +} + +void QmitkDataStorageSelectionConnector::GlobalSelectionChanged(const berry::IWorkbenchPart::Pointer& sourcePart, const berry::ISelection::ConstPointer& selection) +{ + if (sourcePart.IsNull()) + { + return; + } + + QList nodes; + if (selection.IsNull()) + { + // propagate an empty list + nodes = QList(); + } + + // transform valid selection to DataNodeSelection, which allows to retrieve the selected nodes + mitk::DataNodeSelection::ConstPointer dataNodeSelection = selection.Cast(); + if (dataNodeSelection.IsNull()) + { + // propagate an empty list + nodes = QList(); + } + else + { + nodes = QList::fromStdList(dataNodeSelection->GetSelectedDataNodes()); + } + + // set new (possibly empty) selection in the given data storage view + m_DataStorageAbstractView->SetCurrentSelection(nodes); +} + +void QmitkDataStorageSelectionConnector::FireGlobalSelectionChanged(QList nodes) +{ + if (nullptr == m_SelectionProvider) + { + return; + } + + m_SelectionProvider->SetItemSelectionModel(m_DataNodeSelectionModel.get()); + + if (nodes.empty()) + { + m_DataNodeSelectionModel->clearSelection(); + m_DataNodeItemModel->clear(); + } + else + { + m_DataNodeItemModel->clear(); + // fill the temporary helper data node item model with the nodes to select + for(const auto& node : nodes) + { + m_DataNodeItemModel->AddDataNode(node); + } + + m_DataNodeSelectionModel->select(QItemSelection(m_DataNodeItemModel->index(0, 0), m_DataNodeItemModel->index(nodes.size() - 1, 0)), QItemSelectionModel::ClearAndSelect); + } +} \ No newline at end of file diff --git a/Plugins/org.mitk.gui.qt.common/src/QmitkDataStorageSelectionConnector.h b/Plugins/org.mitk.gui.qt.common/src/QmitkDataStorageSelectionConnector.h new file mode 100644 index 0000000000..4ad2f26a74 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.common/src/QmitkDataStorageSelectionConnector.h @@ -0,0 +1,103 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical Image Computing. +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 QMITKDATASTORAGESELECTIONCONNECTOR_H +#define QMITKDATASTORAGESELECTIONCONNECTOR_H + +#include + +// qt widgets module +#include + +// mitk gui qt common plugin +#include "QmitkDataNodeSelectionProvider.h" +#include "internal/QmitkDataNodeItemModel.h" + + // blueberry ui qt plugin +#include + + /* + * @brief The QmitkDataStorageSelectionConnector is used to connect a given 'QmitkDataStorageAbstractView' with the global selection bus. + * The data storage view can be added as a selection listener to a selection service. This should be done by using 'AddPostSelectionListener' + * with the existing selection service of the surrounding 'QmitkAbstractView'. + * The data storage view can be set as a selection provider. This should be done by using 'SetAsSelectionProvider' with the existing + * selection provider of the surrounding 'QmitkAbstractView'. + */ +class MITK_QT_COMMON QmitkDataStorageSelectionConnector : public QObject +{ + Q_OBJECT + +public: + + QmitkDataStorageSelectionConnector(QmitkDataStorageAbstractView* dataStorageAbstractView); + ~QmitkDataStorageSelectionConnector(); + + /* + * @brief Create a selection listener and add it to the list of selection listener of the given selection service. + * The selection listener is connected with the 'GlobalSelectionChanged' member function, which is + * called if a berry selection is changed in the workbench. + */ + void AddPostSelectionListener(berry::ISelectionService* selectionService); + /* + * @brief Remove a selection listener from the list of selection listener of the selection service member. + */ + void RemovePostSelectionListener(); + /* + * @brief Connect the 'CurrentSelectionChanged'-slot from the member 'QmitkDataStorageAbstractView' with the + * private 'FireSelectionChanged'-function of this class. The 'FireSelectionChanged'-function transforms the + * list of selected nodes and propagates the changed selection. + */ + void SetAsSelectionProvider(QmitkDataNodeSelectionProvider* selectionProvider); + /* + * @brief Disconnect the 'CurrentSelectionChanged'-slot of the member 'QmitkDataStorageAbstractView' from the + * private 'FireSelectionChanged'-function of this class. + */ + void RemoveAsSelectionProvider(); + +private Q_SLOTS: + + /* + * @brief Send global selections to the selection provider. + * + * This function is called whenever a local selection is changed in the workbench and the 'QmitkDataStorageAbstractView' + * is set as selection provider. + * The newly selected data nodes are added temporary to the 'QmitkDataNodeItemModel', which is then used to define + * the indices to select. + * The 'QItemSelectionModel' is set for the selection provider and its items are selected by the indices previously defined. + */ + void FireGlobalSelectionChanged(QList nodes); + +private: + + QmitkDataStorageAbstractView* m_DataStorageAbstractView; + std::unique_ptr m_BerrySelectionListener; + berry::ISelectionService* m_SelectionService; + QmitkDataNodeSelectionProvider* m_SelectionProvider; + std::shared_ptr m_DataNodeItemModel; + std::shared_ptr m_DataNodeSelectionModel; + + /* + * @brief Handle global selection received from the selection service. + * + * This function is called whenever a global berry selection is changed in the workbench. + * The new selection is transformed into a data node selection and the contained data nodes are propagated + * as the new current selection of the data storage view member. + */ + void GlobalSelectionChanged(const berry::IWorkbenchPart::Pointer& sourcePart, const berry::ISelection::ConstPointer& selection); + +}; + +#endif // QMITKDATASTORAGESELECTIONCONNECTOR_H