21 #include <QDBusConnection>
22 #include <QDBusMessage>
24 #include <QMetaObject>
25 #include <QMetaMethod>
26 #include <QMetaProperty>
28 #include <QVariantList>
29 #include <QVariantMap>
44 void notify(
const QStringList &propertyFilter);
47 void onChanged(
int propertyIndex);
48 void onPropertyChanged0() { onChanged(0); }
49 void onPropertyChanged1() { onChanged(1); }
50 void onPropertyChanged2() { onChanged(2); }
51 void onPropertyChanged3() { onChanged(3); }
52 void onPropertyChanged4() { onChanged(4); }
53 void onPropertyChanged5() { onChanged(5); }
54 void onPropertyChanged6() { onChanged(6); }
55 void onPropertyChanged7() { onChanged(7); }
56 void onPropertyChanged8() { onChanged(8); }
57 void onPropertyChanged9() { onChanged(9); }
58 void onPropertyChanged10() { onChanged(10); }
59 void onPropertyChanged11() { onChanged(11); }
60 void onPropertyChanged12() { onChanged(12); }
61 void onPropertyChanged13() { onChanged(13); }
62 void onPropertyChanged14() { onChanged(14); }
63 void onPropertyChanged15() { onChanged(15); }
64 void onPropertyChanged16() { onChanged(16); }
65 void onPropertyChanged17() { onChanged(17); }
66 void onPropertyChanged18() { onChanged(18); }
67 void onPropertyChanged19() { onChanged(19); }
70 QDBusConnection m_connection;
74 QVector<int> m_changedPropertyIndexes;
75 QVector<QMetaProperty> m_properties;
76 QVariantMap m_lastValues;
80 const QDBusConnection &connection,
83 m_connection(connection),
87 const QMetaObject *mo = target->metaObject();
94 int index = mo->indexOfClassInfo(
"D-Bus Interface");
95 m_interface = QString::fromUtf8(mo->classInfo(index).value());
100 QStringList properties;
101 int nextFreeSlot = 0;
102 int indexOfFirstSlot = -1;
103 const QMetaObject *ourMo = metaObject();
104 for (
int i = ourMo->methodOffset(); i < ourMo->methodCount(); i++) {
105 if (ourMo->method(i).name().startsWith(
"onPropertyChanged")) {
106 indexOfFirstSlot = i;
111 for (
int i = mo->propertyOffset(); i < mo->propertyCount(); i++) {
112 const QMetaProperty p = mo->property(i);
113 if (!p.hasNotifySignal())
continue;
114 const QMetaMethod signalMethod = p.notifySignal();
115 const QMetaMethod slotMethod =
116 ourMo->method(indexOfFirstSlot + nextFreeSlot);
117 if (Q_UNLIKELY(!slotMethod.isValid())) {
118 qWarning() <<
"No more slots available!";
121 QObject::connect(m_target, signalMethod,
this, slotMethod);
122 m_properties.insert(nextFreeSlot, p);
127 void DBusPropertyNotifierPrivate::onChanged(
int propertyIndex)
129 if (m_changedPropertyIndexes.contains(propertyIndex))
return;
132 const QMetaProperty &p = m_properties[propertyIndex];
133 const QVariant value = p.read(m_target);
134 if (m_lastValues.value(p.name()) == value) {
141 if (m_changedPropertyIndexes.isEmpty()) {
142 QMetaObject::invokeMethod(
this,
144 Qt::QueuedConnection);
146 m_changedPropertyIndexes.append(propertyIndex);
151 QVariantMap changedProperties;
152 for (
int propertyIndex: m_changedPropertyIndexes) {
153 const QMetaProperty &p = m_properties[propertyIndex];
154 const QVariant value = p.read(m_target);
155 if (m_lastValues.value(p.name()) != value) {
156 changedProperties.insert(p.name(), value);
157 m_lastValues.insert(p.name(), value);
161 if (!changedProperties.isEmpty()) {
162 QDBusMessage msg = QDBusMessage::createSignal(m_objectPath,
163 QStringLiteral(
"org.freedesktop.DBus.Properties"),
164 QStringLiteral(
"PropertiesChanged"));
170 m_connection.send(msg);
173 m_changedPropertyIndexes.clear();
178 QVariantMap changedProperties;
179 const QMetaObject *mo = m_target->metaObject();
180 for (
int i = mo->propertyOffset(); i < mo->propertyCount(); i++) {
181 const QMetaProperty p = mo->property(i);
182 const QString propertyName = p.name();
183 if (!propertyFilter.isEmpty() &&
184 !propertyFilter.contains(propertyName)) {
187 const QVariant value = p.read(m_target);
188 if (m_lastValues.value(propertyName) != value) {
189 changedProperties.insert(propertyName, value);
190 m_lastValues.insert(propertyName, value);
194 if (!changedProperties.isEmpty()) {
195 QDBusMessage msg = QDBusMessage::createSignal(m_objectPath,
196 QStringLiteral(
"org.freedesktop.DBus.Properties"),
197 QStringLiteral(
"PropertiesChanged"));
203 m_connection.send(msg);
220 d->notify(propertyFilter);
223 #include "dbus_property_notifier.moc"