Merge lp:~tpeeters/ubuntu-ui-toolkit/noPrivateHeader into lp:~bzoltan/ubuntu-ui-toolkit/landing_140514

Proposed by Tim Peeters
Status: Superseded
Proposed branch: lp:~tpeeters/ubuntu-ui-toolkit/noPrivateHeader
Merge into: lp:~bzoltan/ubuntu-ui-toolkit/landing_140514
Diff against target: 5307 lines (+2765/-560)
87 files modified
CHANGES (+1/-0)
components.api (+55/-2)
debian/changelog (+113/-2)
debian/control (+7/-7)
examples/ubuntu-ui-toolkit-gallery/ListItems.qml (+11/-2)
modules/Ubuntu/Components/AnimatedItem.qml (+1/-38)
modules/Ubuntu/Components/Label.qml (+1/-0)
modules/Ubuntu/Components/ListItems/Base.qml (+1/-1)
modules/Ubuntu/Components/ListItems/Empty.qml (+1/-1)
modules/Ubuntu/Components/ListItems/ThinDivider.qml (+5/-2)
modules/Ubuntu/Components/Page.qml (+7/-0)
modules/Ubuntu/Components/Pickers/DatePicker.qml (+7/-7)
modules/Ubuntu/Components/Pickers/PickerRow.qml (+1/-1)
modules/Ubuntu/Components/TextInputPopover.qml (+7/-7)
modules/Ubuntu/Components/Themes/Ambiance/ActivityIndicatorStyle.qml (+2/-2)
modules/Ubuntu/Components/Themes/Ambiance/TabBarStyle.qml (+2/-2)
modules/Ubuntu/Components/Toolbar.qml (+3/-3)
modules/Ubuntu/Components/ToolbarItems.qml (+1/-1)
modules/Ubuntu/Components/plugin/filterbehavior.cpp (+47/-0)
modules/Ubuntu/Components/plugin/filterbehavior.h (+46/-0)
modules/Ubuntu/Components/plugin/i18n.cpp (+7/-11)
modules/Ubuntu/Components/plugin/plugin.cpp (+10/-1)
modules/Ubuntu/Components/plugin/plugin.pro (+6/-0)
modules/Ubuntu/Components/plugin/shapeitem.cpp (+47/-13)
modules/Ubuntu/Components/plugin/shapeitem.h (+8/-0)
modules/Ubuntu/Components/plugin/shapeitemtexture.h (+2/-3)
modules/Ubuntu/Components/plugin/sortbehavior.cpp (+47/-0)
modules/Ubuntu/Components/plugin/sortbehavior.h (+46/-0)
modules/Ubuntu/Components/plugin/sortfiltermodel.cpp (+252/-0)
modules/Ubuntu/Components/plugin/sortfiltermodel.h (+68/-0)
modules/Ubuntu/Components/plugin/thumbnailgenerator.cpp (+6/-3)
modules/Ubuntu/Components/plugin/ucalarm.cpp (+15/-4)
modules/Ubuntu/Components/plugin/ucthemesettings.cpp (+4/-3)
modules/Ubuntu/Layouts/plugin/plugin.pro (+1/-1)
modules/Ubuntu/Layouts/plugin/propertychanges.cpp (+18/-33)
modules/Ubuntu/Layouts/plugin/propertychanges_p.h (+3/-16)
modules/Ubuntu/Layouts/plugin/ulitemlayout.h (+4/-1)
modules/Ubuntu/Layouts/plugin/ullayouts.cpp (+92/-81)
modules/Ubuntu/Layouts/plugin/ullayouts.h (+8/-3)
modules/Ubuntu/Layouts/plugin/ullayouts_p.h (+3/-5)
po/ca.po (+2/-2)
po/de.po (+2/-2)
po/es.po (+2/-2)
po/fi.po (+2/-2)
po/fr.po (+2/-2)
po/gl.po (+2/-2)
po/he.po (+2/-2)
po/hu.po (+2/-2)
po/ko.po (+2/-2)
po/my.po (+2/-2)
po/nl.po (+2/-2)
po/oc.po (+2/-2)
po/pt_BR.po (+2/-2)
po/sv.po (+2/-2)
po/uk.po (+2/-2)
tests/autopilot/ubuntuuitoolkit/__init__.py (+4/-2)
tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/__init__.py (+4/-2)
tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_common.py (+45/-1)
tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_flickable.py (+53/-30)
tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_header.py (+32/-1)
tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_mainview.py (+1/-1)
tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_qquicklistview.py (+28/-11)
tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_textfield.py (+10/-5)
tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/pickers.py (+255/-0)
tests/autopilot/ubuntuuitoolkit/emulators.py (+2/-2)
tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_date_picker.py (+203/-0)
tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_flickable.py (+201/-0)
tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_header.py (+50/-24)
tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_textfield.py (+27/-0)
tests/autopilot/ubuntuuitoolkit/tests/gallery/test_gallery.py (+4/-0)
tests/autopilot/ubuntuuitoolkit/tests/gallery/test_optionselector.py (+47/-80)
tests/autopilot/ubuntuuitoolkit/tests/test_emulators.py (+1/-1)
tests/qmlapicheck.py (+6/-5)
tests/resources/alarm/Alarms.qml (+1/-1)
tests/resources/toolbar/header.qml (+143/-0)
tests/unit/tst_alarms/tst_alarms.cpp (+46/-0)
tests/unit/tst_components/tst_label.qml (+1/-1)
tests/unit/tst_components/tst_sortfiltermodel.qml (+123/-0)
tests/unit/tst_components/tst_toolbaritems.qml (+10/-1)
tests/unit/tst_i18n/localizedApp/.click/status (+1/-0)
tests/unit/tst_i18n/src/tst_i18n.cpp (+5/-17)
tests/unit/tst_i18n/tst_i18n.pro (+1/-1)
tests/unit_x11/tst_components/tst_datepicker.qml (+1/-1)
tests/unit_x11/tst_layouts/NestedVisibility.qml (+163/-0)
tests/unit_x11/tst_layouts/Visibility.qml (+84/-0)
tests/unit_x11/tst_layouts/tst_layouts.cpp (+214/-86)
tests/unit_x11/tst_layouts/tst_layouts.pro (+3/-1)
To merge this branch: bzr merge lp:~tpeeters/ubuntu-ui-toolkit/noPrivateHeader
Reviewer Review Type Date Requested Status
Zoltan Balogh Pending
Review via email: mp+221280@code.launchpad.net

Commit message

Undo changes of r1082 that cause a regression in messaging-app (and contenthub).

Description of the change

Undo changes of r1082 that cause a regression in messaging-app (and contenthub).

To post a comment you must log in.

Unmerged revisions

1088. By Tim Peeters

revert r1082 because it breaks contenthub (and thus messaging-app)

1087. By Zoltan Balogh

Landing 28/05

1086. By Cris Dywan

Tweak API parsing to include the Button.font property. Fixes: https://bugs.launchpad.net/bugs/1322169.

Approved by PS Jenkins bot.

1085. By Zsombor Egri

Missing "default" keyword added to children property of Base, causing rendering and test case failures on Qt 5.3. Fixes: https://bugs.launchpad.net/bugs/1317881.

Approved by PS Jenkins bot, Tim Peeters.

1084. By Ugo Riboni

Allow requesting extra large thumbnails.

Approved by PS Jenkins bot, Zsombor Egri.

1083. By Florian Boucault

AnimatedItem: deprecated as it was not used and still costly.

Approved by PS Jenkins bot, Zsombor Egri.

1082. By Tim Peeters

Make Header component internal as it was always documented.

Approved by Zsombor Egri, PS Jenkins bot.

1081. By Cris Dywan

Call bindtextdomain on /usr if APP_DIR is not defined. Fixes: https://bugs.launchpad.net/bugs/1322630.

Approved by PS Jenkins bot, Tim Peeters, David Planella.

1080. By Zoltan Balogh

Replace split with match to work around failing split() function usage.

Approved by Zsombor Egri, PS Jenkins bot.

1079. By Cris Dywan

More unit tests and property corrections for SortFilterModel.

