增加通知解析部分逻辑
This commit is contained in:
parent
572f46019a
commit
923dff43f9
|
@ -7,5 +7,10 @@
|
||||||
<arg name="id" type="u" direction="in"/>
|
<arg name="id" type="u" direction="in"/>
|
||||||
<arg name="reason" type="u" direction="in"/>
|
<arg name="reason" type="u" direction="in"/>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="InvokedAction">
|
||||||
|
<arg name="id" type="u" direction="in"/>
|
||||||
|
<arg name="action_key" type="s" direction="in"/>
|
||||||
|
<arg name="display" type="s" direction="in"/>
|
||||||
|
</method>
|
||||||
</interface>
|
</interface>
|
||||||
</node>
|
</node>
|
|
@ -6,10 +6,13 @@ set(ukui-notification_LIB_SRCS
|
||||||
ukui-notification_global.h
|
ukui-notification_global.h
|
||||||
notification-client-private.h
|
notification-client-private.h
|
||||||
)
|
)
|
||||||
|
if(COMMAND qt_add_dbus_interface)
|
||||||
qt_add_dbus_interface(ukui-notification_LIB_SRCS ../dbus/org.freedesktop.Notifications.xml notifications_interface)
|
qt_add_dbus_interface(ukui-notification_LIB_SRCS ../dbus/org.freedesktop.Notifications.xml notifications_interface)
|
||||||
qt_add_dbus_adaptor(ukui-notification_LIB_SRCS ../dbus/org.ukui.NotificationClient.xml notification-client-private.h UkuiNotification::NotificationClientPrivate)
|
qt_add_dbus_adaptor(ukui-notification_LIB_SRCS ../dbus/org.ukui.NotificationClient.xml notification-client-private.h UkuiNotification::NotificationClientPrivate)
|
||||||
|
else()
|
||||||
|
qt5_add_dbus_interface(ukui-notification_LIB_SRCS ../dbus/org.freedesktop.Notifications.xml notifications_interface)
|
||||||
|
qt5_add_dbus_adaptor(ukui-notification_LIB_SRCS ../dbus/org.ukui.NotificationClient.xml notification-client-private.h UkuiNotification::NotificationClientPrivate)
|
||||||
|
endif()
|
||||||
add_library(ukui-notification SHARED ${ukui-notification_LIB_SRCS})
|
add_library(ukui-notification SHARED ${ukui-notification_LIB_SRCS})
|
||||||
target_link_libraries(ukui-notification
|
target_link_libraries(ukui-notification
|
||||||
PRIVATE
|
PRIVATE
|
||||||
|
|
|
@ -7,12 +7,13 @@
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QDBusInterface>
|
#include <QDBusInterface>
|
||||||
#include "notifications_interface.h"
|
#include "notifications_interface.h"
|
||||||
|
#include "notification-client.h"
|
||||||
namespace UkuiNotification {
|
namespace UkuiNotification {
|
||||||
class NotificationClientPrivate : public QObject
|
class NotificationClientPrivate : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit NotificationClientPrivate(QObject *parent = nullptr);
|
explicit NotificationClientPrivate(NotificationClient *q, QObject *parent = nullptr);
|
||||||
~NotificationClientPrivate() override;
|
~NotificationClientPrivate() override;
|
||||||
bool registerClient();
|
bool registerClient();
|
||||||
static QString clientServicePath();
|
static QString clientServicePath();
|
||||||
|
@ -26,10 +27,12 @@ public:
|
||||||
const QStringList &actions,
|
const QStringList &actions,
|
||||||
const QVariantMap &hints,
|
const QVariantMap &hints,
|
||||||
int timeout);
|
int timeout);
|
||||||
void notificationClosed(uint id, uint reason);
|
void closeNotification(uint id, NotificationClient::CloseReason reason);
|
||||||
private:
|
private:
|
||||||
|
void notificationClosed(uint id, uint reason);
|
||||||
OrgFreedesktopNotificationsInterface* m_notificationsInterface = nullptr;
|
OrgFreedesktopNotificationsInterface* m_notificationsInterface = nullptr;
|
||||||
QDBusInterface *m_serverInterface = nullptr;
|
QDBusInterface *m_serverInterface = nullptr;
|
||||||
|
NotificationClient *q;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#endif //UKUI_NOTIFICATION_NOTIFICATION_CLIENT_PRIVATE_H
|
#endif //UKUI_NOTIFICATION_NOTIFICATION_CLIENT_PRIVATE_H
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
using namespace UkuiNotification;
|
using namespace UkuiNotification;
|
||||||
|
|
||||||
NotificationClientPrivate::NotificationClientPrivate(QObject *parent) : QObject(parent)
|
NotificationClientPrivate::NotificationClientPrivate(NotificationClient *q, QObject *parent) : QObject(parent), q(q)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,6 @@ bool NotificationClientPrivate::registerClient()
|
||||||
new NotificationClientAdaptor(this);
|
new NotificationClientAdaptor(this);
|
||||||
QDBusConnection conn = QDBusConnection::sessionBus();
|
QDBusConnection conn = QDBusConnection::sessionBus();
|
||||||
|
|
||||||
|
|
||||||
if(!conn.registerObject(clientServicePath(), clientServiceInterface(), this)) {
|
if(!conn.registerObject(clientServicePath(), clientServiceInterface(), this)) {
|
||||||
qWarning() << "Failed to register NotificationClient DBus object!" << conn.lastError();
|
qWarning() << "Failed to register NotificationClient DBus object!" << conn.lastError();
|
||||||
return false;
|
return false;
|
||||||
|
@ -74,9 +73,35 @@ void NotificationClientPrivate::Notify(const QString &app_name, uint replaces_id
|
||||||
const QString &summary, const QString &body, const QStringList &actions,
|
const QString &summary, const QString &body, const QStringList &actions,
|
||||||
const QVariantMap &hints, int timeout)
|
const QVariantMap &hints, int timeout)
|
||||||
{
|
{
|
||||||
|
PopupNotification notification(replaces_id);
|
||||||
|
notification.setSummary(summary);
|
||||||
|
notification.setBody(body);
|
||||||
|
notification.setApplicationName(app_name);
|
||||||
|
notification.setAplicationIconName(app_icon);
|
||||||
|
notification.setActions(actions);
|
||||||
|
notification.setTimeout(timeout);
|
||||||
|
notification.setHints(hints);
|
||||||
|
Q_EMIT q->newNotification(notification);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NotificationClientPrivate::notificationClosed(uint id, uint reason)
|
void NotificationClientPrivate::notificationClosed(uint id, uint reason)
|
||||||
|
{
|
||||||
|
NotificationClient::CloseReason closeReason = NotificationClient::Undefined;
|
||||||
|
switch (reason) {
|
||||||
|
case 1:
|
||||||
|
closeReason = NotificationClient::Expired;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
closeReason = NotificationClient::DismissedByUser;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
closeReason = NotificationClient::Revoked;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Q_EMIT q->notificationClosed(id, closeReason);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationClientPrivate::closeNotification(uint id, NotificationClient::CloseReason reason)
|
||||||
{
|
{
|
||||||
if(!m_notificationsInterface) {
|
if(!m_notificationsInterface) {
|
||||||
return;
|
return;
|
||||||
|
@ -97,3 +122,8 @@ bool NotificationClient::registerClient()
|
||||||
{
|
{
|
||||||
return d->registerClient();
|
return d->registerClient();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NotificationClient::closeNotification(uint id, NotificationClient::CloseReason reason)
|
||||||
|
{
|
||||||
|
d->closeNotification(id, reason);
|
||||||
|
}
|
|
@ -6,15 +6,34 @@
|
||||||
#define UKUI_NOTIFICATION_NOTIFICATION_CLIENT_H
|
#define UKUI_NOTIFICATION_NOTIFICATION_CLIENT_H
|
||||||
#include "ukui-notification_global.h"
|
#include "ukui-notification_global.h"
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
#include "popup-notification.h"
|
||||||
namespace UkuiNotification {
|
namespace UkuiNotification {
|
||||||
class NotificationClientPrivate;
|
class NotificationClientPrivate;
|
||||||
class UKUINOTIFICATION_EXPORT NotificationClient : public QObject
|
class UKUINOTIFICATION_EXPORT NotificationClient : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
NotificationClient(QObject *parent);
|
/**
|
||||||
~NotificationClient() override;
|
* The reason a notification was closed
|
||||||
|
*/
|
||||||
|
enum CloseReason {
|
||||||
|
Expired = 1, // The notification expired(timed out).
|
||||||
|
DismissedByUser = 2, // The notification was dismissed by the user.
|
||||||
|
Revoked = 3, //< The notification was closed by sender by a call to CloseNotification.
|
||||||
|
Undefined = 4, //Undefined/reserved reasons.
|
||||||
|
};
|
||||||
|
Q_ENUM(CloseReason)
|
||||||
|
explicit NotificationClient(QObject *parent);
|
||||||
|
~NotificationClient();
|
||||||
|
/**
|
||||||
|
* 注册成为弹窗通知客户端
|
||||||
|
* @return ture-成功 false 失败
|
||||||
|
*/
|
||||||
bool registerClient();
|
bool registerClient();
|
||||||
|
void closeNotification(uint id, CloseReason reason);
|
||||||
|
Q_SIGNALS:
|
||||||
|
void newNotification(const PopupNotification ¬ification);
|
||||||
|
void notificationClosed(uint id, CloseReason closeReason);
|
||||||
private:
|
private:
|
||||||
NotificationClientPrivate *d = nullptr;
|
NotificationClientPrivate *d = nullptr;
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,31 +3,153 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "popup-notification.h"
|
#include "popup-notification.h"
|
||||||
class PopupNotificationPrvate
|
#include <QDBusArgument>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QImageReader>
|
||||||
|
namespace UkuiNotification {
|
||||||
|
class PopupNotificationPrivate
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PopupNotificationPrvate();
|
PopupNotificationPrivate();
|
||||||
~PopupNotificationPrvate();
|
~PopupNotificationPrivate();
|
||||||
|
QImage parseImageHint(const QDBusArgument &arg);
|
||||||
|
void loadImageFromPath(const QString &path);
|
||||||
|
QSize maximumImageSize();
|
||||||
|
|
||||||
|
uint m_id = 0;
|
||||||
|
QString m_applicationName;
|
||||||
|
QString m_applicationIconName;
|
||||||
|
QString m_summary;
|
||||||
|
QString m_body;
|
||||||
|
QList<QPair<QString, QString>> m_actions;
|
||||||
|
bool m_hasDefaultAction = false;
|
||||||
|
QString m_defaultActionInfo;
|
||||||
|
QVariantMap m_hints = QVariantMap();
|
||||||
|
QString m_category;
|
||||||
|
QImage m_image;
|
||||||
|
QString m_icon;
|
||||||
|
QDateTime m_createdTime;
|
||||||
|
QString m_desktopEntry;
|
||||||
|
PopupNotification::Urgency m_urgency = PopupNotification::NormalUrgency;
|
||||||
|
int m_timeout = -1;
|
||||||
|
bool m_resident = false;
|
||||||
|
bool m_transient = false;
|
||||||
|
QString m_soundFile;
|
||||||
|
bool m_suppressSound = false;
|
||||||
|
QString m_display;
|
||||||
|
|
||||||
};
|
};
|
||||||
PopupNotificationPrvate::PopupNotificationPrvate()
|
}
|
||||||
{
|
using namespace UkuiNotification;
|
||||||
|
|
||||||
|
PopupNotificationPrivate::PopupNotificationPrivate()
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
PopupNotificationPrvate::~PopupNotificationPrvate()
|
PopupNotificationPrivate::~PopupNotificationPrivate() = default;
|
||||||
{
|
|
||||||
|
|
||||||
|
QImage PopupNotificationPrivate::parseImageHint(const QDBusArgument &arg)
|
||||||
|
{
|
||||||
|
//copy from plasma-workspace
|
||||||
|
int width, height, rowStride, hasAlpha, bitsPerSample, channels;
|
||||||
|
QByteArray pixels;
|
||||||
|
char *ptr;
|
||||||
|
char *end;
|
||||||
|
|
||||||
|
arg.beginStructure();
|
||||||
|
arg >> width >> height >> rowStride >> hasAlpha >> bitsPerSample >> channels >> pixels;
|
||||||
|
arg.endStructure();
|
||||||
|
|
||||||
|
auto 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]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
auto 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]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
QImage::Format format = QImage::Format_Invalid;
|
||||||
|
void (*fcn)(QRgb *, const char *, int) = nullptr;
|
||||||
|
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) {
|
||||||
|
qWarning() << "Unsupported image format (hasAlpha:" << hasAlpha << "bitsPerSample:" << bitsPerSample
|
||||||
|
<< "channels:" << channels << ")";
|
||||||
|
return QImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
PopupNotification::PopupNotification(uint id, QObject *parent) : QObject(parent)
|
QImage image(width, height, format);
|
||||||
{
|
ptr = pixels.data();
|
||||||
|
end = ptr + pixels.length();
|
||||||
|
for (int y = 0; y < height; ++y, ptr += rowStride) {
|
||||||
|
if (ptr + channels * width > end) {
|
||||||
|
qWarning() << "Image data is incomplete. y:" << y << "height:" << height;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fcn((QRgb *)image.scanLine(y), ptr, width);
|
||||||
}
|
}
|
||||||
|
|
||||||
PopupNotification::PopupNotification(const PopupNotification &other)
|
return image;
|
||||||
{
|
}
|
||||||
|
|
||||||
|
void PopupNotificationPrivate::loadImageFromPath(const QString &path)
|
||||||
|
{
|
||||||
|
//copy from plasma-workspace
|
||||||
|
QUrl imageUrl;
|
||||||
|
if (path.startsWith(QLatin1Char('/'))) {
|
||||||
|
imageUrl = QUrl::fromLocalFile(path);
|
||||||
|
} else if (path.contains(QLatin1Char('/'))) {
|
||||||
|
imageUrl = QUrl(path);
|
||||||
|
|
||||||
|
if (!imageUrl.isLocalFile()) {
|
||||||
|
qDebug() << "Refused to load image from" << path << "which isn't a valid local location.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!imageUrl.isValid()) {
|
||||||
|
m_icon = path;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QImageReader reader(imageUrl.toLocalFile());
|
||||||
|
reader.setAutoTransform(true);
|
||||||
|
|
||||||
|
const QSize imageSize = reader.size();
|
||||||
|
if (imageSize.isValid() && (imageSize.width() > maximumImageSize().width() || imageSize.height() > maximumImageSize().height())) {
|
||||||
|
const QSize thumbnailSize = imageSize.scaled(maximumImageSize(), Qt::KeepAspectRatio);
|
||||||
|
reader.setScaledSize(thumbnailSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_image = reader.read();
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize PopupNotificationPrivate::maximumImageSize()
|
||||||
|
{
|
||||||
|
return QSize(256, 256);
|
||||||
|
}
|
||||||
|
|
||||||
|
PopupNotification::PopupNotification(uint id, QObject *parent) : QObject(parent), d(new PopupNotificationPrivate())
|
||||||
|
{
|
||||||
|
d->m_id = id;
|
||||||
|
d->m_createdTime = QDateTime::currentDateTimeUtc();
|
||||||
|
}
|
||||||
|
|
||||||
|
PopupNotification::PopupNotification(const PopupNotification &other) : d(new PopupNotificationPrivate(*other.d))
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
PopupNotification &PopupNotification::operator=( const PopupNotification &other)
|
PopupNotification &PopupNotification::operator=( const PopupNotification &other)
|
||||||
|
@ -44,132 +166,209 @@ PopupNotification &PopupNotification::operator=(PopupNotification &&other) Q_DEC
|
||||||
}
|
}
|
||||||
PopupNotification::~PopupNotification()
|
PopupNotification::~PopupNotification()
|
||||||
{
|
{
|
||||||
|
if(d) {
|
||||||
|
delete d;
|
||||||
|
d = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString PopupNotification::applicationName() const
|
QString PopupNotification::applicationName() const
|
||||||
{
|
{
|
||||||
return QString();
|
return d->m_applicationName;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PopupNotification::setApplicationName(const QString &applicationName)
|
void PopupNotification::setApplicationName(const QString &applicationName)
|
||||||
{
|
{
|
||||||
|
d->m_applicationName = applicationName;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString PopupNotification::icon() const
|
QString PopupNotification::applicationIconName() const
|
||||||
{
|
{
|
||||||
return QString();
|
return d->m_applicationIconName;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PopupNotification::setIcon(const QString &icon)
|
void PopupNotification::setAplicationIconName(const QString &applicationIconName)
|
||||||
{
|
{
|
||||||
|
d->m_applicationIconName = applicationIconName;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString PopupNotification::summary() const
|
QString PopupNotification::summary() const
|
||||||
{
|
{
|
||||||
return QString();
|
return d->m_summary;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PopupNotification::setSummary(const QString &summary)
|
void PopupNotification::setSummary(const QString &summary)
|
||||||
{
|
{
|
||||||
|
d->m_summary = summary;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString PopupNotification::body() const
|
QString PopupNotification::body() const
|
||||||
{
|
{
|
||||||
return QString();
|
return d->m_body;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PopupNotification::setBody(const QString &body)
|
void PopupNotification::setBody(const QString &body)
|
||||||
{
|
{
|
||||||
|
d->m_body = body;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PopupNotification::hasDefaultAction() const
|
bool PopupNotification::hasDefaultAction() const
|
||||||
{
|
{
|
||||||
return false;
|
return d->m_hasDefaultAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString PopupNotification::defauleActionLable()
|
||||||
|
{
|
||||||
|
return d->m_defaultActionInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PopupNotification::setActions(const QStringList &actions)
|
void PopupNotification::setActions(const QStringList &actions)
|
||||||
{
|
{
|
||||||
|
if (actions.count() % 2 != 0) {
|
||||||
|
qWarning() << "List of actions must contain an even number of items, tried to set actions to" << actions;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
d->m_hasDefaultAction = false;
|
||||||
|
|
||||||
|
for (int i = 0; i < actions.count(); i += 2) {
|
||||||
|
const QString &name = actions.at(i);
|
||||||
|
const QString &info = actions.at(i + 1);
|
||||||
|
|
||||||
|
if (!d->m_hasDefaultAction && name == QLatin1String("default")) {
|
||||||
|
d->m_hasDefaultAction = true;
|
||||||
|
d->m_defaultActionInfo = info;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
d->m_actions.append({name, info});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<QPair<QString, QString>> PopupNotification::getActions()
|
QList<QPair<QString, QString>> PopupNotification::getActions()
|
||||||
{
|
{
|
||||||
return QList<QPair<QString, QString>>();
|
return d->m_actions;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariantMap PopupNotification::hints() const
|
QVariantMap PopupNotification::hints() const
|
||||||
{
|
{
|
||||||
return QVariantMap();
|
return d->m_hints;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PopupNotification::setHints(const QVariantMap &hints)
|
void PopupNotification::setHints(const QVariantMap &hints)
|
||||||
{
|
{
|
||||||
|
d->m_hints = hints;
|
||||||
|
d->m_desktopEntry = hints.value(QStringLiteral("desktop-entry")).toString();
|
||||||
|
bool ok;
|
||||||
|
int urgency = hints.value(QStringLiteral("urgency")).toInt(&ok);
|
||||||
|
if(ok) {
|
||||||
|
switch (urgency) {
|
||||||
|
case 0:
|
||||||
|
setUrgency(Urgency::LowUrgency);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
setUrgency(Urgency::NormalUrgency);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
setUrgency(Urgency::CriticalUrgency);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
d->m_resident = hints.value(QStringLiteral("resident")).toBool();
|
||||||
|
d->m_resident = hints.value(QStringLiteral("transient")).toBool();
|
||||||
|
d->m_category = hints.value(QStringLiteral("category")).toString();
|
||||||
|
|
||||||
|
auto end = hints.end();
|
||||||
|
auto it = hints.find(QStringLiteral("image-data"));
|
||||||
|
if (it != end) {
|
||||||
|
d->m_image = d->parseImageHint(it->value<QDBusArgument>());
|
||||||
|
if (d->m_image.isNull()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const QSize max = d->maximumImageSize();
|
||||||
|
if (d->m_image.size().width() > max.width() || d->m_image.size().height() > max.height()) {
|
||||||
|
d->m_image = d->m_image.scaled(max, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (d->m_image.isNull()) {
|
||||||
|
it = hints.find(QStringLiteral("image-path"));
|
||||||
|
|
||||||
|
if (it != end) {
|
||||||
|
d->loadImageFromPath(it->toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//暂不支持声音主题
|
||||||
|
d->m_soundFile = hints.value(QStringLiteral("sound-file")).toString();
|
||||||
|
d->m_suppressSound = hints.value(QStringLiteral("suppress-sound")).toBool();
|
||||||
|
d->m_display = hints.value(QStringLiteral("x-ukui-display")).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
int PopupNotification::timeout() const
|
int PopupNotification::timeout() const
|
||||||
{
|
{
|
||||||
return 0;
|
return d->m_timeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PopupNotification::setTimeout(int timeout)
|
void PopupNotification::setTimeout(int timeout)
|
||||||
{
|
{
|
||||||
|
d->m_timeout = timeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
QDateTime PopupNotification::created() const
|
QDateTime PopupNotification::createdTime() const
|
||||||
{
|
{
|
||||||
return QDateTime();
|
return d->m_createdTime;
|
||||||
}
|
|
||||||
|
|
||||||
void PopupNotification::setCreated(const QDateTime &created)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PopupNotification::enableActionIcons() const
|
bool PopupNotification::enableActionIcons() const
|
||||||
{
|
{
|
||||||
|
//TODO 可以支持action-icon
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString PopupNotification::category() const
|
QString PopupNotification::category() const
|
||||||
{
|
{
|
||||||
return QString();
|
return d->m_category;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString PopupNotification::desktopEntry() const
|
QString PopupNotification::desktopEntry() const
|
||||||
{
|
{
|
||||||
return QString();
|
return d->m_desktopEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
QImage PopupNotification::image() const
|
QImage PopupNotification::image() const
|
||||||
{
|
{
|
||||||
return QImage();
|
return d->m_image;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString PopupNotification::icon() const
|
||||||
|
{
|
||||||
|
return d->m_icon;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PopupNotification::resident() const
|
bool PopupNotification::resident() const
|
||||||
{
|
{
|
||||||
return false;
|
return d->m_resident;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString PopupNotification::soundFile() const
|
QString PopupNotification::soundFile() const
|
||||||
{
|
{
|
||||||
return QString();
|
return d->m_soundFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PopupNotification::suppressSound() const
|
||||||
|
{
|
||||||
|
return d->m_suppressSound;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PopupNotification::transient() const
|
bool PopupNotification::transient() const
|
||||||
{
|
{
|
||||||
return false;
|
return d->m_transient;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString PopupNotification::display() const
|
||||||
|
{
|
||||||
|
return d->m_display;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PopupNotification::setUrgency(PopupNotification::Urgency urgency)
|
void PopupNotification::setUrgency(PopupNotification::Urgency urgency)
|
||||||
{
|
{
|
||||||
|
d->m_urgency = urgency;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,11 @@
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
#include <QVariantMap>
|
#include <QVariantMap>
|
||||||
#include <QImage>
|
#include <QImage>
|
||||||
class PopupNotificationPrvate;
|
#include <QList>
|
||||||
|
#include <QPair>
|
||||||
|
namespace UkuiNotification {
|
||||||
|
class PopupNotificationPrivate;
|
||||||
|
//TODO 可以增加通知基类,实现多种类型通知
|
||||||
class UKUINOTIFICATION_EXPORT PopupNotification : public QObject
|
class UKUINOTIFICATION_EXPORT PopupNotification : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -21,13 +25,11 @@ public:
|
||||||
* The notification urgency.
|
* The notification urgency.
|
||||||
*/
|
*/
|
||||||
enum Urgency {
|
enum Urgency {
|
||||||
LowUrgency = 1 << 0,
|
LowUrgency = 0,
|
||||||
NormalUrgency = 1 << 1,
|
NormalUrgency = 1,
|
||||||
CriticalUrgency = 1 << 2,
|
CriticalUrgency = 2,
|
||||||
};
|
};
|
||||||
Q_ENUM(Urgency)
|
Q_ENUM(Urgency)
|
||||||
Q_DECLARE_FLAGS(Urgencies, Urgency)
|
|
||||||
Q_FLAG(Urgencies)
|
|
||||||
|
|
||||||
explicit PopupNotification(uint id = 0, QObject *parent = nullptr);
|
explicit PopupNotification(uint id = 0, QObject *parent = nullptr);
|
||||||
PopupNotification(const PopupNotification &other);
|
PopupNotification(const PopupNotification &other);
|
||||||
|
@ -38,8 +40,8 @@ public:
|
||||||
QString applicationName() const;
|
QString applicationName() const;
|
||||||
void setApplicationName(const QString &applicationName);
|
void setApplicationName(const QString &applicationName);
|
||||||
|
|
||||||
QString icon() const;
|
QString applicationIconName() const;
|
||||||
void setIcon(const QString &icon);
|
void setAplicationIconName(const QString &applicationIconName);
|
||||||
|
|
||||||
QString summary() const;
|
QString summary() const;
|
||||||
void setSummary(const QString &summary);
|
void setSummary(const QString &summary);
|
||||||
|
@ -48,6 +50,7 @@ public:
|
||||||
void setBody(const QString &body);
|
void setBody(const QString &body);
|
||||||
|
|
||||||
bool hasDefaultAction() const;
|
bool hasDefaultAction() const;
|
||||||
|
QString defauleActionLable();
|
||||||
void setActions(const QStringList &actions);
|
void setActions(const QStringList &actions);
|
||||||
QList<QPair<QString, QString>> getActions();
|
QList<QPair<QString, QString>> getActions();
|
||||||
|
|
||||||
|
@ -57,24 +60,55 @@ public:
|
||||||
int timeout() const;
|
int timeout() const;
|
||||||
void setTimeout(int timeout);
|
void setTimeout(int timeout);
|
||||||
|
|
||||||
QDateTime created() const;
|
QDateTime createdTime() const;
|
||||||
void setCreated(const QDateTime &created);
|
//m_hints
|
||||||
|
/**
|
||||||
//hints
|
* 使用图标显示action
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
bool enableActionIcons() const;
|
bool enableActionIcons() const;
|
||||||
|
/**
|
||||||
|
* 分类
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
QString category() const;
|
QString category() const;
|
||||||
|
/**
|
||||||
|
* desktop名称(不带.desktop后缀)
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
QString desktopEntry() const;
|
QString desktopEntry() const;
|
||||||
|
/**
|
||||||
|
* 对应image-data字段
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
QImage image() const;
|
QImage image() const;
|
||||||
|
/**
|
||||||
|
* 当加载image-data失败,或通过image-path加载image失败时(image-path不是URL),icon会被设置为image-path数据
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
QString icon() const;
|
||||||
|
/**
|
||||||
|
* 是否持续显示,不会自动移除,直到被用户手动或发送者删除
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
bool resident() const;
|
bool resident() const;
|
||||||
|
/**
|
||||||
|
* 声音
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
QString soundFile() const;
|
QString soundFile() const;
|
||||||
|
/**
|
||||||
|
* 暂时通知(会自动移除)
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
bool suppressSound() const;
|
||||||
bool transient() const;
|
bool transient() const;
|
||||||
|
|
||||||
void setUrgency(Urgency urgency);
|
void setUrgency(Urgency urgency);
|
||||||
|
QString display() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PopupNotificationPrvate *d = nullptr;
|
PopupNotificationPrivate *d = nullptr;
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
#endif //UKUI_NOTIFICATION_POPUP_NOTIFICATION_H
|
#endif //UKUI_NOTIFICATION_POPUP_NOTIFICATION_H
|
||||||
|
|
|
@ -18,10 +18,13 @@ set(notificationServer_SRCS
|
||||||
notification.cpp
|
notification.cpp
|
||||||
notification.h
|
notification.h
|
||||||
)
|
)
|
||||||
|
if(COMMAND qt_add_dbus_adaptor)
|
||||||
qt_add_dbus_adaptor(notificationServer_SRCS ../dbus/org.freedesktop.Notifications.xml server-private.h NotificationServer::ServerPrivate)
|
qt_add_dbus_adaptor(notificationServer_SRCS ../dbus/org.freedesktop.Notifications.xml server-private.h NotificationServer::ServerPrivate)
|
||||||
qt_add_dbus_adaptor(notificationServer_SRCS ../dbus/org.ukui.NotificationServer.xml server-private.h NotificationServer::ServerPrivate)
|
qt_add_dbus_adaptor(notificationServer_SRCS ../dbus/org.ukui.NotificationServer.xml server-private.h NotificationServer::ServerPrivate)
|
||||||
|
else()
|
||||||
|
qt5_add_dbus_adaptor(notificationServer_SRCS ../dbus/org.freedesktop.Notifications.xml server-private.h NotificationServer::ServerPrivate)
|
||||||
|
qt5_add_dbus_adaptor(notificationServer_SRCS ../dbus/org.ukui.NotificationServer.xml server-private.h NotificationServer::ServerPrivate)
|
||||||
|
endif()
|
||||||
add_executable(ukui-notification-server ${notificationServer_SRCS})
|
add_executable(ukui-notification-server ${notificationServer_SRCS})
|
||||||
target_include_directories(ukui-notification-server PUBLIC ${3rdParties_DIR})
|
target_include_directories(ukui-notification-server PUBLIC ${3rdParties_DIR})
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ public:
|
||||||
const QVariantMap &hints,
|
const QVariantMap &hints,
|
||||||
int timeout);
|
int timeout);
|
||||||
void CloseNotification(uint id);
|
void CloseNotification(uint id);
|
||||||
QString GetServerInformation(QString &vendor, QString &version, QString &specVersion) const;
|
QString GetServerInformation(QString &vendor, QString &version, QString &spec_version) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 注册成为通知中心客户端
|
* 注册成为通知中心客户端
|
||||||
|
@ -51,6 +51,7 @@ public:
|
||||||
* @param reason 关闭原因
|
* @param reason 关闭原因
|
||||||
*/
|
*/
|
||||||
void CloseNotification(uint id, uint);
|
void CloseNotification(uint id, uint);
|
||||||
|
void InvokedAction(uint id, const QString &action_key, const QString &display);
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void NotificationClosed(uint id, uint reason);
|
void NotificationClosed(uint id, uint reason);
|
||||||
void ActionInvoked(uint id, const QString &actionKey);
|
void ActionInvoked(uint id, const QString &actionKey);
|
||||||
|
|
|
@ -33,7 +33,7 @@ uint ServerPrivate::Notify(const QString &app_name, uint replaces_id, const QStr
|
||||||
id = m_increasedNotificationId++;
|
id = m_increasedNotificationId++;
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO 在hint中增加DISPLAY信息。
|
//TODO 在hint中增加DISPLAY信息,注意区分X和wayland,DISPLAY信息决定了通知弹窗显示和action执行所在的DISPLAY
|
||||||
|
|
||||||
for(const QString &service : m_notificationWatchers->watchedServices()) {
|
for(const QString &service : m_notificationWatchers->watchedServices()) {
|
||||||
QDBusMessage msg = QDBusMessage::createMethodCall(service,
|
QDBusMessage msg = QDBusMessage::createMethodCall(service,
|
||||||
|
@ -46,7 +46,7 @@ uint ServerPrivate::Notify(const QString &app_name, uint replaces_id, const QStr
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ServerPrivate::GetServerInformation(QString &vendor, QString &version, QString &specVersion) const
|
QString ServerPrivate::GetServerInformation(QString &vendor, QString &version, QString &spec_version) const
|
||||||
{
|
{
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
@ -106,8 +106,15 @@ void ServerPrivate::UnRegisterClient()
|
||||||
m_notificationWatchers->removeWatchedService(message().service());
|
m_notificationWatchers->removeWatchedService(message().service());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerPrivate::CloseNotification(uint id, uint)
|
void ServerPrivate::CloseNotification(uint id, uint reason)
|
||||||
{
|
{
|
||||||
|
Q_EMIT NotificationClosed(id, reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerPrivate::InvokedAction(uint id, const QString &action_key, const QString &display)
|
||||||
|
{
|
||||||
|
//TODO: 异步执行action
|
||||||
|
Q_EMIT ActionInvoked(id, action_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
Server::Server(QObject *parent): QObject(parent), d(new ServerPrivate(this))
|
Server::Server(QObject *parent): QObject(parent), d(new ServerPrivate(this))
|
||||||
|
|
Loading…
Reference in New Issue