Merge lp:~zsombi/ubuntu-ui-toolkit/rtm-to-staging into lp:ubuntu-ui-toolkit/staging

Proposed by Zsombor Egri
Status: Merged
Approved by: Zsombor Egri
Approved revision: 1407
Merged at revision: 1407
Proposed branch: lp:~zsombi/ubuntu-ui-toolkit/rtm-to-staging
Merge into: lp:ubuntu-ui-toolkit/staging
Diff against target: 2582 lines (+352/-1002)
19 files modified
components.api (+78/-0)
debian/changelog (+28/-0)
modules/Ubuntu/Components/11/Haptics.qml (+181/-0)
modules/Ubuntu/Components/AbstractButton.qml (+6/-12)
modules/Ubuntu/Components/Themes/Ambiance/ActivityIndicatorStyle.qml (+1/-6)
modules/Ubuntu/Components/plugin/adapters/dbuspropertywatcher_p.cpp (+0/-226)
modules/Ubuntu/Components/plugin/adapters/dbuspropertywatcher_p.h (+0/-55)
modules/Ubuntu/Components/plugin/plugin.pro (+2/-2)
modules/Ubuntu/Components/plugin/ucserviceproperties.cpp (+0/-317)
modules/Ubuntu/Components/plugin/ucserviceproperties.h (+0/-83)
modules/Ubuntu/Components/plugin/ucserviceproperties_p.h (+0/-53)
modules/Ubuntu/Components/qmldir (+3/-0)
tests/unit/runtest.sh (+1/-0)
tests/unit/tst_components/tst_haptics.qml (+52/-0)
tests/unit_x11/tst_serviceproperties/IncomingCallVibrateWatcher.qml (+0/-31)
tests/unit_x11/tst_serviceproperties/InvalidPropertyWatcher.qml (+0/-31)
tests/unit_x11/tst_serviceproperties/InvalidPropertyWatcher2.qml (+0/-32)
tests/unit_x11/tst_serviceproperties/tst_serviceproperties.cpp (+0/-146)
tests/unit_x11/tst_serviceproperties/tst_serviceproperties.pro (+0/-8)
To merge this branch: bzr merge lp:~zsombi/ubuntu-ui-toolkit/rtm-to-staging
Reviewer Review Type Date Requested Status
PS Jenkins bot continuous-integration Approve
Zoltan Balogh Approve
Review via email: mp+249220@code.launchpad.net

Commit message

RTM branch diff merge.

Description of the change

RTM branch diff merge.

To post a comment you must log in.
Revision history for this message
Zoltan Balogh (bzoltan) wrote :

Looks good

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'components.api'
2--- components.api 2015-02-06 11:49:35 +0000
3+++ components.api 2015-02-11 08:57:32 +0000
4@@ -62,6 +62,11 @@
5 property string fadeStyle
6 readonly property bool running
7 readonly property int status
8+Haptics 0.1 1.0
9+Object
10+ readonly property bool enabled
11+ property HapticsEffect effect
12+ function play(customEffect)
13 Header 0.1 1.0
14 AppHeader
15 property string _for_autopilot
16@@ -693,6 +698,64 @@
17 name: "QAbstractProxyModel"
18 prototype: "QAbstractItemModel"
19 Property { name: "sourceModel"; type: "QAbstractItemModel"; isPointer: true }
20+ name: "QDeclarativeFeedbackActuator"
21+ prototype: "QObject"
22+ exports: ["QtFeedback/Actuator 5.0"]
23+ name: "Capability"
24+ name: "State"
25+ Property { name: "actuatorId"; type: "int"; isReadonly: true }
26+ Property { name: "name"; type: "string"; isReadonly: true }
27+ Property { name: "state"; type: "State"; isReadonly: true }
28+ Property { name: "valid"; type: "bool"; isReadonly: true }
29+ Property { name: "enabled"; type: "bool" }
30+ Method {
31+ name: "isCapabilitySupported"
32+ Parameter { name: "capability"; type: "Capability" }
33+ name: "QDeclarativeFeedbackEffect"
34+ prototype: "QObject"
35+ exports: ["QtFeedback/Feedback 5.0", "QtFeedback/FeedbackEffect 5.0"]
36+ name: "Duration"
37+ name: "State"
38+ name: "ErrorType"
39+ Property { name: "running"; type: "bool" }
40+ Property { name: "paused"; type: "bool" }
41+ Property { name: "duration"; type: "int" }
42+ Property { name: "state"; type: "State" }
43+ Property { name: "error"; type: "ErrorType"; isReadonly: true }
44+ Method { name: "updateState" }
45+ Method { name: "start" }
46+ Method { name: "stop" }
47+ Method { name: "pause" }
48+ name: "QDeclarativeFileEffect"
49+ prototype: "QDeclarativeFeedbackEffect"
50+ exports: ["QtFeedback/FileEffect 5.0"]
51+ Property { name: "loaded"; type: "bool" }
52+ Property { name: "source"; type: "QUrl" }
53+ Property { name: "supportedMimeTypes"; type: "QStringList"; isReadonly: true }
54+ Method { name: "load" }
55+ Method { name: "unload" }
56+ name: "QDeclarativeHapticsEffect"
57+ prototype: "QDeclarativeFeedbackEffect"
58+ exports: ["QtFeedback/HapticsEffect 5.0"]
59+ Property {
60+ name: "availableActuators"
61+ Property { name: "intensity"; type: "double" }
62+ Property { name: "attackTime"; type: "int" }
63+ Property { name: "attackIntensity"; type: "double" }
64+ Property { name: "fadeTime"; type: "int" }
65+ Property { name: "fadeIntensity"; type: "double" }
66+ Property { name: "period"; type: "int" }
67+ Property { name: "actuator"; type: "QDeclarativeFeedbackActuator"; isPointer: true }
68+ name: "QDeclarativeThemeEffect"
69+ prototype: "QObject"
70+ exports: ["QtFeedback/EffectPlayer 5.0", "QtFeedback/ThemeEffect 5.0"]
71+ name: "Effect"
72+ Property { name: "supported"; type: "bool"; isReadonly: true }
73+ Property { name: "effect"; type: "Effect" }
74+ Method { name: "play" }
75+ Method {
76+ name: "play"
77+ Parameter { name: "effect"; type: "Effect" }
78 name: "QSortFilterProxyModel"
79 prototype: "QAbstractProxyModel"
80 Property { name: "filterRegExp"; type: "QRegExp" }
81@@ -1056,6 +1119,21 @@
82 name: "tag"
83 Parameter { name: "context"; type: "string" }
84 Parameter { name: "text"; type: "string" }
85+ prototype: "QObject"
86+ name: "Haptics"
87+ exports: ["Haptics -1.-1"]
88+ Property { name: "enabled"; type: "bool"; isReadonly: true }
89+ Property { name: "effect"; type: "QDeclarativeHapticsEffect"; isReadonly: true; isPointer: true }
90+ Method {
91+ name: "play"
92+ Parameter { name: "customEffect"; type: "QVariant" }
93+ Property { name: "__defaultPropertyFix"; type: "QObject"; isList: true; isReadonly: true }
94+ Property { name: "children"; type: "QObject"; isList: true; isReadonly: true }
95+ prototype: "QObject"
96+ name: "Object"
97+ exports: ["Object -1.-1"]
98+ Property { name: "__defaultPropertyFix"; type: "QObject"; isList: true; isReadonly: true }
99+ Property { name: "children"; type: "QObject"; isList: true; isReadonly: true }
100 name: "ULConditionalLayout"
101 prototype: "QObject"
102 exports: ["ConditionalLayout 0.1", "ConditionalLayout 1.0"]
103
104=== modified file 'debian/changelog'
105--- debian/changelog 2015-01-14 13:51:28 +0000
106+++ debian/changelog 2015-02-11 08:57:32 +0000
107@@ -227,6 +227,34 @@
108
109 -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Sun, 02 Nov 2014 13:01:56 +0000
110
111+ubuntu-ui-toolkit (1.1.1298+15.04.20150209~rtm-0ubuntu1) 14.09; urgency=medium
112+
113+ [ Zsombor Egri ]
114+ * isHapticsFeedbackEnabled context property exposed to drive
115+ HapticsFeedback in AbstractButton. (LP: #1391877)
116+ * Haptics singleton component to provide toolkit wide default and
117+ custom feedback functionaity controlled by system settings. (LP:
118+ #1391877)
119+
120+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Mon, 09 Feb 2015 13:10:45 +0000
121+
122+ubuntu-ui-toolkit (1.1.1298+15.04.20150202~rtm-0ubuntu1) 14.09; urgency=medium
123+
124+ [ Tim Peeters ]
125+ * Port "In Progress" translation fix from staging to rtm. (LP:
126+ #1391617, #1081607)
127+
128+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Mon, 02 Feb 2015 09:11:21 +0000
129+
130+ubuntu-ui-toolkit (1.1.1298+15.04.20150116~rtm-0ubuntu1) 14.09; urgency=low
131+
132+ [ Florian Boucault ]
133+ * ActivityIndicator: make its animation rely solely on the rendering
134+ thread so that it does not stop spinning if the main thread is
135+ blocked. (LP: #1411376)
136+
137+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Fri, 16 Jan 2015 10:17:50 +0000
138+
139 ubuntu-ui-toolkit (1.1.1298+15.04.20141111.2~rtm-0ubuntu1) 14.09; urgency=low
140
141 [ Ubuntu daily release ]
142
143=== added file 'modules/Ubuntu/Components/11/Haptics.qml'
144--- modules/Ubuntu/Components/11/Haptics.qml 1970-01-01 00:00:00 +0000
145+++ modules/Ubuntu/Components/11/Haptics.qml 2015-02-11 08:57:32 +0000
146@@ -0,0 +1,181 @@
147+/*
148+ * Copyright 2014 Canonical Ltd.
149+ *
150+ * This program is free software; you can redistribute it and/or modify
151+ * it under the terms of the GNU Lesser General Public License as published by
152+ * the Free Software Foundation; version 3.
153+ *
154+ * This program is distributed in the hope that it will be useful,
155+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
156+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
157+ * GNU Lesser General Public License for more details.
158+ *
159+ * You should have received a copy of the GNU Lesser General Public License
160+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
161+ */
162+
163+pragma Singleton
164+import QtQuick 2.0
165+import QtFeedback 5.0
166+import Ubuntu.Components 1.1
167+
168+/*!
169+ \qmltype Haptics
170+ \inqmlmodule Ubuntu.Components 1.1
171+ \ingroup ubuntu-services
172+ \brief Singleton defining the haptics feedback used in components, where execution
173+ of the feedback is controlled by the system settings.
174+
175+ Supports global feedback as well as custom feedback. Global feedback can be
176+ configured through its properties, and \l play function will play the default
177+ configuration, or a custom one if parameter is given.
178+
179+ Example of using Haptics:
180+ \qml
181+ import QtQuick 2.3
182+ import Ubuntu.Components 1.1
183+
184+ Item {
185+ implicitWidth: units.gu(20)
186+ implicitHeight: units.gu(5)
187+
188+ Label {
189+ text: "Press me"
190+ anchors.fill: parent
191+ horizontalAlignment: Text.AlignHCenter
192+ verticalAlignment: Text.AlignVCenter
193+ }
194+ MouseArea {
195+ anchors.fill: parent
196+ onClicked: Haptics.play()
197+ }
198+ }
199+ \endqml
200+
201+ Custom effects can be played as follows:
202+ \qml
203+ import QtQuick 2.3
204+ import Ubuntu.Components 1.1
205+
206+ Item {
207+ implicitWidth: units.gu(20)
208+ implicitHeight: units.gu(5)
209+
210+ Label {
211+ text: "Press me"
212+ anchors.fill: parent
213+ horizontalAlignment: Text.AlignHCenter
214+ verticalAlignment: Text.AlignVCenter
215+ }
216+ MouseArea {
217+ anchors.fill: parent
218+ onClicked: Haptics.play({duration: 25, attackIntensity: 0.7})
219+ }
220+ }
221+ \endqml
222+
223+ \note Though the \l effect property exposes \c start, \c stop and \c pause
224+ functions, use those only if you want to have feedback independent on what the
225+ system setting is.
226+ */
227+Object {
228+
229+ /*!
230+ \qmlproperty bool enabled
231+ \readonly
232+ The property specifies whether the haptics feedback is enabled or not by the system.
233+ */
234+ readonly property alias enabled: vibra.otherVibrate
235+
236+ /*!
237+ \qmlproperty HapticsEffect effect
238+ The property defines the settings of the haptics effect used by the component.
239+ The default setting is a haptics effect with a duration of 10 milliseconds
240+ with an intensity of 1.0, having fading time of 50 millisecods and fading
241+ intensity 0.0, and attack time of 50 milliseconds and with an intensity of
242+ 0.0.
243+ */
244+ property alias effect: effect
245+
246+ /*!
247+ \qmlmethod play([customEffect])
248+ The function plays the feedback with the configuration specified in \l effect
249+ if no parameter is given. Custom effect can be played by specifying the effect
250+ properties in a JSON object in \c customEffect.
251+
252+ The function will exit unconditionaly if playing the effects is blocked by
253+ system settings.
254+
255+ The function will not stop any ongoing haptics effect played, if that one
256+ was a default haptics effect. In case of custom effects, the previous effect
257+ will be stopped, and settings will be restored before the new haptics will
258+ be played. The custom settings properties (the ones which are required to
259+ be different from the ones defined in the \l effect) must be specified in
260+ the parameter in a JSON object.
261+ */
262+ function play(customEffect) {
263+ if (!vibra.otherVibrate) {
264+ return;
265+ }
266+ if (effectData.data) {
267+ // we have a custom effect playing, stop it
268+ effect.stop();
269+ }
270+ if (effect.running) {
271+ // this is a global effect, leave
272+ return;
273+ }
274+ if (customEffect) {
275+ effectData.backup(customEffect);
276+ }
277+ effect.start();
278+ }
279+
280+ QtObject {
281+ id: effectData
282+ property var data
283+
284+ function backup(customEffect) {
285+ data = customEffect;
286+ for (var p in data) {
287+ var value = data[p];
288+ data[p] = effect[p];
289+ effect[p] = value;
290+ }
291+ }
292+ function restore() {
293+ for (var p in data) {
294+ effect[p] = data[p];
295+ }
296+ data = undefined;
297+ }
298+ }
299+
300+ // local feedback component used to play feedback
301+ HapticsEffect {
302+ id: effect
303+ attackIntensity: 0.0
304+ attackTime: 50
305+ intensity: 1.0
306+ duration: 10
307+ fadeTime: 50
308+ fadeIntensity: 0.0
309+
310+ onStateChanged: {
311+ if (state == HapticsEffect.Stopped) {
312+ effectData.restore();
313+ }
314+ }
315+ }
316+
317+ // watch system settings for otherVibrate
318+ ServiceProperties {
319+ objectName: "system_effect_settings"
320+ id: vibra
321+ service: "org.freedesktop.Accounts"
322+ serviceInterface: "org.freedesktop.Accounts"
323+ path: "/org/freedesktop/Accounts"
324+ adaptorInterface: "com.ubuntu.touch.AccountsService.Sound"
325+ property bool otherVibrate: true
326+ }
327+}
328
329=== modified file 'modules/Ubuntu/Components/AbstractButton.qml'
330--- modules/Ubuntu/Components/AbstractButton.qml 2014-12-03 14:43:27 +0000
331+++ modules/Ubuntu/Components/AbstractButton.qml 2015-02-11 08:57:32 +0000
332@@ -15,7 +15,6 @@
333 */
334
335 import QtQuick 2.0
336-import QtFeedback 5.0
337 import Ubuntu.Components 1.1
338
339 /*!
340@@ -83,16 +82,6 @@
341
342 activeFocusOnPress: true
343
344- HapticsEffect {
345- id: pressEffect
346- attackIntensity: 0.0
347- attackTime: 50
348- intensity: 1.0
349- duration: 10
350- fadeTime: 50
351- fadeIntensity: 0.0
352- }
353-
354 MouseArea {
355 id: mouseArea
356 anchors.fill: parent
357@@ -100,9 +89,14 @@
358 // as it might occlude the newly assigned mouse area.
359 hoverEnabled: true
360
361+ // invoke Haptics singleton earlier than we press the button,
362+ // so we give some time for the singleton to sync settings with the service
363+ property bool hapticsEnabled: Haptics.enabled
364+
365 onClicked: {
366 if (button.__acceptEvents) {
367- pressEffect.start()
368+ // FIXME (Vivid) call this in the style rather than from AbstractButton
369+ Haptics.play();
370 button.clicked()
371 }
372 }
373
374=== modified file 'modules/Ubuntu/Components/Themes/Ambiance/ActivityIndicatorStyle.qml'
375--- modules/Ubuntu/Components/Themes/Ambiance/ActivityIndicatorStyle.qml 2014-07-08 10:59:01 +0000
376+++ modules/Ubuntu/Components/Themes/Ambiance/ActivityIndicatorStyle.qml 2015-02-11 08:57:32 +0000
377@@ -28,12 +28,7 @@
378 verticalAlignment: Image.AlignVCenter
379 source: "artwork/spinner.png"
380
381- /*
382- Changed from RotationAnimator to RotationAnimation to
383- work around bug: https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1338602
384- "Activity Indicator crashes in QML/Widget mixed applications"
385- */
386- RotationAnimation on rotation {
387+ RotationAnimator on rotation {
388 running: styledItem.running
389 from: 0
390 to: 360
391
392=== added file 'modules/Ubuntu/Components/plugin/adapters/dbuspropertywatcher_p.cpp'
393--- modules/Ubuntu/Components/plugin/adapters/dbuspropertywatcher_p.cpp 1970-01-01 00:00:00 +0000
394+++ modules/Ubuntu/Components/plugin/adapters/dbuspropertywatcher_p.cpp 2015-02-11 08:57:32 +0000
395@@ -0,0 +1,226 @@
396+/*
397+ * Copyright 2014 Canonical Ltd.
398+ *
399+ * This program is free software; you can redistribute it and/or modify
400+ * it under the terms of the GNU Lesser General Public License as published by
401+ * the Free Software Foundation; version 3.
402+ *
403+ * This program is distributed in the hope that it will be useful,
404+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
405+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
406+ * GNU Lesser General Public License for more details.
407+ *
408+ * You should have received a copy of the GNU Lesser General Public License
409+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
410+ */
411+
412+#include "dbuspropertywatcher_p.h"
413+#include <QtDBus/QDBusReply>
414+#include <unistd.h>
415+#include <sys/types.h>
416+#include "i18n.h"
417+#include <QtQml/QQmlInfo>
418+
419+#define DYNAMIC_PROPERTY "__q_property"
420+
421+UCServicePropertiesPrivate *createServicePropertiesAdapter(UCServiceProperties *owner)
422+{
423+ return new DBusServiceProperties(owner);
424+}
425+
426+DBusServiceProperties::DBusServiceProperties(UCServiceProperties *qq)
427+ : UCServicePropertiesPrivate(qq)
428+ , connection("")
429+ , watcher(0)
430+ , iface(0)
431+{
432+}
433+
434+bool DBusServiceProperties::init()
435+{
436+ // crear previous connections
437+ setStatus(UCServiceProperties::Inactive);
438+ delete iface;
439+ iface = 0;
440+ delete watcher;
441+ watcher = 0;
442+ setError(QString());
443+
444+ if (service.isEmpty() || path.isEmpty()) {
445+ setStatus(UCServiceProperties::ConnectionError);
446+ setError(UbuntuI18n::instance().tr("No service/path specified"));
447+ return false;
448+ }
449+
450+ switch (type) {
451+ case UCServiceProperties::System:
452+ {
453+ connection = QDBusConnection::systemBus();
454+ break;
455+ }
456+ case UCServiceProperties::Session:
457+ {
458+ connection = QDBusConnection::sessionBus();
459+ break;
460+ }
461+ default:
462+ {
463+ setStatus(UCServiceProperties::ConnectionError);
464+ setError(UbuntuI18n::instance().tr("Invalid bus type: %1.").arg(type));
465+ return false;
466+ }
467+ }
468+
469+ Q_Q(UCServiceProperties);
470+ // connect dbus watcher to catch OwnerChanged
471+ watcher = new QDBusServiceWatcher(service, connection, QDBusServiceWatcher::WatchForOwnerChange, q);
472+ // connect interface
473+ iface = new QDBusInterface(service, path, interface, connection, q);
474+ if (!iface->isValid()) {
475+ setStatus(UCServiceProperties::ConnectionError);
476+ setError(iface->lastError().message());
477+ return false;
478+ }
479+ // connect watcher to get owner changes
480+ QObject::connect(watcher, SIGNAL(serviceOwnerChanged(QString,QString,QString)),
481+ this, SLOT(changeServiceOwner(QString,QString,QString)));
482+ return setupInterface();
483+}
484+
485+/*
486+ * Connect dbus signal identified by (service, path, iface, name) quaduple to a
487+ * slot to receive property changes.
488+ */
489+bool DBusServiceProperties::setupInterface()
490+{
491+ QDBusReply<QDBusObjectPath> dbusObjectPath = iface->call("FindUserById", qlonglong(getuid()));
492+ if (dbusObjectPath.isValid()) {
493+ objectPath = dbusObjectPath.value().path();
494+ iface->connection().connect(
495+ service,
496+ objectPath,
497+ "org.freedesktop.DBus.Properties",
498+ "PropertiesChanged",
499+ this,
500+ SLOT(updateProperties(QString,QVariantMap,QStringList)));
501+ return true;
502+ }
503+
504+ setStatus(UCServiceProperties::ConnectionError);
505+ setError(dbusObjectPath.error().message());
506+ return false;
507+}
508+
509+bool DBusServiceProperties::fetchPropertyValues()
510+{
511+ scannedProperties = properties;
512+ Q_FOREACH(QString property, properties) {
513+ readProperty(property);
514+ }
515+ return true;
516+}
517+
518+/*
519+ * Reads a property value from the adaptorInterface asynchronously.
520+ */
521+bool DBusServiceProperties::readProperty(const QString &property)
522+{
523+ if ((status < UCServiceProperties::Synchronizing) || objectPath.isEmpty()) {
524+ return false;
525+ }
526+ Q_Q(UCServiceProperties);
527+ QDBusInterface readIFace(iface->interface(), objectPath, "org.freedesktop.DBus.Properties", connection);
528+ if (!readIFace.isValid()) {
529+ // report invalid interface only if the property's first letter was with capital one!
530+ if (property[0].isUpper()) {
531+ warning(readIFace.lastError().message());
532+ }
533+ return false;
534+ }
535+ QDBusPendingCall pending = readIFace.asyncCall("Get", adaptor, property);
536+ if (pending.isError()) {
537+ warning(pending.error().message());
538+ return false;
539+ }
540+ QDBusPendingCallWatcher *callWatcher = new QDBusPendingCallWatcher(pending, q);
541+ QObject::connect(callWatcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
542+ this, SLOT(readFinished(QDBusPendingCallWatcher*)));
543+
544+ // set a dynamic property so we know which property are we reading
545+ callWatcher->setProperty(DYNAMIC_PROPERTY, property);
546+ return true;
547+}
548+
549+/*
550+ * Writes a property value to theadaptorInterface synchronously. It is for pure testing purposes.
551+ */
552+bool DBusServiceProperties::testProperty(const QString &property, const QVariant &value)
553+{
554+ if (objectPath.isEmpty()) {
555+ return false;
556+ }
557+ QDBusInterface writeIFace(iface->interface(), objectPath, "org.freedesktop.DBus.Properties", connection);
558+ if (!writeIFace.isValid()) {
559+ // invalid interface
560+ return false;
561+ }
562+ QDBusMessage msg = writeIFace.call("Set", adaptor, property, QVariant::fromValue(QDBusVariant(value)));
563+ return msg.type() == QDBusMessage::ReplyMessage;
564+}
565+
566+/*
567+ * Slot called when the async read operation finishes.
568+ */
569+void DBusServiceProperties::readFinished(QDBusPendingCallWatcher *call)
570+{
571+ Q_Q(UCServiceProperties);
572+ QDBusPendingReply<QVariant> reply = *call;
573+ QString property = call->property(DYNAMIC_PROPERTY).toString();
574+ scannedProperties.removeAll(property);
575+ if (reply.isError()) {
576+ // remove the property from being watched, as it has no property like that
577+ properties.removeAll(property);
578+ if (property[0].isUpper()) {
579+ // report error!
580+ warning(reply.error().message());
581+ }
582+ } else {
583+ // update watched property value
584+ // make sure we have lower case when the property value is updated
585+ property[0] = property[0].toLower();
586+ q->setProperty(property.toLocal8Bit().constData(), reply.value());
587+ }
588+
589+ if ((status == UCServiceProperties::Synchronizing) && scannedProperties.isEmpty()) {
590+ // set status to active
591+ setStatus(UCServiceProperties::Active);
592+ }
593+
594+ // delete watcher
595+ call->deleteLater();
596+}
597+
598+/*
599+ * Slot called when service owner is changed.
600+ */
601+void DBusServiceProperties::changeServiceOwner(const QString &serviceName, const QString &oldOwner, const QString &newOwner)
602+{
603+ Q_UNUSED(oldOwner);
604+ Q_UNUSED(newOwner);
605+ if (serviceName != service) {
606+ return;
607+ }
608+ setupInterface();
609+}
610+
611+/*
612+ * Slot called when the properties are changed in the service.
613+ */
614+void DBusServiceProperties::updateProperties(const QString &onInterface, const QVariantMap &map, const QStringList &invalidated)
615+{
616+ Q_UNUSED(onInterface);
617+ Q_UNUSED(map);
618+ Q_FOREACH(const QString &property, invalidated) {
619+ readProperty(property);
620+ }
621+}
622
623=== removed file 'modules/Ubuntu/Components/plugin/adapters/dbuspropertywatcher_p.cpp'
624--- modules/Ubuntu/Components/plugin/adapters/dbuspropertywatcher_p.cpp 2014-12-03 08:26:33 +0000
625+++ modules/Ubuntu/Components/plugin/adapters/dbuspropertywatcher_p.cpp 1970-01-01 00:00:00 +0000
626@@ -1,226 +0,0 @@
627-/*
628- * Copyright 2014 Canonical Ltd.
629- *
630- * This program is free software; you can redistribute it and/or modify
631- * it under the terms of the GNU Lesser General Public License as published by
632- * the Free Software Foundation; version 3.
633- *
634- * This program is distributed in the hope that it will be useful,
635- * but WITHOUT ANY WARRANTY; without even the implied warranty of
636- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
637- * GNU Lesser General Public License for more details.
638- *
639- * You should have received a copy of the GNU Lesser General Public License
640- * along with this program. If not, see <http://www.gnu.org/licenses/>.
641- */
642-
643-#include "dbuspropertywatcher_p.h"
644-#include <QtDBus/QDBusReply>
645-#include <unistd.h>
646-#include <sys/types.h>
647-#include "i18n.h"
648-#include <QtQml/QQmlInfo>
649-
650-#define DYNAMIC_PROPERTY "__q_property"
651-
652-UCServicePropertiesPrivate *createServicePropertiesAdapter(UCServiceProperties *owner)
653-{
654- return new DBusServiceProperties(owner);
655-}
656-
657-DBusServiceProperties::DBusServiceProperties(UCServiceProperties *qq)
658- : UCServicePropertiesPrivate(qq)
659- , connection("")
660- , watcher(0)
661- , iface(0)
662-{
663-}
664-
665-bool DBusServiceProperties::init()
666-{
667- // crear previous connections
668- setStatus(UCServiceProperties::Inactive);
669- delete iface;
670- iface = 0;
671- delete watcher;
672- watcher = 0;
673- setError(QString());
674-
675- if (service.isEmpty() || path.isEmpty()) {
676- setStatus(UCServiceProperties::ConnectionError);
677- setError(UbuntuI18n::instance().tr("No service/path specified"));
678- return false;
679- }
680-
681- switch (type) {
682- case UCServiceProperties::System:
683- {
684- connection = QDBusConnection::systemBus();
685- break;
686- }
687- case UCServiceProperties::Session:
688- {
689- connection = QDBusConnection::sessionBus();
690- break;
691- }
692- default:
693- {
694- setStatus(UCServiceProperties::ConnectionError);
695- setError(UbuntuI18n::instance().tr("Invalid bus type: %1.").arg(type));
696- return false;
697- }
698- }
699-
700- Q_Q(UCServiceProperties);
701- // connect dbus watcher to catch OwnerChanged
702- watcher = new QDBusServiceWatcher(service, connection, QDBusServiceWatcher::WatchForOwnerChange, q);
703- // connect interface
704- iface = new QDBusInterface(service, path, interface, connection, q);
705- if (!iface->isValid()) {
706- setStatus(UCServiceProperties::ConnectionError);
707- setError(iface->lastError().message());
708- return false;
709- }
710- // connect watcher to get owner changes
711- QObject::connect(watcher, SIGNAL(serviceOwnerChanged(QString,QString,QString)),
712- this, SLOT(changeServiceOwner(QString,QString,QString)));
713- return setupInterface();
714-}
715-
716-/*
717- * Connect dbus signal identified by (service, path, iface, name) quaduple to a
718- * slot to receive property changes.
719- */
720-bool DBusServiceProperties::setupInterface()
721-{
722- QDBusReply<QDBusObjectPath> dbusObjectPath = iface->call("FindUserById", qlonglong(getuid()));
723- if (dbusObjectPath.isValid()) {
724- objectPath = dbusObjectPath.value().path();
725- iface->connection().connect(
726- service,
727- objectPath,
728- "org.freedesktop.DBus.Properties",
729- "PropertiesChanged",
730- this,
731- SLOT(updateProperties(QString,QVariantMap,QStringList)));
732- return true;
733- }
734-
735- setStatus(UCServiceProperties::ConnectionError);
736- setError(dbusObjectPath.error().message());
737- return false;
738-}
739-
740-bool DBusServiceProperties::fetchPropertyValues()
741-{
742- scannedProperties = properties;
743- Q_FOREACH(QString property, properties) {
744- readProperty(property);
745- }
746- return true;
747-}
748-
749-/*
750- * Reads a property value from the adaptorInterface asynchronously.
751- */
752-bool DBusServiceProperties::readProperty(const QString &property)
753-{
754- if ((status < UCServiceProperties::Synchronizing) || objectPath.isEmpty()) {
755- return false;
756- }
757- Q_Q(UCServiceProperties);
758- QDBusInterface readIFace(iface->interface(), objectPath, "org.freedesktop.DBus.Properties", connection);
759- if (!readIFace.isValid()) {
760- // report invalid interface only if the property's first letter was with capital one!
761- if (property[0].isUpper()) {
762- qmlInfo(q) << readIFace.lastError().message();
763- }
764- return false;
765- }
766- QDBusPendingCall pending = readIFace.asyncCall("Get", adaptor, property);
767- if (pending.isError()) {
768- qmlInfo(q) << pending.error().message();
769- return false;
770- }
771- QDBusPendingCallWatcher *callWatcher = new QDBusPendingCallWatcher(pending, q);
772- QObject::connect(callWatcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
773- this, SLOT(readFinished(QDBusPendingCallWatcher*)));
774-
775- // set a dynamic property so we know which property are we reading
776- callWatcher->setProperty(DYNAMIC_PROPERTY, property);
777- return true;
778-}
779-
780-/*
781- * Writes a property value to theadaptorInterface synchronously. It is for pure testing purposes.
782- */
783-bool DBusServiceProperties::testProperty(const QString &property, const QVariant &value)
784-{
785- if (objectPath.isEmpty()) {
786- return false;
787- }
788- QDBusInterface writeIFace(iface->interface(), objectPath, "org.freedesktop.DBus.Properties", connection);
789- if (!writeIFace.isValid()) {
790- // invalid interface
791- return false;
792- }
793- QDBusMessage msg = writeIFace.call("Set", adaptor, property, QVariant::fromValue(QDBusVariant(value)));
794- return msg.type() == QDBusMessage::ReplyMessage;
795-}
796-
797-/*
798- * Slot called when the async read operation finishes.
799- */
800-void DBusServiceProperties::readFinished(QDBusPendingCallWatcher *call)
801-{
802- Q_Q(UCServiceProperties);
803- QDBusPendingReply<QVariant> reply = *call;
804- QString property = call->property(DYNAMIC_PROPERTY).toString();
805- scannedProperties.removeAll(property);
806- if (reply.isError()) {
807- // remove the property from being watched, as it has no property like that
808- properties.removeAll(property);
809- if (property[0].isUpper()) {
810- // report error!
811- qmlInfo(q) << reply.error().message();
812- }
813- } else {
814- // update watched property value
815- // make sure we have lower case when the property value is updated
816- property[0] = property[0].toLower();
817- q->setProperty(property.toLocal8Bit().constData(), reply.value());
818- }
819-
820- if ((status == UCServiceProperties::Synchronizing) && scannedProperties.isEmpty()) {
821- // set status to active
822- setStatus(UCServiceProperties::Active);
823- }
824-
825- // delete watcher
826- call->deleteLater();
827-}
828-
829-/*
830- * Slot called when service owner is changed.
831- */
832-void DBusServiceProperties::changeServiceOwner(const QString &serviceName, const QString &oldOwner, const QString &newOwner)
833-{
834- Q_UNUSED(oldOwner);
835- Q_UNUSED(newOwner);
836- if (serviceName != service) {
837- return;
838- }
839- setupInterface();
840-}
841-
842-/*
843- * Slot called when the properties are changed in the service.
844- */
845-void DBusServiceProperties::updateProperties(const QString &onInterface, const QVariantMap &map, const QStringList &invalidated)
846-{
847- Q_UNUSED(onInterface);
848- Q_UNUSED(map);
849- Q_FOREACH(const QString &property, invalidated) {
850- readProperty(property);
851- }
852-}
853
854=== added file 'modules/Ubuntu/Components/plugin/adapters/dbuspropertywatcher_p.h'
855--- modules/Ubuntu/Components/plugin/adapters/dbuspropertywatcher_p.h 1970-01-01 00:00:00 +0000
856+++ modules/Ubuntu/Components/plugin/adapters/dbuspropertywatcher_p.h 2015-02-11 08:57:32 +0000
857@@ -0,0 +1,55 @@
858+/*
859+ * Copyright 2014 Canonical Ltd.
860+ *
861+ * This program is free software; you can redistribute it and/or modify
862+ * it under the terms of the GNU Lesser General Public License as published by
863+ * the Free Software Foundation; version 3.
864+ *
865+ * This program is distributed in the hope that it will be useful,
866+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
867+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
868+ * GNU Lesser General Public License for more details.
869+ *
870+ * You should have received a copy of the GNU Lesser General Public License
871+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
872+ */
873+
874+#ifndef DBUSPROPERTYWATCHER_P_H
875+#define DBUSPROPERTYWATCHER_P_H
876+
877+#include <QtCore/QObject>
878+#include <QtDBus/QDBusConnection>
879+#include <QtDBus/QDBusServiceWatcher>
880+#include <QtDBus/QDBusInterface>
881+
882+#include "ucserviceproperties_p.h"
883+
884+class QDBusPendingCallWatcher;
885+class DBusServiceProperties : public QObject, public UCServicePropertiesPrivate
886+{
887+ Q_OBJECT
888+ Q_DECLARE_PUBLIC(UCServiceProperties)
889+public:
890+ DBusServiceProperties(UCServiceProperties *qq);
891+
892+ bool init();
893+ bool fetchPropertyValues();
894+ bool readProperty(const QString &property);
895+ // for testing purposes only!!!
896+ bool testProperty(const QString &property, const QVariant &value);
897+
898+ QStringList scannedProperties;
899+ QDBusConnection connection;
900+ QDBusServiceWatcher *watcher;
901+ QDBusInterface *iface;
902+ QString objectPath;
903+
904+ bool setupInterface();
905+
906+public Q_SLOTS:
907+ void readFinished(QDBusPendingCallWatcher *watcher);
908+ void changeServiceOwner(const QString &serviceName, const QString &oldOwner, const QString &newOwner);
909+ void updateProperties(const QString &iface, const QVariantMap &map, const QStringList &invalidated);
910+};
911+
912+#endif // DBUSPROPERTYWATCHER_P_H
913
914=== removed file 'modules/Ubuntu/Components/plugin/adapters/dbuspropertywatcher_p.h'
915--- modules/Ubuntu/Components/plugin/adapters/dbuspropertywatcher_p.h 2014-12-03 08:26:33 +0000
916+++ modules/Ubuntu/Components/plugin/adapters/dbuspropertywatcher_p.h 1970-01-01 00:00:00 +0000
917@@ -1,55 +0,0 @@
918-/*
919- * Copyright 2014 Canonical Ltd.
920- *
921- * This program is free software; you can redistribute it and/or modify
922- * it under the terms of the GNU Lesser General Public License as published by
923- * the Free Software Foundation; version 3.
924- *
925- * This program is distributed in the hope that it will be useful,
926- * but WITHOUT ANY WARRANTY; without even the implied warranty of
927- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
928- * GNU Lesser General Public License for more details.
929- *
930- * You should have received a copy of the GNU Lesser General Public License
931- * along with this program. If not, see <http://www.gnu.org/licenses/>.
932- */
933-
934-#ifndef DBUSPROPERTYWATCHER_P_H
935-#define DBUSPROPERTYWATCHER_P_H
936-
937-#include <QtCore/QObject>
938-#include <QtDBus/QDBusConnection>
939-#include <QtDBus/QDBusServiceWatcher>
940-#include <QtDBus/QDBusInterface>
941-
942-#include "ucserviceproperties_p.h"
943-
944-class QDBusPendingCallWatcher;
945-class DBusServiceProperties : public QObject, public UCServicePropertiesPrivate
946-{
947- Q_OBJECT
948- Q_DECLARE_PUBLIC(UCServiceProperties)
949-public:
950- DBusServiceProperties(UCServiceProperties *qq);
951-
952- bool init();
953- bool fetchPropertyValues();
954- bool readProperty(const QString &property);
955- // for testing purposes only!!!
956- bool testProperty(const QString &property, const QVariant &value);
957-
958- QStringList scannedProperties;
959- QDBusConnection connection;
960- QDBusServiceWatcher *watcher;
961- QDBusInterface *iface;
962- QString objectPath;
963-
964- bool setupInterface();
965-
966-public Q_SLOTS:
967- void readFinished(QDBusPendingCallWatcher *watcher);
968- void changeServiceOwner(const QString &serviceName, const QString &oldOwner, const QString &newOwner);
969- void updateProperties(const QString &iface, const QVariantMap &map, const QStringList &invalidated);
970-};
971-
972-#endif // DBUSPROPERTYWATCHER_P_H
973
974=== modified file 'modules/Ubuntu/Components/plugin/plugin.pro'
975--- modules/Ubuntu/Components/plugin/plugin.pro 2015-01-22 06:26:27 +0000
976+++ modules/Ubuntu/Components/plugin/plugin.pro 2015-02-11 08:57:32 +0000
977@@ -67,13 +67,13 @@
978 ucactioncontext.h \
979 ucactionmanager.h \
980 adapters/actionsproxy_p.h \
981+ adapters/dbuspropertywatcher_p.h \
982 uclistitem.h \
983 uclistitem_p.h \
984 uclistitemactions.h \
985 uclistitemactions_p.h \
986 propertychange_p.h \
987 uclistitemstyle.h \
988- adapters\dbuspropertywatcher_p.h \
989 ucserviceproperties.h \
990 ucserviceproperties_p.h
991
992@@ -112,6 +112,7 @@
993 ucactioncontext.cpp \
994 ucactionmanager.cpp \
995 adapters/actionsproxy_p.cpp \
996+ adapters/dbuspropertywatcher_p.cpp \
997 uclistitem.cpp \
998 uclistitemactions.cpp \
999 propertychange_p.cpp \
1000@@ -119,7 +120,6 @@
1001 ucviewitemsattached.cpp \
1002 uclistitemattached.cpp \
1003 ucactionpanel_p.cpp \
1004- adapters\dbuspropertywatcher_p.cpp \
1005 ucserviceproperties.cpp
1006
1007 # adapters
1008
1009=== added file 'modules/Ubuntu/Components/plugin/ucserviceproperties.cpp'
1010--- modules/Ubuntu/Components/plugin/ucserviceproperties.cpp 1970-01-01 00:00:00 +0000
1011+++ modules/Ubuntu/Components/plugin/ucserviceproperties.cpp 2015-02-11 08:57:32 +0000
1012@@ -0,0 +1,327 @@
1013+/*
1014+ * Copyright 2014 Canonical Ltd.
1015+ *
1016+ * This program is free software; you can redistribute it and/or modify
1017+ * it under the terms of the GNU Lesser General Public License as published by
1018+ * the Free Software Foundation; version 3.
1019+ *
1020+ * This program is distributed in the hope that it will be useful,
1021+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1022+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1023+ * GNU Lesser General Public License for more details.
1024+ *
1025+ * You should have received a copy of the GNU Lesser General Public License
1026+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1027+ */
1028+
1029+#include "ucserviceproperties.h"
1030+#include "ucserviceproperties_p.h"
1031+#include "i18n.h"
1032+#include <QtQml/QQmlInfo>
1033+#include <QtCore/QMetaProperty>
1034+#include <QtQml/QQmlProperty>
1035+#include <QtQml/private/qqmlproperty_p.h>
1036+
1037+UCServicePropertiesPrivate::UCServicePropertiesPrivate(UCServiceProperties *qq)
1038+ : q_ptr(qq)
1039+ , ready(false)
1040+ , status(UCServiceProperties::Inactive)
1041+ , type(UCServiceProperties::System)
1042+{
1043+}
1044+
1045+UCServicePropertiesPrivate::~UCServicePropertiesPrivate()
1046+{
1047+}
1048+
1049+UCServicePropertiesPrivate *UCServicePropertiesPrivate::get(UCServiceProperties *service)
1050+{
1051+ return service->d_func();
1052+}
1053+
1054+void UCServicePropertiesPrivate::warning(const QString &message)
1055+{
1056+ QByteArray suppressWarnings = qgetenv("SUPPRESS_SERVICEPROPERTIES_WARNINGS");
1057+ if ((suppressWarnings == "yes") || (suppressWarnings == "1")) {
1058+ return;
1059+ }
1060+ qmlInfo(q_ptr) << message;
1061+}
1062+
1063+void UCServicePropertiesPrivate::setError(const QString &msg)
1064+{
1065+ if (error == msg) {
1066+ return;
1067+ }
1068+ error = msg;
1069+ Q_EMIT q_ptr->errorChanged();
1070+}
1071+
1072+void UCServicePropertiesPrivate::setStatus(UCServiceProperties::Status status)
1073+{
1074+ if (this->status == status) {
1075+ return;
1076+ }
1077+ this->status = status;
1078+ Q_EMIT q_ptr->statusChanged();
1079+}
1080+
1081+void printLocked(UCServiceProperties *owner)
1082+{
1083+ UCServicePropertiesPrivate::get(owner)->
1084+ warning(UbuntuI18n::instance().tr("Changing connection parameters forbidden."));
1085+}
1086+
1087+/*!
1088+ * \qmltype ServiceProperties
1089+ * \instantiates UCServiceProperties
1090+ * \inqmlmodule Ubuntu.Components 1.1
1091+ * \since Ubuntu.Components 1.1
1092+ * \ingroup ubuntu-services
1093+ * \brief The component enables accessing service properties from QML.
1094+ *
1095+ * The services accessed by the component are ones providing their interfaces
1096+ * through DBus. The component is specialized to read properties exposed by these
1097+ * services, andf to keep these property values up to date. It is not meant to
1098+ * access signals or slots exposed, nor to change the values of the properties
1099+ * watched.
1100+ *
1101+ * Properties watched should be declared within the body of the component like
1102+ * any other QML property, preferably defining a default value for them. The component
1103+ * will enumerate these properties and will ask the service to provide values for
1104+ * those. When enumerating properties, each property will be checked twice, with
1105+ * the case specified as well as with the first letter capitalized.
1106+ * \qml
1107+ * import QtQuick 2.3
1108+ * import Ubuntu.Components 1.1
1109+ *
1110+ * ServiceProperties {
1111+ * service: "org.freenode.AccountsService"
1112+ * path: "/org/freenode/AccountsService"
1113+ * serviceInterface: "org.freenode.AccountsService"
1114+ * adaptorInterface: "com.ubuntu.touch.Accounts.Sound"
1115+ * // listing properties to watch
1116+ * // each property name existence will be checked against the current case
1117+ * // as well as with first character capitalized
1118+ * property bool incomingCallVibrate: true
1119+ * }
1120+ * \endqml
1121+ *
1122+ * Note that there are few properties which must be set in order the component
1123+ * to work. These are \l service, \l path and \l adaptorInterface. Also, once
1124+ * specified, \l service, \l serviceInterface and \l adaptorInterface values
1125+ * should not be changed as it cannot be guaranteed that properties watched will
1126+ * be available on those service. Therefore any change on these properties after
1127+ * the component completion will be ignored. Property bindings on properties
1128+ * watched will be ignored as well, as service will report changes in these property
1129+ * values.
1130+ *
1131+ * The service is connected once the component gets completed (Component.onCompleted).
1132+ * The \l error property specifies any error occured during connection, and the
1133+ * \l status property notifies whether the connection to the service is active or not.
1134+ *
1135+ * \note Pay attention when chosing the service watched, and set your application's
1136+ * AppArmor rights to ensure a successful service connection.
1137+ */
1138+UCServiceProperties::UCServiceProperties(QObject *parent)
1139+ : QObject(parent)
1140+ , d_ptr(createServicePropertiesAdapter(this))
1141+{
1142+}
1143+UCServiceProperties::~UCServiceProperties()
1144+{
1145+ delete d_ptr;
1146+ d_ptr = 0;
1147+}
1148+
1149+void UCServiceProperties::classBegin()
1150+{
1151+}
1152+
1153+void UCServiceProperties::componentComplete()
1154+{
1155+ Q_D(UCServiceProperties);
1156+ d->ready = true;
1157+ // enumerate properties
1158+ const QMetaObject *mo = metaObject();
1159+ for (int i = mo->propertyOffset(); i < mo->propertyCount(); i++) {
1160+ const QMetaProperty prop = mo->property(i);
1161+ QString property(prop.name());
1162+
1163+ // check the binding on the property and warn if there is one.
1164+ QQmlProperty qmlProperty(this, property);
1165+ if (QQmlPropertyPrivate::binding(qmlProperty)) {
1166+ d->warning(UbuntuI18n::instance().
1167+ tr("Binding detected on property '%1' will be removed by the service updates.").
1168+ arg(property));
1169+ }
1170+ // insert both the declared and capitalized first character properties
1171+ d->properties << property;
1172+ property[0] = property[0].toUpper();
1173+ d->properties << property;
1174+ }
1175+ // initialize DBus
1176+ if (d->init()) {
1177+ d->setStatus(UCServiceProperties::Synchronizing);
1178+ d->fetchPropertyValues();
1179+ }
1180+}
1181+
1182+/*!
1183+ * \qmlproperty enum ServiceProperties::type
1184+ * Specifies the DBus connection session type. It can get the following values:
1185+ * \list
1186+ * \li - \e ServiceProperties.System when system bus is used (default)
1187+ * \li - \e ServiceProperties.Session when session bus is used
1188+ * \endlist
1189+ */
1190+UCServiceProperties::ServiceType UCServiceProperties::type() const
1191+{
1192+ Q_D(const UCServiceProperties);
1193+ return d->type;
1194+}
1195+void UCServiceProperties::setType(ServiceType type)
1196+{
1197+ Q_D(UCServiceProperties);
1198+ if (d->type == type) {
1199+ return;
1200+ }
1201+ if (d->ready) {
1202+ printLocked(this);
1203+ return;
1204+ }
1205+ d->type = type;
1206+ Q_EMIT typeChanged();
1207+}
1208+
1209+/*!
1210+ * \qmlproperty string ServiceProperties::service
1211+ * The proeprty specifies the DBus service URI. It is mandatory to be specified.
1212+ */
1213+QString UCServiceProperties::service() const
1214+{
1215+ Q_D(const UCServiceProperties);
1216+ return d->service;
1217+}
1218+void UCServiceProperties::setService(const QString &value)
1219+{
1220+ Q_D(UCServiceProperties);
1221+ if (d->service == value) {
1222+ return;
1223+ }
1224+ if (d->ready) {
1225+ printLocked(this);
1226+ return;
1227+ }
1228+ d->service = value;
1229+ Q_EMIT serviceChanged();
1230+}
1231+
1232+/*!
1233+ * \qmlproperty string ServiceProperties::path
1234+ * The property specifies the DBus service connection path. It is mandatory to be
1235+ * specified.
1236+ */
1237+QString UCServiceProperties::path() const
1238+{
1239+ Q_D(const UCServiceProperties);
1240+ return d->path;
1241+}
1242+void UCServiceProperties::setPath(const QString &value)
1243+{
1244+ Q_D(UCServiceProperties);
1245+ if (d->path == value) {
1246+ return;
1247+ }
1248+ d->path = value;
1249+ Q_EMIT pathChanged();
1250+ if (d->ready) {
1251+ // need to re-initialize connections
1252+ d->init();
1253+ }
1254+}
1255+
1256+/*!
1257+ * \qmlproperty string ServiceProperties::serviceInterface
1258+ * The property specifies the service intertface. If it is an empty string, the
1259+ * component will refer to the merging of all interfaces found in the service.
1260+ */
1261+QString UCServiceProperties::interface() const
1262+{
1263+ Q_D(const UCServiceProperties);
1264+ return d->interface;
1265+}
1266+void UCServiceProperties::setInterface(const QString &value)
1267+{
1268+ Q_D(UCServiceProperties);
1269+ if (d->interface == value) {
1270+ return;
1271+ }
1272+ if (d->ready) {
1273+ printLocked(this);
1274+ return;
1275+ }
1276+ d->interface = value;
1277+ Q_EMIT serviceInterfaceChanged();
1278+}
1279+/*!
1280+ * \qmlproperty string ServiceProperties::adaptorInterface
1281+ * The proeprty specifies the dbus adaptor interface which provides the properties
1282+ * watched. This can be a different interface that the one specified in \l serviceInterface,
1283+ * and in the same way, it can be empty, in which case all the properties from all
1284+ * interfaces of the service will be watched.
1285+ */
1286+QString UCServiceProperties::adaptor() const
1287+{
1288+ Q_D(const UCServiceProperties);
1289+ return d->adaptor;
1290+}
1291+void UCServiceProperties::setAdaptor(const QString &value)
1292+{
1293+ Q_D(UCServiceProperties);
1294+ if (d->adaptor == value) {
1295+ return;
1296+ }
1297+ if (d->ready) {
1298+ printLocked(this);
1299+ return;
1300+ }
1301+ d->adaptor = value;
1302+ Q_EMIT adaptorInterfaceChanged();
1303+}
1304+
1305+/*!
1306+ * \qmlproperty string ServiceProperties::error
1307+ * The property is set with a human readablestring each time an error occurrs
1308+ * during the service connection. Empty string means no error.
1309+ */
1310+QString UCServiceProperties::error()
1311+{
1312+ Q_D(UCServiceProperties);
1313+ return d->error;
1314+}
1315+
1316+/*!
1317+ * \qmlproperty enum ServiceProperties::status
1318+ * The property presents the status of the component.
1319+ * \list
1320+ * \li - \e ServiceProperties.Inactive - the component is inactive, initial state
1321+ * \li - \e ServiceProperties.ConnectionError - there was a connection error, the
1322+ * \l error contains the error string.
1323+ * \li - \e ServiceProperties.Synchronizing - the connection to the service succeeded,
1324+ * and the properties are being synchronized;
1325+ * \li - \e ServiceProperties.Active - the service watcher is active and initial
1326+ * property synchronization completed.
1327+ * \endlist
1328+ * \note While the status is set to \e Synchronizing, the properties are checked
1329+ * against their existence in the service. Each proeprty will be checked as declared
1330+ * as well with capital first letter. If neither of these exists in the service,
1331+ * it will be reported in the \l error property separately.
1332+ */
1333+UCServiceProperties::Status UCServiceProperties::status() const
1334+{
1335+ Q_D(const UCServiceProperties);
1336+ return d->status;
1337+}
1338+
1339+#include "moc_ucserviceproperties.cpp"
1340
1341=== removed file 'modules/Ubuntu/Components/plugin/ucserviceproperties.cpp'
1342--- modules/Ubuntu/Components/plugin/ucserviceproperties.cpp 2014-12-03 08:26:33 +0000
1343+++ modules/Ubuntu/Components/plugin/ucserviceproperties.cpp 1970-01-01 00:00:00 +0000
1344@@ -1,317 +0,0 @@
1345-/*
1346- * Copyright 2014 Canonical Ltd.
1347- *
1348- * This program is free software; you can redistribute it and/or modify
1349- * it under the terms of the GNU Lesser General Public License as published by
1350- * the Free Software Foundation; version 3.
1351- *
1352- * This program is distributed in the hope that it will be useful,
1353- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1354- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1355- * GNU Lesser General Public License for more details.
1356- *
1357- * You should have received a copy of the GNU Lesser General Public License
1358- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1359- */
1360-
1361-#include "ucserviceproperties.h"
1362-#include "ucserviceproperties_p.h"
1363-#include "i18n.h"
1364-#include <QtQml/QQmlInfo>
1365-#include <QtCore/QMetaProperty>
1366-#include <QtQml/QQmlProperty>
1367-#include <QtQml/private/qqmlproperty_p.h>
1368-
1369-UCServicePropertiesPrivate::UCServicePropertiesPrivate(UCServiceProperties *qq)
1370- : q_ptr(qq)
1371- , ready(false)
1372- , status(UCServiceProperties::Inactive)
1373- , type(UCServiceProperties::System)
1374-{
1375-}
1376-
1377-UCServicePropertiesPrivate::~UCServicePropertiesPrivate()
1378-{
1379-}
1380-
1381-UCServicePropertiesPrivate *UCServicePropertiesPrivate::get(UCServiceProperties *service)
1382-{
1383- return service->d_func();
1384-}
1385-
1386-void UCServicePropertiesPrivate::setError(const QString &msg)
1387-{
1388- if (error == msg) {
1389- return;
1390- }
1391- error = msg;
1392- Q_EMIT q_ptr->errorChanged();
1393-}
1394-
1395-void UCServicePropertiesPrivate::setStatus(UCServiceProperties::Status status)
1396-{
1397- if (this->status == status) {
1398- return;
1399- }
1400- this->status = status;
1401- Q_EMIT q_ptr->statusChanged();
1402-}
1403-
1404-void printLocked(UCServiceProperties *owner)
1405-{
1406- qmlInfo(owner) << UbuntuI18n::instance().tr("Changing connection parameters forbidden.");
1407-}
1408-
1409-/*!
1410- * \qmltype ServiceProperties
1411- * \instantiates UCServiceProperties
1412- * \inqmlmodule Ubuntu.Components 1.1
1413- * \since Ubuntu.Components 1.1
1414- * \ingroup ubuntu-services
1415- * \brief The component enables accessing service properties from QML.
1416- *
1417- * The services accessed by the component are ones providing their interfaces
1418- * through DBus. The component is specialized to read properties exposed by these
1419- * services, andf to keep these property values up to date. It is not meant to
1420- * access signals or slots exposed, nor to change the values of the properties
1421- * watched.
1422- *
1423- * Properties watched should be declared within the body of the component like
1424- * any other QML property, preferably defining a default value for them. The component
1425- * will enumerate these properties and will ask the service to provide values for
1426- * those. When enumerating properties, each property will be checked twice, with
1427- * the case specified as well as with the first letter capitalized.
1428- * \qml
1429- * import QtQuick 2.3
1430- * import Ubuntu.Components 1.1
1431- *
1432- * ServiceProperties {
1433- * service: "org.freenode.AccountsService"
1434- * path: "/org/freenode/AccountsService"
1435- * serviceInterface: "org.freenode.AccountsService"
1436- * adaptorInterface: "com.ubuntu.touch.Accounts.Sound"
1437- * // listing properties to watch
1438- * // each property name existence will be checked against the current case
1439- * // as well as with first character capitalized
1440- * property bool incomingCallVibrate: true
1441- * }
1442- * \endqml
1443- *
1444- * Note that there are few properties which must be set in order the component
1445- * to work. These are \l service, \l path and \l adaptorInterface. Also, once
1446- * specified, \l service, \l serviceInterface and \l adaptorInterface values
1447- * should not be changed as it cannot be guaranteed that properties watched will
1448- * be available on those service. Therefore any change on these properties after
1449- * the component completion will be ignored. Property bindings on properties
1450- * watched will be ignored as well, as service will report changes in these property
1451- * values.
1452- *
1453- * The service is connected once the component gets completed (Component.onCompleted).
1454- * The \l error property specifies any error occured during connection, and the
1455- * \l status property notifies whether the connection to the service is active or not.
1456- *
1457- * \note Pay attention when chosing the service watched, and set your application's
1458- * AppArmor rights to ensure a successful service connection.
1459- */
1460-UCServiceProperties::UCServiceProperties(QObject *parent)
1461- : QObject(parent)
1462- , d_ptr(createServicePropertiesAdapter(this))
1463-{
1464-}
1465-UCServiceProperties::~UCServiceProperties()
1466-{
1467- delete d_ptr;
1468- d_ptr = 0;
1469-}
1470-
1471-void UCServiceProperties::classBegin()
1472-{
1473-}
1474-
1475-void UCServiceProperties::componentComplete()
1476-{
1477- Q_D(UCServiceProperties);
1478- d->ready = true;
1479- // enumerate properties
1480- const QMetaObject *mo = metaObject();
1481- for (int i = mo->propertyOffset(); i < mo->propertyCount(); i++) {
1482- const QMetaProperty prop = mo->property(i);
1483- QString property(prop.name());
1484-
1485- // check the binding on the property and warn if there is one.
1486- QQmlProperty qmlProperty(this, property);
1487- if (QQmlPropertyPrivate::binding(qmlProperty)) {
1488- qmlInfo(this) << UbuntuI18n::instance().
1489- tr("Binding detected on property '%1' will be removed by the service updates.").
1490- arg(property);
1491- }
1492- // insert both the declared and capitalized first character properties
1493- d->properties << property;
1494- property[0] = property[0].toUpper();
1495- d->properties << property;
1496- }
1497- // initialize DBus
1498- if (d->init()) {
1499- d->setStatus(UCServiceProperties::Synchronizing);
1500- d->fetchPropertyValues();
1501- }
1502-}
1503-
1504-/*!
1505- * \qmlproperty enum ServiceProperties::type
1506- * Specifies the DBus connection session type. It can get the following values:
1507- * \list
1508- * \li - \e ServiceProperties.System when system bus is used (default)
1509- * \li - \e ServiceProperties.Session when session bus is used
1510- * \endlist
1511- */
1512-UCServiceProperties::ServiceType UCServiceProperties::type() const
1513-{
1514- Q_D(const UCServiceProperties);
1515- return d->type;
1516-}
1517-void UCServiceProperties::setType(ServiceType type)
1518-{
1519- Q_D(UCServiceProperties);
1520- if (d->type == type) {
1521- return;
1522- }
1523- if (d->ready) {
1524- printLocked(this);
1525- return;
1526- }
1527- d->type = type;
1528- Q_EMIT typeChanged();
1529-}
1530-
1531-/*!
1532- * \qmlproperty string ServiceProperties::service
1533- * The proeprty specifies the DBus service URI. It is mandatory to be specified.
1534- */
1535-QString UCServiceProperties::service() const
1536-{
1537- Q_D(const UCServiceProperties);
1538- return d->service;
1539-}
1540-void UCServiceProperties::setService(const QString &value)
1541-{
1542- Q_D(UCServiceProperties);
1543- if (d->service == value) {
1544- return;
1545- }
1546- if (d->ready) {
1547- printLocked(this);
1548- return;
1549- }
1550- d->service = value;
1551- Q_EMIT serviceChanged();
1552-}
1553-
1554-/*!
1555- * \qmlproperty string ServiceProperties::path
1556- * The property specifies the DBus service connection path. It is mandatory to be
1557- * specified.
1558- */
1559-QString UCServiceProperties::path() const
1560-{
1561- Q_D(const UCServiceProperties);
1562- return d->path;
1563-}
1564-void UCServiceProperties::setPath(const QString &value)
1565-{
1566- Q_D(UCServiceProperties);
1567- if (d->path == value) {
1568- return;
1569- }
1570- d->path = value;
1571- Q_EMIT pathChanged();
1572- if (d->ready) {
1573- // need to re-initialize connections
1574- d->init();
1575- }
1576-}
1577-
1578-/*!
1579- * \qmlproperty string ServiceProperties::serviceInterface
1580- * The property specifies the service intertface. If it is an empty string, the
1581- * component will refer to the merging of all interfaces found in the service.
1582- */
1583-QString UCServiceProperties::interface() const
1584-{
1585- Q_D(const UCServiceProperties);
1586- return d->interface;
1587-}
1588-void UCServiceProperties::setInterface(const QString &value)
1589-{
1590- Q_D(UCServiceProperties);
1591- if (d->interface == value) {
1592- return;
1593- }
1594- if (d->ready) {
1595- printLocked(this);
1596- return;
1597- }
1598- d->interface = value;
1599- Q_EMIT serviceInterfaceChanged();
1600-}
1601-/*!
1602- * \qmlproperty string ServiceProperties::adaptorInterface
1603- * The proeprty specifies the dbus adaptor interface which provides the properties
1604- * watched. This can be a different interface that the one specified in \l serviceInterface,
1605- * and in the same way, it can be empty, in which case all the properties from all
1606- * interfaces of the service will be watched.
1607- */
1608-QString UCServiceProperties::adaptor() const
1609-{
1610- Q_D(const UCServiceProperties);
1611- return d->adaptor;
1612-}
1613-void UCServiceProperties::setAdaptor(const QString &value)
1614-{
1615- Q_D(UCServiceProperties);
1616- if (d->adaptor == value) {
1617- return;
1618- }
1619- if (d->ready) {
1620- printLocked(this);
1621- return;
1622- }
1623- d->adaptor = value;
1624- Q_EMIT adaptorInterfaceChanged();
1625-}
1626-
1627-/*!
1628- * \qmlproperty string ServiceProperties::error
1629- * The property is set with a human readablestring each time an error occurrs
1630- * during the service connection. Empty string means no error.
1631- */
1632-QString UCServiceProperties::error()
1633-{
1634- Q_D(UCServiceProperties);
1635- return d->error;
1636-}
1637-
1638-/*!
1639- * \qmlproperty enum ServiceProperties::status
1640- * The property presents the status of the component.
1641- * \list
1642- * \li - \e ServiceProperties.Inactive - the component is inactive, initial state
1643- * \li - \e ServiceProperties.ConnectionError - there was a connection error, the
1644- * \l error contains the error string.
1645- * \li - \e ServiceProperties.Synchronizing - the connection to the service succeeded,
1646- * and the properties are being synchronized;
1647- * \li - \e ServiceProperties.Active - the service watcher is active and initial
1648- * property synchronization completed.
1649- * \endlist
1650- * \note While the status is set to \e Synchronizing, the properties are checked
1651- * against their existence in the service. Each proeprty will be checked as declared
1652- * as well with capital first letter. If neither of these exists in the service,
1653- * it will be reported in the \l error property separately.
1654- */
1655-UCServiceProperties::Status UCServiceProperties::status() const
1656-{
1657- Q_D(const UCServiceProperties);
1658- return d->status;
1659-}
1660-
1661-#include "moc_ucserviceproperties.cpp"
1662
1663=== added file 'modules/Ubuntu/Components/plugin/ucserviceproperties.h'
1664--- modules/Ubuntu/Components/plugin/ucserviceproperties.h 1970-01-01 00:00:00 +0000
1665+++ modules/Ubuntu/Components/plugin/ucserviceproperties.h 2015-02-11 08:57:32 +0000
1666@@ -0,0 +1,83 @@
1667+/*
1668+ * Copyright 2014 Canonical Ltd.
1669+ *
1670+ * This program is free software; you can redistribute it and/or modify
1671+ * it under the terms of the GNU Lesser General Public License as published by
1672+ * the Free Software Foundation; version 3.
1673+ *
1674+ * This program is distributed in the hope that it will be useful,
1675+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1676+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1677+ * GNU Lesser General Public License for more details.
1678+ *
1679+ * You should have received a copy of the GNU Lesser General Public License
1680+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1681+ */
1682+
1683+#ifndef UCSERVICEPROPERTIES_H
1684+#define UCSERVICEPROPERTIES_H
1685+
1686+#include <QtCore/QObject>
1687+#include <QtQml/QQmlParserStatus>
1688+
1689+class UCServicePropertiesPrivate;
1690+class UCServiceProperties : public QObject, public QQmlParserStatus
1691+{
1692+ Q_OBJECT
1693+ Q_INTERFACES(QQmlParserStatus)
1694+
1695+ Q_PROPERTY(ServiceType type READ type WRITE setType NOTIFY typeChanged REVISION 1)
1696+ Q_PROPERTY(QString service READ service WRITE setService NOTIFY serviceChanged REVISION 1)
1697+ Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged REVISION 1)
1698+ Q_PROPERTY(QString serviceInterface READ interface WRITE setInterface NOTIFY serviceInterfaceChanged REVISION 1)
1699+ Q_PROPERTY(QString adaptorInterface READ adaptor WRITE setAdaptor NOTIFY adaptorInterfaceChanged REVISION 1)
1700+ Q_PROPERTY(QString error READ error NOTIFY errorChanged REVISION 1)
1701+ Q_PROPERTY(Status status READ status NOTIFY statusChanged REVISION 1)
1702+
1703+ Q_ENUMS(ServiceType Status)
1704+public:
1705+ enum ServiceType {
1706+ Undefined,
1707+ System,
1708+ Session
1709+ };
1710+ enum Status {
1711+ Inactive,
1712+ ConnectionError,
1713+ Synchronizing,
1714+ Active
1715+ };
1716+
1717+ explicit UCServiceProperties(QObject *parent = 0);
1718+ ~UCServiceProperties();
1719+ void classBegin();
1720+ void componentComplete();
1721+
1722+ ServiceType type() const;
1723+ void setType(ServiceType type);
1724+ QString service() const;
1725+ void setService(const QString &value);
1726+ QString path() const;
1727+ void setPath(const QString &value);
1728+ QString interface() const;
1729+ void setInterface(const QString &value);
1730+ QString adaptor() const;
1731+ void setAdaptor(const QString &value);
1732+ QString error();
1733+ Status status() const;
1734+
1735+Q_SIGNALS:
1736+ void typeChanged();
1737+ void serviceChanged();
1738+ void pathChanged();
1739+ void serviceInterfaceChanged();
1740+ void adaptorInterfaceChanged();
1741+ void errorChanged();
1742+ void statusChanged();
1743+
1744+private:
1745+ UCServicePropertiesPrivate *d_ptr;
1746+ Q_DECLARE_PRIVATE_D(d_ptr, UCServiceProperties)
1747+};
1748+
1749+#endif // UCSERVICEPROPERTIES_H
1750
1751=== removed file 'modules/Ubuntu/Components/plugin/ucserviceproperties.h'
1752--- modules/Ubuntu/Components/plugin/ucserviceproperties.h 2014-12-03 08:26:33 +0000
1753+++ modules/Ubuntu/Components/plugin/ucserviceproperties.h 1970-01-01 00:00:00 +0000
1754@@ -1,83 +0,0 @@
1755-/*
1756- * Copyright 2014 Canonical Ltd.
1757- *
1758- * This program is free software; you can redistribute it and/or modify
1759- * it under the terms of the GNU Lesser General Public License as published by
1760- * the Free Software Foundation; version 3.
1761- *
1762- * This program is distributed in the hope that it will be useful,
1763- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1764- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1765- * GNU Lesser General Public License for more details.
1766- *
1767- * You should have received a copy of the GNU Lesser General Public License
1768- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1769- */
1770-
1771-#ifndef UCSERVICEPROPERTIES_H
1772-#define UCSERVICEPROPERTIES_H
1773-
1774-#include <QtCore/QObject>
1775-#include <QtQml/QQmlParserStatus>
1776-
1777-class UCServicePropertiesPrivate;
1778-class UCServiceProperties : public QObject, public QQmlParserStatus
1779-{
1780- Q_OBJECT
1781- Q_INTERFACES(QQmlParserStatus)
1782-
1783- Q_PROPERTY(ServiceType type READ type WRITE setType NOTIFY typeChanged REVISION 1)
1784- Q_PROPERTY(QString service READ service WRITE setService NOTIFY serviceChanged REVISION 1)
1785- Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged REVISION 1)
1786- Q_PROPERTY(QString serviceInterface READ interface WRITE setInterface NOTIFY serviceInterfaceChanged REVISION 1)
1787- Q_PROPERTY(QString adaptorInterface READ adaptor WRITE setAdaptor NOTIFY adaptorInterfaceChanged REVISION 1)
1788- Q_PROPERTY(QString error READ error NOTIFY errorChanged REVISION 1)
1789- Q_PROPERTY(Status status READ status NOTIFY statusChanged REVISION 1)
1790-
1791- Q_ENUMS(ServiceType Status)
1792-public:
1793- enum ServiceType {
1794- Undefined,
1795- System,
1796- Session
1797- };
1798- enum Status {
1799- Inactive,
1800- ConnectionError,
1801- Synchronizing,
1802- Active
1803- };
1804-
1805- explicit UCServiceProperties(QObject *parent = 0);
1806- ~UCServiceProperties();
1807- void classBegin();
1808- void componentComplete();
1809-
1810- ServiceType type() const;
1811- void setType(ServiceType type);
1812- QString service() const;
1813- void setService(const QString &value);
1814- QString path() const;
1815- void setPath(const QString &value);
1816- QString interface() const;
1817- void setInterface(const QString &value);
1818- QString adaptor() const;
1819- void setAdaptor(const QString &value);
1820- QString error();
1821- Status status() const;
1822-
1823-Q_SIGNALS:
1824- void typeChanged();
1825- void serviceChanged();
1826- void pathChanged();
1827- void serviceInterfaceChanged();
1828- void adaptorInterfaceChanged();
1829- void errorChanged();
1830- void statusChanged();
1831-
1832-private:
1833- UCServicePropertiesPrivate *d_ptr;
1834- Q_DECLARE_PRIVATE_D(d_ptr, UCServiceProperties)
1835-};
1836-
1837-#endif // UCSERVICEPROPERTIES_H
1838
1839=== added file 'modules/Ubuntu/Components/plugin/ucserviceproperties_p.h'
1840--- modules/Ubuntu/Components/plugin/ucserviceproperties_p.h 1970-01-01 00:00:00 +0000
1841+++ modules/Ubuntu/Components/plugin/ucserviceproperties_p.h 2015-02-11 08:57:32 +0000
1842@@ -0,0 +1,54 @@
1843+/*
1844+ * Copyright 2014 Canonical Ltd.
1845+ *
1846+ * This program is free software; you can redistribute it and/or modify
1847+ * it under the terms of the GNU Lesser General Public License as published by
1848+ * the Free Software Foundation; version 3.
1849+ *
1850+ * This program is distributed in the hope that it will be useful,
1851+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1852+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1853+ * GNU Lesser General Public License for more details.
1854+ *
1855+ * You should have received a copy of the GNU Lesser General Public License
1856+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1857+ */
1858+
1859+#ifndef UCSERVICEPROPERTIES_P_H
1860+#define UCSERVICEPROPERTIES_P_H
1861+
1862+#include "ucserviceproperties.h"
1863+#include <QtCore/QStringList>
1864+
1865+class UCServicePropertiesPrivate
1866+{
1867+public:
1868+ UCServicePropertiesPrivate(UCServiceProperties *qq);
1869+ virtual ~UCServicePropertiesPrivate();
1870+
1871+ static UCServicePropertiesPrivate *get(UCServiceProperties *service);
1872+ void warning(const QString &message);
1873+ void setError(const QString &msg);
1874+ void setStatus(UCServiceProperties::Status status);
1875+
1876+ virtual bool init() = 0;
1877+ virtual bool fetchPropertyValues() = 0;
1878+ virtual bool readProperty(const QString &property) = 0;
1879+ virtual bool testProperty(const QString &property, const QVariant &value) = 0;
1880+
1881+ // data
1882+ UCServiceProperties *q_ptr;
1883+ bool ready:1;
1884+ UCServiceProperties::Status status;
1885+ UCServiceProperties::ServiceType type;
1886+ QString service;
1887+ QString path;
1888+ QString interface;
1889+ QString adaptor;
1890+ QString error;
1891+ QStringList properties;
1892+};
1893+
1894+UCServicePropertiesPrivate *createServicePropertiesAdapter(UCServiceProperties *owner);
1895+
1896+#endif // UCSERVICEPROPERTIES_P_H
1897
1898=== removed file 'modules/Ubuntu/Components/plugin/ucserviceproperties_p.h'
1899--- modules/Ubuntu/Components/plugin/ucserviceproperties_p.h 2014-12-03 08:26:33 +0000
1900+++ modules/Ubuntu/Components/plugin/ucserviceproperties_p.h 1970-01-01 00:00:00 +0000
1901@@ -1,53 +0,0 @@
1902-/*
1903- * Copyright 2014 Canonical Ltd.
1904- *
1905- * This program is free software; you can redistribute it and/or modify
1906- * it under the terms of the GNU Lesser General Public License as published by
1907- * the Free Software Foundation; version 3.
1908- *
1909- * This program is distributed in the hope that it will be useful,
1910- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1911- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1912- * GNU Lesser General Public License for more details.
1913- *
1914- * You should have received a copy of the GNU Lesser General Public License
1915- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1916- */
1917-
1918-#ifndef UCSERVICEPROPERTIES_P_H
1919-#define UCSERVICEPROPERTIES_P_H
1920-
1921-#include "ucserviceproperties.h"
1922-#include <QtCore/QStringList>
1923-
1924-class UCServicePropertiesPrivate
1925-{
1926-public:
1927- UCServicePropertiesPrivate(UCServiceProperties *qq);
1928- virtual ~UCServicePropertiesPrivate();
1929-
1930- static UCServicePropertiesPrivate *get(UCServiceProperties *service);
1931- void setError(const QString &msg);
1932- void setStatus(UCServiceProperties::Status status);
1933-
1934- virtual bool init() = 0;
1935- virtual bool fetchPropertyValues() = 0;
1936- virtual bool readProperty(const QString &property) = 0;
1937- virtual bool testProperty(const QString &property, const QVariant &value) = 0;
1938-
1939- // data
1940- UCServiceProperties *q_ptr;
1941- bool ready:1;
1942- UCServiceProperties::Status status;
1943- UCServiceProperties::ServiceType type;
1944- QString service;
1945- QString path;
1946- QString interface;
1947- QString adaptor;
1948- QString error;
1949- QStringList properties;
1950-};
1951-
1952-UCServicePropertiesPrivate *createServicePropertiesAdapter(UCServiceProperties *owner);
1953-
1954-#endif // UCSERVICEPROPERTIES_P_H
1955
1956=== modified file 'modules/Ubuntu/Components/qmldir'
1957--- modules/Ubuntu/Components/qmldir 2015-01-26 17:01:21 +0000
1958+++ modules/Ubuntu/Components/qmldir 2015-02-11 08:57:32 +0000
1959@@ -105,3 +105,6 @@
1960 StyledItem 1.1 StyledItem.qml
1961 singleton UbuntuColors 1.1 11/UbuntuColors.qml
1962 internal MainViewBase MainViewBase.qml
1963+
1964+singleton Haptics 0.1 11/Haptics.qml
1965+singleton Haptics 1.0 11/Haptics.qml
1966
1967=== modified file 'tests/unit/runtest.sh'
1968--- tests/unit/runtest.sh 2015-01-20 09:56:46 +0000
1969+++ tests/unit/runtest.sh 2015-02-11 08:57:32 +0000
1970@@ -63,6 +63,7 @@
1971
1972 QML2_IMPORT_PATH=${_IMPORT_PATH} UBUNTU_UI_TOOLKIT_THEMES_PATH=${_THEMES_PATH} \
1973 ALARM_BACKEND=memory \
1974+ SUPPRESS_SERVICEPROPERTIES_WARNINGS=yes \
1975 $_CMD $_ARGS 2>&1 | grep -v 'QFontDatabase: Cannot find font directory'
1976 # Note: Get first command before the pipe, $? would be ambiguous
1977 RESULT=${PIPESTATUS[0]}
1978
1979=== added file 'tests/unit/tst_components/tst_haptics.qml'
1980--- tests/unit/tst_components/tst_haptics.qml 1970-01-01 00:00:00 +0000
1981+++ tests/unit/tst_components/tst_haptics.qml 2015-02-11 08:57:32 +0000
1982@@ -0,0 +1,52 @@
1983+/*
1984+ * Copyright 2014 Canonical Ltd.
1985+ *
1986+ * This program is free software; you can redistribute it and/or modify
1987+ * it under the terms of the GNU Lesser General Public License as published by
1988+ * the Free Software Foundation; version 3.
1989+ *
1990+ * This program is distributed in the hope that it will be useful,
1991+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1992+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1993+ * GNU Lesser General Public License for more details.
1994+ *
1995+ * You should have received a copy of the GNU Lesser General Public License
1996+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1997+ */
1998+
1999+import QtQuick 2.3
2000+import QtTest 1.0
2001+import Ubuntu.Components 1.1
2002+import Ubuntu.Test 1.0
2003+import QtFeedback 5.0
2004+
2005+UbuntuTestCase {
2006+ name: "HapticsAPI"
2007+
2008+ function waitForHapticsCompleted() {
2009+ tryCompareFunction(function() { return Haptics.effect.state; }, HapticsEffect.Stopped, 1000);
2010+ }
2011+
2012+ function test_0_defaults() {
2013+ verify(Haptics.hasOwnProperty("enabled"), "missing property 'enabled'");
2014+ verify(Haptics.hasOwnProperty("effect"), "missing property 'effect'");
2015+ verify(Haptics.hasOwnProperty("play"), "missing function 'play'");
2016+ }
2017+
2018+ function test_play() {
2019+ Haptics.play();
2020+ if (Haptics.enabled) {
2021+ waitForHapticsCompleted();
2022+ }
2023+ }
2024+
2025+ function test_custom_play() {
2026+ Haptics.play({attackTime: 10, attackIntensity: 0.5, duration: 1200});
2027+ if (Haptics.enabled && Haptics.effect.running) {
2028+ compare(Haptics.effect.attackTime, 10, "attack time not modified");
2029+ compare(Haptics.effect.attackIntensity, 0.5, "attack intensity not modified");
2030+ compare(Haptics.effect.duration, 400, "duration not modified");
2031+ waitForHapticsCompleted();
2032+ }
2033+ }
2034+}
2035
2036=== added directory 'tests/unit_x11/tst_serviceproperties'
2037=== removed directory 'tests/unit_x11/tst_serviceproperties'
2038=== added file 'tests/unit_x11/tst_serviceproperties/IncomingCallVibrateWatcher.qml'
2039--- tests/unit_x11/tst_serviceproperties/IncomingCallVibrateWatcher.qml 1970-01-01 00:00:00 +0000
2040+++ tests/unit_x11/tst_serviceproperties/IncomingCallVibrateWatcher.qml 2015-02-11 08:57:32 +0000
2041@@ -0,0 +1,31 @@
2042+/*
2043+ * Copyright 2014 Canonical Ltd.
2044+ *
2045+ * This program is free software; you can redistribute it and/or modify
2046+ * it under the terms of the GNU Lesser General Public License as published by
2047+ * the Free Software Foundation; version 3.
2048+ *
2049+ * This program is distributed in the hope that it will be useful,
2050+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2051+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2052+ * GNU Lesser General Public License for more details.
2053+ *
2054+ * You should have received a copy of the GNU Lesser General Public License
2055+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2056+ */
2057+
2058+import QtQuick 2.3
2059+import Ubuntu.Components 1.1
2060+
2061+Item {
2062+ property alias service: service
2063+ ServiceProperties {
2064+ id: service
2065+ service: "org.freedesktop.Accounts"
2066+ serviceInterface: "org.freedesktop.Accounts"
2067+ path: "/org/freedesktop/Accounts"
2068+ adaptorInterface: "com.ubuntu.touch.AccountsService.Sound"
2069+
2070+ property bool incomingCallVibrate: true
2071+ }
2072+}
2073
2074=== removed file 'tests/unit_x11/tst_serviceproperties/IncomingCallVibrateWatcher.qml'
2075--- tests/unit_x11/tst_serviceproperties/IncomingCallVibrateWatcher.qml 2014-12-03 08:26:33 +0000
2076+++ tests/unit_x11/tst_serviceproperties/IncomingCallVibrateWatcher.qml 1970-01-01 00:00:00 +0000
2077@@ -1,31 +0,0 @@
2078-/*
2079- * Copyright 2014 Canonical Ltd.
2080- *
2081- * This program is free software; you can redistribute it and/or modify
2082- * it under the terms of the GNU Lesser General Public License as published by
2083- * the Free Software Foundation; version 3.
2084- *
2085- * This program is distributed in the hope that it will be useful,
2086- * but WITHOUT ANY WARRANTY; without even the implied warranty of
2087- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2088- * GNU Lesser General Public License for more details.
2089- *
2090- * You should have received a copy of the GNU Lesser General Public License
2091- * along with this program. If not, see <http://www.gnu.org/licenses/>.
2092- */
2093-
2094-import QtQuick 2.3
2095-import Ubuntu.Components 1.1
2096-
2097-Item {
2098- property alias service: service
2099- ServiceProperties {
2100- id: service
2101- service: "org.freedesktop.Accounts"
2102- serviceInterface: "org.freedesktop.Accounts"
2103- path: "/org/freedesktop/Accounts"
2104- adaptorInterface: "com.ubuntu.touch.AccountsService.Sound"
2105-
2106- property bool incomingCallVibrate: true
2107- }
2108-}
2109
2110=== added file 'tests/unit_x11/tst_serviceproperties/InvalidPropertyWatcher.qml'
2111--- tests/unit_x11/tst_serviceproperties/InvalidPropertyWatcher.qml 1970-01-01 00:00:00 +0000
2112+++ tests/unit_x11/tst_serviceproperties/InvalidPropertyWatcher.qml 2015-02-11 08:57:32 +0000
2113@@ -0,0 +1,31 @@
2114+/*
2115+ * Copyright 2014 Canonical Ltd.
2116+ *
2117+ * This program is free software; you can redistribute it and/or modify
2118+ * it under the terms of the GNU Lesser General Public License as published by
2119+ * the Free Software Foundation; version 3.
2120+ *
2121+ * This program is distributed in the hope that it will be useful,
2122+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2123+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2124+ * GNU Lesser General Public License for more details.
2125+ *
2126+ * You should have received a copy of the GNU Lesser General Public License
2127+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2128+ */
2129+
2130+import QtQuick 2.3
2131+import Ubuntu.Components 1.1
2132+
2133+Item {
2134+ property alias service: service
2135+ ServiceProperties {
2136+ id: service
2137+ service: "org.freedesktop.Accounts"
2138+ serviceInterface: "org.freedesktop.Accounts"
2139+ path: "/org/freedesktop/Accounts"
2140+ adaptorInterface: "com.ubuntu.touch.AccountsService.Sound"
2141+
2142+ property bool thisIsAnInvalidPropertyToWatch: true
2143+ }
2144+}
2145
2146=== removed file 'tests/unit_x11/tst_serviceproperties/InvalidPropertyWatcher.qml'
2147--- tests/unit_x11/tst_serviceproperties/InvalidPropertyWatcher.qml 2014-12-03 08:26:33 +0000
2148+++ tests/unit_x11/tst_serviceproperties/InvalidPropertyWatcher.qml 1970-01-01 00:00:00 +0000
2149@@ -1,31 +0,0 @@
2150-/*
2151- * Copyright 2014 Canonical Ltd.
2152- *
2153- * This program is free software; you can redistribute it and/or modify
2154- * it under the terms of the GNU Lesser General Public License as published by
2155- * the Free Software Foundation; version 3.
2156- *
2157- * This program is distributed in the hope that it will be useful,
2158- * but WITHOUT ANY WARRANTY; without even the implied warranty of
2159- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2160- * GNU Lesser General Public License for more details.
2161- *
2162- * You should have received a copy of the GNU Lesser General Public License
2163- * along with this program. If not, see <http://www.gnu.org/licenses/>.
2164- */
2165-
2166-import QtQuick 2.3
2167-import Ubuntu.Components 1.1
2168-
2169-Item {
2170- property alias service: service
2171- ServiceProperties {
2172- id: service
2173- service: "org.freedesktop.Accounts"
2174- serviceInterface: "org.freedesktop.Accounts"
2175- path: "/org/freedesktop/Accounts"
2176- adaptorInterface: "com.ubuntu.touch.AccountsService.Sound"
2177-
2178- property bool thisIsAnInvalidPropertyToWatch: true
2179- }
2180-}
2181
2182=== added file 'tests/unit_x11/tst_serviceproperties/InvalidPropertyWatcher2.qml'
2183--- tests/unit_x11/tst_serviceproperties/InvalidPropertyWatcher2.qml 1970-01-01 00:00:00 +0000
2184+++ tests/unit_x11/tst_serviceproperties/InvalidPropertyWatcher2.qml 2015-02-11 08:57:32 +0000
2185@@ -0,0 +1,32 @@
2186+/*
2187+ * Copyright 2014 Canonical Ltd.
2188+ *
2189+ * This program is free software; you can redistribute it and/or modify
2190+ * it under the terms of the GNU Lesser General Public License as published by
2191+ * the Free Software Foundation; version 3.
2192+ *
2193+ * This program is distributed in the hope that it will be useful,
2194+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2195+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2196+ * GNU Lesser General Public License for more details.
2197+ *
2198+ * You should have received a copy of the GNU Lesser General Public License
2199+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2200+ */
2201+
2202+import QtQuick 2.3
2203+import Ubuntu.Components 1.1
2204+
2205+Item {
2206+ property alias service: service
2207+ ServiceProperties {
2208+ id: service
2209+ service: "org.freedesktop.Accounts"
2210+ serviceInterface: "org.freedesktop.Accounts"
2211+ path: "/org/freedesktop/Accounts"
2212+ adaptorInterface: "com.ubuntu.touch.AccountsService.Sound"
2213+
2214+ property bool thisIsAnInvalidPropertyToWatch: true
2215+ property bool incomingCallVibrate: true
2216+ }
2217+}
2218
2219=== removed file 'tests/unit_x11/tst_serviceproperties/InvalidPropertyWatcher2.qml'
2220--- tests/unit_x11/tst_serviceproperties/InvalidPropertyWatcher2.qml 2014-12-03 08:26:33 +0000
2221+++ tests/unit_x11/tst_serviceproperties/InvalidPropertyWatcher2.qml 1970-01-01 00:00:00 +0000
2222@@ -1,32 +0,0 @@
2223-/*
2224- * Copyright 2014 Canonical Ltd.
2225- *
2226- * This program is free software; you can redistribute it and/or modify
2227- * it under the terms of the GNU Lesser General Public License as published by
2228- * the Free Software Foundation; version 3.
2229- *
2230- * This program is distributed in the hope that it will be useful,
2231- * but WITHOUT ANY WARRANTY; without even the implied warranty of
2232- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2233- * GNU Lesser General Public License for more details.
2234- *
2235- * You should have received a copy of the GNU Lesser General Public License
2236- * along with this program. If not, see <http://www.gnu.org/licenses/>.
2237- */
2238-
2239-import QtQuick 2.3
2240-import Ubuntu.Components 1.1
2241-
2242-Item {
2243- property alias service: service
2244- ServiceProperties {
2245- id: service
2246- service: "org.freedesktop.Accounts"
2247- serviceInterface: "org.freedesktop.Accounts"
2248- path: "/org/freedesktop/Accounts"
2249- adaptorInterface: "com.ubuntu.touch.AccountsService.Sound"
2250-
2251- property bool thisIsAnInvalidPropertyToWatch: true
2252- property bool incomingCallVibrate: true
2253- }
2254-}
2255
2256=== added file 'tests/unit_x11/tst_serviceproperties/tst_serviceproperties.cpp'
2257--- tests/unit_x11/tst_serviceproperties/tst_serviceproperties.cpp 1970-01-01 00:00:00 +0000
2258+++ tests/unit_x11/tst_serviceproperties/tst_serviceproperties.cpp 2015-02-11 08:57:32 +0000
2259@@ -0,0 +1,146 @@
2260+/*
2261+ * Copyright 2014 Canonical Ltd.
2262+ *
2263+ * This program is free software; you can redistribute it and/or modify
2264+ * it under the terms of the GNU Lesser General Public License as published by
2265+ * the Free Software Foundation; version 3.
2266+ *
2267+ * This program is distributed in the hope that it will be useful,
2268+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2269+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2270+ * GNU Lesser General Public License for more details.
2271+ *
2272+ * You should have received a copy of the GNU Lesser General Public License
2273+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2274+ */
2275+
2276+#include "uctestcase.h"
2277+#include "ucserviceproperties.h"
2278+#include "ucserviceproperties_p.h"
2279+#include <QtCore/QString>
2280+#include <QtCore/QDebug>
2281+#include <QtTest/QTest>
2282+#include <QtTest/QSignalSpy>
2283+
2284+class tst_ServiceProperties : public QObject
2285+{
2286+ Q_OBJECT
2287+
2288+public:
2289+ tst_ServiceProperties() {}
2290+
2291+private:
2292+
2293+ QString error;
2294+
2295+ // FIXME use UbuntuTestCase::ignoreWaring in Vivid
2296+ void ignoreWarning(const QString& fileName, uint line, uint column, const QString& message, uint occurences=1)
2297+ {
2298+ for (uint i = 0; i < occurences; i++) {
2299+ QString url(QUrl::fromLocalFile(QFileInfo(fileName).absoluteFilePath()).toEncoded());
2300+ QString warning(QString("%1:%2:%3: %4").arg(url).arg(line).arg(column).arg(message));
2301+ QTest::ignoreMessage(QtWarningMsg, warning.toUtf8());
2302+ }
2303+ }
2304+
2305+
2306+private Q_SLOTS:
2307+
2308+ void initTestCase()
2309+ {
2310+ // check if the connection is possible, otherwise we must skip all tests
2311+ QScopedPointer<UbuntuTestCase> test(new UbuntuTestCase("IncomingCallVibrateWatcher.qml"));
2312+ UCServiceProperties *watcher = static_cast<UCServiceProperties*>(test->rootObject()->property("service").value<QObject*>());
2313+ QVERIFY(watcher);
2314+ if (watcher->status() == UCServiceProperties::Synchronizing ||
2315+ watcher->status() == UCServiceProperties::Inactive) {
2316+ QSignalSpy wait(watcher, SIGNAL(statusChanged()));
2317+ wait.wait();
2318+ }
2319+ if (watcher->status() == UCServiceProperties::ConnectionError) {
2320+ error = "Skip test: " + watcher->error();
2321+ }
2322+ }
2323+
2324+ void test_change_property()
2325+ {
2326+ if (!error.isEmpty()) {
2327+ QSKIP(qPrintable(error));
2328+ }
2329+ QScopedPointer<UbuntuTestCase> test(new UbuntuTestCase("IncomingCallVibrateWatcher.qml"));
2330+ UCServiceProperties *watcher = static_cast<UCServiceProperties*>(test->rootObject()->property("service").value<QObject*>());
2331+ QVERIFY(watcher);
2332+
2333+ bool backup = watcher->property("incomingCallVibrate").toBool();
2334+ UCServicePropertiesPrivate *pWatcher = UCServicePropertiesPrivate::get(watcher);
2335+ QSignalSpy spy(watcher, SIGNAL(incomingCallVibrateChanged()));
2336+ pWatcher->testProperty("IncomingCallVibrate", !backup);
2337+ spy.wait(400);
2338+ QCOMPARE(spy.count(), 1);
2339+ QCOMPARE(watcher->property("incomingCallVibrate").toBool(), !backup);
2340+
2341+ // restore value
2342+ spy.clear();
2343+ pWatcher->testProperty("IncomingCallVibrate", backup);
2344+ spy.wait(400);
2345+ }
2346+
2347+ void test_invalid_property()
2348+ {
2349+ if (!error.isEmpty()) {
2350+ QSKIP(qPrintable(error));
2351+ }
2352+ ignoreWarning("InvalidPropertyWatcher.qml", 22, 5, "QML ServiceProperties: No such property 'ThisIsAnInvalidPropertyToWatch'");
2353+ QScopedPointer<UbuntuTestCase> test(new UbuntuTestCase("InvalidPropertyWatcher.qml"));
2354+ UCServiceProperties *watcher = static_cast<UCServiceProperties*>(test->rootObject()->property("service").value<QObject*>());
2355+ QVERIFY(watcher);
2356+ // error should not be set
2357+ QCOMPARE(watcher->property("error").toString(), QString());
2358+ }
2359+
2360+ void test_one_valid_one_invalid_property()
2361+ {
2362+ if (!error.isEmpty()) {
2363+ QSKIP(qPrintable(error));
2364+ }
2365+ ignoreWarning("InvalidPropertyWatcher2.qml", 22, 5, "QML ServiceProperties: No such property 'ThisIsAnInvalidPropertyToWatch'");
2366+ QScopedPointer<UbuntuTestCase> test(new UbuntuTestCase("InvalidPropertyWatcher2.qml"));
2367+ UCServiceProperties *watcher = static_cast<UCServiceProperties*>(test->rootObject()->property("service").value<QObject*>());
2368+ QVERIFY(watcher);
2369+ // error should not be set
2370+ QCOMPARE(watcher->property("error").toString(), QString());
2371+ }
2372+
2373+ void test_change_connection_props_data()
2374+ {
2375+ QTest::addColumn<QString>("property");
2376+ QTest::addColumn<QString>("value");
2377+
2378+ QTest::newRow("Changing servcie") << "service" << "anything.else";
2379+ QTest::newRow("Changing interface") << "serviceInterface" << "anything.else";
2380+ QTest::newRow("Changing adaptor") << "adaptorInterface" << "anything.else";
2381+ }
2382+ void test_change_connection_props()
2383+ {
2384+ QFETCH(QString, property);
2385+ QFETCH(QString, value);
2386+
2387+ if (!error.isEmpty()) {
2388+ QSKIP(qPrintable(error));
2389+ }
2390+ ignoreWarning("IncomingCallVibrateWatcher.qml", 22, 5, "QML ServiceProperties: Changing connection parameters forbidden.");
2391+ QScopedPointer<UbuntuTestCase> test(new UbuntuTestCase("IncomingCallVibrateWatcher.qml"));
2392+ UCServiceProperties *watcher = static_cast<UCServiceProperties*>(test->rootObject()->property("service").value<QObject*>());
2393+ QVERIFY(watcher);
2394+
2395+ // try to change the property
2396+ watcher->setProperty(property.toLocal8Bit().constData(), value);
2397+ // no error should be reported
2398+ QCOMPARE(watcher->property("error").toString(), QString());
2399+ }
2400+
2401+};
2402+
2403+QTEST_MAIN(tst_ServiceProperties)
2404+
2405+#include "tst_serviceproperties.moc"
2406
2407=== removed file 'tests/unit_x11/tst_serviceproperties/tst_serviceproperties.cpp'
2408--- tests/unit_x11/tst_serviceproperties/tst_serviceproperties.cpp 2014-12-03 10:22:17 +0000
2409+++ tests/unit_x11/tst_serviceproperties/tst_serviceproperties.cpp 1970-01-01 00:00:00 +0000
2410@@ -1,146 +0,0 @@
2411-/*
2412- * Copyright 2014 Canonical Ltd.
2413- *
2414- * This program is free software; you can redistribute it and/or modify
2415- * it under the terms of the GNU Lesser General Public License as published by
2416- * the Free Software Foundation; version 3.
2417- *
2418- * This program is distributed in the hope that it will be useful,
2419- * but WITHOUT ANY WARRANTY; without even the implied warranty of
2420- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2421- * GNU Lesser General Public License for more details.
2422- *
2423- * You should have received a copy of the GNU Lesser General Public License
2424- * along with this program. If not, see <http://www.gnu.org/licenses/>.
2425- */
2426-
2427-#include "uctestcase.h"
2428-#include "ucserviceproperties.h"
2429-#include "ucserviceproperties_p.h"
2430-#include <QtCore/QString>
2431-#include <QtCore/QDebug>
2432-#include <QtTest/QTest>
2433-#include <QtTest/QSignalSpy>
2434-
2435-class tst_ServiceProperties : public QObject
2436-{
2437- Q_OBJECT
2438-
2439-public:
2440- tst_ServiceProperties() {}
2441-
2442-private:
2443-
2444- QString error;
2445-
2446- // FIXME use UbuntuTestCase::ignoreWaring in Vivid
2447- void ignoreWarning(const QString& fileName, uint line, uint column, const QString& message, uint occurences=1)
2448- {
2449- for (uint i = 0; i < occurences; i++) {
2450- QString url(QUrl::fromLocalFile(QFileInfo(fileName).absoluteFilePath()).toEncoded());
2451- QString warning(QString("%1:%2:%3: %4").arg(url).arg(line).arg(column).arg(message));
2452- QTest::ignoreMessage(QtWarningMsg, warning.toUtf8());
2453- }
2454- }
2455-
2456-
2457-private Q_SLOTS:
2458-
2459- void initTestCase()
2460- {
2461- // check if the connection is possible, otherwise we must skip all tests
2462- QScopedPointer<UbuntuTestCase> test(new UbuntuTestCase("IncomingCallVibrateWatcher.qml"));
2463- UCServiceProperties *watcher = static_cast<UCServiceProperties*>(test->rootObject()->property("service").value<QObject*>());
2464- QVERIFY(watcher);
2465- if (watcher->status() == UCServiceProperties::Synchronizing ||
2466- watcher->status() == UCServiceProperties::Inactive) {
2467- QSignalSpy wait(watcher, SIGNAL(statusChanged()));
2468- wait.wait();
2469- }
2470- if (watcher->status() == UCServiceProperties::ConnectionError) {
2471- error = "Skip test: " + watcher->error();
2472- }
2473- }
2474-
2475- void test_change_property()
2476- {
2477- if (!error.isEmpty()) {
2478- QSKIP(qPrintable(error));
2479- }
2480- QScopedPointer<UbuntuTestCase> test(new UbuntuTestCase("IncomingCallVibrateWatcher.qml"));
2481- UCServiceProperties *watcher = static_cast<UCServiceProperties*>(test->rootObject()->property("service").value<QObject*>());
2482- QVERIFY(watcher);
2483-
2484- bool backup = watcher->property("incomingCallVibrate").toBool();
2485- UCServicePropertiesPrivate *pWatcher = UCServicePropertiesPrivate::get(watcher);
2486- QSignalSpy spy(watcher, SIGNAL(incomingCallVibrateChanged()));
2487- pWatcher->testProperty("IncomingCallVibrate", !backup);
2488- spy.wait(400);
2489- QCOMPARE(spy.count(), 1);
2490- QCOMPARE(watcher->property("incomingCallVibrate").toBool(), !backup);
2491-
2492- // restore value
2493- spy.clear();
2494- pWatcher->testProperty("IncomingCallVibrate", backup);
2495- spy.wait(400);
2496- }
2497-
2498- void test_invalid_property()
2499- {
2500- if (!error.isEmpty()) {
2501- QSKIP(qPrintable(error));
2502- }
2503- ignoreWarning("InvalidPropertyWatcher.qml", 22, 5, "QML ServiceProperties: No such property 'ThisIsAnInvalidPropertyToWatch'");
2504- QScopedPointer<UbuntuTestCase> test(new UbuntuTestCase("InvalidPropertyWatcher.qml"));
2505- UCServiceProperties *watcher = static_cast<UCServiceProperties*>(test->rootObject()->property("service").value<QObject*>());
2506- QVERIFY(watcher);
2507- // error should not be set
2508- QCOMPARE(watcher->property("error").toString(), QString());
2509- }
2510-
2511- void test_one_valid_one_invalid_property()
2512- {
2513- if (!error.isEmpty()) {
2514- QSKIP(qPrintable(error));
2515- }
2516- ignoreWarning("InvalidPropertyWatcher2.qml", 22, 5, "QML ServiceProperties: No such property 'ThisIsAnInvalidPropertyToWatch'");
2517- QScopedPointer<UbuntuTestCase> test(new UbuntuTestCase("InvalidPropertyWatcher2.qml"));
2518- UCServiceProperties *watcher = static_cast<UCServiceProperties*>(test->rootObject()->property("service").value<QObject*>());
2519- QVERIFY(watcher);
2520- // error should not be set
2521- QCOMPARE(watcher->property("error").toString(), QString());
2522- }
2523-
2524- void test_change_connection_props_data()
2525- {
2526- QTest::addColumn<QString>("property");
2527- QTest::addColumn<QString>("value");
2528-
2529- QTest::newRow("Changing servcie") << "service" << "anything.else";
2530- QTest::newRow("Changing interface") << "serviceInterface" << "anything.else";
2531- QTest::newRow("Changing adaptor") << "adaptorInterface" << "anything.else";
2532- }
2533- void test_change_connection_props()
2534- {
2535- QFETCH(QString, property);
2536- QFETCH(QString, value);
2537-
2538- if (!error.isEmpty()) {
2539- QSKIP(qPrintable(error));
2540- }
2541- ignoreWarning("IncomingCallVibrateWatcher.qml", 22, 5, "QML ServiceProperties: Changing connection parameters forbidden.");
2542- QScopedPointer<UbuntuTestCase> test(new UbuntuTestCase("IncomingCallVibrateWatcher.qml"));
2543- UCServiceProperties *watcher = static_cast<UCServiceProperties*>(test->rootObject()->property("service").value<QObject*>());
2544- QVERIFY(watcher);
2545-
2546- // try to change the property
2547- watcher->setProperty(property.toLocal8Bit().constData(), value);
2548- // no error should be reported
2549- QCOMPARE(watcher->property("error").toString(), QString());
2550- }
2551-
2552-};
2553-
2554-QTEST_MAIN(tst_ServiceProperties)
2555-
2556-#include "tst_serviceproperties.moc"
2557
2558=== added file 'tests/unit_x11/tst_serviceproperties/tst_serviceproperties.pro'
2559--- tests/unit_x11/tst_serviceproperties/tst_serviceproperties.pro 1970-01-01 00:00:00 +0000
2560+++ tests/unit_x11/tst_serviceproperties/tst_serviceproperties.pro 2015-02-11 08:57:32 +0000
2561@@ -0,0 +1,8 @@
2562+include(../test-include.pri)
2563+SOURCES += \
2564+ tst_serviceproperties.cpp
2565+
2566+OTHER_FILES += \
2567+ IncomingCallVibrateWatcher.qml \
2568+ InvalidPropertyWatcher.qml \
2569+ InvalidPropertyWatcher2.qml
2570
2571=== removed file 'tests/unit_x11/tst_serviceproperties/tst_serviceproperties.pro'
2572--- tests/unit_x11/tst_serviceproperties/tst_serviceproperties.pro 2014-12-03 08:26:33 +0000
2573+++ tests/unit_x11/tst_serviceproperties/tst_serviceproperties.pro 1970-01-01 00:00:00 +0000
2574@@ -1,8 +0,0 @@
2575-include(../test-include.pri)
2576-SOURCES += \
2577- tst_serviceproperties.cpp
2578-
2579-OTHER_FILES += \
2580- IncomingCallVibrateWatcher.qml \
2581- InvalidPropertyWatcher.qml \
2582- InvalidPropertyWatcher2.qml

Subscribers

People subscribed via source and target branches