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