[SCM] kdeconnect packaging branch, master, updated. debian/0.9g-1-1183-g9d69498
Maximiliano Curia
maxy at moszumanska.debian.org
Fri Oct 14 14:29:25 UTC 2016
Gitweb-URL: http://git.debian.org/?p=pkg-kde/kde-extras/kdeconnect.git;a=commitdiff;h=f072a0c
The following commit has been merged in the master branch:
commit f072a0c615115ecce0c0ab9ec8a83ae7ab0b7622
Author: Holger Kaelberer <holger.k at elberer.de>
Date: Sat Dec 5 23:11:57 2015 +0100
notifications: allow to configure how to sync desktop notifications
Added kcm ui with global and app-specific config options.
Global options affect all notifications:
- Persistent only? --> Sync only notifications with timeout == 0?
- Include body? --> Add body string to summary when syncing?
- Minimum urgency
Per-application options affect notifications sent by a specific
application:
- Sync it at all?
- If yes, allow to define a "blacklist" pattern (QRegularExpression)
to define which notifications should *not* be synced.
Applications are maintained in the per-device config and added when
seen the first time by the notification listener. From that moment on
they can be configured in the kcm ui.
---
core/kdeconnectpluginconfig.cpp | 30 +++
core/kdeconnectpluginconfig.h | 8 +
plugins/notifications/CMakeLists.txt | 25 ++-
.../kdeconnect_notifications_config.desktop | 10 +
plugins/notifications/notifications_config.cpp | 113 ++++++++++
.../notifications_config.h} | 22 +-
plugins/notifications/notifications_config.ui | 210 ++++++++++++++++++
plugins/notifications/notificationslistener.cpp | 69 +++++-
plugins/notifications/notificationslistener.h | 6 +
...icationslistener.h => notifyingapplication.cpp} | 46 ++--
.../{notification.cpp => notifyingapplication.h} | 40 ++--
.../notifications/notifyingapplicationmodel.cpp | 235 +++++++++++++++++++++
plugins/notifications/notifyingapplicationmodel.h | 56 +++++
13 files changed, 814 insertions(+), 56 deletions(-)
diff --git a/core/kdeconnectpluginconfig.cpp b/core/kdeconnectpluginconfig.cpp
index 980235c..7c11e3c 100644
--- a/core/kdeconnectpluginconfig.cpp
+++ b/core/kdeconnectpluginconfig.cpp
@@ -62,6 +62,24 @@ QVariant KdeConnectPluginConfig::get(const QString& key, const QVariant& default
return d->mConfig->value(key, defaultValue);
}
+QVariantList KdeConnectPluginConfig::getList(const QString& key,
+ const QVariantList& defaultValue)
+{
+ QVariantList list;
+ d->mConfig->sync(); // note: need sync() to get recent changes signalled from other process
+ int size = d->mConfig->beginReadArray(key);
+ if (size < 1) {
+ d->mConfig->endArray();
+ return defaultValue;
+ }
+ for (int i = 0; i < size; ++i) {
+ d->mConfig->setArrayIndex(i);
+ list << d->mConfig->value("value");
+ }
+ d->mConfig->endArray();
+ return list;
+}
+
void KdeConnectPluginConfig::set(const QString& key, const QVariant& value)
{
d->mConfig->setValue(key, value);
@@ -69,6 +87,18 @@ void KdeConnectPluginConfig::set(const QString& key, const QVariant& value)
QDBusConnection::sessionBus().send(d->signal);
}
+void KdeConnectPluginConfig::setList(const QString& key, const QVariantList& list)
+{
+ d->mConfig->beginWriteArray(key);
+ for (int i = 0; i < list.size(); ++i) {
+ d->mConfig->setArrayIndex(i);
+ d->mConfig->setValue("value", list.at(i));
+ }
+ d->mConfig->endArray();
+ d->mConfig->sync();
+ QDBusConnection::sessionBus().send(d->signal);
+}
+
void KdeConnectPluginConfig::slotConfigChanged()
{
Q_EMIT configChanged();
diff --git a/core/kdeconnectpluginconfig.h b/core/kdeconnectpluginconfig.h
index 09bf68e..a3fcf18 100644
--- a/core/kdeconnectpluginconfig.h
+++ b/core/kdeconnectpluginconfig.h
@@ -51,6 +51,12 @@ public:
void set(const QString& key, const QVariant& value);
/**
+ * Store a list of values in this config object under the array name
+ * specified in key.
+ */
+ void setList(const QString& key, const QVariantList& list);
+
+ /**
* Read a key-value pair from this config object
*/
QVariant get(const QString& key, const QVariant& defaultValue);
@@ -62,6 +68,8 @@ public:
return get(key, QVariant(defaultValue)).template value<T>(); //Important note: Awesome template syntax is awesome
}
+ QVariantList getList(const QString& key, const QVariantList& defaultValue = {});
+
private Q_SLOTS:
void slotConfigChanged();
diff --git a/plugins/notifications/CMakeLists.txt b/plugins/notifications/CMakeLists.txt
index fbb459e..448be94 100644
--- a/plugins/notifications/CMakeLists.txt
+++ b/plugins/notifications/CMakeLists.txt
@@ -1,10 +1,11 @@
-find_package(KF5 REQUIRED COMPONENTS Notifications)
+find_package(KF5 REQUIRED COMPONENTS Notifications KCMUtils I18n)
set(kdeconnect_notifications_SRCS
notification.cpp
notificationsplugin.cpp
notificationsdbusinterface.cpp
notificationslistener.cpp
+ notifyingapplication.cpp
)
kdeconnect_add_plugin(kdeconnect_notifications JSON kdeconnect_notifications.json SOURCES ${kdeconnect_notifications_SRCS})
@@ -13,4 +14,26 @@ target_link_libraries(kdeconnect_notifications
kdeconnectcore
Qt5::DBus
KF5::Notifications
+ KF5::I18n
)
+
+#######################################
+# Config
+
+set( kdeconnect_notifications_config_SRCS
+ notifications_config.cpp
+ notifyingapplication.cpp
+ notifyingapplicationmodel.cpp
+)
+ki18n_wrap_ui( kdeconnect_notifications_config_SRCS notifications_config.ui )
+
+add_library(kdeconnect_notifications_config MODULE ${kdeconnect_notifications_config_SRCS} )
+target_link_libraries( kdeconnect_notifications_config
+ kdeconnectcore
+ kdeconnectpluginkcm
+ KF5::I18n
+ KF5::KCMUtils
+)
+
+install( TARGETS kdeconnect_notifications_config DESTINATION ${PLUGIN_INSTALL_DIR} )
+install( FILES kdeconnect_notifications_config.desktop DESTINATION ${SERVICES_INSTALL_DIR} )
diff --git a/plugins/notifications/kdeconnect_notifications_config.desktop b/plugins/notifications/kdeconnect_notifications_config.desktop
new file mode 100644
index 0000000..6535bc7
--- /dev/null
+++ b/plugins/notifications/kdeconnect_notifications_config.desktop
@@ -0,0 +1,10 @@
+[Desktop Entry]
+Type=Service
+X-KDE-ServiceTypes=KCModule
+
+X-KDE-Library=kdeconnect_notifications_config
+X-KDE-ParentComponents=kdeconnect_notifications
+
+Name=Notification synchronization plugin settings
+
+Categories=Qt;KDE;X-KDE-settings-kdeconnect;
diff --git a/plugins/notifications/notifications_config.cpp b/plugins/notifications/notifications_config.cpp
new file mode 100644
index 0000000..5086d9f
--- /dev/null
+++ b/plugins/notifications/notifications_config.cpp
@@ -0,0 +1,113 @@
+/**
+ * Copyright 2015 Holger Kaelberer <holger.k at elberer.de>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include "notifications_config.h"
+#include "ui_notifications_config.h"
+#include "notifyingapplicationmodel.h"
+
+#include <KCModule>
+#include <KPluginFactory>
+
+K_PLUGIN_FACTORY(NotificationsConfigFactory, registerPlugin<NotificationsConfig>();)
+
+NotificationsConfig::NotificationsConfig(QWidget *parent, const QVariantList& args)
+ : KdeConnectPluginKcm(parent, args, "kdeconnect_notifications_config")
+ , m_ui(new Ui::NotificationsConfigUi())
+ , appModel(new NotifyingApplicationModel)
+{
+ qRegisterMetaTypeStreamOperators<NotifyingApplication>("NotifyingApplication");
+
+ m_ui->setupUi(this);
+ m_ui->appList->setIconSize(QSize(32,32));
+
+ m_ui->appList->setModel(appModel);
+
+ m_ui->appList->horizontalHeader()->setSectionResizeMode(0, QHeaderView::QHeaderView::Fixed);
+ m_ui->appList->horizontalHeader()->setSectionResizeMode(1, QHeaderView::QHeaderView::Stretch);
+ m_ui->appList->horizontalHeader()->setSectionResizeMode(2, QHeaderView::QHeaderView::Stretch);
+ for (int i = 0; i < 3; i++)
+ m_ui->appList->resizeColumnToContents(i);
+
+ connect(m_ui->appList->horizontalHeader(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)),
+ m_ui->appList, SLOT(sortByColumn(int)));
+
+ connect(m_ui->check_persistent, SIGNAL(toggled(bool)), this, SLOT(changed()));
+ connect(m_ui->spin_urgency, SIGNAL(editingFinished()), this, SLOT(changed()));
+ connect(m_ui->check_body, SIGNAL(toggled(bool)), this, SLOT(changed()));
+
+ connect(appModel, SIGNAL(applicationsChanged()), this, SLOT(changed()));
+
+ connect(config(), SIGNAL(configChanged()), this, SLOT(loadApplications()));
+}
+
+NotificationsConfig::~NotificationsConfig()
+{
+ delete m_ui;
+}
+
+void NotificationsConfig::defaults()
+{
+ KCModule::defaults();
+ m_ui->check_persistent->setChecked(false);
+ m_ui->spin_urgency->setValue(0);
+ Q_EMIT changed(true);
+}
+
+void NotificationsConfig::loadApplications()
+{
+ appModel->clearApplications();
+ QVariantList list = config()->getList("applications");
+ for (const auto& a: list) {
+ NotifyingApplication app = a.value<NotifyingApplication>();
+ if (!appModel->containsApp(app.name)) {
+ appModel->appendApp(app);
+ }
+ }
+}
+
+void NotificationsConfig::load()
+{
+ KCModule::load();
+ bool persistent = config()->get("generalPersistent", false);
+ m_ui->check_persistent->setChecked(persistent);
+ bool body = config()->get("generalIncludeBody", true);
+ m_ui->check_body->setChecked(body);
+ int urgency = config()->get("generalUrgency", 0);
+ m_ui->spin_urgency->setValue(urgency);
+
+ loadApplications();
+ Q_EMIT changed(false);
+}
+
+void NotificationsConfig::save()
+{
+ config()->set("generalPersistent", m_ui->check_persistent->isChecked());
+ config()->set("generalIncludeBody", m_ui->check_body->isChecked());
+ config()->set("generalUrgency", m_ui->spin_urgency->value());
+
+ QVariantList list;
+ for (const auto& a: appModel->apps())
+ list << QVariant::fromValue<NotifyingApplication>(a);
+ config()->setList("applications", list);
+ KCModule::save();
+ Q_EMIT changed(false);
+}
+
+#include "notifications_config.moc"
diff --git a/plugins/pausemusic/pausemusic_config.h b/plugins/notifications/notifications_config.h
similarity index 71%
copy from plugins/pausemusic/pausemusic_config.h
copy to plugins/notifications/notifications_config.h
index 002e39e..fedbfc6 100644
--- a/plugins/pausemusic/pausemusic_config.h
+++ b/plugins/notifications/notifications_config.h
@@ -1,5 +1,5 @@
/**
- * Copyright 2013 Albert Vaca <albertvaka at gmail.com>
+ * Copyright 2015 Holger Kaelberer <holger.k at elberer.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -18,30 +18,36 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef PAUSEMUSIC_CONFIG_H
-#define PAUSEMUSIC_CONFIG_H
+#ifndef NOTIFICATIONS_CONFIG_H
+#define NOTIFICATIONS_CONFIG_H
#include "kcmplugin/kdeconnectpluginkcm.h"
namespace Ui {
- class PauseMusicConfigUi;
+ class NotificationsConfigUi;
}
-class PauseMusicConfig
+class NotifyingApplicationModel;
+
+class NotificationsConfig
: public KdeConnectPluginKcm
{
Q_OBJECT
public:
- PauseMusicConfig(QWidget *parent, const QVariantList&);
- virtual ~PauseMusicConfig();
+ NotificationsConfig(QWidget *parent, const QVariantList&);
+ virtual ~NotificationsConfig();
public Q_SLOTS:
virtual void save() override;
virtual void load() override;
virtual void defaults() override;
+private Q_SLOTS:
+ void loadApplications();
+
private:
- Ui::PauseMusicConfigUi* m_ui;
+ Ui::NotificationsConfigUi* m_ui;
+ NotifyingApplicationModel* appModel;
};
diff --git a/plugins/notifications/notifications_config.ui b/plugins/notifications/notifications_config.ui
new file mode 100644
index 0000000..3f3d8a4
--- /dev/null
+++ b/plugins/notifications/notifications_config.ui
@@ -0,0 +1,210 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>NotificationsConfigUi</class>
+ <widget class="QWidget" name="NotificationsConfigUi">
+ <property name="windowModality">
+ <enum>Qt::WindowModal</enum>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>350</width>
+ <height>326</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>350</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="windowTitle">
+ <string>Pause music plugin</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QGroupBox" name="groupBox_2">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="font">
+ <font>
+ <pointsize>11</pointsize>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="title">
+ <string>General</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QCheckBox" name="check_persistent">
+ <property name="font">
+ <font>
+ <weight>50</weight>
+ <bold>false</bold>
+ </font>
+ </property>
+ <property name="toolTip">
+ <string>Synchronize only notifications with a timeout value of 0?</string>
+ </property>
+ <property name="text">
+ <string>Persistent notifications only</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="check_body">
+ <property name="font">
+ <font>
+ <weight>50</weight>
+ <bold>false</bold>
+ </font>
+ </property>
+ <property name="toolTip">
+ <string>Append the notification body to the summary when synchronizing notifications?</string>
+ </property>
+ <property name="text">
+ <string>Include body</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QWidget" name="horizontalWidget" native="true">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QSpinBox" name="spin_urgency">
+ <property name="maximumSize">
+ <size>
+ <width>40</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="font">
+ <font>
+ <weight>50</weight>
+ <bold>false</bold>
+ </font>
+ </property>
+ <property name="toolTip">
+ <string><html><head/><body><p>Minimum urgency level of the notifications</p></body></html></string>
+ </property>
+ <property name="maximum">
+ <number>2</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="font">
+ <font>
+ <weight>50</weight>
+ <bold>false</bold>
+ </font>
+ </property>
+ <property name="toolTip">
+ <string>Synchronize only notifications with the given urgency level.</string>
+ </property>
+ <property name="text">
+ <string>Minimum urgency level</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="toolTip">
+ <string/>
+ </property>
+ <property name="title">
+ <string>Applications</string>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="QTableView" name="appList">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="font">
+ <font>
+ <weight>50</weight>
+ <bold>false</bold>
+ </font>
+ </property>
+ <property name="alternatingRowColors">
+ <bool>true</bool>
+ </property>
+ <property name="showGrid">
+ <bool>false</bool>
+ </property>
+ <property name="gridStyle">
+ <enum>Qt::NoPen</enum>
+ </property>
+ <property name="sortingEnabled">
+ <bool>true</bool>
+ </property>
+ <attribute name="horizontalHeaderVisible">
+ <bool>true</bool>
+ </attribute>
+ <attribute name="horizontalHeaderDefaultSectionSize">
+ <number>150</number>
+ </attribute>
+ <attribute name="horizontalHeaderMinimumSectionSize">
+ <number>20</number>
+ </attribute>
+ <attribute name="horizontalHeaderShowSortIndicator" stdset="0">
+ <bool>true</bool>
+ </attribute>
+ <attribute name="horizontalHeaderStretchLastSection">
+ <bool>true</bool>
+ </attribute>
+ <attribute name="verticalHeaderVisible">
+ <bool>false</bool>
+ </attribute>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/plugins/notifications/notificationslistener.cpp b/plugins/notifications/notificationslistener.cpp
index 88ad98b..7e643af 100644
--- a/plugins/notifications/notificationslistener.cpp
+++ b/plugins/notifications/notificationslistener.cpp
@@ -30,6 +30,7 @@
#include "notificationsplugin.h"
#include "notification_debug.h"
#include "notificationsdbusinterface.h"
+#include "notifyingapplication.h"
NotificationsListener::NotificationsListener(KdeConnectPlugin* aPlugin,
NotificationsDbusInterface* aDbusInterface)
@@ -37,6 +38,8 @@ NotificationsListener::NotificationsListener(KdeConnectPlugin* aPlugin,
mPlugin(aPlugin),
dbusInterface(aDbusInterface)
{
+ qRegisterMetaTypeStreamOperators<NotifyingApplication>("NotifyingApplication");
+
bool ret = QDBusConnection::sessionBus()
.registerObject("/org/freedesktop/Notifications",
this,
@@ -55,6 +58,10 @@ NotificationsListener::NotificationsListener(KdeConnectPlugin* aPlugin,
"org.freedesktop.DBus");
iface.call("AddMatch",
"interface='org.freedesktop.Notifications',member='Notify',type='method_call',eavesdrop='true'");
+
+ loadApplications();
+
+ connect(mPlugin->config(), SIGNAL(configChanged()), this, SLOT(loadApplications()));
}
NotificationsListener::~NotificationsListener()
@@ -67,6 +74,18 @@ NotificationsListener::~NotificationsListener()
QDBusConnection::sessionBus().unregisterObject("/org/freedesktop/Notifications");
}
+void NotificationsListener::loadApplications()
+{
+ applications.clear();
+ QVariantList list = mPlugin->config()->getList("applications");
+ for (const auto& a: list) {
+ NotifyingApplication app = a.value<NotifyingApplication>();
+ if (!applications.contains(app.name))
+ applications.insert(app.name, app);
+ }
+ //qCDebug(KDECONNECT_PLUGIN_NOTIFICATION) << "Loaded" << applications.size() << " applications";
+}
+
uint NotificationsListener::Notify(const QString &appName, uint replacesId,
const QString &appIcon,
const QString &summary, const QString &body,
@@ -74,20 +93,60 @@ uint NotificationsListener::Notify(const QString &appName, uint replacesId,
const QVariantMap &hints, int timeout)
{
static int id = 0;
- qCDebug(KDECONNECT_PLUGIN_NOTIFICATION) << "Got notification appName=" << appName << "replacesId=" << replacesId << "appIcon=" << appIcon << "summary=" << summary << "body=" << body << "actions=" << actions << "hints=" << hints << "timeout=" << timeout;
- Q_UNUSED(hints);
Q_UNUSED(actions);
- Q_UNUSED(appIcon);
- Q_UNUSED(body);
+
+ //qCDebug(KDECONNECT_PLUGIN_NOTIFICATION) << "Got notification appName=" << appName << "replacesId=" << replacesId << "appIcon=" << appIcon << "summary=" << summary << "body=" << body << "actions=" << actions << "hints=" << hints << "timeout=" << timeout;
// skip our own notifications
if (appName == QLatin1String("KDE Connect"))
return 0;
+ NotifyingApplication app;
+ if (!applications.contains(appName)) {
+ // new application -> add to config
+ app.name = appName;
+ app.icon = appIcon;
+ app.active = true;
+ app.blacklistExpression = QRegularExpression();
+ applications.insert(app.name, app);
+ // update config:
+ QVariantList list;
+ for (const auto& a: applications.values())
+ list << QVariant::fromValue<NotifyingApplication>(a);
+ mPlugin->config()->setList("applications", list);
+ //qCDebug(KDECONNECT_PLUGIN_NOTIFICATION) << "Added new application to config:" << app;
+ } else
+ app = applications.value(appName);
+
+ if (!app.active)
+ return 0;
+
+ if (timeout > 0 && mPlugin->config()->get("generalPersistent", false))
+ return 0;
+
+ int urgency = -1;
+ bool ok;
+ if (hints.contains("urgency"))
+ urgency = hints["urgency"].toInt(&ok);
+ if (!ok)
+ urgency = -1;
+ if (urgency > -1 && urgency < mPlugin->config()->get<int>("generalUrgency", 0))
+ return 0;
+
+ QString ticker = summary;
+ if (!body.isEmpty() && mPlugin->config()->get("generalIncludeBody", true))
+ ticker += QLatin1String(": ") + body;
+
+ if (app.blacklistExpression.isValid() &&
+ !app.blacklistExpression.pattern().isEmpty() &&
+ app.blacklistExpression.match(ticker).hasMatch())
+ return 0;
+
+ //qCDebug(KDECONNECT_PLUGIN_NOTIFICATION) << "Sending notification from" << appName << ":" <<ticker;
NetworkPackage np(PACKAGE_TYPE_NOTIFICATION);
np.set("id", QString::number(replacesId > 0 ? replacesId : ++id));
np.set("appName", appName);
- np.set("ticker", summary);
+ np.set("ticker", ticker);
np.set("isClearable", timeout == 0); // KNotifications are persistent if
// timeout == 0, for other notifications
// clearability is pointless
diff --git a/plugins/notifications/notificationslistener.h b/plugins/notifications/notificationslistener.h
index 7887b59..bb37ead 100644
--- a/plugins/notifications/notificationslistener.h
+++ b/plugins/notifications/notificationslistener.h
@@ -24,6 +24,7 @@
class KdeConnectPlugin;
class NotificationsDbusInterface;
class Notification;
+class NotifyingApplication;
class NotificationsListener : public QDBusAbstractAdaptor
{
@@ -38,9 +39,14 @@ public:
private:
KdeConnectPlugin* mPlugin;
NotificationsDbusInterface* dbusInterface;
+ QHash<QString, NotifyingApplication> applications;
public Q_SLOTS:
Q_SCRIPTABLE uint Notify(const QString&, uint, const QString&,
const QString&, const QString&,
const QStringList&, const QVariantMap&, int);
+
+private Q_SLOTS:
+ void loadApplications();
+
};
diff --git a/plugins/notifications/notificationslistener.h b/plugins/notifications/notifyingapplication.cpp
similarity index 53%
copy from plugins/notifications/notificationslistener.h
copy to plugins/notifications/notifyingapplication.cpp
index 7887b59..dc1c3c1 100644
--- a/plugins/notifications/notificationslistener.h
+++ b/plugins/notifications/notifyingapplication.cpp
@@ -18,29 +18,33 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <QtDBus/QDBusAbstractAdaptor>
-#include <core/device.h>
+#include "notifyingapplication.h"
-class KdeConnectPlugin;
-class NotificationsDbusInterface;
-class Notification;
+#include <QDebug>
+#include <QDataStream>
-class NotificationsListener : public QDBusAbstractAdaptor
+QDataStream &operator<<(QDataStream &out, const NotifyingApplication &app)
{
- Q_OBJECT
- Q_CLASSINFO("D-Bus Interface", "org.freedesktop.Notifications")
+ out << app.name << app.icon << app.active << app.blacklistExpression.pattern();
+ return out;
+}
-public:
- explicit NotificationsListener(KdeConnectPlugin* aPlugin,
- NotificationsDbusInterface* aDbusInterface);
- virtual ~NotificationsListener();
-
-private:
- KdeConnectPlugin* mPlugin;
- NotificationsDbusInterface* dbusInterface;
+QDataStream &operator>>(QDataStream &in, NotifyingApplication &app)
+{
+ QString pattern;
+ in >> app.name;
+ in >> app.icon;
+ in >> app.active;
+ in >> pattern;
+ app.blacklistExpression.setPattern(pattern);
+ return in;
+}
-public Q_SLOTS:
- Q_SCRIPTABLE uint Notify(const QString&, uint, const QString&,
- const QString&, const QString&,
- const QStringList&, const QVariantMap&, int);
-};
+QDebug operator<<(QDebug dbg, const NotifyingApplication& a) {
+ dbg.nospace() << "{ name=" << a.name
+ << ", icon=" << a.icon
+ << ", active=" << a.active
+ << ", blacklistExpression =" << a.blacklistExpression
+ << " }";
+ return dbg.space();
+}
diff --git a/plugins/notifications/notification.cpp b/plugins/notifications/notifyingapplication.h
similarity index 56%
copy from plugins/notifications/notification.cpp
copy to plugins/notifications/notifyingapplication.h
index 3e42f2a..97421aa 100644
--- a/plugins/notifications/notification.cpp
+++ b/plugins/notifications/notifyingapplication.h
@@ -1,5 +1,5 @@
/**
- * Copyright 2013 Albert Vaca <albertvaka at gmail.com>
+ * Copyright 2015 Holger Kaelberer <holger.k at elberer.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -18,29 +18,27 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "notification.h"
+#ifndef NOTIFYINGAPPLICATION_H
+#define NOTIFYINGAPPLICATION_H
-#include <QDBusConnection>
+#include <QRegularExpression>
+#include <QList>
-Notification::Notification(const NetworkPackage& np, const QString& iconPath, QObject* parent)
- : QObject(parent)
-{
- mInternalId = np.get<QString>("id");
- mAppName = np.get<QString>("appName");
- mTicker = np.get<QString>("ticker");
- mDismissable = np.get<bool>("isClearable");
- mIconPath = iconPath;
-}
+struct NotifyingApplication {
+ QString name;
+ QString icon;
+ bool active;
+ QRegularExpression blacklistExpression;
-Notification::~Notification()
-{
+ bool operator==(const NotifyingApplication& other) const {
+ return (name == other.name);
+ }
+};
-}
+Q_DECLARE_METATYPE(NotifyingApplication);
-void Notification::dismiss()
-{
- if (mDismissable) {
- Q_EMIT dismissRequested(mInternalId);
- }
-}
+QDataStream &operator<<(QDataStream &out, const NotifyingApplication &app);
+QDataStream &operator>>(QDataStream &in, NotifyingApplication &app);
+QDebug operator<<(QDebug dbg, const NotifyingApplication &a);
+#endif //NOTIFYINGAPPLICATION_H
diff --git a/plugins/notifications/notifyingapplicationmodel.cpp b/plugins/notifications/notifyingapplicationmodel.cpp
new file mode 100644
index 0000000..eadd46a
--- /dev/null
+++ b/plugins/notifications/notifyingapplicationmodel.cpp
@@ -0,0 +1,235 @@
+/**
+ * Copyright 2015 Holger Kaelberer <holger.k at elberer.de>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <QString>
+#include <QIcon>
+#include <QDebug>
+#include <KLocalizedString>
+#include <algorithm>
+
+#include "notifyingapplicationmodel.h"
+//#include "modeltest.h"
+
+NotifyingApplicationModel::NotifyingApplicationModel(QObject *parent)
+ : QAbstractTableModel(parent)
+{
+}
+
+NotifyingApplicationModel::~NotifyingApplicationModel()
+{
+}
+
+QVector<NotifyingApplication> NotifyingApplicationModel::apps()
+{
+ return m_apps;
+}
+
+void NotifyingApplicationModel::appendApp(const NotifyingApplication& app)
+{
+ if (app.name.isEmpty() || apps().contains(app))
+ return;
+ beginInsertRows(QModelIndex(), m_apps.size(), m_apps.size());
+ m_apps.append(app);
+ endInsertRows();
+}
+
+bool NotifyingApplicationModel::containsApp(const QString& name) const
+{
+ for (const auto& a: m_apps)
+ if (a.name == name)
+ return true;
+ return false;
+}
+
+Qt::ItemFlags NotifyingApplicationModel::flags(const QModelIndex& index) const
+{
+ Qt::ItemFlags flags = Qt::ItemIsEnabled;
+ if (index.isValid() && index.row() >= 0 && index.row() < m_apps.size() &&
+ index.column() < 3)
+ {
+ if (index.column() == 0)
+ flags |= Qt::ItemIsEditable | Qt::ItemIsUserCheckable;
+ else if (index.column() == 2) {
+ if (m_apps[index.row()].active)
+ flags |= Qt::ItemIsEditable;
+ else
+ flags ^= Qt::ItemIsEnabled;
+ }
+ else if (index.column() == 1) {
+ if (!m_apps[index.row()].active)
+ flags ^= Qt::ItemIsEnabled;
+ }
+ }
+ return flags;
+}
+
+void NotifyingApplicationModel::clearApplications()
+{
+ if (!m_apps.isEmpty()) {
+ beginRemoveRows(QModelIndex(), 0, m_apps.size() - 1);
+ m_apps.clear();
+ endRemoveRows();
+ }
+}
+
+QVariant NotifyingApplicationModel::data(const QModelIndex& index, int role) const
+{
+ Q_UNUSED(role);
+ if (!index.isValid()
+ || index.row() < 0
+ || index.row() >= m_apps.size()
+ || index.column() > 3)
+ {
+ return QVariant();
+ }
+
+ switch (role) {
+ case Qt::TextAlignmentRole: {
+ if (index.column() == 0)
+ return int(Qt::AlignCenter | Qt::AlignVCenter );
+ else
+ return int(Qt::AlignLeft | Qt::AlignVCenter );
+ break;
+ }
+ case Qt::DisplayRole: {
+ if (index.column() == 1)
+ return m_apps[index.row()].name;
+ else if (index.column() == 0)
+ return QVariant();//m_apps[index.row()].active;
+ else if (index.column() == 2)
+ return m_apps[index.row()].blacklistExpression.pattern();
+ else
+ return QVariant();
+ break;
+ }
+ case Qt::DecorationRole: {
+ if (index.column() == 1)
+ return QIcon::fromTheme(m_apps[index.row()].icon, QIcon::fromTheme("application-x-executable"));
+ else
+ return QVariant();
+ break;
+ }
+ case Qt::EditRole: {
+ if (index.column() == 0)
+ return m_apps[index.row()].active ? Qt::Checked : Qt::Unchecked;
+ else if (index.column() == 2)
+ return m_apps[index.row()].blacklistExpression.pattern();
+ else
+ return QVariant();
+ break;
+ }
+ case Qt::CheckStateRole: {
+ if (index.column() == 0)
+ return m_apps[index.row()].active ? Qt::Checked : Qt::Unchecked;
+ else
+ return QVariant();
+ break;
+ }
+ }
+ return QVariant();
+}
+
+bool NotifyingApplicationModel::setData(const QModelIndex &index, const QVariant &value, int role)
+{
+ if (!index.isValid() ||
+ (index.column() != 0 && index.column() != 2) ||
+ index.row() < 0 || index.row() >= m_apps.size())
+ return false;
+
+ bool res = false;
+ QModelIndex bottomRight = createIndex(index.row(), index.column());
+ switch (role) {
+ case Qt::CheckStateRole: {
+ if (index.column() == 0) {
+ m_apps[index.row()].active = ((Qt::CheckState)value.toInt() == Qt::Checked);
+ bottomRight = createIndex(index.row(), index.column() + 1);
+ res = true;
+ }
+ break;
+ }
+ case Qt::EditRole: {
+ if (index.column() == 2) {
+ m_apps[index.row()].blacklistExpression.setPattern(value.toString());
+ res = true;
+ }
+ }
+ }
+ if (res) {
+ Q_EMIT dataChanged(index, bottomRight);
+ Q_EMIT applicationsChanged(); // -> notify config that we need to save
+ }
+ return res;
+}
+
+void NotifyingApplicationModel::sort(int column, Qt::SortOrder order)
+{
+ if (column != 1)
+ return;
+
+ if (order == Qt::AscendingOrder)
+ std::sort(m_apps.begin(), m_apps.end(),
+ [](const NotifyingApplication& a, const NotifyingApplication& b) {
+ return (a.name.compare(b.name, Qt::CaseInsensitive) < 1);
+ });
+ else
+ std::sort(m_apps.begin(), m_apps.end(),
+ [](const NotifyingApplication& a, const NotifyingApplication& b) {
+ return (b.name.compare(a.name, Qt::CaseInsensitive) < 1);
+ });
+ Q_EMIT dataChanged(createIndex(0, 0), createIndex(m_apps.size(), 2));
+}
+
+QVariant NotifyingApplicationModel::headerData(int section, Qt::Orientation /*orientation*/,
+ int role) const
+{
+ switch (role) {
+ case Qt::DisplayRole: {
+ if (section == 1)
+ return i18n("Name");
+ else if (section == 0)
+ return QVariant(); //i18n("Sync");
+ else
+ return i18n("Blacklisted");
+ }
+ case Qt::ToolTipRole: {
+ if (section == 1)
+ return i18n("Name of a notifying application.");
+ else if (section == 0)
+ return i18n("Synchronize notifications of an application?");
+ else
+ return i18n("Regular expression defining which notifications should not be sent.
This pattern is applied to the summary and, if selected above, the body of notifications.");
+ }
+ }
+ return QVariant();
+}
+
+int NotifyingApplicationModel::columnCount(const QModelIndex&) const
+{
+ return 3;
+}
+
+int NotifyingApplicationModel::rowCount(const QModelIndex& parent) const
+{
+ if(parent.isValid()) {
+ //Return size 0 if we are a child because this is not a tree
+ return 0;
+ }
+ return m_apps.size();
+}
diff --git a/plugins/notifications/notifyingapplicationmodel.h b/plugins/notifications/notifyingapplicationmodel.h
new file mode 100644
index 0000000..efeda19
--- /dev/null
+++ b/plugins/notifications/notifyingapplicationmodel.h
@@ -0,0 +1,56 @@
+/**
+ * Copyright 2015 Holger Kaelberer <holger.k at elberer.de>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NOTIFYINGAPPLICATIONMODEL_H
+#define NOTIFYINGAPPLICATIONMODEL_H
+
+#include <QAbstractTableModel>
+
+#include "notifyingapplication.h"
+
+class NotifyingApplicationModel: public QAbstractTableModel
+{
+ Q_OBJECT
+
+public:
+ explicit NotifyingApplicationModel(QObject *parent = nullptr);
+ virtual ~NotifyingApplicationModel();
+
+ virtual QVariant data(const QModelIndex& index, int role) const override;
+ virtual bool setData(const QModelIndex &index, const QVariant &value, int role) override;
+ virtual int rowCount(const QModelIndex& parent = QModelIndex()) const override;
+ virtual int columnCount(const QModelIndex& parent = QModelIndex()) const override;
+ virtual Qt::ItemFlags flags(const QModelIndex & index) const override;
+ virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
+ virtual void sort(int column, Qt::SortOrder order = Qt::AscendingOrder) override;
+
+ QVector<NotifyingApplication> apps();
+ void clearApplications();
+ void appendApp(const NotifyingApplication& app);
+ bool containsApp(const QString& name) const;
+
+Q_SIGNALS:
+ void applicationsChanged();
+
+private:
+ QVector<NotifyingApplication> m_apps;
+};
+
+#endif // NOTIFYINGAPPLICATIONMODEL_H
--
kdeconnect packaging
More information about the pkg-kde-commits
mailing list