Merge lp:~aacid/unity8/dash_overview into lp:unity8

Proposed by Albert Astals Cid
Status: Merged
Approved by: Nick Dedekind
Approved revision: 1172
Merged at revision: 1140
Proposed branch: lp:~aacid/unity8/dash_overview
Merge into: lp:unity8
Prerequisite: lp:~aacid/unity8/showSearchOnSearchQueryChange
Diff against target: 3423 lines (+2016/-244)
39 files modified
data/unity8-dash.conf (+1/-1)
plugins/Dash/CardCreator.js (+3/-2)
plugins/Dash/ScopeStyle.qml (+3/-2)
plugins/Dash/listviewwithpageheader.cpp (+10/-2)
plugins/Dash/listviewwithpageheader.h (+3/-0)
po/hu.po (+69/-33)
po/sl.po (+67/-31)
po/unity8.pot (+80/-44)
qml/Components/PageHeader.qml (+3/-1)
qml/Components/ResponsiveGridView.qml (+3/-3)
qml/Dash/CardCarousel.qml (+2/-2)
qml/Dash/CardGrid.qml (+13/-2)
qml/Dash/CardVerticalJournal.qml (+1/-1)
qml/Dash/Dash.qml (+171/-13)
qml/Dash/DashBackground.qml (+24/-0)
qml/Dash/DashContent.qml (+10/-4)
qml/Dash/DashRenderer.qml (+3/-1)
qml/Dash/GenericScopeView.qml (+86/-48)
qml/Dash/PreviewListView.qml (+1/-1)
qml/Dash/ScopesOverview.qml (+533/-0)
qml/Dash/ScopesOverviewAll.qml (+54/-0)
qml/Dash/ScopesOverviewFavorites.qml (+73/-0)
qml/Dash/ScopesOverviewTab.qml (+74/-0)
tests/autopilot/unity8/shell/tests/test_emulators.py (+1/-1)
tests/mocks/Unity/CMakeLists.txt (+1/-0)
tests/mocks/Unity/fake_resultsmodel.cpp (+2/-1)
tests/mocks/Unity/fake_scope.cpp (+17/-5)
tests/mocks/Unity/fake_scope.h (+6/-3)
tests/mocks/Unity/fake_scopes.cpp (+46/-7)
tests/mocks/Unity/fake_scopes.h (+8/-1)
tests/mocks/Unity/fake_scopesoverview.cpp (+281/-0)
tests/mocks/Unity/fake_scopesoverview.h (+104/-0)
tests/plugins/Dash/cardcreator/2.res (+2/-2)
tests/plugins/Dash/cardcreator/5.res (+8/-6)
tests/plugins/Dash/cardcreator/7.res (+4/-4)
tests/plugins/Dash/tst_ScopeStyle.qml (+1/-1)
tests/qmltests/Dash/tst_Dash.qml (+229/-7)
tests/qmltests/Dash/tst_DashContent.qml (+7/-6)
tests/qmltests/Dash/tst_GenericScopeView.qml (+12/-9)
To merge this branch: bzr merge lp:~aacid/unity8/dash_overview
Reviewer Review Type Date Requested Status
Michał Sawicz functional/design Approve
Nick Dedekind (community) Approve
PS Jenkins bot (community) continuous-integration Needs Fixing
Andrea Cimitan (community) Needs Fixing
Michal Hruby (community) Approve
Review via email: mp+228649@code.launchpad.net

This proposal supersedes a proposal from 2014-07-21.

Commit message

Dash Overview

Description of the change

* Are there any related MPs required for this MP to build/function as expected?
https://code.launchpad.net/~unity-team/unity-scopes-shell/overview/+merge/227745
Also we probably want to get the fix for https://bugs.launchpad.net/ubuntu/+source/qtdeclarative-opensource-src/+bug/1339828 AKA https://bugreports.qt-project.org/browse/QTBUG-40385

 * Did you perform an exploratory manual test run of your code change and any related functionality?
Yes, all via make tryDash right now since real scopes backend is not there yet

 * 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?
Still needs to happen

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

Some functional/visual feedback:

1. the initial delay before the scope starts following your finger is annoying, anything we could do about that?
2. I got into a state where the image for a scope was not cross-faded but replaced in one frame, ideas?

Screenshots in https://drive.google.com/open?id=0B32jwBcbaPloTm5uOXh5ZVdram8
vs. visuals in https://sites.google.com/a/canonical.com/unity8dash/scopes/dash-overview

1.png:
- no bottom edge hint

2.png:
- too small and not colourized search icon [fixed by UITK]
- Store and Done button are not visible enough (should be white?)
- overlays not coloured [lp:~aacid/unity8/implementOverlayColor]
- overlay corners don't line up (could be fixed by the above)
- wrong aspect ratio (should be 0.578947368, could we please find a better value?)
- not enough padding above/below buttons in the bottom bar
- not enough top padding in the overlay

3.png:
- bottom bar too translucent
- wrong images [ssserver]

4.png:
- mascot should be gone [ssserver]

5.png:
- background in Results should be gone [ssserver]
- translucent white bar as category separator [separate fix - needs new dividers]
- scopes in Recommendations have wrong card layout [ssserver]

review: Needs Fixing (functional/design)
lp:~aacid/unity8/dash_overview updated
1133. By Albert Astals Cid

Merge

1134. By Albert Astals Cid

Merge

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Albert Astals Cid (aacid) wrote :

> Some functional/visual feedback:
>
> 1. the initial delay before the scope starts following your finger is
> annoying, anything we could do about that?

I think it is there only in the phone because what i do of changing parents of stuff upsets the scenegraph, will try not to do that parent changing and see if it is faster

> 2. I got into a state where the image for a scope was not cross-faded but
> replaced in one frame, ideas?

Can reproduce it on startup for the first scope every time, will have a look.

lp:~aacid/unity8/dash_overview updated
1135. By Albert Astals Cid

Fix issue with the first time fading in to favorites not working

1136. By Albert Astals Cid

Use a ShaderEffectSource instead of changing Dash parent

Much faster rendering

Revision history for this message
Albert Astals Cid (aacid) wrote :

> > Some functional/visual feedback:
> >
> > 1. the initial delay before the scope starts following your finger is
> > annoying, anything we could do about that?
>
> I think it is there only in the phone because what i do of changing parents of
> stuff upsets the scenegraph, will try not to do that parent changing and see
> if it is faster
>
> > 2. I got into a state where the image for a scope was not cross-faded but
> > replaced in one frame, ideas?
>
> Can reproduce it on startup for the first scope every time, will have a look.

Both should be now fixed

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Nick Dedekind (nick-dedekind) wrote :

Comments inline. Still more coming...

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
lp:~aacid/unity8/dash_overview updated
1137. By Albert Astals Cid

Split into two lines

1138. By Albert Astals Cid

Some people have ridiculously narrow screens and make me lose vertical space

Revision history for this message
Albert Astals Cid (aacid) :
lp:~aacid/unity8/dash_overview updated
1139. By Albert Astals Cid

Make this totally harder to read by splitting in two lines as requested on the review

1140. By Albert Astals Cid

Add ;

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Michal Hruby (mhr3) wrote :

14 === modified file 'debian/control'

Missing bump to dep on unity-scopes-impl-3

review: Needs Fixing
lp:~aacid/unity8/dash_overview updated
1141. By Albert Astals Cid

Merge

Revision history for this message
Albert Astals Cid (aacid) wrote :

> 14 === modified file 'debian/control'
>
> Missing bump to dep on unity-scopes-impl-3

Fixed

lp:~aacid/unity8/dash_overview updated
1142. By Albert Astals Cid

require new scopes impl

Revision history for this message
Nick Dedekind (nick-dedekind) wrote :

More comments inline.

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
lp:~aacid/unity8/dash_overview updated
1143. By Albert Astals Cid

Small catches from review

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
lp:~aacid/unity8/dash_overview updated
1144. By Albert Astals Cid

Convert the overrides to functions as Nick suggested

Revision history for this message
Albert Astals Cid (aacid) wrote :

Fixed (except the pageheader one that i'm not sure there's anything to fix)

Revision history for this message
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, requirements in silo

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
lp:~aacid/unity8/dash_overview updated
1145. By Albert Astals Cid

Merge

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Michal Hruby (mhr3) wrote :

Looks good from my pov now.

review: Approve
lp:~aacid/unity8/dash_overview updated
1146. By Albert Astals Cid

Merge lp:~unity-team/unity8/dash-as-app

1147. By Albert Astals Cid

Merge lp:~canonical-platform-qa/unity8/dash-as-app-autopilot

1148. By Albert Astals Cid

Merge

1149. By Albert Astals Cid

pot_file

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
lp:~aacid/unity8/dash_overview updated
1150. By Albert Astals Cid

Don't remember why this is here, remove

1151. By Albert Astals Cid

Add an option for desktop_file_hint since the upstart file is using it

1152. By Albert Astals Cid

I did not want to remove this

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
lp:~aacid/unity8/dash_overview updated
1153. By Albert Astals Cid

We changed the formula

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
lp:~aacid/unity8/dash_overview updated
1154. By Albert Astals Cid

scopes scope is not there by default anymore so use another one

1155. By Albert Astals Cid

make sure the delegate is created (scroll to it)

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Michał Sawicz (saviq) wrote :

Based on silo 11:

> - no bottom edge hint

Still no edge hint, waiting for asset.

> - Store and Done button are not visible enough (should be white?)

Still not good.

> - overlays not coloured [lp:~aacid/unity8/implementOverlayColor]

They are now, but overlay text needs to be switched between light and dark depending on overlay colour.

> - overlay corners don't line up (could be fixed by the above)
> - not enough padding above/below buttons in the bottom bar
>
> - bottom bar too translucent
> - wrong images [ssserver]
>
> 4.png:
> - mascot should be gone [ssserver]

All that still applies.

> 5.png:
> - background in Results should be gone [ssserver]
> - translucent white bar as category separator [separate fix - needs new
> dividers]
> - scopes in Recommendations have wrong layout [ssserver]

As discussed on IRC, search is broken, can't test that.

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

Actually

> - overlay corners don't line up (could be fixed by the above)

doesn't seem to be a problem any more.

lp:~aacid/unity8/dash_overview updated
1156. By Albert Astals Cid

bottom bar should be non opaque and taller

1157. By Albert Astals Cid

set scope active when overview is open

1158. By Albert Astals Cid

search results viewer is always current

1159. By Albert Astals Cid

Merge

1160. By Albert Astals Cid

Merge

1161. By Albert Astals Cid

Merge

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
lp:~aacid/unity8/dash_overview updated
1162. By Albert Astals Cid

Make the goto store button work if store is a favorite

1163. By Albert Astals Cid

"fake" dash should not be visible if we have a temp scope

1164. By Albert Astals Cid

Use icon instead of own image

1165. By Albert Astals Cid

Dash overview handle

1166. By Albert Astals Cid

enable drag handle only if overviewDragHandle.enabled

1167. By Albert Astals Cid

Only use dashContent.pageHeaderTotallyVisible when there's no temp scope

1168. By Albert Astals Cid

overview handle: opacity because of header pos, y because of opening

1169. By Albert Astals Cid

More update

1170. By Albert Astals Cid

hook up the search indicator

1171. By Albert Astals Cid

hook up temp scope processing

1172. By Albert Astals Cid

unfocus++

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Andrea Cimitan (cimi) wrote :

0.1.16 tag present here..

review: Needs Fixing
Revision history for this message
Albert Astals Cid (aacid) wrote :

> 0.1.16 tag present here..

Yes, it's also in trunk.

Revision history for this message
Andrea Cimitan (cimi) wrote :

> > 0.1.16 tag present here..
>
> Yes, it's also in trunk.
It's Friday evening why are we here? :D

Btw I think the activity indicator should be dark in overview, and not with white box...

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Michał Sawicz (saviq) wrote :

> Btw I think the activity indicator should be dark in overview, and not with
> white box...

Yes, this is a problem in trunk as well. Needs some consideration on the solution, but we might need to wait until we put pages in dash on a stack.

Revision history for this message
Nick Dedekind (nick-dedekind) wrote :

I got the dash into a weird state where the search popup was showing but the keyboard wasn't, and it allowed me to pull up the dash overview when the search history was still showing.

Test Failure:
qmltestrunner.Dash::test_dash_overview_show_select_different_favorite

review: Needs Fixing
Revision history for this message
Nick Dedekind (nick-dedekind) wrote :

> I got the dash into a weird state where the search popup was showing but the
> keyboard wasn't, and it allowed me to pull up the dash overview when the
> search history was still showing.
>
>
> Test Failure:
> qmltestrunner.Dash::test_dash_overview_show_select_different_favorite

Ran tests locally. seems to be ok.

 * 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. Unrelated failure.

Revision history for this message
Nick Dedekind (nick-dedekind) :
review: Approve
Revision history for this message
Michał Sawicz (saviq) wrote :

All the functional/design issues were fixed. Thanks!

