Merge lp:~zsombi/ubuntu-ui-toolkit/stylehints into lp:ubuntu-ui-toolkit/staging
- stylehints
- Merge into staging
Status: | Merged |
---|---|
Approved by: | Cris Dywan |
Approved revision: | 1533 |
Merged at revision: | 1526 |
Proposed branch: | lp:~zsombi/ubuntu-ui-toolkit/stylehints |
Merge into: | lp:ubuntu-ui-toolkit/staging |
Diff against target: |
1078 lines (+815/-20) 23 files modified
components.api (+2/-0) modules/Ubuntu/Components/plugin/plugin.cpp (+2/-0) modules/Ubuntu/Components/plugin/plugin.pro (+4/-2) modules/Ubuntu/Components/plugin/propertychange_p.cpp (+30/-9) modules/Ubuntu/Components/plugin/propertychange_p.h (+9/-0) modules/Ubuntu/Components/plugin/ucstyleditembase.cpp (+1/-0) modules/Ubuntu/Components/plugin/ucstyleditembase.h (+1/-0) modules/Ubuntu/Components/plugin/ucstylehints.cpp (+259/-0) modules/Ubuntu/Components/plugin/ucstylehints.h (+92/-0) modules/Ubuntu/Test/plugin/uctestcase.cpp (+9/-5) modules/Ubuntu/Test/plugin/uctestcase.h (+1/-1) tests/unit_x11/tst_subtheming/GroupPropertyBindingHints.qml (+32/-0) tests/unit_x11/tst_subtheming/HintedButton.qml (+24/-0) tests/unit_x11/tst_subtheming/MoreStyleHints.qml (+34/-0) tests/unit_x11/tst_subtheming/OverrideStyleHints.qml (+30/-0) tests/unit_x11/tst_subtheming/PropertyBindingHints.qml (+31/-0) tests/unit_x11/tst_subtheming/SimplePropertyHints.qml (+30/-0) tests/unit_x11/tst_subtheming/StyleHintsElsewhere.qml (+27/-0) tests/unit_x11/tst_subtheming/StyleHintsInvalidProperty.qml (+30/-0) tests/unit_x11/tst_subtheming/StyleHintsWithObject.qml (+29/-0) tests/unit_x11/tst_subtheming/StyleHintsWithSignal.qml (+29/-0) tests/unit_x11/tst_subtheming/tst_subtheming.cpp (+98/-2) tests/unit_x11/tst_subtheming/tst_subtheming.pro (+11/-1) |
To merge this branch: | bzr merge lp:~zsombi/ubuntu-ui-toolkit/stylehints |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Cris Dywan | Approve | ||
PS Jenkins bot | continuous-integration | Approve | |
Review via email: mp+260826@code.launchpad.net |
Commit message
Introducing StyleHints to provide style specific property changes.
Description of the change
PS Jenkins bot (ps-jenkins) wrote : | # |
- 1532. By Zsombor Egri
-
documentation fixed
- 1533. By Zsombor Egri
-
accidental scrollbar style change
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1533
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Cris Dywan (kalikiana) wrote : | # |
I wish all merge requests were this clean, every time I thought "hmm is there a test for that code" there was. Looks pretty slick, and tests pass now.
Preview Diff
1 | === modified file 'components.api' | |||
2 | --- components.api 2015-05-26 07:38:55 +0000 | |||
3 | +++ components.api 2015-06-02 15:25:00 +0000 | |||
4 | @@ -871,6 +871,8 @@ | |||
5 | 871 | property bool iconFrame | 871 | property bool iconFrame |
6 | 872 | property bool progression | 872 | property bool progression |
7 | 873 | Ubuntu.Components.StateSaver 1.0 0.1: QtObject | 873 | Ubuntu.Components.StateSaver 1.0 0.1: QtObject |
8 | 874 | Ubuntu.Components.StyleHints 1.3: QtObject | ||
9 | 875 | property bool ignoreUnknownProperties | ||
10 | 874 | Ubuntu.Components.StyledItem 1.3 1.1 1.0 0.1: Item | 876 | Ubuntu.Components.StyledItem 1.3 1.1 1.0 0.1: Item |
11 | 875 | property bool activeFocusOnPress | 877 | property bool activeFocusOnPress |
12 | 876 | function bool requestFocus(Qt.FocusReason reason) | 878 | function bool requestFocus(Qt.FocusReason reason) |
13 | 877 | 879 | ||
14 | === modified file 'modules/Ubuntu/Components/plugin/plugin.cpp' | |||
15 | --- modules/Ubuntu/Components/plugin/plugin.cpp 2015-05-21 10:50:35 +0000 | |||
16 | +++ modules/Ubuntu/Components/plugin/plugin.cpp 2015-06-02 15:25:00 +0000 | |||
17 | @@ -50,6 +50,7 @@ | |||
18 | 50 | #include "ucinversemouse.h" | 50 | #include "ucinversemouse.h" |
19 | 51 | #include "sortfiltermodel.h" | 51 | #include "sortfiltermodel.h" |
20 | 52 | #include "ucstyleditembase.h" | 52 | #include "ucstyleditembase.h" |
21 | 53 | #include "ucstylehints.h" | ||
22 | 53 | #include "ucaction.h" | 54 | #include "ucaction.h" |
23 | 54 | #include "ucactioncontext.h" | 55 | #include "ucactioncontext.h" |
24 | 55 | #include "ucactionmanager.h" | 56 | #include "ucactionmanager.h" |
25 | @@ -211,6 +212,7 @@ | |||
26 | 211 | qmlRegisterType<UCStyledItemBase, 2>(uri, 1, 3, "StyledItem"); | 212 | qmlRegisterType<UCStyledItemBase, 2>(uri, 1, 3, "StyledItem"); |
27 | 212 | qmlRegisterSingletonType<UCNamespaceV13>(uri, 1, 3, "Ubuntu", registerUbuntuNamespace13); | 213 | qmlRegisterSingletonType<UCNamespaceV13>(uri, 1, 3, "Ubuntu", registerUbuntuNamespace13); |
28 | 213 | qmlRegisterType<UCStyledItemBase, 2>(uri, 1, 3, "StyledItem"); | 214 | qmlRegisterType<UCStyledItemBase, 2>(uri, 1, 3, "StyledItem"); |
29 | 215 | qmlRegisterCustomType<UCStyleHints>(uri, 1, 3, "StyleHints", new UCStyleHintsParser); | ||
30 | 214 | } | 216 | } |
31 | 215 | 217 | ||
32 | 216 | void UbuntuComponentsPlugin::initializeEngine(QQmlEngine *engine, const char *uri) | 218 | void UbuntuComponentsPlugin::initializeEngine(QQmlEngine *engine, const char *uri) |
33 | 217 | 219 | ||
34 | === modified file 'modules/Ubuntu/Components/plugin/plugin.pro' | |||
35 | --- modules/Ubuntu/Components/plugin/plugin.pro 2015-03-13 09:27:53 +0000 | |||
36 | +++ modules/Ubuntu/Components/plugin/plugin.pro 2015-06-02 15:25:00 +0000 | |||
37 | @@ -80,7 +80,8 @@ | |||
38 | 80 | privates/listitemdraghandler.h \ | 80 | privates/listitemdraghandler.h \ |
39 | 81 | ucnamespace.h \ | 81 | ucnamespace.h \ |
40 | 82 | ucdeprecatedtheme.h \ | 82 | ucdeprecatedtheme.h \ |
42 | 83 | ucdefaulttheme.h | 83 | ucdefaulttheme.h \ |
43 | 84 | ucstylehints.h | ||
44 | 84 | 85 | ||
45 | 85 | SOURCES += plugin.cpp \ | 86 | SOURCES += plugin.cpp \ |
46 | 86 | uctheme.cpp \ | 87 | uctheme.cpp \ |
47 | @@ -128,7 +129,8 @@ | |||
48 | 128 | privates/listitemdraghandler.cpp \ | 129 | privates/listitemdraghandler.cpp \ |
49 | 129 | ucnamespace.cpp \ | 130 | ucnamespace.cpp \ |
50 | 130 | ucdeprecatedtheme.cpp \ | 131 | ucdeprecatedtheme.cpp \ |
52 | 131 | ucdefaulttheme.cpp | 132 | ucdefaulttheme.cpp \ |
53 | 133 | ucstylehints.cpp | ||
54 | 132 | 134 | ||
55 | 133 | # adapters | 135 | # adapters |
56 | 134 | SOURCES += adapters/alarmsadapter_organizer.cpp | 136 | SOURCES += adapters/alarmsadapter_organizer.cpp |
57 | 135 | 137 | ||
58 | === modified file 'modules/Ubuntu/Components/plugin/propertychange_p.cpp' | |||
59 | --- modules/Ubuntu/Components/plugin/propertychange_p.cpp 2015-01-27 18:14:44 +0000 | |||
60 | +++ modules/Ubuntu/Components/plugin/propertychange_p.cpp 2015-06-02 15:25:00 +0000 | |||
61 | @@ -28,6 +28,7 @@ | |||
62 | 28 | PropertyChange::PropertyChange(QObject *item, const char *property, bool autoBackup) | 28 | PropertyChange::PropertyChange(QObject *item, const char *property, bool autoBackup) |
63 | 29 | : backedUp(false) | 29 | : backedUp(false) |
64 | 30 | , qmlProperty(item, property, qmlContext(item)) | 30 | , qmlProperty(item, property, qmlContext(item)) |
65 | 31 | , backupBinding(Q_NULLPTR) | ||
66 | 31 | { | 32 | { |
67 | 32 | if (autoBackup) { | 33 | if (autoBackup) { |
68 | 33 | backup(); | 34 | backup(); |
69 | @@ -41,6 +42,7 @@ | |||
70 | 41 | void PropertyChange::backup() | 42 | void PropertyChange::backup() |
71 | 42 | { | 43 | { |
72 | 43 | if (!backedUp) { | 44 | if (!backedUp) { |
73 | 45 | backupBinding = QQmlPropertyPrivate::binding(qmlProperty); | ||
74 | 44 | backupValue = qmlProperty.read(); | 46 | backupValue = qmlProperty.read(); |
75 | 45 | backedUp = true; | 47 | backedUp = true; |
76 | 46 | } | 48 | } |
77 | @@ -56,11 +58,24 @@ | |||
78 | 56 | return; | 58 | return; |
79 | 57 | } | 59 | } |
80 | 58 | change->backup(); | 60 | change->backup(); |
86 | 59 | // write using QQmlPropertyPrivate so we can keep the bindings | 61 | change->qmlProperty.write(value); |
87 | 60 | QQmlPropertyPrivate::write(change->qmlProperty, | 62 | } |
88 | 61 | value, | 63 | |
89 | 62 | QQmlPropertyPrivate::BypassInterceptor | QQmlPropertyPrivate::DontRemoveBinding); | 64 | /* |
90 | 63 | } | 65 | * Same as setValue() but setting a binding. |
91 | 66 | */ | ||
92 | 67 | void PropertyChange::setBinding(PropertyChange *change, QQmlAbstractBinding *binding) | ||
93 | 68 | { | ||
94 | 69 | if (!change) { | ||
95 | 70 | return; | ||
96 | 71 | } | ||
97 | 72 | change->backup(); | ||
98 | 73 | QQmlAbstractBinding *prev = QQmlPropertyPrivate::setBinding(change->qmlProperty, binding); | ||
99 | 74 | if (prev && prev != binding && prev != change->backupBinding) { | ||
100 | 75 | prev->destroy(); | ||
101 | 76 | } | ||
102 | 77 | } | ||
103 | 78 | |||
104 | 64 | 79 | ||
105 | 65 | /* | 80 | /* |
106 | 66 | * Restore backed up value or binding. | 81 | * Restore backed up value or binding. |
107 | @@ -71,10 +86,16 @@ | |||
108 | 71 | return; | 86 | return; |
109 | 72 | } | 87 | } |
110 | 73 | if (change->backedUp) { | 88 | if (change->backedUp) { |
115 | 74 | // write using QQmlPropertyPrivate to keep the bindings | 89 | if (change->qmlProperty.isValid()) { |
116 | 75 | QQmlPropertyPrivate::write(change->qmlProperty, | 90 | if (change->backupBinding) { |
117 | 76 | change->backupValue, | 91 | QQmlAbstractBinding *prev = QQmlPropertyPrivate::setBinding(change->qmlProperty, change->backupBinding); |
118 | 77 | QQmlPropertyPrivate::BypassInterceptor | QQmlPropertyPrivate::DontRemoveBinding); | 92 | if (prev != change->backupBinding && prev) { |
119 | 93 | prev->destroy(); | ||
120 | 94 | } | ||
121 | 95 | } else { | ||
122 | 96 | change->qmlProperty.write(change->backupValue); | ||
123 | 97 | } | ||
124 | 98 | } | ||
125 | 78 | change->backedUp = false; | 99 | change->backedUp = false; |
126 | 79 | } | 100 | } |
127 | 80 | } | 101 | } |
128 | 81 | 102 | ||
129 | === modified file 'modules/Ubuntu/Components/plugin/propertychange_p.h' | |||
130 | --- modules/Ubuntu/Components/plugin/propertychange_p.h 2015-01-27 18:14:44 +0000 | |||
131 | +++ modules/Ubuntu/Components/plugin/propertychange_p.h 2015-06-02 15:25:00 +0000 | |||
132 | @@ -21,6 +21,7 @@ | |||
133 | 21 | #include <QtCore/QObject> | 21 | #include <QtCore/QObject> |
134 | 22 | #include <QtQml/QQmlProperty> | 22 | #include <QtQml/QQmlProperty> |
135 | 23 | 23 | ||
136 | 24 | class QQmlAbstractBinding; | ||
137 | 24 | class PropertyChange | 25 | class PropertyChange |
138 | 25 | { | 26 | { |
139 | 26 | public: | 27 | public: |
140 | @@ -28,11 +29,19 @@ | |||
141 | 28 | ~PropertyChange(); | 29 | ~PropertyChange(); |
142 | 29 | 30 | ||
143 | 30 | static void setValue(PropertyChange* change, const QVariant &value); | 31 | static void setValue(PropertyChange* change, const QVariant &value); |
144 | 32 | static void setBinding(PropertyChange *change, QQmlAbstractBinding *binding); | ||
145 | 31 | static void restore(PropertyChange* change); | 33 | static void restore(PropertyChange* change); |
146 | 34 | |||
147 | 35 | const QQmlProperty &property() | ||
148 | 36 | { | ||
149 | 37 | return qmlProperty; | ||
150 | 38 | } | ||
151 | 39 | |||
152 | 32 | private: | 40 | private: |
153 | 33 | bool backedUp; | 41 | bool backedUp; |
154 | 34 | QQmlProperty qmlProperty; | 42 | QQmlProperty qmlProperty; |
155 | 35 | QVariant backupValue; | 43 | QVariant backupValue; |
156 | 44 | QQmlAbstractBinding *backupBinding; | ||
157 | 36 | 45 | ||
158 | 37 | void backup(); | 46 | void backup(); |
159 | 38 | }; | 47 | }; |
160 | 39 | 48 | ||
161 | === modified file 'modules/Ubuntu/Components/plugin/ucstyleditembase.cpp' | |||
162 | --- modules/Ubuntu/Components/plugin/ucstyleditembase.cpp 2015-05-26 15:05:46 +0000 | |||
163 | +++ modules/Ubuntu/Components/plugin/ucstyleditembase.cpp 2015-06-02 15:25:00 +0000 | |||
164 | @@ -19,6 +19,7 @@ | |||
165 | 19 | #include "ucstyleditembase.h" | 19 | #include "ucstyleditembase.h" |
166 | 20 | #include "ucstyleditembase_p.h" | 20 | #include "ucstyleditembase_p.h" |
167 | 21 | #include "uctheme.h" | 21 | #include "uctheme.h" |
168 | 22 | #include "ucstylehints.h" | ||
169 | 22 | #include <QtQml/QQmlEngine> | 23 | #include <QtQml/QQmlEngine> |
170 | 23 | #include <QtQuick/private/qquickanchors_p.h> | 24 | #include <QtQuick/private/qquickanchors_p.h> |
171 | 24 | 25 | ||
172 | 25 | 26 | ||
173 | === modified file 'modules/Ubuntu/Components/plugin/ucstyleditembase.h' | |||
174 | --- modules/Ubuntu/Components/plugin/ucstyleditembase.h 2015-05-22 13:54:38 +0000 | |||
175 | +++ modules/Ubuntu/Components/plugin/ucstyleditembase.h 2015-06-02 15:25:00 +0000 | |||
176 | @@ -23,6 +23,7 @@ | |||
177 | 23 | 23 | ||
178 | 24 | class UCStyledItemBasePrivate; | 24 | class UCStyledItemBasePrivate; |
179 | 25 | class UCTheme; | 25 | class UCTheme; |
180 | 26 | class UCStyleHints; | ||
181 | 26 | class UCStyledItemBase : public QQuickItem | 27 | class UCStyledItemBase : public QQuickItem |
182 | 27 | { | 28 | { |
183 | 28 | Q_OBJECT | 29 | Q_OBJECT |
184 | 29 | 30 | ||
185 | === added file 'modules/Ubuntu/Components/plugin/ucstylehints.cpp' | |||
186 | --- modules/Ubuntu/Components/plugin/ucstylehints.cpp 1970-01-01 00:00:00 +0000 | |||
187 | +++ modules/Ubuntu/Components/plugin/ucstylehints.cpp 2015-06-02 15:25:00 +0000 | |||
188 | @@ -0,0 +1,259 @@ | |||
189 | 1 | /* | ||
190 | 2 | * Copyright 2015 Canonical Ltd. | ||
191 | 3 | * | ||
192 | 4 | * This program is free software; you can redistribute it and/or modify | ||
193 | 5 | * it under the terms of the GNU Lesser General Public License as published by | ||
194 | 6 | * the Free Software Foundation; version 3. | ||
195 | 7 | * | ||
196 | 8 | * This program is distributed in the hope that it will be useful, | ||
197 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
198 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
199 | 11 | * GNU Lesser General Public License for more details. | ||
200 | 12 | * | ||
201 | 13 | * You should have received a copy of the GNU Lesser General Public License | ||
202 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
203 | 15 | * | ||
204 | 16 | * Author: Zsombor Egri <zsombor.egri@canonical.com> | ||
205 | 17 | */ | ||
206 | 18 | |||
207 | 19 | #include "ucstylehints.h" | ||
208 | 20 | #include "ucstyleditembase_p.h" | ||
209 | 21 | #include "propertychange_p.h" | ||
210 | 22 | #include <QtQml/QQmlInfo> | ||
211 | 23 | |||
212 | 24 | // verifies property declaration correctness | ||
213 | 25 | void UCStyleHintsParser::verifyBindings(const QV4::CompiledData::Unit *qmlUnit, const QList<const QV4::CompiledData::Binding *> &bindings) | ||
214 | 26 | { | ||
215 | 27 | Q_FOREACH(const QV4::CompiledData::Binding *binding, bindings) { | ||
216 | 28 | verifyProperty(qmlUnit, binding); | ||
217 | 29 | } | ||
218 | 30 | } | ||
219 | 31 | |||
220 | 32 | void UCStyleHintsParser::verifyProperty(const QV4::CompiledData::Unit *qmlUnit, const QV4::CompiledData::Binding *binding) | ||
221 | 33 | { | ||
222 | 34 | if (binding->type == QV4::CompiledData::Binding::Type_Object) { | ||
223 | 35 | error(qmlUnit->objectAt(binding->value.objectIndex), "StyleHints does not support creating state-specific objects."); | ||
224 | 36 | return; | ||
225 | 37 | } | ||
226 | 38 | |||
227 | 39 | // group properties or attached properties, we do handle those as well | ||
228 | 40 | if (binding->type == QV4::CompiledData::Binding::Type_GroupProperty | ||
229 | 41 | || binding->type == QV4::CompiledData::Binding::Type_AttachedProperty) { | ||
230 | 42 | const QV4::CompiledData::Object *subObj = qmlUnit->objectAt(binding->value.objectIndex); | ||
231 | 43 | const QV4::CompiledData::Binding *subBinding = subObj->bindingTable(); | ||
232 | 44 | for (quint32 i = 0; i < subObj->nBindings; ++i, ++subBinding) { | ||
233 | 45 | verifyProperty(qmlUnit, subBinding); | ||
234 | 46 | } | ||
235 | 47 | } | ||
236 | 48 | |||
237 | 49 | // filter out signals! | ||
238 | 50 | QString propertyName = qmlUnit->stringAt(binding->propertyNameIndex); | ||
239 | 51 | if (propertyName.startsWith("on") && propertyName.at(2).isUpper()) { | ||
240 | 52 | error(binding, "Signal properties are not supported."); | ||
241 | 53 | return; | ||
242 | 54 | } | ||
243 | 55 | } | ||
244 | 56 | |||
245 | 57 | // decodes property declarations, stores the bindings and values | ||
246 | 58 | void UCStyleHintsParser::applyBindings(QObject *obj, QQmlCompiledData *cdata, const QList<const QV4::CompiledData::Binding *> &bindings) | ||
247 | 59 | { | ||
248 | 60 | UCStyleHints *hints = static_cast<UCStyleHints*>(obj); | ||
249 | 61 | QV4::CompiledData::Unit *qmlUnit = cdata->compilationUnit->data; | ||
250 | 62 | |||
251 | 63 | UCStyledItemBase *styledItem = qobject_cast<UCStyledItemBase*>(hints->parent()); | ||
252 | 64 | if (!styledItem) { | ||
253 | 65 | // error will be reported in componentCompleted | ||
254 | 66 | return; | ||
255 | 67 | } | ||
256 | 68 | |||
257 | 69 | Q_FOREACH(const QV4::CompiledData::Binding *binding, bindings) { | ||
258 | 70 | hints->decodeBinding(QString(), qmlUnit, binding); | ||
259 | 71 | } | ||
260 | 72 | |||
261 | 73 | hints->m_cdata = cdata; | ||
262 | 74 | hints->m_decoded = true; | ||
263 | 75 | } | ||
264 | 76 | |||
265 | 77 | void UCStyleHints::decodeBinding(const QString &propertyPrefix, const QV4::CompiledData::Unit *qmlUnit, const QV4::CompiledData::Binding *binding) | ||
266 | 78 | { | ||
267 | 79 | QString propertyName = propertyPrefix + qmlUnit->stringAt(binding->propertyNameIndex); | ||
268 | 80 | |||
269 | 81 | // handle grouped properties first | ||
270 | 82 | if (binding->type == QV4::CompiledData::Binding::Type_GroupProperty | ||
271 | 83 | || binding->type == QV4::CompiledData::Binding::Type_AttachedProperty) { | ||
272 | 84 | |||
273 | 85 | const QV4::CompiledData::Object *subObj = qmlUnit->objectAt(binding->value.objectIndex); | ||
274 | 86 | const QV4::CompiledData::Binding *subBinding = subObj->bindingTable(); | ||
275 | 87 | QString pre = propertyName + "."; | ||
276 | 88 | for (quint32 i = 0; i < subObj->nBindings; ++i, ++subBinding) { | ||
277 | 89 | decodeBinding(pre, qmlUnit, subBinding); | ||
278 | 90 | } | ||
279 | 91 | return; | ||
280 | 92 | } | ||
281 | 93 | |||
282 | 94 | switch (binding->type) { | ||
283 | 95 | case QV4::CompiledData::Binding::Type_Script: | ||
284 | 96 | { | ||
285 | 97 | QString expression = binding->valueAsScriptString(qmlUnit); | ||
286 | 98 | QUrl url = QUrl(); | ||
287 | 99 | int line = -1; | ||
288 | 100 | int column = -1; | ||
289 | 101 | |||
290 | 102 | QQmlData *ddata = QQmlData::get(this); | ||
291 | 103 | if (ddata && ddata->outerContext && !ddata->outerContext->url.isEmpty()) { | ||
292 | 104 | url = ddata->outerContext->url; | ||
293 | 105 | line = ddata->lineNumber; | ||
294 | 106 | column = ddata->columnNumber; | ||
295 | 107 | } | ||
296 | 108 | m_expressions << Expression(propertyName, binding->value.compiledScriptIndex, expression, url, line, column); | ||
297 | 109 | break; | ||
298 | 110 | } | ||
299 | 111 | case QV4::CompiledData::Binding::Type_Translation: | ||
300 | 112 | case QV4::CompiledData::Binding::Type_TranslationById: | ||
301 | 113 | case QV4::CompiledData::Binding::Type_String: | ||
302 | 114 | { | ||
303 | 115 | m_values << qMakePair(propertyName, binding->valueAsString(qmlUnit)); | ||
304 | 116 | break; | ||
305 | 117 | } | ||
306 | 118 | case QV4::CompiledData::Binding::Type_Number: | ||
307 | 119 | { | ||
308 | 120 | m_values << qMakePair(propertyName, binding->valueAsNumber()); | ||
309 | 121 | break; | ||
310 | 122 | } | ||
311 | 123 | case QV4::CompiledData::Binding::Type_Boolean: | ||
312 | 124 | { | ||
313 | 125 | m_values << qMakePair(propertyName, binding->valueAsBoolean()); | ||
314 | 126 | break; | ||
315 | 127 | } | ||
316 | 128 | } | ||
317 | 129 | } | ||
318 | 130 | |||
319 | 131 | void UCStyleHints::propertyNotFound(const QString &styleName, const QString &property) | ||
320 | 132 | { | ||
321 | 133 | if (!m_ignoreUnknownProperties) { | ||
322 | 134 | qmlInfo(this) << QString("Style '%1' has no property called '%2'.").arg(styleName).arg(property); | ||
323 | 135 | } | ||
324 | 136 | } | ||
325 | 137 | |||
326 | 138 | /*! | ||
327 | 139 | * \qmltype StyleHints | ||
328 | 140 | * \instantiates UCStyleHints | ||
329 | 141 | * \inmodule Ubuntu Components 1.3 | ||
330 | 142 | * \ingroup ubuntu | ||
331 | 143 | * \since Ubuntu.Components 1.3 | ||
332 | 144 | * \brief Component holding style specific properties to configure a particular | ||
333 | 145 | * StyledItem's style runtime. | ||
334 | 146 | * | ||
335 | 147 | * StyleHints is a custom parser, meaning style properties can be listed without | ||
336 | 148 | * any property declaration, same way as in PropertyChanges or Connections, which | ||
337 | 149 | * are similar custom parsers. Properties enumerated do not have to be present in | ||
338 | 150 | * the component's style as default, behavior which can be chenged by setting \l | ||
339 | 151 | * ignoreUnknownProperties to true. In this case properties not found in the style | ||
340 | 152 | * will be displayed as warnings. | ||
341 | 153 | * | ||
342 | 154 | * In the following example the Button will be drawn as white when not pressed, and | ||
343 | 155 | * colored as blue when pressed. | ||
344 | 156 | * \qml | ||
345 | 157 | * Button { | ||
346 | 158 | * id: button | ||
347 | 159 | * StyleHints { | ||
348 | 160 | * defaultColor: button.pressed ? "blue" : "white" | ||
349 | 161 | * } | ||
350 | 162 | * } | ||
351 | 163 | * \endqml | ||
352 | 164 | * | ||
353 | 165 | * StyleHints does not support signal properties (i.e signal handlers) and object | ||
354 | 166 | * declarations as property values. | ||
355 | 167 | * | ||
356 | 168 | * StyleHints can be only declared in a \l StyledItem or as a derivate of it. | ||
357 | 169 | */ | ||
358 | 170 | |||
359 | 171 | /*! | ||
360 | 172 | * \qmlproperty bool StyleHints::ignoreUnknownProperties | ||
361 | 173 | * The property drives whether component should warn on properties not found in | ||
362 | 174 | * the component's style. The default setting is not to warn. | ||
363 | 175 | */ | ||
364 | 176 | UCStyleHints::UCStyleHints(QObject *parent) | ||
365 | 177 | : QObject(parent) | ||
366 | 178 | , m_decoded(false) | ||
367 | 179 | , m_completed(false) | ||
368 | 180 | , m_ignoreUnknownProperties(true) | ||
369 | 181 | { | ||
370 | 182 | } | ||
371 | 183 | |||
372 | 184 | UCStyleHints::~UCStyleHints() | ||
373 | 185 | { | ||
374 | 186 | qDeleteAll(m_propertyBackup); | ||
375 | 187 | m_propertyBackup.clear(); | ||
376 | 188 | } | ||
377 | 189 | |||
378 | 190 | void UCStyleHints::classBegin() | ||
379 | 191 | { | ||
380 | 192 | m_styledItem = qobject_cast<UCStyledItemBase*>(parent()); | ||
381 | 193 | if (m_styledItem) { | ||
382 | 194 | connect(m_styledItem, SIGNAL(styleInstanceChanged()), | ||
383 | 195 | this, SLOT(_q_applyStyleHints())); | ||
384 | 196 | } else { | ||
385 | 197 | qmlInfo(this) << "StyleHints must be declared in a StyledItem or a derivate of it."; | ||
386 | 198 | } | ||
387 | 199 | } | ||
388 | 200 | |||
389 | 201 | void UCStyleHints::componentComplete() | ||
390 | 202 | { | ||
391 | 203 | m_completed = (m_styledItem != Q_NULLPTR); | ||
392 | 204 | _q_applyStyleHints(); | ||
393 | 205 | } | ||
394 | 206 | |||
395 | 207 | // apply the style hints and check each property existence | ||
396 | 208 | void UCStyleHints::_q_applyStyleHints() | ||
397 | 209 | { | ||
398 | 210 | if (!m_completed || !m_decoded || !m_styledItem || !UCStyledItemBasePrivate::get(m_styledItem)->styleItem) { | ||
399 | 211 | return; | ||
400 | 212 | } | ||
401 | 213 | |||
402 | 214 | // restore properties first | ||
403 | 215 | qDeleteAll(m_propertyBackup); | ||
404 | 216 | m_propertyBackup.clear(); | ||
405 | 217 | |||
406 | 218 | QQuickItem *item = UCStyledItemBasePrivate::get(m_styledItem)->styleItem; | ||
407 | 219 | const QMetaObject *mo = item->metaObject(); | ||
408 | 220 | const QString styleName = UCStyledItemBasePrivate::get(m_styledItem)->styleName(); | ||
409 | 221 | // apply values first | ||
410 | 222 | for (int i = 0; i < m_values.size(); i++) { | ||
411 | 223 | if (mo->indexOfProperty(m_values[i].first.toUtf8()) < 0) { | ||
412 | 224 | propertyNotFound(styleName, m_values[i].first); | ||
413 | 225 | continue; | ||
414 | 226 | } | ||
415 | 227 | PropertyChange *change = new PropertyChange(item, m_values[i].first.toUtf8()); | ||
416 | 228 | PropertyChange::setValue(change, m_values[i].second); | ||
417 | 229 | m_propertyBackup << change; | ||
418 | 230 | } | ||
419 | 231 | |||
420 | 232 | QQmlContext *context = qmlContext(this); | ||
421 | 233 | // then apply expressions/bindings | ||
422 | 234 | for (int ii = 0; ii < m_expressions.count(); ii++) { | ||
423 | 235 | Expression e = m_expressions[ii]; | ||
424 | 236 | PropertyChange *change = new PropertyChange(item, e.name.toUtf8()); | ||
425 | 237 | if (!change->property().isValid()) { | ||
426 | 238 | propertyNotFound(styleName, e.name); | ||
427 | 239 | delete change; | ||
428 | 240 | continue; | ||
429 | 241 | } | ||
430 | 242 | |||
431 | 243 | // create a binding object from the expression using the palette context | ||
432 | 244 | QQmlContextData *cdata = QQmlContextData::get(context); | ||
433 | 245 | QQmlBinding *newBinding = 0; | ||
434 | 246 | if (e.id != QQmlBinding::Invalid) { | ||
435 | 247 | QV4::Scope scope(QQmlEnginePrivate::getV4Engine(qmlEngine(this))); | ||
436 | 248 | QV4::ScopedValue function(scope, QV4::QmlBindingWrapper::createQmlCallableForFunction(cdata, item, m_cdata->compilationUnit->runtimeFunctions[e.id])); | ||
437 | 249 | newBinding = new QQmlBinding(function, item, cdata); | ||
438 | 250 | } | ||
439 | 251 | if (!newBinding) { | ||
440 | 252 | newBinding = new QQmlBinding(e.expression, item, cdata, e.url.toString(), e.line, e.column); | ||
441 | 253 | } | ||
442 | 254 | |||
443 | 255 | newBinding->setTarget(change->property()); | ||
444 | 256 | PropertyChange::setBinding(change, newBinding); | ||
445 | 257 | } | ||
446 | 258 | } | ||
447 | 259 | |||
448 | 0 | 260 | ||
449 | === added file 'modules/Ubuntu/Components/plugin/ucstylehints.h' | |||
450 | --- modules/Ubuntu/Components/plugin/ucstylehints.h 1970-01-01 00:00:00 +0000 | |||
451 | +++ modules/Ubuntu/Components/plugin/ucstylehints.h 2015-06-02 15:25:00 +0000 | |||
452 | @@ -0,0 +1,92 @@ | |||
453 | 1 | /* | ||
454 | 2 | * Copyright 2015 Canonical Ltd. | ||
455 | 3 | * | ||
456 | 4 | * This program is free software; you can redistribute it and/or modify | ||
457 | 5 | * it under the terms of the GNU Lesser General Public License as published by | ||
458 | 6 | * the Free Software Foundation; version 3. | ||
459 | 7 | * | ||
460 | 8 | * This program is distributed in the hope that it will be useful, | ||
461 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
462 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
463 | 11 | * GNU Lesser General Public License for more details. | ||
464 | 12 | * | ||
465 | 13 | * You should have received a copy of the GNU Lesser General Public License | ||
466 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
467 | 15 | * | ||
468 | 16 | * Author: Zsombor Egri <zsombor.egri@canonical.com> | ||
469 | 17 | */ | ||
470 | 18 | |||
471 | 19 | #ifndef UCSTYLEHINTS_H | ||
472 | 20 | #define UCSTYLEHINTS_H | ||
473 | 21 | |||
474 | 22 | #include <QtCore/QObject> | ||
475 | 23 | #define foreach Q_FOREACH | ||
476 | 24 | #include <QtQml/private/qqmlcustomparser_p.h> | ||
477 | 25 | #include <private/qv4engine_p.h> | ||
478 | 26 | #include <private/qpodvector_p.h> | ||
479 | 27 | #undef foreach | ||
480 | 28 | #include <QtQml/private/qqmlcompiler_p.h> | ||
481 | 29 | |||
482 | 30 | class UCStyleHintsParser; | ||
483 | 31 | class UCStyledItemBase; | ||
484 | 32 | class QQuickItem; | ||
485 | 33 | class PropertyChange; | ||
486 | 34 | class UCStyleHints : public QObject, public QQmlParserStatus | ||
487 | 35 | { | ||
488 | 36 | Q_OBJECT | ||
489 | 37 | Q_INTERFACES(QQmlParserStatus) | ||
490 | 38 | Q_PROPERTY(bool ignoreUnknownProperties MEMBER m_ignoreUnknownProperties) | ||
491 | 39 | |||
492 | 40 | public: | ||
493 | 41 | explicit UCStyleHints(QObject *parent = 0); | ||
494 | 42 | ~UCStyleHints(); | ||
495 | 43 | |||
496 | 44 | private Q_SLOTS: | ||
497 | 45 | void _q_applyStyleHints(); | ||
498 | 46 | |||
499 | 47 | protected: | ||
500 | 48 | void classBegin(); | ||
501 | 49 | void componentComplete(); | ||
502 | 50 | |||
503 | 51 | private: | ||
504 | 52 | class Expression { | ||
505 | 53 | public: | ||
506 | 54 | Expression(const QString &name, QQmlBinding::Identifier id, const QString& expr, | ||
507 | 55 | const QUrl &url, int line, int column) | ||
508 | 56 | : name(name), id(id), expression(expr), url(url), line(line), column(column) {} | ||
509 | 57 | QString name; | ||
510 | 58 | QQmlBinding::Identifier id; | ||
511 | 59 | QString expression; | ||
512 | 60 | QUrl url; | ||
513 | 61 | int line; | ||
514 | 62 | int column; | ||
515 | 63 | }; | ||
516 | 64 | |||
517 | 65 | bool m_decoded:1; | ||
518 | 66 | bool m_completed:1; | ||
519 | 67 | bool m_ignoreUnknownProperties:1; | ||
520 | 68 | QPointer<UCStyledItemBase> m_styledItem; | ||
521 | 69 | QList<Expression> m_expressions; | ||
522 | 70 | QList< QPair<QString, QVariant> > m_values; | ||
523 | 71 | QList< PropertyChange* > m_propertyBackup; | ||
524 | 72 | QQmlRefPointer<QQmlCompiledData> m_cdata; | ||
525 | 73 | |||
526 | 74 | friend class UCStyleHintsParser; | ||
527 | 75 | |||
528 | 76 | void propertyNotFound(const QString &styleName, const QString &property); | ||
529 | 77 | void decodeBinding(const QString &propertyPrefix, const QV4::CompiledData::Unit *qmlUnit, const QV4::CompiledData::Binding *binding); | ||
530 | 78 | }; | ||
531 | 79 | |||
532 | 80 | class UCStyleHintsParser : public QQmlCustomParser | ||
533 | 81 | { | ||
534 | 82 | public: | ||
535 | 83 | UCStyleHintsParser() : QQmlCustomParser(QQmlCustomParser::AcceptsSignalHandlers) {} | ||
536 | 84 | |||
537 | 85 | virtual void verifyBindings(const QV4::CompiledData::Unit *qmlUnit, const QList<const QV4::CompiledData::Binding *> &bindings); | ||
538 | 86 | virtual void applyBindings(QObject *obj, QQmlCompiledData *cdata, const QList<const QV4::CompiledData::Binding *> &bindings); | ||
539 | 87 | |||
540 | 88 | private: | ||
541 | 89 | void verifyProperty(const QV4::CompiledData::Unit *qmlUnit, const QV4::CompiledData::Binding *binding); | ||
542 | 90 | }; | ||
543 | 91 | |||
544 | 92 | #endif // UCSTYLEHINTS_H | ||
545 | 0 | 93 | ||
546 | === modified file 'modules/Ubuntu/Test/plugin/uctestcase.cpp' | |||
547 | --- modules/Ubuntu/Test/plugin/uctestcase.cpp 2014-11-25 09:58:33 +0000 | |||
548 | +++ modules/Ubuntu/Test/plugin/uctestcase.cpp 2015-06-02 15:25:00 +0000 | |||
549 | @@ -32,7 +32,7 @@ | |||
550 | 32 | * \ingroup ubuntu | 32 | * \ingroup ubuntu |
551 | 33 | * \brief UbuntuTestCase is the C++ pendant to the QML UbuntuTestCase. | 33 | * \brief UbuntuTestCase is the C++ pendant to the QML UbuntuTestCase. |
552 | 34 | */ | 34 | */ |
554 | 35 | UbuntuTestCase::UbuntuTestCase(const QString& file, QWindow* parent) : QQuickView(parent) | 35 | UbuntuTestCase::UbuntuTestCase(const QString& file, bool assertOnFailure, QWindow* parent) : QQuickView(parent) |
555 | 36 | { | 36 | { |
556 | 37 | QString modules(UBUNTU_QML_IMPORT_PATH); | 37 | QString modules(UBUNTU_QML_IMPORT_PATH); |
557 | 38 | Q_ASSERT(QDir(modules).exists()); | 38 | Q_ASSERT(QDir(modules).exists()); |
558 | @@ -45,10 +45,14 @@ | |||
559 | 45 | 45 | ||
560 | 46 | Q_ASSERT(!file.isEmpty()); | 46 | Q_ASSERT(!file.isEmpty()); |
561 | 47 | setSource(QUrl::fromLocalFile(file)); | 47 | setSource(QUrl::fromLocalFile(file)); |
566 | 48 | Q_ASSERT(status() == QQuickView::Ready); | 48 | if (assertOnFailure) { |
567 | 49 | Q_ASSERT(rootObject()); | 49 | Q_ASSERT(status() == QQuickView::Ready); |
568 | 50 | show(); | 50 | Q_ASSERT(rootObject()); |
569 | 51 | QTest::qWaitForWindowExposed(this); | 51 | } |
570 | 52 | if (rootObject()) { | ||
571 | 53 | show(); | ||
572 | 54 | QTest::qWaitForWindowExposed(this); | ||
573 | 55 | } | ||
574 | 52 | } | 56 | } |
575 | 53 | 57 | ||
576 | 54 | /*! | 58 | /*! |
577 | 55 | 59 | ||
578 | === modified file 'modules/Ubuntu/Test/plugin/uctestcase.h' | |||
579 | --- modules/Ubuntu/Test/plugin/uctestcase.h 2015-03-06 14:35:53 +0000 | |||
580 | +++ modules/Ubuntu/Test/plugin/uctestcase.h 2015-06-02 15:25:00 +0000 | |||
581 | @@ -28,7 +28,7 @@ | |||
582 | 28 | { | 28 | { |
583 | 29 | Q_OBJECT | 29 | Q_OBJECT |
584 | 30 | public: | 30 | public: |
586 | 31 | UbuntuTestCase(const QString& file, QWindow* parent = 0); | 31 | UbuntuTestCase(const QString& file, bool assertOnFailure = true, QWindow* parent = 0); |
587 | 32 | int warnings() const; | 32 | int warnings() const; |
588 | 33 | // getter | 33 | // getter |
589 | 34 | template<class T> | 34 | template<class T> |
590 | 35 | 35 | ||
591 | === added file 'tests/unit_x11/tst_subtheming/GroupPropertyBindingHints.qml' | |||
592 | --- tests/unit_x11/tst_subtheming/GroupPropertyBindingHints.qml 1970-01-01 00:00:00 +0000 | |||
593 | +++ tests/unit_x11/tst_subtheming/GroupPropertyBindingHints.qml 2015-06-02 15:25:00 +0000 | |||
594 | @@ -0,0 +1,32 @@ | |||
595 | 1 | /* | ||
596 | 2 | * Copyright 2015 Canonical Ltd. | ||
597 | 3 | * | ||
598 | 4 | * This program is free software; you can redistribute it and/or modify | ||
599 | 5 | * it under the terms of the GNU Lesser General Public License as published by | ||
600 | 6 | * the Free Software Foundation; version 3. | ||
601 | 7 | * | ||
602 | 8 | * This program is distributed in the hope that it will be useful, | ||
603 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
604 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
605 | 11 | * GNU Lesser General Public License for more details. | ||
606 | 12 | * | ||
607 | 13 | * You should have received a copy of the GNU Lesser General Public License | ||
608 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
609 | 15 | */ | ||
610 | 16 | |||
611 | 17 | import QtQuick 2.4 | ||
612 | 18 | import Ubuntu.Components 1.3 | ||
613 | 19 | |||
614 | 20 | Item { | ||
615 | 21 | width: units.gu(40) | ||
616 | 22 | height: units.gu(71) | ||
617 | 23 | |||
618 | 24 | HintedButton { | ||
619 | 25 | objectName: "Button" | ||
620 | 26 | id: button | ||
621 | 27 | gradient: UbuntuColors.greyGradient | ||
622 | 28 | StyleHints { | ||
623 | 29 | gradientProxy.topColor: button.pressed ? "tan" : "blue" | ||
624 | 30 | } | ||
625 | 31 | } | ||
626 | 32 | } | ||
627 | 0 | 33 | ||
628 | === added file 'tests/unit_x11/tst_subtheming/HintedButton.qml' | |||
629 | --- tests/unit_x11/tst_subtheming/HintedButton.qml 1970-01-01 00:00:00 +0000 | |||
630 | +++ tests/unit_x11/tst_subtheming/HintedButton.qml 2015-06-02 15:25:00 +0000 | |||
631 | @@ -0,0 +1,24 @@ | |||
632 | 1 | /* | ||
633 | 2 | * Copyright 2015 Canonical Ltd. | ||
634 | 3 | * | ||
635 | 4 | * This program is free software; you can redistribute it and/or modify | ||
636 | 5 | * it under the terms of the GNU Lesser General Public License as published by | ||
637 | 6 | * the Free Software Foundation; version 3. | ||
638 | 7 | * | ||
639 | 8 | * This program is distributed in the hope that it will be useful, | ||
640 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
641 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
642 | 11 | * GNU Lesser General Public License for more details. | ||
643 | 12 | * | ||
644 | 13 | * You should have received a copy of the GNU Lesser General Public License | ||
645 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
646 | 15 | */ | ||
647 | 16 | |||
648 | 17 | import QtQuick 2.4 | ||
649 | 18 | import Ubuntu.Components 1.3 | ||
650 | 19 | |||
651 | 20 | Button { | ||
652 | 21 | StyleHints { | ||
653 | 22 | minimumWidth: units.gu(20) | ||
654 | 23 | } | ||
655 | 24 | } | ||
656 | 0 | 25 | ||
657 | === added file 'tests/unit_x11/tst_subtheming/MoreStyleHints.qml' | |||
658 | --- tests/unit_x11/tst_subtheming/MoreStyleHints.qml 1970-01-01 00:00:00 +0000 | |||
659 | +++ tests/unit_x11/tst_subtheming/MoreStyleHints.qml 2015-06-02 15:25:00 +0000 | |||
660 | @@ -0,0 +1,34 @@ | |||
661 | 1 | /* | ||
662 | 2 | * Copyright 2015 Canonical Ltd. | ||
663 | 3 | * | ||
664 | 4 | * This program is free software; you can redistribute it and/or modify | ||
665 | 5 | * it under the terms of the GNU Lesser General Public License as published by | ||
666 | 6 | * the Free Software Foundation; version 3. | ||
667 | 7 | * | ||
668 | 8 | * This program is distributed in the hope that it will be useful, | ||
669 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
670 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
671 | 11 | * GNU Lesser General Public License for more details. | ||
672 | 12 | * | ||
673 | 13 | * You should have received a copy of the GNU Lesser General Public License | ||
674 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
675 | 15 | */ | ||
676 | 16 | |||
677 | 17 | import QtQuick 2.4 | ||
678 | 18 | import Ubuntu.Components 1.3 | ||
679 | 19 | |||
680 | 20 | Item { | ||
681 | 21 | width: units.gu(40) | ||
682 | 22 | height: units.gu(71) | ||
683 | 23 | |||
684 | 24 | Button { | ||
685 | 25 | objectName: "Button" | ||
686 | 26 | StyleHints { | ||
687 | 27 | minimumWidth: units.gu(20) | ||
688 | 28 | } | ||
689 | 29 | |||
690 | 30 | StyleHints { | ||
691 | 31 | defaultColor: "brown" | ||
692 | 32 | } | ||
693 | 33 | } | ||
694 | 34 | } | ||
695 | 0 | 35 | ||
696 | === added file 'tests/unit_x11/tst_subtheming/OverrideStyleHints.qml' | |||
697 | --- tests/unit_x11/tst_subtheming/OverrideStyleHints.qml 1970-01-01 00:00:00 +0000 | |||
698 | +++ tests/unit_x11/tst_subtheming/OverrideStyleHints.qml 2015-06-02 15:25:00 +0000 | |||
699 | @@ -0,0 +1,30 @@ | |||
700 | 1 | /* | ||
701 | 2 | * Copyright 2015 Canonical Ltd. | ||
702 | 3 | * | ||
703 | 4 | * This program is free software; you can redistribute it and/or modify | ||
704 | 5 | * it under the terms of the GNU Lesser General Public License as published by | ||
705 | 6 | * the Free Software Foundation; version 3. | ||
706 | 7 | * | ||
707 | 8 | * This program is distributed in the hope that it will be useful, | ||
708 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
709 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
710 | 11 | * GNU Lesser General Public License for more details. | ||
711 | 12 | * | ||
712 | 13 | * You should have received a copy of the GNU Lesser General Public License | ||
713 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
714 | 15 | */ | ||
715 | 16 | |||
716 | 17 | import QtQuick 2.4 | ||
717 | 18 | import Ubuntu.Components 1.3 | ||
718 | 19 | |||
719 | 20 | Item { | ||
720 | 21 | width: units.gu(40) | ||
721 | 22 | height: units.gu(71) | ||
722 | 23 | |||
723 | 24 | HintedButton { | ||
724 | 25 | objectName: "Button" | ||
725 | 26 | StyleHints { | ||
726 | 27 | minimumWidth: 5 | ||
727 | 28 | } | ||
728 | 29 | } | ||
729 | 30 | } | ||
730 | 0 | 31 | ||
731 | === added file 'tests/unit_x11/tst_subtheming/PropertyBindingHints.qml' | |||
732 | --- tests/unit_x11/tst_subtheming/PropertyBindingHints.qml 1970-01-01 00:00:00 +0000 | |||
733 | +++ tests/unit_x11/tst_subtheming/PropertyBindingHints.qml 2015-06-02 15:25:00 +0000 | |||
734 | @@ -0,0 +1,31 @@ | |||
735 | 1 | /* | ||
736 | 2 | * Copyright 2015 Canonical Ltd. | ||
737 | 3 | * | ||
738 | 4 | * This program is free software; you can redistribute it and/or modify | ||
739 | 5 | * it under the terms of the GNU Lesser General Public License as published by | ||
740 | 6 | * the Free Software Foundation; version 3. | ||
741 | 7 | * | ||
742 | 8 | * This program is distributed in the hope that it will be useful, | ||
743 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
744 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
745 | 11 | * GNU Lesser General Public License for more details. | ||
746 | 12 | * | ||
747 | 13 | * You should have received a copy of the GNU Lesser General Public License | ||
748 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
749 | 15 | */ | ||
750 | 16 | |||
751 | 17 | import QtQuick 2.4 | ||
752 | 18 | import Ubuntu.Components 1.3 | ||
753 | 19 | |||
754 | 20 | Item { | ||
755 | 21 | width: units.gu(40) | ||
756 | 22 | height: units.gu(71) | ||
757 | 23 | |||
758 | 24 | Button { | ||
759 | 25 | objectName: "Button" | ||
760 | 26 | id: button | ||
761 | 27 | StyleHints { | ||
762 | 28 | defaultColor: button.pressed ? "tan" : "blue" | ||
763 | 29 | } | ||
764 | 30 | } | ||
765 | 31 | } | ||
766 | 0 | 32 | ||
767 | === added file 'tests/unit_x11/tst_subtheming/SimplePropertyHints.qml' | |||
768 | --- tests/unit_x11/tst_subtheming/SimplePropertyHints.qml 1970-01-01 00:00:00 +0000 | |||
769 | +++ tests/unit_x11/tst_subtheming/SimplePropertyHints.qml 2015-06-02 15:25:00 +0000 | |||
770 | @@ -0,0 +1,30 @@ | |||
771 | 1 | /* | ||
772 | 2 | * Copyright 2015 Canonical Ltd. | ||
773 | 3 | * | ||
774 | 4 | * This program is free software; you can redistribute it and/or modify | ||
775 | 5 | * it under the terms of the GNU Lesser General Public License as published by | ||
776 | 6 | * the Free Software Foundation; version 3. | ||
777 | 7 | * | ||
778 | 8 | * This program is distributed in the hope that it will be useful, | ||
779 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
780 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
781 | 11 | * GNU Lesser General Public License for more details. | ||
782 | 12 | * | ||
783 | 13 | * You should have received a copy of the GNU Lesser General Public License | ||
784 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
785 | 15 | */ | ||
786 | 16 | |||
787 | 17 | import QtQuick 2.4 | ||
788 | 18 | import Ubuntu.Components 1.3 | ||
789 | 19 | |||
790 | 20 | Item { | ||
791 | 21 | width: units.gu(40) | ||
792 | 22 | height: units.gu(71) | ||
793 | 23 | |||
794 | 24 | Button { | ||
795 | 25 | objectName: "Button" | ||
796 | 26 | StyleHints { | ||
797 | 27 | defaultColor: "blue" | ||
798 | 28 | } | ||
799 | 29 | } | ||
800 | 30 | } | ||
801 | 0 | 31 | ||
802 | === added file 'tests/unit_x11/tst_subtheming/StyleHintsElsewhere.qml' | |||
803 | --- tests/unit_x11/tst_subtheming/StyleHintsElsewhere.qml 1970-01-01 00:00:00 +0000 | |||
804 | +++ tests/unit_x11/tst_subtheming/StyleHintsElsewhere.qml 2015-06-02 15:25:00 +0000 | |||
805 | @@ -0,0 +1,27 @@ | |||
806 | 1 | /* | ||
807 | 2 | * Copyright 2015 Canonical Ltd. | ||
808 | 3 | * | ||
809 | 4 | * This program is free software; you can redistribute it and/or modify | ||
810 | 5 | * it under the terms of the GNU Lesser General Public License as published by | ||
811 | 6 | * the Free Software Foundation; version 3. | ||
812 | 7 | * | ||
813 | 8 | * This program is distributed in the hope that it will be useful, | ||
814 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
815 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
816 | 11 | * GNU Lesser General Public License for more details. | ||
817 | 12 | * | ||
818 | 13 | * You should have received a copy of the GNU Lesser General Public License | ||
819 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
820 | 15 | */ | ||
821 | 16 | |||
822 | 17 | import QtQuick 2.4 | ||
823 | 18 | import Ubuntu.Components 1.3 | ||
824 | 19 | |||
825 | 20 | Item { | ||
826 | 21 | width: units.gu(40) | ||
827 | 22 | height: units.gu(71) | ||
828 | 23 | |||
829 | 24 | StyleHints { | ||
830 | 25 | anyProperty: true | ||
831 | 26 | } | ||
832 | 27 | } | ||
833 | 0 | 28 | ||
834 | === added file 'tests/unit_x11/tst_subtheming/StyleHintsInvalidProperty.qml' | |||
835 | --- tests/unit_x11/tst_subtheming/StyleHintsInvalidProperty.qml 1970-01-01 00:00:00 +0000 | |||
836 | +++ tests/unit_x11/tst_subtheming/StyleHintsInvalidProperty.qml 2015-06-02 15:25:00 +0000 | |||
837 | @@ -0,0 +1,30 @@ | |||
838 | 1 | /* | ||
839 | 2 | * Copyright 2015 Canonical Ltd. | ||
840 | 3 | * | ||
841 | 4 | * This program is free software; you can redistribute it and/or modify | ||
842 | 5 | * it under the terms of the GNU Lesser General Public License as published by | ||
843 | 6 | * the Free Software Foundation; version 3. | ||
844 | 7 | * | ||
845 | 8 | * This program is distributed in the hope that it will be useful, | ||
846 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
847 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
848 | 11 | * GNU Lesser General Public License for more details. | ||
849 | 12 | * | ||
850 | 13 | * You should have received a copy of the GNU Lesser General Public License | ||
851 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
852 | 15 | */ | ||
853 | 16 | |||
854 | 17 | import QtQuick 2.4 | ||
855 | 18 | import Ubuntu.Components 1.3 | ||
856 | 19 | |||
857 | 20 | Item { | ||
858 | 21 | width: units.gu(40) | ||
859 | 22 | height: units.gu(71) | ||
860 | 23 | |||
861 | 24 | Button { | ||
862 | 25 | StyleHints { | ||
863 | 26 | ignoreUnknownProperties: false | ||
864 | 27 | invalidProperty: 10 | ||
865 | 28 | } | ||
866 | 29 | } | ||
867 | 30 | } | ||
868 | 0 | 31 | ||
869 | === added file 'tests/unit_x11/tst_subtheming/StyleHintsWithObject.qml' | |||
870 | --- tests/unit_x11/tst_subtheming/StyleHintsWithObject.qml 1970-01-01 00:00:00 +0000 | |||
871 | +++ tests/unit_x11/tst_subtheming/StyleHintsWithObject.qml 2015-06-02 15:25:00 +0000 | |||
872 | @@ -0,0 +1,29 @@ | |||
873 | 1 | /* | ||
874 | 2 | * Copyright 2015 Canonical Ltd. | ||
875 | 3 | * | ||
876 | 4 | * This program is free software; you can redistribute it and/or modify | ||
877 | 5 | * it under the terms of the GNU Lesser General Public License as published by | ||
878 | 6 | * the Free Software Foundation; version 3. | ||
879 | 7 | * | ||
880 | 8 | * This program is distributed in the hope that it will be useful, | ||
881 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
882 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
883 | 11 | * GNU Lesser General Public License for more details. | ||
884 | 12 | * | ||
885 | 13 | * You should have received a copy of the GNU Lesser General Public License | ||
886 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
887 | 15 | */ | ||
888 | 16 | |||
889 | 17 | import QtQuick 2.4 | ||
890 | 18 | import Ubuntu.Components 1.3 | ||
891 | 19 | |||
892 | 20 | Item { | ||
893 | 21 | width: units.gu(40) | ||
894 | 22 | height: units.gu(71) | ||
895 | 23 | |||
896 | 24 | Button { | ||
897 | 25 | StyleHints { | ||
898 | 26 | anyProperty: QtObject{} | ||
899 | 27 | } | ||
900 | 28 | } | ||
901 | 29 | } | ||
902 | 0 | 30 | ||
903 | === added file 'tests/unit_x11/tst_subtheming/StyleHintsWithSignal.qml' | |||
904 | --- tests/unit_x11/tst_subtheming/StyleHintsWithSignal.qml 1970-01-01 00:00:00 +0000 | |||
905 | +++ tests/unit_x11/tst_subtheming/StyleHintsWithSignal.qml 2015-06-02 15:25:00 +0000 | |||
906 | @@ -0,0 +1,29 @@ | |||
907 | 1 | /* | ||
908 | 2 | * Copyright 2015 Canonical Ltd. | ||
909 | 3 | * | ||
910 | 4 | * This program is free software; you can redistribute it and/or modify | ||
911 | 5 | * it under the terms of the GNU Lesser General Public License as published by | ||
912 | 6 | * the Free Software Foundation; version 3. | ||
913 | 7 | * | ||
914 | 8 | * This program is distributed in the hope that it will be useful, | ||
915 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
916 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
917 | 11 | * GNU Lesser General Public License for more details. | ||
918 | 12 | * | ||
919 | 13 | * You should have received a copy of the GNU Lesser General Public License | ||
920 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
921 | 15 | */ | ||
922 | 16 | |||
923 | 17 | import QtQuick 2.4 | ||
924 | 18 | import Ubuntu.Components 1.3 | ||
925 | 19 | |||
926 | 20 | Item { | ||
927 | 21 | width: units.gu(40) | ||
928 | 22 | height: units.gu(71) | ||
929 | 23 | |||
930 | 24 | Button { | ||
931 | 25 | StyleHints { | ||
932 | 26 | onDefaultColorChanged: {} | ||
933 | 27 | } | ||
934 | 28 | } | ||
935 | 29 | } | ||
936 | 0 | 30 | ||
937 | === modified file 'tests/unit_x11/tst_subtheming/tst_subtheming.cpp' | |||
938 | --- tests/unit_x11/tst_subtheming/tst_subtheming.cpp 2015-05-26 15:05:46 +0000 | |||
939 | +++ tests/unit_x11/tst_subtheming/tst_subtheming.cpp 2015-06-02 15:25:00 +0000 | |||
940 | @@ -25,13 +25,14 @@ | |||
941 | 25 | #include "uctestcase.h" | 25 | #include "uctestcase.h" |
942 | 26 | #include "ucstyleditembase_p.h" | 26 | #include "ucstyleditembase_p.h" |
943 | 27 | #include "ucnamespace.h" | 27 | #include "ucnamespace.h" |
944 | 28 | #include "ucunits.h" | ||
945 | 28 | 29 | ||
946 | 29 | class ThemeTestCase : public UbuntuTestCase | 30 | class ThemeTestCase : public UbuntuTestCase |
947 | 30 | { | 31 | { |
948 | 31 | Q_OBJECT | 32 | Q_OBJECT |
949 | 32 | public: | 33 | public: |
952 | 33 | ThemeTestCase(const QString& file, QWindow* parent = 0) | 34 | ThemeTestCase(const QString& file, bool assertOnFailure = true, QWindow* parent = 0) |
953 | 34 | : UbuntuTestCase(file, parent) | 35 | : UbuntuTestCase(file, assertOnFailure, parent) |
954 | 35 | { | 36 | { |
955 | 36 | } | 37 | } |
956 | 37 | 38 | ||
957 | @@ -741,6 +742,101 @@ | |||
958 | 741 | QScopedPointer<ThemeTestCase> view(new ThemeTestCase("DeprecatedTheme.qml")); | 742 | QScopedPointer<ThemeTestCase> view(new ThemeTestCase("DeprecatedTheme.qml")); |
959 | 742 | view->rootObject()->setProperty("styleName", "OptionSelectorStyle.qml"); | 743 | view->rootObject()->setProperty("styleName", "OptionSelectorStyle.qml"); |
960 | 743 | } | 744 | } |
961 | 745 | |||
962 | 746 | void test_stylehints_errors_data() | ||
963 | 747 | { | ||
964 | 748 | QTest::addColumn<QString>("document"); | ||
965 | 749 | QTest::addColumn<int>("row"); | ||
966 | 750 | QTest::addColumn<int>("col"); | ||
967 | 751 | QTest::addColumn<QString>("xfail"); | ||
968 | 752 | |||
969 | 753 | QTest::newRow("No signals") | ||
970 | 754 | << "StyleHintsWithSignal.qml" << 26 << 13 << "Signal properties are not supported. \n" \ | ||
971 | 755 | " onDefaultColorChanged: {} \n" \ | ||
972 | 756 | " ^"; | ||
973 | 757 | QTest::newRow("No embedded objects") | ||
974 | 758 | << "StyleHintsWithObject.qml" << 26 << 26 << "StyleHints does not support creating state-specific objects. \n" \ | ||
975 | 759 | " anyProperty: QtObject{} \n" \ | ||
976 | 760 | " ^"; | ||
977 | 761 | QTest::newRow("StyleHints declared elsewhere") | ||
978 | 762 | << "StyleHintsElsewhere.qml" << 24 << 5 << "QML StyleHints: StyleHints must be declared in a StyledItem or a derivate of it."; | ||
979 | 763 | QTest::newRow("Invalid property") | ||
980 | 764 | << "StyleHintsInvalidProperty.qml" << 25 << 9 << "QML StyleHints: Style 'ButtonStyle' has no property called 'invalidProperty'."; | ||
981 | 765 | } | ||
982 | 766 | void test_stylehints_errors() | ||
983 | 767 | { | ||
984 | 768 | QFETCH(QString, document); | ||
985 | 769 | QFETCH(int, row); | ||
986 | 770 | QFETCH(int, col); | ||
987 | 771 | QFETCH(QString, xfail); | ||
988 | 772 | |||
989 | 773 | if (!xfail.isEmpty()) { | ||
990 | 774 | ThemeTestCase::ignoreWarning(document, row, col, xfail); | ||
991 | 775 | } | ||
992 | 776 | QScopedPointer<ThemeTestCase> view(new ThemeTestCase(document, false)); | ||
993 | 777 | } | ||
994 | 778 | |||
995 | 779 | void test_stylehints_simple_property() | ||
996 | 780 | { | ||
997 | 781 | QScopedPointer<ThemeTestCase> view(new ThemeTestCase("SimplePropertyHints.qml")); | ||
998 | 782 | QQuickItem *button = view->findItem<QQuickItem*>("Button"); | ||
999 | 783 | QColor color = button->property("color").value<QColor>(); | ||
1000 | 784 | QCOMPARE(color, QColor("blue")); | ||
1001 | 785 | } | ||
1002 | 786 | |||
1003 | 787 | void test_stylehints_bindings() | ||
1004 | 788 | { | ||
1005 | 789 | QScopedPointer<ThemeTestCase> view(new ThemeTestCase("PropertyBindingHints.qml")); | ||
1006 | 790 | QQuickItem *button = view->findItem<QQuickItem*>("Button"); | ||
1007 | 791 | QColor color = button->property("color").value<QColor>(); | ||
1008 | 792 | QCOMPARE(color, QColor("blue")); | ||
1009 | 793 | // press the button | ||
1010 | 794 | QPointF pressPt(button->width()/2, button->height()/2); | ||
1011 | 795 | pressPt = view->rootObject()->mapFromItem(button, pressPt); | ||
1012 | 796 | QTest::mousePress(view.data(), Qt::LeftButton, 0, pressPt.toPoint()); | ||
1013 | 797 | color = button->property("color").value<QColor>(); | ||
1014 | 798 | QCOMPARE(color, QColor("tan")); | ||
1015 | 799 | QTest::mouseRelease(view.data(), Qt::LeftButton, 0, pressPt.toPoint()); | ||
1016 | 800 | } | ||
1017 | 801 | |||
1018 | 802 | void test_stylehints_multiple_data() | ||
1019 | 803 | { | ||
1020 | 804 | QTest::addColumn<QString>("document"); | ||
1021 | 805 | QTest::addColumn<QString>("colorProperty"); | ||
1022 | 806 | QTest::addColumn<QColor>("colorReleased"); | ||
1023 | 807 | QTest::addColumn<QColor>("colorPressed"); | ||
1024 | 808 | QTest::addColumn<QString>("widthProperty"); | ||
1025 | 809 | QTest::addColumn<float>("width"); | ||
1026 | 810 | |||
1027 | 811 | QTest::newRow("Same document") | ||
1028 | 812 | << "MoreStyleHints.qml" << "defaultColor" << QColor("brown") << QColor("brown") << "minimumWidth" << UCUnits::instance().gu(20); | ||
1029 | 813 | QTest::newRow("Different document") | ||
1030 | 814 | << "GroupPropertyBindingHints.qml" << "gradientProxy.topColor" << QColor("blue") << QColor("tan") << "minimumWidth" << UCUnits::instance().gu(20); | ||
1031 | 815 | } | ||
1032 | 816 | void test_stylehints_multiple() | ||
1033 | 817 | { | ||
1034 | 818 | QFETCH(QString, document); | ||
1035 | 819 | QFETCH(QString, colorProperty); | ||
1036 | 820 | QFETCH(QColor, colorReleased); | ||
1037 | 821 | QFETCH(QColor, colorPressed); | ||
1038 | 822 | QFETCH(QString, widthProperty); | ||
1039 | 823 | QFETCH(float, width); | ||
1040 | 824 | |||
1041 | 825 | QScopedPointer<ThemeTestCase> view(new ThemeTestCase(document)); | ||
1042 | 826 | UCStyledItemBase *button = view->findItem<UCStyledItemBase*>("Button"); | ||
1043 | 827 | QQuickItem *styleItem = UCStyledItemBasePrivate::get(button)->styleItem; | ||
1044 | 828 | QVERIFY(styleItem); | ||
1045 | 829 | QQmlProperty qmlProperty(styleItem, colorProperty, qmlContext(styleItem)); | ||
1046 | 830 | QCOMPARE(qmlProperty.read().value<QColor>(), colorReleased); | ||
1047 | 831 | QCOMPARE(styleItem->property(widthProperty.toUtf8()).toReal(), width); | ||
1048 | 832 | |||
1049 | 833 | QPointF pressPt(button->width()/2, button->height()/2); | ||
1050 | 834 | pressPt = view->rootObject()->mapFromItem(button, pressPt); | ||
1051 | 835 | QTest::mousePress(view.data(), Qt::LeftButton, 0, pressPt.toPoint()); | ||
1052 | 836 | QColor pressedColor = qmlProperty.read().value<QColor>(); | ||
1053 | 837 | QTest::mouseRelease(view.data(), Qt::LeftButton, 0, pressPt.toPoint()); | ||
1054 | 838 | QCOMPARE(pressedColor, colorPressed); | ||
1055 | 839 | } | ||
1056 | 744 | }; | 840 | }; |
1057 | 745 | 841 | ||
1058 | 746 | QTEST_MAIN(tst_Subtheming) | 842 | QTEST_MAIN(tst_Subtheming) |
1059 | 747 | 843 | ||
1060 | === modified file 'tests/unit_x11/tst_subtheming/tst_subtheming.pro' | |||
1061 | --- tests/unit_x11/tst_subtheming/tst_subtheming.pro 2015-05-22 13:54:38 +0000 | |||
1062 | +++ tests/unit_x11/tst_subtheming/tst_subtheming.pro 2015-06-02 15:25:00 +0000 | |||
1063 | @@ -33,6 +33,16 @@ | |||
1064 | 33 | DeprecatedTheme.qml \ | 33 | DeprecatedTheme.qml \ |
1065 | 34 | StyledItemAppThemeVersioned.qml \ | 34 | StyledItemAppThemeVersioned.qml \ |
1066 | 35 | StyleOverride.qml \ | 35 | StyleOverride.qml \ |
1068 | 36 | StyleKept.qml | 36 | StyleKept.qml \ |
1069 | 37 | SimplePropertyHints.qml \ | ||
1070 | 38 | StyleHintsWithSignal.qml \ | ||
1071 | 39 | StyleHintsWithObject.qml \ | ||
1072 | 40 | StyleHintsElsewhere.qml \ | ||
1073 | 41 | StyleHintsInvalidProperty.qml \ | ||
1074 | 42 | PropertyBindingHints.qml \ | ||
1075 | 43 | MoreStyleHints.qml \ | ||
1076 | 44 | GroupPropertyBindingHints.qml \ | ||
1077 | 45 | OverrideStyleHints.qml \ | ||
1078 | 46 | HintedButton.qml | ||
1079 | 37 | 47 | ||
1080 | 38 | 48 |
FAILED: Continuous integration, rev:1531 jenkins. qa.ubuntu. com/job/ ubuntu- sdk-team- ubuntu- ui-toolkit- staging- ci/1832/ jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- vivid-touch/ 3044/console jenkins. qa.ubuntu. com/job/ ubuntu- sdk-team- ubuntu- ui-toolkit- staging- vivid-amd64- ci/560/ console jenkins. qa.ubuntu. com/job/ ubuntu- sdk-team- ubuntu- ui-toolkit- staging- vivid-armhf- ci/562/ console jenkins. qa.ubuntu. com/job/ ubuntu- sdk-team- ubuntu- ui-toolkit- staging- vivid-i386- ci/559/ console jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- vivid-armhf/ 3042/console
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/ubuntu- sdk-team- ubuntu- ui-toolkit- staging- ci/1832/ rebuild
http://