Merge lp:~unity-team/unity8/scope-settings into lp:unity8

Proposed by Michał Sawicz
Status: Merged
Approved by: Michał Sawicz
Approved revision: 1151
Merged at revision: 1214
Proposed branch: lp:~unity-team/unity8/scope-settings
Merge into: lp:unity8
Prerequisite: lp:~unity-team/unity8/alt_nav_support
Diff against target: 1676 lines (+1093/-74)
28 files modified
qml/Dash/Dash.qml (+1/-1)
qml/Dash/DashContent.qml (+4/-4)
qml/Dash/GenericScopeView.qml (+67/-26)
qml/Dash/PageHeader.qml (+9/-3)
qml/Dash/PreviewListView.qml (+11/-1)
qml/Dash/ScopeSettings/ScopeSetting.qml (+37/-0)
qml/Dash/ScopeSettings/ScopeSettingBoolean.qml (+61/-0)
qml/Dash/ScopeSettings/ScopeSettingList.qml (+50/-0)
qml/Dash/ScopeSettings/ScopeSettingNumber.qml (+21/-0)
qml/Dash/ScopeSettings/ScopeSettingString.qml (+83/-0)
qml/Dash/ScopeSettings/ScopeSettingsWidgetFactory.qml (+57/-0)
qml/Dash/ScopeSettingsPage.qml (+62/-0)
qml/Dash/ScopesOverview.qml (+2/-0)
tests/autopilot/unity8/shell/emulators/dash.py (+5/-5)
tests/mocks/Unity/CMakeLists.txt (+2/-0)
tests/mocks/Unity/fake_scope.cpp (+3/-1)
tests/mocks/Unity/fake_scope.h (+1/-0)
tests/mocks/Unity/fake_settingsmodel.cpp (+95/-0)
tests/mocks/Unity/fake_settingsmodel.h (+54/-0)
tests/mocks/Unity/fake_unity_plugin.cpp (+2/-0)
tests/qmltests/CMakeLists.txt (+5/-0)
tests/qmltests/Dash/Previews/tst_PreviewWidgetFactory.qml (+1/-1)
tests/qmltests/Dash/ScopeSettings/tst_ScopeSettingBoolean.qml (+62/-0)
tests/qmltests/Dash/ScopeSettings/tst_ScopeSettingList.qml (+84/-0)
tests/qmltests/Dash/ScopeSettings/tst_ScopeSettingNumber.qml (+98/-0)
tests/qmltests/Dash/ScopeSettings/tst_ScopeSettingString.qml (+88/-0)
tests/qmltests/Dash/ScopeSettings/tst_ScopeSettingsWidgetFactory.qml (+65/-0)
tests/qmltests/Dash/tst_GenericScopeView.qml (+63/-32)
To merge this branch: bzr merge lp:~unity-team/unity8/scope-settings
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Michał Sawicz Approve
Review via email: mp+232296@code.launchpad.net

This proposal supersedes a proposal from 2014-08-08.

Commit message

Add scope settings UI

Accessible through the page header in scope pages on supported scopes.

Description of the change

 * Are there any related MPs required for this MP to build/function as expected? Please list.
No
 * Did you perform an exploratory manual test run of your code change and any related functionality?
Yes
 * Did you make sure that your branch does not contain spurious tags?
Yes
 * If you changed the packaging (debian), did you subscribe the ubuntu-unity team to this MP?
n/a
 * If you changed the UI, has there been a design review?
There are no final designs yet, but this is consistent with the rest of the UI

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
Michał Sawicz (saviq) wrote : Posted in a previous version of this proposal

Please delete tag 7.85+14.10.20140428.2-0ubuntu1 in this branch and any local checkouts you might have.

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
Michał Sawicz (saviq) wrote : Posted in a previous version of this proposal

You need to disable dash overview when in settings.

Fields don't get focus when tapped on list item.

I assume there's no way to override the color of:
- labels in ItemSelector
- checkbox? should it?

Previews are always opened starting at the first one, not the one clicked. Rebase on lp:~saviq/unity8/fix-horizontal-list-activation and add tests to ensure which item is opened. Doesn't even conflict (but you do need to replace previewListView with subPageLoader).

More to come.

review: Needs Fixing
Revision history for this message
Michał Sawicz (saviq) wrote : Posted in a previous version of this proposal

See inline.

Didn't review tests yet, will review after other review comments are addressed.

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Approve (continuous-integration)
Revision history for this message
Andrea Cimitan (cimi) : Posted in a previous version of this proposal
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
Michał Sawicz (saviq) wrote : Posted in a previous version of this proposal

See inline. There's a bunch of unanswered comments in the previous review, please answer them too.

Re: shown split or separate, I'd rather merge them unless there's a real reason why not to.

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Approve (continuous-integration)
Revision history for this message
Andrea Cimitan (cimi) : Posted in a previous version of this proposal
Revision history for this message
Michał Sawicz (saviq) wrote : Posted in a previous version of this proposal

Do we really only want to show this once the loader is ready? There will be a delay between user tapping and the page going in on screen? OTOH that gives us protection from a broken subpage, so maybe that's fine...

Otherwise see inline.

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Approve (continuous-integration)
Revision history for this message
Michał Sawicz (saviq) : Posted in a previous version of this proposal
review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Michał Sawicz (saviq) :
review: Needs Fixing
lp:~unity-team/unity8/scope-settings updated
1150. By Andrea Cimitan

Add link to bug

1151. By Andrea Cimitan

Fixed indent

Revision history for this message
Michał Sawicz (saviq) wrote :

 * Did you perform an exploratory manual test run of the code change and any related functionality?
Y, works!
 * Did CI run pass? If not, please explain why.
