1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
|
/*
SPDX-FileCopyrightText: 2020 Shah Bhushan <bshah@kde.org>
SPDX-FileCopyrightText: 2018-2019 Kai Uwe Broulik <kde@privat.broulik.de>
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#include "notificationsmodel.h"
#include "notification_p.h"
#include "server.h"
#include "debug.h"
#include <QProcess>
#include <KShell>
using namespace NotificationManager;
NotificationsModel::Ptr NotificationsModel::createNotificationsModel()
{
static QWeakPointer<NotificationsModel> s_instance;
if (!s_instance) {
QSharedPointer<NotificationsModel> ptr(new NotificationsModel());
s_instance = ptr.toWeakRef();
return ptr;
}
return s_instance.toStrongRef();
}
NotificationsModel::NotificationsModel()
{
connect(&Server::self(), &Server::notificationAdded, this, [this](const Notification ¬ification) {
onNotificationAdded(notification);
});
connect(&Server::self(), &Server::notificationReplaced, this, [this](uint replacedId, const Notification ¬ification) {
onNotificationReplaced(replacedId, notification);
});
connect(&Server::self(), &Server::notificationRemoved, this, [this](uint removedId, Server::CloseReason reason) {
onNotificationRemoved(removedId, reason);
});
connect(&Server::self(), &Server::serviceOwnershipLost, this, [this] {
// Expire all notifications as we're defunct now
const auto notificationList = notifications();
for (const Notification ¬ification : notificationList) {
if (!notification.expired()) {
onNotificationRemoved(notification.id(), Server::CloseReason::Expired);
}
}
});
Server::self().init();
}
void NotificationsModel::expire(uint notificationId)
{
if (rowOfNotification(notificationId) > -1) {
Server::self().closeNotification(notificationId, Server::CloseReason::Expired);
}
}
void NotificationsModel::close(uint notificationId)
{
if (rowOfNotification(notificationId) > -1) {
Server::self().closeNotification(notificationId, Server::CloseReason::DismissedByUser);
}
}
void NotificationsModel::invokeDefaultAction(uint notificationId, Notifications::InvokeBehavior behavior)
{
const int row = rowOfNotification(notificationId);
if (row == -1) {
return;
}
const Notification ¬ification = notifications().at(row);
if (!notification.hasDefaultAction()) {
qCWarning(NOTIFICATIONMANAGER) << "Trying to invoke default action on notification" << notificationId << "which doesn't have one";
return;
}
Server::self().invokeAction(notificationId,
QStringLiteral("default"), // FIXME make a static Notification::defaultActionName() or something
notification.d->xdgTokenAppId,
behavior,
window());
}
void NotificationsModel::invokeAction(uint notificationId, const QString &actionName, Notifications::InvokeBehavior behavior)
{
const int row = rowOfNotification(notificationId);
if (row == -1) {
return;
}
const Notification ¬ification = notifications().at(row);
if (!notification.actionNames().contains(actionName)) {
qCWarning(NOTIFICATIONMANAGER) << "Trying to invoke action" << actionName << "on notification" << notificationId << "which it doesn't have";
return;
}
Server::self().invokeAction(notificationId, actionName, notification.d->xdgTokenAppId, behavior, window());
}
void NotificationsModel::reply(uint notificationId, const QString &text, Notifications::InvokeBehavior behavior)
{
const int row = rowOfNotification(notificationId);
if (row == -1) {
return;
}
const Notification ¬ification = notifications().at(row);
if (!notification.hasReplyAction()) {
qCWarning(NOTIFICATIONMANAGER) << "Trying to reply to a notification which doesn't have a reply action";
return;
}
Server::self().reply(notification.dBusService(), notificationId, text, behavior);
}
void NotificationsModel::configure(uint notificationId)
{
const int row = rowOfNotification(notificationId);
if (row == -1) {
return;
}
const Notification ¬ification = notifications().at(row);
if (notification.d->hasConfigureAction) {
Server::self().invokeAction(notificationId,
QStringLiteral("settings"),
notification.d->xdgTokenAppId,
Notifications::None, // FIXME make a static Notification::configureActionName() or something
window());
return;
}
if (!notification.desktopEntry().isEmpty() || !notification.notifyRcName().isEmpty()) {
configure(notification.desktopEntry(), notification.notifyRcName(), notification.eventId());
return;
}
qCWarning(NOTIFICATIONMANAGER) << "Trying to configure notification" << notificationId << "which isn't configurable";
}
void NotificationsModel::configure(const QString &desktopEntry, const QString ¬ifyRcName, const QString &eventId)
{
// TODO would be nice to just have a signal but since NotificationsModel is shared,
// if we connect to this from Notifications you would get a signal in every instance
// and potentially open the config dialog multiple times.
QStringList args;
if (!desktopEntry.isEmpty()) {
args.append(QStringLiteral("--desktop-entry"));
args.append(desktopEntry);
}
if (!notifyRcName.isEmpty()) {
args.append(QStringLiteral("--notifyrc"));
args.append(notifyRcName);
}
if (!eventId.isEmpty()) {
args.append(QStringLiteral("--event-id"));
args.append(eventId);
}
QProcess::startDetached(QStringLiteral("kcmshell5"), {QStringLiteral("notifications"), QStringLiteral("--args"), KShell::joinArgs(args)});
}
|