2
* Copyright 2014 Canonical Ltd.
4
* This program is free software; you can redistribute it and/or modify
5
* it under the terms of the GNU Lesser General Public License as published by
6
* the Free Software Foundation; version 3.
8
* This program is distributed in the hope that it will be useful,
9
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
* GNU Lesser General Public License for more details.
13
* You should have received a copy of the GNU Lesser General Public License
14
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17
#include "ucserviceproperties.h"
18
#include "ucserviceproperties_p.h"
20
#include <QtQml/QQmlInfo>
21
#include <QtCore/QMetaProperty>
22
#include <QtQml/QQmlProperty>
23
#include <QtQml/private/qqmlproperty_p.h>
25
UCServicePropertiesPrivate::UCServicePropertiesPrivate(UCServiceProperties *qq)
28
, status(UCServiceProperties::Inactive)
29
, type(UCServiceProperties::System)
33
UCServicePropertiesPrivate::~UCServicePropertiesPrivate()
37
UCServicePropertiesPrivate *UCServicePropertiesPrivate::get(UCServiceProperties *service)
39
return service->d_func();
42
void UCServicePropertiesPrivate::warning(const QString &message)
44
QByteArray suppressWarnings = qgetenv("SUPPRESS_SERVICEPROPERTIES_WARNINGS");
45
if ((suppressWarnings == "yes") || (suppressWarnings == "1")) {
48
qmlInfo(q_ptr) << message;
51
void UCServicePropertiesPrivate::setError(const QString &msg)
57
Q_EMIT q_ptr->errorChanged();
60
void UCServicePropertiesPrivate::setStatus(UCServiceProperties::Status status)
62
if (this->status == status) {
65
this->status = status;
66
Q_EMIT q_ptr->statusChanged();
69
void printLocked(UCServiceProperties *owner)
71
UCServicePropertiesPrivate::get(owner)->
72
warning(UbuntuI18n::instance().tr("Changing connection parameters forbidden."));
76
* \qmltype ServiceProperties
77
* \instantiates UCServiceProperties
78
* \inqmlmodule Ubuntu.Components 1.1
79
* \since Ubuntu.Components 1.1
80
* \ingroup ubuntu-services
81
* \brief The component enables accessing service properties from QML.
83
* The services accessed by the component are ones providing their interfaces
84
* through DBus. The component is specialized to read properties exposed by these
85
* services, andf to keep these property values up to date. It is not meant to
86
* access signals or slots exposed, nor to change the values of the properties
89
* Properties watched should be declared within the body of the component like
90
* any other QML property, preferably defining a default value for them. The component
91
* will enumerate these properties and will ask the service to provide values for
92
* those. When enumerating properties, each property will be checked twice, with
93
* the case specified as well as with the first letter capitalized.
96
* import Ubuntu.Components 1.1
99
* service: "org.freenode.AccountsService"
100
* path: "/org/freenode/AccountsService"
101
* serviceInterface: "org.freenode.AccountsService"
102
* adaptorInterface: "com.ubuntu.touch.Accounts.Sound"
103
* // listing properties to watch
104
* // each property name existence will be checked against the current case
105
* // as well as with first character capitalized
106
* property bool incomingCallVibrate: true
110
* Note that there are few properties which must be set in order the component
111
* to work. These are \l service, \l path and \l adaptorInterface. Also, once
112
* specified, \l service, \l serviceInterface and \l adaptorInterface values
113
* should not be changed as it cannot be guaranteed that properties watched will
114
* be available on those service. Therefore any change on these properties after
115
* the component completion will be ignored. Property bindings on properties
116
* watched will be ignored as well, as service will report changes in these property
119
* The service is connected once the component gets completed (Component.onCompleted).
120
* The \l error property specifies any error occured during connection, and the
121
* \l status property notifies whether the connection to the service is active or not.
123
* \note Pay attention when chosing the service watched, and set your application's
124
* AppArmor rights to ensure a successful service connection.
126
UCServiceProperties::UCServiceProperties(QObject *parent)
128
, d_ptr(createServicePropertiesAdapter(this))
131
UCServiceProperties::~UCServiceProperties()
137
void UCServiceProperties::classBegin()
141
void UCServiceProperties::componentComplete()
143
Q_D(UCServiceProperties);
145
// enumerate properties
146
const QMetaObject *mo = metaObject();
147
for (int i = mo->propertyOffset(); i < mo->propertyCount(); i++) {
148
const QMetaProperty prop = mo->property(i);
149
QString property(prop.name());
151
// check the binding on the property and warn if there is one.
152
QQmlProperty qmlProperty(this, property);
153
if (QQmlPropertyPrivate::binding(qmlProperty)) {
154
d->warning(UbuntuI18n::instance().
155
tr("Binding detected on property '%1' will be removed by the service updates.").
158
// insert both the declared and capitalized first character properties
159
d->properties << property;
160
property[0] = property[0].toUpper();
161
d->properties << property;
165
d->setStatus(UCServiceProperties::Synchronizing);
166
d->fetchPropertyValues();
171
* \qmlproperty enum ServiceProperties::type
172
* Specifies the DBus connection session type. It can get the following values:
174
* \li - \e ServiceProperties.System when system bus is used (default)
175
* \li - \e ServiceProperties.Session when session bus is used
178
UCServiceProperties::ServiceType UCServiceProperties::type() const
180
Q_D(const UCServiceProperties);
183
void UCServiceProperties::setType(ServiceType type)
185
Q_D(UCServiceProperties);
186
if (d->type == type) {
194
Q_EMIT typeChanged();
198
* \qmlproperty string ServiceProperties::service
199
* The proeprty specifies the DBus service URI. It is mandatory to be specified.
201
QString UCServiceProperties::service() const
203
Q_D(const UCServiceProperties);
206
void UCServiceProperties::setService(const QString &value)
208
Q_D(UCServiceProperties);
209
if (d->service == value) {
217
Q_EMIT serviceChanged();
221
* \qmlproperty string ServiceProperties::path
222
* The property specifies the DBus service connection path. It is mandatory to be
225
QString UCServiceProperties::path() const
227
Q_D(const UCServiceProperties);
230
void UCServiceProperties::setPath(const QString &value)
232
Q_D(UCServiceProperties);
233
if (d->path == value) {
237
Q_EMIT pathChanged();
239
// need to re-initialize connections
245
* \qmlproperty string ServiceProperties::serviceInterface
246
* The property specifies the service intertface. If it is an empty string, the
247
* component will refer to the merging of all interfaces found in the service.
249
QString UCServiceProperties::interface() const
251
Q_D(const UCServiceProperties);
254
void UCServiceProperties::setInterface(const QString &value)
256
Q_D(UCServiceProperties);
257
if (d->interface == value) {
264
d->interface = value;
265
Q_EMIT serviceInterfaceChanged();
268
* \qmlproperty string ServiceProperties::adaptorInterface
269
* The proeprty specifies the dbus adaptor interface which provides the properties
270
* watched. This can be a different interface that the one specified in \l serviceInterface,
271
* and in the same way, it can be empty, in which case all the properties from all
272
* interfaces of the service will be watched.
274
QString UCServiceProperties::adaptor() const
276
Q_D(const UCServiceProperties);
279
void UCServiceProperties::setAdaptor(const QString &value)
281
Q_D(UCServiceProperties);
282
if (d->adaptor == value) {
290
Q_EMIT adaptorInterfaceChanged();
294
* \qmlproperty string ServiceProperties::error
295
* The property is set with a human readablestring each time an error occurrs
296
* during the service connection. Empty string means no error.
298
QString UCServiceProperties::error()
300
Q_D(UCServiceProperties);
305
* \qmlproperty enum ServiceProperties::status
306
* The property presents the status of the component.
308
* \li - \e ServiceProperties.Inactive - the component is inactive, initial state
309
* \li - \e ServiceProperties.ConnectionError - there was a connection error, the
310
* \l error contains the error string.
311
* \li - \e ServiceProperties.Synchronizing - the connection to the service succeeded,
312
* and the properties are being synchronized;
313
* \li - \e ServiceProperties.Active - the service watcher is active and initial
314
* property synchronization completed.
316
* \note While the status is set to \e Synchronizing, the properties are checked
317
* against their existence in the service. Each proeprty will be checked as declared
318
* as well with capital first letter. If neither of these exists in the service,
319
* it will be reported in the \l error property separately.
321
UCServiceProperties::Status UCServiceProperties::status() const
323
Q_D(const UCServiceProperties);
327
#include "moc_ucserviceproperties.cpp"