Y

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'qml/Dash/Dash.qml'
2--- qml/Dash/Dash.qml 2014-08-08 09:41:13 +0000
3+++ qml/Dash/Dash.qml 2014-08-27 08:28:24 +0000
4@@ -341,7 +341,7 @@
5 objectName: "overviewDragHandle"
6 z: 1
7 direction: Direction.Upwards
8- enabled: !dashContent.previewShown &&
9+ enabled: !dashContent.subPageShown &&
10 dashContent.currentScope &&
11 dashContent.currentScope.searchQuery == "" &&
12 (overviewController.progress == 0 || dragging)
13
14=== modified file 'qml/Dash/DashContent.qml'
15--- qml/Dash/DashContent.qml 2014-08-08 08:47:36 +0000
16+++ qml/Dash/DashContent.qml 2014-08-27 08:28:24 +0000
17@@ -27,8 +27,8 @@
18 readonly property alias currentIndex: dashContentList.currentIndex
19 readonly property string currentScopeId: dashContentList.currentItem ? dashContentList.currentItem.scopeId : ""
20 readonly property var currentScope: dashContentList.currentItem ? dashContentList.currentItem.theScope : null
21- readonly property bool previewShown: dashContentList.currentItem && dashContentList.currentItem.item ?
22- dashContentList.currentItem.item.previewShown : false
23+ readonly property bool subPageShown: dashContentList.currentItem && dashContentList.currentItem.item ?
24+ dashContentList.currentItem.item.subPageShown : false
25 readonly property bool processing: dashContentList.currentItem && dashContentList.currentItem.item
26 && dashContentList.currentItem.item.processing || false
27 readonly property bool pageHeaderTotallyVisible: dashContentList.currentItem && dashContentList.currentItem.item
28@@ -96,8 +96,7 @@
29 id: dashContentList
30 objectName: "dashContentList"
31
32- interactive: dashContent.scopes.loaded && currentItem && !currentItem.moving && !currentItem.navigationShown
33-
34+ interactive: dashContent.scopes.loaded && currentItem && !currentItem.moving && !currentItem.navigationShown && !currentItem.subPageShown
35 anchors.fill: parent
36 orientation: ListView.Horizontal
37 boundsBehavior: Flickable.DragAndOvershootBounds
38@@ -137,6 +136,7 @@
39
40 readonly property bool moving: item ? item.moving : false
41 readonly property bool navigationShown: item ? item.navigationShown : false
42+ readonly property bool subPageShown: item ? item.subPageShown : false
43 readonly property var categoryView: item ? item.categoryView : null
44 readonly property var theScope: scope
45
46
47=== modified file 'qml/Dash/GenericScopeView.qml'
48--- qml/Dash/GenericScopeView.qml 2014-08-27 08:28:24 +0000
49+++ qml/Dash/GenericScopeView.qml 2014-08-27 08:28:24 +0000
50@@ -34,7 +34,7 @@
51 property bool enableHeightBehaviorOnNextCreation: false
52 property var categoryView: categoryView
53 property bool showPageHeader: true
54- readonly property alias previewShown: previewListView.open
55+ readonly property alias subPageShown: subPageLoader.subPageShown
56 property int paginationCount: 0
57 property int paginationIndex: 0
58 property alias pageHeaderTotallyVisible: categoryView.pageHeaderTotallyVisible
59@@ -43,7 +43,7 @@
60 style: scope ? scope.customizations : {}
61 }
62
63- readonly property bool processing: scope ? scope.searchInProgress || previewListView.processing : false
64+ readonly property bool processing: scope ? scope.searchInProgress || subPageLoader.processing : false
65
66 signal backClicked()
67
68@@ -56,7 +56,7 @@
69 }
70
71 function closePreview() {
72- previewListView.open = false;
73+ subPageLoader.closeSubPage()
74 }
75
76 function itemClicked(index, result, item, itemModel, resultsModel, limitedCategoryItemCount) {
77@@ -80,19 +80,19 @@
78 if (limitedCategoryItemCount > 0) {
79 previewLimitModel.model = resultsModel;
80 previewLimitModel.limit = limitedCategoryItemCount;
81- previewListView.model = previewLimitModel;
82+ subPageLoader.model = previewLimitModel;
83 } else {
84- previewListView.model = resultsModel;
85+ subPageLoader.model = resultsModel;
86 }
87- previewListView.currentIndex = -1;
88- previewListView.currentIndex = index;
89- previewListView.open = true;
90+ subPageLoader.initialIndex = -1;
91+ subPageLoader.initialIndex = index;
92+ subPageLoader.openSubPage("preview");
93 }
94
95 Binding {
96 target: scope
97 property: "isActive"
98- value: isCurrent && !previewListView.open
99+ value: isCurrent && !subPageLoader.open
100 }
101
102 SortFilterProxyModel {
103@@ -105,10 +105,10 @@
104 }
105
106 onIsCurrentChanged: {
107- if (showPageHeader) {
108+ if (pageHeaderLoader.item && showPageHeader) {
109 pageHeaderLoader.item.resetSearch();
110 }
111- previewListView.open = false;
112+ subPageLoader.closeSubPage();
113 }
114
115 Binding {
116@@ -127,8 +127,8 @@
117
118 Connections {
119 target: scopeView.scope
120- onShowDash: previewListView.open = false;
121- onHideDash: previewListView.open = false;
122+ onShowDash: subPageLoader.closeSubPage()
123+ onHideDash: subPageLoader.closeSubPage()
124 }
125
126 Rectangle {
127@@ -141,7 +141,7 @@
128 id: categoryView
129 objectName: "categoryListView"
130
131- x: previewListView.open ? -width : 0
132+ x: subPageLoader.open ? -width : 0
133 Behavior on x { UbuntuNumberAnimation { } }
134 width: parent.width
135 height: floatingSeeLess.visible ? parent.height - floatingSeeLess.height + floatingSeeLess.yOffset
136@@ -149,7 +149,7 @@
137 clip: height != parent.height
138
139 model: scopeView.categories
140- forceNoClip: previewListView.open
141+ forceNoClip: subPageLoader.open
142 pixelAligned: true
143 interactive: !navigationShown
144
145@@ -294,10 +294,10 @@
146 // If the filter animation will be seen start it, otherwise, just flip the switch
147 var shrinkingVisible = !shouldExpand && y + item.collapsedHeight + seeAll.height < categoryView.height;
148 var growingVisible = shouldExpand && y + height < categoryView.height;
149- if (!previewListView.open || shouldExpand) {
150+ if (!subPageLoader.open || shouldExpand) {
151 var animate = shrinkingVisible || growingVisible;
152 baseItem.expand(shouldExpand, animate)
153- if (shouldExpand && !previewListView.open) {
154+ if (shouldExpand && !subPageLoader.open) {
155 categoryView.maximizeVisibleArea(index, item.expandedHeight + seeAll.height);
156 }
157 }
158@@ -428,6 +428,7 @@
159 searchHint: scopeView.scope && scopeView.scope.searchHint || i18n.tr("Search")
160 showBackButton: scopeView.hasBackAction
161 searchEntryEnabled: true
162+ settingsEnabled: scopeView.scope && scopeView.scope.settings && scopeView.scope.settings.count > 0 || false
163 scopeStyle: scopeView.scopeStyle
164 paginationCount: scopeView.paginationCount
165 paginationIndex: scopeView.paginationIndex
166@@ -441,6 +442,7 @@
167 }
168
169 onBackClicked: scopeView.backClicked()
170+ onSettingsClicked: subPageLoader.openSubPage("settings")
171 }
172 }
173 }
174@@ -501,21 +503,60 @@
175 id: previewLimitModel
176 }
177
178- PreviewListView {
179- id: previewListView
180- objectName: "previewListView"
181+ Loader {
182+ id: subPageLoader
183+ objectName: "subPageLoader"
184 visible: x != width
185- scope: scopeView.scope
186- scopeStyle: scopeView.scopeStyle
187 width: parent.width
188 height: parent.height
189 anchors.left: categoryView.right
190
191- onOpenChanged: {
192- if (showPageHeader) {
193- pageHeaderLoader.item.unfocus();
194+ property bool open: false
195+ property var scope: scopeView.scope
196+ property var scopeStyle: scopeView.scopeStyle
197+ property int initialIndex: -1
198+ property var model: null
199+
200+ readonly property bool processing: item && item.processing || false
201+ readonly property int count: item && item.count || 0
202+ readonly property int currentIndex: item && item.currentIndex || 0
203+ readonly property var currentItem: item && item.currentItem || null
204+
205+ property string subPage: ""
206+ readonly property bool subPageShown: visible && status === Loader.Ready
207+
208+ function openSubPage(page) {
209+ subPage = page;
210+ }
211+
212+ function closeSubPage() {
213+ open = false;
214+ }
215+
216+ source: switch(subPage) {
217+ case "preview": return "PreviewListView.qml";
218+ case "settings": return "ScopeSettingsPage.qml";
219+ default: return "";
220+ }
221+
222+ onLoaded: {
223+ item.scope = Qt.binding(function() { return subPageLoader.scope; } )
224+ item.scopeStyle = Qt.binding(function() { return subPageLoader.scopeStyle; } )
225+ if (subPage == "preview") {
226+ item.open = Qt.binding(function() { return subPageLoader.open; } )
227+ item.initialIndex = Qt.binding(function() { return subPageLoader.initialIndex; } )
228+ item.model = Qt.binding(function() { return subPageLoader.model; } )
229 }
230+ open = true;
231+ }
232+
233+ onOpenChanged: pageHeaderLoader.item.unfocus()
234+
235+ onVisibleChanged: if (!visible) subPage = ""
236+
237+ Connections {
238+ target: subPageLoader.item
239+ onBackClicked: subPageLoader.closeSubPage()
240 }
241 }
242-
243 }
244
245=== modified file 'qml/Dash/PageHeader.qml'
246--- qml/Dash/PageHeader.qml 2014-08-27 08:28:24 +0000
247+++ qml/Dash/PageHeader.qml 2014-08-27 08:28:24 +0000
248@@ -31,6 +31,7 @@
249 property string title
250
251 property bool searchEntryEnabled: false
252+ property bool settingsEnabled: false
253 property ListModel searchHistory: SearchHistoryModel
254 property alias searchQuery: searchTextField.text
255 property alias searchHint: searchTextField.placeholderText
256@@ -44,6 +45,7 @@
257 property var scopeStyle: null
258
259 signal backClicked()
260+ signal settingsClicked()
261
262 onScopeStyleChanged: refreshLogo()
263 onSearchQueryChanged: {
264@@ -246,9 +248,7 @@
265 backAction: Action {
266 iconName: "back"
267 visible: root.showBackButton
268- onTriggered: {
269- root.backClicked();
270- }
271+ onTriggered: root.backClicked()
272 }
273
274 actions: [
275@@ -260,6 +260,12 @@
276 headerContainer.showSearch = true;
277 searchTextField.forceActiveFocus();
278 }
279+ },
280+ Action {
281+ objectName: "settings"
282+ iconName: "settings"
283+ visible: root.settingsEnabled
284+ onTriggered: root.settingsClicked()
285 }
286 ]
287 }
288
289=== modified file 'qml/Dash/PreviewListView.qml'
290--- qml/Dash/PreviewListView.qml 2014-08-27 08:28:24 +0000
291+++ qml/Dash/PreviewListView.qml 2014-08-27 08:28:24 +0000
292@@ -23,6 +23,7 @@
293 Item {
294 id: root
295
296+ property int initialIndex: -1
297 property var scope: null
298 property var scopeStyle: null
299
300@@ -37,6 +38,8 @@
301 readonly property bool processing: currentItem && (!currentItem.previewModel.loaded
302 || currentItem.previewModel.processingAction)
303
304+ signal backClicked()
305+
306 PageHeader {
307 id: header
308 objectName: "pageHeader"
309@@ -46,7 +49,7 @@
310 searchEntryEnabled: false
311 scopeStyle: root.scopeStyle
312
313- onBackClicked: root.open = false
314+ onBackClicked: root.backClicked()
315 }
316
317 ListView {
318@@ -80,6 +83,13 @@
319 }
320 }
321
322+ onCountChanged: {
323+ if (count > 0 && initialIndex >= 0) {
324+ currentIndex = initialIndex;
325+ initialIndex = -1;
326+ }
327+ }
328+
329 delegate: Previews.Preview {
330 id: preview
331 objectName: "preview" + index
332
333=== added directory 'qml/Dash/ScopeSettings'
334=== added file 'qml/Dash/ScopeSettings/ScopeSetting.qml'
335--- qml/Dash/ScopeSettings/ScopeSetting.qml 1970-01-01 00:00:00 +0000
336+++ qml/Dash/ScopeSettings/ScopeSetting.qml 2014-08-27 08:28:24 +0000
337@@ -0,0 +1,37 @@
338+/*
339+ * Copyright (C) 2014 Canonical, Ltd.
340+ *
341+ * This program is free software; you can redistribute it and/or modify
342+ * it under the terms of the GNU General Public License as published by
343+ * the Free Software Foundation; version 3.
344+ *
345+ * This program is distributed in the hope that it will be useful,
346+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
347+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
348+ * GNU General Public License for more details.
349+ *
350+ * You should have received a copy of the GNU General Public License
351+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
352+ */
353+
354+import QtQuick 2.2
355+import Ubuntu.Components 1.1
356+
357+/*! Interface for settings widgets. */
358+
359+Item {
360+ //! The ScopeStyle component.
361+ property var scopeStyle: null
362+
363+ //! Variable used to contain widget's data
364+ property var widgetData: null
365+
366+ /*! \brief This signal should be emitted when a setting action was updated.
367+ *
368+ * \param value the new setting value.
369+ */
370+ signal updated(var value)
371+
372+ //! \internal
373+ readonly property real settingMargins: units.gu(2)
374+}
375
376=== added file 'qml/Dash/ScopeSettings/ScopeSettingBoolean.qml'
377--- qml/Dash/ScopeSettings/ScopeSettingBoolean.qml 1970-01-01 00:00:00 +0000
378+++ qml/Dash/ScopeSettings/ScopeSettingBoolean.qml 2014-08-27 08:28:24 +0000
379@@ -0,0 +1,61 @@
380+/*
381+ * Copyright (C) 2014 Canonical, Ltd.
382+ *
383+ * This program is free software; you can redistribute it and/or modify
384+ * it under the terms of the GNU General Public License as published by
385+ * the Free Software Foundation; version 3.
386+ *
387+ * This program is distributed in the hope that it will be useful,
388+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
389+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
390+ * GNU General Public License for more details.
391+ *
392+ * You should have received a copy of the GNU General Public License
393+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
394+ */
395+
396+import QtQuick 2.2
397+import Ubuntu.Components 1.1
398+import Ubuntu.Components.ListItems 1.0 as ListItem
399+
400+ScopeSetting {
401+ id: root
402+ height: listItem.height
403+
404+ ListItem.Empty {
405+ id: listItem
406+
407+ onClicked: {
408+ control.checked = !control.checked;
409+ updated(control.checked);
410+ }
411+
412+ Label {
413+ anchors {
414+ left: parent.left
415+ leftMargin: settingMargins
416+ right: control.left
417+ rightMargin: units.gu(1)
418+ verticalCenter: parent.verticalCenter
419+ }
420+ text: widgetData.displayName
421+ elide: Text.ElideMiddle
422+ maximumLineCount: 2
423+ wrapMode: Text.Wrap
424+ color: scopeStyle ? scopeStyle.foreground : Theme.palette.normal.baseText
425+ }
426+
427+ CheckBox {
428+ id: control
429+ objectName: "control"
430+ anchors {
431+ right: parent.right
432+ rightMargin: settingMargins
433+ verticalCenter: parent.verticalCenter
434+ }
435+ checked: widgetData.value
436+
437+ onTriggered: root.updated(checked)
438+ }
439+ }
440+}
441
442=== added file 'qml/Dash/ScopeSettings/ScopeSettingList.qml'
443--- qml/Dash/ScopeSettings/ScopeSettingList.qml 1970-01-01 00:00:00 +0000
444+++ qml/Dash/ScopeSettings/ScopeSettingList.qml 2014-08-27 08:28:24 +0000
445@@ -0,0 +1,50 @@
446+/*
447+ * Copyright (C) 2014 Canonical, Ltd.
448+ *
449+ * This program is free software; you can redistribute it and/or modify
450+ * it under the terms of the GNU General Public License as published by
451+ * the Free Software Foundation; version 3.
452+ *
453+ * This program is distributed in the hope that it will be useful,
454+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
455+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
456+ * GNU General Public License for more details.
457+ *
458+ * You should have received a copy of the GNU General Public License
459+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
460+ */
461+
462+import QtQuick 2.2
463+import Ubuntu.Components 1.1
464+import Ubuntu.Components.ListItems 1.0 as ListItem
465+
466+ScopeSetting {
467+ id: root
468+
469+ // FIXME workaround for: https://bugs.launchpad.net/ubuntu/+source/ubuntu-ui-toolkit/+bug/1355830
470+ height: listItem.currentlyExpanded ? listItem.itemHeight * widgetData.properties["values"].length + units.gu(6) : listItem.height
471+
472+ property int initialValue: -1
473+
474+ ListItem.ItemSelector {
475+ id: listItem
476+ objectName: "control"
477+ anchors {
478+ left: parent.left
479+ right: parent.right
480+ }
481+ text: widgetData.displayName
482+ model: widgetData.properties["values"]
483+
484+ onSelectedIndexChanged: {
485+ if (root.initialValue >= 0) {
486+ var tmpValue = root.initialValue;
487+ root.initialValue = -1;
488+ selectedIndex = tmpValue;
489+ return;
490+ }
491+
492+ root.updated(selectedIndex);
493+ }
494+ }
495+}
496
497=== added file 'qml/Dash/ScopeSettings/ScopeSettingNumber.qml'
498--- qml/Dash/ScopeSettings/ScopeSettingNumber.qml 1970-01-01 00:00:00 +0000
499+++ qml/Dash/ScopeSettings/ScopeSettingNumber.qml 2014-08-27 08:28:24 +0000
500@@ -0,0 +1,21 @@
501+/*
502+ * Copyright (C) 2014 Canonical, Ltd.
503+ *
504+ * This program is free software; you can redistribute it and/or modify
505+ * it under the terms of the GNU General Public License as published by
506+ * the Free Software Foundation; version 3.
507+ *
508+ * This program is distributed in the hope that it will be useful,
509+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
510+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
511+ * GNU General Public License for more details.
512+ *
513+ * You should have received a copy of the GNU General Public License
514+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
515+ */
516+
517+import QtQuick 2.2
518+
519+ScopeSettingString {
520+ mode: "number"
521+}
522
523=== added file 'qml/Dash/ScopeSettings/ScopeSettingString.qml'
524--- qml/Dash/ScopeSettings/ScopeSettingString.qml 1970-01-01 00:00:00 +0000
525+++ qml/Dash/ScopeSettings/ScopeSettingString.qml 2014-08-27 08:28:24 +0000
526@@ -0,0 +1,83 @@
527+/*
528+ * Copyright (C) 2014 Canonical, Ltd.
529+ *
530+ * This program is free software; you can redistribute it and/or modify
531+ * it under the terms of the GNU General Public License as published by
532+ * the Free Software Foundation; version 3.
533+ *
534+ * This program is distributed in the hope that it will be useful,
535+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
536+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
537+ * GNU General Public License for more details.
538+ *
539+ * You should have received a copy of the GNU General Public License
540+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
541+ */
542+
543+import QtQuick 2.2
544+import Ubuntu.Components 1.1
545+import Ubuntu.Components.ListItems 1.0 as ListItem
546+
547+ScopeSetting {
548+ id: root
549+ height: listItem.height
550+
551+ property string mode: "string"
552+
553+ ListItem.Empty {
554+ id: listItem
555+ onClicked: {
556+ control.forceActiveFocus();
557+ control.selectAll();
558+ }
559+
560+ Label {
561+ id: label
562+ anchors {
563+ left: parent.left
564+ leftMargin: settingMargins
565+ right: control.left
566+ rightMargin: units.gu(1)
567+ verticalCenter: parent.verticalCenter
568+ }
569+ text: widgetData.displayName
570+ elide: Text.ElideMiddle
571+ maximumLineCount: 2
572+ wrapMode: Text.Wrap
573+ color: scopeStyle ? scopeStyle.foreground : Theme.palette.normal.baseText
574+ }
575+
576+ TextField {
577+ id: control
578+ objectName: "control"
579+ anchors {
580+ right: parent.right
581+ rightMargin: settingMargins
582+ verticalCenter: parent.verticalCenter
583+ }
584+ width: root.mode == "number" ? units.gu(8) : units.gu(12)
585+ text: widgetData.value
586+ color: scopeStyle ? scopeStyle.foreground : Theme.palette.normal.fieldText
587+ validator: root.mode == "number" ? doubleValidator : null
588+ hasClearButton: root.mode == "number" ? false : true
589+
590+ DoubleValidator {
591+ id: doubleValidator
592+ }
593+
594+ function updateText() {
595+ if (acceptableInput) {
596+ text = displayText;
597+ root.updated(text);
598+ }
599+ }
600+
601+ onAccepted: updateText()
602+ onActiveFocusChanged: {
603+ if (!activeFocus) {
604+ updateText();
605+ }
606+ }
607+ }
608+ }
609+}
610
611=== added file 'qml/Dash/ScopeSettings/ScopeSettingsWidgetFactory.qml'
612--- qml/Dash/ScopeSettings/ScopeSettingsWidgetFactory.qml 1970-01-01 00:00:00 +0000
613+++ qml/Dash/ScopeSettings/ScopeSettingsWidgetFactory.qml 2014-08-27 08:28:24 +0000
614@@ -0,0 +1,57 @@
615+/*
616+ * Copyright (C) 2014 Canonical, Ltd.
617+ *
618+ * This program is free software; you can redistribute it and/or modify
619+ * it under the terms of the GNU General Public License as published by
620+ * the Free Software Foundation; version 3.
621+ *
622+ * This program is distributed in the hope that it will be useful,
623+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
624+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
625+ * GNU General Public License for more details.
626+ *
627+ * You should have received a copy of the GNU General Public License
628+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
629+ */
630+
631+import QtQuick 2.2
632+
633+//! \brief This component loads the widgets based on type.
634+
635+Loader {
636+ id: root
637+
638+ //! The ScopeStyle component.
639+ property var scopeStyle: null
640+
641+ //! Variable used to contain widget's data
642+ property var widgetData: null
643+
644+ //! Triggered signal forwarded from the widgets.
645+ signal updated(var value)
646+
647+ source: widgetSource
648+
649+ //! \cond private
650+ property url widgetSource: {
651+ switch (widgetData.type) {
652+ case "boolean": return "ScopeSettingBoolean.qml";
653+ case "list": return "ScopeSettingList.qml";
654+ case "number": return "ScopeSettingNumber.qml";
655+ case "string": return "ScopeSettingString.qml";
656+ default: return "";
657+ }
658+ }
659+ //! \endcond
660+
661+ onLoaded: {
662+ if (item.hasOwnProperty("initialValue")) item.initialValue = root.widgetData.value;
663+ item.widgetData = Qt.binding(function() { return root.widgetData; } )
664+ item.scopeStyle = Qt.binding(function() { return root.scopeStyle; } )
665+ }
666+
667+ Connections {
668+ target: root.item
669+ onUpdated: if (value !== widgetData.value) root.updated(value)
670+ }
671+}
672
673=== added file 'qml/Dash/ScopeSettingsPage.qml'
674--- qml/Dash/ScopeSettingsPage.qml 1970-01-01 00:00:00 +0000
675+++ qml/Dash/ScopeSettingsPage.qml 2014-08-27 08:28:24 +0000
676@@ -0,0 +1,62 @@
677+/*
678+ * Copyright (C) 2014 Canonical, Ltd.
679+ *
680+ * This program is free software; you can redistribute it and/or modify
681+ * it under the terms of the GNU General Public License as published by
682+ * the Free Software Foundation; version 3.
683+ *
684+ * This program is distributed in the hope that it will be useful,
685+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
686+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
687+ * GNU General Public License for more details.
688+ *
689+ * You should have received a copy of the GNU General Public License
690+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
691+ */
692+
693+import QtQuick 2.2
694+import Ubuntu.Components 1.1
695+import Unity 0.2
696+import "../Components"
697+import "ScopeSettings"
698+
699+Item {
700+ id: root
701+
702+ property var scope: null
703+ property var scopeStyle: null
704+
705+ signal backClicked()
706+
707+ PageHeader {
708+ id: header
709+ objectName: "pageHeader"
710+ width: parent.width
711+ title: scope ? scope.name : ""
712+ showBackButton: true
713+ scopeStyle: root.scopeStyle
714+
715+ onBackClicked: root.backClicked()
716+ }
717+
718+ ListView {
719+ id: scopeSettings
720+ objectName: "scopeSettings"
721+ anchors {
722+ top: header.bottom
723+ bottom: parent.bottom
724+ left: parent.left
725+ right: parent.right
726+ }
727+ model: root.scope ? root.scope.settings : null
728+
729+ delegate: ScopeSettingsWidgetFactory {
730+ objectName: "scopeSettingItem" + index
731+ width: root.width
732+ widgetData: model
733+ scopeStyle: root.scopeStyle
734+
735+ onUpdated: model.value = value;
736+ }
737+ }
738+}
739
740=== modified file 'qml/Dash/ScopesOverview.qml'
741--- qml/Dash/ScopesOverview.qml 2014-08-27 08:28:24 +0000
742+++ qml/Dash/ScopesOverview.qml 2014-08-27 08:28:24 +0000
743@@ -468,6 +468,8 @@
744 width: parent.width
745 height: parent.height
746 anchors.left: scopesOverviewContent.right
747+
748+ onBackClicked: open = false
749 }
750
751 Item {
752
753=== modified file 'tests/autopilot/unity8/shell/emulators/dash.py'
754--- tests/autopilot/unity8/shell/emulators/dash.py 2014-08-14 01:29:20 +0000
755+++ tests/autopilot/unity8/shell/emulators/dash.py 2014-08-27 08:28:24 +0000
756@@ -140,10 +140,9 @@
757
758 def enter_search_query(self, query):
759 current_header = self._get_current_page_header()
760- self.pointing_device.move(current_header.globalRect.x +
761- current_header.width - current_header.height / 4,
762- current_header.globalRect.y +
763- current_header.height / 4)
764+ search_button = current_header.select_single(objectName="search_header_button")
765+ self.pointing_device.move(search_button.globalRect.x + search_button.width / 2,
766+ search_button.globalRect.y + search_button.height / 2)
767 self.pointing_device.click()
768 headerContainer = current_header.select_single(
769 objectName="headerContainer")
770@@ -186,7 +185,8 @@
771 # --elopio - 2014-1-14
772 self.click_scope_item(category, app_name)
773 preview_list = self.wait_select_single(
774- 'PreviewListView', objectName='previewListView')
775+ 'QQuickLoader', objectName='subPageLoader')
776+ preview_list.subPageShown.wait_for(True)
777 preview_list.x.wait_for(0)
778 return preview_list.select_single(
779 Preview, objectName='preview{}'.format(preview_list.currentIndex))
780
781=== modified file 'tests/mocks/Unity/CMakeLists.txt'
782--- tests/mocks/Unity/CMakeLists.txt 2014-08-25 10:05:13 +0000
783+++ tests/mocks/Unity/CMakeLists.txt 2014-08-27 08:28:24 +0000
784@@ -24,6 +24,7 @@
785 fake_scope.cpp
786 fake_scopes.cpp
787 fake_scopesoverview.cpp
788+ fake_settingsmodel.cpp
789 fake_categories.cpp
790 fake_navigation.cpp
791 fake_resultsmodel.cpp
792@@ -39,6 +40,7 @@
793 ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/ResultsModelInterface.h
794 ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/ScopeInterface.h
795 ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/ScopesInterface.h
796+ ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/SettingsModelInterface.h
797 )
798
799 add_library(FakeUnityQml MODULE ${UnityQML_SOURCES})
800
801=== modified file 'tests/mocks/Unity/fake_scope.cpp'
802--- tests/mocks/Unity/fake_scope.cpp 2014-08-27 08:28:24 +0000
803+++ tests/mocks/Unity/fake_scope.cpp 2014-08-27 08:28:24 +0000
804@@ -22,6 +22,7 @@
805 #include "fake_navigation.h"
806 #include "fake_resultsmodel.h"
807 #include "fake_scopes.h"
808+#include "fake_settingsmodel.h"
809
810 Scope::Scope(Scopes* parent) : Scope(QString(), QString(), false, parent)
811 {
812@@ -39,6 +40,7 @@
813 , m_previewRendererName("preview-generic")
814 , m_categories(new Categories(categories, this))
815 , m_openScope(nullptr)
816+ , m_settings(new SettingsModel(this))
817 {
818 }
819
820@@ -94,7 +96,7 @@
821
822 unity::shell::scopes::SettingsModelInterface* Scope::settings() const
823 {
824- return nullptr;
825+ return m_settings;
826 }
827
828 QString Scope::noResultsHint() const
829
830=== modified file 'tests/mocks/Unity/fake_scope.h'
831--- tests/mocks/Unity/fake_scope.h 2014-08-07 08:52:59 +0000
832+++ tests/mocks/Unity/fake_scope.h 2014-08-27 08:28:24 +0000
833@@ -96,6 +96,7 @@
834
835 unity::shell::scopes::CategoriesInterface* m_categories;
836 unity::shell::scopes::ScopeInterface* m_openScope;
837+ unity::shell::scopes::SettingsModelInterface* m_settings;
838 };
839
840 #endif // FAKE_SCOPE_H
841
842=== added file 'tests/mocks/Unity/fake_settingsmodel.cpp'
843--- tests/mocks/Unity/fake_settingsmodel.cpp 1970-01-01 00:00:00 +0000
844+++ tests/mocks/Unity/fake_settingsmodel.cpp 2014-08-27 08:28:24 +0000
845@@ -0,0 +1,95 @@
846+/*
847+ * Copyright (C) 2014 Canonical, Ltd.
848+ *
849+ * This program is free software; you can redistribute it and/or modify
850+ * it under the terms of the GNU General Public License as published by
851+ * the Free Software Foundation; version 3.
852+ *
853+ * This program is distributed in the hope that it will be useful,
854+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
855+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
856+ * GNU General Public License for more details.
857+ *
858+ * You should have received a copy of the GNU General Public License
859+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
860+ */
861+
862+#include "fake_settingsmodel.h"
863+
864+SettingsModel::SettingsModel(QObject* parent) :
865+ SettingsModelInterface(parent) {
866+ {
867+ QVariantMap parameters;
868+ m_data << QSharedPointer<Data>(new Data("boolean-setting", "Boolean Setting", "boolean", parameters, true));
869+ }
870+ {
871+ QVariantMap parameters;
872+ parameters["values"] = QVariantList() << "First" << "Second" << "Third";
873+ m_data << QSharedPointer<Data>(new Data("list-setting", "List Setting", "list", parameters, 1));
874+ }
875+ {
876+ QVariantMap parameters;
877+ m_data << QSharedPointer<Data>(new Data("number-setting", "Number Setting", "number", parameters, 1.23));
878+ }
879+ {
880+ QVariantMap parameters;
881+ m_data << QSharedPointer<Data>(new Data("string-setting", "String Setting", "string", parameters, "flibble"));
882+ }
883+}
884+
885+QVariant SettingsModel::data(const QModelIndex& index, int role) const {
886+ int row = index.row();
887+ QVariant result;
888+
889+ if (row < m_data.size()) {
890+ auto data = m_data[row];
891+
892+ switch (role) {
893+ case Roles::RoleSettingId:
894+ result = data->id;
895+ break;
896+ case Roles::RoleDisplayName:
897+ result = data->displayName;
898+ break;
899+ case Roles::RoleType:
900+ result = data->type;
901+ break;
902+ case Roles::RoleProperties:
903+ result = data->properties;
904+ break;
905+ case Roles::RoleValue: {
906+ result = data->value;
907+ break;
908+ }
909+ default:
910+ break;
911+ }
912+ }
913+
914+ return result;
915+}
916+
917+bool SettingsModel::setData(const QModelIndex &index, const QVariant &value, int role) {
918+ int row = index.row();
919+ if (row < m_data.size()) {
920+ switch (role) {
921+ case SettingsModelInterface::RoleValue: {
922+ auto data = m_data[row];
923+ data->value = value;
924+ return true;
925+ }
926+ default:
927+ break;
928+ }
929+ }
930+
931+ return false;
932+}
933+
934+int SettingsModel::rowCount(const QModelIndex&) const {
935+ return count();
936+}
937+
938+int SettingsModel::count() const {
939+ return m_data.size();
940+}
941
942=== added file 'tests/mocks/Unity/fake_settingsmodel.h'
943--- tests/mocks/Unity/fake_settingsmodel.h 1970-01-01 00:00:00 +0000
944+++ tests/mocks/Unity/fake_settingsmodel.h 2014-08-27 08:28:24 +0000
945@@ -0,0 +1,54 @@
946+/*
947+ * Copyright (C) 2014 Canonical, Ltd.
948+ *
949+ * This program is free software; you can redistribute it and/or modify
950+ * it under the terms of the GNU General Public License as published by
951+ * the Free Software Foundation; version 3.
952+ *
953+ * This program is distributed in the hope that it will be useful,
954+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
955+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
956+ * GNU General Public License for more details.
957+ *
958+ * You should have received a copy of the GNU General Public License
959+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
960+ */
961+
962+#ifndef FAKE_SETTINGSMODEL_H
963+#define FAKE_SETTINGSMODEL_H
964+
965+#include <unity/shell/scopes/SettingsModelInterface.h>
966+
967+#include <QList>
968+#include <QSharedPointer>
969+
970+class SettingsModel: public unity::shell::scopes::SettingsModelInterface {
971+Q_OBJECT
972+
973+ struct Data {
974+ QString id;
975+ QString displayName;
976+ QString type;
977+ QVariant properties;
978+ QVariant value;
979+
980+ Data(QString const& id_, QString const& displayName_,
981+ QString const& type_, QVariant const& properties_,
982+ QVariant const& value_) :
983+ id(id_), displayName(displayName_), type(type_),
984+ properties(properties_), value(value_) {}
985+ };
986+
987+public:
988+ explicit SettingsModel(QObject* parent = 0);
989+ ~SettingsModel() = default;
990+ QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
991+ bool setData(const QModelIndex&index, const QVariant& value, int role = Qt::EditRole) override;
992+ int rowCount(const QModelIndex& parent = QModelIndex()) const override;
993+ int count() const override;
994+
995+protected:
996+ QList<QSharedPointer<Data>> m_data;
997+};
998+
999+#endif // FAKE_SETTINGSMODEL_H
1000
1001=== modified file 'tests/mocks/Unity/fake_unity_plugin.cpp'
1002--- tests/mocks/Unity/fake_unity_plugin.cpp 2014-08-11 09:57:29 +0000
1003+++ tests/mocks/Unity/fake_unity_plugin.cpp 2014-08-27 08:28:24 +0000
1004@@ -26,6 +26,7 @@
1005 #include "fake_previewmodel.h"
1006 #include "fake_previewwidgetmodel.h"
1007 #include "fake_resultsmodel.h"
1008+#include "fake_settingsmodel.h"
1009
1010 // External
1011 #include <glib-object.h>
1012@@ -43,6 +44,7 @@
1013 qmlRegisterType<Scopes>(uri, 0, 2, "Scopes");
1014 qmlRegisterType<Scope>(uri, 0, 2, "MockScope");
1015 qmlRegisterUncreatableType<unity::shell::scopes::ScopeInterface>(uri, 0, 2, "Scope", "Can't create Scope object in QML.");
1016+ qmlRegisterUncreatableType<unity::shell::scopes::SettingsModelInterface>(uri, 0, 2, "SettingsModel", "Can't create SettingsModel object in QML.");
1017 qmlRegisterUncreatableType<unity::shell::scopes::NavigationInterface>(uri, 0, 2, "Navigation", "Can't create Navigation object in QML.");
1018 qmlRegisterUncreatableType<unity::shell::scopes::CategoriesInterface>(uri, 0, 2, "Categories", "Can't create Categories object in QML.");
1019 qmlRegisterUncreatableType<unity::shell::scopes::PreviewModelInterface>(uri, 0, 2, "PreviewModel", "Can't create new PreviewModel in QML. Get them from PreviewStack instance.");
1020
1021=== modified file 'tests/qmltests/CMakeLists.txt'
1022--- tests/qmltests/CMakeLists.txt 2014-08-27 08:28:24 +0000
1023+++ tests/qmltests/CMakeLists.txt 2014-08-27 08:28:24 +0000
1024@@ -55,6 +55,11 @@
1025 add_qml_test(Dash/Previews PreviewVideoPlayback)
1026 add_qml_test(Dash/Previews PreviewWidgetFactory)
1027 add_qml_test(Dash/Previews PreviewZoomableImage)
1028+add_qml_test(Dash/ScopeSettings ScopeSettingBoolean)
1029+add_qml_test(Dash/ScopeSettings ScopeSettingList)
1030+add_qml_test(Dash/ScopeSettings ScopeSettingNumber)
1031+add_qml_test(Dash/ScopeSettings ScopeSettingString)
1032+add_qml_test(Dash/ScopeSettings ScopeSettingsWidgetFactory)
1033 add_qml_test(Greeter Lockscreen ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/libusermetrics:${CMAKE_BINARY_DIR}/tests/mocks/LightDM/full")
1034 add_qml_test(Greeter MultiGreeter ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/libusermetrics:${CMAKE_BINARY_DIR}/tests/mocks/LightDM/full")
1035 add_qml_test(Greeter SingleGreeter ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/libusermetrics:${CMAKE_BINARY_DIR}/tests/mocks/LightDM/single")
1036
1037=== modified file 'tests/qmltests/Dash/Previews/tst_PreviewWidgetFactory.qml'
1038--- tests/qmltests/Dash/Previews/tst_PreviewWidgetFactory.qml 2014-08-27 08:28:24 +0000
1039+++ tests/qmltests/Dash/Previews/tst_PreviewWidgetFactory.qml 2014-08-27 08:28:24 +0000
1040@@ -94,7 +94,7 @@
1041 factory.widgetData = { type: data.type };
1042 factory.widgetType = data.type;
1043
1044- verify(("" + factory.source).indexOf(data.source) != -1);
1045+ verify((String(factory.source)).indexOf(data.source) != -1);
1046 }
1047 }
1048 }
1049
1050=== added directory 'tests/qmltests/Dash/ScopeSettings'
1051=== added file 'tests/qmltests/Dash/ScopeSettings/tst_ScopeSettingBoolean.qml'
1052--- tests/qmltests/Dash/ScopeSettings/tst_ScopeSettingBoolean.qml 1970-01-01 00:00:00 +0000
1053+++ tests/qmltests/Dash/ScopeSettings/tst_ScopeSettingBoolean.qml 2014-08-27 08:28:24 +0000
1054@@ -0,0 +1,62 @@
1055+/*
1056+ * Copyright 2014 Canonical Ltd.
1057+ *
1058+ * This program is free software; you can redistribute it and/or modify
1059+ * it under the terms of the GNU General Public License as published by
1060+ * the Free Software Foundation; version 3.
1061+ *
1062+ * This program is distributed in the hope that it will be useful,
1063+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1064+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1065+ * GNU General Public License for more details.
1066+ *
1067+ * You should have received a copy of the GNU General Public License
1068+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1069+ */
1070+
1071+import QtQuick 2.0
1072+import Ubuntu.Components 1.1
1073+import QtTest 1.0
1074+import "../../../../qml/Dash/ScopeSettings"
1075+import Unity.Test 0.1 as UT
1076+
1077+Rectangle {
1078+ id: root
1079+ width: units.gu(40)
1080+ height: units.gu(80)
1081+
1082+ property var settingData: {
1083+ "displayName" : "Mock boolean setting",
1084+ "value": true
1085+ }
1086+
1087+ ScopeSettingBoolean {
1088+ id: scopeSetting
1089+ widgetData: settingData
1090+ width: parent.width
1091+ }
1092+
1093+ SignalSpy {
1094+ id: spy
1095+ target: scopeSetting
1096+ signalName: "updated"
1097+ }
1098+
1099+ UT.UnityTestCase {
1100+ id: testCase
1101+ name: "ScopeSettingBoolean"
1102+ when: windowShown
1103+
1104+ function test_updated() {
1105+ var control = findChild(scopeSetting, "control");
1106+ mouseClick(control, control.width / 2, control.height / 2);
1107+ spy.wait();
1108+ compare(spy.signalArguments[0][0], false);
1109+
1110+ spy.clear();
1111+ mouseClick(scopeSetting, scopeSetting.width / 2, scopeSetting.height / 2);
1112+ spy.wait();
1113+ compare(spy.signalArguments[0][0], true);
1114+ }
1115+ }
1116+}
1117
1118=== added file 'tests/qmltests/Dash/ScopeSettings/tst_ScopeSettingList.qml'
1119--- tests/qmltests/Dash/ScopeSettings/tst_ScopeSettingList.qml 1970-01-01 00:00:00 +0000
1120+++ tests/qmltests/Dash/ScopeSettings/tst_ScopeSettingList.qml 2014-08-27 08:28:24 +0000
1121@@ -0,0 +1,84 @@
1122+/*
1123+ * Copyright 2014 Canonical Ltd.
1124+ *
1125+ * This program is free software; you can redistribute it and/or modify
1126+ * it under the terms of the GNU General Public License as published by
1127+ * the Free Software Foundation; version 3.
1128+ *
1129+ * This program is distributed in the hope that it will be useful,
1130+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1131+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1132+ * GNU General Public License for more details.
1133+ *
1134+ * You should have received a copy of the GNU General Public License
1135+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1136+ */
1137+
1138+import QtQuick 2.0
1139+import Ubuntu.Components 1.1
1140+import QtTest 1.0
1141+import "../../../../qml/Dash/ScopeSettings"
1142+import Unity.Test 0.1 as UT
1143+
1144+Rectangle {
1145+ id: root
1146+ width: units.gu(40)
1147+ height: units.gu(80)
1148+
1149+ property var settingData: {
1150+ "displayName" : "Mock list setting",
1151+ "properties": { "values" : [ "first", "second", "third" ] }
1152+ }
1153+
1154+ ScopeSettingList {
1155+ id: scopeSetting
1156+ width: parent.width
1157+ widgetData: settingData
1158+ }
1159+
1160+ SignalSpy {
1161+ id: spy
1162+ target: scopeSetting
1163+ signalName: "updated"
1164+ }
1165+
1166+ UT.UnityTestCase {
1167+ id: testCase
1168+ name: "ScopeSettingList"
1169+ when: windowShown
1170+
1171+ property var control: findChild(scopeSetting, "control")
1172+
1173+ function cleanup() {
1174+ control.selectedIndex = 0;
1175+ spy.clear();
1176+ }
1177+
1178+ function test_initialValue() {
1179+ // there's no initialIndex, so we workaround, testing is difficult too https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1362031
1180+ var newObject = Qt.createQmlObject('import "../../../../qml/Dash/ScopeSettings" \n\
1181+ ScopeSettingList { initialValue: 2; }', root, "dynamicScopeSettingList");
1182+ newObject.widgetData = settingData;
1183+ var controlDynamic = findChild(newObject, "control");
1184+ tryCompare(controlDynamic, "selectedIndex", 2);
1185+ }
1186+
1187+ function test_updated_data() {
1188+ return [
1189+ { tag: "current", index: 0, updated: false },
1190+ { tag: "second", index: 1, updated: true },
1191+ { tag: "third", index: 2, updated: true }
1192+ ]
1193+ }
1194+
1195+ function test_updated(data) {
1196+ control.selectedIndex = data.index;
1197+ if (data.updated) {
1198+ spy.wait();
1199+ compare(spy.signalArguments[0][0], data.index);
1200+ } else {
1201+ compare(spy.count, 0);
1202+ }
1203+ }
1204+ }
1205+}
1206
1207=== added file 'tests/qmltests/Dash/ScopeSettings/tst_ScopeSettingNumber.qml'
1208--- tests/qmltests/Dash/ScopeSettings/tst_ScopeSettingNumber.qml 1970-01-01 00:00:00 +0000
1209+++ tests/qmltests/Dash/ScopeSettings/tst_ScopeSettingNumber.qml 2014-08-27 08:28:24 +0000
1210@@ -0,0 +1,98 @@
1211+/*
1212+ * Copyright 2014 Canonical Ltd.
1213+ *
1214+ * This program is free software; you can redistribute it and/or modify
1215+ * it under the terms of the GNU General Public License as published by
1216+ * the Free Software Foundation; version 3.
1217+ *
1218+ * This program is distributed in the hope that it will be useful,
1219+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1220+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1221+ * GNU General Public License for more details.
1222+ *
1223+ * You should have received a copy of the GNU General Public License
1224+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1225+ */
1226+
1227+import QtQuick 2.0
1228+import Ubuntu.Components 1.1
1229+import QtTest 1.0
1230+import "../../../../qml/Dash/ScopeSettings"
1231+import Unity.Test 0.1 as UT
1232+
1233+Rectangle {
1234+ id: root
1235+ width: units.gu(40)
1236+ height: units.gu(80)
1237+
1238+ property var settingData: {
1239+ "displayName" : "Mock number setting",
1240+ "value": 0.2
1241+ }
1242+
1243+ ScopeSettingNumber {
1244+ id: scopeSetting
1245+ widgetData: settingData
1246+ width: parent.width
1247+ }
1248+
1249+ SignalSpy {
1250+ id: spy
1251+ target: scopeSetting
1252+ signalName: "updated"
1253+ }
1254+
1255+ UT.UnityTestCase {
1256+ id: testCase
1257+ name: "ScopeSettingNumber"
1258+ when: windowShown
1259+
1260+ property var control: findChild(scopeSetting, "control")
1261+ property real newNumber: 11.7
1262+
1263+ function cleanup() {
1264+ control.focus = false;
1265+ control.text = settingData.value;
1266+ spy.clear();
1267+ }
1268+
1269+ function test_updated_on_unfocus() {
1270+ mouseClick(control, control.width / 2, control.height / 2);
1271+ control.selectAll();
1272+ control.cut();
1273+ control.insert(0, newNumber);
1274+ control.focus = false;
1275+ spy.wait();
1276+ verify(spy.signalArguments[0][0] == newNumber);
1277+ }
1278+
1279+ function test_updated_on_accepted() {
1280+ mouseClick(control, control.width / 2, control.height / 2);
1281+ control.selectAll();
1282+ control.cut();
1283+ control.insert(0, newNumber);
1284+ control.accepted();
1285+ spy.wait();
1286+ verify(spy.signalArguments[0][0] == newNumber);
1287+ }
1288+
1289+ function test_selection_on_listitem_click() {
1290+ mouseClick(scopeSetting, 0, scopeSetting.height / 2);
1291+ compare(control.focus, true);
1292+ // we're checking that selectAll() is being called by omitting it here
1293+ control.cut();
1294+ control.insert(0, newNumber);
1295+ verify(control.displayText == newNumber);
1296+ }
1297+
1298+ function test_unacceptable_input() {
1299+ mouseClick(control, control.width / 2, control.height / 2);
1300+ control.selectAll();
1301+ control.cut();
1302+ control.insert(0, "not valid");
1303+ control.accepted();
1304+ compare(spy.count, 0);
1305+ compare(control.displayText, "");
1306+ }
1307+ }
1308+}
1309
1310=== added file 'tests/qmltests/Dash/ScopeSettings/tst_ScopeSettingString.qml'
1311--- tests/qmltests/Dash/ScopeSettings/tst_ScopeSettingString.qml 1970-01-01 00:00:00 +0000
1312+++ tests/qmltests/Dash/ScopeSettings/tst_ScopeSettingString.qml 2014-08-27 08:28:24 +0000
1313@@ -0,0 +1,88 @@
1314+/*
1315+ * Copyright 2014 Canonical Ltd.
1316+ *
1317+ * This program is free software; you can redistribute it and/or modify
1318+ * it under the terms of the GNU General Public License as published by
1319+ * the Free Software Foundation; version 3.
1320+ *
1321+ * This program is distributed in the hope that it will be useful,
1322+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1323+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1324+ * GNU General Public License for more details.
1325+ *
1326+ * You should have received a copy of the GNU General Public License
1327+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1328+ */
1329+
1330+import QtQuick 2.0
1331+import Ubuntu.Components 1.1
1332+import QtTest 1.0
1333+import "../../../../qml/Dash/ScopeSettings"
1334+import Unity.Test 0.1 as UT
1335+
1336+Rectangle {
1337+ id: root
1338+ width: units.gu(40)
1339+ height: units.gu(80)
1340+
1341+ property var settingData: {
1342+ "displayName" : "Mock string setting",
1343+ "value": "mock string"
1344+ }
1345+
1346+ ScopeSettingString {
1347+ id: scopeSetting
1348+ widgetData: settingData
1349+ width: parent.width
1350+ }
1351+
1352+ SignalSpy {
1353+ id: spy
1354+ target: scopeSetting
1355+ signalName: "updated"
1356+ }
1357+
1358+ UT.UnityTestCase {
1359+ id: testCase
1360+ name: "ScopeSettingString"
1361+ when: windowShown
1362+
1363+ property var control: findChild(scopeSetting, "control")
1364+ property string newText: "new text to compare"
1365+
1366+ function cleanup() {
1367+ control.focus = false;
1368+ control.text = settingData.value;
1369+ spy.clear();
1370+ }
1371+
1372+ function test_updated_on_unfocus() {
1373+ mouseClick(control, control.width / 2, control.height / 2);
1374+ control.selectAll();
1375+ control.cut();
1376+ control.insert(0, newText);
1377+ control.focus = false;
1378+ spy.wait();
1379+ compare(spy.signalArguments[0][0], newText);
1380+ }
1381+
1382+ function test_updated_on_accepted() {
1383+ mouseClick(control, control.width / 2, control.height / 2);
1384+ control.selectAll();
1385+ control.cut();
1386+ control.insert(0, newText);
1387+ control.accepted();
1388+ spy.wait();
1389+ compare(spy.signalArguments[0][0], newText);
1390+ }
1391+
1392+ function test_selection_on_listitem_click() {
1393+ mouseClick(scopeSetting, 0, scopeSetting.height / 2);
1394+ compare(control.focus, true);
1395+ // we're checking that selectAll() is being called by omitting it here
1396+ control.cut();
1397+ control.insert(0, newText);
1398+ compare(control.displayText, newText);
1399+ }
1400+ }
1401+}
1402
1403=== added file 'tests/qmltests/Dash/ScopeSettings/tst_ScopeSettingsWidgetFactory.qml'
1404--- tests/qmltests/Dash/ScopeSettings/tst_ScopeSettingsWidgetFactory.qml 1970-01-01 00:00:00 +0000
1405+++ tests/qmltests/Dash/ScopeSettings/tst_ScopeSettingsWidgetFactory.qml 2014-08-27 08:28:24 +0000
1406@@ -0,0 +1,65 @@
1407+/*
1408+ * Copyright 2014 Canonical Ltd.
1409+ *
1410+ * This program is free software; you can redistribute it and/or modify
1411+ * it under the terms of the GNU General Public License as published by
1412+ * the Free Software Foundation; version 3.
1413+ *
1414+ * This program is distributed in the hope that it will be useful,
1415+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1416+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1417+ * GNU General Public License for more details.
1418+ *
1419+ * You should have received a copy of the GNU General Public License
1420+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1421+ */
1422+
1423+import QtQuick 2.0
1424+import Ubuntu.Components 1.1
1425+import QtTest 1.0
1426+import "../../../../qml/Dash/ScopeSettings"
1427+import Unity.Test 0.1 as UT
1428+
1429+Rectangle {
1430+ id: root
1431+ width: units.gu(40)
1432+ height: units.gu(80)
1433+
1434+ property var settingData: {
1435+ "type": "",
1436+ "displayName" : "Mock setting",
1437+ "value": "1",
1438+ "properties": { "values" : [ "first", "second", "third" ] }
1439+ }
1440+
1441+ ScopeSettingsWidgetFactory {
1442+ id: scopeSettingsWidgetFactory
1443+ anchors {
1444+ left: parent.left
1445+ right: parent.right
1446+ }
1447+ }
1448+
1449+ UT.UnityTestCase {
1450+ id: testCase
1451+ name: "ScopeSettingWidgetFactory"
1452+ when: windowShown
1453+
1454+ function test_mapping_data() {
1455+ return [
1456+ { tag: "Boolean", type: "boolean", source: "ScopeSettingBoolean.qml" },
1457+ { tag: "List", type: "list", source: "ScopeSettingList.qml" },
1458+ { tag: "Number", type: "number", source: "ScopeSettingNumber.qml" },
1459+ { tag: "String", type: "string", source: "ScopeSettingString.qml" }
1460+ ];
1461+ }
1462+
1463+ function test_mapping(data) {
1464+ var newSettingData = settingData;
1465+ newSettingData.type = data.type;
1466+ scopeSettingsWidgetFactory.widgetData = newSettingData;
1467+
1468+ verify((String(scopeSettingsWidgetFactory.source)).indexOf(data.source) != -1);
1469+ }
1470+ }
1471+}
1472
1473=== modified file 'tests/qmltests/Dash/tst_GenericScopeView.qml'
1474--- tests/qmltests/Dash/tst_GenericScopeView.qml 2014-08-27 08:28:24 +0000
1475+++ tests/qmltests/Dash/tst_GenericScopeView.qml 2014-08-27 08:28:24 +0000
1476@@ -39,6 +39,8 @@
1477
1478 Scopes {
1479 id: scopes
1480+ // for tryGenericScopeView
1481+ onLoadedChanged: if (loaded) genericScopeView.scope = scopes.getScope(2);
1482 }
1483
1484 SignalSpy {
1485@@ -59,7 +61,7 @@
1486 name: "GenericScopeView"
1487 when: scopes.loaded && windowShown
1488
1489- property Item previewListView: findChild(genericScopeView, "previewListView")
1490+ property Item subPageLoader: findChild(genericScopeView, "subPageLoader")
1491 property Item header: findChild(genericScopeView, "scopePageHeader")
1492
1493 function init() {
1494@@ -94,24 +96,24 @@
1495 tryCompare(genericScopeView.scope, "isActive", false)
1496 genericScopeView.isCurrent = true
1497 tryCompare(genericScopeView.scope, "isActive", true)
1498- testCase.previewListView.open = true
1499+ testCase.subPageLoader.open = true
1500 tryCompare(genericScopeView.scope, "isActive", false)
1501- testCase.previewListView.open = false
1502+ testCase.subPageLoader.open = false
1503 tryCompare(genericScopeView.scope, "isActive", true)
1504 genericScopeView.isCurrent = false
1505 tryCompare(genericScopeView.scope, "isActive", false)
1506 }
1507
1508 function test_showDash() {
1509- testCase.previewListView.open = true;
1510+ testCase.subPageLoader.open = true;
1511 genericScopeView.scope.showDash();
1512- tryCompare(testCase.previewListView, "open", false);
1513+ tryCompare(testCase.subPageLoader, "open", false);
1514 }
1515
1516 function test_hideDash() {
1517- testCase.previewListView.open = true;
1518+ testCase.subPageLoader.open = true;
1519 genericScopeView.scope.hideDash();
1520- tryCompare(testCase.previewListView, "open", false);
1521+ tryCompare(testCase.subPageLoader, "open", false);
1522 }
1523
1524 function test_searchQuery() {
1525@@ -214,7 +216,7 @@
1526
1527 openPreview(4, 0);
1528
1529- compare(testCase.previewListView.count, 12, "There should only be 12 items in preview.");
1530+ compare(testCase.subPageLoader.count, 12, "There should only be 12 items in preview.");
1531
1532 closePreview();
1533 }
1534@@ -276,19 +278,21 @@
1535 true);
1536 var tile = findChild(findChild(genericScopeView, category), "delegate"+delegate);
1537 mouseClick(tile, tile.width / 2, tile.height / 2);
1538- tryCompare(testCase.previewListView, "open", true);
1539- tryCompare(testCase.previewListView, "x", 0);
1540+ tryCompare(testCase.subPageLoader, "open", true);
1541+ tryCompare(testCase.subPageLoader, "x", 0);
1542 }
1543
1544 function closePreview() {
1545- var closePreviewMouseArea = findChild(genericScopeView, "innerPageHeader");
1546+ var closePreviewMouseArea = findChild(subPageLoader.item, "pageHeader");
1547 mouseClick(closePreviewMouseArea, units.gu(2), units.gu(2));
1548
1549- tryCompare(testCase.previewListView, "open", false);
1550+ tryCompare(testCase.subPageLoader, "open", false);
1551+ tryCompare(testCase.subPageLoader, "visible", false);
1552 }
1553
1554 function test_previewOpenClose() {
1555- tryCompare(testCase.previewListView, "open", false);
1556+ tryCompare(testCase.subPageLoader, "open", false);
1557+ tryCompare(testCase.subPageLoader, "visible", false);
1558
1559 var categoryListView = findChild(genericScopeView, "categoryListView");
1560 categoryListView.positionAtBeginning();
1561@@ -300,7 +304,7 @@
1562 function test_showPreviewCarousel() {
1563 var category = scrollToCategory("dashCategory1");
1564
1565- tryCompare(testCase.previewListView, "open", false);
1566+ tryCompare(testCase.subPageLoader, "open", false);
1567
1568 var tile = findChild(category, "carouselDelegate1");
1569 verify(tile, "Could not find delegate");
1570@@ -308,14 +312,14 @@
1571 mouseClick(tile, tile.width / 2, tile.height / 2);
1572 tryCompare(tile, "explicitlyScaled", true);
1573 mouseClick(tile, tile.width / 2, tile.height / 2);
1574- tryCompare(testCase.previewListView, "open", true);
1575- tryCompare(testCase.previewListView, "x", 0);
1576+ tryCompare(testCase.subPageLoader, "open", true);
1577+ tryCompare(testCase.subPageLoader, "x", 0);
1578
1579 closePreview();
1580
1581 mousePress(tile, tile.width / 2, tile.height / 2);
1582- tryCompare(testCase.previewListView, "open", true);
1583- tryCompare(testCase.previewListView, "x", 0);
1584+ tryCompare(testCase.subPageLoader, "open", true);
1585+ tryCompare(testCase.subPageLoader, "x", 0);
1586 mouseRelease(tile, tile.width / 2, tile.height / 2);
1587
1588 closePreview();
1589@@ -324,20 +328,20 @@
1590 function test_showPreviewHorizontalList() {
1591 var category = scrollToCategory("dashCategory18");
1592
1593- tryCompare(testCase.previewListView, "open", false);
1594+ tryCompare(testCase.subPageLoader, "open", false);
1595
1596 var tile = findChild(category, "delegate1");
1597 verify(tile, "Could not find delegate");
1598
1599 mouseClick(tile, tile.width / 2, tile.height / 2);
1600- tryCompare(testCase.previewListView, "open", true);
1601- tryCompare(testCase.previewListView, "x", 0);
1602+ tryCompare(testCase.subPageLoader, "open", true);
1603+ tryCompare(testCase.subPageLoader, "x", 0);
1604
1605 closePreview();
1606
1607 mousePress(tile, tile.width / 2, tile.height / 2);
1608- tryCompare(testCase.previewListView, "open", true);
1609- tryCompare(testCase.previewListView, "x", 0);
1610+ tryCompare(testCase.subPageLoader, "open", true);
1611+ tryCompare(testCase.subPageLoader, "x", 0);
1612 mouseRelease(tile, tile.width / 2, tile.height / 2);
1613
1614 closePreview();
1615@@ -347,25 +351,52 @@
1616 var categoryListView = findChild(genericScopeView, "categoryListView");
1617 categoryListView.positionAtBeginning();
1618
1619- tryCompare(testCase.previewListView, "open", false);
1620- var previewListViewList = findChild(previewListView, "listView");
1621+ tryCompare(testCase.subPageLoader, "open", false);
1622
1623 openPreview();
1624+ var previewListViewList = findChild(subPageLoader.item, "listView");
1625
1626 // flick to the next previews
1627- tryCompare(testCase.previewListView, "count", 15);
1628- for (var i = 1; i < testCase.previewListView.count; ++i) {
1629- mouseFlick(testCase.previewListView, testCase.previewListView.width - units.gu(1),
1630- testCase.previewListView.height / 2,
1631+ tryCompare(testCase.subPageLoader, "count", 15);
1632+ for (var i = 1; i < testCase.subPageLoader.count; ++i) {
1633+ mouseFlick(testCase.subPageLoader.item, testCase.subPageLoader.width - units.gu(1),
1634+ testCase.subPageLoader.height / 2,
1635 units.gu(2),
1636- testCase.previewListView.height / 2);
1637+ testCase.subPageLoader.height / 2);
1638 tryCompare(previewListViewList, "moving", false);
1639- tryCompare(testCase.previewListView.currentItem, "objectName", "preview" + i);
1640-
1641+ tryCompare(testCase.subPageLoader.currentItem, "objectName", "preview" + i);
1642 }
1643 closePreview();
1644 }
1645
1646+ function test_settingsOpenClose() {
1647+ waitForRendering(genericScopeView);
1648+ verify(header, "Could not find the header.");
1649+ var innerHeader = findChild(header, "innerPageHeader");
1650+ verify(innerHeader, "Could not find the inner header");
1651+
1652+ // open
1653+ tryCompare(testCase.subPageLoader, "open", false);
1654+ tryCompare(testCase.subPageLoader, "visible", false);
1655+ var settings = findChild(innerHeader, "settings_header_button");
1656+ mouseClick(settings, settings.width / 2, settings.height / 2);
1657+ tryCompare(testCase.subPageLoader, "open", true);
1658+ tryCompareFunction(function() { return (String(subPageLoader.source)).indexOf("ScopeSettingsPage.qml") != -1; }, true);
1659+ tryCompare(genericScopeView, "subPageShown", true);
1660+ compare(testCase.subPageLoader.subPage, "settings");
1661+ tryCompare(testCase.subPageLoader, "x", 0);
1662+
1663+ // close
1664+ var settingsHeader = findChild(testCase.subPageLoader.item, "pageHeader");
1665+ mouseClick(settingsHeader, units.gu(2), units.gu(2));
1666+ tryCompare(testCase.subPageLoader, "open", false);
1667+ tryCompare(genericScopeView, "subPageShown", false);
1668+ var categoryListView = findChild(genericScopeView, "categoryListView");
1669+ tryCompare(categoryListView, "x", 0);
1670+ tryCompare(testCase.subPageLoader, "visible", false);
1671+ tryCompare(testCase.subPageLoader, "source", "");
1672+ }
1673+
1674 function test_header_style_data() {
1675 return [
1676 { tag: "Default", index: 0, foreground: UbuntuColors.darkGrey, background: "color:///#f5f5f5", logo: "" },

Subscribers

People subscribed via source and target branches