diff --git a/Modules/QtWidgets/include/QmitkAutomatedLayoutWidget.h b/Modules/QtWidgets/include/QmitkAutomatedLayoutWidget.h index b68c179731..40564ee207 100644 --- a/Modules/QtWidgets/include/QmitkAutomatedLayoutWidget.h +++ b/Modules/QtWidgets/include/QmitkAutomatedLayoutWidget.h @@ -1,47 +1,50 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef QmitkAutomatedLayoutDialog_h #define QmitkAutomatedLayoutDialog_h -#include "MitkQtWidgetsExports.h" +#include -#include "ui_QmitkAutomatedLayoutWidget.h" +#include -#include "mitkDataStorage.h" +#include -#include +namespace Ui +{ + class QmitkAutomatedLayoutWidget; +} class MITKQTWIDGETS_EXPORT QmitkAutomatedLayoutWidget : public QWidget { Q_OBJECT private Q_SLOTS: void OnSetLayoutClicked(); void OnSelectionDialogClosed(); Q_SIGNALS: - void SetDataBasedLayout(QmitkAbstractNodeSelectionWidget::NodeList nodes); + void SetDataBasedLayout(const QList& nodes); public: - QmitkAutomatedLayoutWidget(QWidget* parent = nullptr); + explicit QmitkAutomatedLayoutWidget(QWidget* parent = nullptr); void SetDataStorage(mitk::DataStorage::Pointer dataStorage); private: - Ui::QmitkAutomatedLayoutWidget m_Controls; - mitk::DataStorage::Pointer m_DataStorage = nullptr; + Ui::QmitkAutomatedLayoutWidget* m_Controls; + mitk::DataStorage::Pointer m_DataStorage; }; #endif diff --git a/Modules/QtWidgets/include/QmitkMultiWidgetConfigurationToolBar.h b/Modules/QtWidgets/include/QmitkMultiWidgetConfigurationToolBar.h index 009e90d34f..e5d36d8a7e 100644 --- a/Modules/QtWidgets/include/QmitkMultiWidgetConfigurationToolBar.h +++ b/Modules/QtWidgets/include/QmitkMultiWidgetConfigurationToolBar.h @@ -1,73 +1,73 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef QmitkMultiWidgetConfigurationToolBar_h #define QmitkMultiWidgetConfigurationToolBar_h -#include "MitkQtWidgetsExports.h" +#include #include -#include "mitkDataStorage.h" +#include #include // qt #include class QmitkAbstractMultiWidget; class QmitkMultiWidgetLayoutSelectionWidget; /** * @brief * * */ class MITKQTWIDGETS_EXPORT QmitkMultiWidgetConfigurationToolBar : public QToolBar { Q_OBJECT public: QmitkMultiWidgetConfigurationToolBar(QmitkAbstractMultiWidget* multiWidget); ~QmitkMultiWidgetConfigurationToolBar() override; void SetDataStorage(mitk::DataStorage::Pointer dataStorage); Q_SIGNALS: void LayoutSet(int row, int column); void SaveLayout(std::ostream* outStream); void LoadLayout(const nlohmann::json* jsonData); - void SetDataBasedLayout(QList nodes); + void SetDataBasedLayout(const QList& nodes); void Synchronized(bool synchronized); void InteractionSchemeChanged(mitk::InteractionSchemeSwitcher::InteractionScheme scheme); protected Q_SLOTS: void OnSetLayout(); void OnSynchronize(); void OnInteractionSchemeChanged(); private: void InitializeToolBar();; void AddButtons(); QmitkAbstractMultiWidget* m_MultiWidget; QAction* m_SynchronizeAction; QAction* m_InteractionSchemeChangeAction; QmitkMultiWidgetLayoutSelectionWidget* m_LayoutSelectionPopup; }; #endif diff --git a/Modules/QtWidgets/include/QmitkMultiWidgetLayoutSelectionWidget.h b/Modules/QtWidgets/include/QmitkMultiWidgetLayoutSelectionWidget.h index 5b371453ca..fa38feb2d2 100644 --- a/Modules/QtWidgets/include/QmitkMultiWidgetLayoutSelectionWidget.h +++ b/Modules/QtWidgets/include/QmitkMultiWidgetLayoutSelectionWidget.h @@ -1,70 +1,74 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef QmitkMultiWidgetLayoutSelectionWidget_h #define QmitkMultiWidgetLayoutSelectionWidget_h #include "MitkQtWidgetsExports.h" -#include "ui_QmitkMultiWidgetLayoutSelectionWidget.h" -#include "QmitkAutomatedLayoutWidget.h" +#include #include // qt #include "QWidget" +namespace Ui +{ + class QmitkMultiWidgetLayoutSelectionWidget; +} + /** * @brief * * */ class MITKQTWIDGETS_EXPORT QmitkMultiWidgetLayoutSelectionWidget : public QWidget { Q_OBJECT public: QmitkMultiWidgetLayoutSelectionWidget(QWidget* parent = nullptr); void SetDataStorage(mitk::DataStorage::Pointer dataStorage); Q_SIGNALS: void LayoutSet(int row, int column); - void SetDataBasedLayout(QmitkAbstractNodeSelectionWidget::NodeList nodes); + void SetDataBasedLayout(const QList& nodes); // needs to be connected via Qt::DirectConnection (usually default), to ensure the stream pointers validity void SaveLayout(std::ostream* outStream); void LoadLayout(const nlohmann::json* jsonData); private Q_SLOTS: void OnTableItemSelectionChanged(); void OnSetLayoutButtonClicked(); void OnDataBasedLayoutButtonClicked(); void OnSaveLayoutButtonClicked(); void OnLoadLayoutButtonClicked(); void OnLayoutPresetSelected(int index); private: void Init(); - Ui::QmitkMultiWidgetLayoutSelectionWidget ui; + Ui::QmitkMultiWidgetLayoutSelectionWidget* ui; std::map m_PresetMap; QmitkAutomatedLayoutWidget* m_AutomatedDataLayoutWidget; }; #endif diff --git a/Modules/QtWidgets/include/QmitkMxNMultiWidget.h b/Modules/QtWidgets/include/QmitkMxNMultiWidget.h index bc186f2d49..233d5771e6 100644 --- a/Modules/QtWidgets/include/QmitkMxNMultiWidget.h +++ b/Modules/QtWidgets/include/QmitkMxNMultiWidget.h @@ -1,133 +1,133 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef QmitkMxNMultiWidget_h #define QmitkMxNMultiWidget_h #include "MitkQtWidgetsExports.h" // qt widgets module #include "QmitkAbstractMultiWidget.h" #include #include #include class QSplitter; /** * @brief The 'QmitkMxNMultiWidget' is a 'QmitkAbstractMultiWidget' that is used to display multiple render windows at once. * Render windows can dynamically be added and removed to change the layout of the multi widget. This * is done by using the 'SetLayout'-function to define a layout. This will automatically add or remove * the appropriate number of render window widgets. */ class MITKQTWIDGETS_EXPORT QmitkMxNMultiWidget : public QmitkAbstractMultiWidget { Q_OBJECT public: QmitkMxNMultiWidget(QWidget* parent = nullptr, Qt::WindowFlags f = {}, const QString& multiWidgetName = "mxn"); ~QmitkMxNMultiWidget(); void InitializeMultiWidget() override; void Synchronize(bool synchronized) override; QmitkRenderWindow* GetRenderWindow(const QString& widgetName) const override; QmitkRenderWindow* GetRenderWindow(const mitk::AnatomicalPlane& orientation) const override; void SetActiveRenderWindowWidget(RenderWindowWidgetPointer activeRenderWindowWidget) override; /** * @brief Initialize the active render windows of the MxNMultiWidget to the given geometry. * * @param geometry The geometry to be used to initialize / update the * active render window's time and slice navigation controller. * @param resetCamera If true, the camera and crosshair will be reset to the default view (centered, no zoom). * If false, the current crosshair position and the camera zoom will be stored and reset * after the reference geometry has been updated. */ void InitializeViews(const mitk::TimeGeometry* geometry, bool resetCamera) override; /** * @brief Forward the given time geometry to all base renderers, so that they can store it as their * interaction reference geometry. * This will update the alignment status of the reference geometry for each base renderer. * For more details, see 'BaseRenderer::SetInteractionReferenceGeometry'. * Overridem from 'QmitkAbstractMultiWidget'. */ void SetInteractionReferenceGeometry(const mitk::TimeGeometry* referenceGeometry) override; /** * @brief Returns true if the render windows are coupled; false if not. * * For the MxNMultiWidget the render windows are typically decoupled. */ bool HasCoupledRenderWindows() const override; void SetSelectedPosition(const mitk::Point3D& newPosition, const QString& widgetName) override; const mitk::Point3D GetSelectedPosition(const QString& widgetName) const override; void SetCrosshairVisibility(bool visible) override; bool GetCrosshairVisibility() const override; void SetCrosshairGap(unsigned int gapSize) override; void ResetCrosshair() override; void SetWidgetPlaneMode(int userMode) override; mitk::SliceNavigationController* GetTimeNavigationController(); void EnableCrosshair(); void DisableCrosshair(); public Q_SLOTS: // mouse events void wheelEvent(QWheelEvent* e) override; void mousePressEvent(QMouseEvent* e) override; void moveEvent(QMoveEvent* e) override; void LoadLayout(const nlohmann::json* jsonData); void SaveLayout(std::ostream* outStream); - void SetDataBasedLayout(QmitkAbstractNodeSelectionWidget::NodeList nodes); + void SetDataBasedLayout(const QmitkAbstractNodeSelectionWidget::NodeList& nodes); Q_SIGNALS: void WheelMoved(QWheelEvent *); void Moved(); void UpdateUtilityWidgetViewPlanes(); void LayoutChanged(); private: void SetLayoutImpl() override; void SetInteractionSchemeImpl() override { } QmitkAbstractMultiWidget::RenderWindowWidgetPointer CreateRenderWindowWidget(); QmitkAbstractMultiWidget::RenderWindowWidgetPointer GetWindowFromIndex(size_t index); void SetInitialSelection(); void ToggleSynchronization(QmitkSynchronizedNodeSelectionWidget* synchronizedWidget); static nlohmann::json BuildJSONFromLayout(const QSplitter* splitter); QSplitter* BuildLayoutFromJSON(const nlohmann::json* jsonData, unsigned int* windowCounter, QSplitter* parentSplitter = nullptr); std::unique_ptr m_SynchronizedWidgetConnector; bool m_CrosshairVisibility; }; #endif diff --git a/Modules/QtWidgets/include/QmitkRenderWindowUtilityWidget.h b/Modules/QtWidgets/include/QmitkRenderWindowUtilityWidget.h index 3ae8f1fb18..3ba92caf6f 100644 --- a/Modules/QtWidgets/include/QmitkRenderWindowUtilityWidget.h +++ b/Modules/QtWidgets/include/QmitkRenderWindowUtilityWidget.h @@ -1,79 +1,79 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef QmitkRenderWindowUtilityWidget_h #define QmitkRenderWindowUtilityWidget_h #include "MitkQtWidgetsExports.h" // qt widgets module #include #include #include #include #include // qt #include #include #include #include namespace mitk { class DataStorage; } class QmitkRenderWindow; class MITKQTWIDGETS_EXPORT QmitkRenderWindowUtilityWidget : public QWidget { Q_OBJECT public: QmitkRenderWindowUtilityWidget( QWidget* parent = nullptr, QmitkRenderWindow* renderWindow = nullptr, mitk::DataStorage* dataStorage = nullptr ); ~QmitkRenderWindowUtilityWidget() override; void ToggleSynchronization(bool synchronized); void SetGeometry(const itk::EventObject& event); public Q_SLOTS: void UpdateViewPlaneSelection(); Q_SIGNALS: void SynchronizationToggled(QmitkSynchronizedNodeSelectionWidget* synchronizedWidget); - void SetDataSelection(const QList newSelection); + void SetDataSelection(const QList& newSelection); private: mitk::BaseRenderer* m_BaseRenderer; QmitkSynchronizedNodeSelectionWidget* m_NodeSelectionWidget; QPushButton* m_SynchPushButton; QmitkSliceNavigationWidget* m_SliceNavigationWidget; QmitkStepperAdapter* m_StepperAdapter; std::unique_ptr m_RenderWindowLayerController; std::unique_ptr m_RenderWindowViewDirectionController; QComboBox* m_ViewDirectionSelector; void ChangeViewDirection(const QString& viewDirection); }; #endif diff --git a/Modules/QtWidgets/include/QmitkRenderWindowWidget.h b/Modules/QtWidgets/include/QmitkRenderWindowWidget.h index ca0343a6ec..b9b803e64f 100644 --- a/Modules/QtWidgets/include/QmitkRenderWindowWidget.h +++ b/Modules/QtWidgets/include/QmitkRenderWindowWidget.h @@ -1,125 +1,125 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef QmitkRenderWindowWidget_h #define QmitkRenderWindowWidget_h #include "MitkQtWidgetsExports.h" // qt widgets module #include // mitk core #include #include #include -#include "QmitkRenderWindowUtilityWidget.h" +#include // qt #include #include #include class vtkCornerAnnotation; /** * @brief The 'QmitkRenderWindowWidget' is a QFrame that holds a render window * and some associates properties, e.g. decorations. * Decorations are corner annotation (text and color), frame color or background color * and can be set using this class. * The 'QmitkRenderWindowWidget' is used inside a 'QmitkAbstractMultiWidget', where a map contains * several render window widgets to create the multi widget display. * This class uses a CrosshairManager, which allows to use plane geometries as crosshair. */ class MITKQTWIDGETS_EXPORT QmitkRenderWindowWidget : public QFrame { Q_OBJECT public: QmitkRenderWindowWidget( QWidget* parent = nullptr, const QString& widgetName = "", mitk::DataStorage* dataStorage = nullptr); ~QmitkRenderWindowWidget() override; void SetDataStorage(mitk::DataStorage* dataStorage); const QString& GetWidgetName() const { return m_WidgetName; }; QmitkRenderWindow* GetRenderWindow() const { return m_RenderWindow; }; mitk::SliceNavigationController* GetSliceNavigationController() const; void RequestUpdate(); void ForceImmediateUpdate(); void AddUtilityWidget(QWidget* utilityWidget); QmitkRenderWindowUtilityWidget* GetUtilityWidget(); void SetGradientBackgroundColors(const mitk::Color& upper, const mitk::Color& lower); void ShowGradientBackground(bool enable); std::pair GetGradientBackgroundColors() const { return m_GradientBackgroundColors; }; bool IsGradientBackgroundOn() const; void SetDecorationColor(const mitk::Color& color); mitk::Color GetDecorationColor() const { return m_DecorationColor; }; void ShowColoredRectangle(bool show); bool IsColoredRectangleVisible() const; void ShowCornerAnnotation(bool show); bool IsCornerAnnotationVisible() const; void SetCornerAnnotationText(const std::string& cornerAnnotation); std::string GetCornerAnnotationText() const; bool IsRenderWindowMenuActivated() const; void SetCrosshairVisibility(bool visible); bool GetCrosshairVisibility(); void SetCrosshairGap(unsigned int gapSize); void EnableCrosshair(); void DisableCrosshair(); void SetCrosshairPosition(const mitk::Point3D& newPosition); mitk::Point3D GetCrosshairPosition() const; void SetGeometry(const itk::EventObject& event); void SetGeometrySlice(const itk::EventObject& event); public Q_SLOTS: void OnResetGeometry(); private: void InitializeGUI(); void InitializeDecorations(); void ResetGeometry(const mitk::TimeGeometry* referenceGeometry); QString m_WidgetName; QVBoxLayout* m_Layout; mitk::DataStorage* m_DataStorage; QmitkRenderWindow* m_RenderWindow; mitk::CrosshairManager::Pointer m_CrosshairManager; std::pair m_GradientBackgroundColors; mitk::Color m_DecorationColor; vtkSmartPointer m_CornerAnnotation; }; #endif diff --git a/Modules/QtWidgets/src/QmitkAutomatedLayoutWidget.cpp b/Modules/QtWidgets/src/QmitkAutomatedLayoutWidget.cpp index dc0ede50e2..f0897a3d6b 100644 --- a/Modules/QtWidgets/src/QmitkAutomatedLayoutWidget.cpp +++ b/Modules/QtWidgets/src/QmitkAutomatedLayoutWidget.cpp @@ -1,59 +1,62 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ -#include "QmitkAutomatedLayoutWidget.h" -#include "mitkNodePredicateDataType.h" -#include "mitkNodePredicateAnd.h" -#include "mitkNodePredicateNot.h" -#include "mitkNodePredicateProperty.h" -#include "mitkImage.h" +#include +#include +#include +#include +#include +#include + +#include QmitkAutomatedLayoutWidget::QmitkAutomatedLayoutWidget(QWidget* parent) : QWidget(parent) + , m_Controls(nullptr) { - m_Controls.setupUi(this); + m_Controls->setupUi(this); auto isImage = mitk::TNodePredicateDataType::New(); auto isNotHelper = mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("helper object")); auto isNotHidden = mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("hidden object")); auto isValidImage = mitk::NodePredicateAnd::New(isImage, isNotHelper, isNotHidden); - m_Controls.dataSelector->SetNodePredicate(isValidImage); - m_Controls.dataSelector->SetInvalidInfo(QStringLiteral("Please select images for the layout")); - m_Controls.dataSelector->SetPopUpTitel(QStringLiteral("Select input images")); - m_Controls.dataSelector->SetPopUpHint(QStringLiteral("Select as many images as you want to compare")); + m_Controls->dataSelector->SetNodePredicate(isValidImage); + m_Controls->dataSelector->SetInvalidInfo(QStringLiteral("Please select images for the layout")); + m_Controls->dataSelector->SetPopUpTitel(QStringLiteral("Select input images")); + m_Controls->dataSelector->SetPopUpHint(QStringLiteral("Select as many images as you want to compare")); - m_Controls.setLayoutButton->setEnabled(false); + m_Controls->setLayoutButton->setEnabled(false); - connect(m_Controls.dataSelector, &QmitkMultiNodeSelectionWidget::DialogClosed, this, &QmitkAutomatedLayoutWidget::OnSelectionDialogClosed); - connect(m_Controls.setLayoutButton, &QPushButton::clicked, this, &QmitkAutomatedLayoutWidget::OnSetLayoutClicked); + connect(m_Controls->dataSelector, &QmitkMultiNodeSelectionWidget::DialogClosed, this, &QmitkAutomatedLayoutWidget::OnSelectionDialogClosed); + connect(m_Controls->setLayoutButton, &QPushButton::clicked, this, &QmitkAutomatedLayoutWidget::OnSetLayoutClicked); } void QmitkAutomatedLayoutWidget::SetDataStorage(mitk::DataStorage::Pointer dataStorage) { // smart pointer to data storage needs to be saved here because dataSelector makes it a regular pointer m_DataStorage = dataStorage; - m_Controls.dataSelector->SetDataStorage(m_DataStorage); + m_Controls->dataSelector->SetDataStorage(m_DataStorage); } void QmitkAutomatedLayoutWidget::OnSetLayoutClicked() { - auto selectedNodes = m_Controls.dataSelector->GetSelectedNodes(); + auto selectedNodes = m_Controls->dataSelector->GetSelectedNodes(); emit SetDataBasedLayout(selectedNodes); this->hide(); } void QmitkAutomatedLayoutWidget::OnSelectionDialogClosed() { - bool setLayoutEnabled = m_Controls.dataSelector->GetSelectedNodes().size() > 0; - m_Controls.setLayoutButton->setEnabled(setLayoutEnabled); + bool setLayoutEnabled = m_Controls->dataSelector->GetSelectedNodes().size() > 0; + m_Controls->setLayoutButton->setEnabled(setLayoutEnabled); this->show(); } diff --git a/Modules/QtWidgets/src/QmitkMultiWidgetLayoutSelectionWidget.cpp b/Modules/QtWidgets/src/QmitkMultiWidgetLayoutSelectionWidget.cpp index 1e90051357..7c76184229 100644 --- a/Modules/QtWidgets/src/QmitkMultiWidgetLayoutSelectionWidget.cpp +++ b/Modules/QtWidgets/src/QmitkMultiWidgetLayoutSelectionWidget.cpp @@ -1,158 +1,160 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ -#include "QmitkMultiWidgetLayoutSelectionWidget.h" +#include +#include #include #include #include #include #include QmitkMultiWidgetLayoutSelectionWidget::QmitkMultiWidgetLayoutSelectionWidget(QWidget* parent/* = 0*/) : QWidget(parent) + , ui(nullptr) { Init(); } void QmitkMultiWidgetLayoutSelectionWidget::Init() { - ui.setupUi(this); + ui->setupUi(this); auto stylesheet = "QTableWidget::item{background-color: white;}\nQTableWidget::item:selected{background-color: #1C97EA;}"; - ui.tableWidget->setStyleSheet(stylesheet); + ui->tableWidget->setStyleSheet(stylesheet); m_AutomatedDataLayoutWidget = new QmitkAutomatedLayoutWidget(this); connect(m_AutomatedDataLayoutWidget, &QmitkAutomatedLayoutWidget::SetDataBasedLayout, this, &QmitkMultiWidgetLayoutSelectionWidget::SetDataBasedLayout); m_AutomatedDataLayoutWidget->hide(); - connect(ui.tableWidget, &QTableWidget::itemSelectionChanged, this, &QmitkMultiWidgetLayoutSelectionWidget::OnTableItemSelectionChanged); - connect(ui.setLayoutPushButton, &QPushButton::clicked, this, &QmitkMultiWidgetLayoutSelectionWidget::OnSetLayoutButtonClicked); - connect(ui.dataBasedLayoutButton, &QPushButton::clicked, this, &QmitkMultiWidgetLayoutSelectionWidget::OnDataBasedLayoutButtonClicked); - connect(ui.loadLayoutPushButton, &QPushButton::clicked, this, &QmitkMultiWidgetLayoutSelectionWidget::OnLoadLayoutButtonClicked); - connect(ui.saveLayoutPushButton, &QPushButton::clicked, this, &QmitkMultiWidgetLayoutSelectionWidget::OnSaveLayoutButtonClicked); - connect(ui.selectDefaultLayoutComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, &QmitkMultiWidgetLayoutSelectionWidget::OnLayoutPresetSelected); + connect(ui->tableWidget, &QTableWidget::itemSelectionChanged, this, &QmitkMultiWidgetLayoutSelectionWidget::OnTableItemSelectionChanged); + connect(ui->setLayoutPushButton, &QPushButton::clicked, this, &QmitkMultiWidgetLayoutSelectionWidget::OnSetLayoutButtonClicked); + connect(ui->dataBasedLayoutButton, &QPushButton::clicked, this, &QmitkMultiWidgetLayoutSelectionWidget::OnDataBasedLayoutButtonClicked); + connect(ui->loadLayoutPushButton, &QPushButton::clicked, this, &QmitkMultiWidgetLayoutSelectionWidget::OnLoadLayoutButtonClicked); + connect(ui->saveLayoutPushButton, &QPushButton::clicked, this, &QmitkMultiWidgetLayoutSelectionWidget::OnSaveLayoutButtonClicked); + connect(ui->selectDefaultLayoutComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, &QmitkMultiWidgetLayoutSelectionWidget::OnLayoutPresetSelected); - ui.selectDefaultLayoutComboBox->addItem("Select a layout preset"); + ui->selectDefaultLayoutComboBox->addItem("Select a layout preset"); auto presetResources = us::GetModuleContext()->GetModule()->FindResources("/", "mxnLayout_*.json", false); for (const auto& resource : presetResources) { us::ModuleResourceStream jsonStream(resource); auto data = nlohmann::json::parse(jsonStream); auto resourceName = data["name"].get(); - ui.selectDefaultLayoutComboBox->addItem(QString::fromStdString(resourceName)); - m_PresetMap[ui.selectDefaultLayoutComboBox->count() - 1] = data; + ui->selectDefaultLayoutComboBox->addItem(QString::fromStdString(resourceName)); + m_PresetMap[ui->selectDefaultLayoutComboBox->count() - 1] = data; } } void QmitkMultiWidgetLayoutSelectionWidget::SetDataStorage(mitk::DataStorage::Pointer dataStorage) { if (m_AutomatedDataLayoutWidget == nullptr) return; m_AutomatedDataLayoutWidget->SetDataStorage(dataStorage); } void QmitkMultiWidgetLayoutSelectionWidget::OnTableItemSelectionChanged() { - QItemSelectionModel* selectionModel = ui.tableWidget->selectionModel(); + QItemSelectionModel* selectionModel = ui->tableWidget->selectionModel(); int row = 0; int column = 0; QModelIndexList indices = selectionModel->selectedIndexes(); if (indices.size() > 0) { row = indices[0].row(); column = indices[0].column(); - QModelIndex topLeft = ui.tableWidget->model()->index(0, 0, QModelIndex()); - QModelIndex bottomRight = ui.tableWidget->model()->index(row, column, QModelIndex()); + QModelIndex topLeft = ui->tableWidget->model()->index(0, 0, QModelIndex()); + QModelIndex bottomRight = ui->tableWidget->model()->index(row, column, QModelIndex()); QItemSelection cellSelection; cellSelection.select(topLeft, bottomRight); selectionModel->select(cellSelection, QItemSelectionModel::Select); } } void QmitkMultiWidgetLayoutSelectionWidget::OnSetLayoutButtonClicked() { int row = 0; int column = 0; - QModelIndexList indices = ui.tableWidget->selectionModel()->selectedIndexes(); + QModelIndexList indices = ui->tableWidget->selectionModel()->selectedIndexes(); if (indices.size() > 0) { // find largest row and column for (const auto& modelIndex : std::as_const(indices)) { if (modelIndex.row() > row) { row = modelIndex.row(); } if (modelIndex.column() > column) { column = modelIndex.column(); } } close(); emit LayoutSet(row+1, column+1); } - ui.selectDefaultLayoutComboBox->setCurrentIndex(0); + ui->selectDefaultLayoutComboBox->setCurrentIndex(0); } void QmitkMultiWidgetLayoutSelectionWidget::OnDataBasedLayoutButtonClicked() { this->hide(); m_AutomatedDataLayoutWidget->setWindowFlags(Qt::Popup); m_AutomatedDataLayoutWidget->move(this->pos().x() - m_AutomatedDataLayoutWidget->width() + this->width(), this->pos().y()); m_AutomatedDataLayoutWidget->show(); } void QmitkMultiWidgetLayoutSelectionWidget::OnSaveLayoutButtonClicked() { QString filename = QFileDialog::getSaveFileName(nullptr, "Select where to save the current layout", "", "MITK Window Layout (*.json)"); if (filename.isEmpty()) return; QString fileExt(".json"); if (!filename.endsWith(fileExt)) filename += fileExt; auto outStream = std::ofstream(filename.toStdString()); emit SaveLayout(&outStream); } void QmitkMultiWidgetLayoutSelectionWidget::OnLoadLayoutButtonClicked() { QString filename = QFileDialog::getOpenFileName(nullptr, "Load a layout file", "", "MITK Window Layouts (*.json)"); if (filename.isEmpty()) return; - ui.selectDefaultLayoutComboBox->setCurrentIndex(0); + ui->selectDefaultLayoutComboBox->setCurrentIndex(0); std::ifstream f(filename.toStdString()); auto jsonData = nlohmann::json::parse(f); emit LoadLayout(&jsonData); } void QmitkMultiWidgetLayoutSelectionWidget::OnLayoutPresetSelected(int index) { if (index == 0) { // First entry is only for description return; } auto jsonData = m_PresetMap[index]; close(); emit LoadLayout(&jsonData); } diff --git a/Modules/QtWidgets/src/QmitkMxNMultiWidget.cpp b/Modules/QtWidgets/src/QmitkMxNMultiWidget.cpp index b129e0f61a..ef255e9858 100644 --- a/Modules/QtWidgets/src/QmitkMxNMultiWidget.cpp +++ b/Modules/QtWidgets/src/QmitkMxNMultiWidget.cpp @@ -1,651 +1,650 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "QmitkMxNMultiWidget.h" // mitk core #include #include #include #include #include #include // mitk qt widget #include #include // qt #include #include #include #include QmitkMxNMultiWidget::QmitkMxNMultiWidget(QWidget* parent, Qt::WindowFlags f/* = 0*/, const QString& multiWidgetName/* = "mxn"*/) : QmitkAbstractMultiWidget(parent, f, multiWidgetName) , m_SynchronizedWidgetConnector(std::make_unique()) , m_CrosshairVisibility(false) { } QmitkMxNMultiWidget::~QmitkMxNMultiWidget() { } void QmitkMxNMultiWidget::InitializeMultiWidget() { SetLayout(1, 1); SetDisplayActionEventHandler(std::make_unique()); auto displayActionEventHandler = GetDisplayActionEventHandler(); if (nullptr != displayActionEventHandler) { displayActionEventHandler->InitActions(); } this->SetInitialSelection(); } void QmitkMxNMultiWidget::Synchronize(bool synchronized) { if (synchronized) { SetDisplayActionEventHandler(std::make_unique()); } else { SetDisplayActionEventHandler(std::make_unique()); } auto displayActionEventHandler = GetDisplayActionEventHandler(); if (nullptr != displayActionEventHandler) { displayActionEventHandler->InitActions(); } } QmitkRenderWindow* QmitkMxNMultiWidget::GetRenderWindow(const QString& widgetName) const { if ("axial" == widgetName || "sagittal" == widgetName || "coronal" == widgetName || "3d" == widgetName) { return GetActiveRenderWindowWidget()->GetRenderWindow(); } return QmitkAbstractMultiWidget::GetRenderWindow(widgetName); } QmitkRenderWindow* QmitkMxNMultiWidget::GetRenderWindow(const mitk::AnatomicalPlane& /*orientation*/) const { // currently no mapping between plane orientation and render windows // simply return the currently active render window return GetActiveRenderWindowWidget()->GetRenderWindow(); } void QmitkMxNMultiWidget::SetActiveRenderWindowWidget(RenderWindowWidgetPointer activeRenderWindowWidget) { auto currentActiveRenderWindowWidget = GetActiveRenderWindowWidget(); if (currentActiveRenderWindowWidget == activeRenderWindowWidget) { return; } // reset the decoration color of the previously active render window widget if (nullptr != currentActiveRenderWindowWidget) { auto decorationColor = currentActiveRenderWindowWidget->GetDecorationColor(); QColor hexColor(decorationColor[0] * 255, decorationColor[1] * 255, decorationColor[2] * 255); currentActiveRenderWindowWidget->setStyleSheet("QmitkRenderWindowWidget { border: 2px solid " + hexColor.name(QColor::HexRgb) + "; }"); } // set the new decoration color of the currently active render window widget if (nullptr != activeRenderWindowWidget) { activeRenderWindowWidget->setStyleSheet("QmitkRenderWindowWidget { border: 2px solid #FF6464; }"); } QmitkAbstractMultiWidget::SetActiveRenderWindowWidget(activeRenderWindowWidget); } void QmitkMxNMultiWidget::InitializeViews(const mitk::TimeGeometry* geometry, bool resetCamera) { auto* renderingManager = mitk::RenderingManager::GetInstance(); mitk::Point3D currentPosition = mitk::Point3D(); unsigned int imageTimeStep = 0; if (!resetCamera) { // store the current position to set it again later, if the camera should not be reset currentPosition = this->GetSelectedPosition(""); // store the current time step to set it again later, if the camera should not be reset const mitk::TimePointType currentTimePoint = renderingManager->GetTimeNavigationController()->GetSelectedTimePoint(); if (geometry->IsValidTimePoint(currentTimePoint)) { imageTimeStep = geometry->TimePointToTimeStep(currentTimePoint); } } // initialize active render window renderingManager->InitializeView( this->GetActiveRenderWindowWidget()->GetRenderWindow()->GetVtkRenderWindow(), geometry, resetCamera); if (!resetCamera) { this->SetSelectedPosition(currentPosition, ""); renderingManager->GetTimeNavigationController()->GetStepper()->SetPos(imageTimeStep); } } void QmitkMxNMultiWidget::SetInteractionReferenceGeometry(const mitk::TimeGeometry* referenceGeometry) { // Set the interaction reference referenceGeometry for all render windows. auto allRenderWindows = this->GetRenderWindows(); for (auto& renderWindow : allRenderWindows) { auto* baseRenderer = mitk::BaseRenderer::GetInstance(renderWindow->GetVtkRenderWindow()); baseRenderer->SetInteractionReferenceGeometry(referenceGeometry); } } bool QmitkMxNMultiWidget::HasCoupledRenderWindows() const { return false; } void QmitkMxNMultiWidget::SetSelectedPosition(const mitk::Point3D& newPosition, const QString& widgetName) { RenderWindowWidgetPointer renderWindowWidget; if (widgetName.isNull() || widgetName.isEmpty()) { renderWindowWidget = GetActiveRenderWindowWidget(); } else { renderWindowWidget = GetRenderWindowWidget(widgetName); } if (nullptr != renderWindowWidget) { renderWindowWidget->GetSliceNavigationController()->SelectSliceByPoint(newPosition); return; } MITK_ERROR << "Position can not be set for an unknown render window widget."; } const mitk::Point3D QmitkMxNMultiWidget::GetSelectedPosition(const QString& widgetName) const { RenderWindowWidgetPointer renderWindowWidget; if (widgetName.isNull() || widgetName.isEmpty()) { renderWindowWidget = GetActiveRenderWindowWidget(); } else { renderWindowWidget = GetRenderWindowWidget(widgetName); } if (nullptr != renderWindowWidget) { return renderWindowWidget->GetCrosshairPosition(); } MITK_ERROR << "Crosshair position can not be retrieved."; return mitk::Point3D(0.0); } void QmitkMxNMultiWidget::SetCrosshairVisibility(bool visible) { // get the specific render window that sent the signal QmitkRenderWindow* renderWindow = qobject_cast(sender()); if (nullptr == renderWindow) { return; } auto renderWindowWidget = this->GetRenderWindowWidget(renderWindow); renderWindowWidget->SetCrosshairVisibility(visible); } bool QmitkMxNMultiWidget::GetCrosshairVisibility() const { // get the specific render window that sent the signal QmitkRenderWindow* renderWindow = qobject_cast(sender()); if (nullptr == renderWindow) { return false; } auto renderWindowWidget = this->GetRenderWindowWidget(renderWindow); return renderWindowWidget->GetCrosshairVisibility(); } void QmitkMxNMultiWidget::SetCrosshairGap(unsigned int gapSize) { auto renderWindowWidgets = this->GetRenderWindowWidgets(); for (const auto& renderWindowWidget : renderWindowWidgets) { renderWindowWidget.second->SetCrosshairGap(gapSize); } } void QmitkMxNMultiWidget::ResetCrosshair() { auto dataStorage = GetDataStorage(); if (nullptr == dataStorage) { return; } // get the specific render window that sent the signal QmitkRenderWindow* renderWindow = qobject_cast(sender()); if (nullptr == renderWindow) { return; } mitk::RenderingManager::GetInstance()->InitializeViewByBoundingObjects(renderWindow->GetVtkRenderWindow(), dataStorage); SetWidgetPlaneMode(mitk::InteractionSchemeSwitcher::MITKStandard); } void QmitkMxNMultiWidget::SetWidgetPlaneMode(int userMode) { MITK_DEBUG << "Changing crosshair mode to " << userMode; switch (userMode) { case 0: SetInteractionScheme(mitk::InteractionSchemeSwitcher::MITKStandard); break; case 1: SetInteractionScheme(mitk::InteractionSchemeSwitcher::MITKRotationUncoupled); break; case 2: SetInteractionScheme(mitk::InteractionSchemeSwitcher::MITKRotationCoupled); break; case 3: SetInteractionScheme(mitk::InteractionSchemeSwitcher::MITKSwivel); break; } } void QmitkMxNMultiWidget::EnableCrosshair() { auto renderWindowWidgets = this->GetRenderWindowWidgets(); for (const auto& renderWindowWidget : renderWindowWidgets) { renderWindowWidget.second->EnableCrosshair(); } } void QmitkMxNMultiWidget::DisableCrosshair() { auto renderWindowWidgets = this->GetRenderWindowWidgets(); for (const auto& renderWindowWidget : renderWindowWidgets) { renderWindowWidget.second->DisableCrosshair(); } } ////////////////////////////////////////////////////////////////////////// // PUBLIC SLOTS // MOUSE EVENTS ////////////////////////////////////////////////////////////////////////// void QmitkMxNMultiWidget::wheelEvent(QWheelEvent* e) { emit WheelMoved(e); } void QmitkMxNMultiWidget::mousePressEvent(QMouseEvent*) { // nothing here, but necessary for mouse interactions (.xml-configuration files) } void QmitkMxNMultiWidget::moveEvent(QMoveEvent* e) { QWidget::moveEvent(e); // it is necessary to readjust the position of the overlays as the MultiWidget has moved // unfortunately it's not done by QmitkRenderWindow::moveEvent -> must be done here emit Moved(); } ////////////////////////////////////////////////////////////////////////// // PRIVATE ////////////////////////////////////////////////////////////////////////// void QmitkMxNMultiWidget::SetLayoutImpl() { int requiredRenderWindowWidgets = GetRowCount() * GetColumnCount(); int existingRenderWindowWidgets = GetRenderWindowWidgets().size(); int difference = requiredRenderWindowWidgets - existingRenderWindowWidgets; while (0 < difference) { // more render window widgets needed CreateRenderWindowWidget(); --difference; } while (0 > difference) { // less render window widgets needed RemoveRenderWindowWidget(); ++difference; } auto firstRenderWindowWidget = GetFirstRenderWindowWidget(); if (nullptr != firstRenderWindowWidget) { SetActiveRenderWindowWidget(firstRenderWindowWidget); } GetMultiWidgetLayoutManager()->SetLayoutDesign(QmitkMultiWidgetLayoutManager::LayoutDesign::DEFAULT); } QmitkAbstractMultiWidget::RenderWindowWidgetPointer QmitkMxNMultiWidget::CreateRenderWindowWidget() { // create the render window widget and connect signal / slot QString renderWindowWidgetName = GetNameFromIndex(GetNumberOfRenderWindowWidgets()); RenderWindowWidgetPointer renderWindowWidget = std::make_shared(this, renderWindowWidgetName, GetDataStorage()); renderWindowWidget->SetCornerAnnotationText(renderWindowWidgetName.toStdString()); AddRenderWindowWidget(renderWindowWidgetName, renderWindowWidget); auto renderWindow = renderWindowWidget->GetRenderWindow(); QmitkRenderWindowUtilityWidget* utilityWidget = new QmitkRenderWindowUtilityWidget(this, renderWindow, GetDataStorage()); renderWindowWidget->AddUtilityWidget(utilityWidget); connect(utilityWidget, &QmitkRenderWindowUtilityWidget::SynchronizationToggled, this, &QmitkMxNMultiWidget::ToggleSynchronization); connect(this, &QmitkMxNMultiWidget::UpdateUtilityWidgetViewPlanes, utilityWidget, &QmitkRenderWindowUtilityWidget::UpdateViewPlaneSelection); // needs to be done after 'QmitkRenderWindowUtilityWidget::ToggleSynchronization' has been connected // initially synchronize the node selection widget utilityWidget->ToggleSynchronization(true); auto layoutManager = GetMultiWidgetLayoutManager(); connect(renderWindow, &QmitkRenderWindow::LayoutDesignChanged, layoutManager, &QmitkMultiWidgetLayoutManager::SetLayoutDesign); connect(renderWindow, &QmitkRenderWindow::ResetView, this, &QmitkMxNMultiWidget::ResetCrosshair); connect(renderWindow, &QmitkRenderWindow::CrosshairVisibilityChanged, this, &QmitkMxNMultiWidget::SetCrosshairVisibility); connect(renderWindow, &QmitkRenderWindow::CrosshairRotationModeChanged, this, &QmitkMxNMultiWidget::SetWidgetPlaneMode); return renderWindowWidget; } QmitkAbstractMultiWidget::RenderWindowWidgetPointer QmitkMxNMultiWidget::GetWindowFromIndex(size_t index) { if (index >= GetRenderWindowWidgets().size()) { return nullptr; } auto renderWindowName = this->GetNameFromIndex(index); auto renderWindowWidgets = GetRenderWindowWidgets(); auto it = renderWindowWidgets.find(renderWindowName); if (it != renderWindowWidgets.end()) { return it->second; } else { MITK_ERROR << "Could not find render window " << renderWindowName.toStdString() << ", although it should be there."; return nullptr; } } void QmitkMxNMultiWidget::LoadLayout(const nlohmann::json* jsonData) { if ((*jsonData).is_null()) { QMessageBox::warning(this, "Load layout", "Could not read window layout"); return; } unsigned int windowCounter = 0; try { auto version = jsonData->at("version").get(); if (version != "1.0") { QMessageBox::warning(this, "Load layout", "Unknown layout version, could not load"); return; } delete this->layout(); auto content = BuildLayoutFromJSON(jsonData, &windowCounter); auto hBoxLayout = new QHBoxLayout(this); this->setLayout(hBoxLayout); hBoxLayout->addWidget(content); emit UpdateUtilityWidgetViewPlanes(); } catch (nlohmann::json::out_of_range& e) { MITK_ERROR << "Error in loading window layout from JSON: " << e.what(); return; } while (GetNumberOfRenderWindowWidgets() > windowCounter) { RemoveRenderWindowWidget(); } EnableCrosshair(); emit LayoutChanged(); } void QmitkMxNMultiWidget::SaveLayout(std::ostream* outStream) { if (outStream == nullptr) { return; } auto layout = this->layout(); if (layout == nullptr) return; // There should only ever be one item: a splitter auto widget = layout->itemAt(0)->widget(); auto splitter = dynamic_cast(widget); if (!splitter) { MITK_ERROR << "Tried to save unexpected layout format. Make sure the layout of this instance contains a single QSplitter."; return; } auto layoutJSON = BuildJSONFromLayout(splitter); layoutJSON["version"] = "1.0"; layoutJSON["name"] = "Custom Layout"; *outStream << std::setw(4) << layoutJSON << std::endl; } nlohmann::json QmitkMxNMultiWidget::BuildJSONFromLayout(const QSplitter* splitter) { nlohmann::json resultJSON; resultJSON["isWindow"] = false; resultJSON["vertical"] = (splitter->orientation() == Qt::Vertical) ? true : false; auto sizes = splitter->sizes(); auto content = nlohmann::json::array(); auto countSplitter = splitter->count(); for (int i = 0; i < countSplitter; ++i) { auto widget = splitter->widget(i); nlohmann::json widgetJSON; if (auto widgetSplitter = dynamic_cast(widget); widgetSplitter) { widgetJSON = BuildJSONFromLayout(widgetSplitter); } else if (auto widgetWindow = dynamic_cast(widget); widgetWindow) { widgetJSON["isWindow"] = true; widgetJSON["viewDirection"] = widgetWindow->GetSliceNavigationController()->GetViewDirectionAsString(); } widgetJSON["size"] = sizes[i]; content.push_back(widgetJSON); } resultJSON["content"] = content; return resultJSON; } QSplitter* QmitkMxNMultiWidget::BuildLayoutFromJSON(const nlohmann::json* jsonData, unsigned int* windowCounter, QSplitter* parentSplitter) { bool vertical = jsonData->at("vertical").get(); auto orientation = vertical ? Qt::Vertical : Qt::Horizontal; auto split = new QSplitter(orientation, parentSplitter); QList sizes; for (auto object : jsonData->at("content")) { bool isWindow = object["isWindow"].get(); int size = object["size"].get(); sizes.append(size); if (isWindow) { auto viewDirection = object["viewDirection"].get(); mitk::AnatomicalPlane viewPlane = mitk::AnatomicalPlane::Sagittal; if (viewDirection == "Axial") { viewPlane = mitk::AnatomicalPlane::Axial; } else if (viewDirection == "Coronal") { viewPlane = mitk::AnatomicalPlane::Coronal; } else if (viewDirection == "Original") { viewPlane = mitk::AnatomicalPlane::Original; } else if (viewDirection == "Sagittal") { viewPlane = mitk::AnatomicalPlane::Sagittal; } // repurpose existing render windows as far as they already exist auto window = GetWindowFromIndex(*windowCounter); if (window == nullptr) { window = CreateRenderWindowWidget(); } window->GetSliceNavigationController()->SetDefaultViewDirection(viewPlane); window->GetSliceNavigationController()->Update(); split->addWidget(window.get()); window->show(); (*windowCounter)++; } else { auto subSplitter = BuildLayoutFromJSON(&object, windowCounter, split); split->addWidget(subSplitter); } } split->setSizes(sizes); return split; } -void QmitkMxNMultiWidget::SetDataBasedLayout(QmitkAbstractNodeSelectionWidget::NodeList nodes) +void QmitkMxNMultiWidget::SetDataBasedLayout(const QmitkAbstractNodeSelectionWidget::NodeList& nodes) { auto vSplit = new QSplitter(Qt::Vertical); unsigned int windowCounter = 0; for (auto node : nodes) { auto hSplit = new QSplitter(Qt::Horizontal); for (auto viewPlane : { mitk::AnatomicalPlane::Axial, mitk::AnatomicalPlane::Coronal, mitk::AnatomicalPlane::Sagittal }) { // repurpose existing render windows as far as they already exist - auto window = GetWindowFromIndex(windowCounter); + auto window = GetWindowFromIndex(windowCounter++); if (window == nullptr) { window = CreateRenderWindowWidget(); } auto utilityWidget = window->GetUtilityWidget(); utilityWidget->ToggleSynchronization(false); utilityWidget->SetDataSelection(QList({ node })); window->GetSliceNavigationController()->SetDefaultViewDirection(viewPlane); window->GetSliceNavigationController()->Update(); auto baseRenderer = mitk::BaseRenderer::GetInstance(window->GetRenderWindow()->GetVtkRenderWindow()); mitk::RenderingManager::GetInstance()->InitializeView(baseRenderer->GetRenderWindow(), node->GetData()->GetTimeGeometry()); hSplit->addWidget(window.get()); window->show(); - windowCounter++; } auto sizes = QList({1, 1, 1}); hSplit->setSizes(sizes); vSplit->addWidget(hSplit); } delete this->layout(); auto hBoxLayout = new QHBoxLayout(this); this->setLayout(hBoxLayout); hBoxLayout->addWidget(vSplit); emit UpdateUtilityWidgetViewPlanes(); while (GetNumberOfRenderWindowWidgets() > windowCounter) { RemoveRenderWindowWidget(); } EnableCrosshair(); emit LayoutChanged(); } void QmitkMxNMultiWidget::SetInitialSelection() { auto dataStorage = this->GetDataStorage(); if (nullptr == dataStorage) { return; } mitk::NodePredicateAnd::Pointer noHelperObjects = mitk::NodePredicateAnd::New(); noHelperObjects->AddPredicate(mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("helper object"))); noHelperObjects->AddPredicate(mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("hidden object"))); auto allNodes = dataStorage->GetSubset(noHelperObjects); QmitkSynchronizedNodeSelectionWidget::NodeList currentSelection; for (auto& node : *allNodes) { currentSelection.append(node); } m_SynchronizedWidgetConnector->ChangeSelection(currentSelection); } void QmitkMxNMultiWidget::ToggleSynchronization(QmitkSynchronizedNodeSelectionWidget* synchronizedWidget) { bool synchronized = synchronizedWidget->IsSynchronized(); if (synchronized) { m_SynchronizedWidgetConnector->ConnectWidget(synchronizedWidget); m_SynchronizedWidgetConnector->SynchronizeWidget(synchronizedWidget); } else { m_SynchronizedWidgetConnector->DisconnectWidget(synchronizedWidget); } }