Hello community,

here is the log from the commit of package knotifications for openSUSE:Factory 
checked in at 2018-10-01 08:07:58
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/knotifications (Old)
 and      /work/SRC/openSUSE:Factory/.knotifications.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "knotifications"

Mon Oct  1 08:07:58 2018 rev:58 rq:636014 version:5.50.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/knotifications/knotifications.changes    
2018-08-24 16:54:53.233416863 +0200
+++ /work/SRC/openSUSE:Factory/.knotifications.new/knotifications.changes       
2018-10-01 08:07:59.970301929 +0200
@@ -1,0 +2,10 @@
+Thu Sep 13 21:58:45 UTC 2018 - lbeltr...@kde.org
+
+- Update to 5.50.0
+  * New feature release
+  * For more details please see:
+  * https://www.kde.org/announcements/kde-frameworks-5.50.0.php
+- Changes since 5.49.0:
+  * Support libcanberra for audio notification
+
+-------------------------------------------------------------------

Old:
----
  knotifications-5.49.0.tar.xz

New:
----
  knotifications-5.50.0.tar.xz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ knotifications.spec ++++++
--- /var/tmp/diff_new_pack.y37v2m/_old  2018-10-01 08:08:00.466301663 +0200
+++ /var/tmp/diff_new_pack.y37v2m/_new  2018-10-01 08:08:00.466301663 +0200
@@ -17,14 +17,14 @@
 
 
 %define lname   libKF5Notifications5
-%define _tar_path 5.49
+%define _tar_path 5.50
 # Full KF5 version (e.g. 5.33.0)
 %{!?_kf5_version: %global _kf5_version %{version}}
 # Last major and minor KF5 version (e.g. 5.33)
 %{!?_kf5_bugfix_version: %define _kf5_bugfix_version %(echo %{_kf5_version} | 
awk -F. '{print $1"."$2}')}
 %bcond_without lang
 Name:           knotifications
-Version:        5.49.0
+Version:        5.50.0
 Release:        0
 Summary:        KDE Desktop notifications
 License:        LGPL-2.1-or-later

++++++ knotifications-5.49.0.tar.xz -> knotifications-5.50.0.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/knotifications-5.49.0/CMakeLists.txt 
new/knotifications-5.50.0/CMakeLists.txt
--- old/knotifications-5.49.0/CMakeLists.txt    2018-08-04 13:00:11.000000000 
+0200
+++ new/knotifications-5.50.0/CMakeLists.txt    2018-09-02 21:28:52.000000000 
+0200
@@ -1,16 +1,16 @@
 cmake_minimum_required(VERSION 3.0)
 
-set(KF5_VERSION "5.49.0") # handled by release scripts
-set(KF5_DEP_VERSION "5.49.0") # handled by release scripts
+set(KF5_VERSION "5.50.0") # handled by release scripts
+set(KF5_DEP_VERSION "5.50.0") # handled by release scripts
 project(KNotifications VERSION ${KF5_VERSION})
 
 # ECM setup
 include(FeatureSummary)
-find_package(ECM 5.49.0  NO_MODULE)
+find_package(ECM 5.50.0  NO_MODULE)
 set_package_properties(ECM PROPERTIES TYPE REQUIRED DESCRIPTION "Extra CMake 
Modules." URL 
"https://projects.kde.org/projects/kdesupport/extra-cmake-modules";)
 feature_summary(WHAT REQUIRED_PACKAGES_NOT_FOUND 
FATAL_ON_MISSING_REQUIRED_PACKAGES)
 
-set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR})
+set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR} 
${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules)
 
 
 include(GenerateExportHeader)
@@ -65,13 +65,23 @@
 find_package(KF5Codecs ${KF5_DEP_VERSION} REQUIRED)
 find_package(KF5CoreAddons ${KF5_DEP_VERSION} REQUIRED)
 
