From 891f1bd355c8e390c9c55c80511fcc5b8ac7beab Mon Sep 17 00:00:00 2001 From: Nicolas Fella Date: Thu, 13 Apr 2017 21:31:46 +0200 Subject: [PATCH] Notification icons from Android are now displayed - FileTransferJob is now nonblocking. - Files are stored based on the image MD5. - Some improvements in displaying the notification, e.g. title is only displayed when different than the app name. - Most of the notification display code moved to the Notification class. REVIEW: 130050 --- .gitignore | 5 + core/filetransferjob.h | 3 + plugins/notifications/notification.cpp | 106 ++++++++++++++++-- plugins/notifications/notification.h | 28 ++++- .../notificationsdbusinterface.cpp | 42 ++----- .../notificationsdbusinterface.h | 2 - 6 files changed, 144 insertions(+), 42 deletions(-) diff --git a/.gitignore b/.gitignore index d7f2d6068..fc688c254 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,8 @@ src/*_automoc.cpp* src/moc_*.cpp CMakeTmp CMakeFiles +KDEConnect.config +KDEConnect.creator +KDEConnect.files +KDEConnect.includes +.directory diff --git a/core/filetransferjob.h b/core/filetransferjob.h index a94b38c0b..e56abf196 100644 --- a/core/filetransferjob.h +++ b/core/filetransferjob.h @@ -54,6 +54,9 @@ public: QUrl destination() const { return mDestination; } void setOriginName(const QString& from) { mFrom = from; } + Q_SIGNALS: + void emitResult(); + private Q_SLOTS: void doStart(); diff --git a/plugins/notifications/notification.cpp b/plugins/notifications/notification.cpp index 487ca84fc..0e91e10f1 100644 --- a/plugins/notifications/notification.cpp +++ b/plugins/notifications/notification.cpp @@ -20,16 +20,24 @@ #include "notification.h" -#include +#include +#include +#include +#include +#include -Notification::Notification(const NetworkPackage& np, const QString& iconPath, QObject* parent) +#include + + +Notification::Notification(const NetworkPackage& np, QObject* parent) : QObject(parent) { - mInternalId = np.get(QStringLiteral("id")); - mAppName = np.get(QStringLiteral("appName")); - mTicker = np.get(QStringLiteral("ticker")); - mDismissable = np.get(QStringLiteral("isClearable")); - mIconPath = iconPath; + mImagesDir = QDir::temp().absoluteFilePath(QStringLiteral("kdeconnect")); + mImagesDir.mkpath(mImagesDir.absolutePath()); + mClosed = false; + + parseNetworkPackage(np); + createKNotification(false, np); } Notification::~Notification() @@ -44,3 +52,87 @@ void Notification::dismiss() } } +void Notification::show() +{ + if (!mSilent) { + mClosed = false; + mNotification->sendEvent(); + } +} + +void Notification::applyIconAndShow() +{ + if (!mSilent) { + QPixmap icon(mIconPath, "PNG"); + mNotification->setPixmap(icon); + show(); + } +} + +void Notification::update(const NetworkPackage &np) +{ + parseNetworkPackage(np); + createKNotification(!mClosed, np); +} + +KNotification* Notification::createKNotification(bool update, const NetworkPackage &np) +{ + if (!update) { + mNotification = new KNotification(QStringLiteral("notification"), KNotification::CloseOnTimeout, this); + mNotification->setComponentName(QStringLiteral("kdeconnect")); + } + + mNotification->setTitle(mAppName); + + if (mTitle.isEmpty() && mText.isEmpty()) { + mNotification->setText(mTicker); + } else if (mAppName==mTitle) { + mNotification->setText(mText); + } else if (mTitle.isEmpty()){ + mNotification->setText(mText); + } else if (mText.isEmpty()){ + mNotification->setText(mTitle); + } else { + mNotification->setText(mTitle+": "+mText); + } + + if (!mHasIcon) { + mNotification->setIconName(QStringLiteral("preferences-desktop-notification")); + show(); + } else { + QString filename = mPayloadHash; + + if (filename.isEmpty()) { + mHasIcon = false; + } else { + mIconPath = mImagesDir.absoluteFilePath(filename); + QUrl destinationUrl(mIconPath); + FileTransferJob* job = np.createPayloadTransferJob(destinationUrl); + job->start(); + connect(job, &FileTransferJob::emitResult, this, &Notification::applyIconAndShow); + } + } + + connect(mNotification, &KNotification::closed, this, &Notification::closed); + + return mNotification; +} + +void Notification::closed() +{ + mClosed = true; +} + +void Notification::parseNetworkPackage(const NetworkPackage &np) +{ + mInternalId = np.get(QStringLiteral("id")); + mAppName = np.get(QStringLiteral("appName")); + mTicker = np.get(QStringLiteral("ticker")); + mTitle = np.get(QStringLiteral("title")); + mText = np.get(QStringLiteral("text")); + mDismissable = np.get(QStringLiteral("isClearable")); + mHasIcon = np.hasPayload(); + mSilent = np.get(QStringLiteral("silent")); + mPayloadHash = np.get(QStringLiteral("payloadHash")); +} + diff --git a/plugins/notifications/notification.h b/plugins/notifications/notification.h index 39a73ea43..12ebf2682 100644 --- a/plugins/notifications/notification.h +++ b/plugins/notifications/notification.h @@ -23,6 +23,8 @@ #include #include +#include +#include #include @@ -34,32 +36,54 @@ class Notification Q_PROPERTY(QString internalId READ internalId) Q_PROPERTY(QString appName READ appName) Q_PROPERTY(QString ticker READ ticker) + Q_PROPERTY(QString title READ title) + Q_PROPERTY(QString text READ text) Q_PROPERTY(QString iconPath READ iconPath) Q_PROPERTY(bool dismissable READ dismissable) + Q_PROPERTY(bool hasIcon READ hasIcon) + Q_PROPERTY(bool silent READ silent) public: - Notification(const NetworkPackage& np, const QString& iconPath, QObject* parent); + Notification(const NetworkPackage& np, QObject* parent); ~Notification() override; QString internalId() const { return mInternalId; } QString appName() const { return mAppName; } QString ticker() const { return mTicker; } + QString title() const { return mTitle; } + QString text() const { return mText; } QString iconPath() const { return mIconPath; } bool dismissable() const { return mDismissable; } + bool hasIcon() const { return mHasIcon; } + void show(); + bool silent() const { return mSilent; } + void update(const NetworkPackage &np); + KNotification* createKNotification(bool update, const NetworkPackage &np); public Q_SLOTS: Q_SCRIPTABLE void dismiss(); + Q_SCRIPTABLE void applyIconAndShow(); + void closed(); -Q_SIGNALS: + Q_SIGNALS: void dismissRequested(const QString& mInternalId); private: QString mInternalId; QString mAppName; QString mTicker; + QString mTitle; + QString mText; QString mIconPath; bool mDismissable; + bool mHasIcon; + KNotification* mNotification; + QDir mImagesDir; + bool mSilent; + bool mClosed; + QString mPayloadHash; + void parseNetworkPackage(const NetworkPackage& np); }; #endif diff --git a/plugins/notifications/notificationsdbusinterface.cpp b/plugins/notifications/notificationsdbusinterface.cpp index dbd63099f..69b08ac2d 100644 --- a/plugins/notifications/notificationsdbusinterface.cpp +++ b/plugins/notifications/notificationsdbusinterface.cpp @@ -20,16 +20,11 @@ #include "notificationsdbusinterface.h" #include "notification_debug.h" +#include "notification.h" #include - -#include -#include -#include - #include #include -#include #include "notificationsplugin.h" @@ -38,9 +33,8 @@ NotificationsDbusInterface::NotificationsDbusInterface(KdeConnectPlugin* plugin) , mDevice(plugin->device()) , mPlugin(plugin) , mLastId(0) - , imagesDir(QDir::temp().absoluteFilePath(QStringLiteral("kdeconnect"))) { - imagesDir.mkpath(imagesDir.absolutePath()); + } NotificationsDbusInterface::~NotificationsDbusInterface() @@ -79,32 +73,18 @@ void NotificationsDbusInterface::processPackage(const NetworkPackage& np) }); mPlugin->sendPackage(np); } + } else if(np.get(QStringLiteral("requestAnswer"), false)) { + } else { + QString id = np.get(QStringLiteral("id")); - //TODO: Uncoment when we are able to display app icon on plasmoid - QString destination; - /* - if (np.hasPayload()) { - QString filename = KMD5(np.get("appName").toLatin1()).hexDigest(); //TODO: Store with extension? - destination = imagesDir.absoluteFilePath(filename); - FileTransferJob* job = np.createPayloadTransferJob(destination); - job->start(); + if (!mInternalIdToPublicId.contains(id)) { + Notification* noti = new Notification(np, this); + addNotification(noti); + } else { + QString pubId = mInternalIdToPublicId[id]; + mNotifications[pubId]->update(np); } - */ - - Notification* noti = new Notification(np, destination, this); - - //Do not show updates to existent notification nor answers to a initialization request - if (!mInternalIdToPublicId.contains(noti->internalId()) && !np.get(QStringLiteral("requestAnswer"), false) && !np.get(QStringLiteral("silent"), false)) { - KNotification* notification = new KNotification(QStringLiteral("notification"), KNotification::CloseOnTimeout, this); - notification->setIconName(QStringLiteral("preferences-desktop-notification")); - notification->setComponentName(QStringLiteral("kdeconnect")); - notification->setTitle(mDevice->name()); - notification->setText(noti->appName() + ": " + noti->ticker()); - notification->sendEvent(); - } - - addNotification(noti); } } diff --git a/plugins/notifications/notificationsdbusinterface.h b/plugins/notifications/notificationsdbusinterface.h index b8120f661..1c92ba17b 100644 --- a/plugins/notifications/notificationsdbusinterface.h +++ b/plugins/notifications/notificationsdbusinterface.h @@ -65,8 +65,6 @@ private /*attributes*/: QHash mNotifications; QHash mInternalIdToPublicId; int mLastId; - QDir imagesDir; - }; #endif