Approved by Tim Peeters, PS Jenkins bot.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'CHANGES'
--- CHANGES 2014-04-24 20:35:41 +0000
+++ CHANGES 2014-05-28 18:09:57 +0000
@@ -19,6 +19,7 @@
1919
20API Changes20API Changes
21***********21***********
22* CHANGED IN: ThinDivider: base class Image TO Rectangle
22* ADDED IN: all modules exported as 0.1 as well as 1.0 version23* ADDED IN: all modules exported as 0.1 as well as 1.0 version
23* ADDED IN: PickerDelegate: readonly property Picker picker24* ADDED IN: PickerDelegate: readonly property Picker picker
24* CHANGED IN: OptionSelector: readonly property bool currentlyExpanded TO property bool currentlyExpanded25* CHANGED IN: OptionSelector: readonly property bool currentlyExpanded TO property bool currentlyExpanded
2526
=== modified file 'components.api'
--- components.api 2014-05-13 09:13:32 +0000
+++ components.api 2014-05-28 18:09:57 +0000
@@ -31,6 +31,7 @@
31AbstractButton31AbstractButton
32 property color color32 property color color
33 property Gradient gradient33 property Gradient gradient
34 property font font
34 property string iconPosition35 property string iconPosition
35CheckBox 0.1 1.036CheckBox 0.1 1.0
36AbstractButton37AbstractButton
@@ -94,7 +95,7 @@
94 property real __leftIconMargin95 property real __leftIconMargin
95 property real __rightIconMargin96 property real __rightIconMargin
96 property bool __iconIsItem97 property bool __iconIsItem
97 property internal children98 default property internal children
98Caption 0.1 1.099Caption 0.1 1.0
99Item100Item
100 property string text101 property string text
@@ -140,6 +141,7 @@
140 property bool expanded141 property bool expanded
141 property bool multiSelection142 property bool multiSelection
142 property bool colourImage143 property bool colourImage
144 property Component delegate
143 property real containerHeight145 property real containerHeight
144 property int selectedIndex146 property int selectedIndex
145 property bool currentlyExpanded147 property bool currentlyExpanded
@@ -175,7 +177,7 @@
175Base177Base
176 property string subText178 property string subText
177ThinDivider 0.1 1.0179ThinDivider 0.1 1.0
178Image180Rectangle
179ValueSelector 0.1 1.0181ValueSelector 0.1 1.0
180Empty182Empty
181 property variant icon183 property variant icon
@@ -204,12 +206,14 @@
204Object 0.1 1.0206Object 0.1 1.0
205QtObject207QtObject
206 default property internal children208 default property internal children
209 property list<QtObject> __defaultPropertyFix
207OptionSelector 0.1 1.0210OptionSelector 0.1 1.0
208ListItem.Empty211ListItem.Empty
209 property var model212 property var model
210 property bool expanded213 property bool expanded
211 property bool multiSelection214 property bool multiSelection
212 property bool colourImage215 property bool colourImage
216 property Component delegate
213 property real containerHeight217 property real containerHeight
214 property int selectedIndex218 property int selectedIndex
215 property bool currentlyExpanded219 property bool currentlyExpanded
@@ -235,6 +239,7 @@
235Page 0.1 1.0239Page 0.1 1.0
236PageTreeNode240PageTreeNode
237 property string title241 property string title
242 property Item tools
238 property Item __customHeaderContents243 property Item __customHeaderContents
239 property Flickable flickable244 property Flickable flickable
240 property list<Action> actions245 property list<Action> actions
@@ -355,6 +360,7 @@
355OrientationHelper360OrientationHelper
356 property Item dismissArea361 property Item dismissArea
357 property bool grabDismissAreaEvents362 property bool grabDismissAreaEvents
363 property PropertyAnimation fadingAnimation
358 function show()364 function show()
359 function hide()365 function hide()
360 function __closeIfHidden()366 function __closeIfHidden()
@@ -613,6 +619,11 @@
613 function mouseLongPress(item, x, y, button, modifiers, delay)619 function mouseLongPress(item, x, y, button, modifiers, delay)
614 function tryCompareFunction(func, expectedResult, timeout)620 function tryCompareFunction(func, expectedResult, timeout)
615plugins.qmltypes621plugins.qmltypes
622 name: "FilterBehavior"
623 prototype: "QObject"
624 exports: ["FilterBehavior 1.1"]
625 Property { name: "property"; type: "string" }
626 Property { name: "pattern"; type: "QRegExp" }
616 name: "InverseMouseAreaType"627 name: "InverseMouseAreaType"
617 prototype: "QQuickMouseArea"628 prototype: "QQuickMouseArea"
618 exports: ["InverseMouseArea 0.1", "InverseMouseArea 1.0"]629 exports: ["InverseMouseArea 0.1", "InverseMouseArea 1.0"]
@@ -621,6 +632,41 @@
621 Method {632 Method {
622 name: "contains"633 name: "contains"
623 Parameter { name: "point"; type: "QPointF" }634 Parameter { name: "point"; type: "QPointF" }
635 name: "QAbstractProxyModel"
636 prototype: "QAbstractItemModel"
637 Property { name: "sourceModel"; type: "QAbstractItemModel"; isPointer: true }
638 name: "QSortFilterProxyModel"
639 prototype: "QAbstractProxyModel"
640 Property { name: "filterRegExp"; type: "QRegExp" }
641 Property { name: "filterKeyColumn"; type: "int" }
642 Property { name: "dynamicSortFilter"; type: "bool" }
643 Property { name: "filterCaseSensitivity"; type: "Qt::CaseSensitivity" }
644 Property { name: "sortCaseSensitivity"; type: "Qt::CaseSensitivity" }
645 Property { name: "isSortLocaleAware"; type: "bool" }
646 Property { name: "sortRole"; type: "int" }
647 Property { name: "filterRole"; type: "int" }
648 Method {
649 name: "setFilterRegExp"
650 Parameter { name: "pattern"; type: "string" }
651 Method {
652 name: "setFilterWildcard"
653 Parameter { name: "pattern"; type: "string" }
654 Method {
655 name: "setFilterFixedString"
656 Parameter { name: "pattern"; type: "string" }
657 Method { name: "clear" }
658 Method { name: "invalidate" }
659 name: "QSortFilterProxyModelQML"
660 prototype: "QSortFilterProxyModel"
661 exports: ["SortFilterModel 1.1"]
662 Property { name: "model"; type: "QAbstractItemModel"; isPointer: true }
663 Property { name: "count"; type: "int"; isReadonly: true }
664 Property { name: "sort"; type: "SortBehavior"; isReadonly: true; isPointer: true }
665 Property { name: "filter"; type: "FilterBehavior"; isReadonly: true; isPointer: true }
666 Method {
667 name: "get"
668 Parameter { name: "row"; type: "int" }
669 Method { name: "count"; type: "int" }
624 name: "ShapeItem"670 name: "ShapeItem"
625 prototype: "QQuickItem"671 prototype: "QQuickItem"
626 exports: ["Shape 0.1", "Shape 1.0"]672 exports: ["Shape 0.1", "Shape 1.0"]
@@ -636,6 +682,11 @@
636 Property { name: "borderSource"; type: "string" }682 Property { name: "borderSource"; type: "string" }
637 Signal { name: "borderChanged" }683 Signal { name: "borderChanged" }
638 Method { name: "gridUnitChanged" }684 Method { name: "gridUnitChanged" }
685 name: "SortBehavior"
686 prototype: "QObject"
687 exports: ["SortBehavior 1.1"]
688 Property { name: "property"; type: "string" }
689 Property { name: "order"; type: "Qt::SortOrder" }
639 name: "UCAlarm"690 name: "UCAlarm"
640 prototype: "QObject"691 prototype: "QObject"
641 exports: ["Alarm 0.1", "Alarm 1.0"]692 exports: ["Alarm 0.1", "Alarm 1.0"]
@@ -819,6 +870,8 @@
819 exports: ["Layouts 0.1", "Layouts 1.0"]870 exports: ["Layouts 0.1", "Layouts 1.0"]
820 Property { name: "currentLayout"; type: "string"; isReadonly: true }871 Property { name: "currentLayout"; type: "string"; isReadonly: true }
821 Property { name: "layouts"; type: "ULConditionalLayout"; isList: true; isReadonly: true }872 Property { name: "layouts"; type: "ULConditionalLayout"; isList: true; isReadonly: true }
873 Property { name: "data"; type: "QObject"; isList: true; isReadonly: true }
874 Property { name: "children"; type: "QQuickItem"; isList: true; isReadonly: true }
822 name: "ULLayoutsAttached"875 name: "ULLayoutsAttached"
823 prototype: "QObject"876 prototype: "QObject"
824 Property { name: "item"; type: "string" }877 Property { name: "item"; type: "string" }
825878
=== modified file 'debian/changelog'
--- debian/changelog 2014-05-16 11:56:17 +0000
+++ debian/changelog 2014-05-28 18:09:57 +0000
@@ -1,4 +1,115 @@
1ubuntu-ui-toolkit (0.1.46+14.10.20140512-0ubuntu2) UNRELEASED; urgency=medium1ubuntu-ui-toolkit (0.1.46+14.10.20140527-0ubuntu2) UNRELEASED; urgency=medium
2
3 [ Christian Dywan ]
4 * Tweak API parsing to include the Button.font property.
5 Fixes: https://bugs.launchpad.net/bugs/1322169
6 * Call bindtextdomain on /usr if APP_DIR is not defined.
7 Fixes: https://bugs.launchpad.net/bugs/1322630
8 * More unit tests and property corrections for SortFilterModel.
9 * Read ubuntu-ui-toolkit.ini from $XDG_CONFIG_HOME.
10 * Skip test_ubuntushape which is flakey and add a FIXME.
11
12 [ Zsombor Egri ]
13 * Missing "default" keyword added to children property of Base,
14 causing rendering and test case failures on Qt 5.3.
15 Fixes: https://bugs.launchpad.net/bugs/1317881
16
17 [ Ugo Riboni ]
18 * Allow requesting extra large thumbnails.
19
20 [ Florian Boucault ]
21 * AnimatedItem: deprecated as it was not used and still costly.
22 * Label: default font weight is now light.
23
24 [ Tim Peeters ]
25 * Make Header component internal as it was always documented.
26
27
28 [ Zoltán Balogh ]
29 * Replace split with match to work around failing split()
30 function usage.
31
32 -- Zoltán Balogh <zoltan@bakter.hu> Wed, 28 May 2014 11:54:22 +0200
33
34ubuntu-ui-toolkit (0.1.46+14.10.20140527-0ubuntu1) utopic; urgency=medium
35
36 [ Timo Jyrinki ]
37 * Allow using the renamed QML packages. Allow also old names
38 for eg. trusty backporting. For additional cross-building
39 friendliness, add :any to python build dependencies.
40
41 [ Leo Arias ]
42 * Rewrite OptionSelector tests using new helpers.
43 * Added autopilot helpers to pick a time from a date picker.
44 * In autopilot select all text only if not already selected.
45 Fixes: https://bugs.launchpad.net/bugs/1321222.
46
47 [ Christian Dywan ]
48 * Skip flaky test_updateAlarm_Repeating.
49 * Skip test_ubuntushape which is flakey and add a FIXME.
50 * Read ubuntu-ui-toolkit.ini from $XDG_CONFIG_HOME.
51 * More unit tests and property corrections for SortFilterModel.
52
53 [ Tim Peeters ]
54 * Fix bug where header actions are painted in the middle
55 of the page. Fixes: https://bugs.launchpad.net/bugs/1319861
56 * Add header demo program to the resources.
57 * Show header if it was not visible before clicking header
58 button in autopilot test.
59
60 [ Florian Boucault ]
61 * ActivityIndicator: do not rely on the main thread to animate
62 by using an Animator.
63 * ThinDivider: use a Rectangle instead of an Image.
64 5x faster creation.
65 * Label: default font weight is now light.
66
67 [ Zsombor Egri ]
68 * Ubuntu Layouts reparents those default layout components which
69 are not subject of layout instead of altering their visible and
70 enabled properties.
71 Fixes: https://bugs.launchpad.net/bugs/1204834
72 https://bugs.launchpad.net/bugs/1298886
73 https://bugs.launchpad.net/bugs/1300668.
74
75 [ Alberto Mardegan ]
76 * Keep a map of windows and associated textures.
77 Fixes: https://bugs.launchpad.net/bugs/1296728.
78
79 -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Tue, 27 May 2014 07:51:29 +0000
80
81ubuntu-ui-toolkit (0.1.46+14.10.20140520-0ubuntu1) utopic; urgency=medium
82
83 [ Leo Arias ]
84 * Added the swipe_into_view method to autopilot helpers.
85 Fixed the name of the QQuickFlickable autopilot helper.
86 Fixes: https://bugs.launchpad.net/bugs/1286479
87 https://bugs.launchpad.net/bugs/1314433.
88 * On the autopilot helpers, find the top container starting from
89 the flickable. Fixes: https://bugs.launchpad.net/bugs/1314390.
90
91 [ Christian Dywan ]
92 * Use i18n.dtr for toolkit-owned translations.
93 Fixes: https://bugs.launchpad.net/bugs/1317539
94 * Introduce QML bindings for SortFilterModel.
95 Fixes: https://bugs.launchpad.net/bugs/1266529
96 * Pick data path if .click is present.
97 Fixes: https://bugs.launchpad.net/bugs/1317772
98
99 [ Tim Peeters ]
100 * Quick fix for TabBarStyle.qml:119: TypeError: Cannot
101 read property of null.
102
103 [ Zsombor Egri ]
104 * One time alarms omit dayOfWeek value changes.
105 Fixes: https://bugs.launchpad.net/bugs/1319401
106
107 [ CI bot ]
108 * Resync trunk
109
110 -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Tue, 20 May 2014 08:35:48 +0000
111
112ubuntu-ui-toolkit (0.1.46+14.10.20140516-0ubuntu1) utopic; urgency=medium
2113
3 [ Tim Peeters ]114 [ Tim Peeters ]
4 * Take visibility of actions into account when determining whether 115 * Take visibility of actions into account when determining whether
@@ -31,7 +142,7 @@
31 on mobile architectures (less rattling, more realistic).142 on mobile architectures (less rattling, more realistic).
32 Fixes: https://bugs.launchpad.net/bugs/1290201.143 Fixes: https://bugs.launchpad.net/bugs/1290201.
33144
34 -- Zoltán Balogh <zoltan@bakter.hu> Wed, 14 May 2014 15:46:58 +0300145 -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Fri, 16 May 2014 11:58:25 +0000
35146
36ubuntu-ui-toolkit (0.1.46+14.10.20140512-0ubuntu1) utopic; urgency=low147ubuntu-ui-toolkit (0.1.46+14.10.20140512-0ubuntu1) utopic; urgency=low
37148
38149
=== modified file 'debian/control'
--- debian/control 2014-05-12 09:33:55 +0000
+++ debian/control 2014-05-28 18:09:57 +0000
@@ -6,9 +6,9 @@
6 devscripts,6 devscripts,
7 libgles2-mesa-dev,7 libgles2-mesa-dev,
8 libglib2.0-dev,8 libglib2.0-dev,
9 python3,9 python3:any,
10 python,10 python:any,
11 libqt5qml-graphicaleffects | libqt5graphicaleffects5,11 qml-module-qtgraphicaleffects | libqt5qml-graphicaleffects,
12 qt5-default,12 qt5-default,
13 qtbase5-dev,13 qtbase5-dev,
14 qtbase5-private-dev,14 qtbase5-private-dev,
@@ -17,12 +17,12 @@
17 libqt5sql5-sqlite,17 libqt5sql5-sqlite,
18 qtdeclarative5-dev-tools,18 qtdeclarative5-dev-tools,
19 qtdeclarative5-private-dev,19 qtdeclarative5-private-dev,
20 qtdeclarative5-qtquick2-plugin,20 qml-module-qtquick2 | qtdeclarative5-qtquick2-plugin,
21 qtdeclarative5-test-plugin,21 qml-module-qttest | qtdeclarative5-test-plugin,
22 qtdeclarative5-window-plugin,22 qml-module-qtquick-window2 | qtdeclarative5-window-plugin,
23 qtdeclarative5-qtfeedback-plugin,23 qtdeclarative5-qtfeedback-plugin,
24 qtdeclarative5-unity-action-plugin (>= 1.1.0),24 qtdeclarative5-unity-action-plugin (>= 1.1.0),
25 qtdeclarative5-localstorage-plugin,25 qml-module-qtquick-localstorage | qtdeclarative5-localstorage-plugin,
26 qtdeclarative5-doc-html,26 qtdeclarative5-doc-html,
27 qtwebkit5-doc-html,27 qtwebkit5-doc-html,
28 qtsvg5-doc-html,28 qtsvg5-doc-html,
2929
=== modified file 'examples/ubuntu-ui-toolkit-gallery/ListItems.qml'
--- examples/ubuntu-ui-toolkit-gallery/ListItems.qml 2014-04-28 10:30:06 +0000
+++ examples/ubuntu-ui-toolkit-gallery/ListItems.qml 2014-05-28 18:09:57 +0000
@@ -15,7 +15,7 @@
15 */15 */
1616
17import QtQuick 2.017import QtQuick 2.0
18import Ubuntu.Components 0.1 as Toolkit18import Ubuntu.Components 1.1 as Toolkit
19import Ubuntu.Components.ListItems 0.1 as ListItem19import Ubuntu.Components.ListItems 0.1 as ListItem
2020
21Template {21Template {
@@ -259,11 +259,20 @@
259 ListElement { name: "Potato"; details: "Vegetable" }259 ListElement { name: "Potato"; details: "Vegetable" }
260 }260 }
261261
262 Toolkit.SortFilterModel {
263 id: processedFruits
264 model: fruitModel
265 sort.property: "title"
266 sort.order: Qt.DescendingOrder
267 filter.property: "details"
268 filter.pattern: /Vegetable/
269 }
270
262 Toolkit.UbuntuListView {271 Toolkit.UbuntuListView {
263 id: ubuntuListView272 id: ubuntuListView
264 anchors { left: parent.left; right: parent.right }273 anchors { left: parent.left; right: parent.right }
265 height: units.gu(24)274 height: units.gu(24)
266 model: fruitModel275 model: processedFruits
267 clip: true276 clip: true
268277
269 delegate: ListItem.Expandable {278 delegate: ListItem.Expandable {
270279
=== modified file 'modules/Ubuntu/Components/AnimatedItem.qml'
--- modules/Ubuntu/Components/AnimatedItem.qml 2014-04-23 08:50:20 +0000
+++ modules/Ubuntu/Components/AnimatedItem.qml 2014-05-28 18:09:57 +0000
@@ -30,45 +30,8 @@
30 id: root30 id: root
31 /*!31 /*!
32 \preliminary32 \preliminary
33 \deprecated
33 Specifies whether the component is on the visible area of the Flickable or not.34 Specifies whether the component is on the visible area of the Flickable or not.
34 */35 */
35 property bool onScreen: true36 property bool onScreen: true
36
37 QtObject {
38 id: internal
39 property Flickable flickable
40
41 // returns whether the component is in the visible area of the flickable
42 function checkOnScreen()
43 {
44 var pos = root.mapToItem(flickable, 0, 0)
45 root.onScreen = (pos.y + root.height >= 0) && (pos.y <= internal.flickable.height) &&
46 (pos.x + root.width >= 0) && (pos.x <= internal.flickable.width)
47 }
48 // lookup for a flickable parent
49 function updateFlickableParent()
50 {
51 var flickable = root.parent
52 while (flickable) {
53 if (flickable.hasOwnProperty("flicking") && flickable.hasOwnProperty("flickableDirection")) {
54 // non-interactive flickables must be skipped as those do not provide
55 // on-screen detection support
56 if (flickable.interactive)
57 break
58 }
59 flickable = flickable.parent
60 }
61 internal.flickable = flickable
62 }
63 }
64
65 Connections {
66 target: internal.flickable
67
68 onContentXChanged: internal.checkOnScreen()
69 onContentYChanged: internal.checkOnScreen()
70 }
71
72 Component.onCompleted: internal.updateFlickableParent()
73 onParentChanged: internal.updateFlickableParent()
74}37}
7538
=== modified file 'modules/Ubuntu/Components/Label.qml'
--- modules/Ubuntu/Components/Label.qml 2014-04-23 08:50:20 +0000
+++ modules/Ubuntu/Components/Label.qml 2014-05-28 18:09:57 +0000
@@ -56,6 +56,7 @@
5656
57 font.pixelSize: FontUtils.sizeToPixels(fontSize)57 font.pixelSize: FontUtils.sizeToPixels(fontSize)
58 font.family: "Ubuntu"58 font.family: "Ubuntu"
59 font.weight: Font.Light
59 color: Theme.palette.selected.backgroundText60 color: Theme.palette.selected.backgroundText
6061
61 /* FIXME: workaround for QTBUG 35095 where Text's alignment is incorrect62 /* FIXME: workaround for QTBUG 35095 where Text's alignment is incorrect
6263
=== modified file 'modules/Ubuntu/Components/ListItems/Base.qml'
--- modules/Ubuntu/Components/ListItems/Base.qml 2014-04-28 19:24:56 +0000
+++ modules/Ubuntu/Components/ListItems/Base.qml 2014-05-28 18:09:57 +0000
@@ -159,7 +159,7 @@
159 /*!159 /*!
160 \internal160 \internal
161 */161 */
162 property alias children: middle.data162 default property alias children: middle.data
163 Item {163 Item {
164 id: middle164 id: middle
165 property bool anchorToIconHelper: !__iconIsItem && iconHelper.source != ""165 property bool anchorToIconHelper: !__iconIsItem && iconHelper.source != ""
166166
=== modified file 'modules/Ubuntu/Components/ListItems/Empty.qml'
--- modules/Ubuntu/Components/ListItems/Empty.qml 2014-04-30 11:04:41 +0000
+++ modules/Ubuntu/Components/ListItems/Empty.qml 2014-05-28 18:09:57 +0000
@@ -390,7 +390,7 @@
390 width: units.gu(5)390 width: units.gu(5)
391 }391 }
392 Label {392 Label {
393 text: i18n.tr("Delete")393 text: i18n.dtr('ubuntu-ui-toolkit', 'Delete')
394 verticalAlignment: Text.AlignVCenter394 verticalAlignment: Text.AlignVCenter
395 anchors {395 anchors {
396 verticalCenter: parent.verticalCenter396 verticalCenter: parent.verticalCenter
397397
=== modified file 'modules/Ubuntu/Components/ListItems/ThinDivider.qml'
--- modules/Ubuntu/Components/ListItems/ThinDivider.qml 2014-04-20 19:25:12 +0000
+++ modules/Ubuntu/Components/ListItems/ThinDivider.qml 2014-05-28 18:09:57 +0000
@@ -44,11 +44,14 @@
44 }44 }
45 \endqml45 \endqml
46*/46*/
47Image {47Rectangle {
48 anchors {48 anchors {
49 left: (parent) ? parent.left : null49 left: (parent) ? parent.left : null
50 right: (parent) ? parent.right : null50 right: (parent) ? parent.right : null
51 }51 }
52 height: (visible) ? units.dp(2) : 052 height: (visible) ? units.dp(2) : 0
53 source: "artwork/ListItemDividerHorizontal.png"53 gradient: Gradient {
54 GradientStop { position: 0.0; color: "#26000000" }
55 GradientStop { position: 1.0; color: "#14F3F3E7" }
56 }
54}57}
5558
=== removed file 'modules/Ubuntu/Components/ListItems/artwork/ListItemDividerHorizontal@18.png'
56Binary files modules/Ubuntu/Components/ListItems/artwork/ListItemDividerHorizontal@18.png 2013-02-06 11:48:20 +0000 and modules/Ubuntu/Components/ListItems/artwork/ListItemDividerHorizontal@18.png 1970-01-01 00:00:00 +0000 differ59Binary files modules/Ubuntu/Components/ListItems/artwork/ListItemDividerHorizontal@18.png 2013-02-06 11:48:20 +0000 and modules/Ubuntu/Components/ListItems/artwork/ListItemDividerHorizontal@18.png 1970-01-01 00:00:00 +0000 differ
=== modified file 'modules/Ubuntu/Components/Page.qml'
--- modules/Ubuntu/Components/Page.qml 2014-05-16 11:33:37 +0000
+++ modules/Ubuntu/Components/Page.qml 2014-05-28 18:09:57 +0000
@@ -185,6 +185,13 @@
185 value: page.pageStack185 value: page.pageStack
186 when: tools && tools.hasOwnProperty("pageStack")186 when: tools && tools.hasOwnProperty("pageStack")
187 }187 }
188 Binding {
189 target: tools
190 property: "visible"
191 value: false
192 when: header && !header.useDeprecatedToolbar &&
193 page.tools !== null
194 }
188195
189 function isVerticalFlickable(object) {196 function isVerticalFlickable(object) {
190 if (object && object.hasOwnProperty("flickableDirection") && object.hasOwnProperty("contentHeight")) {197 if (object && object.hasOwnProperty("flickableDirection") && object.hasOwnProperty("contentHeight")) {
191198
=== modified file 'modules/Ubuntu/Components/Pickers/DatePicker.qml'
--- modules/Ubuntu/Components/Pickers/DatePicker.qml 2014-04-23 08:50:20 +0000
+++ modules/Ubuntu/Components/Pickers/DatePicker.qml 2014-05-28 18:09:57 +0000
@@ -42,7 +42,7 @@
42 Column {42 Column {
43 Label {43 Label {
44 text: "Selected date: W" + datePicker.week + " - " +44 text: "Selected date: W" + datePicker.week + " - " +
45 Qt.formatDate(datePicker.date, "dddd, dd-mmmm-yyyy")45 Qt.formatDate(datePicker.date, "dddd, dd-MMMM-yyyy")
46 }46 }
47 DatePicker {47 DatePicker {
48 id: datePicker48 id: datePicker
@@ -61,7 +61,7 @@
6161
62 Column {62 Column {
63 Label {63 Label {
64 text: "Selected month: " + Qt.formatDate(datePicker.date, "mmmm-yyyy")64 text: "Selected month: " + Qt.formatDate(datePicker.date, "MMMM-yyyy")
65 }65 }
66 DatePicker {66 DatePicker {
67 id: datePicker67 id: datePicker
@@ -117,7 +117,7 @@
117117
118 Column {118 Column {
119 Label {119 Label {
120 text: "Selected date: " + Qt.formatDate(datePicker.date, "dddd, dd-mmmm-yyyy")120 text: "Selected date: " + Qt.formatDate(datePicker.date, "dddd, dd-MMMM-yyyy")
121 }121 }
122 DatePicker {122 DatePicker {
123 id: datePicker123 id: datePicker
@@ -523,7 +523,8 @@
523 function updatePickers() {523 function updatePickers() {
524 if (completed) {524 if (completed) {
525 // check mode flags first525 // check mode flags first
526 var modes = datePicker.mode.split(/\W/g);526 // FIXME: The js split(/\W/g) terminates the process on armhf with Qt 5.3 (v4 js) (https://bugreports.qt-project.org/browse/QTBUG-39255)
527 var modes = datePicker.mode.match(/\w+/g);
527528
528 showYearPicker = showMonthPicker = showDayPicker =529 showYearPicker = showMonthPicker = showDayPicker =
529 showHoursPicker = showMinutesPicker = showSecondsPicker = false;530 showHoursPicker = showMinutesPicker = showSecondsPicker = false;
@@ -607,7 +608,8 @@
607 completed = false;608 completed = false;
608609
609 // use short format to exclude any extra characters610 // use short format to exclude any extra characters
610 var format = datePicker.locale.dateFormat(Locale.ShortFormat).split(/\W/g);611 // FIXME: The js split(/\W/g) terminates the process on armhf with Qt 5.3 (v4 js) (https://bugreports.qt-project.org/browse/QTBUG-39255)
612 var format = datePicker.locale.dateFormat(Locale.ShortFormat).match(/\w+/g);
611 // loop through the format to decide the position of the tumbler613 // loop through the format to decide the position of the tumbler
612 var formatIndex = 0;614 var formatIndex = 0;
613 for (var i in format) {615 for (var i in format) {
@@ -667,5 +669,3 @@
667 }669 }
668 }670 }
669}671}
670
671
672672
=== modified file 'modules/Ubuntu/Components/Pickers/PickerRow.qml'
--- modules/Ubuntu/Components/Pickers/PickerRow.qml 2014-04-23 08:50:20 +0000
+++ modules/Ubuntu/Components/Pickers/PickerRow.qml 2014-05-28 18:09:57 +0000
@@ -96,7 +96,7 @@
96 }96 }
97 delegate: PickerDelegate {97 delegate: PickerDelegate {
98 Label {98 Label {
99 objectName: "PickerRow_PickerLabel"99 objectName: "PickerRow_PickerLabel" + (pickerModel ? modelData : "")
100 text: pickerModel ? pickerModel.text(modelData) : ""100 text: pickerModel ? pickerModel.text(modelData) : ""
101 anchors.fill: parent101 anchors.fill: parent
102 verticalAlignment: Text.AlignVCenter102 verticalAlignment: Text.AlignVCenter
103103
=== modified file 'modules/Ubuntu/Components/TextInputPopover.qml'
--- modules/Ubuntu/Components/TextInputPopover.qml 2014-04-28 06:48:28 +0000
+++ modules/Ubuntu/Components/TextInputPopover.qml 2014-05-28 18:09:57 +0000
@@ -22,39 +22,39 @@
22 objectName: "text_input_popover"22 objectName: "text_input_popover"
23 actions: ActionList {23 actions: ActionList {
24 Action {24 Action {
25 text: i18n.tr("Select All")25 text: i18n.dtr('ubuntu-ui-toolkit', "Select All")
26 enabled: target && target.text !== "" && target.text !== target.selectedText26 enabled: target && target.text !== "" && target.text !== target.selectedText
27 onTriggered: target.selectAll()27 onTriggered: target.selectAll()
28 }28 }
29 Action {29 Action {
30 text: i18n.tr("Select Word")30 text: i18n.dtr('ubuntu-ui-toolkit', "Select Word")
31 enabled: target && target.text !== "" && target.selectedText === ""31 enabled: target && target.text !== "" && target.selectedText === ""
32 onTriggered: target.selectWord()32 onTriggered: target.selectWord()
33 }33 }
34 Action {34 Action {
35 text: i18n.tr("Cut")35 text: i18n.dtr('ubuntu-ui-toolkit', "Cut")
36 // If paste/editing is not possible, then disable also "Cut" operation36 // If paste/editing is not possible, then disable also "Cut" operation
37 // It is applicable for ReadOnly's TextFields and TextAreas37 // It is applicable for ReadOnly's TextFields and TextAreas
38 enabled: target && target.selectedText !== "" && target.canPaste38 enabled: target && target.selectedText !== "" && target.canPaste
39 onTriggered: target.cut()39 onTriggered: target.cut()
40 }40 }
41 Action {41 Action {
42 text: i18n.tr("Copy")42 text: i18n.dtr('ubuntu-ui-toolkit', "Copy")
43 enabled: target && target.selectedText !== ""43 enabled: target && target.selectedText !== ""
44 onTriggered: target.copy()44 onTriggered: target.copy()
45 }45 }
46 Action {46 Action {
47 text: i18n.tr("Paste")47 text: i18n.dtr('ubuntu-ui-toolkit', "Paste")
48 enabled: target && target.canPaste48 enabled: target && target.canPaste
49 onTriggered: target.paste()49 onTriggered: target.paste()
50 }50 }
51 Action {51 Action {
52 text: i18n.tr("Undo")52 text: i18n.dtr('ubuntu-ui-toolkit', "Undo")
53 enabled: target && target.canUndo53 enabled: target && target.canUndo
54 onTriggered: target.undo()54 onTriggered: target.undo()
55 }55 }
56 Action {56 Action {
57 text: i18n.tr("Redo")57 text: i18n.dtr('ubuntu-ui-toolkit', "Redo")
58 enabled: target && target.canRedo58 enabled: target && target.canRedo
59 onTriggered: target.redo()59 onTriggered: target.redo()
60 }60 }
6161
=== modified file 'modules/Ubuntu/Components/Themes/Ambiance/ActivityIndicatorStyle.qml'
--- modules/Ubuntu/Components/Themes/Ambiance/ActivityIndicatorStyle.qml 2014-04-23 08:50:20 +0000
+++ modules/Ubuntu/Components/Themes/Ambiance/ActivityIndicatorStyle.qml 2014-05-28 18:09:57 +0000
@@ -14,7 +14,7 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */15 */
1616
17import QtQuick 2.017import QtQuick 2.2
18import Ubuntu.Components 1.118import Ubuntu.Components 1.1
1919
20Image {20Image {
@@ -28,7 +28,7 @@
28 verticalAlignment: Image.AlignVCenter28 verticalAlignment: Image.AlignVCenter
29 source: "artwork/spinner.png"29 source: "artwork/spinner.png"
3030
31 NumberAnimation on rotation {31 RotationAnimator on rotation {
32 running: styledItem.running32 running: styledItem.running
33 from: 033 from: 0
34 to: 36034 to: 360
3535
=== modified file 'modules/Ubuntu/Components/Themes/Ambiance/TabBarStyle.qml'
--- modules/Ubuntu/Components/Themes/Ambiance/TabBarStyle.qml 2014-05-09 11:21:23 +0000
+++ modules/Ubuntu/Components/Themes/Ambiance/TabBarStyle.qml 2014-05-28 18:09:57 +0000
@@ -116,8 +116,8 @@
116 AbstractButton {116 AbstractButton {
117 id: button117 id: button
118 anchors {118 anchors {
119 top: parent.top119 top: parent ? parent.top : undefined
120 bottom: parent.bottom120 bottom: parent ? parent.bottom : undefined
121 }121 }
122 width: text.paintedWidth + text.anchors.leftMargin + text.anchors.rightMargin122 width: text.paintedWidth + text.anchors.leftMargin + text.anchors.rightMargin
123123
124124
=== modified file 'modules/Ubuntu/Components/Toolbar.qml'
--- modules/Ubuntu/Components/Toolbar.qml 2014-04-23 08:50:20 +0000
+++ modules/Ubuntu/Components/Toolbar.qml 2014-05-28 18:09:57 +0000
@@ -27,9 +27,9 @@
27Panel {27Panel {
28 id: toolbar28 id: toolbar
29 anchors {29 anchors {
30 left: parent.left30 left: parent ? parent.left : undefined
31 right: parent.right31 right: parent ? parent.right : undefined
32 bottom: parent.bottom32 bottom: parent ? parent.bottom : undefined
33 }33 }
34 height: background.height34 height: background.height
3535
3636
=== modified file 'modules/Ubuntu/Components/ToolbarItems.qml'
--- modules/Ubuntu/Components/ToolbarItems.qml 2014-04-23 08:50:20 +0000
+++ modules/Ubuntu/Components/ToolbarItems.qml 2014-05-28 18:09:57 +0000
@@ -139,7 +139,7 @@
139 property Item back: ToolbarButton {139 property Item back: ToolbarButton {
140 objectName: "back_toolbar_button"140 objectName: "back_toolbar_button"
141 iconSource: Qt.resolvedUrl("artwork/back.png")141 iconSource: Qt.resolvedUrl("artwork/back.png")
142 text: i18n.tr("Back")142 text: i18n.dtr('ubuntu-ui-toolkit', 'Back')
143 visible: toolbarItems.pageStack && toolbarItems.pageStack.depth > 1143 visible: toolbarItems.pageStack && toolbarItems.pageStack.depth > 1
144 /*!144 /*!
145 If there is a \l PageStack of sufficient depth, triggering the back button145 If there is a \l PageStack of sufficient depth, triggering the back button
146146
=== added file 'modules/Ubuntu/Components/plugin/filterbehavior.cpp'
--- modules/Ubuntu/Components/plugin/filterbehavior.cpp 1970-01-01 00:00:00 +0000
+++ modules/Ubuntu/Components/plugin/filterbehavior.cpp 2014-05-28 18:09:57 +0000
@@ -0,0 +1,47 @@
1/*
2 * Copyright (C) 2014 Canonical, Ltd.
3 *
4 * Authors:
5 * Christian Dywan <christian.dywan@canonical.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as published by
9 * the Free Software Foundation; version 3.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include "filterbehavior.h"
21
22QString
23FilterBehavior::property() const
24{
25 return m_property;
26}
27
28void
29FilterBehavior::setProperty(const QString& property)
30{
31 m_property = property;
32 Q_EMIT propertyChanged();
33}
34
35QRegExp
36FilterBehavior::pattern() const
37{
38 return m_pattern;
39}
40
41void
42FilterBehavior::setPattern(QRegExp pattern)
43{
44 m_pattern = pattern;
45 Q_EMIT patternChanged();
46}
47
048
=== added file 'modules/Ubuntu/Components/plugin/filterbehavior.h'
--- modules/Ubuntu/Components/plugin/filterbehavior.h 1970-01-01 00:00:00 +0000
+++ modules/Ubuntu/Components/plugin/filterbehavior.h 2014-05-28 18:09:57 +0000
@@ -0,0 +1,46 @@
1/*
2 * Copyright (C) 2014 Canonical, Ltd.
3 *
4 * Authors:
5 * Christian Dywan <christian.dywan@canonical.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as published by
9 * the Free Software Foundation; version 3.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#ifndef FILTERBEHAVIOR_H
21#define FILTERBEHAVIOR_H
22
23#include <QSortFilterProxyModel>
24
25class FilterBehavior : public QObject {
26 Q_OBJECT
27
28 Q_PROPERTY(QString property READ property WRITE setProperty NOTIFY propertyChanged)
29 Q_PROPERTY(QRegExp pattern READ pattern WRITE setPattern NOTIFY patternChanged)
30
31public:
32 QString property() const;
33 void setProperty(const QString& property);
34 QRegExp pattern() const;
35 void setPattern(QRegExp pattern);
36
37Q_SIGNALS:
38 void propertyChanged();
39 void patternChanged();
40
41private:
42 QString m_property;
43 QRegExp m_pattern;
44};
45
46#endif // FILTERBEHAVIOR_H
047
=== modified file 'modules/Ubuntu/Components/plugin/i18n.cpp'
--- modules/Ubuntu/Components/plugin/i18n.cpp 2014-04-23 08:50:20 +0000
+++ modules/Ubuntu/Components/plugin/i18n.cpp 2014-05-28 18:09:57 +0000
@@ -17,7 +17,6 @@
17 */17 */
1818
19#include "i18n.h"19#include "i18n.h"
20#include <QtCore/QStandardPaths>
21#include <QtCore/QDir>20#include <QtCore/QDir>
2221
23namespace C {22namespace C {
@@ -102,19 +101,16 @@
102 m_domain = domain;101 m_domain = domain;
103 C::textdomain(domain.toUtf8());102 C::textdomain(domain.toUtf8());
104 /*103 /*
105 Look for locale folder as per XDG basedir spec
106 The default is /usr/share/locale if we don't set a folder104 The default is /usr/share/locale if we don't set a folder
107 We look for share/domain to pick correctly among multiple prefixes105 For click we use APP_DIR/share/locale
106 e.g. /usr/share/click/preinstalled/com.example.foo/current/share/locale
108 */107 */
109 QString dataPath(QStandardPaths::locate(QStandardPaths::GenericDataLocation,108 QString appDir(getenv("APP_DIR"));
110 domain, QStandardPaths::LocateDirectory));109 if (!QDir::isAbsolutePath (appDir)) {
111 if (!dataPath.isEmpty()) {110 appDir = "/usr";
112 QDir dataDir(dataPath);
113 if (dataDir.cdUp() && dataDir.cd("locale")) {
114 QString localePath(dataDir.path());
115 C::bindtextdomain(domain.toUtf8(), localePath.toUtf8());
116 }
117 }111 }
112 QString localePath(QDir(appDir).filePath("share/locale"));
113 C::bindtextdomain(domain.toUtf8(), localePath.toUtf8());
118 Q_EMIT domainChanged();114 Q_EMIT domainChanged();
119}115}
120116
121117
=== modified file 'modules/Ubuntu/Components/plugin/plugin.cpp'
--- modules/Ubuntu/Components/plugin/plugin.cpp 2014-04-20 19:25:12 +0000
+++ modules/Ubuntu/Components/plugin/plugin.cpp 2014-05-28 18:09:57 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright 2012 Canonical Ltd.2 * Copyright 2012-2014 Canonical Ltd.
3 *3 *
4 * This program is free software; you can redistribute it and/or modify4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by5 * it under the terms of the GNU Lesser General Public License as published by
@@ -48,6 +48,7 @@
48#include "ucurihandler.h"48#include "ucurihandler.h"
49#include "ucmouse.h"49#include "ucmouse.h"
50#include "ucinversemouse.h"50#include "ucinversemouse.h"
51#include "sortfiltermodel.h"
5152
52#include <sys/types.h>53#include <sys/types.h>
53#include <unistd.h>54#include <unistd.h>
@@ -186,6 +187,14 @@
186187
187 // register custom event188 // register custom event
188 ForwardedEvent::registerForwardedEvent();189 ForwardedEvent::registerForwardedEvent();
190
191 // register parent type so that properties can get/ set it
192 qmlRegisterUncreatableType<QAbstractItemModel>(uri, 1, 1, "QAbstractItemModel", "Not instantiable");
193
194 // register 1.1 only API
195 qmlRegisterType<QSortFilterProxyModelQML>(uri, 1, 1, "SortFilterModel");
196 qmlRegisterUncreatableType<FilterBehavior>(uri, 1, 1, "FilterBehavior", "Not instantiable");
197 qmlRegisterUncreatableType<SortBehavior>(uri, 1, 1, "SortBehavior", "Not instantiable");
189}198}
190199
191void UbuntuComponentsPlugin::initializeEngine(QQmlEngine *engine, const char *uri)200void UbuntuComponentsPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
192201
=== modified file 'modules/Ubuntu/Components/plugin/plugin.pro'
--- modules/Ubuntu/Components/plugin/plugin.pro 2014-03-25 06:46:36 +0000
+++ modules/Ubuntu/Components/plugin/plugin.pro 2014-05-28 18:09:57 +0000
@@ -55,6 +55,9 @@
55 alarmrequest_p_p.h \55 alarmrequest_p_p.h \
56 adapters/alarmsadapter_p.h \56 adapters/alarmsadapter_p.h \
57 ucstatesaver.h \57 ucstatesaver.h \
58 sortbehavior.h \
59 filterbehavior.h \
60 sortfiltermodel.h \
58 statesaverbackend_p.h \61 statesaverbackend_p.h \
59 ucstatesaver_p.h \62 ucstatesaver_p.h \
60 ucurihandler.h \63 ucurihandler.h \
@@ -87,6 +90,9 @@
87 thumbnailgenerator.cpp \90 thumbnailgenerator.cpp \
88 alarmrequest_p.cpp \91 alarmrequest_p.cpp \
89 ucstatesaver.cpp \92 ucstatesaver.cpp \
93 sortbehavior.cpp \
94 filterbehavior.cpp \
95 sortfiltermodel.cpp \
90 statesaverbackend_p.cpp \96 statesaverbackend_p.cpp \
91 ucurihandler.cpp \97 ucurihandler.cpp \
92 ucmousefilters.cpp \98 ucmousefilters.cpp \
9399
=== modified file 'modules/Ubuntu/Components/plugin/shapeitem.cpp'
--- modules/Ubuntu/Components/plugin/shapeitem.cpp 2014-04-08 18:41:31 +0000
+++ modules/Ubuntu/Components/plugin/shapeitem.cpp 2014-05-28 18:09:57 +0000
@@ -32,6 +32,9 @@
32// Threshold in grid unit defining the texture quality to be used.32// Threshold in grid unit defining the texture quality to be used.
33const float lowHighTextureThreshold = 11.0f;33const float lowHighTextureThreshold = 11.0f;
3434
35// Map of windows and associated textures.
36QHash<QOpenGLContext*, ShapeItem::TextureHandles> ShapeItem::textures_;
37
35static const char* const shapeVertexShader =38static const char* const shapeVertexShader =
36 "uniform lowp mat4 matrix; \n"39 "uniform lowp mat4 matrix; \n"
37 "attribute lowp vec4 positionAttrib; \n"40 "attribute lowp vec4 positionAttrib; \n"
@@ -338,6 +341,21 @@
338 update();341 update();
339}342}
340343
344void ShapeItem::onOpenglContextDestroyed()
345{
346 QOpenGLContext* context = qobject_cast<QOpenGLContext*>(sender());
347 if (Q_UNLIKELY(!context)) return;
348
349 QHash<QOpenGLContext*, TextureHandles>::iterator it =
350 textures_.find(context);
351 if (it != textures_.end()) {
352 TextureHandles &textureHandles = it.value();
353 delete textureHandles.high;
354 delete textureHandles.low;
355 textures_.erase(it);
356 }
357}
358
341QSGNode* ShapeItem::updatePaintNode(QSGNode* old_node, UpdatePaintNodeData* data)359QSGNode* ShapeItem::updatePaintNode(QSGNode* old_node, UpdatePaintNodeData* data)
342{360{
343 Q_UNUSED(data);361 Q_UNUSED(data);
@@ -345,19 +363,28 @@
345 // FIXME(loicm) Shape textures are stored in the read-only data section of the plugin as it363 // FIXME(loicm) Shape textures are stored in the read-only data section of the plugin as it
346 // avoids having to deal with paths for now. It should preferably be loaded from a file.364 // avoids having to deal with paths for now. It should preferably be loaded from a file.
347365
348 /* Textures created with QWindow::createTextureFromImage() become invalid366 // OpenGL allocates textures per context, so we store textures reused by
349 * when the window is destroyed; therefore, we must keep track of which367 // all shape instances per context as well
350 * window was used to create them and be ready to re-create them if that368 QOpenGLContext* openglContext = window() ? window()->openglContext() : NULL;
351 * window goes away. */369 if (Q_UNLIKELY(!openglContext)) {
352 static QPointer<QWindow> textureOwner = 0;370 qCritical() << "Window has no GL context!";
353 if (!textureOwner) {371 delete old_node;
354 shapeTextureHigh.texture = window()->createTextureFromImage(372 return NULL;
373 }
374
375 TextureHandles &textureHandles = textures_[openglContext];
376 // If the hash table didn't contain an entry for the current context, the
377 // line above has just caused the creation of a default-constructed value.
378 if (!textureHandles.high) {
379 textureHandles.high = window()->createTextureFromImage(
355 QImage(shapeTextureHigh.data, shapeTextureHigh.width, shapeTextureHigh.height,380 QImage(shapeTextureHigh.data, shapeTextureHigh.width, shapeTextureHigh.height,
356 QImage::Format_ARGB32_Premultiplied));381 QImage::Format_ARGB32_Premultiplied));
357 shapeTextureLow.texture = window()->createTextureFromImage(382 textureHandles.low = window()->createTextureFromImage(
358 QImage(shapeTextureLow.data, shapeTextureLow.width, shapeTextureLow.height,383 QImage(shapeTextureLow.data, shapeTextureLow.width, shapeTextureLow.height,
359 QImage::Format_ARGB32_Premultiplied));384 QImage::Format_ARGB32_Premultiplied));
360 textureOwner = window();385 QObject::connect(openglContext, SIGNAL(aboutToBeDestroyed()),
386 this, SLOT(onOpenglContextDestroyed()),
387 Qt::DirectConnection);
361 }388 }
362389
363 // The image item sets its texture in its updatePaintNode() method when QtQuick iterates through390 // The image item sets its texture in its updatePaintNode() method when QtQuick iterates through
@@ -387,8 +414,15 @@
387414
388 ShapeTexturedMaterial* texturedMaterial = node->texturedMaterial();415 ShapeTexturedMaterial* texturedMaterial = node->texturedMaterial();
389 ShapeColoredMaterial* coloredMaterial = node->coloredMaterial();416 ShapeColoredMaterial* coloredMaterial = node->coloredMaterial();
390 TextureData* textureData = (gridUnit_ > lowHighTextureThreshold) ?417 TextureData* textureData;
391 &shapeTextureHigh : &shapeTextureLow;418 QSGTexture* textureHandle;
419 if (gridUnit_ > lowHighTextureThreshold) {
420 textureData = &shapeTextureHigh;
421 textureHandle = textureHandles.high;
422 } else {
423 textureData = &shapeTextureLow;
424 textureHandle = textureHandles.low;
425 }
392426
393 // Set the shape texture to be used by the materials depending on current grid unit. The radius427 // Set the shape texture to be used by the materials depending on current grid unit. The radius
394 // is set considering the current grid unit and the texture raster grid unit. When the item size428 // is set considering the current grid unit and the texture raster grid unit. When the item size
@@ -406,8 +440,8 @@
406 radius = halfMinWidthHeight;440 radius = halfMinWidthHeight;
407 scaledDown |= 1;441 scaledDown |= 1;
408 }442 }
409 coloredMaterial->setShapeTexture(textureData->texture, !!scaledDown);443 coloredMaterial->setShapeTexture(textureHandle, !!scaledDown);
410 texturedMaterial->setShapeTexture(textureData->texture, !!scaledDown);444 texturedMaterial->setShapeTexture(textureHandle, !!scaledDown);
411445
412 // Update the other material properties.446 // Update the other material properties.
413 coloredMaterial->setColor(color_);447 coloredMaterial->setColor(color_);
414448
=== modified file 'modules/Ubuntu/Components/plugin/shapeitem.h'
--- modules/Ubuntu/Components/plugin/shapeitem.h 2013-10-18 08:56:39 +0000
+++ modules/Ubuntu/Components/plugin/shapeitem.h 2014-05-28 18:09:57 +0000
@@ -91,6 +91,7 @@
9191
92private Q_SLOTS:92private Q_SLOTS:
93 void onImagePropertiesChanged();93 void onImagePropertiesChanged();
94 void onOpenglContextDestroyed();
9495
95private:96private:
96 enum DirtyFlags {97 enum DirtyFlags {
@@ -110,6 +111,12 @@
110 | DirtyGridUnit | DirtyGeometry)111 | DirtyGridUnit | DirtyGeometry)
111 };112 };
112113
114 struct TextureHandles {
115 TextureHandles(): high(0), low(0) {}
116 QSGTexture* high;
117 QSGTexture* low;
118 };
119
113 QColor color_;120 QColor color_;
114 QColor gradientColor_;121 QColor gradientColor_;
115 bool gradientColorSet_;122 bool gradientColorSet_;
@@ -124,6 +131,7 @@
124 float gridUnit_;131 float gridUnit_;
125 QRectF geometry_;132 QRectF geometry_;
126 QFlags<DirtyFlags> dirtyFlags_;133 QFlags<DirtyFlags> dirtyFlags_;
134 static QHash<QOpenGLContext*, TextureHandles> textures_;
127135
128 Q_DISABLE_COPY(ShapeItem)136 Q_DISABLE_COPY(ShapeItem)
129};137};
130138
=== modified file 'modules/Ubuntu/Components/plugin/shapeitemtexture.h'
--- modules/Ubuntu/Components/plugin/shapeitemtexture.h 2013-01-07 07:59:56 +0000
+++ modules/Ubuntu/Components/plugin/shapeitemtexture.h 2014-05-28 18:09:57 +0000
@@ -20,7 +20,6 @@
2020
21struct TextureData {21struct TextureData {
22 const unsigned char* const data;22 const unsigned char* const data;
23 QSGTexture* texture;
24 int width;23 int width;
25 int height;24 int height;
26 int bytesPerPixel;25 int bytesPerPixel;
@@ -5160,7 +5159,7 @@
51605159
5161// High resolution shape texture.5160// High resolution shape texture.
5162TextureData shapeTextureHigh __attribute__((aligned(16))) = {5161TextureData shapeTextureHigh __attribute__((aligned(16))) = {
5163 shapeTextureHighData, NULL, 256, 128, 4, 32.0f, 64.0f, 18.0f,5162 shapeTextureHighData, 256, 128, 4, 32.0f, 64.0f, 18.0f,
5164 {5163 {
5165 { // Medium raw coords.5164 { // Medium raw coords.
5166 { hh, 0.0f }, { 0.25f-hh, 0.0f }, { 0.25f-hh, 0.0f }, { hh, 0.0f },5165 { hh, 0.0f }, { 0.25f-hh, 0.0f }, { 0.25f-hh, 0.0f }, { hh, 0.0f },
@@ -6484,7 +6483,7 @@
64846483
6485// Low resolution shape texture.6484// Low resolution shape texture.
6486TextureData shapeTextureLow __attribute__((aligned(16))) = {6485TextureData shapeTextureLow __attribute__((aligned(16))) = {
6487 shapeTextureLowData, NULL, 128, 64, 4, 16.0f, 32.0f, 9.0f,6486 shapeTextureLowData, 128, 64, 4, 16.0f, 32.0f, 9.0f,
6488 {6487 {
6489 { // Medium raw coords.6488 { // Medium raw coords.
6490 { hl, 0.0f }, { 0.25f-hl, 0.0f }, { 0.25f-hl, 0.0f }, { hl, 0.0f },6489 { hl, 0.0f }, { 0.25f-hl, 0.0f }, { 0.25f-hl, 0.0f }, { hl, 0.0f },
64916490
=== added file 'modules/Ubuntu/Components/plugin/sortbehavior.cpp'
--- modules/Ubuntu/Components/plugin/sortbehavior.cpp 1970-01-01 00:00:00 +0000
+++ modules/Ubuntu/Components/plugin/sortbehavior.cpp 2014-05-28 18:09:57 +0000
@@ -0,0 +1,47 @@
1/*
2 * Copyright (C) 2014 Canonical, Ltd.
3 *
4 * Authors:
5 * Christian Dywan <christian.dywan@canonical.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as published by
9 * the Free Software Foundation; version 3.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include "sortbehavior.h"
21
22QString
23SortBehavior::property() const
24{
25 return m_property;
26}
27
28Qt::SortOrder
29SortBehavior::order() const
30{
31 return m_order;
32}
33
34void
35SortBehavior::setProperty(const QString& property)
36{
37 m_property = property;
38 Q_EMIT propertyChanged();
39}
40
41void
42SortBehavior::setOrder(Qt::SortOrder order)
43{
44 m_order = order;
45 Q_EMIT orderChanged();
46}
47
048
=== added file 'modules/Ubuntu/Components/plugin/sortbehavior.h'
--- modules/Ubuntu/Components/plugin/sortbehavior.h 1970-01-01 00:00:00 +0000
+++ modules/Ubuntu/Components/plugin/sortbehavior.h 2014-05-28 18:09:57 +0000
@@ -0,0 +1,46 @@
1/*
2 * Copyright (C) 2014 Canonical, Ltd.
3 *
4 * Authors:
5 * Christian Dywan <christian.dywan@canonical.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as published by
9 * the Free Software Foundation; version 3.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#ifndef SORTBEHAVIOR_H
21#define SORTBEHAVIOR_H
22
23#include <QSortFilterProxyModel>
24
25class SortBehavior : public QObject {
26 Q_OBJECT
27
28 Q_PROPERTY(QString property READ property WRITE setProperty NOTIFY propertyChanged)
29 Q_PROPERTY(Qt::SortOrder order READ order WRITE setOrder NOTIFY orderChanged)
30
31public:
32 QString property() const;
33 void setProperty(const QString& property);
34 Qt::SortOrder order() const;
35 void setOrder(Qt::SortOrder order);
36
37Q_SIGNALS:
38 void propertyChanged();
39 void orderChanged();
40
41private:
42 QString m_property;
43 Qt::SortOrder m_order;
44};
45
46#endif // SORTBEHAVIOR_H
047
=== added file 'modules/Ubuntu/Components/plugin/sortfiltermodel.cpp'
--- modules/Ubuntu/Components/plugin/sortfiltermodel.cpp 1970-01-01 00:00:00 +0000
+++ modules/Ubuntu/Components/plugin/sortfiltermodel.cpp 2014-05-28 18:09:57 +0000
@@ -0,0 +1,252 @@
1/*
2 * Copyright (C) 2012-2014 Canonical, Ltd.
3 *
4 * Authors:
5 * Michal Hruby <michal.hruby@canonical.com>
6 * Christian Dywan <christian.dywan@canonical.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU Lesser General Public License as published by
10 * the Free Software Foundation; version 3.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include "sortfiltermodel.h"
22
23/*!
24 * \qmltype SortFilterModel
25 * \instantiates QSortFilterProxyModelQML
26 * \inqmlmodule Ubuntu.Components 0.1
27 * \ingroup ubuntu
28 * \brief SortFilterModel sorts and filters rows from an existing model.
29 *
30 * The SortFilterModel takes an existing model such as a ListModel or
31 * any QAbstractItemModel implementation. The original rows and role names
32 * show up in the SortFilterModel with two basic differences. For one if
33 * \l sort.property is set all rows will be sorted. Further more if
34 * \l filter.property is set only rows matching the filter will be in the model.
35 *
36 * Example usage:
37 * \qml
38 * import QtQuick 2.0
39 * import Ubuntu.Components 1.1
40 * import Ubuntu.Components.ListItems 1.1
41 *
42 * MainView {
43 * width: units.gu(80)
44 * height: units.gu(40)
45 *
46 * ListModel {
47 * id: movies
48 * ListElement {
49 * title: "Esign"
50 * producer: "Chris Larkee"
51 * }
52 * ListElement {
53 * title: "Elephants Dream"
54 * producer: "Blender"
55 * }
56 * ListElement {
57 * title: "Big Buck Bunny"
58 * producer: "Blender"
59 * }
60 * }
61 *
62 * SortFilterModel {
63 * id: sortedMovies
64 * model: movies
65 * sort.property: "title"
66 * sort.order: Qt.DescendingOrder
67 *
68 * filter.property: "producer"
69 * filter.pattern: /blender/
70 * }
71 *
72 * ListView {
73 * model: sortedMovies
74 * anchors.fill: parent
75 *
76 * delegate: Subtitled {
77 * text: title
78 * subText: producer
79 * }
80 *
81 * section.delegate: ListItem.Header { text: i18n.tr(section) }
82 * section.property: "title"
83 * section.criteria: ViewSection.FirstCharacter
84 * }
85 * }
86 * \endqml
87 *
88 * Pay attention to the differences between the original model and the result:
89 * \list
90 * \li Big Buck Bunny will be the first row, because it's sorted by title
91 * \li Esign won't be visible, because it's from the wrong producer
92 * \endlist
93 */
94
95
96QSortFilterProxyModelQML::QSortFilterProxyModelQML(QObject *parent)
97 : QSortFilterProxyModel(parent)
98{
99 // This is virtually always what you want in QML
100 setDynamicSortFilter(true);
101 connect(this, SIGNAL(modelReset()), SIGNAL(countChanged()));
102 connect(this, SIGNAL(rowsInserted(QModelIndex,int,int)), SIGNAL(countChanged()));
103 connect(this, SIGNAL(rowsRemoved(QModelIndex,int,int)), SIGNAL(countChanged()));
104 connect(&m_sortBehavior, &SortBehavior::propertyChanged, this, &QSortFilterProxyModelQML::sortChangedInternal);
105 connect(&m_sortBehavior, &SortBehavior::orderChanged, this, &QSortFilterProxyModelQML::sortChangedInternal);
106 connect(&m_filterBehavior, &FilterBehavior::propertyChanged, this, &QSortFilterProxyModelQML::filterChangedInternal);
107 connect(&m_filterBehavior, &FilterBehavior::patternChanged, this, &QSortFilterProxyModelQML::filterChangedInternal);
108}
109
110int
111QSortFilterProxyModelQML::roleByName(const QString& roleName) const
112{
113 const QHash<int, QByteArray> roles = roleNames();
114 for(int role = 0; role < roles.count(); role++)
115 if (roles[role] == roleName)
116 return role;
117 return 0;
118}
119
120/*!
121 * \qmlproperty string SortFilterModel::sort.property
122 *
123 * If set to a valid role name, all rows will be sorted according to \l sort.order.
124 */
125
126/*!
127 * \qmlproperty string SortFilterModel::sort.order
128 *
129 * The order, if \l sort.property is set.
130 * Qt::AscendingOrder sorts results from A to Z or 0 to 9.
131 * Qt::DescendingOrder sorts results from Z to A or 9 to 0.
132 */
133
134SortBehavior*
135QSortFilterProxyModelQML::sortBehavior()
136{
137 return &m_sortBehavior;
138}
139
140/*!
141 * \qmlproperty string SortFilterModel::filter.pattern
142 *
143 * The pattern all rows must match, if \l filter.property is set.
144 *
145 * Some examples:
146 * \list
147 * \li /possible/ matches anywhere in a word, so both "impossible" and "possible".
148 * \li /^sign/ matches "sign". But not "assignment" because ^ means start.
149 * \li /vest$/ matches "safety vest" and "vest" but not "vested".
150 * \endlist
151 *
152 * For more advanced uses it's recommended to read up on Javascript regular expressions.
153 */
154
155/*!
156 * \qmlproperty string SortFilterModel::filter.property
157 *
158 * If set to a valid role name, only rows matching \l filter.pattern will be in the model.
159 */
160
161FilterBehavior*
162QSortFilterProxyModelQML::filterBehavior()
163{
164 return &m_filterBehavior;
165}
166
167void
168QSortFilterProxyModelQML::sortChangedInternal()
169{
170 setSortRole(roleByName(m_sortBehavior.property()));
171 sort(sortColumn() != -1 ? sortColumn() : 0, m_sortBehavior.order());
172 Q_EMIT sortChanged();
173}
174
175void
176QSortFilterProxyModelQML::filterChangedInternal()
177{
178 setFilterRole(roleByName(m_filterBehavior.property()));
179 setFilterRegExp(m_filterBehavior.pattern());
180 Q_EMIT filterChanged();
181}
182
183QHash<int, QByteArray> QSortFilterProxyModelQML::roleNames() const
184{
185 return sourceModel() ? sourceModel()->roleNames() : QHash<int, QByteArray>();
186}
187
188/*!
189 * \qmlproperty QAbstractItemModel SortFilterModel::model
190 *
191 * The source model to sort and/ or filter.
192 */
193void
194QSortFilterProxyModelQML::setModel(QAbstractItemModel *itemModel)
195{
196 if (itemModel == NULL) {
197 return;
198 }
199
200 if (itemModel != sourceModel()) {
201 if (sourceModel() != NULL) {
202 sourceModel()->disconnect(this);
203 }
204
205 setSourceModel(itemModel);
206 // Roles mapping to role names may change
207 setSortRole(roleByName(m_sortBehavior.property()));
208 setFilterRole(roleByName(m_filterBehavior.property()));
209 Q_EMIT modelChanged();
210 }
211}
212
213QVariantMap
214QSortFilterProxyModelQML::get(int row)
215{
216 QVariantMap res;
217 const QHash<int, QByteArray> roles = roleNames();
218 for(int role = 0; role < roles.count(); role++)
219 res.insert (roles[role], data(row, role));
220 return res;
221}
222
223QVariant
224QSortFilterProxyModelQML::data(int row, int role)
225{
226 if (sourceModel() == NULL) {
227 return QVariant();
228 }
229
230 return index(row, 0).data(role);
231}
232
233int
234QSortFilterProxyModelQML::count()
235{
236 return rowCount();
237}
238
239bool
240QSortFilterProxyModelQML::filterAcceptsRow(int sourceRow,
241 const QModelIndex &sourceParent) const
242{
243 if (filterRegExp().isEmpty()) {
244 return true;
245 }
246
247 bool result = QSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent);
248 return result;
249}
250
251#include "moc_sortfiltermodel.cpp"
252
0253
=== added file 'modules/Ubuntu/Components/plugin/sortfiltermodel.h'
--- modules/Ubuntu/Components/plugin/sortfiltermodel.h 1970-01-01 00:00:00 +0000
+++ modules/Ubuntu/Components/plugin/sortfiltermodel.h 2014-05-28 18:09:57 +0000
@@ -0,0 +1,68 @@
1/*
2 * Copyright (C) 2012-2014 Canonical, Ltd.
3 *
4 * Authors:
5 * Michal Hruby <michal.hruby@canonical.com>
6 * Christian Dywan <christian.dywan@canonical.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU Lesser General Public License as published by
10 * the Free Software Foundation; version 3.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#ifndef QSORTFILTERPROXYMODELQML_H
22#define QSORTFILTERPROXYMODELQML_H
23
24#include <QSortFilterProxyModel>
25#include "sortbehavior.h"
26#include "filterbehavior.h"
27
28class Q_DECL_EXPORT QSortFilterProxyModelQML : public QSortFilterProxyModel
29{
30 Q_OBJECT
31
32 Q_PROPERTY(QAbstractItemModel* model READ sourceModel WRITE setModel NOTIFY modelChanged)
33 Q_PROPERTY(int count READ count NOTIFY countChanged)
34 Q_PROPERTY(SortBehavior* sort READ sortBehavior NOTIFY sortChanged)
35 Q_PROPERTY(FilterBehavior* filter READ filterBehavior NOTIFY filterChanged)
36
37public:
38 explicit QSortFilterProxyModelQML(QObject *parent = 0);
39
40 Q_INVOKABLE QVariantMap get(int row);
41 QVariant data(int row, int role);
42 Q_INVOKABLE int count();
43 virtual bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
44
45 /* getters */
46 QHash<int, QByteArray> roleNames() const;
47
48 /* setters */
49 void setFilterProperty(const QString& property);
50 void setModel(QAbstractItemModel *model);
51
52Q_SIGNALS:
53 void countChanged();
54 void modelChanged();
55 void sortChanged();
56 void filterChanged();
57
58private:
59 SortBehavior m_sortBehavior;
60 SortBehavior* sortBehavior();
61 void sortChangedInternal();
62 FilterBehavior m_filterBehavior;
63 FilterBehavior* filterBehavior();
64 void filterChangedInternal();
65 int roleByName(const QString& roleName) const;
66};
67
68#endif // QSORTFILTERPROXYMODELQML_H
069
=== modified file 'modules/Ubuntu/Components/plugin/thumbnailgenerator.cpp'
--- modules/Ubuntu/Components/plugin/thumbnailgenerator.cpp 2014-02-25 09:14:23 +0000
+++ modules/Ubuntu/Components/plugin/thumbnailgenerator.cpp 2014-05-28 18:09:57 +0000
@@ -43,12 +43,15 @@
43 * is the only way around the issue for now. */43 * is the only way around the issue for now. */
44 std::string src_path(QUrl(id).path().toUtf8().data());44 std::string src_path(QUrl(id).path().toUtf8().data());
45 std::string tgt_path;45 std::string tgt_path;
46 const int xlarge_cutoff = 512;
47 const int large_cutoff = 256;
48 const int small_cutoff = 128;
46 try {49 try {
47 ThumbnailSize desiredSize;50 ThumbnailSize desiredSize;
48 const int large_cutoff = 256;51 if(requestedSize.width() > xlarge_cutoff || requestedSize.height() > xlarge_cutoff) {
49 const int small_cutoff = 128;
50 if(requestedSize.width() > large_cutoff || requestedSize.height() > large_cutoff) {
51 desiredSize = TN_SIZE_ORIGINAL;52 desiredSize = TN_SIZE_ORIGINAL;
53 } else if(requestedSize.width() > large_cutoff || requestedSize.height() > large_cutoff) {
54 desiredSize = TN_SIZE_XLARGE;
52 } else if(requestedSize.width() > small_cutoff || requestedSize.height() > small_cutoff) {55 } else if(requestedSize.width() > small_cutoff || requestedSize.height() > small_cutoff) {
53 desiredSize = TN_SIZE_LARGE;56 desiredSize = TN_SIZE_LARGE;
54 } else {57 } else {
5558
=== modified file 'modules/Ubuntu/Components/plugin/ucalarm.cpp'
--- modules/Ubuntu/Components/plugin/ucalarm.cpp 2014-04-23 08:50:20 +0000
+++ modules/Ubuntu/Components/plugin/ucalarm.cpp 2014-05-28 18:09:57 +0000
@@ -177,6 +177,21 @@
177 return result;177 return result;
178 }178 }
179179
180 // fix lp:1319401 - dayOfWeek omitted if set to other than AutoDetect
181 int dayOfWeek = rawData.date.date().dayOfWeek();
182 if (!isDaySet(dayOfWeek, rawData.days)) {
183 // dayOfWeek has been set by the user, adjust the date to it
184 int nextOccurrence = nextDayOfWeek(rawData.days, dayOfWeek);
185 if (nextOccurrence < dayOfWeek) {
186 // the starting date should be moved to the next week's occurrence
187 rawData.date = rawData.date.addDays(7 - dayOfWeek + nextOccurrence);
188 } else {
189 // the starting date is still this week
190 rawData.date = rawData.date.addDays(nextOccurrence - dayOfWeek);
191 }
192 rawData.changes |= AlarmData::Date;
193 }
194
180 // start date should be later then the current date/time195 // start date should be later then the current date/time
181 if (rawData.date <= AlarmData::normalizeDate(QDateTime::currentDateTime())) {196 if (rawData.date <= AlarmData::normalizeDate(QDateTime::currentDateTime())) {
182 return UCAlarm::EarlyDate;197 return UCAlarm::EarlyDate;
@@ -370,10 +385,6 @@
370 d->rawData.date = AlarmData::normalizeDate(date);385 d->rawData.date = AlarmData::normalizeDate(date);
371 d->rawData.changes |= AlarmData::Date;386 d->rawData.changes |= AlarmData::Date;
372 Q_EMIT dateChanged();387 Q_EMIT dateChanged();
373 if (d->rawData.type == UCAlarm::OneTime) {
374 // adjust dayOfWeek as well
375 setDaysOfWeek(UCAlarm::AutoDetect);
376 }
377}388}
378389
379/*!390/*!
380391
=== modified file 'modules/Ubuntu/Components/plugin/ucthemesettings.cpp'
--- modules/Ubuntu/Components/plugin/ucthemesettings.cpp 2013-10-18 08:56:39 +0000
+++ modules/Ubuntu/Components/plugin/ucthemesettings.cpp 2014-05-28 18:09:57 +0000
@@ -21,19 +21,20 @@
2121
22#include <QtCore/QDir>22#include <QtCore/QDir>
23#include <QtCore/QFile>23#include <QtCore/QFile>
24#include <QtCore/QStandardPaths>
2425
25/*26/*
26 User theme settings are stored in $HOME/.config/ubuntu-ui-toolkit/theme.ini file, which contains27 User theme settings are stored in $XDG_CONFIG_HOME/ubuntu-ui-toolkit/theme.ini file, which contains
27 the current global theme name.28 the current global theme name.
28*/29*/
2930
30const QString SETTINGS_FILE_FORMAT("%1/.config/ubuntu-ui-toolkit/theme.ini");31const QString SETTINGS_FILE_FORMAT("%1/ubuntu-ui-toolkit/theme.ini");
31const QString THEME_KEY("theme");32const QString THEME_KEY("theme");
32const QString DEFAULT_THEME("Ubuntu.Components.Themes.Ambiance");33const QString DEFAULT_THEME("Ubuntu.Components.Themes.Ambiance");
3334
34UCThemeSettings::UCThemeSettings(QObject *parent) :35UCThemeSettings::UCThemeSettings(QObject *parent) :
35 QObject(parent),36 QObject(parent),
36 m_settings(SETTINGS_FILE_FORMAT.arg(QDir::homePath()), QSettings::IniFormat)37 m_settings(SETTINGS_FILE_FORMAT.arg(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation)), QSettings::IniFormat)
37{38{
38 // check if there is a theme settings file, if not, create one39 // check if there is a theme settings file, if not, create one
39 if (!QFile::exists(m_settings.fileName())) {40 if (!QFile::exists(m_settings.fileName())) {
4041
=== modified file 'modules/Ubuntu/Layouts/plugin/plugin.pro'
--- modules/Ubuntu/Layouts/plugin/plugin.pro 2013-11-22 11:15:48 +0000
+++ modules/Ubuntu/Layouts/plugin/plugin.pro 2014-05-28 18:09:57 +0000
@@ -5,7 +5,7 @@
55
6QMAKE_CXXFLAGS += -Werror6QMAKE_CXXFLAGS += -Werror
77
8QT += quick-private8QT += quick-private gui-private
9QT += qml-private core-private9QT += qml-private core-private
1010
11equals(QT_MAJOR_VERSION, 5):lessThan(QT_MINOR_VERSION, 2) {11equals(QT_MAJOR_VERSION, 5):lessThan(QT_MINOR_VERSION, 2) {
1212
=== modified file 'modules/Ubuntu/Layouts/plugin/propertychanges.cpp'
--- modules/Ubuntu/Layouts/plugin/propertychanges.cpp 2013-06-26 09:58:41 +0000
+++ modules/Ubuntu/Layouts/plugin/propertychanges.cpp 2014-05-28 18:09:57 +0000
@@ -145,7 +145,7 @@
145 }145 }
146 if (fromBinding) {146 if (fromBinding) {
147 QQmlAbstractBinding *revertedBinding = QQmlPropertyPrivate::setBinding(property, fromBinding);147 QQmlAbstractBinding *revertedBinding = QQmlPropertyPrivate::setBinding(property, fromBinding);
148 if (revertedBinding && ((revertedBinding != toBinding.data()) || (revertedBinding == toBinding.data() && deleteToBinding))) {148 if (revertedBinding && (revertedBinding != fromBinding) && ((revertedBinding != toBinding.data()) || (revertedBinding == toBinding.data() && deleteToBinding))) {
149 revertedBinding->destroy();149 revertedBinding->destroy();
150 }150 }
151 } else if (!toBinding.isNull() && QQmlPropertyPrivate::binding(property) == toBinding.data()) {151 } else if (!toBinding.isNull() && QQmlPropertyPrivate::binding(property) == toBinding.data()) {
@@ -222,24 +222,6 @@
222{222{
223}223}
224224
225/******************************************************************************
226 * ReparentChange
227 */
228ReparentChange::ReparentChange(QQuickItem *target, const QString &property, QQuickItem *source)
229 : PropertyChange(target, property, QVariant(), Normal)
230 , sourceProperty(source, property, qmlContext(source))
231{
232 action.type = PropertyAction::Binding;
233}
234
235void ReparentChange::saveState()
236{
237 action.toValue = sourceProperty.read();
238 PropertyChange::saveState();
239 if (sourceProperty.isValid()) {
240 action.setTargetBinding(QQmlPropertyPrivate::binding(sourceProperty), false);
241 }
242}
243225
244/******************************************************************************226/******************************************************************************
245 * ParentChange227 * ParentChange
@@ -304,35 +286,31 @@
304 * ItemStackBackup286 * ItemStackBackup
305 * High priority change backing up the item's stack position.287 * High priority change backing up the item's stack position.
306 */288 */
307ItemStackBackup::ItemStackBackup(QQuickItem *item, QQuickItem *currentLayoutItem, QQuickItem *previousLayoutItem)289ItemStackBackup::ItemStackBackup(QQuickItem *item)
308 : PropertyChange(High)290 : PropertyChange(High)
309 , target(item)291 , target(item)
310 , currentLayout(currentLayoutItem)292 , prevItem(0)
311 , previousLayout(previousLayoutItem)
312 , originalStackBefore(0)
313{293{
314}294}
315295
316void ItemStackBackup::saveState()296void ItemStackBackup::saveState()
317{297{
318 QQuickItem *rewindParent = target->parentItem();298 QQuickItem *rewindParent = target->parentItem();
299 if (!rewindParent) {
300 return;
301 }
319 // save original stack position, but detect layout objects!302 // save original stack position, but detect layout objects!
320 QList<QQuickItem*> children = rewindParent->childItems();303 QList<QQuickItem*> children = rewindParent->childItems();
321 for (int ii = 0; ii < children.count() - 1; ++ii) {304 int index = children.indexOf(target);
322 if (children.at(ii) == target) {305 if (index > 0) {
323 originalStackBefore = children.at(ii + 1);306 prevItem = children.at(index - 1);
324 if (originalStackBefore == currentLayout || originalStackBefore == previousLayout) {
325 originalStackBefore = 0;
326 }
327 break;
328 }
329 }307 }
330}308}
331309
332void ItemStackBackup::revert()310void ItemStackBackup::revert()
333{311{
334 if (originalStackBefore) {312 if (prevItem) {
335 target->stackBefore(originalStackBefore);313 target->stackAfter(prevItem);
336 }314 }
337}315}
338316
@@ -459,6 +437,13 @@
459 return *this;437 return *this;
460}438}
461439
440// creates two changes, one for reparenting and one for itemstack backup
441ChangeList &ChangeList::addParentChange(QQuickItem *item, QQuickItem *newParent, bool topmostItem)
442{
443 return addChange(new ParentChange(item, newParent, topmostItem))
444 .addChange(new ItemStackBackup(item));
445}
446
462QList<PropertyChange*> ChangeList::unifiedChanges()447QList<PropertyChange*> ChangeList::unifiedChanges()
463{448{
464 QList<PropertyChange*> list;449 QList<PropertyChange*> list;
465450
=== modified file 'modules/Ubuntu/Layouts/plugin/propertychanges_p.h'
--- modules/Ubuntu/Layouts/plugin/propertychanges_p.h 2013-06-26 09:58:41 +0000
+++ modules/Ubuntu/Layouts/plugin/propertychanges_p.h 2014-05-28 18:09:57 +0000
@@ -104,18 +104,6 @@
104};104};
105105
106106
107class ReparentChange : public PropertyChange
108{
109public:
110 ReparentChange(QQuickItem *item, const QString &property, QQuickItem *source);
111
112protected:
113 virtual void saveState();
114
115 QQmlProperty sourceProperty;
116};
117
118
119class ParentChange : public PropertyChange107class ParentChange : public PropertyChange
120{108{
121public:109public:
@@ -143,16 +131,14 @@
143class ItemStackBackup : public PropertyChange131class ItemStackBackup : public PropertyChange
144{132{
145public:133public:
146 ItemStackBackup(QQuickItem *item, QQuickItem *currentLayoutItem, QQuickItem *previousLayoutItem);134 ItemStackBackup(QQuickItem *item);
147 void apply() {}135 void apply() {}
148 void revert();136 void revert();
149137
150protected:138protected:
151 virtual void saveState();139 virtual void saveState();
152 QQuickItem *target;140 QQuickItem *target;
153 QQuickItem *currentLayout;141 QQuickItem *prevItem;
154 QQuickItem *previousLayout;
155 QQuickItem *originalStackBefore;
156private:142private:
157 friend class ULLayouts;143 friend class ULLayouts;
158};144};
@@ -214,6 +200,7 @@
214 void clear();200 void clear();
215201
216 ChangeList &addChange(PropertyChange *change);202 ChangeList &addChange(PropertyChange *change);
203 ChangeList &addParentChange(QQuickItem *item, QQuickItem *newParent, bool topmostItem);
217204
218private:205private:
219 QList<PropertyChange*> changes[PropertyChange::MaxPriority];206 QList<PropertyChange*> changes[PropertyChange::MaxPriority];
220207
=== modified file 'modules/Ubuntu/Layouts/plugin/ulitemlayout.h'
--- modules/Ubuntu/Layouts/plugin/ulitemlayout.h 2013-06-06 16:00:10 +0000
+++ modules/Ubuntu/Layouts/plugin/ulitemlayout.h 2014-05-28 18:09:57 +0000
@@ -26,7 +26,7 @@
26 Q_OBJECT26 Q_OBJECT
27 Q_DISABLE_COPY(ULItemLayout)27 Q_DISABLE_COPY(ULItemLayout)
2828
29 Q_PROPERTY(QString item READ item WRITE setItem)29 Q_PROPERTY(QString item READ item WRITE setItem NOTIFY itemChanged)
3030
31public:31public:
32 explicit ULItemLayout(QQuickItem *parent = 0);32 explicit ULItemLayout(QQuickItem *parent = 0);
@@ -35,6 +35,9 @@
35 QString item() const;35 QString item() const;
36 void setItem(const QString &value);36 void setItem(const QString &value);
3737
38Q_SIGNALS:
39 void itemChanged();
40
38private:41private:
39 QString m_itemName;42 QString m_itemName;
40};43};
4144
=== modified file 'modules/Ubuntu/Layouts/plugin/ullayouts.cpp'
--- modules/Ubuntu/Layouts/plugin/ullayouts.cpp 2014-04-20 19:25:12 +0000
+++ modules/Ubuntu/Layouts/plugin/ullayouts.cpp 2014-05-28 18:09:57 +0000
@@ -22,15 +22,21 @@
22#include "ulconditionallayout.h"22#include "ulconditionallayout.h"
23#include "propertychanges_p.h"23#include "propertychanges_p.h"
24#include <QtQml/QQmlInfo>24#include <QtQml/QQmlInfo>
25#include <QtQuick/private/qquickitem_p.h>
2526
26ULLayoutsPrivate::ULLayoutsPrivate(ULLayouts *qq)27ULLayoutsPrivate::ULLayoutsPrivate(ULLayouts *qq)
27 : QQmlIncubator(Asynchronous)28 : QQmlIncubator(Asynchronous)
28 , q_ptr(qq)29 , q_ptr(qq)
29 , currentLayoutItem(0)30 , currentLayoutItem(0)
30 , previousLayoutItem(0)31 , previousLayoutItem(0)
32 , contentItem(new QQuickItem)
31 , currentLayoutIndex(-1)33 , currentLayoutIndex(-1)
32 , ready(false)34 , ready(false)
33{35{
36 // hidden container for the components that are not laid out
37 // any component not subject of layout is reparented into this component
38 contentItem->setParent(qq);
39 contentItem->setParentItem(qq);
34}40}
3541
3642
@@ -80,7 +86,6 @@
80 QQuickItem *item = static_cast<QQuickItem*>(object);86 QQuickItem *item = static_cast<QQuickItem*>(object);
81 // set disabled and invisible, and set its parent as last action87 // set disabled and invisible, and set its parent as last action
82 item->setVisible(false);88 item->setVisible(false);
83 item->setEnabled(false);
84}89}
8590
86/*91/*
@@ -98,14 +103,16 @@
98 currentLayoutItem = qobject_cast<QQuickItem*>(object());103 currentLayoutItem = qobject_cast<QQuickItem*>(object());
99 Q_ASSERT(currentLayoutItem);104 Q_ASSERT(currentLayoutItem);
100105
101 // hide all non-laid out items first
102 hideExcludedItems();
103
104 //reparent components to be laid out106 //reparent components to be laid out
105 reparentItems();107 reparentItems();
106 // set parent item, then enable and show layout108 // set parent item, then enable and show layout
107 changes.addChange(new ParentChange(currentLayoutItem, q, false));109 changes.addChange(new ParentChange(currentLayoutItem, q, false));
108 itemActivate(currentLayoutItem, true);110
111 // hide default layout, then show the new one
112 // there's no need to queue these property changes as we do not need
113 // to back up their previosus states
114 contentItem->setVisible(false);
115 currentLayoutItem->setVisible(true);
109 // apply changes116 // apply changes
110 changes.apply();117 changes.apply();
111 // clear previous layout118 // clear previous layout
@@ -114,18 +121,10 @@
114121
115 Q_EMIT q->currentLayoutChanged();122 Q_EMIT q->currentLayoutChanged();
116 } else if (status == Error) {123 } else if (status == Error) {
117 Q_Q(ULLayouts);
118 error(q, errors());124 error(q, errors());
119 }125 }
120}126}
121127
122void ULLayoutsPrivate::hideExcludedItems()
123{
124 for (int i = 0; i < excludedFromLayout.count(); i++) {
125 itemActivate(excludedFromLayout[i], false);
126 }
127}
128
129/*128/*
130 * Re-parent items to the new layout.129 * Re-parent items to the new layout.
131 */130 */
@@ -134,26 +133,32 @@
134 // create copy of items list, to keep track of which ones we change133 // create copy of items list, to keep track of which ones we change
135 LaidOutItemsMap unusedItems = itemsToLayout;134 LaidOutItemsMap unusedItems = itemsToLayout;
136135
137 // iterate through the Layout definition to find containers - those Items with136 // iterate through the Layout definition to find containers - ItemLayout items
138 // ConditionalLayout.items set137 QList<ULItemLayout*> containers = collectContainers(currentLayoutItem);
139 QList<QQuickItem*> items = currentLayoutItem->findChildren<QQuickItem*>();138
140 // add the root item as that also can be the container139 Q_FOREACH(ULItemLayout *container, containers) {
141 items.prepend(currentLayoutItem);140 reparentToItemLayout(unusedItems, container);
142141 }
143 Q_FOREACH(QQuickItem *container, items) {142}
144 // check whether we have ItemLayout declared143
145 ULItemLayout *itemLayout = qobject_cast<ULItemLayout*>(container);144QList<ULItemLayout*> ULLayoutsPrivate::collectContainers(QQuickItem *fromItem)
146 if (itemLayout) {145{
147 reparentToItemLayout(unusedItems, itemLayout);146 QList<ULItemLayout*> result;
147 // check first if the fromItem is also a container
148 ULItemLayout *container = qobject_cast<ULItemLayout*>(fromItem);
149 if (container) {
150 result.append(container);
151 }
152
153 // loop through children but exclude nested Layouts
154 QList<QQuickItem*> children = fromItem->childItems();
155 Q_FOREACH(QQuickItem *child, children) {
156 if (qobject_cast<ULLayouts*>(child)) {
157 continue;
148 }158 }
149 }159 result.append(collectContainers(child));
150160 }
151 // hide the rest of the unused ones161 return result;
152 LaidOutItemsMapIterator i(unusedItems);
153 while (i.hasNext()) {
154 i.next();
155 itemActivate(i.value(), false);
156 }
157}162}
158163
159/*164/*
@@ -176,8 +181,7 @@
176 }181 }
177182
178 // the component fills the parent183 // the component fills the parent
179 changes.addChange(new ParentChange(item, fragment, true));184 changes.addParentChange(item, fragment, true);
180 changes.addChange(new ItemStackBackup(item, currentLayoutItem, previousLayoutItem));
181 changes.addChange(new AnchorChange(item, "fill", fragment));185 changes.addChange(new AnchorChange(item, "fill", fragment));
182 changes.addChange(new PropertyChange(item, "anchors.margins", 0));186 changes.addChange(new PropertyChange(item, "anchors.margins", 0));
183 changes.addChange(new PropertyChange(item, "anchors.leftMargin", 0));187 changes.addChange(new PropertyChange(item, "anchors.leftMargin", 0));
@@ -194,18 +198,6 @@
194 map.remove(itemName);198 map.remove(itemName);
195}199}
196200
197void ULLayoutsPrivate::itemActivate(QQuickItem *item, bool activate)
198{
199 changes.addChange(new PropertyChange(item, "visible", activate))
200 .addChange(new PropertyChange(item, "enabled", activate));
201}
202
203// remove the deleted item from the excluded ones
204void ULLayoutsPrivate::_q_removeExcludedItem(QObject *excludedItem)
205{
206 excludedFromLayout.removeAll(static_cast<QQuickItem*>(excludedItem));
207}
208
209/*201/*
210 * Validates the declared conditional layouts by checking whether they have name202 * Validates the declared conditional layouts by checking whether they have name
211 * property set and whether the value set is unique, and whether the conditional203 * property set and whether the value set is unique, and whether the conditional
@@ -244,44 +236,20 @@
244/*236/*
245 * Collect items to be laid out.237 * Collect items to be laid out.
246 */238 */
247void ULLayoutsPrivate::getLaidOutItems()239void ULLayoutsPrivate::getLaidOutItems(QQuickItem *container)
248{240{
249 Q_Q(ULLayouts);241 Q_FOREACH(QQuickItem *child, container->childItems()) {
250242 // skip nested layouts
251 QList<QQuickItem*> items = q->findChildren<QQuickItem*>();243 if (qobject_cast<ULLayouts*>(child)) {
252 for (int i = 0; i < items.count(); i++) {244 continue;
253 QQuickItem *item = items[i];245 }
254 ULLayoutsAttached *marker = qobject_cast<ULLayoutsAttached*>(246 ULLayoutsAttached *marker = qobject_cast<ULLayoutsAttached*>(
255 qmlAttachedPropertiesObject<ULLayouts>(item, false));247 qmlAttachedPropertiesObject<ULLayouts>(child, false));
256 if (marker && !marker->item().isEmpty()) {248 if (marker && !marker->item().isEmpty()) {
257 itemsToLayout.insert(marker->item(), item);249 itemsToLayout.insert(marker->item(), child);
258 } else {250 } else {
259 // the item is not marked to be laid out but one of its parents251 // continue to search in between the child's children
260 // can be, therefore check252 getLaidOutItems(child);
261 // check if the item's parent is included in the layout
262 QQuickItem *pl = item->parentItem();
263 marker = 0;
264 if (!pl && item->parent()) {
265 // this may be an item instance assigned to a property
266 // like "property var anItem: Item {}"
267 // in which case we must get the parent object of it, not the parent item
268 pl = qobject_cast<QQuickItem*>(item->parent());
269 }
270 while (pl) {
271 marker = qobject_cast<ULLayoutsAttached*>(
272 qmlAttachedPropertiesObject<ULLayouts>(pl, false));
273 if (marker && !marker->item().isEmpty()) {
274 break;
275 }
276 pl = pl->parentItem();
277 }
278 if (!marker || (marker && marker->item().isEmpty())) {
279 // remember theese so we hide them once we switch away from default layout
280 excludedFromLayout << item;
281 // and make sure we remove the item from excluded ones in case the item is destroyed
282 QObject::connect(item, SIGNAL(destroyed(QObject*)),
283 q, SLOT(_q_removeExcludedItem(QObject*)));
284 }
285 }253 }
286 }254 }
287}255}
@@ -344,6 +312,9 @@
344 // revert and clear changes312 // revert and clear changes
345 changes.revert();313 changes.revert();
346 changes.clear();314 changes.clear();
315 // make contentItem visible
316
317 contentItem->setVisible(true);
347 delete currentLayoutItem;318 delete currentLayoutItem;
348 currentLayoutItem = 0;319 currentLayoutItem = 0;
349 currentLayoutIndex = -1;320 currentLayoutIndex = -1;
@@ -606,10 +577,18 @@
606 Q_D(ULLayouts);577 Q_D(ULLayouts);
607 d->ready = true;578 d->ready = true;
608 d->validateConditionalLayouts();579 d->validateConditionalLayouts();
609 d->getLaidOutItems();580 d->getLaidOutItems(d->contentItem);
610 d->updateLayout();581 d->updateLayout();
611}582}
612583
584void ULLayouts::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
585{
586 Q_D(ULLayouts);
587 QQuickItem::geometryChanged(newGeometry, oldGeometry);
588 // simply update the container's width/height to the new width/height
589 d->contentItem->setSize(newGeometry.size());
590}
591
613/*!592/*!
614 * \qmlproperty string Layouts::currentLayout593 * \qmlproperty string Layouts::currentLayout
615 * The property holds the active layout name. The default layout is identified594 * The property holds the active layout name. The default layout is identified
@@ -634,6 +613,17 @@
634}613}
635614
636/*!615/*!
616 * \internal
617 * Returns the contentItem for internal use.
618 */
619QQuickItem *ULLayouts::contentItem() const
620{
621 Q_D(const ULLayouts);
622 return d->contentItem;
623}
624
625
626/*!
637 * \qmlproperty list<ConditionalLayout> Layouts::layouts627 * \qmlproperty list<ConditionalLayout> Layouts::layouts
638 * The property holds the list of different ConditionalLayout elements.628 * The property holds the list of different ConditionalLayout elements.
639 */629 */
@@ -647,4 +637,25 @@
647 &ULLayoutsPrivate::clear_layouts);637 &ULLayoutsPrivate::clear_layouts);
648}638}
649639
640/*!
641 * \internal
642 * Overrides the default data property.
643 */
644QQmlListProperty<QObject> ULLayouts::data()
645{
646 Q_D(ULLayouts);
647 return QQuickItemPrivate::get(d->contentItem)->data();
648}
649
650/*!
651 * \internal
652 * Overrides the default children property.
653 */
654QQmlListProperty<QQuickItem> ULLayouts::children()
655{
656 Q_D(ULLayouts);
657 return QQuickItemPrivate::get(d->contentItem)->children();
658}
659
660
650#include "moc_ullayouts.cpp"661#include "moc_ullayouts.cpp"
651662
=== modified file 'modules/Ubuntu/Layouts/plugin/ullayouts.h'
--- modules/Ubuntu/Layouts/plugin/ullayouts.h 2014-02-18 13:27:23 +0000
+++ modules/Ubuntu/Layouts/plugin/ullayouts.h 2014-05-28 18:09:57 +0000
@@ -55,7 +55,10 @@
5555
56 Q_PROPERTY(QString currentLayout READ currentLayout NOTIFY currentLayoutChanged DESIGNABLE false)56 Q_PROPERTY(QString currentLayout READ currentLayout NOTIFY currentLayoutChanged DESIGNABLE false)
57 Q_PROPERTY(QQmlListProperty<ULConditionalLayout> layouts READ layouts DESIGNABLE false)57 Q_PROPERTY(QQmlListProperty<ULConditionalLayout> layouts READ layouts DESIGNABLE false)
58 58
59 Q_PROPERTY(QQmlListProperty<QObject> data READ data DESIGNABLE false)
60 Q_PROPERTY(QQmlListProperty<QQuickItem> children READ children DESIGNABLE false)
61 Q_CLASSINFO("DefaultProperty", "data")
59public:62public:
60 explicit ULLayouts(QQuickItem *parent = 0);63 explicit ULLayouts(QQuickItem *parent = 0);
61 ~ULLayouts();64 ~ULLayouts();
@@ -64,21 +67,23 @@
6467
65 QString currentLayout() const;68 QString currentLayout() const;
66 QList<ULConditionalLayout*> layoutList();69 QList<ULConditionalLayout*> layoutList();
70 QQuickItem *contentItem() const;
6771
68Q_SIGNALS:72Q_SIGNALS:
69 void currentLayoutChanged();73 void currentLayoutChanged();
7074
71protected:75protected:
72 void componentComplete();76 void componentComplete();
77 void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry);
7378
74private:79private:
75 QQmlListProperty<ULConditionalLayout> layouts();80 QQmlListProperty<ULConditionalLayout> layouts();
81 QQmlListProperty<QObject> data();
82 QQmlListProperty<QQuickItem> children();
7683
77 friend class ULConditionalLayout;84 friend class ULConditionalLayout;
78 Q_DECLARE_PRIVATE(ULLayouts)85 Q_DECLARE_PRIVATE(ULLayouts)
79 QScopedPointer<ULLayoutsPrivate> d_ptr;86 QScopedPointer<ULLayoutsPrivate> d_ptr;
80
81 Q_PRIVATE_SLOT(d_func(), void _q_removeExcludedItem(QObject*))
82};87};
8388
84QML_DECLARE_TYPE(ULLayouts)89QML_DECLARE_TYPE(ULLayouts)
8590
=== modified file 'modules/Ubuntu/Layouts/plugin/ullayouts_p.h'
--- modules/Ubuntu/Layouts/plugin/ullayouts_p.h 2014-02-18 13:27:23 +0000
+++ modules/Ubuntu/Layouts/plugin/ullayouts_p.h 2014-05-28 18:09:57 +0000
@@ -33,9 +33,8 @@
3333
34 ULLayoutsPrivate(ULLayouts *qq);34 ULLayoutsPrivate(ULLayouts *qq);
3535
36 void _q_removeExcludedItem(QObject *excludedItem);
37 void validateConditionalLayouts();36 void validateConditionalLayouts();
38 void getLaidOutItems();37 void getLaidOutItems(QQuickItem *item);
39 void updateLayout();38 void updateLayout();
4039
41 static void error(QObject *item, const QString &message);40 static void error(QObject *item, const QString &message);
@@ -51,9 +50,9 @@
51 QList<ULConditionalLayout*> layouts;50 QList<ULConditionalLayout*> layouts;
52 ChangeList changes;51 ChangeList changes;
53 LaidOutItemsMap itemsToLayout;52 LaidOutItemsMap itemsToLayout;
54 QList<QQuickItem*> excludedFromLayout;
55 QQuickItem* currentLayoutItem;53 QQuickItem* currentLayoutItem;
56 QQuickItem* previousLayoutItem;54 QQuickItem* previousLayoutItem;
55 QQuickItem* contentItem;
57 int currentLayoutIndex;56 int currentLayoutIndex;
58 bool ready:1;57 bool ready:1;
5958
@@ -64,10 +63,9 @@
64 static void clear_layouts(QQmlListProperty<ULConditionalLayout>*);63 static void clear_layouts(QQmlListProperty<ULConditionalLayout>*);
6564
66 void reLayout();65 void reLayout();
67 void hideExcludedItems();
68 void reparentItems();66 void reparentItems();
67 QList<ULItemLayout*> collectContainers(QQuickItem *fromItem);
69 void reparentToItemLayout(LaidOutItemsMap &map, ULItemLayout *fragment);68 void reparentToItemLayout(LaidOutItemsMap &map, ULItemLayout *fragment);
70 void itemActivate(QQuickItem *item, bool activate);
71};69};
7270
73#endif // ULLAYOUTS_P_H71#endif // ULLAYOUTS_P_H
7472
=== modified file 'po/ca.po'
--- po/ca.po 2014-05-10 07:55:56 +0000
+++ po/ca.po 2014-05-28 18:09:57 +0000
@@ -14,8 +14,8 @@
14"MIME-Version: 1.0\n"14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"16"Content-Transfer-Encoding: 8bit\n"
17"X-Launchpad-Export-Date: 2014-05-10 07:55+0000\n"17"X-Launchpad-Export-Date: 2014-05-22 06:44+0000\n"
18"X-Generator: Launchpad (build 16996)\n"18"X-Generator: Launchpad (build 17017)\n"
1919
20#: examples/ubuntu-ui-toolkit-gallery/Animations.qml:2220#: examples/ubuntu-ui-toolkit-gallery/Animations.qml:22
21msgid "NumberAnimation"21msgid "NumberAnimation"
2222
=== modified file 'po/de.po'
--- po/de.po 2014-05-10 07:55:56 +0000
+++ po/de.po 2014-05-28 18:09:57 +0000
@@ -14,8 +14,8 @@
14"MIME-Version: 1.0\n"14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"16"Content-Transfer-Encoding: 8bit\n"
17"X-Launchpad-Export-Date: 2014-05-10 07:55+0000\n"17"X-Launchpad-Export-Date: 2014-05-22 06:44+0000\n"
18"X-Generator: Launchpad (build 16996)\n"18"X-Generator: Launchpad (build 17017)\n"
1919
20#: examples/ubuntu-ui-toolkit-gallery/Animations.qml:2220#: examples/ubuntu-ui-toolkit-gallery/Animations.qml:22
21msgid "NumberAnimation"21msgid "NumberAnimation"
2222
=== modified file 'po/es.po'
--- po/es.po 2014-05-10 07:55:56 +0000
+++ po/es.po 2014-05-28 18:09:57 +0000
@@ -14,8 +14,8 @@
14"MIME-Version: 1.0\n"14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"16"Content-Transfer-Encoding: 8bit\n"
17"X-Launchpad-Export-Date: 2014-05-10 07:55+0000\n"17"X-Launchpad-Export-Date: 2014-05-22 06:44+0000\n"
18"X-Generator: Launchpad (build 16996)\n"18"X-Generator: Launchpad (build 17017)\n"
1919
20#: examples/ubuntu-ui-toolkit-gallery/Animations.qml:2220#: examples/ubuntu-ui-toolkit-gallery/Animations.qml:22
21msgid "NumberAnimation"21msgid "NumberAnimation"
2222
=== modified file 'po/fi.po'
--- po/fi.po 2014-05-10 07:55:56 +0000
+++ po/fi.po 2014-05-28 18:09:57 +0000
@@ -14,8 +14,8 @@
14"MIME-Version: 1.0\n"14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"16"Content-Transfer-Encoding: 8bit\n"
17"X-Launchpad-Export-Date: 2014-05-10 07:55+0000\n"17"X-Launchpad-Export-Date: 2014-05-22 06:44+0000\n"
18"X-Generator: Launchpad (build 16996)\n"18"X-Generator: Launchpad (build 17017)\n"
1919
20#: examples/ubuntu-ui-toolkit-gallery/Animations.qml:2220#: examples/ubuntu-ui-toolkit-gallery/Animations.qml:22
21msgid "NumberAnimation"21msgid "NumberAnimation"
2222
=== modified file 'po/fr.po'
--- po/fr.po 2014-05-10 07:55:56 +0000
+++ po/fr.po 2014-05-28 18:09:57 +0000
@@ -14,8 +14,8 @@
14"MIME-Version: 1.0\n"14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"16"Content-Transfer-Encoding: 8bit\n"
17"X-Launchpad-Export-Date: 2014-05-10 07:55+0000\n"17"X-Launchpad-Export-Date: 2014-05-22 06:44+0000\n"
18"X-Generator: Launchpad (build 16996)\n"18"X-Generator: Launchpad (build 17017)\n"
1919
20#: examples/ubuntu-ui-toolkit-gallery/Animations.qml:2220#: examples/ubuntu-ui-toolkit-gallery/Animations.qml:22
21msgid "NumberAnimation"21msgid "NumberAnimation"
2222
=== modified file 'po/gl.po'
--- po/gl.po 2014-05-10 07:55:56 +0000
+++ po/gl.po 2014-05-28 18:09:57 +0000
@@ -14,8 +14,8 @@
14"MIME-Version: 1.0\n"14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"16"Content-Transfer-Encoding: 8bit\n"
17"X-Launchpad-Export-Date: 2014-05-10 07:55+0000\n"17"X-Launchpad-Export-Date: 2014-05-22 06:44+0000\n"
18"X-Generator: Launchpad (build 16996)\n"18"X-Generator: Launchpad (build 17017)\n"
1919
20#: examples/ubuntu-ui-toolkit-gallery/Animations.qml:2220#: examples/ubuntu-ui-toolkit-gallery/Animations.qml:22
21msgid "NumberAnimation"21msgid "NumberAnimation"
2222
=== modified file 'po/he.po'
--- po/he.po 2014-05-10 07:55:56 +0000
+++ po/he.po 2014-05-28 18:09:57 +0000
@@ -14,8 +14,8 @@
14"MIME-Version: 1.0\n"14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"16"Content-Transfer-Encoding: 8bit\n"
17"X-Launchpad-Export-Date: 2014-05-10 07:55+0000\n"17"X-Launchpad-Export-Date: 2014-05-22 06:44+0000\n"
18"X-Generator: Launchpad (build 16996)\n"18"X-Generator: Launchpad (build 17017)\n"
1919
20#: examples/ubuntu-ui-toolkit-gallery/Animations.qml:2220#: examples/ubuntu-ui-toolkit-gallery/Animations.qml:22
21msgid "NumberAnimation"21msgid "NumberAnimation"
2222
=== modified file 'po/hu.po'
--- po/hu.po 2014-05-10 07:55:56 +0000
+++ po/hu.po 2014-05-28 18:09:57 +0000
@@ -14,8 +14,8 @@
14"MIME-Version: 1.0\n"14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"16"Content-Transfer-Encoding: 8bit\n"
17"X-Launchpad-Export-Date: 2014-05-10 07:55+0000\n"17"X-Launchpad-Export-Date: 2014-05-22 06:44+0000\n"
18"X-Generator: Launchpad (build 16996)\n"18"X-Generator: Launchpad (build 17017)\n"
1919
20#: examples/ubuntu-ui-toolkit-gallery/Animations.qml:2220#: examples/ubuntu-ui-toolkit-gallery/Animations.qml:22
21msgid "NumberAnimation"21msgid "NumberAnimation"
2222
=== modified file 'po/ko.po'
--- po/ko.po 2014-05-10 07:55:56 +0000
+++ po/ko.po 2014-05-28 18:09:57 +0000
@@ -14,8 +14,8 @@
14"MIME-Version: 1.0\n"14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"16"Content-Transfer-Encoding: 8bit\n"
17"X-Launchpad-Export-Date: 2014-05-10 07:55+0000\n"17"X-Launchpad-Export-Date: 2014-05-22 06:44+0000\n"
18"X-Generator: Launchpad (build 16996)\n"18"X-Generator: Launchpad (build 17017)\n"
1919
20#: examples/ubuntu-ui-toolkit-gallery/Animations.qml:2220#: examples/ubuntu-ui-toolkit-gallery/Animations.qml:22
21msgid "NumberAnimation"21msgid "NumberAnimation"
2222
=== modified file 'po/my.po'
--- po/my.po 2014-05-10 07:55:56 +0000
+++ po/my.po 2014-05-28 18:09:57 +0000
@@ -14,8 +14,8 @@
14"MIME-Version: 1.0\n"14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"16"Content-Transfer-Encoding: 8bit\n"
17"X-Launchpad-Export-Date: 2014-05-10 07:55+0000\n"17"X-Launchpad-Export-Date: 2014-05-22 06:44+0000\n"
18"X-Generator: Launchpad (build 16996)\n"18"X-Generator: Launchpad (build 17017)\n"
1919
20#: examples/ubuntu-ui-toolkit-gallery/Animations.qml:2220#: examples/ubuntu-ui-toolkit-gallery/Animations.qml:22
21msgid "NumberAnimation"21msgid "NumberAnimation"
2222
=== modified file 'po/nl.po'
--- po/nl.po 2014-05-10 07:55:56 +0000
+++ po/nl.po 2014-05-28 18:09:57 +0000
@@ -14,8 +14,8 @@
14"MIME-Version: 1.0\n"14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"16"Content-Transfer-Encoding: 8bit\n"
17"X-Launchpad-Export-Date: 2014-05-10 07:55+0000\n"17"X-Launchpad-Export-Date: 2014-05-22 06:44+0000\n"
18"X-Generator: Launchpad (build 16996)\n"18"X-Generator: Launchpad (build 17017)\n"
1919
20#: examples/ubuntu-ui-toolkit-gallery/Animations.qml:2220#: examples/ubuntu-ui-toolkit-gallery/Animations.qml:22
21msgid "NumberAnimation"21msgid "NumberAnimation"
2222
=== modified file 'po/oc.po'
--- po/oc.po 2014-05-10 07:55:56 +0000
+++ po/oc.po 2014-05-28 18:09:57 +0000
@@ -14,8 +14,8 @@
14"MIME-Version: 1.0\n"14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"16"Content-Transfer-Encoding: 8bit\n"
17"X-Launchpad-Export-Date: 2014-05-10 07:55+0000\n"17"X-Launchpad-Export-Date: 2014-05-22 06:44+0000\n"
18"X-Generator: Launchpad (build 16996)\n"18"X-Generator: Launchpad (build 17017)\n"
1919
20#: examples/ubuntu-ui-toolkit-gallery/Animations.qml:2220#: examples/ubuntu-ui-toolkit-gallery/Animations.qml:22
21msgid "NumberAnimation"21msgid "NumberAnimation"
2222
=== modified file 'po/pt_BR.po'
--- po/pt_BR.po 2014-05-10 07:55:56 +0000
+++ po/pt_BR.po 2014-05-28 18:09:57 +0000
@@ -14,8 +14,8 @@
14"MIME-Version: 1.0\n"14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"16"Content-Transfer-Encoding: 8bit\n"
17"X-Launchpad-Export-Date: 2014-05-10 07:55+0000\n"17"X-Launchpad-Export-Date: 2014-05-22 06:44+0000\n"
18"X-Generator: Launchpad (build 16996)\n"18"X-Generator: Launchpad (build 17017)\n"
1919
20#: examples/ubuntu-ui-toolkit-gallery/Animations.qml:2220#: examples/ubuntu-ui-toolkit-gallery/Animations.qml:22
21msgid "NumberAnimation"21msgid "NumberAnimation"
2222
=== modified file 'po/sv.po'
--- po/sv.po 2014-05-10 07:55:56 +0000
+++ po/sv.po 2014-05-28 18:09:57 +0000
@@ -14,8 +14,8 @@
14"MIME-Version: 1.0\n"14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"16"Content-Transfer-Encoding: 8bit\n"
17"X-Launchpad-Export-Date: 2014-05-10 07:55+0000\n"17"X-Launchpad-Export-Date: 2014-05-22 06:44+0000\n"
18"X-Generator: Launchpad (build 16996)\n"18"X-Generator: Launchpad (build 17017)\n"
1919
20#: examples/ubuntu-ui-toolkit-gallery/Animations.qml:2220#: examples/ubuntu-ui-toolkit-gallery/Animations.qml:22
21msgid "NumberAnimation"21msgid "NumberAnimation"
2222
=== modified file 'po/uk.po'
--- po/uk.po 2014-05-10 07:55:56 +0000
+++ po/uk.po 2014-05-28 18:09:57 +0000
@@ -14,8 +14,8 @@
14"MIME-Version: 1.0\n"14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"16"Content-Transfer-Encoding: 8bit\n"
17"X-Launchpad-Export-Date: 2014-05-10 07:55+0000\n"17"X-Launchpad-Export-Date: 2014-05-22 06:44+0000\n"
18"X-Generator: Launchpad (build 16996)\n"18"X-Generator: Launchpad (build 17017)\n"
1919
20#: examples/ubuntu-ui-toolkit-gallery/Animations.qml:2220#: examples/ubuntu-ui-toolkit-gallery/Animations.qml:22
21msgid "NumberAnimation"21msgid "NumberAnimation"
2222
=== modified file 'tests/autopilot/ubuntuuitoolkit/__init__.py'
--- tests/autopilot/ubuntuuitoolkit/__init__.py 2014-04-25 18:39:51 +0000
+++ tests/autopilot/ubuntuuitoolkit/__init__.py 2014-05-28 18:09:57 +0000
@@ -24,14 +24,15 @@
24 'environment',24 'environment',
25 'emulators',25 'emulators',
26 'fixture_setup',26 'fixture_setup',
27 'Flickable',
28 'get_keyboard',27 'get_keyboard',
29 'get_pointing_device',28 'get_pointing_device',
30 'Header',29 'Header',
31 'listitems',30 'listitems',
32 'MainView',31 'MainView',
33 'OptionSelector',32 'OptionSelector',
33 'pickers',
34 'popups',34 'popups',
35 'QQuickFlickable',
35 'QQuickListView',36 'QQuickListView',
36 'TabBar',37 'TabBar',
37 'Tabs',38 'Tabs',
@@ -53,14 +54,15 @@
53from ubuntuuitoolkit._custom_proxy_objects import (54from ubuntuuitoolkit._custom_proxy_objects import (
54 check_autopilot_version,55 check_autopilot_version,
55 CheckBox,56 CheckBox,
56 Flickable,
57 get_keyboard,57 get_keyboard,
58 get_pointing_device,58 get_pointing_device,
59 Header,59 Header,
60 listitems,60 listitems,
61 MainView,61 MainView,
62 OptionSelector,62 OptionSelector,
63 pickers,
63 popups,64 popups,
65 QQuickFlickable,
64 QQuickListView,66 QQuickListView,
65 TabBar,67 TabBar,
66 Tabs,68 Tabs,
6769
=== modified file 'tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/__init__.py'
--- tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/__init__.py 2014-04-28 15:39:24 +0000
+++ tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/__init__.py 2014-05-28 18:09:57 +0000
@@ -20,14 +20,15 @@
20__all__ = [20__all__ = [
21 'check_autopilot_version',21 'check_autopilot_version',
22 'CheckBox',22 'CheckBox',
23 'Flickable',
24 'get_keyboard',23 'get_keyboard',
25 'get_pointing_device',24 'get_pointing_device',
26 'Header',25 'Header',
27 'listitems',26 'listitems',
28 'MainView',27 'MainView',
29 'OptionSelector',28 'OptionSelector',
29 'pickers',
30 'popups',30 'popups',
31 'QQuickFlickable',
31 'QQuickListView',32 'QQuickListView',
32 'TabBar',33 'TabBar',
33 'Tabs',34 'Tabs',
@@ -45,13 +46,14 @@
45 ToolkitException,46 ToolkitException,
46 UbuntuUIToolkitCustomProxyObjectBase,47 UbuntuUIToolkitCustomProxyObjectBase,
47)48)
48from ubuntuuitoolkit._custom_proxy_objects._flickable import Flickable49from ubuntuuitoolkit._custom_proxy_objects._flickable import QQuickFlickable
49from ubuntuuitoolkit._custom_proxy_objects._header import Header50from ubuntuuitoolkit._custom_proxy_objects._header import Header
50from ubuntuuitoolkit._custom_proxy_objects import listitems51from ubuntuuitoolkit._custom_proxy_objects import listitems
51from ubuntuuitoolkit._custom_proxy_objects._mainview import MainView52from ubuntuuitoolkit._custom_proxy_objects._mainview import MainView
52from ubuntuuitoolkit._custom_proxy_objects._optionselector import (53from ubuntuuitoolkit._custom_proxy_objects._optionselector import (
53 OptionSelector54 OptionSelector
54)55)
56from ubuntuuitoolkit._custom_proxy_objects import pickers
55from ubuntuuitoolkit._custom_proxy_objects import popups57from ubuntuuitoolkit._custom_proxy_objects import popups
56from ubuntuuitoolkit._custom_proxy_objects._qquicklistview import (58from ubuntuuitoolkit._custom_proxy_objects._qquicklistview import (
57 QQuickListView59 QQuickListView
5860
=== modified file 'tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_common.py'
--- tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_common.py 2014-04-16 21:13:39 +0000
+++ tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_common.py 2014-05-28 18:09:57 +0000
@@ -16,13 +16,21 @@
1616
17"""Common helpers for Ubuntu UI Toolkit Autopilot custom proxy objects."""17"""Common helpers for Ubuntu UI Toolkit Autopilot custom proxy objects."""
1818
19import logging
19from distutils import version20from distutils import version
2021
21import autopilot22import autopilot
22from autopilot import platform, input23from autopilot import (
24 input,
25 logging as autopilot_logging,
26 platform
27)
23from autopilot.introspection import dbus28from autopilot.introspection import dbus
2429
2530
31logger = logging.getLogger(__name__)
32
33
26class ToolkitException(Exception):34class ToolkitException(Exception):
27 """Exception raised when there is an error with the emulator."""35 """Exception raised when there is an error with the emulator."""
2836
@@ -67,3 +75,39 @@
67 check_autopilot_version()75 check_autopilot_version()
68 super(UbuntuUIToolkitCustomProxyObjectBase, self).__init__(*args)76 super(UbuntuUIToolkitCustomProxyObjectBase, self).__init__(*args)
69 self.pointing_device = get_pointing_device()77 self.pointing_device = get_pointing_device()
78
79 def is_flickable(self):
80 """Check if the object is flickable.
81
82 If the object has a flicking attribute, we consider it as a flickable.
83
84 :return: True if the object is flickable. False otherwise.
85
86 """
87 try:
88 self.flicking
89 return True
90 except AttributeError:
91 return False
92
93 @autopilot_logging.log_action(logger.info)
94 def swipe_into_view(self):
95 """Make the object visible.
96
97 Currently it works only when the object needs to be swiped vertically.
98 TODO implement horizontal swiping. --elopio - 2014-03-21
99
100 """
101 flickable_parent = self._get_flickable_parent()
102 flickable_parent.swipe_child_into_view(self)
103
104 def _get_flickable_parent(self):
105 parent = self.get_parent()
106 root = self.get_root_instance()
107 while parent.id != root.id:
108 if parent.is_flickable():
109 return parent
110 parent = parent.get_parent()
111 raise ToolkitException(
112 "The element is not contained in a Flickable so it can't be "
113 "swiped into view.")
70114
=== modified file 'tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_flickable.py'
--- tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_flickable.py 2014-04-16 21:13:39 +0000
+++ tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_flickable.py 2014-05-28 18:09:57 +0000
@@ -38,21 +38,7 @@
38 return min(containers_bottom)38 return min(containers_bottom)
3939
4040
41class Flickable(_common.UbuntuUIToolkitCustomProxyObjectBase):41class Scrollable(_common.UbuntuUIToolkitCustomProxyObjectBase):
42
43 @autopilot_logging.log_action(logger.info)
44 def swipe_child_into_view(self, child):
45 """Make the child visible.
46
47 Currently it works only when the object needs to be swiped vertically.
48 TODO implement horizontal swiping. --elopio - 2014-03-21
49
50 """
51 containers = self._get_containers()
52 if not self._is_child_visible(child, containers):
53 self._swipe_non_visible_child_into_view(child, containers)
54 else:
55 logger.debug('The element is already visible.')
5642
57 def _get_containers(self):43 def _get_containers(self):
58 """Return a list with the containers to take into account when swiping.44 """Return a list with the containers to take into account when swiping.
@@ -68,15 +54,19 @@
68 def _get_top_container(self):54 def _get_top_container(self):
69 """Return the top-most container with a globalRect."""55 """Return the top-most container with a globalRect."""
70 root = self.get_root_instance()56 root = self.get_root_instance()
71 containers = [root]57 parent = self.get_parent()
72 while len(containers) == 1:58 top_container = None
73 try:59 while parent.id != root.id:
74 containers[0].globalRect60 if hasattr(parent, 'globalRect'):
75 return containers[0]61 top_container = parent
76 except AttributeError:62
77 containers = containers[0].get_children()63 parent = parent.get_parent()
7864
79 raise _common.ToolkitException("Couldn't find the top-most container.")65 if top_container is None:
66 raise _common.ToolkitException(
67 "Couldn't find the top-most container.")
68 else:
69 return top_container
8070
81 def _is_child_visible(self, child, containers):71 def _is_child_visible(self, child, containers):
82 """Check if the center of the child is visible.72 """Check if the center of the child is visible.
@@ -90,8 +80,38 @@
90 return (object_center >= visible_top and80 return (object_center >= visible_top and
91 object_center <= visible_bottom)81 object_center <= visible_bottom)
9282
83 def _slow_drag(self, start_x, stop_x, start_y, stop_y):
84 # If we drag too fast, we end up scrolling more than what we
85 # should, sometimes missing the element we are looking for.
86 # I found that when the flickDeceleration is 1500, the rate should be
87 # 5 and that when it's 100, the rate should be 1. With those two points
88 # we can get that the following equation.
89 # XXX The deceleration might not be linear with respect to the rate,
90 # but this works for the two types of scrollables we have for now.
91 # --elopio - 2014-05-08
92 rate = (self.flickDeceleration + 250) / 350
93 self.pointing_device.drag(start_x, start_y, stop_x, stop_y, rate=rate)
94
95
96class QQuickFlickable(Scrollable):
97
98 @autopilot_logging.log_action(logger.info)
99 def swipe_child_into_view(self, child):
100 """Make the child visible.
101
102 Currently it works only when the object needs to be swiped vertically.
103 TODO implement horizontal swiping. --elopio - 2014-03-21
104
105 """
106 containers = self._get_containers()
107 if not self._is_child_visible(child, containers):
108 self._swipe_non_visible_child_into_view(child, containers)
109 else:
110 logger.debug('The element is already visible.')
111
93 @autopilot_logging.log_action(logger.info)112 @autopilot_logging.log_action(logger.info)
94 def _swipe_non_visible_child_into_view(self, child, containers):113 def _swipe_non_visible_child_into_view(self, child, containers):
114 original_content_y = self.contentY
95 while not self._is_child_visible(child, containers):115 while not self._is_child_visible(child, containers):
96 # Check the direction of the swipe based on the position of the116 # Check the direction of the swipe based on the position of the
97 # child relative to the immediate flickable container.117 # child relative to the immediate flickable container.
@@ -100,6 +120,10 @@
100 else:120 else:
101 self._swipe_to_show_more_below(containers)121 self._swipe_to_show_more_below(containers)
102122
123 if self.contentY == original_content_y:
124 raise _common.ToolkitException(
125 "Couldn't swipe in the flickable.")
126
103 @autopilot_logging.log_action(logger.info)127 @autopilot_logging.log_action(logger.info)
104 def _swipe_to_show_more_above(self, containers):128 def _swipe_to_show_more_above(self, containers):
105 if self.atYBeginning:129 if self.atYBeginning:
@@ -124,8 +148,12 @@
124 # bottom.148 # bottom.
125 top = _get_visible_container_top(containers) + 5149 top = _get_visible_container_top(containers) + 5
126 bottom = _get_visible_container_bottom(containers) - 5150 bottom = _get_visible_container_bottom(containers) - 5
151
127 if direction == 'below':152 if direction == 'below':
128 start_y = bottom153 # Take into account that swiping from below can open the toolbar or
154 # trigger the bottom edge gesture.
155 # XXX Do this only if we are close to the bottom edge.
156 start_y = bottom - 20
129 stop_y = top157 stop_y = top
130 elif direction == 'above':158 elif direction == 'above':
131 start_y = top159 start_y = top
@@ -137,11 +165,6 @@
137 self.dragging.wait_for(False)165 self.dragging.wait_for(False)
138 self.moving.wait_for(False)166 self.moving.wait_for(False)
139167
140 def _slow_drag(self, start_x, stop_x, start_y, stop_y):
141 # If we drag too fast, we end up scrolling more than what we
142 # should, sometimes missing the element we are looking for.
143 self.pointing_device.drag(start_x, start_y, stop_x, stop_y, rate=5)
144
145 @autopilot_logging.log_action(logger.info)168 @autopilot_logging.log_action(logger.info)
146 def _scroll_to_top(self):169 def _scroll_to_top(self):
147 if not self.atYBeginning:170 if not self.atYBeginning:
148171
=== modified file 'tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_header.py'
--- tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_header.py 2014-05-02 18:55:43 +0000
+++ tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_header.py 2014-05-28 18:09:57 +0000
@@ -21,6 +21,7 @@
2121
22from ubuntuuitoolkit._custom_proxy_objects import (22from ubuntuuitoolkit._custom_proxy_objects import (
23 _common,23 _common,
24 _mainview,
24 _tabbar25 _tabbar
25)26)
2627
@@ -36,9 +37,31 @@
3637
37 def __init__(self, *args):38 def __init__(self, *args):
38 super(Header, self).__init__(*args)39 super(Header, self).__init__(*args)
39 self.pointing_device = _common.get_pointing_device()40 # XXX we need a better way to keep reference to the main view.
41 # --elopio - 2014-02-26
42 self.main_view = self.get_root_instance().select_single(
43 _mainview.MainView)
44
45 def _show_if_not_visible(self):
46 if not self._is_visible():
47 self._show()
48
49 def _is_visible(self):
50 return self.y == 0
51
52 def _show(self):
53 # FIXME This will fail if the header is not linked to a flickable that
54 # fills the main view. The header has a flickable property but it
55 # can't be read by autopilot. See bug http://pad.lv/1318829
56 start_x = stop_x = (self.globalRect.x + self.globalRect.width) // 2
57 start_y = self.main_view.globalRect.y + 5
58 stop_y = start_y + self.globalRect.height
59 self.pointing_device.drag(start_x, start_y, stop_x, stop_y)
60 self.y.wait_for(0)
4061
41 def click_back_button(self):62 def click_back_button(self):
63 self._show_if_not_visible()
64
42 if self.useDeprecatedToolbar:65 if self.useDeprecatedToolbar:
43 raise _common.ToolkitException('Old header has no back button')66 raise _common.ToolkitException('Old header has no back button')
44 try:67 try:
@@ -51,6 +74,8 @@
51 self.pointing_device.click_object(back_button)74 self.pointing_device.click_object(back_button)
5275
53 def click_custom_back_button(self):76 def click_custom_back_button(self):
77 self._show_if_not_visible()
78
54 if self.useDeprecatedToolbar:79 if self.useDeprecatedToolbar:
55 raise _common.ToolkitException(80 raise _common.ToolkitException(
56 'Old header has no custom back button')81 'Old header has no custom back button')
@@ -79,6 +104,8 @@
79 :raise ToolkitEmulatorException: If the main view has no tabs.104 :raise ToolkitEmulatorException: If the main view has no tabs.
80105
81 """106 """
107 self._show_if_not_visible()
108
82 if self.useDeprecatedToolbar:109 if self.useDeprecatedToolbar:
83 self._switch_to_next_tab_in_deprecated_tabbar()110 self._switch_to_next_tab_in_deprecated_tabbar()
84 else:111 else:
@@ -108,6 +135,8 @@
108 useDeprecatedToolbar is set.135 useDeprecatedToolbar is set.
109136
110 """137 """
138 self._show_if_not_visible()
139
111 if self.useDeprecatedToolbar:140 if self.useDeprecatedToolbar:
112 raise _common.ToolkitException(141 raise _common.ToolkitException(
113 "Header.swtich_to_tab_by_index only works with new header")142 "Header.swtich_to_tab_by_index only works with new header")
@@ -145,6 +174,8 @@
145 name.174 name.
146175
147 """176 """
177 self._show_if_not_visible()
178
148 button = self._get_action_button(action_object_name)179 button = self._get_action_button(action_object_name)
149 self.pointing_device.click_object(button)180 self.pointing_device.click_object(button)
150181
151182
=== modified file 'tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_mainview.py'
--- tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_mainview.py 2014-04-30 18:17:32 +0000
+++ tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_mainview.py 2014-05-28 18:09:57 +0000
@@ -169,7 +169,7 @@
169 :parameter object_name: The QML objectName property of the popover.169 :parameter object_name: The QML objectName property of the popover.
170170
171 """171 """
172 return self.select_single(172 return self.wait_select_single(
173 popups.ActionSelectionPopover, objectName=object_name)173 popups.ActionSelectionPopover, objectName=object_name)
174174
175 @autopilot_logging.log_action(logger.info)175 @autopilot_logging.log_action(logger.info)
176176
=== modified file 'tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_qquicklistview.py'
--- tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_qquicklistview.py 2014-04-16 21:13:39 +0000
+++ tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_qquicklistview.py 2014-05-28 18:09:57 +0000
@@ -19,22 +19,24 @@
19from autopilot import logging as autopilot_logging19from autopilot import logging as autopilot_logging
20from autopilot.introspection import dbus20from autopilot.introspection import dbus
2121
22from ubuntuuitoolkit._custom_proxy_objects import _flickable22from ubuntuuitoolkit._custom_proxy_objects import _common, _flickable
23from ubuntuuitoolkit._custom_proxy_objects import _common
24
2523
26logger = logging.getLogger(__name__)24logger = logging.getLogger(__name__)
2725
2826
29class QQuickListView(_flickable.Flickable):27class QQuickListView(_flickable.QQuickFlickable):
3028
31 @autopilot_logging.log_action(logger.info)29 @autopilot_logging.log_action(logger.info)
32 def click_element(self, object_name):30 def click_element(self, object_name, direction=None):
33 """Click an element from the list.31 """Click an element from the list.
3432
35 It swipes the element into view if it's center is not visible.33 It swipes the element into view if it's center is not visible.
3634
37 :parameter objectName: The objectName property of the element to click.35 :parameter objectName: The objectName property of the element to click.
36 :parameter direction: The direction where the element is, it can be
37 either 'above' or 'below'. Default value is None, which means we
38 don't know where the object is and we will need to search the full
39 list.
3840
39 """41 """
40 try:42 try:
@@ -42,16 +44,31 @@
42 except dbus.StateNotFoundError:44 except dbus.StateNotFoundError:
43 # The element might be on a part of the list that hasn't been45 # The element might be on a part of the list that hasn't been
44 # created yet. We have to search for it scrolling the entire list.46 # created yet. We have to search for it scrolling the entire list.
45 element = self._find_element(object_name)47 element = self._find_element(object_name, direction)
46 self.swipe_child_into_view(element)48 self.swipe_child_into_view(element)
47 self.pointing_device.click_object(element)49 self.pointing_device.click_object(element)
4850
49 @autopilot_logging.log_action(logger.info)51 @autopilot_logging.log_action(logger.info)
50 def _find_element(self, object_name):52 def _find_element(self, object_name, direction=None):
51 self._scroll_to_top()53 if direction is None:
52 while not self.atYEnd:54 # We don't know where the object is so we start looking for it from
53 containers = self._get_containers()55 # the top.
54 self._swipe_to_show_more_below(containers)56 self._scroll_to_top()
57 direction = 'below'
58
59 if direction == 'below':
60 fail_condition = lambda: self.atYEnd
61 swipe_method = self._swipe_to_show_more_below
62 elif direction == 'above':
63 fail_condition = lambda: self.atYBeginning
64 swipe_method = self._swipe_to_show_more_above
65 else:
66 raise _common.ToolkitException(
67 'Invalid direction: {}'.format(direction))
68
69 containers = self._get_containers()
70 while not fail_condition():
71 swipe_method(containers)
55 try:72 try:
56 return self.select_single(objectName=object_name)73 return self.select_single(objectName=object_name)
57 except dbus.StateNotFoundError:74 except dbus.StateNotFoundError:
5875
=== modified file 'tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_textfield.py'
--- tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_textfield.py 2014-04-16 21:13:39 +0000
+++ tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_textfield.py 2014-05-28 18:09:57 +0000
@@ -81,8 +81,13 @@
81 self.keyboard.press_and_release('BackSpace')81 self.keyboard.press_and_release('BackSpace')
8282
83 def _select_all(self):83 def _select_all(self):
84 self.pointing_device.click_object(self, press_duration=1)84 if not self._is_all_text_selected():
85 root = self.get_root_instance()85 self.pointing_device.click_object(self, press_duration=1)
86 main_view = root.select_single(_mainview.MainView)86 root = self.get_root_instance()
87 popover = main_view.get_action_selection_popover('text_input_popover')87 main_view = root.select_single(_mainview.MainView)
88 popover.click_button_by_text('Select All')88 popover = main_view.get_action_selection_popover(
89 'text_input_popover')
90 popover.click_button_by_text('Select All')
91
92 def _is_all_text_selected(self):
93 return self.text == self.selectedText
8994
=== added file 'tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/pickers.py'
--- tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/pickers.py 1970-01-01 00:00:00 +0000
+++ tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/pickers.py 2014-05-28 18:09:57 +0000
@@ -0,0 +1,255 @@
1# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2#
3# Copyright (C) 2014 Canonical Ltd.
4#
5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU Lesser General Public License as published by
7# the Free Software Foundation; version 3.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU Lesser General Public License for more details.
13#
14# You should have received a copy of the GNU Lesser General Public License
15# along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17import datetime
18import logging
19
20from autopilot import logging as autopilot_logging
21from autopilot.introspection import dbus
22
23from ubuntuuitoolkit._custom_proxy_objects import (
24 _common,
25 _flickable,
26 _qquicklistview
27)
28
29
30logger = logging.getLogger(__name__)
31
32
33class DatePicker(_common.UbuntuUIToolkitCustomProxyObjectBase):
34 """Autopilot helper for the DatePicker component."""
35
36 @autopilot_logging.log_action(logger.info)
37 def pick_date(self, date):
38 """Pick a date from the date picker.
39
40 :parameter date: The date to pick.
41 :type date: An object with year, month and day attributes, like
42 python's datetime.date.
43 :raises ubuntuuitoolkit.ToolkitException if the mode of the picker
44 doesn't let select a date.
45
46 """
47 if not self._is_date_picker():
48 raise _common.ToolkitException(
49 "Can't pick date. The picker mode is: {!r}.".format(self.mode))
50 if 'Years' in self.mode:
51 self._pick_year(date.year)
52 self.year.wait_for(date.year)
53 if 'Month' in self.mode:
54 # Python's date object starts at one. The model in the date picker
55 # at 0.
56 self._pick_month(date.month - 1)
57 self.month.wait_for(date.month - 1)
58 if 'Day' in self.mode:
59 self._pick_day(date.day)
60 self.day.wait_for(date.day)
61
62 def _is_date_picker(self):
63 mode = self.mode
64 if 'Years' in mode or 'Months' in mode or 'Days' in mode:
65 return True
66 else:
67 return False
68
69 @autopilot_logging.log_action(logger.info)
70 def _pick_year(self, year):
71 picker = self.select_single(
72 'Picker', objectName='PickerRow_YearPicker')
73 list_view = picker.select_single(
74 _qquicklistview.QQuickListView, objectName='Picker_Linear')
75 self._pick_value(self.year, year, list_view)
76
77 @autopilot_logging.log_action(logger.info)
78 def _pick_month(self, month):
79 self._pick_value_from_path_view('Month', self.month, month)
80
81 @autopilot_logging.log_action(logger.info)
82 def _pick_day(self, day):
83 # Python's date object starts at one. The model in the date picker
84 # at 0.
85 self._pick_value_from_path_view('Day', self.day - 1, day - 1)
86
87 def _pick_value_from_path_view(self, type_, current_value, new_value):
88 picker = self.select_single(
89 'Picker', objectName='PickerRow_{}Picker'.format(type_))
90 path_view = picker.select_single(
91 QQuickPathView, objectName='Picker_WrapAround')
92 self._pick_value(current_value, new_value, path_view)
93
94 def _pick_value(self, current_value, new_value, scrollable):
95 if new_value > current_value:
96 direction = 'below'
97 elif new_value < current_value:
98 direction = 'above'
99 else:
100 logger.debug('The value is already selected.')
101 return
102 scrollable.click_element(
103 object_name='PickerRow_PickerLabel{}'.format(new_value),
104 direction=direction)
105
106 def get_date(self):
107 """Return the currently selected date.
108
109 :return: a python datetime.date object with the selected date.
110
111 """
112 # Python's date object starts at one. The model in the date picker
113 # at 0.
114 return datetime.date(self.year, self.month + 1, self.day)
115
116 @autopilot_logging.log_action(logger.info)
117 def pick_time(self, time):
118 """Pick a time from the date picker.
119
120 :parameter time: The time to pick.
121 :type time: An object with hour, minute and second attributes, like
122 python's datetime.time.
123 :raises ubuntuuitoolkit.ToolkitException if the mode of the picker
124 doesn't let select a time.
125
126 """
127 if not self._is_time_picker():
128 raise _common.ToolkitException(
129 "Can't pick time. The picker mode is: {!r}.".format(self.mode))
130 if 'Hours' in self.mode:
131 self._pick_hour(time.hour)
132 self.hours.wait_for(time.hour)
133 if 'Minutes' in self.mode:
134 self._pick_minute(time.minute)
135 self.minutes.wait_for(time.minute)
136 if 'Seconds' in self.mode:
137 self._pick_second(time.second)
138 self.seconds.wait_for(time.second)
139
140 def _is_time_picker(self):
141 mode = self.mode
142 if 'Hours' in mode or 'Minutes' in mode or 'Seconds' in mode:
143 return True
144 else:
145 return False
146
147 @autopilot_logging.log_action(logger.info)
148 def _pick_hour(self, hour):
149 self._pick_value_from_path_view('Hours', self.hours, hour)
150
151 @autopilot_logging.log_action(logger.info)
152 def _pick_minute(self, minute):
153 self._pick_value_from_path_view('Minutes', self.minutes, minute)
154
155 @autopilot_logging.log_action(logger.info)
156 def _pick_second(self, second):
157 self._pick_value_from_path_view('Seconds', self.seconds, second)
158
159 def get_time(self):
160 """Return the currently selected time.
161
162 :return: a python datetime.time object with the selected time.
163
164 """
165 return datetime.time(self.hours, self.minutes, self.seconds)
166
167
168class QQuickPathView(_flickable.Scrollable):
169
170 # TODO make it more general and move it to its own module.
171 # --elopio - 2014-05-06
172
173 @autopilot_logging.log_action(logger.info)
174 def click_element(self, object_name, direction='below'):
175 try:
176 element = self.select_single(objectName=object_name)
177 except dbus.StateNotFoundError:
178 # The element might be on a part of the list that hasn't been
179 # created yet. We have to search for it scrolling.
180 element = self._find_element(object_name, direction)
181 self.swipe_child_into_view(element)
182 self.pointing_device.click_object(element)
183
184 @autopilot_logging.log_action(logger.info)
185 def _find_element(self, object_name, direction):
186 containers = self._get_containers()
187 for index in range(self.count):
188 if direction == 'below':
189 swipe_method = self._swipe_to_show_one_more_below
190 elif direction == 'above':
191 swipe_method = self._swipe_to_show_one_more_above
192 else:
193 raise _common.ToolkitException(
194 'Invalid direction: {}'.format(direction))
195
196 swipe_method(containers)
197
198 try:
199 return self.select_single(objectName=object_name)
200 except dbus.StateNotFoundError:
201 pass
202 raise _common.ToolkitException(
203 'List element with objectName "{}" not found.'.format(object_name))
204
205 @autopilot_logging.log_action(logger.info)
206 def _swipe_to_show_one_more_above(self, containers):
207 self._swipe_to_show_one_more('above', containers)
208
209 @autopilot_logging.log_action(logger.info)
210 def _swipe_to_show_one_more_below(self, containers):
211 self._swipe_to_show_one_more('below', containers)
212
213 def _swipe_to_show_one_more(self, direction, containers):
214 start_x = stop_x = self.globalRect.x + (self.globalRect.width // 2)
215 center_y = self.globalRect.y + (self.globalRect.height // 2)
216 # XXX This assumes all the children are of the same height
217 child = self.get_children_by_type('PickerDelegate')[0]
218 top = center_y - (child.globalRect.height // 2)
219 bottom = center_y + (child.globalRect.height // 2)
220 if direction == 'below':
221 start_y = bottom
222 stop_y = top
223 elif direction == 'above':
224 start_y = top
225 stop_y = bottom
226 else:
227 raise _common.ToolkitException(
228 'Invalid direction {}.'.format(direction))
229 self._slow_drag(start_x, stop_x, start_y, stop_y)
230 self.dragging.wait_for(False)
231 self.moving.wait_for(False)
232
233 @autopilot_logging.log_action(logger.info)
234 def swipe_child_into_view(self, child):
235 """Make the child visible.
236
237 Currently it works only when the object needs to be swiped vertically.
238 TODO implement horizontal swiping. --elopio - 2014-03-21
239
240 """
241 containers = self._get_containers()
242 if not self._is_child_visible(child, containers):
243 self._swipe_non_visible_child_into_view(child, containers)
244 else:
245 logger.debug('The element is already visible.')
246
247 @autopilot_logging.log_action(logger.info)
248 def _swipe_non_visible_child_into_view(self, child, containers):
249 while not self._is_child_visible(child, containers):
250 # Check the direction of the swipe based on the position of the
251 # child relative to the immediate flickable container.
252 if child.globalRect.y < self.globalRect.y:
253 self._swipe_to_show_one_more_above(containers)
254 else:
255 self._swipe_to_show_one_more_below(containers)
0256
=== modified file 'tests/autopilot/ubuntuuitoolkit/emulators.py'
--- tests/autopilot/ubuntuuitoolkit/emulators.py 2014-04-25 18:39:51 +0000
+++ tests/autopilot/ubuntuuitoolkit/emulators.py 2014-05-28 18:09:57 +0000
@@ -36,12 +36,12 @@
36 'CheckBox',36 'CheckBox',
37 'ComposerSheet',37 'ComposerSheet',
38 'Empty',38 'Empty',
39 'Flickable',
40 'Header',39 'Header',
41 'ItemSelector',40 'ItemSelector',
42 'MainView',41 'MainView',
43 'MultiValue',42 'MultiValue',
44 'OptionSelector',43 'OptionSelector',
44 'QQuickFlickable',
45 'QQuickListView',45 'QQuickListView',
46 'SingleControl',46 'SingleControl',
47 'SingleValue',47 'SingleValue',
@@ -61,10 +61,10 @@
61 get_keyboard,61 get_keyboard,
62 get_pointing_device,62 get_pointing_device,
63 CheckBox,63 CheckBox,
64 Flickable,
65 Header,64 Header,
66 MainView,65 MainView,
67 OptionSelector,66 OptionSelector,
67 QQuickFlickable,
68 QQuickListView,68 QQuickListView,
69 TabBar,69 TabBar,
70 Tabs,70 Tabs,
7171
=== added file 'tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_date_picker.py'
--- tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_date_picker.py 1970-01-01 00:00:00 +0000
+++ tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_date_picker.py 2014-05-28 18:09:57 +0000
@@ -0,0 +1,203 @@
1# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2#
3# Copyright (C) 2014 Canonical Ltd.
4#
5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU Lesser General Public License as published by
7# the Free Software Foundation; version 3.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU Lesser General Public License for more details.
13#
14# You should have received a copy of the GNU Lesser General Public License
15# along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17import datetime
18
19import ubuntuuitoolkit
20from ubuntuuitoolkit import pickers, tests
21
22
23class DatePickerBaseTestCase(tests.QMLStringAppTestCase):
24
25 test_qml = ("""
26import QtQuick 2.0
27import Ubuntu.Components 1.1
28import Ubuntu.Components.Pickers 1.0
29
30MainView {
31 width: units.gu(48)
32 height: units.gu(60)
33
34 Column {
35 DatePicker {
36 id: datePicker
37 objectName: 'datePicker'
38 mode: 'Years|Months|Days'
39 date: {
40 var d = new Date()
41 // Make sure that the picker will have higher and lower values
42 // to select.
43 d.setFullYear(d.getFullYear() + 25)
44 d.setMonth('5')
45 d.setDate('15')
46 return d
47 }
48 }
49 DatePicker {
50 id: timePicker
51 objectName: 'timePicker'
52 mode: 'Hours|Minutes|Seconds'
53 date: {
54 var d = new Date()
55 // Make sure that the picker will have higher and lower values
56 // to select.
57 d.setHours(12)
58 d.setMinutes('30')
59 d.setSeconds('30')
60 return d
61 }
62 }
63 }
64}
65""")
66
67 def setUp(self):
68 super(DatePickerBaseTestCase, self).setUp()
69 self.date_picker = self.main_view.select_single(
70 pickers.DatePicker, objectName='datePicker')
71 self.time_picker = self.main_view.select_single(
72 pickers.DatePicker, objectName='timePicker')
73
74
75class DatePickerTestCase(DatePickerBaseTestCase):
76
77 def test_select_date_picker_must_return_custom_proxy_object(self):
78 self.assertIsInstance(
79 self.date_picker, pickers.DatePicker)
80
81 def test_pick_date_on_time_picker_must_raise_exception(self):
82 error = self.assertRaises(
83 ubuntuuitoolkit.ToolkitException, self.time_picker.pick_date,
84 'dummy')
85 self.assertEqual(
86 str(error),
87 "Can't pick date. The picker mode is: {!r}.".format(
88 self.time_picker.mode))
89
90 def test_pick_time_on_date_picker_must_raise_exception(self):
91 error = self.assertRaises(
92 ubuntuuitoolkit.ToolkitException, self.date_picker.pick_time,
93 'dummy')
94 self.assertEqual(
95 str(error),
96 "Can't pick time. The picker mode is: {!r}.".format(
97 self.date_picker.mode))
98
99 def test_swipe_to_show_one_more_below_must_select_next_index(self):
100 """Test that we don't end up swiping more than needed.
101
102 This would cause us to miss the element we are looking for, and to have
103 to swipe many times in order to finally click it.
104
105 """
106 picker = self.main_view.select_single(
107 'Picker', objectName='PickerRow_DayPicker')
108 path_view = picker.select_single(
109 pickers.QQuickPathView, objectName='Picker_WrapAround')
110 current_index = path_view.currentIndex
111
112 path_view._swipe_to_show_one_more_below(path_view._get_containers())
113
114 self.assertEqual(path_view.currentIndex, current_index + 1)
115
116 def test_swipe_to_show_one_more_above_must_select_previous_index(self):
117 """Test that we don't end up swiping more than needed.
118
119 This would cause us to miss the element we are looking for, and to have
120 to swipe many times in order to finally click it.
121
122 """
123 picker = self.main_view.select_single(
124 'Picker', objectName='PickerRow_DayPicker')
125 path_view = picker.select_single(
126 pickers.QQuickPathView, objectName='Picker_WrapAround')
127 current_index = path_view.currentIndex
128
129 path_view._swipe_to_show_one_more_above(path_view._get_containers())
130
131 self.assertEqual(path_view.currentIndex, current_index - 1)
132
133
134class PickDateFromDatePickerTestCase(DatePickerBaseTestCase):
135
136 SELECTED_YEAR = datetime.date.today().year + 25
137 SELECTED_MONTH = 6 # June
138 SELECTED_DAY = 15
139
140 scenarios = [
141 ('higher year', {
142 'date_to_pick': datetime.date(
143 SELECTED_YEAR + 10, SELECTED_MONTH, SELECTED_DAY)}),
144 ('lower year', {
145 'date_to_pick': datetime.date(
146 SELECTED_YEAR - 10, SELECTED_MONTH, SELECTED_DAY)}),
147 ('higher month', {
148 'date_to_pick': datetime.date(
149 SELECTED_YEAR, SELECTED_MONTH + 4, SELECTED_DAY)}),
150 ('lower month', {
151 'date_to_pick': datetime.date(
152 SELECTED_YEAR, SELECTED_MONTH - 4, SELECTED_DAY)}),
153 ('higher day', {
154 'date_to_pick': datetime.date(
155 SELECTED_YEAR, SELECTED_MONTH, SELECTED_DAY + 10)}),
156 ('lower day', {
157 'date_to_pick': datetime.date(
158 SELECTED_YEAR, SELECTED_MONTH, SELECTED_DAY - 10)}),
159 ('change all values', {
160 'date_to_pick': datetime.date(
161 SELECTED_YEAR - 10, SELECTED_MONTH + 4, SELECTED_DAY - 10)}),
162 ]
163
164 def test_pick_date(self):
165 """Test that picking a date updates the picker."""
166 self.date_picker.pick_date(self.date_to_pick)
167 self.assertEqual(self.date_picker.get_date(), self.date_to_pick)
168
169
170class PickTimeFromDatePickerTestCase(DatePickerBaseTestCase):
171
172 SELECTED_HOUR = 12
173 SELECTED_MINUTE = 30
174 SELECTED_SECOND = 30
175
176 scenarios = [
177 ('higher hour', {
178 'time_to_pick': datetime.time(
179 SELECTED_HOUR + 6, SELECTED_MINUTE, SELECTED_SECOND)}),
180 ('lower hour', {
181 'time_to_pick': datetime.time(
182 SELECTED_HOUR - 6, SELECTED_MINUTE, SELECTED_SECOND)}),
183 ('higher minute', {
184 'time_to_pick': datetime.time(
185 SELECTED_HOUR, SELECTED_MINUTE + 10, SELECTED_SECOND)}),
186 ('lower minute', {
187 'time_to_pick': datetime.time(
188 SELECTED_HOUR, SELECTED_MINUTE - 10, SELECTED_SECOND)}),
189 ('higher second', {
190 'time_to_pick': datetime.time(
191 SELECTED_HOUR, SELECTED_MINUTE, SELECTED_SECOND + 10)}),
192 ('lower second', {
193 'time_to_pick': datetime.time(
194 SELECTED_HOUR, SELECTED_MINUTE, SELECTED_SECOND - 10)}),
195 ('change all values', {
196 'time_to_pick': datetime.time(
197 SELECTED_HOUR + 6, SELECTED_MINUTE - 10,
198 SELECTED_SECOND + 10)}),
199 ]
200
201 def test_pick_time(self):
202 self.time_picker.pick_time(self.time_to_pick)
203 self.assertEqual(self.time_picker.get_time(), self.time_to_pick)
0204
=== added file 'tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_flickable.py'
--- tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_flickable.py 1970-01-01 00:00:00 +0000
+++ tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_flickable.py 2014-05-28 18:09:57 +0000
@@ -0,0 +1,201 @@
1# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2#
3# Copyright (C) 2014 Canonical Ltd.
4#
5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU Lesser General Public License as published by
7# the Free Software Foundation; version 3.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU Lesser General Public License for more details.
13#
14# You should have received a copy of the GNU Lesser General Public License
15# along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17
18import testtools
19
20import ubuntuuitoolkit
21from ubuntuuitoolkit import tests
22from ubuntuuitoolkit._custom_proxy_objects import _common
23
24
25class FlickableTestCase(testtools.TestCase):
26
27 def test_get_unity_top_container(self):
28 """Test that we can get the top cointainer in Unity."""
29 # This tests bug http://pad.lv/1314390
30 # On Unity, the top container is not the first child as it is in all
31 # the apps that have a MainView. This makes the first implementation of
32 # _get_top_container fail. Instead of going from the top looking for
33 # a container, we should start from the flickable until we find the
34 # top-most container.
35 # FIXME we are faking the QML tree because we have no way to launch
36 # the app with a tree like the one in Unity8. kalikiana has a branch
37 # with an alternate launcher that will let us clean this test.
38 # --elopio - 2014-05-15.
39 RootClass = type('obj', (object,), {'id': 'root'})
40 mock_root_instance = RootClass()
41 # We consider a container is an object with a globalRect.
42 MockNonContainerClass = type('obj', (object,), {})
43 mock_non_container = MockNonContainerClass()
44 MockContainerClass = type(
45 'obj', (object,), {'id': 'container', 'globalRect': 'dummy'})
46 mock_container = MockContainerClass()
47 mock_container.get_parent = lambda: mock_root_instance
48
49 # The root instance has two children. This exposes the bug.
50 mock_root_instance.get_children = lambda: [
51 mock_non_container, mock_container]
52
53 dummy_state = {'id': '10'}
54 flickable = ubuntuuitoolkit.QQuickFlickable(
55 dummy_state, '/dummy'.encode(), 'dummy')
56
57 flickable.get_root_instance = lambda: mock_root_instance
58 # The top container of the flickable is its immediate parent.
59 flickable.get_parent = lambda: mock_container
60
61 top_container = flickable._get_top_container()
62 self.assertEqual(top_container, mock_container)
63
64 def test_is_flickable_with_flicking_property_must_return_true(self):
65 """is_flickable returns True if flickable property exists."""
66 dummy_id = (0, 0)
67 dummy_flicking = (0, 'dummy')
68 state_with_flicking = {'id': dummy_id, 'flicking': dummy_flicking}
69 element = _common.UbuntuUIToolkitCustomProxyObjectBase(
70 state_with_flicking, '/dummy'.encode(), 'dummy')
71 with element.no_automatic_refreshing():
72 self.assertTrue(element.is_flickable())
73
74 def test_is_flickable_without_flicking_property_must_return_false(self):
75 """is_flickable returns False if flickable property doesn't exist."""
76 dummy_id = (0, 0)
77 state_without_flicking = {'id': dummy_id}
78 element = _common.UbuntuUIToolkitCustomProxyObjectBase(
79 state_without_flicking, '/dummy'.encode(), 'dummy')
80 with element.no_automatic_refreshing():
81 self.assertFalse(element.is_flickable())
82
83
84class IsFlickableTestCase(tests.QMLStringAppTestCase):
85 """Functional test to check that is_flickable returns the right value.
86
87 We already have tests for is_flickable with mocks, so here we just check
88 with some real elements.
89
90 """
91
92 test_qml = ("""
93import QtQuick 2.0
94import Ubuntu.Components 0.1
95import Ubuntu.Components.ListItems 0.1 as ListItem
96
97MainView {
98 objectName: 'mainView'
99 width: units.gu(48)
100 height: units.gu(60)
101
102 Flickable {
103 objectName: 'flickable'
104 }
105 ListView {
106 objectName: 'listView'
107 }
108 Label {
109 objectName: 'label'
110 }
111}
112""")
113
114 scenarios = [
115 ('main view', dict(object_name='mainView', is_flickable=False)),
116 ('flickable', dict(object_name='flickable', is_flickable=True)),
117 ('list view', dict(object_name='listView', is_flickable=True)),
118 ('label', dict(object_name='label', is_flickable=False))
119 ]
120
121 def test_is_flickable(self):
122 """Test that is_flickable identifies the elements correctly."""
123 element = self.app.select_single(objectName=self.object_name)
124 self.assertEqual(element.is_flickable(), self.is_flickable)
125
126
127class SwipeIntoViewTestCase(tests.QMLStringAppTestCase):
128
129 test_qml = ("""
130import QtQuick 2.0
131import Ubuntu.Components 0.1
132
133MainView {
134 width: units.gu(48)
135 height: units.gu(60)
136
137 Label {
138 id: clickedLabel
139 objectName: "clickedLabel"
140 text: "No element clicked."
141 }
142
143 Flickable {
144 anchors {
145 fill: parent
146 topMargin: clickedLabel.height
147 // It can't be at the bottom, or the toolbar will be opened
148 // when we try to click it.
149 bottomMargin: units.gu(10)
150 }
151 objectName: 'flickable'
152 height: units.gu(60)
153 contentHeight: bottomButton.y + bottomButton.height
154
155 Button {
156 id: topButton
157 objectName: 'topButton'
158 text: 'Top button'
159 onClicked: clickedLabel.text = objectName
160 }
161 Rectangle {
162 id: emptyRectangle
163 height: units.gu(80)
164 anchors.top: topButton.bottom
165 }
166 Button {
167 id: bottomButton
168 objectName: 'bottomButton'
169 text: 'Bottom button'
170 onClicked: clickedLabel.text = objectName
171 anchors.top: emptyRectangle.bottom
172 }
173 }
174}
175""")
176
177 def setUp(self):
178 super(SwipeIntoViewTestCase, self).setUp()
179 self.label = self.main_view.select_single(
180 'Label', objectName='clickedLabel')
181 self.assertEqual(self.label.text, 'No element clicked.')
182
183 def test_swipe_to_bottom(self):
184 self.main_view.close_toolbar()
185
186 button = self.main_view.select_single(objectName='bottomButton')
187 button.swipe_into_view()
188
189 self.pointing_device.click_object(button)
190 self.assertEqual(self.label.text, 'bottomButton')
191
192 def test_swipe_to_top(self):
193 self.main_view.close_toolbar()
194 bottomButton = self.main_view.select_single(objectName='bottomButton')
195 bottomButton.swipe_into_view()
196
197 topButton = self.main_view.select_single(objectName='topButton')
198 topButton.swipe_into_view()
199
200 self.pointing_device.click_object(topButton)
201 self.assertEqual(self.label.text, 'topButton')
0202
=== modified file 'tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_header.py'
--- tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_header.py 2014-05-10 21:52:19 +0000
+++ tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_header.py 2014-05-28 18:09:57 +0000
@@ -22,7 +22,7 @@
2222
23 test_qml = ("""23 test_qml = ("""
24import QtQuick 2.024import QtQuick 2.0
25import Ubuntu.Components 0.125import Ubuntu.Components 1.1
2626
27MainView {27MainView {
28 width: units.gu(48)28 width: units.gu(48)
@@ -33,11 +33,46 @@
33 Page {33 Page {
34 title: "Test title"34 title: "Test title"
3535
36 Label {36 Flickable {
37 id: label37 anchors.fill: parent
38 objectName: "clicked_label"38 contentHeight: units.gu(120)
39 anchors.centerIn: parent39 objectName: "header_test_flickable"
40 text: "No button clicked."40
41 Label {
42 id: label
43 objectName: "clicked_label"
44 anchors {
45 top: parent.top
46 horizontalCenter: parent.horizontalCenter
47 }
48 text: "No button clicked."
49 }
50
51 Button {
52 objectName: "hide_actions_button"
53 anchors {
54 top: label.bottom
55 topMargin: units.gu(5)
56 horizontalCenter: parent.horizontalCenter
57 }
58 text: "Hide some actions"
59 onClicked: {
60 cancelAction.visible = false;
61 for (var i=0; i < 3; i++) {
62 buttonRepeater.itemAt(i).action.visible = false;
63 }
64 // only three of five visible actions left
65 }
66 }
67 Label {
68 id: endLabel
69 objectName: "end_label"
70 anchors {
71 bottom: parent.bottom
72 horizontalCenter: parent.horizontalCenter
73 }
74 text: "The end."
75 }
41 }76 }
4277
43 tools: ToolbarItems {78 tools: ToolbarItems {
@@ -62,22 +97,6 @@
62 }97 }
63 }98 }
64 }99 }
65
66 Button {
67 objectName: "hide_actions_button"
68 anchors {
69 bottom: parent.bottom
70 horizontalCenter: parent.horizontalCenter
71 }
72 text: "Hide some actions"
73 onClicked: {
74 cancelAction.visible = false;
75 for (var i=0; i < 3; i++) {
76 buttonRepeater.itemAt(i).action.visible = false;
77 }
78 // only three of five visible actions left
79 }
80 }
81 }100 }
82}101}
83""")102""")
@@ -95,8 +114,8 @@
95 self.assertEqual(self.header.title, "Test title")114 self.assertEqual(self.header.title, "Test title")
96115
97 def test_click_header_action_button(self):116 def test_click_header_action_button(self):
98 self.header.click_action_button('action1')117 self.header.click_action_button('action0')
99 self.assertEqual(self.label.text, 'Button 1 clicked.')118 self.assertEqual(self.label.text, 'Button 0 clicked.')
100119
101 def test_click_header_overflow_action_button(self):120 def test_click_header_overflow_action_button(self):
102 # custom back button and first action button go in the header121 # custom back button and first action button go in the header
@@ -117,6 +136,13 @@
117 self.header.click_custom_back_button()136 self.header.click_custom_back_button()
118 self.assertEqual(self.label.text, 'Cancel button clicked.')137 self.assertEqual(self.label.text, 'Cancel button clicked.')
119138
139 def test_click_header_action_button_with_hidden_header(self):
140 bottom_label = self.main_view.select_single(objectName='end_label')
141 bottom_label.swipe_into_view()
142 self.assertFalse(self.header._is_visible())
143 self.header.click_action_button('action0')
144 self.assertEqual(self.label.text, 'Button 0 clicked.')
145
120 def test_overflow_button(self):146 def test_overflow_button(self):
121 # there are 5 actions plus a custom back action147 # there are 5 actions plus a custom back action
122 overflow_button = self.header.select_single(148 overflow_button = self.header.select_single(
123149
=== modified file 'tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_textfield.py'
--- tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_textfield.py 2014-04-17 01:06:31 +0000
+++ tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_textfield.py 2014-05-28 18:09:57 +0000
@@ -14,6 +14,13 @@
14# You should have received a copy of the GNU Lesser General Public License14# You should have received a copy of the GNU Lesser General Public License
15# along with this program. If not, see <http://www.gnu.org/licenses/>.15# along with this program. If not, see <http://www.gnu.org/licenses/>.
1616
17try:
18 from unittest import mock
19except ImportError:
20 import mock
21
22from autopilot import platform
23
17import ubuntuuitoolkit24import ubuntuuitoolkit
18from ubuntuuitoolkit import tests25from ubuntuuitoolkit import tests
1926
@@ -91,3 +98,23 @@
91 self.assertTrue(self.simple_text_field.is_empty())98 self.assertTrue(self.simple_text_field.is_empty())
92 self.simple_text_field.write('test')99 self.simple_text_field.write('test')
93 self.assertFalse(self.simple_text_field.is_empty())100 self.assertFalse(self.simple_text_field.is_empty())
101
102 def test_select_all_selects_all_text(self):
103 if platform.model() != 'Desktop':
104 self.skipTest('Select all is not yet implemented on the phone.')
105 self.simple_text_field.write('Text to select.')
106 self.simple_text_field._select_all()
107
108 self.assertTrue(self.simple_text_field._is_all_text_selected())
109
110 def test_select_all_when_already_selected_must_do_nothing(self):
111 """Test for select all the text when it's already selected."""
112 if platform.model() != 'Desktop':
113 self.skipTest('Select all is not yet implemented on the phone.')
114 self.simple_text_field.write('Text to select.')
115 self.simple_text_field._select_all()
116 with mock.patch.object(
117 self.simple_text_field, 'pointing_device') as mock_device:
118 self.simple_text_field._select_all()
119
120 self.assertFalse(mock_device.called)
94121
=== modified file 'tests/autopilot/ubuntuuitoolkit/tests/gallery/test_gallery.py'
--- tests/autopilot/ubuntuuitoolkit/tests/gallery/test_gallery.py 2014-01-13 15:31:14 +0000
+++ tests/autopilot/ubuntuuitoolkit/tests/gallery/test_gallery.py 2014-05-28 18:09:57 +0000
@@ -75,6 +75,10 @@
75 # TODO: check for properties75 # TODO: check for properties
7676
77 def test_ubuntushape(self):77 def test_ubuntushape(self):
78 # Flaky test case
79 # FIXME: https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1308979
80 return
81
78 item = "Ubuntu Shape"82 item = "Ubuntu Shape"
79 self.loadItem(item)83 self.loadItem(item)
80 self.checkPageHeader(item)84 self.checkPageHeader(item)
8185
=== modified file 'tests/autopilot/ubuntuuitoolkit/tests/gallery/test_optionselector.py'
--- tests/autopilot/ubuntuuitoolkit/tests/gallery/test_optionselector.py 2013-11-08 09:19:02 +0000
+++ tests/autopilot/ubuntuuitoolkit/tests/gallery/test_optionselector.py 2014-05-28 18:09:57 +0000
@@ -1,6 +1,6 @@
1# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-1# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2#2#
3# Copyright (C) 2012, 2013 Canonical Ltd.3# Copyright (C) 2012, 2013, 2014 Canonical Ltd.
4#4#
5# This program is free software; you can redistribute it and/or modify5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU Lesser General Public License as published by6# it under the terms of the GNU Lesser General Public License as published by
@@ -14,85 +14,52 @@
14# You should have received a copy of the GNU Lesser General Public License14# You should have received a copy of the GNU Lesser General Public License
15# along with this program. If not, see <http://www.gnu.org/licenses/>.15# along with this program. If not, see <http://www.gnu.org/licenses/>.
1616
17"""Tests for the Ubuntu UI Toolkit Gallery - OptionSelector component"""17"""Tests for the Ubuntu UI Toolkit Gallery - OptionSelector component."""
18import time18
19from autopilot.matchers import Eventually19import ubuntuuitoolkit
20from testtools.matchers import Equals
21from ubuntuuitoolkit.tests import FlickDirection
22from ubuntuuitoolkit.tests.gallery import GalleryTestCase20from ubuntuuitoolkit.tests.gallery import GalleryTestCase
2321
2422
25class OptionSelectorTests(GalleryTestCase):23class OptionSelectorTestCase(GalleryTestCase):
26 """Generic tests for the Gallery"""24
2725 def setUp(self):
28 def test_optionselector_collapsed(self):26 super(OptionSelectorTestCase, self).setUp()
29 item = "Option Selector"27 item = "Option Selector"
30 self.loadItem(item)28 self.loadItem(item)
31 self.checkPageHeader(item)29 self.checkPageHeader(item)
32 collapsed = self.getObject("optionselector_collapsed")30
33 styleditem = collapsed.select_single('StyledItem',31 def test_select_option_from_collapsed_optionselector(self):
34 objectName='listContainer')32 collapsed_option_selector = self.main_view.select_single(
3533 ubuntuuitoolkit.OptionSelector,
36 self.assertThat(collapsed.selectedIndex, Equals(0))34 objectName='optionselector_collapsed')
37 self.pointing_device.click_object(collapsed)35
38 self.assertThat(styleditem.currentlyExpanded, Eventually(Equals(True)))36 self.assertEqual(
39 #try to search the following list entry few times37 collapsed_option_selector.get_selected_text(), 'Value 1')
40 #as it may not be available immediately.38
41 for t in range(0, 9):39 collapsed_option_selector.select_option('Label', text='Value 4')
42 try:40 self.assertEqual(collapsed_option_selector.get_selected_index(), 3)
43 selectedValue = collapsed.select_single('Label',41
44 text='Value 4')42 def test_select_option_from_expanded_optionselector(self):
45 self.assertIsNotNone(selectedValue)43 expanded_option_selector = self.main_view.select_single(
46 except:44 ubuntuuitoolkit.OptionSelector,
47 time.sleep(1)45 objectName='optionselector_expanded')
4846
49 self.pointing_device.click_object(selectedValue)47 self.assertEqual(
50 self.assertThat(collapsed.selectedIndex, Eventually(Equals(3)))48 expanded_option_selector.get_selected_text(), 'Value 1')
51 self.assertThat(styleditem.currentlyExpanded,49
52 Eventually(Equals(False)))50 expanded_option_selector.select_option('Label', text='Value 4')
5351 self.assertEqual(expanded_option_selector.get_selected_index(), 3)
54 def test_optionselector_expanded(self):52
55 item = "Option Selector"53 def test_select_option_from_optionselector_with_custom_model(self):
56 self.loadItem(item)54 option_selector_with_custom_model = self.main_view.select_single(
57 self.checkPageHeader(item)55 ubuntuuitoolkit.OptionSelector,
58 expanded = self.getObject("optionselector_expanded")56 objectName='optionselector_custommodel')
5957 option_selector_with_custom_model.swipe_into_view()
60 self.assertThat(expanded.selectedIndex, Equals(0))58
61 selectedValue = expanded.select_single('Label', text='Value 4')59 self.assertEqual(
62 self.assertIsNotNone(selectedValue)60 option_selector_with_custom_model.get_selected_index(), 0)
63 self.pointing_device.click_object(selectedValue)61
64 self.assertThat(expanded.selectedIndex, Eventually(Equals(3)))62 option_selector_with_custom_model.select_option(
6563 'Label', text='Name 4')
66 selectedValue = expanded.select_single('Label', text='Value 1')64 self.assertEqual(
67 self.assertIsNotNone(selectedValue)65 option_selector_with_custom_model.get_selected_index(), 3)
68 self.pointing_device.click_object(selectedValue)
69 self.assertThat(expanded.selectedIndex, Eventually(Equals(0)))
70
71 def test_optionselector_custommodel(self):
72 item = "Option Selector"
73 self.loadItem(item)
74 self.checkPageHeader(item)
75
76 custommodel = self.getObject("optionselector_custommodel")
77 flickable = self.main_view.select_single('QQuickFlickable')
78 self.assertIsNotNone(flickable)
79
80 #Flick upward to reveal the hidden ui element.
81 self.reveal_item_by_flick(custommodel, flickable, FlickDirection.UP)
82 self.assertThat(flickable.flicking, Eventually(Equals(False)))
83
84 self.assertThat(custommodel.selectedIndex, Equals(0))
85 selectedValue = custommodel.select_single('Label', text='Name 4')
86 self.assertIsNotNone(selectedValue)
87 self.pointing_device.click_object(selectedValue)
88 self.assertThat(custommodel.selectedIndex, Eventually(Equals(3)))
89
90 selectedValue = custommodel.select_single('Label', text='Name 1')
91 self.assertIsNotNone(selectedValue)
92 self.pointing_device.click_object(selectedValue)
93 self.assertThat(custommodel.selectedIndex, Eventually(Equals(0)))
94
95 #scroll the page downward now.
96 collapsed = self.getObject("optionselector_collapsed")
97 self.reveal_item_by_flick(collapsed, flickable, FlickDirection.DOWN)
98 self.assertThat(flickable.flicking, Eventually(Equals(False)))
9966
=== modified file 'tests/autopilot/ubuntuuitoolkit/tests/test_emulators.py'
--- tests/autopilot/ubuntuuitoolkit/tests/test_emulators.py 2014-04-28 15:39:24 +0000
+++ tests/autopilot/ubuntuuitoolkit/tests/test_emulators.py 2014-05-28 18:09:57 +0000
@@ -32,7 +32,7 @@
3232
33 symbols_retaining_name = [33 symbols_retaining_name = [
34 'check_autopilot_version', 'get_keyboard', 'get_pointing_device',34 'check_autopilot_version', 'get_keyboard', 'get_pointing_device',
35 'CheckBox', 'Flickable', 'Header', 'MainView', 'OptionSelector',35 'CheckBox', 'Header', 'MainView', 'OptionSelector', 'QQuickFlickable',
36 'QQuickListView', 'TabBar', 'Tabs', 'TextField', 'Toolbar',36 'QQuickListView', 'TabBar', 'Tabs', 'TextField', 'Toolbar',
37 ]37 ]
3838
3939
=== modified file 'tests/qmlapicheck.py'
--- tests/qmlapicheck.py 2014-04-24 09:18:38 +0000
+++ tests/qmlapicheck.py 2014-05-28 18:09:57 +0000
@@ -130,10 +130,10 @@
130 if '{' in line and '}' in line:130 if '{' in line and '}' in line:
131 if filetype == 'qmltypes' and not in_builtin_type:131 if filetype == 'qmltypes' and not in_builtin_type:
132 print(' ' + line.strip())132 print(' ' + line.strip())
133 continue133 continue
134134
135 # End of function/ signal/ Item block135 # End of function/ signal/ Item block
136 if '}' in line:136 if '}' in line and not '{' in line:
137 in_block -= 1137 in_block -= 1
138 block_meta = {}138 block_meta = {}
139 if in_block == 1 and in_builtin_type:139 if in_block == 1 and in_builtin_type:
@@ -143,7 +143,7 @@
143 # Only root "Item {" is inspected for QML, otherwise all children143 # Only root "Item {" is inspected for QML, otherwise all children
144 if in_block == 1 or filetype == 'qmltypes':144 if in_block == 1 or filetype == 'qmltypes':
145 # Left hand side specifies a keyword, a type and a variable name145 # Left hand side specifies a keyword, a type and a variable name
146 declaration = line.split(':')[0]146 declaration = line.split(':', 1)[0]
147 words = declaration.strip().split(' ')147 words = declaration.strip().split(' ')
148 # Skip types with prefixes considered builtin148 # Skip types with prefixes considered builtin
149 if filetype == 'qmltypes' and words[0] == 'name':149 if filetype == 'qmltypes' and words[0] == 'name':
@@ -175,7 +175,8 @@
175 for word in words:175 for word in words:
176 if word in keywords:176 if word in keywords:
177 if filetype == 'qml':177 if filetype == 'qml':
178 signature = declaration.split('{')[0].strip()178 separator = '{' if 'function' in declaration else ':'
179 signature = declaration.split(separator, 1)[0].strip()
179 if 'alias' in line:180 if 'alias' in line:
180 no_mods = signature181 no_mods = signature
181 for mod in ['readonly', 'default']:182 for mod in ['readonly', 'default']:
@@ -198,7 +199,7 @@
198 break199 break
199200
200 # Start of function/ signal/ Item block201 # Start of function/ signal/ Item block
201 if '{' in line:202 if '{' in line and not '}' in line:
202 in_block += 1203 in_block += 1
203 block_meta = {}204 block_meta = {}
204 # The parent type can affect API205 # The parent type can affect API
205206
=== modified file 'tests/resources/alarm/Alarms.qml'
--- tests/resources/alarm/Alarms.qml 2014-04-23 08:50:20 +0000
+++ tests/resources/alarm/Alarms.qml 2014-05-28 18:09:57 +0000
@@ -113,7 +113,7 @@
113 id: days113 id: days
114 text: "Occurence"114 text: "Occurence"
115 values: getValues()115 values: getValues()
116 visible: recurence.selectedIndex == 2116 visible: recurence.selectedIndex !== 1
117 onClicked: {117 onClicked: {
118 PopupUtils.open(Qt.resolvedUrl("AlarmDays.qml"), days, {"alarm": alarm});118 PopupUtils.open(Qt.resolvedUrl("AlarmDays.qml"), days, {"alarm": alarm});
119 }119 }
120120
=== added file 'tests/resources/toolbar/header.qml'
--- tests/resources/toolbar/header.qml 1970-01-01 00:00:00 +0000
+++ tests/resources/toolbar/header.qml 2014-05-28 18:09:57 +0000
@@ -0,0 +1,143 @@
1/*
2 * Copyright (C) 2013-2014 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17import QtQuick 2.0
18import Ubuntu.Components 1.1
19
20MainView {
21 id: mainView
22 width: units.gu(40)
23 height: units.gu(50)
24
25 PageStack {
26 id: stack
27
28 Component.onCompleted: stack.push(tabs)
29 Tabs {
30 id: tabs
31 Tab {
32 title: "Tab 1"
33 page: Page {
34 Button {
35 anchors.centerIn: parent
36 text: "Click me"
37 onTriggered: stack.push(pageOnStack)
38 }
39 tools: ToolbarItems {
40 ToolbarButton {
41 action: Action {
42 iconName: "settings"
43 text: "Settings"
44 }
45 }
46 }
47 }
48 }
49 Tab {
50 title: "Tab 2"
51 page: Page {
52 Label {
53 anchors.centerIn: parent
54 text: "Second tab"
55 }
56
57 tools: ToolbarItems {
58 ToolbarButton {
59 action: Action {
60 iconName: "search"
61 text: "Search"
62 }
63 }
64 ToolbarButton {
65 action: Action {
66 iconName: "contact"
67 text: "Contacts"
68 }
69 }
70 ToolbarButton {
71 action: Action {
72 iconName: "share"
73 text: "Share"
74 }
75 }
76 ToolbarButton {
77 action: Action {
78 iconName: "select"
79 text: "Select"
80 }
81 }
82 }
83 }
84 }
85 Tab {
86 title: "Tab 3"
87 page: Page {
88 Switch {
89 id: newHeaderSwitch
90 anchors.centerIn: parent
91 checked: !mainView.useDeprecatedToolbar
92 onTriggered: {
93 mainView.useDeprecatedToolbar = !checked;
94 }
95 }
96 Label {
97 anchors {
98 horizontalCenter: parent.horizontalCenter
99 bottom: newHeaderSwitch.top
100 bottomMargin: units.gu(1)
101 }
102 text: "Use new header"
103 }
104 tools: ToolbarItems {
105 ToolbarButton {
106 action: Action {
107 iconName: "camera-flip"
108 text: "hello"
109 }
110 }
111 }
112
113 }
114 }
115 Tab {
116 title: "Tab 4"
117 page: Page { }
118 }
119 Tab {
120 title: "Tab 5"
121 page: Page { }
122 }
123 }
124 }
125
126 Page {
127 id: pageOnStack
128 visible: false
129 title: "Stacked page"
130 Label {
131 anchors.centerIn: parent
132 text: "Use back button to return"
133 }
134 tools: ToolbarItems {
135 ToolbarButton {
136 action: Action {
137 iconName: "search"
138 text: "Search"
139 }
140 }
141 }
142 }
143}
0144
=== modified file 'tests/unit/tst_alarms/tst_alarms.cpp'
--- tests/unit/tst_alarms/tst_alarms.cpp 2014-04-10 09:53:26 +0000
+++ tests/unit/tst_alarms/tst_alarms.cpp 2014-05-28 18:09:57 +0000
@@ -354,6 +354,7 @@
354 waitForRequest(&alarm);354 waitForRequest(&alarm);
355 QCOMPARE(alarm.error(), (int)UCAlarm::NoError);355 QCOMPARE(alarm.error(), (int)UCAlarm::NoError);
356 QVERIFY(containsAlarm(&alarm));356 QVERIFY(containsAlarm(&alarm));
357 QSKIP("https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1322558");
357358
358 alarm.setDate(alarm.date().addDays(1));359 alarm.setDate(alarm.date().addDays(1));
359 alarm.save();360 alarm.save();
@@ -456,6 +457,51 @@
456 QVERIFY(srcDate.timeZone() != dstDate.timeZone());457 QVERIFY(srcDate.timeZone() != dstDate.timeZone());
457 }458 }
458459
460 void test_oneTime_dow_data() {
461 QTest::addColumn<QString>("message");
462 QTest::addColumn<int>("dow");
463
464 QTest::newRow("Monday") << "Monday" << (int)UCAlarm::Monday;
465 QTest::newRow("Tuesday") << "Tuesday" << (int)UCAlarm::Tuesday;
466 QTest::newRow("Wednesday") << "Wednesday" << (int)UCAlarm::Wednesday;
467 QTest::newRow("Thursday") << "Thursday" << (int)UCAlarm::Thursday;
468 QTest::newRow("Friday") << "Friday" << (int)UCAlarm::Friday;
469 QTest::newRow("Saturday") << "Saturday" << (int)UCAlarm::Saturday;
470 QTest::newRow("Sunday") << "Sunday" << (int)UCAlarm::Sunday;
471 }
472 void test_oneTime_dow() {
473 QFETCH(QString, message);
474 QFETCH(int, dow);
475
476 UCAlarm alarm(QDateTime::currentDateTime().addSecs(3600), "test_oneTime_dow_" + message);
477 alarm.setDaysOfWeek((UCAlarm::DaysOfWeek)dow);
478 alarm.save();
479 waitForRequest(&alarm);
480 QCOMPARE(alarm.error(), (int)UCAlarm::NoError);
481 QVERIFY(containsAlarm(&alarm));
482 }
483
484 void test_oneTime_setDate_does_not_change_dow_data() {
485 QTest::addColumn<QString>("message");
486 QTest::addColumn<int>("dow");
487
488 QTest::newRow("Monday") << "Monday" << (int)UCAlarm::Monday;
489 QTest::newRow("Tuesday") << "Tuesday" << (int)UCAlarm::Tuesday;
490 QTest::newRow("Wednesday") << "Wednesday" << (int)UCAlarm::Wednesday;
491 QTest::newRow("Thursday") << "Thursday" << (int)UCAlarm::Thursday;
492 QTest::newRow("Friday") << "Friday" << (int)UCAlarm::Friday;
493 QTest::newRow("Saturday") << "Saturday" << (int)UCAlarm::Saturday;
494 QTest::newRow("Sunday") << "Sunday" << (int)UCAlarm::Sunday;
495 }
496 void test_oneTime_setDate_does_not_change_dow() {
497 QFETCH(QString, message);
498 QFETCH(int, dow);
499
500 UCAlarm alarm(QDateTime::currentDateTime(), "test_oneTime_setDate_does_not_change_dow_" + message);
501 alarm.setDaysOfWeek((UCAlarm::DaysOfWeek)dow);
502 alarm.setDate(QDateTime::currentDateTime().addSecs(3600));
503 QCOMPARE((int)alarm.daysOfWeek(), dow);
504 }
459};505};
460506
461QTEST_MAIN(tst_UCAlarms)507QTEST_MAIN(tst_UCAlarms)
462508
=== modified file 'tests/unit/tst_components/tst_label.qml'
--- tests/unit/tst_components/tst_label.qml 2014-04-23 08:50:20 +0000
+++ tests/unit/tst_components/tst_label.qml 2014-05-28 18:09:57 +0000
@@ -44,7 +44,7 @@
44 }44 }
4545
46 function test_fontWeight() {46 function test_fontWeight() {
47 compare(textCustom.font.weight, Font.Normal, "font.weight is 'normal' by default")47 compare(textCustom.font.weight, Font.Light, "font.weight is 'light' by default")
4848
49 var fontWeights = [ Font.Light, Font.Normal, Font.DemiBold, Font.Bold, Font.Black ]49 var fontWeights = [ Font.Light, Font.Normal, Font.DemiBold, Font.Bold, Font.Black ]
5050
5151
=== added file 'tests/unit/tst_components/tst_sortfiltermodel.qml'
--- tests/unit/tst_components/tst_sortfiltermodel.qml 1970-01-01 00:00:00 +0000
+++ tests/unit/tst_components/tst_sortfiltermodel.qml 2014-05-28 18:09:57 +0000
@@ -0,0 +1,123 @@
1/*
2 * Copyright 2014 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17import QtQuick 2.0
18import QtTest 1.0
19import Ubuntu.Components 1.1
20
21TestCase {
22 name: "SortFilterModel"
23
24 ListModel {
25 id: things
26 ListElement { foo: "pub"; alpha: "bee"; num: 200 }
27 ListElement { foo: "den"; alpha: "cow"; num: 300 }
28 ListElement { foo: "bar"; alpha: "ant"; num: 100 }
29 }
30
31 SortFilterModel {
32 id: unmodified
33 model: things
34 }
35
36 SortFilterModel {
37 id: alphabetic
38 model: things
39 sort.property: "alpha"
40 }
41
42 SortFilterModel {
43 id: alphaSecond
44 model: things
45 sort.property: "foo"
46 }
47
48 SortFilterModel {
49 id: alphabeticRe
50 model: things
51 sort.property: "alpha"
52 sort.order: Qt.DescendingOrder
53 }
54
55 SortFilterModel {
56 id: numeric
57 model: things
58 sort.property: "num"
59 }
60
61 SortFilterModel {
62 id: numericRe
63 model: things
64 sort.property: "num"
65 sort.order: Qt.DescendingOrder
66 }
67
68 SortFilterModel {
69 id: bee
70 model: things
71 filter.property: "alpha"
72 filter.pattern: /e/
73 }
74
75 function test_passthrough() {
76 compare(unmodified.count, things.count)
77 }
78
79 function test_sort() {
80 // Default is Ascending
81 compare(alphabetic.sort.order, Qt.AscendingOrder)
82 compare(alphabetic.get(0).alpha, "ant")
83 compare(alphabetic.get(1).alpha, "bee")
84 compare(alphabetic.get(2).alpha, "cow")
85
86 // Ensure different columns work also
87 compare(alphaSecond.get(0).foo, "bar")
88
89 // Descending
90 compare(alphabeticRe.sort.order, Qt.DescendingOrder)
91 compare(alphabeticRe.get(0).alpha, "cow")
92 compare(alphabeticRe.get(1).alpha, "bee")
93 compare(alphabeticRe.get(2).alpha, "ant")
94
95 // Numbers
96 compare(numeric.get(0).num, 100)
97 compare(numericRe.get(0).num, 300)
98
99 // Changing roles
100 alphabetic.sort.property = "foo"
101 compare(alphabetic.get(0).foo, "bar")
102 compare(alphabetic.get(1).foo, "den")
103 compare(alphabetic.get(2).foo, "pub")
104 // Sanity check
105 compare(alphabetic.get(1).alpha, "cow")
106 // change again
107 alphabetic.sort.property = "num"
108 compare(alphabetic.get(0).num, 100)
109 compare(alphabetic.get(1).num, 200)
110 compare(alphabetic.get(2).num, 300)
111 // Sanity check
112 compare(alphabetic.get(2).alpha, "cow")
113 }
114
115 function test_filter() {
116 // Default is an empty pattern
117 compare(unmodified.filter.pattern, RegExp())
118
119 // Filter
120 compare(bee.count, 1)
121 compare(bee.get(0).alpha, "bee")
122 }
123}
0124
=== modified file 'tests/unit/tst_components/tst_toolbaritems.qml'
--- tests/unit/tst_components/tst_toolbaritems.qml 2014-04-23 08:50:20 +0000
+++ tests/unit/tst_components/tst_toolbaritems.qml 2014-05-28 18:09:57 +0000
@@ -23,6 +23,7 @@
23 height: 20023 height: 200
2424
25 MainView {25 MainView {
26 id: mainView
26 anchors.fill: parent27 anchors.fill: parent
27 PageStack {28 PageStack {
28 id: pageStack029 id: pageStack0
@@ -37,7 +38,8 @@
3738
38 Page {39 Page {
39 id: page140 id: page1
40 tools: ToolbarItems {41 tools: toolbarItems
42 ToolbarItems {
41 id: toolbarItems43 id: toolbarItems
42 ToolbarButton {44 ToolbarButton {
43 id: button45 id: button
@@ -94,5 +96,12 @@
94 pageStack0.pop();96 pageStack0.pop();
95 compare(pageStack0.depth, 0, "pageStack is empty after popping both pages");97 compare(pageStack0.depth, 0, "pageStack is empty after popping both pages");
96 }98 }
99
100 function test_visible() {
101 compare(toolbarItems.visible, true, "Toolbar items are visible when in toolbar");
102 mainView.useDeprecatedToolbar = false;
103 compare(toolbarItems.visible, false, "Toolbar items are invisible when not using deprecated toolbar");
104 mainView.useDeprecatedToolbar = true;
105 }
97 }106 }
98}107}
99108
=== removed directory 'tests/unit/tst_i18n/appropriate/localizedApp'
=== renamed directory 'tests/unit/tst_i18n/appropriate' => 'tests/unit/tst_i18n/localizedApp'
=== added directory 'tests/unit/tst_i18n/localizedApp/.click'
=== added file 'tests/unit/tst_i18n/localizedApp/.click/status'
--- tests/unit/tst_i18n/localizedApp/.click/status 1970-01-01 00:00:00 +0000
+++ tests/unit/tst_i18n/localizedApp/.click/status 2014-05-28 18:09:57 +0000
@@ -0,0 +1,1 @@
1Package: localizedApp
02
=== added directory 'tests/unit/tst_i18n/localizedApp/share'
=== renamed directory 'tests/unit/tst_i18n/appropriate/locale' => 'tests/unit/tst_i18n/localizedApp/share/locale'
=== modified file 'tests/unit/tst_i18n/src/tst_i18n.cpp'
--- tests/unit/tst_i18n/src/tst_i18n.cpp 2013-12-13 15:37:31 +0000
+++ tests/unit/tst_i18n/src/tst_i18n.cpp 2014-05-28 18:09:57 +0000
@@ -76,19 +76,11 @@
76 {76 {
77 // Set test locale folder in the environment77 // Set test locale folder in the environment
78 // Using setenv because QProcessEnvironment ignores changes78 // Using setenv because QProcessEnvironment ignores changes
79 QString wrongDataFolder(QCoreApplication::applicationDirPath() + "/diversion");79 QString testAppDir(QCoreApplication::applicationDirPath() + "/localizedApp");
80 QString testDataFolder(QCoreApplication::applicationDirPath() + "/appropriate");80 setenv("APP_DIR", testAppDir.toUtf8(), 1);
81 setenv("XDG_DATA_DIRS", (wrongDataFolder + ":" + testDataFolder).toUtf8(), 1);
8281
83 // Verify that we set it correctly82 // Verify that we set it correctly
84 QString dataPath(QStandardPaths::locate(QStandardPaths::GenericDataLocation,83 QVERIFY(QFileInfo(testAppDir + "/share/locale/en/LC_MESSAGES/localizedApp.mo").exists());
85 "localizedApp", QStandardPaths::LocateDirectory));
86 QDir dataDir(dataPath);
87 QVERIFY(dataDir.cdUp());
88 QVERIFY(dataDir.cd("locale"));
89 QString doubleCheckLocalePath(dataDir.path());
90 QCOMPARE(doubleCheckLocalePath, testDataFolder + "/locale");
91 QVERIFY(QFileInfo(testDataFolder + "/locale/en/LC_MESSAGES/localizedApp.mo").exists());
9284
93 QString modules("../../../modules");85 QString modules("../../../modules");
94 QVERIFY(QDir(modules).exists());86 QVERIFY(QDir(modules).exists());
@@ -128,12 +120,8 @@
128120
129 // Was the locale folder detected and set?121 // Was the locale folder detected and set?
130 QString boundDomain(C::bindtextdomain(i18n->domain().toUtf8(), ((const char*)0)));122 QString boundDomain(C::bindtextdomain(i18n->domain().toUtf8(), ((const char*)0)));
131 QString dataPath(QStandardPaths::locate(QStandardPaths::GenericDataLocation,123 QString testAppDir(QCoreApplication::applicationDirPath() + "/localizedApp");
132 i18n->domain(), QStandardPaths::LocateDirectory));124 QString expectedLocalePath(QDir(testAppDir).filePath("share/locale"));
133 QDir dataDir(dataPath);
134 QVERIFY(dataDir.cdUp());
135 QVERIFY(dataDir.cd("locale"));
136 QString expectedLocalePath(dataDir.path());
137 QCOMPARE(boundDomain, expectedLocalePath);125 QCOMPARE(boundDomain, expectedLocalePath);
138 // Is the domain gettext uses correct?126 // Is the domain gettext uses correct?
139 QString gettextDomain(C::textdomain(((const char*)0)));127 QString gettextDomain(C::textdomain(((const char*)0)));
140128
=== modified file 'tests/unit/tst_i18n/tst_i18n.pro'
--- tests/unit/tst_i18n/tst_i18n.pro 2013-12-13 15:37:31 +0000
+++ tests/unit/tst_i18n/tst_i18n.pro 2014-05-28 18:09:57 +0000
@@ -2,7 +2,7 @@
2QT += gui2QT += gui
3DEFINES += SRCDIR=\\\"$$PWD/\\\"3DEFINES += SRCDIR=\\\"$$PWD/\\\"
44
5system(msgfmt po/en_US.po -o appropriate/locale/en/LC_MESSAGES/localizedApp.mo)5system(msgfmt po/en_US.po -o localizedApp/share/locale/en/LC_MESSAGES/localizedApp.mo)
66
7SOURCES += \7SOURCES += \
8 src\/tst_i18n.cpp8 src\/tst_i18n.cpp
99
=== modified file 'tests/unit_x11/tst_components/tst_datepicker.qml'
--- tests/unit_x11/tst_components/tst_datepicker.qml 2014-05-05 17:45:45 +0000
+++ tests/unit_x11/tst_components/tst_datepicker.qml 2014-05-28 18:09:57 +0000
@@ -59,7 +59,7 @@
59 function getPickerLabel(picker, name) {59 function getPickerLabel(picker, name) {
60 var pickerItem = findChild(picker, name);60 var pickerItem = findChild(picker, name);
61 var pickerCurrent = findChild(pickerItem, "Picker_ViewLoader");61 var pickerCurrent = findChild(pickerItem, "Picker_ViewLoader");
62 return findChild(pickerCurrent.item.currentItem, "PickerRow_PickerLabel");62 return pickerCurrent.item.currentItem.children[2];
63 }63 }
64 function getPickerModel(picker, name) {64 function getPickerModel(picker, name) {
65 var pickerItem = findInvisibleChild(picker, name);65 var pickerItem = findInvisibleChild(picker, name);
6666
=== added file 'tests/unit_x11/tst_layouts/NestedVisibility.qml'
--- tests/unit_x11/tst_layouts/NestedVisibility.qml 1970-01-01 00:00:00 +0000
+++ tests/unit_x11/tst_layouts/NestedVisibility.qml 2014-05-28 18:09:57 +0000
@@ -0,0 +1,163 @@
1/*
2 * Copyright 2014 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17import QtQuick 2.0
18import Ubuntu.Components 1.1
19import Ubuntu.Layouts 1.0
20
21MainView {
22 id: main
23 objectName: "mainView"
24 applicationName: "test-app"
25
26 /*
27 This property enables the application to change orientation
28 when the device is rotated. The default is false.
29 */
30 automaticOrientation: true // TODO: support wide aspect ratios, esp. on prepareGamePage
31
32 width: units.gu(40)
33 height: units.gu(75)
34
35 function phoneLayout() {
36 width = units.gu(50);
37 }
38 function tabletPortraitLayout() {
39 width = units.gu(70);
40 }
41 function tabletLandscapeLayout() {
42 width = units.gu(100);
43 }
44
45 PageStack {
46 Component.onCompleted: push(testPage)
47
48 Page {
49 title: i18n.tr("Conditional Layouts with PageStack")
50 id: testPage
51 visible: false
52
53 Layouts {
54 id: layouts
55 objectName: "mainLayout"
56 width: parent.width
57 height: parent.height
58 layouts: [
59 ConditionalLayout {
60 name: "tabletPortrait"
61 when: main.width > units.gu(50)
62 Layouts {
63 anchors.fill: parent
64 objectName: "nestedLayout"
65 layouts: [
66 ConditionalLayout {
67 name: "tabletLandscape"
68 when: main.width > units.gu(70)
69 Row {
70 objectName: "tabletLandscape"
71 anchors.fill: parent
72 Rectangle {
73 height: parent.height
74 color: "white"
75 width: parent.width / 5
76 }
77 Flow {
78 spacing: units.gu(2)
79 ItemLayout {
80 objectName: "nestedMagentaContainer"
81 item: "mainMagenta"
82 width: units.gu(20)
83 height: width
84 }
85 ItemLayout {
86 objectName: "nestedGreenContainer"
87 item: "mainGreen"
88 width: units.gu(60)
89 height: width
90 }
91 }
92 }
93 }
94 ]
95 // Default layout, but can have ItemLayouts
96 // as those will belong to the previous Layouts
97 // and attaching Layouts.item we can layout it further
98 Flow {
99 objectName: "tabletPortrait"
100 anchors.fill: parent
101 ItemLayout {
102 objectName: "greenContainer"
103 item: "mainGreen"
104 width: units.gu(40)
105 height: width
106 Layouts.item: item
107 }
108 ItemLayout {
109 objectName: "magentaContainer"
110 item: "mainMagenta"
111 width: units.gu(60)
112 height: width
113 Layouts.item: item
114 }
115 }
116 }
117 }
118 ]
119
120 // default layout for mainLayout
121 Flow {
122 objectName: "mainDefaultLayout"
123 anchors.fill: parent
124 Rectangle {
125 objectName: "mainRed"
126 width: units.gu(15)
127 height: width
128 color: "red"
129 Layouts.item: "mainRed"
130 }
131 Rectangle {
132 objectName: "mainGreen"
133 width: units.gu(15)
134 height: width
135 color: "green"
136 Layouts.item: "mainGreen"
137 }
138 Rectangle {
139 objectName: "mainBlue"
140 width: units.gu(15)
141 height: width
142 color: "blue"
143 Layouts.item: "mainBlue"
144 }
145 Rectangle {
146 objectName: "mainMagenta"
147 width: units.gu(15)
148 height: width
149 color: "magenta"
150 Layouts.item: "mainMagenta"
151 }
152 Rectangle {
153 objectName: "mainHidden"
154 width: units.gu(15)
155 height: width
156 color: "yellow"
157 visible: false
158 }
159 }
160 }
161 }
162 }
163}
0164
=== added file 'tests/unit_x11/tst_layouts/Visibility.qml'
--- tests/unit_x11/tst_layouts/Visibility.qml 1970-01-01 00:00:00 +0000
+++ tests/unit_x11/tst_layouts/Visibility.qml 2014-05-28 18:09:57 +0000
@@ -0,0 +1,84 @@
1/*
2 * Copyright 2014 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17import QtQuick 2.0
18import Ubuntu.Components 1.1
19import Ubuntu.Layouts 1.0
20
21MainView {
22 id: main
23 objectName: "mainView"
24 applicationName: "test-app"
25
26 /*
27 This property enables the application to change orientation
28 when the device is rotated. The default is false.
29 */
30 automaticOrientation: true // TODO: support wide aspect ratios, esp. on prepareGamePage
31
32 property bool boundValue: true
33
34 width: units.gu(100)
35 height: units.gu(75)
36
37 function portraitLayout() {
38 width = units.gu(50);
39 }
40 function landscapeLayout() {
41 width = units.gu(100);
42 }
43
44 PageStack {
45 Component.onCompleted: push(testPage)
46
47 Page {
48 title: i18n.tr("Conditional Layouts with PageStack")
49 id: testPage
50 visible: false
51
52 Layouts {
53 id: layouts
54 objectName: "layoutManager"
55 width: parent.width
56 height: parent.height
57 layouts: [
58 ConditionalLayout {
59 name: "wide"
60 when: layouts.width < units.gu(60)
61 UbuntuShape {
62 width: units.gu(20)
63 height: units.gu(20)
64 color: "red"
65 Label { text: "wide" }
66 }
67 }
68 ]
69
70 // This is a default layout.
71 // When using a PageStack and layouts is not empty, it won't display or switch to the default layout.
72 // However it only works when putting it into the layouts list with an inversed condition.
73 UbuntuShape {
74 objectName: "DefaultLayout"
75 width: units.gu(20)
76 height: units.gu(20)
77 color: "green"
78 visible: main.boundValue
79 Label { text: "default" }
80 }
81 }
82 }
83 }
84}
085
=== modified file 'tests/unit_x11/tst_layouts/tst_layouts.cpp'
--- tests/unit_x11/tst_layouts/tst_layouts.cpp 2014-03-19 12:48:33 +0000
+++ tests/unit_x11/tst_layouts/tst_layouts.cpp 2014-05-28 18:09:57 +0000
@@ -72,6 +72,25 @@
72 return (children.count() > 0) ? children[0] : 0;72 return (children.count() > 0) ? children[0] : 0;
73 }73 }
7474
75 bool hasChildItem(QQuickItem *child, QQuickItem *parent)
76 {
77 QQuickItem *pl = child->parentItem();
78 while (pl) {
79 if (pl == parent) {
80 return true;
81 }
82 pl = pl->parentItem();
83 }
84 return false;
85 }
86
87 QQuickItem *prevSibling(QQuickItem *item)
88 {
89 QList<QQuickItem*> children = item->parentItem()->childItems();
90 int index = children.indexOf(item);
91 return (index > 0) ? children.at(index - 1) : 0;
92 }
93
7594
76private Q_SLOTS:95private Q_SLOTS:
77 void initTestCase()96 void initTestCase()
@@ -419,16 +438,16 @@
419438
420 void testCase_AnchorFilledReparenting()439 void testCase_AnchorFilledReparenting()
421 {440 {
422 QScopedPointer<QQuickView> view(loadTest("AnchorFilledReparenting.qml"));441 QScopedPointer<UbuntuTestCase> view(new UbuntuTestCase("AnchorFilledReparenting.qml"));
423 QVERIFY(view);442 QVERIFY(view);
424 QQuickItem *root = view->rootObject();443 QQuickItem *root = view->rootObject();
425 QVERIFY(root);444 QVERIFY(root);
426445
427 QQuickItem *layout = testItem(root, "layoutManager");446 ULLayouts *layout = view->findItem<ULLayouts*>("layoutManager");
428 QVERIFY(layout);447 QVERIFY(layout);
429 QSignalSpy layoutChangeSpy(layout, SIGNAL(currentLayoutChanged()));448 QSignalSpy layoutChangeSpy(layout, SIGNAL(currentLayoutChanged()));
430449
431 QQuickItem *item = testItem(root, "testItem");450 QQuickItem *item = view->findItem<QQuickItem*>("testItem");
432 QVERIFY(item);451 QVERIFY(item);
433452
434 QQuickAnchors *anchors = item->property("anchors").value<QQuickAnchors*>();453 QQuickAnchors *anchors = item->property("anchors").value<QQuickAnchors*>();
@@ -436,27 +455,27 @@
436455
437 root->setWidth(root->width() + 100);456 root->setWidth(root->width() + 100);
438 layoutChangeSpy.wait(100);457 layoutChangeSpy.wait(100);
439 QQuickItem *testLayout = testItem(root, "testLayout");458 QQuickItem *testLayout = view->findItem<QQuickItem*>("testLayout");
440 QVERIFY(testLayout);459 QVERIFY(testLayout);
441 QCOMPARE(anchors->fill(), testLayout);460 QCOMPARE(anchors->fill(), testLayout);
442461
443 root->setWidth(root->width() - 100);462 root->setWidth(root->width() - 100);
444 layoutChangeSpy.wait(100);463 layoutChangeSpy.wait(100);
445 QCOMPARE(anchors->fill(), layout);464 QCOMPARE(anchors->fill(), layout->contentItem());
446 }465 }
447466
448 void testCase_AnchorFilledMargins()467 void testCase_AnchorFilledMargins()
449 {468 {
450 QScopedPointer<QQuickView> view(loadTest("AnchorFilledMargins.qml"));469 QScopedPointer<UbuntuTestCase> view(new UbuntuTestCase("AnchorFilledMargins.qml"));
451 QVERIFY(view);470 QVERIFY(view);
452 QQuickItem *root = view->rootObject();471 QQuickItem *root = view->rootObject();
453 QVERIFY(root);472 QVERIFY(root);
454473
455 QQuickItem *layout = testItem(root, "layoutManager");474 ULLayouts *layout = view->findItem<ULLayouts*>("layoutManager");
456 QVERIFY(layout);475 QVERIFY(layout);
457 QSignalSpy layoutChangeSpy(layout, SIGNAL(currentLayoutChanged()));476 QSignalSpy layoutChangeSpy(layout, SIGNAL(currentLayoutChanged()));
458477
459 QQuickItem *item = testItem(root, "testItem");478 QQuickItem *item = view->findItem<QQuickItem*>("testItem");
460 QVERIFY(item);479 QVERIFY(item);
461480
462 QQuickAnchors *anchors = item->property("anchors").value<QQuickAnchors*>();481 QQuickAnchors *anchors = item->property("anchors").value<QQuickAnchors*>();
@@ -465,29 +484,29 @@
465 root->setWidth(root->width() + 100);484 root->setWidth(root->width() + 100);
466 layoutChangeSpy.wait(100);485 layoutChangeSpy.wait(100);
467486
468 QQuickItem *testLayout = testItem(root, "testLayout");487 QQuickItem *testLayout = view->findItem<QQuickItem*>("testLayout");
469 QVERIFY(testLayout);488 QVERIFY(testLayout);
470 QCOMPARE(anchors->fill(), testLayout);489 QCOMPARE(anchors->fill(), testLayout);
471 QCOMPARE(anchors->margins(), 0.0);490 QCOMPARE(anchors->margins(), 0.0);
472491
473 root->setWidth(root->width() - 100);492 root->setWidth(root->width() - 100);
474 layoutChangeSpy.wait(100);493 layoutChangeSpy.wait(100);
475 QCOMPARE(anchors->fill(), layout);494 QCOMPARE(anchors->fill(), layout->contentItem());
476 QCOMPARE(anchors->margins(), 10.0);495 QCOMPARE(anchors->margins(), 10.0);
477 }496 }
478497
479 void testCase_AnchorFilledSeparateMargins()498 void testCase_AnchorFilledSeparateMargins()
480 {499 {
481 QScopedPointer<QQuickView> view(loadTest("AnchorFilledSeparateMargins.qml"));500 QScopedPointer<UbuntuTestCase> view(new UbuntuTestCase("AnchorFilledSeparateMargins.qml"));
482 QVERIFY(view);501 QVERIFY(view);
483 QQuickItem *root = view->rootObject();502 QQuickItem *root = view->rootObject();
484 QVERIFY(root);503 QVERIFY(root);
485504
486 QQuickItem *layout = testItem(root, "layoutManager");505 ULLayouts *layout = view->findItem<ULLayouts*>("layoutManager");
487 QVERIFY(layout);506 QVERIFY(layout);
488 QSignalSpy layoutChangeSpy(layout, SIGNAL(currentLayoutChanged()));507 QSignalSpy layoutChangeSpy(layout, SIGNAL(currentLayoutChanged()));
489508
490 QQuickItem *item = testItem(root, "testItem");509 QQuickItem *item = view->findItem<QQuickItem*>("testItem");
491 QVERIFY(item);510 QVERIFY(item);
492511
493 QQuickAnchors *anchors = item->property("anchors").value<QQuickAnchors*>();512 QQuickAnchors *anchors = item->property("anchors").value<QQuickAnchors*>();
@@ -496,7 +515,7 @@
496 root->setWidth(root->width() + 100);515 root->setWidth(root->width() + 100);
497 layoutChangeSpy.wait(100);516 layoutChangeSpy.wait(100);
498517
499 QQuickItem *testLayout = testItem(root, "testLayout");518 QQuickItem *testLayout = view->findItem<QQuickItem*>("testLayout");
500 QVERIFY(testLayout);519 QVERIFY(testLayout);
501 QCOMPARE(anchors->fill(), testLayout);520 QCOMPARE(anchors->fill(), testLayout);
502 QCOMPARE(anchors->margins(), 0.0);521 QCOMPARE(anchors->margins(), 0.0);
@@ -507,7 +526,7 @@
507526
508 root->setWidth(root->width() - 100);527 root->setWidth(root->width() - 100);
509 layoutChangeSpy.wait(100);528 layoutChangeSpy.wait(100);
510 QCOMPARE(anchors->fill(), layout);529 QCOMPARE(anchors->fill(), layout->contentItem());
511 QCOMPARE(anchors->leftMargin(), 10.0);530 QCOMPARE(anchors->leftMargin(), 10.0);
512 QCOMPARE(anchors->topMargin(), 20.0);531 QCOMPARE(anchors->topMargin(), 20.0);
513 QCOMPARE(anchors->rightMargin(), 30.0);532 QCOMPARE(anchors->rightMargin(), 30.0);
@@ -516,16 +535,16 @@
516535
517 void testCase_AnchorCenteredInDefault()536 void testCase_AnchorCenteredInDefault()
518 {537 {
519 QScopedPointer<QQuickView> view(loadTest("AnchorCenteredInDefault.qml"));538 QScopedPointer<UbuntuTestCase> view(new UbuntuTestCase("AnchorCenteredInDefault.qml"));
520 QVERIFY(view);539 QVERIFY(view);
521 QQuickItem *root = view->rootObject();540 QQuickItem *root = view->rootObject();
522 QVERIFY(root);541 QVERIFY(root);
523542
524 QQuickItem *layout = testItem(root, "layoutManager");543 ULLayouts *layout = view->findItem<ULLayouts*>("layoutManager");
525 QVERIFY(layout);544 QVERIFY(layout);
526 QSignalSpy layoutChangeSpy(layout, SIGNAL(currentLayoutChanged()));545 QSignalSpy layoutChangeSpy(layout, SIGNAL(currentLayoutChanged()));
527546
528 QQuickItem *item = testItem(root, "testItem");547 QQuickItem *item = view->findItem<QQuickItem*>("testItem");
529 QVERIFY(item);548 QVERIFY(item);
530549
531 QQuickAnchors *anchors = item->property("anchors").value<QQuickAnchors*>();550 QQuickAnchors *anchors = item->property("anchors").value<QQuickAnchors*>();
@@ -533,335 +552,335 @@
533552
534 root->setWidth(root->width() + 100);553 root->setWidth(root->width() + 100);
535 layoutChangeSpy.wait(100);554 layoutChangeSpy.wait(100);
536 QQuickItem *testLayout = testItem(root, "testLayout");555 QQuickItem *testLayout = view->findItem<QQuickItem*>("testLayout");
537 QVERIFY(testLayout);556 QVERIFY(testLayout);
538 QCOMPARE(anchors->fill(), testLayout);557 QCOMPARE(anchors->fill(), testLayout);
539558
540 root->setWidth(root->width() - 100);559 root->setWidth(root->width() - 100);
541 layoutChangeSpy.wait(100);560 layoutChangeSpy.wait(100);
542 QCOMPARE(anchors->centerIn(), layout);561 QCOMPARE(anchors->centerIn(), layout->contentItem());
543 }562 }
544563
545 void testCase_AnchorVerticalCenter()564 void testCase_AnchorVerticalCenter()
546 {565 {
547 QScopedPointer<QQuickView> view(loadTest("AnchorVerticalCenter.qml"));566 QScopedPointer<UbuntuTestCase> view(new UbuntuTestCase("AnchorVerticalCenter.qml"));
548 QVERIFY(view);567 QVERIFY(view);
549 QQuickItem *root = view->rootObject();568 QQuickItem *root = view->rootObject();
550 QVERIFY(root);569 QVERIFY(root);
551570
552 QQuickItem *layout = testItem(root, "layoutManager");571 ULLayouts *layout = view->findItem<ULLayouts*>("layoutManager");
553 QVERIFY(layout);572 QVERIFY(layout);
554 QSignalSpy layoutChangeSpy(layout, SIGNAL(currentLayoutChanged()));573 QSignalSpy layoutChangeSpy(layout, SIGNAL(currentLayoutChanged()));
555574
556 QQuickItem *item = testItem(root, "testItem");575 QQuickItem *item = view->findItem<QQuickItem*>("testItem");
557 QVERIFY(item);576 QVERIFY(item);
558577
559 QQuickAnchors *anchors = item->property("anchors").value<QQuickAnchors*>();578 QQuickAnchors *anchors = item->property("anchors").value<QQuickAnchors*>();
560 QVERIFY(anchors);579 QVERIFY(anchors);
561580
562 QCOMPARE(anchors->verticalCenter().item, layout);581 QCOMPARE(anchors->verticalCenter().item, layout->contentItem());
563582
564 root->setWidth(root->width() + 100);583 root->setWidth(root->width() + 100);
565 layoutChangeSpy.wait(100);584 layoutChangeSpy.wait(100);
566 QQuickItem *testLayout = testItem(root, "testLayout");585 QQuickItem *testLayout = view->findItem<QQuickItem*>("testLayout");
567 QVERIFY(testLayout);586 QVERIFY(testLayout);
568 QCOMPARE(anchors->fill(), testLayout);587 QCOMPARE(anchors->fill(), testLayout);
569588
570 root->setWidth(root->width() - 100);589 root->setWidth(root->width() - 100);
571 layoutChangeSpy.wait(100);590 layoutChangeSpy.wait(100);
572 QCOMPARE(anchors->verticalCenter().item, layout);591 QCOMPARE(anchors->verticalCenter().item, layout->contentItem());
573 }592 }
574593
575 void testCase_AnchorVerticalCenterOffset()594 void testCase_AnchorVerticalCenterOffset()
576 {595 {
577 QScopedPointer<QQuickView> view(loadTest("AnchorVerticalCenterOffset.qml"));596 QScopedPointer<UbuntuTestCase> view(new UbuntuTestCase("AnchorVerticalCenterOffset.qml"));
578 QVERIFY(view);597 QVERIFY(view);
579 QQuickItem *root = view->rootObject();598 QQuickItem *root = view->rootObject();
580 QVERIFY(root);599 QVERIFY(root);
581600
582 QQuickItem *layout = testItem(root, "layoutManager");601 ULLayouts *layout = view->findItem<ULLayouts*>("layoutManager");
583 QVERIFY(layout);602 QVERIFY(layout);
584 QSignalSpy layoutChangeSpy(layout, SIGNAL(currentLayoutChanged()));603 QSignalSpy layoutChangeSpy(layout, SIGNAL(currentLayoutChanged()));
585604
586 QQuickItem *item = testItem(root, "testItem");605 QQuickItem *item = view->findItem<QQuickItem*>("testItem");
587 QVERIFY(item);606 QVERIFY(item);
588607
589 QQuickAnchors *anchors = item->property("anchors").value<QQuickAnchors*>();608 QQuickAnchors *anchors = item->property("anchors").value<QQuickAnchors*>();
590 QVERIFY(anchors);609 QVERIFY(anchors);
591610
592 QCOMPARE(anchors->verticalCenter().item, layout);611 QCOMPARE(anchors->verticalCenter().item, layout->contentItem());
593 QCOMPARE(anchors->verticalCenterOffset(), 50.0);612 QCOMPARE(anchors->verticalCenterOffset(), 50.0);
594613
595 root->setWidth(root->width() + 100);614 root->setWidth(root->width() + 100);
596 layoutChangeSpy.wait(100);615 layoutChangeSpy.wait(100);
597 QQuickItem *testLayout = qobject_cast<QQuickItem*>(testItem(root, "testLayout"));616 QQuickItem *testLayout = view->findItem<QQuickItem*>("testLayout");
598 QVERIFY(testLayout);617 QVERIFY(testLayout);
599 QCOMPARE(anchors->fill(), testLayout);618 QCOMPARE(anchors->fill(), testLayout);
600 // no need to check offset as it does not affect the fill619 // no need to check offset as it does not affect the fill
601620
602 root->setWidth(root->width() - 100);621 root->setWidth(root->width() - 100);
603 layoutChangeSpy.wait(100);622 layoutChangeSpy.wait(100);
604 QCOMPARE(anchors->verticalCenter().item, layout);623 QCOMPARE(anchors->verticalCenter().item, layout->contentItem());
605 QCOMPARE(anchors->verticalCenterOffset(), 50.0);624 QCOMPARE(anchors->verticalCenterOffset(), 50.0);
606 }625 }
607626
608 void testCase_AnchorHorizontalCenter()627 void testCase_AnchorHorizontalCenter()
609 {628 {
610 QScopedPointer<QQuickView> view(loadTest("AnchorHorizontalCenter.qml"));629 QScopedPointer<UbuntuTestCase> view(new UbuntuTestCase("AnchorHorizontalCenter.qml"));
611 QVERIFY(view);630 QVERIFY(view);
612 QQuickItem *root = view->rootObject();631 QQuickItem *root = view->rootObject();
613 QVERIFY(root);632 QVERIFY(root);
614633
615 QQuickItem *layout = testItem(root, "layoutManager");634 ULLayouts *layout = view->findItem<ULLayouts*>("layoutManager");
616 QVERIFY(layout);635 QVERIFY(layout);
617 QSignalSpy layoutChangeSpy(layout, SIGNAL(currentLayoutChanged()));636 QSignalSpy layoutChangeSpy(layout, SIGNAL(currentLayoutChanged()));
618637
619 QQuickItem *item = testItem(root, "testItem");638 QQuickItem *item = view->findItem<QQuickItem*>("testItem");
620 QVERIFY(item);639 QVERIFY(item);
621640
622 QQuickAnchors *anchors = item->property("anchors").value<QQuickAnchors*>();641 QQuickAnchors *anchors = item->property("anchors").value<QQuickAnchors*>();
623 QVERIFY(anchors);642 QVERIFY(anchors);
624643
625 QCOMPARE(anchors->horizontalCenter().item, layout);644 QCOMPARE(anchors->horizontalCenter().item, layout->contentItem());
626645
627 root->setWidth(root->width() + 100);646 root->setWidth(root->width() + 100);
628 layoutChangeSpy.wait(100);647 layoutChangeSpy.wait(100);
629 QQuickItem *testLayout = testItem(root, "testLayout");648 QQuickItem *testLayout = view->findItem<QQuickItem*>("testLayout");
630 QVERIFY(testLayout);649 QVERIFY(testLayout);
631 QCOMPARE(anchors->fill(), testLayout);650 QCOMPARE(anchors->fill(), testLayout);
632651
633 root->setWidth(root->width() - 100);652 root->setWidth(root->width() - 100);
634 layoutChangeSpy.wait(100);653 layoutChangeSpy.wait(100);
635 QCOMPARE(anchors->horizontalCenter().item, layout);654 QCOMPARE(anchors->horizontalCenter().item, layout->contentItem());
636 }655 }
637656
638 void testCase_AnchorHorizontalCenterOffset()657 void testCase_AnchorHorizontalCenterOffset()
639 {658 {
640 QScopedPointer<QQuickView> view(loadTest("AnchorHorizontalCenterOffset.qml"));659 QScopedPointer<UbuntuTestCase> view(new UbuntuTestCase("AnchorHorizontalCenterOffset.qml"));
641 QVERIFY(view);660 QVERIFY(view);
642 QQuickItem *root = view->rootObject();661 QQuickItem *root = view->rootObject();
643 QVERIFY(root);662 QVERIFY(root);
644663
645 QQuickItem *layout = testItem(root, "layoutManager");664 ULLayouts *layout = view->findItem<ULLayouts*>("layoutManager");
646 QVERIFY(layout);665 QVERIFY(layout);
647 QSignalSpy layoutChangeSpy(layout, SIGNAL(currentLayoutChanged()));666 QSignalSpy layoutChangeSpy(layout, SIGNAL(currentLayoutChanged()));
648667
649 QQuickItem *item = testItem(root, "testItem");668 QQuickItem *item = view->findItem<QQuickItem*>("testItem");
650 QVERIFY(item);669 QVERIFY(item);
651670
652 QQuickAnchors *anchors = item->property("anchors").value<QQuickAnchors*>();671 QQuickAnchors *anchors = item->property("anchors").value<QQuickAnchors*>();
653 QVERIFY(anchors);672 QVERIFY(anchors);
654673
655 QCOMPARE(anchors->horizontalCenter().item, layout);674 QCOMPARE(anchors->horizontalCenter().item, layout->contentItem());
656 QCOMPARE(anchors->horizontalCenterOffset(), 50.0);675 QCOMPARE(anchors->horizontalCenterOffset(), 50.0);
657676
658 root->setWidth(root->width() + 100);677 root->setWidth(root->width() + 100);
659 layoutChangeSpy.wait(100);678 layoutChangeSpy.wait(100);
660 QQuickItem *testLayout = testItem(root, "testLayout");679 QQuickItem *testLayout = view->findItem<QQuickItem*>("testLayout");
661 QVERIFY(testLayout);680 QVERIFY(testLayout);
662 QCOMPARE(anchors->fill(), testLayout);681 QCOMPARE(anchors->fill(), testLayout);
663 // no need to check offset as it does not affect the fill682 // no need to check offset as it does not affect the fill
664683
665 root->setWidth(root->width() - 100);684 root->setWidth(root->width() - 100);
666 layoutChangeSpy.wait(100);685 layoutChangeSpy.wait(100);
667 QCOMPARE(anchors->horizontalCenter().item, layout);686 QCOMPARE(anchors->horizontalCenter().item, layout->contentItem());
668 QCOMPARE(anchors->horizontalCenterOffset(), 50.0);687 QCOMPARE(anchors->horizontalCenterOffset(), 50.0);
669 }688 }
670689
671 void testCase_AnchorCenterWithOffset()690 void testCase_AnchorCenterWithOffset()
672 {691 {
673 QScopedPointer<QQuickView> view(loadTest("AnchorCenterWithOffset.qml"));692 QScopedPointer<UbuntuTestCase> view(new UbuntuTestCase("AnchorCenterWithOffset.qml"));
674 QVERIFY(view);693 QVERIFY(view);
675 QQuickItem *root = view->rootObject();694 QQuickItem *root = view->rootObject();
676 QVERIFY(root);695 QVERIFY(root);
677696
678 QQuickItem *layout = testItem(root, "layoutManager");697 ULLayouts *layout = view->findItem<ULLayouts*>("layoutManager");
679 QVERIFY(layout);698 QVERIFY(layout);
680 QSignalSpy layoutChangeSpy(layout, SIGNAL(currentLayoutChanged()));699 QSignalSpy layoutChangeSpy(layout, SIGNAL(currentLayoutChanged()));
681700
682 QQuickItem *item = testItem(root, "testItem");701 QQuickItem *item = view->findItem<QQuickItem*>("testItem");
683 QVERIFY(item);702 QVERIFY(item);
684703
685 QQuickAnchors *anchors = item->property("anchors").value<QQuickAnchors*>();704 QQuickAnchors *anchors = item->property("anchors").value<QQuickAnchors*>();
686 QVERIFY(anchors);705 QVERIFY(anchors);
687706
688 QCOMPARE(anchors->centerIn(), layout);707 QCOMPARE(anchors->centerIn(), layout->contentItem());
689 QCOMPARE(anchors->verticalCenterOffset(), 50.0);708 QCOMPARE(anchors->verticalCenterOffset(), 50.0);
690 QCOMPARE(anchors->horizontalCenterOffset(), 40.0);709 QCOMPARE(anchors->horizontalCenterOffset(), 40.0);
691710
692 root->setWidth(root->width() + 100);711 root->setWidth(root->width() + 100);
693 layoutChangeSpy.wait(100);712 layoutChangeSpy.wait(100);
694 QQuickItem *testLayout = testItem(root, "testLayout");713 QQuickItem *testLayout = view->findItem<QQuickItem*>("testLayout");
695 QVERIFY(testLayout);714 QVERIFY(testLayout);
696 QCOMPARE(anchors->fill(), testLayout);715 QCOMPARE(anchors->fill(), testLayout);
697 // no need to check offsets as it does not affect the fill716 // no need to check offsets as it does not affect the fill
698717
699 root->setWidth(root->width() - 100);718 root->setWidth(root->width() - 100);
700 layoutChangeSpy.wait(100);719 layoutChangeSpy.wait(100);
701 QCOMPARE(anchors->centerIn(), layout);720 QCOMPARE(anchors->centerIn(), layout->contentItem());
702 QCOMPARE(anchors->verticalCenterOffset(), 50.0);721 QCOMPARE(anchors->verticalCenterOffset(), 50.0);
703 QCOMPARE(anchors->horizontalCenterOffset(), 40.0);722 QCOMPARE(anchors->horizontalCenterOffset(), 40.0);
704 }723 }
705724
706 void testCase_AnchorLeft()725 void testCase_AnchorLeft()
707 {726 {
708 QScopedPointer<QQuickView> view(loadTest("AnchorLeft.qml"));727 QScopedPointer<UbuntuTestCase> view(new UbuntuTestCase("AnchorLeft.qml"));
709 QVERIFY(view);728 QVERIFY(view);
710 QQuickItem *root = view->rootObject();729 QQuickItem *root = view->rootObject();
711 QVERIFY(root);730 QVERIFY(root);
712731
713 QQuickItem *layout = testItem(root, "layoutManager");732 ULLayouts *layout = view->findItem<ULLayouts*>("layoutManager");
714 QVERIFY(layout);733 QVERIFY(layout);
715 QSignalSpy layoutChangeSpy(layout, SIGNAL(currentLayoutChanged()));734 QSignalSpy layoutChangeSpy(layout, SIGNAL(currentLayoutChanged()));
716735
717 QQuickItem *item = testItem(root, "testItem");736 QQuickItem *item = view->findItem<QQuickItem*>("testItem");
718 QVERIFY(item);737 QVERIFY(item);
719738
720 QQuickAnchors *anchors = item->property("anchors").value<QQuickAnchors*>();739 QQuickAnchors *anchors = item->property("anchors").value<QQuickAnchors*>();
721 QVERIFY(anchors);740 QVERIFY(anchors);
722741
723 QCOMPARE(anchors->left().item, layout);742 QCOMPARE(anchors->left().item, layout->contentItem());
724 QCOMPARE(anchors->leftMargin(), 10.0);743 QCOMPARE(anchors->leftMargin(), 10.0);
725744
726 root->setWidth(root->width() + 100);745 root->setWidth(root->width() + 100);
727 layoutChangeSpy.wait(100);746 layoutChangeSpy.wait(100);
728 QQuickItem *testLayout = testItem(root, "testLayout");747 QQuickItem *testLayout = view->findItem<QQuickItem*>("testLayout");
729 QVERIFY(testLayout);748 QVERIFY(testLayout);
730 QCOMPARE(anchors->fill(), testLayout);749 QCOMPARE(anchors->fill(), testLayout);
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches

to all changes: