mirror of
https://bitbucket.org/smil3y/kde-workspace.git
synced 2025-02-23 10:22:49 +00:00
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:
parent
278acc1fce
commit
3f41dc2c37
19 changed files with 121 additions and 852 deletions
|
@ -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)
|
||||
|
|
|
@ -5,6 +5,7 @@ set(notifications_SRCS
|
|||
jobswidget.cpp
|
||||
jobtrackeradaptor.cpp
|
||||
applicationswidget.cpp
|
||||
notificationsadaptor.cpp
|
||||
)
|
||||
|
||||
kde4_add_plugin(plasma_applet_notifications ${notifications_SRCS})
|
||||
|
|
|
@ -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()));
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
|
||||
#include <QDBusConnection>
|
||||
#include <QGraphicsGridLayout>
|
||||
#include <Plasma/DataEngineManager>
|
||||
#include <Plasma/Animation>
|
||||
#include <KRun>
|
||||
#include <KIconLoader>
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
#include <Plasma/Frame>
|
||||
#include <Plasma/IconWidget>
|
||||
#include <Plasma/Meter>
|
||||
#include <Plasma/DataEngine>
|
||||
|
||||
class NotificationsWidget;
|
||||
|
||||
|
|
51
plasma/applets/notifications/notificationsadaptor.cpp
Normal file
51
plasma/applets/notifications/notificationsadaptor.cpp
Normal 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"
|
49
plasma/applets/notifications/notificationsadaptor.h
Normal file
49
plasma/applets/notifications/notificationsadaptor.h
Normal 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
|
|
@ -1 +0,0 @@
|
|||
add_subdirectory(notifications)
|
|
@ -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})
|
|
@ -1,2 +0,0 @@
|
|||
#!/bin/bash
|
||||
$XGETTEXT *.cpp -o $podir/plasma_engine_notifications.pot
|
|
@ -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"
|
||||
|
|
@ -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
|
|
@ -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"
|
|
@ -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
|
|
@ -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"
|
||||
|
|
@ -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
|
|
@ -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>
|
|
@ -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 dụng
|
||||
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=
|
Loading…
Add table
Reference in a new issue