~aacid/ubuntu-ui-toolkit/nonsquareicons

« back to all changes in this revision

Viewing changes to modules/Ubuntu/Components/plugin/ucserviceproperties.cpp

  • Committer: Tarmac
  • Author(s): Zsombor Egri, Florian Boucault, CI Train Bot, Tim Peeters
  • Date: 2015-02-11 13:51:42 UTC
  • mfrom: (1405.1.2 rtm-to-staging)
  • Revision ID: tarmac-20150211135142-kr635b7awvx84acd
RTM branch diff merge. Fixes: https://bugs.launchpad.net/bugs/1358610.

Approved by PS Jenkins bot, Zoltan Balogh.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright 2014 Canonical Ltd.
 
3
 *
 
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.
 
7
 *
 
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.
 
12
 *
 
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/>.
 
15
 */
 
16
 
 
17
#include "ucserviceproperties.h"
 
18
#include "ucserviceproperties_p.h"
 
19
#include "i18n.h"
 
20
#include <QtQml/QQmlInfo>
 
21
#include <QtCore/QMetaProperty>
 
22
#include <QtQml/QQmlProperty>
 
23
#include <QtQml/private/qqmlproperty_p.h>
 
24
 
 
25
UCServicePropertiesPrivate::UCServicePropertiesPrivate(UCServiceProperties *qq)
 
26
    : q_ptr(qq)
 
27
    , ready(false)
 
28
    , status(UCServiceProperties::Inactive)
 
29
    , type(UCServiceProperties::System)
 
30
{
 
31
}
 
32
 
 
33
UCServicePropertiesPrivate::~UCServicePropertiesPrivate()
 
34
{
 
35
}
 
36
 
 
37
UCServicePropertiesPrivate *UCServicePropertiesPrivate::get(UCServiceProperties *service)
 
38
{
 
39
    return service->d_func();
 
40
}
 
41
 
 
42
void UCServicePropertiesPrivate::warning(const QString &message)
 
43
{
 
44
    QByteArray suppressWarnings = qgetenv("SUPPRESS_SERVICEPROPERTIES_WARNINGS");
 
45
    if ((suppressWarnings == "yes") || (suppressWarnings == "1")) {
 
46
        return;
 
47
    }
 
48
    qmlInfo(q_ptr) << message;
 
49
}
 
50
 
 
51
void UCServicePropertiesPrivate::setError(const QString &msg)
 
52
{
 
53
    if (error == msg) {
 
54
        return;
 
55
    }
 
56
    error = msg;
 
57
    Q_EMIT q_ptr->errorChanged();
 
58
}
 
59
 
 
60
void UCServicePropertiesPrivate::setStatus(UCServiceProperties::Status status)
 
61
{
 
62
    if (this->status == status) {
 
63
        return;
 
64
    }
 
65
    this->status = status;
 
66
    Q_EMIT q_ptr->statusChanged();
 
67
}
 
68
 
 
69
void printLocked(UCServiceProperties *owner)
 
70
{
 
71
    UCServicePropertiesPrivate::get(owner)->
 
72
            warning(UbuntuI18n::instance().tr("Changing connection parameters forbidden."));
 
73
}
 
74
 
 
75
/*!
 
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.
 
82
 *
 
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
 
87
 * watched.
 
88
 *
 
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.
 
94
 * \qml
 
95
 * import QtQuick 2.3
 
96
 * import Ubuntu.Components 1.1
 
97
 *
 
98
 * ServiceProperties {
 
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
 
107
 * }
 
108
 * \endqml
 
109
 *
 
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
 
117
 * values.
 
118
 *
 
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.
 
122
 *
 
123
 * \note Pay attention when chosing the service watched, and set your application's
 
124
 * AppArmor rights to ensure a successful service connection.
 
125
 */
 
126
UCServiceProperties::UCServiceProperties(QObject *parent)
 
127
    : QObject(parent)
 
128
    , d_ptr(createServicePropertiesAdapter(this))
 
129
{
 
130
}
 
131
UCServiceProperties::~UCServiceProperties()
 
132
{
 
133
    delete d_ptr;
 
134
    d_ptr = 0;
 
135
}
 
136
 
 
137
void UCServiceProperties::classBegin()
 
138
{
 
139
}
 
140
 
 
141
void UCServiceProperties::componentComplete()
 
142
{
 
143
    Q_D(UCServiceProperties);
 
144
    d->ready = true;
 
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());
 
150
 
 
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.").
 
156
                       arg(property));
 
157
        }
 
158
        // insert both the declared and capitalized first character properties
 
159
        d->properties << property;
 
160
        property[0] = property[0].toUpper();
 
161
        d->properties << property;
 
162
    }
 
163
    // initialize DBus
 
164
    if (d->init()) {
 
165
        d->setStatus(UCServiceProperties::Synchronizing);
 
166
        d->fetchPropertyValues();
 
167
    }
 
168
}
 
169
 
 
170
/*!
 
171
 * \qmlproperty enum ServiceProperties::type
 
172
 * Specifies the DBus connection session type. It can get the following values:
 
173
 * \list
 
174
 *  \li - \e ServiceProperties.System when system bus is used (default)
 
175
 *  \li - \e ServiceProperties.Session when session bus is used
 
176
 * \endlist
 
177
 */
 
178
UCServiceProperties::ServiceType UCServiceProperties::type() const
 
179
{
 
180
    Q_D(const UCServiceProperties);
 
181
    return d->type;
 
182
}
 
183
void UCServiceProperties::setType(ServiceType type)
 
184
{
 
185
    Q_D(UCServiceProperties);
 
186
    if (d->type == type) {
 
187
        return;
 
188
    }
 
189
    if (d->ready) {
 
190
        printLocked(this);
 
191
        return;
 
192
    }
 
193
    d->type = type;
 
194
    Q_EMIT typeChanged();
 
195
}
 
196
 
 
197
/*!
 
198
 * \qmlproperty string ServiceProperties::service
 
199
 * The proeprty specifies the DBus service URI. It is mandatory to be specified.
 
200
 */
 
201
QString UCServiceProperties::service() const
 
202
{
 
203
    Q_D(const UCServiceProperties);
 
204
    return d->service;
 
205
}
 
206
void UCServiceProperties::setService(const QString &value)
 
207
{
 
208
    Q_D(UCServiceProperties);
 
209
    if (d->service == value) {
 
210
        return;
 
211
    }
 
212
    if (d->ready) {
 
213
        printLocked(this);
 
214
        return;
 
215
    }
 
216
    d->service = value;
 
217
    Q_EMIT serviceChanged();
 
218
}
 
219
 
 
220
/*!
 
221
 * \qmlproperty string ServiceProperties::path
 
222
 * The property specifies the DBus service connection path. It is mandatory to be
 
223
 * specified.
 
224
 */
 
225
QString UCServiceProperties::path() const
 
226
{
 
227
    Q_D(const UCServiceProperties);
 
228
    return d->path;
 
229
}
 
230
void UCServiceProperties::setPath(const QString &value)
 
231
{
 
232
    Q_D(UCServiceProperties);
 
233
    if (d->path == value) {
 
234
        return;
 
235
    }
 
236
    d->path = value;
 
237
    Q_EMIT pathChanged();
 
238
    if (d->ready) {
 
239
        // need to re-initialize connections
 
240
        d->init();
 
241
    }
 
242
}
 
243
 
 
244
/*!
 
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.
 
248
 */
 
249
QString UCServiceProperties::interface() const
 
250
{
 
251
    Q_D(const UCServiceProperties);
 
252
    return d->interface;
 
253
}
 
254
void UCServiceProperties::setInterface(const QString &value)
 
255
{
 
256
    Q_D(UCServiceProperties);
 
257
    if (d->interface == value) {
 
258
        return;
 
259
    }
 
260
    if (d->ready) {
 
261
        printLocked(this);
 
262
        return;
 
263
    }
 
264
    d->interface = value;
 
265
    Q_EMIT serviceInterfaceChanged();
 
266
}
 
267
/*!
 
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.
 
273
 */
 
274
QString UCServiceProperties::adaptor() const
 
275
{
 
276
    Q_D(const UCServiceProperties);
 
277
    return d->adaptor;
 
278
}
 
279
void UCServiceProperties::setAdaptor(const QString &value)
 
280
{
 
281
    Q_D(UCServiceProperties);
 
282
    if (d->adaptor == value) {
 
283
        return;
 
284
    }
 
285
    if (d->ready) {
 
286
        printLocked(this);
 
287
        return;
 
288
    }
 
289
    d->adaptor = value;
 
290
    Q_EMIT adaptorInterfaceChanged();
 
291
}
 
292
 
 
293
/*!
 
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.
 
297
 */
 
298
QString UCServiceProperties::error()
 
299
{
 
300
    Q_D(UCServiceProperties);
 
301
    return d->error;
 
302
}
 
303
 
 
304
/*!
 
305
 * \qmlproperty enum ServiceProperties::status
 
306
 * The property presents the status of the component.
 
307
 * \list
 
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.
 
315
 * \endlist
 
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.
 
320
 */
 
321
UCServiceProperties::Status UCServiceProperties::status() const
 
322
{
 
323
    Q_D(const UCServiceProperties);
 
324
    return d->status;
 
325
}
 
326
 
 
327
#include "moc_ucserviceproperties.cpp"