review: Approve (functional/design)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'data/unity8-dash.conf'
2--- data/unity8-dash.conf 2014-07-29 11:35:10 +0000
3+++ data/unity8-dash.conf 2014-08-08 15:11:52 +0000
4@@ -13,7 +13,7 @@
5 pre-start script
6 if [ -z "$UNITY_SCOPES_LIST" ]; then
7 # FIXME: remove once we have this in dconf
8- initctl set-env UNITY_SCOPES_LIST="scopes;clickscope;musicaggregator;videoaggregator"
9+ initctl set-env UNITY_SCOPES_LIST="clickscope;musicaggregator;videoaggregator"
10 fi
11
12 initctl emit scope-ui-starting
13
14=== modified file 'plugins/Dash/CardCreator.js'
15--- plugins/Dash/CardCreator.js 2014-08-06 19:39:39 +0000
16+++ plugins/Dash/CardCreator.js 2014-08-08 15:11:52 +0000
17@@ -108,6 +108,7 @@
18 sourceComponent: ShaderEffect { \n\
19 id: overlay; \n\
20 height: (fixedHeaderHeight > 0 ? fixedHeaderHeight : headerHeight) + units.gu(2); \n\
21+ property real luminance: 0.2126 * overlayColor.r + 0.7152 * overlayColor.g + 0.0722 * overlayColor.b; \n\
22 property color overlayColor: cardData && cardData["overlayColor"] || "#99000000"; \n\
23 property var source: ShaderEffectSource { \n\
24 id: shaderSource; \n\
25@@ -446,13 +447,13 @@
26 mascotCode = kMascotImageCode.arg(anchors).arg(mascotImageVisible);
27 }
28
29- var summaryColorWithBackground = 'backgroundLoader.active && backgroundLoader.item && backgroundLoader.item.luminance < 0.7 ? "white" : (root.scopeStyle ? root.scopeStyle.foreground : "grey")';
30+ var summaryColorWithBackground = 'backgroundLoader.active && backgroundLoader.item && backgroundLoader.item.luminance < (root.scopeStyle ? root.scopeStyle.threshold : 0.7) ? (root.scopeStyle ? root.scopeStyle.light : "white") : (root.scopeStyle ? root.scopeStyle.dark : "grey")';
31
32 var titleSubtitleCode = "";
33 if (hasTitle) {
34 var color;
35 if (headerAsOverlay) {
36- color = '"white"';
37+ color = 'overlayLoader.item.luminance < (root.scopeStyle ? root.scopeStyle.threshold : 0.7) ? (root.scopeStyle ? root.scopeStyle.light : "white") : (root.scopeStyle ? root.scopeStyle.dark : "grey")';
38 } else if (hasSummary) {
39 color = 'summary.color';
40 } else if (hasBackground) {
41
42=== modified file 'plugins/Dash/ScopeStyle.qml'
43--- plugins/Dash/ScopeStyle.qml 2014-07-25 11:42:06 +0000
44+++ plugins/Dash/ScopeStyle.qml 2014-08-08 15:11:52 +0000
45@@ -49,9 +49,10 @@
46
47 /*! \brief Luminance threshold for switching between fore and background color
48
49- \note If background colour is not fully opaque, it's not taken into account.
50+ \note If background colour is not fully opaque, the defaultLightLuminance it's taken into account instead of it.
51 */
52- readonly property real threshold: background.a !== 1.0 ? foregroundLuminance : (foregroundLuminance + backgroundLuminance) / 2
53+ readonly property real threshold: background.a !== 1.0 ? (foregroundLuminance + d.defaultLightLuminance) / 2
54+ : (foregroundLuminance + backgroundLuminance) / 2
55
56 /*! \brief The lighter of foreground and background colors
57
58
59=== modified file 'plugins/Dash/listviewwithpageheader.cpp'
60--- plugins/Dash/listviewwithpageheader.cpp 2014-07-25 10:47:08 +0000
61+++ plugins/Dash/listviewwithpageheader.cpp 2014-08-08 15:11:52 +0000
62@@ -330,6 +330,11 @@
63 return m_topSectionItem ? m_topSectionItem->height() : 0;
64 }
65
66+qreal ListViewWithPageHeader::headerItemShownHeight() const
67+{
68+ return m_headerItemShownHeight;
69+}
70+
71 void ListViewWithPageHeader::positionAtBeginning()
72 {
73 if (m_delegateModel->count() <= 0)
74@@ -396,6 +401,7 @@
75 firstItem->setY(firstItem->y() - m_headerItemShownHeight);
76 layout();
77 }
78+ Q_EMIT headerItemShownHeightChanged();
79 }
80 m_contentYAnimation->setTo(to);
81 contentYAnimationType = ContentYAnimationShowHeader;
82@@ -544,6 +550,7 @@
83 m_headerItem->setY(-m_minYExtent);
84 }
85 }
86+ Q_EMIT headerItemShownHeightChanged();
87 } else {
88 // Stick the header item to the top when dragging down
89 m_headerItem->setY(contentY());
90@@ -822,8 +829,8 @@
91 ListItem *nextItem = itemAtIndex(modelIndex + 1);
92 if (nextItem) {
93 listItem->setY(nextItem->y() - listItem->height());
94- } else if (modelIndex == 0 && m_headerItem) {
95- listItem->setY(m_headerItem->height());
96+ } else if (modelIndex == 0) {
97+ listItem->setY(m_headerItem ? m_headerItem->height() : 0);
98 } else if (!m_visibleItems.isEmpty()) {
99 lostItem = true;
100 }
101@@ -1096,6 +1103,7 @@
102 m_headerItemShownHeight = qBound(static_cast<qreal>(0.), m_headerItemShownHeight, newHeaderHeight);
103 updateClipItem();
104 adjustMinYExtent();
105+ Q_EMIT headerItemShownHeightChanged();
106 } else {
107 if (oldHeaderY + oldHeaderHeight > contentY()) {
108 // If the header is shown because its position
109
110=== modified file 'plugins/Dash/listviewwithpageheader.h'
111--- plugins/Dash/listviewwithpageheader.h 2014-06-12 14:08:54 +0000
112+++ plugins/Dash/listviewwithpageheader.h 2014-08-08 15:11:52 +0000
113@@ -53,6 +53,7 @@
114 Q_PROPERTY(QString sectionProperty READ sectionProperty WRITE setSectionProperty NOTIFY sectionPropertyChanged)
115 Q_PROPERTY(bool forceNoClip READ forceNoClip WRITE setForceNoClip NOTIFY forceNoClipChanged)
116 Q_PROPERTY(int stickyHeaderHeight READ stickyHeaderHeight NOTIFY stickyHeaderHeightChanged)
117+ Q_PROPERTY(qreal headerItemShownHeight READ headerItemShownHeight NOTIFY headerItemShownHeightChanged)
118
119 friend class ListViewWithPageHeaderTest;
120 friend class ListViewWithPageHeaderTestSection;
121@@ -81,6 +82,7 @@
122 void setForceNoClip(bool noClip);
123
124 int stickyHeaderHeight() const;
125+ qreal headerItemShownHeight() const;
126
127 Q_INVOKABLE void positionAtBeginning();
128 Q_INVOKABLE void showHeader();
129@@ -100,6 +102,7 @@
130 void sectionPropertyChanged();
131 void forceNoClipChanged();
132 void stickyHeaderHeightChanged();
133+ void headerItemShownHeightChanged();
134
135 protected:
136 void componentComplete() override;
137
138=== modified file 'po/hu.po'
139--- po/hu.po 2014-08-08 07:07:33 +0000
140+++ po/hu.po 2014-08-08 15:11:52 +0000
141@@ -6,11 +6,12 @@
142 msgid ""
143 msgstr ""
144 "Project-Id-Version: unity\n"
145-"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
146-"POT-Creation-Date: 2014-07-11 14:59+0200\n"
147+"Report-Msgid-Bugs-To: \n"
148+"POT-Creation-Date: 2014-08-05 19:54+0200\n"
149 "PO-Revision-Date: 2014-08-06 07:41+0000\n"
150 "Last-Translator: Richard Somlói <ricsipontaz@gmail.com>\n"
151 "Language-Team: Hungarian <hu@li.org>\n"
152+"Language: hu\n"
153 "MIME-Version: 1.0\n"
154 "Content-Type: text/plain; charset=UTF-8\n"
155 "Content-Transfer-Encoding: 8bit\n"
156@@ -26,70 +27,86 @@
157 msgid "Unpin shortcut"
158 msgstr "Indító feloldása"
159
160+#: qml/Components/Dialogs.qml:142
161+msgid "Are you sure you would like to turn power off?"
162+msgstr ""
163+
164+#: qml/Components/Dialogs.qml:144
165+msgid "Power off"
166+msgstr ""
167+
168+#: qml/Components/Dialogs.qml:153
169+msgid "Restart"
170+msgstr ""
171+
172+#: qml/Components/Dialogs.qml:162
173+msgid "Cancel"
174+msgstr ""
175+
176 #: qml/Components/EdgeDemoOverlay.qml:151
177 msgid "Skip intro"
178 msgstr "A bemutató kihagyása"
179
180-#: qml/Components/EdgeDemo.qml:113
181+#: qml/Components/EdgeDemo.qml:112
182 msgid "Right edge"
183 msgstr "Jobb szél"
184
185-#: qml/Components/EdgeDemo.qml:114
186+#: qml/Components/EdgeDemo.qml:113
187 msgid "Try swiping from the right edge to unlock the phone"
188 msgstr "A telefon feloldásához csúsztassa ujját a jobb szélről"
189
190-#: qml/Components/EdgeDemo.qml:145
191+#: qml/Components/EdgeDemo.qml:144
192 msgid "Top edge"
193 msgstr "Felső szél"
194
195-#: qml/Components/EdgeDemo.qml:146
196+#: qml/Components/EdgeDemo.qml:145
197 msgid "Try swiping from the top edge to access the indicators"
198 msgstr "Az állapotmenük eléréséhez csúsztassa ujját a felső szélről"
199
200-#: qml/Components/EdgeDemo.qml:171
201+#: qml/Components/EdgeDemo.qml:170
202 msgid "Close"
203 msgstr "Bezárás"
204
205-#: qml/Components/EdgeDemo.qml:172
206+#: qml/Components/EdgeDemo.qml:171
207 msgid "Swipe up again to close the settings screen"
208 msgstr "A beállítások bezárásához csúsztassa ujját újra felfelé"
209
210-#: qml/Components/EdgeDemo.qml:199
211+#: qml/Components/EdgeDemo.qml:198
212 msgid "Left edge"
213 msgstr "Bal szél"
214
215-#: qml/Components/EdgeDemo.qml:200
216+#: qml/Components/EdgeDemo.qml:199
217 msgid "Swipe from the left to reveal the launcher for quick access to apps"
218 msgstr ""
219 "Csúsztassa ujját a bal szélről az indítón található alkalmazások gyors "
220 "eléréséhez"
221
222-#: qml/Components/EdgeDemo.qml:227
223+#: qml/Components/EdgeDemo.qml:226
224 msgid "Well done"
225 msgstr "Rendben"
226
227-#: qml/Components/EdgeDemo.qml:228
228+#: qml/Components/EdgeDemo.qml:227
229 msgid ""
230 "You have now mastered the edge gestures and can start using the "
231 "phone<br><br>Tap on the screen to start"
232 msgstr ""
233-"Elsajátította a gesztusokat, és megkezdheti a telefon "
234-"használatát.<br><br>Koppintson a képernyőre a kezdéshez."
235+"Elsajátította a gesztusokat, és megkezdheti a telefon használatát."
236+"<br><br>Koppintson a képernyőre a kezdéshez."
237
238-#: qml/Components/Lockscreen.qml:214
239+#: qml/Components/Lockscreen.qml:220
240 msgid "Emergency Call"
241 msgstr "Vészhívás"
242
243-#: qml/Components/Lockscreen.qml:231
244+#: qml/Components/Lockscreen.qml:243
245 msgid "OK"
246 msgstr "Ok"
247
248-#: qml/Components/PassphraseLockscreen.qml:60
249+#: qml/Components/PassphraseLockscreen.qml:62
250 #, qt-format
251 msgid "Hello %1"
252 msgstr "Üdv %1"
253
254-#: qml/Components/PassphraseLockscreen.qml:60
255+#: qml/Components/PassphraseLockscreen.qml:62
256 msgid "Hello"
257 msgstr "Üdvözöljük"
258
259@@ -105,15 +122,11 @@
260 msgid "See more"
261 msgstr "Több"
262
263-#: qml/Components/SeeMore.qml:58 qml/Dash/GenericScopeView.qml:330
264+#: qml/Components/SeeMore.qml:58 qml/Dash/GenericScopeView.qml:354
265 msgid "See less"
266 msgstr "Kevesebb"
267
268-#: qml/Dash/DashApps.qml:37
269-msgid "Recent"
270-msgstr "Legutóbbi"
271-
272-#: qml/Dash/GenericScopeView.qml:330
273+#: qml/Dash/GenericScopeView.qml:354
274 msgid "See all"
275 msgstr "Összes megtekintése"
276
277@@ -137,6 +150,26 @@
278 msgid "Send"
279 msgstr "Küldés"
280
281+#: qml/Dash/ScopesOverview.qml:187
282+msgid "Manage Dash"
283+msgstr ""
284+
285+#: qml/Dash/ScopesOverview.qml:392
286+msgid "Done"
287+msgstr ""
288+
289+#: qml/Dash/ScopesOverview.qml:418
290+msgid "Store"
291+msgstr ""
292+
293+#: qml/Dash/ScopesOverviewTab.qml:36
294+msgid "Favorites"
295+msgstr ""
296+
297+#: qml/Dash/ScopesOverviewTab.qml:54
298+msgid "All"
299+msgstr ""
300+
301 #: qml/Greeter/Greeter.qml:157
302 msgid "Swipe to unlock"
303 msgstr "Csúsztasson a feloldáshoz"
304@@ -161,11 +194,11 @@
305 msgid "Speaking..."
306 msgstr "Beszéd…"
307
308-#: qml/Notifications/NotificationMenuItemFactory.qml:91
309+#: qml/Notifications/NotificationMenuItemFactory.qml:97
310 msgid "Show password"
311 msgstr "Jelszó megjelenítése"
312
313-#: qml/Notifications/NotificationMenuItemFactory.qml:103
314+#: qml/Notifications/NotificationMenuItemFactory.qml:112
315 msgid "Please enter SIM PIN"
316 msgstr "Adja meg a SIM PIN kódját"
317
318@@ -177,27 +210,27 @@
319 msgid "Conference"
320 msgstr "Konferencia"
321
322-#: qml/Panel/Indicators/MenuItemFactory.qml:583
323+#: qml/Panel/Indicators/MenuItemFactory.qml:577
324 msgid "In queue…"
325 msgstr "Sorban…"
326
327-#: qml/Panel/Indicators/MenuItemFactory.qml:587
328+#: qml/Panel/Indicators/MenuItemFactory.qml:581
329 msgid "Downloading"
330 msgstr "Letöltés"
331
332-#: qml/Panel/Indicators/MenuItemFactory.qml:589
333+#: qml/Panel/Indicators/MenuItemFactory.qml:583
334 msgid "Paused, tap to resume"
335 msgstr "Szüneteltetve, koppintson a folytatáshoz"
336
337-#: qml/Panel/Indicators/MenuItemFactory.qml:591
338+#: qml/Panel/Indicators/MenuItemFactory.qml:585
339 msgid "Canceled"
340 msgstr "Megszakítva"
341
342-#: qml/Panel/Indicators/MenuItemFactory.qml:593
343+#: qml/Panel/Indicators/MenuItemFactory.qml:587
344 msgid "Finished"
345 msgstr "Befejeződött"
346
347-#: qml/Panel/Indicators/MenuItemFactory.qml:595
348+#: qml/Panel/Indicators/MenuItemFactory.qml:589
349 msgid "Failed, tap to retry"
350 msgstr "Sikertelen, koppintson az újrapróbáláshoz"
351
352@@ -205,7 +238,10 @@
353 msgid "Search"
354 msgstr "Keresés"
355
356-#: qml/Shell.qml:359
357+#: qml/Shell.qml:256
358 #, qt-format
359 msgid "Please enter %1"
360 msgstr "Adja meg a következőt: %1"
361+
362+#~ msgid "Recent"
363+#~ msgstr "Legutóbbi"
364
365=== modified file 'po/sl.po'
366--- po/sl.po 2014-08-08 07:07:33 +0000
367+++ po/sl.po 2014-08-08 15:11:52 +0000
368@@ -6,11 +6,12 @@
369 msgid ""
370 msgstr ""
371 "Project-Id-Version: unity\n"
372-"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
373-"POT-Creation-Date: 2014-07-11 14:59+0200\n"
374+"Report-Msgid-Bugs-To: \n"
375+"POT-Creation-Date: 2014-08-05 19:54+0200\n"
376 "PO-Revision-Date: 2014-08-06 06:11+0000\n"
377 "Last-Translator: Damir Jerovšek <Unknown>\n"
378 "Language-Team: Slovenian <sl@li.org>\n"
379+"Language: sl\n"
380 "MIME-Version: 1.0\n"
381 "Content-Type: text/plain; charset=UTF-8\n"
382 "Content-Transfer-Encoding: 8bit\n"
383@@ -26,49 +27,65 @@
384 msgid "Unpin shortcut"
385 msgstr "Odpni bližnjico"
386
387+#: qml/Components/Dialogs.qml:142
388+msgid "Are you sure you would like to turn power off?"
389+msgstr ""
390+
391+#: qml/Components/Dialogs.qml:144
392+msgid "Power off"
393+msgstr ""
394+
395+#: qml/Components/Dialogs.qml:153
396+msgid "Restart"
397+msgstr ""
398+
399+#: qml/Components/Dialogs.qml:162
400+msgid "Cancel"
401+msgstr ""
402+
403 #: qml/Components/EdgeDemoOverlay.qml:151
404 msgid "Skip intro"
405 msgstr "Preskoči uvod"
406
407-#: qml/Components/EdgeDemo.qml:113
408+#: qml/Components/EdgeDemo.qml:112
409 msgid "Right edge"
410 msgstr "Desni rob"
411
412-#: qml/Components/EdgeDemo.qml:114
413+#: qml/Components/EdgeDemo.qml:113
414 msgid "Try swiping from the right edge to unlock the phone"
415 msgstr "Poskusite povleči od desnega roba za odklep telefona"
416
417-#: qml/Components/EdgeDemo.qml:145
418+#: qml/Components/EdgeDemo.qml:144
419 msgid "Top edge"
420 msgstr "Zgornji rob"
421
422-#: qml/Components/EdgeDemo.qml:146
423+#: qml/Components/EdgeDemo.qml:145
424 msgid "Try swiping from the top edge to access the indicators"
425 msgstr "Poskusite povleči od zgornjega roba za dostop do kazalnikov"
426
427-#: qml/Components/EdgeDemo.qml:171
428+#: qml/Components/EdgeDemo.qml:170
429 msgid "Close"
430 msgstr "Zapri"
431
432-#: qml/Components/EdgeDemo.qml:172
433+#: qml/Components/EdgeDemo.qml:171
434 msgid "Swipe up again to close the settings screen"
435 msgstr "Povlecite ponovno navzgor za zaprtje zaslona z nastavitvami"
436
437-#: qml/Components/EdgeDemo.qml:199
438+#: qml/Components/EdgeDemo.qml:198
439 msgid "Left edge"
440 msgstr "Levi rob"
441
442-#: qml/Components/EdgeDemo.qml:200
443+#: qml/Components/EdgeDemo.qml:199
444 msgid "Swipe from the left to reveal the launcher for quick access to apps"
445 msgstr ""
446 "Poskusite povleči od leve za razkritje zaganjalnika za hiter dostop do "
447 "programov"
448
449-#: qml/Components/EdgeDemo.qml:227
450+#: qml/Components/EdgeDemo.qml:226
451 msgid "Well done"
452 msgstr "Odlično"
453
454-#: qml/Components/EdgeDemo.qml:228
455+#: qml/Components/EdgeDemo.qml:227
456 msgid ""
457 "You have now mastered the edge gestures and can start using the "
458 "phone<br><br>Tap on the screen to start"
459@@ -76,20 +93,20 @@
460 "Sedaj, ko ste osvojili poteze robov, lahko začnete uporabljati "
461 "telefon<br><br>Tapnite na zaslon za začetek"
462
463-#: qml/Components/Lockscreen.qml:214
464+#: qml/Components/Lockscreen.qml:220
465 msgid "Emergency Call"
466 msgstr "Klic v sili"
467
468-#: qml/Components/Lockscreen.qml:231
469+#: qml/Components/Lockscreen.qml:243
470 msgid "OK"
471 msgstr "V REDU"
472
473-#: qml/Components/PassphraseLockscreen.qml:60
474+#: qml/Components/PassphraseLockscreen.qml:62
475 #, qt-format
476 msgid "Hello %1"
477 msgstr "Pozdravljeni, %1"
478
479-#: qml/Components/PassphraseLockscreen.qml:60
480+#: qml/Components/PassphraseLockscreen.qml:62
481 msgid "Hello"
482 msgstr "Pozdravljeni"
483
484@@ -105,15 +122,11 @@
485 msgid "See more"
486 msgstr "Pokaži več"
487
488-#: qml/Components/SeeMore.qml:58 qml/Dash/GenericScopeView.qml:330
489+#: qml/Components/SeeMore.qml:58 qml/Dash/GenericScopeView.qml:354
490 msgid "See less"
491 msgstr "Pokaži manj"
492
493-#: qml/Dash/DashApps.qml:37
494-msgid "Recent"
495-msgstr "Nedavno"
496-
497-#: qml/Dash/GenericScopeView.qml:330
498+#: qml/Dash/GenericScopeView.qml:354
499 msgid "See all"
500 msgstr "Ogled vsega"
501
502@@ -137,6 +150,26 @@
503 msgid "Send"
504 msgstr "Pošlji"
505
506+#: qml/Dash/ScopesOverview.qml:187
507+msgid "Manage Dash"
508+msgstr ""
509+
510+#: qml/Dash/ScopesOverview.qml:392
511+msgid "Done"
512+msgstr ""
513+
514+#: qml/Dash/ScopesOverview.qml:418
515+msgid "Store"
516+msgstr ""
517+
518+#: qml/Dash/ScopesOverviewTab.qml:36
519+msgid "Favorites"
520+msgstr ""
521+
522+#: qml/Dash/ScopesOverviewTab.qml:54
523+msgid "All"
524+msgstr ""
525+
526 #: qml/Greeter/Greeter.qml:157
527 msgid "Swipe to unlock"
528 msgstr "Podrsajte za odklenitev"
529@@ -161,11 +194,11 @@
530 msgid "Speaking..."
531 msgstr "Govorjenje ..."
532
533-#: qml/Notifications/NotificationMenuItemFactory.qml:91
534+#: qml/Notifications/NotificationMenuItemFactory.qml:97
535 msgid "Show password"
536 msgstr "Pokaži geslo"
537
538-#: qml/Notifications/NotificationMenuItemFactory.qml:103
539+#: qml/Notifications/NotificationMenuItemFactory.qml:112
540 msgid "Please enter SIM PIN"
541 msgstr "Vnesite PIN kartice SIM"
542
543@@ -177,27 +210,27 @@
544 msgid "Conference"
545 msgstr "Konferenca"
546
547-#: qml/Panel/Indicators/MenuItemFactory.qml:583
548+#: qml/Panel/Indicators/MenuItemFactory.qml:577
549 msgid "In queue…"
550 msgstr "V vrsti ..."
551
552-#: qml/Panel/Indicators/MenuItemFactory.qml:587
553+#: qml/Panel/Indicators/MenuItemFactory.qml:581
554 msgid "Downloading"
555 msgstr "Prejemanje"
556
557-#: qml/Panel/Indicators/MenuItemFactory.qml:589
558+#: qml/Panel/Indicators/MenuItemFactory.qml:583
559 msgid "Paused, tap to resume"
560 msgstr "Premor, tapnite za nadaljevanje"
561
562-#: qml/Panel/Indicators/MenuItemFactory.qml:591
563+#: qml/Panel/Indicators/MenuItemFactory.qml:585
564 msgid "Canceled"
565 msgstr "Preklicano"
566
567-#: qml/Panel/Indicators/MenuItemFactory.qml:593
568+#: qml/Panel/Indicators/MenuItemFactory.qml:587
569 msgid "Finished"
570 msgstr "Končano"
571
572-#: qml/Panel/Indicators/MenuItemFactory.qml:595
573+#: qml/Panel/Indicators/MenuItemFactory.qml:589
574 msgid "Failed, tap to retry"
575 msgstr "Spodletelo, tapnite za ponovni poskus"
576
577@@ -205,7 +238,10 @@
578 msgid "Search"
579 msgstr "Iskanje"
580
581-#: qml/Shell.qml:359
582+#: qml/Shell.qml:256
583 #, qt-format
584 msgid "Please enter %1"
585 msgstr "Vnesite %1"
586+
587+#~ msgid "Recent"
588+#~ msgstr "Nedavno"
589
590=== modified file 'po/unity8.pot'
591--- po/unity8.pot 2014-07-11 14:20:12 +0000
592+++ po/unity8.pot 2014-08-08 15:11:52 +0000
593@@ -8,7 +8,7 @@
594 msgstr ""
595 "Project-Id-Version: unity8\n"
596 "Report-Msgid-Bugs-To: \n"
597-"POT-Creation-Date: 2014-07-11 14:59+0200\n"
598+"POT-Creation-Date: 2014-08-08 11:17+0200\n"
599 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
600 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
601 "Language-Team: LANGUAGE <LL@li.org>\n"
602@@ -26,66 +26,82 @@
603 msgid "Unpin shortcut"
604 msgstr ""
605
606+#: qml/Components/Dialogs.qml:142
607+msgid "Are you sure you would like to turn power off?"
608+msgstr ""
609+
610+#: qml/Components/Dialogs.qml:144
611+msgid "Power off"
612+msgstr ""
613+
614+#: qml/Components/Dialogs.qml:153
615+msgid "Restart"
616+msgstr ""
617+
618+#: qml/Components/Dialogs.qml:162
619+msgid "Cancel"
620+msgstr ""
621+
622 #: qml/Components/EdgeDemoOverlay.qml:151
623 msgid "Skip intro"
624 msgstr ""
625
626+#: qml/Components/EdgeDemo.qml:112
627+msgid "Right edge"
628+msgstr ""
629+
630 #: qml/Components/EdgeDemo.qml:113
631-msgid "Right edge"
632-msgstr ""
633-
634-#: qml/Components/EdgeDemo.qml:114
635 msgid "Try swiping from the right edge to unlock the phone"
636 msgstr ""
637
638+#: qml/Components/EdgeDemo.qml:144
639+msgid "Top edge"
640+msgstr ""
641+
642 #: qml/Components/EdgeDemo.qml:145
643-msgid "Top edge"
644-msgstr ""
645-
646-#: qml/Components/EdgeDemo.qml:146
647 msgid "Try swiping from the top edge to access the indicators"
648 msgstr ""
649
650+#: qml/Components/EdgeDemo.qml:170
651+msgid "Close"
652+msgstr ""
653+
654 #: qml/Components/EdgeDemo.qml:171
655-msgid "Close"
656-msgstr ""
657-
658-#: qml/Components/EdgeDemo.qml:172
659 msgid "Swipe up again to close the settings screen"
660 msgstr ""
661
662+#: qml/Components/EdgeDemo.qml:198
663+msgid "Left edge"
664+msgstr ""
665+
666 #: qml/Components/EdgeDemo.qml:199
667-msgid "Left edge"
668-msgstr ""
669-
670-#: qml/Components/EdgeDemo.qml:200
671 msgid "Swipe from the left to reveal the launcher for quick access to apps"
672 msgstr ""
673
674+#: qml/Components/EdgeDemo.qml:226
675+msgid "Well done"
676+msgstr ""
677+
678 #: qml/Components/EdgeDemo.qml:227
679-msgid "Well done"
680-msgstr ""
681-
682-#: qml/Components/EdgeDemo.qml:228
683 msgid ""
684 "You have now mastered the edge gestures and can start using the "
685 "phone<br><br>Tap on the screen to start"
686 msgstr ""
687
688-#: qml/Components/Lockscreen.qml:214
689+#: qml/Components/Lockscreen.qml:220
690 msgid "Emergency Call"
691 msgstr ""
692
693-#: qml/Components/Lockscreen.qml:231
694+#: qml/Components/Lockscreen.qml:243
695 msgid "OK"
696 msgstr ""
697
698-#: qml/Components/PassphraseLockscreen.qml:60
699+#: qml/Components/PassphraseLockscreen.qml:62
700 #, qt-format
701 msgid "Hello %1"
702 msgstr ""
703
704-#: qml/Components/PassphraseLockscreen.qml:60
705+#: qml/Components/PassphraseLockscreen.qml:62
706 msgid "Hello"
707 msgstr ""
708
709@@ -97,19 +113,11 @@
710 msgid "DONE"
711 msgstr ""
712
713-#: qml/Components/SeeMore.qml:35
714-msgid "See more"
715-msgstr ""
716-
717-#: qml/Components/SeeMore.qml:58 qml/Dash/GenericScopeView.qml:330
718+#: qml/Dash/GenericScopeView.qml:358
719 msgid "See less"
720 msgstr ""
721
722-#: qml/Dash/DashApps.qml:37
723-msgid "Recent"
724-msgstr ""
725-
726-#: qml/Dash/GenericScopeView.qml:330
727+#: qml/Dash/GenericScopeView.qml:358
728 msgid "See all"
729 msgstr ""
730
731@@ -133,6 +141,26 @@
732 msgid "Send"
733 msgstr ""
734
735+#: qml/Dash/ScopesOverview.qml:200
736+msgid "Manage Dash"
737+msgstr ""
738+
739+#: qml/Dash/ScopesOverview.qml:405
740+msgid "Done"
741+msgstr ""
742+
743+#: qml/Dash/ScopesOverview.qml:431
744+msgid "Store"
745+msgstr ""
746+
747+#: qml/Dash/ScopesOverviewTab.qml:36
748+msgid "Favorites"
749+msgstr ""
750+
751+#: qml/Dash/ScopesOverviewTab.qml:54
752+msgid "All"
753+msgstr ""
754+
755 #: qml/Greeter/Greeter.qml:157
756 msgid "Swipe to unlock"
757 msgstr ""
758@@ -157,11 +185,11 @@
759 msgid "Speaking..."
760 msgstr ""
761
762-#: qml/Notifications/NotificationMenuItemFactory.qml:91
763+#: qml/Notifications/NotificationMenuItemFactory.qml:100
764 msgid "Show password"
765 msgstr ""
766
767-#: qml/Notifications/NotificationMenuItemFactory.qml:103
768+#: qml/Notifications/NotificationMenuItemFactory.qml:115
769 msgid "Please enter SIM PIN"
770 msgstr ""
771
772@@ -173,35 +201,43 @@
773 msgid "Conference"
774 msgstr ""
775
776-#: qml/Panel/Indicators/MenuItemFactory.qml:583
777+#: qml/Panel/Indicators/MenuItemFactory.qml:651
778 msgid "In queue…"
779 msgstr ""
780
781-#: qml/Panel/Indicators/MenuItemFactory.qml:587
782+#: qml/Panel/Indicators/MenuItemFactory.qml:655
783 msgid "Downloading"
784 msgstr ""
785
786-#: qml/Panel/Indicators/MenuItemFactory.qml:589
787+#: qml/Panel/Indicators/MenuItemFactory.qml:657
788 msgid "Paused, tap to resume"
789 msgstr ""
790
791-#: qml/Panel/Indicators/MenuItemFactory.qml:591
792+#: qml/Panel/Indicators/MenuItemFactory.qml:659
793 msgid "Canceled"
794 msgstr ""
795
796-#: qml/Panel/Indicators/MenuItemFactory.qml:593
797+#: qml/Panel/Indicators/MenuItemFactory.qml:661
798 msgid "Finished"
799 msgstr ""
800
801-#: qml/Panel/Indicators/MenuItemFactory.qml:595
802+#: qml/Panel/Indicators/MenuItemFactory.qml:663
803 msgid "Failed, tap to retry"
804 msgstr ""
805
806+#: qml/Panel/Indicators/ModemInfoItem.qml:105
807+msgid "Unlock SIM"
808+msgstr ""
809+
810+#: qml/Panel/Indicators/RoamingIndication.qml:27
811+msgid "Roaming"
812+msgstr ""
813+
814 #: qml/Panel/SearchIndicator.qml:27
815 msgid "Search"
816 msgstr ""
817
818-#: qml/Shell.qml:359
819+#: qml/Shell.qml:256
820 #, qt-format
821 msgid "Please enter %1"
822 msgstr ""
823
824=== modified file 'qml/Components/PageHeader.qml'
825--- qml/Components/PageHeader.qml 2014-08-06 19:39:30 +0000
826+++ qml/Components/PageHeader.qml 2014-08-08 15:11:52 +0000
827@@ -24,7 +24,7 @@
828 Item {
829 id: root
830 objectName: "pageHeader"
831- implicitHeight: headerContainer.height + units.gu(2) + bottomContainer.height
832+ implicitHeight: headerContainer.height + bottomContainer.height + (showSignatureLine ? units.gu(2) : 0)
833
834 property bool showBackButton: false
835 property string title
836@@ -32,6 +32,7 @@
837 property bool searchEntryEnabled: false
838 property ListModel searchHistory: SearchHistoryModel
839 property alias searchQuery: searchTextField.text
840+ property alias showSignatureLine: bottomBorder.visible
841
842 property alias bottomItem: bottomContainer.children
843 property int paginationCount: 0
844@@ -251,6 +252,7 @@
845
846 actions: [
847 Action {
848+ objectName: "search"
849 iconName: "search"
850 visible: root.searchEntryEnabled
851 onTriggered: {
852
853=== modified file 'qml/Components/ResponsiveGridView.qml'
854--- qml/Components/ResponsiveGridView.qml 2014-07-11 12:12:50 +0000
855+++ qml/Components/ResponsiveGridView.qml 2014-08-08 15:11:52 +0000
856@@ -34,7 +34,7 @@
857 readonly property int cellWidth: gridView.cellWidth
858 readonly property int cellHeight: gridView.cellHeight
859 readonly property int totalContentHeight: {
860- return contentHeightForRows(Math.ceil(gridView.model.count / columns))
861+ return contentHeightForRows(Math.ceil(gridView.model.count / columns), cellHeight)
862 }
863 property alias interactive: gridView.interactive
864 readonly property alias flicking: gridView.flicking
865@@ -47,8 +47,8 @@
866 property alias cacheBuffer: gridView.cacheBuffer
867 readonly property alias currentItem: gridView.currentItem
868
869- function contentHeightForRows(rows) {
870- return rows * cellHeight;
871+ function contentHeightForRows(rows, height) {
872+ return rows * height
873 }
874
875 GridView {
876
877=== removed directory 'qml/Dash/Apps'
878=== modified file 'qml/Dash/CardCarousel.qml'
879--- qml/Dash/CardCarousel.qml 2014-07-11 12:13:08 +0000
880+++ qml/Dash/CardCarousel.qml 2014-08-08 15:11:52 +0000
881@@ -48,8 +48,8 @@
882
883 objectName: "carouselDelegate" + index
884
885- function clicked() { cardCarousel.clicked(index, model.result) }
886- function pressAndHold() { cardCarousel.pressAndHold(index, model.result) }
887+ function clicked() { cardCarousel.clicked(index, model.result, loader.item, model) }
888+ function pressAndHold() { cardCarousel.pressAndHold(index) }
889
890 sourceComponent: cardTool.cardComponent
891 onLoaded: {
892
893=== modified file 'qml/Dash/CardGrid.qml'
894--- qml/Dash/CardGrid.qml 2014-07-18 11:35:47 +0000
895+++ qml/Dash/CardGrid.qml 2014-08-08 15:11:52 +0000
896@@ -26,10 +26,20 @@
897 }
898
899 expandedHeight: grid.totalContentHeight
900- collapsedHeight: Math.min(grid.contentHeightForRows(collapsedRows), expandedHeight)
901+ collapsedHeight: Math.min(grid.contentHeightForRows(collapsedRows, grid.cellHeight), expandedHeight)
902 collapsedItemCount: collapsedRows * grid.columns
903 originY: grid.originY
904
905+ function cardPosition(index) {
906+ var pos = {};
907+ var row = Math.floor(index / grid.columns);
908+ var column = index % grid.columns;
909+ // Bit sad this is not symmetrical
910+ pos.x = column * grid.cellWidth + grid.margins;
911+ pos.y = row * grid.cellHeight;
912+ return pos;
913+ }
914+
915 ResponsiveGridView {
916 id: grid
917 anchors.fill: parent
918@@ -53,6 +63,7 @@
919 item.objectName = "delegate" + index;
920 item.width = Qt.binding(function() { return cardTool.cardWidth; });
921 item.height = Qt.binding(function() { return cardTool.cardHeight; });
922+ item.fixedHeaderHeight = Qt.binding(function() { return cardTool.headerHeight; });
923 item.fixedArtShapeSize = Qt.binding(function() { return cardTool.artShapeSize; });
924 item.cardData = Qt.binding(function() { return model; });
925 item.template = Qt.binding(function() { return cardTool.template; });
926@@ -62,7 +73,7 @@
927 }
928 Connections {
929 target: loader.item
930- onClicked: root.clicked(index, result)
931+ onClicked: root.clicked(index, result, loader.item, model)
932 onPressAndHold: root.pressAndHold(index)
933 }
934 }
935
936=== modified file 'qml/Dash/CardVerticalJournal.qml'
937--- qml/Dash/CardVerticalJournal.qml 2014-07-22 12:17:34 +0000
938+++ qml/Dash/CardVerticalJournal.qml 2014-08-08 15:11:52 +0000
939@@ -61,7 +61,7 @@
940 }
941 Connections {
942 target: loader.item
943- onClicked: root.clicked(index, result)
944+ onClicked: root.clicked(index, result, loader.item, model)
945 onPressAndHold: root.pressAndHold(index)
946 }
947 }
948
949=== modified file 'qml/Dash/Dash.qml'
950--- qml/Dash/Dash.qml 2014-08-06 19:39:30 +0000
951+++ qml/Dash/Dash.qml 2014-08-08 15:11:52 +0000
952@@ -16,6 +16,7 @@
953
954 import QtQuick 2.2
955 import Ubuntu.Components 0.1
956+import Ubuntu.Gestures 0.1
957 import Unity 0.2
958 import Utils 0.1
959 import Unity.DashCommunicator 0.1
960@@ -73,26 +74,104 @@
961 id: scopes
962 }
963
964- Image {
965+ QtObject {
966+ id: overviewController
967+ objectName: "overviewController"
968+
969+ property alias enableAnimation: progressAnimation.enabled
970+ property real progress: 0
971+ Behavior on progress {
972+ id: progressAnimation
973+ UbuntuNumberAnimation { }
974+ }
975+ }
976+
977+ ScopesOverview {
978+ id: scopesOverview
979+ objectName: "scopesOverview"
980 anchors.fill: parent
981- source: parent.width > parent.height ? "graphics/paper_landscape.png" : "graphics/paper_portrait.png"
982- fillMode: Image.PreserveAspectCrop
983- horizontalAlignment: Image.AlignRight
984- verticalAlignment: Image.AlignTop
985+ scope: scopes.overviewScope
986+ progress: overviewController.progress
987+ scopeScale: scopeItem.scope ? 0.4 : (1 - overviewController.progress * 0.6)
988+ visible: scopeScale != 1
989+ currentIndex: dashContent.currentIndex
990+ onDone: {
991+ if (currentTab == 1) {
992+ animateDashFromAll(dashContent.currentScopeId);
993+ }
994+ hide();
995+ }
996+ onFavoriteSelected: {
997+ setCurrentScope(scopeId, false, false);
998+ dashContentCache.scheduleUpdate();
999+ hide();
1000+ }
1001+ onAllFavoriteSelected: {
1002+ setCurrentScope(scopeId, false, false);
1003+ dashContentCache.scheduleUpdate();
1004+ animateDashFromAll(dashContent.currentScopeId);
1005+ hide();
1006+ }
1007+ onSearchSelected: {
1008+ var scopeIndex = -1;
1009+ for (var i = 0; i < scopes.count; ++i) {
1010+ if (scopes.getScope(i).id == scopeId) {
1011+ scopeIndex = i;
1012+ break;
1013+ }
1014+ }
1015+ if (scopeIndex >= 0) {
1016+ // Is a favorite one
1017+ setCurrentScope(scopeId, false, false);
1018+ dashContentCache.scheduleUpdate();
1019+ showDashFromPos(pos, size);
1020+ hide();
1021+ } else {
1022+ // Is not a favorite one, activate and get openScope
1023+ scope.activate(result);
1024+ }
1025+ }
1026+ function hide() {
1027+ overviewController.enableAnimation = true;
1028+ overviewController.progress = 0;
1029+ }
1030+ onProgressChanged: {
1031+ if (progress == 0) {
1032+ currentTab = scopeItem.scope ? 1 : 0;
1033+ }
1034+ }
1035+ }
1036+
1037+ ShaderEffectSource {
1038+ id: dashContentCache
1039+ parent: scopesOverview.dashItemEater
1040+ z: 1
1041+ sourceItem: dashContent
1042+ height: sourceItem.height
1043+ width: sourceItem.width
1044+ opacity: 1 - overviewController.progress
1045+ visible: overviewController.progress != 0 && scopeItem.scope === null
1046+ live: false
1047 }
1048
1049 DashContent {
1050 id: dashContent
1051+
1052+ property var scopeThatOpenedScope: null
1053+
1054 objectName: "dashContent"
1055- width: parent.width
1056- height: parent.height
1057+ width: dash.width
1058+ height: dash.height
1059 scopes: scopes
1060- visible: x != -width
1061+ visible: !scopesOverview.showingNonFavoriteScope && x != -width
1062 onGotoScope: {
1063 dash.setCurrentScope(scopeId, true, false);
1064 }
1065 onOpenScope: {
1066+ scopeThatOpenedScope = currentScope;
1067 scopeItem.scope = scope;
1068+ scopesOverview.currentTab = 1;
1069+ scopesOverview.ensureAllScopeVisible(scope.id);
1070 x = -width;
1071 }
1072 onScopeLoaded: {
1073@@ -102,25 +181,63 @@
1074 }
1075 }
1076 scale: dash.contentScale
1077- clip: scale != 1.0 || scopeItem.visible
1078+ clip: scale != 1.0 || scopeItem.visible || overviewController.progress != 0
1079 Behavior on x {
1080 UbuntuNumberAnimation {
1081+ duration: overviewController.progress != 0 ? 0 : UbuntuAnimation.FastDuration
1082 onRunningChanged: {
1083 if (!running && dashContent.x == 0) {
1084- dashContent.closeScope(scopeItem.scope);
1085+ dashContent.scopeThatOpenedScope.closeScope(scopeItem.scope);
1086 scopeItem.scope = null;
1087+ if (overviewController.progress == 0) {
1088+ // Set tab to Favorites only if we are not showing the overview
1089+ scopesOverview.currentTab = 0;
1090+ }
1091 }
1092 }
1093 }
1094 }
1095+
1096+ enabled: overviewController.progress == 0
1097+ opacity: enabled ? 1 : 0
1098+ }
1099+
1100+ DashBackground
1101+ {
1102+ anchors.fill: scopeItem
1103+ visible: scopeItem.visible
1104+ parent: scopeItem.parent
1105+ scale: scopeItem.scale
1106+ opacity: scopeItem.opacity
1107 }
1108
1109 GenericScopeView {
1110 id: scopeItem
1111- anchors.left: dashContent.right
1112+ objectName: "dashTempScopeItem"
1113+
1114+ readonly property real targetOverviewScale: {
1115+ if (scopesOverview.currentTab == 0) {
1116+ return 0.4;
1117+ } else {
1118+ return scopesOverview.allCardSize.width / scopeItem.width;
1119+ }
1120+ }
1121+ readonly property real overviewProgressScale: (1 - overviewController.progress * (1 - targetOverviewScale))
1122+ readonly property var targetOverviewPosition: scope ? scopesOverview.allScopeCardPosition(scope.id) : null
1123+ readonly property real overviewProgressX: scope && scopesOverview.currentTab == 1 && targetOverviewPosition ?
1124+ overviewController.progress * (targetOverviewPosition.x - (width - scopesOverview.allCardSize.width) / 2)
1125+ : 0
1126+ readonly property real overviewProgressY: scope && scopesOverview.currentTab == 1 && targetOverviewPosition ?
1127+ overviewController.progress * (targetOverviewPosition.y - (height - scopesOverview.allCardSize.height) / 2)
1128+ : 0
1129+
1130+ x: overviewController.progress == 0 ? dashContent.x + width : overviewProgressX
1131+ y: overviewController.progress == 0 ? dashContent.y : overviewProgressY
1132 width: parent.width
1133 height: parent.height
1134- scale: dash.contentScale
1135+ scale: dash.contentScale * overviewProgressScale
1136+ enabled: opacity == 1
1137+ opacity: 1 - overviewController.progress
1138 clip: scale != 1.0
1139 visible: scope != null
1140 hasBackAction: true
1141@@ -154,7 +271,7 @@
1142 opacity: 0
1143 visible: opacity > 0
1144
1145- readonly property bool processing: dashContent.processing || scopeItem.processing
1146+ readonly property bool processing: dashContent.processing || scopeItem.processing || scopesOverview.processing
1147
1148 Behavior on opacity {
1149 UbuntuNumberAnimation { duration: UbuntuAnimation.FastDuration }
1150@@ -207,4 +324,45 @@
1151 }
1152 }
1153
1154+ Image {
1155+ source: "graphics/overview_hint.png"
1156+ anchors.horizontalCenter: parent.horizontalCenter
1157+ opacity: (scopeItem.scope ? scopeItem.pageHeaderTotallyVisible : dashContent.pageHeaderTotallyVisible) &&
1158+ (overviewDragHandle.enabled || overviewController.progress != 0) ? 1 : 0
1159+ Behavior on opacity {
1160+ enabled: overviewController.progress == 0
1161+ UbuntuNumberAnimation {}
1162+ }
1163+ y: parent.height - height * (1 - overviewController.progress * 4)
1164+ }
1165+
1166+ EdgeDragArea {
1167+ id: overviewDragHandle
1168+ objectName: "overviewDragHandle"
1169+ z: 1
1170+ direction: Direction.Upwards
1171+ enabled: !dashContent.previewShown &&
1172+ dashContent.currentScope &&
1173+ dashContent.currentScope.searchQuery == "" &&
1174+ (overviewController.progress == 0 || dragging)
1175+
1176+ readonly property real fullMovement: units.gu(20)
1177+
1178+ anchors { left: parent.left; right: parent.right; bottom: parent.bottom }
1179+ height: units.gu(2)
1180+
1181+ onSceneDistanceChanged: {
1182+ if (overviewController.enableAnimation) {
1183+ dashContentCache.scheduleUpdate();
1184+ }
1185+ overviewController.enableAnimation = false;
1186+ overviewController.progress = Math.max(0, Math.min(1, sceneDistance / fullMovement));
1187+ }
1188+
1189+ onDraggingChanged: {
1190+ overviewController.enableAnimation = true;
1191+ overviewController.progress = (overviewController.progress > 0.7) ? 1 : 0;
1192+ }
1193+ }
1194+
1195 }
1196
1197=== added file 'qml/Dash/DashBackground.qml'
1198--- qml/Dash/DashBackground.qml 1970-01-01 00:00:00 +0000
1199+++ qml/Dash/DashBackground.qml 2014-08-08 15:11:52 +0000
1200@@ -0,0 +1,24 @@
1201+/*
1202+ * Copyright (C) 2013, 2014 Canonical, Ltd.
1203+ *
1204+ * This program is free software; you can redistribute it and/or modify
1205+ * it under the terms of the GNU General Public License as published by
1206+ * the Free Software Foundation; version 3.
1207+ *
1208+ * This program is distributed in the hope that it will be useful,
1209+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1210+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1211+ * GNU General Public License for more details.
1212+ *
1213+ * You should have received a copy of the GNU General Public License
1214+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1215+ */
1216+
1217+import QtQuick 2.0
1218+
1219+Image {
1220+ source: anchors.fill.width > anchors.fill.height ? "graphics/paper_landscape.png" : "graphics/paper_portrait.png"
1221+ fillMode: Image.PreserveAspectCrop
1222+ horizontalAlignment: Image.AlignRight
1223+ verticalAlignment: Image.AlignTop
1224+}
1225
1226=== modified file 'qml/Dash/DashContent.qml'
1227--- qml/Dash/DashContent.qml 2014-08-06 19:39:30 +0000
1228+++ qml/Dash/DashContent.qml 2014-08-08 15:11:52 +0000
1229@@ -25,8 +25,14 @@
1230
1231 property alias scopes: dashContentList.model
1232 readonly property alias currentIndex: dashContentList.currentIndex
1233+ readonly property string currentScopeId: dashContentList.currentItem ? dashContentList.currentItem.scopeId : ""
1234+ readonly property var currentScope: dashContentList.currentItem ? dashContentList.currentItem.theScope : null
1235+ readonly property bool previewShown: dashContentList.currentItem && dashContentList.currentItem.item ?
1236+ dashContentList.currentItem.item.previewShown : false
1237 readonly property bool processing: dashContentList.currentItem && dashContentList.currentItem.item
1238 && dashContentList.currentItem.item.processing || false
1239+ readonly property bool pageHeaderTotallyVisible: dashContentList.currentItem && dashContentList.currentItem.item
1240+ && dashContentList.currentItem.item.pageHeaderTotallyVisible || false
1241
1242 signal scopeLoaded(string scopeId)
1243 signal gotoScope(string scopeId)
1244@@ -77,15 +83,15 @@
1245 }
1246 }
1247
1248- function closeScope(scope) {
1249- dashContentList.currentItem.theScope.closeScope(scope)
1250- }
1251-
1252 Item {
1253 id: dashContentListHolder
1254
1255 anchors.fill: parent
1256
1257+ DashBackground {
1258+ anchors.fill: parent
1259+ }
1260+
1261 ListView {
1262 id: dashContentList
1263 objectName: "dashContentList"
1264
1265=== modified file 'qml/Dash/DashRenderer.qml'
1266--- qml/Dash/DashRenderer.qml 2014-07-22 12:17:34 +0000
1267+++ qml/Dash/DashRenderer.qml 2014-08-08 15:11:52 +0000
1268@@ -41,7 +41,9 @@
1269 /// Emitted when the user clicked on an item
1270 /// @param index is the index of the clicked item
1271 /// @param result result model of the cliked item, used for activation
1272- signal clicked(int index, var result)
1273+ /// @param item item that has been clicked
1274+ /// @param itemModel model of the item
1275+ signal clicked(int index, var result, var item, var itemModel)
1276
1277 /// Emitted when the user pressed and held on an item
1278 /// @param index is the index of the held item
1279
1280=== modified file 'qml/Dash/GenericScopeView.qml'
1281--- qml/Dash/GenericScopeView.qml 2014-08-06 19:39:30 +0000
1282+++ qml/Dash/GenericScopeView.qml 2014-08-08 15:11:52 +0000
1283@@ -25,7 +25,7 @@
1284 FocusScope {
1285 id: scopeView
1286
1287- readonly property alias navigationShown: dashNavigation.showList
1288+ readonly property bool navigationShown: pageHeaderLoader.item ? pageHeaderLoader.item.bottomItem[0].showList : false
1289 property var scope: null
1290 property SortFilterProxyModel categories: categoryFilter
1291 property bool isCurrent: false
1292@@ -33,8 +33,11 @@
1293 property bool hasBackAction: false
1294 property bool enableHeightBehaviorOnNextCreation: false
1295 property var categoryView: categoryView
1296- property alias paginationCount: pageHeader.paginationCount
1297- property alias paginationIndex: pageHeader.paginationIndex
1298+ property bool showPageHeader: true
1299+ readonly property alias previewShown: previewListView.open
1300+ property int paginationCount: 0
1301+ property int paginationIndex: 0
1302+ property alias pageHeaderTotallyVisible: categoryView.pageHeaderTotallyVisible
1303
1304 property var scopeStyle: ScopeStyle {
1305 style: scope ? scope.customizations : {}
1306@@ -56,6 +59,34 @@
1307 previewListView.open = false;
1308 }
1309
1310+ function itemClicked(index, result, item, itemModel, resultsModel, limitedCategoryItemCount) {
1311+ if (scope.id === "scopes" || scope.id == "clickscope") {
1312+ // TODO Technically it is possible that calling activate() will make the scope emit
1313+ // previewRequested so that we show a preview but there's no scope that does that yet
1314+ // so it's not implemented
1315+ scope.activate(result)
1316+ } else {
1317+ openPreview(index, resultsModel, limitedCategoryItemCount);
1318+ }
1319+ }
1320+
1321+ function itemPressedAndHeld(index, resultsModel, limitedCategoryItemCount) {
1322+ openPreview(index, resultsModel, limitedCategoryItemCount);
1323+ }
1324+
1325+ function openPreview(index, resultsModel, limitedCategoryItemCount) {
1326+ if (limitedCategoryItemCount > 0) {
1327+ previewLimitModel.model = resultsModel;
1328+ previewLimitModel.limit = limitedCategoryItemCount;
1329+ previewListView.model = previewLimitModel;
1330+ } else {
1331+ previewListView.model = resultsModel;
1332+ }
1333+ previewListView.currentIndex = -1;
1334+ previewListView.currentIndex = index;
1335+ previewListView.open = true;
1336+ }
1337+
1338 Binding {
1339 target: scope
1340 property: "isActive"
1341@@ -72,22 +103,24 @@
1342 }
1343
1344 onIsCurrentChanged: {
1345- pageHeader.resetSearch();
1346+ if (showPageHeader) {
1347+ pageHeaderLoader.item.resetSearch();
1348+ }
1349 previewListView.open = false;
1350 }
1351
1352 Binding {
1353 target: scopeView.scope
1354 property: "searchQuery"
1355- value: pageHeader.searchQuery
1356- when: isCurrent
1357+ value: pageHeaderLoader.item ? pageHeaderLoader.item.searchQuery : ""
1358+ when: isCurrent && showPageHeader
1359 }
1360
1361 Binding {
1362- target: pageHeader
1363+ target: pageHeaderLoader.item
1364 property: "searchQuery"
1365 value: scopeView.scope ? scopeView.scope.searchQuery : ""
1366- when: isCurrent
1367+ when: isCurrent && showPageHeader
1368 }
1369
1370 Connections {
1371@@ -114,10 +147,13 @@
1372 model: scopeView.categories
1373 forceNoClip: previewListView.open
1374 pixelAligned: true
1375- interactive: !dashNavigation.showList
1376+ interactive: !navigationShown
1377
1378 property string expandedCategoryId: ""
1379
1380+ readonly property bool pageHeaderTotallyVisible: scopeView.showPageHeader &&
1381+ ((headerItemShownHeight == 0 && categoryView.contentY <= categoryView.originY) || (headerItemShownHeight == pageHeaderLoader.item.height))
1382+
1383 delegate: ListItems.Base {
1384 id: baseItem
1385 objectName: "dashCategory" + category
1386@@ -223,28 +259,19 @@
1387 Connections {
1388 target: rendererLoader.item
1389 onClicked: {
1390- if (scopeView.scope.id === "scopes" || scopeView.scope.id == "clickscope") {
1391- // TODO Technically it is possible that calling activate() will make the scope emit
1392- // previewRequested so that we show a preview but there's no scope that does that yet
1393- // so it's not implemented
1394- scopeView.scope.activate(result)
1395- } else {
1396- openPreview(index);
1397- }
1398- }
1399- onPressAndHold: openPreview(index)
1400-
1401- function openPreview(index) {
1402+ scopeView.itemClicked(index, result, item, itemModel, target.model, categoryItemCount());
1403+ }
1404+
1405+ onPressAndHold: {
1406+ scopeView.itemPressedAndHeld(index, target.model, categoryItemCount());
1407+ }
1408+
1409+ function categoryItemCount() {
1410+ var categoryItemCount = -1;
1411 if (!rendererLoader.expanded && !seeAllLabel.visible && target.collapsedItemCount > 0) {
1412- previewLimitModel.model = target.model;
1413- previewLimitModel.limit = target.collapsedItemCount;
1414- previewListView.model = previewLimitModel;
1415- } else {
1416- previewListView.model = target.model;
1417+ categoryItemCount = target.collapsedItemCount;
1418 }
1419- previewListView.currentIndex = -1;
1420- previewListView.currentIndex = index;
1421- previewListView.open = true;
1422+ return categoryItemCount;
1423 }
1424 }
1425 Connections {
1426@@ -380,26 +407,35 @@
1427 }
1428 }
1429
1430- pageHeader: PageHeader {
1431- id: pageHeader
1432- objectName: "scopePageHeader"
1433+ pageHeader: scopeView.showPageHeader ? pageHeaderLoader : null
1434+ Loader {
1435+ id: pageHeaderLoader
1436 width: parent.width
1437- title: scopeView.scope ? scopeView.scope.name : ""
1438- showBackButton: scopeView.hasBackAction
1439- searchEntryEnabled: true
1440- scopeStyle: scopeView.scopeStyle
1441-
1442- bottomItem: DashNavigation {
1443- id: dashNavigation
1444- scope: scopeView.scope
1445- width: parent.width <= units.gu(60) ? parent.width : units.gu(40)
1446- anchors.right: parent.right
1447- windowHeight: scopeView.height
1448- windowWidth: scopeView.width
1449- scopeStyle: scopeView.scopeStyle
1450+ sourceComponent: scopeView.showPageHeader ? pageHeaderComponent : undefined
1451+ Component {
1452+ id: pageHeaderComponent
1453+ PageHeader {
1454+ objectName: "scopePageHeader"
1455+ width: parent.width
1456+ title: scopeView.scope ? scopeView.scope.name : ""
1457+ showBackButton: scopeView.hasBackAction
1458+ searchEntryEnabled: true
1459+ scopeStyle: scopeView.scopeStyle
1460+ paginationCount: scopeView.paginationCount
1461+ paginationIndex: scopeView.paginationIndex
1462+
1463+ bottomItem: DashNavigation {
1464+ scope: scopeView.scope
1465+ width: parent.width <= units.gu(60) ? parent.width : units.gu(40)
1466+ anchors.right: parent.right
1467+ windowHeight: scopeView.height
1468+ windowWidth: scopeView.width
1469+ scopeStyle: scopeView.scopeStyle
1470+ }
1471+
1472+ onBackClicked: scopeView.backClicked()
1473+ }
1474 }
1475-
1476- onBackClicked: scopeView.backClicked()
1477 }
1478 }
1479
1480@@ -418,7 +454,9 @@
1481 anchors.left: categoryView.right
1482
1483 onOpenChanged: {
1484- pageHeader.unfocus();
1485+ if (showPageHeader) {
1486+ pageHeaderLoader.item.unfocus();
1487+ }
1488 }
1489 }
1490
1491
1492=== modified file 'qml/Dash/PreviewListView.qml'
1493--- qml/Dash/PreviewListView.qml 2014-07-30 15:46:44 +0000
1494+++ qml/Dash/PreviewListView.qml 2014-08-08 15:11:52 +0000
1495@@ -108,7 +108,7 @@
1496 anchors {
1497 left: parent.left
1498 right: parent.right
1499- top: pageHeader.bottom
1500+ top: header.bottom
1501 bottom: parent.bottom
1502 }
1503
1504
1505=== added file 'qml/Dash/ScopesOverview.qml'
1506--- qml/Dash/ScopesOverview.qml 1970-01-01 00:00:00 +0000
1507+++ qml/Dash/ScopesOverview.qml 2014-08-08 15:11:52 +0000
1508@@ -0,0 +1,533 @@
1509+/*
1510+ * Copyright (C) 2014 Canonical, Ltd.
1511+ *
1512+ * This program is free software; you can redistribute it and/or modify
1513+ * it under the terms of the GNU General Public License as published by
1514+ * the Free Software Foundation; version 3.
1515+ *
1516+ * This program is distributed in the hope that it will be useful,
1517+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1518+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1519+ * GNU General Public License for more details.
1520+ *
1521+ * You should have received a copy of the GNU General Public License
1522+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1523+ */
1524+
1525+import QtQuick 2.0
1526+import Dash 0.1
1527+import Ubuntu.Components 0.1
1528+import "../Components"
1529+
1530+Item {
1531+ id: root
1532+
1533+ // Properties set by parent
1534+ property real progress: 0
1535+ property var scope: null
1536+ property int currentIndex: 0
1537+ property real scopeScale: 1
1538+
1539+ // Properties set and used by parent
1540+ property alias currentTab: tabBar.currentTab
1541+
1542+ // Properties used by parent
1543+ readonly property bool processing: searchResultsViewer.processing || tempScopeItem.processing
1544+ property bool growingDashFromPos: false
1545+ readonly property bool searching: scope && scope.searchQuery == ""
1546+ readonly property bool showingNonFavoriteScope: tempScopeItem.scope != null
1547+ readonly property var dashItemEater: {
1548+ if (!forceXYScalerEater && tabBar.currentTab == 0 && middleItems.count > 0) {
1549+ var loaderItem = middleItems.itemAt(0).item;
1550+ return loaderItem && loaderItem.currentItem ? loaderItem.currentItem : null;
1551+ }
1552+ return scopesOverviewXYScaler;
1553+ }
1554+ readonly property size allCardSize: {
1555+ if (middleItems.count > 1) {
1556+ var loaderItem = middleItems.itemAt(1).item;
1557+ if (loaderItem) {
1558+ var cardTool = loaderItem.cardTool;
1559+ return Qt.size(cardTool.cardWidth, cardTool.cardHeight);
1560+ }
1561+ }
1562+ return Qt.size(0, 0);
1563+ }
1564+
1565+ // Internal properties
1566+ property bool forceXYScalerEater: false
1567+
1568+ signal done()
1569+ signal favoriteSelected(var scopeId)
1570+ signal allFavoriteSelected(var scopeId)
1571+ signal searchSelected(var scopeId, var result, var pos, var size)
1572+
1573+ Connections {
1574+ target: scope
1575+ onOpenScope: {
1576+ var itemPos = scopesOverviewXYScaler.restorePosition;
1577+ var itemSize = scopesOverviewXYScaler.restoreSize;
1578+ scopesOverviewXYScaler.scale = itemSize.width / scopesOverviewXYScaler.width;
1579+ if (itemPos) {
1580+ scopesOverviewXYScaler.x = itemPos.x -(scopesOverviewXYScaler.width - scopesOverviewXYScaler.width * scopesOverviewXYScaler.scale) / 2;
1581+ scopesOverviewXYScaler.y = itemPos.y -(scopesOverviewXYScaler.height - scopesOverviewXYScaler.height * scopesOverviewXYScaler.scale) / 2;
1582+ } else {
1583+ scopesOverviewXYScaler.x = 0;
1584+ scopesOverviewXYScaler.y = 0;
1585+ }
1586+ scopesOverviewXYScaler.opacity = 0;
1587+ tempScopeItem.scope = scope;
1588+ middleItems.overrideOpacity = 0;
1589+ scopesOverviewXYScaler.scale = 1;
1590+ scopesOverviewXYScaler.x = 0;
1591+ scopesOverviewXYScaler.y = 0;
1592+ scopesOverviewXYScaler.opacity = 1;
1593+ }
1594+ onGotoScope: {
1595+ if (tabBar.currentTab == 0) {
1596+ root.favoriteSelected(scopeId);
1597+ } else {
1598+ root.allFavoriteSelected(scopeId);
1599+ }
1600+ }
1601+ }
1602+
1603+ Binding {
1604+ target: scope
1605+ property: "isActive"
1606+ value: progress === 1
1607+ }
1608+
1609+ function animateDashFromAll(scopeId) {
1610+ var currentScopePos = allScopeCardPosition(scopeId);
1611+ if (currentScopePos) {
1612+ showDashFromPos(currentScopePos, allCardSize);
1613+ } else {
1614+ console.log("Warning: Could not find Dash OverView All card position for scope", dashContent.currentScopeId);
1615+ }
1616+ }
1617+
1618+ function showDashFromPos(itemPos, itemSize) {
1619+ scopesOverviewXYScaler.scale = itemSize.width / scopesOverviewXYScaler.width;
1620+ scopesOverviewXYScaler.x = itemPos.x -(scopesOverviewXYScaler.width - scopesOverviewXYScaler.width * scopesOverviewXYScaler.scale) / 2;
1621+ scopesOverviewXYScaler.y = itemPos.y -(scopesOverviewXYScaler.height - scopesOverviewXYScaler.height * scopesOverviewXYScaler.scale) / 2;
1622+ scopesOverviewXYScaler.opacity = 0;
1623+ root.growingDashFromPos = true;
1624+ scopesOverviewXYScaler.scale = 1;
1625+ scopesOverviewXYScaler.x = 0;
1626+ scopesOverviewXYScaler.y = 0;
1627+ scopesOverviewXYScaler.opacity = 1;
1628+ }
1629+
1630+ function allScopeCardPosition(scopeId) {
1631+ if (middleItems.count > 1) {
1632+ var loaderItem = middleItems.itemAt(1).item;
1633+ if (loaderItem) {
1634+ var pos = loaderItem.scopeCardPosition(scopeId);
1635+ return loaderItem.mapToItem(null, pos.x, pos.y);
1636+ }
1637+ }
1638+ }
1639+
1640+ function ensureAllScopeVisible(scopeId) {
1641+ if (middleItems.count > 1) {
1642+ var loaderItem = middleItems.itemAt(1).item;
1643+ if (loaderItem) {
1644+ var pos = loaderItem.scopeCardPosition(scopeId);
1645+ loaderItem.contentY = Math.min(pos.y, loaderItem.contentHeight - loaderItem.height);
1646+ }
1647+ }
1648+ }
1649+
1650+ onProgressChanged: {
1651+ if (progress == 0) {
1652+ pageHeader.resetSearch();
1653+ pageHeader.unfocus(); // Shouldn't the previous call do this too?
1654+ }
1655+ }
1656+
1657+ ScopeStyle {
1658+ id: overviewScopeStyle
1659+ style: { "foreground-color" : "white", "background-color" : "transparent" }
1660+ }
1661+
1662+ DashBackground {
1663+ anchors.fill: parent
1664+ source: "graphics/dark_background.jpg"
1665+ }
1666+
1667+ Connections {
1668+ target: pageHeader
1669+ onSearchQueryChanged: {
1670+ // Need this in order, otherwise something gets unhappy in rendering
1671+ // of the overlay in carousels because the parent of the dash dies for
1672+ // a moment, this way we make sure it's reparented first
1673+ // by forceXYScalerEater making dashItemEater return scopesOverviewXYScaler
1674+ // before we kill the previous parent by scope.searchQuery
1675+ root.forceXYScalerEater = true;
1676+ root.scope.searchQuery = pageHeader.searchQuery;
1677+ root.forceXYScalerEater = false;
1678+ }
1679+ }
1680+
1681+ Binding {
1682+ target: pageHeader
1683+ property: "searchQuery"
1684+ value: scope ? scope.searchQuery : ""
1685+ }
1686+
1687+ Item {
1688+ id: scopesOverviewContent
1689+ x: previewListView.open ? -width : 0
1690+ Behavior on x { UbuntuNumberAnimation { } }
1691+ width: parent.width
1692+ height: parent.height
1693+
1694+ PageHeader {
1695+ id: pageHeader
1696+ objectName: "scopesOverviewPageHeader"
1697+
1698+ readonly property real yDisplacement: pageHeader.height + tabBar.height + tabBar.anchors.margins
1699+
1700+ y: {
1701+ if (root.progress < 0.5) {
1702+ return -yDisplacement;
1703+ } else {
1704+ return -yDisplacement + (root.progress - 0.5) * yDisplacement * 2;
1705+ }
1706+ }
1707+ width: parent.width
1708+ clip: true
1709+ title: i18n.tr("Manage Dash")
1710+ scopeStyle: overviewScopeStyle
1711+ showSignatureLine: false
1712+ searchEntryEnabled: true
1713+ }
1714+
1715+ ScopesOverviewTab {
1716+ id: tabBar
1717+ anchors {
1718+ left: parent.left
1719+ right: parent.right
1720+ top: pageHeader.bottom
1721+ margins: units.gu(2)
1722+ }
1723+ height: units.gu(4)
1724+
1725+ enabled: opacity == 1
1726+ opacity: !scope || scope.searchQuery == "" ? 1 : 0
1727+ Behavior on opacity { UbuntuNumberAnimation { } }
1728+ }
1729+
1730+ Repeater {
1731+ id: middleItems
1732+ objectName: "scopesOverviewRepeater"
1733+ property real overrideOpacity: -1
1734+ model: scope && scope.searchQuery == "" ? scope.categories : null
1735+ delegate: Loader {
1736+ id: loader
1737+ objectName: "scopesOverviewRepeaterChild" + index
1738+
1739+ height: {
1740+ if (index == 0) {
1741+ return root.height;
1742+ } else {
1743+ return root.height - pageHeader.height - tabBar.height - tabBar.anchors.margins - units.gu(2);
1744+ }
1745+ }
1746+ width: {
1747+ if (index == 0) {
1748+ return root.width / scopeScale;
1749+ } else {
1750+ return root.width;
1751+ }
1752+ }
1753+ x: {
1754+ if (index == 0) {
1755+ return (root.width - width) / 2;
1756+ } else {
1757+ return 0;
1758+ }
1759+ }
1760+ anchors {
1761+ bottom: scopesOverviewContent.bottom
1762+ }
1763+
1764+ scale: index == 0 ? scopeScale : 1
1765+
1766+ opacity: {
1767+ if (middleItems.overrideOpacity >= 0)
1768+ return middleItems.overrideOpacity;
1769+
1770+ if (tabBar.currentTab != index)
1771+ return 0;
1772+
1773+ return index == 0 ? 1 : root.progress;
1774+ }
1775+ Behavior on opacity {
1776+ enabled: root.progress == 1
1777+ UbuntuNumberAnimation { }
1778+ }
1779+ enabled: opacity == 1
1780+
1781+ clip: index == 1
1782+
1783+ CardTool {
1784+ id: cardTool
1785+ objectName: "cardTool"
1786+ count: results.count
1787+ template: model.renderer
1788+ components: model.components
1789+ viewWidth: parent.width
1790+ }
1791+
1792+ source: {
1793+ if (index == 0 && categoryId == "favorites") return "ScopesOverviewFavorites.qml";
1794+ else if (index == 1 && categoryId == "all") return "ScopesOverviewAll.qml";
1795+ else return "";
1796+ }
1797+
1798+ onLoaded: {
1799+ item.model = Qt.binding(function() { return results; });
1800+ item.cardTool = cardTool;
1801+ if (index == 0) {
1802+ item.scopeWidth = Qt.binding(function() { return root.width; });
1803+ item.scopeHeight = Qt.binding(function() { return root.height; });
1804+ item.appliedScale = Qt.binding(function() { return loader.scale });
1805+ item.currentIndex = Qt.binding(function() { return root.currentIndex });
1806+ } else if (index == 1) {
1807+ item.extraHeight = bottomBar.height;
1808+ }
1809+ }
1810+
1811+ Connections {
1812+ target: loader.item
1813+ onClicked: {
1814+ pageHeader.unfocus();
1815+ if (tabBar.currentTab == 0) {
1816+ root.favoriteSelected(itemModel.scopeId);
1817+ } else {
1818+ var favoriteScopesItem = middleItems.itemAt(0).item;
1819+ var scopeIndex = favoriteScopesItem.model.scopeIndex(itemModel.scopeId);
1820+ if (scopeIndex >= 0) {
1821+ root.allFavoriteSelected(itemModel.scopeId);
1822+ } else {
1823+ // Will result in an openScope from root.scope
1824+ scopesOverviewXYScaler.restorePosition = item.mapToItem(null, 0, 0);
1825+ scopesOverviewXYScaler.restoreSize = allCardSize;
1826+ root.scope.activate(result);
1827+ }
1828+ }
1829+ }
1830+ onPressAndHold: {
1831+ // Preview can call openScope so make sure restorePosition and restoreSize are set
1832+ scopesOverviewXYScaler.restorePosition = undefined;
1833+ scopesOverviewXYScaler.restoreSize = allCardSize;
1834+
1835+ previewListView.model = target.model;
1836+ previewListView.currentIndex = -1;
1837+ previewListView.currentIndex = index;
1838+ previewListView.open = true;
1839+ }
1840+ }
1841+ }
1842+ }
1843+
1844+ GenericScopeView {
1845+ id: searchResultsViewer
1846+ objectName: "searchResultsViewer"
1847+ anchors {
1848+ top: pageHeader.bottom
1849+ right: parent.right
1850+ left: parent.left
1851+ bottom: parent.bottom
1852+ }
1853+ scope: root.scope && root.scope.searchQuery != "" ? root.scope : null
1854+ scopeStyle: overviewScopeStyle
1855+ enabled: opacity == 1
1856+ showPageHeader: false
1857+ clip: true
1858+ opacity: searchResultsViewer.scope ? 1 : 0
1859+ isCurrent: true
1860+ Behavior on opacity { UbuntuNumberAnimation { } }
1861+
1862+ function itemClicked(index, result, item, itemModel, resultsModel, limitedCategoryItemCount) {
1863+ pageHeader.unfocus();
1864+ pageHeader.closePopup();
1865+ if (itemModel.scopeId) {
1866+ // This can end up in openScope so save restorePosition and restoreSize
1867+ scopesOverviewXYScaler.restorePosition = item.mapToItem(null, 0, 0);
1868+ scopesOverviewXYScaler.restoreSize = Qt.size(item.width, item.height);
1869+ root.searchSelected(itemModel.scopeId, result, item.mapToItem(null, 0, 0), Qt.size(item.width, item.height));
1870+ } else {
1871+ // Not a scope, just activate it
1872+ searchResultsViewer.scope.activate(result);
1873+ }
1874+ }
1875+
1876+ function itemPressedAndHeld(index, resultsModel, limitedCategoryItemCount) {
1877+ // Do nothing
1878+ }
1879+ }
1880+
1881+ Rectangle {
1882+ id: bottomBar
1883+ color: "black"
1884+ height: units.gu(8)
1885+ width: parent.width
1886+ enabled: opacity == 1
1887+ opacity: scope && scope.searchQuery == "" ? 1 : 0
1888+ Behavior on opacity { UbuntuNumberAnimation { } }
1889+ y: {
1890+ if (root.progress < 0.5) {
1891+ return parent.height;
1892+ } else {
1893+ return parent.height - (root.progress - 0.5) * height * 2;
1894+ }
1895+ }
1896+
1897+ AbstractButton {
1898+ objectName: "scopesOverviewDoneButton"
1899+ width: Math.max(label.width + units.gu(2), units.gu(10))
1900+ height: units.gu(4)
1901+ anchors {
1902+ left: parent.left
1903+ leftMargin: units.gu(2)
1904+ verticalCenter: parent.verticalCenter
1905+ }
1906+ Rectangle {
1907+ anchors.fill: parent
1908+ border.color: "white"
1909+ border.width: units.dp(1)
1910+ radius: units.dp(10)
1911+ color: parent.pressed ? "gray" : "transparent"
1912+ }
1913+ Label {
1914+ id: label
1915+ anchors.centerIn: parent
1916+ text: i18n.tr("Done")
1917+ color: parent.pressed ? "black" : "white"
1918+ }
1919+ onClicked: root.done();
1920+ }
1921+
1922+ AbstractButton {
1923+ objectName: "scopesOverviewStoreButton"
1924+ width: Math.max(storeLabel.width, units.gu(10))
1925+ height: units.gu(4)
1926+ anchors {
1927+ right: parent.right
1928+ verticalCenter: parent.verticalCenter
1929+ }
1930+ Icon {
1931+ id: storeImage
1932+ name: "ubuntu-store-symbolic"
1933+ color: "white"
1934+ anchors.horizontalCenter: parent.horizontalCenter
1935+ width: units.gu(2)
1936+ height: units.gu(2)
1937+ }
1938+ Label {
1939+ id: storeLabel
1940+ anchors.horizontalCenter: parent.horizontalCenter
1941+ anchors.top: storeImage.bottom
1942+ text: i18n.tr("Store")
1943+ color: "white"
1944+ }
1945+ onClicked: {
1946+ // Just zoom from the middle
1947+ scopesOverviewXYScaler.restorePosition = undefined;
1948+ scopesOverviewXYScaler.restoreSize = allCardSize;
1949+ scope.performQuery("scope://com.canonical.scopes.clickstore");
1950+ }
1951+ }
1952+ }
1953+ }
1954+
1955+ PreviewListView {
1956+ id: previewListView
1957+ objectName: "scopesOverviewPreviewListView"
1958+ scope: root.scope
1959+ scopeStyle: overviewScopeStyle
1960+ visible: x != width
1961+ width: parent.width
1962+ height: parent.height
1963+ anchors.left: scopesOverviewContent.right
1964+ }
1965+
1966+
1967+
1968+ Item {
1969+ id: scopesOverviewXYScaler
1970+ width: parent.width
1971+ height: parent.height
1972+
1973+ clip: scale != 1.0
1974+ enabled: scale == 1
1975+
1976+ property bool animationsEnabled: root.showingNonFavoriteScope || root.growingDashFromPos
1977+
1978+ property var restorePosition
1979+ property var restoreSize
1980+
1981+ Behavior on x {
1982+ enabled: scopesOverviewXYScaler.animationsEnabled
1983+ UbuntuNumberAnimation { }
1984+ }
1985+ Behavior on y {
1986+ enabled: scopesOverviewXYScaler.animationsEnabled
1987+ UbuntuNumberAnimation { }
1988+ }
1989+ Behavior on opacity {
1990+ enabled: scopesOverviewXYScaler.animationsEnabled
1991+ UbuntuNumberAnimation { }
1992+ }
1993+ Behavior on scale {
1994+ enabled: scopesOverviewXYScaler.animationsEnabled
1995+ UbuntuNumberAnimation {
1996+ onRunningChanged: {
1997+ if (!running) {
1998+ if (root.showingNonFavoriteScope && scopesOverviewXYScaler.scale != 1) {
1999+ root.scope.closeScope(tempScopeItem.scope);
2000+ tempScopeItem.scope = null;
2001+ } else if (root.growingDashFromPos) {
2002+ root.growingDashFromPos = false;
2003+ }
2004+ }
2005+ }
2006+ }
2007+ }
2008+
2009+ DashBackground {
2010+ anchors.fill: tempScopeItem
2011+ visible: tempScopeItem.visible
2012+ parent: tempScopeItem.parent
2013+ }
2014+
2015+ GenericScopeView {
2016+ id: tempScopeItem
2017+ objectName: "scopesOverviewTempScopeItem"
2018+
2019+ width: parent.width
2020+ height: parent.height
2021+ scale: dash.contentScale
2022+ clip: scale != 1.0
2023+ visible: scope != null
2024+ hasBackAction: true
2025+ isCurrent: visible
2026+ onBackClicked: {
2027+ var v = scopesOverviewXYScaler.restoreSize.width / tempScopeItem.width;
2028+ scopesOverviewXYScaler.scale = v;
2029+ if (scopesOverviewXYScaler.restorePosition) {
2030+ scopesOverviewXYScaler.x = scopesOverviewXYScaler.restorePosition.x -(tempScopeItem.width - tempScopeItem.width * v) / 2;
2031+ scopesOverviewXYScaler.y = scopesOverviewXYScaler.restorePosition.y -(tempScopeItem.height - tempScopeItem.height * v) / 2;
2032+ } else {
2033+ scopesOverviewXYScaler.x = 0;
2034+ scopesOverviewXYScaler.y = 0;
2035+ }
2036+ scopesOverviewXYScaler.opacity = 0;
2037+ middleItems.overrideOpacity = -1;
2038+ }
2039+ }
2040+ }
2041+}
2042
2043=== added file 'qml/Dash/ScopesOverviewAll.qml'
2044--- qml/Dash/ScopesOverviewAll.qml 1970-01-01 00:00:00 +0000
2045+++ qml/Dash/ScopesOverviewAll.qml 2014-08-08 15:11:52 +0000
2046@@ -0,0 +1,54 @@
2047+/*
2048+ * Copyright (C) 2014 Canonical, Ltd.
2049+ *
2050+ * This program is free software; you can redistribute it and/or modify
2051+ * it under the terms of the GNU General Public License as published by
2052+ * the Free Software Foundation; version 3.
2053+ *
2054+ * This program is distributed in the hope that it will be useful,
2055+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2056+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2057+ * GNU General Public License for more details.
2058+ *
2059+ * You should have received a copy of the GNU General Public License
2060+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2061+ */
2062+
2063+import QtQuick 2.0
2064+import Ubuntu.Components 0.1
2065+
2066+Flickable {
2067+ id: root
2068+
2069+ property alias model: cardGrid.model
2070+ property alias cardTool: cardGrid.cardTool
2071+
2072+ property real extraHeight: 0
2073+
2074+ signal clicked(int index, var result, var item, var itemModel)
2075+ signal pressAndHold(int index)
2076+
2077+ contentHeight: cardGrid.expandedHeight + extraHeight
2078+ contentWidth: cardGrid.width
2079+ flickableDirection: Flickable.VerticalFlick
2080+
2081+ function scopeCardPosition(scopeId) {
2082+ var index = model.scopeIndex(scopeId);
2083+ var pos = cardGrid.cardPosition(index);
2084+ pos.y = pos.y - root.contentY;
2085+ return pos;
2086+ }
2087+
2088+ CardGrid {
2089+ id: cardGrid
2090+ width: root.width
2091+ height: parent.height
2092+
2093+ onClicked: {
2094+ root.clicked(index, result, item, itemModel);
2095+ }
2096+ onPressAndHold: {
2097+ root.pressAndHold(index);
2098+ }
2099+ }
2100+}
2101
2102=== added file 'qml/Dash/ScopesOverviewFavorites.qml'
2103--- qml/Dash/ScopesOverviewFavorites.qml 1970-01-01 00:00:00 +0000
2104+++ qml/Dash/ScopesOverviewFavorites.qml 2014-08-08 15:11:52 +0000
2105@@ -0,0 +1,73 @@
2106+/*
2107+ * Copyright (C) 2014 Canonical, Ltd.
2108+ *
2109+ * This program is free software; you can redistribute it and/or modify
2110+ * it under the terms of the GNU General Public License as published by
2111+ * the Free Software Foundation; version 3.
2112+ *
2113+ * This program is distributed in the hope that it will be useful,
2114+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2115+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2116+ * GNU General Public License for more details.
2117+ *
2118+ * You should have received a copy of the GNU General Public License
2119+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2120+ */
2121+
2122+import QtQuick 2.0
2123+
2124+Flickable {
2125+ id: root
2126+
2127+ signal clicked(int index, var result, var itemModel)
2128+ signal pressAndHold(int index)
2129+
2130+ property var cardTool: null
2131+ property real scopeHeight: 0
2132+ property real scopeWidth: 0
2133+ property real appliedScale: 1
2134+ property int currentIndex: -1
2135+ property var currentItem: currentIndex < repeater.count ? repeater.itemAt(currentIndex) : null
2136+
2137+ property alias model: repeater.model
2138+
2139+ contentHeight: height
2140+ contentWidth: repeater.count * root.scopeWidth + units.gu(2) / appliedScale * (repeater.count - 1)
2141+
2142+ contentX: {
2143+ var indexX = currentIndex * scopeWidth + units.gu(2) / appliedScale * currentIndex;
2144+ var newContentX = indexX - (width - scopeWidth) / 2;
2145+ newContentX = Math.min(Math.max(newContentX, 0), contentWidth - width);
2146+ return newContentX;
2147+ }
2148+
2149+ Repeater {
2150+ id: repeater
2151+ objectName: "scopesOverviewFavoritesRepeater"
2152+
2153+ delegate: Loader {
2154+ id: loader
2155+
2156+ x: index * root.scopeWidth + units.gu(2) / appliedScale * index
2157+ asynchronous: true
2158+
2159+ sourceComponent: cardTool.cardComponent
2160+ onLoaded: {
2161+ item.fixedArtShapeSize = Qt.binding(function() { return Qt.size(root.scopeWidth, root.scopeHeight); });
2162+ item.fixedHeaderHeight = Qt.binding(function() { return cardTool.headerHeight / appliedScale; });
2163+ item.fontScale = Qt.binding(function() { return 1 / appliedScale; });
2164+ item.height = Qt.binding(function() { return root.scopeHeight; });
2165+ item.width = Qt.binding(function() { return root.scopeWidth; });
2166+ item.cardData = Qt.binding(function() { return model; });
2167+ item.template = Qt.binding(function() { return cardTool.template; });
2168+ item.components = Qt.binding(function() { return cardTool.components; });
2169+ item.headerAlignment = Qt.binding(function() { return cardTool.headerAlignment; });
2170+ }
2171+
2172+ Connections {
2173+ target: loader.item
2174+ onClicked: root.clicked(index, result, model)
2175+ }
2176+ }
2177+ }
2178+}
2179
2180=== added file 'qml/Dash/ScopesOverviewTab.qml'
2181--- qml/Dash/ScopesOverviewTab.qml 1970-01-01 00:00:00 +0000
2182+++ qml/Dash/ScopesOverviewTab.qml 2014-08-08 15:11:52 +0000
2183@@ -0,0 +1,74 @@
2184+/*
2185+ * Copyright (C) 2014 Canonical, Ltd.
2186+ *
2187+ * This program is free software; you can redistribute it and/or modify
2188+ * it under the terms of the GNU General Public License as published by
2189+ * the Free Software Foundation; version 3.
2190+ *
2191+ * This program is distributed in the hope that it will be useful,
2192+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2193+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2194+ * GNU General Public License for more details.
2195+ *
2196+ * You should have received a copy of the GNU General Public License
2197+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2198+ */
2199+
2200+import QtQuick 2.3
2201+import Ubuntu.Components 0.1
2202+
2203+Item {
2204+ id: root
2205+
2206+ property int currentTab: 0
2207+
2208+ AbstractButton {
2209+ id: tab1
2210+ height: parent.height
2211+ width: parent.width / 2
2212+ Rectangle {
2213+ anchors.fill: parent
2214+ color: root.currentTab == 0 && root.enabled ? "white" : "transparent"
2215+ radius: units.dp(10)
2216+ }
2217+ Label {
2218+ anchors.centerIn: parent
2219+ text: i18n.tr("Favorites")
2220+ color: root.currentTab == 0 && root.enabled ? "black" : "white"
2221+ }
2222+ onClicked: root.currentTab = 0
2223+ }
2224+ AbstractButton {
2225+ id: tab2
2226+ objectName: "scopesOverviewAllTabButton"
2227+ x: width
2228+ height: parent.height
2229+ width: parent.width / 2
2230+ Rectangle {
2231+ anchors.fill: parent
2232+ color: root.currentTab == 1 && root.enabled ? "white" : "transparent"
2233+ radius: units.dp(10)
2234+ }
2235+ Label {
2236+ anchors.centerIn: parent
2237+ text: i18n.tr("All")
2238+ color: root.currentTab == 1 && root.enabled ? "black" : "white"
2239+ }
2240+ onClicked: root.currentTab = 1
2241+ }
2242+ Rectangle {
2243+ id: centerPiece
2244+ width: root.enabled ? units.dp(10) : units.dp(1)
2245+ height: parent.height
2246+ color: "white"
2247+ x: root.currentTab == 1 ? tab2.x : tab2.x - width
2248+ }
2249+ Rectangle {
2250+ id: border
2251+ anchors.fill: parent
2252+ radius: units.dp(10)
2253+ color: "transparent"
2254+ border.color: centerPiece.color
2255+ border.width: units.dp(1)
2256+ }
2257+}
2258
2259=== added file 'qml/Dash/graphics/dark_background.jpg'
2260Binary files qml/Dash/graphics/dark_background.jpg 1970-01-01 00:00:00 +0000 and qml/Dash/graphics/dark_background.jpg 2014-08-08 15:11:52 +0000 differ
2261=== added file 'qml/Dash/graphics/overview_hint@27.png'
2262Binary files qml/Dash/graphics/overview_hint@27.png 1970-01-01 00:00:00 +0000 and qml/Dash/graphics/overview_hint@27.png 2014-08-08 15:11:52 +0000 differ
2263=== modified file 'tests/autopilot/unity8/shell/tests/test_emulators.py'
2264--- tests/autopilot/unity8/shell/tests/test_emulators.py 2014-07-30 20:01:30 +0000
2265+++ tests/autopilot/unity8/shell/tests/test_emulators.py 2014-08-08 15:11:52 +0000
2266@@ -122,7 +122,7 @@
2267 self._assert_scope_is_opened(scope, scope_id)
2268
2269 def test_open_generic_scope(self):
2270- scope_id = 'scopes'
2271+ scope_id = 'musicaggregator'
2272 scope = self.dash.open_scope(scope_id)
2273 self._assert_scope_is_opened(scope, scope_id)
2274 self.assertIsInstance(scope, dash_emulators.GenericScopeView)
2275
2276=== modified file 'tests/mocks/Unity/CMakeLists.txt'
2277--- tests/mocks/Unity/CMakeLists.txt 2014-08-06 19:38:57 +0000
2278+++ tests/mocks/Unity/CMakeLists.txt 2014-08-08 15:11:52 +0000
2279@@ -22,6 +22,7 @@
2280 set(UnityQML_SOURCES
2281 fake_scope.cpp
2282 fake_scopes.cpp
2283+ fake_scopesoverview.cpp
2284 fake_categories.cpp
2285 fake_navigation.cpp
2286 fake_resultsmodel.cpp
2287
2288=== modified file 'tests/mocks/Unity/fake_resultsmodel.cpp'
2289--- tests/mocks/Unity/fake_resultsmodel.cpp 2014-05-20 10:29:20 +0000
2290+++ tests/mocks/Unity/fake_resultsmodel.cpp 2014-08-08 15:11:52 +0000
2291@@ -58,8 +58,9 @@
2292 case RoleUri:
2293 case RoleCategoryId:
2294 case RoleDndUri:
2295+ return QString();
2296 case RoleResult:
2297- return QString();
2298+ return QString("Result.%1.%2").arg(m_categoryId).arg(index.row());
2299 case RoleTitle:
2300 return QString("Title.%1.%2").arg(m_categoryId).arg(index.row());
2301 case RoleArt:
2302
2303=== modified file 'tests/mocks/Unity/fake_scope.cpp'
2304--- tests/mocks/Unity/fake_scope.cpp 2014-08-06 10:03:55 +0000
2305+++ tests/mocks/Unity/fake_scope.cpp 2014-08-08 15:11:52 +0000
2306@@ -18,14 +18,16 @@
2307 #include <QUrl>
2308
2309 #include "fake_scope.h"
2310+
2311 #include "fake_navigation.h"
2312 #include "fake_resultsmodel.h"
2313+#include "fake_scopes.h"
2314
2315-Scope::Scope(QObject* parent) : Scope(QString(), QString(), false, parent)
2316+Scope::Scope(Scopes* parent) : Scope(QString(), QString(), false, parent)
2317 {
2318 }
2319
2320-Scope::Scope(QString const& id, QString const& name, bool favorite, QObject* parent, int categories)
2321+Scope::Scope(QString const& id, QString const& name, bool favorite, Scopes* parent, int categories)
2322 : unity::shell::scopes::ScopeInterface(parent)
2323 , m_id(id)
2324 , m_name(name)
2325@@ -36,6 +38,7 @@
2326 , m_currentAltNavigationId("altroot")
2327 , m_previewRendererName("preview-generic")
2328 , m_categories(new Categories(categories, this))
2329+ , m_openScope(nullptr)
2330 {
2331 }
2332
2333@@ -158,7 +161,12 @@
2334
2335 void Scope::activate(QVariant const& result)
2336 {
2337- Q_UNUSED(result);
2338+ qDebug() << "Called activate on scope" << m_id << "with result" << result;
2339+ if (result.toString() == "Result.2.2") {
2340+ Scopes *scopes = dynamic_cast<Scopes*>(parent());
2341+ m_openScope = scopes->getScopeFromAll("MockScope9");
2342+ Q_EMIT openScope(m_openScope);
2343+ }
2344 }
2345
2346 PreviewStack* Scope::preview(QVariant const& result)
2347@@ -174,9 +182,13 @@
2348 {
2349 }
2350
2351-void Scope::closeScope(unity::shell::scopes::ScopeInterface* /*scope*/)
2352+void Scope::closeScope(unity::shell::scopes::ScopeInterface* scope)
2353 {
2354- qFatal("Scope::closeScope is not implemented");
2355+ if (scope != m_openScope) {
2356+ qDebug() << scope << m_openScope;
2357+ qFatal("Scope::closeScope got wrong scope in closeScope");
2358+ }
2359+ m_openScope = nullptr;
2360 }
2361
2362 QString Scope::currentNavigationId() const
2363
2364=== modified file 'tests/mocks/Unity/fake_scope.h'
2365--- tests/mocks/Unity/fake_scope.h 2014-08-06 10:03:55 +0000
2366+++ tests/mocks/Unity/fake_scope.h 2014-08-08 15:11:52 +0000
2367@@ -24,13 +24,15 @@
2368
2369 #include <QTimer>
2370
2371+class Scopes;
2372+
2373 class Scope : public unity::shell::scopes::ScopeInterface
2374 {
2375 Q_OBJECT
2376
2377 public:
2378- Scope(QObject* parent = 0);
2379- Scope(QString const& id, QString const& name, bool favorite, QObject* parent = 0, int categories = 20);
2380+ Scope(Scopes* parent = 0);
2381+ Scope(QString const& id, QString const& name, bool favorite, Scopes* parent = 0, int categories = 20);
2382
2383 /* getters */
2384 QString id() const override;
2385@@ -92,7 +94,8 @@
2386
2387 QString m_previewRendererName;
2388
2389- Categories* m_categories;
2390+ unity::shell::scopes::CategoriesInterface* m_categories;
2391+ unity::shell::scopes::ScopeInterface* m_openScope;
2392 };
2393
2394 #endif // FAKE_SCOPE_H
2395
2396=== modified file 'tests/mocks/Unity/fake_scopes.cpp'
2397--- tests/mocks/Unity/fake_scopes.cpp 2014-08-06 19:38:57 +0000
2398+++ tests/mocks/Unity/fake_scopes.cpp 2014-08-08 15:11:52 +0000
2399@@ -18,6 +18,7 @@
2400
2401 // Self
2402 #include "fake_scopes.h"
2403+#include "fake_scopesoverview.h"
2404
2405 // TODO: Implement remaining pieces, like Categories (i.e. LensView now gives warnings)
2406
2407@@ -26,6 +27,7 @@
2408
2409 Scopes::Scopes(QObject *parent)
2410 : unity::shell::scopes::ScopesInterface(parent)
2411+ , m_scopesOverview(nullptr)
2412 , m_loaded(false)
2413 , timer(this)
2414 {
2415@@ -52,10 +54,17 @@
2416 addScope(new Scope("clickscope", "Apps", true, this));
2417 addScope(new Scope("MockScope5", "Videos", true, this));
2418 addScope(new Scope("SingleCategoryScope", "Single", true, this, 1));
2419+ addScope(new Scope("MockScope4", "MS4", true, this));
2420+ addScope(new Scope("MockScope6", "MS6", true, this));
2421+ addScope(new Scope("MockScope7", "MS7", false, this));
2422+ addScope(new Scope("MockScope8", "MS8", false, this));
2423+ addScope(new Scope("MockScope9", "MS9", false, this));
2424+ m_scopesOverview = new ScopesOverview(this);
2425
2426 if (!m_loaded) {
2427 m_loaded = true;
2428 Q_EMIT loadedChanged();
2429+ Q_EMIT overviewScopeChanged();
2430 }
2431 }
2432
2433@@ -64,10 +73,13 @@
2434 timer.stop();
2435 if (m_scopes.size() > 0) {
2436 beginRemoveRows(QModelIndex(), 0, m_scopes.count()-1);
2437- qDeleteAll(m_scopes);
2438+ qDeleteAll(m_allScopes);
2439+ m_allScopes.clear();
2440 m_scopes.clear();
2441 endRemoveRows();
2442 }
2443+ delete m_scopesOverview;
2444+ m_scopesOverview = nullptr;
2445
2446 if (m_loaded) {
2447 m_loaded = false;
2448@@ -113,8 +125,22 @@
2449 return m_scopes[row];
2450 }
2451
2452-unity::shell::scopes::ScopeInterface* Scopes::getScope(QString const&) const
2453-{
2454+unity::shell::scopes::ScopeInterface* Scopes::getScope(QString const &scope_id) const
2455+{
2456+ // According to mh3 Scopes::getScope should only return favorite scopes (i.e the ones in the model)
2457+ for (Scope *scope : m_scopes) {
2458+ if (scope->id() == scope_id)
2459+ return scope;
2460+ }
2461+ return nullptr;
2462+}
2463+
2464+Scope* Scopes::getScopeFromAll(const QString& scope_id) const
2465+{
2466+ for (Scope *scope : m_allScopes) {
2467+ if (scope->id() == scope_id)
2468+ return scope;
2469+ }
2470 return nullptr;
2471 }
2472
2473@@ -135,13 +161,26 @@
2474
2475 unity::shell::scopes::ScopeInterface* Scopes::overviewScope() const
2476 {
2477- return nullptr;
2478+ return m_scopesOverview;
2479+}
2480+
2481+QList<Scope*> Scopes::scopes() const
2482+{
2483+ return m_scopes;
2484+}
2485+
2486+QList<Scope*> Scopes::allScopes() const
2487+{
2488+ return m_allScopes;
2489 }
2490
2491 void Scopes::addScope(Scope* scope)
2492 {
2493 int index = rowCount();
2494- beginInsertRows(QModelIndex(), index, index);
2495- m_scopes.append(scope);
2496- endInsertRows();
2497+ if (scope->favorite()) {
2498+ beginInsertRows(QModelIndex(), index, index);
2499+ m_scopes.append(scope);
2500+ endInsertRows();
2501+ }
2502+ m_allScopes.append(scope);
2503 }
2504
2505=== modified file 'tests/mocks/Unity/fake_scopes.h'
2506--- tests/mocks/Unity/fake_scopes.h 2014-08-06 19:38:57 +0000
2507+++ tests/mocks/Unity/fake_scopes.h 2014-08-08 15:11:52 +0000
2508@@ -53,11 +53,18 @@
2509 int count() const override;
2510 unity::shell::scopes::ScopeInterface* overviewScope() const override;
2511
2512+ // This is used as part of implementation of the other C++ code, not API
2513+ QList<Scope*> scopes() const;
2514+ QList<Scope*> allScopes() const;
2515+ Scope* getScopeFromAll(const QString& scope_id) const;
2516+
2517 private Q_SLOTS:
2518 void updateScopes();
2519
2520 private:
2521- QList<Scope*> m_scopes;
2522+ QList<Scope*> m_scopes; // the favorite ones
2523+ QList<Scope*> m_allScopes;
2524+ Scope *m_scopesOverview;
2525 bool m_loaded;
2526 QTimer timer;
2527 };
2528
2529=== added file 'tests/mocks/Unity/fake_scopesoverview.cpp'
2530--- tests/mocks/Unity/fake_scopesoverview.cpp 1970-01-01 00:00:00 +0000
2531+++ tests/mocks/Unity/fake_scopesoverview.cpp 2014-08-08 15:11:52 +0000
2532@@ -0,0 +1,281 @@
2533+/*
2534+ * Copyright (C) 2014 Canonical, Ltd.
2535+ *
2536+ * This program is free software; you can redistribute it and/or modify
2537+ * it under the terms of the GNU General Public License as published by
2538+ * the Free Software Foundation; version 3.
2539+ *
2540+ * This program is distributed in the hope that it will be useful,
2541+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2542+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2543+ * GNU General Public License for more details.
2544+ *
2545+ * You should have received a copy of the GNU General Public License
2546+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2547+ */
2548+
2549+#include "fake_scopesoverview.h"
2550+
2551+#include "fake_scopes.h"
2552+
2553+#include <paths.h>
2554+
2555+ScopesOverview::ScopesOverview(Scopes* parent)
2556+ : Scope("scopesOverview", "Scopes Overview", false, parent)
2557+{
2558+ delete m_categories; // delete the usual categories, we're not going to use it
2559+ m_scopesOverviewCategories = new ScopesOverviewCategories(parent, this);
2560+ m_searchCategories = new ScopesOverviewSearchCategories(parent, this);
2561+ m_categories = m_scopesOverviewCategories;
2562+}
2563+
2564+void ScopesOverview::setSearchQuery(const QString& search_query)
2565+{
2566+ Scope::setSearchQuery(search_query);
2567+
2568+ auto origCategories = m_categories;
2569+ if (search_query.isEmpty()) m_categories = m_scopesOverviewCategories;
2570+ else m_categories = m_searchCategories;
2571+
2572+ if (m_categories != origCategories)
2573+ Q_EMIT categoriesChanged();
2574+}
2575+
2576+Q_INVOKABLE void ScopesOverview::activate(QVariant const& result)
2577+{
2578+ Scopes *scopes = dynamic_cast<Scopes*>(parent());
2579+ m_openScope = scopes->getScopeFromAll(result.toString());
2580+ Q_EMIT openScope(m_openScope);
2581+}
2582+
2583+ScopesOverviewCategories::ScopesOverviewCategories(Scopes *scopes, QObject* parent)
2584+ : unity::shell::scopes::CategoriesInterface(parent)
2585+ , m_scopes(scopes)
2586+{
2587+}
2588+
2589+int ScopesOverviewCategories::rowCount(const QModelIndex& /*parent*/) const
2590+{
2591+ return 2;
2592+}
2593+
2594+void ScopesOverviewCategories::addSpecialCategory(QString const&, QString const&, QString const&, QString const&, QObject*)
2595+{
2596+ qFatal("Using un-implemented ScopesOverviewCategories::addSpecialCategory");
2597+}
2598+
2599+bool ScopesOverviewCategories::overrideCategoryJson(QString const& /* categoryId */, QString const& /* json */)
2600+{
2601+ qFatal("Using un-implemented ScopesOverviewCategories::overrideCategoryJson");
2602+}
2603+
2604+QVariant
2605+ScopesOverviewCategories::data(const QModelIndex& index, int role) const
2606+{
2607+ if (!index.isValid()) {
2608+ return QVariant();
2609+ }
2610+
2611+ const QString categoryId = index.row() == 0 ? "favorites" : "all";
2612+
2613+ unity::shell::scopes::ResultsModelInterface *resultsModel = m_resultsModels[index.row()];
2614+ if (!resultsModel) {
2615+ QObject *that = const_cast<ScopesOverviewCategories*>(this);
2616+ QList<Scope*> scopes = index.row() == 0 ? m_scopes->scopes() : m_scopes->allScopes();
2617+ resultsModel = new ScopesOverviewResultsModel(scopes, categoryId, that);
2618+ m_resultsModels[index.row()] = resultsModel;
2619+ }
2620+ switch (role) {
2621+ case RoleCategoryId:
2622+ return categoryId;
2623+ case RoleName:
2624+ return index.row() == 0 ? "Favorites" : "All";
2625+ case RoleIcon:
2626+ return QVariant();
2627+ case RoleRawRendererTemplate:
2628+ qFatal("Using un-implemented RoleRawRendererTemplate Categories role");
2629+ return QVariant();
2630+ case RoleRenderer:
2631+ {
2632+ QVariantMap map;
2633+ map["category-layout"] = "grid";
2634+ map["card-size"] = "small";
2635+ map["overlay"] = true;
2636+ return map;
2637+ }
2638+ case RoleComponents:
2639+ {
2640+ QVariantMap map, artMap;
2641+ artMap["aspect-ratio"] = "0.5";
2642+ artMap["field"] = "art";
2643+ map["art"] = artMap;
2644+ map["title"] = "HOLA";
2645+ return map;
2646+ }
2647+ case RoleResults:
2648+ return QVariant::fromValue(resultsModel);
2649+ case RoleCount:
2650+ return resultsModel->rowCount();
2651+ case RoleHeaderLink:
2652+ return QString();
2653+ default:
2654+ qFatal("Using un-implemented Categories role");
2655+ return QVariant();
2656+ }
2657+}
2658+
2659+
2660+
2661+ScopesOverviewSearchCategories::ScopesOverviewSearchCategories(Scopes *scopes, QObject* parent)
2662+ : unity::shell::scopes::CategoriesInterface(parent)
2663+ , m_scopes(scopes)
2664+{
2665+}
2666+
2667+int ScopesOverviewSearchCategories::rowCount(const QModelIndex& /*parent*/) const
2668+{
2669+ return 2;
2670+}
2671+
2672+void ScopesOverviewSearchCategories::addSpecialCategory(QString const&, QString const&, QString const&, QString const&, QObject*)
2673+{
2674+ qFatal("Using un-implemented ScopesOverviewSearchCategories::addSpecialCategory");
2675+}
2676+
2677+bool ScopesOverviewSearchCategories::overrideCategoryJson(QString const& /* categoryId */, QString const& /* json */)
2678+{
2679+ qFatal("Using un-implemented ScopesOverviewSearchCategories::overrideCategoryJson");
2680+}
2681+
2682+QVariant
2683+ScopesOverviewSearchCategories::data(const QModelIndex& index, int role) const
2684+{
2685+ if (!index.isValid()) {
2686+ return QVariant();
2687+ }
2688+
2689+ const QString categoryId = index.row() == 0 ? "searchA" : "searchB";
2690+
2691+ unity::shell::scopes::ResultsModelInterface *resultsModel = m_resultsModels[index.row()];
2692+ if (!resultsModel) {
2693+ QObject *that = const_cast<ScopesOverviewSearchCategories*>(this);
2694+ QList<Scope *> scopes;
2695+ if (index.row() == 0) {
2696+ scopes << m_scopes->getScopeFromAll("clickscope") << nullptr << m_scopes->getScopeFromAll("MockScope2");
2697+ } else {
2698+ scopes << nullptr << m_scopes->getScopeFromAll("MockScope7") << nullptr << m_scopes->getScopeFromAll("MockScope1");
2699+ }
2700+ resultsModel = new ScopesOverviewResultsModel(scopes, categoryId, that);
2701+ m_resultsModels[index.row()] = resultsModel;
2702+ }
2703+ switch (role) {
2704+ case RoleCategoryId:
2705+ return categoryId;
2706+ case RoleName:
2707+ return index.row() == 0 ? "SearchA" : "SearchB";
2708+ case RoleIcon:
2709+ return QVariant();
2710+ case RoleRawRendererTemplate:
2711+ qFatal("Using un-implemented RoleRawRendererTemplate Categories role");
2712+ return QVariant();
2713+ case RoleRenderer:
2714+ {
2715+ QVariantMap map;
2716+ map["category-layout"] = "grid";
2717+ map["card-size"] = "small";
2718+ map["overlay"] = true;
2719+ return map;
2720+ }
2721+ case RoleComponents:
2722+ {
2723+ QVariantMap map, artMap;
2724+ artMap["aspect-ratio"] = "1";
2725+ artMap["field"] = "art";
2726+ map["art"] = artMap;
2727+ map["title"] = "HOLA";
2728+ return map;
2729+ }
2730+ case RoleResults:
2731+ return QVariant::fromValue(resultsModel);
2732+ case RoleCount:
2733+ return resultsModel->rowCount();
2734+ case RoleHeaderLink:
2735+ return QString();
2736+ default:
2737+ qFatal("Using un-implemented Categories role");
2738+ return QVariant();
2739+ }
2740+}
2741+
2742+
2743+ScopesOverviewResultsModel::ScopesOverviewResultsModel(const QList<Scope *> &scopes, const QString &categoryId, QObject* parent)
2744+ : unity::shell::scopes::ResultsModelInterface(parent)
2745+ , m_scopes(scopes)
2746+ , m_categoryId(categoryId)
2747+{
2748+}
2749+
2750+QString ScopesOverviewResultsModel::categoryId() const
2751+{
2752+ return m_categoryId;
2753+}
2754+
2755+void ScopesOverviewResultsModel::setCategoryId(QString const& /*id*/)
2756+{
2757+ qFatal("Calling un-implemented ScopesOverviewResultsModel::setCategoryId");
2758+}
2759+
2760+int ScopesOverviewResultsModel::scopeIndex(QString const& id) const
2761+{
2762+ const int scopeCount = count();
2763+ for (int i = 0; i < scopeCount; ++i) {
2764+ if (m_scopes[i]->id() == id)
2765+ return i;
2766+ }
2767+ return -1;
2768+}
2769+
2770+QHash<int, QByteArray> ScopesOverviewResultsModel::roleNames() const
2771+{
2772+ QHash<int, QByteArray> roles = unity::shell::scopes::ResultsModelInterface::roleNames();
2773+ roles[RoleBackground + 1] = "scopeId";
2774+ return roles;
2775+}
2776+
2777+int ScopesOverviewResultsModel::rowCount(const QModelIndex& parent) const
2778+{
2779+ Q_UNUSED(parent);
2780+
2781+ return m_scopes.count();
2782+}
2783+
2784+int ScopesOverviewResultsModel::count() const
2785+{
2786+ return rowCount();
2787+}
2788+
2789+QVariant
2790+ScopesOverviewResultsModel::data(const QModelIndex& index, int role) const
2791+{
2792+ unity::shell::scopes::ScopeInterface *scope = m_scopes[index.row()];
2793+ switch (role) {
2794+ case RoleUri:
2795+ case RoleCategoryId:
2796+ case RoleDndUri:
2797+ return QString();
2798+ case RoleResult:
2799+ return scope ? scope->id() : QString("Result.%1.%2").arg(categoryId()).arg(index.row());
2800+ case RoleTitle:
2801+ return scope ? scope->name() : QString("Title.%1.%2").arg(categoryId()).arg(index.row());
2802+ case RoleArt:
2803+ return qmlDirectory() + "graphics/applicationIcons/dash.png";
2804+ case RoleMascot:
2805+ case RoleEmblem:
2806+ case RoleSummary:
2807+ case RoleBackground + 1: // scopeId
2808+ return scope ? scope->id() : nullptr;
2809+ break;
2810+ default:
2811+ return QVariant();
2812+ }
2813+}
2814
2815=== added file 'tests/mocks/Unity/fake_scopesoverview.h'
2816--- tests/mocks/Unity/fake_scopesoverview.h 1970-01-01 00:00:00 +0000
2817+++ tests/mocks/Unity/fake_scopesoverview.h 2014-08-08 15:11:52 +0000
2818@@ -0,0 +1,104 @@
2819+/*
2820+ * Copyright (C) 2014 Canonical, Ltd.
2821+ *
2822+ * This program is free software; you can redistribute it and/or modify
2823+ * it under the terms of the GNU General Public License as published by
2824+ * the Free Software Foundation; version 3.
2825+ *
2826+ * This program is distributed in the hope that it will be useful,
2827+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2828+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2829+ * GNU General Public License for more details.
2830+ *
2831+ * You should have received a copy of the GNU General Public License
2832+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2833+ */
2834+
2835+#ifndef FAKE_SCOPESOVERVIEW_H
2836+#define FAKE_SCOPESOVERVIEW_H
2837+
2838+#include "fake_scope.h"
2839+#include <unity/shell/scopes/ResultsModelInterface.h>
2840+
2841+class Scopes;
2842+
2843+class ScopesOverview : public Scope
2844+{
2845+ Q_OBJECT
2846+
2847+public:
2848+ ScopesOverview(Scopes* parent = 0);
2849+
2850+ void setSearchQuery(const QString& search_query) override;
2851+ Q_INVOKABLE void activate(QVariant const& result) override;
2852+
2853+private:
2854+ unity::shell::scopes::CategoriesInterface *m_scopesOverviewCategories;
2855+ unity::shell::scopes::CategoriesInterface *m_searchCategories;
2856+};
2857+
2858+class ScopesOverviewCategories : public unity::shell::scopes::CategoriesInterface
2859+{
2860+ Q_OBJECT
2861+
2862+public:
2863+ ScopesOverviewCategories(Scopes *scopes, QObject* parent = 0);
2864+
2865+ QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
2866+ int rowCount(const QModelIndex& parent = QModelIndex()) const override;
2867+
2868+ Q_INVOKABLE void addSpecialCategory(QString const& categoryId, QString const& name, QString const& icon, QString const& rawTemplate, QObject* countObject) override;
2869+ Q_INVOKABLE bool overrideCategoryJson(QString const& categoryId, QString const& json) override;
2870+
2871+private:
2872+ mutable QHash<int, unity::shell::scopes::ResultsModelInterface*> m_resultsModels;
2873+
2874+ Scopes *m_scopes;
2875+};
2876+
2877+class ScopesOverviewSearchCategories : public unity::shell::scopes::CategoriesInterface
2878+{
2879+ Q_OBJECT
2880+
2881+public:
2882+ ScopesOverviewSearchCategories(Scopes *scopes, QObject* parent = 0);
2883+
2884+ QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
2885+ int rowCount(const QModelIndex& parent = QModelIndex()) const override;
2886+
2887+ Q_INVOKABLE void addSpecialCategory(QString const& categoryId, QString const& name, QString const& icon, QString const& rawTemplate, QObject* countObject) override;
2888+ Q_INVOKABLE bool overrideCategoryJson(QString const& categoryId, QString const& json) override;
2889+
2890+private:
2891+ mutable QHash<int, unity::shell::scopes::ResultsModelInterface*> m_resultsModels;
2892+
2893+ Scopes *m_scopes;
2894+};
2895+
2896+class ScopesOverviewResultsModel : public unity::shell::scopes::ResultsModelInterface
2897+{
2898+ Q_OBJECT
2899+
2900+public:
2901+ explicit ScopesOverviewResultsModel(const QList<Scope *> &scopes, const QString &categoryId, QObject* parent = 0);
2902+
2903+ int rowCount(const QModelIndex& parent = QModelIndex()) const override;
2904+ QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
2905+
2906+ /* getters */
2907+ QString categoryId() const override;
2908+ int count() const override;
2909+
2910+ /* setters */
2911+ void setCategoryId(QString const& id) override;
2912+
2913+ /* Special API */
2914+ Q_INVOKABLE int scopeIndex(QString const& id) const;
2915+ QHash<int, QByteArray> roleNames() const override;
2916+
2917+private:
2918+ QList<Scope *> m_scopes;
2919+ QString m_categoryId;
2920+};
2921+
2922+#endif // FAKE_SCOPESOVERVIEW_H
2923
2924=== modified file 'tests/plugins/Dash/cardcreator/2.res'
2925--- tests/plugins/Dash/cardcreator/2.res 2014-07-31 13:33:56 +0000
2926+++ tests/plugins/Dash/cardcreator/2.res 2014-08-08 15:11:52 +0000
2927@@ -89,7 +89,7 @@
2928 wrapMode: Text.Wrap;
2929 maximumLineCount: 2;
2930 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
2931- color: backgroundLoader.active && backgroundLoader.item && backgroundLoader.item.luminance < 0.7 ? "white" : (root.scopeStyle ? root.scopeStyle.foreground : "grey");
2932+ color: backgroundLoader.active && backgroundLoader.item && backgroundLoader.item.luminance < (root.scopeStyle ? root.scopeStyle.threshold : 0.7) ? (root.scopeStyle ? root.scopeStyle.light : "white") : (root.scopeStyle ? root.scopeStyle.dark : "grey");
2933 visible: showHeader ;
2934 text: root.title;
2935 font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal;
2936@@ -104,7 +104,7 @@
2937 elide: Text.ElideRight;
2938 fontSize: "small";
2939 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
2940- color: backgroundLoader.active && backgroundLoader.item && backgroundLoader.item.luminance < 0.7 ? "white" : (root.scopeStyle ? root.scopeStyle.foreground : "grey");
2941+ color: backgroundLoader.active && backgroundLoader.item && backgroundLoader.item.luminance < (root.scopeStyle ? root.scopeStyle.threshold : 0.7) ? (root.scopeStyle ? root.scopeStyle.light : "white") : (root.scopeStyle ? root.scopeStyle.dark : "grey");
2942 visible: titleLabel.visible && titleLabel.text;
2943 text: cardData && cardData["subtitle"] || "";
2944 font.weight: Font.Light;
2945
2946=== modified file 'tests/plugins/Dash/cardcreator/5.res'
2947--- tests/plugins/Dash/cardcreator/5.res 2014-08-05 22:51:17 +0000
2948+++ tests/plugins/Dash/cardcreator/5.res 2014-08-08 15:11:52 +0000
2949@@ -68,8 +68,9 @@
2950 visible: showHeader && status == Loader.Ready;
2951 sourceComponent: ShaderEffect {
2952 id: overlay;
2953- height: (fixedHeaderHeight > 0 ? fixedHeaderHeight : headerHeight) + units.gu(2);
2954- opacity: 0.6;
2955+ height: (fixedHeaderHeight > 0 ? fixedHeaderHeight : headerHeight) + units.gu(2);
2956+ property real luminance: 0.2126 * overlayColor.r + 0.7152 * overlayColor.g + 0.0722 * overlayColor.b;
2957+ property color overlayColor: cardData && cardData["overlayColor"] || "#99000000";
2958 property var source: ShaderEffectSource {
2959 id: shaderSource;
2960 sourceItem: artShapeLoader.item;
2961@@ -90,15 +91,16 @@
2962 varying highp vec2 coord;
2963 uniform sampler2D source;
2964 uniform lowp float qt_Opacity;
2965+ uniform highp vec4 overlayColor;
2966 void main() {
2967 lowp vec4 tex = texture2D(source, coord);
2968- gl_FragColor = vec4(0, 0, 0, tex.a) * qt_Opacity;
2969+ gl_FragColor = vec4(overlayColor.r, overlayColor.g, overlayColor.b, 1) * qt_Opacity * overlayColor.a * tex.a;
2970 }";
2971 }
2972 }
2973 readonly property int headerHeight: titleLabel.height + subtitleLabel.height + subtitleLabel.anchors.topMargin;
2974 Label {
2975- id: titleLabel;
2976+ id: titleLabel;
2977 objectName: "titleLabel";
2978 anchors { left: parent.left;
2979 leftMargin: units.gu(1);
2980@@ -112,7 +114,7 @@
2981 wrapMode: Text.Wrap;
2982 maximumLineCount: 2;
2983 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
2984- color: "white";
2985+ color: overlayLoader.item.luminance < (root.scopeStyle ? root.scopeStyle.threshold : 0.7) ? (root.scopeStyle ? root.scopeStyle.light : "white") : (root.scopeStyle ? root.scopeStyle.dark : "grey");
2986 visible: showHeader && overlayLoader.active;
2987 text: root.title;
2988 font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal;
2989@@ -131,7 +133,7 @@
2990 elide: Text.ElideRight;
2991 fontSize: "small";
2992 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
2993- color: "white";
2994+ color: overlayLoader.item.luminance < (root.scopeStyle ? root.scopeStyle.threshold : 0.7) ? (root.scopeStyle ? root.scopeStyle.light : "white") : (root.scopeStyle ? root.scopeStyle.dark : "grey");
2995 visible: titleLabel.visible && titleLabel.text;
2996 text: cardData && cardData["subtitle"] || "";
2997 font.weight: Font.Light;
2998
2999=== modified file 'tests/plugins/Dash/cardcreator/7.res'
3000--- tests/plugins/Dash/cardcreator/7.res 2014-08-05 22:51:17 +0000
3001+++ tests/plugins/Dash/cardcreator/7.res 2014-08-08 15:11:52 +0000
3002@@ -90,7 +90,7 @@
3003 wrapMode: Text.Wrap;
3004 maximumLineCount: 2;
3005 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
3006- color: backgroundLoader.active && backgroundLoader.item && backgroundLoader.item.luminance < 0.7 ? "white" : (root.scopeStyle ? root.scopeStyle.foreground : "grey");
3007+ color: backgroundLoader.active && backgroundLoader.item && backgroundLoader.item.luminance < (root.scopeStyle ? root.scopeStyle.threshold : 0.7) ? (root.scopeStyle ? root.scopeStyle.light : "white") : (root.scopeStyle ? root.scopeStyle.dark : "grey");
3008 visible: showHeader ;
3009 text: root.title;
3010 font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal;
3011@@ -104,7 +104,7 @@
3012 elide: Text.ElideRight;
3013 fontSize: "small";
3014 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
3015- color: backgroundLoader.active && backgroundLoader.item && backgroundLoader.item.luminance < 0.7 ? "white" : (root.scopeStyle ? root.scopeStyle.foreground : "grey");
3016+ color: backgroundLoader.active && backgroundLoader.item && backgroundLoader.item.luminance < (root.scopeStyle ? root.scopeStyle.threshold : 0.7) ? (root.scopeStyle ? root.scopeStyle.light : "white") : (root.scopeStyle ? root.scopeStyle.dark : "grey");
3017 visible: titleLabel.visible && titleLabel.text;
3018 text: cardData && cardData["subtitle"] || "";
3019 font.weight: Font.Light;
3020@@ -115,8 +115,8 @@
3021 id: attributesRow;
3022 objectName: "attributesRow";
3023 anchors { left: parent.left; right: parent.right }
3024- color: backgroundLoader.active && backgroundLoader.item && backgroundLoader.item.luminance < 0.7 ? "white" : (root.scopeStyle ? root.scopeStyle.foreground : "grey");
3025- model: cardData["attributes"];
3026+ color: backgroundLoader.active && backgroundLoader.item && backgroundLoader.item.luminance < (root.scopeStyle ? root.scopeStyle.threshold : 0.7) ? (root.scopeStyle ? root.scopeStyle.light : "white") : (root.scopeStyle ? root.scopeStyle.dark : "grey");
3027+ model: cardData["attributes"];
3028 }
3029
3030 ]
3031
3032=== modified file 'tests/plugins/Dash/tst_ScopeStyle.qml'
3033--- tests/plugins/Dash/tst_ScopeStyle.qml 2014-07-25 11:42:06 +0000
3034+++ tests/plugins/Dash/tst_ScopeStyle.qml 2014-08-08 15:11:52 +0000
3035@@ -101,7 +101,7 @@
3036
3037 function test_threshold_data() {
3038 return [
3039- { tag: "default", index: 0, threshold: 0.5020 },
3040+ { tag: "default", index: 0, threshold: 0.7510 },
3041 { tag: "red on black", index: 1, threshold: 0.1063 },
3042 { tag: "green on white", index: 2, threshold: 0.6795 },
3043 { tag: "blue on darkgrey", index: 3, threshold: 0.3675 },
3044
3045=== modified file 'tests/qmltests/Dash/tst_Dash.qml'
3046--- tests/qmltests/Dash/tst_Dash.qml 2014-08-06 14:50:25 +0000
3047+++ tests/qmltests/Dash/tst_Dash.qml 2014-08-08 15:11:52 +0000
3048@@ -20,8 +20,6 @@
3049 import Ubuntu.Components 0.1
3050 import Unity.Test 0.1 as UT
3051
3052-// TODO We don't have any tests for the overlay scope functionality.
3053-
3054 Item {
3055 id: shell
3056 width: units.gu(40)
3057@@ -61,9 +59,9 @@
3058 function get_scope_data() {
3059 return [
3060 { tag: "MockScope1", visualIndex: 0 },
3061- { tag: "MockScope2", visualIndex: 1 },
3062- { tag: "clickscope", visualIndex: 2 },
3063- { tag: "MockScope5", visualIndex: 3 },
3064+ { tag: "MockScope2", visualIndex: -1 },
3065+ { tag: "clickscope", visualIndex: 1 },
3066+ { tag: "MockScope5", visualIndex: 2 },
3067 ]
3068 }
3069
3070@@ -79,10 +77,234 @@
3071 tryCompare(dashContentList, "count", 0);
3072 scopes.load();
3073 tryCompare(scopes, "loaded", true);
3074- tryCompare(dashContentList, "count", 5);
3075+ tryCompare(dashContentList, "count", 6);
3076
3077 verify(dashContentList != undefined);
3078- tryCompare(dashContentList, "currentIndex", data.visualIndex);
3079+ if (data.visualIndex == -1) {
3080+ tryCompare(dashContentList, "currentIndex", 0);
3081+ expectFail(data.tag, "non favorite scopes should not be visble in the scopes model");
3082+ compare(dashContentList.currentItem.scopeId, data.tag); // this should fail
3083+ } else {
3084+ tryCompare(dashContentList, "currentIndex", data.visualIndex);
3085+ compare(dashContentList.currentItem.scopeId, data.tag);
3086+ }
3087+ }
3088+
3089+ function test_dash_overview_show_select_same_favorite() {
3090+ // Wait for stuff to be loaded
3091+ tryCompare(scopes, "loaded", true);
3092+ var dashContentList = findChild(dash, "dashContentList");
3093+ tryCompare(dashContentList, "count", 6);
3094+ var mockScope1Loader = findChild(dash, "MockScope1 loader");
3095+ tryCompareFunction(function() { return mockScope1Loader.item != null; }, true);
3096+
3097+ // Show the overview
3098+ touchFlick(dash, dash.width / 2, dash.height - 1, dash.width / 2, dash.height - units.gu(18));
3099+ var overviewController = findInvisibleChild(dash, "overviewController");
3100+ tryCompare(overviewController, "progress", 1);
3101+
3102+ // Make sure tab is where it should
3103+ var scopesOverview = findChild(dash, "scopesOverview");
3104+ compare(scopesOverview.currentTab, 0);
3105+
3106+ // Make sure stuff is loaded
3107+ var scopesOverviewFavoritesRepeater = findChild(dash, "scopesOverviewFavoritesRepeater");
3108+ tryCompare(scopesOverviewFavoritesRepeater, "count", 6);
3109+ tryCompareFunction(function() { return scopesOverviewFavoritesRepeater.itemAt(0).item != null; }, true);
3110+ waitForRendering(scopesOverviewFavoritesRepeater.itemAt(0).item);
3111+
3112+ // Click in first item
3113+ mouseClick(scopesOverviewFavoritesRepeater.itemAt(0).item, 0, 0);
3114+
3115+ // Make sure animation went back
3116+ tryCompare(overviewController, "progress", 0);
3117+ compare(dashContentList.currentIndex, 0);
3118+ }
3119+
3120+ function test_dash_overview_show_select_different_favorite() {
3121+ // Wait for stuff to be loaded
3122+ tryCompare(scopes, "loaded", true);
3123+ var dashContentList = findChild(dash, "dashContentList");
3124+ tryCompare(dashContentList, "count", 6);
3125+ var mockScope1Loader = findChild(dash, "MockScope1 loader");
3126+ tryCompareFunction(function() { return mockScope1Loader.item != null; }, true);
3127+
3128+ // Show the overview
3129+ touchFlick(dash, dash.width / 2, dash.height - 1, dash.width / 2, dash.height - units.gu(18));
3130+ var overviewController = findInvisibleChild(dash, "overviewController");
3131+ tryCompare(overviewController, "progress", 1);
3132+
3133+ // Make sure tab is where it should
3134+ var scopesOverview = findChild(dash, "scopesOverview");
3135+ compare(scopesOverview.currentTab, 0);
3136+
3137+ // Make sure stuff is loaded
3138+ var scopesOverviewFavoritesRepeater = findChild(dash, "scopesOverviewFavoritesRepeater");
3139+ tryCompare(scopesOverviewFavoritesRepeater, "count", 6);
3140+ tryCompareFunction(function() { return scopesOverviewFavoritesRepeater.itemAt(0).item != null; }, true);
3141+ waitForRendering(scopesOverviewFavoritesRepeater.itemAt(1).item);
3142+
3143+ // Click in first item
3144+ mouseClick(scopesOverviewFavoritesRepeater.itemAt(1).item, 0, 0);
3145+
3146+ // Make sure animation went back
3147+ tryCompare(overviewController, "progress", 0);
3148+ compare(dashContentList.currentIndex, 1);
3149+ }
3150+
3151+ function test_dash_overview_all_temp_scope_done_from_all() {
3152+ // Wait for stuff to be loaded
3153+ tryCompare(scopes, "loaded", true);
3154+ var dashContentList = findChild(dash, "dashContentList");
3155+ tryCompare(dashContentList, "count", 6);
3156+ var mockScope1Loader = findChild(dash, "MockScope1 loader");
3157+ tryCompareFunction(function() { return mockScope1Loader.item != null; }, true);
3158+
3159+ // Show the overview
3160+ touchFlick(dash, dash.width / 2, dash.height - 1, dash.width / 2, dash.height - units.gu(18));
3161+ var overviewController = findInvisibleChild(dash, "overviewController");
3162+ tryCompare(overviewController, "progress", 1);
3163+
3164+ // Make sure tab is where it should
3165+ var scopesOverview = findChild(dash, "scopesOverview");
3166+ compare(scopesOverview.currentTab, 0);
3167+
3168+ // Make sure stuff is loaded
3169+ var scopesOverviewFavoritesRepeater = findChild(dash, "scopesOverviewFavoritesRepeater");
3170+ tryCompare(scopesOverviewFavoritesRepeater, "count", 6);
3171+ tryCompareFunction(function() { return scopesOverviewFavoritesRepeater.itemAt(0).item != null; }, true);
3172+ waitForRendering(scopesOverviewFavoritesRepeater.itemAt(1).item);
3173+
3174+ // Click on the all tab
3175+ var scopesOverviewAllTabButton = findChild(dash, "scopesOverviewAllTabButton");
3176+ mouseClick(scopesOverviewAllTabButton, 0, 0);
3177+
3178+ // Wait for all tab to be enabled (animation finish)
3179+ var scopesOverviewAllView = findChild(dash, "scopesOverviewRepeaterChild1");
3180+ tryCompare(scopesOverviewAllView, "enabled", true);
3181+
3182+ // Click on a temp scope
3183+ var tempScopeCard = findChild(scopesOverviewAllView, "delegate1");
3184+ mouseClick(tempScopeCard, 0, 0);
3185+
3186+ // Check the bottom edge (overview) is disabled from temp scope
3187+ var overviewDragHandle = findChild(dash, "overviewDragHandle");
3188+ compare(overviewDragHandle.enabled, false);
3189+
3190+ // Check temp scope is there
3191+ var scopesOverviewTempScopeItem = findChild(dash, "scopesOverviewTempScopeItem");
3192+ tryCompareFunction( function() { return scopesOverviewTempScopeItem.scope != null; }, true);
3193+ tryCompare(scopesOverviewTempScopeItem, "enabled", true);
3194+
3195+ // Go back
3196+ var scopesOverviewTempScopeItemHeader = findChild(scopesOverviewTempScopeItem, "scopePageHeader");
3197+ var backButton = findChild(findChild(scopesOverviewTempScopeItemHeader, "innerPageHeader"), "backButton");
3198+ mouseClick(backButton, 0, 0);
3199+
3200+ // Check temp scope is gone
3201+ var scopesOverviewTempScopeItem = findChild(dash, "scopesOverviewTempScopeItem");
3202+ tryCompareFunction( function() { return scopesOverviewTempScopeItem.scope == null; }, true);
3203+ tryCompare(scopesOverviewTempScopeItem, "enabled", false);
3204+
3205+ // Press on done
3206+ var scopesOverviewDoneButton = findChild(scopesOverview, "scopesOverviewDoneButton");
3207+ mouseClick(scopesOverviewDoneButton, 0, 0);
3208+
3209+ // Check the dash overview is gone
3210+ tryCompare(overviewController, "progress", 0);
3211+
3212+ // Original list is still on 0
3213+ compare(dashContentList.currentIndex, 0);
3214+ }
3215+
3216+ function test_temp_scope_dash_overview_all_search_temp_scope_favorite_from_all() {
3217+ // Wait for stuff to be loaded
3218+ tryCompare(scopes, "loaded", true);
3219+ var dashContentList = findChild(dash, "dashContentList");
3220+ tryCompare(dashContentList, "count", 6);
3221+ var mockScope1Loader = findChild(dash, "MockScope1 loader");
3222+ tryCompareFunction(function() { return mockScope1Loader.item != null; }, true);
3223+
3224+ // Swipe right to Apps scope
3225+ touchFlick(dash, dash.width - 1, units.gu(1), dash.width - units.gu(10), units.gu(1));
3226+ tryCompare(dashContentList, "contentX", dashContentList.width);
3227+ tryCompare(dashContentList, "currentIndex", 1);
3228+
3229+ // Click on card that opens temp scope
3230+ var categoryListView = findChild(dashContentList.currentItem, "categoryListView");
3231+ var dashCategory2 = findChild(categoryListView, "dashCategory2");
3232+ tryCompareFunction(function() {
3233+ var d = findChild(dashCategory2, "delegate2");
3234+ if (d) return true;
3235+ categoryListView.contentY += 100;
3236+ return false;
3237+ }, true);
3238+ var card2 = findChild(dashCategory2, "delegate2");
3239+ waitForRendering(card2);
3240+ mouseClick(card2, card2.width / 2, card2.height / 2);
3241+
3242+ // Wait for temp scope to be there
3243+ var dashTempScopeItem = findChild(dash, "dashTempScopeItem");
3244+ tryCompare(dashTempScopeItem, "x", 0);
3245+
3246+ // Show the overview
3247+ touchFlick(dash, dash.width / 2, dash.height - 1, dash.width / 2, dash.height - units.gu(18));
3248+ var overviewController = findInvisibleChild(dash, "overviewController");
3249+ tryCompare(overviewController, "progress", 1);
3250+
3251+ // Make sure tab is where it should
3252+ var scopesOverview = findChild(dash, "scopesOverview");
3253+ compare(scopesOverview.currentTab, 1);
3254+
3255+ // Do a search
3256+ var scopesOverviewPageHeader = findChild(scopesOverview, "scopesOverviewPageHeader");
3257+ var searchButton = findChild(scopesOverviewPageHeader, "search_header_button");
3258+ mouseClick(searchButton, 0, 0);
3259+
3260+ // Type something
3261+ keyClick(Qt.Key_H);
3262+
3263+ // Check results grid is there and the other lists are not
3264+ var searchResultsViewer = findChild(scopesOverview, "searchResultsViewer");
3265+ var scopesOverviewRepeater = findChild(dash, "scopesOverviewRepeater");
3266+ tryCompare(searchResultsViewer, "opacity", 1);
3267+ tryCompare(scopesOverviewRepeater, "count", 0);
3268+
3269+ // Click on a temp scope in the search
3270+ var dashCategorysearchA = findChild(searchResultsViewer, "dashCategorysearchA");
3271+ var cardTempScope = findChild(dashCategorysearchA, "delegate2");
3272+ waitForRendering(cardTempScope);
3273+ mouseClick(cardTempScope, cardTempScope.width / 2, cardTempScope.height / 2);
3274+
3275+ // Check the bottom edge (overview) is disabled from temp scope
3276+ var overviewDragHandle = findChild(dash, "overviewDragHandle");
3277+ compare(overviewDragHandle.enabled, false);
3278+
3279+ // Check temp scope is there
3280+ var scopesOverviewTempScopeItem = findChild(dash, "scopesOverviewTempScopeItem");
3281+ tryCompareFunction( function() { return scopesOverviewTempScopeItem.scope != null; }, true);
3282+ tryCompare(scopesOverviewTempScopeItem, "enabled", true);
3283+
3284+ // Go back
3285+ var scopesOverviewTempScopeItemHeader = findChild(scopesOverviewTempScopeItem, "scopePageHeader");
3286+ var backButton = findChild(findChild(scopesOverviewTempScopeItemHeader, "innerPageHeader"), "backButton");
3287+ mouseClick(backButton, 0, 0);
3288+
3289+ // Check temp scope is gone
3290+ var scopesOverviewTempScopeItem = findChild(dash, "scopesOverviewTempScopeItem");
3291+ tryCompareFunction( function() { return scopesOverviewTempScopeItem.scope == null; }, true);
3292+ tryCompare(scopesOverviewTempScopeItem, "enabled", false);
3293+
3294+ // Press on a favorite
3295+ var dashCategorysearchB = findChild(searchResultsViewer, "dashCategorysearchB");
3296+ var cardFavSearch = findChild(dashCategorysearchB, "delegate3");
3297+ mouseClick(cardFavSearch, 0, 0);
3298+
3299+ // Check the dash overview is gone
3300+ tryCompare(overviewController, "progress", 0);
3301+
3302+ // Original list went to the favorite
3303+ compare(dashContentList.currentIndex, 0);
3304 }
3305
3306 function test_setCurrentScope() {
3307
3308=== modified file 'tests/qmltests/Dash/tst_DashContent.qml'
3309--- tests/qmltests/Dash/tst_DashContent.qml 2014-08-06 10:16:59 +0000
3310+++ tests/qmltests/Dash/tst_DashContent.qml 2014-08-08 15:11:52 +0000
3311@@ -70,7 +70,7 @@
3312 function loadScopes() {
3313 scopeLoadedSpy.clear();
3314 scopesModel.load();
3315- tryCompare(scopeLoadedSpy, "count", 4);
3316+ tryCompare(scopeLoadedSpy, "count", 6);
3317 }
3318
3319 function init() {
3320@@ -114,7 +114,8 @@
3321
3322 loadScopes();
3323
3324- verify(dashContentList.currentIndex >= 0 && dashContentList.currentIndex < 5);
3325+ compare(dashContentList.count, 6);
3326+ verify(dashContentList.currentIndex >= 0 && dashContentList.currentIndex < dashContentList.count);
3327 }
3328
3329 function test_show_header_on_list_movement() {
3330@@ -170,7 +171,7 @@
3331
3332 // test greater than scope count.
3333 var currentScopeIndex = dashContent.currentIndex;
3334- dashContent.setCurrentScopeAtIndex(8, true, false);
3335+ dashContent.setCurrentScopeAtIndex(18, true, false);
3336 compare(dashContent.currentIndex, currentScopeIndex, "Scope should not change if changing to greater index than count");
3337 }
3338
3339@@ -189,9 +190,9 @@
3340 function test_scope_mapping_data() {
3341 return [
3342 {tag: "index0", index: 0, objectName: "MockScope1"},
3343- {tag: "index1", index: 1, objectName: "MockScope2"},
3344- {tag: "index2", index: 2, objectName: "clickscope"},
3345- {tag: "index3", index: 3, objectName: "MockScope5"}
3346+ {tag: "index1", index: 1, objectName: "clickscope"},
3347+ {tag: "index2", index: 2, objectName: "MockScope5"},
3348+ {tag: "index3", index: 3, objectName: "SingleCategoryScope"}
3349 ]
3350 }
3351
3352
3353=== modified file 'tests/qmltests/Dash/tst_GenericScopeView.qml'
3354--- tests/qmltests/Dash/tst_GenericScopeView.qml 2014-08-06 19:39:30 +0000
3355+++ tests/qmltests/Dash/tst_GenericScopeView.qml 2014-08-08 15:11:52 +0000
3356@@ -61,8 +61,8 @@
3357 property Item header: findChild(genericScopeView, "scopePageHeader")
3358
3359 function init() {
3360- genericScopeView.scope = scopes.getScope(1)
3361- shell.width = units.gu(120)
3362+ genericScopeView.scope = scopes.getScope(2);
3363+ shell.width = units.gu(120);
3364 genericScopeView.categoryView.positionAtBeginning();
3365 waitForRendering(genericScopeView.categoryView);
3366 }
3367@@ -88,13 +88,13 @@
3368
3369 function test_showDash() {
3370 testCase.previewListView.open = true;
3371- scopes.getScope(1).showDash();
3372+ genericScopeView.scope.showDash();
3373 tryCompare(testCase.previewListView, "open", false);
3374 }
3375
3376 function test_hideDash() {
3377 testCase.previewListView.open = true;
3378- scopes.getScope(1).hideDash();
3379+ genericScopeView.scope.hideDash();
3380 tryCompare(testCase.previewListView, "open", false);
3381 }
3382
3383@@ -111,8 +111,9 @@
3384
3385 function test_changeScope() {
3386 genericScopeView.scope.searchQuery = "test"
3387- genericScopeView.scope = scopes.getScope(2)
3388- genericScopeView.scope = scopes.getScope(1)
3389+ var originalScopeId = genericScopeView.scope.id;
3390+ genericScopeView.scope = scopes.getScope(originalScopeId + 1)
3391+ genericScopeView.scope = scopes.getScope(originalScopeId)
3392 tryCompare(genericScopeView.scope, "searchQuery", "test")
3393 }
3394
3395@@ -198,6 +199,8 @@
3396 openPreview(4, 0);
3397
3398 compare(testCase.previewListView.count, 12, "There should only be 12 items in preview.");
3399+
3400+ closePreview();
3401 }
3402
3403 function test_narrow_delegate_ranges_expand() {
3404@@ -232,7 +235,7 @@
3405 }
3406
3407 function test_single_category_expansion() {
3408- genericScopeView.scope = scopes.getScope(4);
3409+ genericScopeView.scope = scopes.getScope(3);
3410
3411 tryCompareFunction(function() { return findChild(genericScopeView, "dashCategory0") != undefined; }, true);
3412 var category = findChild(genericScopeView, "dashCategory0")
3413@@ -329,8 +332,8 @@
3414 function test_header_style_data() {
3415 return [
3416 { tag: "Default", index: 0, foreground: "grey", background: "", logo: "" },
3417- { tag: "Foreground", index: 2, foreground: "yellow", background: "", logo: "" },
3418- { tag: "Logo+Background", index: 3, foreground: "grey", background: "gradient:///lightgrey/grey",
3419+ { tag: "Foreground", index: 1, foreground: "yellow", background: "", logo: "" },
3420+ { tag: "Logo+Background", index: 2, foreground: "grey", background: "gradient:///lightgrey/grey",
3421 logo: Qt.resolvedUrl("../Components/tst_PageHeader/logo-ubuntu-orange.svg") },
3422 ];
3423 }

Subscribers

People subscribed via source and target branches