-find_package(Phonon4Qt5 4.6.60 REQUIRED NO_MODULE)
-set_package_properties(Phonon4Qt5 PROPERTIES
-   DESCRIPTION "Qt-based audio library"
-   TYPE REQUIRED
-   PURPOSE "Required to build audio notification support")
-if (Phonon4Qt5_FOUND)
-  add_definitions(-DHAVE_PHONON4QT5)
+find_package(Canberra)
+set_package_properties(Canberra PROPERTIES DESCRIPTION "Library for generating 
event sounds"
+    PURPOSE "Needed to build audio notification support"
+    URL "http://0pointer.de/lennart/projects/libcanberra";
+    TYPE OPTIONAL)
+if (CANBERRA_FOUND)
+    add_definitions(-DHAVE_CANBERRA)
+else()
+    find_package(Phonon4Qt5 4.6.60 NO_MODULE)
+    set_package_properties(Phonon4Qt5 PROPERTIES
+        DESCRIPTION "Qt-based audio library"
+        # This is REQUIRED since you cannot tell CMake "either one of those 
two optional ones are required"
+        TYPE REQUIRED
+        PURPOSE "Needed to build audio notification support when Canberra 
isn't available")
+    if (Phonon4Qt5_FOUND)
+        add_definitions(-DHAVE_PHONON4QT5)
+    endif()
 endif()
 
 remove_definitions(-DQT_NO_CAST_FROM_BYTEARRAY)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/knotifications-5.49.0/cmake/modules/FindCanberra.cmake 
new/knotifications-5.50.0/cmake/modules/FindCanberra.cmake
--- old/knotifications-5.49.0/cmake/modules/FindCanberra.cmake  1970-01-01 
01:00:00.000000000 +0100
+++ new/knotifications-5.50.0/cmake/modules/FindCanberra.cmake  2018-09-02 
21:28:52.000000000 +0200
@@ -0,0 +1,50 @@
+# - Find libcanberra's libraries and headers.
+# This module defines the following variables:
+#
+#  CANBERRA_FOUND        - true if libcanberra was found
+#  CANBERRA_LIBRARIES    - libcanberra libraries to link against
+#  CANBERRA_INCLUDE_DIRS - include path for libcanberra
+#
+# Copyright (c) 2012 Raphael Kubo da Costa <rak...@freebsd.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. Neither the name of the University nor the names of its contributors
+#    may be used to endorse or promote products derived from this software
+#    without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+find_package(PkgConfig)
+pkg_check_modules(PC_CANBERRA libcanberra)
+
+find_library(CANBERRA_LIBRARIES
+    NAMES canberra
+    HINTS ${PC_CANBERRA_LIBRARY_DIRS} ${PC_CANBERRA_LIBDIR}
+)
+
+find_path(CANBERRA_INCLUDE_DIRS
+    NAMES canberra.h
+    HINTS ${PC_CANBERRA_INCLUDE_DIRS} ${PC_CANBERRA_INCLUDEDIR}
+)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Canberra REQUIRED_VARS CANBERRA_LIBRARIES 
CANBERRA_INCLUDE_DIRS)
+
+mark_as_advanced(CANBERRA_LIBRARIES CANBERRA_INCLUDE_DIRS)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/knotifications-5.49.0/po/ar/knotifications5_qt.po 
new/knotifications-5.50.0/po/ar/knotifications5_qt.po
--- old/knotifications-5.49.0/po/ar/knotifications5_qt.po       2018-08-04 
13:00:11.000000000 +0200
+++ new/knotifications-5.50.0/po/ar/knotifications5_qt.po       2018-09-02 
21:28:52.000000000 +0200
@@ -1,19 +1,19 @@
-# Safa Alfulaij <safa1996alful...@gmail.com>, 2014.
+# Safa Alfulaij <safa1996alful...@gmail.com>, 2014, 2018.
 msgid ""
 msgstr ""
 "Project-Id-Version: \n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2014-06-28 15:38+0300\n"
-"PO-Revision-Date: 2014-05-08 20:10+0300\n"
+"PO-Revision-Date: 2018-06-09 21:05+0300\n"
 "Last-Translator: Safa Alfulaij <safa1996alful...@gmail.com>\n"
-"Language-Team: Arabic <kde-i18n-...@kde.org>\n"
+"Language-Team: Arabic <d...@arabeyes.org>\n"
 "Language: ar\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 "
 "&& n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n"
-"X-Generator: Lokalize 1.5\n"
+"X-Generator: Lokalize 2.0\n"
 "X-Qt-Contexts: true\n"
 
 #: knotificationrestrictions.cpp:192
@@ -40,9 +40,9 @@
 #, qt-format
 msgctxt "KStatusNotifierItem|"
 msgid "<qt>Are you sure you want to quit <b>%1</b>?</qt>"
-msgstr "<qt>أأنت متأكد من إنهاء <b>%1</b>؟</qt>"
+msgstr "أمتأكّد من إنهاء <b>%1</b>؟"
 
 #: kstatusnotifieritem.cpp:1066
 msgctxt "KStatusNotifierItem|"
 msgid "Confirm Quit From System Tray"
-msgstr "أكِّد الإنهاء من صينية النظام"
+msgstr "أكّد الإنهاء من صينية النظام"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/knotifications-5.49.0/po/zh_CN/knotifications5_qt.po 
new/knotifications-5.50.0/po/zh_CN/knotifications5_qt.po
--- old/knotifications-5.49.0/po/zh_CN/knotifications5_qt.po    2018-08-04 
13:00:11.000000000 +0200
+++ new/knotifications-5.50.0/po/zh_CN/knotifications5_qt.po    2018-09-02 
21:28:52.000000000 +0200
@@ -13,8 +13,8 @@
 msgid ""
 msgstr ""
 "Project-Id-Version: kdeorg\n"
-"PO-Revision-Date: 2018-07-24 08:41\n"
-"Last-Translator: guoyunhebrave <guoyunhebr...@gmail.com>\n"
+"PO-Revision-Date: 2018-08-30 13:09\n"
+"Last-Translator: guoyunhebrave <yunhe....@protonmail.com>\n"
 "Language-Team: Chinese Simplified\n"
 "Language: zh_CN\n"
 "MIME-Version: 1.0\n"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/knotifications-5.49.0/src/CMakeLists.txt 
