From 5f0258acc1c18db4f1bc40e40cdb01a9f0e16ab2 Mon Sep 17 00:00:00 2001 From: Javier Date: Fri, 8 Jan 2016 01:39:22 +0100 Subject: replace sender with appId and appName --- notification.cpp | 30 ++++++++++++++++++++++------- notification.h | 16 +++++++++++----- notificationmonitor.cpp | 50 +++++++++++++++++++++++++++++++++++++++++++------ notificationmonitor_p.h | 17 ++++++++++++++++- 4 files changed, 94 insertions(+), 19 deletions(-) diff --git a/notification.cpp b/notification.cpp index ba8456e..e57006a 100644 --- a/notification.cpp +++ b/notification.cpp @@ -39,7 +39,8 @@ struct Action struct NotificationPrivate { uint id; - QString sender; + QString appId; + QString appName; QString summary; QString body; QDateTime timestamp; @@ -67,18 +68,33 @@ uint Notification::id() const return d->id; } -QString Notification::sender() const +QString Notification::appId() const { Q_D(const Notification); - return d->sender; + return d->appId; } -void Notification::setSender(const QString &sender) +void Notification::setAppId(const QString &appId) { Q_D(Notification); - if (sender != d->sender) { - d->sender = sender; - emit senderChanged(); + if (appId != d->appId) { + d->appId = appId; + emit appIdChanged(); + } +} + +QString Notification::appName() const +{ + Q_D(const Notification); + return d->appName; +} + +void Notification::setAppName(const QString &appName) +{ + Q_D(Notification); + if (appName != d->appName) { + d->appName = appName; + emit appNameChanged(); } } diff --git a/notification.h b/notification.h index dc58c78..2eb00f1 100644 --- a/notification.h +++ b/notification.h @@ -35,8 +35,10 @@ class Notification : public QObject /** Notification ID */ Q_PROPERTY(uint id READ id CONSTANT) - /** Name of sender program */ - Q_PROPERTY(QString sender READ sender WRITE setSender NOTIFY senderChanged) + /** Binary/harbour name of sending program */ + Q_PROPERTY(QString appId READ appId WRITE setAppId NOTIFY appIdChanged) + /** Human readable name of sender program */ + Q_PROPERTY(QString appName READ appName WRITE setAppName NOTIFY appNameChanged) Q_PROPERTY(QString summary READ summary WRITE setSummary NOTIFY summaryChanged) Q_PROPERTY(QString body READ body WRITE setBody NOTIFY bodyChanged) Q_PROPERTY(QDateTime timestamp READ timestamp WRITE setTimestamp NOTIFY timestampChanged) @@ -66,8 +68,11 @@ public: uint id() const; - QString sender() const; - void setSender(const QString &sender); + QString appId() const; + void setAppId(const QString &appId); + + QString appName() const; + void setAppName(const QString &appName); QString summary() const; void setSummary(const QString &summary); @@ -101,7 +106,8 @@ public slots: void close(); signals: - void senderChanged(); + void appIdChanged(); + void appNameChanged(); void summaryChanged(); void bodyChanged(); void timestampChanged(); diff --git a/notificationmonitor.cpp b/notificationmonitor.cpp index 796c5e0..5e159ec 100644 --- a/notificationmonitor.cpp +++ b/notificationmonitor.cpp @@ -34,8 +34,9 @@ QDebug operator<<(QDebug &debug, const ProtoNotification &proto) { QDebugStateSaver saver(debug); Q_UNUSED(saver); - debug.nospace() << "Notification(sender=" << proto.sender << ", summary=" << proto.summary - << ", body=" << proto.body << ", appIcon=" << proto.appIcon + debug.nospace() << "Notification(appId=" << proto.appId << ", appName=" << proto.appName + << ", summary=" << proto.summary << ", body=" << proto.body + << ", appIcon=" << proto.appIcon << ", hints=" << proto.hints << ", timeout=" << proto.expireTimeout << ", actions=" << proto.actions << ")"; return debug; @@ -100,7 +101,7 @@ void NotificationMonitorPrivate::processIncomingNotification(quint32 id, const P n = new Notification(id, q); } - n->setSender(proto.sender); + n->setAppId(proto.appId); n->setSummary(proto.summary); n->setBody(proto.body); n->setIcon(proto.appIcon); @@ -201,7 +202,7 @@ ProtoNotification NotificationMonitorPrivate::parseNotifyCall(DBusMessage *msg) dbus_message_iter_next(&iter); // Add basic notification information - proto.sender = QString::fromUtf8(app_name); + proto.appName = QString::fromUtf8(app_name); proto.appIcon = QString::fromUtf8(app_icon); proto.summary = QString::fromUtf8(summary); proto.body = QString::fromUtf8(body); @@ -241,6 +242,19 @@ ProtoNotification NotificationMonitorPrivate::parseNotifyCall(DBusMessage *msg) dbus_message_iter_get_basic(&iter, &expire_timeout); proto.expireTimeout = expire_timeout; + if (hints.contains("x-nemo-owner")) { + proto.appId = hints["x-nemo-owner"]; + if (proto.appName.isEmpty()) { + // Lookup application name via .desktop file + proto.appName = getAppName(proto.appId); + // Otherwise just use the appId + if (proto.appName.isEmpty()) { + proto.appName = proto.appId; + } + } + } + + // Lookup category info and merge it with the notification info if found. if (hints.contains("category")) { proto.hints = getCategoryInfo(hints["category"]); proto.hints.unite(hints); @@ -280,6 +294,32 @@ QHash NotificationMonitorPrivate::getCategoryInfo(const QString } } +QString NotificationMonitorPrivate::getAppName(const QString &id) const +{ + bool in_cache = _appNameCache.contains(id); + bool needs_check = !in_cache || + _appNameCache[id].lastCheckTime.secsTo(QDateTime::currentDateTime()) > DESKTOP_REFRESH_CHECK_TIME; + if (needs_check) { + AppNameCacheEntry &entry = _appNameCache[id]; + QFileInfo finfo(QString("%1/%2.desktop").arg(DESKTOP_FILE_DIRECTORY, id)); + if (finfo.exists()) { + if (!in_cache || finfo.lastModified() > entry.lastReadTime) { + QSettings settings(finfo.absoluteFilePath(), QSettings::IniFormat); + settings.beginGroup("Desktop Entry"); + entry.name = settings.value("Name").toString(); // TODO Localization + entry.lastReadTime = finfo.lastModified(); + } + } else { + qCWarning(notificationMonitorCat) << "Desktop file for" << id << "does not exist"; + // Cache negative results, since they might be common... + } + entry.lastCheckTime = QDateTime::currentDateTime(); + return entry.name; + } else { + return _appNameCache[id].name; + } +} + dbus_bool_t NotificationMonitorPrivate::busWatchAdd(DBusWatch *watch, void *data) { NotificationMonitorPrivate *self = static_cast(data); @@ -393,5 +433,3 @@ NotificationMonitor::~NotificationMonitor() } } - -#include "moc_notificationmonitor.cpp" diff --git a/notificationmonitor_p.h b/notificationmonitor_p.h index 069abc4..2f57697 100644 --- a/notificationmonitor_p.h +++ b/notificationmonitor_p.h @@ -9,6 +9,9 @@ #define CATEGORY_DEFINITION_FILE_DIRECTORY "/usr/share/lipstick/notificationcategories" #define CATEGORY_REFRESH_CHECK_TIME 120 +#define DESKTOP_FILE_DIRECTORY "/usr/share/applications" +#define DESKTOP_REFRESH_CHECK_TIME 120 + namespace watchfish { @@ -19,9 +22,17 @@ struct NotificationCategoryCacheEntry QDateTime lastCheckTime; }; +struct AppNameCacheEntry +{ + QString name; + QDateTime lastReadTime; + QDateTime lastCheckTime; +}; + struct ProtoNotification { - QString sender; + QString appId; + QString appName; QString appIcon; QString summary; QString body; @@ -55,6 +66,8 @@ private: QHash getCategoryInfo(const QString &s) const; + QString getAppName(const QString &id) const; + static dbus_bool_t busWatchAdd(DBusWatch *watch, void *data); static void busWatchRemove(DBusWatch *watch, void *data); static void busWatchToggle(DBusWatch *watch, void *data); @@ -76,6 +89,8 @@ private: QHash _pendingConfirmation; /** Cache of notification category info. */ mutable QHash _categoryCache; + /** Cache of application names. */ + mutable QHash _appNameCache; }; -- cgit v1.2.3