void SceneViewer::keyReleaseEvent(QKeyEvent *event) {
  if (m_freezedStatus != NO_FREEZED) return;

  TTool *tool = TApp::instance()->getCurrentTool()->getTool();
  if (!tool || !tool->isEnabled()) return;
  tool->setViewer(this);

  int key = event->key();

  if (key == Qt::Key_Shift || key == Qt::Key_Control || key == Qt::Key_Alt ||
      key == Qt::Key_AltGr) {
    if (key == Qt::Key_Shift)
      modifiers &= ~Qt::ShiftModifier;
    else if (key == Qt::Key_Control)
      modifiers &= ~Qt::ControlModifier;
    else if (key == Qt::Key_Alt || key == Qt::Key_AltGr)
      modifiers &= ~Qt::AltModifier;

    // quando l'utente preme shift/ctrl ecc. alcuni tool (es. pinch) devono
    // cambiare subito la forma del cursore, senza aspettare il prossimo move
    TMouseEvent toonzEvent;
    initToonzEvent(toonzEvent, event);
    toonzEvent.m_pos =
        TPoint(m_lastMousePos.x(), height() - 1 - m_lastMousePos.y());

    TPointD pos = tool->getMatrix().inv() * winToWorld(m_lastMousePos);

    TObjectHandle *objHandle = TApp::instance()->getCurrentObject();
    if (tool->getToolType() & TTool::LevelTool && !objHandle->isSpline()) {
      pos.x /= m_dpiScale.x;
      pos.y /= m_dpiScale.y;
    }

    tool->mouseMove(pos, toonzEvent);
    setToolCursor(this, tool->getCursorId());
  }

  if (tool->getName() == T_Type)
    event->accept();
  else
    event->ignore();
}
void SceneViewer::keyPressEvent(QKeyEvent *event) {
  if (m_freezedStatus != NO_FREEZED) return;

  int key = event->key();

  if (changeFrameSkippingHolds(event)) {
    return;
  }
  if ((event->modifiers() & Qt::ShiftModifier) &&
      (key == Qt::Key_Down || key == Qt::Key_Up)) {
  }

  TTool *tool = TApp::instance()->getCurrentTool()->getTool();
  if (!tool) return;

  bool isTextToolActive = tool->getName() == T_Type && tool->isActive();

  if (!isTextToolActive && ViewerZoomer(this).exec(event)) return;

  if (!isTextToolActive && SceneViewerShortcutReceiver(this).exec(event))
    return;

  if (!tool->isEnabled()) return;

  tool->setViewer(this);

  // If this object is child of Viewer or ComboViewer
  // (m_isStyleShortcutSelective = true),
  // then consider about shortcut for the current style selection.
  if (m_isStyleShortcutSwitchable &&
      Preferences::instance()->isUseNumpadForSwitchingStylesEnabled() &&
      (!isTextToolActive) && (event->modifiers() == Qt::NoModifier ||
                              event->modifiers() == Qt::KeypadModifier) &&
      ((Qt::Key_0 <= key && key <= Qt::Key_9) || key == Qt::Key_Tab ||
       key == Qt::Key_Backtab)) {
    event->ignore();
    return;
  }

  if (key == Qt::Key_Shift)
    modifiers |= Qt::SHIFT;
  else if (key == Qt::Key_Control)
    modifiers |= Qt::CTRL;
  else if (key == Qt::Key_Alt || key == Qt::Key_AltGr)
    modifiers |= Qt::ALT;

  if (key == Qt::Key_Shift || key == Qt::Key_Control || key == Qt::Key_Alt ||
      key == Qt::Key_AltGr) {
    // quando l'utente preme shift/ctrl ecc. alcuni tool (es. pinch) devono
    // cambiare subito la forma del cursore, senza aspettare il prossimo move
    TMouseEvent toonzEvent;
    initToonzEvent(toonzEvent, event);
    toonzEvent.m_pos =
        TPoint(m_lastMousePos.x(), height() - 1 - m_lastMousePos.y());

    TPointD pos = tool->getMatrix().inv() * winToWorld(m_lastMousePos);

    TObjectHandle *objHandle = TApp::instance()->getCurrentObject();
    if (tool->getToolType() & TTool::LevelTool && !objHandle->isSpline()) {
      pos.x /= m_dpiScale.x;
      pos.y /= m_dpiScale.y;
    }

    tool->mouseMove(pos, toonzEvent);
    setToolCursor(this, tool->getCursorId());
  }

  bool shiftButton = QApplication::keyboardModifiers() == Qt::ShiftModifier;

  TUINT32 flags = 0;
  TPoint pos;
  if (key == Qt::Key_Shift)
    flags = TwConsts::TK_ShiftPressed;
  else if (key == Qt::Key_Control)
    flags = TwConsts::TK_CtrlPressed;
  else if (key == Qt::Key_Alt)
    flags = TwConsts::TK_AltPressed;
  else if (key == Qt::Key_CapsLock)
    flags = TwConsts::TK_CapsLock;
  else if (key == Qt::Key_Backspace)
    key = TwConsts::TK_Backspace;
  else if (key == Qt::Key_Return)
    key = TwConsts::TK_Return;
  else if (key == Qt::Key_Left && !shiftButton)
    key = TwConsts::TK_LeftArrow;
  else if (key == Qt::Key_Right && !shiftButton)
    key = TwConsts::TK_RightArrow;
  else if (key == Qt::Key_Up && !shiftButton)
    key = TwConsts::TK_UpArrow;
  else if (key == Qt::Key_Down && !shiftButton)
    key = TwConsts::TK_DownArrow;
  else if (key == Qt::Key_Left && shiftButton)
    key = TwConsts::TK_ShiftLeftArrow;
  else if (key == Qt::Key_Right && shiftButton)
    key = TwConsts::TK_ShiftRightArrow;
  else if (key == Qt::Key_Up && shiftButton)
    key = TwConsts::TK_ShiftUpArrow;
  else if (key == Qt::Key_Down && shiftButton)
    key = TwConsts::TK_ShiftDownArrow;
  else if (key == Qt::Key_Home)
    key = TwConsts::TK_Home;
  else if (key == Qt::Key_End)
    key = TwConsts::TK_End;
  else if (key == Qt::Key_PageUp)
    key = TwConsts::TK_PageUp;
  else if (key == Qt::Key_PageDown)
    key = TwConsts::TK_PageDown;
  else if (key == Qt::Key_Insert)
    key = TwConsts::TK_Insert;
  else if (key == Qt::Key_Delete)
    key = TwConsts::TK_Delete;
  else if (key == Qt::Key_Escape)
    key = TwConsts::TK_Esc;
  else if (key == Qt::Key_F1)
    key = TwConsts::TK_F1;
  else if (key == Qt::Key_F2)
    key = TwConsts::TK_F2;
  else if (key == Qt::Key_F3)
    key = TwConsts::TK_F3;
  else if (key == Qt::Key_F4)
    key = TwConsts::TK_F4;
  else if (key == Qt::Key_F5)
    key = TwConsts::TK_F5;
  else if (key == Qt::Key_F6)
    key = TwConsts::TK_F6;
  else if (key == Qt::Key_F7)
    key = TwConsts::TK_F7;
  else if (key == Qt::Key_F8)
    key = TwConsts::TK_F8;
  else if (key == Qt::Key_F9)
    key = TwConsts::TK_F9;
  else if (key == Qt::Key_F10)
    key = TwConsts::TK_F10;
  else if (key == Qt::Key_F11)
    key = TwConsts::TK_F11;
  else if (key == Qt::Key_F12)
    key = TwConsts::TK_F12;
  else if (key == Qt::Key_Menu || key == Qt::Key_Meta)
    return;

  bool ret = false;
  if (tool)  // && m_toolEnabled)
  {
    QString text = event->text();
    if ((event->modifiers() & Qt::ShiftModifier)) text.toUpper();
    std::wstring unicodeChar = text.toStdWString();
    ret = tool->keyDown(key, unicodeChar, flags, pos);  // per il textTool
    if (ret) {
      update();
      return;
    }
    ret = tool->keyDown(key, flags, pos);  // per gli altri tool
  }
  if (!ret) {
    TFrameHandle *fh = TApp::instance()->getCurrentFrame();

    if (key == TwConsts::TK_UpArrow)
      fh->prevFrame();
    else if (key == TwConsts::TK_DownArrow)
      fh->nextFrame();
    else if (key == TwConsts::TK_Home)
      fh->firstFrame();
    else if (key == TwConsts::TK_End)
      fh->lastFrame();
  }
  update();
  // TODO: devo accettare l'evento?
}
bool SceneViewer::event(QEvent *e) {
  if (e->type() == QEvent::ShortcutOverride || e->type() == QEvent::KeyPress) {
    if (!((QKeyEvent *)e)->isAutoRepeat()) {
      TApp::instance()->getCurrentTool()->storeTool();
    }
  }
  if (e->type() == QEvent::ShortcutOverride) {
    TTool *tool = TApp::instance()->getCurrentTool()->getTool();
    if (tool && tool->isEnabled() && tool->getName() == T_Type &&
        tool->isActive())
      e->accept();
    return true;
  }
  if (e->type() == QEvent::KeyRelease) {
    if (!((QKeyEvent *)e)->isAutoRepeat()) {
      QWidget *focusWidget = QApplication::focusWidget();
      if (focusWidget == 0 ||
          QString(focusWidget->metaObject()->className()) == "SceneViewer")
        TApp::instance()->getCurrentTool()->restoreTool();
    }
  }

  // discard too frequent move events
  static QTime clock;
  if (e->type() == QEvent::MouseButtonPress)
    clock.start();
  else if (e->type() == QEvent::MouseMove) {
    if (clock.elapsed() < 10) {
      e->accept();
      return true;
    }
    clock.start();
  }

  /*
switch(e->type())
{
case QEvent::Enter:
qDebug() << "************************** Enter";
break;
case QEvent::Leave:
qDebug() << "************************** Leave";
break;

case QEvent::TabletPress:
qDebug() << "************************** TabletPress"  << m_pressure;
break;
case QEvent::TabletMove:
qDebug() << "************************** TabletMove";
break;
case QEvent::TabletRelease:
qDebug() << "************************** TabletRelease";
break;


case QEvent::MouseButtonPress:
qDebug() << "**************************MouseButtonPress"  << m_pressure << " "
<< m_tabletEvent;
break;
case QEvent::MouseMove:
qDebug() << "**************************MouseMove" <<  m_pressure;
break;
case QEvent::MouseButtonRelease:
qDebug() << "**************************MouseButtonRelease";
break;

case QEvent::MouseButtonDblClick:
qDebug() << "============================== MouseButtonDblClick";
break;
}
*/

  return QGLWidget::event(e);
}