diff --git a/Modules/Core/src/Interactions/mitkInteractionSchemeSwitcher.cpp b/Modules/Core/src/Interactions/mitkInteractionSchemeSwitcher.cpp index 4b410b4dd3..6827a75fb9 100644 --- a/Modules/Core/src/Interactions/mitkInteractionSchemeSwitcher.cpp +++ b/Modules/Core/src/Interactions/mitkInteractionSchemeSwitcher.cpp @@ -1,101 +1,102 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical Image Computing. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkInteractionSchemeSwitcher.h" // us #include "usGetModuleContext.h" #include "usModuleContext.h" // mitk core #include "mitkInteractionEventObserver.h" +#include mitk::InteractionSchemeSwitcher::InteractionSchemeSwitcher() : m_InteractionScheme(MITKStandard) { // nothing here } mitk::InteractionSchemeSwitcher::~InteractionSchemeSwitcher() { // nothing here } void mitk::InteractionSchemeSwitcher::SetInteractionScheme(mitk::InteractionEventHandler* interactionEventHandler, InteractionScheme interactionScheme) { if (nullptr == interactionEventHandler) { - return; + mitkThrow() << "Not a valid interaction event handler to set the interaction scheme."; } switch (interactionScheme) { // MITK MODE case MITKStandard: { interactionEventHandler->SetEventConfig("DisplayConfigMITK.xml"); break; } case MITKRotationUncoupled: { interactionEventHandler->SetEventConfig("DisplayConfigMITKRotationUnCoupled.xml"); break; } case MITKRotationCoupled: { interactionEventHandler->SetEventConfig("DisplayConfigMITKRotation.xml"); break; } case MITKSwivel: { interactionEventHandler->SetEventConfig("DisplayConfigMITKSwivel.xml"); break; } // PACS MODE case PACSStandard: { interactionEventHandler->SetEventConfig("DisplayConfigPACS.xml"); break; } case PACSLevelWindow: { interactionEventHandler->SetEventConfig("DisplayConfigPACS.xml"); interactionEventHandler->AddEventConfig("DisplayConfigPACSLevelWindow.xml"); break; } case PACSPan: { interactionEventHandler->SetEventConfig("DisplayConfigPACS.xml"); interactionEventHandler->AddEventConfig("DisplayConfigPACSPan.xml"); break; } case PACSScroll: { interactionEventHandler->SetEventConfig("DisplayConfigPACS.xml"); interactionEventHandler->AddEventConfig("DisplayConfigPACSScroll.xml"); break; } case PACSZoom: { interactionEventHandler->SetEventConfig("DisplayConfigPACS.xml"); interactionEventHandler->AddEventConfig("DisplayConfigPACSZoom.xml"); break; } } m_InteractionScheme = interactionScheme; InvokeEvent(InteractionSchemeChangedEvent()); } diff --git a/Modules/QtWidgets/src/QmitkInteractionSchemeToolBar.cpp b/Modules/QtWidgets/src/QmitkInteractionSchemeToolBar.cpp index 98d34e39f5..780fb7e436 100644 --- a/Modules/QtWidgets/src/QmitkInteractionSchemeToolBar.cpp +++ b/Modules/QtWidgets/src/QmitkInteractionSchemeToolBar.cpp @@ -1,82 +1,90 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical Image Computing. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "QmitkInteractionSchemeToolBar.h" #include QmitkInteractionSchemeToolBar::QmitkInteractionSchemeToolBar(QWidget* parent/* = nullptr*/) : QToolBar(parent) , m_ActionGroup(new QActionGroup(this)) , m_InteractionSchemeSwitcher(nullptr) , m_InteractionEventHandler(nullptr) { QToolBar::setOrientation(Qt::Vertical); QToolBar::setIconSize(QSize(17, 17)); m_ActionGroup->setExclusive(true); // only one selectable action AddButton(InteractionScheme::PACSStandard, tr("Pointer"), QIcon(":/Qmitk/mm_pointer.png"), true); AddButton(InteractionScheme::PACSLevelWindow, tr("Level/Window"), QIcon(":/Qmitk/mm_contrast.png")); AddButton(InteractionScheme::PACSPan, tr("Pan"), QIcon(":/Qmitk/mm_pan.png")); AddButton(InteractionScheme::PACSScroll, tr("Scroll"), QIcon(":/Qmitk/mm_scroll.png")); AddButton(InteractionScheme::PACSZoom, tr("Zoom"), QIcon(":/Qmitk/mm_zoom.png")); m_InteractionSchemeSwitcher = mitk::InteractionSchemeSwitcher::New(); } void QmitkInteractionSchemeToolBar::SetInteractionEventHandler(mitk::InteractionEventHandler::Pointer interactionEventHandler) { if (interactionEventHandler == m_InteractionEventHandler) { return; } m_InteractionEventHandler = interactionEventHandler; - if (nullptr != m_InteractionEventHandler) + try { m_InteractionSchemeSwitcher->SetInteractionScheme(m_InteractionEventHandler, InteractionScheme::PACSStandard); } + catch (const mitk::Exception&) + { + return; + } } void QmitkInteractionSchemeToolBar::AddButton(InteractionScheme interactionScheme, const QString& toolName, const QIcon& icon, bool on) { QAction* action = new QAction(icon, toolName, this); action->setCheckable(true); action->setActionGroup(m_ActionGroup); action->setChecked(on); action->setData(interactionScheme); connect(action, SIGNAL(triggered()), this, SLOT(OnInteractionSchemeChanged())); QToolBar::addAction(action); } QmitkInteractionSchemeToolBar::~QmitkInteractionSchemeToolBar() { // nothing here } void QmitkInteractionSchemeToolBar::OnInteractionSchemeChanged() { QAction* action = dynamic_cast(sender()); if (action) { InteractionScheme interactionScheme = static_cast(action->data().toInt()); - if (m_InteractionEventHandler) + try { m_InteractionSchemeSwitcher->SetInteractionScheme(m_InteractionEventHandler, interactionScheme); } + catch (const mitk::Exception&) + { + return; + } } } diff --git a/Modules/QtWidgets/src/QmitkMxNMultiWidget.cpp b/Modules/QtWidgets/src/QmitkMxNMultiWidget.cpp index 6ab1cacbbc..2a174404c3 100644 --- a/Modules/QtWidgets/src/QmitkMxNMultiWidget.cpp +++ b/Modules/QtWidgets/src/QmitkMxNMultiWidget.cpp @@ -1,438 +1,445 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical Image Computing. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "QmitkMxNMultiWidget.h" #include #include #include #include // mitk core #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // qt #include QmitkMxNMultiWidget::QmitkMxNMultiWidget(QWidget* parent, Qt::WindowFlags f/* = 0*/, mitk::RenderingManager* renderingManager/* = nullptr*/, mitk::BaseRenderer::RenderingMode::Type renderingMode/* = mitk::BaseRenderer::RenderingMode::Standard*/, const QString& multiWidgetName/* = "mxnmulti"*/) : QWidget(parent, f) , m_MxNMultiWidgetLayout(nullptr) , m_MultiWidgetRows(0) , m_MultiWidgetColumns(0) , m_PlaneMode(0) , m_RenderingManager(renderingManager) , m_RenderingMode(renderingMode) , m_MultiWidgetName(multiWidgetName) , m_DisplayActionEventBroadcast(nullptr) , m_DisplayActionEventHandler(nullptr) , m_DataStorage(nullptr) { InitializeGUI(); InitializeDisplayActionEventHandling(); resize(QSize(364, 477).expandedTo(minimumSizeHint())); } void QmitkMxNMultiWidget::SetDataStorage(mitk::DataStorage* dataStorage) { if (dataStorage == m_DataStorage) { return; } m_DataStorage = dataStorage; // set new data storage for the render window widgets for (const auto& renderWindowWidget : m_RenderWindowWidgets) { renderWindowWidget.second->SetDataStorage(m_DataStorage); } } void QmitkMxNMultiWidget::InitializeRenderWindowWidgets() { m_MultiWidgetRows = 1; m_MultiWidgetColumns = 1; CreateRenderWindowWidget(); InitializeGUI(); } void QmitkMxNMultiWidget::ResetLayout(int row, int column) { m_MultiWidgetRows = row; m_MultiWidgetColumns = column; int requiredRenderWindowWidgets = m_MultiWidgetRows * m_MultiWidgetColumns; int existingRenderWindowWidgets = m_RenderWindowWidgets.size(); int difference = requiredRenderWindowWidgets - existingRenderWindowWidgets; while(0 < difference) { // more render window widgets needed CreateRenderWindowWidget(); --difference; } while(0 > difference) { // less render window widgets needed DestroyRenderWindowWidget(); ++difference; } InitializeGUI(); } void QmitkMxNMultiWidget::Synchronize(bool synchronized) { auto allObserverTags = m_DisplayActionEventHandler->GetAllObserverTags(); for (auto observerTag : allObserverTags) { m_DisplayActionEventHandler->DisconnectObserver(observerTag); } if (synchronized) { mitk::StdFunctionCommand::ActionFunction actionFunction = mitk::DisplayActionEventFunctions::MoveCameraSynchronizedAction(); m_DisplayActionEventHandler->ConnectDisplayActionEvent(mitk::DisplayMoveEvent(nullptr, mitk::Vector2D()), actionFunction); actionFunction = mitk::DisplayActionEventFunctions::SetCrosshairSynchronizedAction(); m_DisplayActionEventHandler->ConnectDisplayActionEvent(mitk::DisplaySetCrosshairEvent(nullptr, mitk::Point3D()), actionFunction); actionFunction = mitk::DisplayActionEventFunctions::ZoomCameraSynchronizedAction(); m_DisplayActionEventHandler->ConnectDisplayActionEvent(mitk::DisplayZoomEvent(nullptr, 0.0, mitk::Point2D()), actionFunction); actionFunction = mitk::DisplayActionEventFunctions::ScrollSliceStepperSynchronizedAction(); m_DisplayActionEventHandler->ConnectDisplayActionEvent(mitk::DisplayScrollEvent(nullptr, 0), actionFunction); } else { mitk::StdFunctionCommand::ActionFunction actionFunction = mitk::DisplayActionEventFunctions::MoveSenderCameraAction(); m_DisplayActionEventHandler->ConnectDisplayActionEvent(mitk::DisplayMoveEvent(nullptr, mitk::Vector2D()), actionFunction); actionFunction = mitk::DisplayActionEventFunctions::SetCrosshairAction(); m_DisplayActionEventHandler->ConnectDisplayActionEvent(mitk::DisplaySetCrosshairEvent(nullptr, mitk::Point3D()), actionFunction); actionFunction = mitk::DisplayActionEventFunctions::ZoomSenderCameraAction(); m_DisplayActionEventHandler->ConnectDisplayActionEvent(mitk::DisplayZoomEvent(nullptr, 0.0, mitk::Point2D()), actionFunction); actionFunction = mitk::DisplayActionEventFunctions::ScrollSliceStepperAction(); m_DisplayActionEventHandler->ConnectDisplayActionEvent(mitk::DisplayScrollEvent(nullptr, 0), actionFunction); } // use the standard 'set level window' action for both modes mitk::StdFunctionCommand::ActionFunction actionFunction = mitk::DisplayActionEventFunctions::SetLevelWindowAction(); m_DisplayActionEventHandler->ConnectDisplayActionEvent(mitk::DisplaySetLevelWindowEvent(nullptr, mitk::ScalarType(), mitk::ScalarType()), actionFunction); } void QmitkMxNMultiWidget::SetInteractionScheme(mitk::InteractionSchemeSwitcher::InteractionScheme scheme) { auto interactionSchemeSwitcher = mitk::InteractionSchemeSwitcher::New(); auto interactionEventHandler = GetInteractionEventHandler(); - interactionSchemeSwitcher->SetInteractionScheme(interactionEventHandler, scheme); + try + { + interactionSchemeSwitcher->SetInteractionScheme(interactionEventHandler, scheme); + } + catch (const mitk::Exception&) + { + return; + } } QmitkMxNMultiWidget::RenderWindowWidgetMap QmitkMxNMultiWidget::GetRenderWindowWidgets() const { return m_RenderWindowWidgets; } QmitkMxNMultiWidget::RenderWindowWidgetPointer QmitkMxNMultiWidget::GetRenderWindowWidget(int row, int column) const { return GetRenderWindowWidget(GetNameFromIndex(row, column)); } QmitkMxNMultiWidget::RenderWindowWidgetPointer QmitkMxNMultiWidget::GetRenderWindowWidget(const QString& widgetName) const { RenderWindowWidgetMap::const_iterator it = m_RenderWindowWidgets.find(widgetName); if (it != m_RenderWindowWidgets.end()) { return it->second; } return nullptr; } QmitkMxNMultiWidget::RenderWindowHash QmitkMxNMultiWidget::GetRenderWindows() const { RenderWindowHash result; // create QHash on demand auto renderWindowWidgets = GetRenderWindowWidgets(); for (const auto& renderWindowWidget : renderWindowWidgets) { result.insert(renderWindowWidget.first, renderWindowWidget.second->GetRenderWindow()); } return result; } QmitkRenderWindow* QmitkMxNMultiWidget::GetRenderWindow(int row, int column) const { return GetRenderWindow(GetNameFromIndex(row, column)); } QmitkRenderWindow* QmitkMxNMultiWidget::GetRenderWindow(const QString& widgetName) const { RenderWindowWidgetPointer renderWindowWidget = GetRenderWindowWidget(widgetName); if (nullptr != renderWindowWidget) { return renderWindowWidget->GetRenderWindow(); } return nullptr; } void QmitkMxNMultiWidget::SetActiveRenderWindowWidget(RenderWindowWidgetPointer activeRenderWindowWidget) { m_ActiveRenderWindowWidget = activeRenderWindowWidget; } QmitkMxNMultiWidget::RenderWindowWidgetPointer QmitkMxNMultiWidget::GetActiveRenderWindowWidget() const { return m_ActiveRenderWindowWidget; } QmitkMxNMultiWidget::RenderWindowWidgetPointer QmitkMxNMultiWidget::GetFirstRenderWindowWidget() const { if (!m_RenderWindowWidgets.empty()) { return m_RenderWindowWidgets.begin()->second; } else { return nullptr; } } QmitkMxNMultiWidget::RenderWindowWidgetPointer QmitkMxNMultiWidget::GetLastRenderWindowWidget() const { if (!m_RenderWindowWidgets.empty()) { return m_RenderWindowWidgets.rbegin()->second; } else { return nullptr; } } unsigned int QmitkMxNMultiWidget::GetNumberOfRenderWindowWidgets() const { return m_RenderWindowWidgets.size(); } void QmitkMxNMultiWidget::RequestUpdate(const QString& widgetName) { RenderWindowWidgetPointer renderWindowWidget = GetRenderWindowWidget(widgetName); if (nullptr != renderWindowWidget) { return renderWindowWidget->RequestUpdate(); } } void QmitkMxNMultiWidget::RequestUpdateAll() { for (const auto& renderWindowWidget : m_RenderWindowWidgets) { renderWindowWidget.second->RequestUpdate(); } } void QmitkMxNMultiWidget::ForceImmediateUpdate(const QString& widgetName) { RenderWindowWidgetPointer renderWindowWidget = GetRenderWindowWidget(widgetName); if (nullptr != renderWindowWidget) { renderWindowWidget->ForceImmediateUpdate(); } } void QmitkMxNMultiWidget::ForceImmediateUpdateAll() { for (const auto& renderWindowWidget : m_RenderWindowWidgets) { renderWindowWidget.second->ForceImmediateUpdate(); } } void QmitkMxNMultiWidget::ActivateAllCrosshairs(bool activate) { for (const auto& renderWindowWidget : m_RenderWindowWidgets) { renderWindowWidget.second->ActivateCrosshair(activate); } } const mitk::Point3D QmitkMxNMultiWidget::GetSelectedPosition(const QString& /*widgetName*/) const { // see T26208 return mitk::Point3D(); } ////////////////////////////////////////////////////////////////////////// // PUBLIC SLOTS ////////////////////////////////////////////////////////////////////////// void QmitkMxNMultiWidget::SetSelectedPosition(const QString& widgetName, const mitk::Point3D& newPosition) { RenderWindowWidgetPointer renderWindowWidget; if (widgetName.isNull()) { renderWindowWidget = GetActiveRenderWindowWidget(); } else { renderWindowWidget = GetRenderWindowWidget(widgetName); } if (nullptr != renderWindowWidget) { renderWindowWidget->GetSliceNavigationController()->SelectSliceByPoint(newPosition); renderWindowWidget->RequestUpdate(); return; } MITK_ERROR << "Position can not be set for an unknown render window widget."; } ////////////////////////////////////////////////////////////////////////// // MOUSE EVENTS ////////////////////////////////////////////////////////////////////////// void QmitkMxNMultiWidget::wheelEvent(QWheelEvent* e) { emit WheelMoved(e); } void QmitkMxNMultiWidget::mousePressEvent(QMouseEvent* /*e*/) { } 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::InitializeGUI() { delete m_MxNMultiWidgetLayout; m_MxNMultiWidgetLayout = new QGridLayout(this); m_MxNMultiWidgetLayout->setContentsMargins(0, 0, 0, 0); setLayout(m_MxNMultiWidgetLayout); FillMultiWidgetLayout(); } void QmitkMxNMultiWidget::InitializeDisplayActionEventHandling() { m_DisplayActionEventBroadcast = mitk::DisplayActionEventBroadcast::New(); m_DisplayActionEventBroadcast->LoadStateMachine("DisplayInteraction.xml"); m_DisplayActionEventBroadcast->SetEventConfig("DisplayConfigMITK.xml"); m_DisplayActionEventHandler = std::make_unique(); m_DisplayActionEventHandler->SetObservableBroadcast(m_DisplayActionEventBroadcast); Synchronize(true); } void QmitkMxNMultiWidget::CreateRenderWindowWidget() { // create the render window widget and connect signals / slots QString renderWindowWidgetName = GetNameFromIndex(m_RenderWindowWidgets.size()); RenderWindowWidgetPointer renderWindowWidget = std::make_shared(this, renderWindowWidgetName, m_DataStorage); renderWindowWidget->SetCornerAnnotationText(renderWindowWidgetName.toStdString()); // store the newly created render window widget with the UID m_RenderWindowWidgets.insert(std::make_pair(renderWindowWidgetName, renderWindowWidget)); } void QmitkMxNMultiWidget::DestroyRenderWindowWidget() { auto iterator = m_RenderWindowWidgets.find(GetNameFromIndex(m_RenderWindowWidgets.size() - 1)); if (iterator == m_RenderWindowWidgets.end()) { return; } // disconnect each signal of this render window widget RenderWindowWidgetPointer renderWindowWidgetToRemove = iterator->second; disconnect(renderWindowWidgetToRemove.get(), 0, 0, 0); // erase the render window from the map m_RenderWindowWidgets.erase(iterator); } void QmitkMxNMultiWidget::FillMultiWidgetLayout() { for (int row = 0; row < m_MultiWidgetRows; ++row) { for (int column = 0; column < m_MultiWidgetColumns; ++column) { RenderWindowWidgetPointer renderWindowWidget = GetRenderWindowWidget(row, column); if (nullptr != renderWindowWidget) { m_MxNMultiWidgetLayout->addWidget(renderWindowWidget.get(), row, column); SetActiveRenderWindowWidget(renderWindowWidget); } } } } QString QmitkMxNMultiWidget::GetNameFromIndex(int row, int column) const { if (0 <= row && m_MultiWidgetRows > row && 0 <= column && m_MultiWidgetColumns > column) { return GetNameFromIndex(row * m_MultiWidgetColumns + column); } return QString(); } QString QmitkMxNMultiWidget::GetNameFromIndex(size_t index) const { if (index <= m_RenderWindowWidgets.size()) { return m_MultiWidgetName + ".widget" + QString::number(index); } return QString(); }