/****************************************************************************** QtAV Player Demo: this file is part of QtAV examples Copyright (C) 2012-2015 Wang Bin * This file is part of QtAV This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ******************************************************************************/ #include "EventFilter.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "filters/OSDFilter.h" using namespace QtAV; // TODO: watch main window EventFilter::EventFilter(AVPlayer *player) : QObject(player), menu(0) { } EventFilter::~EventFilter() { if (menu) { delete menu; menu = 0; } } void EventFilter::openLocalFile() { QString file = QFileDialog::getOpenFileName(0, tr("Open a video")); if (file.isEmpty()) return; AVPlayer *player = static_cast(parent()); player->play(file); } void EventFilter::openUrl() { QString url = QInputDialog::getText(0, tr("Open an url"), tr("Url")); if (url.isEmpty()) return; AVPlayer *player = static_cast(parent()); player->play(url); } void EventFilter::about() { QtAV::about(); } void EventFilter::aboutFFmpeg() { QtAV::aboutFFmpeg(); } void EventFilter::help() { emit helpRequested(); return; static QString help = QString::fromLatin1("

") +tr("Drag and drop a file to player\n") + QString::fromLatin1("

" "

") + tr("A: switch aspect ratio") + QString::fromLatin1("

" "

") + tr("Double click to switch fullscreen") + QString::fromLatin1("

" "

") + tr("Shortcut:\n") + QString::fromLatin1("

" "

") + tr("Space: pause/continue\n") + QString::fromLatin1("

" "

") + tr("F: fullscreen on/off\n") + QString::fromLatin1("

" "

") + tr("T: stays on top on/off\n") + QString::fromLatin1("

" "

") + tr("N: show next frame. Continue the playing by pressing 'Space'\n") + QString::fromLatin1("

" "

") + tr("Ctrl+O: open a file\n") + QString::fromLatin1("

" "

") + tr("O: OSD\n") + QString::fromLatin1("

" "

") + tr("P: replay\n") + QString::fromLatin1("

" "

") + tr("Q/ESC: quit\n") + QString::fromLatin1("

" "

") + tr("S: stop\n") + QString::fromLatin1("

" "

") + tr("R: rotate 90") + QString::fromLatin1("

" "

") + tr("M: mute on/off\n") + QString::fromLatin1("

" "

") + tr("C: capture video") + QString::fromLatin1("

" "

") + tr("Up/Down: volume +/-\n") + QString::fromLatin1("

" "

") + tr("Ctrl+Up/Down: speed +/-\n") + QString::fromLatin1("

" "

") + tr("->/<-: seek forward/backward\n"); QMessageBox::about(0, tr("Help"), help); } bool EventFilter::eventFilter(QObject *watched, QEvent *event) { Q_UNUSED(watched); AVPlayer *player = static_cast(parent()); if (!player || !player->renderer() || !player->renderer()->widget()) return false; if (qobject_cast(watched) != player->renderer()->widget()) { return false; } #ifndef QT_NO_DYNAMIC_CAST //dynamic_cast is defined as a macro to force a compile error if (player->renderer() != dynamic_cast(watched)) { // return false; } #endif QEvent::Type type = event->type(); switch (type) { case QEvent::KeyPress: { QKeyEvent *key_event = static_cast(event); int key = key_event->key(); Qt::KeyboardModifiers modifiers = key_event->modifiers(); switch (key) { case Qt::Key_C: //capture player->videoCapture()->capture(); break; case Qt::Key_N: //check playing? player->playNextFrame(); break; case Qt::Key_P: player->play(); break; case Qt::Key_Q: case Qt::Key_Escape: qApp->quit(); break; case Qt::Key_S: player->stop(); //check playing? break; case Qt::Key_Space: //check playing? qDebug("isPaused = %d", player->isPaused()); player->pause(!player->isPaused()); break; case Qt::Key_F: { //TODO: move to gui QWidget *w = qApp->activeWindow(); if (!w) return false; w->setWindowState(w->windowState() ^ Qt::WindowFullScreen); } break; case Qt::Key_U: player->setNotifyInterval(player->notifyInterval() + 100); break; case Qt::Key_D: player->setNotifyInterval(player->notifyInterval() - 100); break; case Qt::Key_Up: { AudioOutput *ao = player->audio(); if (modifiers == Qt::ControlModifier) { qreal s = player->speed(); if (s < 1.4) s += 0.02; else s += 0.05; if (qAbs(s-1.0) <= 0.01) s = 1.0; player->setSpeed(s); return true; } if (ao && ao->isAvailable()) { qreal v = player->audio()->volume(); if (v > 0.5) v += 0.1; else if (v > 0.1) v += 0.05; else v += 0.025; player->audio()->setVolume(v); qDebug("vol = %.3f", player->audio()->volume()); } } break; case Qt::Key_Down: { AudioOutput *ao = player->audio(); if (modifiers == Qt::ControlModifier) { qreal s = player->speed(); if (s < 1.4) s -= 0.02; else s -= 0.05; if (qAbs(s-1.0) <= 0.01) s = 1.0; s = qMax(s, 0.0); player->setSpeed(s); return true; } if (ao && ao->isAvailable()) { qreal v = player->audio()->volume(); if (v > 0.5) v -= 0.1; else if (v > 0.1) v -= 0.05; else v -= 0.025; player->audio()->setVolume(v); qDebug("vol = %.3f", player->audio()->volume()); } } break; case Qt::Key_O: { if (modifiers == Qt::ControlModifier) { //TODO: emit a signal so we can use custome dialogs? openLocalFile(); } else/* if (m == Qt::NoModifier) */{ emit showNextOSD(); } } break; case Qt::Key_Left: qDebug("<-"); player->setSeekType(key_event->isAutoRepeat() ? KeyFrameSeek : AccurateSeek); player->seekBackward(); break; case Qt::Key_Right: qDebug("->"); player->setSeekType(key_event->isAutoRepeat() ? KeyFrameSeek : AccurateSeek); player->seekForward(); break; case Qt::Key_M: if (player->audio()) { player->audio()->setMute(!player->audio()->isMute()); } break; case Qt::Key_A: { VideoRenderer* renderer = player->renderer(); VideoRenderer::OutAspectRatioMode r = renderer->outAspectRatioMode(); renderer->setOutAspectRatioMode(VideoRenderer::OutAspectRatioMode(((int)r+1)%2)); } break; case Qt::Key_R: { VideoRenderer* renderer = player->renderer(); renderer->setOrientation(renderer->orientation() + 90); qDebug("orientation: %d", renderer->orientation()); } break; case Qt::Key_T: { QWidget *w = qApp->activeWindow(); if (!w) return false; w->setWindowFlags(w->window()->windowFlags() ^ Qt::WindowStaysOnTopHint); //call setParent() when changing the flags, causing the widget to be hidden w->show(); } break; case Qt::Key_F1: help(); break; default: return false; } break; } case QEvent::DragEnter: case QEvent::DragMove: { QDropEvent *e = static_cast(event); e->acceptProposedAction(); } break; case QEvent::Drop: { QDropEvent *e = static_cast(event); QString path = e->mimeData()->urls().first().toLocalFile(); player->stop(); player->load(path); player->play(); e->acceptProposedAction(); } break; case QEvent::GraphicsSceneContextMenu: { QGraphicsSceneContextMenuEvent *e = static_cast(event); showMenu(e->screenPos()); } break; case QEvent::ContextMenu: { QContextMenuEvent *e = static_cast(event); showMenu(e->globalPos()); } break; default: return false; } return true; //false: for text input } void EventFilter::showMenu(const QPoint &p) { if (!menu) { menu = new QMenu(); menu->addAction(tr("Open"), this, SLOT(openLocalFile())); menu->addAction(tr("Open Url"), this, SLOT(openUrl())); menu->addSeparator(); menu->addAction(tr("About"), this, SLOT(about())); menu->addAction(tr("Help"), this, SLOT(help())); menu->addSeparator(); } menu->exec(p); } WindowEventFilter::WindowEventFilter(QWidget *window) : QObject(window) , mpWindow(window) { } bool WindowEventFilter::eventFilter(QObject *watched, QEvent *event) { if (watched != mpWindow) return false; if (event->type() == QEvent::WindowStateChange) { QWindowStateChangeEvent *e = static_cast(event); mpWindow->updateGeometry(); if (mpWindow->windowState().testFlag(Qt::WindowFullScreen) || e->oldState().testFlag(Qt::WindowFullScreen)) { emit fullscreenChanged(); } return false; } if (event->type() == QEvent::MouseButtonPress) { QMouseEvent *me = static_cast(event); Qt::MouseButton mbt = me->button(); if (mbt == Qt::LeftButton) { gMousePos = me->globalPos(); iMousePos = me->pos(); } return false; } if (event->type() == QEvent::MouseButtonRelease) { QMouseEvent *me = static_cast(event); Qt::MouseButton mbt = me->button(); if (mbt != Qt::LeftButton) return false; iMousePos = QPoint(); gMousePos = QPoint(); return false; } if (event->type() == QEvent::MouseMove) { if (iMousePos.isNull() || gMousePos.isNull()) return false; QMouseEvent *me = static_cast(event); int x = mpWindow->pos().x(); int y = mpWindow->pos().y(); int dx = me->globalPos().x() - gMousePos.x(); int dy = me->globalPos().y() - gMousePos.y(); gMousePos = me->globalPos(); mpWindow->move(x + dx, y + dy); return false; } return false; }