1 #define DBUS_SERVICE "org.freedesktop.Notifications"
2 #define DBUS_PATH "/org/freedesktop/Notifications"
3 #define DBUS_OBJECT "org.freedesktop.Notifications"
4 #define DBUS_CLOSED "NotificationClosed"
5 #define DBUS_ACTION "ActionInvoked"
6 #define DBUS_NOTIFY "Notify"
7 #define DBUS_NCLOSE "CloseNotification"
8
9 #include "asemanlinuxnativenotification.h"
10
11 #include <QDBusConnection>
12 #include <QDBusMessage>
13 #include <QDBusArgument>
14 #include <QCoreApplication>
15 #include <QDebug>
16
17 class AsemanLinuxNativeNotificationPrivate
18 {
19 public:
20 QDBusConnection *connection;
21
22 QSet<uint> notifies;
23 };
24
AsemanLinuxNativeNotification(QObject * parent)25 AsemanLinuxNativeNotification::AsemanLinuxNativeNotification(QObject *parent) :
26 QObject(parent)
27 {
28 p = new AsemanLinuxNativeNotificationPrivate;
29
30 p->connection = new QDBusConnection( QDBusConnection::sessionBus() );
31 p->connection->connect( DBUS_SERVICE , DBUS_PATH , DBUS_OBJECT , DBUS_CLOSED , this , SLOT(notificationClosed(QDBusMessage)) );
32 p->connection->connect( DBUS_SERVICE , DBUS_PATH , DBUS_OBJECT , DBUS_ACTION , this , SLOT(actionInvoked(QDBusMessage)) );
33 }
34
sendNotify(const QString & title,const QString & body,const QString & icon,uint replace_id,int timeOut,const QStringList & actions)35 uint AsemanLinuxNativeNotification::sendNotify(const QString &title, const QString &body, const QString &icon, uint replace_id, int timeOut, const QStringList &actions)
36 {
37 QVariantList args;
38 args << QCoreApplication::applicationName();
39 args << replace_id;
40 args << icon;
41 args << title;
42 args << body;
43 args << QVariant::fromValue<QStringList>(actions) ;
44 args << QVariant::fromValue<QVariantMap>(QVariantMap());
45 args << timeOut;
46
47 QDBusMessage omsg = QDBusMessage::createMethodCall( DBUS_SERVICE , DBUS_PATH , DBUS_OBJECT , DBUS_NOTIFY );
48 omsg.setArguments( args );
49
50 const QDBusMessage & imsg = p->connection->call( omsg , QDBus::BlockWithGui );
51 const QVariantList & res = imsg.arguments();
52 if( res.isEmpty() )
53 return 0;
54
55 uint id_res = res.first().toUInt();
56 p->notifies.insert( id_res );
57 return id_res;
58 }
59
closeNotification(uint id)60 void AsemanLinuxNativeNotification::closeNotification(uint id)
61 {
62 if( !p->notifies.contains(id) )
63 return;
64
65 QVariantList args;
66 args << id;
67
68 QDBusMessage omsg = QDBusMessage::createMethodCall( DBUS_SERVICE , DBUS_PATH , DBUS_OBJECT , DBUS_NCLOSE );
69 omsg.setArguments( args );
70
71 p->connection->call( omsg , QDBus::NoBlock );
72 }
73
notificationClosed(const QDBusMessage & dmsg)74 void AsemanLinuxNativeNotification::notificationClosed(const QDBusMessage &dmsg)
75 {
76 if( dmsg.type() != QDBusMessage::SignalMessage )
77 return ;
78
79 const QVariantList & args = dmsg.arguments();
80 if( args.isEmpty() )
81 return ;
82
83 uint id = args.at(0).toUInt();
84 if( !p->notifies.contains(id) )
85 return;
86
87 if( args.count() == 1 )
88 {
89 emit notifyClosed(id);
90 p->notifies.remove(id);
91 return;
92 }
93
94 int type = args.at(1).toInt();
95 switch (type) {
96 case 1:
97 emit notifyTimedOut( id );
98 break;
99
100 case 2:
101 default:
102 emit notifyClosed( id );
103 p->notifies.remove(id);
104 break;
105 }
106 }
107
actionInvoked(const QDBusMessage & dmsg)108 void AsemanLinuxNativeNotification::actionInvoked(const QDBusMessage &dmsg)
109 {
110 if( dmsg.type() != QDBusMessage::SignalMessage )
111 return ;
112
113 const QVariantList & args = dmsg.arguments();
114 if( args.count() != 2 )
115 return ;
116
117 uint id = args.at(0).toUInt();
118 if( !p->notifies.contains(id) )
119 return;
120
121 QString action = args.at(1).toString();
122 emit notifyAction(id, action);
123 }
124
~AsemanLinuxNativeNotification()125 AsemanLinuxNativeNotification::~AsemanLinuxNativeNotification()
126 {
127 delete p;
128 }
129
130