Fix Notifications in Plasmoid

Summary:
Fixed Issues mentioned in https://phabricator.kde.org/T6729
This patch also fixes a crash when the filetransfer of the icon fails

Test Plan:
Receive a notification with a previously unknown icon -> icon in Plasmoid is displayed correctly
Receive a notification with an already existing id -> notification in Plasmoid is updated

Reviewers: #kde_connect, apol

Reviewed By: #kde_connect, apol

Subscribers: albertvaka, broulik, apol, #kde_connect

Tags: #kde_connect

Differential Revision: https://phabricator.kde.org/D7209
This commit is contained in:
Nicolas Fella 2017-11-06 04:12:16 +01:00
parent e2713f20fa
commit fbf8852d6f
6 changed files with 80 additions and 24 deletions

View file

@ -92,6 +92,8 @@ void NotificationsModel::setDeviceId(const QString& deviceId)
this, &NotificationsModel::notificationRemoved);
connect(m_dbusInterface, &OrgKdeKdeconnectDeviceNotificationsInterface::allNotificationsRemoved,
this, &NotificationsModel::clearNotifications);
connect(m_dbusInterface, &OrgKdeKdeconnectDeviceNotificationsInterface::notificationUpdated,
this, &NotificationsModel::notificationUpdated);
refreshNotificationList();
@ -261,3 +263,9 @@ void NotificationsModel::clearNotifications()
endRemoveRows();
}
}
void NotificationsModel::notificationUpdated(const QString& id)
{
//TODO only emit the affected indices
Q_EMIT dataChanged(index(0,0), index(m_notificationList.size() - 1, 0));
}

View file

@ -71,6 +71,7 @@ public Q_SLOTS:
private Q_SLOTS:
void notificationAdded(const QString& id);
void notificationRemoved(const QString& id);
void notificationUpdated(const QString& id);
void refreshNotificationList();
void receivedNotifications(QDBusPendingCallWatcher* watcher);
void clearNotifications();

View file

@ -19,6 +19,7 @@
*/
#include "notification.h"
#include "notification_debug.h"
#include <KNotification>
#include <QIcon>
@ -36,6 +37,7 @@ Notification::Notification(const NetworkPackage& np, QObject* parent)
m_imagesDir = QDir::temp().absoluteFilePath(QStringLiteral("kdeconnect"));
m_imagesDir.mkpath(m_imagesDir.absolutePath());
m_closed = false;
m_ready = false;
parseNetworkPackage(np);
createKNotification(false, np);
@ -55,21 +57,14 @@ void Notification::dismiss()
void Notification::show()
{
m_ready = true;
Q_EMIT ready();
if (!m_silent) {
m_closed = false;
m_notification->sendEvent();
}
}
void Notification::applyIconAndShow()
{
if (!m_silent) {
QPixmap icon(m_iconPath, "PNG");
m_notification->setPixmap(icon);
show();
}
}
void Notification::update(const NetworkPackage& np)
{
parseNetworkPackage(np);
@ -101,26 +96,25 @@ KNotification* Notification::createKNotification(bool update, const NetworkPacka
m_notification->setText(escapedTitle+": "+escapedText);
}
m_hasIcon = m_hasIcon && !m_payloadHash.isEmpty();
if (!m_hasIcon) {
//HACK The only way to display no icon at all is trying to load a non-existant icon
m_notification->setIconName(QString("not_a_real_icon"));
applyNoIcon();
show();
} else {
QString filename = m_payloadHash;
if (filename.isEmpty()) {
m_hasIcon = false;
m_iconPath = m_imagesDir.absoluteFilePath(m_payloadHash);
if (!QFile::exists(m_iconPath)) {
loadIcon(np);
} else {
m_iconPath = m_imagesDir.absoluteFilePath(filename);
QUrl destinationUrl(m_iconPath);
FileTransferJob* job = np.createPayloadTransferJob(destinationUrl);
job->start();
connect(job, &FileTransferJob::result, this, &Notification::applyIconAndShow);
applyIcon();
show();
}
}
if(!m_requestReplyId.isEmpty()) {
m_notification->setActions( QStringList(i18n("Reply")) );
if (!m_requestReplyId.isEmpty()) {
m_notification->setActions(QStringList(i18n("Reply")));
connect(m_notification, &KNotification::action1Activated, this, &Notification::reply);
}
@ -129,6 +123,36 @@ KNotification* Notification::createKNotification(bool update, const NetworkPacka
return m_notification;
}
void Notification::loadIcon(const NetworkPackage& np)
{
m_ready = false;
FileTransferJob* job = np.createPayloadTransferJob(QUrl::fromLocalFile(m_iconPath));
job->start();
connect(job, &FileTransferJob::result, this, [this, job]{
if (job->error()) {
qCDebug(KDECONNECT_PLUGIN_NOTIFICATION) << "Error in FileTransferJob: " << job->errorString();
applyNoIcon();
} else {
applyIcon();
}
show();
});
}
void Notification::applyIcon()
{
QPixmap icon(m_iconPath, "PNG");
m_notification->setPixmap(icon);
}
void Notification::applyNoIcon()
{
//HACK The only way to display no icon at all is trying to load a non-existant icon
m_notification->setIconName(QStringLiteral("not_a_real_icon"));
}
void Notification::reply()
{
Q_EMIT replyRequested();

View file

@ -60,17 +60,18 @@ public:
void show();
bool silent() const { return m_silent; }
void update(const NetworkPackage& np);
bool isReady() const { return m_ready; }
KNotification* createKNotification(bool update, const NetworkPackage& np);
public Q_SLOTS:
Q_SCRIPTABLE void dismiss();
Q_SCRIPTABLE void applyIconAndShow();
Q_SCRIPTABLE void reply();
void closed();
Q_SIGNALS:
void dismissRequested(const QString& m_internalId);
void replyRequested();
void ready();
private:
QString m_internalId;
@ -87,8 +88,12 @@ private:
bool m_silent;
bool m_closed;
QString m_payloadHash;
bool m_ready;
void parseNetworkPackage(const NetworkPackage& np);
void loadIcon(const NetworkPackage& np);
void applyIcon();
void applyNoIcon();
};
#endif

View file

@ -82,11 +82,28 @@ void NotificationsDbusInterface::processPackage(const NetworkPackage& np)
if (!m_internalIdToPublicId.contains(id)) {
Notification* noti = new Notification(np, this);
addNotification(noti);
if (noti->isReady()) {
addNotification(noti);
} else {
connect(noti, &Notification::ready, this, [this, noti]{
addNotification(noti);
});
}
} else {
QString pubId = m_internalIdToPublicId[id];
m_notifications[pubId]->update(np);
Notification* noti = m_notifications[pubId];
noti->update(np);
if (noti->isReady()) {
Q_EMIT notificationUpdated(pubId);
} else {
connect(noti, &Notification::ready, this, [this, pubId]{
Q_EMIT notificationUpdated(pubId);
});
}
}
}
}

View file

@ -55,6 +55,7 @@ public Q_SLOTS:
Q_SIGNALS:
Q_SCRIPTABLE void notificationPosted(const QString& publicId);
Q_SCRIPTABLE void notificationRemoved(const QString& publicId);
Q_SCRIPTABLE void notificationUpdated(const QString& publicId);
Q_SCRIPTABLE void allNotificationsRemoved();
private /*methods*/: