Merge lp:~aacid/unity8/list_on_bottom_swipe into lp:unity8
- list_on_bottom_swipe
- Merge into trunk
Status: | Merged | ||||||||
---|---|---|---|---|---|---|---|---|---|
Approved by: | Albert Astals Cid | ||||||||
Approved revision: | 1347 | ||||||||
Merged at revision: | 1479 | ||||||||
Proposed branch: | lp:~aacid/unity8/list_on_bottom_swipe | ||||||||
Merge into: | lp:unity8 | ||||||||
Diff against target: |
2435 lines (+792/-1116) 20 files modified
debian/control (+1/-1) po/unity8.pot (+41/-45) qml/Dash/Dash.qml (+89/-127) qml/Dash/DashContent.qml (+11/-1) qml/Dash/GenericScopeView.qml (+1/-1) qml/Dash/PageHeader.qml (+11/-1) qml/Dash/ScopesList.qml (+127/-0) qml/Dash/ScopesListCategory.qml (+176/-0) qml/Dash/ScopesListCategoryItem.qml (+104/-0) qml/Dash/ScopesOverview.qml (+0/-575) qml/Dash/ScopesOverviewAll.qml (+0/-54) qml/Dash/ScopesOverviewFavorites.qml (+0/-73) qml/Dash/ScopesOverviewTab.qml (+0/-74) tests/mocks/Unity/CMakeLists.txt (+1/-1) tests/mocks/Unity/fake_scopes.cpp (+57/-3) tests/mocks/Unity/fake_scopes.h (+8/-3) tests/mocks/Unity/fake_scopesoverview.cpp (+77/-11) tests/mocks/Unity/fake_scopesoverview.h (+18/-3) tests/qmltests/Dash/tst_Dash.qml (+70/-142) tests/qmltests/Dash/tst_GenericScopeView.qml (+0/-1) |
||||||||
To merge this branch: | bzr merge lp:~aacid/unity8/list_on_bottom_swipe | ||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Nick Dedekind (community) | Approve | ||
PS Jenkins bot (community) | continuous-integration | Needs Fixing | |
Benjamin Keyser (community) | design | Approve | |
Review via email: mp+235266@code.launchpad.net |
Commit message
Replace Scopes Overview by the new Manage Dash
Description of the change
The unity-scopes-shell change is not needed if you only want to run tests or use make tryDash
* Are there any related MPs required for this MP to build/function as expected?
https:/
https:/
* 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?
This is a design driven change
PS Jenkins bot (ps-jenkins) wrote : | # |
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1304
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://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1306
http://
Executed test runs:
FAILURE: http://
SUCCESS: http://
SUCCESS: 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:1306
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: 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 : | # |
FAILED: Continuous integration, rev:1306
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: 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 : | # |
FAILED: Continuous integration, rev:1308
http://
Executed test runs:
FAILURE: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Michał Sawicz (saviq) wrote : | # |
Would be nice if the tab with ^ (the hint alone) at the bottom absorbed touches so you couldn't activate items through it.
Omer Akram (om26er) wrote : | # |
When do we plan to land this branch ? The bottom edge interaction seems quite complex and ineffective in its current form. Would really love to see this change land soon.
Albert Astals Cid (aacid) wrote : | # |
@Omer: As you can see on the bug this is targetted for ota-1
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1310
http://
Executed test runs:
FAILURE: http://
SUCCESS: http://
SUCCESS: 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:1311
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: 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 : | # |
FAILED: Continuous integration, rev:1313
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: 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 : | # |
FAILED: Continuous integration, rev:1313
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: 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 : | # |
FAILED: Continuous integration, rev:1318
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: 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 : | # |
FAILED: Continuous integration, rev:1321
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: 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 : | # |
FAILED: Continuous integration, rev:1321
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: 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 : | # |
FAILED: Continuous integration, rev:1322
http://
Executed test runs:
FAILURE: http://
SUCCESS: http://
SUCCESS: 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:1323
http://
Executed test runs:
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1323
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: 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 : | # |
FAILED: Continuous integration, rev:1324
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Nick Dedekind (nick-dedekind) wrote : | # |
TestCase:
1) Open dash management
2) Enter edit mode
3) Tap an item
Expected: Scope lifts and releases in same position.
Actual: Scope is switched with the next scope in the list.
It should only switch position when it's been removed from the list?
Albert Astals Cid (aacid) wrote : | # |
Wops, yes that needs fixing.
Albert Astals Cid (aacid) wrote : | # |
> TestCase:
> 1) Open dash management
> 2) Enter edit mode
> 3) Tap an item
>
> Expected: Scope lifts and releases in same position.
> Actual: Scope is switched with the next scope in the list.
>
> It should only switch position when it's been removed from the list?
Fixed
Nick Dedekind (nick-dedekind) wrote : | # |
Should we bump the libunity-api requirement to 7.93? If so, can you add https:/
Albert Astals Cid (aacid) wrote : | # |
> Should we bump the libunity-api requirement to 7.93? If so, can you add
> https:/
> the related MPs.
Yep, Done :)
Nick Dedekind (nick-dedekind) wrote : | # |
* Did you perform an exploratory manual test run of the code change and any related functionality?
Yes
* Did CI run pass? If not, please explain why.
No, will not pass due to requirements
* Did you make sure that the branch does not contain spurious tags?
Yes
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1324
http://
Executed test runs:
FAILURE: http://
UNSTABLE: http://
SUCCESS: 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:1328
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Nick Dedekind (nick-dedekind) wrote : | # |
Added a few comments when looking over the ScopesList code again. Sorry!
Albert Astals Cid (aacid) wrote : | # |
> Should we not be able to favourite things that aren't in the "other" category? I would think we can [un]favourite anything.
Thigns in search tha are not favorites or others can't be favorited (e.g. a result to wikipedia when you search for metallica)
Albert Astals Cid (aacid) wrote : | # |
> not really sure about this "other" feed. In this context isn't "other" everything except category == "home".
"other" is the new name for "the non favorite", there's "the other other" (e.g. search results that link to wikipedia)
Albert Astals Cid (aacid) wrote : | # |
> where does "name" come from? I feel this is putting a bit too much context inside a fairly generic component. Should we not have a root level property for "title" and give the alternative "Home"/"Other" from the usage:
Done
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1329
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Nick Dedekind (nick-dedekind) wrote : | # |
Ok, all good again :)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1330
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Benjamin Keyser (bjkeyser) wrote : | # |
Hi, this is my first merge review :) James should do the review, but he's out of the office until Thursday so I'm filling in what I know were the last agreed design asks.
1. The category headings should be Medium weight not light: so "home" and "other" headings should be medium.
2. Please change the "Other" heading to "Also installed" ... this change is just a change of mind because now that I see it, it doesn't make as much sense.
Please include the launcher "nudge out of the way" animation when the list item is being moved up and down, so a small space opens between the items before you drop it in. Check the launcher for the comparison.
Albert Astals Cid (aacid) wrote : | # |
> 1. The category headings should be Medium weight not light: so "home" and "other" headings should be medium.
They are medium font size, effectively they use the same code we use for the category in the rest of the dash.
> 2. Please change the "Other" heading to "Also installed" ... this change is just a change of mind because now that I see it, it doesn't make as much sense.
Changed
> Please include the launcher "nudge out of the way" animation when the list item is being moved up and down, so a small space opens between the items before you drop it in. Check the launcher for the comparison.
Working on it
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1331
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Albert Astals Cid (aacid) wrote : | # |
> > Please include the launcher "nudge out of the way" animation when the list
> item is being moved up and down, so a small space opens between the items
> before you drop it in. Check the launcher for the comparison.
> Working on it
This is now done.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1334
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1335
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1336
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1337
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Benjamin Keyser (bjkeyser) : | # |
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1338
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1340
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Nick Dedekind (nick-dedekind) wrote : | # |
Looks good to me.
Albert Astals Cid (aacid) wrote : | # |
I moved to Needs Review thinking i wanted CI to run but then realized it didn't make sense since CI can't run here because of the dependencies so now it looks like i top approved myself but it was in fact Nick Dedekind
- 1348. By Albert Astals Cid
-
Merge
Preview Diff
1 | === modified file 'debian/control' | |||
2 | --- debian/control 2014-12-03 17:22:51 +0000 | |||
3 | +++ debian/control 2014-12-05 10:47:59 +0000 | |||
4 | @@ -25,7 +25,7 @@ | |||
5 | 25 | libqmenumodel-dev (>= 0.2.8), | 25 | libqmenumodel-dev (>= 0.2.8), |
6 | 26 | libqt5xmlpatterns5-dev, | 26 | libqt5xmlpatterns5-dev, |
7 | 27 | libsystemsettings-dev, | 27 | libsystemsettings-dev, |
9 | 28 | libunity-api-dev (>= 7.93), | 28 | libunity-api-dev (>= 7.94), |
10 | 29 | libusermetricsoutput1-dev, | 29 | libusermetricsoutput1-dev, |
11 | 30 | libxcb1-dev, | 30 | libxcb1-dev, |
12 | 31 | pkg-config, | 31 | pkg-config, |
13 | 32 | 32 | ||
14 | === modified file 'po/unity8.pot' | |||
15 | --- po/unity8.pot 2014-11-07 09:59:15 +0000 | |||
16 | +++ po/unity8.pot 2014-12-05 10:47:59 +0000 | |||
17 | @@ -8,7 +8,7 @@ | |||
18 | 8 | msgstr "" | 8 | msgstr "" |
19 | 9 | "Project-Id-Version: unity8\n" | 9 | "Project-Id-Version: unity8\n" |
20 | 10 | "Report-Msgid-Bugs-To: \n" | 10 | "Report-Msgid-Bugs-To: \n" |
22 | 11 | "POT-Creation-Date: 2014-11-07 10:59+0100\n" | 11 | "POT-Creation-Date: 2014-11-20 12:00+0100\n" |
23 | 12 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" | 12 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" |
24 | 13 | "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" | 13 | "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" |
25 | 14 | "Language-Team: LANGUAGE <LL@li.org>\n" | 14 | "Language-Team: LANGUAGE <LL@li.org>\n" |
26 | @@ -172,20 +172,24 @@ | |||
27 | 172 | msgid "See all" | 172 | msgid "See all" |
28 | 173 | msgstr "" | 173 | msgstr "" |
29 | 174 | 174 | ||
31 | 175 | #: qml/Dash/GenericScopeView.qml:496 qml/Dash/PageHeader.qml:258 | 175 | #: qml/Dash/GenericScopeView.qml:496 qml/Dash/PageHeader.qml:267 |
32 | 176 | #: qml/Panel/SearchIndicator.qml:27 | 176 | #: qml/Panel/SearchIndicator.qml:27 |
33 | 177 | msgid "Search" | 177 | msgid "Search" |
34 | 178 | msgstr "" | 178 | msgstr "" |
35 | 179 | 179 | ||
37 | 180 | #: qml/Dash/PageHeader.qml:268 | 180 | #: qml/Dash/PageHeader.qml:260 |
38 | 181 | msgid "Store" | ||
39 | 182 | msgstr "" | ||
40 | 183 | |||
41 | 184 | #: qml/Dash/PageHeader.qml:277 | ||
42 | 181 | msgid "Settings" | 185 | msgid "Settings" |
43 | 182 | msgstr "" | 186 | msgstr "" |
44 | 183 | 187 | ||
46 | 184 | #: qml/Dash/PageHeader.qml:275 | 188 | #: qml/Dash/PageHeader.qml:284 |
47 | 185 | msgid "Remove from Favorites" | 189 | msgid "Remove from Favorites" |
48 | 186 | msgstr "" | 190 | msgstr "" |
49 | 187 | 191 | ||
51 | 188 | #: qml/Dash/PageHeader.qml:275 | 192 | #: qml/Dash/PageHeader.qml:284 |
52 | 189 | msgid "Add to Favorites" | 193 | msgid "Add to Favorites" |
53 | 190 | msgstr "" | 194 | msgstr "" |
54 | 191 | 195 | ||
55 | @@ -217,31 +221,23 @@ | |||
56 | 217 | msgid "Release to refresh…" | 221 | msgid "Release to refresh…" |
57 | 218 | msgstr "" | 222 | msgstr "" |
58 | 219 | 223 | ||
77 | 220 | #: qml/Dash/ScopesOverview.qml:215 | 224 | #: qml/Dash/ScopesList.qml:63 |
78 | 221 | msgid "Manage Scopes" | 225 | msgid "Manage" |
79 | 222 | msgstr "" | 226 | msgstr "" |
80 | 223 | 227 | ||
81 | 224 | #: qml/Dash/ScopesOverview.qml:437 | 228 | #: qml/Dash/ScopesList.qml:105 |
82 | 225 | msgid "Done" | 229 | msgid "Home" |
83 | 226 | msgstr "" | 230 | msgstr "" |
84 | 227 | 231 | ||
85 | 228 | #: qml/Dash/ScopesOverview.qml:463 | 232 | #: qml/Dash/ScopesList.qml:106 |
86 | 229 | msgid "Store" | 233 | msgid "Also installed" |
69 | 230 | msgstr "" | ||
70 | 231 | |||
71 | 232 | #: qml/Dash/ScopesOverviewTab.qml:36 | ||
72 | 233 | msgid "Favorites" | ||
73 | 234 | msgstr "" | ||
74 | 235 | |||
75 | 236 | #: qml/Dash/ScopesOverviewTab.qml:54 | ||
76 | 237 | msgid "All" | ||
87 | 238 | msgstr "" | 234 | msgstr "" |
88 | 239 | 235 | ||
89 | 240 | #: qml/Greeter/Greeter.qml:174 | 236 | #: qml/Greeter/Greeter.qml:174 |
90 | 241 | msgid "Unlock" | 237 | msgid "Unlock" |
91 | 242 | msgstr "" | 238 | msgstr "" |
92 | 243 | 239 | ||
94 | 244 | #: qml/Notifications/NotificationMenuItemFactory.qml:116 | 240 | #: qml/Notifications/NotificationMenuItemFactory.qml:128 |
95 | 245 | msgid "Show password" | 241 | msgid "Show password" |
96 | 246 | msgstr "" | 242 | msgstr "" |
97 | 247 | 243 | ||
98 | @@ -289,55 +285,55 @@ | |||
99 | 289 | msgid "Roaming" | 285 | msgid "Roaming" |
100 | 290 | msgstr "" | 286 | msgstr "" |
101 | 291 | 287 | ||
102 | 288 | #: qml/Shell.qml:390 | ||
103 | 289 | msgid "Enter passphrase" | ||
104 | 290 | msgstr "" | ||
105 | 291 | |||
106 | 292 | #: qml/Shell.qml:391 | 292 | #: qml/Shell.qml:391 |
108 | 293 | msgid "Enter passphrase" | 293 | msgid "Sorry, incorrect passphrase" |
109 | 294 | msgstr "" | 294 | msgstr "" |
110 | 295 | 295 | ||
111 | 296 | #: qml/Shell.qml:392 | 296 | #: qml/Shell.qml:392 |
112 | 297 | msgid "Sorry, incorrect passphrase" | ||
113 | 298 | msgstr "" | ||
114 | 299 | |||
115 | 300 | #: qml/Shell.qml:393 | ||
116 | 301 | msgid "Please re-enter" | 297 | msgid "Please re-enter" |
117 | 302 | msgstr "" | 298 | msgstr "" |
118 | 303 | 299 | ||
119 | 300 | #: qml/Shell.qml:394 | ||
120 | 301 | msgid "Enter passcode" | ||
121 | 302 | msgstr "" | ||
122 | 303 | |||
123 | 304 | #: qml/Shell.qml:395 | 304 | #: qml/Shell.qml:395 |
124 | 305 | msgid "Enter passcode" | ||
125 | 306 | msgstr "" | ||
126 | 307 | |||
127 | 308 | #: qml/Shell.qml:396 | ||
128 | 309 | msgid "Sorry, incorrect passcode" | 305 | msgid "Sorry, incorrect passcode" |
129 | 310 | msgstr "" | 306 | msgstr "" |
130 | 311 | 307 | ||
131 | 308 | #: qml/Shell.qml:398 | ||
132 | 309 | #, qt-format | ||
133 | 310 | msgid "Enter %1" | ||
134 | 311 | msgstr "" | ||
135 | 312 | |||
136 | 312 | #: qml/Shell.qml:399 | 313 | #: qml/Shell.qml:399 |
137 | 313 | #, qt-format | 314 | #, qt-format |
138 | 314 | msgid "Enter %1" | ||
139 | 315 | msgstr "" | ||
140 | 316 | |||
141 | 317 | #: qml/Shell.qml:400 | ||
142 | 318 | #, qt-format | ||
143 | 319 | msgid "Sorry, incorrect %1" | 315 | msgid "Sorry, incorrect %1" |
144 | 320 | msgstr "" | 316 | msgstr "" |
145 | 321 | 317 | ||
146 | 318 | #: qml/Shell.qml:440 | ||
147 | 319 | msgid "Sorry, incorrect passphrase." | ||
148 | 320 | msgstr "" | ||
149 | 321 | |||
150 | 322 | #: qml/Shell.qml:441 | 322 | #: qml/Shell.qml:441 |
152 | 323 | msgid "Sorry, incorrect passphrase." | 323 | msgid "Sorry, incorrect passcode." |
153 | 324 | msgstr "" | 324 | msgstr "" |
154 | 325 | 325 | ||
155 | 326 | #: qml/Shell.qml:442 | 326 | #: qml/Shell.qml:442 |
156 | 327 | msgid "Sorry, incorrect passcode." | ||
157 | 328 | msgstr "" | ||
158 | 329 | |||
159 | 330 | #: qml/Shell.qml:443 | ||
160 | 331 | msgid "This will be your last attempt." | 327 | msgid "This will be your last attempt." |
161 | 332 | msgstr "" | 328 | msgstr "" |
162 | 333 | 329 | ||
164 | 334 | #: qml/Shell.qml:445 | 330 | #: qml/Shell.qml:444 |
165 | 335 | msgid "" | 331 | msgid "" |
166 | 336 | "If passphrase is entered incorrectly, your phone will conduct a factory " | 332 | "If passphrase is entered incorrectly, your phone will conduct a factory " |
167 | 337 | "reset and all personal data will be deleted." | 333 | "reset and all personal data will be deleted." |
168 | 338 | msgstr "" | 334 | msgstr "" |
169 | 339 | 335 | ||
171 | 340 | #: qml/Shell.qml:446 | 336 | #: qml/Shell.qml:445 |
172 | 341 | msgid "" | 337 | msgid "" |
173 | 342 | "If passcode is entered incorrectly, your phone will conduct a factory reset " | 338 | "If passcode is entered incorrectly, your phone will conduct a factory reset " |
174 | 343 | "and all personal data will be deleted." | 339 | "and all personal data will be deleted." |
175 | 344 | 340 | ||
176 | === modified file 'qml/Dash/Dash.qml' | |||
177 | --- qml/Dash/Dash.qml 2014-12-02 09:25:12 +0000 | |||
178 | +++ qml/Dash/Dash.qml 2014-12-05 10:47:59 +0000 | |||
179 | @@ -31,16 +31,13 @@ | |||
180 | 31 | DashCommunicatorService { | 31 | DashCommunicatorService { |
181 | 32 | objectName: "dashCommunicatorService" | 32 | objectName: "dashCommunicatorService" |
182 | 33 | onSetCurrentScopeRequested: { | 33 | onSetCurrentScopeRequested: { |
185 | 34 | if (!isSwipe || !window.active || overviewController.progress != 0 || scopeItem.scope || dashContent.subPageShown) { | 34 | if (!isSwipe || !window.active || bottomEdgeController.progress != 0 || scopeItem.scope || dashContent.subPageShown) { |
186 | 35 | if (overviewController.progress != 0 && window.active) animate = false; | 35 | if (bottomEdgeController.progress != 0 && window.active) animate = false; |
187 | 36 | dashContent.setCurrentScopeAtIndex(index, animate, isSwipe) | 36 | dashContent.setCurrentScopeAtIndex(index, animate, isSwipe) |
188 | 37 | // Close dash overview and nested temp scopes in it | 37 | // Close dash overview and nested temp scopes in it |
195 | 38 | if (overviewController.progress != 0) { | 38 | if (bottomEdgeController.progress != 0) { |
196 | 39 | if (window.active) { | 39 | bottomEdgeController.enableAnimation = window.active && !scopesOverview.showingNonFavoriteScope; |
197 | 40 | dashContentCache.scheduleUpdate(); | 40 | bottomEdgeController.progress = 0; |
192 | 41 | } | ||
193 | 42 | overviewController.enableAnimation = window.active && !scopesOverview.showingNonFavoriteScope; | ||
194 | 43 | overviewController.progress = 0; | ||
198 | 44 | scopesOverview.closeTempScope(); | 41 | scopesOverview.closeTempScope(); |
199 | 45 | } | 42 | } |
200 | 46 | // Close normal temp scopes (e.g. App Store) | 43 | // Close normal temp scopes (e.g. App Store) |
201 | @@ -92,8 +89,8 @@ | |||
202 | 92 | } | 89 | } |
203 | 93 | 90 | ||
204 | 94 | QtObject { | 91 | QtObject { |
207 | 95 | id: overviewController | 92 | id: bottomEdgeController |
208 | 96 | objectName: "overviewController" | 93 | objectName: "bottomEdgeController" |
209 | 97 | 94 | ||
210 | 98 | property alias enableAnimation: progressAnimation.enabled | 95 | property alias enableAnimation: progressAnimation.enabled |
211 | 99 | property real progress: 0 | 96 | property real progress: 0 |
212 | @@ -101,108 +98,40 @@ | |||
213 | 101 | id: progressAnimation | 98 | id: progressAnimation |
214 | 102 | UbuntuNumberAnimation { } | 99 | UbuntuNumberAnimation { } |
215 | 103 | } | 100 | } |
216 | 104 | } | ||
217 | 105 | 101 | ||
218 | 106 | ScopesOverview { | ||
219 | 107 | id: scopesOverview | ||
220 | 108 | objectName: "scopesOverview" | ||
221 | 109 | anchors.fill: parent | ||
222 | 110 | scope: scopes.overviewScope | ||
223 | 111 | progress: overviewController.progress | ||
224 | 112 | scopeScale: scopeItem.scope ? 0.4 : (1 - overviewController.progress * 0.6) | ||
225 | 113 | visible: scopeScale != 1 | ||
226 | 114 | currentIndex: dashContent.currentIndex | ||
227 | 115 | onDone: { | ||
228 | 116 | if (currentTab == 1) { | ||
229 | 117 | animateDashFromAll(dashContent.currentScopeId); | ||
230 | 118 | } | ||
231 | 119 | hide(); | ||
232 | 120 | } | ||
233 | 121 | onFavoriteSelected: { | ||
234 | 122 | setCurrentScope(scopeId, false, false); | ||
235 | 123 | dashContentCache.scheduleUpdate(); | ||
236 | 124 | hide(); | ||
237 | 125 | } | ||
238 | 126 | onAllFavoriteSelected: { | ||
239 | 127 | setCurrentScope(scopeId, false, false); | ||
240 | 128 | dashContentCache.scheduleUpdate(); | ||
241 | 129 | animateDashFromAll(dashContent.currentScopeId); | ||
242 | 130 | hide(); | ||
243 | 131 | } | ||
244 | 132 | onSearchSelected: { | ||
245 | 133 | var scopeIndex = -1; | ||
246 | 134 | for (var i = 0; i < scopes.count; ++i) { | ||
247 | 135 | if (scopes.getScope(i).id == scopeId) { | ||
248 | 136 | scopeIndex = i; | ||
249 | 137 | break; | ||
250 | 138 | } | ||
251 | 139 | } | ||
252 | 140 | if (scopeIndex >= 0) { | ||
253 | 141 | // Is a favorite one | ||
254 | 142 | setCurrentScope(scopeId, false, false); | ||
255 | 143 | dashContentCache.scheduleUpdate(); | ||
256 | 144 | showDashFromPos(pos, size); | ||
257 | 145 | hide(); | ||
258 | 146 | } else { | ||
259 | 147 | // Is not a favorite one, activate and get openScope | ||
260 | 148 | scope.activate(result); | ||
261 | 149 | } | ||
262 | 150 | } | ||
263 | 151 | function hide() { | ||
264 | 152 | overviewController.enableAnimation = true; | ||
265 | 153 | overviewController.progress = 0; | ||
266 | 154 | } | ||
267 | 155 | onProgressChanged: { | 102 | onProgressChanged: { |
270 | 156 | if (progress == 0) { | 103 | // FIXME This is to workaround a Qt bug with the model moving the current item |
271 | 157 | currentTab = scopeItem.scope ? 1 : 0; | 104 | // when the list is ListView.SnapOneItem and ListView.StrictlyEnforceRange |
272 | 105 | // together with the code in DashContent.qml | ||
273 | 106 | if (dashContent.workaroundRestoreIndex != -1) { | ||
274 | 107 | dashContent.currentIndex = dashContent.workaroundRestoreIndex; | ||
275 | 108 | dashContent.workaroundRestoreIndex = -1; | ||
276 | 158 | } | 109 | } |
277 | 159 | } | 110 | } |
278 | 160 | } | 111 | } |
279 | 161 | 112 | ||
280 | 162 | ShaderEffectSource { | ||
281 | 163 | id: dashContentCache | ||
282 | 164 | parent: scopesOverview.dashItemEater | ||
283 | 165 | z: 1 | ||
284 | 166 | sourceItem: dashContent | ||
285 | 167 | height: sourceItem.height | ||
286 | 168 | width: sourceItem.width | ||
287 | 169 | opacity: 1 - overviewController.progress | ||
288 | 170 | visible: overviewController.progress != 0 && scopeItem.scope === null | ||
289 | 171 | live: false | ||
290 | 172 | } | ||
291 | 173 | |||
292 | 174 | DashContent { | 113 | DashContent { |
293 | 175 | id: dashContent | 114 | id: dashContent |
294 | 176 | 115 | ||
295 | 177 | property var scopeThatOpenedScope: null | ||
296 | 178 | |||
297 | 179 | objectName: "dashContent" | 116 | objectName: "dashContent" |
298 | 180 | width: dash.width | 117 | width: dash.width |
299 | 181 | height: dash.height | 118 | height: dash.height |
300 | 182 | scopes: scopes | 119 | scopes: scopes |
302 | 183 | visible: !scopesOverview.showingNonFavoriteScope && x != -width | 120 | visible: x != -width |
303 | 184 | onGotoScope: { | 121 | onGotoScope: { |
304 | 185 | dash.setCurrentScope(scopeId, true, false); | 122 | dash.setCurrentScope(scopeId, true, false); |
305 | 186 | } | 123 | } |
306 | 187 | onOpenScope: { | 124 | onOpenScope: { |
308 | 188 | scopeThatOpenedScope = currentScope; | 125 | scopeItem.scopeThatOpenedScope = currentScope; |
309 | 189 | scopeItem.scope = scope; | 126 | scopeItem.scope = scope; |
310 | 190 | scopesOverview.currentTab = 1; | ||
311 | 191 | scopesOverview.ensureAllScopeVisible(scope.id); | ||
312 | 192 | x = -width; | 127 | x = -width; |
313 | 193 | } | 128 | } |
314 | 194 | clip: scale != 1.0 || scopeItem.visible || overviewController.progress != 0 | ||
315 | 195 | Behavior on x { | 129 | Behavior on x { |
316 | 196 | UbuntuNumberAnimation { | 130 | UbuntuNumberAnimation { |
317 | 197 | duration: overviewController.progress != 0 ? 0 : UbuntuAnimation.FastDuration | ||
318 | 198 | onRunningChanged: { | 131 | onRunningChanged: { |
319 | 199 | if (!running && dashContent.x == 0) { | 132 | if (!running && dashContent.x == 0) { |
321 | 200 | dashContent.scopeThatOpenedScope.closeScope(scopeItem.scope); | 133 | scopeItem.scopeThatOpenedScope.closeScope(scopeItem.scope); |
322 | 201 | scopeItem.scope = null; | 134 | scopeItem.scope = null; |
323 | 202 | if (overviewController.progress == 0) { | ||
324 | 203 | // Set tab to Favorites only if we are not showing the overview | ||
325 | 204 | scopesOverview.currentTab = 0; | ||
326 | 205 | } | ||
327 | 206 | } | 135 | } |
328 | 207 | } | 136 | } |
329 | 208 | } | 137 | } |
330 | @@ -214,47 +143,78 @@ | |||
331 | 214 | // about whether that touch was indeed performing a directional drag gesture. | 143 | // about whether that touch was indeed performing a directional drag gesture. |
332 | 215 | forceNonInteractive: overviewDragHandle.status != DirectionalDragArea.WaitingForTouch | 144 | forceNonInteractive: overviewDragHandle.status != DirectionalDragArea.WaitingForTouch |
333 | 216 | 145 | ||
336 | 217 | enabled: overviewController.progress == 0 | 146 | enabled: bottomEdgeController.progress == 0 |
337 | 218 | opacity: enabled ? 1 : 0 | 147 | } |
338 | 148 | |||
339 | 149 | Rectangle { | ||
340 | 150 | color: "black" | ||
341 | 151 | opacity: bottomEdgeController.progress | ||
342 | 152 | anchors.fill: dashContent | ||
343 | 153 | } | ||
344 | 154 | |||
345 | 155 | ScopesList { | ||
346 | 156 | id: scopesList | ||
347 | 157 | objectName: "scopesList" | ||
348 | 158 | width: dash.width | ||
349 | 159 | height: dash.height | ||
350 | 160 | scope: scopes.overviewScope | ||
351 | 161 | y: dash.height * (1 - bottomEdgeController.progress) | ||
352 | 162 | visible: bottomEdgeController.progress != 0 | ||
353 | 163 | onBackClicked: { | ||
354 | 164 | bottomEdgeController.enableAnimation = true; | ||
355 | 165 | bottomEdgeController.progress = 0; | ||
356 | 166 | } | ||
357 | 167 | onStoreClicked: { | ||
358 | 168 | bottomEdgeController.enableAnimation = true; | ||
359 | 169 | bottomEdgeController.progress = 0; | ||
360 | 170 | dashContent.currentScope.performQuery("scope://com.canonical.scopes.clickstore"); | ||
361 | 171 | } | ||
362 | 172 | onRequestFavorite: { | ||
363 | 173 | scopes.setFavorite(scopeId, favorite); | ||
364 | 174 | } | ||
365 | 175 | onRequestFavoriteMoveTo: { | ||
366 | 176 | scopes.moveFavoriteTo(scopeId, index); | ||
367 | 177 | } | ||
368 | 178 | |||
369 | 179 | Binding { | ||
370 | 180 | target: scopesList.scope | ||
371 | 181 | property: "isActive" | ||
372 | 182 | value: bottomEdgeController.progress === 1 | ||
373 | 183 | } | ||
374 | 184 | |||
375 | 185 | Connections { | ||
376 | 186 | target: scopesList.scope | ||
377 | 187 | onOpenScope: { | ||
378 | 188 | bottomEdgeController.enableAnimation = true; | ||
379 | 189 | bottomEdgeController.progress = 0; | ||
380 | 190 | scopeItem.scopeThatOpenedScope = scopesList.scope; | ||
381 | 191 | scopeItem.scope = scope; | ||
382 | 192 | dashContent.x = -dashContent.width; | ||
383 | 193 | } | ||
384 | 194 | onGotoScope: { | ||
385 | 195 | bottomEdgeController.enableAnimation = true; | ||
386 | 196 | bottomEdgeController.progress = 0; | ||
387 | 197 | dashContent.gotoScope(scopeId); | ||
388 | 198 | } | ||
389 | 199 | } | ||
390 | 219 | } | 200 | } |
391 | 220 | 201 | ||
392 | 221 | DashBackground | 202 | DashBackground |
393 | 222 | { | 203 | { |
394 | 223 | anchors.fill: scopeItem | 204 | anchors.fill: scopeItem |
395 | 224 | visible: scopeItem.visible | 205 | visible: scopeItem.visible |
396 | 225 | parent: scopeItem.parent | ||
397 | 226 | scale: scopeItem.scale | ||
398 | 227 | opacity: scopeItem.opacity | ||
399 | 228 | } | 206 | } |
400 | 229 | 207 | ||
401 | 230 | GenericScopeView { | 208 | GenericScopeView { |
402 | 231 | id: scopeItem | 209 | id: scopeItem |
403 | 232 | objectName: "dashTempScopeItem" | 210 | objectName: "dashTempScopeItem" |
404 | 233 | 211 | ||
420 | 234 | readonly property real targetOverviewScale: { | 212 | property var scopeThatOpenedScope: null |
406 | 235 | if (scopesOverview.currentTab == 0) { | ||
407 | 236 | return 0.4; | ||
408 | 237 | } else { | ||
409 | 238 | return scopesOverview.allCardSize.width / scopeItem.width; | ||
410 | 239 | } | ||
411 | 240 | } | ||
412 | 241 | readonly property real overviewProgressScale: (1 - overviewController.progress * (1 - targetOverviewScale)) | ||
413 | 242 | readonly property var targetOverviewPosition: scope ? scopesOverview.allScopeCardPosition(scope.id) : null | ||
414 | 243 | readonly property real overviewProgressX: scope && scopesOverview.currentTab == 1 && targetOverviewPosition ? | ||
415 | 244 | overviewController.progress * (targetOverviewPosition.x - (width - scopesOverview.allCardSize.width) / 2) | ||
416 | 245 | : 0 | ||
417 | 246 | readonly property real overviewProgressY: scope && scopesOverview.currentTab == 1 && targetOverviewPosition ? | ||
418 | 247 | overviewController.progress * (targetOverviewPosition.y - (height - scopesOverview.allCardSize.height) / 2) | ||
419 | 248 | : 0 | ||
421 | 249 | 213 | ||
424 | 250 | x: overviewController.progress == 0 ? dashContent.x + width : overviewProgressX | 214 | x: dashContent.x + width |
425 | 251 | y: overviewController.progress == 0 ? dashContent.y : overviewProgressY | 215 | y: dashContent.y |
426 | 252 | width: parent.width | 216 | width: parent.width |
427 | 253 | height: parent.height | 217 | height: parent.height |
428 | 254 | scale: overviewProgressScale | ||
429 | 255 | enabled: opacity == 1 | ||
430 | 256 | opacity: 1 - overviewController.progress | ||
431 | 257 | clip: scale != 1.0 | ||
432 | 258 | visible: scope != null | 218 | visible: scope != null |
433 | 259 | hasBackAction: true | 219 | hasBackAction: true |
434 | 260 | isCurrent: visible | 220 | isCurrent: visible |
435 | @@ -288,7 +248,7 @@ | |||
436 | 288 | opacity: 0 | 248 | opacity: 0 |
437 | 289 | visible: opacity > 0 | 249 | visible: opacity > 0 |
438 | 290 | 250 | ||
440 | 291 | readonly property bool processing: dashContent.processing || scopeItem.processing || scopesOverview.processing | 251 | readonly property bool processing: dashContent.processing || scopeItem.processing || scopesList.processing |
441 | 292 | 252 | ||
442 | 293 | Behavior on opacity { | 253 | Behavior on opacity { |
443 | 294 | UbuntuNumberAnimation { duration: UbuntuAnimation.FastDuration } | 254 | UbuntuNumberAnimation { duration: UbuntuAnimation.FastDuration } |
444 | @@ -345,12 +305,17 @@ | |||
445 | 345 | source: "graphics/overview_hint.png" | 305 | source: "graphics/overview_hint.png" |
446 | 346 | anchors.horizontalCenter: parent.horizontalCenter | 306 | anchors.horizontalCenter: parent.horizontalCenter |
447 | 347 | opacity: (scopeItem.scope ? scopeItem.pageHeaderTotallyVisible : dashContent.pageHeaderTotallyVisible) && | 307 | opacity: (scopeItem.scope ? scopeItem.pageHeaderTotallyVisible : dashContent.pageHeaderTotallyVisible) && |
449 | 348 | (overviewDragHandle.enabled || overviewController.progress != 0) ? 1 : 0 | 308 | (overviewDragHandle.enabled || bottomEdgeController.progress != 0) ? 1 : 0 |
450 | 349 | Behavior on opacity { | 309 | Behavior on opacity { |
452 | 350 | enabled: overviewController.progress == 0 | 310 | enabled: bottomEdgeController.progress == 0 |
453 | 351 | UbuntuNumberAnimation {} | 311 | UbuntuNumberAnimation {} |
454 | 352 | } | 312 | } |
456 | 353 | y: parent.height - height * (1 - overviewController.progress * 4) | 313 | y: parent.height - height * (1 - bottomEdgeController.progress * 4) |
457 | 314 | MouseArea { | ||
458 | 315 | // Eat direct presses on the overview hint so that they do not end up in the card below | ||
459 | 316 | anchors.fill: parent | ||
460 | 317 | enabled: parent.opacity != 0 | ||
461 | 318 | } | ||
462 | 354 | } | 319 | } |
463 | 355 | 320 | ||
464 | 356 | EdgeDragArea { | 321 | EdgeDragArea { |
465 | @@ -361,22 +326,19 @@ | |||
466 | 361 | enabled: !dashContent.subPageShown && | 326 | enabled: !dashContent.subPageShown && |
467 | 362 | dashContent.currentScope && | 327 | dashContent.currentScope && |
468 | 363 | dashContent.currentScope.searchQuery == "" && | 328 | dashContent.currentScope.searchQuery == "" && |
471 | 364 | !scopeItem.subPageShown && | 329 | !scopeItem.scope && |
472 | 365 | (overviewController.progress == 0 || dragging) | 330 | (bottomEdgeController.progress == 0 || dragging) |
473 | 366 | 331 | ||
475 | 367 | readonly property real fullMovement: units.gu(20) | 332 | readonly property real fullMovement: dash.height |
476 | 368 | 333 | ||
477 | 369 | anchors { left: parent.left; right: parent.right; bottom: parent.bottom } | 334 | anchors { left: parent.left; right: parent.right; bottom: parent.bottom } |
478 | 370 | height: units.gu(2) | 335 | height: units.gu(2) |
479 | 371 | 336 | ||
480 | 372 | onSceneDistanceChanged: { | 337 | onSceneDistanceChanged: { |
481 | 373 | if (status == DirectionalDragArea.Recognized && initialSceneDistance != -1) { | 338 | if (status == DirectionalDragArea.Recognized && initialSceneDistance != -1) { |
486 | 374 | if (overviewController.enableAnimation) { | 339 | bottomEdgeController.enableAnimation = false; |
483 | 375 | dashContentCache.scheduleUpdate(); | ||
484 | 376 | } | ||
485 | 377 | overviewController.enableAnimation = false; | ||
487 | 378 | var deltaDistance = sceneDistance - initialSceneDistance; | 340 | var deltaDistance = sceneDistance - initialSceneDistance; |
489 | 379 | overviewController.progress = Math.max(0, Math.min(1, deltaDistance / fullMovement)); | 341 | bottomEdgeController.progress = Math.max(0, Math.min(1, deltaDistance / fullMovement)); |
490 | 380 | } | 342 | } |
491 | 381 | } | 343 | } |
492 | 382 | 344 | ||
493 | @@ -392,8 +354,8 @@ | |||
494 | 392 | initialSceneDistance = sceneDistance; | 354 | initialSceneDistance = sceneDistance; |
495 | 393 | } else if (status == DirectionalDragArea.WaitingForTouch && | 355 | } else if (status == DirectionalDragArea.WaitingForTouch && |
496 | 394 | previousStatus == DirectionalDragArea.Recognized) { | 356 | previousStatus == DirectionalDragArea.Recognized) { |
499 | 395 | overviewController.enableAnimation = true; | 357 | bottomEdgeController.enableAnimation = true; |
500 | 396 | overviewController.progress = (overviewController.progress > 0.7) ? 1 : 0; | 358 | bottomEdgeController.progress = (bottomEdgeController.progress > 0.2) ? 1 : 0; |
501 | 397 | initialSceneDistance = -1; | 359 | initialSceneDistance = -1; |
502 | 398 | } | 360 | } |
503 | 399 | } | 361 | } |
504 | 400 | 362 | ||
505 | === modified file 'qml/Dash/DashContent.qml' | |||
506 | --- qml/Dash/DashContent.qml 2014-10-30 21:43:18 +0000 | |||
507 | +++ qml/Dash/DashContent.qml 2014-12-05 10:47:59 +0000 | |||
508 | @@ -25,7 +25,8 @@ | |||
509 | 25 | 25 | ||
510 | 26 | property bool forceNonInteractive: false | 26 | property bool forceNonInteractive: false |
511 | 27 | property alias scopes: dashContentList.model | 27 | property alias scopes: dashContentList.model |
513 | 28 | readonly property alias currentIndex: dashContentList.currentIndex | 28 | property alias currentIndex: dashContentList.currentIndex |
514 | 29 | property int workaroundRestoreIndex: -1 | ||
515 | 29 | readonly property string currentScopeId: dashContentList.currentItem ? dashContentList.currentItem.scopeId : "" | 30 | readonly property string currentScopeId: dashContentList.currentItem ? dashContentList.currentItem.scopeId : "" |
516 | 30 | readonly property var currentScope: dashContentList.currentItem ? dashContentList.currentItem.theScope : null | 31 | readonly property var currentScope: dashContentList.currentItem ? dashContentList.currentItem.theScope : null |
517 | 31 | readonly property bool subPageShown: dashContentList.currentItem && dashContentList.currentItem.item ? | 32 | readonly property bool subPageShown: dashContentList.currentItem && dashContentList.currentItem.item ? |
518 | @@ -51,6 +52,15 @@ | |||
519 | 51 | set_current_index = undefined; | 52 | set_current_index = undefined; |
520 | 52 | } | 53 | } |
521 | 53 | } | 54 | } |
522 | 55 | onRowsMoved: { | ||
523 | 56 | // FIXME This is to workaround a Qt bug with the model moving the current item | ||
524 | 57 | // when the list is ListView.SnapOneItem and ListView.StrictlyEnforceRange | ||
525 | 58 | // together with the code in Dash.qml | ||
526 | 59 | if (row == dashContentList.currentIndex || start == dashContentList.currentIndex) { | ||
527 | 60 | dashContent.workaroundRestoreIndex = dashContentList.currentIndex; | ||
528 | 61 | dashContentList.currentIndex = -1; | ||
529 | 62 | } | ||
530 | 63 | } | ||
531 | 54 | } | 64 | } |
532 | 55 | 65 | ||
533 | 56 | Connections { | 66 | Connections { |
534 | 57 | 67 | ||
535 | === modified file 'qml/Dash/GenericScopeView.qml' | |||
536 | --- qml/Dash/GenericScopeView.qml 2014-11-06 15:25:51 +0000 | |||
537 | +++ qml/Dash/GenericScopeView.qml 2014-12-05 10:47:59 +0000 | |||
538 | @@ -494,7 +494,7 @@ | |||
539 | 494 | showBackButton: scopeView.hasBackAction | 494 | showBackButton: scopeView.hasBackAction |
540 | 495 | searchEntryEnabled: true | 495 | searchEntryEnabled: true |
541 | 496 | settingsEnabled: scopeView.scope && scopeView.scope.settings && scopeView.scope.settings.count > 0 || false | 496 | settingsEnabled: scopeView.scope && scopeView.scope.settings && scopeView.scope.settings.count > 0 || false |
543 | 497 | favoriteEnabled: scopeView.scope && scopeView.scope.id !== "clickscope" | 497 | favoriteEnabled: scopeView.scope |
544 | 498 | favorite: scopeView.scope && scopeView.scope.favorite | 498 | favorite: scopeView.scope && scopeView.scope.favorite |
545 | 499 | scopeStyle: scopeView.scopeStyle | 499 | scopeStyle: scopeView.scopeStyle |
546 | 500 | paginationCount: scopeView.paginationCount | 500 | paginationCount: scopeView.paginationCount |
547 | 501 | 501 | ||
548 | === modified file 'qml/Dash/PageHeader.qml' | |||
549 | --- qml/Dash/PageHeader.qml 2014-11-07 14:31:39 +0000 | |||
550 | +++ qml/Dash/PageHeader.qml 2014-12-05 10:47:59 +0000 | |||
551 | @@ -28,8 +28,10 @@ | |||
552 | 28 | implicitHeight: headerContainer.height + bottomContainer.height + (showSignatureLine ? units.gu(2) : 0) | 28 | implicitHeight: headerContainer.height + bottomContainer.height + (showSignatureLine ? units.gu(2) : 0) |
553 | 29 | 29 | ||
554 | 30 | property bool showBackButton: false | 30 | property bool showBackButton: false |
555 | 31 | property bool backIsClose: false | ||
556 | 31 | property string title | 32 | property string title |
557 | 32 | 33 | ||
558 | 34 | property bool storeEntryEnabled: false | ||
559 | 33 | property bool searchEntryEnabled: false | 35 | property bool searchEntryEnabled: false |
560 | 34 | property bool settingsEnabled: false | 36 | property bool settingsEnabled: false |
561 | 35 | property bool favoriteEnabled: false | 37 | property bool favoriteEnabled: false |
562 | @@ -46,6 +48,7 @@ | |||
563 | 46 | property var scopeStyle: null | 48 | property var scopeStyle: null |
564 | 47 | 49 | ||
565 | 48 | signal backClicked() | 50 | signal backClicked() |
566 | 51 | signal storeClicked() | ||
567 | 49 | signal settingsClicked() | 52 | signal settingsClicked() |
568 | 50 | signal favoriteClicked() | 53 | signal favoriteClicked() |
569 | 51 | 54 | ||
570 | @@ -246,13 +249,20 @@ | |||
571 | 246 | property var config: PageHeadConfiguration { | 249 | property var config: PageHeadConfiguration { |
572 | 247 | foregroundColor: root.scopeStyle ? root.scopeStyle.headerForeground : Theme.palette.normal.baseText | 250 | foregroundColor: root.scopeStyle ? root.scopeStyle.headerForeground : Theme.palette.normal.baseText |
573 | 248 | backAction: Action { | 251 | backAction: Action { |
575 | 249 | iconName: "back" | 252 | iconName: backIsClose ? "close" : "back" |
576 | 250 | visible: root.showBackButton | 253 | visible: root.showBackButton |
577 | 251 | onTriggered: root.backClicked() | 254 | onTriggered: root.backClicked() |
578 | 252 | } | 255 | } |
579 | 253 | 256 | ||
580 | 254 | actions: [ | 257 | actions: [ |
581 | 255 | Action { | 258 | Action { |
582 | 259 | objectName: "store" | ||
583 | 260 | text: i18n.tr("Store") | ||
584 | 261 | iconName: "ubuntu-store-symbolic" | ||
585 | 262 | visible: root.storeEntryEnabled | ||
586 | 263 | onTriggered: root.storeClicked(); | ||
587 | 264 | }, | ||
588 | 265 | Action { | ||
589 | 256 | objectName: "search" | 266 | objectName: "search" |
590 | 257 | text: i18n.tr("Search") | 267 | text: i18n.tr("Search") |
591 | 258 | iconName: "search" | 268 | iconName: "search" |
592 | 259 | 269 | ||
593 | === added file 'qml/Dash/ScopesList.qml' | |||
594 | --- qml/Dash/ScopesList.qml 1970-01-01 00:00:00 +0000 | |||
595 | +++ qml/Dash/ScopesList.qml 2014-12-05 10:47:59 +0000 | |||
596 | @@ -0,0 +1,127 @@ | |||
597 | 1 | /* | ||
598 | 2 | * Copyright (C) 2014 Canonical, Ltd. | ||
599 | 3 | * | ||
600 | 4 | * This program is free software; you can redistribute it and/or modify | ||
601 | 5 | * it under the terms of the GNU General Public License as published by | ||
602 | 6 | * the Free Software Foundation; version 3. | ||
603 | 7 | * | ||
604 | 8 | * This program is distributed in the hope that it will be useful, | ||
605 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
606 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
607 | 11 | * GNU General Public License for more details. | ||
608 | 12 | * | ||
609 | 13 | * You should have received a copy of the GNU General Public License | ||
610 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
611 | 15 | */ | ||
612 | 16 | |||
613 | 17 | import QtQuick 2.3 | ||
614 | 18 | import Dash 0.1 | ||
615 | 19 | |||
616 | 20 | Item { | ||
617 | 21 | id: root | ||
618 | 22 | |||
619 | 23 | // Properties set by parent | ||
620 | 24 | property var scope: null | ||
621 | 25 | |||
622 | 26 | // Properties used by parent | ||
623 | 27 | readonly property bool processing: scope ? scope.searchInProgress : false | ||
624 | 28 | |||
625 | 29 | // Signals | ||
626 | 30 | signal backClicked() | ||
627 | 31 | signal storeClicked() | ||
628 | 32 | signal requestFavorite(string scopeId, bool favorite) | ||
629 | 33 | signal requestFavoriteMoveTo(string scopeId, int index) | ||
630 | 34 | |||
631 | 35 | state: "browse" | ||
632 | 36 | |||
633 | 37 | onStateChanged: { | ||
634 | 38 | if (state == "edit") { | ||
635 | 39 | // As per design entering edit mode clears the possible existing search | ||
636 | 40 | header.resetSearch(false /* false == unfocus */); | ||
637 | 41 | } | ||
638 | 42 | } | ||
639 | 43 | |||
640 | 44 | DashBackground { | ||
641 | 45 | anchors.fill: parent | ||
642 | 46 | } | ||
643 | 47 | |||
644 | 48 | Binding { | ||
645 | 49 | target: root.scope | ||
646 | 50 | property: "searchQuery" | ||
647 | 51 | value: header.searchQuery | ||
648 | 52 | } | ||
649 | 53 | |||
650 | 54 | Binding { | ||
651 | 55 | target: header | ||
652 | 56 | property: "searchQuery" | ||
653 | 57 | value: root.scope ? root.scope.searchQuery : "" | ||
654 | 58 | } | ||
655 | 59 | |||
656 | 60 | PageHeader { | ||
657 | 61 | id: header | ||
658 | 62 | objectName: "pageHeader" | ||
659 | 63 | title: i18n.tr("Manage") | ||
660 | 64 | width: parent.width | ||
661 | 65 | showBackButton: true | ||
662 | 66 | backIsClose: root.state == "edit" | ||
663 | 67 | storeEntryEnabled: root.state == "browse" | ||
664 | 68 | searchEntryEnabled: false // Disable search for now | ||
665 | 69 | onBackClicked: { | ||
666 | 70 | if (backIsClose) { | ||
667 | 71 | root.state = "browse" | ||
668 | 72 | } else { | ||
669 | 73 | root.backClicked() | ||
670 | 74 | } | ||
671 | 75 | } | ||
672 | 76 | onStoreClicked: root.storeClicked(); | ||
673 | 77 | z: 1 | ||
674 | 78 | } | ||
675 | 79 | |||
676 | 80 | Flickable { | ||
677 | 81 | anchors { | ||
678 | 82 | top: header.bottom | ||
679 | 83 | bottom: parent.bottom | ||
680 | 84 | left: parent.left | ||
681 | 85 | right: parent.right | ||
682 | 86 | } | ||
683 | 87 | clip: true | ||
684 | 88 | contentWidth: root.width | ||
685 | 89 | contentHeight: column.height | ||
686 | 90 | onContentHeightChanged: returnToBounds(); | ||
687 | 91 | Column { | ||
688 | 92 | id: column | ||
689 | 93 | Repeater { | ||
690 | 94 | model: scope ? scope.categories : null | ||
691 | 95 | |||
692 | 96 | delegate: Loader { | ||
693 | 97 | asynchronous: true | ||
694 | 98 | width: root.width | ||
695 | 99 | active: results.count > 0 | ||
696 | 100 | visible: active | ||
697 | 101 | sourceComponent: ScopesListCategory { | ||
698 | 102 | objectName: "scopesListCategory" + categoryId | ||
699 | 103 | |||
700 | 104 | model: results | ||
701 | 105 | |||
702 | 106 | title: { | ||
703 | 107 | if (isFavoritesFeed) return i18n.tr("Home"); | ||
704 | 108 | else if (isAlsoInstalled) return i18n.tr("Also installed"); | ||
705 | 109 | else return name; | ||
706 | 110 | } | ||
707 | 111 | |||
708 | 112 | editMode: root.state == "edit" | ||
709 | 113 | |||
710 | 114 | scopeStyle: root.scope.scopeStyle | ||
711 | 115 | isFavoritesFeed: categoryId == "favorites" | ||
712 | 116 | isAlsoInstalled: categoryId == "other" | ||
713 | 117 | |||
714 | 118 | onRequestFavorite: root.requestFavorite(scopeId, favorite); | ||
715 | 119 | onRequestEditMode: root.state = "edit"; | ||
716 | 120 | onRequestScopeMoveTo: root.requestFavoriteMoveTo(scopeId, index); | ||
717 | 121 | onRequestActivate: root.scope.activate(result); | ||
718 | 122 | } | ||
719 | 123 | } | ||
720 | 124 | } | ||
721 | 125 | } | ||
722 | 126 | } | ||
723 | 127 | } | ||
724 | 0 | 128 | ||
725 | === added file 'qml/Dash/ScopesListCategory.qml' | |||
726 | --- qml/Dash/ScopesListCategory.qml 1970-01-01 00:00:00 +0000 | |||
727 | +++ qml/Dash/ScopesListCategory.qml 2014-12-05 10:47:59 +0000 | |||
728 | @@ -0,0 +1,176 @@ | |||
729 | 1 | /* | ||
730 | 2 | * Copyright (C) 2014 Canonical, Ltd. | ||
731 | 3 | * | ||
732 | 4 | * This program is free software; you can redistribute it and/or modify | ||
733 | 5 | * it under the terms of the GNU General Public License as published by | ||
734 | 6 | * the Free Software Foundation; version 3. | ||
735 | 7 | * | ||
736 | 8 | * This program is distributed in the hope that it will be useful, | ||
737 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
738 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
739 | 11 | * GNU General Public License for more details. | ||
740 | 12 | * | ||
741 | 13 | * You should have received a copy of the GNU General Public License | ||
742 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
743 | 15 | */ | ||
744 | 16 | |||
745 | 17 | import QtQuick 2.3 | ||
746 | 18 | import Ubuntu.Components 1.1 | ||
747 | 19 | import Dash 0.1 | ||
748 | 20 | import "../Components/ListItems" as ListItems | ||
749 | 21 | |||
750 | 22 | Item { | ||
751 | 23 | id: root | ||
752 | 24 | |||
753 | 25 | property alias model: list.model | ||
754 | 26 | property alias title: header.text | ||
755 | 27 | property var scopeStyle | ||
756 | 28 | property bool editMode: false | ||
757 | 29 | property bool isFavoritesFeed: false | ||
758 | 30 | property bool isAlsoInstalled: false | ||
759 | 31 | |||
760 | 32 | visible: !editMode || isFavoritesFeed | ||
761 | 33 | |||
762 | 34 | signal requestFavorite(string scopeId, bool favorite) | ||
763 | 35 | signal requestEditMode() | ||
764 | 36 | signal requestScopeMoveTo(string scopeId, int index) | ||
765 | 37 | signal requestActivate(var result) | ||
766 | 38 | |||
767 | 39 | implicitHeight: visible ? childrenRect.height : 0 | ||
768 | 40 | |||
769 | 41 | ListItems.Header { | ||
770 | 42 | id: header | ||
771 | 43 | width: root.width | ||
772 | 44 | height: units.gu(5) | ||
773 | 45 | color: scopeStyle ? scopeStyle.foreground : Theme.palette.normal.baseText | ||
774 | 46 | } | ||
775 | 47 | |||
776 | 48 | readonly property double listItemHeight: units.gu(6) | ||
777 | 49 | |||
778 | 50 | ListView { | ||
779 | 51 | id: list | ||
780 | 52 | objectName: "scopesListCategoryInnerList" | ||
781 | 53 | |||
782 | 54 | readonly property double targetHeight: model.count * listItemHeight | ||
783 | 55 | clip: height != targetHeight | ||
784 | 56 | height: targetHeight | ||
785 | 57 | Behavior on height { enabled: visible; UbuntuNumberAnimation { } } | ||
786 | 58 | width: parent.width | ||
787 | 59 | interactive: false | ||
788 | 60 | |||
789 | 61 | anchors.top: header.bottom | ||
790 | 62 | delegate: Loader { | ||
791 | 63 | id: loader | ||
792 | 64 | readonly property bool addDropHint: { | ||
793 | 65 | if (dragMarker.visible) { | ||
794 | 66 | if (dragItem.originalIndex > index) { | ||
795 | 67 | return dragMarker.index == index; | ||
796 | 68 | } else { | ||
797 | 69 | return dragMarker.index == index - 1; | ||
798 | 70 | } | ||
799 | 71 | } else { | ||
800 | 72 | return false; | ||
801 | 73 | } | ||
802 | 74 | } | ||
803 | 75 | asynchronous: true | ||
804 | 76 | width: root.width | ||
805 | 77 | height: listItemHeight + (addDropHint ? units.gu(2) : 0) | ||
806 | 78 | clip: height < listItemHeight | ||
807 | 79 | Behavior on height { enabled: visible; UbuntuNumberAnimation { } } | ||
808 | 80 | sourceComponent: ScopesListCategoryItem { | ||
809 | 81 | objectName: "delegate" + index | ||
810 | 82 | |||
811 | 83 | width: root.width | ||
812 | 84 | topMargin: height > listItemHeight ? height - listItemHeight : 0 | ||
813 | 85 | |||
814 | 86 | icon: model.art || model.mascot || "" | ||
815 | 87 | text: model.title || "" | ||
816 | 88 | subtext: model.subtitle || "" | ||
817 | 89 | showStar: root.isFavoritesFeed || root.isAlsoInstalled | ||
818 | 90 | isFavorite: root.isFavoritesFeed | ||
819 | 91 | |||
820 | 92 | hideChildren: dragItem.loaderToShrink == loader | ||
821 | 93 | |||
822 | 94 | onClicked: { | ||
823 | 95 | if (!editMode) { | ||
824 | 96 | root.requestActivate(result); | ||
825 | 97 | } | ||
826 | 98 | } | ||
827 | 99 | onPressAndHold: { | ||
828 | 100 | if (!editMode) { | ||
829 | 101 | root.requestEditMode(); | ||
830 | 102 | } | ||
831 | 103 | } | ||
832 | 104 | onRequestFavorite: root.requestFavorite(model.scopeId, favorite); | ||
833 | 105 | onHandlePressed: { | ||
834 | 106 | if (editMode) { | ||
835 | 107 | handle.drag.target = dragItem; | ||
836 | 108 | handle.drag.maximumX = units.gu(1); | ||
837 | 109 | handle.drag.minimumX = units.gu(1); | ||
838 | 110 | handle.drag.minimumY = list.y - dragItem.height / 2; | ||
839 | 111 | handle.drag.maximumY = list.y + list.height - dragItem.height / 2 | ||
840 | 112 | dragItem.icon = icon; | ||
841 | 113 | dragItem.text = text; | ||
842 | 114 | dragItem.subtext = subtext; | ||
843 | 115 | dragItem.originalY = mapToItem(root, 0, 0).y; | ||
844 | 116 | dragItem.originalIndex = index; | ||
845 | 117 | dragItem.y = dragItem.originalY; | ||
846 | 118 | dragItem.x = units.gu(1); | ||
847 | 119 | dragItem.visible = true; | ||
848 | 120 | dragItem.loaderToShrink = loader; | ||
849 | 121 | } | ||
850 | 122 | } | ||
851 | 123 | onHandleReleased: { | ||
852 | 124 | if (dragItem.visible) { | ||
853 | 125 | handle.drag.target = undefined; | ||
854 | 126 | dragItem.visible = false; | ||
855 | 127 | if (dragMarker.visible && dragMarker.index != index) { | ||
856 | 128 | root.requestScopeMoveTo(model.scopeId, dragMarker.index); | ||
857 | 129 | } | ||
858 | 130 | dragMarker.visible = false; | ||
859 | 131 | dragItem.loaderToShrink.height = listItemHeight; | ||
860 | 132 | dragItem.loaderToShrink = null; | ||
861 | 133 | } | ||
862 | 134 | } | ||
863 | 135 | } | ||
864 | 136 | } | ||
865 | 137 | } | ||
866 | 138 | |||
867 | 139 | ListItems.ThinDivider { | ||
868 | 140 | id: dragMarker | ||
869 | 141 | visible: false | ||
870 | 142 | anchors { | ||
871 | 143 | leftMargin: units.gu(1) | ||
872 | 144 | rightMargin: units.gu(1) | ||
873 | 145 | } | ||
874 | 146 | property int index: { | ||
875 | 147 | var i = Math.round((dragItem.y - list.y + dragItem.height/2) / listItemHeight); | ||
876 | 148 | if (i < 0) i = 0; | ||
877 | 149 | if (i >= model.count - 1) i = model.count - 1; | ||
878 | 150 | return i; | ||
879 | 151 | } | ||
880 | 152 | y: list.y + index * listItemHeight + units.gu(1) | ||
881 | 153 | } | ||
882 | 154 | |||
883 | 155 | ScopesListCategoryItem { | ||
884 | 156 | id: dragItem | ||
885 | 157 | |||
886 | 158 | property real originalY | ||
887 | 159 | property int originalIndex | ||
888 | 160 | property var loaderToShrink: null | ||
889 | 161 | |||
890 | 162 | objectName: "dragItem" | ||
891 | 163 | visible: false | ||
892 | 164 | showStar: false | ||
893 | 165 | width: root.width | ||
894 | 166 | height: listItemHeight | ||
895 | 167 | opacity: 0.9 | ||
896 | 168 | |||
897 | 169 | onYChanged: { | ||
898 | 170 | if (!dragMarker.visible && Math.abs(y - originalY) > height / 2) { | ||
899 | 171 | dragMarker.visible = true; | ||
900 | 172 | loaderToShrink.height = 0; | ||
901 | 173 | } | ||
902 | 174 | } | ||
903 | 175 | } | ||
904 | 176 | } | ||
905 | 0 | 177 | ||
906 | === added file 'qml/Dash/ScopesListCategoryItem.qml' | |||
907 | --- qml/Dash/ScopesListCategoryItem.qml 1970-01-01 00:00:00 +0000 | |||
908 | +++ qml/Dash/ScopesListCategoryItem.qml 2014-12-05 10:47:59 +0000 | |||
909 | @@ -0,0 +1,104 @@ | |||
910 | 1 | /* | ||
911 | 2 | * Copyright (C) 2014 Canonical, Ltd. | ||
912 | 3 | * | ||
913 | 4 | * This program is free software; you can redistribute it and/or modify | ||
914 | 5 | * it under the terms of the GNU General Public License as published by | ||
915 | 6 | * the Free Software Foundation; version 3. | ||
916 | 7 | * | ||
917 | 8 | * This program is distributed in the hope that it will be useful, | ||
918 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
919 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
920 | 11 | * GNU General Public License for more details. | ||
921 | 12 | * | ||
922 | 13 | * You should have received a copy of the GNU General Public License | ||
923 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
924 | 15 | */ | ||
925 | 16 | |||
926 | 17 | import QtQuick 2.3 | ||
927 | 18 | import QtQuick.Layouts 1.1 | ||
928 | 19 | import Ubuntu.Components 1.1 | ||
929 | 20 | |||
930 | 21 | MouseArea { | ||
931 | 22 | id: root | ||
932 | 23 | |||
933 | 24 | signal requestFavorite(string scopeId, bool favorite) | ||
934 | 25 | signal handlePressed(var handle) | ||
935 | 26 | signal handleReleased(var handle) | ||
936 | 27 | |||
937 | 28 | property real topMargin: 0 | ||
938 | 29 | property alias icon: shapeImage.source | ||
939 | 30 | property alias text: titleLabel.text | ||
940 | 31 | property alias subtext: subtitleLabel.text | ||
941 | 32 | property alias showStar: star.visible | ||
942 | 33 | |||
943 | 34 | property bool isFavorite: false | ||
944 | 35 | property bool hideChildren: false | ||
945 | 36 | |||
946 | 37 | Item { | ||
947 | 38 | id: holder | ||
948 | 39 | anchors.fill: parent | ||
949 | 40 | anchors.topMargin: root.topMargin | ||
950 | 41 | |||
951 | 42 | UbuntuShape { | ||
952 | 43 | id: shape | ||
953 | 44 | anchors { | ||
954 | 45 | left: parent.left | ||
955 | 46 | leftMargin: units.gu(1) | ||
956 | 47 | verticalCenter: parent.verticalCenter | ||
957 | 48 | } | ||
958 | 49 | width: units.gu(5) | ||
959 | 50 | height: units.gu(5) | ||
960 | 51 | visible: !hideChildren | ||
961 | 52 | image: Image { | ||
962 | 53 | id: shapeImage | ||
963 | 54 | cache: true | ||
964 | 55 | fillMode: Image.PreserveAspectCrop | ||
965 | 56 | } | ||
966 | 57 | } | ||
967 | 58 | |||
968 | 59 | ColumnLayout { | ||
969 | 60 | visible: !hideChildren | ||
970 | 61 | anchors { | ||
971 | 62 | left: shape.right | ||
972 | 63 | leftMargin: units.gu(1) | ||
973 | 64 | right: starArea.right | ||
974 | 65 | rightMargin: units.gu(1) | ||
975 | 66 | verticalCenter: parent.verticalCenter | ||
976 | 67 | } | ||
977 | 68 | Label { | ||
978 | 69 | id: titleLabel | ||
979 | 70 | elide: Text.ElideRight | ||
980 | 71 | wrapMode: Text.Wrap | ||
981 | 72 | maximumLineCount: 1 | ||
982 | 73 | verticalAlignment: Text.AlignHCenter | ||
983 | 74 | } | ||
984 | 75 | Label { | ||
985 | 76 | id: subtitleLabel | ||
986 | 77 | elide: Text.ElideRight | ||
987 | 78 | fontSize: "xx-small" | ||
988 | 79 | wrapMode: Text.Wrap | ||
989 | 80 | maximumLineCount: 1 | ||
990 | 81 | verticalAlignment: Text.AlignHCenter | ||
991 | 82 | visible: text != "" | ||
992 | 83 | } | ||
993 | 84 | } | ||
994 | 85 | MouseArea { | ||
995 | 86 | id: starArea | ||
996 | 87 | height: parent.height | ||
997 | 88 | width: height | ||
998 | 89 | anchors.right: parent.right | ||
999 | 90 | onClicked: if (!editMode) root.requestFavorite(model.scopeId, !isFavorite); | ||
1000 | 91 | onPressed: if (editMode) root.handlePressed(starArea); | ||
1001 | 92 | onReleased: if (editMode) root.handleReleased(starArea); | ||
1002 | 93 | Icon { | ||
1003 | 94 | id: star | ||
1004 | 95 | anchors.centerIn: parent | ||
1005 | 96 | height: units.gu(2) | ||
1006 | 97 | width: units.gu(2) | ||
1007 | 98 | visible: !hideChildren | ||
1008 | 99 | // TODO is view-grid-symbolic what we really want here? Looks good but seems semantically wrong | ||
1009 | 100 | source: editMode ? "image://theme/view-grid-symbolic" : isFavorite ? "image://theme/starred" : "image://theme/non-starred" | ||
1010 | 101 | } | ||
1011 | 102 | } | ||
1012 | 103 | } | ||
1013 | 104 | } | ||
1014 | 0 | 105 | ||
1015 | === removed file 'qml/Dash/ScopesOverview.qml' | |||
1016 | --- qml/Dash/ScopesOverview.qml 2014-10-09 14:04:53 +0000 | |||
1017 | +++ qml/Dash/ScopesOverview.qml 1970-01-01 00:00:00 +0000 | |||
1018 | @@ -1,575 +0,0 @@ | |||
1019 | 1 | /* | ||
1020 | 2 | * Copyright (C) 2014 Canonical, Ltd. | ||
1021 | 3 | * | ||
1022 | 4 | * This program is free software; you can redistribute it and/or modify | ||
1023 | 5 | * it under the terms of the GNU General Public License as published by | ||
1024 | 6 | * the Free Software Foundation; version 3. | ||
1025 | 7 | * | ||
1026 | 8 | * This program is distributed in the hope that it will be useful, | ||
1027 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1028 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1029 | 11 | * GNU General Public License for more details. | ||
1030 | 12 | * | ||
1031 | 13 | * You should have received a copy of the GNU General Public License | ||
1032 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1033 | 15 | */ | ||
1034 | 16 | |||
1035 | 17 | import QtQuick 2.0 | ||
1036 | 18 | import Dash 0.1 | ||
1037 | 19 | import Ubuntu.Components 0.1 | ||
1038 | 20 | import "../Components" | ||
1039 | 21 | |||
1040 | 22 | Item { | ||
1041 | 23 | id: root | ||
1042 | 24 | |||
1043 | 25 | // Properties set by parent | ||
1044 | 26 | property real progress: 0 | ||
1045 | 27 | property var scope: null | ||
1046 | 28 | property int currentIndex: 0 | ||
1047 | 29 | property real scopeScale: 1 | ||
1048 | 30 | |||
1049 | 31 | // Properties set and used by parent | ||
1050 | 32 | property alias currentTab: tabBar.currentTab | ||
1051 | 33 | |||
1052 | 34 | // Properties used by parent | ||
1053 | 35 | readonly property bool processing: searchResultsViewer.processing || tempScopeItem.processing || previewListView.processing | ||
1054 | 36 | property bool growingDashFromPos: false | ||
1055 | 37 | readonly property bool searching: scope && scope.searchQuery == "" | ||
1056 | 38 | readonly property bool showingNonFavoriteScope: tempScopeItem.scope != null | ||
1057 | 39 | readonly property var dashItemEater: { | ||
1058 | 40 | if (!forceXYScalerEater && tabBar.currentTab == 0 && middleItems.count > 0) { | ||
1059 | 41 | var loaderItem = middleItems.itemAt(0).item; | ||
1060 | 42 | return loaderItem && loaderItem.currentItem ? loaderItem.currentItem : null; | ||
1061 | 43 | } | ||
1062 | 44 | return scopesOverviewXYScaler; | ||
1063 | 45 | } | ||
1064 | 46 | readonly property size allCardSize: { | ||
1065 | 47 | if (middleItems.count > 1) { | ||
1066 | 48 | var loaderItem = middleItems.itemAt(1).item; | ||
1067 | 49 | if (loaderItem) { | ||
1068 | 50 | var cardTool = loaderItem.cardTool; | ||
1069 | 51 | return Qt.size(cardTool.cardWidth, cardTool.cardHeight); | ||
1070 | 52 | } | ||
1071 | 53 | } | ||
1072 | 54 | return Qt.size(0, 0); | ||
1073 | 55 | } | ||
1074 | 56 | |||
1075 | 57 | // Internal properties | ||
1076 | 58 | property bool forceXYScalerEater: false | ||
1077 | 59 | |||
1078 | 60 | signal done() | ||
1079 | 61 | signal favoriteSelected(var scopeId) | ||
1080 | 62 | signal allFavoriteSelected(var scopeId) | ||
1081 | 63 | signal searchSelected(var scopeId, var result, var pos, var size) | ||
1082 | 64 | |||
1083 | 65 | Connections { | ||
1084 | 66 | target: scope | ||
1085 | 67 | onOpenScope: { | ||
1086 | 68 | var itemPos = scopesOverviewXYScaler.restorePosition; | ||
1087 | 69 | var itemSize = scopesOverviewXYScaler.restoreSize; | ||
1088 | 70 | scopesOverviewXYScaler.scale = itemSize.width / scopesOverviewXYScaler.width; | ||
1089 | 71 | if (itemPos) { | ||
1090 | 72 | scopesOverviewXYScaler.x = itemPos.x -(scopesOverviewXYScaler.width - scopesOverviewXYScaler.width * scopesOverviewXYScaler.scale) / 2; | ||
1091 | 73 | scopesOverviewXYScaler.y = itemPos.y -(scopesOverviewXYScaler.height - scopesOverviewXYScaler.height * scopesOverviewXYScaler.scale) / 2; | ||
1092 | 74 | } else { | ||
1093 | 75 | scopesOverviewXYScaler.x = 0; | ||
1094 | 76 | scopesOverviewXYScaler.y = 0; | ||
1095 | 77 | } | ||
1096 | 78 | scopesOverviewXYScaler.opacity = 0; | ||
1097 | 79 | tempScopeItem.scope = scope; | ||
1098 | 80 | middleItems.overrideOpacity = 0; | ||
1099 | 81 | scopesOverviewXYScaler.scale = 1; | ||
1100 | 82 | scopesOverviewXYScaler.x = 0; | ||
1101 | 83 | scopesOverviewXYScaler.y = 0; | ||
1102 | 84 | scopesOverviewXYScaler.opacity = 1; | ||
1103 | 85 | } | ||
1104 | 86 | onGotoScope: { | ||
1105 | 87 | if (tabBar.currentTab == 0) { | ||
1106 | 88 | root.favoriteSelected(scopeId); | ||
1107 | 89 | } else { | ||
1108 | 90 | root.allFavoriteSelected(scopeId); | ||
1109 | 91 | } | ||
1110 | 92 | previewListView.open = false; | ||
1111 | 93 | } | ||
1112 | 94 | } | ||
1113 | 95 | |||
1114 | 96 | Binding { | ||
1115 | 97 | target: scope | ||
1116 | 98 | property: "isActive" | ||
1117 | 99 | value: progress === 1 | ||
1118 | 100 | } | ||
1119 | 101 | |||
1120 | 102 | function closeTempScope() { | ||
1121 | 103 | if (tempScopeItem.scope) { | ||
1122 | 104 | root.scope.closeScope(tempScopeItem.scope); | ||
1123 | 105 | tempScopeItem.scope = null; | ||
1124 | 106 | tempScopeItem.backClicked() | ||
1125 | 107 | } | ||
1126 | 108 | } | ||
1127 | 109 | |||
1128 | 110 | function animateDashFromAll(scopeId) { | ||
1129 | 111 | var currentScopePos = allScopeCardPosition(scopeId); | ||
1130 | 112 | if (currentScopePos) { | ||
1131 | 113 | showDashFromPos(currentScopePos, allCardSize); | ||
1132 | 114 | } else { | ||
1133 | 115 | console.log("Warning: Could not find Dash OverView All card position for scope", dashContent.currentScopeId); | ||
1134 | 116 | } | ||
1135 | 117 | } | ||
1136 | 118 | |||
1137 | 119 | function showDashFromPos(itemPos, itemSize) { | ||
1138 | 120 | scopesOverviewXYScaler.scale = itemSize.width / scopesOverviewXYScaler.width; | ||
1139 | 121 | scopesOverviewXYScaler.x = itemPos.x -(scopesOverviewXYScaler.width - scopesOverviewXYScaler.width * scopesOverviewXYScaler.scale) / 2; | ||
1140 | 122 | scopesOverviewXYScaler.y = itemPos.y -(scopesOverviewXYScaler.height - scopesOverviewXYScaler.height * scopesOverviewXYScaler.scale) / 2; | ||
1141 | 123 | scopesOverviewXYScaler.opacity = 0; | ||
1142 | 124 | root.growingDashFromPos = true; | ||
1143 | 125 | scopesOverviewXYScaler.scale = 1; | ||
1144 | 126 | scopesOverviewXYScaler.x = 0; | ||
1145 | 127 | scopesOverviewXYScaler.y = 0; | ||
1146 | 128 | scopesOverviewXYScaler.opacity = 1; | ||
1147 | 129 | } | ||
1148 | 130 | |||
1149 | 131 | function allScopeCardPosition(scopeId) { | ||
1150 | 132 | if (middleItems.count > 1) { | ||
1151 | 133 | var loaderItem = middleItems.itemAt(1).item; | ||
1152 | 134 | if (loaderItem) { | ||
1153 | 135 | var pos = loaderItem.scopeCardPosition(scopeId); | ||
1154 | 136 | return loaderItem.mapToItem(null, pos.x, pos.y); | ||
1155 | 137 | } | ||
1156 | 138 | } | ||
1157 | 139 | } | ||
1158 | 140 | |||
1159 | 141 | function ensureAllScopeVisible(scopeId) { | ||
1160 | 142 | if (middleItems.count > 1) { | ||
1161 | 143 | var loaderItem = middleItems.itemAt(1).item; | ||
1162 | 144 | if (loaderItem) { | ||
1163 | 145 | var pos = loaderItem.scopeCardPosition(scopeId); | ||
1164 | 146 | loaderItem.contentY = Math.min(pos.y, loaderItem.contentHeight - loaderItem.height); | ||
1165 | 147 | } | ||
1166 | 148 | } | ||
1167 | 149 | } | ||
1168 | 150 | |||
1169 | 151 | onProgressChanged: { | ||
1170 | 152 | if (progress == 0) { | ||
1171 | 153 | pageHeader.resetSearch(); | ||
1172 | 154 | pageHeader.unfocus(); // Shouldn't the previous call do this too? | ||
1173 | 155 | } | ||
1174 | 156 | } | ||
1175 | 157 | |||
1176 | 158 | ScopeStyle { | ||
1177 | 159 | id: overviewScopeStyle | ||
1178 | 160 | style: { "foreground-color" : "white", | ||
1179 | 161 | "background-color" : "transparent", | ||
1180 | 162 | "page-header": { | ||
1181 | 163 | "background": "color:///transparent" | ||
1182 | 164 | } | ||
1183 | 165 | } | ||
1184 | 166 | } | ||
1185 | 167 | |||
1186 | 168 | DashBackground { | ||
1187 | 169 | anchors.fill: parent | ||
1188 | 170 | source: "graphics/dark_background.jpg" | ||
1189 | 171 | } | ||
1190 | 172 | |||
1191 | 173 | Connections { | ||
1192 | 174 | target: pageHeader | ||
1193 | 175 | onSearchQueryChanged: { | ||
1194 | 176 | // Need this in order, otherwise something gets unhappy in rendering | ||
1195 | 177 | // of the overlay in carousels because the parent of the dash dies for | ||
1196 | 178 | // a moment, this way we make sure it's reparented first | ||
1197 | 179 | // by forceXYScalerEater making dashItemEater return scopesOverviewXYScaler | ||
1198 | 180 | // before we kill the previous parent by scope.searchQuery | ||
1199 | 181 | root.forceXYScalerEater = true; | ||
1200 | 182 | root.scope.searchQuery = pageHeader.searchQuery; | ||
1201 | 183 | root.forceXYScalerEater = false; | ||
1202 | 184 | } | ||
1203 | 185 | } | ||
1204 | 186 | |||
1205 | 187 | Binding { | ||
1206 | 188 | target: pageHeader | ||
1207 | 189 | property: "searchQuery" | ||
1208 | 190 | value: scope ? scope.searchQuery : "" | ||
1209 | 191 | } | ||
1210 | 192 | |||
1211 | 193 | Item { | ||
1212 | 194 | id: scopesOverviewContent | ||
1213 | 195 | x: previewListView.open ? -width : 0 | ||
1214 | 196 | Behavior on x { UbuntuNumberAnimation { } } | ||
1215 | 197 | width: parent.width | ||
1216 | 198 | height: parent.height | ||
1217 | 199 | |||
1218 | 200 | PageHeader { | ||
1219 | 201 | id: pageHeader | ||
1220 | 202 | objectName: "scopesOverviewPageHeader" | ||
1221 | 203 | |||
1222 | 204 | readonly property real yDisplacement: pageHeader.height + tabBar.height + tabBar.anchors.margins | ||
1223 | 205 | |||
1224 | 206 | y: { | ||
1225 | 207 | if (root.progress < 0.5) { | ||
1226 | 208 | return -yDisplacement; | ||
1227 | 209 | } else { | ||
1228 | 210 | return -yDisplacement + (root.progress - 0.5) * yDisplacement * 2; | ||
1229 | 211 | } | ||
1230 | 212 | } | ||
1231 | 213 | width: parent.width | ||
1232 | 214 | clip: true | ||
1233 | 215 | title: i18n.tr("Manage Scopes") | ||
1234 | 216 | scopeStyle: overviewScopeStyle | ||
1235 | 217 | showSignatureLine: false | ||
1236 | 218 | searchEntryEnabled: true | ||
1237 | 219 | } | ||
1238 | 220 | |||
1239 | 221 | ScopesOverviewTab { | ||
1240 | 222 | id: tabBar | ||
1241 | 223 | anchors { | ||
1242 | 224 | left: parent.left | ||
1243 | 225 | right: parent.right | ||
1244 | 226 | top: pageHeader.bottom | ||
1245 | 227 | margins: units.gu(2) | ||
1246 | 228 | } | ||
1247 | 229 | height: units.gu(4) | ||
1248 | 230 | |||
1249 | 231 | enabled: opacity == 1 | ||
1250 | 232 | opacity: !scope || scope.searchQuery == "" ? 1 : 0 | ||
1251 | 233 | Behavior on opacity { UbuntuNumberAnimation { } } | ||
1252 | 234 | } | ||
1253 | 235 | |||
1254 | 236 | Repeater { | ||
1255 | 237 | id: middleItems | ||
1256 | 238 | objectName: "scopesOverviewRepeater" | ||
1257 | 239 | property real overrideOpacity: -1 | ||
1258 | 240 | model: scope && scope.searchQuery == "" ? scope.categories : null | ||
1259 | 241 | delegate: Loader { | ||
1260 | 242 | id: loader | ||
1261 | 243 | objectName: "scopesOverviewRepeaterChild" + index | ||
1262 | 244 | |||
1263 | 245 | height: { | ||
1264 | 246 | if (index == 0) { | ||
1265 | 247 | return root.height; | ||
1266 | 248 | } else { | ||
1267 | 249 | return root.height - pageHeader.height - tabBar.height - tabBar.anchors.margins - units.gu(2); | ||
1268 | 250 | } | ||
1269 | 251 | } | ||
1270 | 252 | width: { | ||
1271 | 253 | if (index == 0) { | ||
1272 | 254 | return root.width / scopeScale; | ||
1273 | 255 | } else { | ||
1274 | 256 | return root.width; | ||
1275 | 257 | } | ||
1276 | 258 | } | ||
1277 | 259 | x: { | ||
1278 | 260 | if (index == 0) { | ||
1279 | 261 | return (root.width - width) / 2; | ||
1280 | 262 | } else { | ||
1281 | 263 | return 0; | ||
1282 | 264 | } | ||
1283 | 265 | } | ||
1284 | 266 | anchors { | ||
1285 | 267 | bottom: scopesOverviewContent.bottom | ||
1286 | 268 | } | ||
1287 | 269 | |||
1288 | 270 | scale: index == 0 ? scopeScale : 1 | ||
1289 | 271 | |||
1290 | 272 | opacity: { | ||
1291 | 273 | if (middleItems.overrideOpacity >= 0) | ||
1292 | 274 | return middleItems.overrideOpacity; | ||
1293 | 275 | |||
1294 | 276 | if (tabBar.currentTab != index) | ||
1295 | 277 | return 0; | ||
1296 | 278 | |||
1297 | 279 | return index == 0 ? 1 : root.progress; | ||
1298 | 280 | } | ||
1299 | 281 | Behavior on opacity { | ||
1300 | 282 | enabled: root.progress == 1 | ||
1301 | 283 | UbuntuNumberAnimation { } | ||
1302 | 284 | } | ||
1303 | 285 | enabled: opacity == 1 | ||
1304 | 286 | |||
1305 | 287 | clip: index == 1 | ||
1306 | 288 | |||
1307 | 289 | CardTool { | ||
1308 | 290 | id: cardTool | ||
1309 | 291 | objectName: "cardTool" | ||
1310 | 292 | count: results.count | ||
1311 | 293 | template: model.renderer | ||
1312 | 294 | components: model.components | ||
1313 | 295 | viewWidth: parent.width | ||
1314 | 296 | } | ||
1315 | 297 | |||
1316 | 298 | source: { | ||
1317 | 299 | if (index == 0 && categoryId == "favorites") return "ScopesOverviewFavorites.qml"; | ||
1318 | 300 | else if (index == 1 && categoryId == "all") return "ScopesOverviewAll.qml"; | ||
1319 | 301 | else return ""; | ||
1320 | 302 | } | ||
1321 | 303 | |||
1322 | 304 | onLoaded: { | ||
1323 | 305 | item.model = Qt.binding(function() { return results; }); | ||
1324 | 306 | item.cardTool = cardTool; | ||
1325 | 307 | if (index == 0) { | ||
1326 | 308 | item.scopeWidth = Qt.binding(function() { return root.width; }); | ||
1327 | 309 | item.scopeHeight = Qt.binding(function() { return root.height; }); | ||
1328 | 310 | item.appliedScale = Qt.binding(function() { return loader.scale }); | ||
1329 | 311 | item.currentIndex = Qt.binding(function() { return root.currentIndex }); | ||
1330 | 312 | } else if (index == 1) { | ||
1331 | 313 | item.extraHeight = bottomBar.height; | ||
1332 | 314 | } | ||
1333 | 315 | } | ||
1334 | 316 | |||
1335 | 317 | Connections { | ||
1336 | 318 | target: loader.item | ||
1337 | 319 | onClicked: { | ||
1338 | 320 | pageHeader.unfocus(); | ||
1339 | 321 | if (tabBar.currentTab == 0) { | ||
1340 | 322 | root.favoriteSelected(itemModel.scopeId); | ||
1341 | 323 | } else { | ||
1342 | 324 | var favoriteScopesItem = middleItems.itemAt(0).item; | ||
1343 | 325 | var scopeIndex = favoriteScopesItem.model.scopeIndex(itemModel.scopeId); | ||
1344 | 326 | if (scopeIndex >= 0) { | ||
1345 | 327 | root.allFavoriteSelected(itemModel.scopeId); | ||
1346 | 328 | } else { | ||
1347 | 329 | // Will result in an openScope from root.scope | ||
1348 | 330 | scopesOverviewXYScaler.restorePosition = item.mapToItem(null, 0, 0); | ||
1349 | 331 | scopesOverviewXYScaler.restoreSize = allCardSize; | ||
1350 | 332 | root.scope.activate(result); | ||
1351 | 333 | } | ||
1352 | 334 | } | ||
1353 | 335 | } | ||
1354 | 336 | onPressAndHold: { | ||
1355 | 337 | // Preview can call openScope so make sure restorePosition and restoreSize are set | ||
1356 | 338 | scopesOverviewXYScaler.restorePosition = undefined; | ||
1357 | 339 | scopesOverviewXYScaler.restoreSize = allCardSize; | ||
1358 | 340 | |||
1359 | 341 | previewListView.model = target.model; | ||
1360 | 342 | previewListView.currentIndex = -1; | ||
1361 | 343 | previewListView.currentIndex = index; | ||
1362 | 344 | previewListView.open = true; | ||
1363 | 345 | } | ||
1364 | 346 | } | ||
1365 | 347 | } | ||
1366 | 348 | } | ||
1367 | 349 | |||
1368 | 350 | GenericScopeView { | ||
1369 | 351 | id: searchResultsViewer | ||
1370 | 352 | objectName: "searchResultsViewer" | ||
1371 | 353 | anchors { | ||
1372 | 354 | top: pageHeader.bottom | ||
1373 | 355 | right: parent.right | ||
1374 | 356 | left: parent.left | ||
1375 | 357 | bottom: parent.bottom | ||
1376 | 358 | } | ||
1377 | 359 | scope: root.scope && root.scope.searchQuery != "" ? root.scope : null | ||
1378 | 360 | scopeStyle: overviewScopeStyle | ||
1379 | 361 | enabled: opacity == 1 | ||
1380 | 362 | showPageHeader: false | ||
1381 | 363 | clip: true | ||
1382 | 364 | opacity: searchResultsViewer.scope ? 1 : 0 | ||
1383 | 365 | isCurrent: true | ||
1384 | 366 | Behavior on opacity { UbuntuNumberAnimation { } } | ||
1385 | 367 | |||
1386 | 368 | function itemClicked(index, result, item, itemModel, resultsModel, limitedCategoryItemCount) { | ||
1387 | 369 | pageHeader.unfocus(); | ||
1388 | 370 | pageHeader.closePopup(); | ||
1389 | 371 | if (itemModel.scopeId) { | ||
1390 | 372 | // This can end up in openScope so save restorePosition and restoreSize | ||
1391 | 373 | scopesOverviewXYScaler.restorePosition = item.mapToItem(null, 0, 0); | ||
1392 | 374 | scopesOverviewXYScaler.restoreSize = Qt.size(item.width, item.height); | ||
1393 | 375 | root.searchSelected(itemModel.scopeId, result, item.mapToItem(null, 0, 0), Qt.size(item.width, item.height)); | ||
1394 | 376 | } else { | ||
1395 | 377 | // Not a scope, just activate it | ||
1396 | 378 | searchResultsViewer.scope.activate(result); | ||
1397 | 379 | } | ||
1398 | 380 | } | ||
1399 | 381 | |||
1400 | 382 | function itemPressedAndHeld(index, itemModel, resultsModel, limitedCategoryItemCount) { | ||
1401 | 383 | if (itemModel.uri.indexOf("scope://") === 0) { | ||
1402 | 384 | // Preview can call openScope so make sure restorePosition and restoreSize are set | ||
1403 | 385 | scopesOverviewXYScaler.restorePosition = undefined; | ||
1404 | 386 | scopesOverviewXYScaler.restoreSize = allCardSize; | ||
1405 | 387 | |||
1406 | 388 | previewListView.model = resultsModel; | ||
1407 | 389 | previewListView.currentIndex = -1; | ||
1408 | 390 | previewListView.currentIndex = index; | ||
1409 | 391 | previewListView.open = true; | ||
1410 | 392 | } | ||
1411 | 393 | } | ||
1412 | 394 | } | ||
1413 | 395 | |||
1414 | 396 | Rectangle { | ||
1415 | 397 | id: bottomBar | ||
1416 | 398 | objectName: "bottomBar" | ||
1417 | 399 | color: "black" | ||
1418 | 400 | height: units.gu(8) | ||
1419 | 401 | width: parent.width | ||
1420 | 402 | enabled: opacity == 1 | ||
1421 | 403 | opacity: scope && scope.searchQuery == "" ? 1 : 0 | ||
1422 | 404 | Behavior on opacity { UbuntuNumberAnimation { } } | ||
1423 | 405 | y: { | ||
1424 | 406 | if (root.progress < 0.5) { | ||
1425 | 407 | return parent.height; | ||
1426 | 408 | } else { | ||
1427 | 409 | return parent.height - (root.progress - 0.5) * height * 2; | ||
1428 | 410 | } | ||
1429 | 411 | } | ||
1430 | 412 | |||
1431 | 413 | MouseArea { | ||
1432 | 414 | // Just eat any other press since this parent is black opaque | ||
1433 | 415 | anchors.fill: parent | ||
1434 | 416 | } | ||
1435 | 417 | |||
1436 | 418 | AbstractButton { | ||
1437 | 419 | objectName: "scopesOverviewDoneButton" | ||
1438 | 420 | width: Math.max(label.width + units.gu(2), units.gu(10)) | ||
1439 | 421 | height: units.gu(4) | ||
1440 | 422 | anchors { | ||
1441 | 423 | left: parent.left | ||
1442 | 424 | leftMargin: units.gu(2) | ||
1443 | 425 | verticalCenter: parent.verticalCenter | ||
1444 | 426 | } | ||
1445 | 427 | Rectangle { | ||
1446 | 428 | anchors.fill: parent | ||
1447 | 429 | border.color: "white" | ||
1448 | 430 | border.width: units.dp(1) | ||
1449 | 431 | radius: units.dp(10) | ||
1450 | 432 | color: parent.pressed ? Theme.palette.normal.baseText : "transparent" | ||
1451 | 433 | } | ||
1452 | 434 | Label { | ||
1453 | 435 | id: label | ||
1454 | 436 | anchors.centerIn: parent | ||
1455 | 437 | text: i18n.tr("Done") | ||
1456 | 438 | color: parent.pressed ? "black" : "white" | ||
1457 | 439 | } | ||
1458 | 440 | onClicked: root.done(); | ||
1459 | 441 | } | ||
1460 | 442 | |||
1461 | 443 | AbstractButton { | ||
1462 | 444 | objectName: "scopesOverviewStoreButton" | ||
1463 | 445 | width: Math.max(storeLabel.width, units.gu(10)) | ||
1464 | 446 | height: units.gu(4) | ||
1465 | 447 | anchors { | ||
1466 | 448 | right: parent.right | ||
1467 | 449 | verticalCenter: parent.verticalCenter | ||
1468 | 450 | } | ||
1469 | 451 | Icon { | ||
1470 | 452 | id: storeImage | ||
1471 | 453 | name: "ubuntu-store-symbolic" | ||
1472 | 454 | color: "white" | ||
1473 | 455 | anchors.horizontalCenter: parent.horizontalCenter | ||
1474 | 456 | width: units.gu(2) | ||
1475 | 457 | height: units.gu(2) | ||
1476 | 458 | } | ||
1477 | 459 | Label { | ||
1478 | 460 | id: storeLabel | ||
1479 | 461 | anchors.horizontalCenter: parent.horizontalCenter | ||
1480 | 462 | anchors.top: storeImage.bottom | ||
1481 | 463 | text: i18n.tr("Store") | ||
1482 | 464 | color: "white" | ||
1483 | 465 | } | ||
1484 | 466 | onClicked: { | ||
1485 | 467 | // Just zoom from the middle | ||
1486 | 468 | scopesOverviewXYScaler.restorePosition = undefined; | ||
1487 | 469 | scopesOverviewXYScaler.restoreSize = allCardSize; | ||
1488 | 470 | scope.performQuery("scope://com.canonical.scopes.clickstore"); | ||
1489 | 471 | } | ||
1490 | 472 | } | ||
1491 | 473 | } | ||
1492 | 474 | } | ||
1493 | 475 | |||
1494 | 476 | PreviewListView { | ||
1495 | 477 | id: previewListView | ||
1496 | 478 | objectName: "scopesOverviewPreviewListView" | ||
1497 | 479 | scope: root.scope | ||
1498 | 480 | scopeStyle: overviewScopeStyle | ||
1499 | 481 | showSignatureLine: false | ||
1500 | 482 | visible: x != width | ||
1501 | 483 | width: parent.width | ||
1502 | 484 | height: parent.height | ||
1503 | 485 | anchors.left: scopesOverviewContent.right | ||
1504 | 486 | |||
1505 | 487 | onBackClicked: open = false | ||
1506 | 488 | } | ||
1507 | 489 | |||
1508 | 490 | Item { | ||
1509 | 491 | id: scopesOverviewXYScaler | ||
1510 | 492 | width: parent.width | ||
1511 | 493 | height: parent.height | ||
1512 | 494 | |||
1513 | 495 | clip: scale != 1.0 | ||
1514 | 496 | enabled: scale == 1 | ||
1515 | 497 | |||
1516 | 498 | property bool animationsEnabled: root.showingNonFavoriteScope || root.growingDashFromPos | ||
1517 | 499 | |||
1518 | 500 | property var restorePosition | ||
1519 | 501 | property var restoreSize | ||
1520 | 502 | |||
1521 | 503 | Behavior on x { | ||
1522 | 504 | enabled: scopesOverviewXYScaler.animationsEnabled | ||
1523 | 505 | UbuntuNumberAnimation { } | ||
1524 | 506 | } | ||
1525 | 507 | Behavior on y { | ||
1526 | 508 | enabled: scopesOverviewXYScaler.animationsEnabled | ||
1527 | 509 | UbuntuNumberAnimation { } | ||
1528 | 510 | } | ||
1529 | 511 | Behavior on opacity { | ||
1530 | 512 | enabled: scopesOverviewXYScaler.animationsEnabled | ||
1531 | 513 | UbuntuNumberAnimation { } | ||
1532 | 514 | } | ||
1533 | 515 | Behavior on scale { | ||
1534 | 516 | enabled: scopesOverviewXYScaler.animationsEnabled | ||
1535 | 517 | UbuntuNumberAnimation { | ||
1536 | 518 | onRunningChanged: { | ||
1537 | 519 | if (!running) { | ||
1538 | 520 | if (root.showingNonFavoriteScope && scopesOverviewXYScaler.scale != 1) { | ||
1539 | 521 | root.scope.closeScope(tempScopeItem.scope); | ||
1540 | 522 | tempScopeItem.scope = null; | ||
1541 | 523 | } else if (root.growingDashFromPos) { | ||
1542 | 524 | root.growingDashFromPos = false; | ||
1543 | 525 | } | ||
1544 | 526 | } | ||
1545 | 527 | } | ||
1546 | 528 | } | ||
1547 | 529 | } | ||
1548 | 530 | |||
1549 | 531 | DashBackground { | ||
1550 | 532 | anchors.fill: tempScopeItem | ||
1551 | 533 | visible: tempScopeItem.visible | ||
1552 | 534 | parent: tempScopeItem.parent | ||
1553 | 535 | } | ||
1554 | 536 | |||
1555 | 537 | GenericScopeView { | ||
1556 | 538 | id: tempScopeItem | ||
1557 | 539 | objectName: "scopesOverviewTempScopeItem" | ||
1558 | 540 | |||
1559 | 541 | width: parent.width | ||
1560 | 542 | height: parent.height | ||
1561 | 543 | clip: scale != 1.0 | ||
1562 | 544 | visible: scope != null | ||
1563 | 545 | hasBackAction: true | ||
1564 | 546 | isCurrent: visible | ||
1565 | 547 | onBackClicked: { | ||
1566 | 548 | var v = scopesOverviewXYScaler.restoreSize.width / tempScopeItem.width; | ||
1567 | 549 | scopesOverviewXYScaler.scale = v; | ||
1568 | 550 | if (scopesOverviewXYScaler.restorePosition) { | ||
1569 | 551 | scopesOverviewXYScaler.x = scopesOverviewXYScaler.restorePosition.x -(tempScopeItem.width - tempScopeItem.width * v) / 2; | ||
1570 | 552 | scopesOverviewXYScaler.y = scopesOverviewXYScaler.restorePosition.y -(tempScopeItem.height - tempScopeItem.height * v) / 2; | ||
1571 | 553 | } else { | ||
1572 | 554 | scopesOverviewXYScaler.x = 0; | ||
1573 | 555 | scopesOverviewXYScaler.y = 0; | ||
1574 | 556 | } | ||
1575 | 557 | scopesOverviewXYScaler.opacity = 0; | ||
1576 | 558 | middleItems.overrideOpacity = -1; | ||
1577 | 559 | } | ||
1578 | 560 | // TODO Add tests for these connections | ||
1579 | 561 | Connections { | ||
1580 | 562 | target: tempScopeItem.scope | ||
1581 | 563 | onOpenScope: { | ||
1582 | 564 | // TODO Animate the newly opened scope into the foreground (stacked on top of the current scope) | ||
1583 | 565 | tempScopeItem.scope = scope; | ||
1584 | 566 | } | ||
1585 | 567 | onGotoScope: { | ||
1586 | 568 | tempScopeItem.backClicked(); | ||
1587 | 569 | root.currentTab = 0; | ||
1588 | 570 | root.scope.gotoScope(scopeId); | ||
1589 | 571 | } | ||
1590 | 572 | } | ||
1591 | 573 | } | ||
1592 | 574 | } | ||
1593 | 575 | } | ||
1594 | 576 | 0 | ||
1595 | === removed file 'qml/Dash/ScopesOverviewAll.qml' | |||
1596 | --- qml/Dash/ScopesOverviewAll.qml 2014-11-05 08:37:55 +0000 | |||
1597 | +++ qml/Dash/ScopesOverviewAll.qml 1970-01-01 00:00:00 +0000 | |||
1598 | @@ -1,54 +0,0 @@ | |||
1599 | 1 | /* | ||
1600 | 2 | * Copyright (C) 2014 Canonical, Ltd. | ||
1601 | 3 | * | ||
1602 | 4 | * This program is free software; you can redistribute it and/or modify | ||
1603 | 5 | * it under the terms of the GNU General Public License as published by | ||
1604 | 6 | * the Free Software Foundation; version 3. | ||
1605 | 7 | * | ||
1606 | 8 | * This program is distributed in the hope that it will be useful, | ||
1607 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1608 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1609 | 11 | * GNU General Public License for more details. | ||
1610 | 12 | * | ||
1611 | 13 | * You should have received a copy of the GNU General Public License | ||
1612 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1613 | 15 | */ | ||
1614 | 16 | |||
1615 | 17 | import QtQuick 2.0 | ||
1616 | 18 | import Ubuntu.Components 0.1 | ||
1617 | 19 | |||
1618 | 20 | Flickable { | ||
1619 | 21 | id: root | ||
1620 | 22 | |||
1621 | 23 | property alias model: cardGrid.model | ||
1622 | 24 | property alias cardTool: cardGrid.cardTool | ||
1623 | 25 | |||
1624 | 26 | property real extraHeight: 0 | ||
1625 | 27 | |||
1626 | 28 | signal clicked(int index, var result, var item, var itemModel) | ||
1627 | 29 | signal pressAndHold(int index) | ||
1628 | 30 | |||
1629 | 31 | contentHeight: cardGrid.expandedHeight + extraHeight | ||
1630 | 32 | contentWidth: cardGrid.width | ||
1631 | 33 | flickableDirection: Flickable.VerticalFlick | ||
1632 | 34 | |||
1633 | 35 | function scopeCardPosition(scopeId) { | ||
1634 | 36 | var index = model.scopeIndex(scopeId); | ||
1635 | 37 | var pos = cardGrid.cardPosition(index); | ||
1636 | 38 | pos.y = pos.y - root.contentY; | ||
1637 | 39 | return pos; | ||
1638 | 40 | } | ||
1639 | 41 | |||
1640 | 42 | CardGrid { | ||
1641 | 43 | id: cardGrid | ||
1642 | 44 | width: root.width | ||
1643 | 45 | height: parent.height | ||
1644 | 46 | |||
1645 | 47 | onClicked: { | ||
1646 | 48 | root.clicked(index, result, item, itemModel); | ||
1647 | 49 | } | ||
1648 | 50 | onPressAndHold: { | ||
1649 | 51 | root.pressAndHold(index); | ||
1650 | 52 | } | ||
1651 | 53 | } | ||
1652 | 54 | } | ||
1653 | 55 | 0 | ||
1654 | === removed file 'qml/Dash/ScopesOverviewFavorites.qml' | |||
1655 | --- qml/Dash/ScopesOverviewFavorites.qml 2014-10-23 11:59:22 +0000 | |||
1656 | +++ qml/Dash/ScopesOverviewFavorites.qml 1970-01-01 00:00:00 +0000 | |||
1657 | @@ -1,73 +0,0 @@ | |||
1658 | 1 | /* | ||
1659 | 2 | * Copyright (C) 2014 Canonical, Ltd. | ||
1660 | 3 | * | ||
1661 | 4 | * This program is free software; you can redistribute it and/or modify | ||
1662 | 5 | * it under the terms of the GNU General Public License as published by | ||
1663 | 6 | * the Free Software Foundation; version 3. | ||
1664 | 7 | * | ||
1665 | 8 | * This program is distributed in the hope that it will be useful, | ||
1666 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1667 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1668 | 11 | * GNU General Public License for more details. | ||
1669 | 12 | * | ||
1670 | 13 | * You should have received a copy of the GNU General Public License | ||
1671 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1672 | 15 | */ | ||
1673 | 16 | |||
1674 | 17 | import QtQuick 2.0 | ||
1675 | 18 | |||
1676 | 19 | Flickable { | ||
1677 | 20 | id: root | ||
1678 | 21 | |||
1679 | 22 | signal clicked(int index, var result, var itemModel) | ||
1680 | 23 | signal pressAndHold(int index) | ||
1681 | 24 | |||
1682 | 25 | property var cardTool: null | ||
1683 | 26 | property real scopeHeight: 0 | ||
1684 | 27 | property real scopeWidth: 0 | ||
1685 | 28 | property real appliedScale: 1 | ||
1686 | 29 | property int currentIndex: -1 | ||
1687 | 30 | property var currentItem: currentIndex < repeater.count ? repeater.itemAt(currentIndex) : null | ||
1688 | 31 | |||
1689 | 32 | property alias model: repeater.model | ||
1690 | 33 | |||
1691 | 34 | contentHeight: height | ||
1692 | 35 | contentWidth: repeater.count * root.scopeWidth + units.gu(2) / appliedScale * (repeater.count - 1) | ||
1693 | 36 | |||
1694 | 37 | contentX: { | ||
1695 | 38 | var indexX = currentIndex * scopeWidth + units.gu(2) / appliedScale * currentIndex; | ||
1696 | 39 | var newContentX = indexX - (width - scopeWidth) / 2; | ||
1697 | 40 | newContentX = Math.min(Math.max(newContentX, 0), contentWidth - width); | ||
1698 | 41 | return newContentX; | ||
1699 | 42 | } | ||
1700 | 43 | |||
1701 | 44 | Repeater { | ||
1702 | 45 | id: repeater | ||
1703 | 46 | objectName: "scopesOverviewFavoritesRepeater" | ||
1704 | 47 | |||
1705 | 48 | delegate: Loader { | ||
1706 | 49 | id: loader | ||
1707 | 50 | |||
1708 | 51 | x: index * root.scopeWidth + units.gu(2) / appliedScale * index | ||
1709 | 52 | asynchronous: true | ||
1710 | 53 | |||
1711 | 54 | sourceComponent: cardTool.cardComponent | ||
1712 | 55 | onLoaded: { | ||
1713 | 56 | item.fixedArtShapeSize = Qt.binding(function() { return Qt.size(root.scopeWidth, root.scopeHeight); }); | ||
1714 | 57 | item.fixedHeaderHeight = Qt.binding(function() { return cardTool.headerHeight / appliedScale; }); | ||
1715 | 58 | item.fontScale = Qt.binding(function() { return 1 / appliedScale; }); | ||
1716 | 59 | item.height = Qt.binding(function() { return root.scopeHeight; }); | ||
1717 | 60 | item.width = Qt.binding(function() { return root.scopeWidth; }); | ||
1718 | 61 | item.cardData = Qt.binding(function() { return model; }); | ||
1719 | 62 | item.template = Qt.binding(function() { return cardTool.template; }); | ||
1720 | 63 | item.components = Qt.binding(function() { return cardTool.components; }); | ||
1721 | 64 | item.titleAlignment = Qt.binding(function() { return cardTool.titleAlignment; }); | ||
1722 | 65 | } | ||
1723 | 66 | |||
1724 | 67 | Connections { | ||
1725 | 68 | target: loader.item | ||
1726 | 69 | onClicked: root.clicked(index, result, model) | ||
1727 | 70 | } | ||
1728 | 71 | } | ||
1729 | 72 | } | ||
1730 | 73 | } | ||
1731 | 74 | 0 | ||
1732 | === removed file 'qml/Dash/ScopesOverviewTab.qml' | |||
1733 | --- qml/Dash/ScopesOverviewTab.qml 2014-07-21 11:10:06 +0000 | |||
1734 | +++ qml/Dash/ScopesOverviewTab.qml 1970-01-01 00:00:00 +0000 | |||
1735 | @@ -1,74 +0,0 @@ | |||
1736 | 1 | /* | ||
1737 | 2 | * Copyright (C) 2014 Canonical, Ltd. | ||
1738 | 3 | * | ||
1739 | 4 | * This program is free software; you can redistribute it and/or modify | ||
1740 | 5 | * it under the terms of the GNU General Public License as published by | ||
1741 | 6 | * the Free Software Foundation; version 3. | ||
1742 | 7 | * | ||
1743 | 8 | * This program is distributed in the hope that it will be useful, | ||
1744 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1745 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1746 | 11 | * GNU General Public License for more details. | ||
1747 | 12 | * | ||
1748 | 13 | * You should have received a copy of the GNU General Public License | ||
1749 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1750 | 15 | */ | ||
1751 | 16 | |||
1752 | 17 | import QtQuick 2.3 | ||
1753 | 18 | import Ubuntu.Components 0.1 | ||
1754 | 19 | |||
1755 | 20 | Item { | ||
1756 | 21 | id: root | ||
1757 | 22 | |||
1758 | 23 | property int currentTab: 0 | ||
1759 | 24 | |||
1760 | 25 | AbstractButton { | ||
1761 | 26 | id: tab1 | ||
1762 | 27 | height: parent.height | ||
1763 | 28 | width: parent.width / 2 | ||
1764 | 29 | Rectangle { | ||
1765 | 30 | anchors.fill: parent | ||
1766 | 31 | color: root.currentTab == 0 && root.enabled ? "white" : "transparent" | ||
1767 | 32 | radius: units.dp(10) | ||
1768 | 33 | } | ||
1769 | 34 | Label { | ||
1770 | 35 | anchors.centerIn: parent | ||
1771 | 36 | text: i18n.tr("Favorites") | ||
1772 | 37 | color: root.currentTab == 0 && root.enabled ? "black" : "white" | ||
1773 | 38 | } | ||
1774 | 39 | onClicked: root.currentTab = 0 | ||
1775 | 40 | } | ||
1776 | 41 | AbstractButton { | ||
1777 | 42 | id: tab2 | ||
1778 | 43 | objectName: "scopesOverviewAllTabButton" | ||
1779 | 44 | x: width | ||
1780 | 45 | height: parent.height | ||
1781 | 46 | width: parent.width / 2 | ||
1782 | 47 | Rectangle { | ||
1783 | 48 | anchors.fill: parent | ||
1784 | 49 | color: root.currentTab == 1 && root.enabled ? "white" : "transparent" | ||
1785 | 50 | radius: units.dp(10) | ||
1786 | 51 | } | ||
1787 | 52 | Label { | ||
1788 | 53 | anchors.centerIn: parent | ||
1789 | 54 | text: i18n.tr("All") | ||
1790 | 55 | color: root.currentTab == 1 && root.enabled ? "black" : "white" | ||
1791 | 56 | } | ||
1792 | 57 | onClicked: root.currentTab = 1 | ||
1793 | 58 | } | ||
1794 | 59 | Rectangle { | ||
1795 | 60 | id: centerPiece | ||
1796 | 61 | width: root.enabled ? units.dp(10) : units.dp(1) | ||
1797 | 62 | height: parent.height | ||
1798 | 63 | color: "white" | ||
1799 | 64 | x: root.currentTab == 1 ? tab2.x : tab2.x - width | ||
1800 | 65 | } | ||
1801 | 66 | Rectangle { | ||
1802 | 67 | id: border | ||
1803 | 68 | anchors.fill: parent | ||
1804 | 69 | radius: units.dp(10) | ||
1805 | 70 | color: "transparent" | ||
1806 | 71 | border.color: centerPiece.color | ||
1807 | 72 | border.width: units.dp(1) | ||
1808 | 73 | } | ||
1809 | 74 | } | ||
1810 | 75 | 0 | ||
1811 | === modified file 'tests/mocks/Unity/CMakeLists.txt' | |||
1812 | --- tests/mocks/Unity/CMakeLists.txt 2014-10-28 12:29:43 +0000 | |||
1813 | +++ tests/mocks/Unity/CMakeLists.txt 2014-12-05 10:47:59 +0000 | |||
1814 | @@ -6,7 +6,7 @@ | |||
1815 | 6 | add_subdirectory(DashCommunicator) | 6 | add_subdirectory(DashCommunicator) |
1816 | 7 | 7 | ||
1817 | 8 | pkg_search_module(GOBJECT gobject-2.0 REQUIRED) | 8 | pkg_search_module(GOBJECT gobject-2.0 REQUIRED) |
1819 | 9 | pkg_check_modules(SCOPES_API REQUIRED unity-shell-scopes=4) | 9 | pkg_check_modules(SCOPES_API REQUIRED unity-shell-scopes=5) |
1820 | 10 | 10 | ||
1821 | 11 | include_directories( | 11 | include_directories( |
1822 | 12 | ${CMAKE_CURRENT_BINARY_DIR} | 12 | ${CMAKE_CURRENT_BINARY_DIR} |
1823 | 13 | 13 | ||
1824 | === modified file 'tests/mocks/Unity/fake_scopes.cpp' | |||
1825 | --- tests/mocks/Unity/fake_scopes.cpp 2014-09-16 04:44:37 +0000 | |||
1826 | +++ tests/mocks/Unity/fake_scopes.cpp 2014-12-05 10:47:59 +0000 | |||
1827 | @@ -165,14 +165,68 @@ | |||
1828 | 165 | return m_scopesOverview; | 165 | return m_scopesOverview; |
1829 | 166 | } | 166 | } |
1830 | 167 | 167 | ||
1832 | 168 | QList<Scope*> Scopes::scopes() const | 168 | void Scopes::setFavorite(const QString& scopeId, bool favorite) |
1833 | 169 | { | ||
1834 | 170 | if (favorite) { | ||
1835 | 171 | for (Scope *scope : m_scopes) { | ||
1836 | 172 | // Check it's not already there | ||
1837 | 173 | Q_ASSERT(scope->id() != scopeId); | ||
1838 | 174 | } | ||
1839 | 175 | for (Scope *scope : m_allScopes) { | ||
1840 | 176 | if (scope->id() == scopeId) { | ||
1841 | 177 | const int index = rowCount(); | ||
1842 | 178 | beginInsertRows(QModelIndex(), index, index); | ||
1843 | 179 | m_scopes << scope; | ||
1844 | 180 | endInsertRows(); | ||
1845 | 181 | m_scopesOverview->setFavorite(scope, true); | ||
1846 | 182 | return; | ||
1847 | 183 | } | ||
1848 | 184 | } | ||
1849 | 185 | Q_ASSERT(false && "Unknown scopeId"); | ||
1850 | 186 | } else { | ||
1851 | 187 | for (Scope *scope : m_scopes) { | ||
1852 | 188 | if (scope->id() == scopeId) { | ||
1853 | 189 | const int index = m_scopes.indexOf(scope); | ||
1854 | 190 | beginRemoveRows(QModelIndex(), index, index); | ||
1855 | 191 | m_scopes.removeAt(index); | ||
1856 | 192 | endRemoveRows(); | ||
1857 | 193 | m_scopesOverview->setFavorite(scope, false); | ||
1858 | 194 | return; | ||
1859 | 195 | } | ||
1860 | 196 | } | ||
1861 | 197 | Q_ASSERT(false && "Unknown scopeId"); | ||
1862 | 198 | } | ||
1863 | 199 | } | ||
1864 | 200 | |||
1865 | 201 | void Scopes::moveFavoriteTo(const QString& scopeId, int to) | ||
1866 | 202 | { | ||
1867 | 203 | int from = -1; | ||
1868 | 204 | for (int i = 0; i < m_scopes.count(); ++i) { | ||
1869 | 205 | if (m_scopes[i]->id() == scopeId) { | ||
1870 | 206 | from = i; | ||
1871 | 207 | break; | ||
1872 | 208 | } | ||
1873 | 209 | } | ||
1874 | 210 | Q_ASSERT(from != -1); | ||
1875 | 211 | beginMoveRows(QModelIndex(), from, from, QModelIndex(), to + (to > from ? 1 : 0)); | ||
1876 | 212 | m_scopes.move(from, to); | ||
1877 | 213 | endMoveRows(); | ||
1878 | 214 | m_scopesOverview->moveFavoriteTo(m_scopes[to], to); | ||
1879 | 215 | } | ||
1880 | 216 | |||
1881 | 217 | QList<Scope*> Scopes::favScopes() const | ||
1882 | 169 | { | 218 | { |
1883 | 170 | return m_scopes; | 219 | return m_scopes; |
1884 | 171 | } | 220 | } |
1885 | 172 | 221 | ||
1887 | 173 | QList<Scope*> Scopes::allScopes() const | 222 | QList<Scope*> Scopes::nonFavScopes() const |
1888 | 174 | { | 223 | { |
1890 | 175 | return m_allScopes; | 224 | QList<Scope*> res; |
1891 | 225 | for (Scope *scope : m_allScopes) { | ||
1892 | 226 | if (!m_scopes.contains(scope)) | ||
1893 | 227 | res << scope; | ||
1894 | 228 | } | ||
1895 | 229 | return res; | ||
1896 | 176 | } | 230 | } |
1897 | 177 | 231 | ||
1898 | 178 | void Scopes::addScope(Scope* scope) | 232 | void Scopes::addScope(Scope* scope) |
1899 | 179 | 233 | ||
1900 | === modified file 'tests/mocks/Unity/fake_scopes.h' | |||
1901 | --- tests/mocks/Unity/fake_scopes.h 2014-08-25 14:13:24 +0000 | |||
1902 | +++ tests/mocks/Unity/fake_scopes.h 2014-12-05 10:47:59 +0000 | |||
1903 | @@ -28,6 +28,8 @@ | |||
1904 | 28 | #include <QList> | 28 | #include <QList> |
1905 | 29 | #include <QTimer> | 29 | #include <QTimer> |
1906 | 30 | 30 | ||
1907 | 31 | class ScopesOverview; | ||
1908 | 32 | |||
1909 | 31 | class Scopes : public unity::shell::scopes::ScopesInterface | 33 | class Scopes : public unity::shell::scopes::ScopesInterface |
1910 | 32 | { | 34 | { |
1911 | 33 | Q_OBJECT | 35 | Q_OBJECT |
1912 | @@ -53,9 +55,12 @@ | |||
1913 | 53 | int count() const override; | 55 | int count() const override; |
1914 | 54 | unity::shell::scopes::ScopeInterface* overviewScope() const override; | 56 | unity::shell::scopes::ScopeInterface* overviewScope() const override; |
1915 | 55 | 57 | ||
1916 | 58 | Q_INVOKABLE void setFavorite(const QString& scopeId, bool favorite) override; | ||
1917 | 59 | Q_INVOKABLE void moveFavoriteTo(const QString& scopeId, int index) override; | ||
1918 | 60 | |||
1919 | 56 | // This is used as part of implementation of the other C++ code, not API | 61 | // This is used as part of implementation of the other C++ code, not API |
1922 | 57 | QList<Scope*> scopes() const; | 62 | QList<Scope*> favScopes() const; |
1923 | 58 | QList<Scope*> allScopes() const; | 63 | QList<Scope*> nonFavScopes() const; |
1924 | 59 | Q_INVOKABLE Scope* getScopeFromAll(const QString& scope_id) const; | 64 | Q_INVOKABLE Scope* getScopeFromAll(const QString& scope_id) const; |
1925 | 60 | 65 | ||
1926 | 61 | private Q_SLOTS: | 66 | private Q_SLOTS: |
1927 | @@ -64,7 +69,7 @@ | |||
1928 | 64 | private: | 69 | private: |
1929 | 65 | QList<Scope*> m_scopes; // the favorite ones | 70 | QList<Scope*> m_scopes; // the favorite ones |
1930 | 66 | QList<Scope*> m_allScopes; | 71 | QList<Scope*> m_allScopes; |
1932 | 67 | Scope *m_scopesOverview; | 72 | ScopesOverview *m_scopesOverview; |
1933 | 68 | bool m_loaded; | 73 | bool m_loaded; |
1934 | 69 | QTimer timer; | 74 | QTimer timer; |
1935 | 70 | }; | 75 | }; |
1936 | 71 | 76 | ||
1937 | === modified file 'tests/mocks/Unity/fake_scopesoverview.cpp' | |||
1938 | --- tests/mocks/Unity/fake_scopesoverview.cpp 2014-08-13 23:26:36 +0000 | |||
1939 | +++ tests/mocks/Unity/fake_scopesoverview.cpp 2014-12-05 10:47:59 +0000 | |||
1940 | @@ -44,8 +44,22 @@ | |||
1941 | 44 | Q_INVOKABLE void ScopesOverview::activate(QVariant const& result) | 44 | Q_INVOKABLE void ScopesOverview::activate(QVariant const& result) |
1942 | 45 | { | 45 | { |
1943 | 46 | Scopes *scopes = dynamic_cast<Scopes*>(parent()); | 46 | Scopes *scopes = dynamic_cast<Scopes*>(parent()); |
1946 | 47 | m_openScope = scopes->getScopeFromAll(result.toString()); | 47 | if (scopes->getScope(result.toString())) { |
1947 | 48 | Q_EMIT openScope(m_openScope); | 48 | Q_EMIT gotoScope(result.toString()); |
1948 | 49 | } else { | ||
1949 | 50 | m_openScope = scopes->getScopeFromAll(result.toString()); | ||
1950 | 51 | Q_EMIT openScope(m_openScope); | ||
1951 | 52 | } | ||
1952 | 53 | } | ||
1953 | 54 | |||
1954 | 55 | void ScopesOverview::setFavorite(Scope *scope, bool favorite) | ||
1955 | 56 | { | ||
1956 | 57 | m_scopesOverviewCategories->setFavorite(scope, favorite); | ||
1957 | 58 | } | ||
1958 | 59 | |||
1959 | 60 | void ScopesOverview::moveFavoriteTo(Scope *scope, int index) | ||
1960 | 61 | { | ||
1961 | 62 | m_scopesOverviewCategories->moveFavoriteTo(scope, index); | ||
1962 | 49 | } | 63 | } |
1963 | 50 | 64 | ||
1964 | 51 | ScopesOverviewCategories::ScopesOverviewCategories(Scopes *scopes, QObject* parent) | 65 | ScopesOverviewCategories::ScopesOverviewCategories(Scopes *scopes, QObject* parent) |
1965 | @@ -69,19 +83,41 @@ | |||
1966 | 69 | qFatal("Using un-implemented ScopesOverviewCategories::overrideCategoryJson"); | 83 | qFatal("Using un-implemented ScopesOverviewCategories::overrideCategoryJson"); |
1967 | 70 | } | 84 | } |
1968 | 71 | 85 | ||
1971 | 72 | QVariant | 86 | void ScopesOverviewCategories::setFavorite(Scope *scope, bool favorite) |
1972 | 73 | ScopesOverviewCategories::data(const QModelIndex& index, int role) const | 87 | { |
1973 | 88 | if (m_resultsModels.value(0)) { | ||
1974 | 89 | if (favorite) { | ||
1975 | 90 | m_resultsModels[0]->appendScope(scope); | ||
1976 | 91 | } else { | ||
1977 | 92 | m_resultsModels[0]->removeScope(scope); | ||
1978 | 93 | } | ||
1979 | 94 | } | ||
1980 | 95 | if (m_resultsModels.value(1)) { | ||
1981 | 96 | if (favorite) { | ||
1982 | 97 | m_resultsModels[1]->removeScope(scope); | ||
1983 | 98 | } else { | ||
1984 | 99 | m_resultsModels[1]->appendScope(scope); | ||
1985 | 100 | } | ||
1986 | 101 | } | ||
1987 | 102 | } | ||
1988 | 103 | |||
1989 | 104 | void ScopesOverviewCategories::moveFavoriteTo(Scope *scope, int index) | ||
1990 | 105 | { | ||
1991 | 106 | m_resultsModels[0]->moveScopeTo(scope, index); | ||
1992 | 107 | } | ||
1993 | 108 | |||
1994 | 109 | QVariant ScopesOverviewCategories::data(const QModelIndex& index, int role) const | ||
1995 | 74 | { | 110 | { |
1996 | 75 | if (!index.isValid()) { | 111 | if (!index.isValid()) { |
1997 | 76 | return QVariant(); | 112 | return QVariant(); |
1998 | 77 | } | 113 | } |
1999 | 78 | 114 | ||
2001 | 79 | const QString categoryId = index.row() == 0 ? "favorites" : "all"; | 115 | const QString categoryId = index.row() == 0 ? "favorites" : "other"; |
2002 | 80 | 116 | ||
2004 | 81 | unity::shell::scopes::ResultsModelInterface *resultsModel = m_resultsModels[index.row()]; | 117 | ScopesOverviewResultsModel *resultsModel = m_resultsModels[index.row()]; |
2005 | 82 | if (!resultsModel) { | 118 | if (!resultsModel) { |
2006 | 83 | QObject *that = const_cast<ScopesOverviewCategories*>(this); | 119 | QObject *that = const_cast<ScopesOverviewCategories*>(this); |
2008 | 84 | QList<Scope*> scopes = index.row() == 0 ? m_scopes->scopes() : m_scopes->allScopes(); | 120 | QList<Scope*> scopes = index.row() == 0 ? m_scopes->favScopes() : m_scopes->nonFavScopes(); |
2009 | 85 | resultsModel = new ScopesOverviewResultsModel(scopes, categoryId, that); | 121 | resultsModel = new ScopesOverviewResultsModel(scopes, categoryId, that); |
2010 | 86 | m_resultsModels[index.row()] = resultsModel; | 122 | m_resultsModels[index.row()] = resultsModel; |
2011 | 87 | } | 123 | } |
2012 | @@ -89,7 +125,7 @@ | |||
2013 | 89 | case RoleCategoryId: | 125 | case RoleCategoryId: |
2014 | 90 | return categoryId; | 126 | return categoryId; |
2015 | 91 | case RoleName: | 127 | case RoleName: |
2017 | 92 | return index.row() == 0 ? "Favorites" : "All"; | 128 | return index.row() == 0 ? "Favorites" : "Non Favorites"; |
2018 | 93 | case RoleIcon: | 129 | case RoleIcon: |
2019 | 94 | return QVariant(); | 130 | return QVariant(); |
2020 | 95 | case RoleRawRendererTemplate: | 131 | case RoleRawRendererTemplate: |
2021 | @@ -157,7 +193,7 @@ | |||
2022 | 157 | 193 | ||
2023 | 158 | const QString categoryId = index.row() == 0 ? "searchA" : "searchB"; | 194 | const QString categoryId = index.row() == 0 ? "searchA" : "searchB"; |
2024 | 159 | 195 | ||
2026 | 160 | unity::shell::scopes::ResultsModelInterface *resultsModel = m_resultsModels[index.row()]; | 196 | ScopesOverviewResultsModel *resultsModel = m_resultsModels[index.row()]; |
2027 | 161 | if (!resultsModel) { | 197 | if (!resultsModel) { |
2028 | 162 | QObject *that = const_cast<ScopesOverviewSearchCategories*>(this); | 198 | QObject *that = const_cast<ScopesOverviewSearchCategories*>(this); |
2029 | 163 | QList<Scope *> scopes; | 199 | QList<Scope *> scopes; |
2030 | @@ -256,8 +292,7 @@ | |||
2031 | 256 | return rowCount(); | 292 | return rowCount(); |
2032 | 257 | } | 293 | } |
2033 | 258 | 294 | ||
2036 | 259 | QVariant | 295 | QVariant ScopesOverviewResultsModel::data(const QModelIndex& index, int role) const |
2035 | 260 | ScopesOverviewResultsModel::data(const QModelIndex& index, int role) const | ||
2037 | 261 | { | 296 | { |
2038 | 262 | unity::shell::scopes::ScopeInterface *scope = m_scopes[index.row()]; | 297 | unity::shell::scopes::ScopeInterface *scope = m_scopes[index.row()]; |
2039 | 263 | switch (role) { | 298 | switch (role) { |
2040 | @@ -269,6 +304,8 @@ | |||
2041 | 269 | return scope ? scope->id() : QString("Result.%1.%2").arg(categoryId()).arg(index.row()); | 304 | return scope ? scope->id() : QString("Result.%1.%2").arg(categoryId()).arg(index.row()); |
2042 | 270 | case RoleTitle: | 305 | case RoleTitle: |
2043 | 271 | return scope ? scope->name() : QString("Title.%1.%2").arg(categoryId()).arg(index.row()); | 306 | return scope ? scope->name() : QString("Title.%1.%2").arg(categoryId()).arg(index.row()); |
2044 | 307 | case RoleSubtitle: | ||
2045 | 308 | return scope && scope->name() == "Videos" ? "tube, movies, cinema" : QString(); | ||
2046 | 272 | case RoleArt: | 309 | case RoleArt: |
2047 | 273 | return qmlDirectory() + "graphics/applicationIcons/dash.png"; | 310 | return qmlDirectory() + "graphics/applicationIcons/dash.png"; |
2048 | 274 | case RoleMascot: | 311 | case RoleMascot: |
2049 | @@ -281,3 +318,32 @@ | |||
2050 | 281 | return QVariant(); | 318 | return QVariant(); |
2051 | 282 | } | 319 | } |
2052 | 283 | } | 320 | } |
2053 | 321 | |||
2054 | 322 | void ScopesOverviewResultsModel::appendScope(Scope *scope) | ||
2055 | 323 | { | ||
2056 | 324 | Q_ASSERT(!m_scopes.contains(scope)); | ||
2057 | 325 | const int index = rowCount(); | ||
2058 | 326 | beginInsertRows(QModelIndex(), index, index); | ||
2059 | 327 | m_scopes << scope; | ||
2060 | 328 | endInsertRows(); | ||
2061 | 329 | Q_EMIT countChanged(); | ||
2062 | 330 | } | ||
2063 | 331 | |||
2064 | 332 | void ScopesOverviewResultsModel::removeScope(Scope *scope) | ||
2065 | 333 | { | ||
2066 | 334 | const int index = m_scopes.indexOf(scope); | ||
2067 | 335 | Q_ASSERT(index != -1); | ||
2068 | 336 | beginRemoveRows(QModelIndex(), index, index); | ||
2069 | 337 | m_scopes.removeAt(index); | ||
2070 | 338 | endRemoveRows(); | ||
2071 | 339 | Q_EMIT countChanged(); | ||
2072 | 340 | } | ||
2073 | 341 | |||
2074 | 342 | void ScopesOverviewResultsModel::moveScopeTo(Scope *scope, int to) | ||
2075 | 343 | { | ||
2076 | 344 | const int from = m_scopes.indexOf(scope); | ||
2077 | 345 | Q_ASSERT(from!= -1); | ||
2078 | 346 | beginMoveRows(QModelIndex(), from, from, QModelIndex(), to + (to > from ? 1 : 0)); | ||
2079 | 347 | m_scopes.move(from, to); | ||
2080 | 348 | endMoveRows(); | ||
2081 | 349 | } | ||
2082 | 284 | 350 | ||
2083 | === modified file 'tests/mocks/Unity/fake_scopesoverview.h' | |||
2084 | --- tests/mocks/Unity/fake_scopesoverview.h 2014-08-07 08:52:59 +0000 | |||
2085 | +++ tests/mocks/Unity/fake_scopesoverview.h 2014-12-05 10:47:59 +0000 | |||
2086 | @@ -21,6 +21,8 @@ | |||
2087 | 21 | #include <unity/shell/scopes/ResultsModelInterface.h> | 21 | #include <unity/shell/scopes/ResultsModelInterface.h> |
2088 | 22 | 22 | ||
2089 | 23 | class Scopes; | 23 | class Scopes; |
2090 | 24 | class ScopesOverviewCategories; | ||
2091 | 25 | class ScopesOverviewResultsModel; | ||
2092 | 24 | 26 | ||
2093 | 25 | class ScopesOverview : public Scope | 27 | class ScopesOverview : public Scope |
2094 | 26 | { | 28 | { |
2095 | @@ -32,8 +34,12 @@ | |||
2096 | 32 | void setSearchQuery(const QString& search_query) override; | 34 | void setSearchQuery(const QString& search_query) override; |
2097 | 33 | Q_INVOKABLE void activate(QVariant const& result) override; | 35 | Q_INVOKABLE void activate(QVariant const& result) override; |
2098 | 34 | 36 | ||
2099 | 37 | // This is implementation detail | ||
2100 | 38 | void setFavorite(Scope *scope, bool favorite); | ||
2101 | 39 | void moveFavoriteTo(Scope *scope, int index); | ||
2102 | 40 | |||
2103 | 35 | private: | 41 | private: |
2105 | 36 | unity::shell::scopes::CategoriesInterface *m_scopesOverviewCategories; | 42 | ScopesOverviewCategories *m_scopesOverviewCategories; |
2106 | 37 | unity::shell::scopes::CategoriesInterface *m_searchCategories; | 43 | unity::shell::scopes::CategoriesInterface *m_searchCategories; |
2107 | 38 | }; | 44 | }; |
2108 | 39 | 45 | ||
2109 | @@ -50,8 +56,12 @@ | |||
2110 | 50 | Q_INVOKABLE void addSpecialCategory(QString const& categoryId, QString const& name, QString const& icon, QString const& rawTemplate, QObject* countObject) override; | 56 | Q_INVOKABLE void addSpecialCategory(QString const& categoryId, QString const& name, QString const& icon, QString const& rawTemplate, QObject* countObject) override; |
2111 | 51 | Q_INVOKABLE bool overrideCategoryJson(QString const& categoryId, QString const& json) override; | 57 | Q_INVOKABLE bool overrideCategoryJson(QString const& categoryId, QString const& json) override; |
2112 | 52 | 58 | ||
2113 | 59 | // This is implementation detail | ||
2114 | 60 | void setFavorite(Scope *scope, bool favorite); | ||
2115 | 61 | void moveFavoriteTo(Scope *scope, int index); | ||
2116 | 62 | |||
2117 | 53 | private: | 63 | private: |
2119 | 54 | mutable QHash<int, unity::shell::scopes::ResultsModelInterface*> m_resultsModels; | 64 | mutable QHash<int, ScopesOverviewResultsModel*> m_resultsModels; |
2120 | 55 | 65 | ||
2121 | 56 | Scopes *m_scopes; | 66 | Scopes *m_scopes; |
2122 | 57 | }; | 67 | }; |
2123 | @@ -70,7 +80,7 @@ | |||
2124 | 70 | Q_INVOKABLE bool overrideCategoryJson(QString const& categoryId, QString const& json) override; | 80 | Q_INVOKABLE bool overrideCategoryJson(QString const& categoryId, QString const& json) override; |
2125 | 71 | 81 | ||
2126 | 72 | private: | 82 | private: |
2128 | 73 | mutable QHash<int, unity::shell::scopes::ResultsModelInterface*> m_resultsModels; | 83 | mutable QHash<int, ScopesOverviewResultsModel*> m_resultsModels; |
2129 | 74 | 84 | ||
2130 | 75 | Scopes *m_scopes; | 85 | Scopes *m_scopes; |
2131 | 76 | }; | 86 | }; |
2132 | @@ -96,6 +106,11 @@ | |||
2133 | 96 | Q_INVOKABLE int scopeIndex(QString const& id) const; | 106 | Q_INVOKABLE int scopeIndex(QString const& id) const; |
2134 | 97 | QHash<int, QByteArray> roleNames() const override; | 107 | QHash<int, QByteArray> roleNames() const override; |
2135 | 98 | 108 | ||
2136 | 109 | // This is implementation detail | ||
2137 | 110 | void appendScope(Scope *scope); | ||
2138 | 111 | void removeScope(Scope *scope); | ||
2139 | 112 | void moveScopeTo(Scope *scope, int index); | ||
2140 | 113 | |||
2141 | 99 | private: | 114 | private: |
2142 | 100 | QList<Scope *> m_scopes; | 115 | QList<Scope *> m_scopes; |
2143 | 101 | QString m_categoryId; | 116 | QString m_categoryId; |
2144 | 102 | 117 | ||
2145 | === modified file 'tests/qmltests/Dash/tst_Dash.qml' | |||
2146 | --- tests/qmltests/Dash/tst_Dash.qml 2014-12-02 09:25:01 +0000 | |||
2147 | +++ tests/qmltests/Dash/tst_Dash.qml 2014-12-05 10:47:59 +0000 | |||
2148 | @@ -79,175 +79,108 @@ | |||
2149 | 79 | return get_scope_data() | 79 | return get_scope_data() |
2150 | 80 | } | 80 | } |
2151 | 81 | 81 | ||
2161 | 82 | function test_dash_overview_show_select_same_favorite() { | 82 | function test_manage_dash_select_same_favorite() { |
2162 | 83 | // Show the overview | 83 | // Show the manage dash |
2163 | 84 | touchFlick(dash, dash.width / 2, dash.height - 1, dash.width / 2, dash.height - units.gu(18)); | 84 | touchFlick(dash, dash.width / 2, dash.height - 1, dash.width / 2, units.gu(2)); |
2164 | 85 | var overviewController = findInvisibleChild(dash, "overviewController"); | 85 | var bottomEdgeController = findInvisibleChild(dash, "bottomEdgeController"); |
2165 | 86 | tryCompare(overviewController, "progress", 1); | 86 | tryCompare(bottomEdgeController, "progress", 1); |
2157 | 87 | |||
2158 | 88 | // Make sure tab is where it should | ||
2159 | 89 | var scopesOverview = findChild(dash, "scopesOverview"); | ||
2160 | 90 | compare(scopesOverview.currentTab, 0); | ||
2166 | 91 | 87 | ||
2167 | 92 | // Make sure stuff is loaded | 88 | // Make sure stuff is loaded |
2172 | 93 | var scopesOverviewFavoritesRepeater = findChild(dash, "scopesOverviewFavoritesRepeater"); | 89 | var favScopesListCategory = findChild(dash, "scopesListCategoryfavorites"); |
2173 | 94 | tryCompare(scopesOverviewFavoritesRepeater, "count", 6); | 90 | var favScopesListCategoryList = findChild(favScopesListCategory, "scopesListCategoryInnerList"); |
2174 | 95 | tryCompareFunction(function() { return scopesOverviewFavoritesRepeater.itemAt(0).item != null; }, true); | 91 | tryCompare(favScopesListCategoryList, "currentIndex", 0); |
2171 | 96 | waitForRendering(scopesOverviewFavoritesRepeater.itemAt(0).item); | ||
2175 | 97 | 92 | ||
2176 | 98 | // Click in first item | 93 | // Click in first item |
2178 | 99 | mouseClick(scopesOverviewFavoritesRepeater.itemAt(0).item, 0, 0); | 94 | mouseClick(favScopesListCategoryList.currentItem, 0, 0); |
2179 | 100 | 95 | ||
2180 | 101 | // Make sure animation went back | 96 | // Make sure animation went back |
2182 | 102 | tryCompare(overviewController, "progress", 0); | 97 | tryCompare(bottomEdgeController, "progress", 0); |
2183 | 103 | 98 | ||
2184 | 104 | var dashContentList = findChild(dash, "dashContentList"); | 99 | var dashContentList = findChild(dash, "dashContentList"); |
2185 | 105 | compare(dashContentList.currentIndex, 0); | 100 | compare(dashContentList.currentIndex, 0); |
2186 | 106 | } | 101 | } |
2187 | 107 | 102 | ||
2197 | 108 | function test_dash_overview_show_select_different_favorite() { | 103 | function test_manage_dash_select_different_favorite() { |
2198 | 109 | // Show the overview | 104 | // Show the manage dash |
2199 | 110 | touchFlick(dash, dash.width / 2, dash.height - 1, dash.width / 2, dash.height - units.gu(18)); | 105 | touchFlick(dash, dash.width / 2, dash.height - 1, dash.width / 2, units.gu(2)); |
2200 | 111 | var overviewController = findInvisibleChild(dash, "overviewController"); | 106 | var bottomEdgeController = findInvisibleChild(dash, "bottomEdgeController"); |
2201 | 112 | tryCompare(overviewController, "progress", 1); | 107 | tryCompare(bottomEdgeController, "progress", 1); |
2193 | 113 | |||
2194 | 114 | // Make sure tab is where it should | ||
2195 | 115 | var scopesOverview = findChild(dash, "scopesOverview"); | ||
2196 | 116 | compare(scopesOverview.currentTab, 0); | ||
2202 | 117 | 108 | ||
2203 | 118 | // Make sure stuff is loaded | 109 | // Make sure stuff is loaded |
2208 | 119 | var scopesOverviewFavoritesRepeater = findChild(dash, "scopesOverviewFavoritesRepeater"); | 110 | var favScopesListCategory = findChild(dash, "scopesListCategoryfavorites"); |
2209 | 120 | tryCompare(scopesOverviewFavoritesRepeater, "count", 6); | 111 | var favScopesListCategoryList = findChild(favScopesListCategory, "scopesListCategoryInnerList"); |
2210 | 121 | tryCompareFunction(function() { return scopesOverviewFavoritesRepeater.itemAt(0).item != null; }, true); | 112 | tryCompare(favScopesListCategoryList, "currentIndex", 0); |
2207 | 122 | waitForRendering(scopesOverviewFavoritesRepeater.itemAt(1).item); | ||
2211 | 123 | 113 | ||
2214 | 124 | // Click in first item | 114 | // Click in second item |
2215 | 125 | mouseClick(scopesOverviewFavoritesRepeater.itemAt(1).item, 0, 0); | 115 | favScopesListCategoryList.currentIndex = 1; |
2216 | 116 | mouseClick(favScopesListCategoryList.currentItem, 0, 0); | ||
2217 | 126 | 117 | ||
2218 | 127 | // Make sure animation went back | 118 | // Make sure animation went back |
2220 | 128 | tryCompare(overviewController, "progress", 0); | 119 | tryCompare(bottomEdgeController, "progress", 0); |
2221 | 129 | var dashContentList = findChild(dash, "dashContentList"); | 120 | var dashContentList = findChild(dash, "dashContentList"); |
2222 | 130 | compare(dashContentList.currentIndex, 1); | 121 | compare(dashContentList.currentIndex, 1); |
2223 | 131 | } | 122 | } |
2224 | 132 | 123 | ||
2234 | 133 | function test_dash_overview_all_temp_scope_done_from_all() { | 124 | function test_manage_dash_select_non_favorite() { |
2235 | 134 | // Show the overview | 125 | // Show the manage dash |
2236 | 135 | touchFlick(dash, dash.width / 2, dash.height - 1, dash.width / 2, dash.height - units.gu(18)); | 126 | touchFlick(dash, dash.width / 2, dash.height - 1, dash.width / 2, units.gu(2)); |
2237 | 136 | var overviewController = findInvisibleChild(dash, "overviewController"); | 127 | var bottomEdgeController = findInvisibleChild(dash, "bottomEdgeController"); |
2238 | 137 | tryCompare(overviewController, "progress", 1); | 128 | tryCompare(bottomEdgeController, "progress", 1); |
2230 | 138 | |||
2231 | 139 | // Make sure tab is where it should | ||
2232 | 140 | var scopesOverview = findChild(dash, "scopesOverview"); | ||
2233 | 141 | compare(scopesOverview.currentTab, 0); | ||
2239 | 142 | 129 | ||
2240 | 143 | // Make sure stuff is loaded | 130 | // Make sure stuff is loaded |
2267 | 144 | var scopesOverviewFavoritesRepeater = findChild(dash, "scopesOverviewFavoritesRepeater"); | 131 | var nonfavScopesListCategory = findChild(dash, "scopesListCategoryother"); |
2268 | 145 | tryCompare(scopesOverviewFavoritesRepeater, "count", 6); | 132 | var nonfavScopesListCategoryList = findChild(nonfavScopesListCategory, "scopesListCategoryInnerList"); |
2269 | 146 | tryCompareFunction(function() { return scopesOverviewFavoritesRepeater.itemAt(0).item != null; }, true); | 133 | tryCompare(nonfavScopesListCategoryList, "currentIndex", 0); |
2270 | 147 | waitForRendering(scopesOverviewFavoritesRepeater.itemAt(1).item); | 134 | |
2271 | 148 | 135 | // Click on a non favorite scope | |
2272 | 149 | // Click on the all tab | 136 | mouseClick(nonfavScopesListCategoryList.currentItem, 0, 0); |
2273 | 150 | var scopesOverviewAllTabButton = findChild(dash, "scopesOverviewAllTabButton"); | 137 | |
2274 | 151 | mouseClick(scopesOverviewAllTabButton, 0, 0); | 138 | // Check the bottom edge (manage dash) is disabled from temp scope |
2249 | 152 | |||
2250 | 153 | // Wait for all tab to be enabled (animation finish) | ||
2251 | 154 | var scopesOverviewAllView = findChild(dash, "scopesOverviewRepeaterChild1"); | ||
2252 | 155 | tryCompare(scopesOverviewAllView, "enabled", true); | ||
2253 | 156 | |||
2254 | 157 | // Click in the middle of the black bar (nothing happens) | ||
2255 | 158 | var bottomBar = findChild(scopesOverview, "bottomBar"); | ||
2256 | 159 | mouseClick(bottomBar, bottomBar.width / 2, bottomBar.height / 2); | ||
2257 | 160 | // Check temp scope is not there | ||
2258 | 161 | var scopesOverviewTempScopeItem = findChild(dash, "scopesOverviewTempScopeItem"); | ||
2259 | 162 | expectFailContinue("", "Clicking in the middle of bottom bar should not open a temp scope"); | ||
2260 | 163 | tryCompareFunction( function() { return scopesOverviewTempScopeItem.scope != null; }, true); | ||
2261 | 164 | |||
2262 | 165 | // Click on a temp scope | ||
2263 | 166 | var tempScopeCard = findChild(scopesOverviewAllView, "delegate1"); | ||
2264 | 167 | mouseClick(tempScopeCard, 0, 0); | ||
2265 | 168 | |||
2266 | 169 | // Check the bottom edge (overview) is disabled from temp scope | ||
2275 | 170 | var overviewDragHandle = findChild(dash, "overviewDragHandle"); | 139 | var overviewDragHandle = findChild(dash, "overviewDragHandle"); |
2276 | 171 | compare(overviewDragHandle.enabled, false); | 140 | compare(overviewDragHandle.enabled, false); |
2277 | 172 | 141 | ||
2278 | 173 | // Check temp scope is there | 142 | // Check temp scope is there |
2281 | 174 | tryCompareFunction( function() { return scopesOverviewTempScopeItem.scope != null; }, true); | 143 | var dashTempScopeItem = findChild(dash, "dashTempScopeItem"); |
2282 | 175 | tryCompare(scopesOverviewTempScopeItem, "enabled", true); | 144 | tryCompare(dashTempScopeItem, "x", 0); |
2283 | 145 | tryCompare(dashTempScopeItem, "visible", true); | ||
2284 | 146 | |||
2285 | 147 | // Check the manage dash is gone | ||
2286 | 148 | tryCompare(bottomEdgeController, "progress", 0); | ||
2287 | 176 | 149 | ||
2288 | 177 | // Go back | 150 | // Go back |
2291 | 178 | var scopesOverviewTempScopeItemHeader = findChild(scopesOverviewTempScopeItem, "scopePageHeader"); | 151 | var dashTempScopeItemHeader = findChild(dashTempScopeItem, "scopePageHeader"); |
2292 | 179 | var backButton = findChild(findChild(scopesOverviewTempScopeItemHeader, "innerPageHeader"), "backButton"); | 152 | var backButton = findChild(findChild(dashTempScopeItemHeader, "innerPageHeader"), "backButton"); |
2293 | 180 | mouseClick(backButton, 0, 0); | 153 | mouseClick(backButton, 0, 0); |
2294 | 181 | 154 | ||
2295 | 182 | // Check temp scope is gone | 155 | // Check temp scope is gone |
2306 | 183 | var scopesOverviewTempScopeItem = findChild(dash, "scopesOverviewTempScopeItem"); | 156 | tryCompare(dashTempScopeItem, "x", dash.width); |
2307 | 184 | tryCompareFunction( function() { return scopesOverviewTempScopeItem.scope == null; }, true); | 157 | tryCompare(dashTempScopeItem, "visible", false); |
2298 | 185 | tryCompare(scopesOverviewTempScopeItem, "enabled", false); | ||
2299 | 186 | |||
2300 | 187 | // Press on done | ||
2301 | 188 | var scopesOverviewDoneButton = findChild(scopesOverview, "scopesOverviewDoneButton"); | ||
2302 | 189 | mouseClick(scopesOverviewDoneButton, 0, 0); | ||
2303 | 190 | |||
2304 | 191 | // Check the dash overview is gone | ||
2305 | 192 | tryCompare(overviewController, "progress", 0); | ||
2308 | 193 | 158 | ||
2309 | 194 | // Original list is still on 0 | 159 | // Original list is still on 0 |
2310 | 195 | var dashContentList = findChild(dash, "dashContentList"); | 160 | var dashContentList = findChild(dash, "dashContentList"); |
2311 | 196 | compare(dashContentList.currentIndex, 0); | 161 | compare(dashContentList.currentIndex, 0); |
2312 | 197 | } | 162 | } |
2313 | 198 | 163 | ||
2345 | 199 | function test_temp_scope_dash_overview_all_search_temp_scope_favorite_from_all() { | 164 | function test_manage_dash_search_temp_scope() { |
2346 | 200 | // Swipe right to Apps scope | 165 | // Show the manage dash |
2347 | 201 | var dashContentList = findChild(dash, "dashContentList"); | 166 | touchFlick(dash, dash.width / 2, dash.height - 1, dash.width / 2, units.gu(2)); |
2348 | 202 | touchFlick(dash, dash.width - 1, units.gu(1), dash.width - units.gu(10), units.gu(1)); | 167 | var bottomEdgeController = findInvisibleChild(dash, "bottomEdgeController"); |
2349 | 203 | tryCompare(dashContentList, "contentX", dashContentList.width); | 168 | tryCompare(bottomEdgeController, "progress", 1); |
2319 | 204 | tryCompare(dashContentList, "currentIndex", 1); | ||
2320 | 205 | |||
2321 | 206 | // Click on card that opens temp scope | ||
2322 | 207 | var categoryListView = findChild(dashContentList.currentItem, "categoryListView"); | ||
2323 | 208 | var dashCategory2 = findChild(categoryListView, "dashCategory2"); | ||
2324 | 209 | tryCompareFunction(function() { | ||
2325 | 210 | if (dashCategory2.y < 200) return true; | ||
2326 | 211 | categoryListView.contentY += 100; | ||
2327 | 212 | return false; | ||
2328 | 213 | }, true); | ||
2329 | 214 | var card2 = findChild(dashCategory2, "delegate2"); | ||
2330 | 215 | waitForRendering(card2); | ||
2331 | 216 | mouseClick(card2, card2.width / 2, card2.height / 2); | ||
2332 | 217 | |||
2333 | 218 | // Wait for temp scope to be there | ||
2334 | 219 | var dashTempScopeItem = findChild(dash, "dashTempScopeItem"); | ||
2335 | 220 | tryCompare(dashTempScopeItem, "x", 0); | ||
2336 | 221 | |||
2337 | 222 | // Show the overview | ||
2338 | 223 | touchFlick(dash, dash.width / 2, dash.height - 1, dash.width / 2, dash.height - units.gu(18)); | ||
2339 | 224 | var overviewController = findInvisibleChild(dash, "overviewController"); | ||
2340 | 225 | tryCompare(overviewController, "progress", 1); | ||
2341 | 226 | |||
2342 | 227 | // Make sure tab is where it should | ||
2343 | 228 | var scopesOverview = findChild(dash, "scopesOverview"); | ||
2344 | 229 | compare(scopesOverview.currentTab, 1); | ||
2350 | 230 | 169 | ||
2351 | 231 | // Do a search | 170 | // Do a search |
2354 | 232 | var scopesOverviewPageHeader = findChild(scopesOverview, "scopesOverviewPageHeader"); | 171 | var scopesList = findChild(dash, "scopesList"); |
2355 | 233 | var searchButton = findChild(scopesOverviewPageHeader, "search_header_button"); | 172 | var scopesListPageHeader = findChild(scopesList, "pageHeader"); |
2356 | 173 | var searchButton = findChild(scopesListPageHeader, "search_header_button"); | ||
2357 | 234 | mouseClick(searchButton, 0, 0); | 174 | mouseClick(searchButton, 0, 0); |
2358 | 235 | 175 | ||
2359 | 236 | // Type something | 176 | // Type something |
2360 | 237 | keyClick(Qt.Key_H); | 177 | keyClick(Qt.Key_H); |
2361 | 238 | 178 | ||
2362 | 239 | // Check results grid is there and the other lists are not | ||
2363 | 240 | var searchResultsViewer = findChild(scopesOverview, "searchResultsViewer"); | ||
2364 | 241 | var scopesOverviewRepeater = findChild(dash, "scopesOverviewRepeater"); | ||
2365 | 242 | tryCompare(searchResultsViewer, "opacity", 1); | ||
2366 | 243 | tryCompare(scopesOverviewRepeater, "count", 0); | ||
2367 | 244 | |||
2368 | 245 | // Click on a temp scope in the search | 179 | // Click on a temp scope in the search |
2374 | 246 | tryCompareFunction( function() { | 180 | tryCompareFunction( function() { return findChild(scopesList, "scopesListCategorysearchA") != null; }, true); |
2375 | 247 | return findChild(findChild(searchResultsViewer, "dashCategorysearchA"), "delegate2") != null; | 181 | var dashCategorysearchA = findChild(scopesList, "scopesListCategorysearchA"); |
2376 | 248 | }, true); | 182 | tryCompareFunction( function() { return findChild(dashCategorysearchA, "delegate2") != null; }, true); |
2377 | 249 | var cardTempScope = findChild(findChild(searchResultsViewer, "dashCategorysearchA"), "delegate2"); | 183 | var cardTempScope = findChild(dashCategorysearchA, "delegate2"); |
2373 | 250 | verify(cardTempScope, "Could not find delegate2"); | ||
2378 | 251 | 184 | ||
2379 | 252 | waitForRendering(cardTempScope); | 185 | waitForRendering(cardTempScope); |
2380 | 253 | mouseClick(cardTempScope, cardTempScope.width / 2, cardTempScope.height / 2); | 186 | mouseClick(cardTempScope, cardTempScope.width / 2, cardTempScope.height / 2); |
2381 | @@ -257,29 +190,24 @@ | |||
2382 | 257 | compare(overviewDragHandle.enabled, false); | 190 | compare(overviewDragHandle.enabled, false); |
2383 | 258 | 191 | ||
2384 | 259 | // Check temp scope is there | 192 | // Check temp scope is there |
2388 | 260 | var scopesOverviewTempScopeItem = findChild(dash, "scopesOverviewTempScopeItem"); | 193 | var dashTempScopeItem = findChild(dash, "dashTempScopeItem"); |
2389 | 261 | tryCompareFunction( function() { return scopesOverviewTempScopeItem.scope != null; }, true); | 194 | tryCompare(dashTempScopeItem, "x", 0); |
2390 | 262 | tryCompare(scopesOverviewTempScopeItem, "enabled", true); | 195 | tryCompare(dashTempScopeItem, "visible", true); |
2391 | 196 | |||
2392 | 197 | // Check the manage dash is gone | ||
2393 | 198 | tryCompare(bottomEdgeController, "progress", 0); | ||
2394 | 263 | 199 | ||
2395 | 264 | // Go back | 200 | // Go back |
2398 | 265 | var scopesOverviewTempScopeItemHeader = findChild(scopesOverviewTempScopeItem, "scopePageHeader"); | 201 | var dashTempScopeItemHeader = findChild(dashTempScopeItem, "scopePageHeader"); |
2399 | 266 | var backButton = findChild(findChild(scopesOverviewTempScopeItemHeader, "innerPageHeader"), "backButton"); | 202 | var backButton = findChild(findChild(dashTempScopeItemHeader, "innerPageHeader"), "backButton"); |
2400 | 267 | mouseClick(backButton, 0, 0); | 203 | mouseClick(backButton, 0, 0); |
2401 | 268 | 204 | ||
2402 | 269 | // Check temp scope is gone | 205 | // Check temp scope is gone |
2416 | 270 | var scopesOverviewTempScopeItem = findChild(dash, "scopesOverviewTempScopeItem"); | 206 | tryCompare(dashTempScopeItem, "x", dash.width); |
2417 | 271 | tryCompareFunction( function() { return scopesOverviewTempScopeItem.scope == null; }, true); | 207 | tryCompare(dashTempScopeItem, "visible", false); |
2418 | 272 | tryCompare(scopesOverviewTempScopeItem, "enabled", false); | 208 | |
2419 | 273 | 209 | // Original list is still on 0 | |
2420 | 274 | // Press on a favorite | 210 | var dashContentList = findChild(dash, "dashContentList"); |
2408 | 275 | var dashCategorysearchB = findChild(searchResultsViewer, "dashCategorysearchB"); | ||
2409 | 276 | var cardFavSearch = findChild(dashCategorysearchB, "delegate3"); | ||
2410 | 277 | mouseClick(cardFavSearch, 0, 0); | ||
2411 | 278 | |||
2412 | 279 | // Check the dash overview is gone | ||
2413 | 280 | tryCompare(overviewController, "progress", 0); | ||
2414 | 281 | |||
2415 | 282 | // Original list went to the favorite | ||
2421 | 283 | compare(dashContentList.currentIndex, 0); | 211 | compare(dashContentList.currentIndex, 0); |
2422 | 284 | } | 212 | } |
2423 | 285 | 213 | ||
2424 | 286 | 214 | ||
2425 | === modified file 'tests/qmltests/Dash/tst_GenericScopeView.qml' | |||
2426 | --- tests/qmltests/Dash/tst_GenericScopeView.qml 2014-11-26 08:27:45 +0000 | |||
2427 | +++ tests/qmltests/Dash/tst_GenericScopeView.qml 2014-12-05 10:47:59 +0000 | |||
2428 | @@ -574,7 +574,6 @@ | |||
2429 | 574 | var innerHeader = findChild(header, "innerPageHeader"); | 574 | var innerHeader = findChild(header, "innerPageHeader"); |
2430 | 575 | verify(innerHeader, "Could not find the inner header"); | 575 | verify(innerHeader, "Could not find the inner header"); |
2431 | 576 | 576 | ||
2432 | 577 | expectFail("Apps", "Click scope should not have a favorite button"); | ||
2433 | 578 | var favoriteAction = findChild(innerHeader, "favorite_header_button"); | 577 | var favoriteAction = findChild(innerHeader, "favorite_header_button"); |
2434 | 579 | verify(favoriteAction, "Could not find the favorite action."); | 578 | verify(favoriteAction, "Could not find the favorite action."); |
2435 | 580 | mouseClick(favoriteAction, favoriteAction.width / 2, favoriteAction.height / 2); | 579 | mouseClick(favoriteAction, favoriteAction.width / 2, favoriteAction.height / 2); |
FAILED: Continuous integration, rev:1300 jenkins. qa.ubuntu. com/job/ unity8- ci/4519/ jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- utopic- touch/5587/ console jenkins. qa.ubuntu. com/job/ unity-phablet- qmluitests- utopic/ 1504 jenkins. qa.ubuntu. com/job/ unity8- utopic- amd64-ci/ 1613 jenkins. qa.ubuntu. com/job/ unity8- utopic- i386-ci/ 1613 jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- runner- mako/5280/ console jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- utopic- armhf/6839 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- utopic- armhf/6839/ artifact/ work/output/ *zip*/output. zip s-jenkins. ubuntu- ci:8080/ job/touch- flash-device/ 14257
http://
Executed test runs:
FAILURE: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/unity8- ci/4519/ rebuild
http://