new/knotifications-5.50.0/src/CMakeLists.txt
--- old/knotifications-5.49.0/src/CMakeLists.txt        2018-08-04 
13:00:11.000000000 +0200
+++ new/knotifications-5.50.0/src/CMakeLists.txt        2018-09-02 
21:28:52.000000000 +0200
@@ -1,6 +1,9 @@
 if (Phonon4Qt5_FOUND)
     include_directories(${PHONON_INCLUDE_DIR})
 endif()
+if (CANBERRA_FOUND)
+    include_directories(${CANBERRA_INCLUDE_DIRS})
+endif()
 
 ecm_create_qm_loader(knotifications_QM_LOADER knotifications5_qt)
 
@@ -27,9 +30,12 @@
 
 ecm_qt_declare_logging_category(knotifications_SRCS HEADER debug_p.h 
IDENTIFIER LOG_KNOTIFICATIONS CATEGORY_NAME org.kde.knotifications)
 
-if (Phonon4Qt5_FOUND)
+if (CANBERRA_FOUND)
+  set(knotifications_SRCS ${knotifications_SRCS}
+  notifybyaudio_canberra.cpp)
+elseif (Phonon4Qt5_FOUND)
   set(knotifications_SRCS ${knotifications_SRCS}
-  notifybyaudio.cpp)
+  notifybyaudio_phonon.cpp)
 endif()
 
 if (Qt5TextToSpeech_FOUND)
@@ -82,6 +88,11 @@
         ${PHONON_LIBRARIES})
 endif()
 
+if (CANBERRA_FOUND)
+    target_link_libraries(KF5Notifications PRIVATE
+        ${CANBERRA_LIBRARIES})
+endif()
+
 if (Qt5TextToSpeech_FOUND)
     target_link_libraries(KF5Notifications PRIVATE Qt5::TextToSpeech)
 endif()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/knotifications-5.49.0/src/knotificationmanager.cpp 
new/knotifications-5.50.0/src/knotificationmanager.cpp
--- old/knotifications-5.49.0/src/knotificationmanager.cpp      2018-08-04 
13:00:11.000000000 +0200
+++ new/knotifications-5.50.0/src/knotificationmanager.cpp      2018-09-02 
21:28:52.000000000 +0200
@@ -41,8 +41,10 @@
 #include "notifybyflatpak.h"
 #include "debug_p.h"
 
-#ifdef HAVE_PHONON4QT5
-#include "notifybyaudio.h"
+#if defined(HAVE_CANBERRA)
+#include "notifybyaudio_canberra.h"
+#elif defined(HAVE_PHONON4QT5)
+#include "notifybyaudio_phonon.h"
 #endif
 
 #ifdef HAVE_SPEECH
