Skip to content

Commit a13c9d9

Browse files
committed
service/notifications: adopt bindable properties
1 parent abb900b commit a13c9d9

File tree

2 files changed

+81
-112
lines changed

2 files changed

+81
-112
lines changed

src/services/notifications/notification.cpp

Lines changed: 35 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,16 @@
33

44
#include <qcontainerfwd.h>
55
#include <qdbusargument.h>
6+
#include <qlist.h>
67
#include <qlogging.h>
78
#include <qloggingcategory.h>
9+
#include <qobject.h>
10+
#include <qproperty.h>
811
#include <qtmetamacros.h>
912
#include <qtypes.h>
1013

1114
#include "../../core/desktopentry.hpp"
1215
#include "../../core/iconimageprovider.hpp"
13-
#include "../../core/util.hpp"
1416
#include "dbusimage.hpp"
1517
#include "server.hpp"
1618

@@ -84,34 +86,51 @@ void Notification::updateProperties(
8486
QVariantMap hints,
8587
qint32 expireTimeout
8688
) {
87-
auto urgency = hints.contains("urgency") ? hints.value("urgency").value<quint8>()
88-
: static_cast<quint8>(NotificationUrgency::Normal);
89+
Qt::beginPropertyUpdateGroup();
90+
91+
this->bExpireTimeout = expireTimeout;
92+
this->bAppName = appName;
93+
this->bSummary = summary;
94+
this->bBody = body;
95+
this->bHasActionIcons = hints.value("action-icons").toBool();
96+
this->bResident = hints.value("resident").toBool();
97+
this->bTransient = hints.value("transient").toBool();
98+
this->bDesktopEntry = hints.value("desktop-entry").toString();
99+
100+
this->bUrgency = hints.contains("urgency")
101+
? hints.value("urgency").value<NotificationUrgency::Enum>()
102+
: NotificationUrgency::Normal;
103+
104+
if (appIcon.isEmpty() && !this->bDesktopEntry.value().isEmpty()) {
105+
if (auto* entry = DesktopEntryManager::instance()->byId(this->bDesktopEntry.value())) {
106+
appIcon = entry->mIcon;
107+
}
108+
}
89109

90-
auto hasActionIcons = hints.value("action-icons").value<bool>();
91-
auto resident = hints.value("resident").value<bool>();
92-
auto transient = hints.value("transient").value<bool>();
93-
auto desktopEntry = hints.value("desktop-entry").value<QString>();
110+
this->bAppIcon = appIcon;
94111

95112
QString imageDataName;
96113
if (hints.contains("image-data")) imageDataName = "image-data";
97114
else if (hints.contains("image_data")) imageDataName = "image_data";
98115
else if (hints.contains("icon_data")) imageDataName = "icon_data";
99116

100-
NotificationImage* imagePixmap = nullptr;
117+
QString imagePath;
118+
101119
if (!imageDataName.isEmpty()) {
102120
auto value = hints.value(imageDataName).value<QDBusArgument>();
103121
DBusNotificationImage image;
104122
value >> image;
105-
imagePixmap = new NotificationImage(std::move(image), this);
123+
if (this->mImagePixmap) this->mImagePixmap->deleteLater();
124+
this->mImagePixmap = new NotificationImage(std::move(image), this);
125+
imagePath = this->mImagePixmap->url();
106126
}
107127

108-
// don't store giant byte arrays more than necessary
128+
// don't store giant byte arrays longer than necessary
109129
hints.remove("image-data");
110130
hints.remove("image_data");
111131
hints.remove("icon_data");
112132

113-
QString imagePath;
114-
if (!imagePixmap) {
133+
if (!this->mImagePixmap) {
115134
QString imagePathName;
116135
if (hints.contains("image-path")) imagePathName = "image-path";
117136
else if (hints.contains("image_path")) imagePathName = "image_path";
@@ -125,32 +144,10 @@ void Notification::updateProperties(
125144
}
126145
}
127146

128-
if (appIcon.isEmpty() && !desktopEntry.isEmpty()) {
129-
if (auto* entry = DesktopEntryManager::instance()->byId(desktopEntry)) {
130-
appIcon = entry->mIcon;
131-
}
132-
}
147+
this->bImage = imagePath;
148+
this->bHints = hints;
133149

134-
auto expireTimeoutChanged = this->setExpireTimeout(expireTimeout);
135-
auto appNameChanged = this->setAppName(appName);
136-
auto appIconChanged = this->setAppIcon(appIcon);
137-
auto summaryChanged = this->setSummary(summary);
138-
auto bodyChanged = this->setBody(body);
139-
auto urgencyChanged = this->setUrgency(static_cast<NotificationUrgency::Enum>(urgency));
140-
auto hasActionIconsChanged = this->setHasActionIcons(hasActionIcons);
141-
auto residentChanged = this->setResident(resident);
142-
auto transientChanged = this->setTransient(transient);
143-
auto desktopEntryChanged = this->setDesktopEntry(desktopEntry);
144-
DEFINE_DROP_EMIT_IF(imagePixmap || imagePath != this->mImagePath, this, imageChanged);
145-
auto hintsChanged = this->setHints(hints);
146-
147-
NotificationImage* oldImage = nullptr;
148-
149-
if (imageChanged) {
150-
oldImage = this->mImagePixmap;
151-
this->mImagePixmap = imagePixmap;
152-
this->mImagePath = imagePath;
153-
}
150+
Qt::endPropertyUpdateGroup();
154151

155152
bool actionsChanged = false;
156153
auto deletedActions = QVector<NotificationAction*>();
@@ -191,32 +188,16 @@ void Notification::updateProperties(
191188
<< "sent an action set of an invalid length.";
192189
}
193190

194-
DropEmitter::call(
195-
expireTimeoutChanged,
196-
appNameChanged,
197-
appIconChanged,
198-
summaryChanged,
199-
bodyChanged,
200-
urgencyChanged,
201-
hasActionIconsChanged,
202-
residentChanged,
203-
transientChanged,
204-
desktopEntryChanged,
205-
imageChanged,
206-
hintsChanged
207-
);
208-
209191
if (actionsChanged) emit this->actionsChanged();
210192

211193
for (auto* action: deletedActions) {
212194
delete action;
213195
}
214-
215-
delete oldImage;
216196
}
217197

218198
quint32 Notification::id() const { return this->mId; }
219199
bool Notification::isTracked() const { return this->mCloseReason == 0; }
200+
QList<NotificationAction*> Notification::actions() const { return this->mActions; }
220201
NotificationCloseReason::Enum Notification::closeReason() const { return this->mCloseReason; }
221202

222203
void Notification::setTracked(bool tracked) {
@@ -228,26 +209,4 @@ void Notification::setTracked(bool tracked) {
228209
bool Notification::isLastGeneration() const { return this->mLastGeneration; }
229210
void Notification::setLastGeneration() { this->mLastGeneration = true; }
230211

231-
DEFINE_MEMBER_GETSET(Notification, expireTimeout, setExpireTimeout);
232-
DEFINE_MEMBER_GETSET(Notification, appName, setAppName);
233-
DEFINE_MEMBER_GETSET(Notification, appIcon, setAppIcon);
234-
DEFINE_MEMBER_GETSET(Notification, summary, setSummary);
235-
DEFINE_MEMBER_GETSET(Notification, body, setBody);
236-
DEFINE_MEMBER_GETSET(Notification, urgency, setUrgency);
237-
DEFINE_MEMBER_GET(Notification, actions);
238-
DEFINE_MEMBER_GETSET(Notification, hasActionIcons, setHasActionIcons);
239-
DEFINE_MEMBER_GETSET(Notification, resident, setResident);
240-
DEFINE_MEMBER_GETSET(Notification, transient, setTransient);
241-
DEFINE_MEMBER_GETSET(Notification, desktopEntry, setDesktopEntry);
242-
243-
QString Notification::image() const {
244-
if (this->mImagePixmap) {
245-
return this->mImagePixmap->url();
246-
} else {
247-
return this->mImagePath;
248-
}
249-
}
250-
251-
DEFINE_MEMBER_GETSET(Notification, hints, setHints);
252-
253212
} // namespace qs::service::notifications

src/services/notifications/notification.hpp

Lines changed: 46 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <utility>
44

55
#include <qcontainerfwd.h>
6+
#include <qlist.h>
67
#include <qmap.h>
78
#include <qobject.h>
89
#include <qqmlintegration.h>
@@ -80,18 +81,18 @@ class Notification
8081
/// if @@NotificationServer.keepOnReload is true.
8182
Q_PROPERTY(bool lastGeneration READ isLastGeneration CONSTANT);
8283
/// Time in seconds the notification should be valid for
83-
Q_PROPERTY(qreal expireTimeout READ expireTimeout NOTIFY expireTimeoutChanged);
84+
Q_PROPERTY(qreal expireTimeout READ expireTimeout NOTIFY expireTimeoutChanged BINDABLE bindableExpireTimeout);
8485
/// The sending application's name.
85-
Q_PROPERTY(QString appName READ appName NOTIFY appNameChanged);
86+
Q_PROPERTY(QString appName READ appName NOTIFY appNameChanged BINDABLE bindableAppName);
8687
/// The sending application's icon. If none was provided, then the icon from an associated
8788
/// desktop entry will be retrieved. If none was found then "".
88-
Q_PROPERTY(QString appIcon READ appIcon NOTIFY appIconChanged);
89+
Q_PROPERTY(QString appIcon READ appIcon NOTIFY appIconChanged BINDABLE bindableAppIcon);
8990
/// The image associated with this notification, or "" if none.
90-
Q_PROPERTY(QString summary READ summary NOTIFY summaryChanged);
91-
Q_PROPERTY(QString body READ body NOTIFY bodyChanged);
92-
Q_PROPERTY(qs::service::notifications::NotificationUrgency::Enum urgency READ urgency NOTIFY urgencyChanged);
91+
Q_PROPERTY(QString summary READ summary NOTIFY summaryChanged BINDABLE bindableSummary);
92+
Q_PROPERTY(QString body READ body NOTIFY bodyChanged BINDABLE bindableBody);
93+
Q_PROPERTY(qs::service::notifications::NotificationUrgency::Enum urgency READ urgency NOTIFY urgencyChanged BINDABLE bindableUrgency);
9394
/// Actions that can be taken for this notification.
94-
Q_PROPERTY(QVector<qs::service::notifications::NotificationAction*> actions READ actions NOTIFY actionsChanged);
95+
Q_PROPERTY(QList<qs::service::notifications::NotificationAction*> actions READ actions NOTIFY actionsChanged);
9596
/// If actions associated with this notification have icons available.
9697
///
9798
/// See @@NotificationAction.identifier for details.
@@ -136,15 +137,29 @@ class Notification
136137
void close(NotificationCloseReason::Enum reason);
137138

138139
[[nodiscard]] quint32 id() const;
139-
140140
[[nodiscard]] bool isTracked() const;
141-
[[nodiscard]] NotificationCloseReason::Enum closeReason() const;
142-
void setTracked(bool tracked);
143141

144142
[[nodiscard]] bool isLastGeneration() const;
145143
void setLastGeneration();
146144

147-
[[nodiscard]] QString image() const;
145+
QS_BINDABLE_GETTER(qreal, bExpireTimeout, expireTimeout, bindableExpireTimeout);
146+
QS_BINDABLE_GETTER(QString, bAppName, appName, bindableAppName);
147+
QS_BINDABLE_GETTER(QString, bAppIcon, appIcon, bindableAppIcon);
148+
QS_BINDABLE_GETTER(QString, bSummary, summary, bindableSummary);
149+
QS_BINDABLE_GETTER(QString, bBody, body, bindableBody);
150+
QS_BINDABLE_GETTER(NotificationUrgency::Enum, bUrgency, urgency, bindableUrgency);
151+
152+
[[nodiscard]] QList<NotificationAction*> actions() const;
153+
154+
QS_BINDABLE_GETTER(bool, bHasActionIcons, hasActionIcons, bindableHasActionIcons);
155+
QS_BINDABLE_GETTER(bool, bResident, resident, bindableResident);
156+
QS_BINDABLE_GETTER(bool, bTransient, transient, bindableTransient);
157+
QS_BINDABLE_GETTER(QString, bDesktopEntry, desktopEntry, bindableDesktopEntry);
158+
QS_BINDABLE_GETTER(QString, bImage, image, bindableImage);
159+
QS_BINDABLE_GETTER(QVariantMap, bHints, hints, bindableHints);
160+
161+
[[nodiscard]] NotificationCloseReason::Enum closeReason() const;
162+
void setTracked(bool tracked);
148163

149164
signals:
150165
/// Sent when a notification has been closed.
@@ -171,35 +186,30 @@ class Notification
171186
quint32 mId;
172187
NotificationCloseReason::Enum mCloseReason = NotificationCloseReason::Dismissed;
173188
bool mLastGeneration = false;
174-
qreal mExpireTimeout = 0;
175-
QString mAppName;
176-
QString mAppIcon;
177-
QString mSummary;
178-
QString mBody;
179-
NotificationUrgency::Enum mUrgency = NotificationUrgency::Normal;
180-
QVector<NotificationAction*> mActions;
181-
bool mHasActionIcons = false;
182-
bool mResident = false;
183-
bool mTransient = false;
184-
QString mImagePath;
185189
NotificationImage* mImagePixmap = nullptr;
186-
QString mDesktopEntry;
187-
QVariantMap mHints;
190+
QList<NotificationAction*> mActions;
188191

189192
// clang-format off
190-
DECLARE_PRIVATE_MEMBER(Notification, expireTimeout, setExpireTimeout, mExpireTimeout, expireTimeoutChanged);
191-
DECLARE_PRIVATE_MEMBER(Notification, appName, setAppName, mAppName, appNameChanged);
192-
DECLARE_PRIVATE_MEMBER(Notification, appIcon, setAppIcon, mAppIcon, appIconChanged);
193-
DECLARE_PRIVATE_MEMBER(Notification, summary, setSummary, mSummary, summaryChanged);
194-
DECLARE_PRIVATE_MEMBER(Notification, body, setBody, mBody, bodyChanged);
195-
DECLARE_PRIVATE_MEMBER(Notification, urgency, setUrgency, mUrgency, urgencyChanged);
196-
DECLARE_MEMBER_WITH_GET(Notification, actions, mActions, actionsChanged);
197-
DECLARE_PRIVATE_MEMBER(Notification, hasActionIcons, setHasActionIcons, mHasActionIcons, hasActionIconsChanged);
198-
DECLARE_PRIVATE_MEMBER(Notification, resident, setResident, mResident, residentChanged);
199-
DECLARE_PRIVATE_MEMBER(Notification, transient, setTransient, mTransient, transientChanged);
200-
DECLARE_PRIVATE_MEMBER(Notification, desktopEntry, setDesktopEntry, mDesktopEntry, desktopEntryChanged);
201-
DECLARE_PRIVATE_MEMBER(Notification, hints, setHints, mHints, hintsChanged);
193+
Q_OBJECT_BINDABLE_PROPERTY(Notification, qreal, bExpireTimeout, &Notification::expireTimeoutChanged);
194+
Q_OBJECT_BINDABLE_PROPERTY(Notification, QString, bAppName, &Notification::appNameChanged);
195+
Q_OBJECT_BINDABLE_PROPERTY(Notification, QString, bAppIcon, &Notification::appIconChanged);
196+
Q_OBJECT_BINDABLE_PROPERTY(Notification, QString, bSummary, &Notification::summaryChanged);
197+
Q_OBJECT_BINDABLE_PROPERTY(Notification, QString, bBody, &Notification::bodyChanged);
198+
Q_OBJECT_BINDABLE_PROPERTY(Notification, bool, bHasActionIcons, &Notification::hasActionIconsChanged);
199+
Q_OBJECT_BINDABLE_PROPERTY(Notification, bool, bResident, &Notification::residentChanged);
200+
Q_OBJECT_BINDABLE_PROPERTY(Notification, bool, bTransient, &Notification::transientChanged);
201+
Q_OBJECT_BINDABLE_PROPERTY(Notification, QString, bDesktopEntry, &Notification::desktopEntryChanged);
202+
Q_OBJECT_BINDABLE_PROPERTY(Notification, QString, bImage, &Notification::imageChanged);
203+
Q_OBJECT_BINDABLE_PROPERTY(Notification, QVariantMap, bHints, &Notification::hintsChanged);
202204
// clang-format on
205+
206+
Q_OBJECT_BINDABLE_PROPERTY_WITH_ARGS(
207+
Notification,
208+
NotificationUrgency::Enum,
209+
bUrgency,
210+
NotificationUrgency::Normal,
211+
&Notification::urgencyChanged
212+
);
203213
};
204214

205215
///! An action associated with a Notification.

0 commit comments

Comments
 (0)