Port QDBusServiceWatcher::watchedServices to bindable properties

Fixes: QTBUG-92993
Change-Id: I379c67c75bc536e387889de5303b01aef9399fcd
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Sona Kurazyan <sona.kurazyan@qt.io>
This commit is contained in:
Andreas Buhr 2021-04-26 13:08:44 +02:00
parent 40330b8f0a
commit dd24b61d35
4 changed files with 82 additions and 13 deletions

View File

@ -60,7 +60,13 @@ public:
{ {
} }
QStringList servicesWatched; void setWatchedServicesForwardToQ(const QStringList &list)
{
q_func()->setWatchedServices(list);
}
Q_OBJECT_COMPAT_PROPERTY(QDBusServiceWatcherPrivate, QStringList, watchedServicesData,
&QDBusServiceWatcherPrivate::setWatchedServicesForwardToQ)
QDBusConnection connection; QDBusConnection connection;
void setWatchModeForwardToQ(QDBusServiceWatcher::WatchMode mode) void setWatchModeForwardToQ(QDBusServiceWatcher::WatchMode mode)
{ {
@ -92,17 +98,17 @@ void QDBusServiceWatcherPrivate::setConnection(const QStringList &services,
{ {
if (connection.isConnected()) { if (connection.isConnected()) {
// remove older rules // remove older rules
for (const QString &s : qAsConst(servicesWatched)) for (const QString &s : qAsConst(watchedServicesData.value()))
removeService(s); removeService(s);
} }
connection = c; connection = c;
watchMode.setValueBypassingBindings(wm); // caller has to call notify() watchMode.setValueBypassingBindings(wm); // caller has to call notify()
servicesWatched = services; watchedServicesData.setValueBypassingBindings(services); // caller has to call notify()
if (connection.isConnected()) { if (connection.isConnected()) {
// add new rules // add new rules
for (const QString &s : qAsConst(servicesWatched)) for (const QString &s : qAsConst(watchedServicesData.value()))
addService(s); addService(s);
} }
} }
@ -273,7 +279,7 @@ QDBusServiceWatcher::~QDBusServiceWatcher()
*/ */
QStringList QDBusServiceWatcher::watchedServices() const QStringList QDBusServiceWatcher::watchedServices() const
{ {
return d_func()->servicesWatched; return d_func()->watchedServicesData;
} }
/*! /*!
@ -283,27 +289,45 @@ QStringList QDBusServiceWatcher::watchedServices() const
watching services and adding new ones. This is an expensive operation and watching services and adding new ones. This is an expensive operation and
should be avoided, if possible. Instead, use addWatchedService() and should be avoided, if possible. Instead, use addWatchedService() and
removeWatchedService() if you can to manipulate entries in the list. removeWatchedService() if you can to manipulate entries in the list.
Removes any existing binding of watchedServices.
*/ */
void QDBusServiceWatcher::setWatchedServices(const QStringList &services) void QDBusServiceWatcher::setWatchedServices(const QStringList &services)
{ {
Q_D(QDBusServiceWatcher); Q_D(QDBusServiceWatcher);
if (services == d->servicesWatched) d->watchedServicesData.removeBindingUnlessInWrapper();
if (services == d->watchedServicesData)
return; return;
d->setConnection(services, d->connection, d->watchMode); d->setConnection(services, d->connection, d->watchMode);
d->watchedServicesData.notify();
}
QBindable<QStringList> QDBusServiceWatcher::bindableWatchedServices()
{
Q_D(QDBusServiceWatcher);
return &d->watchedServicesData;
} }
/*! /*!
Adds \a newService to the list of services to be watched by this object. Adds \a newService to the list of services to be watched by this object.
This function is more efficient than setWatchedServices() and should be This function is more efficient than setWatchedServices() and should be
used whenever possible to add services. used whenever possible to add services.
Removes any existing binding of watchedServices.
*/ */
void QDBusServiceWatcher::addWatchedService(const QString &newService) void QDBusServiceWatcher::addWatchedService(const QString &newService)
{ {
Q_D(QDBusServiceWatcher); Q_D(QDBusServiceWatcher);
if (d->servicesWatched.contains(newService)) d->watchedServicesData.removeBindingUnlessInWrapper();
if (d->watchedServicesData.value().contains(newService))
return; return;
d->addService(newService); d->addService(newService);
d->servicesWatched << newService;
auto templist = d->watchedServicesData.valueBypassingBindings();
templist << newService;
d->watchedServicesData.setValueBypassingBindings(templist);
d->watchedServicesData.notify();
} }
/*! /*!
@ -312,13 +336,25 @@ void QDBusServiceWatcher::addWatchedService(const QString &newService)
still be signals pending delivery about \a service. Those signals will still be signals pending delivery about \a service. Those signals will
still be emitted whenever the D-Bus messages are processed. still be emitted whenever the D-Bus messages are processed.
Removes any existing binding of watchedServices.
This function returns \c true if any services were removed. This function returns \c true if any services were removed.
*/ */
bool QDBusServiceWatcher::removeWatchedService(const QString &service) bool QDBusServiceWatcher::removeWatchedService(const QString &service)
{ {
Q_D(QDBusServiceWatcher); Q_D(QDBusServiceWatcher);
d->watchedServicesData.removeBindingUnlessInWrapper();
d->removeService(service); d->removeService(service);
return d->servicesWatched.removeOne(service); auto tempList = d->watchedServicesData.value();
bool result = tempList.removeOne(service);
if (result) {
d->watchedServicesData.setValueBypassingBindings(tempList);
d->watchedServicesData.notify();
return true;
} else {
// nothing changed
return false;
}
} }
QDBusServiceWatcher::WatchMode QDBusServiceWatcher::watchMode() const QDBusServiceWatcher::WatchMode QDBusServiceWatcher::watchMode() const
@ -337,7 +373,7 @@ void QDBusServiceWatcher::setWatchMode(WatchMode mode)
d->watchMode.removeBindingUnlessInWrapper(); d->watchMode.removeBindingUnlessInWrapper();
if (mode == d->watchMode.value()) if (mode == d->watchMode.value())
return; return;
d->setConnection(d->servicesWatched, d->connection, mode); d->setConnection(d->watchedServicesData, d->connection, mode);
d->watchMode.notify(); d->watchMode.notify();
} }
@ -368,7 +404,7 @@ void QDBusServiceWatcher::setConnection(const QDBusConnection &connection)
Q_D(QDBusServiceWatcher); Q_D(QDBusServiceWatcher);
if (connection.name() == d->connection.name()) if (connection.name() == d->connection.name())
return; return;
d->setConnection(d->servicesWatched, connection, d->watchMode); d->setConnection(d->watchedServicesData, connection, d->watchMode);
} }
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -53,7 +53,8 @@ class QDBusServiceWatcherPrivate;
class Q_DBUS_EXPORT QDBusServiceWatcher: public QObject class Q_DBUS_EXPORT QDBusServiceWatcher: public QObject
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY(QStringList watchedServices READ watchedServices WRITE setWatchedServices) Q_PROPERTY(QStringList watchedServices READ watchedServices WRITE setWatchedServices
BINDABLE bindableWatchedServices)
Q_PROPERTY(WatchMode watchMode READ watchMode WRITE setWatchMode BINDABLE bindableWatchMode) Q_PROPERTY(WatchMode watchMode READ watchMode WRITE setWatchMode BINDABLE bindableWatchMode)
public: public:
enum WatchModeFlag { enum WatchModeFlag {
@ -73,6 +74,7 @@ public:
void setWatchedServices(const QStringList &services); void setWatchedServices(const QStringList &services);
void addWatchedService(const QString &newService); void addWatchedService(const QString &newService);
bool removeWatchedService(const QString &service); bool removeWatchedService(const QString &service);
QBindable<QStringList> bindableWatchedServices();
WatchMode watchMode() const; WatchMode watchMode() const;
void setWatchMode(WatchMode mode); void setWatchMode(WatchMode mode);

View File

@ -7,6 +7,7 @@
qt_internal_add_test(tst_qdbusservicewatcher qt_internal_add_test(tst_qdbusservicewatcher
SOURCES SOURCES
tst_qdbusservicewatcher.cpp tst_qdbusservicewatcher.cpp
PUBLIC_LIBRARIES LIBRARIES
Qt::DBus Qt::DBus
Qt::TestPrivate
) )

View File

@ -28,6 +28,7 @@
****************************************************************************/ ****************************************************************************/
#include <QTest> #include <QTest>
#include <QtTest/private/qpropertytesthelper_p.h>
#include <QSignalSpy> #include <QSignalSpy>
#include <QTestEventLoop> #include <QTestEventLoop>
#include <QDBusConnection> #include <QDBusConnection>
@ -55,6 +56,7 @@ private slots:
void setConnection_data(); void setConnection_data();
void setConnection(); void setConnection();
void bindings(); void bindings();
void bindingsAutomated();
private: private:
QString generateServiceName(); QString generateServiceName();
@ -469,5 +471,33 @@ void tst_QDBusServiceWatcher::bindings()
QCOMPARE(notificationCounter, 5); QCOMPARE(notificationCounter, 5);
} }
void tst_QDBusServiceWatcher::bindingsAutomated()
{
QString serviceName("normal");
QDBusConnection con("");
QVERIFY(!con.isConnected());
QDBusServiceWatcher watcher(serviceName, con, QDBusServiceWatcher::WatchForRegistration);
QTestPrivate::testReadWritePropertyBasics<QDBusServiceWatcher, QStringList>(
watcher,
QStringList() << "foo" << "bar",
QStringList() << "bar" << "foo",
"watchedServices");
if (QTest::currentTestFailed()) {
qDebug("Failed property test for QDBusServiceWatcher::watchedServices");
return;
}
QTestPrivate::testReadWritePropertyBasics<QDBusServiceWatcher,
QFlags<QDBusServiceWatcher::WatchModeFlag>>(
watcher, QDBusServiceWatcher::WatchForUnregistration,
QDBusServiceWatcher::WatchForRegistration, "watchMode");
if (QTest::currentTestFailed()) {
qDebug("Failed property test for QDBusServiceWatcher::watchMode");
return;
}
}
QTEST_MAIN(tst_QDBusServiceWatcher) QTEST_MAIN(tst_QDBusServiceWatcher)
#include "tst_qdbusservicewatcher.moc" #include "tst_qdbusservicewatcher.moc"