diff --git a/Modules/QtWidgets/include/QmitkNodeDescriptorManager.h b/Modules/QtWidgets/include/QmitkNodeDescriptorManager.h index 924be1623b..8b8024a523 100644 --- a/Modules/QtWidgets/include/QmitkNodeDescriptorManager.h +++ b/Modules/QtWidgets/include/QmitkNodeDescriptorManager.h @@ -1,117 +1,118 @@ /*=================================================================== 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 QmitkNodeDescriptorManager_h #define QmitkNodeDescriptorManager_h #include #include "QmitkNodeDescriptor.h" /** * \ingroup QmitkModule * \brief QmitkNodeDescriptorManager manages a set of QmitkNodeDescriptors * * \sa QmitkNodeDescriptor */ class MITKQTWIDGETS_EXPORT QmitkNodeDescriptorManager : public QObject { Q_OBJECT + public: /// /// \return the solely instance of QmitkNodeDescriptorManager /// - static QmitkNodeDescriptorManager *GetInstance(); + static QmitkNodeDescriptorManager* GetInstance(); /// /// Initializes the QmitkNodeDescriptorManager. /// Adds a few standard Descriptors. /// This Descriptors are added: /// - A QmitkNodeDescriptor for the class of "Image" DataNodes /// - A QmitkNodeDescriptor for the class of "Image Mask" DataNodes /// - A QmitkNodeDescriptor for the class of "Surface" DataNodes /// - A QmitkNodeDescriptor for the class of "PointSet" DataNodes /// virtual void Initialize(); /// /// Adds a new descriptor to the manager. The manager takes the ownership. /// - void AddDescriptor(QmitkNodeDescriptor *_Descriptor); + void AddDescriptor(QmitkNodeDescriptor* descriptor); /// /// Removes and deletes a descriptor from the manager /// - void RemoveDescriptor(QmitkNodeDescriptor *_Descriptor); + void RemoveDescriptor(QmitkNodeDescriptor* descriptor); /// /// Get the last descriptor in the descriptors list that matches the given node. /// *Attention*: More specialized Descriptors should therefore be appended at /// the end of the list, e.g. first add "Image", then add "Image Mask" /// /// \return a QmitkNodeDescriptor for the given node or a QmitkNodeDescriptor describing unknown nodes (never 0) /// \sa AddDescriptor() /// - QmitkNodeDescriptor *GetDescriptor(const mitk::DataNode *_Node) const; + QmitkNodeDescriptor* GetDescriptor(const mitk::DataNode* node) const; /// /// Get the last QmitkNodeDescriptor for the given class name /// /// \return a QmitkNodeDescriptor for the given class name or 0 if there is no QmitkNodeDescriptor for _ClassName /// - QmitkNodeDescriptor *GetDescriptor(const QString &_ClassName) const; + QmitkNodeDescriptor* GetDescriptor(const QString& className) const; /// /// \return The UnknownDataNodeDescriptor, which is the default Descriptor for all Nodes. /// - QmitkNodeDescriptor *GetUnknownDataNodeDescriptor() const; + QmitkNodeDescriptor* GetUnknownDataNodeDescriptor() const; /// /// Returns a list of all actions that are associated with the given node. /// If there are more than one Descriptors for this node all actions /// will be merged together. /// E.g. all actions from the "unknown" DataNodes will be added to /// this list. Generic Actions like Save, Load, etc. are stored there. /// - QList GetActions(const mitk::DataNode *_Node) const; + QList GetActions(const mitk::DataNode* node) const; /// /// \return a list of actions associated with the given nodes /// - QList GetActions(const QList &_Nodes) const; + QList GetActions(const QList& nodes) const; /// /// Deletes all Descriptors in the list /// ~QmitkNodeDescriptorManager() override; protected: /// /// Creates the m_UnknownDataNodeDescriptor /// Calls Initialize /// QmitkNodeDescriptorManager(); protected: /// /// This is the standard QmitkNodeDescriptor matching every node /// - QmitkNodeDescriptor *m_UnknownDataNodeDescriptor; + QmitkNodeDescriptor* m_UnknownDataNodeDescriptor; /// /// Holds all user defined descriptors /// - QList m_NodeDescriptors; + QList m_NodeDescriptors; }; #endif // QmitkNodeDescriptorManager_h diff --git a/Modules/QtWidgets/src/QmitkNodeDescriptorManager.cpp b/Modules/QtWidgets/src/QmitkNodeDescriptorManager.cpp index 1a7b67c88c..c8d380adac 100644 --- a/Modules/QtWidgets/src/QmitkNodeDescriptorManager.cpp +++ b/Modules/QtWidgets/src/QmitkNodeDescriptorManager.cpp @@ -1,180 +1,175 @@ /*=================================================================== 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 "QmitkNodeDescriptorManager.h" #include #include #include #include #include #include #include #include -QmitkNodeDescriptorManager *QmitkNodeDescriptorManager::GetInstance() +QmitkNodeDescriptorManager* QmitkNodeDescriptorManager::GetInstance() { - static QmitkNodeDescriptorManager _Instance; - return &_Instance; + static QmitkNodeDescriptorManager instance; + return &instance; } void QmitkNodeDescriptorManager::Initialize() { auto isImage = mitk::NodePredicateDataType::New("Image"); - this->AddDescriptor(new QmitkNodeDescriptor(tr("Image"), QString(":/Qmitk/Images_48.png"), isImage, this)); + AddDescriptor(new QmitkNodeDescriptor(tr("Image"), QString(":/Qmitk/Images_48.png"), isImage, this)); - auto isMultiComponentImage = - mitk::NodePredicateAnd::New(isImage, mitk::NodePredicateProperty::New("Image.Displayed Component")); - this->AddDescriptor(new QmitkNodeDescriptor( - tr("MultiComponentImage"), QString(": / Qmitk / Images_48.png"), isMultiComponentImage, this)); + auto isMultiComponentImage = mitk::NodePredicateAnd::New(isImage, mitk::NodePredicateProperty::New("Image.Displayed Component")); + AddDescriptor(new QmitkNodeDescriptor(tr("MultiComponentImage"), QString(": / Qmitk / Images_48.png"), isMultiComponentImage, this)); auto isBinary = mitk::NodePredicateProperty::New("binary", mitk::BoolProperty::New(true)); auto isBinaryImage = mitk::NodePredicateAnd::New(isBinary, isImage); - this->AddDescriptor( - new QmitkNodeDescriptor(tr("ImageMask"), QString(":/Qmitk/Binaerbilder_48.png"), isBinaryImage, this)); + AddDescriptor(new QmitkNodeDescriptor(tr("ImageMask"), QString(":/Qmitk/Binaerbilder_48.png"), isBinaryImage, this)); auto isLabelSetImage = mitk::NodePredicateDataType::New("LabelSetImage"); - this->AddDescriptor( - new QmitkNodeDescriptor(tr("LabelSetImage"), QString(":/Qmitk/LabelSetImage_48.png"), isLabelSetImage, this)); + AddDescriptor(new QmitkNodeDescriptor(tr("LabelSetImage"), QString(":/Qmitk/LabelSetImage_48.png"), isLabelSetImage, this)); auto isPointSet = mitk::NodePredicateDataType::New("PointSet"); - this->AddDescriptor(new QmitkNodeDescriptor(tr("PointSet"), QString(":/Qmitk/PointSet_48.png"), isPointSet, this)); + AddDescriptor(new QmitkNodeDescriptor(tr("PointSet"), QString(":/Qmitk/PointSet_48.png"), isPointSet, this)); auto isSurface = mitk::NodePredicateDataType::New("Surface"); - this->AddDescriptor(new QmitkNodeDescriptor(tr("Surface"), QString(":/Qmitk/Surface_48.png"), isSurface, this)); + AddDescriptor(new QmitkNodeDescriptor(tr("Surface"), QString(":/Qmitk/Surface_48.png"), isSurface, this)); auto isNotBinary = mitk::NodePredicateNot::New(isBinary); auto isNoneBinaryImage = mitk::NodePredicateAnd::New(isImage, isNotBinary); - this->AddDescriptor( - new QmitkNodeDescriptor(tr("NoneBinaryImage"), QString(":/Qmitk/Images_48.png"), isNoneBinaryImage, this)); + AddDescriptor(new QmitkNodeDescriptor(tr("NoneBinaryImage"), QString(":/Qmitk/Images_48.png"), isNoneBinaryImage, this)); } -void QmitkNodeDescriptorManager::AddDescriptor(QmitkNodeDescriptor *_Descriptor) +void QmitkNodeDescriptorManager::AddDescriptor(QmitkNodeDescriptor* descriptor) { - _Descriptor->setParent(this); - m_NodeDescriptors.push_back(_Descriptor); + descriptor->setParent(this); + m_NodeDescriptors.push_back(descriptor); } -void QmitkNodeDescriptorManager::RemoveDescriptor(QmitkNodeDescriptor *_Descriptor) +void QmitkNodeDescriptorManager::RemoveDescriptor(QmitkNodeDescriptor* descriptor) { - int index = m_NodeDescriptors.indexOf(_Descriptor); + int index = m_NodeDescriptors.indexOf(descriptor); if (index != -1) { m_NodeDescriptors.removeAt(index); - _Descriptor->setParent(nullptr); - delete _Descriptor; + descriptor->setParent(nullptr); + delete descriptor; } } -QmitkNodeDescriptor *QmitkNodeDescriptorManager::GetDescriptor(const mitk::DataNode *_Node) const +QmitkNodeDescriptor* QmitkNodeDescriptorManager::GetDescriptor(const mitk::DataNode* node) const { - QmitkNodeDescriptor *_Descriptor = m_UnknownDataNodeDescriptor; + QmitkNodeDescriptor* descriptor = m_UnknownDataNodeDescriptor; for (QList::const_iterator it = m_NodeDescriptors.begin(); it != m_NodeDescriptors.end(); ++it) { - if ((*it)->CheckNode(_Node)) - _Descriptor = *it; + if ((*it)->CheckNode(node)) + descriptor = *it; } - return _Descriptor; + return descriptor; } -QmitkNodeDescriptor *QmitkNodeDescriptorManager::GetDescriptor(const QString &_ClassName) const +QmitkNodeDescriptor* QmitkNodeDescriptorManager::GetDescriptor(const QString& className) const { - QmitkNodeDescriptor *_Descriptor = nullptr; + QmitkNodeDescriptor* descriptor = nullptr; - if (_ClassName == "Unknown") + if (className == "Unknown") { return m_UnknownDataNodeDescriptor; } else { - for (QList::const_iterator it = m_NodeDescriptors.begin(); it != m_NodeDescriptors.end(); - ++it) + for (QList::const_iterator it = m_NodeDescriptors.begin(); it != m_NodeDescriptors.end(); ++it) { - if ((*it)->GetNameOfClass() == _ClassName) - _Descriptor = *it; + if ((*it)->GetNameOfClass() == className) + descriptor = *it; } } - return _Descriptor; + return descriptor; } -QList QmitkNodeDescriptorManager::GetActions(const mitk::DataNode *_Node) const + +QList QmitkNodeDescriptorManager::GetActions(const mitk::DataNode* node) const { - QList actions = m_UnknownDataNodeDescriptor->GetBatchActions(); + QList actions = m_UnknownDataNodeDescriptor->GetBatchActions(); actions.append(m_UnknownDataNodeDescriptor->GetActions()); - QmitkNodeDescriptor *lastDescriptor = m_UnknownDataNodeDescriptor; + QmitkNodeDescriptor* lastDescriptor = m_UnknownDataNodeDescriptor; for (QList::const_iterator it = m_NodeDescriptors.begin(); it != m_NodeDescriptors.end(); ++it) { - if ((*it)->CheckNode(_Node)) + if ((*it)->CheckNode(node)) { actions.append(lastDescriptor->GetSeparator()); lastDescriptor = *it; actions.append(lastDescriptor->GetBatchActions()); actions.append(lastDescriptor->GetActions()); } } return actions; } -QList QmitkNodeDescriptorManager::GetActions(const QList &_Nodes) const +QList QmitkNodeDescriptorManager::GetActions(const QList& nodes) const { - QList actions = m_UnknownDataNodeDescriptor->GetBatchActions(); - QSet nodeDescriptors; - QmitkNodeDescriptor *lastDescriptor; + QList actions = m_UnknownDataNodeDescriptor->GetBatchActions(); + QmitkNodeDescriptor* lastDescriptor = m_UnknownDataNodeDescriptor; // find all descriptors for the nodes (unique) - foreach (mitk::DataNode::Pointer node, _Nodes) + QSet nodeDescriptors; + for (const auto& node : nodes) { - for (QList::const_iterator it = m_NodeDescriptors.begin(); it != m_NodeDescriptors.end(); ++it) + for (QList::const_iterator it = m_NodeDescriptors.begin(); it != m_NodeDescriptors.end(); ++it) { if ((*it)->CheckNode(node)) { nodeDescriptors.insert(*it); } } } + // add all actions for the found descriptors - lastDescriptor = m_UnknownDataNodeDescriptor; - foreach (QmitkNodeDescriptor *descr, nodeDescriptors) + for (const auto& nodeDescriptor : nodeDescriptors) { actions.append(lastDescriptor->GetSeparator()); - lastDescriptor = descr; + lastDescriptor = nodeDescriptor; actions.append(lastDescriptor->GetBatchActions()); } return actions; } QmitkNodeDescriptorManager::QmitkNodeDescriptorManager() : m_UnknownDataNodeDescriptor(new QmitkNodeDescriptor("Unknown", QString(":/Qmitk/DataTypeUnknown_48.png"), nullptr, this)) { - this->Initialize(); + Initialize(); } QmitkNodeDescriptorManager::~QmitkNodeDescriptorManager() { // delete m_UnknownDataNodeDescriptor; // qDeleteAll(m_NodeDescriptors); } QmitkNodeDescriptor *QmitkNodeDescriptorManager::GetUnknownDataNodeDescriptor() const { return m_UnknownDataNodeDescriptor; } diff --git a/Modules/RenderWindowManagerUI/src/QmitkDataStorageRenderWindowInspector.cpp b/Modules/RenderWindowManagerUI/src/QmitkDataStorageRenderWindowInspector.cpp index 7ea07d286e..7f9a37659d 100644 --- a/Modules/RenderWindowManagerUI/src/QmitkDataStorageRenderWindowInspector.cpp +++ b/Modules/RenderWindowManagerUI/src/QmitkDataStorageRenderWindowInspector.cpp @@ -1,163 +1,164 @@ /*=================================================================== 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. ===================================================================*/ // render window manager UI module #include "QmitkDataStorageRenderWindowInspector.h" #include "QmitkCustomVariants.h" // mitk core #include // qt #include QmitkDataStorageRenderWindowInspector::QmitkDataStorageRenderWindowInspector(QWidget* parent /*=nullptr*/) : QmitkAbstractDataStorageInspector(parent) { m_Controls.setupUi(this); // initialize the render window view direction controller // and set the controlled renderer (in constructor) and the data storage m_RenderWindowViewDirectionController = std::make_unique(); // create a new model m_StorageModel = std::make_unique(this); m_Controls.renderWindowListView->setModel(m_StorageModel.get()); m_Controls.renderWindowListView->setEditTriggers(QAbstractItemView::NoEditTriggers); m_Controls.renderWindowListView->setSelectionBehavior(QAbstractItemView::SelectRows); m_Controls.renderWindowListView->setSelectionMode(QAbstractItemView::ExtendedSelection); m_Controls.renderWindowListView->setAlternatingRowColors(true); m_Controls.renderWindowListView->setDragEnabled(true); m_Controls.renderWindowListView->setDropIndicatorShown(true); m_Controls.renderWindowListView->setAcceptDrops(true); + m_Controls.renderWindowListView->setContextMenuPolicy(Qt::CustomContextMenu); SetUpConnections(); } QAbstractItemView* QmitkDataStorageRenderWindowInspector::GetView() { return m_Controls.renderWindowListView; }; const QAbstractItemView* QmitkDataStorageRenderWindowInspector::GetView() const { return m_Controls.renderWindowListView; }; void QmitkDataStorageRenderWindowInspector::SetSelectionMode(SelectionMode mode) { m_Controls.renderWindowListView->setSelectionMode(mode); } QmitkDataStorageRenderWindowInspector::SelectionMode QmitkDataStorageRenderWindowInspector::GetSelectionMode() const { return m_Controls.renderWindowListView->selectionMode(); } void QmitkDataStorageRenderWindowInspector::Initialize() { m_StorageModel->SetDataStorage(m_DataStorage.Lock()); m_StorageModel->SetNodePredicate(m_NodePredicate); m_RenderWindowViewDirectionController->SetDataStorage(m_DataStorage.Lock()); m_Connector->SetView(m_Controls.renderWindowListView); } void QmitkDataStorageRenderWindowInspector::SetUpConnections() { connect(m_Controls.pushButtonSetAsBaseLayer, SIGNAL(clicked()), this, SLOT(SetAsBaseLayer())); connect(m_Controls.pushButtonResetRenderer, SIGNAL(clicked()), this, SLOT(ResetRenderer())); connect(m_Controls.pushButtonClearRenderer, SIGNAL(clicked()), this, SLOT(ClearRenderer())); QSignalMapper* changeViewDirectionSignalMapper = new QSignalMapper(this); changeViewDirectionSignalMapper->setMapping(m_Controls.radioButtonAxial, QString("axial")); changeViewDirectionSignalMapper->setMapping(m_Controls.radioButtonCoronal, QString("coronal")); changeViewDirectionSignalMapper->setMapping(m_Controls.radioButtonSagittal, QString("sagittal")); connect(changeViewDirectionSignalMapper, SIGNAL(mapped(const QString&)), this, SLOT(ChangeViewDirection(const QString&))); connect(m_Controls.radioButtonAxial, SIGNAL(clicked()), changeViewDirectionSignalMapper, SLOT(map())); connect(m_Controls.radioButtonCoronal, SIGNAL(clicked()), changeViewDirectionSignalMapper, SLOT(map())); connect(m_Controls.radioButtonSagittal, SIGNAL(clicked()), changeViewDirectionSignalMapper, SLOT(map())); } void QmitkDataStorageRenderWindowInspector::SetControlledRenderer(mitk::RenderWindowLayerUtilities::RendererVector controlledRenderer) { m_StorageModel->SetControlledRenderer(controlledRenderer); m_RenderWindowViewDirectionController->SetControlledRenderer(controlledRenderer); } void QmitkDataStorageRenderWindowInspector::SetActiveRenderWindow(const QString& renderWindowId) { mitk::BaseRenderer* selectedRenderer = mitk::BaseRenderer::GetByName(renderWindowId.toStdString()); if (nullptr == selectedRenderer) { return; } m_StorageModel->SetCurrentRenderer(selectedRenderer); mitk::SliceNavigationController::ViewDirection viewDirection = selectedRenderer->GetSliceNavigationController()->GetDefaultViewDirection(); switch (viewDirection) { case mitk::SliceNavigationController::Axial: m_Controls.radioButtonAxial->setChecked(true); break; case mitk::SliceNavigationController::Frontal: m_Controls.radioButtonCoronal->setChecked(true); break; case mitk::SliceNavigationController::Sagittal: m_Controls.radioButtonSagittal->setChecked(true); break; default: break; } } void QmitkDataStorageRenderWindowInspector::SetAsBaseLayer() { /* QModelIndex selectedIndex = m_Controls.renderWindowListView->currentIndex(); if (selectedIndex.isValid()) { QVariant qvariantDataNode = m_StorageModel->data(selectedIndex, Qt::UserRole); if (qvariantDataNode.canConvert()) { mitk::DataNode* dataNode = qvariantDataNode.value(); m_RenderWindowLayerController->SetBaseDataNode(dataNode, m_StorageModel->GetCurrentRenderer()); m_Controls.renderWindowListView->clearSelection(); } } */ } void QmitkDataStorageRenderWindowInspector::ResetRenderer() { //m_RenderWindowLayerController->ResetRenderer(true, m_StorageModel->GetCurrentRenderer()); m_Controls.renderWindowListView->clearSelection(); } void QmitkDataStorageRenderWindowInspector::ClearRenderer() { //m_RenderWindowLayerController->ResetRenderer(false, m_StorageModel->GetCurrentRenderer()); m_Controls.renderWindowListView->clearSelection(); } void QmitkDataStorageRenderWindowInspector::ChangeViewDirection(const QString& viewDirection) { m_RenderWindowViewDirectionController->SetViewDirectionOfRenderer(viewDirection.toStdString(), m_StorageModel->GetCurrentRenderer()); } diff --git a/Plugins/org.mitk.gui.common/src/mitkWorkbenchUtil.cpp b/Plugins/org.mitk.gui.common/src/mitkWorkbenchUtil.cpp index 3a0fc9455b..7c569071d6 100644 --- a/Plugins/org.mitk.gui.common/src/mitkWorkbenchUtil.cpp +++ b/Plugins/org.mitk.gui.common/src/mitkWorkbenchUtil.cpp @@ -1,376 +1,475 @@ /*=================================================================== 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 "mitkWorkbenchUtil.h" #include #include #include #include #include #include #include "mitkIDataStorageService.h" #include "mitkDataStorageEditorInput.h" #include "mitkRenderingManager.h" -#include "mitkIRenderWindowPart.h" #include "mitkIRenderingManager.h" #include "mitkProperties.h" #include "mitkNodePredicateData.h" #include "mitkNodePredicateNot.h" #include "mitkNodePredicateProperty.h" #include "mitkCoreObjectFactory.h" #include "QmitkIOUtil.h" #include #include #include #include "internal/org_mitk_gui_common_Activator.h" namespace mitk { -struct WorkbenchUtilPrivate { - - /** - * Get the editor descriptor for a given name using the editorDescriptor - * passed in as a default as a starting point. - * - * @param name - * The name of the element to open. - * @param editorReg - * The editor registry to do the lookups from. - * @param defaultDescriptor - * IEditorDescriptor or null - * @return IEditorDescriptor - * @throws PartInitException - * if no valid editor can be found - */ - static berry::IEditorDescriptor::Pointer GetEditorDescriptor(const QString& name, - berry::IEditorRegistry* editorReg, - berry::IEditorDescriptor::Pointer defaultDescriptor) - { - - if (defaultDescriptor.IsNotNull()) + struct WorkbenchUtilPrivate { + + /** + * Get the editor descriptor for a given name using the editorDescriptor + * passed in as a default as a starting point. + * + * @param name + * The name of the element to open. + * @param editorReg + * The editor registry to do the lookups from. + * @param defaultDescriptor + * IEditorDescriptor or null + * @return IEditorDescriptor + * @throws PartInitException + * if no valid editor can be found + */ + static berry::IEditorDescriptor::Pointer GetEditorDescriptor(const QString& name, berry::IEditorRegistry* editorReg, berry::IEditorDescriptor::Pointer defaultDescriptor) { - return defaultDescriptor; - } + if (defaultDescriptor.IsNotNull()) + { + return defaultDescriptor; + } - berry::IEditorDescriptor::Pointer editorDesc = defaultDescriptor; + berry::IEditorDescriptor::Pointer editorDesc = defaultDescriptor; - // next check the OS for in-place editor (OLE on Win32) - if (editorReg->IsSystemInPlaceEditorAvailable(name)) - { - editorDesc = editorReg->FindEditor(berry::IEditorRegistry::SYSTEM_INPLACE_EDITOR_ID); - } + // next check the OS for in-place editor (OLE on Win32) + if (editorReg->IsSystemInPlaceEditorAvailable(name)) + { + editorDesc = editorReg->FindEditor(berry::IEditorRegistry::SYSTEM_INPLACE_EDITOR_ID); + } - // next check with the OS for an external editor - if (editorDesc.IsNull() && editorReg->IsSystemExternalEditorAvailable(name)) - { - editorDesc = editorReg->FindEditor(berry::IEditorRegistry::SYSTEM_EXTERNAL_EDITOR_ID); + // next check with the OS for an external editor + if (editorDesc.IsNull() && editorReg->IsSystemExternalEditorAvailable(name)) + { + editorDesc = editorReg->FindEditor(berry::IEditorRegistry::SYSTEM_EXTERNAL_EDITOR_ID); + } + + // if no valid editor found, bail out + if (editorDesc.IsNull()) + { + throw berry::PartInitException("No editor found"); + } + + return editorDesc; } - // if no valid editor found, bail out - if (editorDesc.IsNull()) + static mitk::IDataStorageReference::Pointer GetDataStorageReference() { - throw berry::PartInitException("No editor found"); - } + ctkPluginContext* context = mitk::PluginActivator::GetContext(); + mitk::IDataStorageService* dss = nullptr; + ctkServiceReference dsRef = context->getServiceReference(); + if (dsRef) + { + dss = context->getService(dsRef); + } - return editorDesc; - } -}; -// //! [UtilLoadFiles] -void WorkbenchUtil::LoadFiles(const QStringList &fileNames, berry::IWorkbenchWindow::Pointer window, bool openEditor) -// //! [UtilLoadFiles] -{ - if (fileNames.empty()) - return; + if (nullptr == dss) + { + QString msg = "IDataStorageService service not available. Unable to open files."; + MITK_WARN << msg.toStdString(); + QMessageBox::warning(QApplication::activeWindow(), "Unable to open files", msg); + return mitk::IDataStorageReference::Pointer(nullptr); + } - mitk::IDataStorageReference::Pointer dataStorageRef; + // Get the active data storage (or the default one, if none is active) + mitk::IDataStorageReference::Pointer dataStorageRef = dss->GetDataStorage(); + context->ungetService(dsRef); + return dataStorageRef; + } + + }; // end struct WorkbenchUtilPrivate + + void WorkbenchUtil::LoadFiles(const QStringList &fileNames, berry::IWorkbenchWindow::Pointer window, bool openEditor) { - ctkPluginContext* context = mitk::PluginActivator::GetContext(); - mitk::IDataStorageService* dss = nullptr; - ctkServiceReference dsRef = context->getServiceReference(); - if (dsRef) + if (fileNames.empty()) { - dss = context->getService(dsRef); + return; } - if (!dss) + mitk::IDataStorageReference::Pointer dataStorageReference = WorkbenchUtilPrivate::GetDataStorageReference(); + if (nullptr == dataStorageReference) { - QString msg = "IDataStorageService service not available. Unable to open files."; - MITK_WARN << msg.toStdString(); - QMessageBox::warning(QApplication::activeWindow(), "Unable to open files", msg); return; } + mitk::DataStorage::Pointer dataStorage = dataStorageReference->GetDataStorage(); - // Get the active data storage (or the default one, if none is active) - dataStorageRef = dss->GetDataStorage(); - context->ungetService(dsRef); - } - - mitk::DataStorage::Pointer dataStorage = dataStorageRef->GetDataStorage(); - - // Do the actual work of loading the data into the data storage - - // Turn off ASSERT - #if defined(_MSC_VER) && !defined(NDEBUG) && defined(_DEBUG) && defined(_CRT_ERROR) - int lastCrtReportType = _CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_DEBUG ); - #endif + // Turn off ASSERT +#if defined(_MSC_VER) && !defined(NDEBUG) && defined(_DEBUG) && defined(_CRT_ERROR) + int lastCrtReportType = _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG); +#endif - DataStorage::SetOfObjects::Pointer data; - try - { - data = QmitkIOUtil::Load(fileNames, *dataStorage); - } - catch (const mitk::Exception& e) - { - MITK_INFO << e; - return; - } - const bool dsmodified = !data->empty(); + // Do the actual work of loading the data into the data storage + DataStorage::SetOfObjects::Pointer data; + try + { + data = QmitkIOUtil::Load(fileNames, *dataStorage); + } + catch (const mitk::Exception& e) + { + MITK_INFO << e; + return; + } + const bool dsmodified = !data->empty(); - // Set ASSERT status back to previous status. - #if defined(_MSC_VER) && !defined(NDEBUG) && defined(_DEBUG) && defined(_CRT_ERROR) + // Set ASSERT status back to previous status. +#if defined(_MSC_VER) && !defined(NDEBUG) && defined(_DEBUG) && defined(_CRT_ERROR) if (lastCrtReportType) - _CrtSetReportMode( _CRT_ASSERT, lastCrtReportType ); - #endif + _CrtSetReportMode(_CRT_ASSERT, lastCrtReportType); +#endif - // Check if there is an open perspective. If not, open the default perspective. - if (window->GetActivePage().IsNull()) - { - QString defaultPerspId = window->GetWorkbench()->GetPerspectiveRegistry()->GetDefaultPerspective(); - window->GetWorkbench()->ShowPerspective(defaultPerspId, window); - } + // Check if there is an open perspective. If not, open the default perspective. + if (window->GetActivePage().IsNull()) + { + QString defaultPerspId = window->GetWorkbench()->GetPerspectiveRegistry()->GetDefaultPerspective(); + window->GetWorkbench()->ShowPerspective(defaultPerspId, window); + } - bool globalReinitOnNodeAdded = true; - berry::IPreferencesService* prefService = berry::Platform::GetPreferencesService(); - if (prefService != nullptr) - { + bool globalReinitOnNodeAdded = true; + berry::IPreferencesService* prefService = berry::Platform::GetPreferencesService(); + if (prefService != nullptr) + { berry::IPreferences::Pointer prefs - = prefService->GetSystemPreferences()->Node("org.mitk.views.datamanager"); - if(prefs.IsNotNull()) + = prefService->GetSystemPreferences()->Node("org.mitk.views.datamanager"); + if (prefs.IsNotNull()) { globalReinitOnNodeAdded = prefs->GetBool("Call global reinit if node is added", true); } - } + } - if (openEditor && globalReinitOnNodeAdded) - { - try + if (openEditor && globalReinitOnNodeAdded) { - // Activate the editor using the same data storage or open the default editor - mitk::DataStorageEditorInput::Pointer input(new mitk::DataStorageEditorInput(dataStorageRef)); - berry::IEditorPart::Pointer editor = mitk::WorkbenchUtil::OpenEditor(window->GetActivePage(), input, true); - mitk::IRenderWindowPart* renderEditor = dynamic_cast(editor.GetPointer()); - mitk::IRenderingManager* renderingManager = renderEditor == nullptr ? nullptr : renderEditor->GetRenderingManager(); - - if(dsmodified && renderingManager) + try { - mitk::RenderingManager::GetInstance()->InitializeViewsByBoundingObjects(dataStorage); + // Activate the editor using the same data storage or open the default editor + mitk::DataStorageEditorInput::Pointer input(new mitk::DataStorageEditorInput(dataStorageReference)); + berry::IEditorPart::Pointer editor = mitk::WorkbenchUtil::OpenEditor(window->GetActivePage(), input, true); + mitk::IRenderWindowPart* renderEditor = dynamic_cast(editor.GetPointer()); + mitk::IRenderingManager* renderingManager = renderEditor == nullptr ? nullptr : renderEditor->GetRenderingManager(); + + if (dsmodified && renderingManager) + { + mitk::RenderingManager::GetInstance()->InitializeViewsByBoundingObjects(dataStorage); + } + } + catch (const berry::PartInitException& e) + { + QString msg = "An error occurred when displaying the file(s): %1"; + QMessageBox::warning(QApplication::activeWindow(), "Error displaying file", + msg.arg(e.message())); } - } - catch (const berry::PartInitException& e) - { - QString msg = "An error occurred when displaying the file(s): %1"; - QMessageBox::warning(QApplication::activeWindow(), "Error displaying file", - msg.arg(e.message())); } } -} - -berry::IEditorPart::Pointer WorkbenchUtil::OpenEditor(berry::IWorkbenchPage::Pointer page, - berry::IEditorInput::Pointer input, - const QString &editorId, bool activate) -{ - // sanity checks - if (page.IsNull()) + + berry::IEditorPart::Pointer WorkbenchUtil::OpenEditor(berry::IWorkbenchPage::Pointer page, berry::IEditorInput::Pointer input, const QString &editorId, bool activate) { - throw std::invalid_argument("page argument must not be nullptr"); + // sanity checks + if (page.IsNull()) + { + throw std::invalid_argument("page argument must not be nullptr"); + } + + // open the editor on the input + return page->OpenEditor(input, editorId, activate); } - // open the editor on the input - return page->OpenEditor(input, editorId, activate); -} - -berry::IEditorPart::Pointer WorkbenchUtil::OpenEditor(berry::IWorkbenchPage::Pointer page, - mitk::DataStorageEditorInput::Pointer input, - bool activate, - bool determineContentType) -{ - // sanity checks - if (page.IsNull()) + berry::IEditorPart::Pointer WorkbenchUtil::OpenEditor(berry::IWorkbenchPage::Pointer page, mitk::DataStorageEditorInput::Pointer input, bool activate, bool determineContentType) { - throw std::invalid_argument("page argument must not be nullptr"); + // sanity checks + if (page.IsNull()) + { + throw std::invalid_argument("page argument must not be nullptr"); + } + + // open the editor on the data storage + QString name = input->GetName() + ".mitk"; + berry::IEditorDescriptor::Pointer editorDesc = WorkbenchUtilPrivate::GetEditorDescriptor(name, + berry::PlatformUI::GetWorkbench()->GetEditorRegistry(), + GetDefaultEditor(name, determineContentType)); + + return page->OpenEditor(input, editorDesc->GetId(), activate); } - // open the editor on the data storage - QString name = input->GetName() + ".mitk"; - berry::IEditorDescriptor::Pointer editorDesc = - WorkbenchUtilPrivate::GetEditorDescriptor(name, - berry::PlatformUI::GetWorkbench()->GetEditorRegistry(), - GetDefaultEditor(name, determineContentType)); - return page->OpenEditor(input, editorDesc->GetId(), activate); -} - -berry::IEditorDescriptor::Pointer WorkbenchUtil::GetEditorDescriptor( - const QString& name, bool /*inferContentType*/) -{ - if (name.isEmpty()) + berry::IEditorDescriptor::Pointer WorkbenchUtil::GetEditorDescriptor(const QString& name, bool /*inferContentType*/) { - throw std::invalid_argument("name argument must not be empty"); - } + if (name.isEmpty()) + { + throw std::invalid_argument("name argument must not be empty"); + } - // no used for now - //IContentType contentType = inferContentType ? Platform - // .getContentTypeManager().findContentTypeFor(name) : null; + // no used for now + //IContentType contentType = inferContentType ? Platform + // .getContentTypeManager().findContentTypeFor(name) : null; - berry::IEditorRegistry* editorReg = berry::PlatformUI::GetWorkbench()->GetEditorRegistry(); + berry::IEditorRegistry* editorReg = berry::PlatformUI::GetWorkbench()->GetEditorRegistry(); - return WorkbenchUtilPrivate::GetEditorDescriptor(name, editorReg, - editorReg->GetDefaultEditor(name /*, contentType*/)); -} + return WorkbenchUtilPrivate::GetEditorDescriptor(name, editorReg, editorReg->GetDefaultEditor(name /*, contentType*/)); + } -berry::IEditorDescriptor::Pointer WorkbenchUtil::GetDefaultEditor(const QString& name, - bool /*determineContentType*/) -{ - // Try file specific editor. - berry::IEditorRegistry* editorReg = berry::PlatformUI::GetWorkbench()->GetEditorRegistry(); - try + berry::IEditorDescriptor::Pointer WorkbenchUtil::GetDefaultEditor(const QString& name, bool /*determineContentType*/) { - QString editorID; // = file.getPersistentProperty(EDITOR_KEY); - if (!editorID.isEmpty()) + // Try file specific editor. + berry::IEditorRegistry* editorReg = berry::PlatformUI::GetWorkbench()->GetEditorRegistry(); + try { - berry::IEditorDescriptor::Pointer desc = editorReg->FindEditor(editorID); - if (desc.IsNotNull()) + QString editorID; // = file.getPersistentProperty(EDITOR_KEY); + if (!editorID.isEmpty()) { - return desc; + berry::IEditorDescriptor::Pointer desc = editorReg->FindEditor(editorID); + if (desc.IsNotNull()) + { + return desc; + } } } - } - catch (const berry::CoreException&) - { - // do nothing - } + catch (const berry::CoreException&) + { + // do nothing + } -// IContentType contentType = null; -// if (determineContentType) -// { -// contentType = getContentType(file); -// } + // IContentType contentType = null; + // if (determineContentType) + // { + // contentType = getContentType(file); + // } - // Try lookup with filename - return editorReg->GetDefaultEditor(name); //, contentType); -} + // Try lookup with filename + return editorReg->GetDefaultEditor(name); //, contentType); + } -bool WorkbenchUtil::SetDepartmentLogoPreference(const QString &logoResource, ctkPluginContext *context) -{ - if (context == nullptr) + mitk::IRenderWindowPart* WorkbenchUtil::GetRenderWindowPart(berry::IWorkbenchPage::Pointer page, IRenderWindowPartStrategies strategies) { - BERRY_WARN << "Plugin context invalid, unable to set custom logo."; - return false; - } + // Return the active editor if it implements mitk::IRenderWindowPart + mitk::IRenderWindowPart* renderWindowPart = dynamic_cast(page->GetActiveEditor().GetPointer()); + if (renderWindowPart) + { + return renderWindowPart; + } - // The logo must be available in the local filesystem. We check if we have not already extracted the - // logo from the plug-in or if this plug-ins timestamp is newer then the already extracted logo timestamp. - // If one of the conditions is true, extract it and write it to the plug-in specific storage location. - const QString logoFileName = logoResource.mid(logoResource.lastIndexOf('/')+1); + // No suitable active editor found, check visible editors + QList editors = page->GetEditorReferences(); + for (QList::iterator i = editors.begin(); i != editors.end(); ++i) + { + berry::IWorkbenchPart::Pointer part = (*i)->GetPart(false); + if (page->IsPartVisible(part)) + { + renderWindowPart = dynamic_cast(part.GetPointer()); + if (renderWindowPart) + { + return renderWindowPart; + } + } + } - if (logoFileName.isEmpty()) - { - BERRY_WARN << "Logo file name empty, unable to set custom logo."; - return false; - } + // No suitable visible editor found, check visible views + QList views = page->GetViewReferences(); + for (QList::iterator i = views.begin(); i != views.end(); ++i) + { + berry::IWorkbenchPart::Pointer part = (*i)->GetPart(false); + if (page->IsPartVisible(part)) + { + renderWindowPart = dynamic_cast(part.GetPointer()); + if (renderWindowPart) + { + return renderWindowPart; + } + } + } - const QString logoPath = context->getDataFile("").absoluteFilePath(); + // No strategies given + if (strategies == NONE) + { + return nullptr; + } - bool extractLogo = true; - QFileInfo logoFileInfo(logoPath + "/" + logoFileName); + mitk::IDataStorageReference::Pointer dataStorageReference = WorkbenchUtilPrivate::GetDataStorageReference(); + if (nullptr == dataStorageReference) + { + return nullptr; + } - if (logoFileInfo.exists()) - { - // The logo has been extracted previously. Check if the plugin timestamp is newer, which - // means it might contain an updated logo. - QString pluginLocation = QUrl(context->getPlugin()->getLocation()).toLocalFile(); - if (!pluginLocation.isEmpty()) + mitk::DataStorageEditorInput::Pointer input(new mitk::DataStorageEditorInput(dataStorageReference)); + + bool activate = false; + if (strategies & ACTIVATE) + { + activate = true; + } + + berry::IEditorPart::Pointer editorPart; + if (strategies & OPEN) { - QFileInfo pluginFileInfo(pluginLocation); - if (logoFileInfo.lastModified() > pluginFileInfo.lastModified()) + // This will create a default editor for the given input. If an editor + // with that input is already open, the editor is brought to the front. + try { - extractLogo = false; + editorPart = mitk::WorkbenchUtil::OpenEditor(page, input, activate); + } + catch (const berry::PartInitException&) + { + // There is no editor registered which can handle the given input. + } + } + else if (activate || (strategies & BRING_TO_FRONT)) + { + // check if a suitable editor is already opened + editorPart = page->FindEditor(input); + if (editorPart) + { + if (activate) + { + page->Activate(editorPart); + } + else + { + page->BringToTop(editorPart); + } } } + + return dynamic_cast(editorPart.GetPointer()); } - if (extractLogo) + mitk::IRenderWindowPart* WorkbenchUtil::OpenRenderWindowPart(berry::IWorkbenchPage::Pointer page, bool activatedEditor/* = true*/) { - // Extract the logo from the shared library and write it to disk. - QFile logo(logoResource); + if (activatedEditor) + { + return GetRenderWindowPart(page, ACTIVATE | OPEN); + } + else + { + return GetRenderWindowPart(page, BRING_TO_FRONT | OPEN); + } + } - if (!logo.exists()) + bool WorkbenchUtil::SetDepartmentLogoPreference(const QString &logoResource, ctkPluginContext *context) + { + if (context == nullptr) { - BERRY_WARN << "Custom logo '" << logoResource << "' does not exist."; + BERRY_WARN << "Plugin context invalid, unable to set custom logo."; return false; } - if (logo.open(QIODevice::ReadOnly)) + // The logo must be available in the local filesystem. We check if we have not already extracted the + // logo from the plug-in or if this plug-ins timestamp is newer then the already extracted logo timestamp. + // If one of the conditions is true, extract it and write it to the plug-in specific storage location. + const QString logoFileName = logoResource.mid(logoResource.lastIndexOf('/') + 1); + + if (logoFileName.isEmpty()) { - QFile localLogo(logoPath + "/" + logoFileName); + BERRY_WARN << "Logo file name empty, unable to set custom logo."; + return false; + } - if (localLogo.open(QIODevice::WriteOnly)) + const QString logoPath = context->getDataFile("").absoluteFilePath(); + + bool extractLogo = true; + QFileInfo logoFileInfo(logoPath + "/" + logoFileName); + + if (logoFileInfo.exists()) + { + // The logo has been extracted previously. Check if the plugin timestamp is newer, which + // means it might contain an updated logo. + QString pluginLocation = QUrl(context->getPlugin()->getLocation()).toLocalFile(); + if (!pluginLocation.isEmpty()) { - localLogo.write(logo.readAll()); - localLogo.flush(); + QFileInfo pluginFileInfo(pluginLocation); + if (logoFileInfo.lastModified() > pluginFileInfo.lastModified()) + { + extractLogo = false; + } } } - } - logoFileInfo.refresh(); - - if (logoFileInfo.exists()) - { - // Get the preferences service - ctkServiceReference prefServiceRef = context->getServiceReference(); - berry::IPreferencesService* prefService = nullptr; - if (prefServiceRef) + if (extractLogo) { - prefService = context->getService(prefServiceRef); + // Extract the logo from the shared library and write it to disk. + QFile logo(logoResource); + + if (!logo.exists()) + { + BERRY_WARN << "Custom logo '" << logoResource << "' does not exist."; + return false; + } + + if (logo.open(QIODevice::ReadOnly)) + { + QFile localLogo(logoPath + "/" + logoFileName); + + if (localLogo.open(QIODevice::WriteOnly)) + { + localLogo.write(logo.readAll()); + localLogo.flush(); + } + } } - if (prefService) + logoFileInfo.refresh(); + + if (logoFileInfo.exists()) { - prefService->GetSystemPreferences()->Put("DepartmentLogo", qPrintable(logoFileInfo.absoluteFilePath())); + // Get the preferences service + ctkServiceReference prefServiceRef = context->getServiceReference(); + berry::IPreferencesService* prefService = nullptr; + if (prefServiceRef) + { + prefService = context->getService(prefServiceRef); + } + + if (prefService) + { + prefService->GetSystemPreferences()->Put("DepartmentLogo", qPrintable(logoFileInfo.absoluteFilePath())); + } + else + { + BERRY_WARN << "Preferences service not available, unable to set custom logo."; + return false; + } } else { - BERRY_WARN << "Preferences service not available, unable to set custom logo."; + BERRY_WARN << "Custom logo at '" << logoFileInfo.absoluteFilePath().toStdString() << "' does not exist."; return false; } - } - else - { - BERRY_WARN << "Custom logo at '" << logoFileInfo.absoluteFilePath().toStdString() << "' does not exist."; - return false; - } - return true; -} + return true; + } } // namespace mitk diff --git a/Plugins/org.mitk.gui.common/src/mitkWorkbenchUtil.h b/Plugins/org.mitk.gui.common/src/mitkWorkbenchUtil.h index b3dc8a8e86..238d8fc94d 100644 --- a/Plugins/org.mitk.gui.common/src/mitkWorkbenchUtil.h +++ b/Plugins/org.mitk.gui.common/src/mitkWorkbenchUtil.h @@ -1,189 +1,214 @@ /*=================================================================== 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 MITKWORKBENCHUTIL_H #define MITKWORKBENCHUTIL_H #include #include "mitkDataStorageEditorInput.h" +#include "mitkIRenderWindowPart.h" + #include #include class ctkPluginContext; namespace mitk { - -/** - * @ingroup org_mitk_gui_common - * - * @brief Utility class for loading data, opening editors and other tasks in a MITK Workbench. - * - * @note Infering the content type is not yet supported (ignore the comments about it - * in the method documentation). - */ -struct MITK_GUI_COMMON_PLUGIN WorkbenchUtil -{ - /** - * Loads the set of given files into the active data storage of the given Workbench window. - * - * If the window already has an editor open on the active datastorage then that editor - * is activated; otherwise the default editor for the "mitk" extension is activated. + * @ingroup org_mitk_gui_common * - * @param fileNames - * A list of file names with absolute path. - * @param wnd - * The Workbench window in which the data will be loaded. - * @param openEditor - * Whether an Editor is to be opened on file loading (for cases there is none). + * @brief Utility class for loading data, opening editors and other tasks in a MITK Workbench. * - * @see mitk::IOUtil + * @note Inferring the content type is not yet supported (ignore the comments about it + * in the method documentation). */ - static void LoadFiles(const QStringList& fileNames, berry::IWorkbenchWindow::Pointer wnd, bool openEditor = true); - - /** + struct MITK_GUI_COMMON_PLUGIN WorkbenchUtil + { + /** + * Describes the strategies to be used for getting an mitk::IRenderWindowPart instance. + */ + enum IRenderWindowPartStrategy { + + // Do nothing. + NONE = 0x00000000, + // Bring the most recently activated mitk::IRenderWindowPart instance to the front. + BRING_TO_FRONT = 0x00000001, + // Activate an mitk::IRenderWindowPart part (implies bringing it to the front). + ACTIVATE = 0x00000002, + // Create an mitk::IRenderWindowPart if none is alredy opened. + OPEN = 0x00000004 + }; + + Q_DECLARE_FLAGS(IRenderWindowPartStrategies, IRenderWindowPartStrategy) + + /** + * Loads the set of given files into the active data storage of the given Workbench window. + * + * If the window already has an editor open on the active datastorage then that editor + * is activated; otherwise the default editor for the "mitk" extension is activated. + * + * @param fileNames + * A list of file names with absolute path. + * @param wnd + * The Workbench window in which the data will be loaded. + * @param openEditor + * Whether an Editor is to be opened on file loading (for cases there is none). + * + * @see mitk::IOUtil + */ + static void LoadFiles(const QStringList& fileNames, berry::IWorkbenchWindow::Pointer wnd, bool openEditor = true); + /** * Opens an editor on the given object. *

* If the page already has an editor open on the target object then that * editor is brought to front; otherwise, a new editor is opened. If * activate == true the editor will be activated. *

* * @param page * the page in which the editor will be opened * @param input * the editor input * @param editorId * the id of the editor extension to use * @param activate * if true the editor will be activated * @return an open editor or null if an external editor was * opened * @exception PartInitException * if the editor could not be initialized * @see IWorkbenchPage#OpenEditor(IEditorInput::Pointer, std::string, bool) */ - static berry::IEditorPart::Pointer OpenEditor(berry::IWorkbenchPage::Pointer page, - berry::IEditorInput::Pointer input, - const QString& editorId, bool activate = false); - - /** + static berry::IEditorPart::Pointer OpenEditor(berry::IWorkbenchPage::Pointer page, berry::IEditorInput::Pointer input, const QString& editorId, bool activate = false); + /** * Opens an editor on the given file resource. This method will attempt to * resolve the editor based on content-type bindings as well as traditional * name/extension bindings if determineContentType is * true. *

* If the page already has an editor open on the target object then that * editor is brought to front; otherwise, a new editor is opened. If * activate == true the editor will be activated. *

* * @param page * the page in which the editor will be opened * @param input * the editor input * @param activate * if true the editor will be activated * @param determineContentType * attempt to resolve the content type for this file * @return an open editor or null if an external editor was * opened * @exception PartInitException * if the editor could not be initialized * @see IWorkbenchPage#OpenEditor(IEditorInput::Pointer,std::string,bool) */ - static berry::IEditorPart::Pointer OpenEditor(berry::IWorkbenchPage::Pointer page, - mitk::DataStorageEditorInput::Pointer input, - bool activate = false, - bool determineContentType = false); - - /** + static berry::IEditorPart::Pointer OpenEditor(berry::IWorkbenchPage::Pointer page, DataStorageEditorInput::Pointer input, bool activate = false, bool determineContentType = false); + /** * Returns an editor descriptor appropriate for opening a file resource with * the given name. *

* The editor descriptor is determined using a multi-step process. This * method will attempt to infer the content type of the file if * inferContentType is true. *

*
    *
  1. The file is consulted for a persistent property named * IDE.EDITOR_KEY containing the preferred editor id to be * used.
  2. *
  3. The workbench editor registry is consulted to determine if an editor * extension has been registered for the file type. If so, an instance of * the editor extension is opened on the file. See * IEditorRegistry#GetDefaultEditor(std::string).
  4. *
  5. The operating system is consulted to determine if an in-place * component editor is available (e.g. OLE editor on Win32 platforms).
  6. *
  7. The operating system is consulted to determine if an external editor * is available.
  8. *
*

* * @param name * the file name * @param inferContentType * attempt to infer the content type from the file name if this * is true * @return an editor descriptor, appropriate for opening the file * @throws PartInitException * if no editor can be found */ - static berry::IEditorDescriptor::Pointer GetEditorDescriptor( - const QString& name, bool inferContentType = true); - - /** + static berry::IEditorDescriptor::Pointer GetEditorDescriptor(const QString& name, bool inferContentType = true); + /** * Returns the default editor for a given file. This method will attempt to * resolve the editor based on content-type bindings as well as traditional * name/extension bindings if determineContentType is * true. *

* A default editor id may be registered for a specific file using * setDefaultEditor. If the given file has a registered * default editor id the default editor will derived from it. If not, the * default editor is determined by taking the file name for the file and * obtaining the default editor for that name. *

* * @param file * the file * @param determineContentType * determine the content type for the given file * @return the descriptor of the default editor, or null if * not found */ - static berry::IEditorDescriptor::Pointer GetDefaultEditor(const QString& file, - bool determineContentType); - /** - * Set the "DepartmentLogo" preference using a Qt resource path. - * - * This is a convenience method to set the preference for a "deparment" logo which is usually - * shown in render windows in the MITK workbench. - * - * @param logoResource A Qt resource path to the logo, e.g. ":/MyLogo.png". - * @param context The plugin context of the plug-in containing the logo resource. - * @return \c true if the preference was set successfully, \c false otherwise. - */ - static bool SetDepartmentLogoPreference(const QString& logoResource, ctkPluginContext* context); - -}; - + static berry::IEditorDescriptor::Pointer GetDefaultEditor(const QString& file, bool determineContentType); + /** + * @brief Returns the currently active mitk::IRenderWindowPart. + * + * @param page The page in which the editor will be opened. + * @param strategies Strategies for returning a mitk::IRenderWindowPart instance if there + * is currently no active one. + * @return The active mitk::IRenderWindowPart. + */ + static IRenderWindowPart* GetRenderWindowPart(berry::IWorkbenchPage::Pointer page, IRenderWindowPartStrategies strategies); + /** + * @brief Uses 'GetRenderWindowPart' to open the a render window part with a certain strategy: + * Calls 'GetRenderWindowPart' with strategy "ACTIVATE | OPEN" if the bool argument is true. + * Calls 'GetRenderWindowPart' with strategy "BRING_TO_FRONT | OPEN" if the bool argument is false. + * + * @param page The page in which the editor will be opened. + * @param activatedEditor Determine if the render window part should be activated or just brought to front. + * @return The active and opened mitk::IRenderWindowPart. + */ + static IRenderWindowPart* OpenRenderWindowPart(berry::IWorkbenchPage::Pointer page, bool activatedEditor = true); + /** + * Set the "DepartmentLogo" preference using a Qt resource path. + * + * This is a convenience method to set the preference for a "department" logo which is usually + * shown in render windows in the MITK workbench. + * + * @param logoResource A Qt resource path to the logo, e.g. ":/MyLogo.png". + * @param context The plugin context of the plug-in containing the logo resource. + * @return \c true if the preference was set successfully, \c false otherwise. + */ + static bool SetDepartmentLogoPreference(const QString& logoResource, ctkPluginContext* context); + }; } +Q_DECLARE_OPERATORS_FOR_FLAGS(mitk::WorkbenchUtil::IRenderWindowPartStrategies) + #endif // MITKWORKBENCHUTIL_H diff --git a/Plugins/org.mitk.gui.qt.application/CMakeLists.txt b/Plugins/org.mitk.gui.qt.application/CMakeLists.txt index 15c4e7f713..04efa26bd0 100644 --- a/Plugins/org.mitk.gui.qt.application/CMakeLists.txt +++ b/Plugins/org.mitk.gui.qt.application/CMakeLists.txt @@ -1,9 +1,9 @@ project(org_mitk_gui_qt_application) mitk_create_plugin( EXPORT_DIRECTIVE MITK_QT_APP EXPORTED_INCLUDE_SUFFIXES src - MODULE_DEPENDS MitkQtWidgets + MODULE_DEPENDS MitkQtWidgets MitkQtWidgetsExt PACKAGE_DEPENDS Qt5|OpenGL+Xml SUBPROJECTS MITK-CoreUI ) diff --git a/Plugins/org.mitk.gui.qt.application/files.cmake b/Plugins/org.mitk.gui.qt.application/files.cmake index bcd9b22a2e..2f3746459b 100644 --- a/Plugins/org.mitk.gui.qt.application/files.cmake +++ b/Plugins/org.mitk.gui.qt.application/files.cmake @@ -1,55 +1,87 @@ set(SRC_CPP_FILES + QmitkAbstractDataNodeAction.cpp QmitkCloseProjectAction.cpp + QmitkDataNodeColorAction.cpp + QmitkDataNodeColorMapAction.cpp + QmitkDataNodeComponentAction.cpp + QmitkDataNodeContextMenu.cpp + QmitkDataNodeGlobalReinitAction.cpp + QmitkDataNodeHideAllNodesAction.cpp + QmitkDataNodeOpacityAction.cpp + QmitkDataNodeReinitAction.cpp + QmitkDataNodeRemoveAction.cpp + QmitkDataNodeShowDetailsAction.cpp + QmitkDataNodeShowSelectedNodesAction.cpp + QmitkDataNodeSurfaceRepresentationAction.cpp + QmitkDataNodeTextureInterpolationAction.cpp + QmitkDataNodeToggleVisibilityAction.cpp QmitkDefaultDropTargetListener.cpp QmitkFileExitAction.cpp QmitkFileOpenAction.cpp QmitkFileSaveAction.cpp QmitkUndoAction.cpp QmitkRedoAction.cpp QmitkPreferencesDialog.cpp QmitkStatusBar.cpp ) set(INTERNAL_CPP_FILES org_mitk_gui_qt_application_Activator.cpp QmitkEditorsPreferencePage.cpp QmitkGeneralPreferencePage.cpp + QmitkInfoDialog.cpp QmitkShowPreferencePageHandler.cpp ) set(MOC_H_FILES + src/QmitkAbstractDataNodeAction.h src/QmitkCloseProjectAction.h + src/QmitkDataNodeColorAction.h + src/QmitkDataNodeColorMapAction.h + src/QmitkDataNodeComponentAction.h + src/QmitkDataNodeGlobalReinitAction.h + src/QmitkDataNodeContextMenu.h + src/QmitkDataNodeHideAllNodesAction.h + src/QmitkDataNodeOpacityAction.h + src/QmitkDataNodeReinitAction.h + src/QmitkDataNodeRemoveAction.h + src/QmitkDataNodeShowDetailsAction.h + src/QmitkDataNodeShowSelectedNodesAction.h + src/QmitkDataNodeSurfaceRepresentationAction.h + src/QmitkDataNodeTextureInterpolationAction.h + src/QmitkDataNodeToggleVisibilityAction.h src/QmitkFileExitAction.h src/QmitkFileOpenAction.h src/QmitkFileSaveAction.h src/QmitkUndoAction.h src/QmitkRedoAction.h src/QmitkPreferencesDialog.h src/internal/org_mitk_gui_qt_application_Activator.h src/internal/QmitkEditorsPreferencePage.h src/internal/QmitkGeneralPreferencePage.h + src/internal/QmitkInfoDialog.h src/internal/QmitkShowPreferencePageHandler.h ) set(UI_FILES src/QmitkPreferencesDialog.ui ) set(CACHED_RESOURCE_FILES plugin.xml ) set(QRC_FILES resources/resources.qrc ) 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.application/src/QmitkAbstractDataNodeAction.cpp b/Plugins/org.mitk.gui.qt.application/src/QmitkAbstractDataNodeAction.cpp new file mode 100644 index 0000000000..4f99755c61 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.application/src/QmitkAbstractDataNodeAction.cpp @@ -0,0 +1,87 @@ +/*=================================================================== + +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 + +#include "mitkIRenderWindowPart.h" + +// mitk gui common plugin +#include + +// berry +#include + +QmitkAbstractDataNodeAction::QmitkAbstractDataNodeAction(berry::IWorkbenchPartSite::Pointer workbenchPartSite) +{ + m_WorkbenchPartSite = workbenchPartSite; +} + +QmitkAbstractDataNodeAction::QmitkAbstractDataNodeAction(berry::IWorkbenchPartSite* workbenchPartSite) +{ + m_WorkbenchPartSite = berry::IWorkbenchPartSite::Pointer(workbenchPartSite); +} + +QmitkAbstractDataNodeAction::~QmitkAbstractDataNodeAction() +{ + // nothing here +} + +void QmitkAbstractDataNodeAction::SetDataStorage(mitk::DataStorage* dataStorage) +{ + if (m_DataStorage != dataStorage) + { + // set the new data storage + m_DataStorage = dataStorage; + } +} + +QList QmitkAbstractDataNodeAction::GetSelectedNodes() +{ + QList selectedNodes; + if (m_WorkbenchPartSite.Expired()) + { + return selectedNodes; + } + + berry::ISelection::ConstPointer selection = m_WorkbenchPartSite.Lock()->GetWorkbenchWindow()->GetSelectionService()->GetSelection(); + mitk::DataNodeSelection::ConstPointer currentSelection = selection.Cast(); + + if (currentSelection.IsNull() || currentSelection->IsEmpty()) + { + return selectedNodes; + } + + selectedNodes = QList::fromStdList(currentSelection->GetSelectedDataNodes()); + return selectedNodes; +} + +mitk::DataNode::Pointer QmitkAbstractDataNodeAction::GetSelectedNode() +{ + QList selectedNodes = GetSelectedNodes(); + if (selectedNodes.empty()) + { + return nullptr; + } + + // no batch action; should only be called with a single node + mitk::DataNode::Pointer dataNode = selectedNodes.front(); + if (nullptr == dataNode) + { + return nullptr; + } + + return dataNode; +} diff --git a/Plugins/org.mitk.gui.qt.application/src/QmitkAbstractDataNodeAction.h b/Plugins/org.mitk.gui.qt.application/src/QmitkAbstractDataNodeAction.h new file mode 100644 index 0000000000..e8ded7f3d5 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.application/src/QmitkAbstractDataNodeAction.h @@ -0,0 +1,57 @@ +/*=================================================================== + +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 QMITKABSTRACTDATANODEACTION_H +#define QMITKABSTRACTDATANODEACTION_H + +#include + +// mitk core +#include +#include + +// berry +#include + +// qt +#include + +class MITK_QT_APP QmitkAbstractDataNodeAction +{ + +public: + + QmitkAbstractDataNodeAction(berry::IWorkbenchPartSite::Pointer workbenchPartSite); + QmitkAbstractDataNodeAction(berry::IWorkbenchPartSite* workbenchPartSite); + + virtual ~QmitkAbstractDataNodeAction(); + + void SetDataStorage(mitk::DataStorage* dataStorage); + + virtual void InitializeWithDataNode(const mitk::DataNode* dataNode) { } + +protected: + + virtual void InitializeAction() = 0; + mitk::DataNode::Pointer GetSelectedNode(); + QList GetSelectedNodes(); + + berry::IWorkbenchPartSite::WeakPtr m_WorkbenchPartSite; + mitk::WeakPointer m_DataStorage; + +}; + +#endif // QMITKABSTRACTDATANODEACTION_H diff --git a/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeColorAction.cpp b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeColorAction.cpp new file mode 100644 index 0000000000..582c667c63 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeColorAction.cpp @@ -0,0 +1,130 @@ +/*=================================================================== + +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 + +// mitk core +#include + +// qt +#include +#include +#include + +QmitkDataNodeColorAction::QmitkDataNodeColorAction(QWidget* parent, berry::IWorkbenchPartSite::Pointer workbenchPartSite) + : QWidgetAction(parent) + , QmitkAbstractDataNodeAction(workbenchPartSite) +{ + InitializeAction(); +} + +QmitkDataNodeColorAction::QmitkDataNodeColorAction(QWidget* parent, berry::IWorkbenchPartSite* workbenchPartSite) + : QWidgetAction(parent) + , QmitkAbstractDataNodeAction(berry::IWorkbenchPartSite::Pointer(workbenchPartSite)) +{ + InitializeAction(); +} + +QmitkDataNodeColorAction::~QmitkDataNodeColorAction() +{ + // nothing here +} + +void QmitkDataNodeColorAction::InitializeAction() +{ + m_ColorButton = new QPushButton; + m_ColorButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); + connect(m_ColorButton, &QPushButton::clicked, this, &QmitkDataNodeColorAction::OnColorChanged); + + QLabel* colorLabel = new QLabel(tr("Color: ")); + colorLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); + QHBoxLayout* colorWidgetLayout = new QHBoxLayout; + colorWidgetLayout->setContentsMargins(4, 4, 4, 4); + colorWidgetLayout->addWidget(colorLabel); + colorWidgetLayout->addWidget(m_ColorButton); + + QWidget* colorWidget = new QWidget; + colorWidget->setLayout(colorWidgetLayout); + + setDefaultWidget(colorWidget); + + connect(this, &QmitkDataNodeColorAction::changed, this, &QmitkDataNodeColorAction::OnActionChanged); +} + +void QmitkDataNodeColorAction::InitializeWithDataNode(const mitk::DataNode* dataNode) +{ + float rgb[3]; + if (dataNode->GetColor(rgb)) + { + QColor color(rgb[0] * 255, rgb[1] * 255, rgb[2] * 255); + QString styleSheet = QString("background-color: ") + color.name(QColor::HexRgb); + m_ColorButton->setAutoFillBackground(true); + m_ColorButton->setStyleSheet(styleSheet); + } +} + +void QmitkDataNodeColorAction::OnColorChanged() +{ + bool selectedColor = false; + QColor newColor; + + auto selectedNodes = GetSelectedNodes(); + for (auto& dataNode : selectedNodes) + { + if (dataNode.IsNull()) + { + continue; + } + + float rgb[3]; + if (dataNode->GetColor(rgb)) + { + if (!selectedColor) + { + QColor initial(rgb[0] * 255, rgb[1] * 255, rgb[2] * 255); + newColor = QColorDialog::getColor(initial, nullptr, QString(tr("Change color"))); + + if (newColor.isValid()) + { + selectedColor = true; + } + else + { + return; + } + } + + dataNode->SetProperty("color", mitk::ColorProperty::New(newColor.redF(), newColor.greenF(), newColor.blueF())); + if (dataNode->GetProperty("binaryimage.selectedcolor")) + { + dataNode->SetProperty("binaryimage.selectedcolor", mitk::ColorProperty::New(newColor.redF(), newColor.greenF(), newColor.blueF())); + } + } + } + + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); +} + +void QmitkDataNodeColorAction::OnActionChanged() +{ + auto dataNode = GetSelectedNode(); + if (dataNode.IsNull()) + { + return; + } + + InitializeWithDataNode(dataNode); +} diff --git a/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeColorAction.h b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeColorAction.h new file mode 100644 index 0000000000..f1bf1c22b5 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeColorAction.h @@ -0,0 +1,56 @@ +/*=================================================================== + +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 QMITKDATANODECOLORACTION_H +#define QMITKDATANODECOLORACTION_H + +#include + +#include "QmitkAbstractDataNodeAction.h" + +// qt +#include +#include + +class MITK_QT_APP QmitkDataNodeColorAction : public QWidgetAction, public QmitkAbstractDataNodeAction +{ + Q_OBJECT + +public: + + QmitkDataNodeColorAction(QWidget* parent, berry::IWorkbenchPartSite::Pointer workbenchPartSite); + QmitkDataNodeColorAction(QWidget* parent, berry::IWorkbenchPartSite* workbenchPartSite); + + virtual ~QmitkDataNodeColorAction() override; + + virtual void InitializeWithDataNode(const mitk::DataNode* dataNode) override; + +private Q_SLOTS: + + void OnColorChanged(); + void OnActionChanged(); + +protected: + + virtual void InitializeAction() override; + +private: + + QPushButton* m_ColorButton; + +}; + +#endif // QMITKDATANODECOLORACTION_H diff --git a/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeColorMapAction.cpp b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeColorMapAction.cpp new file mode 100644 index 0000000000..eb629da7f3 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeColorMapAction.cpp @@ -0,0 +1,141 @@ +/*=================================================================== + +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 + +// mitk core +#include +#include +#include +#include +#include + +// mitk gui common plugin +#include + +// berry +#include + +// qt +#include + +QmitkDataNodeColorMapAction::QmitkDataNodeColorMapAction(QWidget* parent, berry::IWorkbenchPartSite::Pointer workbenchpartSite) + : QAction(parent) + , QmitkAbstractDataNodeAction(workbenchpartSite) +{ + setText(tr("Colormap")); + InitializeAction(); +} + +QmitkDataNodeColorMapAction::QmitkDataNodeColorMapAction(QWidget* parent, berry::IWorkbenchPartSite* workbenchpartSite) + : QAction(parent) + , QmitkAbstractDataNodeAction(berry::IWorkbenchPartSite::Pointer(workbenchpartSite)) +{ + setText(tr("Colormap")); + InitializeAction(); +} + +QmitkDataNodeColorMapAction::~QmitkDataNodeColorMapAction() +{ + // nothing here +} + +void QmitkDataNodeColorMapAction::InitializeAction() +{ + setCheckable(true); + + setMenu(new QMenu); + connect(menu(), &QMenu::aboutToShow, this, &QmitkDataNodeColorMapAction::OnMenuAboutShow); +} + +void QmitkDataNodeColorMapAction::OnMenuAboutShow() +{ + auto dataNode = GetSelectedNode(); + if (dataNode.IsNull()) + { + return; + } + + mitk::LookupTableProperty::Pointer lookupTableProperty = dynamic_cast(dataNode->GetProperty("LookupTable")); + if (lookupTableProperty.IsNull()) + { + mitk::LookupTable::Pointer mitkLut = mitk::LookupTable::New(); + lookupTableProperty = mitk::LookupTableProperty::New(); + lookupTableProperty->SetLookupTable(mitkLut); + dataNode->SetProperty("LookupTable", lookupTableProperty); + } + + mitk::LookupTable::Pointer lookupTable = lookupTableProperty->GetValue(); + if (lookupTable.IsNull()) + { + return; + } + + menu()->clear(); + QAction* tmp; + + int i = 0; + std::string lutType = lookupTable->typenameList[i]; + + while (lutType != "END_OF_ARRAY") + { + tmp = menu()->addAction(QString::fromStdString(lutType)); + tmp->setCheckable(true); + + if (lutType == lookupTable->GetActiveTypeAsString()) + { + tmp->setChecked(true); + } + + connect(tmp, &QAction::triggered, this, &QmitkDataNodeColorMapAction::OnActionTriggered); + + lutType = lookupTable->typenameList[++i]; + } +} + +void QmitkDataNodeColorMapAction::OnActionTriggered(bool checked) +{ + auto dataNode = GetSelectedNode(); + if (dataNode.IsNull()) + { + return; + } + + mitk::LookupTableProperty::Pointer lookupTableProperty = dynamic_cast(dataNode->GetProperty("LookupTable")); + if (lookupTableProperty.IsNull()) + { + return; + } + + mitk::LookupTable::Pointer lookupTable = lookupTableProperty->GetValue(); + if (lookupTable.IsNull()) + { + return; + } + + QAction* senderAction = qobject_cast(QObject::sender()); + if (nullptr == senderAction) + { + return; + } + + std::string activatedItem = senderAction->text().toStdString(); + lookupTable->SetType(activatedItem); + lookupTableProperty->SetValue(lookupTable); + mitk::RenderingModeProperty::Pointer renderingMode = dynamic_cast(dataNode->GetProperty("Image Rendering.Mode")); + renderingMode->SetValue(mitk::RenderingModeProperty::LOOKUPTABLE_LEVELWINDOW_COLOR); + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); +} diff --git a/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeColorMapAction.h b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeColorMapAction.h new file mode 100644 index 0000000000..a646ec1bec --- /dev/null +++ b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeColorMapAction.h @@ -0,0 +1,49 @@ +/*=================================================================== + +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 QMITKDATANODECOLORMAPACTION_H +#define QMITKDATANODECOLORMAPACTION_H + +#include + +#include "QmitkAbstractDataNodeAction.h" + +// qt +#include + +class MITK_QT_APP QmitkDataNodeColorMapAction : public QAction, public QmitkAbstractDataNodeAction +{ + Q_OBJECT + +public: + + QmitkDataNodeColorMapAction(QWidget* parent, berry::IWorkbenchPartSite::Pointer workbenchPartSite); + QmitkDataNodeColorMapAction(QWidget* parent, berry::IWorkbenchPartSite* workbenchPartSite); + + virtual ~QmitkDataNodeColorMapAction() override; + +private Q_SLOTS: + + void OnMenuAboutShow(); + void OnActionTriggered(bool); + +protected: + + virtual void InitializeAction() override; + +}; + +#endif // QMITKDATANODECOLORMAPACTION_H diff --git a/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeComponentAction.cpp b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeComponentAction.cpp new file mode 100644 index 0000000000..0250be552f --- /dev/null +++ b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeComponentAction.cpp @@ -0,0 +1,111 @@ +/*=================================================================== + +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 + +// mitk core +#include +#include +#include + +// mitk gui common plugin +#include + +// berry +#include + +// qt +#include +#include + +QmitkDataNodeComponentAction::QmitkDataNodeComponentAction(QWidget* parent, berry::IWorkbenchPartSite::Pointer workbenchpartSite) + : QWidgetAction(parent) + , QmitkAbstractDataNodeAction(workbenchpartSite) +{ + InitializeAction(); +} + +QmitkDataNodeComponentAction::QmitkDataNodeComponentAction(QWidget* parent, berry::IWorkbenchPartSite* workbenchpartSite) + : QWidgetAction(parent) + , QmitkAbstractDataNodeAction(berry::IWorkbenchPartSite::Pointer(workbenchpartSite)) +{ + InitializeAction(); +} + +QmitkDataNodeComponentAction::~QmitkDataNodeComponentAction() +{ + // nothing here +} + +void QmitkDataNodeComponentAction::InitializeAction() +{ + setCheckable(true); + + m_ComponentSlider = new QmitkNumberPropertySlider; + m_ComponentSlider->setOrientation(Qt::Horizontal); + + QLabel* componentLabel = new QLabel(tr("Component: ")); + QHBoxLayout* componentWidgetLayout = new QHBoxLayout; + componentWidgetLayout->setContentsMargins(4, 4, 4, 4); + componentWidgetLayout->addWidget(componentLabel); + componentWidgetLayout->addWidget(m_ComponentSlider); + QLabel* componentValueLabel = new QLabel(); + componentWidgetLayout->addWidget(componentValueLabel); + connect(m_ComponentSlider, &QmitkNumberPropertySlider::valueChanged, componentValueLabel, static_cast(&QLabel::setNum)); + + QWidget* componentWidget = new QWidget; + componentWidget->setLayout(componentWidgetLayout); + + setDefaultWidget(componentWidget); + + connect(this, &QmitkDataNodeComponentAction::changed, this, &QmitkDataNodeComponentAction::OnActionChanged); +} + +void QmitkDataNodeComponentAction::InitializeWithDataNode(const mitk::DataNode* dataNode) +{ + if (nullptr == dataNode) + { + m_ComponentSlider->SetProperty(static_cast(nullptr)); + return; + } + + mitk::Image* img = dynamic_cast(dataNode->GetData()); + if (nullptr == img) + { + m_ComponentSlider->SetProperty(static_cast(nullptr)); + return; + } + + int numComponents = 0; + numComponents = img->GetPixelType().GetNumberOfComponents(); + mitk::IntProperty* componentProperty = dynamic_cast(dataNode->GetProperty("Image.Displayed Component")); + if (numComponents <= 1 || nullptr == componentProperty) + { + m_ComponentSlider->SetProperty(static_cast(nullptr)); + return; + } + + m_ComponentSlider->SetProperty(componentProperty); + m_ComponentSlider->setMinValue(0); + m_ComponentSlider->setMaxValue(numComponents - 1); +} + +void QmitkDataNodeComponentAction::OnActionChanged() +{ + auto dataNode = GetSelectedNode(); + + InitializeWithDataNode(dataNode); +} diff --git a/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeComponentAction.h b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeComponentAction.h new file mode 100644 index 0000000000..3da6b93db6 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeComponentAction.h @@ -0,0 +1,57 @@ +/*=================================================================== + +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 QMITKDATANODECOMPONENTACTION_H +#define QMITKDATANODECOMPONENTACTION_H + +#include + +// qt widgets ext module +#include + +#include "QmitkAbstractDataNodeAction.h" + +// qt +#include + +class MITK_QT_APP QmitkDataNodeComponentAction : public QWidgetAction, public QmitkAbstractDataNodeAction +{ + Q_OBJECT + +public: + + QmitkDataNodeComponentAction(QWidget* parent, berry::IWorkbenchPartSite::Pointer workbenchPartSite); + QmitkDataNodeComponentAction(QWidget* parent, berry::IWorkbenchPartSite* workbenchPartSite); + + virtual ~QmitkDataNodeComponentAction() override; + + virtual void InitializeWithDataNode(const mitk::DataNode* dataNode) override; + +private Q_SLOTS: + + void OnActionChanged(); + +protected: + + virtual void InitializeAction() override; + +private: + + QmitkNumberPropertySlider* m_ComponentSlider; + +}; + +#endif // QMITKDATANODECOMPONENTACTION_H diff --git a/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeContextMenu.cpp b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeContextMenu.cpp new file mode 100644 index 0000000000..6512b9616b --- /dev/null +++ b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeContextMenu.cpp @@ -0,0 +1,538 @@ +/*=================================================================== + +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) +{ + if (m_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::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.application/src/QmitkDataNodeContextMenu.h b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeContextMenu.h new file mode 100644 index 0000000000..d5f3055074 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeContextMenu.h @@ -0,0 +1,134 @@ +/*=================================================================== + +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 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 + +// 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); + + virtual ~QmitkDataNodeContextMenu() override; + + void SetDataStorage(mitk::DataStorage* dataStorage); + void SetSurfaceDecimation(bool surfaceDecimation); + +public Q_SLOTS: + + void OnContextMenuRequested(const QPoint& pos); + void OnExtensionPointActionTriggered(bool); + +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; + 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 diff --git a/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeGlobalReinitAction.cpp b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeGlobalReinitAction.cpp new file mode 100644 index 0000000000..5a35e9f376 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeGlobalReinitAction.cpp @@ -0,0 +1,87 @@ +/*=================================================================== + +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 + +// mitk core +#include + +// mitk gui common plugin +#include + +const QString QmitkDataNodeGlobalReinitAction::ACTION_ID = "org.mitk.gui.qt.application.globalreinitaction"; + +// namespace that contains the concrete action +namespace GlobalReinitAction +{ + void Run(berry::IWorkbenchPartSite::Pointer workbenchPartSite, mitk::DataStorage::Pointer dataStorage) + { + auto renderWindow = mitk::WorkbenchUtil::GetRenderWindowPart(workbenchPartSite->GetPage(), mitk::WorkbenchUtil::NONE); + + if (nullptr == renderWindow) + { + renderWindow = mitk::WorkbenchUtil::OpenRenderWindowPart(workbenchPartSite->GetPage(), false); + if (nullptr == renderWindow) + { + // no render window available + return; + } + } + + mitk::RenderingManager::GetInstance()->InitializeViewsByBoundingObjects(dataStorage); + } +} + +QmitkDataNodeGlobalReinitAction::QmitkDataNodeGlobalReinitAction(QWidget* parent, berry::IWorkbenchPartSite::Pointer workbenchPartSite) + : QAction(parent) + , QmitkAbstractDataNodeAction(workbenchPartSite) +{ + setText(tr("Global Reinit")); + InitializeAction(); +} + +QmitkDataNodeGlobalReinitAction::QmitkDataNodeGlobalReinitAction(QWidget* parent, berry::IWorkbenchPartSite* workbenchPartSite) + : QAction(parent) + , QmitkAbstractDataNodeAction(berry::IWorkbenchPartSite::Pointer(workbenchPartSite)) +{ + setText(tr("Global Reinit")); + InitializeAction(); +} + +QmitkDataNodeGlobalReinitAction::~QmitkDataNodeGlobalReinitAction() +{ + // nothing here +} + +void QmitkDataNodeGlobalReinitAction::InitializeAction() +{ + connect(this, &QmitkDataNodeGlobalReinitAction::triggered, this, &QmitkDataNodeGlobalReinitAction::OnActionTriggered); +} + +void QmitkDataNodeGlobalReinitAction::OnActionTriggered(bool checked) +{ + if (m_WorkbenchPartSite.Expired()) + { + return; + } + + if (m_DataStorage.IsExpired()) + { + return; + } + + GlobalReinitAction::Run(m_WorkbenchPartSite.Lock(), m_DataStorage.Lock()); +} diff --git a/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeGlobalReinitAction.h b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeGlobalReinitAction.h new file mode 100644 index 0000000000..5202843495 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeGlobalReinitAction.h @@ -0,0 +1,55 @@ +/*=================================================================== + +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 QMITKDATANODEGLOBALREINITACTION_H +#define QMITKDATANODEGLOBALREINITACTION_H + +#include + +#include "QmitkAbstractDataNodeAction.h" + +// qt +#include + +namespace GlobalReinitAction +{ + MITK_QT_APP void Run(berry::IWorkbenchPartSite::Pointer workbenchPartSite, mitk::DataStorage::Pointer dataStorage); +} + +class MITK_QT_APP QmitkDataNodeGlobalReinitAction : public QAction, public QmitkAbstractDataNodeAction +{ + Q_OBJECT + +public: + + static const QString ACTION_ID; // = "org.mitk.gui.qt.application.globalreinitaction"; + + QmitkDataNodeGlobalReinitAction(QWidget* parent, berry::IWorkbenchPartSite::Pointer workbenchPartSite); + QmitkDataNodeGlobalReinitAction(QWidget* parent, berry::IWorkbenchPartSite* workbenchPartSite); + + virtual ~QmitkDataNodeGlobalReinitAction() override; + +private Q_SLOTS: + + void OnActionTriggered(bool); + +private: + + virtual void InitializeAction() override; + +}; + +#endif // QMITKDATANODEGLOBALREINITACTION_H diff --git a/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeHideAllNodesAction.cpp b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeHideAllNodesAction.cpp new file mode 100644 index 0000000000..9d034351df --- /dev/null +++ b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeHideAllNodesAction.cpp @@ -0,0 +1,65 @@ +/*=================================================================== + +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 + +// mitk core +#include + +QmitkDataNodeHideAllNodesAction::QmitkDataNodeHideAllNodesAction(QWidget* parent, berry::IWorkbenchPartSite::Pointer workbenchpartSite) + : QAction(parent) + , QmitkAbstractDataNodeAction(workbenchpartSite) +{ + setText(tr("Hide all nodes")); + InitializeAction(); +} + +QmitkDataNodeHideAllNodesAction::QmitkDataNodeHideAllNodesAction(QWidget* parent, berry::IWorkbenchPartSite* workbenchpartSite) + : QAction(parent) + , QmitkAbstractDataNodeAction(berry::IWorkbenchPartSite::Pointer(workbenchpartSite)) +{ + setText(tr("Hide all nodes")); + InitializeAction(); +} + +QmitkDataNodeHideAllNodesAction::~QmitkDataNodeHideAllNodesAction() +{ + // nothing here +} + +void QmitkDataNodeHideAllNodesAction::InitializeAction() +{ + connect(this, &QmitkDataNodeHideAllNodesAction::triggered, this, &QmitkDataNodeHideAllNodesAction::OnActionTriggered); +} + +void QmitkDataNodeHideAllNodesAction::OnActionTriggered(bool checked) +{ + if (m_DataStorage.IsExpired()) + { + return; + } + + auto nodeset = m_DataStorage.Lock()->GetAll(); + for (auto& node : *nodeset) + { + if (node.IsNotNull()) + { + node->SetVisibility(false); + } + } + + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); +} diff --git a/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeHideAllNodesAction.h b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeHideAllNodesAction.h new file mode 100644 index 0000000000..e398114567 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeHideAllNodesAction.h @@ -0,0 +1,48 @@ +/*=================================================================== + +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 QMITKDATANODEHIDEALLNODESACTION_H +#define QMITKDATANODEHIDEALLNODESACTION_H + +#include + +#include "QmitkAbstractDataNodeAction.h" + +// qt +#include + +class MITK_QT_APP QmitkDataNodeHideAllNodesAction : public QAction, public QmitkAbstractDataNodeAction +{ + Q_OBJECT + +public: + + QmitkDataNodeHideAllNodesAction(QWidget* parent, berry::IWorkbenchPartSite::Pointer workbenchPartSite); + QmitkDataNodeHideAllNodesAction(QWidget* parent, berry::IWorkbenchPartSite* workbenchPartSite); + + virtual ~QmitkDataNodeHideAllNodesAction() override; + +private Q_SLOTS: + + void OnActionTriggered(bool); + +protected: + + virtual void InitializeAction() override; + +}; + +#endif // QMITKDATANODEHIDEALLNODESACTION_H diff --git a/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeOpacityAction.cpp b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeOpacityAction.cpp new file mode 100644 index 0000000000..58c58830bc --- /dev/null +++ b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeOpacityAction.cpp @@ -0,0 +1,99 @@ +/*=================================================================== + +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 + +// mitk core +#include + +// qt +#include +#include + +QmitkDataNodeOpacityAction::QmitkDataNodeOpacityAction(QWidget* parent, berry::IWorkbenchPartSite::Pointer workbenchPartSite) + : QWidgetAction(parent) + , QmitkAbstractDataNodeAction(workbenchPartSite) +{ + InitializeAction(); +} + +QmitkDataNodeOpacityAction::QmitkDataNodeOpacityAction(QWidget* parent, berry::IWorkbenchPartSite* workbenchPartSite) + : QWidgetAction(parent) + , QmitkAbstractDataNodeAction(berry::IWorkbenchPartSite::Pointer(workbenchPartSite)) +{ + InitializeAction(); +} + +QmitkDataNodeOpacityAction::~QmitkDataNodeOpacityAction() +{ + // nothing here +} + +void QmitkDataNodeOpacityAction::InitializeAction() +{ + m_OpacitySlider = new QSlider; + m_OpacitySlider->setMinimum(0); + m_OpacitySlider->setMaximum(100); + m_OpacitySlider->setOrientation(Qt::Horizontal); + connect(m_OpacitySlider, &QSlider::valueChanged, this, &QmitkDataNodeOpacityAction::OnOpacityChanged); + + QLabel* opacityLabel = new QLabel(tr("Opacity: ")); + QHBoxLayout* opacityWidgetLayout = new QHBoxLayout; + opacityWidgetLayout->setContentsMargins(4, 4, 4, 4); + opacityWidgetLayout->addWidget(opacityLabel); + opacityWidgetLayout->addWidget(m_OpacitySlider); + + QWidget* opacityWidget = new QWidget; + opacityWidget->setLayout(opacityWidgetLayout); + + setDefaultWidget(opacityWidget); + + connect(this, &QAction::changed, this, &QmitkDataNodeOpacityAction::OnActionChanged); +} + +void QmitkDataNodeOpacityAction::InitializeWithDataNode(const mitk::DataNode* dataNode) +{ + float opacity = 0.0; + if (dataNode->GetFloatProperty("opacity", opacity)) + { + m_OpacitySlider->setValue(static_cast(opacity * 100)); + } +} + +void QmitkDataNodeOpacityAction::OnOpacityChanged(int value) +{ + auto dataNode = GetSelectedNode(); + if (dataNode.IsNull()) + { + return; + } + + float opacity = static_cast(value) / 100.0f; + dataNode->SetFloatProperty("opacity", opacity); + + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); +} + +void QmitkDataNodeOpacityAction::OnActionChanged() +{ + auto dataNode = GetSelectedNode(); + if (dataNode.IsNull()) + { + return; + } + + InitializeWithDataNode(dataNode); +} diff --git a/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeOpacityAction.h b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeOpacityAction.h new file mode 100644 index 0000000000..637732249a --- /dev/null +++ b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeOpacityAction.h @@ -0,0 +1,54 @@ +/*=================================================================== + +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 QMITKDATANODEOPACITYACTION_H +#define QMITKDATANODEOPACITYACTION_H + +#include + +#include "QmitkAbstractDataNodeAction.h" + +// qt +#include +#include + +class MITK_QT_APP QmitkDataNodeOpacityAction : public QWidgetAction, public QmitkAbstractDataNodeAction +{ + Q_OBJECT + +public: + + QmitkDataNodeOpacityAction(QWidget* parent, berry::IWorkbenchPartSite::Pointer workbenchPartSite); + QmitkDataNodeOpacityAction(QWidget* parent, berry::IWorkbenchPartSite* workbenchPartSite); + + virtual ~QmitkDataNodeOpacityAction() override; + + virtual void InitializeWithDataNode(const mitk::DataNode* dataNode) override; + +private Q_SLOTS: + + void OnOpacityChanged(int); + void OnActionChanged(); + +protected: + + virtual void InitializeAction() override; + + QSlider* m_OpacitySlider; + +}; + +#endif // QMITKDATANODEOPACITYACTION_H diff --git a/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeReinitAction.cpp b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeReinitAction.cpp new file mode 100644 index 0000000000..925d417c6b --- /dev/null +++ b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeReinitAction.cpp @@ -0,0 +1,116 @@ +/*=================================================================== + +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 + +// mitk core +#include +#include +#include +#include +#include + +// mitk gui common plugin +#include + +QmitkDataNodeReinitAction::QmitkDataNodeReinitAction(QWidget* parent, berry::IWorkbenchPartSite::Pointer workbenchpartSite) + : QAction(parent) + , QmitkAbstractDataNodeAction(workbenchpartSite) +{ + setText(tr("Reinit")); + InitializeAction(); +} + +QmitkDataNodeReinitAction::QmitkDataNodeReinitAction(QWidget* parent, berry::IWorkbenchPartSite* workbenchpartSite) + : QAction(parent) + , QmitkAbstractDataNodeAction(berry::IWorkbenchPartSite::Pointer(workbenchpartSite)) +{ + setText(tr("Reinit")); + InitializeAction(); +} + +QmitkDataNodeReinitAction::~QmitkDataNodeReinitAction() +{ + // nothing here +} + +void QmitkDataNodeReinitAction::InitializeAction() +{ + connect(this, &QmitkDataNodeReinitAction::triggered, this, &QmitkDataNodeReinitAction::OnActionTriggered); +} + +void QmitkDataNodeReinitAction::OnActionTriggered(bool checked) +{ + if (m_WorkbenchPartSite.Expired()) + { + return; + } + + auto renderWindow = mitk::WorkbenchUtil::GetRenderWindowPart(m_WorkbenchPartSite.Lock()->GetPage(), mitk::WorkbenchUtil::NONE); + + if (nullptr == renderWindow) + { + renderWindow = mitk::WorkbenchUtil::OpenRenderWindowPart(m_WorkbenchPartSite.Lock()->GetPage(), false); + if (nullptr == renderWindow) + { + // no render window available + return; + } + } + + if (m_DataStorage.IsExpired()) + { + return; + } + + auto dataStorage = m_DataStorage.Lock(); + + auto dataNodes = GetSelectedNodes(); + if (dataNodes.isEmpty()) + { + return; + } + + auto boundingBoxPredicate = mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("includeInBoundingBox", mitk::BoolProperty::New(false))); + + mitk::DataStorage::SetOfObjects::Pointer nodes = mitk::DataStorage::SetOfObjects::New(); + for (const auto& dataNode : dataNodes) + { + if (boundingBoxPredicate->CheckNode(dataNode)) + { + nodes->InsertElement(nodes->Size(), dataNode); + } + } + + if (nodes->empty()) + { + return; + } + + if (1 == nodes->Size()) // Special case: If exactly one ... + { + auto image = dynamic_cast(nodes->ElementAt(0)->GetData()); + + if (nullptr != image) // ... image is selected, reinit is expected to rectify askew images. + { + mitk::RenderingManager::GetInstance()->InitializeViews(image->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true); + return; + } + } + + auto boundingGeometry = dataStorage->ComputeBoundingGeometry3D(nodes, "visible"); + mitk::RenderingManager::GetInstance()->InitializeViews(boundingGeometry); +} diff --git a/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeReinitAction.h b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeReinitAction.h new file mode 100644 index 0000000000..7fdd174232 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeReinitAction.h @@ -0,0 +1,48 @@ +/*=================================================================== + +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 QMITKDATANODEREINITACTION_H +#define QMITKDATANODEREINITACTION_H + +#include + +#include "QmitkAbstractDataNodeAction.h" + +// qt +#include + +class MITK_QT_APP QmitkDataNodeReinitAction : public QAction, public QmitkAbstractDataNodeAction +{ + Q_OBJECT + +public: + + QmitkDataNodeReinitAction(QWidget* parent, berry::IWorkbenchPartSite::Pointer workbenchPartSite); + QmitkDataNodeReinitAction(QWidget* parent, berry::IWorkbenchPartSite* workbenchPartSite); + + virtual ~QmitkDataNodeReinitAction() override; + +private Q_SLOTS: + + void OnActionTriggered(bool); + +protected: + + virtual void InitializeAction() override; + +}; + +#endif // QMITKDATANODEREINITACTION_H diff --git a/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeRemoveAction.cpp b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeRemoveAction.cpp new file mode 100644 index 0000000000..678252076a --- /dev/null +++ b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeRemoveAction.cpp @@ -0,0 +1,106 @@ +/*=================================================================== + +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 +#include + +// qt +#include + +// berry +#include +#include +#include + +QmitkDataNodeRemoveAction::QmitkDataNodeRemoveAction(QWidget* parent, berry::IWorkbenchPartSite::Pointer workbenchpartSite) + : QAction(parent) + , QmitkAbstractDataNodeAction(workbenchpartSite) +{ + setText(tr("Remove")); + m_Parent = parent; + InitializeAction(); +} + +QmitkDataNodeRemoveAction::QmitkDataNodeRemoveAction(QWidget* parent, berry::IWorkbenchPartSite* workbenchpartSite) + : QAction(parent) + , QmitkAbstractDataNodeAction(berry::IWorkbenchPartSite::Pointer(workbenchpartSite)) +{ + setText(tr("Remove")); + m_Parent = parent; + InitializeAction(); +} + +QmitkDataNodeRemoveAction::~QmitkDataNodeRemoveAction() +{ + // nothing here +} + +void QmitkDataNodeRemoveAction::InitializeAction() +{ + connect(this, &QmitkDataNodeRemoveAction::triggered, this, &QmitkDataNodeRemoveAction::OnActionTriggered); +} + +void QmitkDataNodeRemoveAction::OnActionTriggered(bool checked) +{ + if (m_DataStorage.IsExpired()) + { + return; + } + + auto dataStorage = m_DataStorage.Lock(); + + QString question = tr("Do you really want to remove "); + auto selectedNodes = GetSelectedNodes(); + for (auto& dataNode : selectedNodes) + { + if (nullptr == dataNode) + { + continue; + } + + question.append(QString::fromStdString(dataNode->GetName())); + question.append(", "); + } + + // remove the last two characters = ", " + question = question.remove(question.size() - 2, 2); + question.append(tr(" from data storage?")); + + QMessageBox::StandardButton answerButton = QMessageBox::question(m_Parent, tr("DataManager"), question, + QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); + + if (answerButton == QMessageBox::Yes) + { + for (auto& dataNode : selectedNodes) + { + if (nullptr == dataNode) + { + continue; + } + + dataStorage->Remove(dataNode); + } + + berry::IPreferencesService* prefService = berry::Platform::GetPreferencesService(); + berry::IPreferences::Pointer preferencesNode = prefService->GetSystemPreferences()->Node(QmitkDataNodeGlobalReinitAction::ACTION_ID); + + bool globalReinit = preferencesNode->GetBool("Call global reinit if node is deleted", true); + if (globalReinit) + { + GlobalReinitAction::Run(m_WorkbenchPartSite.Lock(), dataStorage); + } + } +} diff --git a/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeRemoveAction.h b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeRemoveAction.h new file mode 100644 index 0000000000..42be9f33c8 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeRemoveAction.h @@ -0,0 +1,52 @@ +/*=================================================================== + +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 QMITKDATANODEREMOVEACTION_H +#define QMITKDATANODEREMOVEACTION_H + +#include + +#include "QmitkAbstractDataNodeAction.h" + +// qt +#include + +class MITK_QT_APP QmitkDataNodeRemoveAction : public QAction, public QmitkAbstractDataNodeAction +{ + Q_OBJECT + +public: + + QmitkDataNodeRemoveAction(QWidget* parent, berry::IWorkbenchPartSite::Pointer workbenchPartSite); + QmitkDataNodeRemoveAction(QWidget* parent, berry::IWorkbenchPartSite* workbenchPartSite); + + virtual ~QmitkDataNodeRemoveAction() override; + +private Q_SLOTS: + + void OnActionTriggered(bool); + +protected: + + virtual void InitializeAction() override; + +private: + + QWidget* m_Parent; + +}; + +#endif // QMITKDATANODEREMOVEACTION_H diff --git a/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeShowDetailsAction.cpp b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeShowDetailsAction.cpp new file mode 100644 index 0000000000..0e55a7da54 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeShowDetailsAction.cpp @@ -0,0 +1,56 @@ +/*=================================================================== + +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 + +// mitk gui qt application +#include "src/internal/QmitkInfoDialog.h" + +QmitkDataNodeShowDetailsAction::QmitkDataNodeShowDetailsAction(QWidget* parent, berry::IWorkbenchPartSite::Pointer workbenchpartSite) + : QAction(parent) + , QmitkAbstractDataNodeAction(workbenchpartSite) +{ + setText(tr("Show details")); + m_Parent = parent; + InitializeAction(); +} + +QmitkDataNodeShowDetailsAction::QmitkDataNodeShowDetailsAction(QWidget* parent, berry::IWorkbenchPartSite* workbenchpartSite) + : QAction(parent) + , QmitkAbstractDataNodeAction(berry::IWorkbenchPartSite::Pointer(workbenchpartSite)) +{ + setText(tr("Show details")); + m_Parent = parent; + InitializeAction(); +} + +QmitkDataNodeShowDetailsAction::~QmitkDataNodeShowDetailsAction() +{ + // nothing here +} + +void QmitkDataNodeShowDetailsAction::InitializeAction() +{ + connect(this, &QmitkDataNodeShowDetailsAction::triggered, this, &QmitkDataNodeShowDetailsAction::OnActionTriggered); +} + +void QmitkDataNodeShowDetailsAction::OnActionTriggered(bool checked) +{ + auto selectedNodes = GetSelectedNodes(); + + QmitkInfoDialog infoDialog(selectedNodes, m_Parent); + infoDialog.exec(); +} diff --git a/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeShowDetailsAction.h b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeShowDetailsAction.h new file mode 100644 index 0000000000..37128e25bd --- /dev/null +++ b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeShowDetailsAction.h @@ -0,0 +1,52 @@ +/*=================================================================== + +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 QMITKDATANODESHOWDETAILSACTION_H +#define QMITKDATANODESHOWDETAILSACTION_H + +#include + +#include "QmitkAbstractDataNodeAction.h" + +// qt +#include + +class MITK_QT_APP QmitkDataNodeShowDetailsAction : public QAction, public QmitkAbstractDataNodeAction +{ + Q_OBJECT + +public: + + QmitkDataNodeShowDetailsAction(QWidget* parent, berry::IWorkbenchPartSite::Pointer workbenchPartSite); + QmitkDataNodeShowDetailsAction(QWidget* parent, berry::IWorkbenchPartSite* workbenchPartSite); + + virtual ~QmitkDataNodeShowDetailsAction() override; + +private Q_SLOTS: + + void OnActionTriggered(bool); + +protected: + + virtual void InitializeAction() override; + +private: + + QWidget* m_Parent; + +}; + +#endif // QMITKDATANODESHOWDETAILSACTION_H diff --git a/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeShowSelectedNodesAction.cpp b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeShowSelectedNodesAction.cpp new file mode 100644 index 0000000000..43a802af99 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeShowSelectedNodesAction.cpp @@ -0,0 +1,68 @@ +/*=================================================================== + +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 + +// mitk core +#include + +QmitkDataNodeShowSelectedNodesAction::QmitkDataNodeShowSelectedNodesAction(QWidget* parent, berry::IWorkbenchPartSite::Pointer workbenchpartSite) + : QAction(parent) + , QmitkAbstractDataNodeAction(workbenchpartSite) +{ + setText(tr("Show only selected nodes")); + InitializeAction(); +} + +QmitkDataNodeShowSelectedNodesAction::QmitkDataNodeShowSelectedNodesAction(QWidget* parent, berry::IWorkbenchPartSite* workbenchpartSite) + : QAction(parent) + , QmitkAbstractDataNodeAction(berry::IWorkbenchPartSite::Pointer(workbenchpartSite)) +{ + setText(tr("Show only selected nodes")); + InitializeAction(); +} + +QmitkDataNodeShowSelectedNodesAction::~QmitkDataNodeShowSelectedNodesAction() +{ + // nothing here +} + +void QmitkDataNodeShowSelectedNodesAction::InitializeAction() +{ + connect(this, &QmitkDataNodeShowSelectedNodesAction::triggered, this, &QmitkDataNodeShowSelectedNodesAction::OnActionTriggered); +} + +void QmitkDataNodeShowSelectedNodesAction::OnActionTriggered(bool checked) +{ + if (m_DataStorage.IsExpired()) + { + return; + } + + auto dataStorage = m_DataStorage.Lock(); + + auto selectedNodes = GetSelectedNodes(); + auto nodeset = dataStorage->GetAll(); + for (auto& node : *nodeset) + { + if (node.IsNotNull()) + { + node->SetVisibility(selectedNodes.contains(node)); + } + } + + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); +} diff --git a/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeShowSelectedNodesAction.h b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeShowSelectedNodesAction.h new file mode 100644 index 0000000000..1847481291 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeShowSelectedNodesAction.h @@ -0,0 +1,48 @@ +/*=================================================================== + +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 QMITKDATANODESHOWSELECTEDNODESACTION_H +#define QMITKDATANODESHOWSELECTEDNODESACTION_H + +#include + +#include "QmitkAbstractDataNodeAction.h" + +// qt +#include + +class MITK_QT_APP QmitkDataNodeShowSelectedNodesAction : public QAction, public QmitkAbstractDataNodeAction +{ + Q_OBJECT + +public: + + QmitkDataNodeShowSelectedNodesAction(QWidget* parent, berry::IWorkbenchPartSite::Pointer workbenchPartSite); + QmitkDataNodeShowSelectedNodesAction(QWidget* parent, berry::IWorkbenchPartSite* workbenchPartSite); + + virtual ~QmitkDataNodeShowSelectedNodesAction() override; + +private Q_SLOTS: + + void OnActionTriggered(bool); + +protected: + + virtual void InitializeAction() override; + +}; + +#endif // QMITKDATANODESHOWSELECTEDNODESACTION_H diff --git a/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeSurfaceRepresentationAction.cpp b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeSurfaceRepresentationAction.cpp new file mode 100644 index 0000000000..9e71bd0de8 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeSurfaceRepresentationAction.cpp @@ -0,0 +1,118 @@ +/*=================================================================== + +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 + +// mitk core +#include +#include + +// qt +#include + +QmitkDataNodeSurfaceRepresentationAction::QmitkDataNodeSurfaceRepresentationAction(QWidget* parent, berry::IWorkbenchPartSite::Pointer workbenchpartSite) + : QAction(parent) + , QmitkAbstractDataNodeAction(workbenchpartSite) +{ + setText(tr("Surface Representation")); + InitializeAction(); +} + +QmitkDataNodeSurfaceRepresentationAction::QmitkDataNodeSurfaceRepresentationAction(QWidget* parent, berry::IWorkbenchPartSite* workbenchpartSite) + : QAction(parent) + , QmitkAbstractDataNodeAction(berry::IWorkbenchPartSite::Pointer(workbenchpartSite)) +{ + setText(tr("Surface Representation")); + InitializeAction(); +} + +QmitkDataNodeSurfaceRepresentationAction::~QmitkDataNodeSurfaceRepresentationAction() +{ + // nothing here +} + +void QmitkDataNodeSurfaceRepresentationAction::InitializeAction() +{ + setCheckable(true); + + setMenu(new QMenu); + connect(menu(), &QMenu::aboutToShow, this, &QmitkDataNodeSurfaceRepresentationAction::OnMenuAboutShow); +} + +void QmitkDataNodeSurfaceRepresentationAction::OnMenuAboutShow() +{ + mitk::DataNode::Pointer dataNode = GetSelectedNode(); + if (nullptr == dataNode) + { + return; + } + + mitk::EnumerationProperty* representationProp = dynamic_cast(dataNode->GetProperty("material.representation")); + if (nullptr == representationProp) + { + return; + } + + menu()->clear(); + QAction* tmp; + + for (mitk::EnumerationProperty::EnumConstIterator it = representationProp->Begin(); it != representationProp->End(); ++it) + { + tmp = menu()->addAction(QString::fromStdString(it->second)); + tmp->setCheckable(true); + + if (it->second == representationProp->GetValueAsString()) + { + tmp->setChecked(true); + } + + connect(tmp, &QAction::triggered, this, &QmitkDataNodeSurfaceRepresentationAction::OnActionTriggered); + } +} + +void QmitkDataNodeSurfaceRepresentationAction::OnActionTriggered(bool checked) +{ + auto dataNode = GetSelectedNode(); + if (dataNode.IsNull()) + { + return; + } + + mitk::EnumerationProperty* representationProp = dynamic_cast(dataNode->GetProperty("material.representation")); + if (nullptr == representationProp) + { + return; + } + + QAction* senderAction = qobject_cast(QObject::sender()); + if (nullptr == senderAction) + { + return; + } + + std::string activatedItem = senderAction->text().toStdString(); + if (activatedItem != representationProp->GetValueAsString()) + { + if (representationProp->IsValidEnumerationValue(activatedItem)) + { + representationProp->SetValue(activatedItem); + representationProp->InvokeEvent(itk::ModifiedEvent()); + representationProp->Modified(); + + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); + } + } +} diff --git a/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeSurfaceRepresentationAction.h b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeSurfaceRepresentationAction.h new file mode 100644 index 0000000000..57abbf8e87 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeSurfaceRepresentationAction.h @@ -0,0 +1,49 @@ +/*=================================================================== + +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 QMITKDATANODESURFACEREPRESENTATIONACTION_H +#define QMITKDATANODESURFACEREPRESENTATIONACTION_H + +#include + +#include "QmitkAbstractDataNodeAction.h" + +// qt +#include + +class MITK_QT_APP QmitkDataNodeSurfaceRepresentationAction : public QAction, public QmitkAbstractDataNodeAction +{ + Q_OBJECT + +public: + + QmitkDataNodeSurfaceRepresentationAction(QWidget* parent, berry::IWorkbenchPartSite::Pointer workbenchPartSite); + QmitkDataNodeSurfaceRepresentationAction(QWidget* parent, berry::IWorkbenchPartSite* workbenchPartSite); + + virtual ~QmitkDataNodeSurfaceRepresentationAction() override; + +private Q_SLOTS: + + void OnMenuAboutShow(); + void OnActionTriggered(bool); + +protected: + + virtual void InitializeAction() override; + +}; + +#endif // QMITKDATANODESURFACEREPRESENTATIONACTION_H diff --git a/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeTextureInterpolationAction.cpp b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeTextureInterpolationAction.cpp new file mode 100644 index 0000000000..7dfac8d873 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeTextureInterpolationAction.cpp @@ -0,0 +1,79 @@ +/*=================================================================== + +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 + +// mitk core +#include + +QmitkDataNodeTextureInterpolationAction::QmitkDataNodeTextureInterpolationAction(QWidget* parent, berry::IWorkbenchPartSite::Pointer workbenchpartSite) + : QAction(parent) + , QmitkAbstractDataNodeAction(workbenchpartSite) +{ + setText(tr("Texture Interpolation")); + InitializeAction(); +} + +QmitkDataNodeTextureInterpolationAction::QmitkDataNodeTextureInterpolationAction(QWidget* parent, berry::IWorkbenchPartSite* workbenchpartSite) + : QAction(parent) + , QmitkAbstractDataNodeAction(berry::IWorkbenchPartSite::Pointer(workbenchpartSite)) +{ + setText(tr("Texture Interpolation")); + InitializeAction(); +} + +QmitkDataNodeTextureInterpolationAction::~QmitkDataNodeTextureInterpolationAction() +{ + // nothing here +} + +void QmitkDataNodeTextureInterpolationAction::InitializeAction() +{ + setCheckable(true); + + connect(this, &QmitkDataNodeTextureInterpolationAction::toggled, this, &QmitkDataNodeTextureInterpolationAction::OnActionToggled); + connect(this, &QmitkDataNodeTextureInterpolationAction::changed, this, &QmitkDataNodeTextureInterpolationAction::OnActionChanged); +} + +void QmitkDataNodeTextureInterpolationAction::InitializeWithDataNode(const mitk::DataNode* dataNode) +{ + bool textureInterpolation = false; + dataNode->GetBoolProperty("texture interpolation", textureInterpolation); + setChecked(textureInterpolation); +} + +void QmitkDataNodeTextureInterpolationAction::OnActionToggled(bool checked) +{ + auto dataNode = GetSelectedNode(); + if (dataNode.IsNull()) + { + return; + } + + dataNode->SetBoolProperty("texture interpolation", checked); + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); +} + +void QmitkDataNodeTextureInterpolationAction::OnActionChanged() +{ + auto dataNode = GetSelectedNode(); + if (dataNode.IsNull()) + { + return; + } + + InitializeWithDataNode(dataNode); +} diff --git a/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeTextureInterpolationAction.h b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeTextureInterpolationAction.h new file mode 100644 index 0000000000..589c2b2f95 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeTextureInterpolationAction.h @@ -0,0 +1,51 @@ +/*=================================================================== + +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 QMITKDATANODETEXTUREINTERPOLATIONACTION_H +#define QMITKDATANODETEXTUREINTERPOLATIONACTION_H + +#include + +#include "QmitkAbstractDataNodeAction.h" + +// qt +#include + +class MITK_QT_APP QmitkDataNodeTextureInterpolationAction : public QAction, public QmitkAbstractDataNodeAction +{ + Q_OBJECT + +public: + + QmitkDataNodeTextureInterpolationAction(QWidget* parent, berry::IWorkbenchPartSite::Pointer workbenchPartSite); + QmitkDataNodeTextureInterpolationAction(QWidget* parent, berry::IWorkbenchPartSite* workbenchPartSite); + + virtual ~QmitkDataNodeTextureInterpolationAction() override; + + virtual void InitializeWithDataNode(const mitk::DataNode* dataNode) override; + +private Q_SLOTS: + + void OnActionChanged(); + void OnActionToggled(bool); + +protected: + + virtual void InitializeAction() override; + +}; + +#endif // QMITKDATANODETEXTUREINTERPOLATIONACTION_H diff --git a/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeToggleVisibilityAction.cpp b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeToggleVisibilityAction.cpp new file mode 100644 index 0000000000..1b40a398b5 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeToggleVisibilityAction.cpp @@ -0,0 +1,99 @@ +/*=================================================================== + +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 +#include + +// mitk core +#include + +// berry +#include +#include +#include + +// namespace that contains the concrete action +namespace ToggleVisibilityAction +{ + void Run(berry::IWorkbenchPartSite::Pointer workbenchPartSite, mitk::DataStorage::Pointer dataStorage, QList selectedNodes /* = QList()*/) + { + bool isVisible; + for (auto& node : selectedNodes) + { + if (node.IsNotNull()) + { + isVisible = false; + node->GetBoolProperty("visible", isVisible); + node->SetVisibility(!isVisible); + } + } + + berry::IPreferencesService* prefService = berry::Platform::GetPreferencesService(); + berry::IPreferences::Pointer preferencesNode = prefService->GetSystemPreferences()->Node(QmitkDataNodeGlobalReinitAction::ACTION_ID); + + bool globalReinit = preferencesNode->GetBool("Call global reinit if node visibility is changed", false); + if (globalReinit) + { + GlobalReinitAction::Run(workbenchPartSite, dataStorage); + } + else + { + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); + } + } +} + +QmitkDataNodeToggleVisibilityAction::QmitkDataNodeToggleVisibilityAction(QWidget* parent, berry::IWorkbenchPartSite::Pointer workbenchpartSite) + : QAction(parent) + , QmitkAbstractDataNodeAction(workbenchpartSite) +{ + setText(tr("Toggle visibility")); + InitializeAction(); +} + +QmitkDataNodeToggleVisibilityAction::QmitkDataNodeToggleVisibilityAction(QWidget* parent, berry::IWorkbenchPartSite* workbenchpartSite) + : QAction(parent) + , QmitkAbstractDataNodeAction(berry::IWorkbenchPartSite::Pointer(workbenchpartSite)) +{ + setText(tr("Toggle visibility")); + InitializeAction(); +} + +QmitkDataNodeToggleVisibilityAction::~QmitkDataNodeToggleVisibilityAction() +{ + // nothing here +} + +void QmitkDataNodeToggleVisibilityAction::InitializeAction() +{ + connect(this, &QmitkDataNodeToggleVisibilityAction::triggered, this, &QmitkDataNodeToggleVisibilityAction::OnActionTriggered); +} + +void QmitkDataNodeToggleVisibilityAction::OnActionTriggered(bool checked) +{ + if (m_WorkbenchPartSite.Expired()) + { + return; + } + + if (m_DataStorage.IsExpired()) + { + return; + } + + auto selectedNodes = GetSelectedNodes(); + ToggleVisibilityAction::Run(m_WorkbenchPartSite.Lock(), m_DataStorage.Lock(), selectedNodes); +} diff --git a/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeToggleVisibilityAction.h b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeToggleVisibilityAction.h new file mode 100644 index 0000000000..acd9138b91 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeToggleVisibilityAction.h @@ -0,0 +1,53 @@ +/*=================================================================== + +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 QMITKDATANODETOGGLEVISIBILITYACTION_H +#define QMITKDATANODETOGGLEVISIBILITYACTION_H + +#include + +#include "QmitkAbstractDataNodeAction.h" + +// qt +#include + +namespace ToggleVisibilityAction +{ + MITK_QT_APP void Run(berry::IWorkbenchPartSite::Pointer workbenchPartSite, mitk::DataStorage::Pointer dataStorage, QList selectedNodes = QList()); +} + +class MITK_QT_APP QmitkDataNodeToggleVisibilityAction : public QAction, public QmitkAbstractDataNodeAction +{ + Q_OBJECT + +public: + + QmitkDataNodeToggleVisibilityAction(QWidget* parent, berry::IWorkbenchPartSite::Pointer workbenchPartSite); + QmitkDataNodeToggleVisibilityAction(QWidget* parent, berry::IWorkbenchPartSite* workbenchPartSite); + + virtual ~QmitkDataNodeToggleVisibilityAction() override; + +private Q_SLOTS: + + void OnActionTriggered(bool); + +protected: + + virtual void InitializeAction() override; + +}; + +#endif // QMITKDATANODETOGGLEVISIBILITYACTION_H diff --git a/Plugins/org.mitk.gui.qt.application/src/QmitkFileOpenAction.cpp b/Plugins/org.mitk.gui.qt.application/src/QmitkFileOpenAction.cpp index f8cbab6c8a..8e37af88e6 100644 --- a/Plugins/org.mitk.gui.qt.application/src/QmitkFileOpenAction.cpp +++ b/Plugins/org.mitk.gui.qt.application/src/QmitkFileOpenAction.cpp @@ -1,123 +1,125 @@ /*=================================================================== 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 "QmitkFileOpenAction.h" #include "internal/org_mitk_gui_qt_application_Activator.h" #include #include #include #include class QmitkFileOpenActionPrivate { public: - void init ( berry::IWorkbenchWindow* window, QmitkFileOpenAction* action ) + void Init(berry::IWorkbenchWindow* window, QmitkFileOpenAction* action) { m_Window = window; action->setText("&Open File..."); action->setToolTip("Open data files (images, surfaces,...)"); QObject::connect(action, SIGNAL(triggered(bool)), action, SLOT(Run())); } berry::IPreferences::Pointer GetPreferences() const { berry::IPreferencesService* prefService = mitk::PluginActivator::GetInstance()->GetPreferencesService(); - if (prefService) + if (prefService != nullptr) { return prefService->GetSystemPreferences()->Node("/General"); } return berry::IPreferences::Pointer(nullptr); } - QString getLastFileOpenPath() const + QString GetLastFileOpenPath() const { berry::IPreferences::Pointer prefs = GetPreferences(); - if(prefs.IsNotNull()) + if (prefs.IsNotNull()) { return prefs->Get("LastFileOpenPath", ""); } return QString(); } - void setLastFileOpenPath(const QString& path) const + void SetLastFileOpenPath(const QString& path) const { berry::IPreferences::Pointer prefs = GetPreferences(); - if(prefs.IsNotNull()) + if (prefs.IsNotNull()) { prefs->Put("LastFileOpenPath", path); prefs->Flush(); } } bool GetOpenEditor() const { berry::IPreferences::Pointer prefs = GetPreferences(); - if(prefs.IsNotNull()) + if (prefs.IsNotNull()) { return prefs->GetBool("OpenEditor", true); } return true; } berry::IWorkbenchWindow* m_Window; }; QmitkFileOpenAction::QmitkFileOpenAction(berry::IWorkbenchWindow::Pointer window) - : QAction(nullptr), d(new QmitkFileOpenActionPrivate) + : QAction(nullptr) + , d(new QmitkFileOpenActionPrivate) { - d->init(window.GetPointer(), this); + d->Init(window.GetPointer(), this); } -QmitkFileOpenAction::QmitkFileOpenAction(const QIcon & icon, berry::IWorkbenchWindow::Pointer window) - : QAction(nullptr), d(new QmitkFileOpenActionPrivate) +QmitkFileOpenAction::QmitkFileOpenAction(const QIcon& icon, berry::IWorkbenchWindow::Pointer window) + : QAction(nullptr) + , d(new QmitkFileOpenActionPrivate) { - d->init(window.GetPointer(), this); - this->setIcon(icon); + d->Init(window.GetPointer(), this); + setIcon(icon); } QmitkFileOpenAction::QmitkFileOpenAction(const QIcon& icon, berry::IWorkbenchWindow* window) : QAction(nullptr), d(new QmitkFileOpenActionPrivate) { - d->init(window, this); - this->setIcon(icon); + d->Init(window, this); + setIcon(icon); } QmitkFileOpenAction::~QmitkFileOpenAction() { } void QmitkFileOpenAction::Run() { - - // Ask the user for a list of files to open + // ask the user for a list of files to open QStringList fileNames = QFileDialog::getOpenFileNames(nullptr, "Open", - d->getLastFileOpenPath(), + d->GetLastFileOpenPath(), QmitkIOUtil::GetFileOpenFilterString()); if (fileNames.empty()) + { return; + } - d->setLastFileOpenPath(fileNames.front()); - mitk::WorkbenchUtil::LoadFiles(fileNames, berry::IWorkbenchWindow::Pointer(d->m_Window), - d->GetOpenEditor()); + d->SetLastFileOpenPath(fileNames.front()); + mitk::WorkbenchUtil::LoadFiles(fileNames, berry::IWorkbenchWindow::Pointer(d->m_Window), d->GetOpenEditor()); } diff --git a/Plugins/org.mitk.gui.qt.application/src/QmitkFileOpenAction.h b/Plugins/org.mitk.gui.qt.application/src/QmitkFileOpenAction.h index 79675eb528..5f032d9d6a 100644 --- a/Plugins/org.mitk.gui.qt.application/src/QmitkFileOpenAction.h +++ b/Plugins/org.mitk.gui.qt.application/src/QmitkFileOpenAction.h @@ -1,56 +1,53 @@ /*=================================================================== 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 QMITKFILEOPENACTION_H_ #define QMITKFILEOPENACTION_H_ -#include -#include +#include #include -#include - -#include +// qt +#include +#include class QmitkFileOpenActionPrivate; -/** - * \ingroup org_mitk_gui_qt_application - */ class MITK_QT_APP QmitkFileOpenAction : public QAction { Q_OBJECT public: + QmitkFileOpenAction(berry::IWorkbenchWindow::Pointer window); - QmitkFileOpenAction(const QIcon & icon, berry::IWorkbenchWindow::Pointer window); - QmitkFileOpenAction(const QIcon & icon, berry::IWorkbenchWindow* window); + QmitkFileOpenAction(const QIcon& icon, berry::IWorkbenchWindow::Pointer window); + QmitkFileOpenAction(const QIcon& icon, berry::IWorkbenchWindow* window); - ~QmitkFileOpenAction() override; + virtual ~QmitkFileOpenAction() override; protected slots: virtual void Run(); private: const QScopedPointer d; }; #endif /*QMITKFILEOPENACTION_H_*/ diff --git a/Plugins/org.mitk.gui.qt.application/src/QmitkFileSaveAction.cpp b/Plugins/org.mitk.gui.qt.application/src/QmitkFileSaveAction.cpp index d755511a5f..8efe3f43eb 100644 --- a/Plugins/org.mitk.gui.qt.application/src/QmitkFileSaveAction.cpp +++ b/Plugins/org.mitk.gui.qt.application/src/QmitkFileSaveAction.cpp @@ -1,196 +1,193 @@ /*=================================================================== 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 "QmitkFileSaveAction.h" #include "internal/org_mitk_gui_qt_application_Activator.h" #include #include #include #include #include #include -#include -#include - class QmitkFileSaveActionPrivate { private: void HandleSelectionChanged(const berry::IWorkbenchPart::Pointer& /*part*/, const berry::ISelection::ConstPointer& selection) { - this->setEnabled(selection); + this->SetEnabled(selection); } QScopedPointer m_SelectionListener; public: QmitkFileSaveActionPrivate() : m_SelectionListener(new berry::NullSelectionChangedAdapter( this, &QmitkFileSaveActionPrivate::HandleSelectionChanged)) { } ~QmitkFileSaveActionPrivate() { if (!m_Window.Expired()) { m_Window.Lock()->GetSelectionService()->RemoveSelectionListener(m_SelectionListener.data()); } } - void init ( berry::IWorkbenchWindow* window, QmitkFileSaveAction* action ) + void Init(berry::IWorkbenchWindow* window, QAction* action) { m_Window = berry::IWorkbenchWindow::Pointer(window); m_Action = action; - action->setText("&Save..."); - action->setToolTip("Save data objects (images, surfaces,...)"); + m_Action->setText("&Save..."); + m_Action->setToolTip("Save data objects (images, surfaces,...)"); berry::ISelectionService* selectionService = m_Window.Lock()->GetSelectionService(); - setEnabled(selectionService->GetSelection()); + SetEnabled(selectionService->GetSelection()); selectionService->AddSelectionListener(m_SelectionListener.data()); - QObject::connect(action, SIGNAL(triggered(bool)), action, SLOT(Run())); + QObject::connect(m_Action, SIGNAL(triggered(bool)), m_Action, SLOT(Run())); } berry::IPreferences::Pointer GetPreferences() const { berry::IPreferencesService* prefService = mitk::PluginActivator::GetInstance()->GetPreferencesService(); if (prefService != nullptr) { return prefService->GetSystemPreferences()->Node("/General"); } return berry::IPreferences::Pointer(nullptr); } - QString getLastFileSavePath() const + QString GetLastFileSavePath() const { berry::IPreferences::Pointer prefs = GetPreferences(); - if(prefs.IsNotNull()) + if (prefs.IsNotNull()) { return prefs->Get("LastFileSavePath", ""); } return QString(); } - void setLastFileSavePath(const QString& path) const + void SetLastFileSavePath(const QString& path) const { berry::IPreferences::Pointer prefs = GetPreferences(); - if(prefs.IsNotNull()) + if (prefs.IsNotNull()) { prefs->Put("LastFileSavePath", path); prefs->Flush(); } } - void setEnabled(berry::ISelection::ConstPointer selection) + void SetEnabled(berry::ISelection::ConstPointer selection) { mitk::DataNodeSelection::ConstPointer nodeSelection = selection.Cast(); if (nodeSelection.IsNotNull() && !selection->IsEmpty()) { bool enable = false; std::list dataNodes = nodeSelection->GetSelectedDataNodes(); - for (std::list::const_iterator nodeIter = dataNodes.begin(), - nodeIterEnd = dataNodes.end(); nodeIter != nodeIterEnd; ++nodeIter) + for (std::list::const_iterator nodeIter = dataNodes.begin(), nodeIterEnd = dataNodes.end(); nodeIter != nodeIterEnd; ++nodeIter) { if ((*nodeIter)->GetData() != nullptr) { enable = true; break; } } m_Action->setEnabled(enable); } else { m_Action->setEnabled(false); } } berry::IWorkbenchWindow::WeakPtr m_Window; QAction* m_Action; }; QmitkFileSaveAction::QmitkFileSaveAction(berry::IWorkbenchWindow::Pointer window) - : QAction(nullptr), d(new QmitkFileSaveActionPrivate) + : QAction(tr("Save...")) + , d(new QmitkFileSaveActionPrivate) { - d->init(window.GetPointer(), this); + d->Init(window.GetPointer(), this); } -QmitkFileSaveAction::QmitkFileSaveAction(const QIcon & icon, berry::IWorkbenchWindow::Pointer window) - : QAction(nullptr), d(new QmitkFileSaveActionPrivate) +QmitkFileSaveAction::QmitkFileSaveAction(const QIcon& icon, berry::IWorkbenchWindow::Pointer window) + : QAction(tr("Save...")) + , d(new QmitkFileSaveActionPrivate) { - d->init(window.GetPointer(), this); - this->setIcon(icon); + d->Init(window.GetPointer(), this); + setIcon(icon); } QmitkFileSaveAction::QmitkFileSaveAction(const QIcon& icon, berry::IWorkbenchWindow* window) - : QAction(nullptr), d(new QmitkFileSaveActionPrivate) + : QAction(tr("Save...")) + , d(new QmitkFileSaveActionPrivate) { - d->init(window, this); - this->setIcon(icon); + d->Init(window, this); + setIcon(icon); } QmitkFileSaveAction::~QmitkFileSaveAction() { } void QmitkFileSaveAction::Run() { - // Get the list of selected base data objects + // get the list of selected base data objects mitk::DataNodeSelection::ConstPointer selection = d->m_Window.Lock()->GetSelectionService()->GetSelection().Cast(); if (selection.IsNull() || selection->IsEmpty()) { MITK_ERROR << "Assertion failed: data node selection is nullptr or empty"; return; } std::list dataNodes = selection->GetSelectedDataNodes(); std::vector data; QStringList names; - for (std::list::const_iterator nodeIter = dataNodes.begin(), - nodeIterEnd = dataNodes.end(); nodeIter != nodeIterEnd; ++nodeIter) + for (std::list::const_iterator nodeIter = dataNodes.begin(), nodeIterEnd = dataNodes.end(); nodeIter != nodeIterEnd; ++nodeIter) { data.push_back((*nodeIter)->GetData()); std::string name; (*nodeIter)->GetStringProperty("name", name); names.push_back(QString::fromStdString(name)); } try { - QStringList fileNames = QmitkIOUtil::Save(data, names, d->getLastFileSavePath(), - d->m_Action->parentWidget()); + QStringList fileNames = QmitkIOUtil::Save(data, names, d->GetLastFileSavePath(), d->m_Action->parentWidget()); if (!fileNames.empty()) { - d->setLastFileSavePath(QFileInfo(fileNames.back()).absolutePath()); + d->SetLastFileSavePath(QFileInfo(fileNames.back()).absolutePath()); } } catch (const mitk::Exception& e) { MITK_INFO << e; return; } } diff --git a/Plugins/org.mitk.gui.qt.application/src/QmitkFileSaveAction.h b/Plugins/org.mitk.gui.qt.application/src/QmitkFileSaveAction.h index e6c5e0deb4..069afbdc42 100644 --- a/Plugins/org.mitk.gui.qt.application/src/QmitkFileSaveAction.h +++ b/Plugins/org.mitk.gui.qt.application/src/QmitkFileSaveAction.h @@ -1,56 +1,53 @@ /*=================================================================== 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 QMITKFILESAVEACTION_H_ #define QMITKFILESAVEACTION_H_ -#include -#include +#include #include -#include - -#include +// qt +#include +#include class QmitkFileSaveActionPrivate; -/** - * \ingroup org_mitk_gui_qt_application - */ class MITK_QT_APP QmitkFileSaveAction : public QAction { Q_OBJECT public: + QmitkFileSaveAction(berry::IWorkbenchWindow::Pointer window); - QmitkFileSaveAction(const QIcon & icon, berry::IWorkbenchWindow::Pointer window); - QmitkFileSaveAction(const QIcon & icon, berry::IWorkbenchWindow* window); + QmitkFileSaveAction(const QIcon& icon, berry::IWorkbenchWindow::Pointer window); + QmitkFileSaveAction(const QIcon& icon, berry::IWorkbenchWindow* window); - ~QmitkFileSaveAction() override; + virtual ~QmitkFileSaveAction() override; protected slots: virtual void Run(); private: const QScopedPointer d; }; #endif /*QMITKFILESAVEACTION_H_*/ diff --git a/Plugins/org.mitk.gui.qt.application/src/internal/QmitkGeneralPreferencePage.cpp b/Plugins/org.mitk.gui.qt.application/src/internal/QmitkGeneralPreferencePage.cpp index 0e6057f917..02afc531fd 100644 --- a/Plugins/org.mitk.gui.qt.application/src/internal/QmitkGeneralPreferencePage.cpp +++ b/Plugins/org.mitk.gui.qt.application/src/internal/QmitkGeneralPreferencePage.cpp @@ -1,66 +1,78 @@ /*=================================================================== 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 "QmitkGeneralPreferencePage.h" -#include +#include "QmitkDataNodeGlobalReinitAction.h" -#include -#include #include -#include -#include +#include + +#include +#include QmitkGeneralPreferencePage::QmitkGeneralPreferencePage() -: m_MainControl(nullptr) + : m_MainControl(nullptr) { - + // nothing here } -void QmitkGeneralPreferencePage::Init(berry::IWorkbench::Pointer ) +void QmitkGeneralPreferencePage::Init(berry::IWorkbench::Pointer) { + // nothing here } void QmitkGeneralPreferencePage::CreateQtControl(QWidget* parent) { - //empty page + berry::IPreferencesService* prefService = berry::Platform::GetPreferencesService(); + m_GeneralPreferencesNode = prefService->GetSystemPreferences()->Node(QmitkDataNodeGlobalReinitAction::ACTION_ID); + m_MainControl = new QWidget(parent); - auto layout = new QVBoxLayout; - layout->addStretch(); - m_MainControl->setLayout(layout); + m_GlobalReinitOnNodeDelete = new QCheckBox; + m_GlobalReinitOnNodeVisibilityChanged = new QCheckBox; + + auto formLayout = new QFormLayout; + formLayout->addRow("&Call global reinit if node is deleted", m_GlobalReinitOnNodeDelete); + formLayout->addRow("&Call global reinit if node visibility is changed", m_GlobalReinitOnNodeVisibilityChanged); - this->Update(); + m_MainControl->setLayout(formLayout); + Update(); } QWidget* QmitkGeneralPreferencePage::GetQtControl() const { return m_MainControl; } bool QmitkGeneralPreferencePage::PerformOk() { + m_GeneralPreferencesNode->PutBool("Call global reinit if node is deleted", m_GlobalReinitOnNodeDelete->isChecked()); + m_GeneralPreferencesNode->PutBool("Call global reinit if node visibility is changed", m_GlobalReinitOnNodeVisibilityChanged->isChecked()); + return true; } void QmitkGeneralPreferencePage::PerformCancel() { - + // nothing here } void QmitkGeneralPreferencePage::Update() { + m_GlobalReinitOnNodeDelete->setChecked(m_GeneralPreferencesNode->GetBool("Call global reinit if node is deleted", true)); + m_GlobalReinitOnNodeVisibilityChanged->setChecked(m_GeneralPreferencesNode->GetBool("Call global reinit if node visibility is changed", false)); } diff --git a/Plugins/org.mitk.gui.qt.application/src/internal/QmitkGeneralPreferencePage.h b/Plugins/org.mitk.gui.qt.application/src/internal/QmitkGeneralPreferencePage.h index 8f3c289dcc..31882e5f01 100644 --- a/Plugins/org.mitk.gui.qt.application/src/internal/QmitkGeneralPreferencePage.h +++ b/Plugins/org.mitk.gui.qt.application/src/internal/QmitkGeneralPreferencePage.h @@ -1,75 +1,75 @@ /*=================================================================== 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 QMITKGENERALPREFERENCEPAGE_H_ -#define QMITKGENERALPREFERENCEPAGE_H_ +#ifndef QMITKGENERALPREFERENCEPAGE_H +#define QMITKGENERALPREFERENCEPAGE_H #include "berryIQtPreferencePage.h" #include class QWidget; class QCheckBox; class QmitkGeneralPreferencePage : public QObject, public berry::IQtPreferencePage { Q_OBJECT Q_INTERFACES(berry::IPreferencePage) public: - /** - * Default constructor - */ QmitkGeneralPreferencePage(); /** * @see berry::IPreferencePage::Init(berry::IWorkbench::Pointer workbench) */ void Init(berry::IWorkbench::Pointer workbench) override; /** * @see berry::IPreferencePage::CreateQtControl(void* parent) */ void CreateQtControl(QWidget* widget) override; /** * @see berry::IPreferencePage::CreateQtControl() */ QWidget* GetQtControl() const override; /** * @see berry::IPreferencePage::PerformOk() */ bool PerformOk() override; /** * @see berry::IPreferencePage::PerformCancel() */ void PerformCancel() override; /** * @see berry::IPreferencePage::Update() */ void Update() override; protected: QWidget* m_MainControl; + QCheckBox* m_GlobalReinitOnNodeDelete; + QCheckBox* m_GlobalReinitOnNodeVisibilityChanged; + + berry::IPreferences::Pointer m_GeneralPreferencesNode; }; -#endif /* QMITKGENERALPREFERENCEPAGE_H_ */ +#endif // QMITKGENERALPREFERENCEPAGE_H diff --git a/Plugins/org.mitk.gui.qt.application/src/internal/QmitkInfoDialog.cpp b/Plugins/org.mitk.gui.qt.application/src/internal/QmitkInfoDialog.cpp new file mode 100644 index 0000000000..11a8efc17d --- /dev/null +++ b/Plugins/org.mitk.gui.qt.application/src/internal/QmitkInfoDialog.cpp @@ -0,0 +1,127 @@ +/*=================================================================== + +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 "QmitkInfoDialog.h" + +#include "QmitkDataStorageComboBox.h" + +#include + +#include +#include +#include +#include +#include +#include + +QmitkInfoDialog::QmitkInfoDialog(const QList& nodes, QWidget* parent /*= nullptr*/, Qt::WindowFlags flags /*= nullptr */) + : QDialog(parent, flags) +{ + auto parentLayout = new QGridLayout; + auto dataStorageComboBox = new QmitkDataStorageComboBox(this, true); + m_KeyWord = new QLineEdit; + m_KeyWord->installEventFilter(this); + m_SearchButton = new QPushButton("Search (F3)", this); + m_SearchButton->installEventFilter(this); + m_TextBrowser = new QTextBrowser(this); + QPushButton* cancelButton = new QPushButton("Cancel", this); + + setMinimumSize(512, 512); + setLayout(parentLayout); + setSizeGripEnabled(true); + setModal(true); + + parentLayout->addWidget(dataStorageComboBox, 0, 0, 1, 2); + parentLayout->addWidget(m_KeyWord, 1, 0); + parentLayout->addWidget(m_SearchButton, 1, 1); + parentLayout->addWidget(m_TextBrowser, 2, 0, 1, 2); + parentLayout->addWidget(cancelButton, 3, 0, 1, 2); + + connect(dataStorageComboBox, &QmitkDataStorageComboBox::OnSelectionChanged, this, &QmitkInfoDialog::OnSelectionChanged); + + for(auto& node : nodes) + { + dataStorageComboBox->AddNode(node); + } + + connect(m_KeyWord, &QLineEdit::textChanged, this, &QmitkInfoDialog::KeyWordTextChanged); + connect(m_SearchButton, &QPushButton::clicked, this, &QmitkInfoDialog::OnSearchButtonClicked); + connect(cancelButton, &QPushButton::clicked, this, &QmitkInfoDialog::OnCancelButtonClicked); + + cancelButton->setDefault(true); +} + +void QmitkInfoDialog::OnSelectionChanged(const mitk::DataNode* node) +{ + if (nullptr == node) + { + return; + } + + std::ostringstream s; + itk::Indent i(2); + mitk::BaseData* baseData = node->GetData(); + if (nullptr != baseData) + { + baseData->Print(s, i); + } + + m_TextBrowser->setPlainText(QString::fromStdString(s.str())); +} + +void QmitkInfoDialog::OnSearchButtonClicked(bool /*checked*/ /*= false */) +{ + QString keyWord = m_KeyWord->text(); + QString text = m_TextBrowser->toPlainText(); + + if (keyWord.isEmpty() || text.isEmpty()) + { + return; + } + + m_TextBrowser->find(keyWord); + m_SearchButton->setText("Search Next(F3)"); +} + +void QmitkInfoDialog::OnCancelButtonClicked(bool /*checked*/ /*= false */) +{ + done(0); +} + +bool QmitkInfoDialog::eventFilter(QObject* obj, QEvent* event) +{ + if (event->type() == QEvent::KeyPress) + { + QKeyEvent *keyEvent = static_cast(event); + if (keyEvent->key() == Qt::Key_F3 || keyEvent->key() == Qt::Key_Return) + { + // trigger deletion of selected node(s) + OnSearchButtonClicked(true); + // return true: this means the delete key event is not send to the table + return true; + } + } + // standard event processing + return QObject::eventFilter(obj, event); +} + +void QmitkInfoDialog::KeyWordTextChanged(const QString& /*text*/) +{ + QTextCursor textCursor = m_TextBrowser->textCursor(); + textCursor.setPosition(0); + m_TextBrowser->setTextCursor(textCursor); + m_SearchButton->setText("Search (F3)"); +} diff --git a/Plugins/org.mitk.gui.qt.application/src/internal/QmitkInfoDialog.h b/Plugins/org.mitk.gui.qt.application/src/internal/QmitkInfoDialog.h new file mode 100644 index 0000000000..f5cdd17572 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.application/src/internal/QmitkInfoDialog.h @@ -0,0 +1,54 @@ +/*=================================================================== + +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 QMITKINFODIALOG_H +#define QMITKINFODIALOG_H + +#include + +#include + +class QLineEdit; +class QTextBrowser; + +class QmitkInfoDialog : public QDialog +{ + Q_OBJECT + +public: + + QmitkInfoDialog(const QList& nodes, QWidget* parent = nullptr, Qt::WindowFlags flags = nullptr); + +public Q_SLOTS: + + void OnSelectionChanged(const mitk::DataNode*); + void OnSearchButtonClicked(bool checked = false); + void OnCancelButtonClicked(bool checked = false); + void KeyWordTextChanged(const QString& text); + +protected: + + bool eventFilter(QObject* obj, QEvent* event) override; + +protected: + + QLineEdit* m_KeyWord; + QPushButton* m_SearchButton; + QTextBrowser* m_TextBrowser; + +}; + +#endif // QMITKINFODIALOG_H diff --git a/Plugins/org.mitk.gui.qt.datamanager/src/mitkIContextMenuAction.h b/Plugins/org.mitk.gui.qt.application/src/mitkIContextMenuAction.h similarity index 89% rename from Plugins/org.mitk.gui.qt.datamanager/src/mitkIContextMenuAction.h rename to Plugins/org.mitk.gui.qt.application/src/mitkIContextMenuAction.h index fa3dabbc5c..18133dcdd5 100644 --- a/Plugins/org.mitk.gui.qt.datamanager/src/mitkIContextMenuAction.h +++ b/Plugins/org.mitk.gui.qt.application/src/mitkIContextMenuAction.h @@ -1,53 +1,53 @@ /*=================================================================== 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 mitkIContextMenuAction_H_ #define mitkIContextMenuAction_H_ #include #include #include #include #include "mitkDataStorage.h" namespace mitk { /** * A context menu action, which is linked to the context menu
* through an extension point. For an example check the
* plugin.xml and the connected classes of
* the the segmentation bundle and also the QmitkDataManagerView.cpp
* in this bundle. */ struct IContextMenuAction { - /** - * @brief Executes the action, that linked to the context menu entry. - */ - virtual void Run( const QList& selectedNodes ) = 0; + /** + * @brief Executes the action, that linked to the context menu entry. + */ + virtual void Run(const QList& selectedNodes) = 0; // Setters virtual void SetDataStorage(mitk::DataStorage* dataStorage) = 0; virtual void SetSmoothed(bool smoothed) = 0; virtual void SetDecimated(bool decimated) = 0; virtual void SetFunctionality(berry::QtViewPart* functionality) = 0; }; } Q_DECLARE_INTERFACE(mitk::IContextMenuAction, "org.mitk.datamanager.IContextMenuAction") #endif // mitkIContextMenuAction_H_ diff --git a/Plugins/org.mitk.gui.qt.common/src/QmitkAbstractView.cpp b/Plugins/org.mitk.gui.qt.common/src/QmitkAbstractView.cpp index 33c8bf4dd2..fc92092b26 100644 --- a/Plugins/org.mitk.gui.qt.common/src/QmitkAbstractView.cpp +++ b/Plugins/org.mitk.gui.qt.common/src/QmitkAbstractView.cpp @@ -1,602 +1,526 @@ /*=================================================================== 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 "QmitkAbstractView.h" #include "QmitkDataNodeSelectionProvider.h" #include "internal/QmitkCommonActivator.h" #include "internal/QmitkDataNodeItemModel.h" // mitk Includes #include #include #include -#include #include #include // berry Includes #include #include #include #include #include // CTK Includes #include // Qt Includes #include #include #include #include #include class QmitkAbstractViewPrivate { public: QmitkAbstractViewPrivate(QmitkAbstractView* qq) : q(qq) , m_PrefServiceTracker(QmitkCommonActivator::GetContext()) , m_DataStorageServiceTracker(QmitkCommonActivator::GetContext()) , m_Parent(nullptr) , m_DataNodeItemModel(new QmitkDataNodeItemModel) , m_DataNodeSelectionModel(new QItemSelectionModel(m_DataNodeItemModel)) , m_InDataStorageChanged(false) { m_PrefServiceTracker.open(); m_DataStorageServiceTracker.open(); } ~QmitkAbstractViewPrivate() { delete m_DataNodeSelectionModel; delete m_DataNodeItemModel; m_PrefServiceTracker.close(); m_DataStorageServiceTracker.close(); } /** * Called when a DataStorage Add Event was thrown. Sets * m_InDataStorageChanged to true and calls NodeAdded afterwards. * \see m_InDataStorageChanged */ void NodeAddedProxy(const mitk::DataNode* node) { // garantuee no recursions when a new node event is thrown in NodeAdded() if(!m_InDataStorageChanged) { m_InDataStorageChanged = true; q->NodeAdded(node); q->DataStorageModified(); m_InDataStorageChanged = false; } } /** * Called when a DataStorage remove event was thrown. Sets * m_InDataStorageChanged to true and calls NodeRemoved afterwards. * \see m_InDataStorageChanged */ void NodeRemovedProxy(const mitk::DataNode* node) { // garantuee no recursions when a new node event is thrown in NodeAdded() if(!m_InDataStorageChanged) { m_InDataStorageChanged = true; q->NodeRemoved(node); q->DataStorageModified(); m_InDataStorageChanged = false; } } /** * Called when a DataStorage changed event was thrown. Sets * m_InDataStorageChanged to true and calls NodeChanged afterwards. * \see m_InDataStorageChanged */ void NodeChangedProxy(const mitk::DataNode* node) { // garantuee no recursions when a new node event is thrown in NodeAdded() if(!m_InDataStorageChanged) { m_InDataStorageChanged = true; q->NodeChanged(node); q->DataStorageModified(); m_InDataStorageChanged = false; } } /** * reactions to selection events from views */ void BlueBerrySelectionChanged(const berry::IWorkbenchPart::Pointer& sourcepart, const berry::ISelection::ConstPointer& selection) { if(sourcepart.IsNull() || sourcepart.GetPointer() == static_cast(q)) return; if(selection.IsNull()) { q->OnNullSelection(sourcepart); return; } mitk::DataNodeSelection::ConstPointer _DataNodeSelection = selection.Cast(); q->OnSelectionChanged(sourcepart, this->DataNodeSelectionToQList(_DataNodeSelection)); } /** * Converts a mitk::DataNodeSelection to a QList (possibly empty) */ QList DataNodeSelectionToQList(mitk::DataNodeSelection::ConstPointer currentSelection) const; QmitkAbstractView* const q; ctkServiceTracker m_PrefServiceTracker; ctkServiceTracker m_DataStorageServiceTracker; /** * Saves the parent of this view (this is the scrollarea created in CreatePartControl(QWidget*) * \see CreatePartControl(QWidget*) */ QWidget* m_Parent; /** * Holds the current selection (selection made by this View !!!) */ QmitkDataNodeSelectionProvider::Pointer m_SelectionProvider; /** * Holds a helper model for firing selection events. */ QmitkDataNodeItemModel* m_DataNodeItemModel; /** * The selection model for the QmitkDataNodeItemModel; */ QItemSelectionModel* m_DataNodeSelectionModel; /** * object to observe BlueBerry selections */ QScopedPointer m_BlueBerrySelectionListener; /** * Saves if this class is currently working on DataStorage changes. * This is a protector variable to avoid recursive calls on event listener functions. */ bool m_InDataStorageChanged; }; QmitkAbstractView::QmitkAbstractView() : d(new QmitkAbstractViewPrivate(this)) { } void QmitkAbstractView::CreatePartControl(QWidget* parent) { // scrollArea auto scrollArea = new QScrollArea; //QVBoxLayout* scrollAreaLayout = new QVBoxLayout(scrollArea); scrollArea->setFrameShadow(QFrame::Plain); scrollArea->setFrameShape(QFrame::NoFrame); scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); // m_Parent d->m_Parent = new QWidget; //m_Parent->setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding)); this->CreateQtPartControl(d->m_Parent); //scrollAreaLayout->addWidget(m_Parent); //scrollArea->setLayout(scrollAreaLayout); // set the widget now scrollArea->setWidgetResizable(true); scrollArea->setWidget(d->m_Parent); // add the scroll area to the real parent (the view tabbar) QWidget* parentQWidget = static_cast(parent); auto parentLayout = new QVBoxLayout(parentQWidget); parentLayout->setMargin(0); parentLayout->setSpacing(0); parentLayout->addWidget(scrollArea); // finally set the layout containing the scroll area to the parent widget (= show it) parentQWidget->setLayout(parentLayout); this->AfterCreateQtPartControl(); } void QmitkAbstractView::AfterCreateQtPartControl() { this->SetSelectionProvider(); // REGISTER DATASTORAGE LISTENER this->GetDataStorage()->AddNodeEvent.AddListener( mitk::MessageDelegate1 ( d.data(), &QmitkAbstractViewPrivate::NodeAddedProxy ) ); this->GetDataStorage()->ChangedNodeEvent.AddListener( mitk::MessageDelegate1 ( d.data(), &QmitkAbstractViewPrivate::NodeChangedProxy ) ); this->GetDataStorage()->RemoveNodeEvent.AddListener( mitk::MessageDelegate1 ( d.data(), &QmitkAbstractViewPrivate::NodeRemovedProxy ) ); // REGISTER PREFERENCES LISTENER berry::IBerryPreferences::Pointer prefs = this->GetPreferences().Cast(); if(prefs.IsNotNull()) prefs->OnChanged.AddListener( berry::MessageDelegate1(this, &QmitkAbstractView::OnPreferencesChanged)); // REGISTER FOR WORKBENCH SELECTION EVENTS d->m_BlueBerrySelectionListener.reset(new berry::NullSelectionChangedAdapter( d.data(), &QmitkAbstractViewPrivate::BlueBerrySelectionChanged)); this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->AddPostSelectionListener(d->m_BlueBerrySelectionListener.data()); // EMULATE INITIAL SELECTION EVENTS // send the current selection berry::IWorkbenchPart::Pointer activePart = this->GetSite()->GetPage()->GetActivePart(); if (activePart.IsNotNull()) { this->OnSelectionChanged(activePart, this->GetCurrentSelection()); } // send preferences changed event this->OnPreferencesChanged(this->GetPreferences().Cast().GetPointer()); } QmitkAbstractView::~QmitkAbstractView() { this->Register(); this->GetDataStorage()->AddNodeEvent.RemoveListener( mitk::MessageDelegate1 ( d.data(), &QmitkAbstractViewPrivate::NodeAddedProxy ) ); this->GetDataStorage()->RemoveNodeEvent.RemoveListener( mitk::MessageDelegate1 ( d.data(), &QmitkAbstractViewPrivate::NodeRemovedProxy) ); this->GetDataStorage()->ChangedNodeEvent.RemoveListener( mitk::MessageDelegate1 ( d.data(), &QmitkAbstractViewPrivate::NodeChangedProxy ) ); berry::IBerryPreferences::Pointer prefs = this->GetPreferences().Cast(); if(prefs.IsNotNull()) { prefs->OnChanged.RemoveListener( berry::MessageDelegate1(this, &QmitkAbstractView::OnPreferencesChanged)); // flush the preferences here (disabled, everyone should flush them by themselves at the right moment) // prefs->Flush(); } // REMOVE SELECTION PROVIDER this->GetSite()->SetSelectionProvider(berry::ISelectionProvider::Pointer(nullptr)); berry::ISelectionService* s = GetSite()->GetWorkbenchWindow()->GetSelectionService(); if(s) { s->RemovePostSelectionListener(d->m_BlueBerrySelectionListener.data()); } this->UnRegister(false); } void QmitkAbstractView::SetSelectionProvider() { // REGISTER A SELECTION PROVIDER d->m_SelectionProvider = QmitkDataNodeSelectionProvider::Pointer(new QmitkDataNodeSelectionProvider); d->m_SelectionProvider->SetItemSelectionModel(GetDataNodeSelectionModel()); this->GetSite()->SetSelectionProvider(berry::ISelectionProvider::Pointer(d->m_SelectionProvider)); } QItemSelectionModel *QmitkAbstractView::GetDataNodeSelectionModel() const { return nullptr; } void QmitkAbstractView::OnPreferencesChanged( const berry::IBerryPreferences* ) { } void QmitkAbstractView::DataStorageModified() { } void QmitkAbstractView::DataStorageChanged(mitk::IDataStorageReference::Pointer /*dsRef*/) { } -mitk::IRenderWindowPart* QmitkAbstractView::GetRenderWindowPart( IRenderWindowPartStrategies strategies ) const +mitk::IRenderWindowPart* QmitkAbstractView::GetRenderWindowPart(mitk::WorkbenchUtil::IRenderWindowPartStrategies strategies) const { - berry::IWorkbenchPage::Pointer page = this->GetSite()->GetPage(); - - // Return the active editor if it implements mitk::IRenderWindowPart - mitk::IRenderWindowPart* renderPart = - dynamic_cast(page->GetActiveEditor().GetPointer()); - if (renderPart) return renderPart; - - // No suitable active editor found, check visible editors - QList editors = page->GetEditorReferences(); - for (QList::iterator i = editors.begin(); - i != editors.end(); ++i) - { - berry::IWorkbenchPart::Pointer part = (*i)->GetPart(false); - if (page->IsPartVisible(part)) - { - renderPart = dynamic_cast(part.GetPointer()); - if (renderPart) return renderPart; - } - } - - // No suitable visible editor found, check visible views - QList views = page->GetViewReferences(); - for(QList::iterator i = views.begin(); - i != views.end(); ++i) - { - berry::IWorkbenchPart::Pointer part = (*i)->GetPart(false); - if (page->IsPartVisible(part)) - { - renderPart = dynamic_cast(part.GetPointer()); - if (renderPart) return renderPart; - } - } - - // No strategies given - if (strategies == NONE) return nullptr; - - mitk::DataStorageEditorInput::Pointer input(new mitk::DataStorageEditorInput(GetDataStorageReference())); - - bool activate = false; - if(strategies & ACTIVATE) - { - activate = true; - } - - berry::IEditorPart::Pointer editorPart; - - if(strategies & OPEN) - { - // This will create a default editor for the given input. If an editor - // with that input is already open, the editor is brought to the front. - try - { - editorPart = mitk::WorkbenchUtil::OpenEditor(page, input, activate); - } - catch (const berry::PartInitException&) - { - // There is no editor registered which can handle the given input. - } - } - else if (activate || (strategies & BRING_TO_FRONT)) - { - // check if a suitable editor is already opened - editorPart = page->FindEditor(input); - if (editorPart) - { - if (activate) - { - page->Activate(editorPart); - } - else - { - page->BringToTop(editorPart); - } - } - } - - return dynamic_cast(editorPart.GetPointer()); + berry::IWorkbenchPage::Pointer page = GetSite()->GetPage(); + return mitk::WorkbenchUtil::GetRenderWindowPart(page, strategies); } void QmitkAbstractView::RequestRenderWindowUpdate(mitk::RenderingManager::RequestType requestType) { mitk::IRenderWindowPart* renderPart = this->GetRenderWindowPart(); if (renderPart == nullptr) return; if (mitk::IRenderingManager* renderingManager = renderPart->GetRenderingManager()) { renderingManager->RequestUpdateAll(requestType); } else { renderPart->RequestUpdate(requestType); } } void QmitkAbstractView::HandleException( const char* str, QWidget* parent, bool showDialog ) const { //itkGenericOutputMacro( << "Exception caught: " << str ); MITK_ERROR << str; if ( showDialog ) { QMessageBox::critical ( parent, "Exception caught!", str ); } } void QmitkAbstractView::HandleException( std::exception& e, QWidget* parent, bool showDialog ) const { HandleException( e.what(), parent, showDialog ); } void QmitkAbstractView::WaitCursorOn() { QApplication::setOverrideCursor( QCursor(Qt::WaitCursor) ); } void QmitkAbstractView::BusyCursorOn() { QApplication::setOverrideCursor( QCursor(Qt::BusyCursor) ); } void QmitkAbstractView::WaitCursorOff() { this->RestoreOverrideCursor(); } void QmitkAbstractView::BusyCursorOff() { this->RestoreOverrideCursor(); } void QmitkAbstractView::RestoreOverrideCursor() { QApplication::restoreOverrideCursor(); } berry::IPreferences::Pointer QmitkAbstractView::GetPreferences() const { berry::IPreferencesService* prefService = d->m_PrefServiceTracker.getService(); // const_cast workaround for bad programming: const uncorrectness this->GetViewSite() should be const QString id = "/" + (const_cast(this))->GetViewSite()->GetId(); return prefService ? prefService->GetSystemPreferences()->Node(id): berry::IPreferences::Pointer(nullptr); } mitk::DataStorage::Pointer QmitkAbstractView::GetDataStorage() const { mitk::IDataStorageService* dsService = d->m_DataStorageServiceTracker.getService(); if (dsService != nullptr) { return dsService->GetDataStorage()->GetDataStorage(); } return nullptr; } mitk::IDataStorageReference::Pointer QmitkAbstractView::GetDataStorageReference() const { mitk::IDataStorageService* dsService = d->m_DataStorageServiceTracker.getService(); if (dsService != nullptr) { return dsService->GetDataStorage(); } return mitk::IDataStorageReference::Pointer(nullptr); } QList QmitkAbstractView::GetCurrentSelection() const { berry::ISelection::ConstPointer selection( this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->GetSelection()); mitk::DataNodeSelection::ConstPointer currentSelection = selection.Cast(); return d->DataNodeSelectionToQList(currentSelection); } bool QmitkAbstractView::IsCurrentSelectionValid() const { return this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->GetSelection(); } QList QmitkAbstractView::GetDataManagerSelection() const { berry::ISelection::ConstPointer selection( this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->GetSelection("org.mitk.views.datamanager")); mitk::DataNodeSelection::ConstPointer currentSelection = selection.Cast(); return d->DataNodeSelectionToQList(currentSelection); } bool QmitkAbstractView::IsDataManagerSelectionValid() const { return this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->GetSelection("org.mitk.views.datamanager"); } void QmitkAbstractView::SetDataManagerSelection(const berry::ISelection::ConstPointer &selection, QItemSelectionModel::SelectionFlags flags) const { berry::IViewPart::Pointer datamanagerView = this->GetSite()->GetWorkbenchWindow()->GetActivePage()->FindView("org.mitk.views.datamanager"); if (datamanagerView.IsNull()) return; datamanagerView->GetSite()->GetSelectionProvider().Cast()->SetSelection(selection, flags); } void QmitkAbstractView::SynchronizeDataManagerSelection() const { berry::ISelection::ConstPointer currentSelection = this->GetSite()->GetSelectionProvider()->GetSelection(); if (currentSelection.IsNull()) return; SetDataManagerSelection(currentSelection); } void QmitkAbstractView::OnSelectionChanged(berry::IWorkbenchPart::Pointer /*part*/, const QList& /*nodes*/) { } void QmitkAbstractView::OnNullSelection(berry::IWorkbenchPart::Pointer /*part*/) { } QList QmitkAbstractViewPrivate::DataNodeSelectionToQList(mitk::DataNodeSelection::ConstPointer currentSelection) const { if (currentSelection.IsNull()) return QList(); return QList::fromStdList(currentSelection->GetSelectedDataNodes()); } void QmitkAbstractView::NodeAdded( const mitk::DataNode* /*node*/ ) { } void QmitkAbstractView::NodeRemoved( const mitk::DataNode* /*node*/ ) { } void QmitkAbstractView::NodeChanged( const mitk::DataNode* /*node*/ ) { } void QmitkAbstractView::FireNodeSelected( mitk::DataNode::Pointer node ) { QList nodes; nodes << node; this->FireNodesSelected(nodes); } void QmitkAbstractView::FireNodesSelected( const QList& nodes ) { // if this is the first call to FireNodesSelected and the selection provider has no QItemSelectiomMode // yet, set our helper model if (d->m_SelectionProvider->GetItemSelectionModel() == nullptr) { d->m_SelectionProvider->SetItemSelectionModel(d->m_DataNodeSelectionModel); } else if (d->m_SelectionProvider->GetItemSelectionModel() != d->m_DataNodeSelectionModel) { MITK_WARN << "A custom data node selection model has been set. Ignoring call to FireNodesSelected()."; return; } if (nodes.empty()) { d->m_DataNodeSelectionModel->clearSelection(); d->m_DataNodeItemModel->clear(); } else { // The helper data node model is just used for sending selection events. // We add the to be selected nodes and set the selection range to everything. d->m_DataNodeItemModel->clear(); foreach(mitk::DataNode::Pointer node, nodes) { d->m_DataNodeItemModel->AddDataNode(node); } d->m_DataNodeSelectionModel->select(QItemSelection(d->m_DataNodeItemModel->index(0,0), d->m_DataNodeItemModel->index(nodes.size()-1, 0)), QItemSelectionModel::ClearAndSelect); } } diff --git a/Plugins/org.mitk.gui.qt.common/src/QmitkAbstractView.h b/Plugins/org.mitk.gui.qt.common/src/QmitkAbstractView.h index d92f6560ad..75fff11011 100644 --- a/Plugins/org.mitk.gui.qt.common/src/QmitkAbstractView.h +++ b/Plugins/org.mitk.gui.qt.common/src/QmitkAbstractView.h @@ -1,384 +1,366 @@ /*=================================================================== 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 QMITKABSTRACTVIEW_H_ #define QMITKABSTRACTVIEW_H_ //# blueberry stuff #include #include #include #include //# mitk stuff #include #include "mitkDataNodeSelection.h" #include "mitkIRenderWindowPart.h" +#include + #include #include #include #include namespace mitk { class DataNode; } namespace berry { struct IBerryPreferences; } class QmitkAbstractViewPrivate; class QmitkAbstractViewSelectionProvider; /** * \ingroup org_mitk_gui_qt_common * * \brief A convenient base class for MITK related BlueBerry Views. * * QmitkAbstractView provides several convenience methods that ease the introduction of a new view: * *
    *
  1. Access to the DataStorage (~ the shared data repository) *
  2. Access to the active IRenderWindowPart *
  3. Access to and update notification for the view's preferences *
  4. Access to and update notification for the current DataNode selection / to DataNode selection events send through the SelectionService *
  5. Access to and update notification for DataNode events (added/removed/modified) *
  6. Methods to send DataNode selections through the SelectionService *
  7. Some minor important convenience methods (like changing the mouse cursor/exception handling) *
* * Usually all MITK Views inherit from QmitkAbstractView to achieve a consistent Workbench behavior. * * When inheriting from QmitkAbstractView, you must implement the following methods: *
    *
  • void CreateQtPartControl(QWidget* parent) *
  • void SetFocus() *
* * You may reimplement the following private virtual methods to customize your View's behavior: *
    *
  • void SetSelectionProvider() *
  • QItemSelectionModel* GetDataNodeSelectionModel() const *
* * You may reimplement the following private virtual methods to be notified about certain changes: *
    *
  • void OnSelectionChanged(berry::IWorkbenchPart::Pointer part, const QList &nodes) *
  • void OnNullSelection(berry::IWorkbenchPart::Pointer part) *
  • void OnPreferencesChanged(const berry::IBerryPreferences*) *
  • void NodeAdded(const mitk::DataNode* node) *
  • void NodeChanged(const mitk::DataNode* node) *
  • void NodeRemoved(const mitk::DataNode* node) *
  • void DataStorageModified() *
  • void DataStorageChanged(mitk::IDataStorageReference::Pointer dsRef) *
* * \see mitk::ILifecycleAwarePart * \see mitk::IZombieViewPart * \see mitk::IRenderWindowPartListener */ class MITK_QT_COMMON QmitkAbstractView : public berry::QtViewPart { public: - /** - * Describes the strategies to be used for getting a mitk::IRenderWindowPart - * instance. - */ - enum IRenderWindowPartStrategy { - - /** Do nothing. */ - NONE = 0x00000000, - /** Bring the most recently activated mitk::IRenderWindowPart instance to the front. */ - BRING_TO_FRONT = 0x00000001, - /** Activate a mitk::IRenderWindowPart part (implies bringing it to the front). */ - ACTIVATE = 0x00000002, - /** Create a mitk::IRenderWindowPart if none is alredy opened. */ - OPEN = 0x00000004 - }; - - Q_DECLARE_FLAGS(IRenderWindowPartStrategies, IRenderWindowPartStrategy) - /** * Creates smartpointer typedefs */ berryObjectMacro(QmitkAbstractView); /** * Nothing to do in the standard ctor. Initiliaze your GUI in CreateQtPartControl(QWidget*) * \see berry::QtViewPart::CreateQtPartControl(QWidget*) */ QmitkAbstractView(); /** * Disconnects all standard event listeners */ ~QmitkAbstractView() override; protected: /** * Informs other parts of the workbench that node is selected via the blueberry selection service. * * \note This method should not be used if you have set your own selection provider via * SetSelectionProvider() or your own QItemSelectionModel via GetDataNodeSelectionModel(). */ void FireNodeSelected(mitk::DataNode::Pointer node); /** * Informs other parts of the workbench that the nodes are selected via the blueberry selection service. * * \note This method should not be used if you have set your own selection provider via * SetSelectionProvider() or your own QItemSelectionModel via GetDataNodeSelectionModel(). */ virtual void FireNodesSelected(const QList& nodes); /** * \return The selection of the currently active part of the workbench or an empty list * if there is no selection or if it is empty. * * \see IsCurrentSelectionValid */ QList GetCurrentSelection() const; /** * Queries the state of the current selection. * * \return If the current selection is nullptr, this method returns * false and true otherwise. */ bool IsCurrentSelectionValid() const; /** * Returns the current selection made in the datamanager bundle or an empty list * if there is no selection or if it is empty. * * \see IsDataManagerSelectionValid */ QList GetDataManagerSelection() const; /** * Queries the state of the current selection of the data manager view. * * \return If the current data manager selection is nullptr, this method returns * false and true otherwise. */ bool IsDataManagerSelectionValid() const; /** * Sets the selection of the data manager view if available. * * \param selection The new selection for the data manager. * \param flags The Qt selection flags for controlling the way how the selection is updated. */ void SetDataManagerSelection(const berry::ISelection::ConstPointer& selection, QItemSelectionModel::SelectionFlags flags = QItemSelectionModel::ClearAndSelect) const; /** * Takes the current selection and sets it on the data manager. Only matching nodes in the * data manager view will be selected. */ void SynchronizeDataManagerSelection() const; /** * Returns the Preferences object for this View. * Important: When refering to this preferences, e.g. in a PreferencePage: The ID * for this preferences object is "/", e.g. "/org.mitk.views.datamanager" */ berry::IPreferences::Pointer GetPreferences() const; /** * Returns a reference to the currently active DataStorage. */ mitk::IDataStorageReference::Pointer GetDataStorageReference() const; /** * Returns the currently active DataStorage. */ mitk::DataStorage::Pointer GetDataStorage() const; /** * Returns the currently active mitk::IRenderWindowPart. * * \param strategies Strategies for returning a mitk::IRenderWindowPart instance if there * is currently no active one. * \return The active mitk::IRenderWindowPart. */ - mitk::IRenderWindowPart* GetRenderWindowPart(IRenderWindowPartStrategies strategies = NONE) const; + mitk::IRenderWindowPart* GetRenderWindowPart(mitk::WorkbenchUtil::IRenderWindowPartStrategies strategies = mitk::WorkbenchUtil::NONE) const; /** * Request an update of all render windows of the currently active IRenderWindowPart. * * \param requestType Specifies the type of render windows for which an update * will be requested. */ void RequestRenderWindowUpdate(mitk::RenderingManager::RequestType requestType = mitk::RenderingManager::REQUEST_UPDATE_ALL); /** * Outputs an error message to the console and displays a message box containing * the exception description. * \param e the exception which should be handled * \param showDialog controls, whether additionally a message box should be * displayed to inform the user that something went wrong */ void HandleException( std::exception& e, QWidget* parent = nullptr, bool showDialog = true ) const; /** * Calls HandleException ( std::exception&, QWidget*, bool ) internally * \see HandleException ( std::exception&, QWidget*, bool ) */ void HandleException( const char* str, QWidget* parent = nullptr, bool showDialog = true ) const; /** * Convenient method to set and reset a wait cursor ("hourglass") */ void WaitCursorOn(); /** * Convenient method to restore the standard cursor */ void WaitCursorOff(); /** * Convenient method to set and reset a busy cursor */ void BusyCursorOn(); /** * Convenient method to restore the standard cursor */ void BusyCursorOff(); /** * Convenient method to restore the standard cursor */ void RestoreOverrideCursor(); private: /** * Reimplement this method to set a custom selection provider. This method is * called once after CreateQtPartControl(). * * The default implementation registers a QmitkDataNodeSelectionProvider with * a QItemSelectionModel returned by GetDataNodeSelectionModel(). */ virtual void SetSelectionProvider(); /** * Reimplement this method to supply a custom Qt selection model. The custom * model will be used with the default selection provider QmitkDataNodeSelectionProvider * to inform the MITK Workbench about selection changes. * * If you reimplement this method, the methods FireNodeSelected() and FireNodesSelected() * will have no effect. Use your custom selection model to notify the MITK Workbench * about selection changes. * * The Qt item model used with the custom selection model must return mitk::DataNode::Pointer * objects for model indexes when the role is QmitkDataNodeRole. */ virtual QItemSelectionModel* GetDataNodeSelectionModel() const; /** * Called when the selection in the workbench changed. * May be reimplemented by deriving classes. * * \param part The source part responsible for the selection change. * \param nodes A list of selected nodes. * * \see OnNullSelection */ virtual void OnSelectionChanged(berry::IWorkbenchPart::Pointer part, const QList &nodes); /** * Called when a nullptr selection occurs. * * \param part The source part responsible for the selection change. */ virtual void OnNullSelection(berry::IWorkbenchPart::Pointer part); /** * Called when the preferences object of this view changed. * May be reimplemented by deriving classes. * * \see GetPreferences() */ virtual void OnPreferencesChanged(const berry::IBerryPreferences*); /** * Called when a DataStorage Add event was thrown. May be reimplemented * by deriving classes. */ virtual void NodeAdded(const mitk::DataNode* node); /** * Called when a DataStorage Changed event was thrown. May be reimplemented * by deriving classes. */ virtual void NodeChanged(const mitk::DataNode* node); /** * Called when a DataStorage Remove event was thrown. May be reimplemented * by deriving classes. */ virtual void NodeRemoved(const mitk::DataNode* node); /** * Called when a DataStorage add *or* remove *or* change event from the currently active * data storage is thrown. * * May be reimplemented by deriving classes. */ virtual void DataStorageModified(); /** * Called when the currently active DataStorage changed. * May be reimplemented by deriving classes. * * \param dsRef A reference to the new active DataStorage. */ virtual void DataStorageChanged(mitk::IDataStorageReference::Pointer dsRef); /** * Creates a scroll area for this view and calls CreateQtPartControl then */ void CreatePartControl(QWidget* parent) override; /** * Called immediately after CreateQtPartControl(). * Here standard event listeners for a QmitkAbstractView are registered */ void AfterCreateQtPartControl(); private: friend class QmitkAbstractViewPrivate; friend class QmitkViewCoordinator; Q_DISABLE_COPY(QmitkAbstractView) const QScopedPointer d; }; -Q_DECLARE_OPERATORS_FOR_FLAGS(QmitkAbstractView::IRenderWindowPartStrategies) - #endif /*QMITKABSTRACTVIEW_H_*/ diff --git a/Plugins/org.mitk.gui.qt.datamanager/files.cmake b/Plugins/org.mitk.gui.qt.datamanager/files.cmake index 6efe7d4b61..13fd4bb937 100644 --- a/Plugins/org.mitk.gui.qt.datamanager/files.cmake +++ b/Plugins/org.mitk.gui.qt.datamanager/files.cmake @@ -1,42 +1,36 @@ set(SRC_CPP_FILES berrySingleNodeSelection.cpp QmitkDataManagerView.cpp QmitkDataManagerPreferencePage.cpp - QmitkDataManagerHotkeysPrefPage.cpp ) set(INTERNAL_CPP_FILES mitkPluginActivator.cpp - QmitkNodeTableViewKeyFilter.cpp - QmitkInfoDialog.cpp QmitkDataManagerItemDelegate.cpp ) set(MOC_H_FILES src/QmitkDataManagerView.h src/QmitkDataManagerPreferencePage.h - src/QmitkDataManagerHotkeysPrefPage.h - src/internal/QmitkNodeTableViewKeyFilter.h - src/internal/QmitkInfoDialog.h src/internal/QmitkDataManagerItemDelegate.h src/internal/mitkPluginActivator.h ) set(CPP_FILES ) set(CACHED_RESOURCE_FILES plugin.xml resources/data-manager.svg ) set(QRC_FILES resources/datamanager.qrc ) 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.datamanager/plugin.xml b/Plugins/org.mitk.gui.qt.datamanager/plugin.xml index d214d15842..ea6019bd8c 100644 --- a/Plugins/org.mitk.gui.qt.datamanager/plugin.xml +++ b/Plugins/org.mitk.gui.qt.datamanager/plugin.xml @@ -1,29 +1,25 @@ - - - - diff --git a/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerHotkeysPrefPage.cpp b/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerHotkeysPrefPage.cpp deleted file mode 100644 index defbae33ea..0000000000 --- a/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerHotkeysPrefPage.cpp +++ /dev/null @@ -1,154 +0,0 @@ -/*=================================================================== - -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 "QmitkDataManagerHotkeysPrefPage.h" -#include - -#include "berryIPreferencesService.h" -#include "berryPlatform.h" - -#include -#include -#include -#include -#include -#include - -#include - -using namespace berry; - -QmitkDataManagerHotkeysPrefPage::QmitkDataManagerHotkeysPrefPage() -: m_MainControl(nullptr) -{ - -} - -void QmitkDataManagerHotkeysPrefPage::Init(berry::IWorkbench::Pointer ) -{ - -} - -void QmitkDataManagerHotkeysPrefPage::CreateQtControl(QWidget* parent) -{ - IPreferencesService* prefService = Platform::GetPreferencesService(); - berry::IPreferences::Pointer _DataManagerHotkeysPreferencesNode = prefService->GetSystemPreferences()->Node("/DataManager/Hotkeys"); - m_DataManagerHotkeysPreferencesNode = _DataManagerHotkeysPreferencesNode; - - m_HotkeyEditors["Make all nodes invisible"] = new QmitkHotkeyLineEdit("Ctrl+, V"); - - m_HotkeyEditors["Toggle visibility of selected nodes"] = new QmitkHotkeyLineEdit("V"); - - m_HotkeyEditors["Delete selected nodes"] = new QmitkHotkeyLineEdit("Del"); - - m_HotkeyEditors["Reinit selected nodes"] = new QmitkHotkeyLineEdit("R"); - - m_HotkeyEditors["Global Reinit"] = new QmitkHotkeyLineEdit("Ctrl+, R"); - - m_HotkeyEditors["Show Node Information"] = new QmitkHotkeyLineEdit("Ctrl+, I"); - - m_MainControl = new QWidget(parent); - - auto layout = new QGridLayout; - int i = 0; - for (auto it = m_HotkeyEditors.begin() - ; it != m_HotkeyEditors.end(); ++it) - { - layout->addWidget(new QLabel(it->first), i,0); - layout->addWidget(it->second, i,1); - layout->setRowStretch(i,0); - ++i; - } - layout->setRowStretch(i+1,10); - - m_MainControl->setLayout(layout); - this->Update(); -} - -QWidget* QmitkDataManagerHotkeysPrefPage::GetQtControl() const -{ - return m_MainControl; -} - -bool QmitkDataManagerHotkeysPrefPage::PerformOk() -{ - IPreferences::Pointer _DataManagerHotkeysPreferencesNode = m_DataManagerHotkeysPreferencesNode.Lock(); - if(_DataManagerHotkeysPreferencesNode.IsNotNull()) - { - bool duplicate = false; - QString keyString; - QString errString; - for (auto it = m_HotkeyEditors.begin() - ; it != m_HotkeyEditors.end(); ++it) - { - keyString = it->second->GetKeySequenceAsString(); - - if(keyString.isEmpty()) - errString = QString("No valid key sequence for \"%1\"").arg(it->first); - - if(errString.isEmpty()) - { - std::map::iterator it2; - // search for duplicated key - for (it2 = m_HotkeyEditors.begin(); it2 != m_HotkeyEditors.end(); ++it2) - { - if(it->first != it2->first && keyString == it2->second->GetKeySequenceAsString()) - { - duplicate = true; - break; - } - } - if(duplicate == true) - errString = QString("Duplicate hot key for \"%1\" and \"%2\"").arg(it->first).arg(it2->first); - } - - if(!errString.isEmpty()) - { - QMessageBox::critical(QApplication::activeWindow(), "Error", errString); - return false; - } - } - - //# no errors -> save all values and flush to file - for (auto it = m_HotkeyEditors.begin() - ; it != m_HotkeyEditors.end(); ++it) - _DataManagerHotkeysPreferencesNode->Put(it->first - , it->second->GetKeySequenceAsString()); - - _DataManagerHotkeysPreferencesNode->Flush(); - - return true; - } - return false; -} - -void QmitkDataManagerHotkeysPrefPage::PerformCancel() -{ - -} - -void QmitkDataManagerHotkeysPrefPage::Update() -{ - IPreferences::Pointer _DataManagerHotkeysPreferencesNode = m_DataManagerHotkeysPreferencesNode.Lock(); - if(_DataManagerHotkeysPreferencesNode.IsNotNull()) - { - for (auto it = m_HotkeyEditors.begin() - ; it != m_HotkeyEditors.end(); ++it) - { - it->second->setText(_DataManagerHotkeysPreferencesNode->Get(it->first, it->second->text())); - } - } -} diff --git a/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerHotkeysPrefPage.h b/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerHotkeysPrefPage.h deleted file mode 100644 index 59cf49fe46..0000000000 --- a/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerHotkeysPrefPage.h +++ /dev/null @@ -1,72 +0,0 @@ -/*=================================================================== - -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 QMITKDATAMANAGERHOTKEYSPREFPAGE_H_ -#define QMITKDATAMANAGERHOTKEYSPREFPAGE_H_ - -#include "berryIQtPreferencePage.h" -#include - -#include -#include - -class QmitkHotkeyLineEdit; - -struct MITK_QT_DATAMANAGER QmitkDataManagerHotkeysPrefPage : public QObject, public berry::IQtPreferencePage -{ - Q_OBJECT - Q_INTERFACES(berry::IPreferencePage) - -public: - QmitkDataManagerHotkeysPrefPage(); - - void Init(berry::IWorkbench::Pointer workbench) override; - - void CreateQtControl(QWidget* parent) override; - - QWidget* GetQtControl() const override; - - /// - /// \see IPreferencePage::PerformOk() - /// - bool PerformOk() override; - - /// - /// \see IPreferencePage::PerformCancel() - /// - void PerformCancel() override; - - /// - /// \see IPreferencePage::Update() - /// - void Update() override; - -protected: - /// - /// The node from which the properties are taken (will be catched from the preferences service in ctor) - /// - berry::IPreferences::WeakPtr m_DataManagerHotkeysPreferencesNode; - - /// - /// Maps a label to hotkey lineedit, e.g. "Toggle Visibility of selected nodes" => QmitkHotkeyLineEdit - /// - std::map m_HotkeyEditors; - - QWidget* m_MainControl; -}; - -#endif /* QMITKDATAMANAGERHOTKEYSPREFPAGE_H_ */ diff --git a/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerPreferencePage.cpp b/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerPreferencePage.cpp index 5ce2e74497..8e58ac714b 100644 --- a/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerPreferencePage.cpp +++ b/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerPreferencePage.cpp @@ -1,106 +1,96 @@ /*=================================================================== 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 "QmitkDataManagerPreferencePage.h" #include "QmitkDataManagerView.h" #include #include #include #include #include #include QmitkDataManagerPreferencePage::QmitkDataManagerPreferencePage() : m_MainControl(nullptr) { - + // nothing here } void QmitkDataManagerPreferencePage::Init(berry::IWorkbench::Pointer ) { - + // nothing here } void QmitkDataManagerPreferencePage::CreateQtControl(QWidget* parent) { berry::IPreferencesService* prefService = berry::Platform::GetPreferencesService(); m_DataManagerPreferencesNode = prefService->GetSystemPreferences()->Node(QmitkDataManagerView::VIEW_ID); m_MainControl = new QWidget(parent); m_EnableSingleEditing = new QCheckBox; m_PlaceNewNodesOnTop = new QCheckBox; m_ShowHelperObjects = new QCheckBox; m_ShowNodesContainingNoData = new QCheckBox; - m_GlobalReinitOnNodeDelete = new QCheckBox; - m_GlobalReinitOnNodeAdded = new QCheckBox; - m_GlobalReinitOnNodeVisibilityChanged = new QCheckBox; + m_UseSurfaceDecimation = new QCheckBox; m_AllowParentChange = new QCheckBox; - auto formLayout = new QFormLayout; + auto formLayout = new QFormLayout; formLayout->addRow("&Single click property editing:", m_EnableSingleEditing); formLayout->addRow("&Place new nodes on top:", m_PlaceNewNodesOnTop); formLayout->addRow("&Show helper objects:", m_ShowHelperObjects); formLayout->addRow("&Show nodes containing no data", m_ShowNodesContainingNoData); - formLayout->addRow("&Call global reinit if node is deleted", m_GlobalReinitOnNodeDelete); - formLayout->addRow("&Call global reinit if node is added", m_GlobalReinitOnNodeAdded); - formLayout->addRow("&Call global reinit if node visibility is changed", m_GlobalReinitOnNodeVisibilityChanged); formLayout->addRow("&Use surface decimation:", m_UseSurfaceDecimation); formLayout->addRow("&Allow changing of parent node:", m_AllowParentChange); m_MainControl->setLayout(formLayout); - this->Update(); + Update(); } QWidget* QmitkDataManagerPreferencePage::GetQtControl() const { return m_MainControl; } bool QmitkDataManagerPreferencePage::PerformOk() { m_DataManagerPreferencesNode->PutBool("Single click property editing", m_EnableSingleEditing->isChecked()); m_DataManagerPreferencesNode->PutBool("Place new nodes on top", m_PlaceNewNodesOnTop->isChecked()); m_DataManagerPreferencesNode->PutBool("Show helper objects", m_ShowHelperObjects->isChecked()); m_DataManagerPreferencesNode->PutBool("Show nodes containing no data", m_ShowNodesContainingNoData->isChecked()); - m_DataManagerPreferencesNode->PutBool("Call global reinit if node is deleted", m_GlobalReinitOnNodeDelete->isChecked()); - m_DataManagerPreferencesNode->PutBool("Call global reinit if node is added", m_GlobalReinitOnNodeAdded->isChecked()); - m_DataManagerPreferencesNode->PutBool("Call global reinit if node visibility is changed", m_GlobalReinitOnNodeVisibilityChanged->isChecked()); m_DataManagerPreferencesNode->PutBool("Use surface decimation", m_UseSurfaceDecimation->isChecked()); m_DataManagerPreferencesNode->PutBool("Allow changing of parent node", m_AllowParentChange->isChecked()); + return true; } void QmitkDataManagerPreferencePage::PerformCancel() { - + // nothing here } void QmitkDataManagerPreferencePage::Update() { m_EnableSingleEditing->setChecked(m_DataManagerPreferencesNode->GetBool("Single click property editing", true)); m_PlaceNewNodesOnTop->setChecked(m_DataManagerPreferencesNode->GetBool("Place new nodes on top", true)); m_ShowHelperObjects->setChecked(m_DataManagerPreferencesNode->GetBool("Show helper objects", false)); m_ShowNodesContainingNoData->setChecked(m_DataManagerPreferencesNode->GetBool("Show nodes containing no data", false)); m_UseSurfaceDecimation->setChecked(m_DataManagerPreferencesNode->GetBool("Use surface decimation", true)); - m_GlobalReinitOnNodeDelete->setChecked(m_DataManagerPreferencesNode->GetBool("Call global reinit if node is deleted", true)); - m_GlobalReinitOnNodeAdded->setChecked(m_DataManagerPreferencesNode->GetBool("Call global reinit if node is added", true)); - m_GlobalReinitOnNodeVisibilityChanged->setChecked(m_DataManagerPreferencesNode->GetBool("Call global reinit if node visibility is changed", false)); m_AllowParentChange->setChecked(m_DataManagerPreferencesNode->GetBool("Allow changing of parent node", false)); } diff --git a/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerPreferencePage.h b/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerPreferencePage.h index 2c4f826626..ea80139eea 100644 --- a/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerPreferencePage.h +++ b/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerPreferencePage.h @@ -1,71 +1,68 @@ /*=================================================================== 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 QMITKDATAMANAGERPREFERENCEPAGE_H_ #define QMITKDATAMANAGERPREFERENCEPAGE_H_ #include "berryIQtPreferencePage.h" #include #include class QWidget; class QCheckBox; struct MITK_QT_DATAMANAGER QmitkDataManagerPreferencePage : public QObject, public berry::IQtPreferencePage { Q_OBJECT Q_INTERFACES(berry::IPreferencePage) public: QmitkDataManagerPreferencePage(); void Init(berry::IWorkbench::Pointer workbench) override; void CreateQtControl(QWidget* widget) override; QWidget* GetQtControl() const override; /// /// \see IPreferencePage::PerformOk() /// bool PerformOk() override; /// /// \see IPreferencePage::PerformCancel() /// void PerformCancel() override; /// /// \see IPreferencePage::Update() /// void Update() override; protected: QWidget* m_MainControl; QCheckBox* m_EnableSingleEditing; QCheckBox* m_PlaceNewNodesOnTop; QCheckBox* m_ShowHelperObjects; QCheckBox* m_ShowNodesContainingNoData; - QCheckBox* m_GlobalReinitOnNodeDelete; - QCheckBox* m_GlobalReinitOnNodeAdded; - QCheckBox* m_GlobalReinitOnNodeVisibilityChanged; QCheckBox* m_UseSurfaceDecimation; QCheckBox* m_AllowParentChange; berry::IPreferences::Pointer m_DataManagerPreferencesNode; }; #endif /* QMITKDATAMANAGERPREFERENCEPAGE_H_ */ diff --git a/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.cpp b/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.cpp index 6eb4dc9bb7..99646505a1 100644 --- a/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.cpp +++ b/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.cpp @@ -1,1218 +1,281 @@ /*=================================================================== 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" -//# Own Includes -//## mitk -#include "mitkDataStorageEditorInput.h" -#include "mitkIDataStorageReference.h" -#include "mitkNodePredicateDataType.h" -#include "mitkCoreObjectFactory.h" -#include "mitkColorProperty.h" -#include "mitkCommon.h" -#include "mitkNodePredicateData.h" -#include "mitkNodePredicateNot.h" -#include "mitkNodePredicateOr.h" -#include "mitkNodePredicateProperty.h" -#include "mitkEnumerationProperty.h" -#include "mitkLookupTableProperty.h" -#include "mitkProperties.h" -#include -#include -#include -#include +// mitk gui qt datamanager +#include "src/internal/QmitkDataManagerItemDelegate.h" + +// mitk core +#include +#include +#include #include -//## Qmitk -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// qt widgets module #include -#include #include -#include -#include "src/internal/QmitkNodeTableViewKeyFilter.h" -#include "src/internal/QmitkInfoDialog.h" -#include "src/internal/QmitkDataManagerItemDelegate.h" -//## Berry +#include +#include +#include + +// beery plugins #include #include #include -#include +#include +#include #include +#include #include #include -#include -//# Toolkit Includes -#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 #include -#include #include -#include -#include -#include #include #include -#include -#include -#include -#include -#include -#include #include -#include "mitkDataNodeObject.h" -#include "mitkIContextMenuAction.h" -#include "berryIExtensionRegistry.h" -#include "mitkRenderingModeProperty.h" - const QString QmitkDataManagerView::VIEW_ID = "org.mitk.views.datamanager"; QmitkDataManagerView::QmitkDataManagerView() - : m_GlobalReinitOnNodeDelete(true) - , m_GlobalReinitOnNodeVisibilityChanged(false) - , m_ItemDelegate(nullptr) + : m_ItemDelegate(nullptr) { } QmitkDataManagerView::~QmitkDataManagerView() { - //Remove all registered actions from each descriptor - for (std::vector< std::pair< QmitkNodeDescriptor*, QAction* > >::iterator it = m_DescriptorActionList.begin();it != m_DescriptorActionList.end(); it++) - { - // first== the NodeDescriptor; second== the registered QAction - (it->first)->RemoveAction(it->second); - } + // 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 ) ); + 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(this->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_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))); + 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->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_NodeTreeView->installEventFilter(new QmitkNodeTableViewKeyFilter(this)); m_ItemDelegate = new QmitkDataManagerItemDelegate(m_NodeTreeView); m_NodeTreeView->setItemDelegate(m_ItemDelegate); - connect( m_NodeTreeView, SIGNAL(customContextMenuRequested(const QPoint&)) - , this, SLOT(NodeTableViewContextMenuRequested(const QPoint&)) ); - 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, 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); - //# m_NodeMenu - m_NodeMenu = new QMenu(m_NodeTreeView); + // 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&))); - // # Actions 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))); } - auto unknownDataNodeDescriptor = - QmitkNodeDescriptorManager::GetInstance()->GetUnknownDataNodeDescriptor(); - - auto imageDataNodeDescriptor = - QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("Image"); - - auto multiComponentImageDataNodeDescriptor = - QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("MultiComponentImage"); - - auto diffusionImageDataNodeDescriptor = - QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("DiffusionImage"); - - auto fiberBundleDataNodeDescriptor = - QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("FiberBundle"); - - auto peakImageDataNodeDescriptor = - QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("PeakImage"); - - auto segmentDataNodeDescriptor = - QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("Segment"); - - auto surfaceDataNodeDescriptor = - QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("Surface"); - - auto pointSetNodeDescriptor = - QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("PointSet"); - - auto planarLineNodeDescriptor = - QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("PlanarLine"); - auto planarCircleNodeDescriptor = - QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("PlanarCircle"); - auto planarEllipseNodeDescriptor = - QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("PlanarEllipse"); - auto planarAngleNodeDescriptor = - QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("PlanarAngle"); - auto planarFourPointAngleNodeDescriptor = - QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("PlanarFourPointAngle"); - auto planarRectangleNodeDescriptor = - QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("PlanarRectangle"); - auto planarPolygonNodeDescriptor = - QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("PlanarPolygon"); - auto planarPathNodeDescriptor = - QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("PlanarPath"); - auto planarDoubleEllipseNodeDescriptor = - QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("PlanarDoubleEllipse"); - auto planarBezierCurveNodeDescriptor = - QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("PlanarBezierCurve"); - auto planarSubdivisionPolygonNodeDescriptor = - QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("PlanarSubdivisionPolygon"); - - QAction* globalReinitAction = new QAction(QIcon(":/org.mitk.gui.qt.datamanager/Refresh_48.png"), tr("Global Reinit"), this); - QObject::connect( globalReinitAction, SIGNAL( triggered(bool) ) - , this, SLOT( GlobalReinit(bool) ) ); - unknownDataNodeDescriptor->AddAction(globalReinitAction); - m_DescriptorActionList.push_back(std::make_pair(unknownDataNodeDescriptor, globalReinitAction)); - - QAction* saveAction = new QmitkFileSaveAction(QIcon(":/org.mitk.gui.qt.datamanager/Save_48.png"), - this->GetSite()->GetWorkbenchWindow()); - unknownDataNodeDescriptor->AddAction(saveAction); - m_DescriptorActionList.push_back(std::make_pair(unknownDataNodeDescriptor,saveAction)); - - QAction* removeAction = new QAction(QIcon(":/org.mitk.gui.qt.datamanager/Remove_48.png"), tr("Remove"), this); - QObject::connect( removeAction, SIGNAL( triggered(bool) ) - , this, SLOT( RemoveSelectedNodes(bool) ) ); - unknownDataNodeDescriptor->AddAction(removeAction); - m_DescriptorActionList.push_back(std::make_pair(unknownDataNodeDescriptor,removeAction)); - - QAction* reinitAction = new QAction(QIcon(":/org.mitk.gui.qt.datamanager/Refresh_48.png"), tr("Reinit"), this); - QObject::connect( reinitAction, SIGNAL( triggered(bool) ) - , this, SLOT( ReinitSelectedNodes(bool) ) ); - unknownDataNodeDescriptor->AddAction(reinitAction); - m_DescriptorActionList.push_back(std::make_pair(unknownDataNodeDescriptor,reinitAction)); - - // 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_ConfElements.clear(); - DescriptorActionListType customMenuEntries; - for (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()) - { - continue; - } - - QString actionIconName = customMenuConfig->GetAttribute("icon"); - - // Find matching descriptor - auto nodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor(actionNodeDescriptorName); - if ( nodeDescriptor == nullptr) - { - MITK_WARN << "Cannot add action \"" << actionLabel << "\" because descriptor " << actionNodeDescriptorName << " does not exist."; - continue; - } - - // Create action with or without icon - QAction* contextMenuAction; - 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, parent); - } else - { - contextMenuAction = new QAction(actionLabel, parent); - } - - // Define menu handler to trigger on click - connect(contextMenuAction, static_cast(&QAction::triggered), - this, &QmitkDataManagerView::ContextMenuActionTriggered); - - // Mark configuration element into lookup list for context menu handler - m_ConfElements[contextMenuAction] = customMenuConfig; - // Mark new action in sortable list for addition to descriptor - customMenuEntries.emplace_back(nodeDescriptor, contextMenuAction); - } - - // Sort all custom QActions by their texts - { - using ListEntryType = std::pair; - std::sort(customMenuEntries.begin(), customMenuEntries.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 - int globalAddedMenuIndex=1; - for (auto& menuEntryToAdd : customMenuEntries) - { - auto& nodeDescriptor = menuEntryToAdd.first; - auto& contextMenuAction = menuEntryToAdd.second; - - // TODO is the action "data" used by anything? Otherwise remove! - contextMenuAction->setData(static_cast(globalAddedMenuIndex)); - ++globalAddedMenuIndex; - - // Really add this action to that descriptor (in pre-defined order) - nodeDescriptor->AddAction(contextMenuAction); - - // Mark new action into list of descriptors to remove in d'tor - m_DescriptorActionList.push_back(menuEntryToAdd); - } - - m_OpacitySlider = new QSlider; - m_OpacitySlider->setMinimum(0); - m_OpacitySlider->setMaximum(100); - m_OpacitySlider->setOrientation(Qt::Horizontal); - QObject::connect( m_OpacitySlider, SIGNAL( valueChanged(int) ) - , this, SLOT( OpacityChanged(int) ) ); - - QLabel* _OpacityLabel = new QLabel(tr("Opacity: ")); - QHBoxLayout* _OpacityWidgetLayout = new QHBoxLayout; - _OpacityWidgetLayout->setContentsMargins(4,4,4,4); - _OpacityWidgetLayout->addWidget(_OpacityLabel); - _OpacityWidgetLayout->addWidget(m_OpacitySlider); - QWidget* _OpacityWidget = new QWidget; - _OpacityWidget->setLayout(_OpacityWidgetLayout); - - QWidgetAction* opacityAction = new QWidgetAction(this); - opacityAction ->setDefaultWidget(_OpacityWidget); - QObject::connect( opacityAction , SIGNAL( changed() ) - , this, SLOT( OpacityActionChanged() ) ); - unknownDataNodeDescriptor->AddAction(opacityAction , false); - m_DescriptorActionList.push_back(std::make_pair(unknownDataNodeDescriptor,opacityAction)); - - m_ColorButton = new QPushButton; - m_ColorButton->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Minimum); - //m_ColorButton->setText("Change color"); - QObject::connect( m_ColorButton, SIGNAL( clicked() ) - , this, SLOT( ColorChanged() ) ); - - QLabel* _ColorLabel = new QLabel(tr("Color: ")); - _ColorLabel->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum); - QHBoxLayout* _ColorWidgetLayout = new QHBoxLayout; - _ColorWidgetLayout->setContentsMargins(4,4,4,4); - _ColorWidgetLayout->addWidget(_ColorLabel); - _ColorWidgetLayout->addWidget(m_ColorButton); - QWidget* _ColorWidget = new QWidget; - _ColorWidget->setLayout(_ColorWidgetLayout); - - QWidgetAction* colorAction = new QWidgetAction(this); - colorAction->setDefaultWidget(_ColorWidget); - QObject::connect( colorAction, SIGNAL( changed() ) - , this, SLOT( ColorActionChanged() ) ); - - { // only give the color context menu option where appropriate - bool colorActionCanBatch = true; - if (imageDataNodeDescriptor != nullptr) - { - imageDataNodeDescriptor->AddAction(colorAction, colorActionCanBatch); - m_DescriptorActionList.push_back(std::make_pair(imageDataNodeDescriptor, colorAction)); - } - if (multiComponentImageDataNodeDescriptor != nullptr) - { - multiComponentImageDataNodeDescriptor->AddAction(colorAction, colorActionCanBatch); - m_DescriptorActionList.push_back(std::make_pair(multiComponentImageDataNodeDescriptor, colorAction)); - } - if (diffusionImageDataNodeDescriptor != nullptr) - { - diffusionImageDataNodeDescriptor->AddAction(colorAction, colorActionCanBatch); - m_DescriptorActionList.push_back(std::make_pair(diffusionImageDataNodeDescriptor, colorAction)); - } - if (fiberBundleDataNodeDescriptor != nullptr) - { - fiberBundleDataNodeDescriptor->AddAction(colorAction, false); - m_DescriptorActionList.push_back(std::make_pair(fiberBundleDataNodeDescriptor, colorAction)); - } - if (peakImageDataNodeDescriptor != nullptr) - { - peakImageDataNodeDescriptor->AddAction(colorAction, false); - m_DescriptorActionList.push_back(std::make_pair(peakImageDataNodeDescriptor, colorAction)); - } - if (segmentDataNodeDescriptor != nullptr) - { - segmentDataNodeDescriptor->AddAction(colorAction, false); - m_DescriptorActionList.push_back(std::make_pair(segmentDataNodeDescriptor, colorAction)); - } - if (surfaceDataNodeDescriptor != nullptr) - { - surfaceDataNodeDescriptor->AddAction(colorAction, colorActionCanBatch); - m_DescriptorActionList.push_back(std::make_pair(surfaceDataNodeDescriptor, colorAction)); - } - if (pointSetNodeDescriptor != nullptr) - { - pointSetNodeDescriptor->AddAction(colorAction, colorActionCanBatch); - m_DescriptorActionList.push_back(std::make_pair(pointSetNodeDescriptor, colorAction)); - } - - if (planarLineNodeDescriptor != nullptr) - { - planarLineNodeDescriptor->AddAction(colorAction, colorActionCanBatch); - m_DescriptorActionList.push_back(std::make_pair(planarLineNodeDescriptor, colorAction)); - } - - if (planarCircleNodeDescriptor != nullptr) - { - planarCircleNodeDescriptor->AddAction(colorAction, colorActionCanBatch); - m_DescriptorActionList.push_back(std::make_pair(planarCircleNodeDescriptor, colorAction)); - } - - if (planarEllipseNodeDescriptor != nullptr) - { - planarEllipseNodeDescriptor->AddAction(colorAction, colorActionCanBatch); - m_DescriptorActionList.push_back(std::make_pair(planarEllipseNodeDescriptor, colorAction)); - } - - if (planarAngleNodeDescriptor != nullptr) - { - planarAngleNodeDescriptor->AddAction(colorAction, colorActionCanBatch); - m_DescriptorActionList.push_back(std::make_pair(planarAngleNodeDescriptor, colorAction)); - } - - if (planarFourPointAngleNodeDescriptor != nullptr) - { - planarFourPointAngleNodeDescriptor->AddAction(colorAction, colorActionCanBatch); - m_DescriptorActionList.push_back(std::make_pair(planarFourPointAngleNodeDescriptor, colorAction)); - } - - if (planarRectangleNodeDescriptor != nullptr) - { - planarRectangleNodeDescriptor->AddAction(colorAction, colorActionCanBatch); - m_DescriptorActionList.push_back(std::make_pair(planarRectangleNodeDescriptor, colorAction)); - } - - if (planarPolygonNodeDescriptor != nullptr) - { - planarPolygonNodeDescriptor->AddAction(colorAction, colorActionCanBatch); - m_DescriptorActionList.push_back(std::make_pair(planarPolygonNodeDescriptor, colorAction)); - } - - if (planarPathNodeDescriptor != nullptr) - { - planarPathNodeDescriptor->AddAction(colorAction, colorActionCanBatch); - m_DescriptorActionList.push_back(std::make_pair(planarPathNodeDescriptor, colorAction)); - } - - if (planarDoubleEllipseNodeDescriptor != nullptr) - { - planarDoubleEllipseNodeDescriptor->AddAction(colorAction, colorActionCanBatch); - m_DescriptorActionList.push_back(std::make_pair(planarDoubleEllipseNodeDescriptor, colorAction)); - } - - if (planarBezierCurveNodeDescriptor != nullptr) - { - planarBezierCurveNodeDescriptor->AddAction(colorAction, colorActionCanBatch); - m_DescriptorActionList.push_back(std::make_pair(planarBezierCurveNodeDescriptor, colorAction)); - } - - if (planarSubdivisionPolygonNodeDescriptor != nullptr) - { - planarSubdivisionPolygonNodeDescriptor->AddAction(colorAction, colorActionCanBatch); - m_DescriptorActionList.push_back(std::make_pair(planarSubdivisionPolygonNodeDescriptor, colorAction)); - } - } - - m_ComponentSlider = new QmitkNumberPropertySlider; - m_ComponentSlider->setOrientation(Qt::Horizontal); - //QObject::connect( m_OpacitySlider, SIGNAL( valueChanged(int) ) - // , this, SLOT( OpacityChanged(int) ) ); - - QLabel* _ComponentLabel = new QLabel(tr("Component: ")); - QHBoxLayout* _ComponentWidgetLayout = new QHBoxLayout; - _ComponentWidgetLayout->setContentsMargins(4,4,4,4); - _ComponentWidgetLayout->addWidget(_ComponentLabel); - _ComponentWidgetLayout->addWidget(m_ComponentSlider); - QLabel* _ComponentValueLabel = new QLabel(); - _ComponentWidgetLayout->addWidget(_ComponentValueLabel); - connect(m_ComponentSlider, SIGNAL(valueChanged(int)), _ComponentValueLabel, SLOT(setNum(int))); - QWidget* _ComponentWidget = new QWidget; - _ComponentWidget->setLayout(_ComponentWidgetLayout); - - QWidgetAction* componentAction = new QWidgetAction(this); - componentAction->setDefaultWidget(_ComponentWidget); - QObject::connect( componentAction , SIGNAL( changed() ) - , this, SLOT( ComponentActionChanged() ) ); - multiComponentImageDataNodeDescriptor->AddAction(componentAction, false); - m_DescriptorActionList.push_back(std::make_pair(multiComponentImageDataNodeDescriptor,componentAction)); - if (diffusionImageDataNodeDescriptor!=nullptr) - { - diffusionImageDataNodeDescriptor->AddAction(componentAction, false); - m_DescriptorActionList.push_back(std::make_pair(diffusionImageDataNodeDescriptor,componentAction)); - } - - m_TextureInterpolation = new QAction(tr("Texture Interpolation"), this); - m_TextureInterpolation->setCheckable ( true ); - QObject::connect( m_TextureInterpolation, SIGNAL( changed() ) - , this, SLOT( TextureInterpolationChanged() ) ); - QObject::connect( m_TextureInterpolation, SIGNAL( toggled(bool) ) - , this, SLOT( TextureInterpolationToggled(bool) ) ); - imageDataNodeDescriptor->AddAction(m_TextureInterpolation, false); - m_DescriptorActionList.push_back(std::make_pair(imageDataNodeDescriptor,m_TextureInterpolation)); - if (diffusionImageDataNodeDescriptor!=nullptr) - { - diffusionImageDataNodeDescriptor->AddAction(m_TextureInterpolation, false); - m_DescriptorActionList.push_back(std::make_pair(diffusionImageDataNodeDescriptor,m_TextureInterpolation)); - } - if (segmentDataNodeDescriptor != nullptr) - { - segmentDataNodeDescriptor->AddAction(m_TextureInterpolation, false); - m_DescriptorActionList.push_back(std::make_pair(segmentDataNodeDescriptor, m_TextureInterpolation)); - } - - m_ColormapAction = new QAction(tr("Colormap"), this); - m_ColormapAction->setMenu(new QMenu); - QObject::connect( m_ColormapAction->menu(), SIGNAL( aboutToShow() ) - , this, SLOT( ColormapMenuAboutToShow() ) ); - imageDataNodeDescriptor->AddAction(m_ColormapAction, false); - m_DescriptorActionList.push_back(std::make_pair(imageDataNodeDescriptor, m_ColormapAction)); - if (diffusionImageDataNodeDescriptor!=nullptr) - { - diffusionImageDataNodeDescriptor->AddAction(m_ColormapAction, false); - m_DescriptorActionList.push_back(std::make_pair(diffusionImageDataNodeDescriptor, m_ColormapAction)); - } - - m_SurfaceRepresentation = new QAction(tr("Surface Representation"), this); - m_SurfaceRepresentation->setMenu(new QMenu(m_NodeTreeView)); - QObject::connect( m_SurfaceRepresentation->menu(), SIGNAL( aboutToShow() ) - , this, SLOT( SurfaceRepresentationMenuAboutToShow() ) ); - surfaceDataNodeDescriptor->AddAction(m_SurfaceRepresentation, false); - m_DescriptorActionList.push_back(std::make_pair(surfaceDataNodeDescriptor, m_SurfaceRepresentation)); + QGridLayout* dndFrameWidgetLayout = new QGridLayout; + dndFrameWidgetLayout->addWidget(m_NodeTreeView, 0, 0); + dndFrameWidgetLayout->setContentsMargins(0, 0, 0, 0); - QAction* showOnlySelectedNodes - = new QAction(QIcon(":/org.mitk.gui.qt.datamanager/ShowSelectedNode_48.png") - , tr("Show only selected nodes"), this); - QObject::connect( showOnlySelectedNodes, SIGNAL( triggered(bool) ) - , this, SLOT( ShowOnlySelectedNodes(bool) ) ); - unknownDataNodeDescriptor->AddAction(showOnlySelectedNodes); - m_DescriptorActionList.push_back(std::make_pair(unknownDataNodeDescriptor, showOnlySelectedNodes)); - - QAction* toggleSelectedVisibility - = new QAction(QIcon(":/org.mitk.gui.qt.datamanager/InvertShowSelectedNode_48.png") - , tr("Toggle visibility"), this); - QObject::connect( toggleSelectedVisibility, SIGNAL( triggered(bool) ) - , this, SLOT( ToggleVisibilityOfSelectedNodes(bool) ) ); - unknownDataNodeDescriptor->AddAction(toggleSelectedVisibility); - m_DescriptorActionList.push_back(std::make_pair(unknownDataNodeDescriptor,toggleSelectedVisibility)); - - QAction* actionShowInfoDialog - = new QAction(QIcon(":/org.mitk.gui.qt.datamanager/ShowDataInfo_48.png") - , tr("Details..."), this); - QObject::connect( actionShowInfoDialog, SIGNAL( triggered(bool) ) - , this, SLOT( ShowInfoDialogForSelectedNodes(bool) ) ); - unknownDataNodeDescriptor->AddAction(actionShowInfoDialog); - m_DescriptorActionList.push_back(std::make_pair(unknownDataNodeDescriptor,actionShowInfoDialog)); - - 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); + 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); + layout->addWidget(m_DnDFrameWidget); + layout->setContentsMargins(0, 0, 0, 0); m_Parent->setLayout(layout); } void QmitkDataManagerView::SetFocus() { } -void QmitkDataManagerView::ContextMenuActionTriggered( bool ) +void QmitkDataManagerView::NodeChanged(const mitk::DataNode* /*node*/) { - QAction* action = qobject_cast ( sender() ); - - std::map::iterator it - = m_ConfElements.find( action ); - if( it == m_ConfElements.end() ) - { - MITK_WARN << "associated conf 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"); - - contextMenuAction->SetDataStorage(this->GetDataStorage()); - - if(className == "QmitkCreatePolygonModelAction") - { - - if(smoothed == "false") - { - contextMenuAction->SetSmoothed(false); - } - else - { - contextMenuAction->SetSmoothed(true); - } - contextMenuAction->SetDecimated(m_SurfaceDecimation); - } - else if(className == "QmitkStatisticsAction") - { - contextMenuAction->SetFunctionality(this); - } - - contextMenuAction->Run( this->GetCurrentSelection() ); // run the action + // 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_GlobalReinitOnNodeDelete = prefs->GetBool("Call global reinit if node is deleted", true); - m_GlobalReinitOnNodeVisibilityChanged = prefs->GetBool("Call global reinit if node visibility is changed", false); - 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)); - this->GlobalReinit(); + GlobalReinitAction::Run(GetSite(), GetDataStorage()); } -void QmitkDataManagerView::NodeTableViewContextMenuRequested( const QPoint & pos ) -{ - QModelIndex selectedProxy = m_NodeTreeView->indexAt ( pos ); - QModelIndex selected = m_FilterModel->mapToSource(selectedProxy); - mitk::DataNode::Pointer node = m_NodeTreeModel->GetNode(selected); - QList selectedNodes = this->GetCurrentSelection(); - - if(!selectedNodes.isEmpty()) - { - ColorActionChanged(); // update color button - - m_NodeMenu->clear(); - QList actions; - if(selectedNodes.size() == 1 ) - { - actions = QmitkNodeDescriptorManager::GetInstance()->GetActions(node); - - for(QList::iterator it = actions.begin(); it != actions.end(); ++it) - { - (*it)->setData(QVariant::fromValue(node.GetPointer())); - } - } - else - actions = QmitkNodeDescriptorManager::GetInstance()->GetActions(selectedNodes); - - if (!m_ShowInActions.isEmpty()) - { - QMenu* showInMenu = m_NodeMenu->addMenu(tr("Show In")); - showInMenu->addActions(m_ShowInActions); - } - m_NodeMenu->addActions(actions); - m_NodeMenu->popup(QCursor::pos()); - } -} - -void QmitkDataManagerView::OpacityChanged(int value) -{ - mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex())); - if(node) - { - float opacity = static_cast(value)/100.0f; - node->SetFloatProperty("opacity", opacity); - mitk::RenderingManager::GetInstance()->RequestUpdateAll(); - } -} - -void QmitkDataManagerView::OpacityActionChanged() -{ - mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex())); - if(node) - { - float opacity = 0.0; - if(node->GetFloatProperty("opacity", opacity)) - { - m_OpacitySlider->setValue(static_cast(opacity*100)); - } - } -} - -void QmitkDataManagerView::ComponentActionChanged() -{ - mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex())); - mitk::IntProperty* componentProperty = nullptr; - int numComponents = 0; - if(node) - { - componentProperty = - dynamic_cast(node->GetProperty("Image.Displayed Component")); - mitk::Image* img = dynamic_cast(node->GetData()); - if (img != nullptr) - { - numComponents = img->GetPixelType().GetNumberOfComponents(); - } - } - if (componentProperty && numComponents > 1) - { - m_ComponentSlider->SetProperty(componentProperty); - m_ComponentSlider->setMinValue(0); - m_ComponentSlider->setMaxValue(numComponents-1); - } - else - { - m_ComponentSlider->SetProperty(static_cast(nullptr)); - } -} - -void QmitkDataManagerView::ColorChanged() -{ - bool color_selected = false; - QColor newColor; - - auto selected_indices = m_NodeTreeView->selectionModel()->selectedIndexes(); - for (auto& selected_index : selected_indices) - { - auto node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(selected_index)); - if(node) - { - float rgb[3]; - if (node->GetColor(rgb)) - { - if (!color_selected) - { - QColor initial(rgb[0] * 255, rgb[1] * 255, rgb[2] * 255); - newColor = QColorDialog::getColor(initial, nullptr, QString(tr("Change color"))); - - if ( newColor.isValid() ) - { - color_selected = true; - } - else - { - return; - } - } - - node->SetProperty("color", mitk::ColorProperty::New(newColor.redF(), newColor.greenF(), newColor.blueF())); - if ( node->GetProperty("binaryimage.selectedcolor") ) - { - node->SetProperty("binaryimage.selectedcolor", mitk::ColorProperty::New(newColor.redF(), newColor.greenF(), newColor.blueF())); - } - } - } - } - - mitk::RenderingManager::GetInstance()->RequestUpdateAll(); -} - -void QmitkDataManagerView::ColorActionChanged() -{ - // Adapts color displayed in context menu item - auto selected_indices = m_NodeTreeView->selectionModel()->selectedIndexes(); - if (selected_indices.isEmpty()) - return; - - mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(selected_indices.front())); - if(node) - { - float rgb[3]; - if (node->GetColor(rgb)) - { - QColor color(rgb[0] * 255, rgb[1] * 255, rgb[2] * 255); - QString styleSheet = QString("background-color: ") + color.name(QColor::HexRgb); - m_ColorButton->setAutoFillBackground(true); - m_ColorButton->setStyleSheet(styleSheet); - } - } -} - -void QmitkDataManagerView::TextureInterpolationChanged() -{ - mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex())); - if(node) - { - bool textureInterpolation = false; - node->GetBoolProperty("texture interpolation", textureInterpolation); - m_TextureInterpolation->setChecked(textureInterpolation); - } -} - -void QmitkDataManagerView::TextureInterpolationToggled( bool checked ) -{ - mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex())); - if(node) - { - node->SetBoolProperty("texture interpolation", checked); - mitk::RenderingManager::GetInstance()->RequestUpdateAll(); - } - -} - -void QmitkDataManagerView::ColormapActionToggled( bool /*checked*/ ) -{ - mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex())); - if(!node) - return; - - mitk::LookupTableProperty::Pointer lookupTableProperty = - dynamic_cast(node->GetProperty("LookupTable")); - if (!lookupTableProperty) - return; - - QAction* senderAction = qobject_cast(QObject::sender()); - if(!senderAction) - return; - - std::string activatedItem = senderAction->text().toStdString(); - - mitk::LookupTable::Pointer lookupTable = lookupTableProperty->GetValue(); - if (!lookupTable) - return; - - lookupTable->SetType(activatedItem); - lookupTableProperty->SetValue(lookupTable); - mitk::RenderingModeProperty::Pointer renderingMode = - dynamic_cast(node->GetProperty("Image Rendering.Mode")); - renderingMode->SetValue(mitk::RenderingModeProperty::LOOKUPTABLE_LEVELWINDOW_COLOR); - mitk::RenderingManager::GetInstance()->RequestUpdateAll(); -} - -void QmitkDataManagerView::ColormapMenuAboutToShow() -{ - mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex())); - if(!node) - return; - - mitk::LookupTableProperty::Pointer lookupTableProperty = - dynamic_cast(node->GetProperty("LookupTable")); - if (!lookupTableProperty) - { - mitk::LookupTable::Pointer mitkLut = mitk::LookupTable::New(); - lookupTableProperty = mitk::LookupTableProperty::New(); - lookupTableProperty->SetLookupTable(mitkLut); - node->SetProperty("LookupTable", lookupTableProperty); - } - - mitk::LookupTable::Pointer lookupTable = lookupTableProperty->GetValue(); - if (!lookupTable) - return; - - m_ColormapAction->menu()->clear(); - QAction* tmp; - - int i = 0; - std::string lutType = lookupTable->typenameList[i]; - - while (lutType != "END_OF_ARRAY") - { - tmp = m_ColormapAction->menu()->addAction(QString::fromStdString(lutType)); - tmp->setCheckable(true); - - if (lutType == lookupTable->GetActiveTypeAsString()) - { - tmp->setChecked(true); - } - - QObject::connect(tmp, SIGNAL(triggered(bool)), this, SLOT(ColormapActionToggled(bool))); - - lutType = lookupTable->typenameList[++i]; - } -} - -void QmitkDataManagerView::SurfaceRepresentationMenuAboutToShow() -{ - mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex())); - if(!node) - return; - - mitk::EnumerationProperty* representationProp = - dynamic_cast (node->GetProperty("material.representation")); - if(!representationProp) - return; - - // clear menu - m_SurfaceRepresentation->menu()->clear(); - QAction* tmp; - - // create menu entries - for(mitk::EnumerationProperty::EnumConstIterator it=representationProp->Begin(); it!=representationProp->End() - ; it++) - { - tmp = m_SurfaceRepresentation->menu()->addAction(QString::fromStdString(it->second)); - tmp->setCheckable(true); - - if(it->second == representationProp->GetValueAsString()) - { - tmp->setChecked(true); - } - - QObject::connect( tmp, SIGNAL( triggered(bool) ) - , this, SLOT( SurfaceRepresentationActionToggled(bool) ) ); - } -} - -void QmitkDataManagerView::SurfaceRepresentationActionToggled( bool /*checked*/ ) -{ - mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex())); - if(!node) - return; - - mitk::EnumerationProperty* representationProp = - dynamic_cast (node->GetProperty("material.representation")); - if(!representationProp) - return; - - QAction* senderAction = qobject_cast ( QObject::sender() ); - - if(!senderAction) - return; - - std::string activatedItem = senderAction->text().toStdString(); - - if ( activatedItem != representationProp->GetValueAsString() ) - { - if ( representationProp->IsValidEnumerationValue( activatedItem ) ) - { - representationProp->SetValue( activatedItem ); - representationProp->InvokeEvent( itk::ModifiedEvent() ); - representationProp->Modified(); - - mitk::RenderingManager::GetInstance()->RequestUpdateAll(); - } - } - -} - -void QmitkDataManagerView::ReinitSelectedNodes( bool ) -{ - auto renderWindow = this->GetRenderWindowPart(); - - if (nullptr == renderWindow) - renderWindow = this->OpenRenderWindowPart(false); - - if (nullptr == renderWindow) - return; - - auto dataStorage = this->GetDataStorage(); - - auto selectedNodesIncludedInBoundingBox = mitk::NodePredicateAnd::New( - mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("includeInBoundingBox", mitk::BoolProperty::New(false))), - mitk::NodePredicateProperty::New("selected", mitk::BoolProperty::New(true))); - - auto nodes = dataStorage->GetSubset(selectedNodesIncludedInBoundingBox); - - if (nodes->empty()) - return; - - if (1 == nodes->Size()) // Special case: If exactly one ... - { - auto image = dynamic_cast(nodes->ElementAt(0)->GetData()); - - if (nullptr != image) // ... image is selected, reinit is expected to rectify askew images. - { - mitk::RenderingManager::GetInstance()->InitializeViews(image->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true); - return; - } - } - - auto boundingGeometry = dataStorage->ComputeBoundingGeometry3D(nodes, "visible"); - - mitk::RenderingManager::GetInstance()->InitializeViews(boundingGeometry); -} - -void QmitkDataManagerView::RemoveSelectedNodes( bool ) -{ - QModelIndexList indexesOfSelectedRowsFiltered = m_NodeTreeView->selectionModel()->selectedRows(); - QModelIndexList indexesOfSelectedRows; - for (int i = 0; i < indexesOfSelectedRowsFiltered.size(); ++i) - { - indexesOfSelectedRows.push_back(m_FilterModel->mapToSource(indexesOfSelectedRowsFiltered[i])); - } - if(indexesOfSelectedRows.size() < 1) - { - return; - } - std::vector selectedNodes; - - mitk::DataNode::Pointer node = nullptr; - QString question = tr("Do you really want to remove "); - - for (QModelIndexList::iterator it = indexesOfSelectedRows.begin() - ; it != indexesOfSelectedRows.end(); it++) - { - node = m_NodeTreeModel->GetNode(*it); - // if node is not defined or if the node contains geometry data do not remove it - if ( node.IsNotNull() /*& strcmp(node->GetData()->GetNameOfClass(), "PlaneGeometryData") != 0*/ ) - { - selectedNodes.push_back(node); - question.append(QString::fromStdString(node->GetName())); - question.append(", "); - } - } - // remove the last two characters = ", " - question = question.remove(question.size()-2, 2); - question.append(tr(" from data storage?")); - - QMessageBox::StandardButton answerButton = QMessageBox::question( m_Parent - , tr("DataManager") - , question - , QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); - - if(answerButton == QMessageBox::Yes) - { - for (std::vector::iterator it = selectedNodes.begin() - ; it != selectedNodes.end(); it++) - { - node = *it; - this->GetDataStorage()->Remove(node); - if (m_GlobalReinitOnNodeDelete) - this->GlobalReinit(false); - } - } -} - -void QmitkDataManagerView::MakeAllNodesInvisible( bool ) -{ - QList nodes = m_NodeTreeModel->GetNodeSet(); - - foreach(mitk::DataNode::Pointer node, nodes) - { - node->SetVisibility(false); - } - mitk::RenderingManager::GetInstance()->RequestUpdateAll(); -} - -void QmitkDataManagerView::ShowOnlySelectedNodes( bool ) -{ - QList selectedNodes = this->GetCurrentSelection(); - QList allNodes = m_NodeTreeModel->GetNodeSet(); - - foreach(mitk::DataNode::Pointer node, allNodes) - { - node->SetVisibility(selectedNodes.contains(node)); - } - mitk::RenderingManager::GetInstance()->RequestUpdateAll(); -} - -void QmitkDataManagerView::ToggleVisibilityOfSelectedNodes( bool ) -{ - QList selectedNodes = this->GetCurrentSelection(); - - bool isVisible = false; - foreach(mitk::DataNode::Pointer node, selectedNodes) - { - isVisible = false; - node->GetBoolProperty("visible", isVisible); - node->SetVisibility(!isVisible); - } - mitk::RenderingManager::GetInstance()->RequestUpdateAll(); -} - -void QmitkDataManagerView::ShowInfoDialogForSelectedNodes( bool ) -{ - QList selectedNodes = this->GetCurrentSelection(); - - QmitkInfoDialog _QmitkInfoDialog(selectedNodes, this->m_Parent); - _QmitkInfoDialog.exec(); -} - -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 ); -} - -QItemSelectionModel *QmitkDataManagerView::GetDataNodeSelectionModel() const -{ - return m_NodeTreeView->selectionModel(); -} - -void QmitkDataManagerView::GlobalReinit( bool ) -{ - mitk::IRenderWindowPart* renderWindow = this->GetRenderWindowPart(); - - if (renderWindow == nullptr) - renderWindow = this->OpenRenderWindowPart(false); - - // no render window available - if (renderWindow == nullptr) return; - - mitk::RenderingManager::GetInstance()->InitializeViewsByBoundingObjects(this->GetDataStorage()); -} - -void QmitkDataManagerView::NodeTreeViewRowsRemoved ( - const QModelIndex & /*parent*/, int /*start*/, int /*end*/ ) -{ - m_CurrentRowCount = m_NodeTreeModel->rowCount(); -} -void QmitkDataManagerView::NodeTreeViewRowsInserted( const QModelIndex & parent, int, int ) +////////////////////////////////////////////////////////////////////////// +// 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 ) + if (m_CurrentRowCount == 0 && m_NodeTreeModel->rowCount() == 1) { - this->OpenRenderWindowPart(); + mitk::WorkbenchUtil::OpenRenderWindowPart(GetSite()->GetPage()); m_CurrentRowCount = m_NodeTreeModel->rowCount(); } } -void QmitkDataManagerView::NodeSelectionChanged( const QItemSelection & /*selected*/, const QItemSelection & /*deselected*/ ) +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 = this->GetCurrentSelection(); + auto selectedNodes = GetCurrentSelection(); + auto nodeSet = m_NodeTreeModel->GetNodeSet(); - for (auto node : m_NodeTreeModel->GetNodeSet()) + for (auto node : nodeSet) { if (node.IsNotNull()) + { node->SetSelected(selectedNodes.contains(node)); + } } } void QmitkDataManagerView::OnNodeVisibilityChanged() { - if (m_GlobalReinitOnNodeVisibilityChanged) - { - mitk::RenderingManager::GetInstance()->InitializeViewsByBoundingObjects(GetDataStorage()); - } - else - { - mitk::RenderingManager::GetInstance()->RequestUpdateAll(); - } + ToggleVisibilityAction::Run(GetSite(), GetDataStorage()); } -void QmitkDataManagerView::ShowIn(const QString &editorId) +void QmitkDataManagerView::ShowIn(const QString& editorId) { - berry::IWorkbenchPage::Pointer page = this->GetSite()->GetPage(); - berry::IEditorInput::Pointer input(new mitk::DataStorageEditorInput(this->GetDataStorageReference())); + berry::IWorkbenchPage::Pointer page = GetSite()->GetPage(); + berry::IEditorInput::Pointer input(new mitk::DataStorageEditorInput(GetDataStorageReference())); page->OpenEditor(input, editorId, false, berry::IWorkbenchPage::MATCH_ID); } -mitk::IRenderWindowPart* QmitkDataManagerView::OpenRenderWindowPart(bool activatedEditor) +QItemSelectionModel* QmitkDataManagerView::GetDataNodeSelectionModel() const { - if (activatedEditor) - { - return this->GetRenderWindowPart(QmitkAbstractView::ACTIVATE | QmitkAbstractView::OPEN); - } - else - { - return this->GetRenderWindowPart(QmitkAbstractView::BRING_TO_FRONT | QmitkAbstractView::OPEN); - } + 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 2d2e5515aa..2be976e22a 100644 --- a/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.h +++ b/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.h @@ -1,270 +1,142 @@ /*=================================================================== 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_ -// BlueBerry includes +#include + +// mitk core +#include + +// berry plugin #include -/// Qmitk +// mitk gui qt common plugin #include -#include -/// Qt -#include +// mitk gui qt application +#include -#include +// qt +#include -// Forward declarations -class QMenu; +// forward declarations class QAction; -class QComboBox; -class QWidgetAction; -class QSlider; class QModelIndex; class QTreeView; -class QPushButton; -class QToolBar; -class QMenu; class QSignalMapper; class QmitkDnDFrameWidget; class QmitkDataStorageTreeModel; class QmitkDataManagerItemDelegate; -class QmitkNumberPropertySlider; class QmitkDataStorageFilterProxyModel; -/// -/// \ingroup org_mitk_gui_qt_datamanager_internal -/// -/// \brief A View class that can show all data tree nodes of a certain DataStorage -/// -/// \TODO: complete PACS support, in save dialog show regular filename -/// +/** +* @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.extapp.defaultperspective" - /// - /// \brief Standard ctor. - /// + static const QString VIEW_ID; // = "org.mitk.views.datamanager" + QmitkDataManagerView(); - /// - /// \brief Standard dtor. - /// ~QmitkDataManagerView() override; -public slots: - /// - /// Invoked when the opacity slider changed - /// - void OpacityChanged(int value); - /// - /// Invoked when the opacity action changed - /// In this function the the opacity slider is set to the selected nodes opacity value - /// - void OpacityActionChanged(); - /// Invoked when the component action changed - /// In this function the the opacity slider is set to the selected nodes opacity value - /// - void ComponentActionChanged(); - /// - /// Invoked when the color button is pressed - /// - void ColorChanged(); - /// - /// Invoked when the color action changed - /// - void ColorActionChanged(); - /// - /// Invoked when the color button is pressed - /// - void TextureInterpolationChanged(); - /// - /// Invoked when the color action changed - /// - void TextureInterpolationToggled ( bool checked ); - /// - /// \brief Agreggates available colormaps - /// - void ColormapMenuAboutToShow (); - /// - /// \brief changes the active colormap - /// - void ColormapActionToggled (bool); - /// - /// SurfaceRepresentationActionToggled - /// - void SurfaceRepresentationMenuAboutToShow (); - /// - /// SurfaceRepresentationActionToggled - /// - void SurfaceRepresentationActionToggled ( bool checked ); - /// - /// \brief Shows a node context menu. - /// - void NodeTableViewContextMenuRequested( const QPoint & index ); - /// - /// \brief Invoked when an element should be removed. - /// - void RemoveSelectedNodes( bool checked = false ); - /// - /// \brief Invoked when an element should be reinitiliased. - /// - void ReinitSelectedNodes( bool checked = false ); - /// - /// \brief Invoked when the visibility of the selected nodes should be toggled. - /// - void MakeAllNodesInvisible ( bool checked = false ); - /// - /// \brief Makes all selected nodes visible, all other nodes invisible. - /// - void ShowOnlySelectedNodes ( bool checked = false ); - /// - /// \brief Invoked when the visibility of the selected nodes should be toggled. - /// - void ToggleVisibilityOfSelectedNodes ( bool checked = false ); - /// - /// \brief Invoked when infos of the selected nodes should be shown in a dialog. - /// - void ShowInfoDialogForSelectedNodes ( bool checked = false ); - /// - /// \brief Reinits everything. - /// - void GlobalReinit ( bool checked = false ); - /// - /// Invoked when the preferences were changed - /// - void OnPreferencesChanged(const berry::IBerryPreferences*) override; - /// - /// \brief will be toggled when a extension point context menu action is toggled - /// this is a proxy method which will load the corresponding extension class - /// and run IContextMenuAction - /// - void ContextMenuActionTriggered( bool ); +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 ); + void NodeTreeViewRowsInserted(const QModelIndex& parent, int start, int end); /// will setup m_CurrentRowCount - void NodeTreeViewRowsRemoved ( const QModelIndex & parent, int start, int end ); + 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 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: - /// - /// \brief Create the view here. - /// void CreateQtPartControl(QWidget* parent) override; void SetFocus() override; - - /// - /// \brief Shows a file open dialog. - /// - void FileOpen( const char * fileName, mitk::DataNode* parentNode ); - /// /// React to node changes. Overridden from QmitkAbstractView. /// - void NodeChanged(const mitk::DataNode* /*node*/) override; + void NodeChanged(const mitk::DataNode* node) override; + protected: QWidget* m_Parent; - QmitkDnDFrameWidget* m_DndFrameWidget; + 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 datamanager. + /// Holds the preferences for the data manager. /// berry::IBerryPreferences::Pointer m_DataManagerPreferencesNode; /// - /// saves the configuration elements for the context menu actions from extension points - /// - std::map m_ConfElements; - /// /// \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. /// - QMenu* m_NodeMenu; + QmitkDataNodeContextMenu* m_DataNodeContextMenu; /// /// \brief flag indicating whether a surface created from a selected decimation is decimated with vtkQuadricDecimation or not /// bool m_SurfaceDecimation; - - ///# A list of ALL actions for the Context Menu - using DescriptorActionListType = std::vector< std::pair< QmitkNodeDescriptor*, QAction* > >; - DescriptorActionListType m_DescriptorActionList; - - /// A Slider widget to change the opacity of a node - QSlider* m_OpacitySlider; - /// A Slider widget to change the rendered vector component of an image - QmitkNumberPropertySlider* m_ComponentSlider; - /// button to change the color of a node - QPushButton* m_ColorButton; - /// TextureInterpolation action - QAction* m_TextureInterpolation; - /// SurfaceRepresentation action - QAction* m_SurfaceRepresentation; - /// Lookuptable selection action - QAction* m_ColormapAction; - /// 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 datamanager + /// saves the current amount of rows shown in the data manager size_t m_CurrentRowCount; - /// if true, GlobalReinit() is called if a node is deleted - bool m_GlobalReinitOnNodeDelete; - bool m_GlobalReinitOnNodeVisibilityChanged; - QmitkDataManagerItemDelegate* m_ItemDelegate; private: QItemSelectionModel* GetDataNodeSelectionModel() const override; - /// Reopen multi widget editor if it has been closed - mitk::IRenderWindowPart *OpenRenderWindowPart(bool activatedEditor = true); }; -#endif /*QMITKDATAMANAGERVIEW_H_*/ +#endif // QMITKDATAMANAGERVIEW_H_ diff --git a/Plugins/org.mitk.gui.qt.datamanager/src/internal/QmitkInfoDialog.cpp b/Plugins/org.mitk.gui.qt.datamanager/src/internal/QmitkInfoDialog.cpp deleted file mode 100644 index 29240dbbce..0000000000 --- a/Plugins/org.mitk.gui.qt.datamanager/src/internal/QmitkInfoDialog.cpp +++ /dev/null @@ -1,126 +0,0 @@ -/*=================================================================== - -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 "QmitkInfoDialog.h" - -#include "QmitkDataStorageComboBox.h" - -#include - -#include -#include -#include -#include -#include -#include - -QmitkInfoDialog::QmitkInfoDialog( const QList &_Nodes, QWidget * parent /*= 0*/, Qt::WindowFlags f /*= 0 */ ) -: QDialog(parent, f) -{ - // DIM - auto parentLayout = new QGridLayout; - auto _QmitkDataStorageComboBox = new QmitkDataStorageComboBox(this, true); - m_KeyWord = new QLineEdit; - m_KeyWord->installEventFilter(this); - m_SearchButton = new QPushButton("Search (F3)", this); - m_SearchButton->installEventFilter(this); - m_TextBrowser = new QTextBrowser(this); - QPushButton* _CancelButton = new QPushButton("Cancel", this); - - // SET - this->setMinimumSize(512, 512); - this->setLayout(parentLayout); - this->setSizeGripEnabled(true); - this->setModal(true); - - parentLayout->addWidget(_QmitkDataStorageComboBox, 0, 0, 1, 2); - parentLayout->addWidget(m_KeyWord, 1, 0); - parentLayout->addWidget(m_SearchButton, 1, 1); - parentLayout->addWidget(m_TextBrowser, 2, 0, 1, 2); - parentLayout->addWidget(_CancelButton, 3, 0, 1, 2); - - QObject::connect( _QmitkDataStorageComboBox, SIGNAL( OnSelectionChanged( const mitk::DataNode* ) ) - , this, SLOT( OnSelectionChanged( const mitk::DataNode* ) ) ); - - foreach(mitk::DataNode::Pointer node, _Nodes) - { - _QmitkDataStorageComboBox->AddNode(node); - } - - QObject::connect( m_KeyWord, SIGNAL( textChanged ( const QString & ) ) - , this, SLOT( KeyWordTextChanged(const QString &) ) ); - - QObject::connect( m_SearchButton, SIGNAL( clicked ( bool ) ) - , this, SLOT( OnSearchButtonClicked( bool ) ) ); - - QObject::connect( _CancelButton, SIGNAL( clicked ( bool ) ) - , this, SLOT( OnCancelButtonClicked( bool ) ) ); - - _CancelButton->setDefault(true); - -} - -void QmitkInfoDialog::OnSelectionChanged( const mitk::DataNode* node ) -{ - std::ostringstream s; - itk::Indent i(2); - mitk::BaseData* _BaseData = node->GetData(); - if(_BaseData) - _BaseData->Print(s, i); - m_TextBrowser->setPlainText(QString::fromStdString(s.str())); -} - -void QmitkInfoDialog::OnSearchButtonClicked( bool /*checked*/ /*= false */ ) -{ - QString keyWord = m_KeyWord->text(); - QString text = m_TextBrowser->toPlainText(); - - if(keyWord.isEmpty() || text.isEmpty()) - return; - - m_TextBrowser->find(keyWord); - m_SearchButton->setText("Search Next(F3)"); -} - -void QmitkInfoDialog::OnCancelButtonClicked( bool /*checked*/ /*= false */ ) -{ - this->done(0); -} - -bool QmitkInfoDialog::eventFilter( QObject *obj, QEvent *event ) -{ - if (event->type() == QEvent::KeyPress) - { - QKeyEvent *keyEvent = static_cast(event); - if(keyEvent->key() == Qt::Key_F3 || keyEvent->key() == Qt::Key_Return) - { - // trigger deletion of selected node(s) - this->OnSearchButtonClicked(true); - // return true: this means the delete key event is not send to the table - return true; - } - } - // standard event processing - return QObject::eventFilter(obj, event); -} - -void QmitkInfoDialog::KeyWordTextChanged(const QString & /*text*/) -{ - QTextCursor textCursor = m_TextBrowser->textCursor(); - textCursor.setPosition(0); - m_TextBrowser->setTextCursor(textCursor); - m_SearchButton->setText("Search (F3)"); -} diff --git a/Plugins/org.mitk.gui.qt.datamanager/src/internal/QmitkInfoDialog.h b/Plugins/org.mitk.gui.qt.datamanager/src/internal/QmitkInfoDialog.h deleted file mode 100644 index 30a03edb08..0000000000 --- a/Plugins/org.mitk.gui.qt.datamanager/src/internal/QmitkInfoDialog.h +++ /dev/null @@ -1,50 +0,0 @@ -/*=================================================================== - -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 QMITKINFODIALOG_H_ -#define QMITKINFODIALOG_H_ - -#include - -#include - -class QTextBrowser; -class QLineEdit; - -/// -/// A small class which "eats" all Del-Key-pressed events on the node table. -/// When the Del Key is pressed selected nodes should be removed. -/// -class QmitkInfoDialog : public QDialog -{ - Q_OBJECT - - public: - QmitkInfoDialog(const QList& _Nodes, QWidget * parent = nullptr, Qt::WindowFlags f = nullptr ); - public slots: - void OnSelectionChanged(const mitk::DataNode*); - void OnSearchButtonClicked ( bool checked = false ); - void OnCancelButtonClicked ( bool checked = false ); - void KeyWordTextChanged(const QString & text); - protected: - bool eventFilter(QObject *obj, QEvent *event) override; - protected: - QLineEdit* m_KeyWord; - QPushButton* m_SearchButton; - QTextBrowser* m_TextBrowser; -}; - -#endif // QMITKINFODIALOG_H_ diff --git a/Plugins/org.mitk.gui.qt.datamanager/src/internal/QmitkNodeTableViewKeyFilter.cpp b/Plugins/org.mitk.gui.qt.datamanager/src/internal/QmitkNodeTableViewKeyFilter.cpp deleted file mode 100644 index fa6fb7f330..0000000000 --- a/Plugins/org.mitk.gui.qt.datamanager/src/internal/QmitkNodeTableViewKeyFilter.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/*=================================================================== - -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 "QmitkNodeTableViewKeyFilter.h" - -#include -#include -#include "../QmitkDataManagerView.h" - -#include "berryIPreferencesService.h" -#include "berryPlatform.h" - -QmitkNodeTableViewKeyFilter::QmitkNodeTableViewKeyFilter( QObject* _DataManagerView ) -: QObject(_DataManagerView) -{ - m_PreferencesService = berry::Platform::GetPreferencesService(); -} - -bool QmitkNodeTableViewKeyFilter::eventFilter( QObject *obj, QEvent *event ) -{ - QmitkDataManagerView* _DataManagerView = qobject_cast(this->parent()); - if (event->type() == QEvent::KeyPress && _DataManagerView) - { - berry::IPreferences::Pointer nodeTableKeyPrefs = m_PreferencesService->GetSystemPreferences()->Node("/DataManager/Hotkeys"); - - QKeySequence _MakeAllInvisible = QKeySequence(nodeTableKeyPrefs->Get("Make all nodes invisible", "Ctrl+, V")); - QKeySequence _ToggleVisibility = QKeySequence(nodeTableKeyPrefs->Get("Toggle visibility of selected nodes", "V")); - QKeySequence _DeleteSelectedNodes = QKeySequence(nodeTableKeyPrefs->Get("Delete selected nodes", "Del")); - QKeySequence _Reinit = QKeySequence(nodeTableKeyPrefs->Get("Reinit selected nodes", "R")); - QKeySequence _GlobalReinit = QKeySequence(nodeTableKeyPrefs->Get("Global Reinit", "Ctrl+, R")); - QKeySequence _ShowInfo = QKeySequence(nodeTableKeyPrefs->Get("Show Node Information", "Ctrl+, I")); - - QKeyEvent *keyEvent = static_cast(event); - - QKeySequence _KeySequence = QKeySequence(keyEvent->modifiers(), keyEvent->key()); - // if no modifier was pressed the sequence is now empty - if(_KeySequence.isEmpty()) - _KeySequence = QKeySequence(keyEvent->key()); - - if(_KeySequence == _MakeAllInvisible) - { - // trigger deletion of selected node(s) - _DataManagerView->MakeAllNodesInvisible(true); - // return true: this means the delete key event is not send to the table - return true; - } - else if(_KeySequence == _DeleteSelectedNodes) - { - // trigger deletion of selected node(s) - _DataManagerView->RemoveSelectedNodes(true); - // return true: this means the delete key event is not send to the table - return true; - } - else if(_KeySequence == _ToggleVisibility) - { - // trigger deletion of selected node(s) - _DataManagerView->ToggleVisibilityOfSelectedNodes(true); - // return true: this means the delete key event is not send to the table - return true; - } - else if(_KeySequence == _Reinit) - { - _DataManagerView->ReinitSelectedNodes(true); - return true; - } - else if(_KeySequence == _GlobalReinit) - { - _DataManagerView->GlobalReinit(true); - return true; - } - else if(_KeySequence == _ShowInfo) - { - _DataManagerView->ShowInfoDialogForSelectedNodes(true); - return true; - } - } - // standard event processing - return QObject::eventFilter(obj, event); -} diff --git a/Plugins/org.mitk.gui.qt.datamanager/src/internal/QmitkNodeTableViewKeyFilter.h b/Plugins/org.mitk.gui.qt.datamanager/src/internal/QmitkNodeTableViewKeyFilter.h deleted file mode 100644 index 2964e08356..0000000000 --- a/Plugins/org.mitk.gui.qt.datamanager/src/internal/QmitkNodeTableViewKeyFilter.h +++ /dev/null @@ -1,44 +0,0 @@ -/*=================================================================== - -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 QMITKNODETABLEVIEWKEYFILTER_H_ -#define QMITKNODETABLEVIEWKEYFILTER_H_ - -#include - -namespace berry { -struct IPreferencesService; -} - -/// -/// A small class which "eats" all Del-Key-pressed events on the node table. -/// When the Del Key is pressed selected nodes should be removed. -/// -class QmitkNodeTableViewKeyFilter : public QObject -{ - Q_OBJECT -public: - QmitkNodeTableViewKeyFilter(QObject* _DataManagerView = nullptr); -protected: - bool eventFilter(QObject *obj, QEvent *event) override; - - /// - /// The Preferences Service to retrieve and store preferences. - /// - berry::IPreferencesService* m_PreferencesService; -}; - -#endif // QMITKNODETABLEVIEWKEYFILTER_H_ diff --git a/Plugins/org.mitk.gui.qt.datamanager/src/internal/mitkPluginActivator.cpp b/Plugins/org.mitk.gui.qt.datamanager/src/internal/mitkPluginActivator.cpp index 7624f77580..d5996e14b3 100644 --- a/Plugins/org.mitk.gui.qt.datamanager/src/internal/mitkPluginActivator.cpp +++ b/Plugins/org.mitk.gui.qt.datamanager/src/internal/mitkPluginActivator.cpp @@ -1,35 +1,33 @@ /*=================================================================== 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 "mitkPluginActivator.h" #include "../QmitkDataManagerView.h" #include "../QmitkDataManagerPreferencePage.h" -#include "../QmitkDataManagerHotkeysPrefPage.h" namespace mitk { void PluginActivator::start(ctkPluginContext* context) { BERRY_REGISTER_EXTENSION_CLASS(QmitkDataManagerView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkDataManagerPreferencePage, context) - BERRY_REGISTER_EXTENSION_CLASS(QmitkDataManagerHotkeysPrefPage, context) } void PluginActivator::stop(ctkPluginContext* context) { Q_UNUSED(context) } } diff --git a/Plugins/org.mitk.gui.qt.renderwindowmanager/manifest_headers.cmake b/Plugins/org.mitk.gui.qt.renderwindowmanager/manifest_headers.cmake index 047fb72062..72676e48b5 100644 --- a/Plugins/org.mitk.gui.qt.renderwindowmanager/manifest_headers.cmake +++ b/Plugins/org.mitk.gui.qt.renderwindowmanager/manifest_headers.cmake @@ -1,5 +1,5 @@ set(Plugin-Name "MITK Render window layer manager") set(Plugin-Version "0.1") set(Plugin-Vendor "DKFZ") set(Plugin-ContactAddress "http://www.mitk.org") -set(Require-Plugin org.mitk.gui.qt.common) +set(Require-Plugin org.mitk.gui.qt.application org.mitk.gui.qt.common) diff --git a/Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkRenderWindowManagerView.cpp b/Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkRenderWindowManagerView.cpp index 78e159649f..b3b5016eb4 100644 --- a/Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkRenderWindowManagerView.cpp +++ b/Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkRenderWindowManagerView.cpp @@ -1,72 +1,83 @@ /*=================================================================== 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. ===================================================================*/ // render window manager plugin #include "QmitkRenderWindowManagerView.h" // mitk core #include #include const std::string QmitkRenderWindowManagerView::VIEW_ID = "org.mitk.views.renderwindowmanager"; void QmitkRenderWindowManagerView::SetFocus() { // nothing here } void QmitkRenderWindowManagerView::CreateQtPartControl(QWidget* parent) { // create GUI widgets m_Controls.setupUi(parent); // add custom render window manager UI widget to the 'renderWindowManagerTab' m_RenderWindowInspector = new QmitkDataStorageRenderWindowInspector(parent); m_RenderWindowInspector->SetDataStorage(GetDataStorage()); m_RenderWindowInspector->setObjectName(QStringLiteral("m_RenderWindowManipulatorWidget")); m_Controls.verticalLayout->addWidget(m_RenderWindowInspector); SetControlledRenderer(); for (const auto& renderer : m_ControlledRenderer) { m_Controls.comboBoxRenderWindowSelection->addItem(renderer->GetName()); } OnRenderWindowSelectionChanged(m_Controls.comboBoxRenderWindowSelection->itemText(0)); - connect(m_Controls.comboBoxRenderWindowSelection, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(OnRenderWindowSelectionChanged(const QString&))); + + // data node context menu and menu actions + m_InspectorView = m_RenderWindowInspector->GetView(); + m_DataNodeContextMenu = new QmitkDataNodeContextMenu(GetSite(), m_InspectorView); + m_DataNodeContextMenu->SetDataStorage(GetDataStorage()); + //m_DataNodeContextMenu->SetSurfaceDecimation(m_SurfaceDecimation); + connect(m_InspectorView, SIGNAL(customContextMenuRequested(const QPoint&)), m_DataNodeContextMenu, SLOT(OnContextMenuRequested(const QPoint&))); } void QmitkRenderWindowManagerView::SetControlledRenderer() { const mitk::RenderingManager::RenderWindowVector allRegisteredRenderWindows = mitk::RenderingManager::GetInstance()->GetAllRegisteredRenderWindows(); mitk::BaseRenderer* baseRenderer = nullptr; for (const auto &renderWindow : allRegisteredRenderWindows) { baseRenderer = mitk::BaseRenderer::GetInstance(renderWindow); if (nullptr != baseRenderer) { m_ControlledRenderer.push_back(baseRenderer); } } m_RenderWindowInspector->SetControlledRenderer(m_ControlledRenderer); } void QmitkRenderWindowManagerView::OnRenderWindowSelectionChanged(const QString &renderWindowId) { m_RenderWindowInspector->SetActiveRenderWindow(renderWindowId); } + +QItemSelectionModel* QmitkRenderWindowManagerView::GetDataNodeSelectionModel() const +{ + return m_InspectorView->selectionModel(); +} diff --git a/Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkRenderWindowManagerView.h b/Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkRenderWindowManagerView.h index 1c1cbdcff1..e94bf0afac 100644 --- a/Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkRenderWindowManagerView.h +++ b/Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkRenderWindowManagerView.h @@ -1,66 +1,75 @@ /*=================================================================== 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 QMITKRENDERWINDOWMANAGERVIEW_H #define QMITKRENDERWINDOWMANAGERVIEW_H // render window manager plugin #include "ui_QmitkRenderWindowManagerControls.h" // render window manager UI module #include +// mitk gui qt application +#include + // mitk gui qt common plugin #include /** * @brief RenderWindowManager */ class QmitkRenderWindowManagerView : public QmitkAbstractView { Q_OBJECT public: static const std::string VIEW_ID; protected: virtual void SetFocus() override; virtual void CreateQtPartControl(QWidget* parent) override; private Q_SLOTS: /** * @brief Called when the user changes the render window selection in the combo box. * * @param renderWindowId The text inside the combo box. */ void OnRenderWindowSelectionChanged(const QString &renderWindowId); private: void SetControlledRenderer(); QWidget* m_Parent; Ui::QmitkRenderWindowManagerControls m_Controls; QmitkDataStorageRenderWindowInspector* m_RenderWindowInspector; + QmitkDataNodeContextMenu* m_DataNodeContextMenu; + QAbstractItemView* m_InspectorView; + mitk::RenderWindowLayerUtilities::RendererVector m_ControlledRenderer; + + virtual QItemSelectionModel* GetDataNodeSelectionModel() const override; + }; #endif // QMITKRENDERWINDOWMANAGERVIEW_H diff --git a/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationView.cpp b/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationView.cpp index 38476db4cc..e3a88a5d86 100644 --- a/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationView.cpp +++ b/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationView.cpp @@ -1,1127 +1,1125 @@ /*=================================================================== 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 #include "mitkProperties.h" #include "mitkSegTool2D.h" #include "mitkStatusBar.h" #include "QmitkNewSegmentationDialog.h" #include #include #include #include "QmitkSegmentationView.h" #include #include "mitkVtkResliceInterpolationProperty.h" #include "mitkApplicationCursor.h" #include "mitkSegmentationObjectFactory.h" #include "mitkPluginActivator.h" #include "mitkCameraController.h" #include "mitkLabelSetImage.h" #include #include "usModuleResource.h" #include "usModuleResourceStream.h" //micro service to get the ToolManager instance #include "mitkToolManagerProvider.h" +#include + const std::string QmitkSegmentationView::VIEW_ID = "org.mitk.views.segmentation"; QmitkSegmentationView::QmitkSegmentationView() : m_Parent(nullptr) , m_Controls(nullptr) , m_RenderWindowPart(nullptr) , m_MouseCursorSet(false) , m_DataSelectionChanged(false) , m_AutoSelectionEnabled(false) { mitk::TNodePredicateDataType::Pointer isImage = mitk::TNodePredicateDataType::New(); mitk::NodePredicateDataType::Pointer isDwi = mitk::NodePredicateDataType::New("DiffusionImage"); mitk::NodePredicateDataType::Pointer isDti = mitk::NodePredicateDataType::New("TensorImage"); mitk::NodePredicateDataType::Pointer isOdf = mitk::NodePredicateDataType::New("OdfImage"); auto isSegment = mitk::NodePredicateDataType::New("Segment"); mitk::NodePredicateOr::Pointer validImages = mitk::NodePredicateOr::New(); validImages->AddPredicate(mitk::NodePredicateAnd::New(isImage, mitk::NodePredicateNot::New(isSegment))); validImages->AddPredicate(isDwi); validImages->AddPredicate(isDti); validImages->AddPredicate(isOdf); mitk::NodePredicateNot::Pointer isNotAHelperObject = mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("helper object", mitk::BoolProperty::New(true))); m_IsOfTypeImagePredicate = mitk::NodePredicateAnd::New(validImages, isNotAHelperObject); mitk::NodePredicateProperty::Pointer isBinaryPredicate = mitk::NodePredicateProperty::New("binary", mitk::BoolProperty::New(true)); mitk::NodePredicateNot::Pointer isNotBinaryPredicate = mitk::NodePredicateNot::New(isBinaryPredicate); mitk::NodePredicateAnd::Pointer isABinaryImagePredicate = mitk::NodePredicateAnd::New(m_IsOfTypeImagePredicate, isBinaryPredicate); mitk::NodePredicateAnd::Pointer isNotABinaryImagePredicate = mitk::NodePredicateAnd::New(m_IsOfTypeImagePredicate, isNotBinaryPredicate); m_IsASegmentationImagePredicate = mitk::NodePredicateOr::New(isABinaryImagePredicate, mitk::TNodePredicateDataType::New()); m_IsAPatientImagePredicate = mitk::NodePredicateAnd::New(isNotABinaryImagePredicate, mitk::NodePredicateNot::New(mitk::TNodePredicateDataType::New())); } QmitkSegmentationView::~QmitkSegmentationView() { if (m_Controls) { SetToolSelectionBoxesEnabled(false); // deactivate all tools mitk::ToolManagerProvider::GetInstance()->GetToolManager()->ActivateTool(-1); // removing all observers for (NodeTagMapType::iterator dataIter = m_WorkingDataObserverTags.begin(); dataIter != m_WorkingDataObserverTags.end(); ++dataIter) { (*dataIter).first->GetProperty("visible")->RemoveObserver((*dataIter).second); } m_WorkingDataObserverTags.clear(); for (NodeTagMapType::iterator dataIter = m_BinaryPropertyObserverTags.begin(); dataIter != m_BinaryPropertyObserverTags.end(); ++dataIter) { (*dataIter).first->GetProperty("binary")->RemoveObserver((*dataIter).second); } m_BinaryPropertyObserverTags.clear(); mitk::RenderingManager::GetInstance()->RemoveObserver(m_RenderingManagerObserverTag); ctkPluginContext* context = mitk::PluginActivator::getContext(); ctkServiceReference ppmRef = context->getServiceReference(); mitk::PlanePositionManagerService* service = context->getService(ppmRef); service->RemoveAllPlanePositions(); context->ungetService(ppmRef); SetToolManagerSelection(0, 0); } delete m_Controls; } void QmitkSegmentationView::NewNodesGenerated() { MITK_WARN << "Use of deprecated function: NewNodesGenerated!! This function is empty and will be removed in the next time!"; } void QmitkSegmentationView::NewNodeObjectsGenerated(mitk::ToolManager::DataVectorType* nodes) { if (!nodes) return; mitk::ToolManager* toolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager(); if (!toolManager) return; for (mitk::ToolManager::DataVectorType::iterator iter = nodes->begin(); iter != nodes->end(); ++iter) { this->FireNodeSelected( *iter ); // only last iteration meaningful, multiple generated objects are not taken into account here } } void QmitkSegmentationView::Visible() { } void QmitkSegmentationView::Hidden() { } void QmitkSegmentationView::Activated() { } void QmitkSegmentationView::Deactivated() { } void QmitkSegmentationView::RenderWindowPartActivated(mitk::IRenderWindowPart* renderWindowPart) { if (m_RenderWindowPart != renderWindowPart) { m_RenderWindowPart = renderWindowPart; } if (m_Parent) { m_Parent->setEnabled(true); } // tell the interpolation about tool manager, data storage and render window part if (m_Controls) { mitk::ToolManager* toolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager(); m_Controls->m_SlicesInterpolator->SetDataStorage(this->GetDataStorage()); QList controllers; controllers.push_back(renderWindowPart->GetQmitkRenderWindow("axial")->GetSliceNavigationController()); controllers.push_back(renderWindowPart->GetQmitkRenderWindow("sagittal")->GetSliceNavigationController()); controllers.push_back(renderWindowPart->GetQmitkRenderWindow("coronal")->GetSliceNavigationController()); m_Controls->m_SlicesInterpolator->Initialize(toolManager, controllers); } } void QmitkSegmentationView::RenderWindowPartDeactivated(mitk::IRenderWindowPart* /*renderWindowPart*/) { m_RenderWindowPart = nullptr; if (m_Parent) { m_Parent->setEnabled(false); } } void QmitkSegmentationView::OnPreferencesChanged(const berry::IBerryPreferences* prefs) { if (m_Controls != nullptr) { bool slimView = prefs->GetBool("slim view", false); m_Controls->m_ManualToolSelectionBox2D->SetShowNames(!slimView); m_Controls->m_ManualToolSelectionBox3D->SetShowNames(!slimView); m_Controls->btnNewSegmentation->setToolButtonStyle(slimView ? Qt::ToolButtonIconOnly : Qt::ToolButtonTextOnly); } m_AutoSelectionEnabled = prefs->GetBool("auto selection", false); this->ForceDisplayPreferencesUponAllImages(); } void QmitkSegmentationView::CreateNewSegmentation() { mitk::DataNode::Pointer node = mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetReferenceData(0); if (node.IsNotNull()) { mitk::Image::Pointer image = dynamic_cast(node->GetData()); if (image.IsNotNull()) { if (image->GetDimension() > 1) { // ask about the name and organ type of the new segmentation QmitkNewSegmentationDialog* dialog = new QmitkNewSegmentationDialog(m_Parent); // needs a QWidget as parent, "this" is not QWidget QStringList organColors = mitk::OrganNamesHandling::GetDefaultOrganColorString();; dialog->SetSuggestionList(organColors); int dialogReturnValue = dialog->exec(); if (dialogReturnValue == QDialog::Rejected) { // user clicked cancel or pressed Esc or something similar return; } // ask the user about an organ type and name, add this information to the image's (!) propertylist // create a new image of the same dimensions and smallest possible pixel type mitk::ToolManager* toolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager(); mitk::Tool* firstTool = toolManager->GetToolById(0); if (firstTool) { try { std::string newNodeName = dialog->GetSegmentationName().toStdString(); if (newNodeName.empty()) { newNodeName = "no_name"; } mitk::DataNode::Pointer emptySegmentation = firstTool->CreateEmptySegmentationNode(image, newNodeName, dialog->GetColor()); // initialize showVolume to false to prevent recalculating the volume while working on the segmentation emptySegmentation->SetProperty("showVolume", mitk::BoolProperty::New(false)); if (!emptySegmentation) { return; // could be aborted by user } mitk::OrganNamesHandling::UpdateOrganList(organColors, dialog->GetSegmentationName(), dialog->GetColor()); // escape ';' here (replace by '\;'), see longer comment above QString stringForStorage = organColors.replaceInStrings(";", "\\;").join(";"); MITK_DEBUG << "Will store: " << stringForStorage; this->GetPreferences()->Put("Organ-Color-List", stringForStorage); this->GetPreferences()->Flush(); if (mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetWorkingData(0)) { mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetWorkingData(0)->SetSelected(false); } emptySegmentation->SetSelected(true); this->GetDataStorage()->Add(emptySegmentation, node); // add as a child, because the segmentation "derives" from the original this->FireNodeSelected(emptySegmentation); this->OnSelectionChanged(emptySegmentation); m_Controls->segImageSelector->SetSelectedNode(emptySegmentation); mitk::RenderingManager::GetInstance()->InitializeViews(emptySegmentation->GetData()->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true); } catch (std::bad_alloc) { QMessageBox::warning(nullptr, tr("Create new segmentation"), tr("Could not allocate memory for new segmentation")); } } } else { QMessageBox::information(nullptr, tr("Segmentation"), tr("Segmentation is currently not supported for 2D images")); } } } else { MITK_ERROR << "'Create new segmentation' button should never be clickable unless a patient image is selected..."; } } void QmitkSegmentationView::OnVisiblePropertyChanged() { mitk::DataNode* selectedNode = m_Controls->segImageSelector->GetSelectedNode(); if ( !selectedNode ) { this->SetToolSelectionBoxesEnabled(false); return; } mitk::IRenderWindowPart* renderWindowPart = this->GetRenderWindowPart(); bool selectedNodeIsVisible = renderWindowPart && selectedNode->IsVisible(renderWindowPart->GetQmitkRenderWindow("axial")->GetRenderer()); if (!selectedNodeIsVisible) { this->SetToolSelectionBoxesEnabled(false); this->UpdateWarningLabel(tr("The selected segmentation is currently not visible!")); } else { this->SetToolSelectionBoxesEnabled(true); this->UpdateWarningLabel(""); } } void QmitkSegmentationView::OnBinaryPropertyChanged() { mitk::DataStorage::SetOfObjects::ConstPointer patImages = m_Controls->patImageSelector->GetNodes(); for (mitk::DataStorage::SetOfObjects::ConstIterator it = patImages->Begin(); it != patImages->End(); ++it) { const mitk::DataNode* node = it->Value(); if(m_IsASegmentationImagePredicate->CheckNode(node)) { m_Controls->patImageSelector->RemoveNode(node); m_Controls->segImageSelector->AddNode(node); this->SetToolManagerSelection(nullptr,nullptr); return; } } mitk::DataStorage::SetOfObjects::ConstPointer segImages = m_Controls->segImageSelector->GetNodes(); for (mitk::DataStorage::SetOfObjects::ConstIterator it = segImages->Begin(); it != segImages->End(); ++it) { const mitk::DataNode* node = it->Value(); if(!m_IsASegmentationImagePredicate->CheckNode(node)) { m_Controls->segImageSelector->RemoveNode(node); m_Controls->patImageSelector->AddNode(node); if (mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetWorkingData(0) == node) { mitk::ToolManagerProvider::GetInstance()->GetToolManager()->SetWorkingData(nullptr); } return; } } } void QmitkSegmentationView::NodeAdded(const mitk::DataNode *node) { if (!m_IsOfTypeImagePredicate->CheckNode(node)) { return; } itk::SimpleMemberCommand::Pointer command = itk::SimpleMemberCommand::New(); command->SetCallbackFunction(this, &QmitkSegmentationView::OnVisiblePropertyChanged); m_WorkingDataObserverTags.insert(std::pair(const_cast(node), node->GetProperty("visible")->AddObserver(itk::ModifiedEvent(), command))); itk::SimpleMemberCommand::Pointer command2 = itk::SimpleMemberCommand::New(); command2->SetCallbackFunction(this, &QmitkSegmentationView::OnBinaryPropertyChanged); m_BinaryPropertyObserverTags.insert(std::pair(const_cast(node), node->GetProperty("binary")->AddObserver(itk::ModifiedEvent(), command2))); ApplyDisplayOptions(const_cast(node)); } void QmitkSegmentationView::NodeRemoved(const mitk::DataNode* node) { if (m_IsASegmentationImagePredicate->CheckNode(node)) { //First of all remove all possible contour markers of the segmentation mitk::DataStorage::SetOfObjects::ConstPointer allContourMarkers = this->GetDataStorage()->GetDerivations(node, mitk::NodePredicateProperty::New("isContourMarker", mitk::BoolProperty::New(true))); ctkPluginContext* context = mitk::PluginActivator::getContext(); ctkServiceReference ppmRef = context->getServiceReference(); mitk::PlanePositionManagerService* service = context->getService(ppmRef); for (mitk::DataStorage::SetOfObjects::ConstIterator it = allContourMarkers->Begin(); it != allContourMarkers->End(); ++it) { std::string nodeName = node->GetName(); unsigned int t = nodeName.find_last_of(" "); unsigned int id = atof(nodeName.substr(t + 1).c_str()) - 1; service->RemovePlanePosition(id); this->GetDataStorage()->Remove(it->Value()); } context->ungetService(ppmRef); service = nullptr; if ((mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetWorkingData(0) == node) && m_Controls->patImageSelector->GetSelectedNode().IsNotNull()) { this->SetToolManagerSelection(mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetReferenceData(0), nullptr); this->UpdateWarningLabel(tr("Select or create a segmentation")); } mitk::Image* image = dynamic_cast(node->GetData()); mitk::SurfaceInterpolationController::GetInstance()->RemoveInterpolationSession(image); } mitk::DataNode* tempNode = const_cast(node); //Since the binary property could be changed during runtime by the user if (m_IsOfTypeImagePredicate->CheckNode(node)) { node->GetProperty("visible")->RemoveObserver(m_WorkingDataObserverTags[tempNode]); m_WorkingDataObserverTags.erase(tempNode); node->GetProperty("binary")->RemoveObserver(m_BinaryPropertyObserverTags[tempNode]); m_BinaryPropertyObserverTags.erase(tempNode); } if (mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetReferenceData(0) == node) { //as we don't know which node was actually removed e.g. our reference node, disable 'New Segmentation' button. //consider the case that there is no more image in the datastorage this->SetToolManagerSelection(nullptr, nullptr); this->SetToolSelectionBoxesEnabled(false); } } void QmitkSegmentationView::OnPatientComboBoxSelectionChanged( const mitk::DataNode* node ) { //mitk::DataNode* selectedNode = const_cast(node); if( node != nullptr ) { this->UpdateWarningLabel(""); mitk::DataNode* segNode = m_Controls->segImageSelector->GetSelectedNode(); if (segNode) { mitk::DataStorage::SetOfObjects::ConstPointer possibleParents = this->GetDataStorage()->GetSources(segNode, m_IsAPatientImagePredicate); bool isSourceNode(false); for (mitk::DataStorage::SetOfObjects::ConstIterator it = possibleParents->Begin(); it != possibleParents->End(); it++) { if (it.Value() == node) isSourceNode = true; } if ( !isSourceNode && (!this->CheckForSameGeometry(segNode, node) || possibleParents->Size() > 0 )) { this->SetToolManagerSelection(node, nullptr); this->SetToolSelectionBoxesEnabled( false ); this->UpdateWarningLabel(tr("The selected patient image does not match with the selected segmentation!")); } else if ((!isSourceNode && this->CheckForSameGeometry(segNode, node)) || isSourceNode ) { this->SetToolManagerSelection(node, segNode); //Doing this we can assure that the segmenation is always visible if the segmentation and the patient image are //loaded separately int layer(10); node->GetIntProperty("layer", layer); layer++; segNode->SetProperty("layer", mitk::IntProperty::New(layer)); //this->UpdateWarningLabel(""); RenderingManagerReinitialized(); } } else { this->SetToolManagerSelection(node, nullptr); this->SetToolSelectionBoxesEnabled( false ); this->UpdateWarningLabel(tr("Select or create a segmentation")); } } else { this->UpdateWarningLabel(tr("Please load an image!")); this->SetToolSelectionBoxesEnabled( false ); } } void QmitkSegmentationView::OnSegmentationComboBoxSelectionChanged(const mitk::DataNode *node) { if (node == nullptr) { this->UpdateWarningLabel(tr("Select or create a segmentation")); this->SetToolSelectionBoxesEnabled( false ); return; } mitk::DataNode* refNode = m_Controls->patImageSelector->GetSelectedNode(); RenderingManagerReinitialized(); if ( m_Controls->lblSegmentationWarnings->isVisible()) // "RenderingManagerReinitialized()" caused a warning. we do not need to go any further return; if (m_AutoSelectionEnabled) { this->OnSelectionChanged(const_cast(node)); } else { mitk::DataStorage::SetOfObjects::ConstPointer possibleParents = this->GetDataStorage()->GetSources(node, m_IsAPatientImagePredicate); if ( possibleParents->Size() == 1 ) { mitk::DataNode* parentNode = possibleParents->ElementAt(0); if (parentNode != refNode) { this->UpdateWarningLabel(tr("The selected segmentation does not match with the selected patient image!")); this->SetToolSelectionBoxesEnabled( false ); this->SetToolManagerSelection(nullptr, node); } else { this->UpdateWarningLabel(""); this->SetToolManagerSelection(refNode, node); } } else if (refNode && this->CheckForSameGeometry(node, refNode)) { this->UpdateWarningLabel(""); this->SetToolManagerSelection(refNode, node); } else if (!refNode || !this->CheckForSameGeometry(node, refNode)) { this->UpdateWarningLabel(tr("Please select or load the according patient image!")); } } mitk::IRenderWindowPart* renderWindowPart = this->GetRenderWindowPart(); if (!renderWindowPart || !node->IsVisible(renderWindowPart->GetQmitkRenderWindow("axial")->GetRenderer())) { this->UpdateWarningLabel(tr("The selected segmentation is currently not visible!")); this->SetToolSelectionBoxesEnabled( false ); } } void QmitkSegmentationView::OnShowMarkerNodes (bool state) { mitk::SegTool2D::Pointer manualSegmentationTool; unsigned int numberOfExistingTools = mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetTools().size(); for(unsigned int i = 0; i < numberOfExistingTools; i++) { manualSegmentationTool = dynamic_cast(mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetToolById(i)); if (manualSegmentationTool) { if(state == true) { manualSegmentationTool->SetShowMarkerNodes( true ); } else { manualSegmentationTool->SetShowMarkerNodes( false ); } } } } void QmitkSegmentationView::OnSelectionChanged(mitk::DataNode* node) { berry::IWorkbenchPart::Pointer nullPart; QList nodes; nodes.push_back(node); this->OnSelectionChanged(nullPart, nodes); } void QmitkSegmentationView::OnSelectionChanged(berry::IWorkbenchPart::Pointer /*part*/, const QList& nodes) { if (nodes.size() != 0) { std::string markerName = "Position"; unsigned int numberOfNodes = nodes.size(); std::string nodeName = nodes.at(0)->GetName(); if ((numberOfNodes == 1) && (nodeName.find(markerName) == 0)) { OnContourMarkerSelected(nodes.at(0)); return; } } if (m_AutoSelectionEnabled) { if (nodes.size() == 0 && m_Controls->patImageSelector->GetSelectedNode().IsNull()) { SetToolManagerSelection(nullptr, nullptr); } else if (nodes.size() == 1) { mitk::DataNode::Pointer selectedNode = nodes.at(0); if (selectedNode.IsNull()) { return; } mitk::Image::Pointer selectedImage = dynamic_cast(selectedNode->GetData()); if (selectedImage.IsNull()) { SetToolManagerSelection(nullptr, nullptr); return; } if (m_IsASegmentationImagePredicate->CheckNode(selectedNode)) { // set all nodes to invisible mitk::DataStorage::SetOfObjects::ConstPointer allImages = GetDataStorage()->GetSubset(m_IsOfTypeImagePredicate); for (mitk::DataStorage::SetOfObjects::const_iterator iter = allImages->begin(); iter != allImages->end(); ++iter) { (*iter)->SetVisibility(false); } // if a segmentation is selected find a possible patient image mitk::DataStorage::SetOfObjects::ConstPointer sources = GetDataStorage()->GetSources(selectedNode, m_IsAPatientImagePredicate); mitk::DataNode::Pointer refNode; if (sources->Size() != 0) { // found one or more sources - use the first one refNode = sources->ElementAt(0); refNode->SetVisibility(true); selectedNode->SetVisibility(true); SetToolManagerSelection(refNode, selectedNode); } else { // did not find a source / patient image, check all images and compare geometry mitk::DataStorage::SetOfObjects::ConstPointer possiblePatientImages = GetDataStorage()->GetSubset(m_IsAPatientImagePredicate); for (mitk::DataStorage::SetOfObjects::ConstIterator iter = possiblePatientImages->Begin(); iter != possiblePatientImages->End(); ++iter) { refNode = iter->Value(); if (CheckForSameGeometry(selectedNode, iter->Value())) { refNode->SetVisibility(true); selectedNode->SetVisibility(true); SetToolManagerSelection(refNode, selectedNode); // doing this we can assure that the segmentation is always visible if the segmentation and the patient image are at the // same level in the data manager int layer(10); refNode->GetIntProperty("layer", layer); layer++; selectedNode->SetProperty("layer", mitk::IntProperty::New(layer)); return; } } // did not find a source / patient image with the same geometry SetToolManagerSelection(nullptr, selectedNode); } mitk::RenderingManager::GetInstance()->InitializeViews(selectedNode->GetData()->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true); } else { if (mitk::ToolManagerProvider::GetInstance()->GetToolManager()->GetReferenceData(0) != selectedNode) { SetToolManagerSelection(selectedNode, nullptr); // may be a bug in the selection services. A node which is deselected will be passed as selected node to the OnSelectionChanged function mitk::IRenderWindowPart* renderWindowPart = GetRenderWindowPart(); if (renderWindowPart && !selectedNode->IsVisible(renderWindowPart->GetQmitkRenderWindow("axial")->GetRenderer())) { selectedNode->SetVisibility(true); } UpdateWarningLabel(tr("The selected patient image does not match with the selected segmentation!")); SetToolSelectionBoxesEnabled(false); } } } if (m_Controls->lblSegmentationWarnings->isVisible()) // "RenderingManagerReinitialized()" caused a warning. we do not need to go any further { return; } RenderingManagerReinitialized(); } } void QmitkSegmentationView::OnContourMarkerSelected(const mitk::DataNode *node) { QmitkRenderWindow* selectedRenderWindow = 0; - QmitkRenderWindow* axialRenderWindow = - this->GetRenderWindowPart(OPEN)->GetQmitkRenderWindow("axial"); - QmitkRenderWindow* sagittalRenderWindow = - this->GetRenderWindowPart(OPEN)->GetQmitkRenderWindow("sagittal"); - QmitkRenderWindow* coronalRenderWindow = - this->GetRenderWindowPart(OPEN)->GetQmitkRenderWindow("coronal"); - QmitkRenderWindow* _3DRenderWindow = - this->GetRenderWindowPart(OPEN)->GetQmitkRenderWindow("3d"); + QmitkRenderWindow* axialRenderWindow = GetRenderWindowPart(mitk::WorkbenchUtil::OPEN)->GetQmitkRenderWindow("axial"); + QmitkRenderWindow* sagittalRenderWindow = GetRenderWindowPart(mitk::WorkbenchUtil::OPEN)->GetQmitkRenderWindow("sagittal"); + QmitkRenderWindow* coronalRenderWindow = GetRenderWindowPart(mitk::WorkbenchUtil::OPEN)->GetQmitkRenderWindow("coronal"); + QmitkRenderWindow* _3DRenderWindow = GetRenderWindowPart(mitk::WorkbenchUtil::OPEN)->GetQmitkRenderWindow("3d"); bool PlanarFigureInitializedWindow = false; // find initialized renderwindow if (node->GetBoolProperty("PlanarFigureInitializedWindow", PlanarFigureInitializedWindow, axialRenderWindow->GetRenderer())) { selectedRenderWindow = axialRenderWindow; } if (!selectedRenderWindow && node->GetBoolProperty( "PlanarFigureInitializedWindow", PlanarFigureInitializedWindow, sagittalRenderWindow->GetRenderer())) { selectedRenderWindow = sagittalRenderWindow; } if (!selectedRenderWindow && node->GetBoolProperty( "PlanarFigureInitializedWindow", PlanarFigureInitializedWindow, coronalRenderWindow->GetRenderer())) { selectedRenderWindow = coronalRenderWindow; } if (!selectedRenderWindow && node->GetBoolProperty( "PlanarFigureInitializedWindow", PlanarFigureInitializedWindow, _3DRenderWindow->GetRenderer())) { selectedRenderWindow = _3DRenderWindow; } // make node visible if (selectedRenderWindow) { std::string nodeName = node->GetName(); unsigned int t = nodeName.find_last_of(" "); unsigned int id = atof(nodeName.substr(t+1).c_str())-1; { ctkPluginContext* context = mitk::PluginActivator::getContext(); ctkServiceReference ppmRef = context->getServiceReference(); mitk::PlanePositionManagerService* service = context->getService(ppmRef); selectedRenderWindow->GetSliceNavigationController()->ExecuteOperation(service->GetPlanePosition(id)); context->ungetService(ppmRef); } selectedRenderWindow->GetRenderer()->GetCameraController()->Fit(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkSegmentationView::OnTabWidgetChanged(int id) { //always disable tools on tab changed mitk::ToolManagerProvider::GetInstance()->GetToolManager()->ActivateTool(-1); //2D Tab ID = 0 //3D Tab ID = 1 if (id == 0) { //Hide 3D selection box, show 2D selection box m_Controls->m_ManualToolSelectionBox3D->hide(); m_Controls->m_ManualToolSelectionBox2D->show(); //Deactivate possible active tool //TODO Remove possible visible interpolations -> Maybe changes in SlicesInterpolator } else { //Hide 3D selection box, show 2D selection box m_Controls->m_ManualToolSelectionBox2D->hide(); m_Controls->m_ManualToolSelectionBox3D->show(); //Deactivate possible active tool } } void QmitkSegmentationView::InitToolManagerSelection(const mitk::DataNode* referenceData, const mitk::DataNode* workingData) { // initial tool manager selection, called from 'CreateQtPartControl' mitk::ToolManager* toolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager(); toolManager->SetReferenceData(const_cast(referenceData)); toolManager->SetWorkingData(const_cast(workingData)); // check original image m_Controls->btnNewSegmentation->setEnabled(referenceData != nullptr); if (referenceData) { UpdateWarningLabel(""); } } void QmitkSegmentationView::SetToolManagerSelection(const mitk::DataNode* referenceData, const mitk::DataNode* workingData) { // called as a result of new BlueBerry selections // tells the ToolManager for manual segmentation about new selections // updates GUI information about what the user should select mitk::ToolManager* toolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager(); toolManager->SetReferenceData(const_cast(referenceData)); toolManager->SetWorkingData(const_cast(workingData)); // check original image m_Controls->btnNewSegmentation->setEnabled(referenceData != nullptr); if (referenceData) { UpdateWarningLabel(""); disconnect(m_Controls->patImageSelector, SIGNAL(OnSelectionChanged(const mitk::DataNode*)), this, SLOT(OnPatientComboBoxSelectionChanged(const mitk::DataNode*))); m_Controls->patImageSelector->setCurrentIndex(m_Controls->patImageSelector->Find(referenceData)); connect(m_Controls->patImageSelector, SIGNAL(OnSelectionChanged(const mitk::DataNode*)), this, SLOT(OnPatientComboBoxSelectionChanged(const mitk::DataNode*))); // check segmentation if (workingData) { //FireNodeSelected(const_cast(workingData)); disconnect(m_Controls->segImageSelector, SIGNAL(OnSelectionChanged(const mitk::DataNode*)), this, SLOT(OnSegmentationComboBoxSelectionChanged(const mitk::DataNode*))); m_Controls->segImageSelector->setCurrentIndex(m_Controls->segImageSelector->Find(workingData)); connect(m_Controls->segImageSelector, SIGNAL(OnSelectionChanged(const mitk::DataNode*)), this, SLOT(OnSegmentationComboBoxSelectionChanged(const mitk::DataNode*))); } } } void QmitkSegmentationView::ForceDisplayPreferencesUponAllImages() { if (!m_Parent) { return; } // check all images and segmentations in DataStorage: // (items in brackets are implicitly done by previous steps) // 1. // if a reference image is selected, // show the reference image // and hide all other images (orignal and segmentation), // (and hide all segmentations of the other original images) // and show all the reference's segmentations // if no reference image is selected, do do nothing // // 2. // if a segmentation is selected, // show it // (and hide all all its siblings (childs of the same parent, incl, nullptr parent)) // if no segmentation is selected, do nothing if (!m_Controls) { return; // might happen on initialization (preferences loaded) } mitk::ToolManager* toolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager(); mitk::DataNode::Pointer referenceData = toolManager->GetReferenceData(0); mitk::DataNode::Pointer workingData = toolManager->GetWorkingData(0); // 1. if (referenceData.IsNotNull()) { // iterate all images mitk::DataStorage::SetOfObjects::ConstPointer allImages = this->GetDataStorage()->GetSubset(m_IsASegmentationImagePredicate); for ( mitk::DataStorage::SetOfObjects::const_iterator iter = allImages->begin(); iter != allImages->end(); ++iter) { mitk::DataNode* node = *iter; // apply display preferences ApplyDisplayOptions(node); // set visibility node->SetVisibility(node == referenceData); } } // 2. if (workingData.IsNotNull()) workingData->SetVisibility(true); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkSegmentationView::ApplyDisplayOptions(mitk::DataNode* node) { if (!node) { return; } mitk::BoolProperty::Pointer drawOutline = mitk::BoolProperty::New(GetPreferences()->GetBool("draw outline", true)); mitk::BoolProperty::Pointer volumeRendering = mitk::BoolProperty::New(GetPreferences()->GetBool("volume rendering", false)); mitk::LabelSetImage* labelSetImage = dynamic_cast(node->GetData()); if (nullptr != labelSetImage) { // node is actually a multi label segmentation, // but its outline property can be set in the 'single label' segmentation preference page as well node->SetProperty("labelset.contour.active", drawOutline); node->SetProperty("opacity", mitk::FloatProperty::New(drawOutline->GetValue() ? 1.0f : 0.3f)); node->SetProperty("volumerendering", volumeRendering); // force render window update to show outline node->GetData()->Modified(); } else { // node is a 'single label' segmentation bool isBinary = false; node->GetBoolProperty("binary", isBinary); if (isBinary) { node->SetProperty("outline binary", drawOutline); node->SetProperty("outline width", mitk::FloatProperty::New(2.0)); node->SetProperty("opacity", mitk::FloatProperty::New(drawOutline->GetValue() ? 1.0f : 0.3f)); node->SetProperty("volumerendering", volumeRendering); // force render window update to show outline node->GetData()->Modified(); } } } void QmitkSegmentationView::RenderingManagerReinitialized() { if (!this->GetRenderWindowPart()) { return; } /* * Here we check whether the geometry of the selected segmentation image if aligned with the worldgeometry * At the moment it is not supported to use a geometry different from the selected image for reslicing. * For further information see Bug 16063 */ mitk::DataNode* workingNode = m_Controls->segImageSelector->GetSelectedNode(); const mitk::BaseGeometry* worldGeo = this->GetRenderWindowPart()->GetQmitkRenderWindow("3d")->GetSliceNavigationController()->GetCurrentGeometry3D(); if (workingNode && worldGeo) { const mitk::BaseGeometry* workingNodeGeo = workingNode->GetData()->GetGeometry(); const mitk::BaseGeometry* worldGeo = this->GetRenderWindowPart()->GetQmitkRenderWindow("3d")->GetSliceNavigationController()->GetCurrentGeometry3D(); if (mitk::Equal(*workingNodeGeo->GetBoundingBox(), *worldGeo->GetBoundingBox(), mitk::eps, true)) { this->SetToolManagerSelection(m_Controls->patImageSelector->GetSelectedNode(), workingNode); this->SetToolSelectionBoxesEnabled(true); this->UpdateWarningLabel(""); } else { this->SetToolManagerSelection(m_Controls->patImageSelector->GetSelectedNode(), nullptr); this->SetToolSelectionBoxesEnabled(false); this->UpdateWarningLabel(tr("Please perform a reinit on the segmentation image!")); } } } bool QmitkSegmentationView::CheckForSameGeometry(const mitk::DataNode *node1, const mitk::DataNode *node2) const { bool isSameGeometry(true); mitk::Image* image1 = dynamic_cast(node1->GetData()); mitk::Image* image2 = dynamic_cast(node2->GetData()); if (image1 && image2) { mitk::BaseGeometry* geo1 = image1->GetGeometry(); mitk::BaseGeometry* geo2 = image2->GetGeometry(); isSameGeometry = isSameGeometry && mitk::Equal(geo1->GetOrigin(), geo2->GetOrigin()); isSameGeometry = isSameGeometry && mitk::Equal(geo1->GetExtent(0), geo2->GetExtent(0)); isSameGeometry = isSameGeometry && mitk::Equal(geo1->GetExtent(1), geo2->GetExtent(1)); isSameGeometry = isSameGeometry && mitk::Equal(geo1->GetExtent(2), geo2->GetExtent(2)); isSameGeometry = isSameGeometry && mitk::Equal(geo1->GetSpacing(), geo2->GetSpacing()); isSameGeometry = isSameGeometry && mitk::MatrixEqualElementWise(geo1->GetIndexToWorldTransform()->GetMatrix(), geo2->GetIndexToWorldTransform()->GetMatrix()); return isSameGeometry; } else { return false; } } void QmitkSegmentationView::UpdateWarningLabel(QString text) { if (text.size() == 0) m_Controls->lblSegmentationWarnings->hide(); else m_Controls->lblSegmentationWarnings->show(); m_Controls->lblSegmentationWarnings->setText(text); } void QmitkSegmentationView::CreateQtPartControl(QWidget* parent) { // setup the basic GUI of this view m_Parent = parent; m_Controls = new Ui::QmitkSegmentationControls; m_Controls->setupUi(parent); m_Controls->patImageSelector->SetDataStorage(GetDataStorage()); m_Controls->patImageSelector->SetPredicate(m_IsAPatientImagePredicate); UpdateWarningLabel(tr("Please load an image")); if (m_Controls->patImageSelector->GetSelectedNode().IsNotNull()) { UpdateWarningLabel(tr("Select or create a new segmentation")); } m_Controls->segImageSelector->SetDataStorage(GetDataStorage()); m_Controls->segImageSelector->SetPredicate(m_IsASegmentationImagePredicate); if (m_Controls->segImageSelector->GetSelectedNode().IsNotNull()) { UpdateWarningLabel(""); } mitk::ToolManager* toolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager(); assert(toolManager); toolManager->SetDataStorage(*(GetDataStorage())); toolManager->InitializeTools(); // all part of open source MITK m_Controls->m_ManualToolSelectionBox2D->setEnabled(true); m_Controls->m_ManualToolSelectionBox2D->SetGenerateAccelerators(true); m_Controls->m_ManualToolSelectionBox2D->SetToolGUIArea( m_Controls->m_ManualToolGUIContainer2D ); m_Controls->m_ManualToolSelectionBox2D->SetDisplayedToolGroups(tr("Add Subtract Correction Paint Wipe 'Region Growing' Fill Erase 'Live Wire' '2D Fast Marching'").toStdString()); m_Controls->m_ManualToolSelectionBox2D->SetLayoutColumns(3); m_Controls->m_ManualToolSelectionBox2D->SetEnabledMode( QmitkToolSelectionBox::EnabledWithReferenceAndWorkingDataVisible ); connect( m_Controls->m_ManualToolSelectionBox2D, SIGNAL(ToolSelected(int)), this, SLOT(OnManualTool2DSelected(int)) ); //setup 3D Tools m_Controls->m_ManualToolSelectionBox3D->setEnabled(true); m_Controls->m_ManualToolSelectionBox3D->SetGenerateAccelerators(true); m_Controls->m_ManualToolSelectionBox3D->SetToolGUIArea( m_Controls->m_ManualToolGUIContainer3D ); //specify tools to be added to 3D Tool area m_Controls->m_ManualToolSelectionBox3D->SetDisplayedToolGroups(tr("Threshold 'UL Threshold' Otsu 'Fast Marching 3D' 'Region Growing 3D' Watershed Picking").toStdString()); m_Controls->m_ManualToolSelectionBox3D->SetLayoutColumns(3); m_Controls->m_ManualToolSelectionBox3D->SetEnabledMode( QmitkToolSelectionBox::EnabledWithReferenceAndWorkingDataVisible ); //Hide 3D selection box, show 2D selection box m_Controls->m_ManualToolSelectionBox3D->hide(); m_Controls->m_ManualToolSelectionBox2D->show(); // update the list of segmentations toolManager->NewNodesGenerated += mitk::MessageDelegate(this, &QmitkSegmentationView::NewNodesGenerated); // update the list of segmentations toolManager->NewNodeObjectsGenerated += mitk::MessageDelegate1(this, &QmitkSegmentationView::NewNodeObjectsGenerated); // create signal/slot connections connect(m_Controls->patImageSelector, SIGNAL(OnSelectionChanged(const mitk::DataNode*)), this, SLOT(OnPatientComboBoxSelectionChanged(const mitk::DataNode*))); connect(m_Controls->segImageSelector, SIGNAL(OnSelectionChanged(const mitk::DataNode*)), this, SLOT(OnSegmentationComboBoxSelectionChanged(const mitk::DataNode*))); connect( m_Controls->btnNewSegmentation, SIGNAL(clicked()), this, SLOT(CreateNewSegmentation()) ); // connect( m_Controls->CreateSegmentationFromSurface, SIGNAL(clicked()), this, SLOT(CreateSegmentationFromSurface()) ); // connect( m_Controls->widgetStack, SIGNAL(currentChanged(int)), this, SLOT(ToolboxStackPageChanged(int)) ); connect( m_Controls->tabWidgetSegmentationTools, SIGNAL(currentChanged(int)), this, SLOT(OnTabWidgetChanged(int))); // connect(m_Controls->MaskSurfaces, SIGNAL( OnSelectionChanged( const mitk::DataNode* ) ), // this, SLOT( OnSurfaceSelectionChanged( ) ) ); connect(m_Controls->m_SlicesInterpolator, SIGNAL(SignalShowMarkerNodes(bool)), this, SLOT(OnShowMarkerNodes(bool))); // m_Controls->MaskSurfaces->SetDataStorage(this->GetDataStorage()); // m_Controls->MaskSurfaces->SetPredicate(mitk::NodePredicateDataType::New("Surface")); mitk::DataStorage::SetOfObjects::ConstPointer patientImages = GetDataStorage()->GetSubset(m_IsAPatientImagePredicate); if (!patientImages->empty()) { OnSelectionChanged(*patientImages->begin()); } // set callback function for already existing nodes (images & segmentations) mitk::DataStorage::SetOfObjects::ConstPointer allImages = GetDataStorage()->GetSubset(m_IsOfTypeImagePredicate); for (mitk::DataStorage::SetOfObjects::const_iterator iter = allImages->begin(); iter != allImages->end(); ++iter) { mitk::DataNode* node = *iter; itk::SimpleMemberCommand::Pointer command = itk::SimpleMemberCommand::New(); command->SetCallbackFunction(this, &QmitkSegmentationView::OnVisiblePropertyChanged); m_WorkingDataObserverTags.insert(std::pair(node, node->GetProperty("visible")->AddObserver(itk::ModifiedEvent(), command))); itk::SimpleMemberCommand::Pointer command2 = itk::SimpleMemberCommand::New(); command2->SetCallbackFunction(this, &QmitkSegmentationView::OnBinaryPropertyChanged); m_BinaryPropertyObserverTags.insert(std::pair(node, node->GetProperty("binary")->AddObserver(itk::ModifiedEvent(), command2))); } itk::SimpleMemberCommand::Pointer command = itk::SimpleMemberCommand::New(); command->SetCallbackFunction(this, &QmitkSegmentationView::RenderingManagerReinitialized); m_RenderingManagerObserverTag = mitk::RenderingManager::GetInstance()->AddObserver(mitk::RenderingManagerViewsInitializedEvent(), command); InitToolManagerSelection(m_Controls->patImageSelector->GetSelectedNode(), m_Controls->segImageSelector->GetSelectedNode()); m_RenderWindowPart = GetRenderWindowPart(); if (m_RenderWindowPart) { RenderWindowPartActivated(m_RenderWindowPart); } } void QmitkSegmentationView::SetFocus() { m_Controls->btnNewSegmentation->setFocus(); } void QmitkSegmentationView::OnManualTool2DSelected(int id) { if (id >= 0) { std::string text = "Active Tool: \""; mitk::ToolManager* toolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager(); text += toolManager->GetToolById(id)->GetName(); text += "\""; mitk::StatusBar::GetInstance()->DisplayText(text.c_str()); us::ModuleResource resource = toolManager->GetToolById(id)->GetCursorIconResource(); this->SetMouseCursor(resource, 0, 0); } else { this->ResetMouseCursor(); mitk::StatusBar::GetInstance()->DisplayText(""); } } void QmitkSegmentationView::ResetMouseCursor() { if ( m_MouseCursorSet ) { mitk::ApplicationCursor::GetInstance()->PopCursor(); m_MouseCursorSet = false; } } void QmitkSegmentationView::SetMouseCursor( const us::ModuleResource& resource, int hotspotX, int hotspotY ) { if (!resource) return; // Remove previously set mouse cursor if ( m_MouseCursorSet ) { mitk::ApplicationCursor::GetInstance()->PopCursor(); } us::ModuleResourceStream cursor(resource, std::ios::binary); mitk::ApplicationCursor::GetInstance()->PushCursor( cursor, hotspotX, hotspotY ); m_MouseCursorSet = true; } void QmitkSegmentationView::SetToolSelectionBoxesEnabled(bool status) { if (status) { m_Controls->m_ManualToolSelectionBox2D->RecreateButtons(); m_Controls->m_ManualToolSelectionBox3D->RecreateButtons(); } m_Controls->m_ManualToolSelectionBox2D->setEnabled(status); m_Controls->m_ManualToolSelectionBox3D->setEnabled(status); m_Controls->m_SlicesInterpolator->setEnabled(status); }