diff --git a/plugins/notifications/CMakeLists.txt b/plugins/notifications/CMakeLists.txt --- a/plugins/notifications/CMakeLists.txt +++ b/plugins/notifications/CMakeLists.txt @@ -4,6 +4,7 @@ notification.cpp notificationsplugin.cpp notificationsdbusinterface.cpp + sendreplydialog.cpp ) kdeconnect_add_plugin(kdeconnect_notifications JSON kdeconnect_notifications.json SOURCES ${kdeconnect_notifications_SRCS}) diff --git a/plugins/notifications/kdeconnect_notifications.json b/plugins/notifications/kdeconnect_notifications.json --- a/plugins/notifications/kdeconnect_notifications.json +++ b/plugins/notifications/kdeconnect_notifications.json @@ -83,7 +83,8 @@ "Website": "http://albertvaka.wordpress.com" }, "X-KdeConnect-OutgoingPackageType": [ - "kdeconnect.notification.request" + "kdeconnect.notification.request", + "kdeconnect.notification.reply" ], "X-KdeConnect-SupportedPackageType": [ "kdeconnect.notification" diff --git a/plugins/notifications/notification.h b/plugins/notifications/notification.h --- a/plugins/notifications/notification.h +++ b/plugins/notifications/notification.h @@ -42,6 +42,7 @@ Q_PROPERTY(bool dismissable READ dismissable) Q_PROPERTY(bool hasIcon READ hasIcon) Q_PROPERTY(bool silent READ silent) + Q_PROPERTY(QString replyId READ replyId) public: Notification(const NetworkPackage& np, QObject* parent); @@ -54,6 +55,7 @@ QString text() const { return mText; } QString iconPath() const { return mIconPath; } bool dismissable() const { return mDismissable; } + QString replyId() const { return mRequestReplyId; } bool hasIcon() const { return mHasIcon; } void show(); bool silent() const { return mSilent; } @@ -67,14 +69,16 @@ Q_SIGNALS: void dismissRequested(const QString& mInternalId); + void replyRequested(); private: QString mInternalId; QString mAppName; QString mTicker; QString mTitle; QString mText; QString mIconPath; + QString mRequestReplyId; bool mDismissable; bool mHasIcon; KNotification* mNotification; diff --git a/plugins/notifications/notification.cpp b/plugins/notifications/notification.cpp --- a/plugins/notifications/notification.cpp +++ b/plugins/notifications/notification.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include @@ -116,6 +117,11 @@ connect(job, &FileTransferJob::result, this, &Notification::applyIconAndShow); } } + + if(!mRequestReplyId.isEmpty()) { + mNotification->setActions( QStringList(i18n("Reply")) ); + connect(mNotification, &KNotification::action1Activated, this, &Notification::replyRequested); + } connect(mNotification, &KNotification::closed, this, &Notification::closed); @@ -138,5 +144,6 @@ mHasIcon = np.hasPayload(); mSilent = np.get(QStringLiteral("silent")); mPayloadHash = np.get(QStringLiteral("payloadHash")); + mRequestReplyId = np.get(QStringLiteral("requestReplyId"), QString()); } diff --git a/plugins/notifications/notificationsdbusinterface.h b/plugins/notifications/notificationsdbusinterface.h --- a/plugins/notifications/notificationsdbusinterface.h +++ b/plugins/notifications/notificationsdbusinterface.h @@ -45,10 +45,12 @@ void processPackage(const NetworkPackage& np); void clearNotifications(); void dismissRequested(const QString& notification); + void replyRequested(Notification* noti); void addNotification(Notification* noti); public Q_SLOTS: Q_SCRIPTABLE QStringList activeNotifications(); + Q_SCRIPTABLE void sendReply(const QString& replyId, const QString& message); Q_SIGNALS: Q_SCRIPTABLE void notificationPosted(const QString& publicId); diff --git a/plugins/notifications/notificationsdbusinterface.cpp b/plugins/notifications/notificationsdbusinterface.cpp --- a/plugins/notifications/notificationsdbusinterface.cpp +++ b/plugins/notifications/notificationsdbusinterface.cpp @@ -23,10 +23,12 @@ #include "notification.h" #include + #include #include #include "notificationsplugin.h" +#include "sendreplydialog.h" NotificationsDbusInterface::NotificationsDbusInterface(KdeConnectPlugin* plugin) : QDBusAbstractAdaptor(const_cast(plugin->device())) @@ -100,6 +102,10 @@ connect(noti, &Notification::dismissRequested, this, &NotificationsDbusInterface::dismissRequested); + + connect(noti, &Notification::replyRequested, this, [this,noti]{ + replyRequested(noti); + }); const QString& publicId = newId(); mNotifications[publicId] = noti; @@ -146,6 +152,24 @@ removeNotification(internalId); } +void NotificationsDbusInterface::replyRequested(Notification* noti) +{ + QString replyId = noti->replyId(); + QString appName = noti->appName(); + QString originalMessage = noti->ticker(); + SendReplyDialog* dialog = new SendReplyDialog(originalMessage, replyId, appName); + connect(dialog, &SendReplyDialog::sendReply, this, &NotificationsDbusInterface::sendReply); + dialog->show(); +} + +void NotificationsDbusInterface::sendReply(const QString& replyId, const QString& message) +{ + NetworkPackage np(PACKAGE_TYPE_NOTIFICATION_REPLY); + np.set(QStringLiteral("requestReplyId"), replyId); + np.set(QStringLiteral("message"), message); + mPlugin->sendPackage(np); +} + QString NotificationsDbusInterface::newId() { return QString::number(++mLastId); diff --git a/plugins/notifications/notificationsplugin.h b/plugins/notifications/notificationsplugin.h --- a/plugins/notifications/notificationsplugin.h +++ b/plugins/notifications/notificationsplugin.h @@ -26,6 +26,7 @@ #include #define PACKAGE_TYPE_NOTIFICATION_REQUEST QStringLiteral("kdeconnect.notification.request") +#define PACKAGE_TYPE_NOTIFICATION_REPLY QStringLiteral("kdeconnect.notification.reply") /* * This class is just a proxy for NotificationsDbusInterface diff --git a/plugins/notifications/sendreplydialog.h b/plugins/notifications/sendreplydialog.h new file mode 100644 --- /dev/null +++ b/plugins/notifications/sendreplydialog.h @@ -0,0 +1,50 @@ +/** + * Copyright 2015 Albert Vaca + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License or (at your option) version 3 or any later version + * accepted by the membership of KDE e.V. (or its successor approved + * by the membership of KDE e.V.), which shall act as a proxy + * defined in Section 14 of version 3 of the license. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef SENDREPLYDIALOG_H +#define SENDREPLYDIALOG_H + +#include +#include + +class QTextEdit; +class QLineEdit; +class QPushButton; + +class SendReplyDialog : public QDialog +{ + Q_OBJECT + +public: + explicit SendReplyDialog(const QString& originalMessage, const QString& replyId, const QString& topicName, QWidget *parent = nullptr); + QSize sizeHint() const override; + +private Q_SLOTS: + void sendButtonClicked(); + +Q_SIGNALS: + void sendReply(const QString& replyId, const QString& messageBody); + +private: + QString mReplyId; + QTextEdit *mTextEdit; +}; + +#endif diff --git a/plugins/notifications/sendreplydialog.cpp b/plugins/notifications/sendreplydialog.cpp new file mode 100644 --- /dev/null +++ b/plugins/notifications/sendreplydialog.cpp @@ -0,0 +1,64 @@ +/** + * Copyright 2015 Albert Vaca + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License or (at your option) version 3 or any later version + * accepted by the membership of KDE e.V. (or its successor approved + * by the membership of KDE e.V.), which shall act as a proxy + * defined in Section 14 of version 3 of the license. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "sendreplydialog.h" + +#include +#include +#include +#include + +#include + +SendReplyDialog::SendReplyDialog(const QString& originalMessage, const QString& replyId, const QString& topicName, QWidget* parent) + : QDialog(parent) + , mReplyId(replyId) +{ + QVBoxLayout* layout = new QVBoxLayout; + + QTextEdit* textView = new QTextEdit(this); + textView->setReadOnly(true); + textView->setText(topicName + ": \n" + originalMessage); + layout->addWidget(textView); + + mTextEdit = new QTextEdit(this); + layout->addWidget(mTextEdit); + + QPushButton* sendButton = new QPushButton(i18n("Send"), this); + connect(sendButton, &QAbstractButton::clicked, this, &SendReplyDialog::sendButtonClicked); + layout->addWidget(sendButton); + + setLayout(layout); + setWindowTitle(topicName); + setWindowIcon(QIcon::fromTheme(QStringLiteral("kdeconnect"))); + setAttribute(Qt::WA_DeleteOnClose); +} + + +void SendReplyDialog::sendButtonClicked() +{ + Q_EMIT sendReply(mReplyId, mTextEdit->toPlainText()); + close(); +} + +QSize SendReplyDialog::sizeHint() const +{ + return QSize(512, 64); +}