From: Hendrik Leppkes Date: Wed, 10 Feb 2016 09:21:09 +0000 (+0100) Subject: Implement QtMultimedia notification backend X-Git-Tag: travis-deploy-test~483 X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=commitdiff_plain;h=680565f39c50f27cc339cb3e96bbd0abc6f47144 Implement QtMultimedia notification backend Phonon is no longer officially supported since Qt5, while QtMultimedia implements all the required functionality to provide audio notifications. Closes GH-182. --- diff --git a/CMakeLists.txt b/CMakeLists.txt index d238691a..38733c63 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -215,13 +215,22 @@ if (USE_QT5) ) endif() - find_package(Phonon4Qt5 QUIET) - set_package_properties(Phonon4Qt5 PROPERTIES TYPE RECOMMENDED - URL "https://projects.kde.org/projects/kdesupport/phonon" - DESCRIPTION "a multimedia abstraction library" + find_package(Qt5Multimedia QUIET) + set_package_properties(Qt5Multimedia PROPERTIES TYPE RECOMMENDED + URL "http://qt.digia.com" + DESCRIPTION "Multimedia support for Qt5" PURPOSE "Required for audio notifications" ) + if (NOT Qt5Multimedia_FOUND) + find_package(Phonon4Qt5 QUIET) + set_package_properties(Phonon4Qt5 PROPERTIES TYPE RECOMMENDED + URL "https://projects.kde.org/projects/kdesupport/phonon" + DESCRIPTION "a multimedia abstraction library" + PURPOSE "Required for audio notifications" + ) + endif() + find_package(LibsnoreQt5 0.7.0 QUIET) set_package_properties(LibsnoreQt5 PROPERTIES TYPE OPTIONAL URL "https://projects.kde.org/projects/playground/libs/snorenotify" diff --git a/src/qtui/CMakeLists.txt b/src/qtui/CMakeLists.txt index eedb69c6..fdf5eaa8 100644 --- a/src/qtui/CMakeLists.txt +++ b/src/qtui/CMakeLists.txt @@ -102,6 +102,13 @@ if (LibsnoreQt5_FOUND) list(APPEND LIBS Snore::Libsnore Snore::LibsnoreSettings) endif() +if (Qt5Multimedia_FOUND) + add_definitions(-DHAVE_QTMULTIMEDIA) + list(APPEND QT_MODULES Multimedia) + set(SOURCES ${SOURCES} qtmultimedianotificationbackend.cpp) + set(FORMS ${FORMS} qtmultimedianotificationconfigwidget.ui) +endif() + if (PHONON_FOUND OR Phonon4Qt5_FOUND) add_definitions(-DHAVE_PHONON) include_directories(${PHONON_INCLUDES}) diff --git a/src/qtui/mainwin.cpp b/src/qtui/mainwin.cpp index ca31fcec..640b09cc 100644 --- a/src/qtui/mainwin.cpp +++ b/src/qtui/mainwin.cpp @@ -101,6 +101,9 @@ #include "verticaldock.h" #ifndef HAVE_KDE +# ifdef HAVE_QTMULTIMEDIA +# include "qtmultimedianotificationbackend.h" +# endif # ifdef HAVE_PHONON # include "phononnotificationbackend.h" # endif @@ -228,6 +231,9 @@ void MainWin::init() setupHotList(); #ifndef HAVE_KDE +# ifdef HAVE_QTMULTIMEDIA + QtUi::registerNotificationBackend(new QtMultimediaNotificationBackend(this)); +# endif # ifdef HAVE_PHONON QtUi::registerNotificationBackend(new PhononNotificationBackend(this)); # endif diff --git a/src/qtui/qtmultimedianotificationbackend.cpp b/src/qtui/qtmultimedianotificationbackend.cpp new file mode 100644 index 00000000..746c21cb --- /dev/null +++ b/src/qtui/qtmultimedianotificationbackend.cpp @@ -0,0 +1,211 @@ +/*************************************************************************** + * Copyright (C) 2005-2015 by the Quassel Project * + * devel@quassel-irc.org * + * * + * 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 2 of the License, or * + * (at your option) version 3. * + * * + * 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, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include +#include +#include + +#include "qtmultimedianotificationbackend.h" + +#include "clientsettings.h" +#include "mainwin.h" +#include "qtui.h" + +QtMultimediaNotificationBackend::QtMultimediaNotificationBackend(QObject *parent) + : AbstractNotificationBackend(parent), + _media(0) +{ + NotificationSettings notificationSettings; + notificationSettings.notify("QtMultimedia/Enabled", this, SLOT(enabledChanged(const QVariant &))); + notificationSettings.notify("QtMultimedia/AudioFile", this, SLOT(audioFileChanged(const QVariant &))); + + createMediaObject(notificationSettings.value("QtMultimedia/AudioFile", QString()).toString()); + + _enabled = notificationSettings.value("QtMultimedia/Enabled", true).toBool(); +} + + +QtMultimediaNotificationBackend::~QtMultimediaNotificationBackend() +{ + if (_media) + delete _media; +} + + +void QtMultimediaNotificationBackend::notify(const Notification ¬ification) +{ + if (_enabled && (notification.type == Highlight || notification.type == PrivMsg)) { + if (_media && _media->availability() == QMultimedia::Available) { + _media->stop(); + _media->play(); + } + else + QApplication::beep(); + } +} + + +void QtMultimediaNotificationBackend::close(uint notificationId) +{ + Q_UNUSED(notificationId); +} + + +void QtMultimediaNotificationBackend::enabledChanged(const QVariant &v) +{ + _enabled = v.toBool(); +} + + +void QtMultimediaNotificationBackend::audioFileChanged(const QVariant &v) +{ + createMediaObject(v.toString()); +} + + +SettingsPage *QtMultimediaNotificationBackend::createConfigWidget() const +{ + return new ConfigWidget(); +} + + +void QtMultimediaNotificationBackend::createMediaObject(const QString &file) +{ + if (_media) + delete _media; + + if (file.isEmpty()) { + _media = 0; + return; + } + + _media = new QMediaPlayer; + _media->setMedia(QUrl::fromLocalFile(file)); +} + + +/***************************************************************************/ + +QtMultimediaNotificationBackend::ConfigWidget::ConfigWidget(QWidget *parent) + : SettingsPage("Internal", "QtMultimediaNotification", parent), + audioPreview(0) +{ + ui.setupUi(this); + ui.enabled->setIcon(QIcon::fromTheme("media-playback-start")); + ui.play->setIcon(QIcon::fromTheme("media-playback-start")); + ui.open->setIcon(QIcon::fromTheme("document-open")); + + QMediaPlayer *player = new QMediaPlayer; + _audioAvailable = player->availability() == QMultimedia::Available; + delete player; + + connect(ui.enabled, SIGNAL(toggled(bool)), SLOT(widgetChanged())); + connect(ui.filename, SIGNAL(textChanged(const QString &)), SLOT(widgetChanged())); +} + + +QtMultimediaNotificationBackend::ConfigWidget::~ConfigWidget() +{ + if (audioPreview) + delete audioPreview; +} + + +void QtMultimediaNotificationBackend::ConfigWidget::widgetChanged() +{ + if (! _audioAvailable) { + ui.play->setEnabled(ui.enabled->isChecked()); + ui.open->setEnabled(false); + ui.filename->setEnabled(false); + ui.filename->setText(QString()); + } + else { + ui.play->setEnabled(ui.enabled->isChecked() && !ui.filename->text().isEmpty()); + + bool changed = (enabled != ui.enabled->isChecked() || filename != ui.filename->text()); + + if (changed != hasChanged()) + setChangedState(changed); + } +} + + +bool QtMultimediaNotificationBackend::ConfigWidget::hasDefaults() const +{ + return true; +} + + +void QtMultimediaNotificationBackend::ConfigWidget::defaults() +{ + ui.enabled->setChecked(false); + ui.filename->setText(QString()); + widgetChanged(); +} + + +void QtMultimediaNotificationBackend::ConfigWidget::load() +{ + NotificationSettings s; + enabled = s.value("QtMultimedia/Enabled", false).toBool(); + filename = s.value("QtMultimedia/AudioFile", QString()).toString(); + + ui.enabled->setChecked(enabled); + ui.filename->setText(filename); + + setChangedState(false); +} + + +void QtMultimediaNotificationBackend::ConfigWidget::save() +{ + NotificationSettings s; + s.setValue("QtMultimedia/Enabled", ui.enabled->isChecked()); + s.setValue("QtMultimedia/AudioFile", ui.filename->text()); + load(); +} + + +void QtMultimediaNotificationBackend::ConfigWidget::on_open_clicked() +{ + QString file = QFileDialog::getOpenFileName(this, tr("Select Audio File")); + if (!file.isEmpty()) { + ui.filename->setText(file); + ui.play->setEnabled(true); + widgetChanged(); + } +} + + +void QtMultimediaNotificationBackend::ConfigWidget::on_play_clicked() +{ + if (_audioAvailable) { + if (!ui.filename->text().isEmpty()) { + if (audioPreview) + delete audioPreview; + + audioPreview = new QMediaPlayer; + audioPreview->setMedia(QUrl::fromLocalFile(ui.filename->text())); + audioPreview->play(); + } + } + else + QApplication::beep(); +} diff --git a/src/qtui/qtmultimedianotificationbackend.h b/src/qtui/qtmultimedianotificationbackend.h new file mode 100644 index 00000000..aa028bd4 --- /dev/null +++ b/src/qtui/qtmultimedianotificationbackend.h @@ -0,0 +1,84 @@ +/*************************************************************************** + * Copyright (C) 2005-2015 by the Quassel Project * + * devel@quassel-irc.org * + * * + * 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 2 of the License, or * + * (at your option) version 3. * + * * + * 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, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#ifndef PHONONNOTIFICATIONBACKEND_H_ +#define PHONONNOTIFICATIONBACKEND_H_ + +#include + +#include "abstractnotificationbackend.h" +#include "settingspage.h" + +#include "ui_qtmultimedianotificationconfigwidget.h" + +class QtMultimediaNotificationBackend : public AbstractNotificationBackend +{ + Q_OBJECT + +public: + QtMultimediaNotificationBackend(QObject *parent = 0); + ~QtMultimediaNotificationBackend(); + + void notify(const Notification &); + void close(uint notificationId); + virtual SettingsPage *createConfigWidget() const; + +private slots: + void enabledChanged(const QVariant &); + void audioFileChanged(const QVariant &); + void createMediaObject(const QString &name); + +private: + class ConfigWidget; + + bool _enabled; + QMediaPlayer *_media; +}; + + +class QtMultimediaNotificationBackend::ConfigWidget : public SettingsPage +{ + Q_OBJECT + +public: + ConfigWidget(QWidget *parent = 0); + ~ConfigWidget(); + + void save(); + void load(); + bool hasDefaults() const; + void defaults(); + +private slots: + void widgetChanged(); + void on_open_clicked(); + void on_play_clicked(); + +private: + Ui::QtMultimediaNotificationConfigWidget ui; + + bool enabled; + bool _audioAvailable; + QString filename; + QMediaPlayer *audioPreview; +}; + + +#endif diff --git a/src/qtui/ui/qtmultimedianotificationconfigwidget.ui b/src/qtui/ui/qtmultimedianotificationconfigwidget.ui new file mode 100644 index 00000000..539d757e --- /dev/null +++ b/src/qtui/ui/qtmultimedianotificationconfigwidget.ui @@ -0,0 +1,113 @@ + + + QtMultimediaNotificationConfigWidget + + + + 0 + 0 + 439 + 36 + + + + Form + + + + + + Play a sound + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + false + + + Prelisten to the selected sound + + + + + + + + + + false + + + Select the sound file to play + + + + + + + false + + + Select the sound file to play + + + + + + + + + + + + enabled + toggled(bool) + filename + setEnabled(bool) + + + 59 + 15 + + + 246 + 20 + + + + + enabled + toggled(bool) + open + setEnabled(bool) + + + 89 + 18 + + + 426 + 22 + + + + +