@@ -137,7 +139,7 @@
         plugin = new NotifyByTaskbar(this);
         addPlugin(plugin);
     } else if (action == QLatin1String("Sound")) {
-#ifdef HAVE_PHONON4QT5
+#if defined(HAVE_PHONON4QT5) || defined(HAVE_CANBERRA)
         plugin = new NotifyByAudio(this);
         addPlugin(plugin);
 #endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/knotifications-5.49.0/src/notifybyaudio.cpp 
new/knotifications-5.50.0/src/notifybyaudio.cpp
--- old/knotifications-5.49.0/src/notifybyaudio.cpp     2018-08-04 
13:00:11.000000000 +0200
+++ new/knotifications-5.50.0/src/notifybyaudio.cpp     1970-01-01 
01:00:00.000000000 +0100
@@ -1,188 +0,0 @@
-/* This file is part of the KDE libraries
-   Copyright (C) 2014-2015 by Martin Klapetek <mklape...@kde.org>
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) version 3, or any
-   later version accepted by the membership of KDE e.V. (or its
-   successor approved by the membership of KDE e.V.), which shall
-   act as a proxy defined in Section 6 of version 3 of the license.
-
-   This library 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
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library.  If not, see 
<http://www.gnu.org/licenses/>.
-
-*/
-
-#include "notifybyaudio.h"
-#include "debug_p.h"
-
-#include <QDateTime>
-#include <QFile>
-#include <QTextStream>
-#include <QUrl>
-#include <QString>
-
-#include "knotifyconfig.h"
-#include "knotification.h"
-
-#include <phonon/mediaobject.h>
-#include <phonon/mediasource.h>
-#include <phonon/audiooutput.h>
-
-NotifyByAudio::NotifyByAudio(QObject *parent)
-    : KNotificationPlugin(parent),
-      m_audioOutput(nullptr)
-{
-}
-
-NotifyByAudio::~NotifyByAudio()
-{
-    qDeleteAll(m_reusablePhonons);
-    delete m_audioOutput;
-}
-
-void NotifyByAudio::notify(KNotification *notification, KNotifyConfig *config)
-{
-    if (!m_audioOutput) {
-        m_audioOutput = new Phonon::AudioOutput(Phonon::NotificationCategory, 
this);
-    }
-    const QString soundFilename = config->readEntry(QStringLiteral("Sound"));
-    if (soundFilename.isEmpty()) {
-        qCWarning(LOG_KNOTIFICATIONS) << "Audio notification requested, but no 
sound file provided in notifyrc file, aborting audio notification";
-
-        finish(notification);
-        return;
-    }
-
-    QUrl soundURL;
-    const auto dataLocations = 
QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation);
-    for (const QString &dataLocation : dataLocations) {
-        soundURL = QUrl::fromUserInput(soundFilename,
-                                       dataLocation + 
QStringLiteral("/sounds"),
-                                       QUrl::AssumeLocalFile);
-        if (soundURL.isLocalFile() && QFile::exists(soundURL.toLocalFile())) {
-            break;
-        } else if (!soundURL.isLocalFile() && soundURL.isValid()) {
-            break;
-        }
-        soundURL.clear();
-    }
-    if (soundURL.isEmpty()) {
-        qCWarning(LOG_KNOTIFICATIONS) << "Audio notification requested, but 
sound file from notifyrc file was not found, aborting audio notification";
-        finish(notification);
-        return;
-    }
-
-    Phonon::MediaObject *m;
-
-    if (m_reusablePhonons.isEmpty()) {
-        m = new Phonon::MediaObject(this);
-        connect(m, &Phonon::MediaObject::finished, this, 
&NotifyByAudio::onAudioFinished);
-        connect(m, &Phonon::MediaObject::stateChanged, this, 
&NotifyByAudio::stateChanged);
-        Phonon::createPath(m, m_audioOutput);
-    } else {
-        m = m_reusablePhonons.takeFirst();
-    }
-
-    m->setCurrentSource(soundURL);
-    m->play();
-
-    if (notification->flags() & KNotification::LoopSound) {
-        // Enqueing essentially prevents the subsystem pipeline from partial 
teardown
-        // which is the most desired thing in terms of load and delay between 
loop cycles.
-        // All of this is timing dependent, which is why we want at least one 
source queued;
-        // in reality the shorter the source the more sources we want to be 
queued to prevent
-        // the MO from running out of sources.
-        // Point being that all phonon signals are forcefully queued (becuase 
qthread has problems detecting !pthread threads),
-        // so when you get for example the aboutToFinish signal the MO might 
already have stopped playing.
-        //
-        // And so we queue it three times at least; doesn't cost anything and 
keeps us safe.
-
-        m->enqueue(soundURL);
-        m->enqueue(soundURL);
-        m->enqueue(soundURL);
-
-        connect(m, SIGNAL(currentSourceChanged(Phonon::MediaSource)), 
SLOT(onAudioSourceChanged(Phonon::MediaSource)));
-    }
-
-    Q_ASSERT(!m_notifications.value(m));
-    m_notifications.insert(m, notification);
-}
-
-void NotifyByAudio::stateChanged(Phonon::State newState, Phonon::State 
oldState)
-{
-    qCDebug(LOG_KNOTIFICATIONS) << "Changing audio state from" << oldState << 
"to" << newState;
-}
-
-void NotifyByAudio::close(KNotification *notification)
-{
-    Phonon::MediaObject *m = m_notifications.key(notification);
-
-    if (!m) {
-        return;
-    }
-
-    m->stop();
-    finishNotification(notification, m);
-}
-
-void NotifyByAudio::onAudioFinished()
-{
-    Phonon::MediaObject *m = qobject_cast<Phonon::MediaObject*>(sender());
-
-    if (!m) {
-        return;
-    }
-
-    KNotification *notification = m_notifications.value(m, nullptr);
-
-    if (!notification) {
-        // This means that close was called already so there's nothing else to 
do.
-        // Ideally we should not be getting here if close has already been 
called
-        // since stoping a mediaobject means it won't emit finished() *BUT*
-        // since the finished signal is a queued connection in phonon it can 
happen
-        // that the playing had already finished and we just had not got the 
signal yet
-        return;
-    }
-
-    //if the sound is short enough, we can't guarantee new sounds are
-    //enqueued before finished is emitted.
-    //so to make sure we are looping restart it when the sound finished
-    if (notification && (notification->flags() & KNotification::LoopSound)) {
-        m->play();
-        return;
-    }
-
-    finishNotification(notification, m);
-}
-
-void NotifyByAudio::finishNotification(KNotification *notification, 
Phonon::MediaObject *m)
-{
-    m_notifications.remove(m);
-
-    if (notification) {
-        finish(notification);
-    }
-
-    disconnect(m, SIGNAL(currentSourceChanged(Phonon::MediaSource)), this, 
SLOT(onAudioSourceChanged(Phonon::MediaSource)));
-
-    m_reusablePhonons.append(m);
-}
-
-void NotifyByAudio::onAudioSourceChanged(const Phonon::MediaSource &source)
-{
-    Phonon::MediaObject *m = qobject_cast<Phonon::MediaObject*>(sender());
-
-    if (!m) {
-        return;
-    }
-
-    m->enqueue(source);
-}
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/knotifications-5.49.0/src/notifybyaudio.h 
new/knotifications-5.50.0/src/notifybyaudio.h
--- old/knotifications-5.49.0/src/notifybyaudio.h       2018-08-04 
13:00:11.000000000 +0200
+++ new/knotifications-5.50.0/src/notifybyaudio.h       1970-01-01 
01:00:00.000000000 +0100
@@ -1,64 +0,0 @@
-/* This file is part of the KDE libraries
-   Copyright 2014 by Martin Klapetek <mklape...@kde.org>
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) version 3, or any
-   later version accepted by the membership of KDE e.V. (or its
-   successor approved by the membership of KDE e.V.), which shall
-   act as a proxy defined in Section 6 of version 3 of the license.
-
-   This library 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
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library.  If not, see 
<http://www.gnu.org/licenses/>.
-
-*/
-
-
-#ifndef NOTIFYBYAUDIO_H
-#define NOTIFYBYAUDIO_H
-
-#include "knotificationplugin.h"
-
-#include <phonon/MediaObject>
-
-namespace Phonon {
-// class MediaObject;
-class MediaSource;
-class AudioOutput;
-}
-
-class KNotification;
-
-class NotifyByAudio : public KNotificationPlugin
-{
-    Q_OBJECT
-
-public:
-    explicit NotifyByAudio(QObject *parent = nullptr);
-    ~NotifyByAudio() override;
-
-    QString optionName() override { return QStringLiteral("Sound"); }
-    void notify(KNotification *notification, KNotifyConfig *config) override;
-    void close(KNotification *notification) override;
-
-private Q_SLOTS:
-    void onAudioFinished();
-    void onAudioSourceChanged(const Phonon::MediaSource &source);
-    void stateChanged(Phonon::State newState, Phonon::State oldState);
-
-
-private:
-    void finishNotification(KNotification *notification, Phonon::MediaObject 
*m);
-
-    QList<Phonon::MediaObject*> m_reusablePhonons;
-    QHash<Phonon::MediaObject*, KNotification*> m_notifications;
-    Phonon::AudioOutput *m_audioOutput;
-};
-
-#endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/knotifications-5.49.0/src/notifybyaudio_canberra.cpp 
new/knotifications-5.50.0/src/notifybyaudio_canberra.cpp
--- old/knotifications-5.49.0/src/notifybyaudio_canberra.cpp    1970-01-01 
01:00:00.000000000 +0100
+++ new/knotifications-5.50.0/src/notifybyaudio_canberra.cpp    2018-09-02 
21:28:52.000000000 +0200
@@ -0,0 +1,190 @@
+/* This file is part of the KDE libraries
+   Copyright (C) 2014-2015 by Martin Klapetek <mklape...@kde.org>
+   Copyright (C) 2018 Kai Uwe Broulik <k...@privat.broulik.de>
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) version 3, or any
+   later version accepted by the membership of KDE e.V. (or its
+   successor approved by the membership of KDE e.V.), which shall
+   act as a proxy defined in Section 6 of version 3 of the license.
+
+   This library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library.  If not, see 
<http://www.gnu.org/licenses/>.
+
+*/
+
+#include "notifybyaudio_canberra.h"
+#include "debug_p.h"
+
+#include <QGuiApplication>
+#include <QFile>
+#include <QFileInfo>
+#include <QIcon>
+#include <QString>
+
+#include "knotifyconfig.h"
+#include "knotification.h"
+
+#include <canberra.h>
+
+NotifyByAudio::NotifyByAudio(QObject *parent)
+    : KNotificationPlugin(parent)
+{
+    qRegisterMetaType<uint32_t>("uint32_t");
+
+    int ret = ca_context_create(&m_context);
+    if (ret != CA_SUCCESS) {
+        qCWarning(LOG_KNOTIFICATIONS) << "Failed to initialize canberra 
context for audio notification:" << ca_strerror(ret);
+        m_context = nullptr;
+        return;
+    }
+
+    ret = ca_context_change_props(m_context,
+        CA_PROP_APPLICATION_NAME, 
qUtf8Printable(qApp->applicationDisplayName()),
+        CA_PROP_APPLICATION_ID, qUtf8Printable(qApp->desktopFileName()),
+        CA_PROP_APPLICATION_ICON_NAME, 
qUtf8Printable(qApp->windowIcon().name()),
+        nullptr);
+    if (ret != CA_SUCCESS) {
+        qCWarning(LOG_KNOTIFICATIONS) << "Failed to set application properties 
on canberra context for audio notification:" << ca_strerror(ret);
+    }
+}
+
+NotifyByAudio::~NotifyByAudio()
+{
+    if (m_context) {
+        ca_context_destroy(m_context);
+    }
+    m_context = nullptr;
+}
+
+void NotifyByAudio::notify(KNotification *notification, KNotifyConfig *config)
+{
+    const QString soundFilename = config->readEntry(QStringLiteral("Sound"));
+    if (soundFilename.isEmpty()) {
+        qCWarning(LOG_KNOTIFICATIONS) << "Audio notification requested, but no 
sound file provided in notifyrc file, aborting audio notification";
+
+        finish(notification);
+        return;
+    }
+
+    QUrl soundURL;
+    const auto dataLocations = 
QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation);
+    for (const QString &dataLocation : dataLocations) {
+        soundURL = QUrl::fromUserInput(soundFilename,
+                                       dataLocation + 
QStringLiteral("/sounds"),
+                                       QUrl::AssumeLocalFile);
+        if (soundURL.isLocalFile() && 
QFileInfo::exists(soundURL.toLocalFile())) {
+            break;
+        } else if (!soundURL.isLocalFile() && soundURL.isValid()) {
+            break;
+        }
+        soundURL.clear();
+    }
+    if (soundURL.isEmpty()) {
+        qCWarning(LOG_KNOTIFICATIONS) << "Audio notification requested, but 
sound file from notifyrc file was not found, aborting audio notification";
+        finish(notification);
+        return;
+    }
+
+    // Looping happens in the finishCallback
+    if (!playSound(m_currentId, soundURL)) {
+        finish(notification);
+        return;
+    }
+
+    if (notification->flags() & KNotification::LoopSound) {
+        m_loopSoundUrls.insert(m_currentId, soundURL);
+    }
+
+    Q_ASSERT(!m_notifications.value(m_currentId));
+    m_notifications.insert(m_currentId, notification);
+
+    ++m_currentId;
+}
+
+bool NotifyByAudio::playSound(quint32 id, const QUrl &url)
+{
+    if (!m_context) {
+        qCWarning(LOG_KNOTIFICATIONS) << "Cannot play notification sound 
without canberra context";
+        return false;
+    }
+
+    ca_proplist *props = nullptr;
+    ca_proplist_create(&props);
+
+    // We'll also want this cached for a time. volatile makes sure the cache is
+    // dropped after some time or when the cache is under pressure.
+    ca_proplist_sets(props, CA_PROP_MEDIA_FILENAME, 
QFile::encodeName(url.toLocalFile()).constData());
+    ca_proplist_sets(props, CA_PROP_CANBERRA_CACHE_CONTROL, "volatile");
+
+    int ret = ca_context_play_full(m_context, id, props, &ca_finish_callback, 
this);
+
+    ca_proplist_destroy(props);
+
+    if (ret != CA_SUCCESS) {
+        qCWarning(LOG_KNOTIFICATIONS) << "Failed to play sound with canberra:" 
<< ca_strerror(ret);
+        return false;
+    }
+
+    return true;
+}
+
+void NotifyByAudio::ca_finish_callback(ca_context *c, uint32_t id, int 
error_code, void *userdata)
+{
+    Q_UNUSED(c);
+    QMetaObject::invokeMethod(static_cast<NotifyByAudio*>(userdata),
+                              "finishCallback",
+                              Q_ARG(uint32_t, id),
+                              Q_ARG(int, error_code));
+}
+
+void NotifyByAudio::finishCallback(uint32_t id, int error_code)
+{
+    KNotification *notification = m_notifications.value(id, nullptr);
+
+    if (error_code == CA_SUCCESS) {
+        // Loop the sound now if we have one
+        const QUrl soundUrl = m_loopSoundUrls.value(id);
+        if (soundUrl.isValid()) {
+            if (!playSound(id, soundUrl)) {
+                finishNotification(notification, id);
+            }
+            return;
+        }
+    } else if (error_code != CA_ERROR_CANCELED) {
+        qCWarning(LOG_KNOTIFICATIONS) << "Playing audio notification failed:" 
<< ca_strerror(error_code);
+    }
+
+    finishNotification(notification, id);
+}
+
+void NotifyByAudio::close(KNotification *notification)
+{
+    if (!m_notifications.values().contains(notification)) {
+        return;
+    }
+
+    const auto id = m_notifications.key(notification);
+    if (m_context) {
+        int ret = ca_context_cancel(m_context, id);
+        if (ret != CA_SUCCESS) {
+            qCWarning(LOG_KNOTIFICATIONS) << "Failed to cancel canberra 
context for audio notification:" << ca_strerror(ret);
+            return;
+        }
+    }
+}
+
+
+void NotifyByAudio::finishNotification(KNotification *notification, quint32 id)
+{
+    m_notifications.remove(id);
+    m_loopSoundUrls.remove(id);
+    finish(notification);
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/knotifications-5.49.0/src/notifybyaudio_canberra.h 
new/knotifications-5.50.0/src/notifybyaudio_canberra.h
--- old/knotifications-5.49.0/src/notifybyaudio_canberra.h      1970-01-01 
01:00:00.000000000 +0100
+++ new/knotifications-5.50.0/src/notifybyaudio_canberra.h      2018-09-02 
21:28:52.000000000 +0200
@@ -0,0 +1,68 @@
+/* This file is part of the KDE libraries
+   Copyright 2014 by Martin Klapetek <mklape...@kde.org>
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) version 3, or any
+   later version accepted by the membership of KDE e.V. (or its
+   successor approved by the membership of KDE e.V.), which shall
+   act as a proxy defined in Section 6 of version 3 of the license.
+
+   This library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library.  If not, see 
<http://www.gnu.org/licenses/>.
+
+*/
+
+
+#ifndef NOTIFYBYAUDIO_H
+#define NOTIFYBYAUDIO_H
+
+#include "knotificationplugin.h"
+
+#include <QHash>
+#include <QUrl>
+
+class KNotification;
+
+struct ca_context;
+
+class NotifyByAudio : public KNotificationPlugin
+{
+    Q_OBJECT
+
+public:
+    explicit NotifyByAudio(QObject *parent = nullptr);
+    ~NotifyByAudio() override;
+
+    QString optionName() override { return QStringLiteral("Sound"); }
+    void notify(KNotification *notification, KNotifyConfig *config) override;
+    void close(KNotification *notification) override;
+
+private Q_SLOTS:
+    void finishCallback(uint32_t id,
+                        int error_code);
+
+private:
+    static void ca_finish_callback(ca_context *c,
+                                   uint32_t id,
+                                   int error_code,
+                                   void *userdata);
+
+    void finishNotification(KNotification *notification, quint32 id);
+
+    bool playSound(quint32 id, const QUrl &url);
+
+    ca_context *m_context = nullptr;
+    quint32 m_currentId = 0;
+    QHash<quint32, KNotification*> m_notifications;
+    // in case we loop we store the URL for the notification to be able to 
replay it
+    QHash<quint32, QUrl> m_loopSoundUrls;
+};
+
+#endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/knotifications-5.49.0/src/notifybyaudio_phonon.cpp 
new/knotifications-5.50.0/src/notifybyaudio_phonon.cpp
--- old/knotifications-5.49.0/src/notifybyaudio_phonon.cpp      1970-01-01 
01:00:00.000000000 +0100
+++ new/knotifications-5.50.0/src/notifybyaudio_phonon.cpp      2018-09-02 
21:28:52.000000000 +0200
@@ -0,0 +1,188 @@
+/* This file is part of the KDE libraries
+   Copyright (C) 2014-2015 by Martin Klapetek <mklape...@kde.org>
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) version 3, or any
+   later version accepted by the membership of KDE e.V. (or its
+   successor approved by the membership of KDE e.V.), which shall
+   act as a proxy defined in Section 6 of version 3 of the license.
+
+   This library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library.  If not, see 
<http://www.gnu.org/licenses/>.
+
+*/
+
+#include "notifybyaudio_phonon.h"
+#include "debug_p.h"
+
+#include <QDateTime>
+#include <QFile>
+#include <QTextStream>
+#include <QUrl>
+#include <QString>
+
+#include "knotifyconfig.h"
+#include "knotification.h"
+
+#include <phonon/mediaobject.h>
+#include <phonon/mediasource.h>
+#include <phonon/audiooutput.h>
+
+NotifyByAudio::NotifyByAudio(QObject *parent)
+    : KNotificationPlugin(parent),
+      m_audioOutput(nullptr)
+{
+}
+
+NotifyByAudio::~NotifyByAudio()
+{
+    qDeleteAll(m_reusablePhonons);
+    delete m_audioOutput;
+}
+
+void NotifyByAudio::notify(KNotification *notification, KNotifyConfig *config)
+{
+    if (!m_audioOutput) {
+        m_audioOutput = new Phonon::AudioOutput(Phonon::NotificationCategory, 
this);
+    }
+    const QString soundFilename = config->readEntry(QStringLiteral("Sound"));
+    if (soundFilename.isEmpty()) {
+        qCWarning(LOG_KNOTIFICATIONS) << "Audio notification requested, but no 
sound file provided in notifyrc file, aborting audio notification";
+
+        finish(notification);
+        return;
+    }
+
+    QUrl soundURL;
+    const auto dataLocations = 
QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation);
+    for (const QString &dataLocation : dataLocations) {
+        soundURL = QUrl::fromUserInput(soundFilename,
+                                       dataLocation + 
QStringLiteral("/sounds"),
+                                       QUrl::AssumeLocalFile);
+        if (soundURL.isLocalFile() && QFile::exists(soundURL.toLocalFile())) {
+            break;
+        } else if (!soundURL.isLocalFile() && soundURL.isValid()) {
+            break;
+        }
+        soundURL.clear();
+    }
+    if (soundURL.isEmpty()) {
+        qCWarning(LOG_KNOTIFICATIONS) << "Audio notification requested, but 
sound file from notifyrc file was not found, aborting audio notification";
+        finish(notification);
+        return;
+    }
+
+    Phonon::MediaObject *m;
+
+    if (m_reusablePhonons.isEmpty()) {
+        m = new Phonon::MediaObject(this);
+        connect(m, &Phonon::MediaObject::finished, this, 
&NotifyByAudio::onAudioFinished);
+        connect(m, &Phonon::MediaObject::stateChanged, this, 
&NotifyByAudio::stateChanged);
+        Phonon::createPath(m, m_audioOutput);
+    } else {
+        m = m_reusablePhonons.takeFirst();
+    }
+
+    m->setCurrentSource(soundURL);
+    m->play();
+
+    if (notification->flags() & KNotification::LoopSound) {
+        // Enqueing essentially prevents the subsystem pipeline from partial 
teardown
+        // which is the most desired thing in terms of load and delay between 
loop cycles.
+        // All of this is timing dependent, which is why we want at least one 
source queued;
+        // in reality the shorter the source the more sources we want to be 
queued to prevent
+        // the MO from running out of sources.
+        // Point being that all phonon signals are forcefully queued (becuase 
qthread has problems detecting !pthread threads),
+        // so when you get for example the aboutToFinish signal the MO might 
already have stopped playing.
+        //
+        // And so we queue it three times at least; doesn't cost anything and 
keeps us safe.
+
+        m->enqueue(soundURL);
+        m->enqueue(soundURL);
+        m->enqueue(soundURL);
+
+        connect(m, SIGNAL(currentSourceChanged(Phonon::MediaSource)), 
SLOT(onAudioSourceChanged(Phonon::MediaSource)));
+    }
+
+    Q_ASSERT(!m_notifications.value(m));
+    m_notifications.insert(m, notification);
+}
+
+void NotifyByAudio::stateChanged(Phonon::State newState, Phonon::State 
oldState)
+{
+    qCDebug(LOG_KNOTIFICATIONS) << "Changing audio state from" << oldState << 
"to" << newState;
+}
+
+void NotifyByAudio::close(KNotification *notification)
+{
+    Phonon::MediaObject *m = m_notifications.key(notification);
+
+    if (!m) {
+        return;
+    }
+
+    m->stop();
+    finishNotification(notification, m);
+}
+
+void NotifyByAudio::onAudioFinished()
+{
+    Phonon::MediaObject *m = qobject_cast<Phonon::MediaObject*>(sender());
+
+    if (!m) {
+        return;
+    }
+
+    KNotification *notification = m_notifications.value(m, nullptr);
+
+    if (!notification) {
+        // This means that close was called already so there's nothing else to 
do.
+        // Ideally we should not be getting here if close has already been 
called
+        // since stoping a mediaobject means it won't emit finished() *BUT*
+        // since the finished signal is a queued connection in phonon it can 
happen
+        // that the playing had already finished and we just had not got the 
signal yet
+        return;
+    }
+
+    //if the sound is short enough, we can't guarantee new sounds are
+    //enqueued before finished is emitted.
+    //so to make sure we are looping restart it when the sound finished
+    if (notification && (notification->flags() & KNotification::LoopSound)) {
+        m->play();
+        return;
+    }
+
+    finishNotification(notification, m);
+}
+
+void NotifyByAudio::finishNotification(KNotification *notification, 
Phonon::MediaObject *m)
+{
+    m_notifications.remove(m);
+
+    if (notification) {
+        finish(notification);
+    }
+
+    disconnect(m, SIGNAL(currentSourceChanged(Phonon::MediaSource)), this, 
SLOT(onAudioSourceChanged(Phonon::MediaSource)));
+
+    m_reusablePhonons.append(m);
+}
+
+void NotifyByAudio::onAudioSourceChanged(const Phonon::MediaSource &source)
+{
+    Phonon::MediaObject *m = qobject_cast<Phonon::MediaObject*>(sender());
+
+    if (!m) {
+        return;
+    }
+
+    m->enqueue(source);
+}
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/knotifications-5.49.0/src/notifybyaudio_phonon.h 
new/knotifications-5.50.0/src/notifybyaudio_phonon.h
--- old/knotifications-5.49.0/src/notifybyaudio_phonon.h        1970-01-01 
01:00:00.000000000 +0100
+++ new/knotifications-5.50.0/src/notifybyaudio_phonon.h        2018-09-02 
21:28:52.000000000 +0200
@@ -0,0 +1,64 @@
+/* This file is part of the KDE libraries
+   Copyright 2014 by Martin Klapetek <mklape...@kde.org>
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) version 3, or any
+   later version accepted by the membership of KDE e.V. (or its
+   successor approved by the membership of KDE e.V.), which shall
+   act as a proxy defined in Section 6 of version 3 of the license.
+
+   This library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library.  If not, see 
<http://www.gnu.org/licenses/>.
+
+*/
+
+
+#ifndef NOTIFYBYAUDIO_H
+#define NOTIFYBYAUDIO_H
+
+#include "knotificationplugin.h"
+
+#include <phonon/MediaObject>
+
+namespace Phonon {
+// class MediaObject;
+class MediaSource;
+class AudioOutput;
+}
+
+class KNotification;
+
+class NotifyByAudio : public KNotificationPlugin
+{
+    Q_OBJECT
+
+public:
+    explicit NotifyByAudio(QObject *parent = nullptr);
+    ~NotifyByAudio() override;
+
+    QString optionName() override { return QStringLiteral("Sound"); }
+    void notify(KNotification *notification, KNotifyConfig *config) override;
+    void close(KNotification *notification) override;
+
+private Q_SLOTS:
+    void onAudioFinished();
+    void onAudioSourceChanged(const Phonon::MediaSource &source);
+    void stateChanged(Phonon::State newState, Phonon::State oldState);
+
+
+private:
+    void finishNotification(KNotification *notification, Phonon::MediaObject 
*m);
+
+    QList<Phonon::MediaObject*> m_reusablePhonons;
+    QHash<Phonon::MediaObject*, KNotification*> m_notifications;
+    Phonon::AudioOutput *m_audioOutput;
+};
+
+#endif


Reply via email to