Merge lp:~bzoltan/ubuntu-ui-toolkit/landing_09-16 into lp:ubuntu-ui-toolkit
- landing_09-16
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Zoltan Balogh |
Approved revision: | 1642 |
Merged at revision: | 1227 |
Proposed branch: | lp:~bzoltan/ubuntu-ui-toolkit/landing_09-16 |
Merge into: | lp:ubuntu-ui-toolkit |
Diff against target: |
2359 lines (+1045/-356) 47 files modified
.bzrignore (+1/-1) components.api (+6/-0) debian/changelog (+36/-0) debian/control (+13/-1) debian/ubuntu-ui-toolkit-autopilot.install (+0/-1) debian/ubuntu-ui-toolkit-tools.install (+1/-0) examples/ubuntu-ui-toolkit-gallery/gallery (+1/-1) examples/ubuntu-ui-toolkit-gallery/ubuntu-ui-toolkit-gallery.desktop (+1/-1) src/Ubuntu/Components/1.0/Icon.qml (+4/-4) src/Ubuntu/Components/1.2/TextInputPopover.qml (+0/-7) src/Ubuntu/Components/1.3/PageWrapperUtils.js (+9/-2) src/Ubuntu/Components/1.3/TextInputPopover.qml (+0/-6) src/Ubuntu/Components/Popups/1.2/ActionSelectionPopover.qml (+3/-1) src/Ubuntu/Components/Popups/1.2/PopupBase.qml (+1/-0) src/Ubuntu/Components/Popups/1.3/ActionSelectionPopover.qml (+3/-1) src/Ubuntu/Components/Popups/1.3/PopupBase.qml (+1/-0) src/Ubuntu/Components/Themes/Ambiance/1.3/ListItemStyle.qml (+1/-1) src/Ubuntu/Components/plugin/plugin.cpp (+2/-0) src/Ubuntu/Components/plugin/privates/listitemdragarea.cpp (+3/-2) src/Ubuntu/Components/plugin/sortfiltermodel.cpp (+5/-2) src/Ubuntu/Components/plugin/ucactionitem.cpp (+61/-36) src/Ubuntu/Components/plugin/ucactionitem.h (+13/-4) src/Ubuntu/Components/plugin/uclistitem.cpp (+88/-49) src/Ubuntu/Components/plugin/uclistitem.h (+0/-1) src/Ubuntu/Components/plugin/uclistitem_p.h (+3/-7) src/Ubuntu/Components/plugin/ucviewitemsattached.cpp (+0/-64) tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/popups.py (+27/-6) tests/autopilot/ubuntuuitoolkit/base.py (+2/-3) tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_popups.py (+56/-2) tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_tabs.TabsTestCase.deprecated_TabBar.1.3.qml (+9/-10) tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_tabs.py (+4/-2) tests/autopilot/ubuntuuitoolkit/tests/gallery/test_gallery.py (+13/-12) tests/resources/listitems/ListItemTest.qml (+7/-2) tests/resources/navigation/Blackbox.qml (+48/-0) tests/tests.pro (+0/-2) tests/uitk_test_plan.sh (+19/-8) tests/unit_x11/tst_components/ListItemTestCase.qml (+4/-0) tests/unit_x11/tst_components/ListItemTestCase13.qml (+14/-0) tests/unit_x11/tst_components/tst_actionitem.qml (+178/-82) tests/unit_x11/tst_components/tst_icon.qml (+35/-0) tests/unit_x11/tst_components/tst_listitem.qml (+14/-14) tests/unit_x11/tst_components/tst_listitem13.qml (+13/-14) tests/unit_x11/tst_components/tst_listitem_extras.qml (+136/-4) tests/unit_x11/tst_components/tst_popover.qml (+33/-0) tests/unit_x11/tst_components/tst_popover13.qml (+174/-0) ubuntu-sdk.pro (+1/-1) ubuntu-ui-toolkit-launcher/ubuntu-ui-toolkit-launcher.pro (+2/-2) |
To merge this branch: | bzr merge lp:~bzoltan/ubuntu-ui-toolkit/landing_09-16 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot | continuous-integration | Approve | |
Ubuntu SDK team | Pending | ||
Review via email: mp+271274@code.launchpad.net |
Commit message
Landing 2015-09-16
Description of the change
Landing 2015-09-16
PS Jenkins bot (ps-jenkins) wrote : | # |
- 1640. By Zoltan Balogh
-
bump version
- 1641. By Zoltan Balogh
-
sync
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1641
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
- 1642. By Zoltan Balogh
-
Sync with staging
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1642
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
Preview Diff
1 | === modified file '.bzrignore' |
2 | --- .bzrignore 2015-08-18 21:07:56 +0000 |
3 | +++ .bzrignore 2015-09-18 16:36:01 +0000 |
4 | @@ -21,5 +21,5 @@ |
5 | tests/unit/tst_i18n/*/share/locale/en/LC_MESSAGES/*.mo |
6 | tests/unit/tst_units/dpr*/dpr* |
7 | tests/apicheck/apicheck |
8 | -tests/launcher/launcher |
9 | +ubuntu-ui-toolkit-launcher/ubuntu-ui-toolkit-launcher |
10 | build_paths.inc |
11 | |
12 | === modified file 'components.api' |
13 | --- components.api 2015-09-04 12:35:16 +0000 |
14 | +++ components.api 2015-09-18 16:36:01 +0000 |
15 | @@ -1244,6 +1244,12 @@ |
16 | property bool locked |
17 | property bool opened |
18 | property Item pageStack |
19 | +Ubuntu.Components.UCApplication 1.0 0.1: QtObject |
20 | + property string applicationName |
21 | + property QtObject inputMethod |
22 | +Ubuntu.Components.UCFontUtils 1.0 0.1: QtObject |
23 | + function double sizeToPixels(string size) |
24 | + function double modularScale(string size) |
25 | UCListItemDivider: Item |
26 | property color colorFrom |
27 | property color colorTo |
28 | |
29 | === modified file 'debian/changelog' |
30 | --- debian/changelog 2015-09-08 04:10:51 +0000 |
31 | +++ debian/changelog 2015-09-18 16:36:01 +0000 |
32 | @@ -1,3 +1,39 @@ |
33 | +ubuntu-ui-toolkit (1.3.1641+15.10.20150916-0ubuntu1) UNRELEASED; urgency=medium |
34 | + |
35 | + [ Zsombor Egri ] |
36 | + * ActionItem visible and enabled internal bindings not broken when the |
37 | + property values are having new bindings or value assignments. |
38 | + Fixes LP: #1495408 |
39 | + * ListItem swipe over leading/trailing actions blocked. |
40 | + Fixes LP: #1486008, LP: #1496468, LP: #1497156 |
41 | + |
42 | + [ Christian Dywan ] |
43 | + * Use new launcher path in gallery script and .bzrignore. |
44 | + * FragmentShader of Icon shouldn't activate when unwanted. |
45 | + * Unit test that popovers block mouse clicks. Fixes LP: #1488540 |
46 | + * Install ubuntu-ui-toolkit-launcher under /usr/bin. |
47 | + * Register UCApplication and UCFontsUtils so they appear in .api. |
48 | + * Cope with different AbstractButton class name in 1.3. |
49 | + * Implement click_action_button in ActionSelectionPopover CPO. |
50 | + Fixes LP: #1205144 |
51 | + |
52 | + [ Albert Astals Cid ] |
53 | + * Make sure pageWrapper.incubator is set before manually calling |
54 | + incubatorStatusChanged |
55 | + * Bring back pageComponent.createObject for sync pages Fixes regression in |
56 | + unity8's unity8.settings_wizard.tests.test_settings_wizard. |
57 | + SkipThroughSettingsWizardTestCase.test_skipping_through_wizard autopilot |
58 | + |
59 | + [ Olivier Tilloy ] |
60 | + * Take custom key indexes into account in QSortFilterProxyModelQML::get(). |
61 | + Fixes LP: #1495641 |
62 | + |
63 | + [ Zoltan Balogh ] |
64 | + * Customize the UITK test plan and add silo pinning. |
65 | + * Disable crahsing gallery.test_gallery.OpenPagesTestCase.test_open_page |
66 | + |
67 | + -- Zoltán Balogh <zoltan@bakter.hu> Wed, 16 Sep 2015 13:17:52 +0300 |
68 | + |
69 | ubuntu-ui-toolkit (1.3.1627+15.10.20150908-0ubuntu1) wily; urgency=medium |
70 | |
71 | [ Zsombor Egri ] |
72 | |
73 | === modified file 'debian/control' |
74 | --- debian/control 2015-08-20 08:10:44 +0000 |
75 | +++ debian/control 2015-09-18 16:36:01 +0000 |
76 | @@ -120,7 +120,7 @@ |
77 | Package: ubuntu-ui-toolkit-examples |
78 | Section: devel |
79 | Architecture: any |
80 | -Depends: qmlscene, |
81 | +Depends: ubuntu-ui-toolkit-tools (>= ${source:Version}), |
82 | qtdeclarative5-ubuntu-ui-toolkit-plugin (= ${binary:Version}) | qtdeclarative5-ubuntu-ui-toolkit-plugin-gles, |
83 | ubuntu-ui-toolkit-theme (= ${binary:Version}), |
84 | qml-module-qtquick-xmllistmodel | qtdeclarative5-xmllistmodel-plugin, |
85 | @@ -160,3 +160,15 @@ |
86 | qml-module-qttest | qtdeclarative5-test-plugin, |
87 | Description: Test package for Ubuntu UI Toolkit |
88 | Autopilot tests for the ubuntu-ui-toolkit package |
89 | + |
90 | +Package: ubuntu-ui-toolkit-tools |
91 | +Architecture: any |
92 | +Depends: ${misc:Depends}, |
93 | + ${shlibs:Depends} |
94 | +Description: Qt Components for Ubuntu - productive tools |
95 | + Qt Components for Ubuntu offers a set of reusable user interface |
96 | + components for Qt Quick 2 / QML. |
97 | + . |
98 | + This package contains the application launcher, which is a drop-in |
99 | + replacement for qmlscene, oxideqmlscene, qml and derivatives. |
100 | + |
101 | |
102 | === modified file 'debian/ubuntu-ui-toolkit-autopilot.install' |
103 | --- debian/ubuntu-ui-toolkit-autopilot.install 2015-04-29 13:02:11 +0000 |
104 | +++ debian/ubuntu-ui-toolkit-autopilot.install 2015-09-18 16:36:01 +0000 |
105 | @@ -1,3 +1,2 @@ |
106 | usr/lib/python3 |
107 | usr/lib/*/ubuntu-ui-toolkit/apicheck |
108 | -usr/lib/*/ubuntu-ui-toolkit/launcher |
109 | |
110 | === added file 'debian/ubuntu-ui-toolkit-tools.install' |
111 | --- debian/ubuntu-ui-toolkit-tools.install 1970-01-01 00:00:00 +0000 |
112 | +++ debian/ubuntu-ui-toolkit-tools.install 2015-09-18 16:36:01 +0000 |
113 | @@ -0,0 +1,1 @@ |
114 | +usr/bin/ubuntu-ui-toolkit-launcher |
115 | |
116 | === modified file 'examples/ubuntu-ui-toolkit-gallery/gallery' |
117 | --- examples/ubuntu-ui-toolkit-gallery/gallery 2015-08-11 15:42:46 +0000 |
118 | +++ examples/ubuntu-ui-toolkit-gallery/gallery 2015-09-18 16:36:01 +0000 |
119 | @@ -3,4 +3,4 @@ |
120 | . `dirname $0`/../../build_paths.inc |
121 | |
122 | SCRIPT_DIRECTORY=`dirname $0` |
123 | -$BUILD_DIR/tests/launcher/launcher $@ $SCRIPT_DIRECTORY/ubuntu-ui-toolkit-gallery.qml |
124 | +$BUILD_DIR/ubuntu-ui-toolkit-launcher/ubuntu-ui-toolkit-launcher $@ $SCRIPT_DIRECTORY/ubuntu-ui-toolkit-gallery.qml |
125 | |
126 | === modified file 'examples/ubuntu-ui-toolkit-gallery/ubuntu-ui-toolkit-gallery.desktop' |
127 | --- examples/ubuntu-ui-toolkit-gallery/ubuntu-ui-toolkit-gallery.desktop 2014-11-17 11:52:44 +0000 |
128 | +++ examples/ubuntu-ui-toolkit-gallery/ubuntu-ui-toolkit-gallery.desktop 2015-09-18 16:36:01 +0000 |
129 | @@ -1,6 +1,6 @@ |
130 | [Desktop Entry] |
131 | Name=Ubuntu UI Toolkit Gallery |
132 | -Exec=/usr/bin/qmlscene $@ /usr/lib/ubuntu-ui-toolkit/examples/ubuntu-ui-toolkit-gallery/ubuntu-ui-toolkit-gallery.qml |
133 | +Exec=/usr/bin/ubuntu-ui-toolkit-launcher $@ /usr/lib/ubuntu-ui-toolkit/examples/ubuntu-ui-toolkit-gallery/ubuntu-ui-toolkit-gallery.qml |
134 | Terminal=false |
135 | Type=Application |
136 | X-Ubuntu-Touch=true |
137 | |
138 | === modified file 'src/Ubuntu/Components/1.0/Icon.qml' |
139 | --- src/Ubuntu/Components/1.0/Icon.qml 2015-07-24 09:53:20 +0000 |
140 | +++ src/Ubuntu/Components/1.0/Icon.qml 2015-09-18 16:36:01 +0000 |
141 | @@ -55,19 +55,19 @@ |
142 | } |
143 | |
144 | cache: true |
145 | - visible: !colorizedImage.active |
146 | + visible: !colorizedImage.visible |
147 | } |
148 | |
149 | ShaderEffect { |
150 | id: colorizedImage |
151 | + objectName: "shader" |
152 | |
153 | anchors.fill: parent |
154 | - visible: active |
155 | |
156 | // Whether or not a color has been set. |
157 | - property bool active: keyColorOut != Qt.rgba(0.0, 0.0, 0.0, 0.0) |
158 | + visible: image.status == Image.Ready && keyColorOut != Qt.rgba(0.0, 0.0, 0.0, 0.0) |
159 | |
160 | - property Image source: active && image.status == Image.Ready ? image : null |
161 | + property Image source: image |
162 | property color keyColorOut: Qt.rgba(0.0, 0.0, 0.0, 0.0) |
163 | property color keyColorIn: "#808080" |
164 | property real threshold: 0.1 |
165 | |
166 | === modified file 'src/Ubuntu/Components/1.2/TextInputPopover.qml' |
167 | --- src/Ubuntu/Components/1.2/TextInputPopover.qml 2015-08-19 06:55:11 +0000 |
168 | +++ src/Ubuntu/Components/1.2/TextInputPopover.qml 2015-09-18 16:36:01 +0000 |
169 | @@ -83,13 +83,6 @@ |
170 | model: actions.length |
171 | AbstractButton { |
172 | id: button |
173 | - /* |
174 | - Workaround for autopilot used in the text input's context menu to access |
175 | - action.text so we can get the proper button by text, action being not |
176 | - accessible. https://bugs.launchpad.net/autopilot/+bug/1334599 |
177 | - */ |
178 | - // FIXME: AbstractButton has text property, which is getting the action.text, so no need to override! |
179 | - property string text: action.text |
180 | width: Math.max(units.gu(5), implicitWidth) + units.gu(2) |
181 | height: units.gu(6) |
182 | action: actions[modelData] |
183 | |
184 | === modified file 'src/Ubuntu/Components/1.3/PageWrapperUtils.js' |
185 | --- src/Ubuntu/Components/1.3/PageWrapperUtils.js 2015-09-01 11:59:13 +0000 |
186 | +++ src/Ubuntu/Components/1.3/PageWrapperUtils.js 2015-09-18 16:36:01 +0000 |
187 | @@ -73,6 +73,7 @@ |
188 | if (incubator.status != Component.Ready) { |
189 | incubator.onStatusChanged = incubatorStatusChanged; |
190 | } else { |
191 | + pageWrapper.incubator = this; |
192 | incubatorStatusChanged(incubator.status); |
193 | } |
194 | } |
195 | @@ -103,9 +104,15 @@ |
196 | throw new Error("Error while loading page: " + pageComponent.errorString()); |
197 | } else { |
198 | // create the object |
199 | - pageWrapper.incubator = new Incubator(pageWrapper, pageComponent); |
200 | if (synchronous) { |
201 | - pageWrapper.incubator.forceCompletion(); |
202 | + if (pageWrapper.properties) { |
203 | + // initialize the object with the given properties |
204 | + pageWrapper.object = pageComponent.createObject(pageWrapper, pageWrapper.properties); |
205 | + } else { |
206 | + pageWrapper.object = pageComponent.createObject(pageWrapper); |
207 | + } |
208 | + } else { |
209 | + pageWrapper.incubator = new Incubator(pageWrapper, pageComponent); |
210 | } |
211 | pageWrapper.canDestroy = true; |
212 | } |
213 | |
214 | === modified file 'src/Ubuntu/Components/1.3/TextInputPopover.qml' |
215 | --- src/Ubuntu/Components/1.3/TextInputPopover.qml 2015-07-02 23:33:22 +0000 |
216 | +++ src/Ubuntu/Components/1.3/TextInputPopover.qml 2015-09-18 16:36:01 +0000 |
217 | @@ -83,12 +83,6 @@ |
218 | model: actions.length |
219 | AbstractButton { |
220 | id: button |
221 | - /* |
222 | - Workaround for autopilot used in the text input's context menu to access |
223 | - action.text so we can get the proper button by text, action being not |
224 | - accessible. https://bugs.launchpad.net/autopilot/+bug/1334599 |
225 | - */ |
226 | - property string text: action.text |
227 | width: Math.max(units.gu(5), implicitWidth) + units.gu(2) |
228 | height: units.gu(6) |
229 | action: actions[modelData] |
230 | |
231 | === modified file 'src/Ubuntu/Components/Popups/1.2/ActionSelectionPopover.qml' |
232 | --- src/Ubuntu/Components/Popups/1.2/ActionSelectionPopover.qml 2015-04-30 08:32:44 +0000 |
233 | +++ src/Ubuntu/Components/Popups/1.2/ActionSelectionPopover.qml 2015-09-18 16:36:01 +0000 |
234 | @@ -147,8 +147,10 @@ |
235 | onStatusChanged: { |
236 | if (item && status == Loader.Ready) { |
237 | // set model data |
238 | - if (item.hasOwnProperty("action")) |
239 | + if (item.hasOwnProperty("action")) { |
240 | item.action = modelData; |
241 | + item.objectName = item.action.objectName + '_button'; |
242 | + } |
243 | if (item.hasOwnProperty("refModelData")) |
244 | item.refModelData = modelData; |
245 | if (item.hasOwnProperty("modelData")) |
246 | |
247 | === modified file 'src/Ubuntu/Components/Popups/1.2/PopupBase.qml' |
248 | --- src/Ubuntu/Components/Popups/1.2/PopupBase.qml 2015-04-30 08:32:44 +0000 |
249 | +++ src/Ubuntu/Components/Popups/1.2/PopupBase.qml 2015-09-18 16:36:01 +0000 |
250 | @@ -161,6 +161,7 @@ |
251 | } |
252 | |
253 | MouseArea { |
254 | + acceptedButtons: Qt.LeftButton | Qt.MiddleButton | Qt.RightButton |
255 | anchors.fill: __foreground |
256 | onWheel: wheel.accepted = true |
257 | } |
258 | |
259 | === modified file 'src/Ubuntu/Components/Popups/1.3/ActionSelectionPopover.qml' |
260 | --- src/Ubuntu/Components/Popups/1.3/ActionSelectionPopover.qml 2015-05-14 21:32:51 +0000 |
261 | +++ src/Ubuntu/Components/Popups/1.3/ActionSelectionPopover.qml 2015-09-18 16:36:01 +0000 |
262 | @@ -147,8 +147,10 @@ |
263 | onStatusChanged: { |
264 | if (item && status == Loader.Ready) { |
265 | // set model data |
266 | - if (item.hasOwnProperty("action")) |
267 | + if (item.hasOwnProperty("action")) { |
268 | item.action = modelData; |
269 | + item.objectName = item.action.objectName + '_button'; |
270 | + } |
271 | if (item.hasOwnProperty("refModelData")) |
272 | item.refModelData = modelData; |
273 | if (item.hasOwnProperty("modelData")) |
274 | |
275 | === modified file 'src/Ubuntu/Components/Popups/1.3/PopupBase.qml' |
276 | --- src/Ubuntu/Components/Popups/1.3/PopupBase.qml 2015-04-29 08:55:31 +0000 |
277 | +++ src/Ubuntu/Components/Popups/1.3/PopupBase.qml 2015-09-18 16:36:01 +0000 |
278 | @@ -161,6 +161,7 @@ |
279 | } |
280 | |
281 | MouseArea { |
282 | + acceptedButtons: Qt.LeftButton | Qt.MiddleButton | Qt.RightButton |
283 | anchors.fill: __foreground |
284 | onWheel: wheel.accepted = true |
285 | } |
286 | |
287 | === modified file 'src/Ubuntu/Components/Themes/Ambiance/1.3/ListItemStyle.qml' |
288 | --- src/Ubuntu/Components/Themes/Ambiance/1.3/ListItemStyle.qml 2015-09-04 09:32:31 +0000 |
289 | +++ src/Ubuntu/Components/Themes/Ambiance/1.3/ListItemStyle.qml 2015-09-18 16:36:01 +0000 |
290 | @@ -70,7 +70,7 @@ |
291 | } |
292 | |
293 | readonly property real maxItemWidth: parent.width / itemActions.actions.length |
294 | - readonly property real minItemWidth: units.gu(5) // 2GU icon + 2* 1.5GU margin |
295 | + readonly property real minItemWidth: units.gu(6) // 2GU icon + 2* 2GU margin |
296 | |
297 | Repeater { |
298 | model: itemActions.actions |
299 | |
300 | === modified file 'src/Ubuntu/Components/plugin/plugin.cpp' |
301 | --- src/Ubuntu/Components/plugin/plugin.cpp 2015-08-31 15:43:14 +0000 |
302 | +++ src/Ubuntu/Components/plugin/plugin.cpp 2015-09-18 16:36:01 +0000 |
303 | @@ -163,7 +163,9 @@ |
304 | { |
305 | qmlRegisterType<UCAction>(uri, major, minor, "Action"); |
306 | qmlRegisterType<UCActionContext>(uri, major, minor, "ActionContext"); |
307 | + qmlRegisterUncreatableType<UCApplication>(uri, major, minor, "UCApplication", "Not instantiable"); |
308 | qmlRegisterType<UCActionManager>(uri, major, minor, "ActionManager"); |
309 | + qmlRegisterUncreatableType<UCFontUtils>(uri, major, minor, "UCFontUtils", "Not instantiable"); |
310 | qmlRegisterType<UCStyledItemBase>(uri, major, minor, "StyledItem"); |
311 | qmlRegisterUncreatableType<UbuntuI18n>(uri, major, minor, "i18n", "Singleton object"); |
312 | qmlRegisterExtendedType<QQuickImageBase, UCQQuickImageExtension>(uri, major, minor, "QQuickImageBase"); |
313 | |
314 | === modified file 'src/Ubuntu/Components/plugin/privates/listitemdragarea.cpp' |
315 | --- src/Ubuntu/Components/plugin/privates/listitemdragarea.cpp 2015-08-31 15:43:14 +0000 |
316 | +++ src/Ubuntu/Components/plugin/privates/listitemdragarea.cpp 2015-09-18 16:36:01 +0000 |
317 | @@ -123,7 +123,8 @@ |
318 | "No dragging will be possible."); |
319 | } |
320 | if (start) { |
321 | - pViewAttached->buildChangesList(false); |
322 | + // keep the mouse event in house |
323 | + setKeepMouseGrab(true); |
324 | fromIndex = toIndex = index; |
325 | lastPos = pos; |
326 | // create temp drag item |
327 | @@ -152,7 +153,7 @@ |
328 | } |
329 | } |
330 | // unlock flickables |
331 | - pViewAttached->clearChangesList(); |
332 | + setKeepMouseGrab(false); |
333 | // perform drop |
334 | UCListItemPrivate::get(item.data())->dragHandler->drop(); |
335 | item = 0; |
336 | |
337 | === modified file 'src/Ubuntu/Components/plugin/sortfiltermodel.cpp' |
338 | --- src/Ubuntu/Components/plugin/sortfiltermodel.cpp 2015-08-20 17:08:49 +0000 |
339 | +++ src/Ubuntu/Components/plugin/sortfiltermodel.cpp 2015-09-18 16:36:01 +0000 |
340 | @@ -220,8 +220,11 @@ |
341 | { |
342 | QVariantMap res; |
343 | const QHash<int, QByteArray> roles = roleNames(); |
344 | - for(int role = 0; role < roles.count(); role++) |
345 | - res.insert (roles[role], data(row, role)); |
346 | + QHashIterator<int, QByteArray> i(roles); |
347 | + while (i.hasNext()) { |
348 | + i.next(); |
349 | + res.insert(i.value(), data(row, i.key())); |
350 | + } |
351 | return res; |
352 | } |
353 | |
354 | |
355 | === modified file 'src/Ubuntu/Components/plugin/ucactionitem.cpp' |
356 | --- src/Ubuntu/Components/plugin/ucactionitem.cpp 2015-08-25 11:31:29 +0000 |
357 | +++ src/Ubuntu/Components/plugin/ucactionitem.cpp 2015-09-18 16:36:01 +0000 |
358 | @@ -16,6 +16,10 @@ |
359 | |
360 | #include "ucactionitem.h" |
361 | #include "ucaction.h" |
362 | +#include "ucstyleditembase_p.h" |
363 | +#define foreach Q_FOREACH |
364 | +#include <QtQml/private/qqmlbinding_p.h> |
365 | +#undef foreach |
366 | |
367 | /*! |
368 | * \qmltype ActionItem |
369 | @@ -40,8 +44,14 @@ |
370 | , m_action(Q_NULLPTR) |
371 | , m_flags(0) |
372 | { |
373 | - connect(this, &UCActionItem::visibleChanged, this, &UCActionItem::_q_visibleChanged); |
374 | - connect(this, &UCActionItem::enabledChanged, this, &UCActionItem::_q_enabledChanged); |
375 | + connect(this, &UCActionItem::enabledChanged, this, &UCActionItem::enabledChanged2); |
376 | + connect(this, &UCActionItem::visibleChanged, this, &UCActionItem::visibleChanged2); |
377 | +} |
378 | + |
379 | +bool UCActionItem::hasBindingOnProperty(const QString &name) |
380 | +{ |
381 | + QQmlProperty property(this, name, qmlContext(this)); |
382 | + return QQmlPropertyPrivate::binding(property) != Q_NULLPTR; |
383 | } |
384 | |
385 | void UCActionItem::componentComplete() |
386 | @@ -55,40 +65,47 @@ |
387 | } |
388 | } |
389 | |
390 | -void UCActionItem::_q_visibleChanged() |
391 | -{ |
392 | - m_flags |= CustomVisible; |
393 | - disconnect(this, &UCActionItem::visibleChanged, this, &UCActionItem::_q_visibleChanged); |
394 | -} |
395 | - |
396 | -void UCActionItem::_q_enabledChanged() |
397 | -{ |
398 | - m_flags |= CustomEnabled; |
399 | - disconnect(this, &UCActionItem::enabledChanged, this, &UCActionItem::_q_enabledChanged); |
400 | -} |
401 | - |
402 | // update visible property |
403 | -void UCActionItem::_q_updateVisible() |
404 | +void UCActionItem::_q_visibleBinding() |
405 | { |
406 | + if (m_flags & CustomVisible) { |
407 | + return; |
408 | + } |
409 | + if (hasBindingOnProperty(QStringLiteral("visible"))) { |
410 | + m_flags |= CustomEnabled; |
411 | + return; |
412 | + } |
413 | bool visible = m_action ? m_action->m_visible : true; |
414 | setVisible(visible); |
415 | - // reset flag and reconnect signal handler disconnected by the |
416 | - m_flags &= ~CustomVisible; |
417 | - if (m_action) { |
418 | - connect(this, &UCActionItem::visibleChanged, this, &UCActionItem::_q_visibleChanged); |
419 | - } |
420 | } |
421 | |
422 | // update enabled property |
423 | -void UCActionItem::_q_updateEnabled() |
424 | +void UCActionItem::_q_enabledBinding() |
425 | { |
426 | + if (m_flags & CustomEnabled) { |
427 | + return; |
428 | + } |
429 | + if (hasBindingOnProperty(QStringLiteral("enabled"))) { |
430 | + m_flags |= CustomEnabled; |
431 | + return; |
432 | + } |
433 | bool enabled = m_action ? m_action->m_enabled : true; |
434 | setEnabled(enabled); |
435 | - // reset flag and reconnect signal handler disconnected by the |
436 | - m_flags &= ~CustomEnabled; |
437 | - if (m_action) { |
438 | - connect(this, &UCActionItem::enabledChanged, this, &UCActionItem::_q_enabledChanged); |
439 | - } |
440 | +} |
441 | + |
442 | +// setter called when bindings from QML set the value. Internal functions will |
443 | +// all use the setVisible setter, so initialization and (re)parenting related |
444 | +// visible alteration won't set the custom flag |
445 | +void UCActionItem::setVisible2(bool visible) |
446 | +{ |
447 | + // set the custom flag and forward the value to the original proepry setter |
448 | + m_flags |= CustomVisible; |
449 | + setVisible(visible); |
450 | +} |
451 | +void UCActionItem::setEnabled2(bool enabled) |
452 | +{ |
453 | + m_flags |= CustomEnabled; |
454 | + setEnabled(enabled); |
455 | } |
456 | |
457 | void UCActionItem::updateProperties() |
458 | @@ -109,10 +126,14 @@ |
459 | if (attach) { |
460 | connect(this, SIGNAL(triggered(QVariant)), |
461 | m_action, SLOT(trigger(QVariant)), Qt::DirectConnection); |
462 | - connect(m_action, &UCAction::visibleChanged, |
463 | - this, &UCActionItem::_q_updateVisible, Qt::DirectConnection); |
464 | - connect(m_action, &UCAction::enabledChanged, |
465 | - this, &UCActionItem::_q_updateEnabled, Qt::DirectConnection); |
466 | + if (!(m_flags & CustomVisible)) { |
467 | + connect(m_action, &UCAction::visibleChanged, |
468 | + this, &UCActionItem::_q_visibleBinding, Qt::DirectConnection); |
469 | + } |
470 | + if (!(m_flags & CustomEnabled)) { |
471 | + connect(m_action, &UCAction::enabledChanged, |
472 | + this, &UCActionItem::_q_enabledBinding, Qt::DirectConnection); |
473 | + } |
474 | if (!(m_flags & CustomText)) { |
475 | connect(m_action, &UCAction::textChanged, |
476 | this, &UCActionItem::textChanged, Qt::DirectConnection); |
477 | @@ -128,10 +149,14 @@ |
478 | } else { |
479 | disconnect(this, SIGNAL(triggered(QVariant)), |
480 | m_action, SLOT(trigger(QVariant))); |
481 | - disconnect(m_action, &UCAction::visibleChanged, |
482 | - this, &UCActionItem::_q_updateVisible); |
483 | - disconnect(m_action, &UCAction::enabledChanged, |
484 | - this, &UCActionItem::_q_updateEnabled); |
485 | + if (!(m_flags & CustomVisible)) { |
486 | + disconnect(m_action, &UCAction::visibleChanged, |
487 | + this, &UCActionItem::_q_visibleBinding); |
488 | + } |
489 | + if (!(m_flags & CustomEnabled)) { |
490 | + disconnect(m_action, &UCAction::enabledChanged, |
491 | + this, &UCActionItem::_q_enabledBinding); |
492 | + } |
493 | if (!(m_flags & CustomText)) { |
494 | disconnect(m_action, &UCAction::textChanged, |
495 | this, &UCActionItem::textChanged); |
496 | @@ -167,8 +192,8 @@ |
497 | if (m_action) { |
498 | attachAction(true); |
499 | } |
500 | - _q_updateVisible(); |
501 | - _q_updateEnabled(); |
502 | + _q_visibleBinding(); |
503 | + _q_enabledBinding(); |
504 | updateProperties(); |
505 | } |
506 | |
507 | |
508 | === modified file 'src/Ubuntu/Components/plugin/ucactionitem.h' |
509 | --- src/Ubuntu/Components/plugin/ucactionitem.h 2015-08-25 11:31:29 +0000 |
510 | +++ src/Ubuntu/Components/plugin/ucactionitem.h 2015-09-18 16:36:01 +0000 |
511 | @@ -26,6 +26,10 @@ |
512 | Q_PROPERTY(QString text READ text WRITE setText RESET resetText NOTIFY textChanged) |
513 | Q_PROPERTY(QUrl iconSource READ iconSource WRITE setIconSource RESET resetIconSource NOTIFY iconSourceChanged) |
514 | Q_PROPERTY(QString iconName READ iconName WRITE setIconName RESET resetIconName NOTIFY iconNameChanged) |
515 | + |
516 | + // overrides |
517 | + Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled2 NOTIFY enabledChanged2) |
518 | + Q_PROPERTY(bool visible READ isVisible WRITE setVisible2 NOTIFY visibleChanged2 FINAL) |
519 | public: |
520 | explicit UCActionItem(QQuickItem *parent = 0); |
521 | |
522 | @@ -40,6 +44,9 @@ |
523 | void setIconName(const QString &iconName); |
524 | void resetIconName(); |
525 | |
526 | + void setVisible2(bool visible); |
527 | + void setEnabled2(bool enabled); |
528 | + |
529 | Q_SIGNALS: |
530 | void actionChanged(); |
531 | void textChanged(); |
532 | @@ -47,14 +54,15 @@ |
533 | void iconNameChanged(); |
534 | void triggered(const QVariant &value); |
535 | |
536 | + void enabledChanged2(); |
537 | + void visibleChanged2(); |
538 | + |
539 | public Q_SLOTS: |
540 | void trigger(const QVariant &value = QVariant()); |
541 | |
542 | protected Q_SLOTS: |
543 | - void _q_visibleChanged(); |
544 | - void _q_enabledChanged(); |
545 | - void _q_updateVisible(); |
546 | - void _q_updateEnabled(); |
547 | + void _q_visibleBinding(); |
548 | + void _q_enabledBinding(); |
549 | |
550 | protected: |
551 | enum { |
552 | @@ -72,6 +80,7 @@ |
553 | |
554 | void componentComplete(); |
555 | |
556 | + bool hasBindingOnProperty(const QString &name); |
557 | void updateProperties(); |
558 | void attachAction(bool attach); |
559 | }; |
560 | |
561 | === modified file 'src/Ubuntu/Components/plugin/uclistitem.cpp' |
562 | --- src/Ubuntu/Components/plugin/uclistitem.cpp 2015-09-04 09:32:31 +0000 |
563 | +++ src/Ubuntu/Components/plugin/uclistitem.cpp 2015-09-18 16:36:01 +0000 |
564 | @@ -474,7 +474,7 @@ |
565 | if (parentAttached) { |
566 | Q_Q(UCListItem); |
567 | // restore flickable's interactive and cleanup |
568 | - parentAttached->disableInteractive(q, false); |
569 | + q->setKeepMouseGrab(false); |
570 | // no need to listen flickables any longer |
571 | listenToRebind(false); |
572 | } |
573 | @@ -1123,7 +1123,7 @@ |
574 | |
575 | // grabs the left mouse button event by turning highlight on, and triggering |
576 | // swipe events; child items should no longer get mouse events |
577 | -void UCListItemPrivate::grabLeftButtonEvents(QMouseEvent *event) |
578 | +void UCListItemPrivate::handleLeftButtonPress(QMouseEvent *event) |
579 | { |
580 | Q_Q(UCListItem); |
581 | button = event->button(); |
582 | @@ -1133,11 +1133,15 @@ |
583 | lastPos = pressedPos = event->localPos(); |
584 | // connect the Flickable to know when to rebound |
585 | listenToRebind(true); |
586 | - if (swiped && parentAttached) { |
587 | - parentAttached->disableInteractive(q, true); |
588 | + if (swiped) { |
589 | + // grab now, and ungrab in snapOut |
590 | + q->setKeepMouseGrab(true); |
591 | + q->grabMouse(); |
592 | } |
593 | // stop any ongoing animation! |
594 | swipeEvent(event->localPos(), UCSwipeEvent::Started); |
595 | + // accept the event so we get the rest of the events as well |
596 | + event->accept(); |
597 | } |
598 | |
599 | void UCListItem::mousePressEvent(QMouseEvent *event) |
600 | @@ -1150,10 +1154,8 @@ |
601 | return; |
602 | } |
603 | if (d->canHighlight() && !d->highlighted && event->button() == Qt::LeftButton) { |
604 | - d->grabLeftButtonEvents(event); |
605 | + d->handleLeftButtonPress(event); |
606 | } |
607 | - // accept the event so we get the rest of the events as well |
608 | - event->setAccepted(true); |
609 | } |
610 | |
611 | bool UCListItem13::shouldShowContextMenu(QMouseEvent *event) |
612 | @@ -1203,15 +1205,16 @@ |
613 | } |
614 | |
615 | // ungrabs any previously grabbed left mouse button event |
616 | -void UCListItemPrivate::ungrabLeftButtonEvents(QMouseEvent *event) |
617 | +void UCListItemPrivate::handleLeftButtonRelease(QMouseEvent *event) |
618 | { |
619 | Q_Q(UCListItem); |
620 | // set released |
621 | if (highlighted) { |
622 | // unblock ascending Flickables |
623 | listenToRebind(false); |
624 | - if (parentAttached) { |
625 | - parentAttached->disableInteractive(q, false); |
626 | + q->setKeepMouseGrab(false); |
627 | + if (window && window->mouseGrabberItem() == q) { |
628 | + q->ungrabMouse(); |
629 | } |
630 | |
631 | if (!suppressClick) { |
632 | @@ -1231,15 +1234,14 @@ |
633 | } |
634 | } |
635 | button = Qt::NoButton; |
636 | + event->accept(); |
637 | } |
638 | |
639 | void UCListItem::mouseReleaseEvent(QMouseEvent *event) |
640 | { |
641 | UCStyledItemBase::mouseReleaseEvent(event); |
642 | Q_D(UCListItem); |
643 | - d->ungrabLeftButtonEvents(event); |
644 | - // make sure we ungrab the mouse! |
645 | - ungrabMouse(); |
646 | + d->handleLeftButtonRelease(event); |
647 | } |
648 | |
649 | void UCListItem13::mouseReleaseEvent(QMouseEvent *event) |
650 | @@ -1275,9 +1277,7 @@ |
651 | if (d->swipedOverThreshold(event->localPos(), d->pressedPos)) { |
652 | // the press went out of the threshold area, enable move, if the direction allows it |
653 | d->lastPos = event->localPos(); |
654 | - if (d->parentAttached) { |
655 | - d->parentAttached->disableInteractive(this, true); |
656 | - } |
657 | + setKeepMouseGrab(true); |
658 | qreal mouseX = event->localPos().x(); |
659 | qreal pressedX = d->pressedPos.x(); |
660 | bool doSwipe = (d->leadingActions && (mouseX > pressedX)) || |
661 | @@ -1298,42 +1298,81 @@ |
662 | } |
663 | } |
664 | |
665 | +bool UCListItemPrivate::sendMouseEvent(QQuickItem *item, QMouseEvent *event) |
666 | +{ |
667 | + Q_UNUSED(item); |
668 | + Q_Q(UCListItem); |
669 | + QQuickItem *grabber = window ? window->mouseGrabberItem() : Q_NULLPTR; |
670 | + if (grabber == q) { |
671 | + // already the grabber, return |
672 | + return true; |
673 | + } |
674 | + |
675 | + bool consumed = false; |
676 | + if (contentItem->contains(contentItem->mapFromScene(event->windowPos()))) { |
677 | + QPointF localPos = q->mapFromScene(event->windowPos()); |
678 | + |
679 | + switch (event->type()) { |
680 | + case QEvent::MouseButtonPress: { |
681 | + // remember pressed point over active areas |
682 | + if (event->button() == Qt::LeftButton) { |
683 | + if (swiped) { |
684 | + // handle as full press and grab the event from the children |
685 | + QScopedPointer<QMouseEvent> mouseEvent(QQuickWindowPrivate::cloneMouseEvent(event, &localPos)); |
686 | + handleLeftButtonPress(mouseEvent.data()); |
687 | + consumed = true; |
688 | + } else { |
689 | + // remember the position |
690 | + pressedPos = localPos; |
691 | + button = event->button(); |
692 | + } |
693 | + } |
694 | + break; |
695 | + } |
696 | + case QEvent::MouseButtonRelease: { |
697 | + QScopedPointer<QMouseEvent> mouseEvent(QQuickWindowPrivate::cloneMouseEvent(event, &localPos)); |
698 | + handleLeftButtonRelease(mouseEvent.data()); |
699 | + suppressClick = false; |
700 | + break; |
701 | + } |
702 | + case QEvent::MouseMove: { |
703 | + if ((button == Qt::LeftButton) && swipedOverThreshold(localPos, pressedPos) && !highlighted) { |
704 | + // grab the event from the child, so the click doesn't happen anymore, and initiate swiping |
705 | + QMouseEvent pressed(QEvent::MouseButtonPress, localPos, event->windowPos(), event->screenPos(), |
706 | + Qt::LeftButton, event->buttons(), event->modifiers()); |
707 | + handleLeftButtonPress(&pressed); |
708 | + // grab any further events so all land in the list item |
709 | + q->setKeepMouseGrab(true); |
710 | + q->grabMouse(); |
711 | + consumed = true; |
712 | + } |
713 | + break; |
714 | + } |
715 | + default: break; |
716 | + } |
717 | + } |
718 | + |
719 | + return consumed; |
720 | +} |
721 | + |
722 | bool UCListItem::childMouseEventFilter(QQuickItem *child, QEvent *event) |
723 | { |
724 | - QEvent::Type type = event->type(); |
725 | + if (!isVisible() || !isEnabled()) { |
726 | + return UCStyledItemBase::childMouseEventFilter(child, event); |
727 | + } |
728 | + |
729 | Q_D(UCListItem); |
730 | - if (type == QEvent::MouseButtonPress) { |
731 | - // suppress click event if pressed over an active area, except Text, which can also handle |
732 | - // mouse clicks when content is an URL |
733 | - QMouseEvent *mouse = static_cast<QMouseEvent*>(event); |
734 | - if (child->isEnabled() && (child->acceptedMouseButtons() & mouse->button()) && !qobject_cast<QQuickText*>(child)) { |
735 | - // suppress click |
736 | - d->suppressClick = true; |
737 | - // listen for flickable to be able to rebind if movement started there! |
738 | - d->listenToRebind(true); |
739 | - // if left button pressed, remember the position |
740 | - if (mouse->button() == Qt::LeftButton) { |
741 | - d->pressedPos = mapFromItem(child, mouse->localPos()); |
742 | - d->button = mouse->button(); |
743 | - } |
744 | - } |
745 | - } else if (type == QEvent::MouseButtonRelease) { |
746 | - Q_D(UCListItem); |
747 | - d->suppressClick = false; |
748 | - } else if (type == QEvent::MouseMove) { |
749 | - QMouseEvent *mouse = static_cast<QMouseEvent*>(event); |
750 | - const QPointF localPos = mapFromItem(child, mouse->localPos()); |
751 | - if ((mouse->buttons() & Qt::LeftButton) && d->swipedOverThreshold(localPos, d->pressedPos) && !d->highlighted) { |
752 | - // grab the event from the child, so the click doesn't happen anymore, and initiate swiping |
753 | - QMouseEvent pressed(QEvent::MouseButtonPress, localPos, mouse->windowPos(), mouse->screenPos(), |
754 | - Qt::LeftButton, mouse->buttons(), mouse->modifiers()); |
755 | - d->grabLeftButtonEvents(&pressed); |
756 | - // stop click and pressAndHold, then grab the mouse so children do not get the mouse events anymore |
757 | - d->suppressClick = true; |
758 | - d->pressAndHoldTimer.stop(); |
759 | - grabMouse(); |
760 | - } |
761 | - } |
762 | + switch (event->type()) { |
763 | + case QEvent::MouseButtonPress: |
764 | + case QEvent::MouseMove: |
765 | + case QEvent::MouseButtonRelease: { |
766 | + if (d->sendMouseEvent(child, static_cast<QMouseEvent*>(event))) { |
767 | + return true; |
768 | + } |
769 | + } |
770 | + default: break; |
771 | + } |
772 | + |
773 | return UCStyledItemBase::childMouseEventFilter(child, event); |
774 | } |
775 | |
776 | |
777 | === modified file 'src/Ubuntu/Components/plugin/uclistitem.h' |
778 | --- src/Ubuntu/Components/plugin/uclistitem.h 2015-09-04 09:32:31 +0000 |
779 | +++ src/Ubuntu/Components/plugin/uclistitem.h 2015-09-18 16:36:01 +0000 |
780 | @@ -180,7 +180,6 @@ |
781 | static UCViewItemsAttached *qmlAttachedProperties(QObject *owner); |
782 | |
783 | bool listenToRebind(UCListItem *item, bool listen); |
784 | - void disableInteractive(UCListItem *item, bool disable); |
785 | bool isMoving(); |
786 | bool isBoundTo(UCListItem *item); |
787 | |
788 | |
789 | === modified file 'src/Ubuntu/Components/plugin/uclistitem_p.h' |
790 | --- src/Ubuntu/Components/plugin/uclistitem_p.h 2015-09-01 07:16:59 +0000 |
791 | +++ src/Ubuntu/Components/plugin/uclistitem_p.h 2015-09-18 16:36:01 +0000 |
792 | @@ -68,8 +68,9 @@ |
793 | void snapOut(); |
794 | void swipeEvent(const QPointF &localPos, UCSwipeEvent::Status status); |
795 | bool swipedOverThreshold(const QPointF &mousePos, const QPointF relativePos); |
796 | - void grabLeftButtonEvents(QMouseEvent *event); |
797 | - void ungrabLeftButtonEvents(QMouseEvent *event); |
798 | + void handleLeftButtonPress(QMouseEvent *event); |
799 | + void handleLeftButtonRelease(QMouseEvent *event); |
800 | + bool sendMouseEvent(QQuickItem *item, QMouseEvent *event); |
801 | |
802 | quint16 defaultThemeVersion; |
803 | bool highlighted:1; |
804 | @@ -138,8 +139,6 @@ |
805 | |
806 | void clearFlickablesList(); |
807 | void buildFlickablesList(); |
808 | - void clearChangesList(); |
809 | - void buildChangesList(const QVariant &newValue); |
810 | bool addSelectedItem(UCListItem *item); |
811 | bool removeSelectedItem(UCListItem *item); |
812 | bool isItemSelected(UCListItem *item); |
813 | @@ -157,13 +156,10 @@ |
814 | QSet<int> selectedList; |
815 | QMap<int, QPointer<UCListItem13> > expansionList; |
816 | QList< QPointer<QQuickFlickable> > flickables; |
817 | - QList< PropertyChange* > changes; |
818 | QPointer<UCListItem> boundItem; |
819 | - QPointer<UCListItem> disablerItem; |
820 | QQuickFlickable *listView; |
821 | ListItemDragArea *dragArea; |
822 | UCViewItemsAttached::ExpansionFlags expansionFlags; |
823 | - bool globalDisabled:1; |
824 | bool selectable:1; |
825 | bool draggable:1; |
826 | bool ready:1; |
827 | |
828 | === modified file 'src/Ubuntu/Components/plugin/ucviewitemsattached.cpp' |
829 | --- src/Ubuntu/Components/plugin/ucviewitemsattached.cpp 2015-09-04 08:55:29 +0000 |
830 | +++ src/Ubuntu/Components/plugin/ucviewitemsattached.cpp 2015-09-18 16:36:01 +0000 |
831 | @@ -105,7 +105,6 @@ |
832 | , listView(0) |
833 | , dragArea(0) |
834 | , expansionFlags(UCViewItemsAttached::Exclusive) |
835 | - , globalDisabled(false) |
836 | , selectable(false) |
837 | , draggable(false) |
838 | , ready(false) |
839 | @@ -114,7 +113,6 @@ |
840 | |
841 | UCViewItemsAttachedPrivate::~UCViewItemsAttachedPrivate() |
842 | { |
843 | - clearChangesList(); |
844 | clearFlickablesList(); |
845 | } |
846 | |
847 | @@ -155,33 +153,6 @@ |
848 | } |
849 | } |
850 | |
851 | -void UCViewItemsAttachedPrivate::clearChangesList() |
852 | -{ |
853 | - // clear property change objects |
854 | - qDeleteAll(changes); |
855 | - changes.clear(); |
856 | -} |
857 | - |
858 | -void UCViewItemsAttachedPrivate::buildChangesList(const QVariant &newValue) |
859 | -{ |
860 | - // collect all ascendant flickables |
861 | - Q_Q(UCViewItemsAttached); |
862 | - QQuickItem *item = qobject_cast<QQuickItem*>(q->parent()); |
863 | - if (!item) { |
864 | - return; |
865 | - } |
866 | - clearChangesList(); |
867 | - while (item) { |
868 | - QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(item); |
869 | - if (flickable) { |
870 | - PropertyChange *change = new PropertyChange(item, "interactive"); |
871 | - PropertyChange::setValue(change, newValue); |
872 | - changes << change; |
873 | - } |
874 | - item = item->parentItem(); |
875 | - } |
876 | -} |
877 | - |
878 | /*! |
879 | * \qmltype ViewItems |
880 | * \instantiates UCViewItemsAttached |
881 | @@ -252,41 +223,6 @@ |
882 | return d->boundItem == item; |
883 | } |
884 | |
885 | -/* |
886 | - * Disable/enable interactive flag for the ascendant flickables. The item is used |
887 | - * to detect whether the same item is trying to enable the flickables which disabled |
888 | - * it before. The enabled/disabled states are not equivalent to the enabled/disabled |
889 | - * state of the interactive flag. |
890 | - * When disabled, always the last item disabling will be kept as active disabler, |
891 | - * and only the active disabler can enable (restore) the interactive flag state. |
892 | - */ |
893 | -void UCViewItemsAttached::disableInteractive(UCListItem *item, bool disable) |
894 | -{ |
895 | - Q_D(UCViewItemsAttached); |
896 | - if (disable) { |
897 | - // disabling or re-disabling |
898 | - d->disablerItem = item; |
899 | - if (d->globalDisabled == disable) { |
900 | - // was already disabled, leave |
901 | - return; |
902 | - } |
903 | - d->globalDisabled = true; |
904 | - } else if (d->globalDisabled && d->disablerItem == item) { |
905 | - // the one disabled it will enable |
906 | - d->globalDisabled = false; |
907 | - d->disablerItem.clear(); |
908 | - } else { |
909 | - // !disabled && (!globalDisabled || item != d->disablerItem) |
910 | - return; |
911 | - } |
912 | - if (disable) { |
913 | - // (re)build changes list with disabling the interactive value |
914 | - d->buildChangesList(false); |
915 | - } else { |
916 | - d->clearChangesList(); |
917 | - } |
918 | -} |
919 | - |
920 | void UCViewItemsAttached::unbindItem() |
921 | { |
922 | Q_D(UCViewItemsAttached); |
923 | |
924 | === modified file 'tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/popups.py' |
925 | --- tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/popups.py 2015-09-07 13:46:58 +0000 |
926 | +++ tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/popups.py 2015-09-18 16:36:01 +0000 |
927 | @@ -81,16 +81,37 @@ |
928 | class ActionSelectionPopover(_common.UbuntuUIToolkitCustomProxyObjectBase): |
929 | """ActionSelectionPopover Autopilot custom proxy object.""" |
930 | |
931 | + def click_action_button(self, action_object_name): |
932 | + """Click an action button on the popover. |
933 | + |
934 | + :parameter object_name: The QML objectName property of the action |
935 | + :raise ToolkitException: If there is no visible button with that object |
936 | + name or the popover is not open. |
937 | + |
938 | + """ |
939 | + |
940 | + if not self.visible: |
941 | + raise _common.ToolkitException('The popover is not open.') |
942 | + try: |
943 | + object_name = action_object_name + "_button" |
944 | + button = self.select_single(objectName=object_name) |
945 | + except dbus.StateNotFoundError: |
946 | + raise _common.ToolkitException( |
947 | + 'Action with objectName "{0}" not found.'.format(object_name)) |
948 | + self.pointing_device.click_object(button) |
949 | + if self.autoClose: |
950 | + try: |
951 | + self.visible.wait_for(False) |
952 | + except dbus.StateNotFoundError: |
953 | + # The popover was removed from the tree. |
954 | + pass |
955 | + |
956 | def click_button_by_text(self, text): |
957 | """Click a button on the popover. |
958 | |
959 | - XXX We are receiving the text because there's no way to set the |
960 | - objectName on the action. This is reported at |
961 | - https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1205144 |
962 | - --elopio - 2013-07-25 |
963 | - |
964 | :parameter text: The text of the button. |
965 | - :raise ToolkitException: If the popover is not open. |
966 | + :raise ToolkitException: If there is no visible button with that label |
967 | + or the popover is not open. |
968 | |
969 | """ |
970 | if not self.visible: |
971 | |
972 | === modified file 'tests/autopilot/ubuntuuitoolkit/base.py' |
973 | --- tests/autopilot/ubuntuuitoolkit/base.py 2015-04-14 21:02:06 +0000 |
974 | +++ tests/autopilot/ubuntuuitoolkit/base.py 2015-09-18 16:36:01 +0000 |
975 | @@ -61,13 +61,12 @@ |
976 | def get_toolkit_launcher_command(): |
977 | root = ubuntuuitoolkit.tests.get_path_to_build_root() |
978 | path_to_local_launcher = os.path.join( |
979 | - root, 'tests', 'launcher', 'launcher') |
980 | + root, 'ubuntu-ui-toolkit-launcher', 'ubuntu-ui-toolkit-launcher') |
981 | if os.path.exists(path_to_local_launcher): |
982 | return path_to_local_launcher |
983 | else: |
984 | - arch = ubuntuuitoolkit.base.get_host_multiarch() |
985 | path_to_installed_launcher = os.path.join( |
986 | - '/', 'usr', 'lib', arch, 'ubuntu-ui-toolkit', 'launcher') |
987 | + '/', 'usr', 'bin', 'ubuntu-ui-toolkit-launcher') |
988 | return path_to_installed_launcher |
989 | |
990 | |
991 | |
992 | === modified file 'tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_popups.py' |
993 | --- tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_popups.py 2015-04-14 21:02:06 +0000 |
994 | +++ tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_popups.py 2015-09-18 16:36:01 +0000 |
995 | @@ -51,19 +51,30 @@ |
996 | actions: ActionList { |
997 | Action { |
998 | text: "Action one" |
999 | + objectName: "actionOne" |
1000 | onTriggered: label.text = "Button clicked." |
1001 | + }, |
1002 | + Action { |
1003 | + text: "Action two" |
1004 | + objectName: "actionDisabled" |
1005 | + onTriggered: label.text = "Disabled button clicked." |
1006 | + }, |
1007 | + Action { |
1008 | + text: "Action three" |
1009 | + objectName: "actionHidden" |
1010 | + onTriggered: label.text = "Hidden button clicked." |
1011 | } |
1012 | } |
1013 | } |
1014 | } |
1015 | """) |
1016 | |
1017 | - def test_action_selection_popover_custom_proxy_object(self): |
1018 | + def test_custom_proxy_object(self): |
1019 | popover = self.main_view.get_action_selection_popover( |
1020 | 'test_actions_popover') |
1021 | self.assertIsInstance(popover, popups.ActionSelectionPopover) |
1022 | |
1023 | - def test_click_action_select_popover_button(self): |
1024 | + def test_click_button_by_label(self): |
1025 | label = self.app.select_single('Label', objectName='clicked_label') |
1026 | self.assertNotEqual(label.text, 'Button clicked.') |
1027 | self._open_popover() |
1028 | @@ -72,6 +83,49 @@ |
1029 | popover.click_button_by_text('Action one') |
1030 | self.assertEqual(label.text, 'Button clicked.') |
1031 | |
1032 | + def test_click_button_by_object_name(self): |
1033 | + label = self.app.select_single('Label', objectName='clicked_label') |
1034 | + self.assertNotEqual(label.text, 'Button clicked.') |
1035 | + self._open_popover() |
1036 | + popover = self.main_view.get_action_selection_popover( |
1037 | + 'test_actions_popover') |
1038 | + popover.click_action_button('actionOne') |
1039 | + self.assertEqual(label.text, 'Button clicked.') |
1040 | + |
1041 | + def test_click_unexisting_button_by_object_name(self): |
1042 | + self._open_popover() |
1043 | + popover = self.main_view.get_action_selection_popover( |
1044 | + 'test_actions_popover') |
1045 | + error = self.assertRaises( |
1046 | + ubuntuuitoolkit.ToolkitException, |
1047 | + popover.click_action_button, 'actionTwo') |
1048 | + self.assertEqual( |
1049 | + str(error), |
1050 | + 'Action with objectName "actionTwo" not found.') |
1051 | + |
1052 | + def test_click_disabled_button_by_object_name(self): |
1053 | + self._open_popover() |
1054 | + popover = self.main_view.get_action_selection_popover( |
1055 | + 'test_actions_popover') |
1056 | + # Disabled actions are not shown in ActionSelectionPopover |
1057 | + error = self.assertRaises( |
1058 | + ubuntuuitoolkit.ToolkitException, |
1059 | + popover.click_action_button, 'actionDisabled') |
1060 | + self.assertEqual( |
1061 | + str(error), |
1062 | + 'Action with objectName "actionDisabled" not found.') |
1063 | + |
1064 | + def test_click_hidden_button_by_object_name(self): |
1065 | + self._open_popover() |
1066 | + popover = self.main_view.get_action_selection_popover( |
1067 | + 'test_actions_popover') |
1068 | + error = self.assertRaises( |
1069 | + ubuntuuitoolkit.ToolkitException, |
1070 | + popover.click_action_button, 'actionHidden') |
1071 | + self.assertEqual( |
1072 | + str(error), |
1073 | + 'Action with objectName "actionHidden" not found.') |
1074 | + |
1075 | def _open_popover(self): |
1076 | open_button = self.main_view.select_single( |
1077 | 'Button', objectName='open_popover') |
1078 | |
1079 | === modified file 'tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_tabs.TabsTestCase.deprecated_TabBar.1.3.qml' |
1080 | --- tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_tabs.TabsTestCase.deprecated_TabBar.1.3.qml 2015-09-07 15:46:58 +0000 |
1081 | +++ tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_tabs.TabsTestCase.deprecated_TabBar.1.3.qml 2015-09-18 16:36:01 +0000 |
1082 | @@ -20,7 +20,6 @@ |
1083 | MainView { |
1084 | width: units.gu(70) |
1085 | height: units.gu(60) |
1086 | - useDeprecatedToolbar: true |
1087 | objectName: "mainView" |
1088 | |
1089 | Tabs { |
1090 | @@ -29,33 +28,33 @@ |
1091 | objectName: "tab1" |
1092 | title: "Tab1" |
1093 | Page { |
1094 | - tools: ToolbarItems { |
1095 | - ToolbarButton { |
1096 | + head.actions: [ |
1097 | + Action { |
1098 | text: "Test1" |
1099 | } |
1100 | - } |
1101 | + ] |
1102 | } |
1103 | } |
1104 | Tab { |
1105 | objectName: "tab2" |
1106 | title: "Tab2" |
1107 | Page { |
1108 | - tools: ToolbarItems { |
1109 | - ToolbarButton { |
1110 | + head.actions: [ |
1111 | + Action { |
1112 | text: "Test2" |
1113 | } |
1114 | - } |
1115 | + ] |
1116 | } |
1117 | } |
1118 | Tab { |
1119 | objectName: "tab3" |
1120 | title: "Tab3" |
1121 | Page { |
1122 | - tools: ToolbarItems { |
1123 | - ToolbarButton { |
1124 | + head.actions: [ |
1125 | + Action { |
1126 | text: "Test3" |
1127 | } |
1128 | - } |
1129 | + ] |
1130 | } |
1131 | } |
1132 | } |
1133 | |
1134 | === modified file 'tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_tabs.py' |
1135 | --- tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_tabs.py 2015-09-07 15:46:58 +0000 |
1136 | +++ tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_tabs.py 2015-09-18 16:36:01 +0000 |
1137 | @@ -28,10 +28,12 @@ |
1138 | dir_path = os.path.dirname(path) |
1139 | deprecated_tabbar_test_qml_file_path = os.path.join( |
1140 | dir_path, 'test_tabs.TabsTestCase.deprecated_TabBar.qml') |
1141 | - deprecated_tabbar_test_qml_file_path = os.path.join( |
1142 | + deprecated_tabbar_1_3_test_qml_file_path = os.path.join( |
1143 | dir_path, 'test_tabs.TabsTestCase.deprecated_TabBar.1.3.qml') |
1144 | new_header_test_qml_file_path = os.path.join( |
1145 | dir_path, 'test_tabs.TabsTestCase.new_header.qml') |
1146 | + new_header_1_3_test_qml_file_path = os.path.join( |
1147 | + dir_path, 'test_tabs.TabsTestCase.new_header.1.3.qml') |
1148 | |
1149 | scenarios = [ |
1150 | ('deprecated TabBar', |
1151 | @@ -39,7 +41,7 @@ |
1152 | ('deprecated TabBar 1.3', |
1153 | dict(test_qml_file_path=deprecated_tabbar_1_3_test_qml_file_path)), |
1154 | ('new header', |
1155 | - dict(test_qml_file_path=new_header_test_qml_file_path)) |
1156 | + dict(test_qml_file_path=new_header_test_qml_file_path)), |
1157 | ('new header 1.3', |
1158 | dict(test_qml_file_path=new_header_1_3_test_qml_file_path)) |
1159 | ] |
1160 | |
1161 | === modified file 'tests/autopilot/ubuntuuitoolkit/tests/gallery/test_gallery.py' |
1162 | --- tests/autopilot/ubuntuuitoolkit/tests/gallery/test_gallery.py 2014-07-07 14:43:52 +0000 |
1163 | +++ tests/autopilot/ubuntuuitoolkit/tests/gallery/test_gallery.py 2015-09-18 16:36:01 +0000 |
1164 | @@ -107,15 +107,16 @@ |
1165 | ubuntu_scenarios.get_device_simulation_scenarios(), |
1166 | pages_scenarios) |
1167 | |
1168 | - def test_open_page(self): |
1169 | - self.open_page(self.element_name) |
1170 | - element = self.main_view.select_single( |
1171 | - 'Standard', objectName=self.element_name) |
1172 | - self.checkPageHeader(element.text) |
1173 | - if self.template_name == 'textinputsTemplate': |
1174 | - page_type = 'TextInputs' |
1175 | - else: |
1176 | - page_type = 'Template' |
1177 | - self.main_view.wait_select_single( |
1178 | - page_type, objectName=self.template_name) |
1179 | - # TODO check that the template is visible. --elopio - 2013-11-28 |
1180 | + # --- THIS TEST CRASHES THE WHOLE UITK TEST PLAN |
1181 | + # def test_open_page(self): |
1182 | + # self.open_page(self.element_name) |
1183 | + # element = self.main_view.select_single( |
1184 | + # 'Standard', objectName=self.element_name) |
1185 | + # self.checkPageHeader(element.text) |
1186 | + # if self.template_name == 'textinputsTemplate': |
1187 | + # page_type = 'TextInputs' |
1188 | + # else: |
1189 | + # page_type = 'Template' |
1190 | + # self.main_view.wait_select_single( |
1191 | + # page_type, objectName=self.template_name) |
1192 | + # TODO check that the template is visible. --elopio - 2013-11-28 |
1193 | |
1194 | === modified file 'tests/resources/listitems/ListItemTest.qml' |
1195 | --- tests/resources/listitems/ListItemTest.qml 2015-07-30 13:27:32 +0000 |
1196 | +++ tests/resources/listitems/ListItemTest.qml 2015-09-18 16:36:01 +0000 |
1197 | @@ -15,8 +15,8 @@ |
1198 | */ |
1199 | |
1200 | import QtQuick 2.4 |
1201 | -import Ubuntu.Components 1.3 |
1202 | -import Ubuntu.Components.Styles 1.3 |
1203 | +import Ubuntu.Components 1.2 |
1204 | +import Ubuntu.Components.Styles 1.2 |
1205 | import QtQuick.Layouts 1.1 |
1206 | |
1207 | MainView { |
1208 | @@ -263,6 +263,11 @@ |
1209 | Label { |
1210 | text: modelData + " Flickable item" |
1211 | } |
1212 | + Button { |
1213 | + text: "Pressme..." |
1214 | + anchors.centerIn: parent |
1215 | + } |
1216 | + |
1217 | onClicked: divider.visible = !divider.visible |
1218 | } |
1219 | } |
1220 | |
1221 | === added file 'tests/resources/navigation/Blackbox.qml' |
1222 | --- tests/resources/navigation/Blackbox.qml 1970-01-01 00:00:00 +0000 |
1223 | +++ tests/resources/navigation/Blackbox.qml 2015-09-18 16:36:01 +0000 |
1224 | @@ -0,0 +1,48 @@ |
1225 | +/* |
1226 | + * Copyright 2015 Canonical Ltd. |
1227 | + * |
1228 | + * This program is free software; you can redistribute it and/or modify |
1229 | + * it under the terms of the GNU Lesser General Public License as published by |
1230 | + * the Free Software Foundation; version 3. |
1231 | + * |
1232 | + * This program is distributed in the hope that it will be useful, |
1233 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1234 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1235 | + * GNU Lesser General Public License for more details. |
1236 | + * |
1237 | + * You should have received a copy of the GNU Lesser General Public License |
1238 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1239 | + */ |
1240 | + |
1241 | +import QtQuick 2.4 |
1242 | +import Ubuntu.Components 1.2 |
1243 | + |
1244 | +MainView { |
1245 | + width: units.gu(40) |
1246 | + height: units.gu(60) |
1247 | + Component.onCompleted: pageStack.push(page1) |
1248 | + |
1249 | + PageStack { |
1250 | + id: pageStack |
1251 | + } |
1252 | + |
1253 | + Page { |
1254 | + id: page1 |
1255 | + title: "one" |
1256 | + Button { |
1257 | + anchors.centerIn: parent |
1258 | + text: "next" |
1259 | + onClicked: pageStack.push(page2) |
1260 | + } |
1261 | + } |
1262 | + Page { |
1263 | + id: page2 |
1264 | + title: "two" |
1265 | + visible: false |
1266 | + |
1267 | + head.backAction: Action { |
1268 | + iconName: "back" |
1269 | + onTriggered: pageStack.pop() |
1270 | + } |
1271 | + } |
1272 | +} |
1273 | |
1274 | === modified file 'tests/tests.pro' |
1275 | --- tests/tests.pro 2015-05-20 14:47:16 +0000 |
1276 | +++ tests/tests.pro 2015-09-18 16:36:01 +0000 |
1277 | @@ -4,8 +4,6 @@ |
1278 | autopilot_module.path = /usr/lib/python3/dist-packages/ubuntuuitoolkit |
1279 | autopilot_module.files = autopilot/ubuntuuitoolkit/* |
1280 | |
1281 | -SUBDIRS += launcher |
1282 | - |
1283 | SUBDIRS += apicheck |
1284 | |
1285 | INSTALLS += autopilot_module |
1286 | |
1287 | === modified file 'tests/uitk_test_plan.sh' |
1288 | --- tests/uitk_test_plan.sh 2015-07-13 08:04:32 +0000 |
1289 | +++ tests/uitk_test_plan.sh 2015-09-18 16:36:01 +0000 |
1290 | @@ -32,7 +32,7 @@ |
1291 | SERIES="vivid" |
1292 | CHANNEL="ubuntu-touch/rc-proposed/${DISTRO}" |
1293 | PASSWORD="0000" |
1294 | -BOOTTIME=500 |
1295 | +BOOTTIME=250 |
1296 | ONLYCOMPARE=false |
1297 | DISTUPGRADE=false |
1298 | BOOTSTRAP=false |
1299 | @@ -56,7 +56,7 @@ |
1300 | # comment out if filemanager AP:s broken |
1301 | # " filemanager" |
1302 | # " ubuntu_terminal_app" |
1303 | - " -n unity8" |
1304 | +# " -n unity8" |
1305 | " ubuntu_clock_app" |
1306 | # " -p dialer-app-autopilot dialer_app" |
1307 | # " -p reminders-app-autopilot reminders" |
1308 | @@ -78,7 +78,7 @@ |
1309 | reminders-app-autopilot \ |
1310 | address-book-app-autopilot \ |
1311 | # messaging-app-autopilot \ |
1312 | - unity8-autopilot \ |
1313 | +# unity8-autopilot \ |
1314 | dialer-app-autopilot \ |
1315 | camera-app-autopilot \ |
1316 | webbrowser-app-autopilot \ |
1317 | @@ -89,6 +89,12 @@ |
1318 | ubuntu-system-settings-online-accounts-autopilot" |
1319 | # messaging-app-autopilot \ |
1320 | |
1321 | +declare -a UNREGISTERED_APPS=( |
1322 | + "com.ubuntu.terminal" |
1323 | + "com.ubuntu.calculator" |
1324 | + "com.ubuntu.shorts" |
1325 | +) |
1326 | + |
1327 | fatal_failure () { |
1328 | echo -e "\e[31mFailed operation:\e[0m $1" |
1329 | exit |
1330 | @@ -178,10 +184,13 @@ |
1331 | network |
1332 | adb -s ${SERIALNUMBER} shell "echo ${PASSWORD}|sudo -S reboot 2>&1|grep -v password" |
1333 | sleep_indicator 120 |
1334 | - # Required for at least rtm-14.09/mako, phablet-click-test-setup fails otherwise and we don't need terminal |
1335 | - adb -s ${SERIALNUMBER} shell "echo ${PASSWORD}|sudo -S click unregister com.ubuntu.terminal 2>&1|grep -v password" |
1336 | - # Enable if calculator AP:s broken, to prevent phablet-click-test-setup trying to check out its tests. |
1337 | - #adb -s ${SERIALNUMBER} shell "echo ${PASSWORD}|sudo -S click unregister com.ubuntu.calculator 2>&1|grep -v password" |
1338 | + # Unregister few apps as they break phablet-click-test-setup or something else |
1339 | + echo -e "Unregister few apps" |
1340 | + for APP_TO_UNREGISTER in "${UNREGISTERED_APPS[@]}" |
1341 | + do |
1342 | + echo -e "\e[31m${APP_TO_UNREGISTER}\e[0m" |
1343 | + adb -s ${SERIALNUMBER} shell "echo ${PASSWORD}|sudo -S click unregister ${APP_TO_UNREGISTER} 2>&1|grep -v password" |
1344 | + done |
1345 | echo -e "phablet-click-test-setup \e[31m${DISTRO} ${SERIES}\e[0m" |
1346 | phablet-click-test-setup -s ${SERIALNUMBER} --distribution=${DISTRO} --series=${SERIES} 2>&1 || fatal_failure "phablet-click-test-setup has failed" |
1347 | echo "Sleep after phablet-click-test-setup"; |
1348 | @@ -200,6 +209,9 @@ |
1349 | network |
1350 | # TODO: hide the sudo output |
1351 | adb -s ${SERIALNUMBER} shell "echo ${PASSWORD}|sudo -S bash -c 'echo \"deb http://ppa.launchpad.net/ci-train-ppa-service/landing-${PPA}/${DISTRO} ${SERIES} main\" > /etc/apt/sources.list.d/silo-${PPA}.list' 2>&1|grep -v password > /dev/null " |
1352 | + # pin up the silo |
1353 | + adb -s ${SERIALNUMBER} shell "echo ${PASSWORD}|sudo -S bash -c 'echo -e \"Package: *\nPin: release o=LP-PPA-ci-train-ppa-service-landing-${PPA}\nPin-Priority: 1100\" > /etc/apt/preferences.d/silo.pref' 2>&1|grep -v password > /dev/null " |
1354 | + # Resynchronize the package index files from their sources. |
1355 | adb -s ${SERIALNUMBER} shell "echo ${PASSWORD}|sudo -S apt-get update 2>&1|grep -v password > /dev/null" |
1356 | else |
1357 | echo -e "Set up with the PPA \e[31m${PPA}\e[0m" |
1358 | @@ -208,7 +220,6 @@ |
1359 | network |
1360 | adb -s ${SERIALNUMBER} shell "echo ${PASSWORD}|sudo -S bash -c 'echo \"deb http://ppa.launchpad.net/${PPA}/${DISTRO} ${SERIES} main\" > /etc/apt/sources.list.d/testing-ppa.list' 2>&1|grep -v password > /dev/null" |
1361 | adb -s ${SERIALNUMBER} shell "echo ${PASSWORD}|sudo -S apt-get update 2>&1|grep -v password > /dev/null" |
1362 | - |
1363 | fi |
1364 | fi |
1365 | adb -s ${SERIALNUMBER} shell rm -rf /home/phablet/autopilot/ubuntuuitoolkit |
1366 | |
1367 | === modified file 'tests/unit_x11/tst_components/ListItemTestCase.qml' |
1368 | --- tests/unit_x11/tst_components/ListItemTestCase.qml 2015-09-02 13:18:51 +0000 |
1369 | +++ tests/unit_x11/tst_components/ListItemTestCase.qml 2015-09-18 16:36:01 +0000 |
1370 | @@ -82,6 +82,10 @@ |
1371 | spyWait(); |
1372 | } |
1373 | |
1374 | + function tugNoWait(item, x, y, dx, dy) { |
1375 | + TestExtras.touchDrag(0, item, Qt.point(x, y), Qt.point(dx, dy)); |
1376 | + } |
1377 | + |
1378 | // returns the leading or trailing panel item |
1379 | function panelItem(item, leading) { |
1380 | return findInvisibleChild(item, (leading ? "ListItemPanelLeading" : "ListItemPanelTrailing")); |
1381 | |
1382 | === modified file 'tests/unit_x11/tst_components/ListItemTestCase13.qml' |
1383 | --- tests/unit_x11/tst_components/ListItemTestCase13.qml 2015-09-02 10:55:46 +0000 |
1384 | +++ tests/unit_x11/tst_components/ListItemTestCase13.qml 2015-09-18 16:36:01 +0000 |
1385 | @@ -76,12 +76,26 @@ |
1386 | flick(item, x, y, dx, dy, 0, 0, undefined, undefined, 100); |
1387 | } |
1388 | |
1389 | + // touch swipes |
1390 | + function swipeTouch(touchId, item, x, y, dx, dy) { |
1391 | + setupSpy(item, "contentMovementEnded"); |
1392 | + flickTouch(touchId, item, x, y, dx, dy, 0, 100); |
1393 | + spyWait(); |
1394 | + } |
1395 | + function swipeTouchNoWait(touchId, item, x, y, dx, dy) { |
1396 | + flickTouch(touchId, item, x, y, dx, dy, 0, 100); |
1397 | + } |
1398 | + |
1399 | function tug(item, x, y, dx, dy) { |
1400 | setupSpy(item, "contentMovementEnded"); |
1401 | TestExtras.touchDrag(0, item, Qt.point(x, y), Qt.point(dx, dy)); |
1402 | spyWait(); |
1403 | } |
1404 | |
1405 | + function tugNoWait(item, x, y, dx, dy) { |
1406 | + TestExtras.touchDrag(0, item, Qt.point(x, y), Qt.point(dx, dy)); |
1407 | + } |
1408 | + |
1409 | // returns the leading or trailing panel item |
1410 | function panelItem(item, leading) { |
1411 | return findInvisibleChild(item, (leading ? "ListItemPanelLeading" : "ListItemPanelTrailing")); |
1412 | |
1413 | === renamed file 'tests/unit/tst_components/tst_actionitem.qml' => 'tests/unit_x11/tst_components/tst_actionitem.qml' |
1414 | --- tests/unit/tst_components/tst_actionitem.qml 2015-08-18 16:58:41 +0000 |
1415 | +++ tests/unit_x11/tst_components/tst_actionitem.qml 2015-09-18 16:36:01 +0000 |
1416 | @@ -18,86 +18,182 @@ |
1417 | import QtTest 1.0 |
1418 | import Ubuntu.Components 1.1 |
1419 | |
1420 | -TestCase { |
1421 | - name: "ActionItemAPI" |
1422 | - |
1423 | - SignalSpy { |
1424 | - id: triggerSpy |
1425 | - target: action1 |
1426 | - signalName: "triggered" |
1427 | - } |
1428 | - |
1429 | - function initTestCase() { |
1430 | - compare(item1.action, null, "action is null by default") |
1431 | - compare(item1.text, "", "text is empty string set by default") |
1432 | - compare(item1.iconSource, "", "iconSource is empty string by default") |
1433 | - compare(item1.iconName, "", "iconSource is empty string by default") |
1434 | - } |
1435 | - |
1436 | - function cleanup() { |
1437 | - item1.action = null; |
1438 | - triggerSpy.clear(); |
1439 | - } |
1440 | - |
1441 | - function test_action() { |
1442 | - compare(item1.action, null,"Action is null by default") |
1443 | - item1.action = action1 |
1444 | - compare(item1.action, action1, "Action can be set") |
1445 | - compare(item1.text, action1.text, "text is automatically set to action text") |
1446 | - compare(item1.iconSource, action1.iconSource, "iconSource is automatically set to action iconSource") |
1447 | - item1.triggered(null) |
1448 | - triggerSpy.wait(400); |
1449 | - } |
1450 | - |
1451 | - // NOTE: This test must be run AFTER test_action(), otherwise setting the action will |
1452 | - // not update the text |
1453 | - function test_text() { |
1454 | - compare(item1.text, "", "text is empty string by default") |
1455 | - var newText = "new text" |
1456 | - item1.text = newText |
1457 | - compare(item1.text, newText, "text can be set") |
1458 | - item1.text = "" |
1459 | - compare(item1.text, "", "text can be unset") |
1460 | - } |
1461 | - |
1462 | - // NOTE: This test must be run AFTER test_action(), otherwise setting the action will |
1463 | - // will not update the iconSource |
1464 | - function test_iconSource() { |
1465 | - compare(item1.iconSource, "", "iconSource is empty string by default") |
1466 | - var newIconSource = Qt.resolvedUrl("../../../examples/ubuntu-ui-toolkit-gallery/small_avatar.png") |
1467 | - item1.iconSource = newIconSource |
1468 | - compare(item1.iconSource, newIconSource, "iconSource can be set") |
1469 | - item1.iconSource = "" |
1470 | - compare(item1.iconSource, "", "iconSource can be unset") |
1471 | - } |
1472 | - |
1473 | - // NOTE: This test must be run AFTER test_action(), otherwise setting the action will |
1474 | - // will not update the iconName |
1475 | - function test_iconName() { |
1476 | - compare(item1.iconName, "", "iconName is empty string by default") |
1477 | - var newIconName = "compose" |
1478 | - item1.iconName = newIconName |
1479 | - compare(item1.iconName, newIconName, "iconName can be set") |
1480 | - item1.iconName = "" |
1481 | - compare(item1.iconName, "", "iconName can be unset") |
1482 | - } |
1483 | - |
1484 | - function test_signal_triggered() { |
1485 | - signalSpy.signalName = "triggered"; |
1486 | - compare(signalSpy.valid,true,"triggered signal exists") |
1487 | - } |
1488 | - |
1489 | - ActionItem { |
1490 | - id: item1 |
1491 | - SignalSpy { |
1492 | - id: signalSpy |
1493 | - target: parent |
1494 | - } |
1495 | - } |
1496 | - |
1497 | - Action { |
1498 | - id: action1 |
1499 | - text: "actionText" |
1500 | - iconSource: "imageURL" |
1501 | - } |
1502 | +Item { |
1503 | + id: main |
1504 | + width: units.gu(20) |
1505 | + height: units.gu(20) |
1506 | + |
1507 | + property bool customVisible: true |
1508 | + property bool customEnabled: true |
1509 | + |
1510 | + ActionItem { |
1511 | + id: item1 |
1512 | + SignalSpy { |
1513 | + id: signalSpy |
1514 | + target: parent |
1515 | + } |
1516 | + } |
1517 | + |
1518 | + Component { |
1519 | + id: dynamicItem |
1520 | + ActionItem { |
1521 | + action: action1 |
1522 | + } |
1523 | + } |
1524 | + Component { |
1525 | + id: dynamicItem2 |
1526 | + ActionItem { |
1527 | + action: action1 |
1528 | + visible: customVisible |
1529 | + enabled: customEnabled |
1530 | + } |
1531 | + } |
1532 | + |
1533 | + Action { |
1534 | + id: action1 |
1535 | + objectName: "action1" |
1536 | + text: "actionText" |
1537 | + iconSource: "imageURL" |
1538 | + } |
1539 | + Action { |
1540 | + id: action2 |
1541 | + objectName: "action2" |
1542 | + } |
1543 | + |
1544 | + Loader { |
1545 | + id: loader |
1546 | + asynchronous: false |
1547 | + } |
1548 | + |
1549 | + TestCase { |
1550 | + id: testCase |
1551 | + when: windowShown |
1552 | + name: "ActionItemAPI" |
1553 | + |
1554 | + SignalSpy { |
1555 | + id: triggerSpy |
1556 | + target: action1 |
1557 | + signalName: "triggered" |
1558 | + } |
1559 | + |
1560 | + function initTestCase() { |
1561 | + compare(item1.action, null, "action is null by default") |
1562 | + compare(item1.text, "", "text is empty string set by default") |
1563 | + compare(item1.iconSource, "", "iconSource is empty string by default") |
1564 | + compare(item1.iconName, "", "iconSource is empty string by default") |
1565 | + } |
1566 | + |
1567 | + function cleanup() { |
1568 | + loader.sourceComponent = null; |
1569 | + item1.action = null; |
1570 | + action1.visible = true; |
1571 | + action1.enabled = true; |
1572 | + action2.visible = true; |
1573 | + action2.enabled = true; |
1574 | + main.customEnabled = true; |
1575 | + main.customVisible = true; |
1576 | + triggerSpy.clear(); |
1577 | + } |
1578 | + |
1579 | + function test_action() { |
1580 | + compare(item1.action, null,"Action is null by default") |
1581 | + item1.action = action1 |
1582 | + compare(item1.action, action1, "Action can be set") |
1583 | + compare(item1.text, action1.text, "text is automatically set to action text") |
1584 | + compare(item1.iconSource, action1.iconSource, "iconSource is automatically set to action iconSource") |
1585 | + item1.triggered(null) |
1586 | + triggerSpy.wait(400); |
1587 | + } |
1588 | + |
1589 | + // NOTE: This test must be run AFTER test_action(), otherwise setting the action will |
1590 | + // not update the text |
1591 | + function test_text() { |
1592 | + compare(item1.text, "", "text is empty string by default") |
1593 | + var newText = "new text" |
1594 | + item1.text = newText |
1595 | + compare(item1.text, newText, "text can be set") |
1596 | + item1.text = "" |
1597 | + compare(item1.text, "", "text can be unset") |
1598 | + } |
1599 | + |
1600 | + // NOTE: This test must be run AFTER test_action(), otherwise setting the action will |
1601 | + // will not update the iconSource |
1602 | + function test_iconSource() { |
1603 | + compare(item1.iconSource, "", "iconSource is empty string by default") |
1604 | + var newIconSource = Qt.resolvedUrl("../../../examples/ubuntu-ui-toolkit-gallery/small_avatar.png") |
1605 | + item1.iconSource = newIconSource |
1606 | + compare(item1.iconSource, newIconSource, "iconSource can be set") |
1607 | + item1.iconSource = "" |
1608 | + compare(item1.iconSource, "", "iconSource can be unset") |
1609 | + } |
1610 | + |
1611 | + // NOTE: This test must be run AFTER test_action(), otherwise setting the action will |
1612 | + // will not update the iconName |
1613 | + function test_iconName() { |
1614 | + compare(item1.iconName, "", "iconName is empty string by default") |
1615 | + var newIconName = "compose" |
1616 | + item1.iconName = newIconName |
1617 | + compare(item1.iconName, newIconName, "iconName can be set") |
1618 | + item1.iconName = "" |
1619 | + compare(item1.iconName, "", "iconName can be unset") |
1620 | + } |
1621 | + |
1622 | + function test_signal_triggered() { |
1623 | + signalSpy.signalName = "triggered"; |
1624 | + compare(signalSpy.valid,true,"triggered signal exists") |
1625 | + } |
1626 | + |
1627 | + function test_default_bindings_visible_enabled_data() { |
1628 | + return [ |
1629 | + {tag: "visible", property: "visible"}, |
1630 | + {tag: "enabled", property: "enabled"}, |
1631 | + ]; |
1632 | + } |
1633 | + function test_default_bindings_visible_enabled(data) { |
1634 | + item1.action = action1; |
1635 | + action1[data.property] = false; |
1636 | + compare(item1[data.property], action1[data.property], "The item1 and action1 '" + data.property + "' value differs"); |
1637 | + } |
1638 | + |
1639 | + function test_custom_bindings_visible_enabled_bug1495408_data() { |
1640 | + return [ |
1641 | + {tag: "visible", component: dynamicItem, property: "visible"}, |
1642 | + {tag: "enabled", component: dynamicItem, property: "enabled"}, |
1643 | + {tag: "visible binding", component: dynamicItem2, property: "visible", customProperty: "customVisible"}, |
1644 | + {tag: "enabled binding", component: dynamicItem2, property: "enabled", customProperty: "customEnabled"}, |
1645 | + ]; |
1646 | + } |
1647 | + function test_custom_bindings_visible_enabled_bug1495408(data) { |
1648 | + loader.sourceComponent = data.component; |
1649 | + var item = loader.item; |
1650 | + compare(item[data.property], action1[data.property], "The item and action1 '" + data.property + "' value differs"); |
1651 | + if (data.customProperty) { |
1652 | + main[data.customProperty] = false; |
1653 | + } else { |
1654 | + item[data.property] = false; |
1655 | + } |
1656 | + // change the action so the internal bindings are updated |
1657 | + item.action = action2; |
1658 | + expectFail(data.tag, "default binding must be broken"); |
1659 | + compare(item[data.property], item.action[data.property], "The item's and action's '" + data.property + "' value is the same"); |
1660 | + } |
1661 | + function test_custom_bindings_visible_enabled_reparenting_bug1495408_data() { |
1662 | + return [ |
1663 | + {tag: "visible binding", component: dynamicItem2, property: "visible"}, |
1664 | + {tag: "enabled binding", component: dynamicItem2, property: "enabled"}, |
1665 | + ]; |
1666 | + } |
1667 | + function test_custom_bindings_visible_enabled_reparenting_bug1495408(data) { |
1668 | + loader.sourceComponent = dynamicItem2; |
1669 | + var item = loader.item; |
1670 | + compare(item[data.property], item.action[data.property], "The item and item.action '" + data.property + "' value differs"); |
1671 | + // then reparent |
1672 | + item.parent = item1; |
1673 | + // change the action property |
1674 | + |
1675 | + item.action[data.property] = false; |
1676 | + expectFail(data.tag, "default binding must be broken"); |
1677 | + compare(item[data.property], item.action[data.property], "The item and action2 '" + data.property + "' value is the same"); |
1678 | + } |
1679 | + } |
1680 | } |
1681 | |
1682 | === modified file 'tests/unit_x11/tst_components/tst_icon.qml' |
1683 | --- tests/unit_x11/tst_components/tst_icon.qml 2015-03-03 13:20:06 +0000 |
1684 | +++ tests/unit_x11/tst_components/tst_icon.qml 2015-09-18 16:36:01 +0000 |
1685 | @@ -64,6 +64,11 @@ |
1686 | name: "Icon" |
1687 | when: windowShown |
1688 | |
1689 | + SignalSpy { |
1690 | + id: shaderSpy |
1691 | + signalName: 'onStatusChanged' |
1692 | + } |
1693 | + |
1694 | function cleanup() { |
1695 | icon2.name = ""; |
1696 | } |
1697 | @@ -93,5 +98,35 @@ |
1698 | "file:///usr/share/icons/suru/actions/scalable/search.svg", |
1699 | "Source of the image should equal icon2.source."); |
1700 | } |
1701 | + |
1702 | + function test_keyColor() { |
1703 | + icon.visible = true; |
1704 | + var image = findChild(icon, "image"); |
1705 | + var shader = findChild(icon, "shader"); |
1706 | + shaderSpy.target = shader; |
1707 | + |
1708 | + compare(icon.name, 'search'); |
1709 | + compare(shader.visible, false); |
1710 | + compare(shader.status, ShaderEffect.Uncompiled) |
1711 | + icon.color = UbuntuColors.orange; |
1712 | + shaderSpy.wait(); |
1713 | + compare(shader.status, ShaderEffect.Compiled) |
1714 | + compare(shader.keyColorOut, icon.color); |
1715 | + compare(shader.visible, true); |
1716 | + compare(shader.source, image); |
1717 | + icon.keyColor = UbuntuColors.purple; |
1718 | + compare(shader.keyColorIn, icon.keyColor); |
1719 | + // Unsetting the icon name should disable the shader |
1720 | + icon.name = ''; |
1721 | + compare(icon.source, ''); |
1722 | + compare(shader.visible, false); |
1723 | + // Let's get back to a valid source |
1724 | + icon.name = 'search'; |
1725 | + compare(shader.visible, true); |
1726 | + compare(shader.source, image); |
1727 | + // Unsetting the keyColor should also disable the shader |
1728 | + icon.color = Qt.rgba(0.0, 0.0, 0.0, 0.0); |
1729 | + compare(shader.visible, false); |
1730 | + } |
1731 | } |
1732 | } |
1733 | |
1734 | === modified file 'tests/unit_x11/tst_components/tst_listitem.qml' |
1735 | --- tests/unit_x11/tst_components/tst_listitem.qml 2015-09-02 06:47:25 +0000 |
1736 | +++ tests/unit_x11/tst_components/tst_listitem.qml 2015-09-18 16:36:01 +0000 |
1737 | @@ -198,8 +198,8 @@ |
1738 | signalName: "onTriggered" |
1739 | } |
1740 | SignalSpy { |
1741 | - id: interactiveSpy |
1742 | - signalName: "interactiveChanged" |
1743 | + id: flickableSpy |
1744 | + signalName: "movementStarted" |
1745 | } |
1746 | |
1747 | SignalSpy { |
1748 | @@ -227,7 +227,7 @@ |
1749 | actionSpy.clear(); |
1750 | pressAndHoldSpy.clear(); |
1751 | buttonSpy.clear(); |
1752 | - interactiveSpy.clear(); |
1753 | + flickableSpy.clear(); |
1754 | listView.interactive = true; |
1755 | listView.ViewItems.selectMode = false; |
1756 | listView.ViewItems.dragMode = false; |
1757 | @@ -235,8 +235,8 @@ |
1758 | mouseClick(defaults, 0, 0) |
1759 | movingSpy.target = null; |
1760 | movingSpy.clear(); |
1761 | - interactiveSpy.target = null; |
1762 | - interactiveSpy.clear(); |
1763 | + flickableSpy.target = null; |
1764 | + flickableSpy.clear(); |
1765 | trailing.delegate = null; |
1766 | listView.positionViewAtBeginning(); |
1767 | // keep additional timeout for proper cleanup |
1768 | @@ -434,6 +434,7 @@ |
1769 | rebound(data.clickOn, data.item) |
1770 | } |
1771 | |
1772 | + // the function tests whether the Flickable/ListView moves when the ListItem is swiped |
1773 | function test_listview_not_interactive_while_tugged_data() { |
1774 | var item0 = findChild(listView, "listItem0"); |
1775 | var item1 = findChild(listView, "listItem1"); |
1776 | @@ -446,17 +447,15 @@ |
1777 | } |
1778 | function test_listview_not_interactive_while_tugged(data) { |
1779 | listView.positionViewAtBeginning(); |
1780 | - interactiveSpy.target = listView; |
1781 | + flickableSpy.target = listView; |
1782 | compare(listView.interactive, true, "ListView is not interactive"); |
1783 | - interactiveSpy.target = listView; |
1784 | if (data.mouse) { |
1785 | - swipe(data.item, data.pos.x, data.pos.y, data.dx, data.dy); |
1786 | + swipe(data.item, data.pos.x, data.pos.y, data.dx, units.gu(5)); |
1787 | } else { |
1788 | - tug(data.item, data.pos.x, data.pos.y, data.dx, data.dy); |
1789 | + tug(data.item, data.pos.x, data.pos.y, data.dx, units.gu(5)); |
1790 | } |
1791 | // animation should no longer be running! |
1792 | - compare(listView.interactive, true, "The ListView is still non-interactive!"); |
1793 | - compare(interactiveSpy.count, 2, "Less/more times changed!"); |
1794 | + compare(flickableSpy.count, 0, "Flickable moved!"); |
1795 | // check if it snapped in |
1796 | verify(data.item.contentItem.x != 0.0, "Not snapped in!!"); |
1797 | // dismiss |
1798 | @@ -629,7 +628,7 @@ |
1799 | wait(2000); |
1800 | verify(data.item.contentItem.x != data.item.contentItem.anchors.leftMargin, "Not snapped in"); |
1801 | |
1802 | - var panel = panelItem(data.item, "Leading"); |
1803 | + var panel = panelItem(data.item, true); |
1804 | var action = findChild(panel, "leading_2"); |
1805 | verify(action, "actions panel cannot be reached"); |
1806 | // we test the action closest to the list item's contentItem |
1807 | @@ -724,11 +723,12 @@ |
1808 | function test_listitem_blocks_ascendant_flickables() { |
1809 | var listItem = findChild(nestedListView, "listItem0"); |
1810 | verify(listItem, "Cannot find test item"); |
1811 | - interactiveSpy.target = testFlickable; |
1812 | + flickableSpy.target = testFlickable; |
1813 | // tug leading |
1814 | swipe(listItem, centerOf(listItem).x, centerOf(listItem).y, listItem.width / 2, 0); |
1815 | // check if interactive got changed |
1816 | - interactiveSpy.wait(); |
1817 | + expectFailContinue("", "Flickable should not move"); |
1818 | + flickableSpy.wait(200); |
1819 | |
1820 | // cleanup!!! |
1821 | rebound(listItem); |
1822 | |
1823 | === modified file 'tests/unit_x11/tst_components/tst_listitem13.qml' |
1824 | --- tests/unit_x11/tst_components/tst_listitem13.qml 2015-09-02 10:55:46 +0000 |
1825 | +++ tests/unit_x11/tst_components/tst_listitem13.qml 2015-09-18 16:36:01 +0000 |
1826 | @@ -198,8 +198,8 @@ |
1827 | signalName: "onTriggered" |
1828 | } |
1829 | SignalSpy { |
1830 | - id: interactiveSpy |
1831 | - signalName: "interactiveChanged" |
1832 | + id: flickableSpy |
1833 | + signalName: "movementStarted" |
1834 | } |
1835 | |
1836 | SignalSpy { |
1837 | @@ -227,7 +227,7 @@ |
1838 | actionSpy.clear(); |
1839 | pressAndHoldSpy.clear(); |
1840 | buttonSpy.clear(); |
1841 | - interactiveSpy.clear(); |
1842 | + flickableSpy.clear(); |
1843 | listView.interactive = true; |
1844 | listView.ViewItems.selectMode = false; |
1845 | listView.ViewItems.dragMode = false; |
1846 | @@ -235,8 +235,8 @@ |
1847 | mouseClick(defaults, 0, 0) |
1848 | movingSpy.target = null; |
1849 | movingSpy.clear(); |
1850 | - interactiveSpy.target = null; |
1851 | - interactiveSpy.clear(); |
1852 | + flickableSpy.target = null; |
1853 | + flickableSpy.clear(); |
1854 | trailing.delegate = null; |
1855 | listView.positionViewAtBeginning(); |
1856 | // keep additional timeout for proper cleanup |
1857 | @@ -466,17 +466,15 @@ |
1858 | } |
1859 | function test_listview_not_interactive_while_tugged(data) { |
1860 | listView.positionViewAtBeginning(); |
1861 | - interactiveSpy.target = listView; |
1862 | + flickableSpy.target = listView; |
1863 | compare(listView.interactive, true, "ListView is not interactive"); |
1864 | - interactiveSpy.target = listView; |
1865 | if (data.mouse) { |
1866 | - swipe(data.item, data.pos.x, data.pos.y, data.dx, data.dy); |
1867 | + swipe(data.item, data.pos.x, data.pos.y, data.dx, units.gu(5)); |
1868 | } else { |
1869 | - tug(data.item, data.pos.x, data.pos.y, data.dx, data.dy); |
1870 | + tug(data.item, data.pos.x, data.pos.y, data.dx, units.gu(5)); |
1871 | } |
1872 | // animation should no longer be running! |
1873 | - compare(listView.interactive, true, "The ListView is still non-interactive!"); |
1874 | - compare(interactiveSpy.count, 2, "Less/more times changed!"); |
1875 | + compare(flickableSpy.count, 0, "Flickable moved!"); |
1876 | // check if it snapped in |
1877 | verify(data.item.contentItem.x != 0.0, "Not snapped in!!"); |
1878 | // dismiss |
1879 | @@ -744,11 +742,12 @@ |
1880 | function test_listitem_blocks_ascendant_flickables() { |
1881 | var listItem = findChild(nestedListView, "listItem0"); |
1882 | verify(listItem, "Cannot find test item"); |
1883 | - interactiveSpy.target = testFlickable; |
1884 | + flickableSpy.target = testFlickable; |
1885 | // tug leading |
1886 | swipe(listItem, centerOf(listItem).x, centerOf(listItem).y, listItem.width / 2, 0); |
1887 | // check if interactive got changed |
1888 | - interactiveSpy.wait(); |
1889 | + expectFailContinue("", "Flickable should not move."); |
1890 | + flickableSpy.wait(200); |
1891 | |
1892 | // cleanup!!! |
1893 | rebound(listItem); |
1894 | @@ -1200,7 +1199,7 @@ |
1895 | |
1896 | var icon = findChild(testItem, data.action); |
1897 | verify(icon); |
1898 | - compare(icon.width, units.gu(5), "icon width should be the same no matter of the height set"); |
1899 | + compare(icon.width, units.gu(6), "icon width should be the same no matter of the height set"); |
1900 | |
1901 | rebound(testItem); |
1902 | |
1903 | |
1904 | === modified file 'tests/unit_x11/tst_components/tst_listitem_extras.qml' |
1905 | --- tests/unit_x11/tst_components/tst_listitem_extras.qml 2015-09-02 10:55:46 +0000 |
1906 | +++ tests/unit_x11/tst_components/tst_listitem_extras.qml 2015-09-18 16:36:01 +0000 |
1907 | @@ -30,18 +30,18 @@ |
1908 | Action { |
1909 | iconName: "starred" |
1910 | text: 'Bookmark' |
1911 | - objectName: "leading_1" |
1912 | + objectName: "trailing1" |
1913 | }, |
1914 | Action { |
1915 | iconName: "edit" |
1916 | text: 'Edit' |
1917 | - objectName: "leading_2" |
1918 | + objectName: "trailing2" |
1919 | onTriggered: text = 'Edit Again' |
1920 | }, |
1921 | Action { |
1922 | iconName: "camcorder" |
1923 | text: 'Record' |
1924 | - objectName: "leading_3" |
1925 | + objectName: "trailing3" |
1926 | } |
1927 | ] |
1928 | } |
1929 | @@ -50,7 +50,7 @@ |
1930 | actions: Action { |
1931 | id: stockAction |
1932 | iconName: "torch-on" |
1933 | - objectName: "stockAction" |
1934 | + objectName: "leading1" |
1935 | text: 'Switch lights on' |
1936 | } |
1937 | } |
1938 | @@ -80,6 +80,22 @@ |
1939 | onPressed: mouse.accepted = overlaidMouseArea.acceptEvent |
1940 | } |
1941 | } |
1942 | + ListView { |
1943 | + id: listView |
1944 | + width: parent.width |
1945 | + height: 4 * units.gu(7) // 4 items |
1946 | + clip: true |
1947 | + model: 5 |
1948 | + delegate: ListItem { |
1949 | + objectName: "listItem" + index |
1950 | + Label { |
1951 | + anchors.centerIn: parent |
1952 | + text: index |
1953 | + } |
1954 | + |
1955 | + leadingActions: leading |
1956 | + } |
1957 | + } |
1958 | } |
1959 | |
1960 | ListItemTestCase13 { |
1961 | @@ -89,11 +105,16 @@ |
1962 | signalName: "clicked" |
1963 | } |
1964 | |
1965 | + function initTestCase() { |
1966 | + TestExtras.registerTouchDevice(); |
1967 | + } |
1968 | + |
1969 | function cleanup() { |
1970 | rebound(testWithActiveItem); |
1971 | rebound(overlaidMouseArea); |
1972 | clickSpy.target = null; |
1973 | clickSpy.clear(); |
1974 | + wait(200); |
1975 | } |
1976 | |
1977 | function test_swipe_over_active_item() { |
1978 | @@ -114,5 +135,116 @@ |
1979 | swipeNoWait(overlayArea, centerOf(overlayArea).x, centerOf(overlayArea).y, units.gu(10)); |
1980 | spyWait(); |
1981 | } |
1982 | + |
1983 | + function test_swipe_out_from_overlay_button_bug1497156_data() { |
1984 | + return [ |
1985 | + {tag: "leading with mouse", touch: false, swipeInDx: units.gu(20), swipeOutDx: -units.gu(5)}, |
1986 | + {tag: "trailing with mouse", touch: false, swipeInDx: -units.gu(20), swipeOutDx: units.gu(5)}, |
1987 | + {tag: "leading with touch", touch: true, swipeInDx: units.gu(20), swipeOutDx: -units.gu(5)}, |
1988 | + {tag: "trailing with touch", touch: true, swipeInDx: -units.gu(20), swipeOutDx: units.gu(5)}, |
1989 | + ] |
1990 | + } |
1991 | + function test_swipe_out_from_overlay_button_bug1497156(data) { |
1992 | + // swipe in and out from teh same point |
1993 | + if (data.touch) { |
1994 | + tug(testWithActiveItem, centerOf(testWithActiveItem).x, centerOf(testWithActiveItem).y, data.swipeInDx, 0); |
1995 | + } else { |
1996 | + swipe(testWithActiveItem, centerOf(testWithActiveItem).x, centerOf(testWithActiveItem).y, data.swipeInDx, 0); |
1997 | + } |
1998 | + verify(testWithActiveItem.contentItem.x != 0, "Not swiped in"); |
1999 | + // swipe out |
2000 | + if (data.touch) { |
2001 | + tug(testWithActiveItem, centerOf(testWithActiveItem).x, centerOf(testWithActiveItem).y, data.swipeOutDx, 0); |
2002 | + } else { |
2003 | + swipe(testWithActiveItem, centerOf(testWithActiveItem).x, centerOf(testWithActiveItem).y, data.swipeOutDx, 0); |
2004 | + } |
2005 | + tryCompareFunction(function() { |
2006 | + return testWithActiveItem.contentItem.x == testWithActiveItem.contentItem.anchors.leftMargin; |
2007 | + }, true, 500); |
2008 | + } |
2009 | + |
2010 | + function test_swipe_over_contextual_actions_bug1486008_data() { |
2011 | + return [ |
2012 | + {tag: "leading action with mouse", touch: false, dx: units.gu(20), leadingPanel: true, action: "leading1"}, |
2013 | + {tag: "trailing action with mouse", touch: false, dx: -units.gu(20), leadingPanel: false, action: "trailing1"}, |
2014 | + {tag: "leading action with touch", touch: true, dx: units.gu(20), leadingPanel: true, action: "leading1"}, |
2015 | + {tag: "trailing action with touch", touch: true, dx: -units.gu(20), leadingPanel: false, action: "trailing1"}, |
2016 | + ]; |
2017 | + } |
2018 | + function test_swipe_over_contextual_actions_bug1486008(data) { |
2019 | + if (data.touch) { |
2020 | + tug(testWithActiveItem, centerOf(testWithActiveItem).x, centerOf(testWithActiveItem).y, data.dx, 0); |
2021 | + } else { |
2022 | + swipe(testWithActiveItem, centerOf(testWithActiveItem).x, centerOf(testWithActiveItem).y, data.dx, 0); |
2023 | + } |
2024 | + var panel = panelItem(testWithActiveItem, data.leadingPanel); |
2025 | + var actionItem = findChild(panel, data.action); |
2026 | + verify(actionItem, data.action + " action not found."); |
2027 | + // swipe over the action |
2028 | + setupSpy(testWithActiveItem, "contentMovementStarted"); |
2029 | + if (data.touch) { |
2030 | + tugNoWait(actionItem, centerOf(actionItem).x, centerOf(actionItem).y, -data.dx, 0); |
2031 | + } else { |
2032 | + swipeNoWait(actionItem, centerOf(actionItem).x, centerOf(actionItem).y, -data.dx, 0); |
2033 | + } |
2034 | + expectFail(data.tag, "should not swipe"); |
2035 | + spyWait(); |
2036 | + } |
2037 | + |
2038 | + function test_button_inactive_while_swiped_data() { |
2039 | + return [ |
2040 | + {tag: "mouse", touch: false, dx: units.gu(20)}, |
2041 | + {tag: "touch", touch: true, dx: units.gu(20)}, |
2042 | + ]; |
2043 | + } |
2044 | + function test_button_inactive_while_swiped(data) { |
2045 | + clickSpy.target = activeItem; |
2046 | + if (data.touch) { |
2047 | + tug(testWithActiveItem, centerOf(testWithActiveItem).x, centerOf(testWithActiveItem).y, data.dx, 0); |
2048 | + TestExtras.touchClick(0, activeItem, centerOf(activeItem)); |
2049 | + } else { |
2050 | + swipe(testWithActiveItem, centerOf(testWithActiveItem).x, centerOf(testWithActiveItem).y, data.dx, 0); |
2051 | + mouseClick(activeItem, centerOf(activeItem).x, centerOf(activeItem).y); |
2052 | + } |
2053 | + expectFail(data.tag, "Button is inactive while swiped"); |
2054 | + clickSpy.wait(200); |
2055 | + } |
2056 | + |
2057 | + function test_click_before_and_after_snapout_bug1496468_data() { |
2058 | + var item0 = findChild(listView, "listItem0"); |
2059 | + var item1 = findChild(listView, "listItem1"); |
2060 | + return [ |
2061 | + {tag: "mouse", touch: false, clickedItem: item0, swipedItem: item1, dx: units.gu(20), reboundDx: -units.gu(5)}, |
2062 | + {tag: "touch", touch: true, clickedItem: item0, swipedItem: item1, dx: units.gu(20), reboundDx: -units.gu(5)}, |
2063 | + ]; |
2064 | + } |
2065 | + function test_click_before_and_after_snapout_bug1496468(data) { |
2066 | + clickSpy.target = data.clickedItem; |
2067 | + if (data.touch) { |
2068 | + TestExtras.touchClick(0, data.clickedItem, centerOf(data.clickedItem)); |
2069 | + } else { |
2070 | + mouseClick(data.clickedItem, centerOf(data.clickedItem).x, centerOf(data.clickedItem).y); |
2071 | + } |
2072 | + clickSpy.wait(200); |
2073 | + // swipe in then rebound |
2074 | + if (data.touch) { |
2075 | + tug(data.swipedItem, centerOf(data.swipedItem).x, centerOf(data.swipedItem).y, data.dx, 0); |
2076 | + wait(200); |
2077 | + tug(data.swipedItem, centerOf(data.swipedItem).x, centerOf(data.swipedItem).y, data.reboundDx, 0); |
2078 | + } else { |
2079 | + swipe(data.swipedItem, centerOf(data.swipedItem).x, centerOf(data.swipedItem).y, data.dx, 0); |
2080 | + wait(200); |
2081 | + swipe(data.swipedItem, centerOf(data.swipedItem).x, centerOf(data.swipedItem).y, data.reboundDx, 0); |
2082 | + } |
2083 | + // then test click |
2084 | + clickSpy.target = data.swipedItem; |
2085 | + clickSpy.clear(); |
2086 | + if (data.touch) { |
2087 | + TestExtras.touchClick(0, data.swipedItem, centerOf(data.swipedItem)); |
2088 | + } else { |
2089 | + mouseClick(data.swipedItem, centerOf(data.swipedItem).x, centerOf(data.swipedItem).y); |
2090 | + } |
2091 | + clickSpy.wait(200); |
2092 | + } |
2093 | } |
2094 | } |
2095 | |
2096 | === modified file 'tests/unit_x11/tst_components/tst_popover.qml' |
2097 | --- tests/unit_x11/tst_components/tst_popover.qml 2015-03-03 13:20:06 +0000 |
2098 | +++ tests/unit_x11/tst_components/tst_popover.qml 2015-09-18 16:36:01 +0000 |
2099 | @@ -29,6 +29,11 @@ |
2100 | y: main.height / 2 |
2101 | height: units.gu(10) |
2102 | width: height |
2103 | + MouseArea { |
2104 | + id: whiteSpace |
2105 | + anchors.fill: parent |
2106 | + acceptedButtons: Qt.LeftButton | Qt.MiddleButton | Qt.RightButton |
2107 | + } |
2108 | |
2109 | Button { |
2110 | id: pressMe |
2111 | @@ -68,6 +73,11 @@ |
2112 | id: popoverSpy |
2113 | signalName: "hideCompleted" |
2114 | } |
2115 | + SignalSpy { |
2116 | + id: whiteSpy |
2117 | + signalName: "clicked" |
2118 | + target: whiteSpace |
2119 | + } |
2120 | |
2121 | Component { |
2122 | id: popoverComponent |
2123 | @@ -116,6 +126,29 @@ |
2124 | popoverSpy.wait(); |
2125 | } |
2126 | |
2127 | + function test_popover_consumes_clicks_bug1488540_data() { |
2128 | + return [ |
2129 | + { tag: 'Left-click', button: Qt.LeftButton }, |
2130 | + { tag: 'Right-click', button: Qt.RightButton }, |
2131 | + { tag: 'Middle-click', button: Qt.MiddleButton }, |
2132 | + ] |
2133 | + } |
2134 | + function test_popover_consumes_clicks_bug1488540(data) { |
2135 | + mouseClick(pressMe, pressMe.width / 2, pressMe.height / 2); |
2136 | + waitForRendering(pressMe); |
2137 | + verify(popoverSpy.target !== null, "The popover did not open"); |
2138 | + var popover = popoverSpy.target; |
2139 | + // Click in the popover, the rectangle doesn't handle clicks |
2140 | + whiteSpy.clear(); |
2141 | + mouseClick(popover, popover.width / 2, popover.height / 2, data.button); |
2142 | + // dismiss |
2143 | + mouseClick(main, 10, 10, Qt.LeftButton); |
2144 | + popoverSpy.wait(); |
2145 | + // Did the click reach through the popover foreground? |
2146 | + compare(whiteSpy.count, 0, 'Click passed through popover foreground!'); |
2147 | + |
2148 | + } |
2149 | + |
2150 | function test_popover_follows_pointerTarget_bug1199502_data() { |
2151 | return [ |
2152 | { tag: "Moving pointerTarget", button: pressMe, dir: "down", y: 318 }, |
2153 | |
2154 | === added file 'tests/unit_x11/tst_components/tst_popover13.qml' |
2155 | --- tests/unit_x11/tst_components/tst_popover13.qml 1970-01-01 00:00:00 +0000 |
2156 | +++ tests/unit_x11/tst_components/tst_popover13.qml 2015-09-18 16:36:01 +0000 |
2157 | @@ -0,0 +1,174 @@ |
2158 | +/* |
2159 | + * Copyright 2014-2015 Canonical Ltd. |
2160 | + * |
2161 | + * This program is free software; you can redistribute it and/or modify |
2162 | + * it under the terms of the GNU Lesser General Public License as published by |
2163 | + * the Free Software Foundation; version 3. |
2164 | + * |
2165 | + * This program is distributed in the hope that it will be useful, |
2166 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2167 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2168 | + * GNU Lesser General Public License for more details. |
2169 | + * |
2170 | + * You should have received a copy of the GNU Lesser General Public License |
2171 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2172 | + */ |
2173 | +import QtQuick 2.0 |
2174 | +import QtTest 1.0 |
2175 | +import Ubuntu.Test 1.0 |
2176 | +import Ubuntu.Components 1.3 |
2177 | +import Ubuntu.Components.Popups 1.3 |
2178 | + |
2179 | +MainView { |
2180 | + id: main |
2181 | + width: units.gu(50) |
2182 | + height: units.gu(71) |
2183 | + |
2184 | + Rectangle { |
2185 | + id: rect |
2186 | + y: main.height / 2 |
2187 | + height: units.gu(10) |
2188 | + width: height |
2189 | + MouseArea { |
2190 | + id: whiteSpace |
2191 | + anchors.fill: parent |
2192 | + acceptedButtons: Qt.LeftButton | Qt.MiddleButton | Qt.RightButton |
2193 | + } |
2194 | + |
2195 | + Button { |
2196 | + id: pressMe |
2197 | + anchors.top: parent.top |
2198 | + text: "Press me" |
2199 | + onClicked: { |
2200 | + testCase.resetPositions(); |
2201 | + var popover = PopupUtils.open(popoverComponent, pressMe); |
2202 | + popoverSpy.target = testCase.findChild(popover, "popover_foreground"); |
2203 | + popoverSpy.clear(); |
2204 | + pressMe.parent.height = units.gu(25) |
2205 | + pressMe.anchors.top = parent.bottom |
2206 | + } |
2207 | + } |
2208 | + |
2209 | + Button { |
2210 | + id: pushMe |
2211 | + anchors.bottom: parent.bottom |
2212 | + text: "Push me" |
2213 | + onClicked: { |
2214 | + testCase.resetPositions(); |
2215 | + var popover = PopupUtils.open(popoverComponent, pushMe); |
2216 | + popoverSpy.target = testCase.findChild(popover, "popover_foreground"); |
2217 | + popoverSpy.clear(); |
2218 | + rect.y = main.height / 10 |
2219 | + } |
2220 | + } |
2221 | + } |
2222 | + Label { |
2223 | + id: other |
2224 | + text: "Ignore me" |
2225 | + anchors.centerIn: parent |
2226 | + } |
2227 | + |
2228 | + // spy to listen on the popover foreground's hideCompleted() signal |
2229 | + SignalSpy { |
2230 | + id: popoverSpy |
2231 | + signalName: "hideCompleted" |
2232 | + } |
2233 | + SignalSpy { |
2234 | + id: whiteSpy |
2235 | + signalName: "clicked" |
2236 | + target: whiteSpace |
2237 | + } |
2238 | + |
2239 | + Component { |
2240 | + id: popoverComponent |
2241 | + Popover { |
2242 | + objectName: "popover" |
2243 | + Rectangle { |
2244 | + width: units.gu(20) |
2245 | + height: units.gu(20) |
2246 | + color: "blue" |
2247 | + } |
2248 | + } |
2249 | + } |
2250 | + |
2251 | + UbuntuTestCase { |
2252 | + id: testCase |
2253 | + name: "PopoverTests" |
2254 | + when: windowShown |
2255 | + |
2256 | + function resetPositions() { |
2257 | + pressMe.parent.height = units.gu(10) |
2258 | + rect.y = main.height / 2 |
2259 | + } |
2260 | + |
2261 | + function cleanup() { |
2262 | + resetPositions() |
2263 | + popoverSpy.target = null; |
2264 | + popoverSpy.clear(); |
2265 | + waitForRendering(main, 500); |
2266 | + } |
2267 | + |
2268 | + function test_dismiss_on_click_data() { |
2269 | + return [ |
2270 | + {button: Qt.LeftButton}, |
2271 | + {button: Qt.MiddleButton}, |
2272 | + {button: Qt.RightButton}, |
2273 | + ]; |
2274 | + } |
2275 | + |
2276 | + function test_dismiss_on_click(data) { |
2277 | + mouseClick(pressMe, pressMe.width / 2, pressMe.height / 2); |
2278 | + waitForRendering(pressMe); |
2279 | + verify(popoverSpy.target !== null, "The popover did not open"); |
2280 | + |
2281 | + // dismiss |
2282 | + mouseClick(main, 10, 10, data.button); |
2283 | + popoverSpy.wait(); |
2284 | + } |
2285 | + |
2286 | + function test_popover_consumes_clicks_bug1488540_data() { |
2287 | + return [ |
2288 | + { tag: 'Left-click', button: Qt.LeftButton }, |
2289 | + { tag: 'Right-click', button: Qt.RightButton }, |
2290 | + { tag: 'Middle-click', button: Qt.MiddleButton }, |
2291 | + ] |
2292 | + } |
2293 | + function test_popover_consumes_clicks_bug1488540(data) { |
2294 | + mouseClick(pressMe, pressMe.width / 2, pressMe.height / 2); |
2295 | + waitForRendering(pressMe); |
2296 | + verify(popoverSpy.target !== null, "The popover did not open"); |
2297 | + var popover = popoverSpy.target; |
2298 | + // Click in the popover, the rectangle doesn't handle clicks |
2299 | + whiteSpy.clear(); |
2300 | + mouseClick(popover, popover.width / 2, popover.height / 2, data.button); |
2301 | + // dismiss |
2302 | + mouseClick(main, 10, 10, Qt.LeftButton); |
2303 | + popoverSpy.wait(); |
2304 | + // Did the click reach through the popover foreground? |
2305 | + compare(whiteSpy.count, 0, 'Click passed through popover foreground!'); |
2306 | + |
2307 | + } |
2308 | + |
2309 | + function test_popover_follows_pointerTarget_bug1199502_data() { |
2310 | + return [ |
2311 | + { tag: "Moving pointerTarget", button: pressMe, dir: "down", y: 318 }, |
2312 | + // FIXME: { tag: "Moving parent", button: pushMe, dir: "up", y: 142.8 }, |
2313 | + // https://bugs.launchpad.net/ubuntu/+source/ubuntu-ui-toolkit/+bug/1427557 |
2314 | + ] |
2315 | + } |
2316 | + function test_popover_follows_pointerTarget_bug1199502(data) { |
2317 | + mouseClick(data.button, data.button.width / 2, data.button.height / 2); |
2318 | + waitForRendering(data.button); |
2319 | + var dir = popoverSpy.target.direction |
2320 | + var popoverY = popoverSpy.target.y |
2321 | + |
2322 | + // dismiss |
2323 | + mouseClick(main, 10, 10, Qt.LeftButton); |
2324 | + popoverSpy.wait(); |
2325 | + |
2326 | + // ensure popover was next to caller |
2327 | + compare(dir, data.dir, "Popover arrow is wrong") |
2328 | + compare(popoverY, data.y, "Popover isn't pointing at the caller") |
2329 | + } |
2330 | + } |
2331 | +} |
2332 | |
2333 | === modified file 'ubuntu-sdk.pro' |
2334 | --- ubuntu-sdk.pro 2015-08-13 09:20:05 +0000 |
2335 | +++ ubuntu-sdk.pro 2015-09-18 16:36:01 +0000 |
2336 | @@ -8,7 +8,7 @@ |
2337 | requires(qtHaveModule(quick)) |
2338 | load(qt_parts) |
2339 | |
2340 | -SUBDIRS += po documentation |
2341 | +SUBDIRS += po documentation ubuntu-ui-toolkit-launcher |
2342 | |
2343 | #when standalone we always want tests to be built |
2344 | !build_with_qt{ |
2345 | |
2346 | === renamed directory 'tests/launcher' => 'ubuntu-ui-toolkit-launcher' |
2347 | === renamed file 'tests/launcher/launcher.pro' => 'ubuntu-ui-toolkit-launcher/ubuntu-ui-toolkit-launcher.pro' |
2348 | --- tests/launcher/launcher.pro 2014-06-17 07:12:49 +0000 |
2349 | +++ ubuntu-ui-toolkit-launcher/ubuntu-ui-toolkit-launcher.pro 2015-09-18 16:36:01 +0000 |
2350 | @@ -6,8 +6,8 @@ |
2351 | HEADERS += MouseTouchAdaptor.h |
2352 | SOURCES += launcher.cpp \ |
2353 | MouseTouchAdaptor.cpp |
2354 | -installPath = $$[QT_INSTALL_LIBS]/ubuntu-ui-toolkit |
2355 | +installPath = $$[QT_INSTALL_PREFIX]/bin |
2356 | launcher.path = $$installPath |
2357 | -launcher.files = launcher |
2358 | +launcher.files = ubuntu-ui-toolkit-launcher |
2359 | INSTALLS += launcher |
2360 |
PASSED: Continuous integration, rev:1639 jenkins. qa.ubuntu. com/job/ ubuntu- ui-toolkit- ci/2234/ jenkins. qa.ubuntu. com/job/ ubuntu- ui-toolkit- vivid-amd64- ci/58 jenkins. qa.ubuntu. com/job/ ubuntu- ui-toolkit- vivid-armhf- ci/58 jenkins. qa.ubuntu. com/job/ ubuntu- ui-toolkit- vivid-armhf- ci/58/artifact/ work/output/ *zip*/output. zip
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/ubuntu- ui-toolkit- ci/2234/ rebuild
http://