Merge lp:~fboucault/ubuntu-ui-toolkit/state_saving_store_type into lp:ubuntu-ui-toolkit/staging
- state_saving_store_type
- Merge into staging
Status: | Merged |
---|---|
Approved by: | Cris Dywan |
Approved revision: | 1167 |
Merged at revision: | 1167 |
Proposed branch: | lp:~fboucault/ubuntu-ui-toolkit/state_saving_store_type |
Merge into: | lp:ubuntu-ui-toolkit/staging |
Diff against target: |
146 lines (+79/-3) 4 files modified
modules/Ubuntu/Components/plugin/statesaverbackend_p.cpp (+23/-2) tests/unit_x11/tst_statesaver/SaveEnum.qml (+23/-0) tests/unit_x11/tst_statesaver/tst_statesaver.cpp (+31/-0) tests/unit_x11/tst_statesaver/tst_statesaver.pro (+2/-1) |
To merge this branch: | bzr merge lp:~fboucault/ubuntu-ui-toolkit/state_saving_store_type |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Cris Dywan | Approve | ||
PS Jenkins bot | continuous-integration | Approve | |
Tim Peeters | Pending | ||
Review via email: mp+228503@code.launchpad.net |
Commit message
StateSaver: also save the type of each property along with its value so that we can convert them back to the right type during state restoration.
This makes some problematic cases such as enumeration to work.
Description of the change
PS Jenkins bot (ps-jenkins) wrote : | # |
Cris Dywan (kalikiana) wrote : | # |
See comments inline.
Question: can this ultimately be addressed in QSettings and could a bug be filed/ added as a comment? Provided it's not a fundamental design problem.
Florian Boucault (fboucault) wrote : | # |
> See comments inline.
>
> Question: can this ultimately be addressed in QSettings and could a bug be
> filed/ added as a comment? Provided it's not a fundamental design problem.
It does sound like QSettings should do a better job. Not sure how to describe it.
Cris Dywan (kalikiana) wrote : | # |
Nice. Thanks a lot!
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1164
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Autolanding.
More details in the following jenkins job:
http://
Executed test runs:
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1166
http://
Executed test runs:
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
Cris Dywan (kalikiana) wrote : | # |
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/usr/lib/
return restart_
File "/usr/lib/
pid = _get_unity_pid()
File "/usr/lib/
return int(status.
ValueError: invalid literal for int() with base 10: 'start/running'
- 1167. By Florian Boucault
-
Empty commit
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1167
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
Cris Dywan (kalikiana) : | # |
Preview Diff
1 | === modified file 'modules/Ubuntu/Components/plugin/statesaverbackend_p.cpp' | |||
2 | --- modules/Ubuntu/Components/plugin/statesaverbackend_p.cpp 2014-03-17 11:57:53 +0000 | |||
3 | +++ modules/Ubuntu/Components/plugin/statesaverbackend_p.cpp 2014-07-29 09:48:52 +0000 | |||
4 | @@ -145,8 +145,20 @@ | |||
5 | 145 | } | 145 | } |
6 | 146 | QQmlProperty qmlProperty(item, propertyName.toLocal8Bit().constData(), qmlContext(item)); | 146 | QQmlProperty qmlProperty(item, propertyName.toLocal8Bit().constData(), qmlContext(item)); |
7 | 147 | if (qmlProperty.isValid() && qmlProperty.isWritable()) { | 147 | if (qmlProperty.isValid() && qmlProperty.isWritable()) { |
10 | 148 | qmlProperty.write(value); | 148 | QVariant type = m_archive.data()->value(propertyName + "_TYPE"); |
11 | 149 | result++; | 149 | value.convert(type.toInt()); |
12 | 150 | bool writeSuccess = qmlProperty.write(value); | ||
13 | 151 | if (writeSuccess) { | ||
14 | 152 | result++; | ||
15 | 153 | } else { | ||
16 | 154 | qmlInfo(item) << UbuntuI18n::instance().tr("property \"%1\" of " | ||
17 | 155 | "object %2 has type %3 and cannot be set to value \"%4\" of" | ||
18 | 156 | " type %5").arg(propertyName) | ||
19 | 157 | .arg(qmlContext(item)->nameForObject(item)) | ||
20 | 158 | .arg(qmlProperty.propertyTypeName()) | ||
21 | 159 | .arg(value.toString()) | ||
22 | 160 | .arg(value.typeName()); | ||
23 | 161 | } | ||
24 | 150 | } else { | 162 | } else { |
25 | 151 | qmlInfo(item) << UbuntuI18n::instance().tr("property \"%1\" does not exist or is not writable for object %2") | 163 | qmlInfo(item) << UbuntuI18n::instance().tr("property \"%1\" does not exist or is not writable for object %2") |
26 | 152 | .arg(propertyName).arg(qmlContext(item)->nameForObject(item)); | 164 | .arg(propertyName).arg(qmlContext(item)->nameForObject(item)); |
27 | @@ -173,6 +185,15 @@ | |||
28 | 173 | QVariant value = qmlProperty.read(); | 185 | QVariant value = qmlProperty.read(); |
29 | 174 | if (static_cast<QMetaType::Type>(value.type()) != QMetaType::QObjectStar) { | 186 | if (static_cast<QMetaType::Type>(value.type()) != QMetaType::QObjectStar) { |
30 | 175 | m_archive.data()->setValue(propertyName, value); | 187 | m_archive.data()->setValue(propertyName, value); |
31 | 188 | /* Save the type of the property along with its value. | ||
32 | 189 | * This is important because QSettings deserializes values as QString. | ||
33 | 190 | * Setting these strings to QML properties usually works because the | ||
34 | 191 | * implicit type conversion from string to the type of the QML property | ||
35 | 192 | * usually works. In some cases cases however (e.g. enum) it fails. | ||
36 | 193 | * | ||
37 | 194 | * See Qt Bug: https://bugreports.qt-project.org/browse/QTBUG-40474 | ||
38 | 195 | */ | ||
39 | 196 | m_archive.data()->setValue(propertyName + "_TYPE", QVariant::fromValue((int)value.type())); | ||
40 | 176 | result++; | 197 | result++; |
41 | 177 | } | 198 | } |
42 | 178 | } | 199 | } |
43 | 179 | 200 | ||
44 | === added file 'tests/unit_x11/tst_statesaver/SaveEnum.qml' | |||
45 | --- tests/unit_x11/tst_statesaver/SaveEnum.qml 1970-01-01 00:00:00 +0000 | |||
46 | +++ tests/unit_x11/tst_statesaver/SaveEnum.qml 2014-07-29 09:48:52 +0000 | |||
47 | @@ -0,0 +1,23 @@ | |||
48 | 1 | /* | ||
49 | 2 | * Copyright 2014 Canonical Ltd. | ||
50 | 3 | * | ||
51 | 4 | * This program is free software; you can redistribute it and/or modify | ||
52 | 5 | * it under the terms of the GNU Lesser General Public License as published by | ||
53 | 6 | * the Free Software Foundation; version 3. | ||
54 | 7 | * | ||
55 | 8 | * This program is distributed in the hope that it will be useful, | ||
56 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
57 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
58 | 11 | * GNU Lesser General Public License for more details. | ||
59 | 12 | * | ||
60 | 13 | * You should have received a copy of the GNU Lesser General Public License | ||
61 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
62 | 15 | */ | ||
63 | 16 | |||
64 | 17 | import QtQuick 2.0 | ||
65 | 18 | import Ubuntu.Components 1.1 | ||
66 | 19 | |||
67 | 20 | Text { | ||
68 | 21 | id: testItem | ||
69 | 22 | StateSaver.properties: "horizontalAlignment" | ||
70 | 23 | } | ||
71 | 0 | 24 | ||
72 | === modified file 'tests/unit_x11/tst_statesaver/tst_statesaver.cpp' | |||
73 | --- tests/unit_x11/tst_statesaver/tst_statesaver.cpp 2014-04-10 09:36:36 +0000 | |||
74 | +++ tests/unit_x11/tst_statesaver/tst_statesaver.cpp 2014-07-29 09:48:52 +0000 | |||
75 | @@ -36,8 +36,10 @@ | |||
76 | 36 | #include <signal.h> | 36 | #include <signal.h> |
77 | 37 | 37 | ||
78 | 38 | #define protected public | 38 | #define protected public |
79 | 39 | #define private public | ||
80 | 39 | #include "ucstatesaver.h" | 40 | #include "ucstatesaver.h" |
81 | 40 | #include "statesaverbackend_p.h" | 41 | #include "statesaverbackend_p.h" |
82 | 42 | #undef private | ||
83 | 41 | #undef protected | 43 | #undef protected |
84 | 42 | 44 | ||
85 | 43 | class tst_StateSaverTest : public QObject | 45 | class tst_StateSaverTest : public QObject |
86 | @@ -59,6 +61,8 @@ | |||
87 | 59 | { | 61 | { |
88 | 60 | Q_EMIT StateSaverBackend::instance().initiateStateSaving(); | 62 | Q_EMIT StateSaverBackend::instance().initiateStateSaving(); |
89 | 61 | view.reset(); | 63 | view.reset(); |
90 | 64 | // Make sure that the state is reloaded from file | ||
91 | 65 | StateSaverBackend::instance().m_archive.data()->sync(); | ||
92 | 62 | view.reset(new UbuntuTestCase(file)); | 66 | view.reset(new UbuntuTestCase(file)); |
93 | 63 | } | 67 | } |
94 | 64 | 68 | ||
95 | @@ -66,6 +70,8 @@ | |||
96 | 66 | { | 70 | { |
97 | 67 | Q_EMIT StateSaverBackend::instance().initiateStateSaving(); | 71 | Q_EMIT StateSaverBackend::instance().initiateStateSaving(); |
98 | 68 | view.reset(); | 72 | view.reset(); |
99 | 73 | // Make sure that the state is reloaded from file | ||
100 | 74 | StateSaverBackend::instance().m_archive.data()->sync(); | ||
101 | 69 | view.reset(createView(file)); | 75 | view.reset(createView(file)); |
102 | 70 | } | 76 | } |
103 | 71 | 77 | ||
104 | @@ -171,6 +177,31 @@ | |||
105 | 171 | } | 177 | } |
106 | 172 | } | 178 | } |
107 | 173 | 179 | ||
108 | 180 | void test_SaveEnum() | ||
109 | 181 | { | ||
110 | 182 | /* This test is important because when saving the value of an enum | ||
111 | 183 | * property to QSettings, it is deserialized as a string. Setting that | ||
112 | 184 | * string value to an enum property fails and therefore the state | ||
113 | 185 | * restoration does not work. | ||
114 | 186 | * In most cases implicit type conversion from string to the appropriate | ||
115 | 187 | * type works. | ||
116 | 188 | */ | ||
117 | 189 | QScopedPointer<QQuickView> view(createView("SaveEnum.qml")); | ||
118 | 190 | QVERIFY(view); | ||
119 | 191 | QObject *testItem = view->rootObject(); | ||
120 | 192 | QVERIFY(testItem); | ||
121 | 193 | |||
122 | 194 | testItem->setProperty("horizontalAlignment", Qt::AlignRight); | ||
123 | 195 | |||
124 | 196 | resetView(view, "SaveEnum.qml"); | ||
125 | 197 | QVERIFY(view); | ||
126 | 198 | testItem = view->rootObject(); | ||
127 | 199 | QVERIFY(testItem); | ||
128 | 200 | |||
129 | 201 | |||
130 | 202 | QVERIFY(testItem->property("horizontalAlignment") == Qt::AlignRight); | ||
131 | 203 | } | ||
132 | 204 | |||
133 | 174 | void test_SavePropertyGroup() | 205 | void test_SavePropertyGroup() |
134 | 175 | { | 206 | { |
135 | 176 | QScopedPointer<QQuickView> view(createView("SavePropertyGroups.qml")); | 207 | QScopedPointer<QQuickView> view(createView("SavePropertyGroups.qml")); |
136 | 177 | 208 | ||
137 | === modified file 'tests/unit_x11/tst_statesaver/tst_statesaver.pro' | |||
138 | --- tests/unit_x11/tst_statesaver/tst_statesaver.pro 2014-02-06 19:16:34 +0000 | |||
139 | +++ tests/unit_x11/tst_statesaver/tst_statesaver.pro 2014-07-29 09:48:52 +0000 | |||
140 | @@ -26,4 +26,5 @@ | |||
141 | 26 | RepeaterStates.qml \ | 26 | RepeaterStates.qml \ |
142 | 27 | ListViewItems.qml \ | 27 | ListViewItems.qml \ |
143 | 28 | GridViewItems.qml \ | 28 | GridViewItems.qml \ |
145 | 29 | NormalAppClose.qml | 29 | NormalAppClose.qml \ |
146 | 30 | SaveEnum.qml |
PASSED: Continuous integration, rev:1163 jenkins. qa.ubuntu. com/job/ ubuntu- sdk-team- ubuntu- ui-toolkit- staging- ci/668/ jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- utopic- touch/2582 jenkins. qa.ubuntu. com/job/ generic- mediumtests- utopic/ 2065 jenkins. qa.ubuntu. com/job/ ubuntu- sdk-team- ubuntu- ui-toolkit- staging- utopic- amd64-ci/ 500 jenkins. qa.ubuntu. com/job/ ubuntu- sdk-team- ubuntu- ui-toolkit- staging- utopic- armhf-ci/ 500 jenkins. qa.ubuntu. com/job/ ubuntu- sdk-team- ubuntu- ui-toolkit- staging- utopic- armhf-ci/ 500/artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ ubuntu- sdk-team- ubuntu- ui-toolkit- staging- utopic- i386-ci/ 500 jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- runner- mako/2720 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- utopic- armhf/3825 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- utopic- armhf/3825/ artifact/ work/output/ *zip*/output. zip s-jenkins. ubuntu- ci:8080/ job/touch- flash-device/ 10534 jenkins. qa.ubuntu. com/job/ autopilot- testrunner- otto-utopic/ 1727 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- utopic- amd64/2318 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- utopic- amd64/2318/ artifact/ work/output/ *zip*/output. zip
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/ubuntu- sdk-team- ubuntu- ui-toolkit- staging- ci/668/ rebuild
http://