Merge lp:~canonical-platform-qa/ubuntu-ui-toolkit/fix1429163-nopy2 into lp:ubuntu-ui-toolkit

Proposed by Leo Arias
Status: Superseded
Proposed branch: lp:~canonical-platform-qa/ubuntu-ui-toolkit/fix1429163-nopy2
Merge into: lp:ubuntu-ui-toolkit
Diff against target: 7506 lines (+3595/-1319)
124 files modified
components.api (+23/-1)
debian/control (+0/-12)
debian/rules (+1/-0)
debian/ubuntu-ui-toolkit-autopilot.install (+0/-1)
examples/ubuntu-ui-toolkit-gallery/WebLink.qml (+5/-0)
modules/Ubuntu/Components/AppHeader.qml (+104/-15)
modules/Ubuntu/Components/MainView.qml (+2/-1)
modules/Ubuntu/Components/MainView12.qml (+18/-8)
modules/Ubuntu/Components/Page10.qml (+3/-31)
modules/Ubuntu/Components/Page11.qml (+5/-3)
modules/Ubuntu/Components/Page13.qml (+84/-0)
modules/Ubuntu/Components/PageHeadConfiguration.qdoc (+202/-0)
modules/Ubuntu/Components/PageHeadConfiguration11.qml (+3/-155)
modules/Ubuntu/Components/PageHeadConfiguration13.qml (+30/-0)
modules/Ubuntu/Components/StyledItem.qml (+1/-1)
modules/Ubuntu/Components/Styles/PageHeadStyle.qml (+3/-3)
modules/Ubuntu/Components/Tab.qml (+20/-2)
modules/Ubuntu/Components/Tabs.qml (+4/-1)
modules/Ubuntu/Components/Themes/Ambiance/HeadDividerStyle.qml (+3/-0)
modules/Ubuntu/Components/Themes/Ambiance/OverflowPanel.qml (+119/-1)
modules/Ubuntu/Components/Themes/Ambiance/PageHeadButton.qml (+1/-1)
modules/Ubuntu/Components/Themes/Ambiance/PageHeadStyle.qml (+51/-187)
modules/Ubuntu/Components/pageUtils.js (+47/-0)
modules/Ubuntu/Components/plugin/plugin.cpp (+10/-3)
modules/Ubuntu/Components/plugin/plugin.pro (+6/-4)
modules/Ubuntu/Components/plugin/shaders/shape.vert (+2/-2)
modules/Ubuntu/Components/plugin/shaders/shapeoverlay.vert (+2/-2)
modules/Ubuntu/Components/plugin/ucdefaulttheme.cpp (+8/-8)
modules/Ubuntu/Components/plugin/ucdefaulttheme.h (+6/-6)
modules/Ubuntu/Components/plugin/ucdeprecatedtheme.cpp (+122/-0)
modules/Ubuntu/Components/plugin/ucdeprecatedtheme.h (+53/-0)
modules/Ubuntu/Components/plugin/uclistitem.cpp (+7/-4)
modules/Ubuntu/Components/plugin/ucstyleditembase.cpp (+213/-2)
modules/Ubuntu/Components/plugin/ucstyleditembase.h (+7/-1)
modules/Ubuntu/Components/plugin/ucstyleditembase_p.h (+19/-1)
modules/Ubuntu/Components/plugin/uctheme.cpp (+229/-132)
modules/Ubuntu/Components/plugin/uctheme.h (+39/-19)
modules/Ubuntu/Components/qmldir (+5/-1)
modules/Ubuntu/Test/UbuntuTestCase.qml (+20/-2)
modules/Ubuntu/Test/plugin/uctestcase.h (+0/-1)
push_to_phone.sh (+0/-1)
tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_common.py (+2/-2)
tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_header.py (+5/-2)
tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_mainview.py (+2/-2)
tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_textfield.py (+1/-1)
tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/popups.py (+0/-3)
tests/autopilot/ubuntuuitoolkit/base.py (+2/-2)
tests/autopilot/ubuntuuitoolkit/fixture_setup.py (+10/-10)
tests/autopilot/ubuntuuitoolkit/tests/__init__.py (+3/-3)
tests/autopilot/ubuntuuitoolkit/tests/components/test_header.py (+2/-2)
tests/autopilot/ubuntuuitoolkit/tests/components/test_popover.py (+1/-4)
tests/autopilot/ubuntuuitoolkit/tests/components/test_textinput.py (+3/-3)
tests/autopilot/ubuntuuitoolkit/tests/components/test_units.py (+61/-0)
tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_checkbox.py (+2/-5)
tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_common.py (+2/-5)
tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_date_picker.py (+2/-2)
tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_dialog.py (+1/-4)
tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_flickable.py (+2/-5)
tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_header.py (+4/-4)
tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_listitem.py (+1/-1)
tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_listitems.py (+3/-6)
tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_main_view.py (+2/-5)
tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_optionselector.py (+3/-3)
tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_popups.py (+1/-1)
tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_pull_to_refresh.py (+2/-2)
tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_qquicklistview.py (+4/-7)
tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_tabs.py (+2/-5)
tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_textarea.py (+2/-5)
tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_textfield.py (+2/-5)
tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_toolbar.py (+2/-5)
tests/autopilot/ubuntuuitoolkit/tests/gallery/__init__.py (+3/-3)
tests/autopilot/ubuntuuitoolkit/tests/gallery/test_buttons.py (+1/-1)
tests/autopilot/ubuntuuitoolkit/tests/gallery/test_optionselector.py (+2/-2)
tests/autopilot/ubuntuuitoolkit/tests/gallery/test_scrollbar.py (+2/-2)
tests/autopilot/ubuntuuitoolkit/tests/gallery/test_textinput.py (+3/-3)
tests/autopilot/ubuntuuitoolkit/tests/gallery/test_toggles.py (+3/-3)
tests/autopilot/ubuntuuitoolkit/tests/test_fixture_setup.py (+4/-9)
tests/autopilot/ubuntuuitoolkit/tests/test_launcher.py (+1/-7)
tests/autopilot/ubuntuuitoolkit/tests/test_ubuntu_scenarios.py (+2/-5)
tests/autopilot/ubuntuuitoolkit/units.py (+38/-0)
tests/license/checklicense.sh (+16/-21)
tests/resources/header/actions.qml (+0/-47)
tests/resources/header/backButton.qml (+0/-59)
tests/resources/header/lockedToolbar.deprecated.qml (+0/-52)
tests/resources/header/sections.qml (+0/-41)
tests/resources/navigation/simpleTabs.qml (+0/-60)
tests/resources/subtheming/Simple.qml (+53/-0)
tests/uitk_test_plan.sh (+3/-1)
tests/unit/tst_components/tst_styleditem13.qml (+35/-0)
tests/unit/tst_performance/StyledItemOldTheming.qml (+72/-0)
tests/unit/tst_performance/Styling.qml (+76/-0)
tests/unit/tst_performance/tst_performance.cpp (+33/-4)
tests/unit/tst_performance/tst_performance.pro (+3/-1)
tests/unit_x11/tst_components/tst_app_theming.qml (+54/-0)
tests/unit_x11/tst_components/tst_components.pro (+2/-2)
tests/unit_x11/tst_components/tst_header_back_action.qml (+64/-21)
tests/unit_x11/tst_components/tst_header_contents_width.qml (+5/-10)
tests/unit_x11/tst_components/tst_header_sections.qml (+65/-56)
tests/unit_x11/tst_components/tst_header_visible.qml (+288/-0)
tests/unit_x11/tst_components/tst_page11.qml (+1/-1)
tests/unit_x11/tst_components/tst_page13.qml (+126/-0)
tests/unit_x11/tst_components/tst_pagestack.new_header.qml (+32/-40)
tests/unit_x11/tst_deprecated_theme_engine/Parent.qml (+14/-4)
tests/unit_x11/tst_deprecated_theme_engine/SimpleItem.qml (+20/-0)
tests/unit_x11/tst_deprecated_theme_engine/themes/CustomTheme/TestStyle.qml (+0/-1)
tests/unit_x11/tst_deprecated_theme_engine/themes/TestModule/TestTheme/TestStyle.qml (+0/-1)
tests/unit_x11/tst_deprecated_theme_engine/tst_deprecated_theme_engine.cpp (+113/-113)
tests/unit_x11/tst_deprecated_theme_engine/tst_deprecated_theme_engine.pro (+9/-2)
tests/unit_x11/tst_subtheming/DifferentThemes.qml (+46/-0)
tests/unit_x11/tst_subtheming/DynamicAssignment.qml (+38/-0)
tests/unit_x11/tst_subtheming/ParentChanges.qml (+37/-0)
tests/unit_x11/tst_subtheming/SimpleItem.qml (+30/-0)
tests/unit_x11/tst_subtheming/TestMain.qml (+39/-0)
tests/unit_x11/tst_subtheming/TestModule/TestTheme/TestStyle.qml (+20/-0)
tests/unit_x11/tst_subtheming/TestStyleChange.qml (+69/-0)
tests/unit_x11/tst_subtheming/themes/CustomTheme/TestStyle.qml (+22/-0)
tests/unit_x11/tst_subtheming/themes/CustomTheme/parent_theme (+1/-0)
tests/unit_x11/tst_subtheming/themes/TestModule/TestTheme/TestStyle.qml (+22/-0)
tests/unit_x11/tst_subtheming/themes/TestModule/TestTheme/parent_theme (+1/-0)
tests/unit_x11/tst_subtheming/themes/TestModule/TestTheme/qmldir (+2/-0)
tests/unit_x11/tst_subtheming/tst_subtheming.cpp (+496/-0)
tests/unit_x11/tst_subtheming/tst_subtheming.pro (+20/-0)
tests/unit_x11/tst_theme_engine/TestApp.qml (+0/-29)
tests/unit_x11/unit_x11.pro (+3/-2)
To merge this branch: bzr merge lp:~canonical-platform-qa/ubuntu-ui-toolkit/fix1429163-nopy2
Reviewer Review Type Date Requested Status
Ubuntu SDK team Pending
Review via email: mp+256219@code.launchpad.net

This proposal has been superseded by a proposal from 2015-04-14.

Commit message

Removed python2 support from autopilot tests and helpers.

To post a comment you must log in.
1476. By Leo Arias

Remove py2 from the makefiles.

Unmerged revisions

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-03-10 13:58:52 +0000
3+++ components.api 2015-04-14 21:04:03 +0000
4@@ -246,7 +246,12 @@
5 property Flickable flickable
6 property list<Action> actions
7 Page 1.1
8-Page10
9+Toolkit10.Page
10+ readonly property PageHeadConfiguration head
11+Page 1.3
12+PageTreeNode
13+ property string title
14+ property Flickable flickable
15 readonly property PageHeadConfiguration head
16 PageHeadConfiguration 1.1
17 Object
18@@ -256,6 +261,10 @@
19 property string preset
20 readonly property PageHeadSections sections
21 property color foregroundColor
22+PageHeadConfiguration 1.3
23+Toolkit12.PageHeadConfiguration
24+ property bool locked
25+ property bool visible
26 PageHeadSections 1.1
27 QtObject
28 property bool enabled
29@@ -692,6 +701,7 @@
30 function tryCompareFunction(func, expectedResult, timeout)
31 function typeString(string)
32 function warningFormat(line, column, message)
33+ function waitForHeaderAnimation(mainView)
34 plugins.qmltypes
35 name: "FilterBehavior"
36 prototype: "QObject"
37@@ -1045,6 +1055,8 @@
38 prototype: "QQuickItem"
39 exports: [
40 Property { name: "activeFocusOnPress"; revision: 1; type: "bool" }
41+ Property { name: "theme"; revision: 2; type: "UCTheme"; isPointer: true }
42+ Signal { name: "themeChanged"; revision: 2 }
43 Method {
44 name: "requestFocus"
45 Parameter { name: "reason"; type: "Qt::FocusReason" }
46@@ -1057,6 +1069,16 @@
47 Property { name: "from"; type: "QPointF"; isReadonly: true }
48 Property { name: "content"; type: "QPointF" }
49 Property { name: "status"; type: "Status"; isReadonly: true }
50+ name: "UCTheme"
51+ prototype: "QObject"
52+ exports: ["ThemeSettings 1.3"]
53+ Property { name: "parentTheme"; type: "UCTheme"; isReadonly: true; isPointer: true }
54+ Property { name: "name"; type: "string" }
55+ Property { name: "palette"; type: "QObject"; isReadonly: true; isPointer: true }
56+ Method {
57+ name: "createStyleComponent"
58+ Parameter { name: "styleName"; type: "string" }
59+ Parameter { name: "parent"; type: "QObject"; isPointer: true }
60 name: "UCUbuntuAnimation"
61 prototype: "QObject"
62 exports: ["UbuntuAnimation 0.1", "UbuntuAnimation 1.0"]
63
64=== modified file 'debian/control'
65--- debian/control 2015-03-24 10:24:18 +0000
66+++ debian/control 2015-04-14 21:04:03 +0000
67@@ -7,13 +7,10 @@
68 libgles2-mesa-dev,
69 libglib2.0-dev,
70 python3:any,
71- python:any,
72 qml-module-qtgraphicaleffects | libqt5qml-graphicaleffects,
73- qt5-default,
74 qtbase5-dev,
75 qtbase5-private-dev,
76 qttools5-dev-tools,
77- qtbase5-dev-tools,
78 libqt5sql5-sqlite,
79 qtdeclarative5-dev-tools,
80 qtdeclarative5-private-dev,
81@@ -34,7 +31,6 @@
82 qtmultimedia5-doc-html,
83 unity-action-doc,
84 devscripts,
85- libqt5organizer5,
86 qtpim5-dev,
87 language-pack-en-base,
88 libdbus-1-dev,
89@@ -47,7 +43,6 @@
90 locales,
91 suru-icon-theme,
92 uuid-runtime,
93- python-autopilot (>= 1.4),
94 python3-sphinx,
95 Standards-Version: 3.9.4
96 Homepage: https://launchpad.net/ubuntu-ui-toolkit
97@@ -144,13 +139,6 @@
98 dpkg-dev,
99 libqt5test5,
100 libqt5widgets5,
101- python-autopilot (>= 1.4),
102- python-fixtures,
103- python-gi,
104- python-mock,
105- python-testscenarios,
106- python-testtools,
107- python-autopilot-trace,
108 python3-fixtures,
109 python3-gi,
110 python3-testscenarios,
111
112=== modified file 'debian/rules'
113--- debian/rules 2015-01-23 18:11:22 +0000
114+++ debian/rules 2015-04-14 21:04:03 +0000
115@@ -4,6 +4,7 @@
116 # export DH_VERBOSE=1
117 export DPKG_GENSYMBOLS_CHECK_LEVEL=4
118 export QMAKEFEATURES=$(CURDIR)/features
119+export QT_SELECT := qt5
120 DEB_HOST_MULTI_ARCH ?= $(shell dpkg-architecture -qDEB_BUILD_MULTIARCH)
121 DEB_HOST_ARCH ?= $(shell dpkg-architecture -qDEB_HOST_ARCH)
122
123
124=== modified file 'debian/ubuntu-ui-toolkit-autopilot.install'
125--- debian/ubuntu-ui-toolkit-autopilot.install 2014-06-17 07:12:49 +0000
126+++ debian/ubuntu-ui-toolkit-autopilot.install 2015-04-14 21:04:03 +0000
127@@ -1,3 +1,2 @@
128 usr/lib/python3
129 usr/lib/*/ubuntu-ui-toolkit/launcher
130-usr/lib/python2.7
131
132=== modified file 'examples/ubuntu-ui-toolkit-gallery/WebLink.qml'
133--- examples/ubuntu-ui-toolkit-gallery/WebLink.qml 2015-03-03 13:20:06 +0000
134+++ examples/ubuntu-ui-toolkit-gallery/WebLink.qml 2015-04-14 21:04:03 +0000
135@@ -27,4 +27,9 @@
136 text: "<a href=\"%1\">%2</a>".arg(webLink.url).arg(webLink.label)
137 linkColor: UbuntuColors.orange
138 onLinkActivated: Qt.openUrlExternally(link)
139+ MouseArea {
140+ anchors.fill: webLink
141+ cursorShape: Qt.PointingHandCursor
142+ acceptedButtons: Qt.NoButton
143+ }
144 }
145
146=== modified file 'modules/Ubuntu/Components/AppHeader.qml'
147--- modules/Ubuntu/Components/AppHeader.qml 2015-03-03 13:47:48 +0000
148+++ modules/Ubuntu/Components/AppHeader.qml 2015-04-14 21:04:03 +0000
149@@ -1,5 +1,5 @@
150 /*
151- * Copyright 2013-2014 Canonical Ltd.
152+ * Copyright 2013-2015 Canonical Ltd.
153 *
154 * This program is free software; you can redistribute it and/or modify
155 * it under the terms of the GNU Lesser General Public License as published by
156@@ -60,7 +60,8 @@
157 internal.movementEnded();
158 }
159
160- visible: title || contents || tabsModel
161+ // with PageHeadConfiguration 1.2, always be visible.
162+ visible: title || contents || tabsModel || internal.newConfig
163 onVisibleChanged: {
164 internal.checkFlickableMargins();
165 }
166@@ -69,6 +70,9 @@
167 Show the header
168 */
169 function show() {
170+ if (internal.newConfig) {
171+ header.config.visible = true;
172+ }
173 header.y = 0;
174 }
175
176@@ -76,7 +80,10 @@
177 Hide the header
178 */
179 function hide() {
180- header.y = - header.height;
181+ if (internal.newConfig) {
182+ header.config.visible = false;
183+ }
184+ header.y = -header.height;
185 }
186
187 /*!
188@@ -84,15 +91,22 @@
189 */
190 property string title: ""
191 onTitleChanged: {
192- header.show();
193+ // deprecated for new versions of PageHeadConfiguration
194+ if (!internal.newConfig) {
195+ header.show();
196+ }
197 }
198
199 /*!
200 The contents of the header. If this is set, \l title will be ignored.
201+ DEPRECATED and replaced by Page.head.contents.
202 */
203 property Item contents: null
204 onContentsChanged: {
205- header.show();
206+ // deprecated for new versions of PageHeadConfiguration
207+ if (!internal.newConfig) {
208+ header.show();
209+ }
210 }
211
212 /*!
213@@ -151,9 +165,10 @@
214 */
215 property Flickable flickable: null
216 onFlickableChanged: {
217- internal.checkFlickableMargins();
218 internal.connectFlickable();
219- header.show();
220+ if (!internal.newConfig || !header.config.locked) {
221+ header.show();
222+ }
223 }
224
225 /*!
226@@ -163,12 +178,68 @@
227
228 /*!
229 Configuration of the header.
230+ FIXME: Must be of type PageHeadConfiguration. Setting that as the property type
231+ however will use the latest version (1.3) and a Page that uses an older
232+ version (1.1) will no longer work.
233 */
234- property PageHeadConfiguration config: null
235+ property Object config: null
236+ onConfigChanged: {
237+ // set internal.newConfig because when we rely on the binding,
238+ // the value of newConfig may be updated after executing the code below.
239+ internal.newConfig = config && config.hasOwnProperty("visible") &&
240+ config.hasOwnProperty("locked");
241+ internal.connectFlickable();
242+
243+ if (internal.newConfig && header.config.locked &&!header.config.visible) {
244+ header.hide();
245+ } else {
246+ header.show();
247+ }
248+ }
249+ Connections {
250+ target: header.config
251+ ignoreUnknownSignals: true // PageHeadConfiguration <1.2 lacks the signals below
252+ onVisibleChanged: {
253+ if (header.config.visible) {
254+ header.show();
255+ } else {
256+ header.hide();
257+ }
258+ internal.checkFlickableMargins();
259+ }
260+ onLockedChanged: {
261+ internal.connectFlickable();
262+ if (!header.config.locked) {
263+ internal.movementEnded();
264+ }
265+ }
266+ }
267+
268+ /*!
269+ The header is not fully opened or fully closed.
270+
271+ This property is true if the header is animating towards a fully
272+ opened or fully closed state, or if the header is moving due to user
273+ interaction with the flickable.
274+
275+ The value of moving is always false when using an old version of
276+ PageHeadConfiguration (which does not have the visible property).
277+
278+ Used in tst_header_locked_visible.qml.
279+ */
280+ readonly property bool moving: internal.newConfig &&
281+ ((config.visible && header.y !== 0) ||
282+ (!config.visible && header.y !== -header.height))
283
284 QtObject {
285 id: internal
286
287+ // This property is updated in header.onConfigChanged to ensure it
288+ // is updated before other functions are called in onConfigChanged.
289+ property bool newConfig: header.config &&
290+ header.config.hasOwnProperty("locked") &&
291+ header.config.hasOwnProperty("visible")
292+
293 /*!
294 Track the y-position inside the flickable.
295 */
296@@ -183,20 +254,26 @@
297 Disconnect previous flickable, and connect the new one.
298 */
299 function connectFlickable() {
300+ // Finish the current header movement in case the current
301+ // flickable is disconnected while scrolling:
302+ internal.movementEnded();
303+
304 if (previousFlickable) {
305 previousFlickable.contentYChanged.disconnect(internal.scrollContents);
306 previousFlickable.movementEnded.disconnect(internal.movementEnded);
307 previousFlickable.interactiveChanged.disconnect(internal.interactiveChanged);
308+ previousFlickable = null;
309 }
310- if (flickable) {
311+ if (flickable && !(internal.newConfig && header.config.locked)) {
312 // Connect flicking to movements of the header
313 previousContentY = flickable.contentY;
314 flickable.contentYChanged.connect(internal.scrollContents);
315 flickable.movementEnded.connect(internal.movementEnded);
316 flickable.interactiveChanged.connect(internal.interactiveChanged);
317 flickable.contentHeightChanged.connect(internal.contentHeightChanged);
318+ previousFlickable = flickable;
319 }
320- previousFlickable = flickable;
321+ internal.checkFlickableMargins();
322 }
323
324 /*!
325@@ -216,9 +293,14 @@
326 Fully show or hide the header, depending on its current y.
327 */
328 function movementEnded() {
329- if (flickable && flickable.contentY < 0) header.show();
330- else if (header.y < -header.height/2) header.hide();
331- else header.show();
332+ if (!(internal.newConfig && header.config.locked)) {
333+ if ( (flickable && flickable.contentY < 0) ||
334+ (header.y > -header.height/2)) {
335+ header.show();
336+ } else {
337+ header.hide();
338+ }
339+ }
340 }
341
342 /*
343@@ -241,13 +323,20 @@
344 */
345 function checkFlickableMargins() {
346 if (header.flickable) {
347- var headerHeight = header.visible ? header.height : 0
348+ var headerHeight = 0;
349+ if (header.visible && !(internal.newConfig &&
350+ header.config.locked &&
351+ !header.config.visible)) {
352+ headerHeight = header.height;
353+ }
354+
355 if (flickable.topMargin !== headerHeight) {
356+ var oldContentY = flickable.contentY;
357 var previousHeaderHeight = flickable.topMargin;
358 flickable.topMargin = headerHeight;
359 // push down contents when header grows,
360 // pull up contents when header shrinks.
361- flickable.contentY -= headerHeight - previousHeaderHeight;
362+ flickable.contentY = oldContentY - headerHeight + previousHeaderHeight;
363 }
364 }
365 }
366
367=== modified file 'modules/Ubuntu/Components/MainView.qml'
368--- modules/Ubuntu/Components/MainView.qml 2015-03-03 13:47:48 +0000
369+++ modules/Ubuntu/Components/MainView.qml 2015-04-14 21:04:03 +0000
370@@ -125,6 +125,7 @@
371 AppHeader {
372 // This objectName is used in the MainView autopilot custom proxy object
373 // in order to select the application header.
374+ // Also used in tst_header_locked_visible.qml.
375 objectName: "MainView_Header"
376 id: headerItem
377 property real bottomY: headerItem.y + headerItem.height
378@@ -136,7 +137,7 @@
379 flickable: internal.activePage ? internal.activePage.flickable : null
380 pageStack: internal.activePage ? internal.activePage.pageStack : null
381
382- PageHeadConfiguration {
383+ Toolkit.PageHeadConfiguration {
384 id: headerConfig
385 // for backwards compatibility with deprecated tools property
386 actions: internal.activePage ?
387
388=== modified file 'modules/Ubuntu/Components/MainView12.qml'
389--- modules/Ubuntu/Components/MainView12.qml 2015-03-03 12:53:42 +0000
390+++ modules/Ubuntu/Components/MainView12.qml 2015-04-14 21:04:03 +0000
391@@ -69,6 +69,7 @@
392 AppHeader {
393 // This objectName is used in the MainView autopilot custom proxy object
394 // in order to select the application header.
395+ // Also used in tst_header_locked_visible.qml.
396 objectName: "MainView_Header"
397 id: headerItem
398 property real bottomY: headerItem.y + headerItem.height
399@@ -80,10 +81,11 @@
400 flickable: internal.activePage ? internal.activePage.flickable : null
401 pageStack: internal.activePage ? internal.activePage.pageStack : null
402
403- contents: internal.activePage ?
404+ contents: internal.activePage &&
405+ internal.activePage.hasOwnProperty("__customHeaderContents") ?
406 internal.activePage.__customHeaderContents : null
407
408- PageHeadConfiguration {
409+ Toolkit.PageHeadConfiguration {
410 id: defaultConfig
411 // Used when there is no active Page, or a Page 1.0 is used which
412 // does not have a PageHeadConfiguration.
413@@ -114,9 +116,13 @@
414 target: Qt.application
415 onActiveChanged: {
416 if (Qt.application.active) {
417- headerItem.animate = false;
418- headerItem.show();
419- headerItem.animate = true;
420+ if (!(headerItem.config &&
421+ headerItem.config.hasOwnProperty("locked") &&
422+ headerItem.locked)) {
423+ headerItem.animate = false;
424+ headerItem.show();
425+ headerItem.animate = true;
426+ }
427 }
428 }
429 }
430@@ -127,11 +133,15 @@
431
432 // Even when using MainView 1.1, we still support Page 1.0.
433 // PageBase (=Page 1.0) is the superclass of Page 1.1.
434- property PageBase activePage: isPage(mainView.activeLeafNode) ? mainView.activeLeafNode : null
435+ property Item activePage: isPage(mainView.activeLeafNode) ? mainView.activeLeafNode : null
436
437 function isPage(item) {
438- return item && item.hasOwnProperty("__isPageTreeNode") && item.__isPageTreeNode &&
439- item.hasOwnProperty("title") && item.hasOwnProperty("tools");
440+ return item && item.hasOwnProperty("__isPageTreeNode") &&
441+ item.__isPageTreeNode &&
442+ item.hasOwnProperty("title") &&
443+ item.hasOwnProperty("flickable") &&
444+ item.hasOwnProperty("active") &&
445+ item.hasOwnProperty("pageStack")
446 }
447 }
448
449
450=== modified file 'modules/Ubuntu/Components/Page10.qml'
451--- modules/Ubuntu/Components/Page10.qml 2015-03-03 13:47:48 +0000
452+++ modules/Ubuntu/Components/Page10.qml 2015-04-14 21:04:03 +0000
453@@ -15,7 +15,8 @@
454 */
455
456 import QtQuick 2.4
457-import Ubuntu.Components 1.2 as Toolkit
458+import Ubuntu.Components 1.0 as Toolkit
459+import "pageUtils.js" as Utils
460
461 /*!
462 \internal
463@@ -53,7 +54,7 @@
464 */
465 property Item __customHeaderContents: null
466
467- property Flickable flickable: internal.getFlickableChild(page)
468+ property Flickable flickable: Utils.getFlickableChild(page)
469
470 /*! \internal */
471 onActiveChanged: {
472@@ -95,34 +96,5 @@
473 when: internal.header && !internal.header.useDeprecatedToolbar &&
474 page.tools !== null
475 }
476-
477- function isVerticalFlickable(object) {
478- if (object && object.hasOwnProperty("flickableDirection") && object.hasOwnProperty("contentHeight")) {
479- var direction = object.flickableDirection;
480- if ( ((direction === Flickable.AutoFlickDirection) && (object.contentHeight !== object.height) )
481- || direction === Flickable.VerticalFlick
482- || direction === Flickable.HorizontalAndVerticalFlick) {
483- return true;
484- }
485- }
486- return false;
487- }
488-
489- /*!
490- Return the first flickable child of this page.
491- */
492- function getFlickableChild(item) {
493- if (item && item.hasOwnProperty("children")) {
494- for (var i=0; i < item.children.length; i++) {
495- var child = item.children[i];
496- if (internal.isVerticalFlickable(child)) {
497- if (child.anchors.top === page.top || child.anchors.fill === page) {
498- return item.children[i];
499- }
500- }
501- }
502- }
503- return null;
504- }
505 }
506 }
507
508=== modified file 'modules/Ubuntu/Components/Page11.qml'
509--- modules/Ubuntu/Components/Page11.qml 2015-03-03 12:53:42 +0000
510+++ modules/Ubuntu/Components/Page11.qml 2015-04-14 21:04:03 +0000
511@@ -15,16 +15,18 @@
512 */
513
514 import QtQuick 2.4
515+import Ubuntu.Components 1.0 as Toolkit10
516+import Ubuntu.Components 1.1 as Toolkit11
517
518 /*! \internal */
519 // Documentation in Page.qdoc
520-Page10 {
521+Toolkit10.Page {
522 id: page
523 /*!
524 \qmlproperty PageHeadConfiguration head
525 */
526 readonly property alias head: headerConfig
527- PageHeadConfiguration {
528+ Toolkit11.PageHeadConfiguration {
529 id: headerConfig
530 }
531
532@@ -32,7 +34,7 @@
533 print("Page.tools is a deprecated property. Please use Page.head instead.");
534 }
535
536- Object {
537+ Toolkit11.Object {
538 id: internal
539
540 // Note: The bindings below need to check whether headerConfig.contents
541
542=== added file 'modules/Ubuntu/Components/Page13.qml'
543--- modules/Ubuntu/Components/Page13.qml 1970-01-01 00:00:00 +0000
544+++ modules/Ubuntu/Components/Page13.qml 2015-04-14 21:04:03 +0000
545@@ -0,0 +1,84 @@
546+/*
547+ * Copyright 2015 Canonical Ltd.
548+ *
549+ * This program is free software; you can redistribute it and/or modify
550+ * it under the terms of the GNU Lesser General Public License as published by
551+ * the Free Software Foundation; version 3.
552+ *
553+ * This program is distributed in the hope that it will be useful,
554+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
555+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
556+ * GNU Lesser General Public License for more details.
557+ *
558+ * You should have received a copy of the GNU Lesser General Public License
559+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
560+ */
561+
562+import QtQuick 2.4
563+import Ubuntu.Components 1.3 as Toolkit13
564+import "pageUtils.js" as Utils
565+
566+/*!
567+ \internal
568+ Documentation is in Page.qdoc
569+*/
570+PageTreeNode {
571+ id: page
572+ anchors {
573+ left: parent ? parent.left : undefined
574+ bottom: parent ? parent.bottom : undefined
575+ }
576+ // Set width and height so that a parent Loader can be automatically resized
577+ // to the size of the loaded Page.
578+ width: parentNode ? parentNode.width - page.x : undefined
579+ height: parentNode ? page.flickable ? parentNode.height : parentNode.height - internal.headerHeight : undefined
580+
581+ isLeaf: true
582+ property string title: parentNode && parentNode.hasOwnProperty("title") ? parentNode.title : ""
583+ property Flickable flickable: Utils.getFlickableChild(page)
584+
585+ /*!
586+ \qmlproperty PageHeadConfiguration head
587+ */
588+ readonly property alias head: headerConfig
589+ Toolkit13.PageHeadConfiguration {
590+ id: headerConfig
591+ }
592+
593+ Object {
594+ id: internal
595+
596+ property AppHeader header: page.__propagated && page.__propagated.header ? page.__propagated.header : null
597+ // Used to position the Page when there is no flickable.
598+ // When there is a flickable, the header will automatically position it.
599+ property real headerHeight: internal.header && internal.header.visible ? internal.header.height : 0
600+
601+ // Note: The bindings below need to check whether headerConfig.contents
602+ // is valid in the "value", even when that is required in the Binding's "when"
603+ // property, to avoid TypeErrors while/after a page becomes (in)active.
604+ //
605+ // Note 2: contents.parent binding is made by PageHeadStyle.
606+ property bool hasParent: headerConfig.contents &&
607+ headerConfig.contents.parent
608+
609+ Binding {
610+ target: headerConfig.contents
611+ property: "visible"
612+ value: page.active
613+ when: headerConfig.contents
614+ }
615+ Binding {
616+ target: headerConfig.contents
617+ property: "anchors.verticalCenter"
618+ value: internal.hasParent ? headerConfig.contents.parent.verticalCenter :
619+ undefined
620+ when: headerConfig.contents
621+ }
622+ Binding {
623+ target: headerConfig.contents
624+ property: "anchors.left"
625+ value: internal.hasParent ? headerConfig.contents.parent.left : undefined
626+ when: headerConfig.contents
627+ }
628+ }
629+}
630
631=== added file 'modules/Ubuntu/Components/PageHeadConfiguration.qdoc'
632--- modules/Ubuntu/Components/PageHeadConfiguration.qdoc 1970-01-01 00:00:00 +0000
633+++ modules/Ubuntu/Components/PageHeadConfiguration.qdoc 2015-04-14 21:04:03 +0000
634@@ -0,0 +1,202 @@
635+/*
636+ * Copyright 2014-2015 Canonical Ltd.
637+ *
638+ * This program is free software; you can redistribute it and/or modify
639+ * it under the terms of the GNU Lesser General Public License as published by
640+ * the Free Software Foundation; version 3.
641+ *
642+ * This program is distributed in the hope that it will be useful,
643+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
644+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
645+ * GNU Lesser General Public License for more details.
646+ *
647+ * You should have received a copy of the GNU Lesser General Public License
648+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
649+ */
650+
651+/*!
652+ \qmltype PageHeadConfiguration
653+ \inqmlmodule Ubuntu.Components 1.1
654+ \ingroup ubuntu
655+ \since Ubuntu.Components 1.1
656+ \brief Page.head is used to configure the header for a \l Page.
657+
658+ For examples how to use Page.head, see \l Page.
659+ */
660+
661+/*!
662+ List of actions to show in the header.
663+
664+ Example:
665+ \qml
666+ Page {
667+ title: "Custom header actions"
668+ head.actions: [
669+ Action {
670+ iconName: "save"
671+ text: i18n.tr("Save")
672+ },
673+ Action {
674+ iconName: "add"
675+ text: i18n.tr("Add")
676+ }
677+ ]
678+ }
679+ \endqml
680+ \qmlproperty list<Action> PageHeadConfiguration::actions
681+ */
682+
683+/*!
684+ \qmlproperty Action PageHeadConfiguration::backAction
685+ Overrides the default \l PageStack back button and the
686+ \l Tabs drawer button in the header.
687+
688+ Example:
689+ \qml
690+ Page {
691+ title: "Back Action Page"
692+ head.backAction: Action {
693+ iconName: "close"
694+ onTriggered: {
695+ console.log("Run custom back action")
696+ }
697+ }
698+ }
699+ \endqml
700+ */
701+
702+/*!
703+ \qmlproperty Item PageHeadConfiguration::contents
704+ Set this property to show this Item in the header instead of
705+ the title. Use a \l TextField here for implementing search in header.
706+
707+ The parent of this Item will be binded while the \l Page is active.
708+ The header contents will automatically be anchored to the left and
709+ vertically centered inside the header.
710+
711+ Example:
712+ \qml
713+ Page {
714+ title: "Invisible title"
715+ head.contents: Rectangle {
716+ color: UbuntuColors.orange
717+ height: units.gu(5)
718+ width: parent ? parent.width - units.gu(2) : undefined
719+ }
720+ }
721+ \endqml
722+
723+ See \l PageHeadState for an example that shows how search mode can
724+ be implemented.
725+ */
726+
727+// FIXME: The example below can be much simplified using PageHeadState
728+// when bug #1345775 has been fixed.
729+/*!
730+ \qmlproperty string PageHeadConfiguration::preset
731+ Choose a preset for the header visuals and behavior.
732+ The default is an empty string "".
733+ By setting this to "select", title will be hidden and
734+ actions will be represented by icons with a label.
735+
736+ Example:
737+ \qml
738+ import QtQuick 2.4
739+ import Ubuntu.Components 1.2
740+
741+ MainView {
742+ id: mainView
743+ width: units.gu(40)
744+ height: units.gu(50)
745+
746+ Page {
747+ id: page
748+ title: "Demo"
749+
750+ state: "default"
751+ states: [
752+ PageHeadState {
753+ name: "default"
754+ head: page.head
755+ actions: [
756+ Action {
757+ iconName: "contact"
758+ text: "Contact"
759+ }
760+ ]
761+ },
762+ State {
763+ id: selectState
764+ name: "select"
765+
766+ property Action leaveSelect: Action {
767+ iconName: "back"
768+ text: "Back"
769+ onTriggered: page.state = "default"
770+ }
771+ property list<Action> actions: [
772+ Action {
773+ iconName: "select"
774+ text: "Select All"
775+ },
776+ Action {
777+ iconName: "delete"
778+ text: "Delete"
779+ }
780+ ]
781+ PropertyChanges {
782+ target: page.head
783+ backAction: selectState.leaveSelect
784+ actions: selectState.actions
785+ preset: "select"
786+ }
787+ }
788+ ]
789+
790+ Label {
791+ anchors.centerIn: parent
792+ text: "Use back button to leave selection mode."
793+ visible: page.state == "select"
794+ }
795+
796+ Button {
797+ anchors.centerIn: parent
798+ onClicked: page.state = "select"
799+ visible: page.state != "select"
800+ text: "selection mode"
801+ }
802+ }
803+ }
804+ \endqml
805+ */
806+
807+/*!
808+ \qmlproperty PageHeadSections PageHeadConfiguration::sections
809+ Defines the sections in the page header divider.
810+ */
811+
812+/*!
813+ \qmlproperty color PageHeadConfiguration::foregroundColor
814+ The color of the text and icons.
815+ */
816+
817+/*!
818+ \qmlproperty bool PageHeadConfiguration::locked
819+ \since 1.2
820+ When the \l Page is active, the locked property controls the behavior
821+ of the header. A locked header stays visible or invisible, depending
822+ on the value of the \l visible property. An unlocked header automatically
823+ shows and hides if the \l Page has a flickable in which the user
824+ scrolls up or down.
825+ Default value: false
826+ */
827+
828+/*!
829+ \qmlproperty bool PageHeadConfiguration::visible
830+ \since 1.2
831+ Update the value of the visible property to show or hide the header.
832+ This works both when the header is \l locked and unlocked. An unlocked
833+ header can also become visible or hidden when the user scrolls the
834+ active \l Page's flickable. The value of the visible property will be
835+ updated at the end of the showing/hiding animation of the header.
836+ */
837
838=== renamed file 'modules/Ubuntu/Components/PageHeadConfiguration.qml' => 'modules/Ubuntu/Components/PageHeadConfiguration11.qml'
839--- modules/Ubuntu/Components/PageHeadConfiguration.qml 2015-03-03 13:47:48 +0000
840+++ modules/Ubuntu/Components/PageHeadConfiguration11.qml 2015-04-14 21:04:03 +0000
841@@ -15,92 +15,24 @@
842 */
843
844 import QtQuick 2.4
845-import Ubuntu.Components 1.2
846+import Ubuntu.Components 1.1
847
848 /*!
849- \qmltype PageHeadConfiguration
850- \inqmlmodule Ubuntu.Components 1.1
851- \ingroup ubuntu
852- \since Ubuntu.Components 1.1
853- \brief Page.head is used to configure the header for a \l Page.
854-
855- For examples how to use Page.head, see \l Page.
856+ \internal
857+ Documented in PageHeadConfiguration.qdoc
858 */
859 Object {
860 // To be used inside a Page only.
861 id: headerConfig
862
863- /*!
864- List of actions to show in the header.
865-
866- Example:
867- \qml
868- Page {
869- title: "Custom header actions"
870- head.actions: [
871- Action {
872- iconName: "save"
873- text: i18n.tr("Save")
874- },
875- Action {
876- iconName: "add"
877- text: i18n.tr("Add")
878- }
879- ]
880- }
881- \endqml
882- */
883 property list<Action> actions
884-
885- /*!
886- Overrides the default \l PageStack back button and the
887- \l Tabs drawer button in the header.
888-
889- Example:
890- \qml
891- Page {
892- title: "Back Action Page"
893- head.backAction: Action {
894- iconName: "close"
895- onTriggered: {
896- console.log("Run custom back action")
897- }
898- }
899- }
900- \endqml
901- */
902 property Action backAction: null
903-
904- /*!
905- Set this property to show this Item in the header instead of
906- the title. Use a \l TextField here for implementing search in header.
907-
908- The parent of this Item will be binded while the \l Page is active.
909- The header contents will automatically be anchored to the left and
910- vertically centered inside the header.
911-
912- Example:
913- \qml
914- Page {
915- title: "Invisible title"
916- head.contents: Rectangle {
917- color: UbuntuColors.orange
918- height: units.gu(5)
919- width: parent ? parent.width - units.gu(2) : undefined
920- }
921- }
922- \endqml
923-
924- See \l PageHeadState for an example that shows how search mode can
925- be implemented.
926- */
927 property Item contents: null
928
929 QtObject {
930 id: internal
931 property Item oldContents: null
932 }
933-
934 onContentsChanged: {
935 if (internal.oldContents) {
936 // FIX: bug #1341814 and #1400297
937@@ -111,97 +43,13 @@
938 internal.oldContents = contents;
939 }
940
941- // FIXME: The example below can be much simplified using PageHeadState
942- // when bug #1345775 has been fixed.
943- /*!
944- Choose a preset for the header visuals and behavior.
945- The default is an empty string "".
946- By setting this to "select", title will be hidden and
947- actions will be represented by icons with a label.
948-
949- Example:
950- \qml
951- import QtQuick 2.4
952- import Ubuntu.Components 1.2
953-
954- MainView {
955- id: mainView
956- width: units.gu(40)
957- height: units.gu(50)
958-
959- Page {
960- id: page
961- title: "Demo"
962-
963- state: "default"
964- states: [
965- PageHeadState {
966- name: "default"
967- head: page.head
968- actions: [
969- Action {
970- iconName: "contact"
971- text: "Contact"
972- }
973- ]
974- },
975- State {
976- id: selectState
977- name: "select"
978-
979- property Action leaveSelect: Action {
980- iconName: "back"
981- text: "Back"
982- onTriggered: page.state = "default"
983- }
984- property list<Action> actions: [
985- Action {
986- iconName: "select"
987- text: "Select All"
988- },
989- Action {
990- iconName: "delete"
991- text: "Delete"
992- }
993- ]
994- PropertyChanges {
995- target: page.head
996- backAction: selectState.leaveSelect
997- actions: selectState.actions
998- preset: "select"
999- }
1000- }
1001- ]
1002-
1003- Label {
1004- anchors.centerIn: parent
1005- text: "Use back button to leave selection mode."
1006- visible: page.state == "select"
1007- }
1008-
1009- Button {
1010- anchors.centerIn: parent
1011- onClicked: page.state = "select"
1012- visible: page.state != "select"
1013- text: "selection mode"
1014- }
1015- }
1016- }
1017- \endqml
1018- */
1019 property string preset: ""
1020-
1021 /*!
1022 \qmlproperty PageHeadSections sections
1023- Defines the sections in the page header divider.
1024 */
1025 readonly property alias sections: headSections
1026 PageHeadSections {
1027 id: headSections
1028 }
1029-
1030- /*!
1031- The color of the text and icons.
1032- */
1033 property color foregroundColor: Theme.palette.selected.backgroundText
1034 }
1035
1036=== added file 'modules/Ubuntu/Components/PageHeadConfiguration13.qml'
1037--- modules/Ubuntu/Components/PageHeadConfiguration13.qml 1970-01-01 00:00:00 +0000
1038+++ modules/Ubuntu/Components/PageHeadConfiguration13.qml 2015-04-14 21:04:03 +0000
1039@@ -0,0 +1,30 @@
1040+/*
1041+ * Copyright 2015 Canonical Ltd.
1042+ *
1043+ * This program is free software; you can redistribute it and/or modify
1044+ * it under the terms of the GNU Lesser General Public License as published by
1045+ * the Free Software Foundation; version 3.
1046+ *
1047+ * This program is distributed in the hope that it will be useful,
1048+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1049+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1050+ * GNU Lesser General Public License for more details.
1051+ *
1052+ * You should have received a copy of the GNU Lesser General Public License
1053+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1054+ */
1055+
1056+import Ubuntu.Components 1.2 as Toolkit12
1057+
1058+/*!
1059+ \internal
1060+ documented in PageHeadConfiguration.qdoc
1061+ */
1062+Toolkit12.PageHeadConfiguration {
1063+ id: headerConfig
1064+
1065+ property bool locked: false
1066+
1067+ // auto-updated by AppHeader, but may be set by the developer
1068+ property bool visible
1069+}
1070
1071=== modified file 'modules/Ubuntu/Components/StyledItem.qml'
1072--- modules/Ubuntu/Components/StyledItem.qml 2015-03-03 13:47:48 +0000
1073+++ modules/Ubuntu/Components/StyledItem.qml 2015-04-14 21:04:03 +0000
1074@@ -15,7 +15,7 @@
1075 */
1076
1077 import QtQuick 2.4
1078-import Ubuntu.Components 1.2
1079+import Ubuntu.Components 1.3
1080
1081 /*!
1082 \qmlabstract StyledItem
1083
1084=== modified file 'modules/Ubuntu/Components/Styles/PageHeadStyle.qml'
1085--- modules/Ubuntu/Components/Styles/PageHeadStyle.qml 2015-03-03 13:47:48 +0000
1086+++ modules/Ubuntu/Components/Styles/PageHeadStyle.qml 2015-04-14 21:04:03 +0000
1087@@ -1,5 +1,5 @@
1088 /*
1089- * Copyright 2014 Canonical Ltd.
1090+ * Copyright 2014-2015 Canonical Ltd.
1091 *
1092 * This program is free software; you can redistribute it and/or modify
1093 * it under the terms of the GNU Lesser General Public License as published by
1094@@ -25,8 +25,8 @@
1095 */
1096 Item {
1097 /*!
1098- The height of the headercontents, which is the full height of
1099- the header minus the separators shown at the bottom of it.
1100+ The height of the header excluding the height of the bottom divider and
1101+ the (optional) row that displays the sections.
1102 */
1103 property real contentHeight
1104
1105
1106=== modified file 'modules/Ubuntu/Components/Tab.qml'
1107--- modules/Ubuntu/Components/Tab.qml 2015-03-03 13:47:48 +0000
1108+++ modules/Ubuntu/Components/Tab.qml 2015-04-14 21:04:03 +0000
1109@@ -1,5 +1,5 @@
1110 /*
1111- * Copyright 2012 Canonical Ltd.
1112+ * Copyright 2015 Canonical Ltd.
1113 *
1114 * This program is free software; you can redistribute it and/or modify
1115 * it under the terms of the GNU Lesser General Public License as published by
1116@@ -15,6 +15,7 @@
1117 */
1118
1119 import QtQuick 2.4
1120+import Ubuntu.Components 1.3 as Toolkit
1121
1122 /*!
1123 \qmltype Tab
1124@@ -137,7 +138,7 @@
1125 \internal
1126 */
1127 property alias __protected: internal
1128- QtObject {
1129+ Object {
1130 id: internal
1131 /*
1132 Specifies the index of the Tab in Tabs.
1133@@ -164,5 +165,22 @@
1134 component stack (children) change.
1135 */
1136 property bool removedFromTabs: false
1137+
1138+ /*!
1139+ Triggering this action will select the tab. Used by the tabs OverflowPanel.
1140+ */
1141+ property alias action: selectTabAction
1142+ Toolkit.Action {
1143+ id: selectTabAction
1144+ text: tab.title
1145+ objectName: "select_tab_"+index
1146+ iconSource: tab.iconSource
1147+ onTriggered: {
1148+ if (internal.index < 0) return;
1149+ if (tab.parentNode && tab.parentNode.hasOwnProperty("selectedTabIndex")) {
1150+ tab.parentNode.selectedTabIndex = internal.index;
1151+ }
1152+ }
1153+ }
1154 }
1155 }
1156
1157=== modified file 'modules/Ubuntu/Components/Tabs.qml'
1158--- modules/Ubuntu/Components/Tabs.qml 2015-03-05 09:35:06 +0000
1159+++ modules/Ubuntu/Components/Tabs.qml 2015-04-14 21:04:03 +0000
1160@@ -310,7 +310,10 @@
1161 if (tabBar && tabBar.__styleInstance && tabBar.__styleInstance.hasOwnProperty("sync")) {
1162 tabBar.__styleInstance.sync();
1163 }
1164- if (tabs.active && internal.header) {
1165+ if ((tabs.active && internal.header) &&
1166+ !(internal.header.config &&
1167+ internal.header.config.hasOwnProperty("locked") &&
1168+ internal.header.config.locked)) {
1169 internal.header.show();
1170 }
1171 // deprecated, however use it till we remove it completely
1172
1173=== modified file 'modules/Ubuntu/Components/Themes/Ambiance/HeadDividerStyle.qml'
1174--- modules/Ubuntu/Components/Themes/Ambiance/HeadDividerStyle.qml 2015-03-03 12:53:42 +0000
1175+++ modules/Ubuntu/Components/Themes/Ambiance/HeadDividerStyle.qml 2015-04-14 21:04:03 +0000
1176@@ -15,6 +15,9 @@
1177 */
1178 import QtQuick 2.4
1179
1180+/*!
1181+ This component is DEPRECATED and no longer used. The divider is now a simple line.
1182+ */
1183 Item {
1184 id: dividerStyle
1185
1186
1187=== modified file 'modules/Ubuntu/Components/Themes/Ambiance/OverflowPanel.qml'
1188--- modules/Ubuntu/Components/Themes/Ambiance/OverflowPanel.qml 2015-03-03 13:47:48 +0000
1189+++ modules/Ubuntu/Components/Themes/Ambiance/OverflowPanel.qml 2015-04-14 21:04:03 +0000
1190@@ -1,5 +1,5 @@
1191 /*
1192- * Copyright 2014 Canonical Ltd.
1193+ * Copyright 2015 Canonical Ltd.
1194 *
1195 * This program is free software; you can redistribute it and/or modify
1196 * it under the terms of the GNU Lesser General Public License as published by
1197@@ -16,7 +16,125 @@
1198
1199 import QtQuick 2.4
1200 import Ubuntu.Components.Popups 1.0
1201+import Ubuntu.Components 1.3
1202+import Ubuntu.Components.ListItems 1.0 as ListItem
1203
1204+/*!
1205+ \internal
1206+ */
1207 Popover {
1208+ id: overflow
1209+
1210+ /*!
1211+ The background color of the tabs panel and the actions overflow panel.
1212+ */
1213+ property color backgroundColor: styledItem.panelColor
1214+
1215+ /*!
1216+ The background color of the tapped item in the panel.
1217+ */
1218+ property color highlightColor: Theme.palette.selected.background
1219+
1220+ /*!
1221+ The foreground color (icon and text) of actions in the panel.
1222+ */
1223+ property color foregroundColor: Theme.palette.selected.backgroundText
1224+
1225 property bool square: true
1226+ callerMargin: -units.gu(1) + units.dp(4)
1227+ contentWidth: units.gu(20)
1228+
1229+ /*!
1230+ False implies the model is a list of Actions.
1231+ True implies the model is a ListModel with a 'tab' role,
1232+ and false implies that the model is a list of actions.
1233+ */
1234+ property bool tabsOverflow: false
1235+ // FIXME: In the input, generate a list of actions from the Tabs
1236+ // so that we no longer need to make a distinction between the tabs ListModel
1237+ // and a list of Actions.
1238+ property var model: null
1239+
1240+ Binding {
1241+ target: overflow.__foreground.__styleInstance
1242+ property: "color"
1243+ value: overflow.backgroundColor
1244+ when: overflow.__foreground &&
1245+ overflow.__foreground.__styleInstance
1246+ }
1247+
1248+ Column {
1249+ anchors {
1250+ left: parent.left
1251+ top: parent.top
1252+ right: parent.right
1253+ }
1254+ Repeater {
1255+ id: overflowRepeater
1256+ model: overflow.model
1257+ AbstractButton {
1258+ action: overflow.tabsOverflow ? tab.__protected.action
1259+ : modelData
1260+
1261+ // These objectNames are used in the CPOs for header and tabs.
1262+ objectName: overflow.tabsOverflow ?
1263+ "tabButton" + index :
1264+ action.objectName + "_header_overflow_button"
1265+
1266+ // close after triggering the action.
1267+ onClicked: overflow.hide()
1268+
1269+ implicitHeight: units.gu(6) + bottomDividerLine.height
1270+ width: parent ? parent.width : units.gu(31)
1271+
1272+ Rectangle {
1273+ visible: parent.pressed
1274+ anchors {
1275+ left: parent.left
1276+ right: parent.right
1277+ top: parent.top
1278+ }
1279+ height: parent.height - bottomDividerLine.height
1280+ color: overflow.highlightColor
1281+ }
1282+
1283+ Icon {
1284+ id: actionIcon
1285+ visible: !overflow.tabsOverflow
1286+ source: action.iconSource
1287+ color: overflow.foregroundColor
1288+ anchors {
1289+ verticalCenter: parent.verticalCenter
1290+ verticalCenterOffset: units.dp(-1)
1291+ left: parent.left
1292+ leftMargin: units.gu(2)
1293+ }
1294+ width: units.gu(2)
1295+ height: units.gu(2)
1296+ opacity: action.enabled ? 1.0 : 0.5
1297+ }
1298+
1299+ Label {
1300+ anchors {
1301+ verticalCenter: parent.verticalCenter
1302+ verticalCenterOffset: units.dp(-1)
1303+ left: actionIcon.visible ? actionIcon.right : parent.left
1304+ leftMargin: units.gu(2)
1305+ right: parent.right
1306+ }
1307+ fontSize: overflow.tabsOverflow ? "medium" : "small"
1308+ elide: Text.ElideRight
1309+ text: action.text
1310+ color: overflow.foregroundColor
1311+ opacity: action.enabled ? 1.0 : 0.5
1312+ }
1313+
1314+ ListItem.ThinDivider {
1315+ id: bottomDividerLine
1316+ anchors.bottom: parent.bottom
1317+ visible: index !== overflowRepeater.count - 1
1318+ }
1319+ }
1320+ }
1321+ }
1322 }
1323
1324=== modified file 'modules/Ubuntu/Components/Themes/Ambiance/PageHeadButton.qml'
1325--- modules/Ubuntu/Components/Themes/Ambiance/PageHeadButton.qml 2015-03-03 13:47:48 +0000
1326+++ modules/Ubuntu/Components/Themes/Ambiance/PageHeadButton.qml 2015-04-14 21:04:03 +0000
1327@@ -20,7 +20,7 @@
1328 AbstractButton {
1329 id: button
1330
1331- property real iconWidth: units.gu(2.5)
1332+ property real iconWidth: units.gu(2)
1333 property real iconHeight: iconWidth
1334
1335 width: visible ? units.gu(5) : 0
1336
1337=== modified file 'modules/Ubuntu/Components/Themes/Ambiance/PageHeadStyle.qml'
1338--- modules/Ubuntu/Components/Themes/Ambiance/PageHeadStyle.qml 2015-03-04 09:09:39 +0000
1339+++ modules/Ubuntu/Components/Themes/Ambiance/PageHeadStyle.qml 2015-04-14 21:04:03 +0000
1340@@ -1,5 +1,5 @@
1341 /*
1342- * Copyright 2014 Canonical Ltd.
1343+ * Copyright 2015 Canonical Ltd.
1344 *
1345 * This program is free software; you can redistribute it and/or modify
1346 * it under the terms of the GNU Lesser General Public License as published by
1347@@ -22,9 +22,9 @@
1348 Style.PageHeadStyle {
1349 id: headerStyle
1350 objectName: "PageHeadStyle" // used in unit tests
1351- contentHeight: units.gu(7)
1352+ contentHeight: units.gu(6)
1353 fontWeight: Font.Light
1354- fontSize: "x-large"
1355+ fontSize: "large"
1356 textLeftMargin: units.gu(2)
1357 maximumNumberOfActions: 3
1358
1359@@ -39,21 +39,6 @@
1360 property color titleColor: styledItem.config.foregroundColor
1361
1362 /*!
1363- The background color of the tabs panel and the actions overflow panel.
1364- */
1365- property color panelBackgroundColor: styledItem.panelColor
1366-
1367- /*!
1368- The background color of the tapped item in the panel.
1369- */
1370- property color panelHighlightColor: Theme.palette.selected.background
1371-
1372- /*!
1373- The foreground color (icon and text) of actions in the panel.
1374- */
1375- property color panelForegroundColor: Theme.palette.selected.backgroundText
1376-
1377- /*!
1378 The text color of unselected sections and the section divider.
1379 */
1380 property color sectionColor: Theme.palette.selected.backgroundText
1381@@ -68,7 +53,12 @@
1382 */
1383 property color sectionHighlightColor: Theme.palette.selected.background
1384
1385- implicitHeight: headerStyle.contentHeight + divider.height
1386+ implicitHeight: headerStyle.contentHeight + divider.height + sectionsItem.height
1387+
1388+ /*!
1389+ The height of the row displaying the sections, if sections are specified.
1390+ */
1391+ property real sectionsHeight: units.gu(4)
1392
1393 // FIXME: Workaround to get sectionsRepeater.count in autopilot tests,
1394 // see also FIXME in AppHeader where this property is used.
1395@@ -83,50 +73,57 @@
1396 // have a separator.
1397 property alias __separator_visible: divider.visible
1398
1399- StyledItem {
1400+ Rectangle {
1401 id: divider
1402 anchors {
1403+ left: parent.left
1404+ right: parent.right
1405 bottom: parent.bottom
1406+ }
1407+ height: units.dp(1)
1408+ color: styledItem.dividerColor
1409+ }
1410+
1411+ Item {
1412+ id: sectionsItem
1413+ anchors {
1414+ bottom: divider.top
1415 left: parent.left
1416 right: parent.right
1417 }
1418
1419- height: sectionsRow.visible ? units.gu(3) : units.gu(2)
1420-
1421- // separatorSource and separatorBottomSource are needed for the deprecated
1422- // HeadSeparatorImageStyle.
1423- property url separatorSource: headerStyle.separatorSource
1424- property url separatorBottomSource: headerStyle.separatorBottomSource
1425-
1426- // backgroundColor is used in the new HeadDividerStyle
1427- property color backgroundColor: styledItem.dividerColor
1428-
1429- style: Theme.createStyleComponent("HeadDividerStyle.qml", divider)
1430+ visible: sectionsItem.sections.model !== undefined
1431+ height: visible ? headerStyle.sectionsHeight : 0
1432
1433 property PageHeadSections sections: styledItem.config.sections
1434
1435 Row {
1436 id: sectionsRow
1437- anchors.centerIn: parent
1438+ anchors {
1439+ top: parent.top
1440+ bottom: parent.bottom
1441+ horizontalCenter: parent.horizontalCenter
1442+ }
1443 width: childrenRect.width
1444- height: parent.height
1445- enabled: divider.sections.enabled
1446- visible: divider.sections.model !== undefined
1447+ enabled: sectionsItem.sections.enabled
1448+ visible: sectionsItem.sections.model !== undefined
1449 opacity: enabled ? 1.0 : 0.5
1450
1451 Repeater {
1452 id: sectionsRepeater
1453- model: divider.sections.model
1454+ model: sectionsItem.sections.model
1455 objectName: "page_head_sections_repeater"
1456 AbstractButton {
1457 id: sectionButton
1458- anchors.verticalCenter: parent ? parent.verticalCenter : undefined
1459+ anchors {
1460+ top: parent.top
1461+ bottom: parent.bottom
1462+ }
1463 objectName: "section_button_" + index
1464 enabled: sectionsRow.enabled
1465- width: label.width + units.gu(4)
1466- height: sectionsRow.height + units.gu(2)
1467- property bool selected: index === divider.sections.selectedIndex
1468- onClicked: divider.sections.selectedIndex = index;
1469+ width: label.width + units.gu(4) // FIXME: expose spacing as style property
1470+ property bool selected: index === sectionsItem.sections.selectedIndex
1471+ onClicked: sectionsItem.sections.selectedIndex = index;
1472
1473 Rectangle {
1474 visible: parent.pressed
1475@@ -134,7 +131,6 @@
1476 verticalCenter: parent.verticalCenter
1477 left: parent.left
1478 right: parent.right
1479- rightMargin: verticalDividerLine.width
1480 }
1481 height: sectionsRow.height
1482 color: headerStyle.sectionHighlightColor
1483@@ -144,25 +140,24 @@
1484 id: label
1485 text: modelData
1486 fontSize: "small"
1487- anchors.centerIn: sectionButton
1488+ anchors.centerIn: parent
1489 horizontalAlignment: Text.AlignHCenter
1490 color: sectionButton.selected ?
1491 headerStyle.selectedSectionColor :
1492 headerStyle.sectionColor
1493 }
1494
1495- // vertical divider line
1496 Rectangle {
1497- id: verticalDividerLine
1498+ id: sectionLine
1499 anchors {
1500- verticalCenter: parent.verticalCenter
1501+ bottom: parent.bottom
1502+ left: parent.left
1503 right: parent.right
1504 }
1505- height: units.dp(10)
1506- width: units.dp(1)
1507- visible: index < sectionsRepeater.model.length - 1
1508- color: headerStyle.sectionColor
1509- opacity: 0.2
1510+ height: units.dp(2) // FIXME: Expose as style property
1511+ color: sectionButton.selected ?
1512+ headerStyle.selectedSectionColor :
1513+ styledItem.dividerColor
1514 }
1515 }
1516 }
1517@@ -341,67 +336,8 @@
1518 OverflowPanel {
1519 id: tabsPopover
1520 objectName: "tabsPopover"
1521- callerMargin: -units.gu(1) + units.dp(4)
1522- contentWidth: units.gu(20)
1523-
1524- Binding {
1525- target: tabsPopover.__foreground.__styleInstance
1526- property: "color"
1527- value: headerStyle.panelBackgroundColor
1528- when: tabsPopover.__foreground &&
1529- tabsPopover.__foreground.__styleInstance
1530- }
1531-
1532- Column {
1533- anchors {
1534- left: parent.left
1535- top: parent.top
1536- right: parent.right
1537- }
1538- Repeater {
1539- model: styledItem.tabsModel
1540- AbstractButton {
1541- objectName: "tabButton" + index
1542- onClicked: {
1543- styledItem.tabsModel.selectedIndex = index;
1544- tabsPopover.hide();
1545- }
1546- implicitHeight: units.gu(6) + bottomDividerLine.height
1547- width: parent ? parent.width : units.gu(31)
1548-
1549- Rectangle {
1550- visible: parent.pressed
1551- anchors {
1552- left: parent.left
1553- right: parent.right
1554- top: parent.top
1555- }
1556- height: parent.height - bottomDividerLine.height
1557- color: headerStyle.panelHighlightColor
1558- }
1559-
1560- Label {
1561- anchors {
1562- verticalCenter: parent.verticalCenter
1563- verticalCenterOffset: units.dp(-1)
1564- left: parent.left
1565- leftMargin: units.gu(2)
1566- right: parent.right
1567- }
1568- fontSize: "medium"
1569- elide: Text.ElideRight
1570- text: tab.title // FIXME: only "title" doesn't work with i18n.tr(). Why not?
1571- color: headerStyle.panelForegroundColor
1572- }
1573-
1574- ListItem.ThinDivider {
1575- id: bottomDividerLine
1576- anchors.bottom: parent.bottom
1577- visible: index < styledItem.tabsModel.count - 1
1578- }
1579- }
1580- }
1581- }
1582+ tabsOverflow: true
1583+ model: styledItem.tabsModel
1584 }
1585 }
1586 }
1587@@ -527,16 +463,6 @@
1588 OverflowPanel {
1589 id: actionsOverflowPopover
1590 objectName: "actions_overflow_popover"
1591- callerMargin: -units.gu(1) + units.dp(4)
1592- contentWidth: units.gu(20)
1593-
1594- Binding {
1595- target: actionsOverflowPopover.__foreground.__styleInstance
1596- property: "color"
1597- value: headerStyle.panelBackgroundColor
1598- when: actionsOverflowPopover.__foreground &&
1599- actionsOverflowPopover.__foreground.__styleInstance
1600- }
1601
1602 // Ensure the popover closes when actions change and
1603 // the list item below may be destroyed before its
1604@@ -555,71 +481,9 @@
1605 }
1606 }
1607
1608- Column {
1609- anchors {
1610- left: parent.left
1611- top: parent.top
1612- right: parent.right
1613- }
1614- Repeater {
1615- id: overflowRepeater
1616- model: numberOfSlots.requested - numberOfSlots.used
1617- AbstractButton {
1618- action: actionsContainer.visibleActions[numberOfSlots.used + index]
1619- objectName: action.objectName + "_header_overflow_button"
1620- onClicked: actionsOverflowPopover.hide()
1621- implicitHeight: units.gu(6) + bottomDividerLine.height
1622- width: parent ? parent.width : units.gu(31)
1623-
1624- Rectangle {
1625- visible: parent.pressed
1626- anchors {
1627- left: parent.left
1628- right: parent.right
1629- top: parent.top
1630- }
1631- height: parent.height - bottomDividerLine.height
1632- color: headerStyle.panelHighlightColor
1633- }
1634-
1635- Icon {
1636- id: actionIcon
1637- source: action.iconSource
1638- color: headerStyle.panelForegroundColor
1639- anchors {
1640- verticalCenter: parent.verticalCenter
1641- verticalCenterOffset: units.dp(-1)
1642- left: parent.left
1643- leftMargin: units.gu(2)
1644- }
1645- width: units.gu(2)
1646- height: units.gu(2)
1647- opacity: action.enabled ? 1.0 : 0.5
1648- }
1649-
1650- Label {
1651- anchors {
1652- verticalCenter: parent.verticalCenter
1653- verticalCenterOffset: units.dp(-1)
1654- left: actionIcon.right
1655- leftMargin: units.gu(2)
1656- right: parent.right
1657- }
1658- fontSize: "small"
1659- elide: Text.ElideRight
1660- text: action.text
1661- color: headerStyle.panelForegroundColor
1662- opacity: action.enabled ? 1.0 : 0.5
1663- }
1664-
1665- ListItem.ThinDivider {
1666- id: bottomDividerLine
1667- anchors.bottom: parent.bottom
1668- visible: index !== overflowRepeater.count - 1
1669- }
1670- }
1671- }
1672- }
1673+ tabsOverflow: false
1674+ model: actionsContainer.visibleActions.slice(numberOfSlots.used,
1675+ numberOfSlots.requested)
1676 }
1677 }
1678 }
1679
1680=== added file 'modules/Ubuntu/Components/pageUtils.js'
1681--- modules/Ubuntu/Components/pageUtils.js 1970-01-01 00:00:00 +0000
1682+++ modules/Ubuntu/Components/pageUtils.js 2015-04-14 21:04:03 +0000
1683@@ -0,0 +1,47 @@
1684+/*
1685+ * Copyright 2015 Canonical Ltd.
1686+ *
1687+ * This program is free software; you can redistribute it and/or modify
1688+ * it under the terms of the GNU Lesser General Public License as published by
1689+ * the Free Software Foundation; version 3.
1690+ *
1691+ * This program is distributed in the hope that it will be useful,
1692+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1693+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1694+ * GNU Lesser General Public License for more details.
1695+ *
1696+ * You should have received a copy of the GNU Lesser General Public License
1697+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1698+ */
1699+
1700+/*!
1701+ Return true if the object is a Flickable that can be flicked in vertical direction.
1702+ */
1703+function isVerticalFlickable(object) {
1704+ if (object && object.hasOwnProperty("flickableDirection") && object.hasOwnProperty("contentHeight")) {
1705+ var direction = object.flickableDirection;
1706+ if ( ((direction === Flickable.AutoFlickDirection) && (object.contentHeight !== object.height) )
1707+ || direction === Flickable.VerticalFlick
1708+ || direction === Flickable.HorizontalAndVerticalFlick) {
1709+ return true;
1710+ }
1711+ }
1712+ return false;
1713+}
1714+
1715+/*!
1716+ Return the first child of the item that is flickable in the vertical direction.
1717+ */
1718+function getFlickableChild(item) {
1719+ if (item && item.hasOwnProperty("children")) {
1720+ for (var i=0; i < item.children.length; i++) {
1721+ var child = item.children[i];
1722+ if (isVerticalFlickable(child)) {
1723+ if (child.anchors.top === page.top || child.anchors.fill === page) {
1724+ return item.children[i];
1725+ }
1726+ }
1727+ }
1728+ }
1729+ return null;
1730+}
1731
1732=== modified file 'modules/Ubuntu/Components/plugin/plugin.cpp'
1733--- modules/Ubuntu/Components/plugin/plugin.cpp 2015-03-04 19:07:58 +0000
1734+++ modules/Ubuntu/Components/plugin/plugin.cpp 2015-04-14 21:04:03 +0000
1735@@ -1,5 +1,5 @@
1736 /*
1737- * Copyright 2012-2014 Canonical Ltd.
1738+ * Copyright 2015 Canonical Ltd.
1739 *
1740 * This program is free software; you can redistribute it and/or modify
1741 * it under the terms of the GNU Lesser General Public License as published by
1742@@ -13,7 +13,6 @@
1743 * You should have received a copy of the GNU Lesser General Public License
1744 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1745 *
1746- * Author: Juhapekka Piiroinen <juhapekka.piiroinen@canonical.com>
1747 */
1748
1749 #include <QtQuick/private/qquickimagebase_p.h>
1750@@ -23,6 +22,7 @@
1751
1752 #include "plugin.h"
1753 #include "uctheme.h"
1754+#include "ucdeprecatedtheme.h"
1755
1756 #include <QtQml/QQmlContext>
1757 #include "i18n.h"
1758@@ -189,6 +189,10 @@
1759 qmlRegisterSingletonType<UCNamespace>(uri, 1, 2, "Ubuntu", registerUbuntuNamespace);
1760 qmlRegisterType<UCUbuntuShape, 1>(uri, 1, 2, "UbuntuShape");
1761 qmlRegisterType<UCUbuntuShapeOverlay>(uri, 1, 2, "UbuntuShapeOverlay");
1762+
1763+ // register 1.3 API
1764+ qmlRegisterType<UCTheme>(uri, 1, 3, "ThemeSettings");
1765+ qmlRegisterType<UCStyledItemBase, 2>(uri, 1, 3, "StyledItemBase");
1766 }
1767
1768 void UbuntuComponentsPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
1769@@ -207,7 +211,10 @@
1770 // that can be accessed from any object
1771 context->setContextProperty("QuickUtils", &QuickUtils::instance());
1772
1773- UCTheme::instance().registerToContext(context);
1774+ // register theme context property
1775+ UCTheme::registerToContext(context);
1776+
1777+ UCDeprecatedTheme::instance().registerToContext(context);
1778
1779 context->setContextProperty("i18n", &UbuntuI18n::instance());
1780 ContextPropertyChangeListener *i18nChangeListener =
1781
1782=== modified file 'modules/Ubuntu/Components/plugin/plugin.pro'
1783--- modules/Ubuntu/Components/plugin/plugin.pro 2015-03-04 19:07:58 +0000
1784+++ modules/Ubuntu/Components/plugin/plugin.pro 2015-04-14 21:04:03 +0000
1785@@ -26,7 +26,6 @@
1786
1787 HEADERS += plugin.h \
1788 uctheme.h \
1789- ucthemesettings.h \
1790 i18n.h \
1791 listener.h \
1792 ucscalingimageprovider.h \
1793@@ -79,11 +78,12 @@
1794 ucserviceproperties_p.h \
1795 privates/listitemdragarea.h \
1796 privates/listitemdraghandler.h \
1797- ucnamespace.h
1798+ ucnamespace.h \
1799+ ucdeprecatedtheme.h \
1800+ ucdefaulttheme.h
1801
1802 SOURCES += plugin.cpp \
1803 uctheme.cpp \
1804- ucthemesettings.cpp \
1805 i18n.cpp \
1806 listener.cpp \
1807 ucscalingimageprovider.cpp \
1808@@ -126,7 +126,9 @@
1809 ucserviceproperties.cpp \
1810 privates/listitemdragarea.cpp \
1811 privates/listitemdraghandler.cpp \
1812- ucnamespace.cpp
1813+ ucnamespace.cpp \
1814+ ucdeprecatedtheme.cpp \
1815+ ucdefaulttheme.cpp
1816
1817 # adapters
1818 SOURCES += adapters/alarmsadapter_organizer.cpp
1819
1820=== modified file 'modules/Ubuntu/Components/plugin/shaders/shape.vert'
1821--- modules/Ubuntu/Components/plugin/shaders/shape.vert 2015-01-29 17:16:40 +0000
1822+++ modules/Ubuntu/Components/plugin/shaders/shape.vert 2015-04-14 21:04:03 +0000
1823@@ -14,10 +14,10 @@
1824 //
1825 // Author: Loïc Molinari <loic.molinari@canonical.com>
1826
1827-uniform mediump mat4 matrix;
1828+uniform highp mat4 matrix; // mediump was interpreted as lowp on PowerVR Rogue G6200 (arale).
1829 uniform bool textured;
1830
1831-attribute mediump vec4 positionAttrib;
1832+attribute highp vec4 positionAttrib; // highp because of matrix precision qualifier.
1833 attribute mediump vec2 shapeCoordAttrib;
1834 attribute mediump vec4 sourceCoordAttrib;
1835 attribute lowp vec4 backgroundColorAttrib;
1836
1837=== modified file 'modules/Ubuntu/Components/plugin/shaders/shapeoverlay.vert'
1838--- modules/Ubuntu/Components/plugin/shaders/shapeoverlay.vert 2015-01-29 18:08:38 +0000
1839+++ modules/Ubuntu/Components/plugin/shaders/shapeoverlay.vert 2015-04-14 21:04:03 +0000
1840@@ -14,10 +14,10 @@
1841 //
1842 // Author: Loïc Molinari <loic.molinari@canonical.com>
1843
1844-uniform mediump mat4 matrix;
1845+uniform highp mat4 matrix; // mediump was interpreted as lowp on PowerVR Rogue G6200 (arale).
1846 uniform bool textured;
1847
1848-attribute mediump vec4 positionAttrib;
1849+attribute highp vec4 positionAttrib; // highp because of matrix precision qualifier.
1850 attribute mediump vec2 shapeCoordAttrib;
1851 attribute mediump vec4 sourceCoordAttrib;
1852 attribute lowp vec4 backgroundColorAttrib;
1853
1854=== renamed file 'modules/Ubuntu/Components/plugin/ucthemesettings.cpp' => 'modules/Ubuntu/Components/plugin/ucdefaulttheme.cpp'
1855--- modules/Ubuntu/Components/plugin/ucthemesettings.cpp 2015-01-20 10:33:29 +0000
1856+++ modules/Ubuntu/Components/plugin/ucdefaulttheme.cpp 2015-04-14 21:04:03 +0000
1857@@ -1,5 +1,5 @@
1858 /*
1859- * Copyright 2013 Canonical Ltd.
1860+ * Copyright 2013-2015 Canonical Ltd.
1861 *
1862 * This program is free software; you can redistribute it and/or modify
1863 * it under the terms of the GNU Lesser General Public License as published by
1864@@ -17,7 +17,7 @@
1865 * Florian Boucault <florian.boucault@canonical.com>
1866 */
1867
1868-#include "ucthemesettings.h"
1869+#include "ucdefaulttheme.h"
1870 #include "uctheme.h"
1871
1872 #include <QDebug>
1873@@ -34,12 +34,12 @@
1874 const QString THEME_KEY("theme");
1875 const QString DEFAULT_THEME("Ubuntu.Components.Themes.Ambiance");
1876
1877-UCThemeSettings::UCThemeSettings(QObject *parent) :
1878+UCDefaultTheme::UCDefaultTheme(QObject *parent) :
1879 QObject(parent),
1880 m_settings(SETTINGS_FILE_FORMAT.arg(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation)), QSettings::IniFormat)
1881 {
1882 // fundamental features rely on the default theme, so bail out if it's absent
1883- if (UCTheme::pathFromThemeName(DEFAULT_THEME).isEmpty()) {
1884+ if (pathFromThemeName(DEFAULT_THEME).isEmpty()) {
1885 qWarning() << "Mandatory default theme" << DEFAULT_THEME << "missing!";
1886 }
1887
1888@@ -51,11 +51,11 @@
1889 }
1890
1891 QObject::connect(&m_settingsFileWatcher, &QFileSystemWatcher::fileChanged,
1892- this, &UCThemeSettings::reloadSettings);
1893+ this, &UCDefaultTheme::reloadSettings);
1894 reloadSettings();
1895 }
1896
1897-void UCThemeSettings::reloadSettings()
1898+void UCDefaultTheme::reloadSettings()
1899 {
1900 m_settings.sync();
1901 m_settingsFileWatcher.addPath(m_settings.fileName());
1902@@ -67,12 +67,12 @@
1903 }
1904 }
1905
1906-QString UCThemeSettings::themeName() const
1907+QString UCDefaultTheme::themeName() const
1908 {
1909 return m_themeName;
1910 }
1911
1912-void UCThemeSettings::setThemeName(const QString &themeName)
1913+void UCDefaultTheme::setThemeName(const QString &themeName)
1914 {
1915 if (themeName != m_themeName) {
1916 m_themeName = themeName;
1917
1918=== renamed file 'modules/Ubuntu/Components/plugin/ucthemesettings.h' => 'modules/Ubuntu/Components/plugin/ucdefaulttheme.h'
1919--- modules/Ubuntu/Components/plugin/ucthemesettings.h 2013-10-18 08:56:39 +0000
1920+++ modules/Ubuntu/Components/plugin/ucdefaulttheme.h 2015-04-14 21:04:03 +0000
1921@@ -1,5 +1,5 @@
1922 /*
1923- * Copyright 2013 Canonical Ltd.
1924+ * Copyright 2013-2015 Canonical Ltd.
1925 *
1926 * This program is free software; you can redistribute it and/or modify
1927 * it under the terms of the GNU Lesser General Public License as published by
1928@@ -17,20 +17,20 @@
1929 * Florian Boucault <florian.boucault@canonical.com>
1930 */
1931
1932-#ifndef UCTHEMESETTINGS_H
1933-#define UCTHEMESETTINGS_H
1934+#ifndef UCDEFAULTTHEME_H
1935+#define UCDEFAULTTHEME_H
1936
1937 #include <QtCore/QFileSystemWatcher>
1938 #include <QtCore/QSettings>
1939 #include <QtCore/QObject>
1940
1941-class UCThemeSettings : public QObject
1942+class UCDefaultTheme : public QObject
1943 {
1944 Q_OBJECT
1945
1946 Q_PROPERTY(QString themeName READ themeName WRITE setThemeName NOTIFY themeNameChanged)
1947 public:
1948- explicit UCThemeSettings(QObject *parent = 0);
1949+ explicit UCDefaultTheme(QObject *parent = 0);
1950
1951 // getter/setters
1952 QString themeName() const;
1953@@ -47,4 +47,4 @@
1954 QString m_themeName;
1955 };
1956
1957-#endif // UCTHEMESETTINGS_H
1958+#endif // UCDEFAULTTHEME_H
1959
1960=== added file 'modules/Ubuntu/Components/plugin/ucdeprecatedtheme.cpp'
1961--- modules/Ubuntu/Components/plugin/ucdeprecatedtheme.cpp 1970-01-01 00:00:00 +0000
1962+++ modules/Ubuntu/Components/plugin/ucdeprecatedtheme.cpp 2015-04-14 21:04:03 +0000
1963@@ -0,0 +1,122 @@
1964+/*
1965+ * Copyright 2015 Canonical Ltd.
1966+ *
1967+ * This program is free software; you can redistribute it and/or modify
1968+ * it under the terms of the GNU Lesser General Public License as published by
1969+ * the Free Software Foundation; version 3.
1970+ *
1971+ * This program is distributed in the hope that it will be useful,
1972+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1973+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1974+ * GNU Lesser General Public License for more details.
1975+ *
1976+ * You should have received a copy of the GNU Lesser General Public License
1977+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1978+ *
1979+ * Authors: Zsombor Egri <zsombor.egri@canonical.com>
1980+ */
1981+
1982+#include "ucdeprecatedtheme.h"
1983+#include "uctheme.h"
1984+#include "listener.h"
1985+#include <QtQml/QQmlComponent>
1986+#include <QtQml/QQmlContext>
1987+#include <QtQml/QQmlInfo>
1988+
1989+/*!
1990+ \qmltype Theme
1991+ \instantiates UCTheme
1992+ \inqmlmodule Ubuntu.Components 1.1
1993+ \ingroup theming
1994+ \brief The Theme class provides facilities to interact with the current theme.
1995+
1996+ A global instance is exposed as the \b Theme context property.
1997+
1998+ The theme defines the visual aspect of the Ubuntu components.
1999+
2000+ Example changing the current theme:
2001+
2002+ \qml
2003+ import QtQuick 2.4
2004+ import Ubuntu.Components 1.2
2005+
2006+ Item {
2007+ Button {
2008+ onClicked: Theme.name = "Ubuntu.Components.Themes.Ambiance"
2009+ }
2010+ }
2011+ \endqml
2012+
2013+ Example creating a style component:
2014+
2015+ \qml
2016+ import QtQuick 2.4
2017+ import Ubuntu.Components 1.2
2018+
2019+ StyledItem {
2020+ id: myItem
2021+ style: Theme.createStyleComponent("MyItemStyle.qml", myItem)
2022+ }
2023+ \endqml
2024+
2025+ \sa {StyledItem}
2026+*/
2027+UCDeprecatedTheme::UCDeprecatedTheme(QObject *parent)
2028+ : QObject(parent)
2029+{
2030+ connect(&UCTheme::defaultTheme(), &UCTheme::nameChanged,
2031+ this, &UCDeprecatedTheme::nameChanged);
2032+ connect(&UCTheme::defaultTheme(), &UCTheme::paletteChanged,
2033+ this, &UCDeprecatedTheme::paletteChanged);
2034+}
2035+
2036+/*!
2037+ \qmlproperty string Theme::name
2038+
2039+ The name of the current theme.
2040+*/
2041+QString UCDeprecatedTheme::name() const
2042+{
2043+ return UCTheme::defaultTheme().name();
2044+}
2045+void UCDeprecatedTheme::setName(const QString& name)
2046+{
2047+ UCTheme::defaultTheme().setName(name);
2048+}
2049+void UCDeprecatedTheme::resetName()
2050+{
2051+ UCTheme::defaultTheme().resetName();
2052+}
2053+
2054+/*!
2055+ \qmlproperty Palette Theme::palette
2056+
2057+ The palette of the current theme.
2058+*/
2059+QObject* UCDeprecatedTheme::palette()
2060+{
2061+ return UCTheme::defaultTheme().palette();
2062+}
2063+
2064+/*!
2065+ \qmlmethod Component Theme::createStyleComponent(string styleName, object parent)
2066+
2067+ Returns an instance of the style component named \a styleName.
2068+*/
2069+QQmlComponent* UCDeprecatedTheme::createStyleComponent(const QString& styleName, QObject* parent)
2070+{
2071+ return UCTheme::defaultTheme().createStyleComponent(styleName, parent);
2072+}
2073+
2074+void UCDeprecatedTheme::registerToContext(QQmlContext* context)
2075+{
2076+ UCTheme::defaultTheme().m_engine = context->engine();
2077+ UCTheme::defaultTheme().updateEnginePaths();
2078+ // register deprecated Theme property
2079+ context->setContextProperty("Theme", this);
2080+
2081+ ContextPropertyChangeListener *themeChangeListener =
2082+ new ContextPropertyChangeListener(context, "Theme");
2083+ QObject::connect(this, SIGNAL(nameChanged()),
2084+ themeChangeListener, SLOT(updateContextProperty()));
2085+}
2086
2087=== added file 'modules/Ubuntu/Components/plugin/ucdeprecatedtheme.h'
2088--- modules/Ubuntu/Components/plugin/ucdeprecatedtheme.h 1970-01-01 00:00:00 +0000
2089+++ modules/Ubuntu/Components/plugin/ucdeprecatedtheme.h 2015-04-14 21:04:03 +0000
2090@@ -0,0 +1,53 @@
2091+/*
2092+ * Copyright 2015 Canonical Ltd.
2093+ *
2094+ * This program is free software; you can redistribute it and/or modify
2095+ * it under the terms of the GNU Lesser General Public License as published by
2096+ * the Free Software Foundation; version 3.
2097+ *
2098+ * This program is distributed in the hope that it will be useful,
2099+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2100+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2101+ * GNU Lesser General Public License for more details.
2102+ *
2103+ * You should have received a copy of the GNU Lesser General Public License
2104+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2105+ *
2106+ * Authors: Zsombor Egri <zsombor.egri@canonical.com>
2107+ */
2108+
2109+#ifndef UCDEPRECATEDTHEME_H
2110+#define UCDEPRECATEDTHEME_H
2111+
2112+#include <QtCore/QObject>
2113+
2114+class QQmlComponent;
2115+class QQmlContext;
2116+class UCTheme;
2117+class UCDeprecatedTheme : public QObject
2118+{
2119+ Q_OBJECT
2120+ Q_PROPERTY(QString name READ name WRITE setName RESET resetName NOTIFY nameChanged)
2121+ Q_PROPERTY(QObject* palette READ palette NOTIFY paletteChanged)
2122+public:
2123+ static UCDeprecatedTheme& instance() {
2124+ static UCDeprecatedTheme instance;
2125+ return instance;
2126+ }
2127+ explicit UCDeprecatedTheme(QObject *parent = 0);
2128+
2129+ // getter/setters
2130+ QString name() const;
2131+ void setName(const QString& name);
2132+ void resetName();
2133+ QObject* palette();
2134+
2135+ Q_INVOKABLE QQmlComponent* createStyleComponent(const QString& styleName, QObject* parent);
2136+ void registerToContext(QQmlContext* context);
2137+
2138+Q_SIGNALS:
2139+ void nameChanged();
2140+ void paletteChanged();
2141+};
2142+
2143+#endif // UCDEPRECATEDTHEME_H
2144
2145=== modified file 'modules/Ubuntu/Components/plugin/uclistitem.cpp'
2146--- modules/Ubuntu/Components/plugin/uclistitem.cpp 2015-03-03 13:47:48 +0000
2147+++ modules/Ubuntu/Components/plugin/uclistitem.cpp 2015-04-14 21:04:03 +0000
2148@@ -15,7 +15,7 @@
2149 */
2150
2151 #include "ucunits.h"
2152-#include "uctheme.h"
2153+#include "ucdeprecatedtheme.h"
2154 #include "uclistitem.h"
2155 #include "uclistitem_p.h"
2156 #include "uclistitemactions.h"
2157@@ -40,7 +40,8 @@
2158 QColor getPaletteColor(const char *profile, const char *color)
2159 {
2160 QColor result;
2161- QObject *palette = UCTheme::instance().palette();
2162+ // FIXME: use theme when available
2163+ QObject *palette = UCDeprecatedTheme::instance().palette();
2164 if (palette) {
2165 QObject *paletteProfile = palette->property(profile).value<QObject*>();
2166 if (paletteProfile) {
2167@@ -237,7 +238,8 @@
2168 q, SLOT(_q_updateSwiping()), Qt::DirectConnection);
2169
2170 // catch theme changes
2171- QObject::connect(&UCTheme::instance(), SIGNAL(nameChanged()), q, SLOT(_q_updateThemedData()));
2172+ // FIXME: use theme when available
2173+ QObject::connect(&UCDeprecatedTheme::instance(), SIGNAL(nameChanged()), q, SLOT(_q_updateThemedData()));
2174 _q_updateThemedData();
2175
2176 // watch grid unit size change and set implicit size
2177@@ -379,7 +381,8 @@
2178 }
2179 delete implicitStyleComponent;
2180 Q_Q(UCListItem);
2181- implicitStyleComponent = UCTheme::instance().createStyleComponent("ListItemStyle.qml", q);
2182+ // FIXME: use theme when available
2183+ implicitStyleComponent = UCDeprecatedTheme::instance().createStyleComponent("ListItemStyle.qml", q);
2184 if (implicitStyleComponent) {
2185 // set the objectnane for testing in tst_listitems.qml
2186 implicitStyleComponent->setObjectName("ListItemThemeStyle");
2187
2188=== modified file 'modules/Ubuntu/Components/plugin/ucstyleditembase.cpp'
2189--- modules/Ubuntu/Components/plugin/ucstyleditembase.cpp 2015-03-03 13:47:48 +0000
2190+++ modules/Ubuntu/Components/plugin/ucstyleditembase.cpp 2015-04-14 21:04:03 +0000
2191@@ -1,5 +1,5 @@
2192 /*
2193- * Copyright 2014 Canonical Ltd.
2194+ * Copyright 2015 Canonical Ltd.
2195 *
2196 * This program is free software; you can redistribute it and/or modify
2197 * it under the terms of the GNU Lesser General Public License as published by
2198@@ -18,9 +18,13 @@
2199
2200 #include "ucstyleditembase.h"
2201 #include "ucstyleditembase_p.h"
2202+#include "uctheme.h"
2203
2204 UCStyledItemBasePrivate::UCStyledItemBasePrivate()
2205 : activeFocusOnPress(false)
2206+ , subthemingEnabled(true)
2207+ , theme(0)
2208+ , parentStyledItem(0)
2209 {
2210 }
2211
2212@@ -32,6 +36,16 @@
2213 {
2214 Q_Q(UCStyledItemBase);
2215 q->setFlag(QQuickItem::ItemIsFocusScope);
2216+ QByteArray env = qgetenv("UITK_SUBTHEMING");
2217+ subthemingEnabled = (env.isEmpty() || env == QByteArrayLiteral("yes"));
2218+ if (!subthemingEnabled) {
2219+ // every theme will be using the default theme
2220+ theme = &UCTheme::defaultTheme();
2221+ QObject::connect(theme, &UCTheme::nameChanged, q, &UCStyledItemBase::themeChanged);
2222+ } else {
2223+ QObject::connect(&UCTheme::defaultTheme(), &UCTheme::nameChanged,
2224+ q, &UCStyledItemBase::themeChanged);
2225+ }
2226 }
2227
2228
2229@@ -48,7 +62,7 @@
2230 if (!activeFocusOnPress) {
2231 return false;
2232 }
2233- QQuickItem *pl = q->parentItem();
2234+ QQuickItem *pl = parentItem;
2235 while (pl) {
2236 UCStyledItemBase *scope = qobject_cast<UCStyledItemBase*>(pl);
2237 if (scope) {
2238@@ -168,6 +182,189 @@
2239 Q_EMIT activeFocusOnPressChanged();
2240 }
2241
2242+/*!
2243+ * \qmlproperty ThemeSettings StyledItem::theme
2244+ * \since Ubuntu.Components 1.3
2245+ * The property configures the theme the component and all its sub-components
2246+ * will use. By default it is set to the closest ancestor StyledItem's theme
2247+ * if any, or to the system default theme.
2248+ */
2249+UCTheme *UCStyledItemBasePrivate::getTheme() const
2250+{
2251+ if (subthemingEnabled) {
2252+ if (theme) {
2253+ return theme;
2254+ } else if (!parentStyledItem.isNull()) {
2255+ return UCStyledItemBasePrivate::get(parentStyledItem)->getTheme();
2256+ }
2257+ }
2258+ return &UCTheme::defaultTheme();
2259+}
2260+void UCStyledItemBasePrivate::setTheme(UCTheme *newTheme)
2261+{
2262+ Q_Q(UCStyledItemBase);
2263+ if (theme == newTheme) {
2264+ return;
2265+ }
2266+
2267+ if (!subthemingEnabled) {
2268+ // no subtheming
2269+ if (newTheme) {
2270+ theme = newTheme;
2271+ UCTheme::defaultTheme().setName(theme->name());
2272+ } else {
2273+ UCTheme::defaultTheme().resetName();
2274+ }
2275+ return;
2276+ }
2277+
2278+ // disconnect from the previous set
2279+ UCTheme *connectedSet = theme ?
2280+ theme :
2281+ (!parentStyledItem ? &UCTheme::defaultTheme() : NULL);
2282+ if (connectedSet) {
2283+ QObject::disconnect(connectedSet, &UCTheme::nameChanged,
2284+ q, &UCStyledItemBase::themeChanged);
2285+ }
2286+
2287+ UCTheme *prevSet = theme;
2288+
2289+ // resolve new theme
2290+ if (theme && newTheme) {
2291+ // no need to redo the parentStack, simply set the theme and leave
2292+ theme = newTheme;
2293+ } else {
2294+ theme = newTheme;
2295+ if (!newTheme) {
2296+ // redo the parent chanin
2297+ disconnectTillItem(0);
2298+ connectParents(0);
2299+ }
2300+ }
2301+
2302+ // connect to the new set
2303+ connectedSet = theme ?
2304+ theme :
2305+ (!parentStyledItem ? &UCTheme::defaultTheme() : NULL);
2306+ if (connectedSet) {
2307+ QObject::connect(connectedSet, &UCTheme::nameChanged,
2308+ q, &UCStyledItemBase::themeChanged);
2309+ }
2310+ // detach previous set and attach the new one
2311+ if (prevSet) {
2312+ Q_EMIT prevSet->parentThemeChanged();
2313+ }
2314+ if (theme) {
2315+ // re-parent theme to make sure we have it
2316+ // for the entire lifetime of the styled item
2317+ theme->setParent(q);
2318+ Q_EMIT theme->parentThemeChanged();
2319+ }
2320+
2321+ Q_EMIT q->themeChanged();
2322+}
2323+void UCStyledItemBasePrivate::resetTheme()
2324+{
2325+ setTheme(NULL);
2326+}
2327+
2328+// link/unlink all ascendant items until we reach a StyledItem, returns true if the
2329+// theme change signal emission is justified
2330+bool UCStyledItemBasePrivate::connectParents(QQuickItem *fromItem)
2331+{
2332+ Q_Q(UCStyledItemBase);
2333+ QQuickItem *item = fromItem ? fromItem : parentItem;
2334+ while (item) {
2335+ // push the item onto the stack
2336+ parentStack.push(QPointer<QQuickItem>(item));
2337+ UCStyledItemBase *styledItem = qobject_cast<UCStyledItemBase*>(item);
2338+ if (styledItem) {
2339+ // this is the closest StyledItem, connect its themeChanged() signal
2340+ QObject::connect(styledItem, SIGNAL(themeChanged()),
2341+ q, SLOT(_q_parentStyleChanged()), Qt::DirectConnection);
2342+ // set the current style set to the one in the parent's one if differs
2343+ return setParentStyled(styledItem);
2344+ } else {
2345+ // connect to the item's parentChanged() signal so we can detect when the parent changes
2346+ QObject::connect(item, SIGNAL(parentChanged(QQuickItem*)),
2347+ q, SLOT(_q_ascendantChanged(QQuickItem*)), Qt::DirectConnection);
2348+ }
2349+ item = item->parentItem();
2350+ }
2351+ return false;
2352+}
2353+
2354+// set the used parent styled item's style; returns true if the parent styled got changed
2355+bool UCStyledItemBasePrivate::setParentStyled(UCStyledItemBase *styledItem)
2356+{
2357+ if (parentStyledItem == styledItem) {
2358+ return false;
2359+ }
2360+ parentStyledItem = styledItem;
2361+ if (theme) {
2362+ Q_EMIT theme->parentThemeChanged();
2363+ }
2364+ return (theme == NULL);
2365+}
2366+
2367+// disconnect parent stack till item is reached; all the stack if item == 0
2368+void UCStyledItemBasePrivate::disconnectTillItem(QQuickItem *item)
2369+{
2370+ if (!subthemingEnabled) {
2371+ return;
2372+ }
2373+ Q_Q(UCStyledItemBase);
2374+ while (!parentStack.isEmpty() && item != parentStack.top()) {
2375+ QPointer<QQuickItem> stackItem = parentStack.pop();
2376+ // the topmost item can be the only one which is a StyledItem
2377+ UCStyledItemBase *styledItem = qobject_cast<UCStyledItemBase*>(stackItem.data());
2378+ if (styledItem) {
2379+ QObject::disconnect(styledItem, SIGNAL(themeChanged()),
2380+ q, SLOT(_q_parentStyleChanged()));
2381+ } else if (!stackItem.isNull()) {
2382+ QObject::disconnect(stackItem.data(), SIGNAL(parentChanged(QQuickItem*)),
2383+ q, SLOT(_q_ascendantChanged(QQuickItem*)));
2384+ }
2385+ }
2386+}
2387+
2388+// captures ascendant change signal, the sender is the one which counts!
2389+void UCStyledItemBasePrivate::_q_ascendantChanged(QQuickItem *ascendant)
2390+{
2391+ Q_Q(UCStyledItemBase);
2392+ QQuickItem *sender = static_cast<QQuickItem*>(q->sender());
2393+ if (!sender) {
2394+ // cannot detect the sender, leave!
2395+ return;
2396+ }
2397+ if (ascendant) {
2398+ // disconnect from the previous ones
2399+ disconnectTillItem(sender);
2400+ // traverse ascendants till we reach a StyledItem or root and push them into the stack
2401+ if (connectParents(ascendant)) {
2402+ Q_EMIT q->themeChanged();
2403+ }
2404+ }
2405+}
2406+
2407+// syncs the ascendant StyledItem's style
2408+void UCStyledItemBasePrivate::_q_parentStyleChanged()
2409+{
2410+ // do not trigger themeChanged() on this item if we have a
2411+ // custom one, but resolve its eventual parent change!
2412+ if (theme) {
2413+ Q_EMIT theme->parentThemeChanged();
2414+ return;
2415+ }
2416+ Q_Q(UCStyledItemBase);
2417+ UCStyledItemBase *styledItem = static_cast<UCStyledItemBase*>(q->sender());
2418+ if (!styledItem) {
2419+ return;
2420+ }
2421+ setParentStyled(styledItem);
2422+ Q_EMIT q->themeChanged();
2423+}
2424+
2425 // grab pressed state and focus if it can be
2426 void UCStyledItemBase::mousePressEvent(QMouseEvent *event)
2427 {
2428@@ -194,4 +391,18 @@
2429 return QQuickItem::childMouseEventFilter(child, event);
2430 }
2431
2432+// catch parent change event so we can lookup for the parent chain theme
2433+void UCStyledItemBase::itemChange(ItemChange change, const ItemChangeData &data)
2434+{
2435+ QQuickItem::itemChange(change, data);
2436+ Q_D(UCStyledItemBase);
2437+ if (change == ItemParentHasChanged && d->subthemingEnabled) {
2438+ if (!data.item) {
2439+ d->disconnectTillItem(0);
2440+ } else if (d->connectParents(0)) {
2441+ Q_EMIT themeChanged();
2442+ }
2443+ }
2444+}
2445+
2446 #include "moc_ucstyleditembase.cpp"
2447
2448=== modified file 'modules/Ubuntu/Components/plugin/ucstyleditembase.h'
2449--- modules/Ubuntu/Components/plugin/ucstyleditembase.h 2014-09-02 05:52:32 +0000
2450+++ modules/Ubuntu/Components/plugin/ucstyleditembase.h 2015-04-14 21:04:03 +0000
2451@@ -1,5 +1,5 @@
2452 /*
2453- * Copyright 2014 Canonical Ltd.
2454+ * Copyright 2015 Canonical Ltd.
2455 *
2456 * This program is free software; you can redistribute it and/or modify
2457 * it under the terms of the GNU Lesser General Public License as published by
2458@@ -22,12 +22,14 @@
2459 #include <QtQuick/QQuickItem>
2460
2461 class UCStyledItemBasePrivate;
2462+class UCTheme;
2463 class UCStyledItemBase : public QQuickItem
2464 {
2465 Q_OBJECT
2466 Q_PROPERTY(bool activeFocusOnPress
2467 READ activefocusOnPress WRITE setActiveFocusOnPress
2468 NOTIFY activeFocusOnPressChanged REVISION 1)
2469+ Q_PRIVATE_PROPERTY(d_func(), UCTheme *theme READ getTheme WRITE setTheme RESET resetTheme NOTIFY themeChanged REVISION 2)
2470 public:
2471 explicit UCStyledItemBase(QQuickItem *parent = 0);
2472
2473@@ -39,15 +41,19 @@
2474
2475 Q_SIGNALS:
2476 void activeFocusOnPressChanged();
2477+ Q_REVISION(2) void themeChanged();
2478
2479 protected:
2480 UCStyledItemBase(UCStyledItemBasePrivate &, QQuickItem *parent);
2481
2482 void mousePressEvent(QMouseEvent *event);
2483 bool childMouseEventFilter(QQuickItem *child, QEvent *event);
2484+ void itemChange(ItemChange, const ItemChangeData &);
2485
2486 private:
2487 Q_DECLARE_PRIVATE(UCStyledItemBase)
2488+ Q_PRIVATE_SLOT(d_func(), void _q_ascendantChanged(QQuickItem*))
2489+ Q_PRIVATE_SLOT(d_func(), void _q_parentStyleChanged())
2490 };
2491
2492 #endif // UCSTYLEDITEMBASE_H
2493
2494=== modified file 'modules/Ubuntu/Components/plugin/ucstyleditembase_p.h'
2495--- modules/Ubuntu/Components/plugin/ucstyleditembase_p.h 2014-08-20 12:56:51 +0000
2496+++ modules/Ubuntu/Components/plugin/ucstyleditembase_p.h 2015-04-14 21:04:03 +0000
2497@@ -1,5 +1,5 @@
2498 /*
2499- * Copyright 2014 Canonical Ltd.
2500+ * Copyright 2015 Canonical Ltd.
2501 *
2502 * This program is free software; you can redistribute it and/or modify
2503 * it under the terms of the GNU Lesser General Public License as published by
2504@@ -20,6 +20,7 @@
2505 #define UCSTYLEDITEMBASE_P_H
2506
2507 #include <QtQuick/private/qquickitem_p.h>
2508+#include "ucstyleditembase.h"
2509
2510 class QQuickMouseArea;
2511 class UCStyledItemBase;
2512@@ -32,6 +33,9 @@
2513 return item->d_func();
2514 }
2515
2516+ void _q_ascendantChanged(QQuickItem *ascendant);
2517+ void _q_parentStyleChanged();
2518+
2519 UCStyledItemBasePrivate();
2520 virtual ~UCStyledItemBasePrivate();
2521 void init();
2522@@ -39,8 +43,22 @@
2523 virtual void setFocusable(bool focus);
2524 bool isParentFocusable();
2525
2526+ UCTheme *getTheme() const;
2527+ void setTheme(UCTheme *styleSet);
2528+ void resetTheme();
2529+
2530 public:
2531 bool activeFocusOnPress:1;
2532+ bool subthemingEnabled:1;
2533+ UCTheme *theme;
2534+ QPointer<UCStyledItemBase> parentStyledItem;
2535+
2536+private:
2537+ QStack< QPointer<QQuickItem> > parentStack;
2538+
2539+ bool connectParents(QQuickItem *fromItem);
2540+ bool setParentStyled(UCStyledItemBase *styledItem);
2541+ void disconnectTillItem(QQuickItem *item);
2542 };
2543
2544 #endif // UCSTYLEDITEMBASE_P_H
2545
2546=== modified file 'modules/Ubuntu/Components/plugin/uctheme.cpp'
2547--- modules/Ubuntu/Components/plugin/uctheme.cpp 2015-03-03 13:47:48 +0000
2548+++ modules/Ubuntu/Components/plugin/uctheme.cpp 2015-04-14 21:04:03 +0000
2549@@ -1,5 +1,5 @@
2550 /*
2551- * Copyright 2013 Canonical Ltd.
2552+ * Copyright 2015 Canonical Ltd.
2553 *
2554 * This program is free software; you can redistribute it and/or modify
2555 * it under the terms of the GNU Lesser General Public License as published by
2556@@ -22,12 +22,12 @@
2557 #include "quickutils.h"
2558 #include "i18n.h"
2559 #include "ucfontutils.h"
2560+#include "ucstyleditembase_p.h"
2561
2562 #include <QtQml/qqml.h>
2563 #include <QtQml/qqmlinfo.h>
2564 #include <QtQml/QQmlEngine>
2565 #include <QtQml/QQmlContext>
2566-#include <QtCore/QDebug>
2567 #include <QtCore/QDir>
2568 #include <QtCore/QFile>
2569 #include <QtCore/QTextStream>
2570@@ -37,43 +37,100 @@
2571 #include <QtGui/QFont>
2572
2573 /*!
2574- \qmltype Theme
2575- \instantiates UCTheme
2576- \inqmlmodule Ubuntu.Components 1.1
2577- \ingroup theming
2578- \brief The Theme class provides facilities to interact with the current theme.
2579-
2580- A global instance is exposed as the \b Theme context property.
2581-
2582- The theme defines the visual aspect of the Ubuntu components.
2583-
2584- Example changing the current theme:
2585-
2586- \qml
2587- import QtQuick 2.4
2588- import Ubuntu.Components 1.2
2589-
2590- Item {
2591- Button {
2592- onClicked: Theme.name = "Ubuntu.Components.Themes.Ambiance"
2593- }
2594- }
2595- \endqml
2596-
2597- Example creating a style component:
2598-
2599- \qml
2600- import QtQuick 2.4
2601- import Ubuntu.Components 1.2
2602-
2603- StyledItem {
2604- id: myItem
2605- style: Theme.createStyleComponent("MyItemStyle.qml", myItem)
2606- }
2607- \endqml
2608-
2609- \sa {StyledItem}
2610-*/
2611+ * \qmltype ThemeSettings
2612+ * \instantiates UCTheme
2613+ * \inqmlmodule Ubuntu.Components 1.3
2614+ * \since Ubuntu.Components 1.3
2615+ * \ingroup theming
2616+ * \brief The ThemeSettings class provides facilities to define the theme of a
2617+ * StyledItem.
2618+ *
2619+ * A global instance is exposed as the \b theme context property.
2620+ *
2621+ * The theme defines the visual aspect of the Ubuntu components. An application
2622+ * can use one or more theme the same time. The ThemeSettings component provides
2623+ * abilities to change the theme used by the component and all its child components.
2624+ *
2625+ * Changing the theme of the entire application can be achieved by changing
2626+ * the name of the root StyledItem's, i.e. MainView's current theme.
2627+ *
2628+ * \qml
2629+ * import QtQuick 2.4
2630+ * import Ubuntu.Components 1.3
2631+ *
2632+ * MainView {
2633+ * width: units.gu(40)
2634+ * height: units.gu(71)
2635+ *
2636+ * theme.name: "Ubuntu.Components.Themes.Ambiance"
2637+ * }
2638+ * \endqml
2639+ * By default, styled items inherit the theme they use from their closest styled
2640+ * item ancestor. In case the application uses MainView, all components will inherit
2641+ * the theme from the MainView.
2642+ * \qml
2643+ * import QtQuick 2.4
2644+ * import Ubuntu.Components 1.3
2645+ *
2646+ * MainView {
2647+ * width: units.gu(40)
2648+ * height: units.gu(71)
2649+ *
2650+ * Page {
2651+ * title: "Style test"
2652+ * Button {
2653+ * text: theme.name == "Ubuntu.Components.Themes.Ambiance" ?
2654+ * "SuruDark" : "Ambiance"
2655+ * onClicked: theme.name = (text == "Ambiance" ?
2656+ * "Ubuntu.Components.Themes.SuruDark" :
2657+ * "Ubuntu.Components.Themes.Ambiance")
2658+ * }
2659+ * }
2660+ * }
2661+ * \endqml
2662+ * \note In the example above the Button inherits the theme from Page, which
2663+ * inherits it from MainView. Therefore changing the theme name in this way will
2664+ * result in a change of the inherited theme. In case a different theme is desired,
2665+ * a new instance of the ThemeSettings must be created on the styled item desired.
2666+ * \qml
2667+ * import QtQuick 2.4
2668+ * import Ubuntu.Components 1.3
2669+ *
2670+ * MainView {
2671+ * width: units.gu(40)
2672+ * height: units.gu(71)
2673+ *
2674+ * Page {
2675+ * title: "Style test"
2676+ * theme: ThemeSettings{}
2677+ * Button {
2678+ * text: theme.name == "Ubuntu.Components.Themes.Ambiance" ?
2679+ * "SuruDark" : "Ambiance"
2680+ * onClicked: theme.name = (text == "Ambiance" ?
2681+ * "Ubuntu.Components.Themes.SuruDark" :
2682+ * "Ubuntu.Components.Themes.Ambiance")
2683+ * }
2684+ * }
2685+ * }
2686+ * \endqml
2687+ *
2688+ * The \l createStyleComponent function can be used to create the style for a
2689+ * component. The following example will create the style with the inherited
2690+ * theme.
2691+ * \qml
2692+ * import QtQuick 2.4
2693+ * import Ubuntu.Components 1.3
2694+ * StyledItem {
2695+ * id: myItem
2696+ * style: theme.createStyleComponent("MyItemStyle.qml", myItem)
2697+ * }
2698+ * \endqml
2699+ * All styled toolkit components such as \l Button, \l CheckBox, \l Switch, etc.
2700+ * create their style in this way. Note that the style component must be part
2701+ * of the theme, otherwise the style creation will fail.
2702+ *
2703+ * \sa {StyledItem}
2704+ */
2705
2706 const QString THEME_FOLDER_FORMAT("%1/%2/");
2707 const QString PARENT_THEME_FILE("parent_theme");
2708@@ -111,20 +168,53 @@
2709 return result;
2710 }
2711
2712-UCTheme::UCTheme(QObject *parent) :
2713- QObject(parent),
2714- m_palette(NULL),
2715- m_engine(NULL),
2716- m_engineUpdated(false)
2717-{
2718- m_name = m_themeSettings.themeName();
2719- QObject::connect(&m_themeSettings, &UCThemeSettings::themeNameChanged,
2720- this, &UCTheme::onThemeNameChanged);
2721- updateThemePaths();
2722-
2723- QObject::connect(this, SIGNAL(nameChanged()),
2724- this, SLOT(loadPalette()), Qt::UniqueConnection);
2725-
2726+QUrl pathFromThemeName(QString themeName)
2727+{
2728+ themeName.replace('.', '/');
2729+ QStringList pathList = themeSearchPath();
2730+ Q_FOREACH(const QString &path, pathList) {
2731+ QString themeFolder = THEME_FOLDER_FORMAT.arg(path, themeName);
2732+ // QUrl needs a trailing slash to understand it's a directory
2733+ QString absoluteThemeFolder = QDir(themeFolder).absolutePath().append('/');
2734+ if (QDir(absoluteThemeFolder).exists()) {
2735+ return QUrl::fromLocalFile(absoluteThemeFolder);
2736+ }
2737+ }
2738+ return QUrl();
2739+}
2740+
2741+QString parentThemeName(const QString& themeName)
2742+{
2743+ QString parentTheme;
2744+ QUrl themePath = pathFromThemeName(themeName);
2745+ if (!themePath.isValid()) {
2746+ qWarning() << qPrintable(UbuntuI18n::instance().tr("Theme not found: \"%1\"").arg(themeName));
2747+ } else {
2748+ QFile file(themePath.resolved(PARENT_THEME_FILE).toLocalFile());
2749+ if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
2750+ QTextStream in(&file);
2751+ parentTheme = in.readLine();
2752+ }
2753+ }
2754+ return parentTheme;
2755+}
2756+
2757+UCTheme::UCTheme(QObject *parent)
2758+ : QObject(parent)
2759+ , m_palette(UCTheme::defaultTheme().m_palette)
2760+ , m_engine(UCTheme::defaultTheme().m_engine)
2761+ , m_defaultStyle(false)
2762+{
2763+ init();
2764+}
2765+
2766+UCTheme::UCTheme(bool defaultStyle, QObject *parent)
2767+ : QObject(parent)
2768+ , m_palette(NULL)
2769+ , m_engine(NULL)
2770+ , m_defaultStyle(defaultStyle)
2771+{
2772+ init();
2773 // set the default font
2774 QFont defaultFont;
2775 defaultFont.setFamily("Ubuntu");
2776@@ -133,9 +223,24 @@
2777 QGuiApplication::setFont(defaultFont);
2778 }
2779
2780+void UCTheme::init()
2781+{
2782+ m_completed = false;
2783+ QObject::connect(&m_defaultTheme, &UCDefaultTheme::themeNameChanged,
2784+ this, &UCTheme::_q_defaultThemeChanged);
2785+ updateThemePaths();
2786+}
2787+
2788+void UCTheme::classBegin()
2789+{
2790+ m_engine = qmlEngine(this);
2791+ updateEnginePaths();
2792+ loadPalette();
2793+}
2794+
2795 void UCTheme::updateEnginePaths()
2796 {
2797- if (!m_engine || m_engineUpdated) {
2798+ if (!m_engine) {
2799 return;
2800 }
2801
2802@@ -145,38 +250,19 @@
2803 m_engine->addImportPath(path);
2804 }
2805 }
2806- m_engineUpdated = true;
2807-}
2808-
2809-void UCTheme::onThemeNameChanged()
2810-{
2811- if (m_themeSettings.themeName() != m_name) {
2812- m_name = m_themeSettings.themeName();
2813- updateThemePaths();
2814- Q_EMIT nameChanged();
2815- }
2816-}
2817-
2818-QUrl UCTheme::pathFromThemeName(QString themeName)
2819-{
2820- themeName.replace('.', '/');
2821- QStringList pathList = themeSearchPath();
2822- Q_FOREACH(const QString &path, pathList) {
2823- QString themeFolder = THEME_FOLDER_FORMAT.arg(path, themeName);
2824- // QUrl needs a trailing slash to understand it's a directory
2825- QString absoluteThemeFolder = QDir(themeFolder).absolutePath().append('/');
2826- if (QDir(absoluteThemeFolder).exists()) {
2827- return QUrl::fromLocalFile(absoluteThemeFolder);
2828- }
2829- }
2830- return QUrl();
2831+}
2832+
2833+void UCTheme::_q_defaultThemeChanged()
2834+{
2835+ updateThemePaths();
2836+ Q_EMIT nameChanged();
2837 }
2838
2839 void UCTheme::updateThemePaths()
2840 {
2841 m_themePaths.clear();
2842
2843- QString themeName = m_name;
2844+ QString themeName = name();
2845 while (!themeName.isEmpty()) {
2846 QUrl themePath = pathFromThemeName(themeName);
2847 if (themePath.isValid()) {
2848@@ -187,31 +273,53 @@
2849 }
2850
2851 /*!
2852- \qmlproperty string Theme::name
2853+ * \qmlproperty ThemeSettings ThemeSettings::parentTheme
2854+ * \readonly
2855+ * The property specifies the parent ThemeSettings instance.
2856+ */
2857+UCTheme *UCTheme::parentTheme()
2858+{
2859+ UCStyledItemBase *owner = qobject_cast<UCStyledItemBase*>(parent());
2860+ UCStyledItemBasePrivate *pOwner = owner ? UCStyledItemBasePrivate::get(owner) : NULL;
2861+ if (pOwner && pOwner->theme == this && pOwner->parentStyledItem) {
2862+ return UCStyledItemBasePrivate::get(pOwner->parentStyledItem)->getTheme();
2863+ }
2864+ return NULL;
2865+}
2866
2867- The name of the current theme.
2868-*/
2869+/*!
2870+ * \qmlproperty string ThemeSettings::name
2871+ * The name of the current theme in dotted format i.e. "Ubuntu.Components.Themes.Ambiance".
2872+ */
2873 QString UCTheme::name() const
2874 {
2875- return m_name;
2876+ return !m_name.isEmpty() ? m_name : m_defaultTheme.themeName();
2877 }
2878-
2879 void UCTheme::setName(const QString& name)
2880 {
2881- if (name != m_name) {
2882- QObject::disconnect(&m_themeSettings, &UCThemeSettings::themeNameChanged,
2883- this, &UCTheme::onThemeNameChanged);
2884- m_name = name;
2885+ if (name == m_name) {
2886+ return;
2887+ }
2888+ m_name = name;
2889+ if (name.isEmpty()) {
2890+ init();
2891+ } else {
2892+ QObject::disconnect(&m_defaultTheme, &UCDefaultTheme::themeNameChanged,
2893+ this, &UCTheme::_q_defaultThemeChanged);
2894 updateThemePaths();
2895- Q_EMIT nameChanged();
2896 }
2897+ loadPalette();
2898+ Q_EMIT nameChanged();
2899+}
2900+void UCTheme::resetName()
2901+{
2902+ setName(QString());
2903 }
2904
2905 /*!
2906- \qmlproperty Palette Theme::palette
2907-
2908- The palette of the current theme.
2909-*/
2910+ * \qmlproperty Palette ThemeSettings::palette
2911+ * The palette of the current theme.
2912+ */
2913 QObject* UCTheme::palette()
2914 {
2915 if (!m_palette) {
2916@@ -232,27 +340,25 @@
2917 return QUrl();
2918 }
2919
2920-QString UCTheme::parentThemeName(const QString& themeName)
2921+// registers the default theme property to the root context
2922+void UCTheme::registerToContext(QQmlContext* context)
2923 {
2924- QString parentTheme;
2925- QUrl themePath = pathFromThemeName(themeName);
2926- if (!themePath.isValid()) {
2927- qWarning() << qPrintable(UbuntuI18n::instance().tr("Theme not found: \"%1\"").arg(themeName));
2928- } else {
2929- QFile file(themePath.resolved(PARENT_THEME_FILE).toLocalFile());
2930- if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
2931- QTextStream in(&file);
2932- parentTheme = in.readLine();
2933- }
2934- }
2935- return parentTheme;
2936+ UCTheme *defaultTheme = &UCTheme::defaultTheme();
2937+ defaultTheme->m_engine = context->engine();
2938+ defaultTheme->updateEnginePaths();
2939+
2940+ context->setContextProperty("theme", defaultTheme);
2941+ ContextPropertyChangeListener *listener =
2942+ new ContextPropertyChangeListener(context, "theme");
2943+ QObject::connect(defaultTheme, &UCTheme::nameChanged,
2944+ listener, &ContextPropertyChangeListener::updateContextProperty);
2945 }
2946
2947 /*!
2948- \qmlmethod Component Theme::createStyleComponent(string styleName, object parent)
2949-
2950- Returns an instance of the style component named \a styleName.
2951-*/
2952+ * \qmlmethod Component ThemeSettings::createStyleComponent(string styleName, object parent)
2953+ * Returns an instance of the style component named \a styleName and parented
2954+ * to \a parent.
2955+ */
2956 QQmlComponent* UCTheme::createStyleComponent(const QString& styleName, QObject* parent)
2957 {
2958 QQmlComponent *component = NULL;
2959@@ -275,7 +381,7 @@
2960 }
2961 } else {
2962 qmlInfo(parent) <<
2963- UbuntuI18n::instance().tr(QString("Warning: Style %1 not found in theme %2").arg(styleName).arg(m_name));
2964+ UbuntuI18n::instance().tr(QString("Warning: Style %1 not found in theme %2").arg(styleName).arg(name()));
2965 }
2966 }
2967 }
2968@@ -283,32 +389,23 @@
2969 return component;
2970 }
2971
2972-void UCTheme::registerToContext(QQmlContext* context)
2973-{
2974- // add paths to engine search folder
2975- m_engine = context->engine();
2976- updateEnginePaths();
2977-
2978- // register Theme
2979- context->setContextProperty("Theme", this);
2980-
2981- ContextPropertyChangeListener *themeChangeListener =
2982- new ContextPropertyChangeListener(context, "Theme");
2983- QObject::connect(this, SIGNAL(nameChanged()),
2984- themeChangeListener, SLOT(updateContextProperty()));
2985-
2986-}
2987-
2988 void UCTheme::loadPalette(bool notify)
2989 {
2990 if (!m_engine) {
2991 return;
2992 }
2993- if (m_palette != NULL) {
2994+ if (!m_palette.isNull()) {
2995 delete m_palette;
2996 }
2997- m_palette = QuickUtils::instance().createQmlObject(styleUrl("Palette.qml"), m_engine);
2998- if (notify) {
2999- Q_EMIT paletteChanged();
3000+ // theme may not have palette defined
3001+ QUrl paletteUrl = styleUrl("Palette.qml");
3002+ if (paletteUrl.isValid()) {
3003+ m_palette = QuickUtils::instance().createQmlObject(paletteUrl, m_engine);
3004+ if (notify) {
3005+ Q_EMIT paletteChanged();
3006+ }
3007+ } else {
3008+ // use the default palette if none defined
3009+ m_palette = defaultTheme().m_palette;
3010 }
3011 }
3012
3013=== modified file 'modules/Ubuntu/Components/plugin/uctheme.h'
3014--- modules/Ubuntu/Components/plugin/uctheme.h 2014-11-24 15:08:26 +0000
3015+++ modules/Ubuntu/Components/plugin/uctheme.h 2015-04-14 21:04:03 +0000
3016@@ -1,5 +1,5 @@
3017 /*
3018- * Copyright 2013 Canonical Ltd.
3019+ * Copyright 2015 Canonical Ltd.
3020 *
3021 * This program is free software; you can redistribute it and/or modify
3022 * it under the terms of the GNU Lesser General Public License as published by
3023@@ -21,54 +21,74 @@
3024 #define UCTHEME_H
3025
3026 #include <QtCore/QObject>
3027+#include <QtCore/QPointer>
3028 #include <QtCore/QUrl>
3029 #include <QtCore/QString>
3030 #include <QtQml/QQmlComponent>
3031-
3032-#include "ucthemesettings.h"
3033-
3034-class UCTheme : public QObject
3035+#include <QtQml/QQmlParserStatus>
3036+
3037+#include "ucdefaulttheme.h"
3038+
3039+class UCStyledItemBase;
3040+class UCTheme : public QObject, public QQmlParserStatus
3041 {
3042 Q_OBJECT
3043-
3044- Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
3045+ Q_INTERFACES(QQmlParserStatus)
3046+ Q_PROPERTY(UCTheme *parentTheme READ parentTheme NOTIFY parentThemeChanged)
3047+ Q_PROPERTY(QString name READ name WRITE setName RESET resetName NOTIFY nameChanged)
3048 Q_PROPERTY(QObject* palette READ palette NOTIFY paletteChanged)
3049 public:
3050- static UCTheme& instance() {
3051- static UCTheme instance;
3052+ explicit UCTheme(QObject *parent = 0);
3053+ static UCTheme &defaultTheme()
3054+ {
3055+ static UCTheme instance(true);
3056 return instance;
3057 }
3058
3059- explicit UCTheme(QObject *parent = 0);
3060-
3061 // getter/setters
3062+ UCTheme *parentTheme();
3063 QString name() const;
3064 void setName(const QString& name);
3065+ void resetName();
3066 QObject* palette();
3067
3068 Q_INVOKABLE QQmlComponent* createStyleComponent(const QString& styleName, QObject* parent);
3069- void registerToContext(QQmlContext* context);
3070- static QUrl pathFromThemeName(QString themeName);
3071+ static void registerToContext(QQmlContext* context);
3072
3073 Q_SIGNALS:
3074+ void parentThemeChanged();
3075 void nameChanged();
3076 void paletteChanged();
3077
3078+protected:
3079+ void classBegin();
3080+ void componentComplete()
3081+ {
3082+ m_completed = true;
3083+ }
3084+
3085 private Q_SLOTS:
3086+ void _q_defaultThemeChanged();
3087+
3088+private:
3089+ UCTheme(bool defaultStyle, QObject *parent = 0);
3090+ void init();
3091 void updateEnginePaths();
3092- void onThemeNameChanged();
3093 void updateThemePaths();
3094 QUrl styleUrl(const QString& styleName);
3095- QString parentThemeName(const QString& themeName);
3096 void loadPalette(bool notify = true);
3097
3098-private:
3099 QString m_name;
3100- QObject* m_palette;
3101+ QPointer<QObject> m_palette; // the palette might be from the default style if the theme doesn't define palette
3102 QQmlEngine *m_engine;
3103 QList<QUrl> m_themePaths;
3104- UCThemeSettings m_themeSettings;
3105- bool m_engineUpdated;
3106+ UCDefaultTheme m_defaultTheme;
3107+ bool m_defaultStyle:1;
3108+ bool m_completed:1;
3109+
3110+ friend class UCDeprecatedTheme;
3111 };
3112
3113+QUrl pathFromThemeName(QString themeName);
3114+
3115 #endif // UCTHEME_H
3116
3117=== modified file 'modules/Ubuntu/Components/qmldir'
3118--- modules/Ubuntu/Components/qmldir 2015-03-02 13:39:03 +0000
3119+++ modules/Ubuntu/Components/qmldir 2015-04-14 21:04:03 +0000
3120@@ -98,7 +98,7 @@
3121 UbuntuListView 1.1 UbuntuListView11.qml
3122 internal PageBase Page10.qml
3123 Page 1.1 Page11.qml
3124-PageHeadConfiguration 1.1 PageHeadConfiguration.qml
3125+PageHeadConfiguration 1.1 PageHeadConfiguration11.qml
3126 PageHeadSections 1.1 PageHeadSections.qml
3127 PageHeadState 1.1 PageHeadState.qml
3128 Icon 1.1 Icon11.qml
3129@@ -111,3 +111,7 @@
3130 #version 1.2
3131 MainView 1.2 MainView12.qml
3132 Captions 1.2 Captions.qml
3133+
3134+#version 1.3
3135+Page 1.3 Page13.qml
3136+PageHeadConfiguration 1.3 PageHeadConfiguration13.qml
3137
3138=== modified file 'modules/Ubuntu/Test/UbuntuTestCase.qml'
3139--- modules/Ubuntu/Test/UbuntuTestCase.qml 2015-03-03 13:47:48 +0000
3140+++ modules/Ubuntu/Test/UbuntuTestCase.qml 2015-04-14 21:04:03 +0000
3141@@ -115,10 +115,10 @@
3142 var iy = 0;
3143
3144 for (var step=0; step < steps; step++) {
3145- if (ix < abs_dx) {
3146+ if (Math.abs(ix) < abs_dx) {
3147 ix += step_dx;
3148 }
3149- if (iy < abs_dy) {
3150+ if (Math.abs(iy) < abs_dy) {
3151 iy += step_dy;
3152 }
3153 mouseMove(item, x + ix, y + iy, stepdelay);
3154@@ -237,4 +237,22 @@
3155 function warningFormat(line, column, message) {
3156 return util.callerFile() + ":" + line + ":" + column + ": " + message;
3157 }
3158+
3159+ /*!
3160+ Wait for animations of the header and the style inside the header to finish.
3161+ The MainView that has the header that may animate must be passed as an argument.
3162+ */
3163+ function waitForHeaderAnimation(mainView) {
3164+ var header = findChild(mainView, "MainView_Header");
3165+ verify(header !== null, "Could not find header.");
3166+ var headerStyle = findChild(header, "PageHeadStyle");
3167+ verify(headerStyle !== null, "Could not find header style.");
3168+
3169+ // Wait for the header to start to move:
3170+ wait(50);
3171+ // Wait for animation of the style inside the header (when pushing/popping):
3172+ tryCompareFunction(function(){ return headerStyle.animating }, false);
3173+ // Wait for the header to finish showing/hiding:
3174+ tryCompareFunction(function(){ return header.moving }, false);
3175+ }
3176 }
3177
3178=== modified file 'modules/Ubuntu/Test/plugin/uctestcase.h'
3179--- modules/Ubuntu/Test/plugin/uctestcase.h 2014-10-06 14:18:35 +0000
3180+++ modules/Ubuntu/Test/plugin/uctestcase.h 2015-04-14 21:04:03 +0000
3181@@ -27,7 +27,6 @@
3182 class UbuntuTestCase : public QQuickView
3183 {
3184 Q_OBJECT
3185-
3186 public:
3187 UbuntuTestCase(const QString& file, QWindow* parent = 0);
3188 int warnings() const;
3189
3190=== modified file 'push_to_phone.sh'
3191--- push_to_phone.sh 2015-02-24 15:50:34 +0000
3192+++ push_to_phone.sh 2015-04-14 21:04:03 +0000
3193@@ -84,7 +84,6 @@
3194
3195 # Autopilot tests should always match the Toolkit
3196 adb push tests/autopilot/ubuntuuitoolkit/ $STONE/ap || exit 1
3197-echo cp -R ap/* /usr/lib/python2.7/dist-packages/ubuntuuitoolkit >> $RUN/copy.sh || exit 1
3198 echo cp -R ap/* /usr/lib/python3/dist-packages/ubuntuuitoolkit >> $RUN/copy.sh || exit 1
3199 adb push examples/ubuntu-ui-toolkit-gallery/ $STONE/ex >> $RUN/copy.sh || exit 1
3200 echo cp -R ex/* /usr/lib/ubuntu-ui-toolkit/examples/ubuntu-ui-toolkit-gallery
3201
3202=== modified file 'tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_common.py'
3203--- tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_common.py 2014-07-16 19:19:03 +0000
3204+++ tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_common.py 2015-04-14 21:04:03 +0000
3205@@ -1,6 +1,6 @@
3206 # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
3207 #
3208-# Copyright (C) 2012, 2013, 2014 Canonical Ltd.
3209+# Copyright (C) 2012, 2013, 2014, 2015 Canonical Ltd.
3210 #
3211 # This program is free software; you can redistribute it and/or modify
3212 # it under the terms of the GNU Lesser General Public License as published by
3213@@ -73,7 +73,7 @@
3214
3215 def __init__(self, *args):
3216 check_autopilot_version()
3217- super(UbuntuUIToolkitCustomProxyObjectBase, self).__init__(*args)
3218+ super().__init__(*args)
3219 self.pointing_device = get_pointing_device()
3220
3221 def is_flickable(self):
3222
3223=== modified file 'tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_header.py'
3224--- tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_header.py 2015-03-04 21:57:25 +0000
3225+++ tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_header.py 2015-04-14 21:04:03 +0000
3226@@ -1,6 +1,6 @@
3227 # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
3228 #
3229-# Copyright (C) 2012, 2013, 2014 Canonical Ltd.
3230+# Copyright (C) 2012-2015 Canonical Ltd.
3231 #
3232 # This program is free software; you can redistribute it and/or modify
3233 # it under the terms of the GNU Lesser General Public License as published by
3234@@ -64,6 +64,9 @@
3235 # so no need to wait.
3236 return
3237
3238+ # Wait showing/hiding animation of the header.
3239+ self.moving.wait_for(False)
3240+
3241 @autopilot_logging.log_action(logger.info)
3242 def switch_to_section_by_index(self, index):
3243 """Select a section in the header divider
3244@@ -265,4 +268,4 @@
3245 'Header is an internal QML component of Ubuntu.Components and '
3246 'its API may change or be removed at any moment. Please use '
3247 'MainView and Page instead.')
3248- super(Header, self).__init__(*args)
3249+ super().__init__(*args)
3250
3251=== modified file 'tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_mainview.py'
3252--- tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_mainview.py 2015-02-11 23:37:40 +0000
3253+++ tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_mainview.py 2015-04-14 21:04:03 +0000
3254@@ -1,6 +1,6 @@
3255 # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
3256 #
3257-# Copyright (C) 2012, 2013, 2014 Canonical Ltd.
3258+# Copyright (C) 2012, 2013, 2014, 2015 Canonical Ltd.
3259 #
3260 # This program is free software; you can redistribute it and/or modify
3261 # it under the terms of the GNU Lesser General Public License as published by
3262@@ -42,7 +42,7 @@
3263
3264 @classmethod
3265 def validate_dbus_object(cls, path, state):
3266- if super(MainView, cls).validate_dbus_object(path, state):
3267+ if super().validate_dbus_object(path, state):
3268 # This covers MainView 0.1/1.0/1.1 and possible components
3269 # derived from MainView (e.g. "CustomMainView") that have
3270 # their own CPO.
3271
3272=== modified file 'tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_textfield.py'
3273--- tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_textfield.py 2014-08-26 16:29:26 +0000
3274+++ tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_textfield.py 2015-04-14 21:04:03 +0000
3275@@ -34,7 +34,7 @@
3276 """TextField Autopilot custom proxy object."""
3277
3278 def __init__(self, *args):
3279- super(TextField, self).__init__(*args)
3280+ super().__init__(*args)
3281 self.keyboard = _common.get_keyboard()
3282
3283 @autopilot_logging.log_action(logger.info)
3284
3285=== modified file 'tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/popups.py'
3286--- tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/popups.py 2015-03-10 11:49:27 +0000
3287+++ tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/popups.py 2015-04-14 21:04:03 +0000
3288@@ -113,9 +113,6 @@
3289 class ComposerSheet(_common.UbuntuUIToolkitCustomProxyObjectBase):
3290 """ComposerSheet Autopilot custom proxy object."""
3291
3292- def __init__(self, *args):
3293- super(ComposerSheet, self).__init__(*args)
3294-
3295 @autopilot_logging.log_action(logger.info)
3296 def confirm(self):
3297 """Confirm the composer sheet."""
3298
3299=== modified file 'tests/autopilot/ubuntuuitoolkit/base.py'
3300--- tests/autopilot/ubuntuuitoolkit/base.py 2014-12-01 11:03:48 +0000
3301+++ tests/autopilot/ubuntuuitoolkit/base.py 2015-04-14 21:04:03 +0000
3302@@ -1,6 +1,6 @@
3303 # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
3304 #
3305-# Copyright (C) 2013, 2014 Canonical Ltd.
3306+# Copyright (C) 2013, 2014, 2015 Canonical Ltd.
3307 #
3308 # This program is free software; you can redistribute it and/or modify
3309 # it under the terms of the GNU Lesser General Public License as published by
3310@@ -75,7 +75,7 @@
3311 """Autopilot test case for applications using the Ubuntu UI Toolkit."""
3312
3313 def setUp(self):
3314- super(UbuntuUIToolkitAppTestCase, self).setUp()
3315+ super().setUp()
3316 self.input_device_class = self._get_input_device_class()
3317
3318 def _get_input_device_class(self):
3319
3320=== modified file 'tests/autopilot/ubuntuuitoolkit/fixture_setup.py'
3321--- tests/autopilot/ubuntuuitoolkit/fixture_setup.py 2015-03-03 13:20:06 +0000
3322+++ tests/autopilot/ubuntuuitoolkit/fixture_setup.py 2015-04-14 21:04:03 +0000
3323@@ -1,6 +1,6 @@
3324 # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
3325 #
3326-# Copyright (C) 2014 Canonical Ltd.
3327+# Copyright (C) 2014, 2015 Canonical Ltd.
3328 #
3329 # This program is free software; you can redistribute it and/or modify
3330 # it under the terms of the GNU Lesser General Public License as published by
3331@@ -57,7 +57,7 @@
3332 def __init__(
3333 self, qml_file_contents=DEFAULT_QML_FILE_CONTENTS,
3334 desktop_file_dict=None):
3335- super(FakeApplication, self).__init__()
3336+ super().__init__()
3337 self._qml_file_contents = qml_file_contents
3338 if desktop_file_dict is None:
3339 self._desktop_file_dict = copy.deepcopy(DEFAULT_DESKTOP_FILE_DICT)
3340@@ -65,7 +65,7 @@
3341 self._desktop_file_dict = copy.deepcopy(desktop_file_dict)
3342
3343 def setUp(self):
3344- super(FakeApplication, self).setUp()
3345+ super().setUp()
3346 self.qml_file_path, self.desktop_file_path = (
3347 self._create_test_application())
3348
3349@@ -116,7 +116,7 @@
3350 """Set the value of initctl environment variables."""
3351
3352 def __init__(self, global_=False, **kwargs):
3353- super(InitctlEnvironmentVariable, self).__init__()
3354+ super().__init__()
3355 # Added one level of indirection to be able to spy the calls to
3356 # environment during tests.
3357 self.environment = environment
3358@@ -124,7 +124,7 @@
3359 self.global_ = global_
3360
3361 def setUp(self):
3362- super(InitctlEnvironmentVariable, self).setUp()
3363+ super().setUp()
3364 for variable, value in self.variables.items():
3365 self._add_variable_cleanup(variable)
3366 self.environment.set_initctl_env_var(
3367@@ -154,11 +154,11 @@
3368 should_copy_xauthority_file = True
3369
3370 def __init__(self, directory=None):
3371- super(FakeHome, self).__init__()
3372+ super().__init__()
3373 self.directory = directory
3374
3375 def setUp(self):
3376- super(FakeHome, self).setUp()
3377+ super().setUp()
3378 self.directory = self._make_directory_if_not_specified()
3379 if self.should_copy_xauthority_file:
3380 self._copy_xauthority_file(self.directory)
3381@@ -202,7 +202,7 @@
3382 _UNITYSHELL_LAUNCHER_HIDDEN_MODE = 1 # launcher hidden
3383
3384 def setUp(self):
3385- super(HideUnity7Launcher, self).setUp()
3386+ super().setUp()
3387 self._hide_launcher()
3388
3389 def _hide_launcher(self):
3390@@ -232,14 +232,14 @@
3391 class SimulateDevice(fixtures.Fixture):
3392
3393 def __init__(self, app_width, app_height, grid_unit_px):
3394- super(SimulateDevice, self).__init__()
3395+ super().__init__()
3396 self.app_width = app_width
3397 self.app_height = app_height
3398 self.grid_unit_px = grid_unit_px
3399 self._screen = None
3400
3401 def setUp(self):
3402- super(SimulateDevice, self).setUp()
3403+ super().setUp()
3404 if self._is_geometry_larger_than_display(
3405 self.app_width, self.app_height):
3406 scale_divisor = self._get_scale_divisor()
3407
3408=== modified file 'tests/autopilot/ubuntuuitoolkit/tests/__init__.py'
3409--- tests/autopilot/ubuntuuitoolkit/tests/__init__.py 2015-03-03 13:20:06 +0000
3410+++ tests/autopilot/ubuntuuitoolkit/tests/__init__.py 2015-04-14 21:04:03 +0000
3411@@ -92,7 +92,7 @@
3412 """)
3413
3414 def setUp(self):
3415- super(UbuntuUIToolkitWithFakeAppRunningTestCase, self).setUp()
3416+ super().setUp()
3417 self.launch_application()
3418
3419 def launch_application(self):
3420@@ -126,7 +126,7 @@
3421 """Base test case for self tests that define the QML on an string."""
3422
3423 def setUp(self):
3424- super(QMLStringAppTestCase, self).setUp()
3425+ super().setUp()
3426 self.assertThat(
3427 self.main_view.visible, Eventually(Equals(True)))
3428
3429@@ -156,7 +156,7 @@
3430 desktop_file_path = None
3431
3432 def setUp(self):
3433- super(QMLFileAppTestCase, self).setUp()
3434+ super().setUp()
3435 self.pointing_device = Pointer(self.input_device_class.create())
3436 self.launch_application()
3437
3438
3439=== modified file 'tests/autopilot/ubuntuuitoolkit/tests/components/test_header.py'
3440--- tests/autopilot/ubuntuuitoolkit/tests/components/test_header.py 2015-02-03 11:54:53 +0000
3441+++ tests/autopilot/ubuntuuitoolkit/tests/components/test_header.py 2015-04-14 21:04:03 +0000
3442@@ -40,7 +40,7 @@
3443 ]
3444
3445 def setUp(self):
3446- super(HeaderActionsOverflowTestCase, self).setUp()
3447+ super().setUp()
3448 self.header = self.main_view.get_header()
3449
3450 def test_click_header_overflow_action_must_close_popover(self):
3451@@ -71,7 +71,7 @@
3452 dir_path, 'test_header.HeaderContentsTestCase.qml')
3453
3454 def setUp(self):
3455- super(HeaderContentsTestCase, self).setUp()
3456+ super().setUp()
3457 self.header = self.main_view.get_header()
3458
3459 def test_open_page_with_head_contents_must_change_header(self):
3460
3461=== modified file 'tests/autopilot/ubuntuuitoolkit/tests/components/test_popover.py'
3462--- tests/autopilot/ubuntuuitoolkit/tests/components/test_popover.py 2014-10-06 10:44:31 +0000
3463+++ tests/autopilot/ubuntuuitoolkit/tests/components/test_popover.py 2015-04-14 21:04:03 +0000
3464@@ -1,6 +1,6 @@
3465 # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
3466 #
3467-# Copyright (C) 2014 Canonical Ltd.
3468+# Copyright (C) 2014, 2015 Canonical Ltd.
3469 #
3470 # This program is free software; you can redistribute it and/or modify
3471 # it under the terms of the GNU Lesser General Public License as published by
3472@@ -28,9 +28,6 @@
3473 test_qml_file_path = os.path.join(
3474 dir_path, 'test_popover.qml')
3475
3476- def setUp(self):
3477- super(DialogScrollTestCase, self).setUp()
3478-
3479 def test_dialog_small(self):
3480 button = self.main_view.select_single(objectName='button_small')
3481 self.pointing_device.click_object(button)
3482
3483=== modified file 'tests/autopilot/ubuntuuitoolkit/tests/components/test_textinput.py'
3484--- tests/autopilot/ubuntuuitoolkit/tests/components/test_textinput.py 2015-03-16 10:01:09 +0000
3485+++ tests/autopilot/ubuntuuitoolkit/tests/components/test_textinput.py 2015-04-14 21:04:03 +0000
3486@@ -1,6 +1,6 @@
3487 # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
3488 #
3489-# Copyright (C) 2014 Canonical Ltd.
3490+# Copyright (C) 2014, 2015 Canonical Ltd.
3491 #
3492 # This program is free software; you can redistribute it and/or modify
3493 # it under the terms of the GNU Lesser General Public License as published by
3494@@ -59,7 +59,7 @@
3495 return command_line
3496
3497 def setUp(self):
3498- super(CaretTextInputTestCase, self).setUp()
3499+ super().setUp()
3500 self.textfield = self.main_view.select_single(
3501 objectName=self.objectName)
3502 self.assertFalse(self.textfield.focus)
3503@@ -130,7 +130,7 @@
3504 return command_line
3505
3506 def setUp(self):
3507- super(InsertModeTextInputTestCase, self).setUp()
3508+ super().setUp()
3509 self.textfield = self.main_view.select_single(
3510 objectName=self.objectName)
3511 self.assertFalse(self.textfield.focus)
3512
3513=== added file 'tests/autopilot/ubuntuuitoolkit/tests/components/test_units.py'
3514--- tests/autopilot/ubuntuuitoolkit/tests/components/test_units.py 1970-01-01 00:00:00 +0000
3515+++ tests/autopilot/ubuntuuitoolkit/tests/components/test_units.py 2015-04-14 21:04:03 +0000
3516@@ -0,0 +1,61 @@
3517+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
3518+#
3519+# Copyright (C) 2015 Canonical Ltd.
3520+#
3521+# This program is free software; you can redistribute it and/or modify
3522+# it under the terms of the GNU Lesser General Public License as published by
3523+# the Free Software Foundation; version 3.
3524+#
3525+# This program is distributed in the hope that it will be useful,
3526+# but WITHOUT ANY WARRANTY; without even the implied warranty of
3527+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3528+# GNU Lesser General Public License for more details.
3529+#
3530+# You should have received a copy of the GNU Lesser General Public License
3531+# along with this program. If not, see <http://www.gnu.org/licenses/>.
3532+
3533+"""Tests for the Ubuntu UI Toolkit units helpers."""
3534+
3535+import logging
3536+import os
3537+import testscenarios
3538+import testtools
3539+
3540+import fixtures
3541+
3542+from ubuntuuitoolkit import (
3543+ fixture_setup,
3544+ units
3545+)
3546+
3547+
3548+logger = logging.getLogger(__name__)
3549+
3550+
3551+class UnitsTestCase(testscenarios.TestWithScenarios,
3552+ testtools.TestCase):
3553+
3554+ WIDTH_IN_GU = 20
3555+
3556+ path = os.path.abspath(__file__)
3557+ dir_path = os.path.dirname(path)
3558+ test_qml_file_path = os.path.join(
3559+ dir_path, 'test_units.UnitsTestCase.qml')
3560+
3561+ scenarios = [
3562+ ('with default GRID_UNIT_PX', {'grid_unit_px': '',
3563+ 'expected_pixels': 160}),
3564+ ('with GRID_UNIT_PX environment variable set', {'grid_unit_px': '10',
3565+ 'expected_pixels': 200})
3566+ ]
3567+
3568+ def setUp(self):
3569+ self.useFixture(fixtures.EnvironmentVariable(
3570+ 'GRID_UNIT_PX', self.grid_unit_px))
3571+ self.useFixture(fixture_setup.InitctlEnvironmentVariable(
3572+ global_=True, GRID_UNIT_PX=self.grid_unit_px))
3573+ super().setUp()
3574+
3575+ def test_gu(self):
3576+ pixels = units.gu(self.WIDTH_IN_GU)
3577+ self.assertEquals(pixels, self.expected_pixels)
3578
3579=== modified file 'tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_checkbox.py'
3580--- tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_checkbox.py 2015-03-03 13:20:06 +0000
3581+++ tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_checkbox.py 2015-04-14 21:04:03 +0000
3582@@ -18,10 +18,7 @@
3583
3584 from autopilot import input
3585 from testtools.matchers import GreaterThan, LessThan
3586-try:
3587- from unittest import mock
3588-except ImportError:
3589- import mock
3590+from unittest import mock
3591
3592 import ubuntuuitoolkit
3593 from ubuntuuitoolkit import tests
3594@@ -75,7 +72,7 @@
3595 ]
3596
3597 def setUp(self):
3598- super(ToggleTestCase, self).setUp()
3599+ super().setUp()
3600 self.toggle = self.main_view.select_single(
3601 ubuntuuitoolkit.CheckBox, objectName=self.objectName)
3602 self.assertFalse(self.toggle.checked)
3603
3604=== modified file 'tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_common.py'
3605--- tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_common.py 2014-04-17 01:11:03 +0000
3606+++ tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_common.py 2015-04-14 21:04:03 +0000
3607@@ -1,6 +1,6 @@
3608 # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
3609 #
3610-# Copyright (C) 2013, 2014 Canonical Ltd.
3611+# Copyright (C) 2013, 2014, 2015 Canonical Ltd.
3612 #
3613 # This program is free software; you can redistribute it and/or modify
3614 # it under the terms of the GNU Lesser General Public License as published by
3615@@ -18,10 +18,7 @@
3616
3617 import autopilot
3618 from autopilot import platform, input
3619-try:
3620- from unittest import mock
3621-except ImportError:
3622- import mock
3623+from unittest import mock
3624
3625 import ubuntuuitoolkit
3626 from ubuntuuitoolkit import tests
3627
3628=== modified file 'tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_date_picker.py'
3629--- tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_date_picker.py 2015-03-03 13:20:06 +0000
3630+++ tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_date_picker.py 2015-04-14 21:04:03 +0000
3631@@ -1,6 +1,6 @@
3632 # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
3633 #
3634-# Copyright (C) 2014 Canonical Ltd.
3635+# Copyright (C) 2014, 2015 Canonical Ltd.
3636 #
3637 # This program is free software; you can redistribute it and/or modify
3638 # it under the terms of the GNU Lesser General Public License as published by
3639@@ -82,7 +82,7 @@
3640 """)
3641
3642 def setUp(self):
3643- super(DatePickerBaseTestCase, self).setUp()
3644+ super().setUp()
3645 self.date_picker = self.main_view.select_single(
3646 pickers.DatePicker, objectName='datePicker')
3647 self.time_picker = self.main_view.select_single(
3648
3649=== modified file 'tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_dialog.py'
3650--- tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_dialog.py 2014-12-17 12:11:51 +0000
3651+++ tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_dialog.py 2015-04-14 21:04:03 +0000
3652@@ -1,6 +1,6 @@
3653 # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
3654 #
3655-# Copyright (C) 2013, 2014 Canonical Ltd.
3656+# Copyright (C) 2013, 2014, 2015 Canonical Ltd.
3657 #
3658 # This program is free software; you can redistribute it and/or modify
3659 # it under the terms of the GNU Lesser General Public License as published by
3660@@ -25,9 +25,6 @@
3661 test_qml_file_path = os.path.join(
3662 dir_path, 'test_dialog.DialogTestCase.qml')
3663
3664- def setUp(self):
3665- super(DialogTestCase, self).setUp()
3666-
3667 def test_dialog(self):
3668 open_button = self.main_view.wait_select_single('Button',
3669 objectName='button')
3670
3671=== modified file 'tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_flickable.py'
3672--- tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_flickable.py 2015-03-03 13:20:06 +0000
3673+++ tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_flickable.py 2015-04-14 21:04:03 +0000
3674@@ -14,10 +14,7 @@
3675 # You should have received a copy of the GNU Lesser General Public License
3676 # along with this program. If not, see <http://www.gnu.org/licenses/>.
3677
3678-try:
3679- from unittest import mock
3680-except ImportError:
3681- import mock
3682+from unittest import mock
3683
3684 import testtools
3685 import ubuntuuitoolkit
3686@@ -143,7 +140,7 @@
3687 """)
3688
3689 def setUp(self):
3690- super(SwipeFlickableTestCase, self).setUp()
3691+ super().setUp()
3692 self.flickable = self.main_view.select_single(
3693 ubuntuuitoolkit.QQuickFlickable, objectName='flickable')
3694 self.label = self.main_view.select_single(
3695
3696=== modified file 'tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_header.py'
3697--- tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_header.py 2015-03-04 16:29:23 +0000
3698+++ tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_header.py 2015-04-14 21:04:03 +0000
3699@@ -34,7 +34,7 @@
3700 'test_header.HideShowTestCase.qml')
3701
3702 def setUp(self):
3703- super(HideShowTestCase, self).setUp()
3704+ super().setUp()
3705 self.header = self.main_view.get_header()
3706
3707 def test_ensure_header_visible_must_show_it_when_not_visible(self):
3708@@ -70,7 +70,7 @@
3709 ]
3710
3711 def setUp(self):
3712- super(ActionsTestCase, self).setUp()
3713+ super().setUp()
3714 self.header = self.main_view.get_header()
3715 self.label = self.app.select_single(
3716 'Label', objectName='clicked_label')
3717@@ -134,7 +134,7 @@
3718 dir_path, 'test_header.SectionsTestCase.qml')
3719
3720 def setUp(self):
3721- super(SectionsTestCase, self).setUp()
3722+ super().setUp()
3723 self.header = self.main_view.get_header()
3724 # initially, section 0 is selected
3725 self.assertEqual(self.header.get_selected_section_index(), 0)
3726@@ -162,7 +162,7 @@
3727 dir_path, 'test_header.DeprecatedHeaderSectionsTestCase.qml')
3728
3729 def setUp(self):
3730- super(DeprecatedHeaderSectionsTestCase, self).setUp()
3731+ super().setUp()
3732 self.header = self.main_view.get_header()
3733
3734 def test_get_selection_index(self):
3735
3736=== modified file 'tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_listitem.py'
3737--- tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_listitem.py 2015-01-15 15:06:02 +0000
3738+++ tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_listitem.py 2015-04-14 21:04:03 +0000
3739@@ -27,7 +27,7 @@
3740 dir_path, 'test_listitem.ListItemTestCase.qml')
3741
3742 def setUp(self):
3743- super(ListItemTestCase, self).setUp()
3744+ super().setUp()
3745 self.list_view = self.main_view.select_single(
3746 ubuntuuitoolkit.QQuickListView, objectName='test_view')
3747 self.test_listitem = self.main_view.select_single(
3748
3749=== modified file 'tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_listitems.py'
3750--- tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_listitems.py 2015-03-03 13:20:06 +0000
3751+++ tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_listitems.py 2015-04-14 21:04:03 +0000
3752@@ -14,10 +14,7 @@
3753 # You should have received a copy of the GNU Lesser General Public License
3754 # along with this program. If not, see <http://www.gnu.org/licenses/>.
3755
3756-try:
3757- from unittest import mock
3758-except ImportError:
3759- import mock
3760+from unittest import mock
3761
3762 import logging
3763 import os
3764@@ -121,7 +118,7 @@
3765 """)
3766
3767 def setUp(self):
3768- super(SwipeToDeleteTestCase, self).setUp()
3769+ super().setUp()
3770 self._item = self.main_view.select_single(
3771 listitems.Standard, objectName='listitem_standard')
3772 self.assertTrue(self._item.exists())
3773@@ -208,7 +205,7 @@
3774 dir_path, 'test_listitems.ExpandableTestCase.qml')
3775
3776 def setUp(self):
3777- super(ExpandableTestCase, self).setUp()
3778+ super().setUp()
3779 self.test_expandable = self.main_view.select_single(
3780 listitems.Expandable, objectName='expandable0')
3781
3782
3783=== modified file 'tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_main_view.py'
3784--- tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_main_view.py 2015-03-03 13:20:06 +0000
3785+++ tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_main_view.py 2015-04-14 21:04:03 +0000
3786@@ -14,10 +14,7 @@
3787 # You should have received a copy of the GNU Lesser General Public License
3788 # along with this program. If not, see <http://www.gnu.org/licenses/>.
3789
3790-try:
3791- from unittest import mock
3792-except ImportError:
3793- import mock
3794+from unittest import mock
3795
3796 import ubuntuuitoolkit
3797 from ubuntuuitoolkit import tests
3798@@ -179,7 +176,7 @@
3799 ]
3800
3801 def setUp(self):
3802- super(GoBackTestCase, self).setUp()
3803+ super().setUp()
3804 self.header = self.main_view.get_header()
3805 self.assertEqual(self.header.title, 'Page 0')
3806
3807
3808=== modified file 'tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_optionselector.py'
3809--- tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_optionselector.py 2015-03-03 13:20:06 +0000
3810+++ tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_optionselector.py 2015-04-14 21:04:03 +0000
3811@@ -1,6 +1,6 @@
3812 # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
3813 #
3814-# Copyright (C) 2013, 2014 Canonical Ltd.
3815+# Copyright (C) 2013, 2014, 2015 Canonical Ltd.
3816 #
3817 # This program is free software; you can redistribute it and/or modify
3818 # it under the terms of the GNU Lesser General Public License as published by
3819@@ -68,7 +68,7 @@
3820 """)
3821
3822 def setUp(self):
3823- super(OptionSelectorCustomDelegateTestCase, self).setUp()
3824+ super().setUp()
3825 self.option_selector = self.main_view.select_single(
3826 ubuntuuitoolkit.OptionSelector,
3827 objectName="test_option_selector_collapsed")
3828@@ -151,7 +151,7 @@
3829 """)
3830
3831 def setUp(self):
3832- super(OptionSelectorTestCase, self).setUp()
3833+ super().setUp()
3834 self.option_selector = self.main_view.select_single(
3835 ubuntuuitoolkit.OptionSelector,
3836 objectName="option_selector")
3837
3838=== modified file 'tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_popups.py'
3839--- tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_popups.py 2015-03-03 13:20:06 +0000
3840+++ tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_popups.py 2015-04-14 21:04:03 +0000
3841@@ -139,7 +139,7 @@
3842 """)
3843
3844 def setUp(self):
3845- super(ComposerSheetTestCase, self).setUp()
3846+ super().setUp()
3847 self.label = self.main_view.select_single(
3848 'Label', objectName='actionLabel')
3849 self.assertEqual(self.label.text, 'No action taken.')
3850
3851=== modified file 'tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_pull_to_refresh.py'
3852--- tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_pull_to_refresh.py 2014-09-22 13:19:47 +0000
3853+++ tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_pull_to_refresh.py 2015-04-14 21:04:03 +0000
3854@@ -1,6 +1,6 @@
3855 # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
3856 #
3857-# Copyright (C) 2014 Canonical Ltd.
3858+# Copyright (C) 2014, 2015 Canonical Ltd.
3859 #
3860 # This program is free software; you can redistribute it and/or modify
3861 # it under the terms of the GNU Lesser General Public License as published by
3862@@ -30,7 +30,7 @@
3863 test_qml_file_path = os.path.join(dir_path, 'test_pull_to_refresh.qml')
3864
3865 def setUp(self):
3866- super(PullToRefreshTestCase, self).setUp()
3867+ super().setUp()
3868 self.label = self.main_view.select_single(
3869 'Label', objectName='refreshedLabel')
3870 self.assertEqual(self.label.text, 'Not refreshed.')
3871
3872=== modified file 'tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_qquicklistview.py'
3873--- tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_qquicklistview.py 2015-03-18 17:06:21 +0000
3874+++ tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_qquicklistview.py 2015-04-14 21:04:03 +0000
3875@@ -14,10 +14,7 @@
3876 # You should have received a copy of the GNU Lesser General Public License
3877 # along with this program. If not, see <http://www.gnu.org/licenses/>.
3878
3879-try:
3880- from unittest import mock
3881-except ImportError:
3882- import mock
3883+from unittest import mock
3884
3885 import os
3886
3887@@ -76,7 +73,7 @@
3888 """)
3889
3890 def setUp(self):
3891- super(QQuickListViewTestCase, self).setUp()
3892+ super().setUp()
3893 self.list_view = self.main_view.select_single(
3894 ubuntuuitoolkit.QQuickListView, objectName='testListView')
3895 self.label = self.main_view.select_single(
3896@@ -206,7 +203,7 @@
3897 """)
3898
3899 def setUp(self):
3900- super(QQuickListViewOutOfViewTestCase, self).setUp()
3901+ super().setUp()
3902 self.list_view = self.main_view.select_single(
3903 ubuntuuitoolkit.QQuickListView, objectName='testListView')
3904 self.label = self.main_view.select_single(
3905@@ -238,7 +235,7 @@
3906 self.test_qml_file_path = os.path.join(
3907 dir_path, self.qml_file_name)
3908
3909- super(QQuickListViewDraggingBaseTestCase, self).setUp()
3910+ super().setUp()
3911 self.list_view = self.main_view.select_single(
3912 ubuntuuitoolkit.QQuickListView, objectName='test_view')
3913
3914
3915=== modified file 'tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_tabs.py'
3916--- tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_tabs.py 2014-09-04 13:21:35 +0000
3917+++ tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_tabs.py 2015-04-14 21:04:03 +0000
3918@@ -1,6 +1,6 @@
3919 # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
3920 #
3921-# Copyright (C) 2013, 2014 Canonical Ltd.
3922+# Copyright (C) 2013, 2014, 2015 Canonical Ltd.
3923 #
3924 # This program is free software; you can redistribute it and/or modify
3925 # it under the terms of the GNU Lesser General Public License as published by
3926@@ -16,10 +16,7 @@
3927
3928 import os
3929
3930-try:
3931- from unittest import mock
3932-except ImportError:
3933- import mock
3934+from unittest import mock
3935
3936 import ubuntuuitoolkit
3937 from ubuntuuitoolkit import tests
3938
3939=== modified file 'tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_textarea.py'
3940--- tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_textarea.py 2015-03-03 13:20:06 +0000
3941+++ tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_textarea.py 2015-04-14 21:04:03 +0000
3942@@ -14,10 +14,7 @@
3943 # You should have received a copy of the GNU Lesser General Public License
3944 # along with this program. If not, see <http://www.gnu.org/licenses/>.
3945
3946-try:
3947- from unittest import mock
3948-except ImportError:
3949- import mock
3950+from unittest import mock
3951
3952 from autopilot import platform
3953 from testtools.matchers import GreaterThan
3954@@ -46,7 +43,7 @@
3955 """)
3956
3957 def setUp(self):
3958- super(TextAreaTestCase, self).setUp()
3959+ super().setUp()
3960 self.simple_text_area = self.main_view.select_single(
3961 ubuntuuitoolkit.TextArea, objectName='simple_text_area')
3962
3963
3964=== modified file 'tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_textfield.py'
3965--- tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_textfield.py 2015-03-03 13:20:06 +0000
3966+++ tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_textfield.py 2015-04-14 21:04:03 +0000
3967@@ -14,10 +14,7 @@
3968 # You should have received a copy of the GNU Lesser General Public License
3969 # along with this program. If not, see <http://www.gnu.org/licenses/>.
3970
3971-try:
3972- from unittest import mock
3973-except ImportError:
3974- import mock
3975+from unittest import mock
3976
3977 from autopilot import platform
3978
3979@@ -52,7 +49,7 @@
3980 """)
3981
3982 def setUp(self):
3983- super(TextFieldTestCase, self).setUp()
3984+ super().setUp()
3985 self.simple_text_field = self.main_view.select_single(
3986 ubuntuuitoolkit.TextField, objectName='simple_text_field')
3987
3988
3989=== modified file 'tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_toolbar.py'
3990--- tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_toolbar.py 2015-03-03 13:20:06 +0000
3991+++ tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_toolbar.py 2015-04-14 21:04:03 +0000
3992@@ -14,10 +14,7 @@
3993 # You should have received a copy of the GNU Lesser General Public License
3994 # along with this program. If not, see <http://www.gnu.org/licenses/>.
3995
3996-try:
3997- from unittest import mock
3998-except ImportError:
3999- import mock
4000+from unittest import mock
4001
4002 import ubuntuuitoolkit
4003 from ubuntuuitoolkit import tests
4004@@ -62,7 +59,7 @@
4005 """)
4006
4007 def setUp(self):
4008- super(ToolbarTestCase, self).setUp()
4009+ super().setUp()
4010 self.toolbar = self.main_view.get_toolbar()
4011 # toolbar may be opened or closed now, depending on whether
4012 # the application has been deactivated and resumed already
4013
4014=== modified file 'tests/autopilot/ubuntuuitoolkit/tests/gallery/__init__.py'
4015--- tests/autopilot/ubuntuuitoolkit/tests/gallery/__init__.py 2014-07-07 17:08:13 +0000
4016+++ tests/autopilot/ubuntuuitoolkit/tests/gallery/__init__.py 2015-04-14 21:04:03 +0000
4017@@ -1,6 +1,6 @@
4018 # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
4019 #
4020-# Copyright (C) 2012, 2013, 2014 Canonical Ltd.
4021+# Copyright (C) 2012, 2013, 2014, 2015 Canonical Ltd.
4022 #
4023 # This program is free software; you can redistribute it and/or modify
4024 # it under the terms of the GNU Lesser General Public License as published by
4025@@ -45,7 +45,7 @@
4026 # the app.
4027 self.simulate_device()
4028
4029- super(GalleryTestCase, self).setUp()
4030+ super().setUp()
4031
4032 if self.should_simulate_device():
4033 # XXX Currently we have no way to launch the application with a
4034@@ -133,7 +133,7 @@
4035 element.selected.wait_for(True)
4036
4037 def tearDown(self):
4038- super(GalleryTestCase, self).tearDown()
4039+ super().tearDown()
4040 # We can't delete the desktop file before we close the application,
4041 # so we save it on an attribute to be deleted on tear down.
4042 if self.local_desktop_file_path is not None:
4043
4044=== modified file 'tests/autopilot/ubuntuuitoolkit/tests/gallery/test_buttons.py'
4045--- tests/autopilot/ubuntuuitoolkit/tests/gallery/test_buttons.py 2014-07-30 18:47:37 +0000
4046+++ tests/autopilot/ubuntuuitoolkit/tests/gallery/test_buttons.py 2015-04-14 21:04:03 +0000
4047@@ -56,7 +56,7 @@
4048 def setUp(self):
4049 # Reset the locale to English
4050 os.environ['LANGUAGE'] = 'en'
4051- super(ButtonsTestCase, self).setUp()
4052+ super().setUp()
4053
4054 def test_buttons(self):
4055 self.open_page('buttonsElement')
4056
4057=== modified file 'tests/autopilot/ubuntuuitoolkit/tests/gallery/test_optionselector.py'
4058--- tests/autopilot/ubuntuuitoolkit/tests/gallery/test_optionselector.py 2014-07-23 19:27:18 +0000
4059+++ tests/autopilot/ubuntuuitoolkit/tests/gallery/test_optionselector.py 2015-04-14 21:04:03 +0000
4060@@ -1,6 +1,6 @@
4061 # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
4062 #
4063-# Copyright (C) 2012, 2013, 2014 Canonical Ltd.
4064+# Copyright (C) 2012, 2013, 2014, 2015 Canonical Ltd.
4065 #
4066 # This program is free software; you can redistribute it and/or modify
4067 # it under the terms of the GNU Lesser General Public License as published by
4068@@ -26,7 +26,7 @@
4069 scenarios = ubuntu_scenarios.get_device_simulation_scenarios()
4070
4071 def setUp(self):
4072- super(OptionSelectorTestCase, self).setUp()
4073+ super().setUp()
4074 self.open_page('optionSelectorsElement')
4075
4076 def test_select_option_from_collapsed_optionselector(self):
4077
4078=== modified file 'tests/autopilot/ubuntuuitoolkit/tests/gallery/test_scrollbar.py'
4079--- tests/autopilot/ubuntuuitoolkit/tests/gallery/test_scrollbar.py 2014-08-22 17:26:11 +0000
4080+++ tests/autopilot/ubuntuuitoolkit/tests/gallery/test_scrollbar.py 2015-04-14 21:04:03 +0000
4081@@ -1,6 +1,6 @@
4082 # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
4083 #
4084-# Copyright (C) 2014 Canonical Ltd.
4085+# Copyright (C) 2014, 2015 Canonical Ltd.
4086 #
4087 # This program is free software; you can redistribute it and/or modify
4088 # it under the terms of the GNU Lesser General Public License as published by
4089@@ -25,7 +25,7 @@
4090 scenarios = ubuntu_scenarios.get_device_simulation_scenarios()
4091
4092 def setUp(self):
4093- super(ScrollBarTestCase, self).setUp()
4094+ super().setUp()
4095 self.open_page('navigationElement')
4096 self.scrollbar = self.main_view.wait_select_single(
4097 'Scrollbar', objectName="TemplateScrollbar")
4098
4099=== modified file 'tests/autopilot/ubuntuuitoolkit/tests/gallery/test_textinput.py'
4100--- tests/autopilot/ubuntuuitoolkit/tests/gallery/test_textinput.py 2014-11-04 01:25:13 +0000
4101+++ tests/autopilot/ubuntuuitoolkit/tests/gallery/test_textinput.py 2015-04-14 21:04:03 +0000
4102@@ -1,6 +1,6 @@
4103 # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
4104 #
4105-# Copyright (C) 2012, 2013, 2014 Canonical Ltd.
4106+# Copyright (C) 2012, 2013, 2014, 2015 Canonical Ltd.
4107 #
4108 # This program is free software; you can redistribute it and/or modify
4109 # it under the terms of the GNU Lesser General Public License as published by
4110@@ -56,7 +56,7 @@
4111 text_input_scenarios)
4112
4113 def setUp(self):
4114- super(WriteAndClearTextInputTestCase, self).setUp()
4115+ super().setUp()
4116 # Apply the user locale from the environment
4117 # The UITK does the same, so the test must be localized
4118 locale.setlocale(locale.LC_ALL, "")
4119@@ -83,7 +83,7 @@
4120 scenarios = ubuntu_scenarios.get_device_simulation_scenarios()
4121
4122 def setUp(self):
4123- super(DisabledTextInputTestCase, self).setUp()
4124+ super().setUp()
4125 self.open_page('textinputsElement')
4126
4127 def test_textfield_disabled(self):
4128
4129=== modified file 'tests/autopilot/ubuntuuitoolkit/tests/gallery/test_toggles.py'
4130--- tests/autopilot/ubuntuuitoolkit/tests/gallery/test_toggles.py 2014-06-26 04:24:52 +0000
4131+++ tests/autopilot/ubuntuuitoolkit/tests/gallery/test_toggles.py 2015-04-14 21:04:03 +0000
4132@@ -1,6 +1,6 @@
4133 # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
4134 #
4135-# Copyright (C) 2012, 2013, 2014 Canonical Ltd.
4136+# Copyright (C) 2012, 2013, 2014, 2015 Canonical Ltd.
4137 #
4138 # This program is free software; you can redistribute it and/or modify
4139 # it under the terms of the GNU Lesser General Public License as published by
4140@@ -40,7 +40,7 @@
4141 toggles_scenarios)
4142
4143 def setUp(self):
4144- super(EnabledTogglesTestCase, self).setUp()
4145+ super().setUp()
4146 self.open_page('togglesElement')
4147
4148 def test_change_toggles_state(self):
4149@@ -71,7 +71,7 @@
4150 toggles_scenarios)
4151
4152 def setUp(self):
4153- super(DisabledTogglesTestCase, self).setUp()
4154+ super().setUp()
4155 self.open_page('togglesElement')
4156
4157 def test_change_toggles_state(self):
4158
4159=== modified file 'tests/autopilot/ubuntuuitoolkit/tests/test_fixture_setup.py'
4160--- tests/autopilot/ubuntuuitoolkit/tests/test_fixture_setup.py 2014-08-28 21:34:46 +0000
4161+++ tests/autopilot/ubuntuuitoolkit/tests/test_fixture_setup.py 2015-04-14 21:04:03 +0000
4162@@ -1,6 +1,6 @@
4163 # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
4164 #
4165-# Copyright (C) 2014 Canonical Ltd.
4166+# Copyright (C) 2014, 2015 Canonical Ltd.
4167 #
4168 # This program is free software; you can redistribute it and/or modify
4169 # it under the terms of the GNU Lesser General Public License as published by
4170@@ -17,12 +17,7 @@
4171 import os
4172 import tempfile
4173
4174-try:
4175- # Python 3.
4176- from unittest import mock
4177-except ImportError:
4178- # Python 2 add-on: python-mock.
4179- import mock
4180+from unittest import mock
4181 import testscenarios
4182 import testtools
4183 from autopilot import (
4184@@ -408,7 +403,7 @@
4185 if platform.model() != 'Desktop':
4186 self.skipTest('Unity 7 runs only on desktop.')
4187 self.useFixture(fixture_setup.HideUnity7Launcher())
4188- super(HideUnity7LauncherTestCase, self).setUp()
4189+ super().setUp()
4190
4191 def test_maximized_application_must_use_all_screen_width(self):
4192 application = self.process_manager.get_running_applications()[0]
4193@@ -434,7 +429,7 @@
4194 """Fake display with fixed widht and height for use in tests."""
4195
4196 def __init__(self, width, height):
4197- super(FakeDisplay, self).__init__()
4198+ super().__init__()
4199 self.width = width
4200 self.height = height
4201
4202
4203=== modified file 'tests/autopilot/ubuntuuitoolkit/tests/test_launcher.py'
4204--- tests/autopilot/ubuntuuitoolkit/tests/test_launcher.py 2014-11-19 11:59:31 +0000
4205+++ tests/autopilot/ubuntuuitoolkit/tests/test_launcher.py 2015-04-14 21:04:03 +0000
4206@@ -1,6 +1,6 @@
4207 # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
4208 #
4209-# Copyright (C) 2014 Canonical Ltd.
4210+# Copyright (C) 2014, 2015 Canonical Ltd.
4211 #
4212 # This program is free software; you can redistribute it and/or modify
4213 # it under the terms of the GNU Lesser General Public License as published by
4214@@ -30,9 +30,6 @@
4215 command_line.append('-touch')
4216 return command_line
4217
4218- def setUp(self):
4219- super(LauncherTouchTestCase, self).setUp()
4220-
4221 def test_apparent_touch_screen(self):
4222 textfield = self.main_view.select_single(objectName="textarea")
4223 # Trigger handlers as a courtesy to a watching person
4224@@ -46,9 +43,6 @@
4225 test_qml_file_path = os.path.join(
4226 dir_path, 'test_launcher.testcase.qml')
4227
4228- def setUp(self):
4229- super(LauncherQtTestTestCase, self).setUp()
4230-
4231 def test_can_run_qt_test_case(self):
4232 textfield = self.main_view.select_single(objectName="textarea")
4233 self.assertThat(textfield.text,
4234
4235=== modified file 'tests/autopilot/ubuntuuitoolkit/tests/test_ubuntu_scenarios.py'
4236--- tests/autopilot/ubuntuuitoolkit/tests/test_ubuntu_scenarios.py 2014-07-08 05:52:48 +0000
4237+++ tests/autopilot/ubuntuuitoolkit/tests/test_ubuntu_scenarios.py 2015-04-14 21:04:03 +0000
4238@@ -1,6 +1,6 @@
4239 # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
4240 #
4241-# Copyright (C) 2014 Canonical Ltd.
4242+# Copyright (C) 2014, 2015 Canonical Ltd.
4243 #
4244 # This program is free software; you can redistribute it and/or modify
4245 # it under the terms of the GNU Lesser General Public License as published by
4246@@ -14,10 +14,7 @@
4247 # You should have received a copy of the GNU Lesser General Public License
4248 # along with this program. If not, see <http://www.gnu.org/licenses/>.
4249
4250-try:
4251- from unittest import mock
4252-except ImportError:
4253- import mock
4254+from unittest import mock
4255
4256 import testtools
4257
4258
4259=== added file 'tests/autopilot/ubuntuuitoolkit/units.py'
4260--- tests/autopilot/ubuntuuitoolkit/units.py 1970-01-01 00:00:00 +0000
4261+++ tests/autopilot/ubuntuuitoolkit/units.py 2015-04-14 21:04:03 +0000
4262@@ -0,0 +1,38 @@
4263+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
4264+#
4265+# Copyright (C) 2015 Canonical Ltd.
4266+#
4267+# This program is free software; you can redistribute it and/or modify
4268+# it under the terms of the GNU Lesser General Public License as published by
4269+# the Free Software Foundation; version 3.
4270+#
4271+# This program is distributed in the hope that it will be useful,
4272+# but WITHOUT ANY WARRANTY; without even the implied warranty of
4273+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4274+# GNU Lesser General Public License for more details.
4275+#
4276+# You should have received a copy of the GNU Lesser General Public License
4277+# along with this program. If not, see <http://www.gnu.org/licenses/>.
4278+
4279+"""Ubuntu UI Toolkit units helpers."""
4280+
4281+import os
4282+
4283+from ubuntuuitoolkit import environment
4284+
4285+
4286+ENV_GRID_UNIT_PX = 'GRID_UNIT_PX'
4287+DEFAULT_GRID_UNIT_PX = 8
4288+
4289+
4290+def get_grid_unit():
4291+ grid_unit_px = os.environ.get(ENV_GRID_UNIT_PX, None)
4292+ if not grid_unit_px and environment.is_initctl_env_var_set(
4293+ ENV_GRID_UNIT_PX):
4294+ grid_unit_px = environment.get_initctl_env_var(ENV_GRID_UNIT_PX)
4295+ return float(grid_unit_px or DEFAULT_GRID_UNIT_PX)
4296+
4297+
4298+def gu(value):
4299+ """"Return the number of pixels corresponding to value in grid units."""
4300+ return value * get_grid_unit()
4301
4302=== modified file 'tests/license/checklicense.sh'
4303--- tests/license/checklicense.sh 2015-03-12 14:13:58 +0000
4304+++ tests/license/checklicense.sh 2015-04-14 21:04:03 +0000
4305@@ -1,6 +1,6 @@
4306-#!/usr/bin/env sh
4307+#!/bin/bash -e
4308 #
4309-# Copyright 2013 Canonical Ltd.
4310+# Copyright 2015 Canonical Ltd.
4311 #
4312 # This program is free software; you can redistribute it and/or modify
4313 # it under the terms of the GNU Lesser General Public License as published by
4314@@ -13,25 +13,20 @@
4315 #
4316 # You should have received a copy of the GNU Lesser General Public License
4317 # along with this program. If not, see <http://www.gnu.org/licenses/>.
4318-#
4319-################################################################################
4320-PATTERN='\.(c(c|pp|xx)?|h(h|pp|xx)?|p(l|m)|php|py(|x)|java|js|css|vala|qml)$'
4321-SKIP='(Canonical|GENERATED FILE|Yahoo! Inc. All rights reserved)'
4322-COMMAND="licensecheck --noconf -r * --copyright -c $PATTERN"
4323-echo Executing $COMMAND
4324-RESULTS=$($COMMAND)
4325-RESULT=$?
4326-ERRORS=$(echo "$RESULTS" | egrep -v "$SKIP" | grep '*No copyright*')
4327-COUNT=$(echo "$ERRORS" | sed 's/^ *//g' | wc -l)
4328-if [ "$ERRORS" != "" ]; then
4329- echo Found $COUNT license problems:
4330- echo "$ERRORS"
4331- return $RESULT
4332-elif [ "$RESULT" != 0 ]; then
4333- echo License check with unknown cause:
4334- echo "RESULTS"
4335- return $RESULT
4336-elif [ "$ERRORS" = "" ]; then
4337+
4338+# Based on pbuilderjenkins license checking script.
4339+
4340+include_files="\.(c(c|pp|xx)?|h(h|pp|xx)?|p(l|m)|php|py(|x)|java|js|vala|qml)$"
4341+exclude_dirs="(3rd_party|qrc_|moc_)"
4342+allowed_licenses="(Canonical|Android|Google|Digia)"
4343+issues_count=`licensecheck --noconf -r * --copyright -m -c $include_files -i $exclude_dirs | egrep -v $allowed_licenses | wc -l`
4344+
4345+if [ $issues_count -eq 0 ]; then
4346 echo No license problems found.
4347 exit 0
4348+else
4349+ echo Found $issues_count license problems:
4350+ # Run it a second time to print a nice list of issues
4351+ licensecheck --noconf -r * --copyright -m -c $include_files -i $exclude_dirs | egrep -v $allowed_licenses
4352+ exit 1
4353 fi
4354
4355=== removed file 'tests/resources/header/actions.qml'
4356--- tests/resources/header/actions.qml 2015-03-02 23:48:42 +0000
4357+++ tests/resources/header/actions.qml 1970-01-01 00:00:00 +0000
4358@@ -1,47 +0,0 @@
4359-/*
4360- * Copyright (C) 2013-2015 Canonical Ltd.
4361- *
4362- * This program is free software; you can redistribute it and/or modify
4363- * it under the terms of the GNU Lesser General Public License as published by
4364- * the Free Software Foundation; version 3.
4365- *
4366- * This program is distributed in the hope that it will be useful,
4367- * but WITHOUT ANY WARRANTY; without even the implied warranty of
4368- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4369- * GNU Lesser General Public License for more details.
4370- *
4371- * You should have received a copy of the GNU Lesser General Public License
4372- * along with this program. If not, see <http://www.gnu.org/licenses/>.
4373- */
4374-
4375-import QtQuick 2.4
4376-import Ubuntu.Components 1.2
4377-
4378-MainView {
4379- width: units.gu(50)
4380- height: units.gu(70)
4381-
4382- Page {
4383- title: "Actions"
4384- Label {
4385- anchors.centerIn: parent
4386- text: "New API"
4387- }
4388- head {
4389- actions: [
4390- Action {
4391- iconName: "settings"
4392- onTriggered: print("Trigger first action")
4393- },
4394- Action {
4395- iconName: "camera-flip"
4396- onTriggered: print("Trigger second action")
4397- }
4398- ]
4399- backAction: Action {
4400- iconName: "close"
4401- onTriggered: print("Trigger custom back action")
4402- }
4403- }
4404- }
4405-}
4406
4407=== removed file 'tests/resources/header/backButton.qml'
4408--- tests/resources/header/backButton.qml 2015-03-02 23:48:42 +0000
4409+++ tests/resources/header/backButton.qml 1970-01-01 00:00:00 +0000
4410@@ -1,59 +0,0 @@
4411-/*
4412- * Copyright (C) 2013-2015 Canonical Ltd.
4413- *
4414- * This program is free software; you can redistribute it and/or modify
4415- * it under the terms of the GNU Lesser General Public License as published by
4416- * the Free Software Foundation; version 3.
4417- *
4418- * This program is distributed in the hope that it will be useful,
4419- * but WITHOUT ANY WARRANTY; without even the implied warranty of
4420- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4421- * GNU Lesser General Public License for more details.
4422- *
4423- * You should have received a copy of the GNU Lesser General Public License
4424- * along with this program. If not, see <http://www.gnu.org/licenses/>.
4425- */
4426-
4427-import QtQuick 2.4
4428-import Ubuntu.Components 1.2
4429-
4430-MainView {
4431- id: mainView
4432- width: units.gu(50)
4433- height: units.gu(70)
4434-
4435- PageStack {
4436- id: stack
4437-
4438- Component.onCompleted: stack.push(firstPage)
4439- Page {
4440- id: firstPage
4441- title: "Stack"
4442- Button {
4443- anchors.centerIn: parent
4444- text: "Click me"
4445- onTriggered: stack.push(pageOnStack)
4446- }
4447- head {
4448- actions: Action {
4449- iconName: "settings"
4450- text: "Settings"
4451- }
4452- }
4453- }
4454-
4455- Page {
4456- id: pageOnStack
4457- visible: false
4458- title: "Stacked page"
4459- Label {
4460- anchors.centerIn: parent
4461- text: "Use back button to return"
4462- }
4463- head.actions: Action {
4464- iconName: "info"
4465- text: "information"
4466- }
4467- }
4468- }
4469-}
4470
4471=== removed file 'tests/resources/header/lockedToolbar.deprecated.qml'
4472--- tests/resources/header/lockedToolbar.deprecated.qml 2015-03-06 12:42:00 +0000
4473+++ tests/resources/header/lockedToolbar.deprecated.qml 1970-01-01 00:00:00 +0000
4474@@ -1,52 +0,0 @@
4475-/*
4476- * Copyright (C) 2014 Canonical Ltd.
4477- *
4478- * This program is free software; you can redistribute it and/or modify
4479- * it under the terms of the GNU Lesser General Public License as published by
4480- * the Free Software Foundation; version 3.
4481- *
4482- * This program is distributed in the hope that it will be useful,
4483- * but WITHOUT ANY WARRANTY; without even the implied warranty of
4484- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4485- * GNU Lesser General Public License for more details.
4486- *
4487- * You should have received a copy of the GNU Lesser General Public License
4488- * along with this program. If not, see <http://www.gnu.org/licenses/>.
4489- */
4490-
4491-import QtQuick 2.0
4492-import Ubuntu.Components 1.1
4493-
4494-MainView {
4495- width: units.gu(50)
4496- height: units.gu(80)
4497- id: mainView
4498-
4499- Page {
4500- id: page
4501- title: "test page"
4502- Label {
4503- anchors.centerIn: parent
4504- text: "testing the toolbar"
4505- }
4506- tools: ToolbarItems {
4507- id: toolbarItems
4508- ToolbarButton {
4509- text: "action1"
4510- }
4511- }
4512- }
4513-
4514- ToolbarItems {
4515- id: lockedTools
4516- ToolbarButton {
4517- text: "locked"
4518- }
4519- locked: true
4520- opened: true
4521- }
4522-
4523- Component.onCompleted: {
4524- page.tools = lockedTools;
4525- }
4526-}
4527
4528=== removed file 'tests/resources/header/sections.qml'
4529--- tests/resources/header/sections.qml 2015-03-02 23:48:42 +0000
4530+++ tests/resources/header/sections.qml 1970-01-01 00:00:00 +0000
4531@@ -1,41 +0,0 @@
4532-/*
4533- * Copyright (C) 2013-2015 Canonical Ltd.
4534- *
4535- * This program is free software; you can redistribute it and/or modify
4536- * it under the terms of the GNU Lesser General Public License as published by
4537- * the Free Software Foundation; version 3.
4538- *
4539- * This program is distributed in the hope that it will be useful,
4540- * but WITHOUT ANY WARRANTY; without even the implied warranty of
4541- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4542- * GNU Lesser General Public License for more details.
4543- *
4544- * You should have received a copy of the GNU Lesser General Public License
4545- * along with this program. If not, see <http://www.gnu.org/licenses/>.
4546- */
4547-
4548-import QtQuick 2.4
4549-import Ubuntu.Components 1.2
4550-
4551-MainView {
4552- id: mainView
4553- width: units.gu(50)
4554- height: units.gu(70)
4555-
4556- Page {
4557- title: "Sections"
4558- id: sectionsPage
4559- head {
4560- sections {
4561- model: ["navy", "lightblue", "brown"]
4562- }
4563- }
4564- Rectangle {
4565- anchors {
4566- fill: parent
4567- margins: units.gu(2)
4568- }
4569- color: sectionsPage.head.sections.model[sectionsPage.head.sections.selectedIndex]
4570- }
4571- }
4572-}
4573
4574=== removed file 'tests/resources/navigation/simpleTabs.qml'
4575--- tests/resources/navigation/simpleTabs.qml 2015-03-06 12:42:00 +0000
4576+++ tests/resources/navigation/simpleTabs.qml 1970-01-01 00:00:00 +0000
4577@@ -1,60 +0,0 @@
4578-/*
4579- * Copyright 2013 Canonical Ltd.
4580- *
4581- * This program is free software; you can redistribute it and/or modify
4582- * it under the terms of the GNU Lesser General Public License as published by
4583- * the Free Software Foundation; version 3.
4584- *
4585- * This program is distributed in the hope that it will be useful,
4586- * but WITHOUT ANY WARRANTY; without even the implied warranty of
4587- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4588- * GNU Lesser General Public License for more details.
4589- *
4590- * You should have received a copy of the GNU Lesser General Public License
4591- * along with this program. If not, see <http://www.gnu.org/licenses/>.
4592- */
4593-
4594-import QtQuick 2.0
4595-import Ubuntu.Components 1.1
4596-
4597-MainView {
4598- width: 800
4599- height: 600
4600- useDeprecatedToolbar: false
4601-
4602- Tabs {
4603- id: tabs
4604- selectedTabIndex: 1
4605-
4606- Tab {
4607- title: i18n.tr("One")
4608- page: Page {
4609- Label {
4610- anchors.centerIn: parent
4611- text: i18n.tr("First page")
4612- }
4613- tools: ToolbarItems {
4614- ToolbarButton {
4615- text: "1111"
4616- iconSource: "call_icon.png"
4617- }
4618- }
4619- }
4620- }
4621- Tab {
4622- title: i18n.tr("Two")
4623- page: Page {
4624- Label {
4625- anchors.centerIn: parent
4626- text: i18n.tr("Second page")
4627- }
4628- tools: ToolbarItems {
4629- ToolbarButton {
4630- text: "2222"
4631- iconSource: "call_icon.png"
4632- }
4633- }
4634- }
4635- }
4636- }
4637-}
4638
4639=== added directory 'tests/resources/subtheming'
4640=== added file 'tests/resources/subtheming/Simple.qml'
4641--- tests/resources/subtheming/Simple.qml 1970-01-01 00:00:00 +0000
4642+++ tests/resources/subtheming/Simple.qml 2015-04-14 21:04:03 +0000
4643@@ -0,0 +1,53 @@
4644+/*
4645+ * Copyright 2015 Canonical Ltd.
4646+ *
4647+ * This program is free software; you can redistribute it and/or modify
4648+ * it under the terms of the GNU Lesser General Public License as published by
4649+ * the Free Software Foundation; version 3.
4650+ *
4651+ * This program is distributed in the hope that it will be useful,
4652+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4653+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4654+ * GNU Lesser General Public License for more details.
4655+ *
4656+ * You should have received a copy of the GNU Lesser General Public License
4657+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4658+ */
4659+
4660+import QtQuick 2.4
4661+import Ubuntu.Components 1.3
4662+
4663+Item {
4664+ id: component1
4665+ objectName: "TopItem"
4666+ width: units.gu(50)
4667+ height: units.gu(100)
4668+
4669+ Column {
4670+ objectName: "Column"
4671+ anchors.fill: parent
4672+ Label {
4673+ text: "Hallo"
4674+ }
4675+ Button {
4676+ text: "Theme change"
4677+ onClicked: theme.name = "Ubuntu.Components.Themes.SuruDark"
4678+ }
4679+
4680+ TextField {
4681+ objectName: "OuterText"
4682+ property string styleName: theme.name
4683+ onStyleNameChanged: print(objectName, styleName)
4684+ }
4685+ StyledItem {
4686+ objectName: "SuruDarkStyled"
4687+ width: parent.width
4688+ height: units.gu(10)
4689+ TextField {
4690+ objectName: "InnerText"
4691+ property string styleName: theme.name
4692+ onStyleNameChanged: print(objectName, styleName)
4693+ }
4694+ }
4695+ }
4696+}
4697
4698=== modified file 'tests/uitk_test_plan.sh'
4699--- tests/uitk_test_plan.sh 2015-03-12 06:19:17 +0000
4700+++ tests/uitk_test_plan.sh 2015-04-14 21:04:03 +0000
4701@@ -53,7 +53,7 @@
4702 " music_app"
4703 " gallery_app"
4704 " filemanager"
4705- " ubuntu_terminal_app"
4706+# " ubuntu_terminal_app"
4707 " -n unity8"
4708 " ubuntu_clock_app"
4709 # " -p dialer-app-autopilot dialer_app"
4710@@ -176,6 +176,8 @@
4711 network
4712 adb -s ${SERIALNUMBER} shell "echo ${PASSWORD}|sudo -S reboot 2>&1|grep -v password"
4713 sleep_indicator 120
4714+ # Required for at least rtm-14.09/mako, phablet-click-test-setup fails otherwise and we don't need terminal
4715+ adb -s ${SERIALNUMBER} shell "echo ${PASSWORD}|sudo -S click unregister com.ubuntu.terminal 2>&1|grep -v password"
4716 echo -e "phablet-click-test-setup \e[31m${DISTRO} ${SERIES}\e[0m"
4717 phablet-click-test-setup -s ${SERIALNUMBER} --distribution=${DISTRO} --series=${SERIES} 2>&1 || fatal_failure "phablet-click-test-setup has failed"
4718 echo "Sleep after phablet-click-test-setup";
4719
4720=== added file 'tests/unit/tst_components/tst_styleditem13.qml'
4721--- tests/unit/tst_components/tst_styleditem13.qml 1970-01-01 00:00:00 +0000
4722+++ tests/unit/tst_components/tst_styleditem13.qml 2015-04-14 21:04:03 +0000
4723@@ -0,0 +1,35 @@
4724+/*
4725+ * Copyright 2015 Canonical Ltd.
4726+ *
4727+ * This program is free software; you can redistribute it and/or modify
4728+ * it under the terms of the GNU Lesser General Public License as published by
4729+ * the Free Software Foundation; version 3.
4730+ *
4731+ * This program is distributed in the hope that it will be useful,
4732+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4733+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4734+ * GNU Lesser General Public License for more details.
4735+ *
4736+ * You should have received a copy of the GNU Lesser General Public License
4737+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4738+ */
4739+
4740+import QtTest 1.0
4741+import Ubuntu.Components 1.3
4742+import QtQuick 2.4
4743+
4744+TestCase {
4745+ name: "StyledItemAPI"
4746+
4747+ StyledItem {
4748+ id: scope
4749+ StyledItem {
4750+ id: inner
4751+ }
4752+ }
4753+
4754+ function test_api() {
4755+ verify(scope.theme, "Null default theme");
4756+ compare(inner.theme, scope.theme, "default themes should be inherited!");
4757+ }
4758+}
4759
4760=== added file 'tests/unit/tst_performance/StyledItemOldTheming.qml'
4761--- tests/unit/tst_performance/StyledItemOldTheming.qml 1970-01-01 00:00:00 +0000
4762+++ tests/unit/tst_performance/StyledItemOldTheming.qml 2015-04-14 21:04:03 +0000
4763@@ -0,0 +1,72 @@
4764+/*
4765+ * Copyright 2015 Canonical Ltd.
4766+ *
4767+ * This program is free software; you can redistribute it and/or modify
4768+ * it under the terms of the GNU Lesser General Public License as published by
4769+ * the Free Software Foundation; version 3.
4770+ *
4771+ * This program is distributed in the hope that it will be useful,
4772+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4773+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4774+ * GNU Lesser General Public License for more details.
4775+ *
4776+ * You should have received a copy of the GNU Lesser General Public License
4777+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4778+ */
4779+
4780+import QtQuick 2.4
4781+import Ubuntu.Components 1.2
4782+
4783+StyledItem {
4784+ id: component1
4785+ width: units.gu(50)
4786+ height: units.gu(100)
4787+
4788+ property string newTheme
4789+ onNewThemeChanged: Theme.name = newTheme
4790+
4791+ Column {
4792+ anchors.fill: parent
4793+ StyledItem {
4794+ id: component2
4795+ width: units.gu(40)
4796+ height: units.gu(80)
4797+
4798+ StyledItem {
4799+ id: component3
4800+ width: units.gu(40)
4801+ height: units.gu(80)
4802+ Item {
4803+ anchors.fill: parent
4804+ StyledItem {
4805+ id: component4
4806+ width: units.gu(40)
4807+ height: units.gu(80)
4808+ }
4809+ Loader {
4810+ id: loader1
4811+ width: units.gu(30)
4812+ height: units.gu(30)
4813+ sourceComponent: dynamicItem
4814+ }
4815+ }
4816+ }
4817+ }
4818+ Component {
4819+ id: dynamicItem
4820+ Item {
4821+ StyledItem {
4822+ id: component5
4823+ anchors.fill: parent
4824+ }
4825+ }
4826+ }
4827+
4828+ Loader {
4829+ id: loader2
4830+ width: units.gu(30)
4831+ height: units.gu(30)
4832+ sourceComponent: dynamicItem
4833+ }
4834+ }
4835+}
4836
4837=== added file 'tests/unit/tst_performance/Styling.qml'
4838--- tests/unit/tst_performance/Styling.qml 1970-01-01 00:00:00 +0000
4839+++ tests/unit/tst_performance/Styling.qml 2015-04-14 21:04:03 +0000
4840@@ -0,0 +1,76 @@
4841+/*
4842+ * Copyright 2015 Canonical Ltd.
4843+ *
4844+ * This program is free software; you can redistribute it and/or modify
4845+ * it under the terms of the GNU Lesser General Public License as published by
4846+ * the Free Software Foundation; version 3.
4847+ *
4848+ * This program is distributed in the hope that it will be useful,
4849+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4850+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4851+ * GNU Lesser General Public License for more details.
4852+ *
4853+ * You should have received a copy of the GNU Lesser General Public License
4854+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4855+ */
4856+
4857+import QtQuick 2.4
4858+import Ubuntu.Components 1.3
4859+
4860+StyledItem {
4861+ id: component1
4862+ width: units.gu(50)
4863+ height: units.gu(100)
4864+
4865+ property string newTheme
4866+ onNewThemeChanged: component3.theme.name = newTheme
4867+
4868+ Column {
4869+ anchors.fill: parent
4870+ StyledItem {
4871+ id: component2
4872+ width: units.gu(40)
4873+ height: units.gu(80)
4874+
4875+ StyledItem {
4876+ id: component3
4877+ width: units.gu(40)
4878+ height: units.gu(80)
4879+ Item {
4880+ anchors.fill: parent
4881+ StyledItem {
4882+ id: component4
4883+ theme: ThemeSettings {
4884+ name: "Ubuntu.Components.Themes.Ambiance"
4885+ }
4886+
4887+ width: units.gu(40)
4888+ height: units.gu(80)
4889+ }
4890+ Loader {
4891+ id: loader1
4892+ width: units.gu(30)
4893+ height: units.gu(30)
4894+ sourceComponent: dynamicItem
4895+ }
4896+ }
4897+ }
4898+ }
4899+ Component {
4900+ id: dynamicItem
4901+ Item {
4902+ StyledItem {
4903+ id: component5
4904+ anchors.fill: parent
4905+ }
4906+ }
4907+ }
4908+
4909+ Loader {
4910+ id: loader2
4911+ width: units.gu(30)
4912+ height: units.gu(30)
4913+ sourceComponent: dynamicItem
4914+ }
4915+ }
4916+}
4917
4918=== modified file 'tests/unit/tst_performance/tst_performance.cpp'
4919--- tests/unit/tst_performance/tst_performance.cpp 2015-03-02 13:49:13 +0000
4920+++ tests/unit/tst_performance/tst_performance.cpp 2015-04-14 21:04:03 +0000
4921@@ -1,5 +1,5 @@
4922 /*
4923- * Copyright 2012 Canonical Ltd.
4924+ * Copyright 2015 Canonical Ltd.
4925 *
4926 * This program is free software; you can redistribute it and/or modify
4927 * it under the terms of the GNU Lesser General Public License as published by
4928@@ -22,8 +22,6 @@
4929 #include <QtQuick/QQuickView>
4930 #include <QtQuick/QQuickItem>
4931
4932-#include "uctheme.h"
4933-
4934 class tst_Performance : public QObject
4935 {
4936 Q_OBJECT
4937@@ -65,6 +63,35 @@
4938 delete quickView;
4939 }
4940
4941+ void benchmark_theming_data()
4942+ {
4943+ QTest::addColumn<QString>("document");
4944+ QTest::addColumn<QUrl>("theme");
4945+ QTest::addColumn<QByteArray>("enableSubtheming");
4946+
4947+ QTest::newRow("old theming, subtheming disabled") << "StyledItemOldTheming.qml" << QUrl("Ubuntu.Components.Themes.SuruDark") << QByteArray("no");
4948+ QTest::newRow("old theming, subtheming enabled") << "StyledItemOldTheming.qml" << QUrl("Ubuntu.Components.Themes.SuruDark") << QByteArray("yes");
4949+ QTest::newRow("subtheming, no changes on themes") << "Styling.qml" << QUrl() << QByteArray("yes");
4950+ QTest::newRow("subtheming, change mid item") << "Styling.qml" << QUrl("Ubuntu.Components.Themes.SuruDark") << QByteArray("yes");
4951+ }
4952+ void benchmark_theming()
4953+ {
4954+ QFETCH(QString, document);
4955+ QFETCH(QUrl, theme);
4956+ QFETCH(QByteArray, enableSubtheming);
4957+
4958+ qputenv("UITK_SUBTHEMING", enableSubtheming);
4959+ QQuickItem *root = 0;
4960+ QBENCHMARK {
4961+ root = loadDocument(document);
4962+ if (root && theme.isValid()) {
4963+ root->setProperty("newTheme", theme.toString());
4964+ }
4965+ }
4966+ if (root)
4967+ delete root;
4968+ }
4969+
4970 void benchmark_GridOfComponents_data() {
4971 QTest::addColumn<QString>("document");
4972 QTest::addColumn<QUrl>("theme");
4973@@ -95,6 +122,9 @@
4974 QQuickItem *root = 0;
4975 QBENCHMARK {
4976 root = loadDocument(document);
4977+ if (root && theme.isValid()) {
4978+ root->setProperty("newTheme", theme.toString());
4979+ }
4980 }
4981 if (root)
4982 delete root;
4983@@ -115,7 +145,6 @@
4984 loadDocument(document);
4985 }
4986 }
4987-
4988 };
4989
4990 QTEST_MAIN(tst_Performance)
4991
4992=== modified file 'tests/unit/tst_performance/tst_performance.pro'
4993--- tests/unit/tst_performance/tst_performance.pro 2015-03-02 13:39:03 +0000
4994+++ tests/unit/tst_performance/tst_performance.pro 2015-04-14 21:04:03 +0000
4995@@ -25,4 +25,6 @@
4996 ListItemsEmptyList.qml \
4997 ListItemsBaseList.qml \
4998 ListItemWithInlineActionsList.qml \
4999- ListItemWithActionsList.qml
5000+ ListItemWithActionsList.qml \
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches

to status/vote changes: