1 /*
2 SPDX-FileCopyrightText: 2020 Shah Bhushan <bshah@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
5 */
6
7 #include "watchednotificationsmodel.h"
8
9 #include <QDBusConnection>
10 #include <QDBusConnectionInterface>
11 #include <QDBusMetaType>
12 #include <QDBusServiceWatcher>
13
14 #include <QDebug>
15
16 #include "fdonotifications_interface.h"
17
18 using namespace NotificationManager;
19
20 class WatchedNotificationsModel::Private : public QObject
21 {
22 Q_OBJECT
23 public:
24 explicit Private(WatchedNotificationsModel *q, QObject *parent = nullptr);
25 ~Private();
26 bool valid = false;
27
28 public Q_SLOTS:
29 Q_SCRIPTABLE void Notify(uint id,
30 const QString &app_name,
31 uint replaces_id,
32 const QString &app_icon,
33 const QString &summary,
34 const QString &body,
35 const QStringList &actions,
36 const QVariantMap &hints,
37 int timeout);
38 Q_SCRIPTABLE void CloseNotification(uint id);
39 void NotificationClosed(uint id, uint reason);
40
41 private:
42 WatchedNotificationsModel *q;
43 OrgFreedesktopNotificationsInterface *fdoNotificationsInterface;
44 };
45
Private(WatchedNotificationsModel * q,QObject * parent)46 WatchedNotificationsModel::Private::Private(WatchedNotificationsModel *q, QObject *parent)
47 : QObject(parent)
48 , q(q)
49 {
50 QDBusConnection dbus = QDBusConnection::sessionBus();
51 fdoNotificationsInterface =
52 new OrgFreedesktopNotificationsInterface(QStringLiteral("org.freedesktop.Notifications"), QStringLiteral("/org/freedesktop/Notifications"), dbus, this);
53 connect(fdoNotificationsInterface,
54 &OrgFreedesktopNotificationsInterface::NotificationClosed,
55 this,
56 &WatchedNotificationsModel::Private::NotificationClosed);
57 dbus.registerObject("/NotificationWatcher", QStringLiteral("org.kde.NotificationWatcher"), this, QDBusConnection::ExportScriptableSlots);
58 QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.freedesktop.Notifications"),
59 QStringLiteral("/org/freedesktop/Notifications"),
60 QStringLiteral("org.kde.NotificationManager"),
61 QStringLiteral("RegisterWatcher"));
62 QDBusMessage reply = QDBusConnection::sessionBus().call(msg, QDBus::NoBlock);
63 if (reply.type() != QDBusMessage::ErrorMessage) {
64 valid = true;
65 Q_EMIT q->validChanged(valid);
66 }
67 }
68
~Private()69 WatchedNotificationsModel::Private::~Private()
70 {
71 QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.freedesktop.Notifications"),
72 QStringLiteral("/org/freedesktop/Notifications"),
73 QStringLiteral("org.kde.NotificationManager"),
74 QStringLiteral("UnRegisterWatcher"));
75 QDBusConnection::sessionBus().call(msg, QDBus::NoBlock);
76 }
77
Notify(uint id,const QString & app_name,uint replaces_id,const QString & app_icon,const QString & summary,const QString & body,const QStringList & actions,const QVariantMap & hints,int timeout)78 void WatchedNotificationsModel::Private::Notify(uint id,
79 const QString &app_name,
80 uint replaces_id,
81 const QString &app_icon,
82 const QString &summary,
83 const QString &body,
84 const QStringList &actions,
85 const QVariantMap &hints,
86 int timeout)
87 {
88 const bool wasReplaced = replaces_id > 0;
89
90 Notification notification(id);
91 notification.setSummary(summary);
92 notification.setBody(body);
93 notification.setApplicationName(app_name);
94
95 notification.setActions(actions);
96 notification.setTimeout(timeout);
97 notification.setHints(hints);
98 notification.setIcon(app_icon);
99 notification.processHints(hints);
100
101 if (wasReplaced) {
102 q->onNotificationReplaced(replaces_id, notification);
103 } else {
104 q->onNotificationAdded(notification);
105 }
106 }
107
CloseNotification(uint id)108 void WatchedNotificationsModel::Private::CloseNotification(uint id)
109 {
110 q->onNotificationRemoved(id, Server::CloseReason::Expired);
111 }
112
NotificationClosed(uint id,uint reason)113 void WatchedNotificationsModel::Private::NotificationClosed(uint id, uint reason)
114 {
115 q->onNotificationRemoved(id, static_cast<Server::CloseReason>(reason));
116 }
117
WatchedNotificationsModel()118 WatchedNotificationsModel::WatchedNotificationsModel()
119 : AbstractNotificationsModel()
120 , d(new Private(this, nullptr))
121 {
122 }
123
~WatchedNotificationsModel()124 WatchedNotificationsModel::~WatchedNotificationsModel()
125 {
126 }
127
close(uint notificationId)128 void WatchedNotificationsModel::close(uint notificationId)
129 {
130 onNotificationRemoved(notificationId, Server::CloseReason::DismissedByUser);
131 }
132
expire(uint notificationId)133 void WatchedNotificationsModel::expire(uint notificationId)
134 {
135 onNotificationRemoved(notificationId, Server::CloseReason::Expired);
136 }
137
invokeDefaultAction(uint notificationId)138 void WatchedNotificationsModel::invokeDefaultAction(uint notificationId)
139 {
140 this->invokeAction(notificationId, QStringLiteral("default"));
141 }
142
invokeAction(uint notificationId,const QString & actionName)143 void WatchedNotificationsModel::invokeAction(uint notificationId, const QString &actionName)
144 {
145 QDBusConnection dbus = QDBusConnection::sessionBus();
146 dbus.registerObject("/NotificationWatcher", this, QDBusConnection::ExportScriptableSlots);
147 QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.freedesktop.Notifications"),
148 QStringLiteral("/org/freedesktop/Notifications"),
149 QStringLiteral("org.kde.NotificationManager"),
150 QStringLiteral("InvokeAction"));
151 msg.setArguments({notificationId, actionName});
152 QDBusConnection::sessionBus().call(msg, QDBus::NoBlock);
153 }
154
reply(uint notificationId,const QString & text)155 void WatchedNotificationsModel::reply(uint notificationId, const QString &text)
156 {
157 // todo
158 Q_UNUSED(notificationId)
159 Q_UNUSED(text)
160 }
161
valid()162 bool WatchedNotificationsModel::valid()
163 {
164 return d->valid;
165 }
166
167 #include "watchednotificationsmodel.moc"
168