/*========================================================================= Program: Visualization Toolkit Module: QVTKInteractorAdapter.cxx Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. See Copyright.txt or http://www.kitware.com/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ /* * Copyright 2004 Sandia Corporation. * Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive * license for use of this work by or on behalf of the * U.S. Government. Redistribution and use in source and binary forms, with * or without modification, are permitted provided that this Notice and any * statement of authorship are reproduced on all copies. */ /*======================================================================== For general information about using VTK and Qt, see: http://www.trolltech.com/products/3rdparty/vtksupport.html =========================================================================*/ #ifdef _MSC_VER // Disable warnings that Qt headers give. #pragma warning(disable : 4127) #pragma warning(disable : 4512) #endif #include "QVTKInteractorAdapter.h" #include "QVTKInteractor.h" #include #include #include #include #include #include "vtkCommand.h" // function to get VTK keysyms from ascii characters static const char* ascii_to_key_sym(int); // function to get VTK keysyms from Qt keys static const char* qt_key_to_key_sym(Qt::Key, Qt::KeyboardModifiers modifiers); // Tolerance used when truncating the device pixel ratio scaled // window size in calls to SetSize. const double QVTKInteractorAdapter::DevicePixelRatioTolerance = 1e-5; QVTKInteractorAdapter::QVTKInteractorAdapter(QObject* parentObject) : QObject(parentObject) , AccumulatedDelta(0) , DevicePixelRatio(1.0) { } QVTKInteractorAdapter::~QVTKInteractorAdapter() = default; void QVTKInteractorAdapter::SetDevicePixelRatio(float ratio, vtkRenderWindowInteractor* iren) { if (ratio != DevicePixelRatio) { if (iren) { int tmp[2]; iren->GetSize(tmp); if (ratio == 1.0) { iren->SetSize(tmp[0] / 2, tmp[1] / 2); } else { iren->SetSize(static_cast(tmp[0] * ratio + DevicePixelRatioTolerance), static_cast(tmp[1] * ratio + DevicePixelRatioTolerance)); } } this->DevicePixelRatio = ratio; } } bool QVTKInteractorAdapter::ProcessEvent(QEvent* e, vtkRenderWindowInteractor* iren) { if (iren == nullptr || e == nullptr) return false; const QEvent::Type t = e->type(); if (t == QEvent::FocusIn) { // For 3DConnexion devices: QVTKInteractor* qiren = QVTKInteractor::SafeDownCast(iren); if (qiren) { qiren->StartListening(); } return true; } if (t == QEvent::FocusOut) { // For 3DConnexion devices: QVTKInteractor* qiren = QVTKInteractor::SafeDownCast(iren); if (qiren) { qiren->StopListening(); } return true; } if (t == QEvent::HoverLeave) { iren->InvokeEvent(vtkCommand::HoverEvent, nullptr); } // the following events only happen if the interactor is enabled if (!iren->GetEnabled()) return false; if (t == QEvent::MouseButtonPress || t == QEvent::MouseButtonRelease || t == QEvent::MouseButtonDblClick || t == QEvent::MouseMove) { QMouseEvent* e2 = static_cast(e); // give interactor the event information #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) auto x = e2->x(); auto y = e2->y(); #else auto x = e2->position().x(); auto y = e2->position().y(); #endif iren->SetEventInformationFlipY( static_cast(x * this->DevicePixelRatio + DevicePixelRatioTolerance), static_cast(y * this->DevicePixelRatio + DevicePixelRatioTolerance), (e2->modifiers() & Qt::ControlModifier) > 0 ? 1 : 0, (e2->modifiers() & Qt::ShiftModifier) > 0 ? 1 : 0, 0, e2->type() == QEvent::MouseButtonDblClick ? 1 : 0); iren->SetAltKey((e2->modifiers() & Qt::AltModifier) > 0 ? 1 : 0); if (t == QEvent::MouseMove) { iren->InvokeEvent(vtkCommand::MouseMoveEvent, e2); } else if (t == QEvent::MouseButtonPress) { switch (e2->button()) { case Qt::LeftButton: iren->InvokeEvent(vtkCommand::LeftButtonPressEvent, e2); break; case Qt::MiddleButton: iren->InvokeEvent(vtkCommand::MiddleButtonPressEvent, e2); break; case Qt::RightButton: iren->InvokeEvent(vtkCommand::RightButtonPressEvent, e2); break; default: break; } } else if (t == QEvent::MouseButtonDblClick) { switch (e2->button()) { case Qt::LeftButton: iren->InvokeEvent(vtkCommand::LeftButtonDoubleClickEvent, e2); break; case Qt::MiddleButton: iren->InvokeEvent(vtkCommand::MiddleButtonDoubleClickEvent, e2); break; case Qt::RightButton: iren->InvokeEvent(vtkCommand::RightButtonDoubleClickEvent, e2); break; default: break; } } else if (t == QEvent::MouseButtonRelease) { switch (e2->button()) { case Qt::LeftButton: iren->InvokeEvent(vtkCommand::LeftButtonReleaseEvent, e2); break; case Qt::MiddleButton: iren->InvokeEvent(vtkCommand::MiddleButtonReleaseEvent, e2); break; case Qt::RightButton: iren->InvokeEvent(vtkCommand::RightButtonReleaseEvent, e2); break; default: break; } } return true; } if (t == QEvent::TouchBegin || t == QEvent::TouchUpdate || t == QEvent::TouchEnd) { QTouchEvent* e2 = dynamic_cast(e); #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) Q_FOREACH (const QTouchEvent::TouchPoint& point, e2->touchPoints()) #else Q_FOREACH (const QTouchEvent::TouchPoint& point, e2->points()) #endif { if (point.id() >= VTKI_MAX_POINTERS) { break; } #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) QPointF pos = point.pos(); #else QPointF pos = point.position(); #endif // give interactor the event information iren->SetEventInformationFlipY( static_cast(pos.x() * this->DevicePixelRatio + DevicePixelRatioTolerance), static_cast(pos.y() * this->DevicePixelRatio + DevicePixelRatioTolerance), (e2->modifiers() & Qt::ControlModifier) > 0 ? 1 : 0, (e2->modifiers() & Qt::ShiftModifier) > 0 ? 1 : 0, 0, 0, nullptr, point.id()); } #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) Q_FOREACH (const QTouchEvent::TouchPoint& point, e2->touchPoints()) #else Q_FOREACH (const QTouchEvent::TouchPoint& point, e2->points()) #endif { if (point.id() >= VTKI_MAX_POINTERS) { break; } iren->SetPointerIndex(point.id()); if (point.state() & Qt::TouchPointReleased) { iren->InvokeEvent(vtkCommand::LeftButtonReleaseEvent, nullptr); } if (point.state() & Qt::TouchPointPressed) { iren->InvokeEvent(vtkCommand::LeftButtonPressEvent, nullptr); } if (point.state() & Qt::TouchPointMoved) { iren->InvokeEvent(vtkCommand::MouseMoveEvent, nullptr); } } e2->accept(); return true; } if (t == QEvent::Enter) { iren->InvokeEvent(vtkCommand::EnterEvent, e); return true; } if (t == QEvent::Leave) { iren->InvokeEvent(vtkCommand::LeaveEvent, e); return true; } if (t == QEvent::KeyPress || t == QEvent::KeyRelease) { QKeyEvent* e2 = static_cast(e); // get key and keysym information int ascii_key = e2->text().length() ? e2->text().unicode()->toLatin1() : 0; const char* keysym = ascii_to_key_sym(ascii_key); if (!keysym || e2->modifiers() == Qt::KeypadModifier) { // get virtual keys keysym = qt_key_to_key_sym(static_cast(e2->key()), e2->modifiers()); } if (!keysym) { keysym = "None"; } // give interactor event information iren->SetKeyEventInformation((e2->modifiers() & Qt::ControlModifier), (e2->modifiers() & Qt::ShiftModifier), ascii_key, e2->count(), keysym); iren->SetAltKey((e2->modifiers() & Qt::AltModifier) > 0 ? 1 : 0); if (t == QEvent::KeyPress) { // invoke vtk event iren->InvokeEvent(vtkCommand::KeyPressEvent, e2); // invoke char event only for ascii characters if (ascii_key) { iren->InvokeEvent(vtkCommand::CharEvent, e2); } } else { iren->InvokeEvent(vtkCommand::KeyReleaseEvent, e2); } return true; } if (t == QEvent::Wheel) { QWheelEvent* e2 = static_cast(e); #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) auto x = e2->x(); auto y = e2->y(); #else auto x = e2->position().x(); auto y = e2->position().y(); #endif iren->SetEventInformationFlipY( static_cast(x * this->DevicePixelRatio + DevicePixelRatioTolerance), static_cast(y * this->DevicePixelRatio + DevicePixelRatioTolerance), (e2->modifiers() & Qt::ControlModifier) > 0 ? 1 : 0, (e2->modifiers() & Qt::ShiftModifier) > 0 ? 1 : 0); iren->SetAltKey((e2->modifiers() & Qt::AltModifier) > 0 ? 1 : 0); double horizontalDelta = e2->angleDelta().x(); double verticalDelta = e2->angleDelta().y(); this->AccumulatedDelta += verticalDelta + horizontalDelta; const int threshold = 120; // invoke vtk event when accumulated delta passes the threshold if (this->AccumulatedDelta >= threshold && verticalDelta != 0.0) { iren->InvokeEvent(vtkCommand::MouseWheelForwardEvent, e2); this->AccumulatedDelta = 0; } else if (this->AccumulatedDelta <= -threshold && verticalDelta != 0.0) { iren->InvokeEvent(vtkCommand::MouseWheelBackwardEvent, e2); this->AccumulatedDelta = 0; } else if (this->AccumulatedDelta >= threshold && horizontalDelta != 0.0) { iren->InvokeEvent(vtkCommand::MouseWheelLeftEvent, e2); this->AccumulatedDelta = 0; } else if (this->AccumulatedDelta <= -threshold && horizontalDelta != 0.0) { iren->InvokeEvent(vtkCommand::MouseWheelRightEvent, e2); this->AccumulatedDelta = 0; } return true; } if (t == QEvent::ContextMenu) { QContextMenuEvent* e2 = static_cast(e); // give interactor the event information iren->SetEventInformationFlipY( static_cast(e2->x() * this->DevicePixelRatio + DevicePixelRatioTolerance), static_cast(e2->y() * this->DevicePixelRatio + DevicePixelRatioTolerance), (e2->modifiers() & Qt::ControlModifier) > 0 ? 1 : 0, (e2->modifiers() & Qt::ShiftModifier) > 0 ? 1 : 0); iren->SetAltKey((e2->modifiers() & Qt::AltModifier) > 0 ? 1 : 0); // invoke event and pass qt event for additional data as well iren->InvokeEvent(QVTKInteractor::ContextMenuEvent, e2); return true; } if (t == QEvent::DragEnter) { QDragEnterEvent* e2 = static_cast(e); // invoke event and pass qt event for additional data as well iren->InvokeEvent(QVTKInteractor::DragEnterEvent, e2); return true; } if (t == QEvent::DragLeave) { QDragLeaveEvent* e2 = static_cast(e); // invoke event and pass qt event for additional data as well iren->InvokeEvent(QVTKInteractor::DragLeaveEvent, e2); return true; } if (t == QEvent::DragMove) { QDragMoveEvent* e2 = static_cast(e); // give interactor the event information #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) QPoint pos = e2->pos(); #else QPoint pos = e2->position().toPoint(); #endif iren->SetEventInformationFlipY( static_cast(pos.x() * this->DevicePixelRatio + DevicePixelRatioTolerance), static_cast(pos.y() * this->DevicePixelRatio + DevicePixelRatioTolerance)); // invoke event and pass qt event for additional data as well iren->InvokeEvent(QVTKInteractor::DragMoveEvent, e2); return true; } if (t == QEvent::Drop) { QDropEvent* e2 = static_cast(e); // give interactor the event information #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) QPoint pos = e2->pos(); #else QPoint pos = e2->position().toPoint(); #endif iren->SetEventInformationFlipY( static_cast(pos.x() * this->DevicePixelRatio + DevicePixelRatioTolerance), static_cast(pos.y() * this->DevicePixelRatio + DevicePixelRatioTolerance)); // invoke event and pass qt event for additional data as well iren->InvokeEvent(QVTKInteractor::DropEvent, e2); return true; } if (e->type() == QEvent::Gesture) { // Store event information to restore after gesture is completed int eventPosition[2]; iren->GetEventPosition(eventPosition); int lastEventPosition[2]; iren->GetLastEventPosition(lastEventPosition); QGestureEvent* e2 = static_cast(e); if (QSwipeGesture* swipe = static_cast(e2->gesture(Qt::SwipeGesture))) { e2->accept(Qt::SwipeGesture); double angle = swipe->swipeAngle(); iren->SetRotation(angle); switch (swipe->state()) { case Qt::GestureCanceled: case Qt::GestureFinished: iren->InvokeEvent(vtkCommand::EndSwipeEvent, e2); break; case Qt::GestureStarted: iren->InvokeEvent(vtkCommand::StartSwipeEvent, e2); iren->InvokeEvent(vtkCommand::SwipeEvent, e2); break; default: iren->InvokeEvent(vtkCommand::SwipeEvent, e2); } } if (QPinchGesture* pinch = static_cast(e2->gesture(Qt::PinchGesture))) { e2->accept(Qt::PinchGesture); QPointF position = pinch->centerPoint().toPoint(); // When using MacOS trackpad, the center of the pinch event is already reported in widget // coordinates. For other platforms, the coordinates need to be converted from global to // local. #ifndef Q_OS_OSX QWidget* widget = qobject_cast(this->parent()); if (widget) { position = widget->mapFromGlobal(pinch->centerPoint().toPoint()); } else { // Pinch gesture position is in global coordinates, but could not find a widget to convert // to local coordinates QVTKInteractorAdapter parent is not set in QVTKRenderWindowAdapter. // Gesture coordinate mapping may be incorrect. qWarning("Could not find parent widget. Gesture coordinate mapping may be incorrect"); } #endif iren->SetEventInformationFlipY( static_cast(position.x() * this->DevicePixelRatio + DevicePixelRatioTolerance), static_cast(position.y() * this->DevicePixelRatio + DevicePixelRatioTolerance)); iren->SetScale(1.0); iren->SetScale(pinch->scaleFactor()); switch (pinch->state()) { case Qt::GestureFinished: case Qt::GestureCanceled: iren->InvokeEvent(vtkCommand::EndPinchEvent, e2); break; case Qt::GestureStarted: iren->InvokeEvent(vtkCommand::StartPinchEvent, e2); iren->InvokeEvent(vtkCommand::PinchEvent, e2); break; default: iren->InvokeEvent(vtkCommand::PinchEvent, e2); } iren->SetRotation(-1.0 * pinch->lastRotationAngle()); iren->SetRotation(-1.0 * pinch->rotationAngle()); switch (pinch->state()) { case Qt::GestureFinished: case Qt::GestureCanceled: iren->InvokeEvent(vtkCommand::EndRotateEvent, e2); break; case Qt::GestureStarted: iren->InvokeEvent(vtkCommand::StartRotateEvent, e2); iren->InvokeEvent(vtkCommand::RotateEvent, e2); break; default: iren->InvokeEvent(vtkCommand::RotateEvent, e2); } } if (QPanGesture* pan = static_cast(e2->gesture(Qt::PanGesture))) { e2->accept(Qt::PanGesture); QPointF delta = pan->delta(); double translation[2] = { (delta.x() * this->DevicePixelRatio + QVTKInteractorAdapter::DevicePixelRatioTolerance), -(delta.y() * this->DevicePixelRatio + QVTKInteractorAdapter::DevicePixelRatioTolerance) }; iren->SetTranslation(translation); switch (pan->state()) { case Qt::GestureFinished: case Qt::GestureCanceled: iren->InvokeEvent(vtkCommand::EndPanEvent, e2); break; case Qt::GestureStarted: iren->InvokeEvent(vtkCommand::StartPanEvent, e2); iren->InvokeEvent(vtkCommand::PanEvent, e2); break; default: iren->InvokeEvent(vtkCommand::PanEvent, e2); } } if (QTapGesture* tap = static_cast(e2->gesture(Qt::TapGesture))) { e2->accept(Qt::TapGesture); QPointF position = tap->position().toPoint(); iren->SetEventInformationFlipY(static_cast(position.x() * this->DevicePixelRatio + QVTKInteractorAdapter::DevicePixelRatioTolerance), static_cast(position.y() * this->DevicePixelRatio + QVTKInteractorAdapter::DevicePixelRatioTolerance)); if (tap->state() == Qt::GestureStarted) { iren->InvokeEvent(vtkCommand::TapEvent, e2); } } if (QTapAndHoldGesture* tapAndHold = static_cast(e2->gesture(Qt::TapAndHoldGesture))) { e2->accept(Qt::TapAndHoldGesture); QPointF position = tapAndHold->position().toPoint(); QWidget* widget = qobject_cast(this->parent()); if (widget) { position = widget->mapFromGlobal(tapAndHold->position().toPoint()); } else { // TapAndHold gesture position is in global coordinates, but could not find a widget to // convert to local coordinates QVTKInteractorAdapter parent is not set in // QVTKRenderWindowAdapter. Gesture coordinate mapping may be incorrect. qWarning("Could not find parent widget. Gesture coordinate mapping may be incorrect"); } iren->SetEventInformationFlipY(static_cast(position.x() * this->DevicePixelRatio + QVTKInteractorAdapter::DevicePixelRatioTolerance), static_cast(position.y() * this->DevicePixelRatio + QVTKInteractorAdapter::DevicePixelRatioTolerance)); if (tapAndHold->state() == Qt::GestureStarted) { iren->InvokeEvent(vtkCommand::LongTapEvent, e2); } } iren->SetEventPosition(eventPosition); iren->SetLastEventPosition(lastEventPosition); return true; } return false; } // ***** keysym stuff below ***** static const char* AsciiToKeySymTable[] = { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, "Tab", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, "space", "exclam", "quotedbl", "numbersign", "dollar", "percent", "ampersand", "quoteright", "parenleft", "parenright", "asterisk", "plus", "comma", "minus", "period", "slash", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "colon", "semicolon", "less", "equal", "greater", "question", "at", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "bracketleft", "backslash", "bracketright", "asciicircum", "underscore", "quoteleft", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "braceleft", "bar", "braceright", "asciitilde", "Delete", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr }; const char* ascii_to_key_sym(int i) { if (i >= 0) { return AsciiToKeySymTable[i]; } return nullptr; } #define QVTK_HANDLE(x, y) \ case x: \ ret = y; \ break; #define QVTK_HANDLE_KEYPAD(x, y, z) \ case x: \ ret = (modifiers & Qt::KeypadModifier) ? (y) : (z); \ break; const char* qt_key_to_key_sym(Qt::Key i, Qt::KeyboardModifiers modifiers) { const char* ret = nullptr; switch (i) { // Cancel QVTK_HANDLE(Qt::Key_Backspace, "BackSpace") QVTK_HANDLE(Qt::Key_Tab, "Tab") QVTK_HANDLE(Qt::Key_Backtab, "Tab") QVTK_HANDLE(Qt::Key_Clear, "Clear") QVTK_HANDLE(Qt::Key_Return, "Return") QVTK_HANDLE(Qt::Key_Enter, "Return") QVTK_HANDLE(Qt::Key_Shift, "Shift_L") QVTK_HANDLE(Qt::Key_Control, "Control_L") QVTK_HANDLE(Qt::Key_Alt, "Alt_L") QVTK_HANDLE(Qt::Key_Pause, "Pause") QVTK_HANDLE(Qt::Key_CapsLock, "Caps_Lock") QVTK_HANDLE(Qt::Key_Escape, "Escape") QVTK_HANDLE(Qt::Key_Space, "space") QVTK_HANDLE(Qt::Key_PageUp, "Prior") QVTK_HANDLE(Qt::Key_PageDown, "Next") QVTK_HANDLE(Qt::Key_End, "End") QVTK_HANDLE(Qt::Key_Home, "Home") QVTK_HANDLE(Qt::Key_Left, "Left") QVTK_HANDLE(Qt::Key_Up, "Up") QVTK_HANDLE(Qt::Key_Right, "Right") QVTK_HANDLE(Qt::Key_Down, "Down") QVTK_HANDLE(Qt::Key_Select, "Select") QVTK_HANDLE(Qt::Key_Execute, "Execute") QVTK_HANDLE(Qt::Key_SysReq, "Snapshot") QVTK_HANDLE(Qt::Key_Insert, "Insert") QVTK_HANDLE(Qt::Key_Delete, "Delete") QVTK_HANDLE(Qt::Key_Help, "Help") QVTK_HANDLE_KEYPAD(Qt::Key_0, "KP_0", "0") QVTK_HANDLE_KEYPAD(Qt::Key_1, "KP_1", "1") QVTK_HANDLE_KEYPAD(Qt::Key_2, "KP_2", "2") QVTK_HANDLE_KEYPAD(Qt::Key_3, "KP_3", "3") QVTK_HANDLE_KEYPAD(Qt::Key_4, "KP_4", "4") QVTK_HANDLE_KEYPAD(Qt::Key_5, "KP_5", "5") QVTK_HANDLE_KEYPAD(Qt::Key_6, "KP_6", "6") QVTK_HANDLE_KEYPAD(Qt::Key_7, "KP_7", "7") QVTK_HANDLE_KEYPAD(Qt::Key_8, "KP_8", "8") QVTK_HANDLE_KEYPAD(Qt::Key_9, "KP_9", "9") QVTK_HANDLE(Qt::Key_A, "a") QVTK_HANDLE(Qt::Key_B, "b") QVTK_HANDLE(Qt::Key_C, "c") QVTK_HANDLE(Qt::Key_D, "d") QVTK_HANDLE(Qt::Key_E, "e") QVTK_HANDLE(Qt::Key_F, "f") QVTK_HANDLE(Qt::Key_G, "g") QVTK_HANDLE(Qt::Key_H, "h") QVTK_HANDLE(Qt::Key_I, "i") QVTK_HANDLE(Qt::Key_J, "h") QVTK_HANDLE(Qt::Key_K, "k") QVTK_HANDLE(Qt::Key_L, "l") QVTK_HANDLE(Qt::Key_M, "m") QVTK_HANDLE(Qt::Key_N, "n") QVTK_HANDLE(Qt::Key_O, "o") QVTK_HANDLE(Qt::Key_P, "p") QVTK_HANDLE(Qt::Key_Q, "q") QVTK_HANDLE(Qt::Key_R, "r") QVTK_HANDLE(Qt::Key_S, "s") QVTK_HANDLE(Qt::Key_T, "t") QVTK_HANDLE(Qt::Key_U, "u") QVTK_HANDLE(Qt::Key_V, "v") QVTK_HANDLE(Qt::Key_W, "w") QVTK_HANDLE(Qt::Key_X, "x") QVTK_HANDLE(Qt::Key_Y, "y") QVTK_HANDLE(Qt::Key_Z, "z") QVTK_HANDLE(Qt::Key_Asterisk, "asterisk") QVTK_HANDLE(Qt::Key_Plus, "plus") QVTK_HANDLE(Qt::Key_Bar, "bar") QVTK_HANDLE(Qt::Key_Minus, "minus") QVTK_HANDLE(Qt::Key_Period, "period") QVTK_HANDLE(Qt::Key_Slash, "slash") QVTK_HANDLE(Qt::Key_F1, "F1") QVTK_HANDLE(Qt::Key_F2, "F2") QVTK_HANDLE(Qt::Key_F3, "F3") QVTK_HANDLE(Qt::Key_F4, "F4") QVTK_HANDLE(Qt::Key_F5, "F5") QVTK_HANDLE(Qt::Key_F6, "F6") QVTK_HANDLE(Qt::Key_F7, "F7") QVTK_HANDLE(Qt::Key_F8, "F8") QVTK_HANDLE(Qt::Key_F9, "F9") QVTK_HANDLE(Qt::Key_F10, "F10") QVTK_HANDLE(Qt::Key_F11, "F11") QVTK_HANDLE(Qt::Key_F12, "F12") QVTK_HANDLE(Qt::Key_F13, "F13") QVTK_HANDLE(Qt::Key_F14, "F14") QVTK_HANDLE(Qt::Key_F15, "F15") QVTK_HANDLE(Qt::Key_F16, "F16") QVTK_HANDLE(Qt::Key_F17, "F17") QVTK_HANDLE(Qt::Key_F18, "F18") QVTK_HANDLE(Qt::Key_F19, "F19") QVTK_HANDLE(Qt::Key_F20, "F20") QVTK_HANDLE(Qt::Key_F21, "F21") QVTK_HANDLE(Qt::Key_F22, "F22") QVTK_HANDLE(Qt::Key_F23, "F23") QVTK_HANDLE(Qt::Key_F24, "F24") QVTK_HANDLE(Qt::Key_NumLock, "Num_Lock") QVTK_HANDLE(Qt::Key_ScrollLock, "Scroll_Lock") default: break; } return ret; }