KNotifyConfig

knotifyconfigactionswidget.cpp
1/*
2 This file is part of the KDE libraries
3 SPDX-FileCopyrightText: 2005-2007 Olivier Goffart <ogoffart at kde.org>
4
5 SPDX-License-Identifier: LGPL-2.0-only
6*/
7
8#include "knotifyconfigactionswidget.h"
9
10#include "knotifyconfigelement.h"
11#include <knotifyconfig_debug.h>
12
13#include <QFile>
14#include <QStandardPaths>
15#include <QUrl>
16
17#if HAVE_CANBERRA
18#include <canberra.h>
19#elif HAVE_PHONON
20#include <phonon/mediaobject.h>
21#endif
22
23KNotifyConfigActionsWidget::KNotifyConfigActionsWidget(QWidget *parent)
24 : QWidget(parent)
25{
26 m_ui.setupUi(this);
27
28 // Show sounds directory by default
30 if (!soundDirs.isEmpty()) {
31 m_ui.Sound_select->setStartDir(QUrl::fromLocalFile(soundDirs.last()));
32 }
33 m_ui.Sound_select->setMimeTypeFilters({QStringLiteral("audio/x-vorbis+ogg"), QStringLiteral("audio/x-wav")});
34
35 m_ui.Sound_play->setIcon(QIcon::fromTheme(QStringLiteral("media-playback-start")));
36 m_ui.Sound_check->setIcon(QIcon::fromTheme(QStringLiteral("media-playback-start")));
37 m_ui.Popup_check->setIcon(QIcon::fromTheme(QStringLiteral("dialog-information")));
38
39 connect(m_ui.Sound_check, SIGNAL(toggled(bool)), this, SIGNAL(changed()));
40 connect(m_ui.Popup_check, SIGNAL(toggled(bool)), this, SIGNAL(changed()));
41 connect(m_ui.Sound_select, SIGNAL(textChanged(QString)), this, SIGNAL(changed()));
42 connect(m_ui.Sound_play, SIGNAL(clicked()), this, SLOT(slotPlay()));
43}
44
45KNotifyConfigActionsWidget::~KNotifyConfigActionsWidget()
46{
47#if HAVE_CANBERRA
48 if (m_context) {
49 ca_context_destroy(m_context);
50 }
51 m_context = nullptr;
52#endif
53}
54
55void KNotifyConfigActionsWidget::setConfigElement(KNotifyConfigElement *config)
56{
57 bool blocked = blockSignals(true); // to block the changed() signal
58 QString prstring = config->readEntry(QStringLiteral("Action"));
59 QStringList actions = prstring.split(QLatin1Char('|'));
60
61 m_ui.Sound_check->setChecked(actions.contains(QStringLiteral("Sound")));
62 m_ui.Popup_check->setChecked(actions.contains(QStringLiteral("Popup")));
63
64 m_ui.Sound_select->setUrl(QUrl(config->readEntry(QStringLiteral("Sound"), true)));
65
66 blockSignals(blocked);
67}
68
69void KNotifyConfigActionsWidget::save(KNotifyConfigElement *config)
70{
72 if (m_ui.Sound_check->isChecked()) {
73 actions << QStringLiteral("Sound");
74 }
75 if (m_ui.Popup_check->isChecked()) {
76 actions << QStringLiteral("Popup");
77 }
78
79 config->writeEntry(QStringLiteral("Action"), actions.join(QLatin1Char('|')));
80
81 config->writeEntry(QStringLiteral("Sound"),
82 m_ui.Sound_select->text()); // don't use .url() here, .notifyrc files have predefined "static" entries with no path
83}
84
85void KNotifyConfigActionsWidget::slotPlay()
86{
87 const QString soundFilename = m_ui.Sound_select->text();
88 QUrl soundURL;
90 for (const QString &dataLocation : dataLocations) {
91 soundURL = QUrl::fromUserInput(soundFilename, dataLocation + QStringLiteral("/sounds"), QUrl::AssumeLocalFile);
92 if (soundURL.isLocalFile() && QFile::exists(soundURL.toLocalFile())) {
93 break;
94 } else if (!soundURL.isLocalFile() && soundURL.isValid()) {
95 break;
96 }
97 soundURL.clear();
98 }
99
100#if HAVE_CANBERRA
101 if (!m_context) {
102 int ret = ca_context_create(&m_context);
103 if (ret != CA_SUCCESS) {
104 qCWarning(KNOTIFYCONFIG_LOG) << "Failed to initialize canberra context for audio notification:" << ca_strerror(ret);
105 m_context = nullptr;
106 return;
107 }
108
109 QString desktopFileName = QGuiApplication::desktopFileName();
110 // handle apps which set the desktopFileName property with filename suffix,
111 // due to unclear API dox (https://bugreports.qt.io/browse/QTBUG-75521)
112 if (desktopFileName.endsWith(QLatin1String(".desktop"))) {
113 desktopFileName.chop(8);
114 }
115 ret = ca_context_change_props(m_context,
116 CA_PROP_APPLICATION_NAME,
117 qUtf8Printable(qApp->applicationDisplayName()),
118 CA_PROP_APPLICATION_ID,
119 qUtf8Printable(desktopFileName),
120 CA_PROP_APPLICATION_ICON_NAME,
121 qUtf8Printable(qApp->windowIcon().name()),
122 nullptr);
123 if (ret != CA_SUCCESS) {
124 qCWarning(KNOTIFYCONFIG_LOG) << "Failed to set application properties on canberra context for audio notification:" << ca_strerror(ret);
125 }
126 }
127
128 ca_proplist *props = nullptr;
129 ca_proplist_create(&props);
130
131 // We'll also want this cached for a time. volatile makes sure the cache is
132 // dropped after some time or when the cache is under pressure.
133 ca_proplist_sets(props, CA_PROP_MEDIA_FILENAME, QFile::encodeName(soundURL.toLocalFile()).constData());
134 ca_proplist_sets(props, CA_PROP_CANBERRA_CACHE_CONTROL, "volatile");
135
136 int ret = ca_context_play_full(m_context, 0, props, nullptr, nullptr);
137
138 ca_proplist_destroy(props);
139
140 if (ret != CA_SUCCESS) {
141 qCWarning(KNOTIFYCONFIG_LOG) << "Failed to play sound with canberra:" << ca_strerror(ret);
142 return;
143 }
144#elif HAVE_PHONON
145 Phonon::MediaObject *media = Phonon::createPlayer(Phonon::NotificationCategory, soundURL);
146 media->play();
147 connect(media, SIGNAL(finished()), media, SLOT(deleteLater()));
148#endif
149}
150
151#include "moc_knotifyconfigactionswidget.cpp"
Represent the config for an event.
const char * constData() const const
QByteArray encodeName(const QString &fileName)
bool exists() const const
QIcon fromTheme(const QString &name)
bool contains(const AT &value) const const
bool isEmpty() const const
T & last()
bool blockSignals(bool block)
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
void deleteLater()
QStringList locateAll(StandardLocation type, const QString &fileName, LocateOptions options)
QStringList standardLocations(StandardLocation type)
void chop(qsizetype n)
bool endsWith(QChar c, Qt::CaseSensitivity cs) const const
QStringList split(QChar sep, Qt::SplitBehavior behavior, Qt::CaseSensitivity cs) const const
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
AssumeLocalFile
void clear()
QUrl fromLocalFile(const QString &localFile)
QUrl fromUserInput(const QString &userInput, const QString &workingDirectory, UserInputResolutionOptions options)
bool isLocalFile() const const
bool isValid() const const
QString toLocalFile() const const
QList< QAction * > actions() const const
void setupUi(QWidget *widget)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:19:45 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.