diff --git a/Modules/QtWidgets/files.cmake b/Modules/QtWidgets/files.cmake index 3045fb9029..970d05401a 100644 --- a/Modules/QtWidgets/files.cmake +++ b/Modules/QtWidgets/files.cmake @@ -1,130 +1,135 @@ file(GLOB_RECURSE H_FILES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/include/*") set(CPP_FILES QmitkAbstractDataStorageModel.cpp QmitkAbstractMultiWidget.cpp QmitkApplicationCursor.cpp QmitkDataStorageComboBox.cpp QmitkDataStorageDefaultListModel.cpp + QmitkDataStorageHistoryModel.cpp QmitkDataStorageListModel.cpp QmitkDataStorageTableModel.cpp QmitkDataStorageSimpleTreeModel.cpp QmitkDataStorageTreeModel.cpp QmitkDataStorageTreeModelInternalItem.cpp QmitkDnDDataNodeWidget.cpp QmitkFileReaderOptionsDialog.cpp QmitkFileReaderWriterOptionsWidget.cpp QmitkFileWriterOptionsDialog.cpp QmitkInteractionSchemeToolBar.cpp QmitkIOUtil.cpp QmitkLevelWindowPresetDefinitionDialog.cpp QmitkLevelWindowRangeChangeDialog.cpp QmitkLevelWindowWidgetContextMenu.cpp QmitkLevelWindowWidget.cpp QmitkLineEditLevelWindowWidget.cpp QmitkMemoryUsageIndicatorView.cpp QmitkMouseModeSwitcher.cpp QmitkMimeTypes.cpp QmitkMultiWidgetConfigurationToolBar.cpp QmitkMultiWidgetLayoutManager.cpp QmitkMultiWidgetLayoutSelectionWidget.cpp QmitkNodeDescriptor.cpp QmitkColoredNodeDescriptor.cpp QmitkNodeDescriptorManager.cpp QmitkProgressBar.cpp QmitkPropertiesTableEditor.cpp QmitkPropertiesTableModel.cpp QmitkPropertyDelegate.cpp QmitkRegisterClasses.cpp QmitkRenderingManager.cpp QmitkRenderingManagerFactory.cpp QmitkRenderWindow.cpp QmitkRenderWindowMenu.cpp QmitkRenderWindowWidget.cpp QmitkServiceListWidget.cpp QmitkSliderLevelWindowWidget.cpp QmitkStdMultiWidget.cpp QmitkMxNMultiWidget.cpp QmitkDataStorageComboBoxWithSelectNone.cpp QmitkDataStorageFilterProxyModel.cpp QmitkPropertyItem.cpp QmitkPropertyItemDelegate.cpp QmitkPropertyItemModel.cpp QmitkStyleManager.cpp QmitkAbstractDataStorageInspector.cpp QmitkDataStorageFavoriteNodesInspector.cpp QmitkDataStorageListInspector.cpp QmitkDataStorageTreeInspector.cpp + QmitkDataStorageSelectionHistoryInspector.cpp QmitkModelViewSelectionConnector.cpp mitkIDataStorageInspectorProvider.cpp mitkQtWidgetsActivator.cpp mitkDataStorageInspectorGenerator.cpp QmitkOverlayWidget.cpp QmitkNodeDetailsDialog.cpp ) set(MOC_H_FILES include/QmitkAbstractDataStorageModel.h include/QmitkAbstractMultiWidget.h include/QmitkDataStorageComboBox.h include/QmitkDataStorageTableModel.h include/QmitkDataStorageTreeModel.h include/QmitkDataStorageSimpleTreeModel.h include/QmitkDataStorageDefaultListModel.h include/QmitkDnDDataNodeWidget.h include/QmitkFileReaderOptionsDialog.h include/QmitkFileReaderWriterOptionsWidget.h include/QmitkFileWriterOptionsDialog.h include/QmitkInteractionSchemeToolBar.h include/QmitkLevelWindowPresetDefinitionDialog.h include/QmitkLevelWindowRangeChangeDialog.h include/QmitkLevelWindowWidgetContextMenu.h include/QmitkLevelWindowWidget.h include/QmitkLineEditLevelWindowWidget.h include/QmitkMemoryUsageIndicatorView.h include/QmitkMouseModeSwitcher.h include/QmitkMultiWidgetConfigurationToolBar.h include/QmitkMultiWidgetLayoutManager.h include/QmitkMultiWidgetLayoutSelectionWidget.h include/QmitkNodeDescriptor.h include/QmitkColoredNodeDescriptor.h include/QmitkNodeDescriptorManager.h include/QmitkProgressBar.h include/QmitkPropertiesTableEditor.h include/QmitkPropertyDelegate.h include/QmitkRenderingManager.h include/QmitkRenderWindow.h include/QmitkRenderWindowMenu.h include/QmitkRenderWindowWidget.h include/QmitkServiceListWidget.h include/QmitkSliderLevelWindowWidget.h include/QmitkStdMultiWidget.h include/QmitkMxNMultiWidget.h include/QmitkDataStorageComboBoxWithSelectNone.h include/QmitkPropertyItemDelegate.h include/QmitkPropertyItemModel.h include/QmitkAbstractDataStorageInspector.h include/QmitkDataStorageFavoriteNodesInspector.h include/QmitkDataStorageListInspector.h include/QmitkDataStorageTreeInspector.h + include/QmitkDataStorageHistoryModel.h + include/QmitkDataStorageSelectionHistoryInspector.h include/QmitkModelViewSelectionConnector.h include/QmitkOverlayWidget.h include/QmitkNodeDetailsDialog.h ) set(UI_FILES src/QmitkFileReaderOptionsDialog.ui src/QmitkFileWriterOptionsDialog.ui src/QmitkLevelWindowPresetDefinition.ui src/QmitkLevelWindowWidget.ui src/QmitkLevelWindowRangeChange.ui src/QmitkMemoryUsageIndicator.ui src/QmitkMultiWidgetLayoutSelectionWidget.ui src/QmitkServiceListWidgetControls.ui src/QmitkDataStorageListInspector.ui src/QmitkDataStorageTreeInspector.ui + src/QmitkDataStorageSelectionHistoryInspector.ui ) set(QRC_FILES resource/Qmitk.qrc ) diff --git a/Modules/QtWidgets/include/QmitkDataStorageDefaultListModel.h b/Modules/QtWidgets/include/QmitkDataStorageDefaultListModel.h index 2de2f0a400..100af89c77 100644 --- a/Modules/QtWidgets/include/QmitkDataStorageDefaultListModel.h +++ b/Modules/QtWidgets/include/QmitkDataStorageDefaultListModel.h @@ -1,78 +1,78 @@ /*============================================================================ 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 QMITKDATASTORAGEDEFAULTLISTMODEL_H #define QMITKDATASTORAGEDEFAULTLISTMODEL_H #include // qt widgets module #include /** * @brief The 'QmitkDataStorageDefaultListModel' is a basic list model, derived from the 'QmitkAbstractDataStorageModel'. * It provides functions to accept a data storage and a node predicate in order to customize the model data nodes. * Furthermore it overrides the functions of 'QAbstractItemModel' to create a simple qt list model. * This model can be used in conjunction with a 'QmitkDataStorageSelectionConnector'. */ class MITKQTWIDGETS_EXPORT QmitkDataStorageDefaultListModel : public QmitkAbstractDataStorageModel { Q_OBJECT public: QmitkDataStorageDefaultListModel(QObject *parent); // override from 'QmitkAbstractDataStorageModel' /* * @brief See 'QmitkAbstractDataStorageModel' */ void DataStorageChanged() override; /* * @brief See 'QmitkAbstractDataStorageModel' */ void NodePredicateChanged() override; /* * @brief See 'QmitkAbstractDataStorageModel' */ void NodeAdded(const mitk::DataNode* node) override; /* * @brief See 'QmitkAbstractDataStorageModel' */ void NodeChanged(const mitk::DataNode* node) override; /* * @brief See 'QmitkAbstractDataStorageModel' */ void NodeRemoved(const mitk::DataNode* node) override; // override pure virtual from 'QAbstractItemModel' QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; QModelIndex parent(const QModelIndex &child) const override; int rowCount(const QModelIndex &parent = QModelIndex()) const override; int columnCount(const QModelIndex &parent = QModelIndex()) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; // override for customization QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; Qt::ItemFlags flags(const QModelIndex &index) const override; -private: +protected: - void UpdateModelData(); + virtual void UpdateModelData(); std::vector m_DataNodes; }; #endif // QMITKDATASTORAGEDEFAULTLISTMODEL_H diff --git a/Modules/QtWidgets/include/QmitkDataStorageHistoryModel.h b/Modules/QtWidgets/include/QmitkDataStorageHistoryModel.h new file mode 100644 index 0000000000..8e77a6d8f5 --- /dev/null +++ b/Modules/QtWidgets/include/QmitkDataStorageHistoryModel.h @@ -0,0 +1,48 @@ +/*============================================================================ + +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 QMITKDATASTORAGEHISTORYMODEL_H +#define QMITKDATASTORAGEHISTORYMODEL_H + +#include + +#include + +/** +* @brief Internal DataStorage model to represent the history of node selections. +* +* The model will present all nodes in the history under the following conditions +* - the nodes are sorted by selection time (lifo -> last is first) +* - node must be in the storage +* - node must be valid +* - node will only be in the history once. +* +*/ + +class MITKQTWIDGETS_EXPORT QmitkDataStorageHistoryModel : public QmitkDataStorageDefaultListModel +{ + Q_OBJECT + +public: + + QmitkDataStorageHistoryModel(QObject *parent); + + /** Adds the passed node to the history. If the node is already in the history, old instances will be removed. + If the passed node is nullptr, it will be ignored.*/ + static void AddNodeToHistory(mitk::DataNode* node); + static void ResetHistory(); + +protected: + void UpdateModelData() override; +}; + +#endif // QMITKDATASTORAGEHISTORYMODEL_H diff --git a/Modules/QtWidgets/include/QmitkDataStorageInspectorProviderBase.h b/Modules/QtWidgets/include/QmitkDataStorageInspectorProviderBase.h index 65ffd67736..44c32549e4 100644 --- a/Modules/QtWidgets/include/QmitkDataStorageInspectorProviderBase.h +++ b/Modules/QtWidgets/include/QmitkDataStorageInspectorProviderBase.h @@ -1,75 +1,78 @@ /*============================================================================ 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 __QMITK_DATA_STORAGE_INSPECTOR_PROVIDER_BASE_H #define __QMITK_DATA_STORAGE_INSPECTOR_PROVIDER_BASE_H #include // Microservices #include #include #include // MITK #include /** * @brief Base class for DataStorage inspector provider. + * + * This class is the default implementation for a inspector provider. You can template it with + * the respective inspector class to directly use it. */ template class QmitkDataStorageInspectorProviderBase : public mitk::IDataStorageInspectorProvider { public: QmitkAbstractDataStorageInspector* CreateInspector() const override; std::string GetInspectorID() const override; std::string GetInspectorDisplayName() const override; std::string GetInspectorDescription() const override; us::ServiceRegistration RegisterService( us::ModuleContext *context = us::GetModuleContext()); void UnregisterService(); QmitkDataStorageInspectorProviderBase(const std::string& id); QmitkDataStorageInspectorProviderBase(const std::string& id, const std::string& displayName, const std::string& desc= "" ); ~QmitkDataStorageInspectorProviderBase() override; protected: QmitkDataStorageInspectorProviderBase(const QmitkDataStorageInspectorProviderBase &other); QmitkDataStorageInspectorProviderBase &operator=(const QmitkDataStorageInspectorProviderBase &other) = delete; virtual us::ServiceProperties GetServiceProperties() const; /** * \brief Set the service ranking for this file reader. * * Default is zero and should only be chosen differently for a reason. * The ranking is used to determine which provider to use if several * equivalent providers have been found. * It may be used to replace a default provider from MITK in your own project. */ void SetRanking(int ranking); int GetRanking() const; private: class Impl; std::unique_ptr d; }; #ifndef ITK_MANUAL_INSTANTIATION #include "QmitkDataStorageInspectorProviderBase.tpp" #endif #endif /* __QMITK_DATA_STORAGE_INSPECTOR_PROVIDER_BASE_H */ diff --git a/Modules/QtWidgets/include/QmitkDataStorageSelectionHistoryInspector.h b/Modules/QtWidgets/include/QmitkDataStorageSelectionHistoryInspector.h new file mode 100644 index 0000000000..80ba29e334 --- /dev/null +++ b/Modules/QtWidgets/include/QmitkDataStorageSelectionHistoryInspector.h @@ -0,0 +1,49 @@ +/*============================================================================ + +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 QMITKDATASTORAGESELECTIONHISTORYINSPECTOR_H +#define QMITKDATASTORAGESELECTIONHISTORYINSPECTOR_H + +#include + +#include +#include + +#include "ui_QmitkDataStorageSelectionHistoryInspector.h" + +/* +* @brief This is an inspector that offers a simple list view on the last selected nodes (in chronologic order) in a data storage. +*/ +class MITKQTWIDGETS_EXPORT QmitkDataStorageSelectionHistoryInspector : public QmitkAbstractDataStorageInspector +{ + Q_OBJECT + +public: + QmitkDataStorageSelectionHistoryInspector(QWidget* parent = nullptr); + + QAbstractItemView* GetView() override; + const QAbstractItemView* GetView() const override; + + void SetSelectionMode(SelectionMode mode) override; + SelectionMode GetSelectionMode() const override; + + static void AddNodeToHistory(mitk::DataNode* node); + static void ResetHistory(); + +protected: + void Initialize() override; + + QmitkAbstractDataStorageModel* m_StorageModel; + Ui_QmitkDataStorageSelectionHistoryInspector m_Controls; +}; + +#endif // QMITKDATASTORAGESELECTIONHISTORYINSPECTOR_H diff --git a/Modules/QtWidgets/include/QmitkModelViewSelectionConnector.h b/Modules/QtWidgets/include/QmitkModelViewSelectionConnector.h index 08ba039adc..8a502c8f93 100644 --- a/Modules/QtWidgets/include/QmitkModelViewSelectionConnector.h +++ b/Modules/QtWidgets/include/QmitkModelViewSelectionConnector.h @@ -1,151 +1,152 @@ /*============================================================================ 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 QMITKMODELVIEWSELECTIONCONNECTOR_H #define QMITKMODELVIEWSELECTIONCONNECTOR_H #include // qt widgets module #include // qt #include /** -* @brief The 'QmitkModelViewSelectionConnector' is used to handle the selections of a model-view-pair. +* @brief The 'QmitkModelViewSelectionConnector' is used to handle the selections of a model-view-pair and to synchornize them with external node selections +* (e.g. communicated by the application). * -* The class accepts a view and a model, which are used to react to selection changes. This class is able to propagate selection changes +* The class accepts a view and its model, which are used to react to selection changes. This class is able to propagate selection changes * to and receive from its surrounding class. * * The model-view-pair 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 model-view-pair can be set as a selection provider. This should be done by using 'SetAsSelectionProvider' with the existing * selection provider of the surrounding 'QmitkAbstractView'. * * The 'QmitkModelViewSelectionConnector' offers a public slot and signal that can be used to set / propagate the selected * nodes in the current view: * The 'SetCurrentSelection'-slot finds the indices of the given selected nodes in its internal data storage model and * changes the selection of the internal data storage model accordingly. * The 'CurrentSelectionChanged'-signal sends a list of selected nodes to its environment. * The 'CurrentSelectionChanged'-signal is emitted by the 'ChangeModelSelection'-function, which transforms the internal item view's * selection into a data node list. The 'ChangeModelSelection'-function is called whenever the selection of the item view's * selection model changes. */ class MITKQTWIDGETS_EXPORT QmitkModelViewSelectionConnector : public QObject { Q_OBJECT public: QmitkModelViewSelectionConnector(); /** * @brief Set the view whose selection model is used to propagate or receive selection changes. Use the view's data model * to transform selected nodes into model indexes and vice versa. * * @pre The view's data model needs to be a 'QmitkAbstractDataStorageModel'. If so, the data model is received from * the view and stored as a private member. * The data model must return 'mitk::DataNode::Pointer' objects for model indexes if the role is 'QmitkDataNodeRole'. * @throw mitk::Exception, if the view is invalid or the view's data model is not a valid 'QmitkAbstractDataStorageModel'. * * @param view The view to set. */ void SetView(QAbstractItemView* view); /** * @brief Retrieve the currently selected nodes (equals the last CurrentSelectionChanged values). */ QList GetSelectedNodes() const; bool GetSelectOnlyVisibleNodes() const; Q_SIGNALS: /** * @brief A signal that will be emitted by the 'ChangeModelSelection'-function. This happens if the selection model * of the private member item view has changed. * * @param nodes A list of data nodes that are newly selected. */ void CurrentSelectionChanged(QList nodes); public Q_SLOTS: /** * @brief Change the selection mode of the item view's selection model. * * If true, an incoming selection will be filtered (reduced) to only those nodes that are visible to the current view. * An outgoing selection can then at most contain the filtered nodes. * If false, the incoming non-visible selection will be stored and later added to the outgoing selection, * to include the part of the original selection that was not visible. * The part of the original selection, that is non-visible are the nodes that do not met the predicate of the * associated QmitkAbstractDataStorageModel. * * @param selectOnlyVisibleNodes The bool value to define the selection modus. */ void SetSelectOnlyVisibleNodes(bool selectOnlyVisibleNodes); /** * @brief Transform a list of data nodes into a model selection and set this as a new selection of the * selection model of the private member item view. * * The function filters the given list of nodes according to the 'm_SelectOnlyVisibleNodes' member variable. If * necessary, the non-visible nodes are stored. This is done if 'm_SelectOnlyVisibleNodes' is false: In this case * the selection may be filtered and only a subset of the selected nodes may be visible and therefore (de-)selectable * in the data storage viewer. By storing the non-visible nodes it is possible to send the new, modified selection * but also include the selected nodes from the original selection that could not be modified (see 'SetSelectOnlyVisibleNodes'). * * @param nodes A list of data nodes that should be newly selected. */ void SetCurrentSelection(QList selectedNodes); private Q_SLOTS: /** * @brief Transform a model selection into a data node list and emit the 'CurrentSelectionChanged'-signal. * * The function adds the selected nodes from the original selection that could not be modified, if * 'm_SelectOnlyVisibleNodes' is false. * This slot is internally connected to the 'selectionChanged'-signal of the selection model of the private member item view. * * @param selected The newly selected items. * @param deselected The newly deselected items. */ void ChangeModelSelection(const QItemSelection& selected, const QItemSelection& deselected); private: QmitkAbstractDataStorageModel* m_Model; QAbstractItemView* m_View; bool m_SelectOnlyVisibleNodes; QList m_NonVisibleSelection; /* * @brief Retrieve the currently selected nodes from the selection model of the private member item view by * transforming the selection indexes into a data node list. * * In order to transform the indices into data nodes, the private data storage model must return * 'mitk::DataNode::Pointer' objects for model indexes if the role is QmitkDataNodeRole. */ QList GetInternalSelectedNodes() const; /* * @brief Filter the list of given nodes such that only those nodes are used that are valid * when using the data storage model's node predicate. * If no node predicate was set or the data storage model is invalid, the input list * of given nodes is returned. */ QList FilterNodeList(const QList& nodes) const; }; /* * @brief Return true, if the nodes in the list of two given selections are equal (Sorting is ignored. Any permutation is valid.)*/ bool MITKQTWIDGETS_EXPORT EqualNodeSelections(const QList& selection1, const QList& selection2); #endif // QMITKMODELVIEWSELECTIONCONNECTOR_H diff --git a/Modules/QtWidgets/src/QmitkDataStorageHistoryModel.cpp b/Modules/QtWidgets/src/QmitkDataStorageHistoryModel.cpp new file mode 100644 index 0000000000..6bfcd722e3 --- /dev/null +++ b/Modules/QtWidgets/src/QmitkDataStorageHistoryModel.cpp @@ -0,0 +1,86 @@ +/*============================================================================ + +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 + +#include "mitkWeakPointer.h" +#include +#include +#include + +/** Type of the internal history container. + Remark: It stores raw pointer instead of mitk::WeakPointer + because this lead to occasional crashes when the application was closed (see T24770 for a similar problem + with the same reason*/ +using NodeHistoryType = std::deque< const mitk::DataNode* >; + +/** History of node selection. It is sorted from new to old.*/ +NodeHistoryType _nodeHistory; +std::mutex _historyMutex; + +QmitkDataStorageHistoryModel::QmitkDataStorageHistoryModel(QObject *parent) : QmitkDataStorageDefaultListModel(parent) +{ +} + +void QmitkDataStorageHistoryModel::UpdateModelData() +{ + std::vector dataNodes; + if (!m_DataStorage.IsExpired()) + { + auto dataStorage = m_DataStorage.Lock(); + mitk::DataStorage::SetOfObjects::ConstPointer nodesCandidats; + if (m_NodePredicate.IsNotNull()) + { + nodesCandidats = dataStorage->GetSubset(m_NodePredicate); + } + else + { + nodesCandidats = dataStorage->GetAll(); + } + + const std::lock_guard lock(_historyMutex); + + for (auto historyNode : _nodeHistory) + { + auto finding = std::find(nodesCandidats->begin(), nodesCandidats->end(), historyNode); + if (finding != nodesCandidats->end()) + { + dataNodes.push_back(*finding); + } + } + } + + // update the model, so that it will be filled with the nodes of the new data storage + beginResetModel(); + m_DataNodes = dataNodes; + endResetModel(); +} + +void QmitkDataStorageHistoryModel::AddNodeToHistory(mitk::DataNode* node) +{ + const std::lock_guard lock(_historyMutex); + + auto finding = std::find(std::begin(_nodeHistory), std::end(_nodeHistory), node); + while (finding != std::end(_nodeHistory)) + { + _nodeHistory.erase(finding); + finding = std::find(std::begin(_nodeHistory), std::end(_nodeHistory), node); + } + + _nodeHistory.push_front(node); +} + +void QmitkDataStorageHistoryModel::ResetHistory() +{ + const std::lock_guard lock(_historyMutex); + _nodeHistory.clear(); +} diff --git a/Modules/QtWidgets/src/QmitkDataStorageSelectionHistoryInspector.cpp b/Modules/QtWidgets/src/QmitkDataStorageSelectionHistoryInspector.cpp new file mode 100644 index 0000000000..a9fe9b5722 --- /dev/null +++ b/Modules/QtWidgets/src/QmitkDataStorageSelectionHistoryInspector.cpp @@ -0,0 +1,67 @@ +/*============================================================================ + +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 + +#include + +QmitkDataStorageSelectionHistoryInspector::QmitkDataStorageSelectionHistoryInspector(QWidget* parent/* = nullptr*/) + : QmitkAbstractDataStorageInspector(parent) +{ + m_Controls.setupUi(this); + + m_Controls.view->setSelectionMode(QAbstractItemView::ExtendedSelection); + m_Controls.view->setSelectionBehavior(QAbstractItemView::SelectRows); + m_Controls.view->setAlternatingRowColors(true); + + m_StorageModel = new QmitkDataStorageHistoryModel(this); + + m_Controls.view->setModel(m_StorageModel); +} + +QAbstractItemView* QmitkDataStorageSelectionHistoryInspector::GetView() +{ + return m_Controls.view; +} + +const QAbstractItemView* QmitkDataStorageSelectionHistoryInspector::GetView() const +{ + return m_Controls.view; +} + +void QmitkDataStorageSelectionHistoryInspector::Initialize() +{ + m_StorageModel->SetDataStorage(m_DataStorage.Lock()); + m_StorageModel->SetNodePredicate(m_NodePredicate); + + m_Connector->SetView(m_Controls.view); +} + +void QmitkDataStorageSelectionHistoryInspector::SetSelectionMode(SelectionMode mode) +{ + m_Controls.view->setSelectionMode(mode); +} + +QmitkDataStorageSelectionHistoryInspector::SelectionMode QmitkDataStorageSelectionHistoryInspector::GetSelectionMode() const +{ + return m_Controls.view->selectionMode(); +} + +void QmitkDataStorageSelectionHistoryInspector::AddNodeToHistory(mitk::DataNode* node) +{ + QmitkDataStorageHistoryModel::AddNodeToHistory(node); +} + +void QmitkDataStorageSelectionHistoryInspector::ResetHistory() +{ + QmitkDataStorageHistoryModel::ResetHistory(); +} diff --git a/Modules/QtWidgets/src/QmitkDataStorageSelectionHistoryInspector.ui b/Modules/QtWidgets/src/QmitkDataStorageSelectionHistoryInspector.ui new file mode 100644 index 0000000000..99d360615f --- /dev/null +++ b/Modules/QtWidgets/src/QmitkDataStorageSelectionHistoryInspector.ui @@ -0,0 +1,46 @@ + + + QmitkDataStorageSelectionHistoryInspector + + + + 0 + 0 + 400 + 300 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QAbstractItemView::NoEditTriggers + + + true + + + + + + + + diff --git a/Modules/QtWidgets/src/mitkQtWidgetsActivator.cpp b/Modules/QtWidgets/src/mitkQtWidgetsActivator.cpp index 078cc309c1..deaf7af8b7 100644 --- a/Modules/QtWidgets/src/mitkQtWidgetsActivator.cpp +++ b/Modules/QtWidgets/src/mitkQtWidgetsActivator.cpp @@ -1,36 +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. ============================================================================*/ #include "mitkQtWidgetsActivator.h" // Micro Services #include #include // Qmitk #include "QmitkDataStorageInspectorProviderBase.h" #include "QmitkDataStorageListInspector.h" #include "QmitkDataStorageTreeInspector.h" +#include "QmitkDataStorageSelectionHistoryInspector.h" #include "QmitkDataStorageFavoriteNodesInspector.h" void MitkQtWidgetsActivator::Load(us::ModuleContext * /*context*/) { m_TreeInspector.reset(new QmitkDataStorageInspectorProviderBase("org.mitk.QmitkDataStorageListInspector", "Simple list", "Displays the filtered content of the data storage in a simple list.")); m_ListInspector.reset(new QmitkDataStorageInspectorProviderBase("org.mitk.QmitkDataStorageTreeInspector", "Rendering tree", "Displays the filtered content of the data storage as the current rendering tree. \n(Equals the old data manager view)")); + m_HistoryInspector.reset(new QmitkDataStorageInspectorProviderBase("org.mitk.QmitkDataStorageSelectionHistoryInspector", "Selection history", "Displays the filtered history of all node selections in this application session. \nThe nodes are sorted from new to old selections.\nOnly nodes that are still in the data storage will be displayed.")); m_FavoriteNodesInspector.reset(new QmitkDataStorageInspectorProviderBase("org.mitk.QmitkDataStorageFavoriteNodesInspector", "Favorite nodes list", "Displays the favorite nodes of the data storage in a simple list.")); } void MitkQtWidgetsActivator::Unload(us::ModuleContext *) { } US_EXPORT_MODULE_ACTIVATOR(MitkQtWidgetsActivator) diff --git a/Modules/QtWidgets/src/mitkQtWidgetsActivator.h b/Modules/QtWidgets/src/mitkQtWidgetsActivator.h index d80790ffa1..6a72708a07 100644 --- a/Modules/QtWidgets/src/mitkQtWidgetsActivator.h +++ b/Modules/QtWidgets/src/mitkQtWidgetsActivator.h @@ -1,41 +1,42 @@ /*============================================================================ 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 MITKQTWIDGETSACTIVATOR_H_ #define MITKQTWIDGETSACTIVATOR_H_ // Micro Services #include #include #include #include #include #include "mitkIDataStorageInspectorProvider.h" /* * This is the module activator for the "QtWidgets" module. */ class MitkQtWidgetsActivator : public us::ModuleActivator { public: void Load(us::ModuleContext *context) override; void Unload(us::ModuleContext *) override; private: std::unique_ptr m_TreeInspector; std::unique_ptr m_ListInspector; + std::unique_ptr m_HistoryInspector; std::unique_ptr m_FavoriteNodesInspector; }; #endif // MITKCOREACTIVATOR_H_ diff --git a/Plugins/org.mitk.gui.qt.common/src/QmitkNodeSelectionDialog.cpp b/Plugins/org.mitk.gui.qt.common/src/QmitkNodeSelectionDialog.cpp index cce75d4439..fc074dfb4a 100644 --- a/Plugins/org.mitk.gui.qt.common/src/QmitkNodeSelectionDialog.cpp +++ b/Plugins/org.mitk.gui.qt.common/src/QmitkNodeSelectionDialog.cpp @@ -1,193 +1,199 @@ /*============================================================================ 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 "QmitkNodeSelectionDialog.h" #include #include +#include QmitkNodeSelectionDialog::QmitkNodeSelectionDialog(QWidget* parent, QString title, QString hint) : QDialog(parent), m_NodePredicate(nullptr), m_SelectOnlyVisibleNodes(false), m_SelectedNodes(NodeList()), m_SelectionMode(QAbstractItemView::SingleSelection) { m_Controls.setupUi(this); auto providers = mitk::DataStorageInspectorGenerator::GetProviders(); auto visibleProviders = mitk::GetVisibleDataStorageInspectors(); auto favoriteID = mitk::GetFavoriteDataStorageInspector(); if (visibleProviders.empty()) { MITK_DEBUG << "No presets for visible node selection inspectors available. Use fallback (show all available inspectors)"; unsigned int order = 0; for (auto proIter : providers) { visibleProviders.insert(std::make_pair(order, proIter.first)); ++order; } } int favIndex = 0; bool favoriteFound = false; for (auto proIter : visibleProviders) { auto finding = providers.find(proIter.second); if (finding != providers.end()) { auto inspector = finding->second->CreateInspector(); QString name = QString::fromStdString(finding->second->GetInspectorDisplayName()); QString desc = QString::fromStdString(finding->second->GetInspectorDescription()); AddPanel(inspector, name, desc); favoriteFound = favoriteFound || proIter.second == favoriteID; if (!favoriteFound) { ++favIndex; } } else { MITK_DEBUG << "No provider registered for inspector that is defined as visible in the preferences. Illegal inspector ID: " << proIter.second; } } m_Controls.tabWidget->setCurrentIndex(favIndex); this->setWindowTitle(title); this->setToolTip(hint); m_Controls.hint->setText(hint); m_Controls.hint->setVisible(!hint.isEmpty()); m_FavoriteNodesButton = new QPushButton("Add to favorites"); m_Controls.buttonBox->addButton(m_FavoriteNodesButton, QDialogButtonBox::ActionRole); connect(m_FavoriteNodesButton, &QPushButton::clicked, this, &QmitkNodeSelectionDialog::OnFavoriteNodesButtonClicked); connect(m_Controls.buttonBox, SIGNAL(accepted()), this, SLOT(OnOK())); connect(m_Controls.buttonBox, SIGNAL(rejected()), this, SLOT(OnCancel())); } void QmitkNodeSelectionDialog::SetDataStorage(mitk::DataStorage* dataStorage) { if (m_DataStorage != dataStorage) { m_DataStorage = dataStorage; if (!m_DataStorage.IsExpired()) { for (auto panel : m_Panels) { panel->SetDataStorage(dataStorage); } } } } void QmitkNodeSelectionDialog::SetNodePredicate(mitk::NodePredicateBase* nodePredicate) { if (m_NodePredicate != nodePredicate) { m_NodePredicate = nodePredicate; for (auto panel : m_Panels) { panel->SetNodePredicate(m_NodePredicate); } } } mitk::NodePredicateBase* QmitkNodeSelectionDialog::GetNodePredicate() const { return m_NodePredicate; } QmitkNodeSelectionDialog::NodeList QmitkNodeSelectionDialog::GetSelectedNodes() const { return m_SelectedNodes; } void QmitkNodeSelectionDialog::SetSelectOnlyVisibleNodes(bool selectOnlyVisibleNodes) { if (m_SelectOnlyVisibleNodes != selectOnlyVisibleNodes) { m_SelectOnlyVisibleNodes = selectOnlyVisibleNodes; for (auto panel : m_Panels) { panel->SetSelectOnlyVisibleNodes(m_SelectOnlyVisibleNodes); } } } void QmitkNodeSelectionDialog::SetCurrentSelection(NodeList selectedNodes) { m_SelectedNodes = selectedNodes; for (auto panel : m_Panels) { panel->SetCurrentSelection(selectedNodes); } } void QmitkNodeSelectionDialog::OnSelectionChanged(NodeList selectedNodes) { SetCurrentSelection(selectedNodes); emit CurrentSelectionChanged(selectedNodes); } void QmitkNodeSelectionDialog::AddPanel(QmitkAbstractDataStorageInspector* view, QString name, QString desc) { view->setParent(this); view->SetSelectionMode(m_SelectionMode); auto tabPanel = new QWidget(); tabPanel->setObjectName(QString("tab_")+name); tabPanel->setToolTip(desc); m_Controls.tabWidget->insertTab(m_Controls.tabWidget->count(), tabPanel, name); auto verticalLayout = new QVBoxLayout(tabPanel); verticalLayout->setSpacing(0); verticalLayout->setContentsMargins(0, 0, 0, 0); verticalLayout->addWidget(view); m_Panels.push_back(view); connect(view, &QmitkAbstractDataStorageInspector::CurrentSelectionChanged, this, &QmitkNodeSelectionDialog::OnSelectionChanged); } void QmitkNodeSelectionDialog::OnFavoriteNodesButtonClicked() { for (auto node : m_SelectedNodes) { node->SetBoolProperty("org.mitk.selection.favorite", true); } } void QmitkNodeSelectionDialog::OnOK() { + for (auto node : m_SelectedNodes) + { + QmitkDataStorageSelectionHistoryInspector::AddNodeToHistory(node); + } + this->accept(); } void QmitkNodeSelectionDialog::OnCancel() { this->reject(); } void QmitkNodeSelectionDialog::SetSelectionMode(SelectionMode mode) { m_SelectionMode = mode; for (auto panel : m_Panels) { panel->SetSelectionMode(mode); } } QmitkNodeSelectionDialog::SelectionMode QmitkNodeSelectionDialog::GetSelectionMode() const { return m_SelectionMode; }