plasma: use custom interface for notifications

proxy for compat can be implemented too but do not think I will need
that

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
Ivailo Monev 2024-04-08 10:18:25 +03:00
parent 278acc1fce
commit 3f41dc2c37
19 changed files with 121 additions and 852 deletions

View file

@ -8,7 +8,6 @@ add_definitions(-DKDE_DEFAULT_DEBUG_AREA=1204)
add_subdirectory(applets)
add_subdirectory(containmentactions)
add_subdirectory(containments)
add_subdirectory(dataengines)
add_subdirectory(desktoptheme)
add_subdirectory(runners)
add_subdirectory(shells)

View file

@ -5,6 +5,7 @@ set(notifications_SRCS
jobswidget.cpp
jobtrackeradaptor.cpp
applicationswidget.cpp
notificationsadaptor.cpp
)
kde4_add_plugin(plasma_applet_notifications ${notifications_SRCS})

View file

@ -18,9 +18,9 @@
#include "applicationswidget.h"
#include <QDBusConnection>
#include <QTimer>
#include <QGraphicsGridLayout>
#include <Plasma/DataEngineManager>
#include <Plasma/Animation>
#include <Plasma/Service>
#include <KIconLoader>
@ -129,7 +129,7 @@ ApplicationsWidget::ApplicationsWidget(QGraphicsItem *parent, NotificationsWidge
m_notificationswidget(notificationswidget),
m_layout(nullptr),
m_label(nullptr),
m_dataengine(nullptr)
m_adaptor(nullptr)
{
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
m_layout = new QGraphicsLinearLayout(Qt::Vertical, this);
@ -142,22 +142,21 @@ ApplicationsWidget::ApplicationsWidget(QGraphicsItem *parent, NotificationsWidge
m_layout->addStretch();
setLayout(m_layout);
m_dataengine = Plasma::DataEngineManager::self()->loadEngine("notifications");
if (!m_dataengine) {
kWarning() << "Could not load notifications data engine";
return;
}
m_adaptor = new NotificationsAdaptor(this);
connect(
m_dataengine, SIGNAL(sourceAdded(QString)),
this, SLOT(sourceAdded(QString))
m_adaptor, SIGNAL(notificationAdded(QString)),
this, SLOT(slotNotificationAdded(QString))
);
connect(
m_adaptor, SIGNAL(notificationUpdated(QString,QVariantMap)),
this, SLOT(slotNotificationUpdated(QString,QVariantMap))
);
QDBusConnection session = QDBusConnection::sessionBus();
session.registerObject("/Notifications", this);
}
ApplicationsWidget::~ApplicationsWidget()
{
if (m_dataengine) {
Plasma::DataEngineManager::self()->unloadEngine("notifications");
}
}
int ApplicationsWidget::count() const
@ -165,7 +164,7 @@ int ApplicationsWidget::count() const
return m_frames.size();
}
void ApplicationsWidget::sourceAdded(const QString &name)
void ApplicationsWidget::slotNotificationAdded(const QString &name)
{
QMutexLocker locker(&m_mutex);
ApplicationFrame* frame = new ApplicationFrame(name, this);
@ -179,11 +178,9 @@ void ApplicationsWidget::sourceAdded(const QString &name)
adjustSize();
emit countChanged();
locker.unlock();
m_dataengine->connectSource(name, this);
}
void ApplicationsWidget::dataUpdated(const QString &name, const Plasma::DataEngine::Data &data)
void ApplicationsWidget::slotNotificationUpdated(const QString &name, const QVariantMap &data)
{
QMutexLocker locker(&m_mutex);
foreach (ApplicationFrame* frame, m_frames) {
@ -256,15 +253,7 @@ void ApplicationsWidget::slotRemoveActivated()
while (iter.hasNext()) {
ApplicationFrame* frame = iter.next();
if (frame == applicationframe) {
Plasma::Service* plasmaservice = m_dataengine->serviceForSource(applicationframe->name);
if (!plasmaservice) {
kWarning() << "Could not get service for" << applicationframe->name;
} else {
plasmaservice->setParent(this);
const QVariantMap plasmaserviceargs = plasmaservice->operationParameters("userClosed");
(void)plasmaservice->startOperationCall("userClosed", plasmaserviceargs);
}
m_dataengine->disconnectSource(applicationframe->name, this);
m_adaptor->closeNotification(applicationframe->name);
QGraphicsGridLayout* framelayout = static_cast<QGraphicsGridLayout*>(frame->layout());
Q_ASSERT(framelayout != nullptr);
kClearButtons(framelayout);
@ -281,8 +270,6 @@ void ApplicationsWidget::slotConfigureActivated()
const Plasma::IconWidget* configurewidget = qobject_cast<Plasma::IconWidget*>(sender());
const QString frameapprealname = configurewidget->property("_k_apprealname").toString();
locker.unlock();
// same thing the notifications service does except without going trought the data engine
// meaning faster
KNotificationConfigWidget::configure(frameapprealname, nullptr);
}
@ -293,15 +280,7 @@ void ApplicationsWidget::slotActionReleased()
ApplicationFrame* actionframe = qobject_cast<ApplicationFrame*>(actionbutton->parentObject());
Q_ASSERT(actionframe != nullptr);
const QString actionid = actionbutton->property("_k_actionid").toString();
Plasma::Service* plasmaservice = m_dataengine->serviceForSource(actionframe->name);
if (!plasmaservice) {
kWarning() << "Could not get service for" << actionframe->name;
} else {
plasmaservice->setParent(this);
QVariantMap plasmaserviceargs = plasmaservice->operationParameters("invokeAction");
plasmaserviceargs["actionId"] = actionid;
(void)plasmaservice->startOperationCall("invokeAction", plasmaserviceargs);
}
m_adaptor->invokeAction(actionframe->name, actionid);
locker.unlock();
// remove notification too (compat)
QTimer::singleShot(200, actionframe->removewidget, SIGNAL(activated()));

View file

@ -19,6 +19,8 @@
#ifndef APPLICATIONSWIDGET_H
#define APPLICATIONSWIDGET_H
#include "notificationsadaptor.h"
#include <QMutex>
#include <QGraphicsWidget>
#include <QGraphicsLinearLayout>
@ -26,7 +28,6 @@
#include <Plasma/Frame>
#include <Plasma/IconWidget>
#include <Plasma/PushButton>
#include <Plasma/DataEngine>
class NotificationsWidget;
@ -66,8 +67,8 @@ public Q_SLOTS:
void slotActionReleased();
private Q_SLOTS:
void sourceAdded(const QString &name);
void dataUpdated(const QString &name, const Plasma::DataEngine::Data &data);
void slotNotificationAdded(const QString &name);
void slotNotificationUpdated(const QString &name, const QVariantMap &data);
private:
QMutex m_mutex;
@ -75,7 +76,7 @@ private:
QGraphicsLinearLayout* m_layout;
Plasma::Label* m_label;
QList<ApplicationFrame*> m_frames;
Plasma::DataEngine* m_dataengine;
NotificationsAdaptor* m_adaptor;
};
#endif // APPLICATIONSWIDGET_H

View file

@ -20,7 +20,6 @@
#include <QDBusConnection>
#include <QGraphicsGridLayout>
#include <Plasma/DataEngineManager>
#include <Plasma/Animation>
#include <KRun>
#include <KIconLoader>

View file

@ -28,7 +28,6 @@
#include <Plasma/Frame>
#include <Plasma/IconWidget>
#include <Plasma/Meter>
#include <Plasma/DataEngine>
class NotificationsWidget;

View file

@ -0,0 +1,51 @@
/*
This file is part of the KDE project
Copyright (C) 2024 Ivailo Monev <xakepa10@gmail.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License version 2, as published by the Free Software Foundation.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "notificationsadaptor.h"
NotificationsAdaptor::NotificationsAdaptor(QObject *parent)
: QDBusAbstractAdaptor(parent)
{
}
NotificationsAdaptor::~NotificationsAdaptor()
{
}
void NotificationsAdaptor::addNotification(const QString &name)
{
emit notificationAdded(name);
}
void NotificationsAdaptor::updateNotification(const QString &name, const QVariantMap &data)
{
emit notificationUpdated(name, data);
}
void NotificationsAdaptor::closeNotification(const QString &name)
{
emit closeRequested(name);
}
void NotificationsAdaptor::invokeAction(const QString &name, const QString &action)
{
emit actionRequested(name, action);
}
#include "moc_notificationsadaptor.cpp"

View file

@ -0,0 +1,49 @@
/*
This file is part of the KDE project
Copyright (C) 2024 Ivailo Monev <xakepa10@gmail.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License version 2, as published by the Free Software Foundation.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef NOTIFICATIONSADAPTOR_H
#define NOTIFICATIONSADAPTOR_H
#include <QDBusAbstractAdaptor>
#include <QVariantMap>
// Adaptor class for interface org.kde.Notifications
class NotificationsAdaptor: public QDBusAbstractAdaptor
{
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", "org.kde.Notifications")
public:
NotificationsAdaptor(QObject *parent);
~NotificationsAdaptor();
public Q_SLOTS:
void addNotification(const QString &name);
void updateNotification(const QString &name, const QVariantMap &data);
void closeNotification(const QString &name);
void invokeAction(const QString &name, const QString &action);
Q_SIGNALS:
void notificationAdded(const QString &name);
void notificationUpdated(const QString &name, const QVariantMap &data);
void closeRequested(const QString &name);
void actionRequested(const QString &name, const QString &action);
};
#endif // NOTIFICATIONSADAPTOR_H

View file

@ -1 +0,0 @@
add_subdirectory(notifications)

View file

@ -1,14 +0,0 @@
set(notifications_engine_SRCS
notificationsengine.cpp
notificationservice.cpp
notificationaction.cpp
)
qt4_add_dbus_adaptor( notifications_engine_SRCS org.freedesktop.Notifications.xml notificationsengine.h NotificationsEngine )
kde4_add_plugin(plasma_engine_notifications ${notifications_engine_SRCS})
target_link_libraries(plasma_engine_notifications KDE4::plasma KDE4::kdecore KDE4::kdeui)
install(TARGETS plasma_engine_notifications DESTINATION ${KDE4_PLUGIN_INSTALL_DIR})
install(FILES plasma-dataengine-notifications.desktop DESTINATION ${KDE4_SERVICES_INSTALL_DIR})

View file

@ -1,2 +0,0 @@
#!/bin/bash
$XGETTEXT *.cpp -o $podir/plasma_engine_notifications.pot

View file

@ -1,73 +0,0 @@
/*
* Copyright © 2008 Rob Scheepmaker <r.scheepmaker@student.utwente.nl>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License version 2 as
* published by the Free Software Foundation
*
* 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 Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "notificationaction.h"
#include "notificationsengine.h"
#include <kdebug.h>
void NotificationAction::start()
{
//kDebug() << "Trying to perform the action " << operationName() << " on " << destination();
//kDebug() << "actionId: " << parameters()["actionId"].toString();
//kDebug() << "params: " << parameters();
if (!m_engine) {
setErrorText(i18n("The notification dataEngine is not set."));
setError(-1);
emitResult();
return;
}
const QStringList dest = destination().split(' ');
uint id = 0;
if (dest.count() > 1 && !dest[1].toInt()) {
setErrorText(i18n("Invalid destination: %1", destination()));
setError(-2);
emitResult();
return;
} else if (dest.count() > 1) {
id = dest[1].toUInt();
}
if (operationName() == "invokeAction") {
//kDebug() << "invoking action on " << id;
emit m_engine->ActionInvoked(id, parameters()["actionId"].toString());
} else if (operationName() == "userClosed") {
//userClosedNotification deletes the job, so we have to invoke it queued, in this case emitResult() can be called
m_engine->metaObject()->invokeMethod(m_engine, "userClosedNotification", Qt::QueuedConnection, Q_ARG(uint, id));
} else if (operationName() == "createNotification") {
int rv = m_engine->createNotification(parameters().value("appName").toString(),
parameters().value("appIcon").toString(),
parameters().value("summary").toString(),
parameters().value("body").toString(),
parameters().value("timeout").toInt(),
false,
QString()
);
setResult(rv);
} else if (operationName() == "configureNotification") {
m_engine->configureNotification(parameters()["appRealName"].toString());
}
emitResult();
}
#include "moc_notificationaction.cpp"

View file

@ -1,49 +0,0 @@
/*
* Copyright © 2008 Rob Scheepmaker <r.scheepmaker@student.utwente.nl>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License version 2 as
* published by the Free Software Foundation
*
* 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 Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef NOTIFICATIONACTION_H
#define NOTIFICATIONACTION_H
#include "notificationsengine.h"
#include <kdebug.h>
#include <Plasma/ServiceJob>
class NotificationAction : public Plasma::ServiceJob
{
Q_OBJECT
public:
NotificationAction(NotificationsEngine* engine,
const QString& destination,
const QString& operation,
const QMap<QString,QVariant>& parameters,
QObject* parent = 0)
: ServiceJob(destination, operation, parameters, parent),
m_engine(engine)
{
}
void start();
private:
NotificationsEngine* m_engine;
};
#endif //NOTIFICATIONACTION_H

View file

@ -1,313 +0,0 @@
/*
* Copyright (C) 2008 Dmitry Suzdalev <dimsuz@gmail.com>
*
* This program is free software you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "notificationsengine.h"
#include "notificationservice.h"
#include "notificationsadaptor.h"
#include <KUrl>
#include <KConfigGroup>
#include <KGlobal>
#include <KNotificationConfigWidget>
#include <KStandardDirs>
#include <KIconLoader>
#include <KDebug>
#include <Plasma/DataContainer>
#include <Plasma/Service>
#include <QImage>
#include <QTimerEvent>
// for reference:
// https://specifications.freedesktop.org/notification-spec/notification-spec-latest.html
static void copyLineRGB32(QRgb* dst, const char* src, int width)
{
const char* end = src + width * 3;
for (; src != end; ++dst, src+=3) {
*dst = qRgb(src[0], src[1], src[2]);
}
}
static void copyLineARGB32(QRgb* dst, const char* src, int width)
{
const char* end = src + width * 4;
for (; src != end; ++dst, src+=4) {
*dst = qRgba(src[0], src[1], src[2], src[3]);
}
}
static QImage decodeNotificationSpecImageHint(const QDBusArgument& arg)
{
int width = 0;
int height = 0;
int rowStride = 0;
bool hasAlpha = false;
int bitsPerSample = 0;
int channels = 0;
QByteArray pixels;
arg.beginStructure();
arg >> width >> height >> rowStride >> hasAlpha >> bitsPerSample >> channels >> pixels;
arg.endStructure();
// kDebug() << width << height << rowStride << hasAlpha << bitsPerSample << channels;
#define SANITY_CHECK(condition) \
if (!(condition)) { \
kWarning() << "Sanity check failed on" << #condition; \
return QImage(); \
}
SANITY_CHECK(width > 0);
SANITY_CHECK(width < 2048);
SANITY_CHECK(height > 0);
SANITY_CHECK(height < 2048);
SANITY_CHECK(rowStride > 0);
#undef SANITY_CHECK
QImage::Format format = QImage::Format_Invalid;
void (*fcn)(QRgb*, const char*, int) = 0;
if (bitsPerSample == 8) {
if (channels == 4) {
format = QImage::Format_ARGB32;
fcn = copyLineARGB32;
} else if (channels == 3) {
format = QImage::Format_RGB32;
fcn = copyLineRGB32;
}
}
if (format == QImage::Format_Invalid) {
kWarning() << "Unsupported image format (hasAlpha:" << hasAlpha << "bitsPerSample:" << bitsPerSample << "channels:" << channels << ")";
return QImage();
}
QImage image(width, height, format);
const char* ptr = pixels.constData();
const char* end = ptr + pixels.length();
for (int y=0; y<height; ++y, ptr += rowStride) {
if (ptr + channels * width > end) {
kWarning() << "Image data is incomplete. y:" << y << "height:" << height;
break;
}
fcn((QRgb*)image.scanLine(y), ptr, width);
}
return image;
}
static QString findImageForSpecImagePath(const QString &_path)
{
QString path = _path;
if (path.startsWith(QLatin1String("file:"))) {
KUrl url(path);
path = url.toLocalFile();
}
return KIconLoader::global()->iconPath(
path, -KIconLoader::SizeHuge,
true /* canReturnNull */
);
}
NotificationsEngine::NotificationsEngine(QObject *parent, const QVariantList &args)
: Plasma::DataEngine(parent, args),
m_nextId(1)
{
new NotificationsAdaptor(this);
QDBusConnection dbus = QDBusConnection::sessionBus();
dbus.registerService( "org.freedesktop.Notifications" );
dbus.registerObject( "/org/freedesktop/Notifications", this );
}
NotificationsEngine::~NotificationsEngine()
{
QDBusConnection dbus = QDBusConnection::sessionBus();
dbus.unregisterService("org.freedesktop.Notifications");
}
uint NotificationsEngine::Notify(const QString &app_name, uint replaces_id,
const QString &app_icon, const QString &summary, const QString &body,
const QStringList &actions, const QVariantMap &hints, int timeout)
{
uint id = 0;
id = replaces_id ? replaces_id : m_nextId++;
QString appname_str = app_name;
if (appname_str.isEmpty()) {
appname_str = i18n("Unknown Application");
}
if (timeout == -1) {
const int AVERAGE_WORD_LENGTH = 6;
const int WORD_PER_MINUTE = 250;
int count = summary.length() + body.length();
timeout = 60000 * count / AVERAGE_WORD_LENGTH / WORD_PER_MINUTE;
// Add two seconds for the user to notice the notification, and ensure
// it last at least five seconds, otherwise all the user see is a
// flash
timeout = 2000 + qMax(timeout, 3000);
}
const QString source = QString("notification %1").arg(id);
if (replaces_id) {
Plasma::DataContainer *container = containerForSource(source);
if (container && container->data()["expireTimeout"].toInt() != timeout) {
int timerId = m_sourceTimers.value(source);
killTimer(timerId);
m_sourceTimers.remove(source);
m_timeouts.remove(timerId);
}
}
Plasma::DataEngine::Data notificationData;
notificationData.insert("id", QString::number(id));
notificationData.insert("appName", appname_str);
notificationData.insert("appIcon", app_icon);
notificationData.insert("summary", summary);
notificationData.insert("body", body);
notificationData.insert("actions", actions);
notificationData.insert("expireTimeout", timeout);
QString appRealName;
bool configurable = false;
if (hints.contains("x-kde-appname")) {
appRealName = hints["x-kde-appname"].toString();
configurable = true;
}
notificationData.insert("appRealName", appRealName);
notificationData.insert("configurable", configurable);
QImage image;
if (hints.contains("image_data")) { // v1.1
QDBusArgument arg = hints["image_data"].value<QDBusArgument>();
image = decodeNotificationSpecImageHint(arg);
} else if (hints.contains("image-data")) { // v1.2
QDBusArgument arg = hints["image-data"].value<QDBusArgument>();
image = decodeNotificationSpecImageHint(arg);
} else if (hints.contains("image_path")) { // v1.1
QString path = findImageForSpecImagePath(hints["image_path"].toString());
if (!path.isEmpty()) {
image.load(path);
}
} else if (hints.contains("image-path")) { // v1.2
QString path = findImageForSpecImagePath(hints["image-path"].toString());
if (!path.isEmpty()) {
image.load(path);
}
} else if (hints.contains("icon_data")) { // v1.0
QDBusArgument arg = hints["icon_data"].value<QDBusArgument>();
image = decodeNotificationSpecImageHint(arg);
}
notificationData.insert("image", image);
if (hints.contains("urgency")) {
notificationData.insert("urgency", hints["urgency"].toInt());
}
setData(source, notificationData);
if (timeout) {
int timerId = startTimer(timeout);
m_sourceTimers.insert(source, timerId);
m_timeouts.insert(timerId, source);
}
return id;
}
void NotificationsEngine::timerEvent(QTimerEvent *event)
{
const QString source = m_timeouts.value(event->timerId());
if (!source.isEmpty()) {
killTimer(event->timerId());
m_sourceTimers.remove(source);
m_timeouts.remove(event->timerId());
removeSource(source);
emit NotificationClosed(source.split(" ").last().toInt(), 1);
return;
}
Plasma::DataEngine::timerEvent(event);
}
void NotificationsEngine::CloseNotification(uint id)
{
removeSource(QString("notification %1").arg(id));
emit NotificationClosed(id, 3);
}
void NotificationsEngine::userClosedNotification(uint id)
{
removeSource(QString("notification %1").arg(id));
emit NotificationClosed(id, 2);
}
Plasma::Service* NotificationsEngine::serviceForSource(const QString& source)
{
return new NotificationService(this, source);
}
QStringList NotificationsEngine::GetCapabilities()
{
return QStringList()
<< "body"
<< "body-hyperlinks"
<< "body-markup"
<< "icon-static"
<< "actions";
}
// FIXME: Signature is ugly
QString NotificationsEngine::GetServerInformation(QString &vendor, QString &version, QString &specVersion)
{
vendor = "KDE";
version = KDE_VERSION_STRING;
specVersion = "1.2";
return "Plasma";
}
int NotificationsEngine::createNotification(const QString &appName, const QString &appIcon, const QString &summary,
const QString &body, int timeout, bool configurable, const QString &appRealName)
{
const QString source = QString("notification %1").arg(++m_nextId);
Plasma::DataEngine::Data notificationData;
notificationData.insert("id", QString::number(m_nextId));
notificationData.insert("appName", appName);
notificationData.insert("appIcon", appIcon);
notificationData.insert("summary", summary);
notificationData.insert("body", body);
notificationData.insert("expireTimeout", timeout);
notificationData.insert("configurable", configurable);
notificationData.insert("appRealName", appRealName);
setData(source, notificationData);
return m_nextId;
}
void NotificationsEngine::configureNotification(const QString &appName)
{
KNotificationConfigWidget::configure(appName, nullptr);
}
K_EXPORT_PLASMA_DATAENGINE(notifications, NotificationsEngine)
#include "moc_notificationsengine.cpp"

View file

@ -1,83 +0,0 @@
/*
* Copyright (C) 2008 Dmitry Suzdalev <dimsuz@gmail.com>
*
* This program is free software you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef NOTIFICATIONSENGINE_H
#define NOTIFICATIONSENGINE_H
#include <Plasma/DataEngine>
#include <QTimer>
/**
* Engine which provides data sources for notifications.
* Each notification is represented by one source.
*/
class NotificationsEngine : public Plasma::DataEngine
{
Q_OBJECT
public:
NotificationsEngine(QObject* parent, const QVariantList &args);
~NotificationsEngine();
/**
* This function implements part of Notifications DBus interface.
* Once called, will add notification source to the engine
*/
uint Notify(const QString &app_name, uint replaces_id, const QString &app_icon,
const QString &summary, const QString &body, const QStringList &actions,
const QVariantMap &hints, int timeout);
void CloseNotification(uint id);
Plasma::Service* serviceForSource(const QString &source);
QStringList GetCapabilities();
QString GetServerInformation(QString &vendor, QString &version, QString &specVersion);
int createNotification(const QString &appName, const QString &appIcon, const QString &summary,
const QString &body, int timeout, bool configurable, const QString &appRealName);
void configureNotification(const QString &appName);
public Q_SLOTS:
void userClosedNotification(uint id);
signals:
void NotificationClosed(uint id, uint reason);
void ActionInvoked(uint id, const QString &actionKey);
protected:
void timerEvent(QTimerEvent *event);
private:
/**
* Holds the id that will be assigned to the next notification source
* that will be created
*/
uint m_nextId;
QHash<int, QString> m_timeouts; // timerIDs -> sources
QHash<QString, int> m_sourceTimers; // sources -> timerIDs
friend class NotificationAction;
};
#endif

View file

@ -1,45 +0,0 @@
/*
* Copyright © 2008 Rob Scheepmaker <r.scheepmaker@student.utwente.nl>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License version 2 as
* published by the Free Software Foundation
*
* 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 Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "notificationservice.h"
#include "notificationaction.h"
#include "notificationsengine.h"
NotificationService::NotificationService(NotificationsEngine* parent, const QString& source)
: Plasma::Service(parent),
m_notificationEngine(parent)
{
setName("notifications");
setOperationNames(
QStringList()
<< "invokeAction"
<< "userClosed"
<< "createNotification"
<< "configureNotification"
);
setDestination(source);
}
Plasma::ServiceJob* NotificationService::createJob(const QString& operation,
const QMap<QString,QVariant>& parameters)
{
return new NotificationAction(m_notificationEngine, destination(), operation, parameters, this);
}
#include "moc_notificationservice.cpp"

View file

@ -1,42 +0,0 @@
/*
* Copyright © 2008 Rob Scheepmaker <r.scheepmaker@student.utwente.nl>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License version 2 as
* published by the Free Software Foundation
*
* 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 Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef NOTIFICATIONSERVICE_H
#define NOTIFICATIONSERVICE_H
#include <Plasma/Service>
class NotificationsEngine;
class NotificationService : public Plasma::Service
{
Q_OBJECT
public:
NotificationService(NotificationsEngine* parent, const QString& source);
protected:
Plasma::ServiceJob* createJob(const QString& operation,
const QMap<QString,QVariant>& parameters);
private:
NotificationsEngine* m_notificationEngine;
};
#endif // NOTIFICATIONSERVICE_H

View file

@ -1,37 +0,0 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="org.freedesktop.Notifications">
<signal name="NotificationClosed">
<arg name="id" type="u" direction="out"/>
<arg name="reason" type="u" direction="out"/>
</signal>
<signal name="ActionInvoked">
<arg name="id" type="u" direction="out"/>
<arg name="action_key" type="s" direction="out"/>
</signal>
<method name="Notify">
<annotation name="org.qtproject.QtDBus.QtTypeName.In6" value="QVariantMap"/>
<arg type="u" direction="out"/>
<arg name="app_name" type="s" direction="in"/>
<arg name="replaces_id" type="u" direction="in"/>
<arg name="app_icon" type="s" direction="in"/>
<arg name="summary" type="s" direction="in"/>
<arg name="body" type="s" direction="in"/>
<arg name="actions" type="as" direction="in"/>
<arg name="hints" type="a{sv}" direction="in"/>
<arg name="timeout" type="i" direction="in"/>
</method>
<method name="CloseNotification">
<arg name="id" type="u" direction="in"/>
</method>
<method name="GetCapabilities">
<arg type="as" name="caps" direction="out"/>
</method>
<method name="GetServerInformation">
<arg type="s" name="name" direction="out"/>
<arg type="s" name="vendor" direction="out"/>
<arg type="s" name="version" direction="out"/>
<arg type="s" name="spec_version" direction="out"/>
</method>
</interface>
</node>

View file

@ -1,150 +0,0 @@
[Desktop Entry]
Name=Application Notifications
Name[ar]=تنبيهات التطبيقات
Name[ast]=Notificaciones d'aplicaciones
Name[be@latin]=Infarmavańni aplikacyj
Name[bg]=Програмни съобщения
Name[bn]=ি িি
Name[bn_IN]=ি
Name[bs]=obavještenja programa
Name[ca]=Notificacions de les aplicacions
Name[ca@valencia]=Notificacions de les aplicacions
Name[cs]=Oznamování aplikací
Name[csb]=Dôwanié wiédzë ò aplikacëjach
Name[da]=Programbekendtgørelser
Name[de]=Anwendungs-Benachrichtigungen
Name[el]=Ειδοποιήσεις εφαρμογών
Name[en_GB]=Application Notifications
Name[eo]=Aplikaĵaj Atentigoj
Name[es]=Notificaciones de aplicaciones
Name[et]=Rakenduste märguanded
Name[eu]=Aplikazioen jakinarazpenak
Name[fi]=Sovellusilmoitukset
Name[fr]=Notifications des applications
Name[fy]=Applikaasje ntifikaasjes
Name[ga]=Fógairtí Feidhmchláir
Name[gl]=Notificacións dos programas
Name[gu]=
Name[he]=הודעות יישומים
Name[hi]=
Name[hne]=
Name[hr]=Obavijesti aplikacija
Name[hu]=Értesítő üzenetek
Name[ia]=Notificationes de application
Name[id]=Notifikasi Aplikasi
Name[is]=Tilkynningar forrita
Name[it]=Notifiche delle applicazioni
Name[ja]=
Name[kk]=Қолданба құлақтандырулары
Name[km]=
Name[kn]=
Name[ko]=
Name[ku]=Hişyariyên Sepanê
Name[lt]=Programų pranešimai
Name[lv]=Programmu paziņojumi
Name[mk]=Известувања за апликации
Name[ml]= ിി
Name[mr]=
Name[nb]=Programvarslinger
Name[nds]=Programm-Bescheden
Name[nl]=Programmameldingen
Name[nn]=Programvarsel
Name[or]= ିିି
Name[pa]= ਿ
Name[pl]=Powiadomienia programów
Name[pt]=Notificações das Aplicações
Name[pt_BR]=Notificações do aplicativo
Name[ro]=Notificări aplicații
Name[ru]=Уведомления приложений
Name[si]=
Name[sk]=Upozornenia aplikácií
Name[sl]=Obvestila programov
Name[sr]=обавештења програма
Name[sr@ijekavian]=обавјештења програма
Name[sr@ijekavianlatin]=obavještenja programa
Name[sr@latin]=obaveštenja programa
Name[sv]=Programunderrättelser
Name[ta]= ி
Name[tg]=Огоҳномаҳои система
Name[th]=
Name[tr]=Uygulama Bildirimleri
Name[ug]=پروگرامما ئۇقتۇرۇشى
Name[uk]=Сповіщення програм
Name[vi]=Thông báo cho ng dng
Name[wa]=Notifiaedjes do programe
Name[x-test]=xxApplication Notificationsxx
Name[zh_CN]=
Name[zh_TW]=
Comment=Passive visual notifications for the user.
Comment[ar]=إشعارات مرئية غير متفاعلة للمستخدم
Comment[ast]=Notificaciones visuales pasives pal usuariu.
Comment[bg]=Пасивни визуални съобщения за потребителя.
Comment[bs]=Pasivna vizuelna obavještenja za korisnika.
Comment[ca]=Notificacions visuals passives per a l'usuari.
Comment[ca@valencia]=Notificacions visuals passives per a l'usuari.
Comment[cs]=Pasivní vizuální upozornění pro uživatele.
Comment[da]=Passive visuelle bekendtgørelser til brugeren.
Comment[de]=Passive sichtbare Benachrichtigungen für den Anwender.
Comment[el]=Παθητικές οπτικές ειδοποιήσεις για το χρήστη.
Comment[en_GB]=Passive visual notifications for the user.
Comment[es]=Notificaciones visuales pasivas para el usuario.
Comment[et]=Passiivsed visuaalsed märguanded kasutajale.
Comment[eu]=Erabiltzailearentzako ikusizko jakinarazpen pasiboak.
Comment[fi]=Passiivinen visuaali-ilmoitus käyttäjälle.
Comment[fr]=Notifications visuelles passives pour l'utilisateur
Comment[fy]=Pasive fisuele notifikaasje foar de brûker.
Comment[gl]=Notificacións visuais pasivas para o usuario.
Comment[he]=הודעות ויזאוליות פאסיביות עבור המשתמש.
Comment[hr]=Pasivne vizualne obavijesti korisniku.
Comment[hu]=Passzív értesítő üzeneteket tud küldeni a felhasználónak.
Comment[ia]=Notificationes visual passive pro le usator.
Comment[id]=Notifikasi visual pasif untuk pengguna.
Comment[is]=Hlutlausar sjónrænar tilkynningar til notandans.
Comment[it]=Notifiche visuali passive per l'utente.
Comment[ja]=
Comment[kk]=Үнсіз көрсетілетін құлақтандыру.
Comment[km]= 
Comment[kn]= ಿಿಿ .
Comment[ko]= .
Comment[lt]=Pasyvūs vizualūs pranešimai naudotojui.
Comment[lv]=Pasīvi vizuālie paziņojumi lietotājam.
Comment[mk]=Пасивни визуелни известувања за корисникот.
Comment[ml]=ി ി
Comment[mr]= .
Comment[nb]=Passive visuelle varslinger for brukeren.
Comment[nds]=Passiev sichtbor Bescheden för den Bruker
Comment[nl]=Passieve visuele meldingen voor de gebruiker.
Comment[nn]=Passive visuelle varsel for brukaren.
Comment[pa]= ਿ ਿ ਿ
Comment[pl]=Bierne, graficzne powiadomienia dla użytkownika.
Comment[pt]=Notificações passivas visuais para o utilizador.
Comment[pt_BR]=Notificações visuais passivas para o usuário.
Comment[ro]=Notificări vizuale pasive pentru utilizator.
Comment[ru]=Пассивные визуальные уведомления для пользователя.
Comment[si]= .
Comment[sk]=Pasívne vizuálne upozornenia pre užívateľa.
Comment[sl]=Pasivna vidna obvestila za uporabnika.
Comment[sr]=Пасивна визуелна обавештења за корисника.
Comment[sr@ijekavian]=Пасивна визуелна обавјештења за корисника.
Comment[sr@ijekavianlatin]=Pasivna vizuelna obavještenja za korisnika.
Comment[sr@latin]=Pasivna vizuelna obaveštenja za korisnika.
Comment[sv]=Passiva visuella underrättelser för användaren.
Comment[th]=
Comment[tr]=Kullanıcı için pasif görsel bildirimler.
Comment[ug]=ئىشلەتكۈچىگە پاسسىپ كۆرۈنىدىغان كۆرۈش ئۈنۈم ئۇقتۇرۇشىنى تەمىنلەيدۇ
Comment[uk]=Пасивні візуальні сповіщення для користувача.
Comment[wa]=Notifiaedjes doirmants veyåves po l' uzeu.
Comment[x-test]=xxPassive visual notifications for the user.xx
Comment[zh_CN]=
Comment[zh_TW]=使
X-KDE-ServiceTypes=Plasma/DataEngine
Type=Service
Icon=preferences-desktop-notification
X-KDE-Library=plasma_engine_notifications
X-KDE-PluginInfo-Author=
X-KDE-PluginInfo-Email=
X-KDE-PluginInfo-Name=notifications
X-KDE-PluginInfo-Version=
X-KDE-PluginInfo-Website=
X-KDE-PluginInfo-Category=