diff --git a/Modules/QtWidgets/src/QmitkRenderWindow.cpp b/Modules/QtWidgets/src/QmitkRenderWindow.cpp index ac15146160..ab9657b238 100644 --- a/Modules/QtWidgets/src/QmitkRenderWindow.cpp +++ b/Modules/QtWidgets/src/QmitkRenderWindow.cpp @@ -1,516 +1,516 @@ /*============================================================================ 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 "QmitkRenderWindow.h" #include "mitkInteractionKeyEvent.h" #include "mitkInternalEvent.h" #include "mitkMouseDoubleClickEvent.h" #include "mitkMouseMoveEvent.h" #include "mitkMousePressEvent.h" #include "mitkMouseReleaseEvent.h" #include "mitkMouseWheelEvent.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include QmitkRenderWindow::QmitkRenderWindow(QWidget *parent, const QString &name, mitk::VtkPropRenderer *) : QVTKOpenGLNativeWidget(parent) , m_ResendQtEvents(true) , m_MenuWidget(nullptr) , m_MenuWidgetActivated(false) , m_LayoutIndex(QmitkRenderWindowMenu::LayoutIndex::Axial) , m_GeometryViolationWarningOverlay(nullptr) { m_InternalRenderWindow = vtkSmartPointer::New(); m_InternalRenderWindow->SetMultiSamples(0); m_InternalRenderWindow->SetAlphaBitPlanes(0); setRenderWindow(m_InternalRenderWindow); Initialize(name.toStdString().c_str()); setFocusPolicy(Qt::StrongFocus); setMouseTracking(true); QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); setSizePolicy(sizePolicy); // setup overlay widget to show a warning message with a button m_GeometryViolationWarningOverlay = new QmitkButtonOverlayWidget(this); m_GeometryViolationWarningOverlay->setVisible(false); m_GeometryViolationWarningOverlay->SetOverlayText( QStringLiteral("

Interaction is not possible because the " "render window geometry
does not match the interaction reference geometry.

")); m_GeometryViolationWarningOverlay->SetButtonText("Reset geometry"); m_GeometryViolationWarningOverlay->SetButtonIcon(QmitkStyleManager::ThemeIcon(QLatin1String(":/Qmitk/reset.svg"))); connect(m_GeometryViolationWarningOverlay, &QmitkButtonOverlayWidget::Clicked, this, &QmitkRenderWindow::ResetGeometry); } QmitkRenderWindow::~QmitkRenderWindow() { Destroy(); // Destroy mitkRenderWindowBase } void QmitkRenderWindow::SetResendQtEvents(bool resend) { m_ResendQtEvents = resend; } void QmitkRenderWindow::SetLayoutIndex(QmitkRenderWindowMenu::LayoutIndex layoutIndex) { m_LayoutIndex = layoutIndex; if (nullptr != m_MenuWidget) { m_MenuWidget->SetLayoutIndex(layoutIndex); } } QmitkRenderWindowMenu::LayoutIndex QmitkRenderWindow::GetLayoutIndex() { if (nullptr != m_MenuWidget) { return m_MenuWidget->GetLayoutIndex(); } else { return QmitkRenderWindowMenu::LayoutIndex::Axial; } } void QmitkRenderWindow::UpdateLayoutDesignList(QmitkRenderWindowMenu::LayoutDesign layoutDesign) { if (nullptr != m_MenuWidget) { m_MenuWidget->UpdateLayoutDesignList(layoutDesign); } } void QmitkRenderWindow::UpdateCrosshairVisibility(bool visible) { m_MenuWidget->UpdateCrosshairVisibility(visible); } void QmitkRenderWindow::UpdateCrosshairRotationMode(int mode) { m_MenuWidget->UpdateCrosshairRotationMode(mode); } void QmitkRenderWindow::ActivateMenuWidget(bool state) { if (nullptr == m_MenuWidget) { m_MenuWidget = new QmitkRenderWindowMenu(this, {}, m_Renderer); m_MenuWidget->SetLayoutIndex(m_LayoutIndex); } if (m_MenuWidgetActivated == state) { // no new state; nothing to do return; } m_MenuWidgetActivated = state; if (m_MenuWidgetActivated) { connect(m_MenuWidget, &QmitkRenderWindowMenu::LayoutDesignChanged, this, &QmitkRenderWindow::LayoutDesignChanged); connect(m_MenuWidget, &QmitkRenderWindowMenu::ResetView, this, &QmitkRenderWindow::ResetView); connect(m_MenuWidget, &QmitkRenderWindowMenu::CrosshairVisibilityChanged, this, &QmitkRenderWindow::CrosshairVisibilityChanged); connect(m_MenuWidget, &QmitkRenderWindowMenu::CrosshairRotationModeChanged, this, &QmitkRenderWindow::CrosshairRotationModeChanged); } else { disconnect(m_MenuWidget, &QmitkRenderWindowMenu::LayoutDesignChanged, this, &QmitkRenderWindow::LayoutDesignChanged); disconnect(m_MenuWidget, &QmitkRenderWindowMenu::ResetView, this, &QmitkRenderWindow::ResetView); disconnect(m_MenuWidget, &QmitkRenderWindowMenu::CrosshairVisibilityChanged, this, &QmitkRenderWindow::CrosshairVisibilityChanged); disconnect(m_MenuWidget, &QmitkRenderWindowMenu::CrosshairRotationModeChanged, this, &QmitkRenderWindow::CrosshairRotationModeChanged); m_MenuWidget->hide(); } } void QmitkRenderWindow::ShowOverlayMessage(bool show) { m_GeometryViolationWarningOverlay->setVisible(show); } void QmitkRenderWindow::moveEvent(QMoveEvent *event) { QVTKOpenGLNativeWidget::moveEvent(event); // after a move the overlays need to be positioned emit moved(); } void QmitkRenderWindow::showEvent(QShowEvent *event) { QVTKOpenGLNativeWidget::showEvent(event); // this singleshot is necessary to have the overlays positioned correctly after initial show // simple call of moved() is no use here!! QTimer::singleShot(0, this, SIGNAL(moved())); } bool QmitkRenderWindow::event(QEvent* e) { mitk::InteractionEvent::Pointer mitkEvent = nullptr; mitk::Point2D mousePosition; bool updateStatusBar = false; switch (e->type()) { case QEvent::MouseMove: { auto me = static_cast(e); mousePosition = this->GetMousePosition(me); mitkEvent = mitk::MouseMoveEvent::New(m_Renderer, mousePosition, GetButtonState(me), GetModifiers(me)); updateStatusBar = true; break; } case QEvent::MouseButtonPress: { auto me = static_cast(e); mitkEvent = mitk::MousePressEvent::New( m_Renderer, GetMousePosition(me), GetButtonState(me), GetModifiers(me), GetEventButton(me)); break; } case QEvent::MouseButtonRelease: { auto me = static_cast(e); mitkEvent = mitk::MouseReleaseEvent::New( m_Renderer, GetMousePosition(me), GetButtonState(me), GetModifiers(me), GetEventButton(me)); break; } case QEvent::MouseButtonDblClick: { auto me = static_cast(e); mitkEvent = mitk::MouseDoubleClickEvent::New( m_Renderer, GetMousePosition(me), GetButtonState(me), GetModifiers(me), GetEventButton(me)); break; } case QEvent::Wheel: { auto we = static_cast(e); mousePosition = this->GetMousePosition(we); mitkEvent = mitk::MouseWheelEvent::New(m_Renderer, mousePosition, GetButtonState(we), GetModifiers(we), GetDelta(we)); updateStatusBar = true; break; } case QEvent::KeyPress: { auto ke = static_cast(e); mitkEvent = mitk::InteractionKeyEvent::New(m_Renderer, GetKeyLetter(ke), GetModifiers(ke)); break; } case QEvent::Resize: { if (nullptr != m_MenuWidget) m_MenuWidget->MoveWidgetToCorrectPos(); } default: { break; } } if (mitkEvent != nullptr) { if (this->HandleEvent(mitkEvent.GetPointer())) { return m_ResendQtEvents ? false : true; } } if (updateStatusBar) { this->UpdateStatusBar(mousePosition); } return QVTKOpenGLNativeWidget::event(e); } void QmitkRenderWindow::enterEvent(QEnterEvent *e) { auto* baseRenderer = mitk::BaseRenderer::GetInstance(this->GetVtkRenderWindow()); this->ShowOverlayMessage(!baseRenderer->GetReferenceGeometryAligned()); if (nullptr != m_MenuWidget) m_MenuWidget->ShowMenu(); QVTKOpenGLNativeWidget::enterEvent(e); } void QmitkRenderWindow::leaveEvent(QEvent *e) { auto statusBar = mitk::StatusBar::GetInstance(); statusBar->DisplayGreyValueText(""); this->ShowOverlayMessage(false); if (nullptr != m_MenuWidget) m_MenuWidget->HideMenu(); QVTKOpenGLNativeWidget::leaveEvent(e); } void QmitkRenderWindow::resizeGL(int w, int h) { QVTKOpenGLNativeWidget::resizeGL(w, h); mitk::RenderingManager::GetInstance()->ForceImmediateUpdate(renderWindow()); } void QmitkRenderWindow::dragEnterEvent(QDragEnterEvent *event) { if (event->mimeData()->hasFormat("application/x-mitk-datanodes")) { event->accept(); } } void QmitkRenderWindow::dropEvent(QDropEvent *event) { QList dataNodeList = QmitkMimeTypes::ToDataNodePtrList(event->mimeData()); if (!dataNodeList.empty()) { std::vector dataNodes(dataNodeList.begin(), dataNodeList.end()); emit NodesDropped(this, dataNodes); } } void QmitkRenderWindow::DeferredHideMenu() { MITK_DEBUG << "QmitkRenderWindow::DeferredHideMenu"; if (nullptr != m_MenuWidget) { m_MenuWidget->HideMenu(); } } mitk::Point2D QmitkRenderWindow::GetMousePosition(QMouseEvent *me) const { mitk::Point2D point; const auto scale = this->devicePixelRatioF(); point[0] = me->x()*scale; // We need to convert the y component, as the display and vtk have other definitions for the y direction point[1] = m_Renderer->GetSizeY() - me->y()*scale; return point; } mitk::Point2D QmitkRenderWindow::GetMousePosition(QWheelEvent *we) const { mitk::Point2D point; const auto scale = this->devicePixelRatioF(); - point[0] = we->x()*scale; + point[0] = we->position().x()*scale; // We need to convert the y component, as the display and vtk have other definitions for the y direction - point[1] = m_Renderer->GetSizeY() - we->y()*scale; + point[1] = m_Renderer->GetSizeY() - we->position().y()*scale; return point; } mitk::InteractionEvent::MouseButtons QmitkRenderWindow::GetEventButton(QMouseEvent *me) const { mitk::InteractionEvent::MouseButtons eventButton; switch (me->button()) { case Qt::LeftButton: eventButton = mitk::InteractionEvent::LeftMouseButton; break; case Qt::RightButton: eventButton = mitk::InteractionEvent::RightMouseButton; break; case Qt::MiddleButton: eventButton = mitk::InteractionEvent::MiddleMouseButton; break; default: eventButton = mitk::InteractionEvent::NoButton; break; } return eventButton; } mitk::InteractionEvent::MouseButtons QmitkRenderWindow::GetButtonState(QMouseEvent *me) const { mitk::InteractionEvent::MouseButtons buttonState = mitk::InteractionEvent::NoButton; if (me->buttons() & Qt::LeftButton) { buttonState = buttonState | mitk::InteractionEvent::LeftMouseButton; } if (me->buttons() & Qt::RightButton) { buttonState = buttonState | mitk::InteractionEvent::RightMouseButton; } if (me->buttons() & Qt::MiddleButton) { buttonState = buttonState | mitk::InteractionEvent::MiddleMouseButton; } return buttonState; } mitk::InteractionEvent::ModifierKeys QmitkRenderWindow::GetModifiers(QInputEvent *me) const { mitk::InteractionEvent::ModifierKeys modifiers = mitk::InteractionEvent::NoKey; if (me->modifiers() & Qt::ALT) { modifiers = modifiers | mitk::InteractionEvent::AltKey; } if (me->modifiers() & Qt::CTRL) { modifiers = modifiers | mitk::InteractionEvent::ControlKey; } if (me->modifiers() & Qt::SHIFT) { modifiers = modifiers | mitk::InteractionEvent::ShiftKey; } return modifiers; } mitk::InteractionEvent::MouseButtons QmitkRenderWindow::GetButtonState(QWheelEvent *we) const { mitk::InteractionEvent::MouseButtons buttonState = mitk::InteractionEvent::NoButton; if (we->buttons() & Qt::LeftButton) { buttonState = buttonState | mitk::InteractionEvent::LeftMouseButton; } if (we->buttons() & Qt::RightButton) { buttonState = buttonState | mitk::InteractionEvent::RightMouseButton; } if (we->buttons() & Qt::MiddleButton) { buttonState = buttonState | mitk::InteractionEvent::MiddleMouseButton; } return buttonState; } std::string QmitkRenderWindow::GetKeyLetter(QKeyEvent *ke) const { // Converting Qt Key Event to string element. std::string key = ""; int tkey = ke->key(); if (tkey < 128) { // standard ascii letter key = (char)toupper(tkey); } else { // special keys switch (tkey) { case Qt::Key_Return: key = mitk::InteractionEvent::KeyReturn; break; case Qt::Key_Enter: key = mitk::InteractionEvent::KeyEnter; break; case Qt::Key_Escape: key = mitk::InteractionEvent::KeyEsc; break; case Qt::Key_Delete: key = mitk::InteractionEvent::KeyDelete; break; case Qt::Key_Up: key = mitk::InteractionEvent::KeyArrowUp; break; case Qt::Key_Down: key = mitk::InteractionEvent::KeyArrowDown; break; case Qt::Key_Left: key = mitk::InteractionEvent::KeyArrowLeft; break; case Qt::Key_Right: key = mitk::InteractionEvent::KeyArrowRight; break; case Qt::Key_F1: key = mitk::InteractionEvent::KeyF1; break; case Qt::Key_F2: key = mitk::InteractionEvent::KeyF2; break; case Qt::Key_F3: key = mitk::InteractionEvent::KeyF3; break; case Qt::Key_F4: key = mitk::InteractionEvent::KeyF4; break; case Qt::Key_F5: key = mitk::InteractionEvent::KeyF5; break; case Qt::Key_F6: key = mitk::InteractionEvent::KeyF6; break; case Qt::Key_F7: key = mitk::InteractionEvent::KeyF7; break; case Qt::Key_F8: key = mitk::InteractionEvent::KeyF8; break; case Qt::Key_F9: key = mitk::InteractionEvent::KeyF9; break; case Qt::Key_F10: key = mitk::InteractionEvent::KeyF10; break; case Qt::Key_F11: key = mitk::InteractionEvent::KeyF11; break; case Qt::Key_F12: key = mitk::InteractionEvent::KeyF12; break; case Qt::Key_End: key = mitk::InteractionEvent::KeyEnd; break; case Qt::Key_Home: key = mitk::InteractionEvent::KeyPos1; break; case Qt::Key_Insert: key = mitk::InteractionEvent::KeyInsert; break; case Qt::Key_PageDown: key = mitk::InteractionEvent::KeyPageDown; break; case Qt::Key_PageUp: key = mitk::InteractionEvent::KeyPageUp; break; case Qt::Key_Space: key = mitk::InteractionEvent::KeySpace; break; } } return key; } int QmitkRenderWindow::GetDelta(QWheelEvent *we) const { - return we->delta(); + return we->angleDelta().y(); } void QmitkRenderWindow::UpdateStatusBar(mitk::Point2D pointerPositionOnScreen) { mitk::Point3D worldPosition; m_Renderer->ForceImmediateUpdate(); m_Renderer->DisplayToWorld(pointerPositionOnScreen, worldPosition); auto statusBar = mitk::StatusBar::GetInstance(); statusBar->DisplayRendererInfo(worldPosition, m_Renderer->GetTime()); } diff --git a/Modules/QtWidgetsExt/src/QmitkPointListView.cpp b/Modules/QtWidgetsExt/src/QmitkPointListView.cpp index cf25972d78..3d3ec8c652 100644 --- a/Modules/QtWidgetsExt/src/QmitkPointListView.cpp +++ b/Modules/QtWidgetsExt/src/QmitkPointListView.cpp @@ -1,336 +1,336 @@ /*============================================================================ 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 "QmitkPointListView.h" #include #include #include #include #include #include #include #include #include #include QmitkPointListView::QmitkPointListView(QWidget *parent) : QListView(parent), m_PointListModel(new QmitkPointListModel()), m_SelfCall(false), m_showFading(false), m_MultiWidget(nullptr) { QListView::setAlternatingRowColors(true); QListView::setSelectionBehavior(QAbstractItemView::SelectItems); QListView::setSelectionMode(QAbstractItemView::SingleSelection); QListView::setModel(m_PointListModel); QString tooltip = QString("Use the F2/F3 keys to move a point up/down, the Del key to remove a point\nand the mouse " "wheel to change the timestep.\n\nTimeStep:\t%1") .arg(0); QListView::setToolTip(tooltip); this->setContextMenuPolicy(Qt::CustomContextMenu); this->setMinimumHeight(40); this->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); connect(m_PointListModel, SIGNAL(SignalUpdateSelection()), this, SLOT(OnPointSetSelectionChanged())); connect(this, SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT(OnPointDoubleClicked(const QModelIndex &))); connect(QListView::selectionModel(), SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)), this, SLOT(OnListViewSelectionChanged(const QItemSelection &, const QItemSelection &))); // T28213: Every single action in the context menu is either not implemented or working. Implement/fix or remove in future. // connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(ctxMenu(const QPoint &))); } QmitkPointListView::~QmitkPointListView() { delete m_PointListModel; } void QmitkPointListView::SetPointSetNode(mitk::DataNode *pointSetNode) { m_PointListModel->SetPointSetNode(pointSetNode); } const mitk::PointSet *QmitkPointListView::GetPointSet() const { return m_PointListModel->GetPointSet(); } void QmitkPointListView::SetMultiWidget(QmitkAbstractMultiWidget* multiWidget) { m_MultiWidget = multiWidget; if (nullptr != m_MultiWidget) { for (const auto& renderWindow : m_MultiWidget->GetRenderWindows().values()) { AddSliceNavigationController(renderWindow->GetSliceNavigationController()); } } } QmitkAbstractMultiWidget* QmitkPointListView::GetMultiWidget() const { return m_MultiWidget; } void QmitkPointListView::OnPointDoubleClicked(const QModelIndex &index) { mitk::PointSet::PointType p; mitk::PointSet::PointIdentifier id; m_PointListModel->GetPointForModelIndex(index, p, id); QmitkEditPointDialog _EditPointDialog(this); _EditPointDialog.SetPoint(m_PointListModel->GetPointSet(), id, m_PointListModel->GetTimeStep()); _EditPointDialog.exec(); } void QmitkPointListView::OnPointSetSelectionChanged() { const mitk::PointSet *pointSet = m_PointListModel->GetPointSet(); if (pointSet == nullptr) return; // update this view's selection status as a result to changes in the point set data structure m_SelfCall = true; int timeStep = m_PointListModel->GetTimeStep(); if (pointSet->GetNumberOfSelected(timeStep) > 1) { MITK_ERROR << "Point set has multiple selected points. This view is not designed for more than one selected point."; } int selectedIndex = pointSet->SearchSelectedPoint(timeStep); if (selectedIndex == -1) // no selected point is found { m_SelfCall = false; return; } QModelIndex index; bool modelIndexOkay = m_PointListModel->GetModelIndexForPointID(selectedIndex, index); if (modelIndexOkay == true) QListView::selectionModel()->select(index, QItemSelectionModel::ClearAndSelect); emit SignalPointSelectionChanged(); m_SelfCall = false; } void QmitkPointListView::OnListViewSelectionChanged(const QItemSelection &selected, const QItemSelection & /*deselected*/) { if (m_SelfCall) return; mitk::PointSet *pointSet = const_cast(m_PointListModel->GetPointSet()); if (pointSet == nullptr) return; // (take care that this widget doesn't react to self-induced changes by setting m_SelfCall) m_SelfCall = true; // update selection of all points in pointset: select the one(s) that are selected in the view, deselect all others QModelIndexList selectedIndexes = selected.indexes(); // only call setSelectInfo on a point set with 'selected = true' if you deselcted the other entries int indexToSelect = -1; for (mitk::PointSet::PointsContainer::Iterator it = pointSet->GetPointSet(m_PointListModel->GetTimeStep())->GetPoints()->Begin(); it != pointSet->GetPointSet(m_PointListModel->GetTimeStep())->GetPoints()->End(); ++it) { QModelIndex index; if (m_PointListModel->GetModelIndexForPointID(it->Index(), index)) { if (selectedIndexes.indexOf(index) != -1) // index is found in the selected indices list { indexToSelect = it->Index(); } else { pointSet->SetSelectInfo(it->Index(), false, m_PointListModel->GetTimeStep()); } } } // force selection of only one index after deselecting the others if (indexToSelect > -1) { pointSet->SetSelectInfo(indexToSelect, true, m_PointListModel->GetTimeStep()); mitk::Point3D p = pointSet->GetPoint(indexToSelect, m_PointListModel->GetTimeStep()); for (auto snc : m_Sncs) snc->SelectSliceByPoint(p); } m_SelfCall = false; emit SignalPointSelectionChanged(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkPointListView::keyPressEvent(QKeyEvent *e) { if (m_PointListModel == nullptr) return; int key = e->key(); switch (key) { case Qt::Key_F2: m_PointListModel->MoveSelectedPointUp(); break; case Qt::Key_F3: m_PointListModel->MoveSelectedPointDown(); break; case Qt::Key_Delete: m_PointListModel->RemoveSelectedPoint(); break; default: break; } } void QmitkPointListView::wheelEvent(QWheelEvent *event) { if (!m_PointListModel || !m_PointListModel->GetPointSet() || (int)(m_PointListModel->GetPointSet()->GetTimeSteps()) == 1) return; - int whe = event->delta(); + int whe = event->angleDelta().y(); mitk::PointSet::Pointer ps = dynamic_cast(m_PointListModel->GetPointSet()); unsigned int numberOfTS = ps->GetTimeSteps(); if (numberOfTS == 1) return; int currentTS = this->m_PointListModel->GetTimeStep(); if (whe > 0) { if ((currentTS + 1 >= (int)numberOfTS)) return; this->m_PointListModel->SetTimeStep(++currentTS); } else { if ((currentTS <= 0)) return; this->m_PointListModel->SetTimeStep(--currentTS); } QString tooltip = QString("Use the F2/F3 keys to move a point up/down, the Del key to remove a point\nand the mouse " "wheel to change the timestep.\n\nTimeStep:\t%1") .arg(currentTS); this->setToolTip(tooltip); emit SignalTimeStepChanged(currentTS); } void QmitkPointListView::ctxMenu(const QPoint &pos) { QMenu *menu = new QMenu; // add Fading check QAction *showFading = new QAction(this); showFading->setCheckable(false); // TODO: reset when fading is working showFading->setEnabled(false); // TODO: reset when fading is working showFading->setText("Fade TimeStep"); connect(showFading, SIGNAL(triggered(bool)), this, SLOT(SetFading(bool))); menu->addAction(showFading); // add Clear action QAction *clearList = new QAction(this); clearList->setText("Clear List"); connect(clearList, SIGNAL(triggered()), this, SLOT(ClearPointList())); menu->addAction(clearList); // add Clear TimeStep action QAction *clearTS = new QAction(this); clearTS->setText("Clear current time step"); connect(clearTS, SIGNAL(triggered()), this, SLOT(ClearPointListTS())); menu->addAction(clearTS); menu->exec(this->mapToGlobal(pos)); } void QmitkPointListView::SetFading(bool onOff) { m_showFading = onOff; } void QmitkPointListView::ClearPointList() { if (!m_PointListModel->GetPointSet()) return; mitk::PointSet::Pointer curPS = m_PointListModel->GetPointSet(); if (curPS->GetSize() == 0) return; switch (QMessageBox::question(this, tr("Clear Points"), tr("Remove all points from the displayed list?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No)) { case QMessageBox::Yes: { mitk::PointSet::PointsIterator it; mitk::PointSet::PointsContainer *curPsPoints; while (!curPS->IsEmptyTimeStep(0)) { curPsPoints = curPS->GetPointSet()->GetPoints(); it = curPsPoints->Begin(); curPS->SetSelectInfo(it->Index(), true); m_PointListModel->RemoveSelectedPoint(); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); break; } case QMessageBox::No: default: break; } } void QmitkPointListView::ClearPointListTS() { } void QmitkPointListView::AddSliceNavigationController(mitk::SliceNavigationController *snc) { if (snc == nullptr) return; m_Sncs.insert(snc); } void QmitkPointListView::RemoveSliceNavigationController(mitk::SliceNavigationController *snc) { if (snc == nullptr) return; m_Sncs.erase(snc); } diff --git a/Modules/QtWidgetsExt/src/QmitkSliceWidget.cpp b/Modules/QtWidgetsExt/src/QmitkSliceWidget.cpp index 69da61ffbb..c3ec916a01 100644 --- a/Modules/QtWidgetsExt/src/QmitkSliceWidget.cpp +++ b/Modules/QtWidgetsExt/src/QmitkSliceWidget.cpp @@ -1,266 +1,266 @@ /*============================================================================ 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 "QmitkSliceWidget.h" #include "QmitkStepperAdapter.h" #include "mitkCameraController.h" #include "mitkImage.h" #include "mitkNodePredicateDataType.h" #include #include #include #include QmitkSliceWidget::QmitkSliceWidget(QWidget *parent, const char *name, Qt::WindowFlags f) : QWidget(parent, f) { this->setupUi(this); if (name != nullptr) this->setObjectName(name); popUp = new QMenu(this); popUp->addAction("Axial"); popUp->addAction("Coronal"); popUp->addAction("Sagittal"); QObject::connect(popUp, SIGNAL(triggered(QAction *)), this, SLOT(ChangeView(QAction *))); setPopUpEnabled(false); m_SlicedGeometry = nullptr; m_View = mitk::AnatomicalPlane::Axial; QHBoxLayout *hlayout = new QHBoxLayout(container); hlayout->setContentsMargins({}); // create widget QString composedName("QmitkSliceWidget::"); if (!this->objectName().isEmpty()) composedName += this->objectName(); else composedName += "QmitkGLWidget"; m_RenderWindow = new QmitkRenderWindow(container, composedName); m_Renderer = m_RenderWindow->GetRenderer(); hlayout->addWidget(m_RenderWindow); new QmitkStepperAdapter(sliceNavigationWidget, m_RenderWindow->GetSliceNavigationController()->GetStepper()); SetLevelWindowEnabled(true); } mitk::VtkPropRenderer *QmitkSliceWidget::GetRenderer() { return m_Renderer; } QFrame *QmitkSliceWidget::GetSelectionFrame() { return SelectionFrame; } void QmitkSliceWidget::SetDataStorage(mitk::StandaloneDataStorage::Pointer storage) { m_DataStorage = storage; m_Renderer->SetDataStorage(m_DataStorage); } mitk::StandaloneDataStorage *QmitkSliceWidget::GetDataStorage() { return m_DataStorage; } void QmitkSliceWidget::SetData(mitk::DataStorage::SetOfObjects::ConstIterator it) { SetData(it->Value(), m_View); } void QmitkSliceWidget::SetData(mitk::DataStorage::SetOfObjects::ConstIterator it, mitk::AnatomicalPlane view) { SetData(it->Value(), view); } void QmitkSliceWidget::SetData(mitk::DataNode::Pointer node) { try { if (m_DataStorage.IsNotNull()) { m_DataStorage->Add(node); } } catch (...) { } SetData(node, m_View); } void QmitkSliceWidget::SetData(mitk::DataNode::Pointer node, mitk::AnatomicalPlane view) { mitk::Image::Pointer image = dynamic_cast(node->GetData()); if (image.IsNull()) { MITK_WARN << "QmitkSliceWidget data is not an image!"; return; } m_SlicedGeometry = image->GetSlicedGeometry(); this->InitWidget(view); } void QmitkSliceWidget::InitWidget(mitk::AnatomicalPlane view) { m_View = view; mitk::SliceNavigationController *controller = m_RenderWindow->GetSliceNavigationController(); if (view == mitk::AnatomicalPlane::Axial) { controller->SetViewDirection(mitk::AnatomicalPlane::Axial); } else if (view == mitk::AnatomicalPlane::Coronal) { controller->SetViewDirection(mitk::AnatomicalPlane::Coronal); } // init sagittal view for all other cases ('original' is covered here as well) else { controller->SetViewDirection(mitk::AnatomicalPlane::Sagittal); } if (m_SlicedGeometry.IsNull()) { return; } mitk::BaseGeometry::Pointer geometry = static_cast(m_SlicedGeometry->Clone().GetPointer()); const mitk::BoundingBox::Pointer boundingbox = m_DataStorage->ComputeVisibleBoundingBox(GetRenderer(), nullptr); if (boundingbox->GetPoints()->Size() > 0) { // let's see if we have data with a limited live-span ... mitk::TimeBounds timebounds = m_DataStorage->ComputeTimeBounds(GetRenderer(), nullptr); mitk::ProportionalTimeGeometry::Pointer timeGeometry = mitk::ProportionalTimeGeometry::New(); timeGeometry->Initialize(geometry, 1); { timeGeometry->SetFirstTimePoint(timebounds[0]); timeGeometry->SetStepDuration(1.0); } if (timeGeometry->GetBoundingBoxInWorld()->GetDiagonalLength2() >= mitk::eps) { controller->SetInputWorldTimeGeometry(timeGeometry); controller->Update(); } } GetRenderer()->GetCameraController()->Fit(); mitk::RenderingManager::GetInstance()->RequestUpdate(GetRenderer()->GetRenderWindow()); } void QmitkSliceWidget::UpdateGL() { GetRenderer()->GetCameraController()->Fit(); mitk::RenderingManager::GetInstance()->RequestUpdate(GetRenderer()->GetRenderWindow()); } void QmitkSliceWidget::mousePressEvent(QMouseEvent *e) { if (e->button() == Qt::RightButton && popUpEnabled) { popUp->popup(QCursor::pos()); } } void QmitkSliceWidget::wheelEvent(QWheelEvent *e) { int val = sliceNavigationWidget->GetPos(); - if (e->orientation() * e->delta() > 0) + if (e->angleDelta().y() > 0) { sliceNavigationWidget->SetPos(val + 1); } else { if (val > 0) sliceNavigationWidget->SetPos(val - 1); } } void QmitkSliceWidget::ChangeView(QAction *val) { if (val->text() == "Axial") { InitWidget(mitk::AnatomicalPlane::Axial); } else if (val->text() == "Coronal") { InitWidget(mitk::AnatomicalPlane::Coronal); } else if (val->text() == "Sagittal") { InitWidget(mitk::AnatomicalPlane::Sagittal); } } void QmitkSliceWidget::setPopUpEnabled(bool b) { popUpEnabled = b; } QmitkSliceNavigationWidget* QmitkSliceWidget::GetSliceNavigationWidget() { return sliceNavigationWidget; } void QmitkSliceWidget::SetLevelWindowEnabled(bool enable) { levelWindow->setEnabled(enable); if (!enable) { levelWindow->setMinimumWidth(0); levelWindow->setMaximumWidth(0); } else { levelWindow->setMinimumWidth(28); levelWindow->setMaximumWidth(28); } } bool QmitkSliceWidget::IsLevelWindowEnabled() { return levelWindow->isEnabled(); } QmitkRenderWindow *QmitkSliceWidget::GetRenderWindow() { return m_RenderWindow; } mitk::SliceNavigationController *QmitkSliceWidget::GetSliceNavigationController() const { return m_RenderWindow->GetSliceNavigationController(); } mitk::CameraRotationController *QmitkSliceWidget::GetCameraRotationController() const { return m_RenderWindow->GetCameraRotationController(); } mitk::BaseController *QmitkSliceWidget::GetController() const { return m_RenderWindow->GetController(); } diff --git a/Plugins/org.blueberry.ui.qt.help/src/internal/berryHelpWebView.cpp b/Plugins/org.blueberry.ui.qt.help/src/internal/berryHelpWebView.cpp index 95f80daed9..55ebd3efc6 100644 --- a/Plugins/org.blueberry.ui.qt.help/src/internal/berryHelpWebView.cpp +++ b/Plugins/org.blueberry.ui.qt.help/src/internal/berryHelpWebView.cpp @@ -1,450 +1,450 @@ /*============================================================================ 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 "berryHelpWebView.h" #include "berryHelpPluginActivator.h" #include "berryHelpEditor.h" #include "berryHelpEditorInput.h" #include "berryQHelpEngineWrapper.h" #include #include #include #include #include #include #include #include #include #include #include namespace berry { struct ExtensionMap { const char *extension; const char *mimeType; } extensionMap[] = { { ".bmp", "image/bmp" }, { ".css", "text/css" }, { ".gif", "image/gif" }, { ".html", "text/html" }, { ".htm", "text/html" }, { ".ico", "image/x-icon" }, { ".jpeg", "image/jpeg" }, { ".jpg", "image/jpeg" }, { ".js", "application/x-javascript" }, { ".mng", "video/x-mng" }, { ".pbm", "image/x-portable-bitmap" }, { ".pgm", "image/x-portable-graymap" }, { ".pdf", "application/pdf" }, { ".png", "image/png" }, { ".ppm", "image/x-portable-pixmap" }, { ".rss", "application/rss+xml" }, { ".svg", "image/svg+xml" }, { ".svgz", "image/svg+xml" }, { ".text", "text/plain" }, { ".tif", "image/tiff" }, { ".tiff", "image/tiff" }, { ".txt", "text/plain" }, { ".xbm", "image/x-xbitmap" }, { ".xml", "text/xml" }, { ".xpm", "image/x-xpm" }, { ".xsl", "text/xsl" }, { ".xhtml", "application/xhtml+xml" }, { ".wml", "text/vnd.wap.wml" }, { ".wmlc", "application/vnd.wap.wmlc" }, { "about:blank", nullptr }, { nullptr, nullptr } }; class HelpDeviceReply final : public QIODevice { public: HelpDeviceReply(const QUrl& request, const QByteArray& fileData); ~HelpDeviceReply() override; qint64 bytesAvailable() const override; void close() override; private: qint64 readData(char* data, qint64 maxlen) override; qint64 writeData(const char* data, qint64 maxlen) override; QByteArray m_Data; const qint64 m_OrigLen; }; HelpDeviceReply::HelpDeviceReply(const QUrl&, const QByteArray& fileData) : m_Data(fileData), m_OrigLen(fileData.length()) { this->setOpenMode(QIODevice::ReadOnly); QTimer::singleShot(0, this, &QIODevice::readyRead); QTimer::singleShot(0, this, &QIODevice::readChannelFinished); } HelpDeviceReply::~HelpDeviceReply() { } qint64 HelpDeviceReply::bytesAvailable() const { return m_Data.length() + QIODevice::bytesAvailable(); } void HelpDeviceReply::close() { QIODevice::close(); this->deleteLater(); } qint64 HelpDeviceReply::readData(char* data, qint64 maxlen) { qint64 len = qMin(qint64(m_Data.length()), maxlen); if (len) { memcpy(data, m_Data.constData(), len); m_Data.remove(0, len); } return len; } qint64 HelpDeviceReply::writeData(const char*, qint64) { return 0; } class HelpUrlSchemeHandler final : public QWebEngineUrlSchemeHandler { public: explicit HelpUrlSchemeHandler(QObject* parent = nullptr); ~HelpUrlSchemeHandler() override; void requestStarted(QWebEngineUrlRequestJob* job) override; }; HelpUrlSchemeHandler::HelpUrlSchemeHandler(QObject* parent) : QWebEngineUrlSchemeHandler(parent) { } HelpUrlSchemeHandler::~HelpUrlSchemeHandler() { } enum class ResolveUrlResult { Error, Redirect, Data }; ResolveUrlResult ResolveUrl(const QUrl& url, QUrl& redirectedUrl, QByteArray& data) { auto& helpEngine = HelpPluginActivator::getInstance()->getQHelpEngine(); const auto targetUrl = helpEngine.findFile(url); if (!targetUrl.isValid()) return ResolveUrlResult::Error; if (targetUrl != url) { redirectedUrl = targetUrl; return ResolveUrlResult::Redirect; } data = helpEngine.fileData(targetUrl); return ResolveUrlResult::Data; } void HelpUrlSchemeHandler::requestStarted(QWebEngineUrlRequestJob* job) { QUrl url = job->requestUrl(); QUrl redirectedUrl; QByteArray data; switch (ResolveUrl(url, redirectedUrl, data)) { case ResolveUrlResult::Data: job->reply( HelpWebView::mimeFromUrl(url).toLatin1(), new HelpDeviceReply(url, data)); break; case ResolveUrlResult::Redirect: job->redirect(redirectedUrl); break; case ResolveUrlResult::Error: job->reply( QByteArrayLiteral("text/html"), new HelpDeviceReply(url, HelpWebView::m_PageNotFoundMessage.arg(url.toString()).toUtf8())); break; } } const QString HelpWebView::m_PageNotFoundMessage = QCoreApplication::translate("org.blueberry.ui.qt.help", "Context Help


No help page found for identifier


'%1'" "

"); const QString HelpWebView::m_MissingContextMessage = QCoreApplication::translate("org.blueberry.ui.qt.help", "Context Help


Unknown context..

 

Please click inside a view and hit F1 again!

"); class HelpPage final : public QWebEnginePage { public: explicit HelpPage(QObject* parent = nullptr); ~HelpPage() override; private: bool acceptNavigationRequest(const QUrl& url, NavigationType type, bool isMainFrame) override; }; HelpPage::HelpPage(QObject* parent) : QWebEnginePage(parent) { } HelpPage::~HelpPage() { } bool HelpPage::acceptNavigationRequest(const QUrl& url, NavigationType, bool) { if (url.scheme().contains("http")) { QDesktopServices::openUrl(url); return false; } return true; } HelpWebView::HelpWebView(IEditorSite::Pointer, QWidget *parent, qreal zoom) : QWebEngineView(parent), m_LoadFinished(false), m_HelpEngine(HelpPluginActivator::getInstance()->getQHelpEngine()), m_HelpSchemeHandler(new HelpUrlSchemeHandler(this)) { QWebEngineProfile::defaultProfile()->installUrlSchemeHandler("qthelp", m_HelpSchemeHandler); auto helpPage = new HelpPage(this); this->setPage(helpPage); this->setAcceptDrops(false); auto action = pageAction(QWebEnginePage::OpenLinkInNewWindow); action->setText("Open Link in New Tab"); if (parent == nullptr) action->setVisible(false); this->pageAction(QWebEnginePage::DownloadLinkToDisk)->setVisible(false); this->pageAction(QWebEnginePage::DownloadImageToDisk)->setVisible(false); connect(pageAction(QWebEnginePage::Copy), SIGNAL(changed()), this, SLOT(actionChanged())); connect(pageAction(QWebEnginePage::Back), SIGNAL(changed()), this, SLOT(actionChanged())); connect(pageAction(QWebEnginePage::Forward), SIGNAL(changed()), this, SLOT(actionChanged())); connect(page(), SIGNAL(linkHovered(QString)), this, SIGNAL(highlighted(QString))); connect(this, SIGNAL(urlChanged(QUrl)), this, SIGNAL(sourceChanged(QUrl))); connect(this, SIGNAL(loadStarted()), this, SLOT(setLoadStarted())); connect(this, SIGNAL(loadFinished(bool)), this, SLOT(setLoadFinished(bool))); this->setFont(this->viewerFont()); this->setZoomFactor(zoom == 0.0 ? 1.0 : zoom); } HelpWebView::~HelpWebView() { } QFont HelpWebView::viewerFont() const { QWebEngineSettings *webSettings = QWebEngineSettings::globalSettings(); return QFont(webSettings->fontFamily(QWebEngineSettings::StandardFont), webSettings->fontSize(QWebEngineSettings::DefaultFontSize)); } void HelpWebView::setViewerFont(const QFont &font) { QWebEngineSettings *webSettings = settings(); webSettings->setFontFamily(QWebEngineSettings::StandardFont, font.family()); webSettings->setFontSize(QWebEngineSettings::DefaultFontSize, font.pointSize()); } void HelpWebView::scaleUp() { setZoomFactor(zoomFactor() + 0.1); } void HelpWebView::scaleDown() { setZoomFactor(qMax(0.0, zoomFactor() - 0.1)); } void HelpWebView::resetScale() { setZoomFactor(1.0); } bool HelpWebView::handleForwardBackwardMouseButtons(QMouseEvent *e) { if (e->button() == Qt::XButton1) { triggerPageAction(QWebEnginePage::Back); return true; } if (e->button() == Qt::XButton2) { triggerPageAction(QWebEnginePage::Forward); return true; } return false; } void HelpWebView::setSource(const QUrl &url) { if (url.toString().trimmed().isEmpty()) { setHtml(m_MissingContextMessage); } else if (m_HelpEngine.findFile(url).isValid()) { load(url); } else { setHtml(m_PageNotFoundMessage.arg(url.toString())); } } void HelpWebView::wheelEvent(QWheelEvent *e) { if (e->modifiers()& Qt::ControlModifier) { e->accept(); - e->delta() > 0 ? scaleUp() : scaleDown(); + e->angleDelta().y() > 0 ? scaleUp() : scaleDown(); } else { QWebEngineView::wheelEvent(e); } } void HelpWebView::actionChanged() { QAction *a = qobject_cast(sender()); if (a == pageAction(QWebEnginePage::Copy)) emit copyAvailable(a->isEnabled()); else if (a == pageAction(QWebEnginePage::Back)) emit backwardAvailable(a->isEnabled()); else if (a == pageAction(QWebEnginePage::Forward)) emit forwardAvailable(a->isEnabled()); } void HelpWebView::setLoadStarted() { m_LoadFinished = false; } void HelpWebView::setLoadFinished(bool ok) { m_LoadFinished = ok; emit sourceChanged(url()); } QString HelpWebView::mimeFromUrl(const QUrl &url) { const QString &path = url.path(); const int index = path.lastIndexOf(QLatin1Char('.')); const QByteArray &ext = path.mid(index).toUtf8().toLower(); const ExtensionMap *e = extensionMap; while (e->extension) { if (ext == e->extension) return QLatin1String(e->mimeType); ++e; } return QLatin1String(""); } bool HelpWebView::canOpenPage(const QString &url) { return !mimeFromUrl(url).isEmpty(); } bool HelpWebView::isLocalUrl(const QUrl &url) { const QString &scheme = url.scheme(); return scheme.isEmpty() || scheme == QLatin1String("file") || scheme == QLatin1String("qrc") || scheme == QLatin1String("data") || scheme == QLatin1String("qthelp") || scheme == QLatin1String("about"); } bool HelpWebView::launchWithExternalApp(const QUrl &url) { if (isLocalUrl(url)) { const QHelpEngine& helpEngine = HelpPluginActivator::getInstance()->getQHelpEngine(); const QUrl &resolvedUrl = helpEngine.findFile(url); if (!resolvedUrl.isValid()) return false; const QString& path = resolvedUrl.path(); if (!canOpenPage(path)) { QTemporaryFile tmpTmpFile; if (!tmpTmpFile.open()) return false; const QString &extension = QFileInfo(path).completeSuffix(); QFile actualTmpFile(tmpTmpFile.fileName() % QLatin1String(".") % extension); if (!actualTmpFile.open(QIODevice::ReadWrite | QIODevice::Truncate)) return false; actualTmpFile.write(helpEngine.fileData(resolvedUrl)); actualTmpFile.close(); return QDesktopServices::openUrl(QUrl(actualTmpFile.fileName())); } } else if (url.scheme() == QLatin1String("http")) { return QDesktopServices::openUrl(url); } return false; } void HelpWebView::home() { setSource(m_HelpEngine.homePage()); } }