on xenial help sign in
Merge
f9129dfAlbert Astals
cmake/modules/QmlTest.cmake+2−2
@@ -135,7 +135,7 @@ macro(add_binary_qml_test CLASS_NAME LD_PATH DEPS)
135 set(testCommand
135 set(testCommand
136 LD_LIBRARY_PATH=${LD_PATH}
136 LD_LIBRARY_PATH=${LD_PATH}
137 ${CMAKE_CURRENT_BINARY_DIR}/${CLASS_NAME}TestExec
137 ${CMAKE_CURRENT_BINARY_DIR}/${CLASS_NAME}TestExec
138− -o ${CMAKE_BINARY_DIR}/${CLASS_NAME}Test.xml,xunitxml
138+ -o ${CMAKE_BINARY_DIR}/test${CLASS_NAME}.xml,xunitxml
139 -o -,txt)
139 -o -,txt)
140
140
141 add_qmltest_target(test${CLASS_NAME} "${testCommand}" FALSE TRUE)
141 add_qmltest_target(test${CLASS_NAME} "${testCommand}" FALSE TRUE)
@@ -151,7 +151,7 @@ macro(add_binary_qml_test CLASS_NAME LD_PATH DEPS)
151 LD_LIBRARY_PATH=${LD_PATH}
151 LD_LIBRARY_PATH=${LD_PATH}
152 xvfb-run --server-args "-screen 0 1024x768x24" --auto-servernum
152 xvfb-run --server-args "-screen 0 1024x768x24" --auto-servernum
153 ${CMAKE_CURRENT_BINARY_DIR}/${CLASS_NAME}TestExec
153 ${CMAKE_CURRENT_BINARY_DIR}/${CLASS_NAME}TestExec
154− -o ${CMAKE_BINARY_DIR}/${CLASS_NAME}Test.xml,xunitxml
154+ -o ${CMAKE_BINARY_DIR}/test${CLASS_NAME}.xml,xunitxml
155 -o -,txt)
155 -o -,txt)
156
156
157 add_qmltest_target(xvfbtest${CLASS_NAME} "${xvfbtestCommand}" FALSE TRUE)
157 add_qmltest_target(xvfbtest${CLASS_NAME} "${xvfbtestCommand}" FALSE TRUE)
debian/changelog+58
@@ -1,3 +1,61 @@
1+unity8 (8.00+14.10.20140806.1-0ubuntu1) utopic; urgency=low
2+
3+ [ Michal Hruby ]
4+ * Work with the scopes-v4 branch + departments->navigation renaming
5+
6+ [ Michał Sawicz ]
7+ * Hardcode art shape size for click scope local and predefined
8+ categories While at it, drop the fillmode of cards
9+ * Use the correct API in PageHeader. (LP: #1353048)
10+ * Refactor dash activity indicator. (LP: #1351539)
11+
12+ [ Albert Astals ]
13+ * Dash Departments fixes Update maxHeight manually since it depends on
14+ the position of the item and its parents and it can't know when the
15+ binding has to be updated Make parent stuff non interactive when the
16+ department list is shown
17+ * PageHeader: when on search clip y-coordinates otherwise the
18+ background spills out when on search (LP: #1350398)
19+ * Dash: Implement OverlayColor support in Cards
20+ * Hardcode art shape size for click scope local and predefined
21+ categories While at it, drop the fillmode of cards
22+ * Make test_departments test more stable There's various
23+ DashDepartments on the dash, make sure we're working over the one
24+ that is on screen, otherwise clicks don't end up where they should
25+ * Work with the scopes-v4 branch + departments->navigation renaming
26+ * Fixes for dash as app Load i18n catalog Process command line options
27+ Add the posibility to have a mouse touch adaptor (LP: #1353351)
28+ * Implement the Expandable Preview Widget Now TextSummary is not
29+ expandable by itself anymore, you have to use it inside an
30+ Expandable to get the behaviour
31+ * Add test prefix to xml output, seems CI needs it
32+
33+ [ Antti Kaijanmäki ]
34+ * Indicators: Adds new ModemInfoItem to be used with indicator-network
35+ (LP: #1329204)
36+
37+ [ Michael Terry ]
38+ * When the edge demo is running, don't show the greeter if the screen
39+ is turned off. This avoids an odd interaction where parts of the
40+ greeter are disabled but the edge demo isn't visible until you slide
41+ the greeter away. (LP: #1283425)
42+ * Don't hardcode the phablet password in our testing script.
43+
44+ [ Ying-Chun Liu ]
45+ * Add divider dots.
46+
47+ [ Mirco Müller ]
48+ * Make sure the TextField of a snap-decision notification has the
49+ active focus upon creation, thus the osk shows up right away. (LP:
50+ #1346867)
51+
52+ [ Andrea Cimitan ]
53+ * Add touchdown effect to dash cards.
54+ * Import Ubuntu.Components for preview image gallery to pick up
55+ default flicking speeds.
56+
57+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Wed, 06 Aug 2014 19:40:05 +0000
58+
1unity8 (8.00+14.10.20140805-0ubuntu1) utopic; urgency=low
59unity8 (8.00+14.10.20140805-0ubuntu1) utopic; urgency=low
2
60
3 [ Michael Zanetti ]
61 [ Michael Zanetti ]
debian/control+2−2
@@ -24,7 +24,7 @@ Build-Depends: cmake,
24 libpulse-dev,
24 libpulse-dev,
25 libqmenumodel-dev (>= 0.2.8),
25 libqmenumodel-dev (>= 0.2.8),
26 libqt5xmlpatterns5-dev,
26 libqt5xmlpatterns5-dev,
27− libunity-api-dev (>= 7.87),
27+ libunity-api-dev (>= 7.88),
28 libusermetricsoutput1-dev,
28 libusermetricsoutput1-dev,
29 libxcb1-dev,
29 libxcb1-dev,
30 pkg-config,
30 pkg-config,
@@ -112,7 +112,7 @@ Depends: qtdeclarative5-ubuntu-thumbnailer0.1 | ubuntu-thumbnailer-impl,
112 unity-application-impl-2,
112 unity-application-impl-2,
113 unity-notifications-impl-3,
113 unity-notifications-impl-3,
114 unity-plugin-scopes | unity-scopes-impl,
114 unity-plugin-scopes | unity-scopes-impl,
115− unity-scopes-impl-3,
115+ unity-scopes-impl-4,
116 unity8-fake-env | unity-application-impl,
116 unity8-fake-env | unity-application-impl,
117 ${misc:Depends},
117 ${misc:Depends},
118Breaks: unity8 (<< 7.86),
118Breaks: unity8 (<< 7.86),
plugins/Dash/CardCreator.js+28−13
@@ -71,19 +71,14 @@ var kArtShapeHolderCode = 'Item { \n\
71 visible: image.status == Image.Ready; \n\
71 visible: image.status == Image.Ready; \n\
72 readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1; \n\
72 readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1; \n\
73 readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1; \n\
73 readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1; \n\
74− readonly property bool aspectSmallerThanImageAspect: aspect < image.aspect; \n\
75 Component.onCompleted: { updateWidthHeightBindings(); if (artShapeBorderSource !== undefined) borderSource = artShapeBorderSource; } \n\
74 Component.onCompleted: { updateWidthHeightBindings(); if (artShapeBorderSource !== undefined) borderSource = artShapeBorderSource; } \n\
76− onAspectSmallerThanImageAspectChanged: updateWidthHeightBindings(); \n\
77 Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); } \n\
75 Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); } \n\
78 function updateWidthHeightBindings() { \n\
76 function updateWidthHeightBindings() { \n\
79 if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) { \n\
77 if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) { \n\
80 width = root.fixedArtShapeSize.width; \n\
78 width = root.fixedArtShapeSize.width; \n\
81 height = root.fixedArtShapeSize.height; \n\
79 height = root.fixedArtShapeSize.height; \n\
82− } else if (aspectSmallerThanImageAspect) { \n\
83− width = Qt.binding(function() { return !visible ? 0 : image.width }); \n\
84− height = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.height : width / image.aspect }); \n\
85 } else { \n\
80 } else { \n\
86− width = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.width : height * image.aspect }); \n\
81+ width = Qt.binding(function() { return !visible ? 0 : image.width }); \n\
87 height = Qt.binding(function() { return !visible ? 0 : image.height }); \n\
82 height = Qt.binding(function() { return !visible ? 0 : image.height }); \n\
88 } \n\
83 } \n\
89 } \n\
84 } \n\
@@ -92,8 +87,7 @@ var kArtShapeHolderCode = 'Item { \n\
92 source: cardData && cardData["art"] || ""; \n\
87 source: cardData && cardData["art"] || ""; \n\
93 cache: true; \n\
88 cache: true; \n\
94 asynchronous: root.asynchronous; \n\
89 asynchronous: root.asynchronous; \n\
95− fillMode: components && components["art"]["fill-mode"] === "fit" ? Image.PreserveAspectFit: Image.PreserveAspectCrop; \n\
90+ fillMode: Image.PreserveAspectCrop; \n\
96− readonly property real aspect: implicitWidth / implicitHeight; \n\
97 width: %2; \n\
91 width: %2; \n\
98 height: %3; \n\
92 height: %3; \n\
99 } \n\
93 } \n\
@@ -114,7 +108,8 @@ var kOverlayLoaderCode = 'Loader { \n\
114 sourceComponent: ShaderEffect { \n\
108 sourceComponent: ShaderEffect { \n\
115 id: overlay; \n\
109 id: overlay; \n\
116 height: (fixedHeaderHeight > 0 ? fixedHeaderHeight : headerHeight) + units.gu(2); \n\
110 height: (fixedHeaderHeight > 0 ? fixedHeaderHeight : headerHeight) + units.gu(2); \n\
117− opacity: 0.6; \n\
111+ property real luminance: 0.2126 * overlayColor.r + 0.7152 * overlayColor.g + 0.0722 * overlayColor.b; \n\
112+ property color overlayColor: cardData && cardData["overlayColor"] || "#99000000"; \n\
118 property var source: ShaderEffectSource { \n\
113 property var source: ShaderEffectSource { \n\
119 id: shaderSource; \n\
114 id: shaderSource; \n\
120 sourceItem: artShapeLoader.item; \n\
115 sourceItem: artShapeLoader.item; \n\
@@ -135,9 +130,10 @@ var kOverlayLoaderCode = 'Loader { \n\
135 varying highp vec2 coord; \n\
130 varying highp vec2 coord; \n\
136 uniform sampler2D source; \n\
131 uniform sampler2D source; \n\
137 uniform lowp float qt_Opacity; \n\
132 uniform lowp float qt_Opacity; \n\
133+ uniform highp vec4 overlayColor; \n\
138 void main() { \n\
134 void main() { \n\
139 lowp vec4 tex = texture2D(source, coord); \n\
135 lowp vec4 tex = texture2D(source, coord); \n\
140− gl_FragColor = vec4(0, 0, 0, tex.a) * qt_Opacity; \n\
136+ gl_FragColor = vec4(overlayColor.r, overlayColor.g, overlayColor.b, 1) * qt_Opacity * overlayColor.a * tex.a; \n\
141 }"; \n\
137 }"; \n\
142 } \n\
138 } \n\
143 }\n';
139 }\n';
@@ -257,6 +253,16 @@ var kTitleLabelCode = 'Label { \n\
257 horizontalAlignment: root.headerAlignment; \n\
253 horizontalAlignment: root.headerAlignment; \n\
258 }\n';
254 }\n';
259
255
256+// %1 is used as anchors of touchdown effect
257+var kTouchdownCode = 'UbuntuShape { \n\
258+ id: touchdown; \n\
259+ objectName: "touchdown"; \n\
260+ anchors { %1 } \n\
261+ visible: root.pressed; \n\
262+ radius: "medium"; \n\
263+ borderSource: "radius_pressed.sci" \n\
264+ }\n';
265+
260// %1 is used as anchors of subtitleLabel
266// %1 is used as anchors of subtitleLabel
261// %2 is used as color of subtitleLabel
267// %2 is used as color of subtitleLabel
262var kSubtitleLabelCode = 'Label { \n\
268var kSubtitleLabelCode = 'Label { \n\
@@ -279,7 +285,7 @@ var kAttributesRowCode = 'CardAttributes { \n\
279 objectName: "attributesRow"; \n\
285 objectName: "attributesRow"; \n\
280 anchors { %1 } \n\
286 anchors { %1 } \n\
281 color: %2; \n\
287 color: %2; \n\
282− model: cardData && cardData["attributes"] || undefined; \n\
288+ model: cardData["attributes"]; \n\
283 }\n';
289 }\n';
284
290
285// %1 is used as top anchor of summary
291// %1 is used as top anchor of summary
@@ -447,7 +453,7 @@ function cardString(template, components) {
447 if (hasTitle) {
453 if (hasTitle) {
448 var color;
454 var color;
449 if (headerAsOverlay) {
455 if (headerAsOverlay) {
450− color = '"white"';
456+ color = 'overlayLoader.item.luminance < (root.scopeStyle ? root.scopeStyle.threshold : 0.7) ? (root.scopeStyle ? root.scopeStyle.light : "white") : (root.scopeStyle ? root.scopeStyle.dark : "grey")';
451 } else if (hasSummary) {
457 } else if (hasSummary) {
452 color = 'summary.color';
458 color = 'summary.color';
453 } else if (hasBackground) {
459 } else if (hasBackground) {
@@ -569,6 +575,16 @@ function cardString(template, components) {
569 code += kSummaryLabelCode.arg(summaryTopAnchor).arg(summaryTopMargin).arg(color);
575 code += kSummaryLabelCode.arg(summaryTopAnchor).arg(summaryTopMargin).arg(color);
570 }
576 }
571
577
578+ var touchdownAnchors;
579+ if (hasBackground) {
580+ touchdownAnchors = 'fill: backgroundLoader';
581+ } else if (hasArt && !hasMascot && !hasSummary) {
582+ touchdownAnchors = 'fill: artShapeHolder';
583+ } else {
584+ touchdownAnchors = 'fill: root'
585+ }
586+ code += kTouchdownCode.arg(touchdownAnchors);
587+
572 if (hasSummary) {
588 if (hasSummary) {
573 code += 'implicitHeight: summary.y + summary.height + (summary.text ? units.gu(1) : 0);\n';
589 code += 'implicitHeight: summary.y + summary.height + (summary.text ? units.gu(1) : 0);\n';
574 } else if (hasHeaderRow) {
590 } else if (hasHeaderRow) {
@@ -593,7 +609,6 @@ function cardString(template, components) {
593function createCardComponent(parent, template, components) {
609function createCardComponent(parent, template, components) {
594 var imports = 'import QtQuick 2.2; \n\
610 var imports = 'import QtQuick 2.2; \n\
595 import Ubuntu.Components 0.1; \n\
611 import Ubuntu.Components 0.1; \n\
596− import Ubuntu.Thumbnailer 0.1;\n\
597 import Dash 0.1;\n';
612 import Dash 0.1;\n';
598 var card = cardString(template, components);
613 var card = cardString(template, components);
599 var code = imports + 'Component {\n' + card + '}\n';
614 var code = imports + 'Component {\n' + card + '}\n';
plugins/Dash/ScopeStyle.qml+12−9
@@ -38,15 +38,21 @@ QtObject {
38 /// Color used for text and symbolic icons
38 /// Color used for text and symbolic icons
39 readonly property color foreground: "foreground-color" in style ? style["foreground-color"] : d.defaultDark
39 readonly property color foreground: "foreground-color" in style ? style["foreground-color"] : d.defaultDark
40
40
41+ /// Luminance of the foreground color
42+ readonly property real foregroundLuminance: foreground ? luminance(foreground) : d.defaultForegroundLuminance
43+
41 /// Color used for the overall background
44 /// Color used for the overall background
42 readonly property color background: "background-color" in style ? style["background-color"] : "transparent"
45 readonly property color background: "background-color" in style ? style["background-color"] : "transparent"
43
46
47+ /// Luminance of the foreground color
48+ readonly property real backgroundLuminance: background ? luminance(background) : d.defaultBackgroundLuminance
49+
44 /*! \brief Luminance threshold for switching between fore and background color
50 /*! \brief Luminance threshold for switching between fore and background color
45
51
46 \note If background colour is not fully opaque, the defaultLightLuminance it's taken into account instead of it.
52 \note If background colour is not fully opaque, the defaultLightLuminance it's taken into account instead of it.
47 */
53 */
48− readonly property real threshold: background.a !== 1.0 ? (d.foregroundLuminance + d.defaultLightLuminance) / 2
54+ readonly property real threshold: background.a !== 1.0 ? (foregroundLuminance + d.defaultLightLuminance) / 2
49− : (d.foregroundLuminance + d.backgroundLuminance) / 2
55+ : (foregroundLuminance + backgroundLuminance) / 2
50
56
51 /*! \brief The lighter of foreground and background colors
57 /*! \brief The lighter of foreground and background colors
52
58
@@ -54,8 +60,8 @@ QtObject {
54 and defaults to the theme-provided light color.
60 and defaults to the theme-provided light color.
55 */
61 */
56 readonly property color light: {
62 readonly property color light: {
57− if (background.a !== 1.0) return d.foregroundLuminance > d.defaultLightLuminance ? foreground : d.defaultLight;
63+ if (background.a !== 1.0) return foregroundLuminance > d.defaultLightLuminance ? foreground : d.defaultLight;
58− return d.foregroundLuminance > d.backgroundLuminance ? foreground : background;
64+ return foregroundLuminance > backgroundLuminance ? foreground : background;
59 }
65 }
60
66
61 /*! \brief The darker of foreground and background colors
67 /*! \brief The darker of foreground and background colors
@@ -64,8 +70,8 @@ QtObject {
64 and defaults to the theme-provided dark color.
70 and defaults to the theme-provided dark color.
65 */
71 */
66 readonly property color dark: {
72 readonly property color dark: {
67− if (background.a !== 1.0) return d.foregroundLuminance < d.defaultDarkLuminance ? foreground : d.defaultDark;
73+ if (background.a !== 1.0) return foregroundLuminance < d.defaultDarkLuminance ? foreground : d.defaultDark;
68− return d.foregroundLuminance < d.backgroundLuminance ? foreground : background;
74+ return foregroundLuminance < backgroundLuminance ? foreground : background;
69 }
75 }
70
76
71 /// Source of the logo image for the header
77 /// Source of the logo image for the header
@@ -79,9 +85,6 @@ QtObject {
79
85
80 //! @cond
86 //! @cond
81 property var d: QtObject {
87 property var d: QtObject {
82− readonly property real foregroundLuminance: luminance(foreground)
83− readonly property real backgroundLuminance: luminance(background)
84−
85 // FIXME: should be taken from the theme
88 // FIXME: should be taken from the theme
86 readonly property color defaultLight: "white"
89 readonly property color defaultLight: "white"
87 readonly property color defaultDark: "grey"
90 readonly property color defaultDark: "grey"
po/es.po+5−5
@@ -8,14 +8,14 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2014-07-11 14:59+0200\n"
10"POT-Creation-Date: 2014-07-11 14:59+0200\n"
11−"PO-Revision-Date: 2014-07-26 06:22+0000\n"
11+"PO-Revision-Date: 2014-08-06 15:24+0000\n"
12−"Last-Translator: Paco Molinero <paco@byasl.com>\n"
12+"Last-Translator: Leo Arias <leo.arias@canonical.com>\n"
13"Language-Team: Spanish <es@li.org>\n"
13"Language-Team: Spanish <es@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2014-07-27 06:35+0000\n"
17+"X-Launchpad-Export-Date: 2014-08-07 06:27+0000\n"
18−"X-Generator: Launchpad (build 17131)\n"
18+"X-Generator: Launchpad (build 17147)\n"
19
19
20#: plugins/Unity/Launcher/launcheritem.cpp:43
20#: plugins/Unity/Launcher/launcheritem.cpp:43
21#: plugins/Unity/Launcher/launcheritem.cpp:73
21#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -116,7 +116,7 @@ msgstr "Recientes"
116
116
117#: qml/Dash/GenericScopeView.qml:330
117#: qml/Dash/GenericScopeView.qml:330
118msgid "See all"
118msgid "See all"
119−msgstr "Ver todo"
119+msgstr "Ver todas"
120
120
121#: qml/Dash/Previews/PreviewActionCombo.qml:34
121#: qml/Dash/Previews/PreviewActionCombo.qml:34
122msgid "More..."
122msgid "More..."
po/eu.po+7−6
@@ -8,14 +8,14 @@ msgstr ""
8"Project-Id-Version: unity8\n"
8"Project-Id-Version: unity8\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2014-07-11 14:59+0200\n"
10"POT-Creation-Date: 2014-07-11 14:59+0200\n"
11−"PO-Revision-Date: 2014-07-25 12:38+0000\n"
11+"PO-Revision-Date: 2014-08-06 22:51+0000\n"
12"Last-Translator: Ibai Oihanguren Sala <Unknown>\n"
12"Last-Translator: Ibai Oihanguren Sala <Unknown>\n"
13"Language-Team: Basque <eu@li.org>\n"
13"Language-Team: Basque <eu@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2014-07-26 07:16+0000\n"
17+"X-Launchpad-Export-Date: 2014-08-07 06:27+0000\n"
18−"X-Generator: Launchpad (build 17131)\n"
18+"X-Generator: Launchpad (build 17147)\n"
19
19
20#: plugins/Unity/Launcher/launcheritem.cpp:43
20#: plugins/Unity/Launcher/launcheritem.cpp:43
21#: plugins/Unity/Launcher/launcheritem.cpp:73
21#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -36,7 +36,8 @@ msgstr "Eskuineko ertza"
36
36
37#: qml/Components/EdgeDemo.qml:114
37#: qml/Components/EdgeDemo.qml:114
38msgid "Try swiping from the right edge to unlock the phone"
38msgid "Try swiping from the right edge to unlock the phone"
39+msgstr ""
39−msgstr "Probatu eskuineko ertzetik arrastatzen telefonoa desblokeatzeko"
40+"Pasatu hatza eskuineko ertzetik ezkerrerantz telefonoa desblokeatzeko"
40
41
41#: qml/Components/EdgeDemo.qml:145
42#: qml/Components/EdgeDemo.qml:145
42msgid "Top edge"
43msgid "Top edge"
@@ -44,7 +45,7 @@ msgstr "Goiko ertza"
44
45
45#: qml/Components/EdgeDemo.qml:146
46#: qml/Components/EdgeDemo.qml:146
46msgid "Try swiping from the top edge to access the indicators"
47msgid "Try swiping from the top edge to access the indicators"
47−msgstr "Probatu goiko ertzetik arrastatzen adierazleak ikusteko"
48+msgstr "Pasatu hatza goiko ertzetik beherantz adierazleak ikusteko"
48
49
49#: qml/Components/EdgeDemo.qml:171
50#: qml/Components/EdgeDemo.qml:171
50msgid "Close"
51msgid "Close"
@@ -52,7 +53,7 @@ msgstr "Itxi"
52
53
53#: qml/Components/EdgeDemo.qml:172
54#: qml/Components/EdgeDemo.qml:172
54msgid "Swipe up again to close the settings screen"
55msgid "Swipe up again to close the settings screen"
55−msgstr "Pasatu hatza gora berriro ezarpenen leihoa ixteko"
56+msgstr "Pasatu hatza berriro gora ezarpenen leihoa ixteko"
56
57
57#: qml/Components/EdgeDemo.qml:199
58#: qml/Components/EdgeDemo.qml:199
58msgid "Left edge"
59msgid "Left edge"
po/hu.po+72−36
@@ -6,15 +6,16 @@
6msgid ""
6msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
10−"POT-Creation-Date: 2014-07-11 14:59+0200\n"
10+"POT-Creation-Date: 2014-08-05 19:54+0200\n"
11−"PO-Revision-Date: 2014-08-04 09:10+0000\n"
11+"PO-Revision-Date: 2014-08-06 07:41+0000\n"
12"Last-Translator: Richard Somlói <ricsipontaz@gmail.com>\n"
12"Last-Translator: Richard Somlói <ricsipontaz@gmail.com>\n"
13"Language-Team: Hungarian <hu@li.org>\n"
13"Language-Team: Hungarian <hu@li.org>\n"
14+"Language: hu\n"
14"MIME-Version: 1.0\n"
15"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2014-08-05 06:45+0000\n"
18+"X-Launchpad-Export-Date: 2014-08-07 06:27+0000\n"
18"X-Generator: Launchpad (build 17147)\n"
19"X-Generator: Launchpad (build 17147)\n"
19
20
20#: plugins/Unity/Launcher/launcheritem.cpp:43
21#: plugins/Unity/Launcher/launcheritem.cpp:43
@@ -26,72 +27,88 @@ msgstr "Indító rögzítése"
26msgid "Unpin shortcut"
27msgid "Unpin shortcut"
27msgstr "Indító feloldása"
28msgstr "Indító feloldása"
28
29
30+#: qml/Components/Dialogs.qml:142
31+msgid "Are you sure you would like to turn power off?"
32+msgstr ""
33+
34+#: qml/Components/Dialogs.qml:144
35+msgid "Power off"
36+msgstr ""
37+
38+#: qml/Components/Dialogs.qml:153
39+msgid "Restart"
40+msgstr ""
41+
42+#: qml/Components/Dialogs.qml:162
43+msgid "Cancel"
44+msgstr ""
45+
29#: qml/Components/EdgeDemoOverlay.qml:151
46#: qml/Components/EdgeDemoOverlay.qml:151
30msgid "Skip intro"
47msgid "Skip intro"
31msgstr "A bemutató kihagyása"
48msgstr "A bemutató kihagyása"
32
49
33−#: qml/Components/EdgeDemo.qml:113
50+#: qml/Components/EdgeDemo.qml:112
34msgid "Right edge"
51msgid "Right edge"
35msgstr "Jobb szél"
52msgstr "Jobb szél"
36
53
37−#: qml/Components/EdgeDemo.qml:114
54+#: qml/Components/EdgeDemo.qml:113
38msgid "Try swiping from the right edge to unlock the phone"
55msgid "Try swiping from the right edge to unlock the phone"
39msgstr "A telefon feloldásához csúsztassa ujját a jobb szélről"
56msgstr "A telefon feloldásához csúsztassa ujját a jobb szélről"
40
57
41−#: qml/Components/EdgeDemo.qml:145
58+#: qml/Components/EdgeDemo.qml:144
42msgid "Top edge"
59msgid "Top edge"
43msgstr "Felső szél"
60msgstr "Felső szél"
44
61
45−#: qml/Components/EdgeDemo.qml:146
62+#: qml/Components/EdgeDemo.qml:145
46msgid "Try swiping from the top edge to access the indicators"
63msgid "Try swiping from the top edge to access the indicators"
47msgstr "Az állapotmenük eléréséhez csúsztassa ujját a felső szélről"
64msgstr "Az állapotmenük eléréséhez csúsztassa ujját a felső szélről"
48
65
49−#: qml/Components/EdgeDemo.qml:171
66+#: qml/Components/EdgeDemo.qml:170
50msgid "Close"
67msgid "Close"
51msgstr "Bezárás"
68msgstr "Bezárás"
52
69
53−#: qml/Components/EdgeDemo.qml:172
70+#: qml/Components/EdgeDemo.qml:171
54msgid "Swipe up again to close the settings screen"
71msgid "Swipe up again to close the settings screen"
55msgstr "A beállítások bezárásához csúsztassa ujját újra felfelé"
72msgstr "A beállítások bezárásához csúsztassa ujját újra felfelé"
56
73
57−#: qml/Components/EdgeDemo.qml:199
74+#: qml/Components/EdgeDemo.qml:198
58msgid "Left edge"
75msgid "Left edge"
59msgstr "Bal szél"
76msgstr "Bal szél"
60
77
61−#: qml/Components/EdgeDemo.qml:200
78+#: qml/Components/EdgeDemo.qml:199
62msgid "Swipe from the left to reveal the launcher for quick access to apps"
79msgid "Swipe from the left to reveal the launcher for quick access to apps"
63msgstr ""
80msgstr ""
64"Csúsztassa ujját a bal szélről az indítón található alkalmazások gyors "
81"Csúsztassa ujját a bal szélről az indítón található alkalmazások gyors "
65"eléréséhez"
82"eléréséhez"
66
83
67−#: qml/Components/EdgeDemo.qml:227
84+#: qml/Components/EdgeDemo.qml:226
68msgid "Well done"
85msgid "Well done"
69msgstr "Rendben"
86msgstr "Rendben"
70
87
71−#: qml/Components/EdgeDemo.qml:228
88+#: qml/Components/EdgeDemo.qml:227
72msgid ""
89msgid ""
73"You have now mastered the edge gestures and can start using the "
90"You have now mastered the edge gestures and can start using the "
74"phone<br><br>Tap on the screen to start"
91"phone<br><br>Tap on the screen to start"
75msgstr ""
92msgstr ""
76−"Elsajátította a gesztusokat, és megkezdheti a telefon "
93+"Elsajátította a gesztusokat, és megkezdheti a telefon használatát."
77−"használatát.<br><br>Koppintson a képernyőre a kezdéshez."
94+"<br><br>Koppintson a képernyőre a kezdéshez."
78
95
79−#: qml/Components/Lockscreen.qml:214
96+#: qml/Components/Lockscreen.qml:220
80msgid "Emergency Call"
97msgid "Emergency Call"
81msgstr "Vészhívás"
98msgstr "Vészhívás"
82
99
83−#: qml/Components/Lockscreen.qml:231
100+#: qml/Components/Lockscreen.qml:243
84msgid "OK"
101msgid "OK"
85msgstr "Ok"
102msgstr "Ok"
86
103
87−#: qml/Components/PassphraseLockscreen.qml:60
104+#: qml/Components/PassphraseLockscreen.qml:62
88#, qt-format
105#, qt-format
89msgid "Hello %1"
106msgid "Hello %1"
90msgstr "Üdv %1"
107msgstr "Üdv %1"
91
108
92−#: qml/Components/PassphraseLockscreen.qml:60
109+#: qml/Components/PassphraseLockscreen.qml:62
93msgid "Hello"
110msgid "Hello"
94−msgstr "Üdv"
111+msgstr "Üdvözöljük"
95
112
96#: qml/Components/PinLockscreen.qml:198
113#: qml/Components/PinLockscreen.qml:198
97msgid "CANCEL"
114msgid "CANCEL"
@@ -105,15 +122,11 @@ msgstr "KÉSZ"
105msgid "See more"
122msgid "See more"
106msgstr "Több"
123msgstr "Több"
107
124
108−#: qml/Components/SeeMore.qml:58 qml/Dash/GenericScopeView.qml:330
125+#: qml/Components/SeeMore.qml:58 qml/Dash/GenericScopeView.qml:354
109msgid "See less"
126msgid "See less"
110msgstr "Kevesebb"
127msgstr "Kevesebb"
111
128
112−#: qml/Dash/DashApps.qml:37
113−msgid "Recent"
114−msgstr "Legutóbbi"
115−
116−#: qml/Dash/GenericScopeView.qml:330
129+#: qml/Dash/GenericScopeView.qml:354
117msgid "See all"
130msgid "See all"
118msgstr "Összes megtekintése"
131msgstr "Összes megtekintése"
119
132
@@ -137,6 +150,26 @@ msgstr "Értékelés hozzáadása"
137msgid "Send"
150msgid "Send"
138msgstr "Küldés"
151msgstr "Küldés"
139
152
153+#: qml/Dash/ScopesOverview.qml:187
154+msgid "Manage Dash"
155+msgstr ""
156+
157+#: qml/Dash/ScopesOverview.qml:392
158+msgid "Done"
159+msgstr ""
160+
161+#: qml/Dash/ScopesOverview.qml:418
162+msgid "Store"
163+msgstr ""
164+
165+#: qml/Dash/ScopesOverviewTab.qml:36
166+msgid "Favorites"
167+msgstr ""
168+
169+#: qml/Dash/ScopesOverviewTab.qml:54
170+msgid "All"
171+msgstr ""
172+
140#: qml/Greeter/Greeter.qml:157
173#: qml/Greeter/Greeter.qml:157
141msgid "Swipe to unlock"
174msgid "Swipe to unlock"
142msgstr "Csúsztasson a feloldáshoz"
175msgstr "Csúsztasson a feloldáshoz"
@@ -161,11 +194,11 @@ msgstr "Most beszéljen…"
161msgid "Speaking..."
194msgid "Speaking..."
162msgstr "Beszéd…"
195msgstr "Beszéd…"
163
196
164−#: qml/Notifications/NotificationMenuItemFactory.qml:91
197+#: qml/Notifications/NotificationMenuItemFactory.qml:97
165msgid "Show password"
198msgid "Show password"
166msgstr "Jelszó megjelenítése"
199msgstr "Jelszó megjelenítése"
167
200
168−#: qml/Notifications/NotificationMenuItemFactory.qml:103
201+#: qml/Notifications/NotificationMenuItemFactory.qml:112
169msgid "Please enter SIM PIN"
202msgid "Please enter SIM PIN"
170msgstr "Adja meg a SIM PIN kódját"
203msgstr "Adja meg a SIM PIN kódját"
171
204
@@ -177,27 +210,27 @@ msgstr "Érintse meg, hogy visszatérjen a híváshoz..."
177msgid "Conference"
210msgid "Conference"
178msgstr "Konferencia"
211msgstr "Konferencia"
179
212
180−#: qml/Panel/Indicators/MenuItemFactory.qml:583
213+#: qml/Panel/Indicators/MenuItemFactory.qml:577
181msgid "In queue…"
214msgid "In queue…"
182msgstr "Sorban…"
215msgstr "Sorban…"
183
216
184−#: qml/Panel/Indicators/MenuItemFactory.qml:587
217+#: qml/Panel/Indicators/MenuItemFactory.qml:581
185msgid "Downloading"
218msgid "Downloading"
186msgstr "Letöltés"
219msgstr "Letöltés"
187
220
188−#: qml/Panel/Indicators/MenuItemFactory.qml:589
221+#: qml/Panel/Indicators/MenuItemFactory.qml:583
189msgid "Paused, tap to resume"
222msgid "Paused, tap to resume"
190msgstr "Szüneteltetve, koppintson a folytatáshoz"
223msgstr "Szüneteltetve, koppintson a folytatáshoz"
191
224
192−#: qml/Panel/Indicators/MenuItemFactory.qml:591
225+#: qml/Panel/Indicators/MenuItemFactory.qml:585
193msgid "Canceled"
226msgid "Canceled"
194msgstr "Megszakítva"
227msgstr "Megszakítva"
195
228
196−#: qml/Panel/Indicators/MenuItemFactory.qml:593
229+#: qml/Panel/Indicators/MenuItemFactory.qml:587
197msgid "Finished"
230msgid "Finished"
198msgstr "Befejeződött"
231msgstr "Befejeződött"
199
232
200−#: qml/Panel/Indicators/MenuItemFactory.qml:595
233+#: qml/Panel/Indicators/MenuItemFactory.qml:589
201msgid "Failed, tap to retry"
234msgid "Failed, tap to retry"
202msgstr "Sikertelen, koppintson az újrapróbáláshoz"
235msgstr "Sikertelen, koppintson az újrapróbáláshoz"
203
236
@@ -205,7 +238,10 @@ msgstr "Sikertelen, koppintson az újrapróbáláshoz"
205msgid "Search"
238msgid "Search"
206msgstr "Keresés"
239msgstr "Keresés"
207
240
208−#: qml/Shell.qml:359
241+#: qml/Shell.qml:256
209#, qt-format
242#, qt-format
210msgid "Please enter %1"
243msgid "Please enter %1"
211msgstr "Adja meg a következőt: %1"
244msgstr "Adja meg a következőt: %1"
245+
246+#~ msgid "Recent"
247+#~ msgstr "Legutóbbi"
po/ja.po+11−11
@@ -8,14 +8,14 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2014-07-11 14:59+0200\n"
10"POT-Creation-Date: 2014-07-11 14:59+0200\n"
11−"PO-Revision-Date: 2014-01-18 07:01+0000\n"
11+"PO-Revision-Date: 2014-08-06 15:19+0000\n"
12"Last-Translator: Shushi Kurose <md81bird@hitaki.net>\n"
12"Last-Translator: Shushi Kurose <md81bird@hitaki.net>\n"
13"Language-Team: Japanese <ja@li.org>\n"
13"Language-Team: Japanese <ja@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2014-07-26 07:16+0000\n"
17+"X-Launchpad-Export-Date: 2014-08-07 06:27+0000\n"
18−"X-Generator: Launchpad (build 17131)\n"
18+"X-Generator: Launchpad (build 17147)\n"
19
19
20#: plugins/Unity/Launcher/launcheritem.cpp:43
20#: plugins/Unity/Launcher/launcheritem.cpp:43
21#: plugins/Unity/Launcher/launcheritem.cpp:73
21#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -28,7 +28,7 @@ msgstr ""
28
28
29#: qml/Components/EdgeDemoOverlay.qml:151
29#: qml/Components/EdgeDemoOverlay.qml:151
30msgid "Skip intro"
30msgid "Skip intro"
31−msgstr ""
31+msgstr "導入ガイドをスキップ"
32
32
33#: qml/Components/EdgeDemo.qml:113
33#: qml/Components/EdgeDemo.qml:113
34msgid "Right edge"
34msgid "Right edge"
@@ -44,7 +44,7 @@ msgstr "上端"
44
44
45#: qml/Components/EdgeDemo.qml:146
45#: qml/Components/EdgeDemo.qml:146
46msgid "Try swiping from the top edge to access the indicators"
46msgid "Try swiping from the top edge to access the indicators"
47−msgstr ""
47+msgstr "インジケーターにアクセスするには上端からスワイプしてみてください"
48
48
49#: qml/Components/EdgeDemo.qml:171
49#: qml/Components/EdgeDemo.qml:171
50msgid "Close"
50msgid "Close"
@@ -52,7 +52,7 @@ msgstr "閉じる"
52
52
53#: qml/Components/EdgeDemo.qml:172
53#: qml/Components/EdgeDemo.qml:172
54msgid "Swipe up again to close the settings screen"
54msgid "Swipe up again to close the settings screen"
55−msgstr ""
55+msgstr "設定画面を閉じるにはもう一度上にスワイプしてください"
56
56
57#: qml/Components/EdgeDemo.qml:199
57#: qml/Components/EdgeDemo.qml:199
58msgid "Left edge"
58msgid "Left edge"
@@ -60,11 +60,11 @@ msgstr "左端"
60
60
61#: qml/Components/EdgeDemo.qml:200
61#: qml/Components/EdgeDemo.qml:200
62msgid "Swipe from the left to reveal the launcher for quick access to apps"
62msgid "Swipe from the left to reveal the launcher for quick access to apps"
63−msgstr ""
63+msgstr "アプリに素早くアクセスできるLauncherを表示するには左からスワイプしてください"
64
64
65#: qml/Components/EdgeDemo.qml:227
65#: qml/Components/EdgeDemo.qml:227
66msgid "Well done"
66msgid "Well done"
67−msgstr ""
67+msgstr "よくできました!"
68
68
69#: qml/Components/EdgeDemo.qml:228
69#: qml/Components/EdgeDemo.qml:228
70msgid ""
70msgid ""
@@ -74,7 +74,7 @@ msgstr ""
74
74
75#: qml/Components/Lockscreen.qml:214
75#: qml/Components/Lockscreen.qml:214
76msgid "Emergency Call"
76msgid "Emergency Call"
77−msgstr ""
77+msgstr "緊急通報"
78
78
79#: qml/Components/Lockscreen.qml:231
79#: qml/Components/Lockscreen.qml:231
80msgid "OK"
80msgid "OK"
@@ -83,7 +83,7 @@ msgstr ""
83#: qml/Components/PassphraseLockscreen.qml:60
83#: qml/Components/PassphraseLockscreen.qml:60
84#, qt-format
84#, qt-format
85msgid "Hello %1"
85msgid "Hello %1"
86−msgstr ""
86+msgstr "こんにちは %1 さん"
87
87
88#: qml/Components/PassphraseLockscreen.qml:60
88#: qml/Components/PassphraseLockscreen.qml:60
89msgid "Hello"
89msgid "Hello"
@@ -127,7 +127,7 @@ msgstr ""
127
127
128#: qml/Dash/Previews/PreviewRatingInput.qml:126
128#: qml/Dash/Previews/PreviewRatingInput.qml:126
129msgid "Add a review"
129msgid "Add a review"
130−msgstr ""
130+msgstr "レビューを追加"
131
131
132#: qml/Dash/Previews/PreviewRatingInput.qml:166
132#: qml/Dash/Previews/PreviewRatingInput.qml:166
133msgid "Send"
133msgid "Send"
po/sl.po+71−35
@@ -6,16 +6,17 @@
6msgid ""
6msgid ""
7msgstr ""
7msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9+"Report-Msgid-Bugs-To: \n"
10−"POT-Creation-Date: 2014-07-11 14:59+0200\n"
10+"POT-Creation-Date: 2014-08-05 19:54+0200\n"
11−"PO-Revision-Date: 2014-07-28 12:32+0000\n"
11+"PO-Revision-Date: 2014-08-06 06:11+0000\n"
12"Last-Translator: Damir Jerovšek <Unknown>\n"
12"Last-Translator: Damir Jerovšek <Unknown>\n"
13"Language-Team: Slovenian <sl@li.org>\n"
13"Language-Team: Slovenian <sl@li.org>\n"
14+"Language: sl\n"
14"MIME-Version: 1.0\n"
15"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2014-07-29 06:54+0000\n"
18+"X-Launchpad-Export-Date: 2014-08-07 06:27+0000\n"
18−"X-Generator: Launchpad (build 17131)\n"
19+"X-Generator: Launchpad (build 17147)\n"
19
20
20#: plugins/Unity/Launcher/launcheritem.cpp:43
21#: plugins/Unity/Launcher/launcheritem.cpp:43
21#: plugins/Unity/Launcher/launcheritem.cpp:73
22#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -26,49 +27,65 @@ msgstr "Pripni bližnjico"
26msgid "Unpin shortcut"
27msgid "Unpin shortcut"
27msgstr "Odpni bližnjico"
28msgstr "Odpni bližnjico"
28
29
30+#: qml/Components/Dialogs.qml:142
31+msgid "Are you sure you would like to turn power off?"
32+msgstr ""
33+
34+#: qml/Components/Dialogs.qml:144
35+msgid "Power off"
36+msgstr ""
37+
38+#: qml/Components/Dialogs.qml:153
39+msgid "Restart"
40+msgstr ""
41+
42+#: qml/Components/Dialogs.qml:162
43+msgid "Cancel"
44+msgstr ""
45+
29#: qml/Components/EdgeDemoOverlay.qml:151
46#: qml/Components/EdgeDemoOverlay.qml:151
30msgid "Skip intro"
47msgid "Skip intro"
31msgstr "Preskoči uvod"
48msgstr "Preskoči uvod"
32
49
33−#: qml/Components/EdgeDemo.qml:113
50+#: qml/Components/EdgeDemo.qml:112
34msgid "Right edge"
51msgid "Right edge"
35msgstr "Desni rob"
52msgstr "Desni rob"
36
53
37−#: qml/Components/EdgeDemo.qml:114
54+#: qml/Components/EdgeDemo.qml:113
38msgid "Try swiping from the right edge to unlock the phone"
55msgid "Try swiping from the right edge to unlock the phone"
39msgstr "Poskusite povleči od desnega roba za odklep telefona"
56msgstr "Poskusite povleči od desnega roba za odklep telefona"
40
57
41−#: qml/Components/EdgeDemo.qml:145
58+#: qml/Components/EdgeDemo.qml:144
42msgid "Top edge"
59msgid "Top edge"
43msgstr "Zgornji rob"
60msgstr "Zgornji rob"
44
61
45−#: qml/Components/EdgeDemo.qml:146
62+#: qml/Components/EdgeDemo.qml:145
46msgid "Try swiping from the top edge to access the indicators"
63msgid "Try swiping from the top edge to access the indicators"
47msgstr "Poskusite povleči od zgornjega roba za dostop do kazalnikov"
64msgstr "Poskusite povleči od zgornjega roba za dostop do kazalnikov"
48
65
49−#: qml/Components/EdgeDemo.qml:171
66+#: qml/Components/EdgeDemo.qml:170
50msgid "Close"
67msgid "Close"
51msgstr "Zapri"
68msgstr "Zapri"
52
69
53−#: qml/Components/EdgeDemo.qml:172
70+#: qml/Components/EdgeDemo.qml:171
54msgid "Swipe up again to close the settings screen"
71msgid "Swipe up again to close the settings screen"
55msgstr "Povlecite ponovno navzgor za zaprtje zaslona z nastavitvami"
72msgstr "Povlecite ponovno navzgor za zaprtje zaslona z nastavitvami"
56
73
57−#: qml/Components/EdgeDemo.qml:199
74+#: qml/Components/EdgeDemo.qml:198
58msgid "Left edge"
75msgid "Left edge"
59msgstr "Levi rob"
76msgstr "Levi rob"
60
77
61−#: qml/Components/EdgeDemo.qml:200
78+#: qml/Components/EdgeDemo.qml:199
62msgid "Swipe from the left to reveal the launcher for quick access to apps"
79msgid "Swipe from the left to reveal the launcher for quick access to apps"
63msgstr ""
80msgstr ""
64"Poskusite povleči od leve za razkritje zaganjalnika za hiter dostop do "
81"Poskusite povleči od leve za razkritje zaganjalnika za hiter dostop do "
65"programov"
82"programov"
66
83
67−#: qml/Components/EdgeDemo.qml:227
84+#: qml/Components/EdgeDemo.qml:226
68msgid "Well done"
85msgid "Well done"
69msgstr "Odlično"
86msgstr "Odlično"
70
87
71−#: qml/Components/EdgeDemo.qml:228
88+#: qml/Components/EdgeDemo.qml:227
72msgid ""
89msgid ""
73"You have now mastered the edge gestures and can start using the "
90"You have now mastered the edge gestures and can start using the "
74"phone<br><br>Tap on the screen to start"
91"phone<br><br>Tap on the screen to start"
@@ -76,20 +93,20 @@ msgstr ""
76"Sedaj, ko ste osvojili poteze robov, lahko začnete uporabljati "
93"Sedaj, ko ste osvojili poteze robov, lahko začnete uporabljati "
77"telefon<br><br>Tapnite na zaslon za začetek"
94"telefon<br><br>Tapnite na zaslon za začetek"
78
95
79−#: qml/Components/Lockscreen.qml:214
96+#: qml/Components/Lockscreen.qml:220
80msgid "Emergency Call"
97msgid "Emergency Call"
81msgstr "Klic v sili"
98msgstr "Klic v sili"
82
99
83−#: qml/Components/Lockscreen.qml:231
100+#: qml/Components/Lockscreen.qml:243
84msgid "OK"
101msgid "OK"
85msgstr "V REDU"
102msgstr "V REDU"
86
103
87−#: qml/Components/PassphraseLockscreen.qml:60
104+#: qml/Components/PassphraseLockscreen.qml:62
88#, qt-format
105#, qt-format
89msgid "Hello %1"
106msgid "Hello %1"
90msgstr "Pozdravljeni, %1"
107msgstr "Pozdravljeni, %1"
91
108
92−#: qml/Components/PassphraseLockscreen.qml:60
109+#: qml/Components/PassphraseLockscreen.qml:62
93msgid "Hello"
110msgid "Hello"
94msgstr "Pozdravljeni"
111msgstr "Pozdravljeni"
95
112
@@ -105,17 +122,13 @@ msgstr "KONČANO"
105msgid "See more"
122msgid "See more"
106msgstr "Pokaži več"
123msgstr "Pokaži več"
107
124
108−#: qml/Components/SeeMore.qml:58 qml/Dash/GenericScopeView.qml:330
125+#: qml/Components/SeeMore.qml:58 qml/Dash/GenericScopeView.qml:354
109msgid "See less"
126msgid "See less"
110msgstr "Pokaži manj"
127msgstr "Pokaži manj"
111
128
112−#: qml/Dash/DashApps.qml:37
113−msgid "Recent"
114−msgstr "Nedavno"
115−
116−#: qml/Dash/GenericScopeView.qml:330
129+#: qml/Dash/GenericScopeView.qml:354
117msgid "See all"
130msgid "See all"
118−msgstr ""
131+msgstr "Ogled vsega"
119
132
120#: qml/Dash/Previews/PreviewActionCombo.qml:34
133#: qml/Dash/Previews/PreviewActionCombo.qml:34
121msgid "More..."
134msgid "More..."
@@ -137,6 +150,26 @@ msgstr "Dodaj oceno"
137msgid "Send"
150msgid "Send"
138msgstr "Pošlji"
151msgstr "Pošlji"
139
152
153+#: qml/Dash/ScopesOverview.qml:187
154+msgid "Manage Dash"
155+msgstr ""
156+
157+#: qml/Dash/ScopesOverview.qml:392
158+msgid "Done"
159+msgstr ""
160+
161+#: qml/Dash/ScopesOverview.qml:418
162+msgid "Store"
163+msgstr ""
164+
165+#: qml/Dash/ScopesOverviewTab.qml:36
166+msgid "Favorites"
167+msgstr ""
168+
169+#: qml/Dash/ScopesOverviewTab.qml:54
170+msgid "All"
171+msgstr ""
172+
140#: qml/Greeter/Greeter.qml:157
173#: qml/Greeter/Greeter.qml:157
141msgid "Swipe to unlock"
174msgid "Swipe to unlock"
142msgstr "Podrsajte za odklenitev"
175msgstr "Podrsajte za odklenitev"
@@ -161,11 +194,11 @@ msgstr "Govorite zdaj ..."
161msgid "Speaking..."
194msgid "Speaking..."
162msgstr "Govorjenje ..."
195msgstr "Govorjenje ..."
163
196
164−#: qml/Notifications/NotificationMenuItemFactory.qml:91
197+#: qml/Notifications/NotificationMenuItemFactory.qml:97
165msgid "Show password"
198msgid "Show password"
166msgstr "Pokaži geslo"
199msgstr "Pokaži geslo"
167
200
168−#: qml/Notifications/NotificationMenuItemFactory.qml:103
201+#: qml/Notifications/NotificationMenuItemFactory.qml:112
169msgid "Please enter SIM PIN"
202msgid "Please enter SIM PIN"
170msgstr "Vnesite PIN kartice SIM"
203msgstr "Vnesite PIN kartice SIM"
171
204
@@ -177,27 +210,27 @@ msgstr "Tapnite za vrnitev v klic ..."
177msgid "Conference"
210msgid "Conference"
178msgstr "Konferenca"
211msgstr "Konferenca"
179
212
180−#: qml/Panel/Indicators/MenuItemFactory.qml:583
213+#: qml/Panel/Indicators/MenuItemFactory.qml:577
181msgid "In queue…"
214msgid "In queue…"
182msgstr "V vrsti ..."
215msgstr "V vrsti ..."
183
216
184−#: qml/Panel/Indicators/MenuItemFactory.qml:587
217+#: qml/Panel/Indicators/MenuItemFactory.qml:581
185msgid "Downloading"
218msgid "Downloading"
186msgstr "Prejemanje"
219msgstr "Prejemanje"
187
220
188−#: qml/Panel/Indicators/MenuItemFactory.qml:589
221+#: qml/Panel/Indicators/MenuItemFactory.qml:583
189msgid "Paused, tap to resume"
222msgid "Paused, tap to resume"
190msgstr "Premor, tapnite za nadaljevanje"
223msgstr "Premor, tapnite za nadaljevanje"
191
224
192−#: qml/Panel/Indicators/MenuItemFactory.qml:591
225+#: qml/Panel/Indicators/MenuItemFactory.qml:585
193msgid "Canceled"
226msgid "Canceled"
194msgstr "Preklicano"
227msgstr "Preklicano"
195
228
196−#: qml/Panel/Indicators/MenuItemFactory.qml:593
229+#: qml/Panel/Indicators/MenuItemFactory.qml:587
197msgid "Finished"
230msgid "Finished"
198msgstr "Končano"
231msgstr "Končano"
199
232
200−#: qml/Panel/Indicators/MenuItemFactory.qml:595
233+#: qml/Panel/Indicators/MenuItemFactory.qml:589
201msgid "Failed, tap to retry"
234msgid "Failed, tap to retry"
202msgstr "Spodletelo, tapnite za ponovni poskus"
235msgstr "Spodletelo, tapnite za ponovni poskus"
203
236
@@ -205,7 +238,10 @@ msgstr "Spodletelo, tapnite za ponovni poskus"
205msgid "Search"
238msgid "Search"
206msgstr "Iskanje"
239msgstr "Iskanje"
207
240
208−#: qml/Shell.qml:359
241+#: qml/Shell.qml:256
209#, qt-format
242#, qt-format
210msgid "Please enter %1"
243msgid "Please enter %1"
211msgstr "Vnesite %1"
244msgstr "Vnesite %1"
245+
246+#~ msgid "Recent"
247+#~ msgstr "Nedavno"
qml/Components/EdgeDemo.qml+15−15
@@ -24,13 +24,13 @@ Item {
24 property Item greeter
24 property Item greeter
25 property Item launcher
25 property Item launcher
26 property Item indicators
26 property Item indicators
27− property Item underlay
27+ property Item stages
28
28
29 property bool launcherEnabled: true
29 property bool launcherEnabled: true
30− property bool dashEnabled: true
30+ property bool stagesEnabled: true
31 property bool panelEnabled: true
31 property bool panelEnabled: true
32 property bool panelContentEnabled: true
32 property bool panelContentEnabled: true
33− property bool running: !launcherEnabled || !dashEnabled || !panelEnabled || !panelContentEnabled
33+ property bool running: !launcherEnabled || !stagesEnabled || !panelEnabled || !panelContentEnabled
34
34
35 property bool paused: false
35 property bool paused: false
36
36
@@ -58,7 +58,7 @@ Item {
58
58
59 function stopDemo() {
59 function stopDemo() {
60 launcherEnabled = true
60 launcherEnabled = true
61− dashEnabled = true
61+ stagesEnabled = true
62 panelEnabled = true
62 panelEnabled = true
63 panelContentEnabled = true
63 panelContentEnabled = true
64 if (d.rightEdgeDemo) d.rightEdgeDemo.destroy()
64 if (d.rightEdgeDemo) d.rightEdgeDemo.destroy()
@@ -74,11 +74,11 @@ Item {
74 }
74 }
75
75
76 launcherEnabled = false;
76 launcherEnabled = false;
77− dashEnabled = false;
77+ stagesEnabled = false;
78 panelEnabled = false;
78 panelEnabled = false;
79 panelContentEnabled = false;
79 panelContentEnabled = false;
80
80
81− // Begin with either greeter or dash, depending on which is visible
81+ // Begin with either greeter or top, depending on which is visible
82 if (greeter && greeter.shown) {
82 if (greeter && greeter.shown) {
83 startRightEdgeDemo()
83 startRightEdgeDemo()
84 } else {
84 } else {
@@ -138,12 +138,12 @@ Item {
138
138
139 function startTopEdgeDemo() {
139 function startTopEdgeDemo() {
140 demo.panelEnabled = true;
140 demo.panelEnabled = true;
141− if (demo.dash && demo.underlay) {
141+ if (demo.stages) {
142− d.topEdgeDemo = d.overlay.createObject(demo.underlay, {
142+ d.topEdgeDemo = d.overlay.createObject(demo.stages, {
143 "edge": "top",
143 "edge": "top",
144 "title": i18n.tr("Top edge"),
144 "title": i18n.tr("Top edge"),
145 "text": i18n.tr("Try swiping from the top edge to access the indicators"),
145 "text": i18n.tr("Try swiping from the top edge to access the indicators"),
146− "anchors.fill": demo.underlay,
146+ "anchors.fill": demo.stages,
147 });
147 });
148 }
148 }
149 if (d.topEdgeDemo) {
149 if (d.topEdgeDemo) {
@@ -192,12 +192,12 @@ Item {
192 function startLeftEdgeDemo() {
192 function startLeftEdgeDemo() {
193 demo.panelEnabled = false;
193 demo.panelEnabled = false;
194 demo.launcherEnabled = true;
194 demo.launcherEnabled = true;
195− if (demo.underlay) {
195+ if (demo.stages) {
196− d.leftEdgeDemo = d.overlay.createObject(demo.underlay, {
196+ d.leftEdgeDemo = d.overlay.createObject(demo.stages, {
197 "edge": "left",
197 "edge": "left",
198 "title": i18n.tr("Left edge"),
198 "title": i18n.tr("Left edge"),
199 "text": i18n.tr("Swipe from the left to reveal the launcher for quick access to apps"),
199 "text": i18n.tr("Swipe from the left to reveal the launcher for quick access to apps"),
200− "anchors.fill": demo.underlay,
200+ "anchors.fill": demo.stages,
201 });
201 });
202 }
202 }
203 if (d.leftEdgeDemo) {
203 if (d.leftEdgeDemo) {
@@ -220,12 +220,12 @@ Item {
220
220
221 function startFinalEdgeDemo() {
221 function startFinalEdgeDemo() {
222 demo.launcherEnabled = false;
222 demo.launcherEnabled = false;
223− if (demo.underlay) {
223+ if (demo.stages) {
224− d.finalEdgeDemo = d.overlay.createObject(demo.underlay, {
224+ d.finalEdgeDemo = d.overlay.createObject(demo.stages, {
225 "edge": "none",
225 "edge": "none",
226 "title": i18n.tr("Well done"),
226 "title": i18n.tr("Well done"),
227 "text": i18n.tr("You have now mastered the edge gestures and can start using the phone<br><br>Tap on the screen to start"),
227 "text": i18n.tr("You have now mastered the edge gestures and can start using the phone<br><br>Tap on the screen to start"),
228− "anchors.fill": demo.underlay,
228+ "anchors.fill": demo.stages,
229 "showSkip": false,
229 "showSkip": false,
230 });
230 });
231 }
231 }
qml/Components/PageHeader.qml+25−16
@@ -32,10 +32,11 @@ Item {
32 property bool searchEntryEnabled: false
32 property bool searchEntryEnabled: false
33 property ListModel searchHistory: SearchHistoryModel
33 property ListModel searchHistory: SearchHistoryModel
34 property alias searchQuery: searchTextField.text
34 property alias searchQuery: searchTextField.text
35− property bool searchInProgress: false
36 property alias showSignatureLine: bottomBorder.visible
35 property alias showSignatureLine: bottomBorder.visible
37
36
38 property alias bottomItem: bottomContainer.children
37 property alias bottomItem: bottomContainer.children
38+ property int paginationCount: 0
39+ property int paginationIndex: -1
39
40
40 // TODO We should use foreground for the icons
41 // TODO We should use foreground for the icons
41 // of the toolbar but unfortunately Action does not have
42 // of the toolbar but unfortunately Action does not have
@@ -126,7 +127,7 @@ Item {
126 Flickable {
127 Flickable {
127 id: headerContainer
128 id: headerContainer
128 objectName: "headerContainer"
129 objectName: "headerContainer"
129− clip: openSearchAnimation.running
130+ clip: contentY < height
130 anchors { left: parent.left; top: parent.top; right: parent.right }
131 anchors { left: parent.left; top: parent.top; right: parent.right }
131 height: units.gu(6.5)
132 height: units.gu(6.5)
132 contentHeight: headersColumn.height
133 contentHeight: headersColumn.height
@@ -170,6 +171,7 @@ Item {
170 property var styledItem: searchHeader
171 property var styledItem: searchHeader
171 property string title
172 property string title
172 property var config: PageHeadConfiguration {
173 property var config: PageHeadConfiguration {
174+ foregroundColor: root.scopeStyle ? root.scopeStyle.headerForeground : "grey"
173 backAction: Action {
175 backAction: Action {
174 iconName: "back"
176 iconName: "back"
175 onTriggered: {
177 onTriggered: {
@@ -201,25 +203,13 @@ Item {
201 anchors.fill: parent
203 anchors.fill: parent
202 anchors.margins: units.gu(.75)
204 anchors.margins: units.gu(.75)
203 source: "image://theme/clear"
205 source: "image://theme/clear"
204− opacity: searchTextField.text.length > 0 && !searchActivityIndicator.running
206+ opacity: searchTextField.text.length > 0
205 visible: opacity > 0
207 visible: opacity > 0
206 Behavior on opacity {
208 Behavior on opacity {
207 UbuntuNumberAnimation { duration: UbuntuAnimation.FastDuration }
209 UbuntuNumberAnimation { duration: UbuntuAnimation.FastDuration }
208 }
210 }
209 }
211 }
210
212
211− ActivityIndicator {
212− id: searchActivityIndicator
213− objectName: "searchIndicator"
214− anchors.fill: parent
215− anchors.margins: units.gu(.75)
216− running: root.searchInProgress
217− opacity: running ? 1 : 0
218− Behavior on opacity {
219− UbuntuNumberAnimation { duration: UbuntuAnimation.FastDuration }
220− }
221− }
222−
223 onClicked: {
213 onClicked: {
224 root.resetSearch(true);
214 root.resetSearch(true);
225 root.openSearchHistory();
215 root.openSearchHistory();
@@ -248,10 +238,10 @@ Item {
248 contentHeight: height
238 contentHeight: height
249 opacity: headerContainer.clip || !headerContainer.showSearch ? 1 : 0 // setting visible false cause column to relayout
239 opacity: headerContainer.clip || !headerContainer.showSearch ? 1 : 0 // setting visible false cause column to relayout
250 separatorSource: ""
240 separatorSource: ""
251− textColor: root.scopeStyle ? root.scopeStyle.headerForeground : "grey"
252 property var styledItem: header
241 property var styledItem: header
253 property string title: root.title
242 property string title: root.title
254 property var config: PageHeadConfiguration {
243 property var config: PageHeadConfiguration {
244+ foregroundColor: root.scopeStyle ? root.scopeStyle.headerForeground : "grey"
255 backAction: Action {
245 backAction: Action {
256 iconName: "back"
246 iconName: "back"
257 visible: root.showBackButton
247 visible: root.showBackButton
@@ -296,6 +286,25 @@ Item {
296 }
286 }
297 }
287 }
298
288
289+ Row {
290+ spacing: units.gu(.5)
291+ Repeater {
292+ objectName: "paginationRepeater"
293+ model: root.paginationCount
294+ Image {
295+ objectName: "paginationDots_" + index
296+ height: units.gu(1)
297+ width: height
298+ source: (index == root.paginationIndex) ? "graphics/pagination_dot_on.png" : "graphics/pagination_dot_off.png"
299+ }
300+ }
301+ anchors {
302+ top: headerContainer.bottom
303+ horizontalCenter: headerContainer.horizontalCenter
304+ topMargin: units.gu(.5)
305+ }
306+ }
307+
299 Component {
308 Component {
300 id: popoverComponent
309 id: popoverComponent
301 Popover {
310 Popover {
qml/Components/SeeMore.qmldeleted−70
@@ -1,70 +0,0 @@
1−/*
2− * Copyright (C) 2014 Canonical, Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1
19−
20−/*! Widget that can be used in combination with a text area to allow easy 'expand/collapse' functionality. */
21−
22−Item {
23− //! Boolean set to true when it suggests expanded functionality
24− property bool more: false
25−
26− implicitHeight: seeMoreLabel.height + units.gu(2)
27−
28− Row {
29− anchors.centerIn: parent
30− spacing: units.gu(2)
31−
32− Label {
33− id: seeMoreLabel
34− objectName: "seeMoreLabel"
35− text: i18n.tr("See more")
36− opacity: !more ? 0.8 : 0.4
37− // TODO: Fix requiring Palette update
38− color: "grey" //Theme.palette.selected.backgroundText
39− font.weight: Font.Bold
40−
41− MouseArea {
42− anchors.fill: parent
43− onClicked: more = true
44− }
45− }
46−
47− Image {
48− anchors {
49− top: parent.top
50− bottom: parent.bottom
51− }
52− width: units.dp(2)
53− source: "ListItems/graphics/ListItemDividerVertical.png"
54− }
55−
56− Label {
57− objectName: "seeLessLabel"
58− text: i18n.tr("See less")
59− opacity: more ? 0.8 : 0.4
60− // TODO: Fix requiring Palette update
61− color: "grey" //Theme.palette.selected.backgroundText
62− font.weight: Font.Bold
63−
64− MouseArea {
65− anchors.fill: parent
66− onClicked: more = false
67− }
68− }
69− }
70−}
qml/Components/graphics/pagination_dot_off@30.pngnew file

Binary file not shown.

qml/Components/graphics/pagination_dot_on@30.pngnew file

Binary file not shown.

qml/Dash/CardTool.qml+1−1
@@ -126,7 +126,7 @@ Item {
126 type:real \brief Height of the card's header.
126 type:real \brief Height of the card's header.
127 */
127 */
128 readonly property int headerHeight: cardLoader.item ? cardLoader.item.headerHeight : 0
128 readonly property int headerHeight: cardLoader.item ? cardLoader.item.headerHeight : 0
129− readonly property size artShapeSize: cardLoader.item ? cardLoader.item.artShapeSize : 0
129+ property size artShapeSize: cardLoader.item ? cardLoader.item.artShapeSize : 0
130
130
131 /*!
131 /*!
132 \brief Desired alignment of header components.
132 \brief Desired alignment of header components.
qml/Dash/Dash.qml+83−13
@@ -14,7 +14,7 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
15 */
16
16
17−import QtQuick 2.0
17+import QtQuick 2.2
18import Ubuntu.Components 0.1
18import Ubuntu.Components 0.1
19import Ubuntu.Gestures 0.1
19import Ubuntu.Gestures 0.1
20import Unity 0.2
20import Unity 0.2
@@ -39,7 +39,13 @@ Showable {
39 }
39 }
40
40
41 function setCurrentScope(scopeId, animate, reset) {
41 function setCurrentScope(scopeId, animate, reset) {
42− var scopeIndex = filteredScopes.findFirst(Scopes.RoleId, scopeId)
42+ var scopeIndex = -1;
43+ for (var i = 0; i < scopes.count; ++i) {
44+ if (scopes.getScope(i).id == scopeId) {
45+ scopeIndex = i;
46+ break;
47+ }
48+ }
43
49
44 if (scopeIndex == -1) {
50 if (scopeIndex == -1) {
45 console.warn("No match for scope with id: %1".arg(scopeId))
51 console.warn("No match for scope with id: %1".arg(scopeId))
@@ -64,15 +70,8 @@ Showable {
64 }
70 }
65 }
71 }
66
72
67− SortFilterProxyModel {
73+ Scopes {
68− id: filteredScopes
69− model: Scopes {
70− id: scopes
74+ id: scopes
71− }
72− dynamicSortFilter: true
73−
74− filterRole: Scopes.RoleVisible
75− filterRegExp: RegExp("^true$")
76 }
75 }
77
76
78 QtObject {
77 QtObject {
@@ -114,7 +113,13 @@ Showable {
114 hide();
113 hide();
115 }
114 }
116 onSearchSelected: {
115 onSearchSelected: {
117− var scopeIndex = filteredScopes.findFirst(Scopes.RoleId, scopeId);
116+ var scopeIndex = -1;
117+ for (var i = 0; i < scopes.count; ++i) {
118+ if (scopes.getScope(i).id == scopeId) {
119+ scopeIndex = i;
120+ break;
121+ }
122+ }
118 if (scopeIndex >= 0) {
123 if (scopeIndex >= 0) {
119 // Is a favorite one
124 // Is a favorite one
120 setCurrentScope(scopeId, false, false);
125 setCurrentScope(scopeId, false, false);
@@ -157,7 +162,6 @@ Showable {
157 objectName: "dashContent"
162 objectName: "dashContent"
158 width: dash.width
163 width: dash.width
159 height: dash.height
164 height: dash.height
160− model: filteredScopes
161 scopes: scopes
165 scopes: scopes
162 visible: !scopesOverview.showingNonFavoriteScope && x != -width
166 visible: !scopesOverview.showingNonFavoriteScope && x != -width
163 onGotoScope: {
167 onGotoScope: {
@@ -254,6 +258,72 @@ Showable {
254 }
258 }
255 }
259 }
256
260
261+ Rectangle {
262+ id: indicator
263+ objectName: "processingIndicator"
264+ anchors {
265+ left: parent.left
266+ right: parent.right
267+ bottom: parent.bottom
268+ }
269+ height: units.dp(3)
270+ color: scopeStyle.backgroundLuminance > 0.7 ? "#50000000" : "#50ffffff"
271+ opacity: 0
272+ visible: opacity > 0
273+
274+ readonly property bool processing: dashContent.processing || scopeItem.processing
275+
276+ Behavior on opacity {
277+ UbuntuNumberAnimation { duration: UbuntuAnimation.FastDuration }
278+ }
279+
280+ onProcessingChanged: {
281+ if (processing) delay.start();
282+ else if (!persist.running) indicator.opacity = 0;
283+ }
284+
285+ Timer {
286+ id: delay
287+ interval: 200
288+ onTriggered: if (indicator.processing) {
289+ persist.restart();
290+ indicator.opacity = 1;
291+ }
292+ }
293+
294+ Timer {
295+ id: persist
296+ interval: 2 * UbuntuAnimation.SleepyDuration - UbuntuAnimation.FastDuration
297+ onTriggered: if (!indicator.processing) indicator.opacity = 0
298+ }
299+
300+ Rectangle {
301+ id: orange
302+ anchors { top: parent.top; bottom: parent.bottom }
303+ width: parent.width / 4
304+ color: Theme.palette.selected.foreground
305+
306+ SequentialAnimation {
307+ running: indicator.visible
308+ loops: Animation.Infinite
309+ XAnimator {
310+ from: -orange.width / 2
311+ to: indicator.width - orange.width / 2
312+ duration: UbuntuAnimation.SleepyDuration
313+ easing.type: Easing.InOutSine
314+ target: orange
315+ }
316+ XAnimator {
317+ from: indicator.width - orange.width / 2
318+ to: -orange.width / 2
319+ duration: UbuntuAnimation.SleepyDuration
320+ easing.type: Easing.InOutSine
321+ target: orange
322+ }
323+ }
324+ }
325+ }
326+
257 EdgeDragArea {
327 EdgeDragArea {
258 id: overviewDragHandle
328 id: overviewDragHandle
259 objectName: "overviewDragHandle"
329 objectName: "overviewDragHandle"
qml/Dash/DashApplication.qml+7
@@ -16,6 +16,7 @@
16
16
17import QtQuick 2.2
17import QtQuick 2.2
18import Ubuntu.Components 1.0
18import Ubuntu.Components 1.0
19+import Ubuntu.Thumbnailer 0.1 // Register support for image://thumbnailer/ and image://albumart/
19
20
20MainView {
21MainView {
21 width: units.gu(40)
22 width: units.gu(40)
@@ -23,6 +24,12 @@ MainView {
23
24
24 useDeprecatedToolbar: false
25 useDeprecatedToolbar: false
25
26
27+ Binding {
28+ target: i18n
29+ property: "domain"
30+ value: "unity8"
31+ }
32+
26 Dash {
33 Dash {
27 anchors.fill: parent
34 anchors.fill: parent
28 }
35 }
qml/Dash/DashContent.qml+7−4
@@ -23,13 +23,14 @@ import "../Components"
23Item {
23Item {
24 id: dashContent
24 id: dashContent
25
25
26− property var model: null
26+ property alias scopes: dashContentList.model
27− property var scopes: null
28 readonly property alias currentIndex: dashContentList.currentIndex
27 readonly property alias currentIndex: dashContentList.currentIndex
29 readonly property string currentScopeId: dashContentList.currentItem ? dashContentList.currentItem.scopeId : ""
28 readonly property string currentScopeId: dashContentList.currentItem ? dashContentList.currentItem.scopeId : ""
30 readonly property var currentScope: dashContentList.currentItem ? dashContentList.currentItem.theScope : null
29 readonly property var currentScope: dashContentList.currentItem ? dashContentList.currentItem.theScope : null
31 readonly property bool previewShown: dashContentList.currentItem && dashContentList.currentItem.item ?
30 readonly property bool previewShown: dashContentList.currentItem && dashContentList.currentItem.item ?
32 dashContentList.currentItem.item.previewShown : false
31 dashContentList.currentItem.item.previewShown : false
32+ readonly property bool processing: dashContentList.currentItem && dashContentList.currentItem.item
33+ && dashContentList.currentItem.item.processing || false
33
34
34 signal scopeLoaded(string scopeId)
35 signal scopeLoaded(string scopeId)
35 signal gotoScope(string scopeId)
36 signal gotoScope(string scopeId)
@@ -93,10 +94,9 @@ Item {
93 id: dashContentList
94 id: dashContentList
94 objectName: "dashContentList"
95 objectName: "dashContentList"
95
96
96− interactive: dashContent.scopes.loaded && currentItem && !currentItem.moving
97+ interactive: dashContent.scopes.loaded && currentItem && !currentItem.moving && !currentItem.navigationShown
97
98
98 anchors.fill: parent
99 anchors.fill: parent
99− model: dashContent.model
100 orientation: ListView.Horizontal
100 orientation: ListView.Horizontal
101 boundsBehavior: Flickable.DragAndOvershootBounds
101 boundsBehavior: Flickable.DragAndOvershootBounds
102 flickDeceleration: units.gu(625)
102 flickDeceleration: units.gu(625)
@@ -134,6 +134,7 @@ Item {
134 objectName: scope.id + " loader"
134 objectName: scope.id + " loader"
135
135
136 readonly property bool moving: item ? item.moving : false
136 readonly property bool moving: item ? item.moving : false
137+ readonly property bool navigationShown: item ? item.navigationShown : false
137 readonly property var categoryView: item ? item.categoryView : null
138 readonly property var categoryView: item ? item.categoryView : null
138 readonly property var theScope: scope
139 readonly property var theScope: scope
139
140
@@ -147,6 +148,8 @@ Item {
147 item.scope = Qt.binding(function() { return scope })
148 item.scope = Qt.binding(function() { return scope })
148 item.isCurrent = Qt.binding(function() { return visible && ListView.isCurrentItem })
149 item.isCurrent = Qt.binding(function() { return visible && ListView.isCurrentItem })
149 dashContent.scopeLoaded(item.scope.id)
150 dashContent.scopeLoaded(item.scope.id)
151+ item.paginationCount = Qt.binding(function() { return dashContentList.count } )
152+ item.paginationIndex = Qt.binding(function() { return dashContentList.currentIndex } )
150 }
153 }
151 Connections {
154 Connections {
152 target: isCurrent ? scope : null
155 target: isCurrent ? scope : null
qml/Dash/DashDepartments.qml → qml/Dash/DashNavigation.qmlrenamed+50−43
@@ -15,17 +15,17 @@
15 */
15 */
16
16
17import QtQuick 2.2
17import QtQuick 2.2
18−import Ubuntu.Components 0.1
18+import Ubuntu.Components 1.1
19
19
20AbstractButton {
20AbstractButton {
21 id: root
21 id: root
22− objectName: "dashDepartments"
22+ objectName: "dashNavigation"
23
23
24 property var scope: null
24 property var scope: null
25
25
26 property bool showList: false
26 property bool showList: false
27
27
28− readonly property var currentDepartment: scope && scope.hasDepartments ? scope.getDepartment(scope.currentDepartmentId) : null
28+ readonly property var currentNavigation: scope && scope.hasNavigation ? scope.getNavigation(scope.currentNavigationId) : null
29
29
30 property alias windowWidth: blackRect.width
30 property alias windowWidth: blackRect.width
31 property alias windowHeight: blackRect.height
31 property alias windowHeight: blackRect.height
@@ -34,20 +34,21 @@ AbstractButton {
34 // Are we drilling down the tree or up?
34 // Are we drilling down the tree or up?
35 property bool isGoingBack: false
35 property bool isGoingBack: false
36
36
37− visible: root.currentDepartment != null
37+ visible: root.currentNavigation != null
38
38
39 height: visible ? units.gu(5) : 0
39 height: visible ? units.gu(5) : 0
40
40
41 onClicked: {
41 onClicked: {
42+ navigationListView.updateMaxHeight();
42 root.showList = !root.showList;
43 root.showList = !root.showList;
43 }
44 }
44
45
45 Rectangle {
46 Rectangle {
46 id: blackRect
47 id: blackRect
47 color: "black"
48 color: "black"
48− opacity: departmentListView.currentItem && departmentListView.currentItem.visible ? 0.3 : 0
49+ opacity: navigationListView.currentItem && navigationListView.currentItem.visible ? 0.3 : 0
49 Behavior on opacity { UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration } }
50 Behavior on opacity { UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration } }
50− anchors.top: departmentListView.top
51+ anchors.top: navigationListView.top
51 anchors.right: parent.right
52 anchors.right: parent.right
52 visible: opacity != 0
53 visible: opacity != 0
53 }
54 }
@@ -78,7 +79,7 @@ AbstractButton {
78 anchors.fill: parent
79 anchors.fill: parent
79 anchors.margins: units.gu(2)
80 anchors.margins: units.gu(2)
80 verticalAlignment: Text.AlignVCenter
81 verticalAlignment: Text.AlignVCenter
81− text: root.currentDepartment ? root.currentDepartment.label : ""
82+ text: root.currentNavigation ? root.currentNavigation.label : ""
82 color: root.scopeStyle ? root.scopeStyle.foreground : "grey"
83 color: root.scopeStyle ? root.scopeStyle.foreground : "grey"
83 }
84 }
84
85
@@ -92,18 +93,18 @@ AbstractButton {
92 color: root.scopeStyle ? root.scopeStyle.foreground : "grey"
93 color: root.scopeStyle ? root.scopeStyle.foreground : "grey"
93 }
94 }
94
95
95− // departmentListView is outside root
96+ // navigationListView is outside root
96 ListView {
97 ListView {
97− id: departmentListView
98+ id: navigationListView
98− objectName: "departmentListView"
99+ objectName: "navigationListView"
99 orientation: ListView.Horizontal
100 orientation: ListView.Horizontal
100 interactive: false
101 interactive: false
101 clip: root.width != windowWidth
102 clip: root.width != windowWidth
102 model: ListModel {
103 model: ListModel {
103− id: departmentModel
104+ id: navigationModel
104 // We have two roles
105 // We have two roles
105− // departmentId: the department id of the department the list represents
106+ // navigationId: the navigation id of the navigation the list represents
106− // nullifyDepartment: overrides departmentId to be null
107+ // nullifyNavigation: overrides navigationId to be null
107 // This is used to "clear" the delegate when going "right" on the tree
108 // This is used to "clear" the delegate when going "right" on the tree
108 }
109 }
109 anchors {
110 anchors {
@@ -111,7 +112,12 @@ AbstractButton {
111 right: parent.right
112 right: parent.right
112 top: root.bottom
113 top: root.bottom
113 }
114 }
115+ property int maxHeight: -1
116+ Component.onCompleted: updateMaxHeight();
117+ function updateMaxHeight()
118+ {
114− readonly property int maxHeight: (windowHeight - mapToItem(null, root.x, root.y).y) - units.gu(8)
119+ maxHeight = (windowHeight - mapToItem(null, 0, 0).y) - units.gu(8);
120+ }
115 property int prevHeight: maxHeight
121 property int prevHeight: maxHeight
116 height: currentItem ? currentItem.height : maxHeight
122 height: currentItem ? currentItem.height : maxHeight
117 onHeightChanged: {
123 onHeightChanged: {
@@ -120,83 +126,84 @@ AbstractButton {
120 }
126 }
121 }
127 }
122 highlightMoveDuration: UbuntuAnimation.FastDuration
128 highlightMoveDuration: UbuntuAnimation.FastDuration
123− delegate: DashDepartmentsList {
129+ delegate: DashNavigationList {
124− objectName: "department" + index
130+ objectName: "navigation" + index
125 visible: height != 0
131 visible: height != 0
126− width: departmentListView.width
132+ width: navigationListView.width
127 scopeStyle: root.scopeStyle
133 scopeStyle: root.scopeStyle
128 property real desiredHeight: {
134 property real desiredHeight: {
129 if (root.showList) {
135 if (root.showList) {
130− if (department && department.loaded && x == departmentListView.contentX)
136+ if (navigation && navigation.loaded && x == navigationListView.contentX)
131 {
137 {
138+ navigationListView.updateMaxHeight();
132− return Math.min(implicitHeight, departmentListView.maxHeight);
139+ return Math.min(implicitHeight, navigationListView.maxHeight);
133 } else {
140 } else {
134− return departmentListView.prevHeight;
141+ return navigationListView.prevHeight;
135 }
142 }
136 } else {
143 } else {
137 return 0;
144 return 0;
138 }
145 }
139 }
146 }
140 height: desiredHeight
147 height: desiredHeight
141− department: (nullifyDepartment || !scope) ? null : scope.getDepartment(departmentId)
148+ navigation: (nullifyNavigation || !scope) ? null : scope.getNavigation(navigationId)
142− currentDepartment: root.currentDepartment
149+ currentNavigation: root.currentNavigation
143− onEnterDepartment: {
150+ onEnterNavigation: {
144− scope.loadDepartment(newDepartmentId);
151+ scope.setNavigationState(newNavigationId, false);
145 // We only need to add a new item to the model
152 // We only need to add a new item to the model
146 // if we have children, otherwise just load it
153 // if we have children, otherwise just load it
147 if (hasChildren) {
154 if (hasChildren) {
148 isGoingBack = false;
155 isGoingBack = false;
149− departmentModel.append({"departmentId": newDepartmentId, "nullifyDepartment": false});
156+ navigationModel.append({"navigationId": newNavigationId, "nullifyNavigation": false});
150− departmentListView.currentIndex++;
157+ navigationListView.currentIndex++;
151 } else {
158 } else {
152 showList = false;
159 showList = false;
153 }
160 }
154 }
161 }
155 onGoBackToParentClicked: {
162 onGoBackToParentClicked: {
156− scope.loadDepartment(department.parentDepartmentId);
163+ scope.setNavigationState(navigation.parentNavigationId, false);
157 isGoingBack = true;
164 isGoingBack = true;
158− departmentModel.setProperty(departmentListView.currentIndex - 1, "nullifyDepartment", false);
165+ navigationModel.setProperty(navigationListView.currentIndex - 1, "nullifyNavigation", false);
159− departmentListView.currentIndex--;
166+ navigationListView.currentIndex--;
160 }
167 }
161− onAllDepartmentClicked: {
168+ onAllNavigationClicked: {
162 showList = false;
169 showList = false;
163− if (root.currentDepartment.parentDepartmentId == department.departmentId) {
170+ if (root.currentNavigation.parentNavigationId == navigation.navigationId) {
164 // For leaves we have to go to the parent too
171 // For leaves we have to go to the parent too
165− scope.loadDepartment(root.currentDepartment.parentDepartmentId);
172+ scope.setNavigationState(root.currentNavigation.parentNavigationId, false);
166 }
173 }
167 }
174 }
168 }
175 }
169 onContentXChanged: {
176 onContentXChanged: {
170− if (contentX == width * departmentListView.currentIndex) {
177+ if (contentX == width * navigationListView.currentIndex) {
171 if (isGoingBack) {
178 if (isGoingBack) {
172− departmentModel.remove(departmentListView.currentIndex + 1);
179+ navigationModel.remove(navigationListView.currentIndex + 1);
173 } else {
180 } else {
174− departmentModel.setProperty(departmentListView.currentIndex - 1, "nullifyDepartment", true);
181+ navigationModel.setProperty(navigationListView.currentIndex - 1, "nullifyNavigation", true);
175 }
182 }
176 }
183 }
177 }
184 }
178 }
185 }
179
186
180 InverseMouseArea {
187 InverseMouseArea {
181− anchors.fill: departmentListView
188+ anchors.fill: navigationListView
182 enabled: root.showList
189 enabled: root.showList
183 onClicked: root.showList = false
190 onClicked: root.showList = false
184 }
191 }
185
192
186 onScopeChanged: {
193 onScopeChanged: {
187− departmentModel.clear();
194+ navigationModel.clear();
188− if (scope && scope.hasDepartments) {
195+ if (scope && scope.hasNavigation) {
189− departmentModel.append({"departmentId": scope.currentDepartmentId, "nullifyDepartment": false});
196+ navigationModel.append({"navigationId": scope.currentNavigationId, "nullifyNavigation": false});
190 }
197 }
191 }
198 }
192
199
193 Connections {
200 Connections {
194 target: scope
201 target: scope
195− onHasDepartmentsChanged: {
202+ onHasNavigationChanged: {
196− if (scope.hasDepartments) {
203+ if (scope.hasNavigation) {
197− departmentModel.append({"departmentId": scope.currentDepartmentId, "nullifyDepartment": false});
204+ navigationModel.append({"navigationId": scope.currentNavigationId, "nullifyNavigation": false});
198 } else {
205 } else {
199− departmentModel.clear();
206+ navigationModel.clear();
200 }
207 }
201 }
208 }
202 }
209 }
qml/Dash/DashDepartmentsList.qml → qml/Dash/DashNavigationList.qmlrenamed+14−18
@@ -15,16 +15,16 @@
15 */
15 */
16
16
17import QtQuick 2.2
17import QtQuick 2.2
18−import Ubuntu.Components 0.1
18+import Ubuntu.Components 1.1
19
19
20Item {
20Item {
21 id: root
21 id: root
22− property var department: null
22+ property var navigation: null
23− property var currentDepartment: null
23+ property var currentNavigation: null
24 property var scopeStyle: null
24 property var scopeStyle: null
25− signal enterDepartment(var newDepartmentId, bool hasChildren)
25+ signal enterNavigation(var newNavigationId, bool hasChildren)
26 signal goBackToParentClicked()
26 signal goBackToParentClicked()
27− signal allDepartmentClicked()
27+ signal allNavigationClicked()
28
28
29 readonly property int itemHeight: units.gu(5)
29 readonly property int itemHeight: units.gu(5)
30 readonly property color foregroundColor: root.scopeStyle ? root.scopeStyle.foreground : "grey"
30 readonly property color foregroundColor: root.scopeStyle ? root.scopeStyle.foreground : "grey"
@@ -35,11 +35,6 @@ Item {
35 anchors.fill: parent
35 anchors.fill: parent
36 }
36 }
37
37
38− ActivityIndicator {
39− id: loadingIndicator
40− anchors.centerIn: parent
41− running: !(department && department.loaded)
42− }
43 clip: true
38 clip: true
44
39
45 Behavior on height {
40 Behavior on height {
@@ -54,6 +49,7 @@ Item {
54
49
55 anchors.fill: parent
50 anchors.fill: parent
56
51
52+ flickableDirection: Flickable.VerticalFlick
57 contentHeight: column.height
53 contentHeight: column.height
58 contentWidth: width
54 contentWidth: width
59
55
@@ -68,7 +64,7 @@ Item {
68 id: backButton
64 id: backButton
69 objectName: "backButton"
65 objectName: "backButton"
70 width: parent.width
66 width: parent.width
71− visible: department && !department.isRoot || false
67+ visible: navigation && !navigation.isRoot || false
72 height: itemHeight
68 height: itemHeight
73
69
74 onClicked: root.goBackToParentClicked();
70 onClicked: root.goBackToParentClicked();
@@ -92,7 +88,7 @@ Item {
92 left: backImage.right
88 left: backImage.right
93 leftMargin: units.gu(0.5)
89 leftMargin: units.gu(0.5)
94 }
90 }
95− text: department ? department.parentLabel : ""
91+ text: navigation ? navigation.parentLabel : ""
96 color: root.foregroundColor
92 color: root.foregroundColor
97 }
93 }
98
94
@@ -114,7 +110,7 @@ Item {
114 id: allButton
110 id: allButton
115 objectName: "allButton"
111 objectName: "allButton"
116 width: parent.width
112 width: parent.width
117− visible: department && (!department.isRoot || (root.currentDepartment && !root.currentDepartment.isRoot && root.currentDepartment.parentDepartmentId == department.departmentId)) || false
113+ visible: navigation && (!navigation.isRoot || (root.currentNavigation && !root.currentNavigation.isRoot && root.currentNavigation.parentNavigationId == navigation.navigationId)) || false
118 height: itemHeight
114 height: itemHeight
119
115
120 Label {
116 Label {
@@ -123,7 +119,7 @@ Item {
123 left: parent.left
119 left: parent.left
124 leftMargin: units.gu(2)
120 leftMargin: units.gu(2)
125 }
121 }
126− text: department ? (department.allLabel != "" ? department.allLabel : department.label) : ""
122+ text: navigation ? (navigation.allLabel != "" ? navigation.allLabel : navigation.label) : ""
127 font.bold: true
123 font.bold: true
128 color: root.foregroundColor
124 color: root.foregroundColor
129 }
125 }
@@ -141,18 +137,18 @@ Item {
141 height: units.dp(1)
137 height: units.dp(1)
142 }
138 }
143
139
144− onClicked: root.allDepartmentClicked();
140+ onClicked: root.allNavigationClicked();
145 }
141 }
146
142
147 Repeater {
143 Repeater {
148− model: department && department.loaded ? department : null
144+ model: navigation && navigation.loaded ? navigation : null
149 clip: true
145 clip: true
150 delegate: AbstractButton {
146 delegate: AbstractButton {
151 objectName: root.objectName + "child" + index
147 objectName: root.objectName + "child" + index
152 height: root.itemHeight
148 height: root.itemHeight
153 width: root.width
149 width: root.width
154
150
155− onClicked: root.enterDepartment(departmentId, hasChildren)
151+ onClicked: root.enterNavigation(navigationId, hasChildren)
156
152
157 Label {
153 Label {
158 anchors {
154 anchors {
@@ -188,7 +184,7 @@ Item {
188 color: root.foregroundColor
184 color: root.foregroundColor
189 opacity: 0.1
185 opacity: 0.1
190 height: units.dp(1)
186 height: units.dp(1)
191− visible: index != department.count - 1
187+ visible: index != navigation.count - 1
192 }
188 }
193 }
189 }
194 }
190 }
qml/Dash/GenericScopeView.qml+13−12
@@ -25,6 +25,7 @@ import "../Components/ListItems" as ListItems
25FocusScope {
25FocusScope {
26 id: scopeView
26 id: scopeView
27
27
28+ readonly property bool navigationShown: pageHeaderLoader.item ? pageHeaderLoader.item.bottomItem[0].showList : false
28 property var scope: null
29 property var scope: null
29 property SortFilterProxyModel categories: categoryFilter
30 property SortFilterProxyModel categories: categoryFilter
30 property bool isCurrent: false
31 property bool isCurrent: false
@@ -34,22 +35,16 @@ FocusScope {
34 property var categoryView: categoryView
35 property var categoryView: categoryView
35 property bool showPageHeader: true
36 property bool showPageHeader: true
36 readonly property alias previewShown: previewListView.open
37 readonly property alias previewShown: previewListView.open
38+ property int paginationCount: 0
39+ property int paginationIndex: 0
37
40
38 property var scopeStyle: ScopeStyle {
41 property var scopeStyle: ScopeStyle {
39 style: scope ? scope.customizations : {}
42 style: scope ? scope.customizations : {}
40 }
43 }
41
44
42− signal backClicked()
45+ readonly property bool processing: scope ? scope.searchInProgress || previewListView.processing : false
43−
44− onScopeChanged: {
45− if (scope) {
46− scope.activateApplication.connect(activateApp);
47− }
48− }
49
46
50− function activateApp(appId) {
47+ signal backClicked()
51− Qt.openUrlExternally(appId);
52− }
53
48
54 function positionAtBeginning() {
49 function positionAtBeginning() {
55 categoryView.positionAtBeginning()
50 categoryView.positionAtBeginning()
@@ -153,6 +148,7 @@ FocusScope {
153 model: scopeView.categories
148 model: scopeView.categories
154 forceNoClip: previewListView.open
149 forceNoClip: previewListView.open
155 pixelAligned: true
150 pixelAligned: true
151+ interactive: !navigationShown
156
152
157 property string expandedCategoryId: ""
153 property string expandedCategoryId: ""
158
154
@@ -245,6 +241,10 @@ FocusScope {
245 baseItem.expand(shouldExpand, false /*animate*/);
241 baseItem.expand(shouldExpand, false /*animate*/);
246 }
242 }
247 updateDelegateCreationRange();
243 updateDelegateCreationRange();
244+ if (scope && scope.id === "clickscope" && (categoryId === "predefined" || categoryId === "local")) {
245+ // Yeah, hackish :/
246+ cardTool.artShapeSize = Qt.size(units.gu(8), units.gu(7.5));
247+ }
248 item.cardTool = cardTool;
248 item.cardTool = cardTool;
249 }
249 }
250
250
@@ -418,10 +418,11 @@ FocusScope {
418 title: scopeView.scope ? scopeView.scope.name : ""
418 title: scopeView.scope ? scopeView.scope.name : ""
419 showBackButton: scopeView.hasBackAction
419 showBackButton: scopeView.hasBackAction
420 searchEntryEnabled: true
420 searchEntryEnabled: true
421− searchInProgress: scopeView.scope ? scopeView.scope.searchInProgress : false
422 scopeStyle: scopeView.scopeStyle
421 scopeStyle: scopeView.scopeStyle
422+ paginationCount: scopeView.paginationCount
423+ paginationIndex: scopeView.paginationIndex
423
424
424− bottomItem: DashDepartments {
425+ bottomItem: DashNavigation {
425 scope: scopeView.scope
426 scope: scopeView.scope
426 width: parent.width <= units.gu(60) ? parent.width : units.gu(40)
427 width: parent.width <= units.gu(60) ? parent.width : units.gu(40)
427 anchors.right: parent.right
428 anchors.right: parent.right
qml/Dash/PreviewListView.qml+23−27
@@ -32,6 +32,9 @@ Item {
32 property alias currentItem: previewListView.currentItem
32 property alias currentItem: previewListView.currentItem
33 property alias count: previewListView.count
33 property alias count: previewListView.count
34
34
35+ readonly property bool processing: currentItem && (!currentItem.previewModel.loaded
36+ || currentItem.previewModel.processingAction)
37+
35 PageHeader {
38 PageHeader {
36 id: header
39 id: header
37 objectName: "pageHeader"
40 objectName: "pageHeader"
@@ -83,39 +86,32 @@ Item {
83 }
86 }
84 }
87 }
85
88
86− delegate: Item {
89+ delegate: Previews.Preview {
90+ id: preview
87− objectName: "previewItem" + index
91+ objectName: "preview" + index
88 height: previewListView.height
92 height: previewListView.height
89 width: previewListView.width
93 width: previewListView.width
90
94
91− readonly property bool ready: preview.previewModel && preview.previewModel.loaded
95+ isCurrent: ListView.isCurrentItem
92−
93− Previews.Preview {
94− id: preview
95− objectName: "preview" + index
96− anchors.fill: parent
97
96
98− isCurrent: parent.ListView.isCurrentItem
99−
100− previewModel: {
97+ previewModel: {
101− var previewStack = root.scope.preview(result);
98+ var previewStack = root.scope.preview(result);
102− return previewStack.getPreviewModel(0);
99+ return previewStack.getPreviewModel(0);
103− }
104− scopeStyle: root.scopeStyle
105 }
100 }
101+ scopeStyle: root.scopeStyle
102+ }
103+ }
106
104
107− MouseArea {
105+ MouseArea {
108− id: processingMouseArea
106+ id: processingMouseArea
109− objectName: "processingMouseArea"
107+ objectName: "processingMouseArea"
110− anchors.fill: parent
108+ anchors {
111− enabled: preview.previewModel && (!preview.previewModel.loaded || preview.previewModel.processingAction)
109+ left: parent.left
112−
110+ right: parent.right
113− ActivityIndicator {
111+ top: header.bottom
114− anchors.centerIn: parent
112+ bottom: parent.bottom
115− visible: root.open && parent.enabled
116− running: visible
117− }
118− }
119 }
113 }
114+
115+ enabled: root.processing
120 }
116 }
121}
117}
qml/Dash/Previews/PreviewExpandable.qmlnew file+101
@@ -0,0 +1,101 @@
1+/*
2+ * Copyright (C) 2014 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.3
18+import Ubuntu.Components 1.1
19+import "../../Components"
20+
21+/*! \brief Preview widget for expandable widgets.
22+
23+ This widget shows a list of widgets defined in widgetData["widgets"]
24+ Those widgets can be collapsed or uncollapsed. When uncollapsed
25+ all the widgets are shown, when collapsed only the first
26+ widgetData["collapsed-widgets"] are shown. It has a title that comes
27+ in via widgetData["title"]
28+ */
29+
30+PreviewWidget {
31+ id: root
32+ implicitHeight: childrenRect.height
33+
34+ expanded: false
35+
36+ Label {
37+ id: titleLabel
38+ objectName: "titleLabel"
39+ anchors {
40+ left: parent.left
41+ right: expandButton.left
42+ }
43+ fontSize: "large"
44+ color: root.scopeStyle ? root.scopeStyle.foreground : "grey"
45+ visible: text !== ""
46+ opacity: .8
47+ text: widgetData["title"] || ""
48+ wrapMode: Text.Wrap
49+ }
50+
51+ AbstractButton {
52+ id: expandButton
53+ objectName: "expandButton"
54+ width: titleLabel.height
55+ height: titleLabel.height
56+ anchors.right: parent.right
57+ onClicked: {
58+ root.expanded = !root.expanded;
59+ }
60+ Icon {
61+ anchors.fill: parent
62+ width: 64
63+ height: 64
64+ name: root.expanded ? "view-collapse" : "view-expand"
65+ }
66+ }
67+
68+ Column {
69+ anchors {
70+ top: titleLabel.bottom
71+ topMargin: units.gu(1)
72+ left: parent.left
73+ right: parent.right
74+ }
75+ spacing: units.gu(1)
76+ Repeater {
77+ id: repeater
78+ objectName: "repeater"
79+ model: widgetData["widgets"]
80+ delegate: PreviewWidgetFactory {
81+ height: visible ? implicitHeight : 0
82+ width: parent.width
83+ widgetId: modelData.widgetId
84+ widgetType: modelData.type
85+ widgetData: modelData.properties
86+ isCurrentPreview: root.isCurrentPreview
87+ scopeStyle: root.scopeStyle
88+ anchors {
89+ left: parent.left
90+ right: parent.right
91+ }
92+ expanded: root.expanded
93+ visible: root.expanded || index < root.widgetData["collapsed-widgets"]
94+
95+ onTriggered: {
96+ root.triggered(widgetId, actionId, data);
97+ }
98+ }
99+ }
100+ }
101+}
qml/Dash/Previews/PreviewImageGallery.qml+1
@@ -15,6 +15,7 @@
15 */
15 */
16
16
17import QtQuick 2.0
17import QtQuick 2.0
18+import Ubuntu.Components 1.1
18import "../../Components"
19import "../../Components"
19
20
20/*! This preview widget shows a horizontal list of images.
21/*! This preview widget shows a horizontal list of images.
qml/Dash/Previews/PreviewTextSummary.qml+3−16
@@ -23,7 +23,7 @@ import "../../Components"
23 This widget shows text contained in widgetData["text"]
23 This widget shows text contained in widgetData["text"]
24 along with a title that comes from widgetData["title"].
24 along with a title that comes from widgetData["title"].
25
25
26− In case the text does not fit in 7 lines a See More / Less widget is also shown.
26+ In case the widget is collapsed it only shows 3 lines of text.
27 */
27 */
28
28
29PreviewWidget {
29PreviewWidget {
@@ -50,14 +50,14 @@ PreviewWidget {
50 id: textLabel
50 id: textLabel
51 objectName: "textLabel"
51 objectName: "textLabel"
52
52
53− readonly property int maximumCollapsedLineCount: 7
53+ readonly property int maximumCollapsedLineCount: 3
54
54
55 anchors {
55 anchors {
56 left: parent.left
56 left: parent.left
57 right: parent.right
57 right: parent.right
58 top: titleLabel.visible ? titleLabel.bottom : parent.top
58 top: titleLabel.visible ? titleLabel.bottom : parent.top
59 }
59 }
60− height: (!seeMore.visible || seeMore.more) ? contentHeight : contentHeight / lineCount * (maximumCollapsedLineCount - 2)
60+ height: (lineCount <= maximumCollapsedLineCount || root.expanded) ? contentHeight : contentHeight / lineCount * maximumCollapsedLineCount
61 clip: true
61 clip: true
62 fontSize: "small"
62 fontSize: "small"
63 lineHeight: 1.2
63 lineHeight: 1.2
@@ -70,17 +70,4 @@ PreviewWidget {
70 UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration }
70 UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration }
71 }
71 }
72 }
72 }
73−
74− SeeMore {
75− id: seeMore
76− objectName: "seeMore"
77− anchors {
78− left: parent.left
79− right: parent.right
80− top: textLabel.bottom
81− topMargin: visible ? units.gu(1) : 0
82− }
83− height: visible ? implicitHeight : 0
84− visible: textLabel.lineCount > textLabel.maximumCollapsedLineCount
85− }
86}
73}
qml/Dash/Previews/PreviewWidget.qml+3
@@ -31,6 +31,9 @@ Item {
31 //! The ScopeStyle component.
31 //! The ScopeStyle component.
32 property var scopeStyle: null
32 property var scopeStyle: null
33
33
34+ //! Should the widget show in expanded mode (For those that support it)
35+ property bool expanded: true
36+
34 /*! \brief This signal should be emitted when a preview action was triggered.
37 /*! \brief This signal should be emitted when a preview action was triggered.
35 *
38 *
36 * \param widgetId, actionId Respective identifiers from widgetData.
39 * \param widgetId, actionId Respective identifiers from widgetData.
qml/Dash/Previews/PreviewWidgetFactory.qml+5
@@ -34,6 +34,9 @@ Loader {
34 //! The ScopeStyle component.
34 //! The ScopeStyle component.
35 property var scopeStyle: null
35 property var scopeStyle: null
36
36
37+ //! Should the widget show in expanded mode (For those that support it)
38+ property bool expanded: true
39+
37 //! Set to true if the parent preview is displayed.
40 //! Set to true if the parent preview is displayed.
38 property bool isCurrentPreview: false
41 property bool isCurrentPreview: false
39
42
@@ -47,6 +50,7 @@ Loader {
47 switch (widgetType) {
50 switch (widgetType) {
48 case "actions": return "PreviewActions.qml";
51 case "actions": return "PreviewActions.qml";
49 case "audio": return "PreviewAudioPlayback.qml";
52 case "audio": return "PreviewAudioPlayback.qml";
53+ case "expandable": return "PreviewExpandable.qml";
50 case "gallery": return "PreviewImageGallery.qml";
54 case "gallery": return "PreviewImageGallery.qml";
51 case "header": return "PreviewHeader.qml";
55 case "header": return "PreviewHeader.qml";
52 case "image": return "PreviewZoomableImage.qml";
56 case "image": return "PreviewZoomableImage.qml";
@@ -65,6 +69,7 @@ Loader {
65 item.widgetId = Qt.binding(function() { return root.widgetId } )
69 item.widgetId = Qt.binding(function() { return root.widgetId } )
66 item.widgetData = Qt.binding(function() { return root.widgetData } )
70 item.widgetData = Qt.binding(function() { return root.widgetData } )
67 item.isCurrentPreview = Qt.binding(function() { return root.isCurrentPreview } )
71 item.isCurrentPreview = Qt.binding(function() { return root.isCurrentPreview } )
72+ item.expanded = Qt.binding(function() { return root.expanded } )
68 if (item.hasOwnProperty("scopeStyle")) item.scopeStyle = root.scopeStyle;
73 if (item.hasOwnProperty("scopeStyle")) item.scopeStyle = root.scopeStyle;
69 }
74 }
70
75
qml/Dash/ScopesOverview.qml+10−4
@@ -84,6 +84,12 @@ Item {
84 }
84 }
85 }
85 }
86
86
87+ Binding {
88+ target: scope
89+ property: "isActive"
90+ value: progress === 1
91+ }
92+
87 function animateDashFromAll(scopeId) {
93 function animateDashFromAll(scopeId) {
88 var currentScopePos = allScopeCardPosition(scopeId);
94 var currentScopePos = allScopeCardPosition(scopeId);
89 if (currentScopePos) {
95 if (currentScopePos) {
@@ -188,7 +194,6 @@ Item {
188 scopeStyle: overviewScopeStyle
194 scopeStyle: overviewScopeStyle
189 showSignatureLine: false
195 showSignatureLine: false
190 searchEntryEnabled: true
196 searchEntryEnabled: true
191− searchInProgress: root.scope ? root.scope.searchInProgress : false
192 }
197 }
193
198
194 ScopesOverviewTab {
199 ScopesOverviewTab {
@@ -334,6 +339,7 @@ Item {
334 showPageHeader: false
339 showPageHeader: false
335 clip: true
340 clip: true
336 opacity: searchResultsViewer.scope ? 1 : 0
341 opacity: searchResultsViewer.scope ? 1 : 0
342+ isCurrent: true
337 Behavior on opacity { UbuntuNumberAnimation { } }
343 Behavior on opacity { UbuntuNumberAnimation { } }
338
344
339 function itemClicked(index, result, item, itemModel, resultsModel, limitedCategoryItemCount) {
345 function itemClicked(index, result, item, itemModel, resultsModel, limitedCategoryItemCount) {
@@ -357,10 +363,10 @@ Item {
357 Rectangle {
363 Rectangle {
358 id: bottomBar
364 id: bottomBar
359 color: "black"
365 color: "black"
360− height: units.gu(6)
366+ height: units.gu(8)
361 width: parent.width
367 width: parent.width
362− enabled: opacity == 0.4
368+ enabled: opacity == 1
363− opacity: scope && scope.searchQuery == "" ? 0.4 : 0
369+ opacity: scope && scope.searchQuery == "" ? 1 : 0
364 Behavior on opacity { UbuntuNumberAnimation { } }
370 Behavior on opacity { UbuntuNumberAnimation { } }
365 y: {
371 y: {
366 if (root.progress < 0.5) {
372 if (root.progress < 0.5) {
qml/Greeter/Greeter.qml+1−1
@@ -70,7 +70,7 @@ Showable {
70 DraggingArea {
70 DraggingArea {
71 id: dragHandle
71 id: dragHandle
72 anchors.fill: parent
72 anchors.fill: parent
73− enabled: (greeter.narrowMode || !greeter.locked) && greeter.enabled
73+ enabled: (greeter.narrowMode || !greeter.locked) && greeter.enabled && greeter.shown
74 orientation: Qt.Horizontal
74 orientation: Qt.Horizontal
75 propagateComposedEvents: true
75 propagateComposedEvents: true
76
76
qml/Notifications/NotificationMenuItemFactory.qml+3
@@ -76,6 +76,9 @@ Loader {
76 }
76 }
77 echoMode: checkBox.checked ? TextInput.Normal : TextInput.Password
77 echoMode: checkBox.checked ? TextInput.Normal : TextInput.Password
78 height: units.gu(5)
78 height: units.gu(5)
79+ Component.onCompleted: {
80+ forceActiveFocus();
81+ }
79 onTextChanged: {
82 onTextChanged: {
80 menuModel.changeState(menuIndex, text);
83 menuModel.changeState(menuIndex, text);
81 }
84 }
qml/Panel/Indicators/MenuItemFactory.qml+74
@@ -57,6 +57,7 @@ Item {
57
57
58 "unity.widgets.systemsettings.tablet.wifisection" : wifiSection,
58 "unity.widgets.systemsettings.tablet.wifisection" : wifiSection,
59 "unity.widgets.systemsettings.tablet.accesspoint" : accessPoint,
59 "unity.widgets.systemsettings.tablet.accesspoint" : accessPoint,
60+ "com.canonical.indicator.network.modeminfoitem" : modeminfoitem,
60 }
61 }
61
62
62 function getExtendedProperty(object, propertyName, defaultValue) {
63 function getExtendedProperty(object, propertyName, defaultValue) {
@@ -374,6 +375,79 @@ Item {
374 }
375 }
375 }
376 }
376
377
378+ Component {
379+ id: modeminfoitem;
380+ ModemInfoItem {
381+ objectName: "modemInfoItem"
382+ property QtObject menuData: null
383+ property var menuModel: menuFactory.menuModel
384+ property int menuIndex: -1
385+ property var extendedData: menuData && menuData.ext || undefined
386+
387+ property var statusLabelAction: UnityMenuAction {
388+ model: menuModel
389+ index: menuIndex
390+ name: getExtendedProperty(extendedData, "xCanonicalModemStatusLabelAction", "")
391+ }
392+ statusText: statusLabelAction.valid ? statusLabelAction.state : ""
393+
394+ property var statusIconAction: UnityMenuAction {
395+ model: menuModel
396+ index: menuIndex
397+ name: getExtendedProperty(extendedData, "xCanonicalModemStatusIconAction", "")
398+ }
399+ statusIcon: statusIconAction.valid ? statusIconAction.state : ""
400+
401+ property var connectivityIconAction: UnityMenuAction {
402+ model: menuModel
403+ index: menuIndex
404+ name: getExtendedProperty(extendedData, "xCanonicalModemConnectivityIconAction", "")
405+ }
406+ connectivityIcon: connectivityIconAction.valid ? connectivityIconAction.state : ""
407+
408+ property var simIdentifierLabelAction: UnityMenuAction {
409+ model: menuModel
410+ index: menuIndex
411+ name: getExtendedProperty(extendedData, "xCanonicalModemSimIdentifierLabelAction", "")
412+ }
413+ simIdentifierText: simIdentifierLabelAction.valid ? simIdentifierLabelAction.state : ""
414+
415+ property var roamingAction: UnityMenuAction {
416+ model: menuModel
417+ index: menuIndex
418+ name: getExtendedProperty(extendedData, "xCanonicalModemRoamingAction", "")
419+ }
420+ roaming: roamingAction.valid ? roamingAction.state : false
421+
422+ property var unlockAction: UnityMenuAction {
423+ model: menuModel
424+ index: menuIndex
425+ name: getExtendedProperty(extendedData, "xCanonicalModemLockedAction", "")
426+ }
427+ onUnlock: {
428+ unlockAction.activate();
429+ }
430+ locked: unlockAction.valid ? unlockAction.state : false
431+
432+ onMenuModelChanged: {
433+ loadAttributes();
434+ }
435+ onMenuIndexChanged: {
436+ loadAttributes();
437+ }
438+
439+ function loadAttributes() {
440+ if (!menuModel || menuIndex == -1) return;
441+ menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-modem-status-label-action': 'string',
442+ 'x-canonical-modem-status-icon-action': 'string',
443+ 'x-canonical-modem-connectivity-icon-action': 'string',
444+ 'x-canonical-modem-sim-identifier-label-action': 'string',
445+ 'x-canonical-modem-roaming-action': 'string',
446+ 'x-canonical-modem-locked-action': 'string'});
447+ }
448+ }
449+ }
450+
377 Component {
451 Component {
378 id: messageItem
452 id: messageItem
379
453
qml/Panel/Indicators/ModemInfoItem.qmlnew file+111
@@ -0,0 +1,111 @@
1+/*
2+ * Copyright 2014 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import QtQuick.Layouts 1.1
19+import Ubuntu.Components 0.1
20+import Ubuntu.Components.ListItems 0.1 as ListItem
21+
22+ListItem.Empty {
23+ id: menu
24+ implicitHeight: mainColumn.implicitHeight
25+ + mainColumn.anchors.topMargin
26+ + mainColumn.anchors.bottomMargin
27+
28+ property alias statusIcon: statusIcon.name
29+ property alias statusText: labelStatus.text
30+ property alias connectivityIcon: iconConnectivity.name
31+ property alias simIdentifierText: labelSimIdentifier.text
32+ property bool locked : false
33+ property bool roaming: false
34+ signal unlock
35+
36+ ColumnLayout {
37+ id: mainColumn
38+ anchors.fill: parent
39+ anchors.margins: menu.__contentsMargins
40+ spacing: units.gu(0.5)
41+
42+ Label {
43+ id: labelSimIdentifier
44+ elide: Text.ElideRight
45+ visible: text !== ""
46+ font.bold: true
47+ opacity: menu.locked ? 0.6 : 1.0
48+ }
49+
50+ RowLayout {
51+ id: statusRow
52+ spacing: units.gu(1)
53+
54+ height: labelStatus.height
55+ width: parent.width
56+
57+ Label {
58+ id: labelStatus
59+ elide: Text.ElideRight
60+ opacity: 0.6
61+ }
62+
63+ RowLayout {
64+ spacing: 0.5
65+ height: parent.height
66+ Icon {
67+ id: statusIcon
68+ color: Theme.palette.selected.backgroundText
69+
70+ Layout.preferredHeight: parent.height
71+ Layout.preferredWidth: Layout.preferredHeight
72+
73+ visible: name !== ""
74+ }
75+
76+ Icon {
77+ id: iconConnectivity
78+ color: Theme.palette.selected.backgroundText
79+
80+ Layout.preferredHeight: parent.height
81+ Layout.preferredWidth: Layout.preferredHeight
82+
83+ visible: name !== ""
84+ }
85+ }
86+
87+ Item {
88+ // eat up all the excess space so that RoamingIndication
89+ // ends up to the far right
90+ Layout.fillWidth: true
91+ }
92+
93+ RoamingIndication {
94+ id: roamingIndication
95+ visible: menu.roaming
96+ Layout.fillHeight: true
97+ }
98+ }
99+
100+ Button {
101+ id: buttonUnlock
102+ objectName: "buttonUnlockSim"
103+ visible: menu.locked
104+
105+ text: i18n.tr("Unlock SIM")
106+ Layout.preferredWidth: implicitWidth + units.gu(5)
107+
108+ onTriggered: menu.unlock()
109+ }
110+ }
111+}
qml/Panel/Indicators/RoamingIndication.qmlnew file+40
@@ -0,0 +1,40 @@
1+/*
2+ * Copyright 2014 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import QtQuick.Layouts 1.1
19+import Ubuntu.Components 0.1
20+
21+RowLayout {
22+ spacing: units.gu(0.5)
23+ Label {
24+ id: labelRoaming
25+ elide: Text.ElideRight
26+ fontSize: "x-small"
27+ text: i18n.tr("Roaming")
28+ opacity: 0.6
29+ }
30+
31+ Icon {
32+ id: iconRoaming
33+ color: Theme.palette.selected.backgroundText
34+
35+ Layout.preferredHeight: parent.height
36+ Layout.preferredWidth: Layout.preferredHeight
37+
38+ name: "network-cellular-roaming"
39+ }
40+}
qml/ScopeTool.qml+2−11
@@ -17,6 +17,7 @@
17import QtQuick 2.0
17import QtQuick 2.0
18import Ubuntu.Components 0.1
18import Ubuntu.Components 0.1
19import Ubuntu.Components.Popups 0.1
19import Ubuntu.Components.Popups 0.1
20+import Ubuntu.Thumbnailer 0.1 // Register support for image://thumbnailer/ and image://albumart/
20import Utils 0.1
21import Utils 0.1
21import Unity 0.2
22import Unity 0.2
22import "Components"
23import "Components"
@@ -45,16 +46,6 @@ Rectangle {
45 signal searchClicked
46 signal searchClicked
46 }
47 }
47
48
48− SortFilterProxyModel {
49− id: filteredScopes
50− model: Scopes {
51− id: scopes
52− }
53− dynamicSortFilter: true
54−
55− filterRole: Scopes.RoleVisible
56− filterRegExp: RegExp("^true$")
57− }
58
49
59 Rectangle {
50 Rectangle {
60 anchors.fill: dashContent
51 anchors.fill: dashContent
@@ -72,8 +63,8 @@ Rectangle {
72 DashContent {
63 DashContent {
73 id: dashContent
64 id: dashContent
74
65
75− model: filteredScopes
76 property var scope: scopes.getScope(currentIndex)
66 property var scope: scopes.getScope(currentIndex)
67+ scopes: Scopes { }
77
68
78 anchors {
69 anchors {
79 top: parent.top
70 top: parent.top
qml/Shell.qml+4−4
@@ -167,12 +167,12 @@ Item {
167 Binding {
167 Binding {
168 target: applicationsDisplayLoader.item
168 target: applicationsDisplayLoader.item
169 property: "interactive"
169 property: "interactive"
170− value: !greeter.shown && !lockscreen.shown && panel.indicators.fullyClosed && launcher.progress == 0
170+ value: edgeDemo.stagesEnabled && !greeter.shown && !lockscreen.shown && panel.indicators.fullyClosed && launcher.progress == 0
171 }
171 }
172 Binding {
172 Binding {
173 target: applicationsDisplayLoader.item
173 target: applicationsDisplayLoader.item
174 property: "spreadEnabled"
174 property: "spreadEnabled"
175− value: greeter.fakeActiveForApp === "" // to support emergency dialer hack
175+ value: edgeDemo.stagesEnabled && greeter.fakeActiveForApp === "" // to support emergency dialer hack
176 }
176 }
177 Binding {
177 Binding {
178 target: applicationsDisplayLoader.item
178 target: applicationsDisplayLoader.item
@@ -381,7 +381,7 @@ Item {
381 onDisplayPowerStateChange: {
381 onDisplayPowerStateChange: {
382 // We ignore any display-off signals when the proximity sensor
382 // We ignore any display-off signals when the proximity sensor
383 // is active. This usually indicates something like a phone call.
383 // is active. This usually indicates something like a phone call.
384− if (status == Powerd.Off && reason != Powerd.Proximity) {
384+ if (status == Powerd.Off && reason != Powerd.Proximity && !edgeDemo.running) {
385 greeter.showNow();
385 greeter.showNow();
386 }
386 }
387
387
@@ -561,7 +561,7 @@ Item {
561 greeter: greeter
561 greeter: greeter
562 launcher: launcher
562 launcher: launcher
563 indicators: panel.indicators
563 indicators: panel.indicators
564− underlay: underlay
564+ stages: stages
565 }
565 }
566
566
567 Connections {
567 Connections {
run_on_device.sh+1−3
@@ -2,7 +2,6 @@
2CODE_DIR=shell
2CODE_DIR=shell
3USER=phablet
3USER=phablet
4USER_ID=32011
4USER_ID=32011
5−PASSWORD=phablet
6PACKAGE=unity8
5PACKAGE=unity8
7BINARY=unity8
6BINARY=unity8
8TARGET_IP=${TARGET_IP-127.0.0.1}
7TARGET_IP=${TARGET_IP-127.0.0.1}
@@ -13,7 +12,6 @@ SETUP=false
13GDB=false
12GDB=false
14PINLOCK=false
13PINLOCK=false
15KEYLOCK=false
14KEYLOCK=false
16−SUDO="echo $PASSWORD | sudo -S"
17NUM_JOBS='$(( `grep -c ^processor /proc/cpuinfo` + 1 ))'
15NUM_JOBS='$(( `grep -c ^processor /proc/cpuinfo` + 1 ))'
18FLIPPED=false
16FLIPPED=false
19CHROOT_PREFIX="/data/ubuntu"
17CHROOT_PREFIX="/data/ubuntu"
@@ -76,7 +74,7 @@ setup_adb_forwarding() {
76
74
77install_dependencies() {
75install_dependencies() {
78 exec_with_adb apt-get update
76 exec_with_adb apt-get update
79− exec_with_ssh $SUDO apt-get -y install build-essential rsync bzr ccache gdb ninja-build devscripts equivs unity-plugin-scopes
77+ exec_with_adb apt-get -y --force-yes install build-essential rsync bzr ccache gdb ninja-build devscripts equivs unity-plugin-scopes
80}
78}
81
79
82sync_code() {
80sync_code() {
src/Dash/main.cpp+5−5
@@ -24,6 +24,7 @@
24#include <QDebug>
24#include <QDebug>
25#include <QCommandLineParser>
25#include <QCommandLineParser>
26#include <QLibrary>
26#include <QLibrary>
27+#include <libintl.h>
27
28
28#include <paths.h>
29#include <paths.h>
29#include "../MouseTouchAdaptor.h"
30#include "../MouseTouchAdaptor.h"
@@ -40,10 +41,7 @@ int main(int argc, const char *argv[])
40 "Allow the mouse to provide touch input");
41 "Allow the mouse to provide touch input");
41 parser.addOption(mousetouchOption);
42 parser.addOption(mousetouchOption);
42
43
43− QCommandLineOption testabilityOption("testability",
44+ // FIXME Remove once we drop the need of the hint
44− "Load the testability driver (Alternatively export QT_LOAD_TESTABILITY");
45− parser.addOption(testabilityOption);
46−
47 QCommandLineOption desktopFileHintOption("desktop_file_hint",
45 QCommandLineOption desktopFileHintOption("desktop_file_hint",
48 "The desktop_file_hint option for QtMir", "hint_file");
46 "The desktop_file_hint option for QtMir", "hint_file");
49 parser.addOption(desktopFileHintOption);
47 parser.addOption(desktopFileHintOption);
@@ -53,7 +51,7 @@ int main(int argc, const char *argv[])
53 parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions);
51 parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions);
54 parser.process(*application);
52 parser.process(*application);
55
53
56− if (parser.isSet(testabilityOption) || getenv("QT_LOAD_TESTABILITY")) {
54+ if (getenv("QT_LOAD_TESTABILITY")) {
57 QLibrary testLib(QLatin1String("qttestability"));
55 QLibrary testLib(QLatin1String("qttestability"));
58 if (testLib.load()) {
56 if (testLib.load()) {
59 typedef void (*TasInitialize)(void);
57 typedef void (*TasInitialize)(void);
@@ -68,6 +66,8 @@ int main(int argc, const char *argv[])
68 }
66 }
69 }
67 }
70
68
69+ bindtextdomain("unity8", translationDirectory().toUtf8().data());
70+
71 QQuickView* view = new QQuickView();
71 QQuickView* view = new QQuickView();
72 view->setResizeMode(QQuickView::SizeRootObjectToView);
72 view->setResizeMode(QQuickView::SizeRootObjectToView);
73 view->setTitle("Unity Dash");
73 view->setTitle("Unity Dash");
tests/autopilot/unity8/shell/emulators/dash.py+1−1
@@ -150,7 +150,7 @@ class Dash(emulators.UnityEmulatorBase):
150 headerContainer.contentY.wait_for(0)
150 headerContainer.contentY.wait_for(0)
151 search_text_field = self._get_search_text_field()
151 search_text_field = self._get_search_text_field()
152 search_text_field.write(query)
152 search_text_field.write(query)
153− current_header.select_single(objectName="searchIndicator").running.wait_for(False)
153+ self.select_single(objectName="processingIndicator").visible.wait_for(False)
154
154
155 def _get_search_text_field(self):
155 def _get_search_text_field(self):
156 page_header = self._get_current_page_header()
156 page_header = self._get_current_page_header()
tests/mocks/Unity/CMakeLists.txt+3−3
@@ -7,7 +7,7 @@ add_subdirectory(DashCommunicator)
7pkg_search_module(DEE dee-1.0 REQUIRED)
7pkg_search_module(DEE dee-1.0 REQUIRED)
8pkg_search_module(GOBJECT gobject-2.0 REQUIRED)
8pkg_search_module(GOBJECT gobject-2.0 REQUIRED)
9pkg_search_module(DEEQT libdee-qt5 REQUIRED)
9pkg_search_module(DEEQT libdee-qt5 REQUIRED)
10−pkg_check_modules(SCOPES_API REQUIRED unity-shell-scopes=3)
10+pkg_check_modules(SCOPES_API REQUIRED unity-shell-scopes=4)
11
11
12include_directories(
12include_directories(
13 ${CMAKE_CURRENT_BINARY_DIR}
13 ${CMAKE_CURRENT_BINARY_DIR}
@@ -24,14 +24,14 @@ set(UnityQML_SOURCES
24 fake_scopes.cpp
24 fake_scopes.cpp
25 fake_scopesoverview.cpp
25 fake_scopesoverview.cpp
26 fake_categories.cpp
26 fake_categories.cpp
27− fake_department.cpp
27+ fake_navigation.cpp
28 fake_resultsmodel.cpp
28 fake_resultsmodel.cpp
29 fake_previewmodel.cpp
29 fake_previewmodel.cpp
30 fake_previewstack.cpp
30 fake_previewstack.cpp
31 fake_previewwidgetmodel.cpp
31 fake_previewwidgetmodel.cpp
32 fake_unity_plugin.cpp
32 fake_unity_plugin.cpp
33 ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/CategoriesInterface.h
33 ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/CategoriesInterface.h
34− ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/DepartmentInterface.h
34+ ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/NavigationInterface.h
35 ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/PreviewModelInterface.h
35 ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/PreviewModelInterface.h
36 ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/PreviewStackInterface.h
36 ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/PreviewStackInterface.h
37 ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/PreviewWidgetModelInterface.h
37 ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/PreviewWidgetModelInterface.h
tests/mocks/Unity/Unity.qmltypes+79−27
@@ -24,6 +24,12 @@ Module {
24 Parameter { name: "categoryId"; type: "string" }
24 Parameter { name: "categoryId"; type: "string" }
25 Parameter { name: "json"; type: "string" }
25 Parameter { name: "json"; type: "string" }
26 }
26 }
27+ Method {
28+ name: "data"
29+ type: "QVariant"
30+ Parameter { name: "row"; type: "int" }
31+ Parameter { name: "role"; type: "int" }
32+ }
27 }
33 }
28 Component {
34 Component {
29 name: "PreviewModel"
35 name: "PreviewModel"
@@ -62,6 +68,10 @@ Module {
62 prototype: "unity::shell::scopes::ScopeInterface"
68 prototype: "unity::shell::scopes::ScopeInterface"
63 exports: ["Unity/MockScope 0.2"]
69 exports: ["Unity/MockScope 0.2"]
64 exportMetaObjectRevisions: [0]
70 exportMetaObjectRevisions: [0]
71+ Signal {
72+ name: "performQuery"
73+ Parameter { name: "query"; type: "string" }
74+ }
65 Method {
75 Method {
66 name: "setSearchInProgress"
76 name: "setSearchInProgress"
67 Parameter { name: "inProg"; type: "bool" }
77 Parameter { name: "inProg"; type: "bool" }
@@ -81,18 +91,21 @@ Module {
81 Parameter { name: "scope"; type: "unity::shell::scopes::ScopeInterface"; isPointer: true }
91 Parameter { name: "scope"; type: "unity::shell::scopes::ScopeInterface"; isPointer: true }
82 }
92 }
83 Method {
93 Method {
84− name: "getDepartment"
94+ name: "getNavigation"
85− type: "unity::shell::scopes::DepartmentInterface*"
95+ type: "unity::shell::scopes::NavigationInterface*"
86− Parameter { name: "id"; type: "string" }
96+ Parameter { name: "navigationId"; type: "string" }
87 }
97 }
88 Method {
98 Method {
89− name: "loadDepartment"
99+ name: "getAltNavigation"
100+ type: "unity::shell::scopes::NavigationInterface*"
90− Parameter { name: "id"; type: "string" }
101+ Parameter { name: "altNavigationId"; type: "string" }
91 }
102 }
92 Method {
103 Method {
93− name: "performQuery"
104+ name: "setNavigationState"
94− Parameter { name: "query"; type: "string" }
105+ Parameter { name: "navigationId"; type: "string" }
106+ Parameter { name: "isAltNavigation"; type: "bool" }
95 }
107 }
108+ Method { name: "refresh" }
96 }
109 }
97 Component {
110 Component {
98 name: "Scopes"
111 name: "Scopes"
@@ -137,6 +150,7 @@ Module {
137 "RoleRawRendererTemplate": 3,
150 "RoleRawRendererTemplate": 3,
138 "RoleRenderer": 4,
151 "RoleRenderer": 4,
139 "RoleComponents": 5,
152 "RoleComponents": 5,
153+ "RoleHeaderLink": 6,
140 "RoleResults": 7,
154 "RoleResults": 7,
141 "RoleCount": 8
155 "RoleCount": 8
142 }
156 }
@@ -157,27 +171,28 @@ Module {
157 }
171 }
158 }
172 }
159 Component {
173 Component {
160− name: "unity::shell::scopes::DepartmentInterface"
174+ name: "unity::shell::scopes::NavigationInterface"
161 prototype: "QAbstractListModel"
175 prototype: "QAbstractListModel"
162− exports: ["Unity/Department 0.2"]
176+ exports: ["Unity/Navigation 0.2"]
163 isCreatable: false
177 isCreatable: false
164 exportMetaObjectRevisions: [0]
178 exportMetaObjectRevisions: [0]
165 Enum {
179 Enum {
166 name: "Roles"
180 name: "Roles"
167 values: {
181 values: {
168− "RoleDepartmentId": 0,
182+ "RoleNavigationId": 0,
169 "RoleLabel": 1,
183 "RoleLabel": 1,
170 "RoleHasChildren": 2,
184 "RoleHasChildren": 2,
171 "RoleIsActive": 3
185 "RoleIsActive": 3
172 }
186 }
173 }
187 }
174− Property { name: "departmentId"; type: "string"; isReadonly: true }
188+ Property { name: "navigationId"; type: "string"; isReadonly: true }
175 Property { name: "label"; type: "string"; isReadonly: true }
189 Property { name: "label"; type: "string"; isReadonly: true }
176 Property { name: "allLabel"; type: "string"; isReadonly: true }
190 Property { name: "allLabel"; type: "string"; isReadonly: true }
177− Property { name: "parentDepartmentId"; type: "string"; isReadonly: true }
191+ Property { name: "parentNavigationId"; type: "string"; isReadonly: true }
178 Property { name: "parentLabel"; type: "string"; isReadonly: true }
192 Property { name: "parentLabel"; type: "string"; isReadonly: true }
179 Property { name: "loaded"; type: "bool"; isReadonly: true }
193 Property { name: "loaded"; type: "bool"; isReadonly: true }
180 Property { name: "isRoot"; type: "bool"; isReadonly: true }
194 Property { name: "isRoot"; type: "bool"; isReadonly: true }
195+ Property { name: "hidden"; type: "bool"; isReadonly: true }
181 Property { name: "count"; type: "int"; isReadonly: true }
196 Property { name: "count"; type: "int"; isReadonly: true }
182 }
197 }
183 Component {
198 Component {
@@ -247,7 +262,8 @@ Module {
247 "RoleEmblem": 8,
262 "RoleEmblem": 8,
248 "RoleSummary": 9,
263 "RoleSummary": 9,
249 "RoleAttributes": 10,
264 "RoleAttributes": 10,
250− "RoleBackground": 11
265+ "RoleBackground": 11,
266+ "RoleOverlayColor": 12
251 }
267 }
252 }
268 }
253 Property { name: "categoryId"; type: "string" }
269 Property { name: "categoryId"; type: "string" }
@@ -259,13 +275,22 @@ Module {
259 exports: ["Unity/Scope 0.2"]
275 exports: ["Unity/Scope 0.2"]
260 isCreatable: false
276 isCreatable: false
261 exportMetaObjectRevisions: [0]
277 exportMetaObjectRevisions: [0]
278+ Enum {
279+ name: "Status"
280+ values: {
281+ "Okay": 0,
282+ "NoInternet": 1,
283+ "NoLocationData": 2,
284+ "Unknown": 3
285+ }
286+ }
262 Property { name: "id"; type: "string"; isReadonly: true }
287 Property { name: "id"; type: "string"; isReadonly: true }
263 Property { name: "name"; type: "string"; isReadonly: true }
288 Property { name: "name"; type: "string"; isReadonly: true }
264 Property { name: "iconHint"; type: "string"; isReadonly: true }
289 Property { name: "iconHint"; type: "string"; isReadonly: true }
265 Property { name: "description"; type: "string"; isReadonly: true }
290 Property { name: "description"; type: "string"; isReadonly: true }
266 Property { name: "searchHint"; type: "string"; isReadonly: true }
291 Property { name: "searchHint"; type: "string"; isReadonly: true }
267 Property { name: "searchInProgress"; type: "bool"; isReadonly: true }
292 Property { name: "searchInProgress"; type: "bool"; isReadonly: true }
268− Property { name: "visible"; type: "bool"; isReadonly: true }
293+ Property { name: "favorite"; type: "bool" }
269 Property { name: "shortcut"; type: "string"; isReadonly: true }
294 Property { name: "shortcut"; type: "string"; isReadonly: true }
270 Property {
295 Property {
271 name: "categories"
296 name: "categories"
@@ -273,13 +298,27 @@ Module {
273 isReadonly: true
298 isReadonly: true
274 isPointer: true
299 isPointer: true
275 }
300 }
301+ Property {
302+ name: "settings"
303+ type: "unity::shell::scopes::SettingsModelInterface"
304+ isReadonly: true
305+ isPointer: true
306+ }
276 Property { name: "searchQuery"; type: "string" }
307 Property { name: "searchQuery"; type: "string" }
277 Property { name: "noResultsHint"; type: "string" }
308 Property { name: "noResultsHint"; type: "string" }
278 Property { name: "formFactor"; type: "string" }
309 Property { name: "formFactor"; type: "string" }
279 Property { name: "isActive"; type: "bool" }
310 Property { name: "isActive"; type: "bool" }
311+ Property { name: "currentNavigationId"; type: "string"; isReadonly: true }
312+ Property { name: "hasNavigation"; type: "bool"; isReadonly: true }
280− Property { name: "currentDepartmentId"; type: "string"; isReadonly: true }
313+ Property { name: "currentAltNavigationId"; type: "string"; isReadonly: true }
281− Property { name: "hasDepartments"; type: "bool"; isReadonly: true }
314+ Property { name: "hasAltNavigation"; type: "bool"; isReadonly: true }
282 Property { name: "customizations"; type: "QVariantMap"; isReadonly: true }
315 Property { name: "customizations"; type: "QVariantMap"; isReadonly: true }
316+ Property {
317+ name: "status"
318+ type: "unity::shell::scopes::ScopeInterface::Status"
319+ isReadonly: true
320+ }
321+ Signal { name: "detailsChanged" }
283 Signal { name: "showDash" }
322 Signal { name: "showDash" }
284 Signal { name: "hideDash" }
323 Signal { name: "hideDash" }
285 Signal {
324 Signal {
@@ -298,10 +337,6 @@ Module {
298 name: "openScope"
337 name: "openScope"
299 Parameter { name: "scope"; type: "unity::shell::scopes::ScopeInterface"; isPointer: true }
338 Parameter { name: "scope"; type: "unity::shell::scopes::ScopeInterface"; isPointer: true }
300 }
339 }
301− Signal {
302− name: "activateApplication"
303− Parameter { name: "desktop"; type: "string" }
304− }
305 Method {
340 Method {
306 name: "activate"
341 name: "activate"
307 Parameter { name: "result"; type: "QVariant" }
342 Parameter { name: "result"; type: "QVariant" }
@@ -317,14 +352,25 @@ Module {
317 Parameter { name: "scope"; type: "unity::shell::scopes::ScopeInterface"; isPointer: true }
352 Parameter { name: "scope"; type: "unity::shell::scopes::ScopeInterface"; isPointer: true }
318 }
353 }
319 Method {
354 Method {
320− name: "getDepartment"
355+ name: "getNavigation"
321− type: "unity::shell::scopes::DepartmentInterface*"
356+ type: "unity::shell::scopes::NavigationInterface*"
322− Parameter { name: "departmentId"; type: "string" }
357+ Parameter { name: "navigationId"; type: "string" }
358+ }
359+ Method {
360+ name: "getAltNavigation"
361+ type: "unity::shell::scopes::NavigationInterface*"
362+ Parameter { name: "altNavigationId"; type: "string" }
323 }
363 }
324 Method {
364 Method {
325− name: "loadDepartment"
365+ name: "setNavigationState"
326− Parameter { name: "departmentId"; type: "string" }
366+ Parameter { name: "navId"; type: "string" }
367+ Parameter { name: "altNavigation"; type: "bool" }
327 }
368 }
369+ Method {
370+ name: "performQuery"
371+ Parameter { name: "cannedQuery"; type: "string" }
372+ }
373+ Method { name: "refresh" }
328 }
374 }
329 Component {
375 Component {
330 name: "unity::shell::scopes::ScopesInterface"
376 name: "unity::shell::scopes::ScopesInterface"
@@ -334,11 +380,17 @@ Module {
334 values: {
380 values: {
335 "RoleScope": 0,
381 "RoleScope": 0,
336 "RoleId": 1,
382 "RoleId": 1,
337− "RoleVisible": 2,
338− "RoleTitle": 3
383+ "RoleTitle": 2
339 }
384 }
340 }
385 }
341 Property { name: "loaded"; type: "bool"; isReadonly: true }
386 Property { name: "loaded"; type: "bool"; isReadonly: true }
387+ Property { name: "count"; type: "int"; isReadonly: true }
388+ Property {
389+ name: "overviewScope"
390+ type: "unity::shell::scopes::ScopeInterface"
391+ isReadonly: true
392+ isPointer: true
393+ }
342 Method {
394 Method {
343 name: "getScope"
395 name: "getScope"
344 type: "unity::shell::scopes::ScopeInterface*"
396 type: "unity::shell::scopes::ScopeInterface*"
tests/mocks/Unity/fake_department.cpp → tests/mocks/Unity/fake_navigation.cpprenamed+32−40
@@ -14,14 +14,15 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
15 */
16
16
17−#include "fake_department.h"
17+#include "fake_navigation.h"
18
18
19#include "fake_scope.h"
19#include "fake_scope.h"
20
20
21+#include <QDebug>
21#include <QTimer>
22#include <QTimer>
22
23
23−Department::Department(const QString& departmentId, const QString& label, const QString& allLabel, const QString& parentId, const QString& parentLabel, Scope* scope)
24+Navigation::Navigation(const QString& navigationId, const QString& label, const QString& allLabel, const QString& parentId, const QString& parentLabel, Scope* scope)
24− : m_departmentId(departmentId)
25+ : m_navigationId(navigationId)
25 , m_label(label)
26 , m_label(label)
26 , m_allLabel(allLabel)
27 , m_allLabel(allLabel)
27 , m_parentId(parentId)
28 , m_parentId(parentId)
@@ -30,96 +31,87 @@ Department::Department(const QString& departmentId, const QString& label, const
30 , m_scope(scope)
31 , m_scope(scope)
31{
32{
32 QTimer::singleShot(1500, this, SLOT(slotLoaded()));
33 QTimer::singleShot(1500, this, SLOT(slotLoaded()));
33− connect(scope, SIGNAL(currentDepartmentIdChanged()), this, SLOT(slotCurrentDepartmentChanged()));
34+ connect(scope, SIGNAL(currentNavigationIdChanged()), this, SLOT(slotCurrentNavigationChanged()));
34}
35}
35
36
36−QString Department::departmentId() const
37+QString Navigation::navigationId() const
37{
38{
38− return m_departmentId;
39+ return m_navigationId;
39}
40}
40
41
41−QString Department::label() const
42+QString Navigation::label() const
42{
43{
43 return m_label;
44 return m_label;
44}
45}
45
46
46−QString Department::allLabel() const
47+QString Navigation::allLabel() const
47{
48{
48 return m_allLabel;
49 return m_allLabel;
49}
50}
50
51
51−QString Department::parentDepartmentId() const
52+QString Navigation::parentNavigationId() const
52{
53{
53 return m_parentId;
54 return m_parentId;
54}
55}
55
56
56−QString Department::parentLabel() const
57+QString Navigation::parentLabel() const
57{
58{
58 return m_parentLabel;
59 return m_parentLabel;
59}
60}
60
61
61−void Department::slotLoaded()
62+void Navigation::slotLoaded()
62{
63{
63 m_loaded = true;
64 m_loaded = true;
64 Q_EMIT loadedChanged();
65 Q_EMIT loadedChanged();
65}
66}
66
67
67−bool Department::loaded() const
68+bool Navigation::loaded() const
68{
69{
69 return m_loaded;
70 return m_loaded;
70}
71}
71
72
72−int Department::count() const
73+int Navigation::count() const
73{
74{
74 return rowCount();
75 return rowCount();
75}
76}
76
77
77−bool Department::isRoot() const
78+bool Navigation::isRoot() const
78{
79{
79− return m_departmentId == "root";
80+ return m_navigationId == "root" || m_navigationId == "altroot";
80}
81}
81
82
82−int Department::rowCount(const QModelIndex & /*parent*/) const
83+bool Navigation::hidden() const
83{
84{
84− if (!m_loaded || m_departmentId.startsWith("child") || m_departmentId == "middle3")
85+ return m_navigationId == "altroot";
85− return 0;
86− else
87− return 8;
88}
86}
89
87
90−QHash<int, QByteArray> Department::roleNames() const
88+int Navigation::rowCount(const QModelIndex & /*parent*/) const
91{
89{
92− QHash<int, QByteArray> res;
90+ if (!m_loaded || m_navigationId.startsWith("child") || m_navigationId == "middle3")
93− res[RoleDepartmentId] = "departmentId";
91+ return 0;
94− res[RoleLabel] = "label";
92+ else
95− res[RoleHasChildren] = "hasChildren";
96− res[RoleIsActive] = "isActive";
97− return res;
93+ return 8;
98}
94}
99
95
100−QVariant Department::data(const QModelIndex &index, int role) const
96+QVariant Navigation::data(const QModelIndex &index, int role) const
101{
97{
102 switch (role) {
98 switch (role) {
103− case RoleDepartmentId:
99+ case RoleNavigationId:
104− if (m_departmentId == "root")
100+ if (m_navigationId == "root")
105 return QString("middle%1").arg(index.row());
101 return QString("middle%1").arg(index.row());
106− else if (m_departmentId.startsWith("middle"))
102+ else if (m_navigationId.startsWith("middle"))
107− return QString("child%1%2").arg(m_departmentId).arg(index.row());
103+ return QString("child%1%2").arg(m_navigationId).arg(index.row());
108− break;
109 case RoleLabel:
104 case RoleLabel:
110− return QString("%1Child%2").arg(m_departmentId).arg(index.row());
105+ return QString("%1Child%2").arg(m_navigationId).arg(index.row());
111− break;
112 case RoleHasChildren:
106 case RoleHasChildren:
113− return m_departmentId == "root" && index.row() != 3;
107+ return m_navigationId == "root" && index.row() != 3;
114− break;
115 case RoleIsActive:
108 case RoleIsActive:
116− return m_scope->currentDepartmentId() == data(index, RoleDepartmentId);
109+ return m_scope->currentNavigationId() == data(index, RoleNavigationId);
117− break;
118 }
110 }
119 return QVariant();
111 return QVariant();
120}
112}
121
113
122−void Department::slotCurrentDepartmentChanged()
114+void Navigation::slotCurrentNavigationChanged()
123{
115{
124 // This is wasteful, should only emit it if really something changed in this
116 // This is wasteful, should only emit it if really something changed in this
125 // deparment, but this is a mock, so no need to optimize
117 // deparment, but this is a mock, so no need to optimize
tests/mocks/Unity/fake_department.h → tests/mocks/Unity/fake_navigation.hrenamed+13−13
@@ -14,48 +14,48 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
15 */
16
16
17−#ifndef FAKE_DEPARTMENT_H
17+#ifndef FAKE_NAVIGATION_H
18−#define FAKE_DEPARTMENT_H
18+#define FAKE_NAVIGATION_H
19
19
20−#include <unity/shell/scopes/DepartmentInterface.h>
20+#include <unity/shell/scopes/NavigationInterface.h>
21
21
22class Scope;
22class Scope;
23
23
24−class Department : public unity::shell::scopes::DepartmentInterface
24+class Navigation : public unity::shell::scopes::NavigationInterface
25{
25{
26 Q_OBJECT
26 Q_OBJECT
27
27
28public:
28public:
29− Department(const QString& departmentId, const QString& label, const QString& allLabel, const QString& parentId, const QString& parentLabel, Scope* scope);
29+ Navigation(const QString& navigationId, const QString& label, const QString& allLabel, const QString& parentId, const QString& parentLabel, Scope* scope);
30
30
31− QString departmentId() const override;
31+ QString navigationId() const override;
32 QString label() const override;
32 QString label() const override;
33 QString allLabel() const override;
33 QString allLabel() const override;
34− QString parentDepartmentId() const override;
34+ QString parentNavigationId() const override;
35 QString parentLabel() const override;
35 QString parentLabel() const override;
36 bool loaded() const override;
36 bool loaded() const override;
37− int count() const override;
38 bool isRoot() const override;
37 bool isRoot() const override;
38+ bool hidden() const override;
39+ int count() const override;
39
40
40 int rowCount(const QModelIndex &parent = QModelIndex()) const override;
41 int rowCount(const QModelIndex &parent = QModelIndex()) const override;
41− QHash<int, QByteArray> roleNames() const;
42 QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
42 QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
43
43
44public Q_SLOTS:
44public Q_SLOTS:
45− void slotCurrentDepartmentChanged();
45+ void slotCurrentNavigationChanged();
46
46
47private Q_SLOTS:
47private Q_SLOTS:
48 void slotLoaded();
48 void slotLoaded();
49
49
50private:
50private:
51− QString m_departmentId;
51+ QString m_navigationId;
52 QString m_label;
52 QString m_label;
53 QString m_allLabel;
53 QString m_allLabel;
54 QString m_parentId;
54 QString m_parentId;
55 QString m_parentLabel;
55 QString m_parentLabel;
56 bool m_loaded;
56 bool m_loaded;
57− QString m_currentDepartment;
57+ QString m_currentNavigation;
58 Scope *m_scope;
58 Scope *m_scope;
59};
59};
60
60
61−#endif // FAKE_DEPARTMENT_H
61+#endif // FAKE_NAVIGATION_H
tests/mocks/Unity/fake_scope.cpp+64−17
@@ -19,7 +19,7 @@
19
19
20#include "fake_scope.h"
20#include "fake_scope.h"
21
21
22−#include "fake_department.h"
22+#include "fake_navigation.h"
23#include "fake_resultsmodel.h"
23#include "fake_resultsmodel.h"
24#include "fake_scopes.h"
24#include "fake_scopes.h"
25
25
@@ -27,14 +27,15 @@ Scope::Scope(Scopes* parent) : Scope(QString(), QString(), false, parent)
27{
27{
28}
28}
29
29
30−Scope::Scope(QString const& id, QString const& name, bool visible, Scopes* parent, int categories)
30+Scope::Scope(QString const& id, QString const& name, bool favorite, Scopes* parent, int categories)
31 : unity::shell::scopes::ScopeInterface(parent)
31 : unity::shell::scopes::ScopeInterface(parent)
32 , m_id(id)
32 , m_id(id)
33 , m_name(name)
33 , m_name(name)
34− , m_visible(visible)
35 , m_searching(false)
34 , m_searching(false)
35+ , m_favorite(favorite)
36 , m_isActive(false)
36 , m_isActive(false)
37− , m_currentDeparment("root")
37+ , m_currentNavigationId("root")
38+ , m_currentAltNavigationId("altroot")
38 , m_previewRendererName("preview-generic")
39 , m_previewRendererName("preview-generic")
39 , m_categories(new Categories(categories, this))
40 , m_categories(new Categories(categories, this))
40 , m_openScope(nullptr)
41 , m_openScope(nullptr)
@@ -81,6 +82,11 @@ bool Scope::searchInProgress() const
81 return m_searching;
82 return m_searching;
82}
83}
83
84
85+bool Scope::favorite() const
86+{
87+ return m_favorite;
88+}
89+
84unity::shell::scopes::CategoriesInterface* Scope::categories() const
90unity::shell::scopes::CategoriesInterface* Scope::categories() const
85{
91{
86 return m_categories;
92 return m_categories;
@@ -101,11 +107,6 @@ QString Scope::formFactor() const
101 return m_formFactor;
107 return m_formFactor;
102}
108}
103
109
104−bool Scope::visible() const
105−{
106− return m_visible;
107−}
108−
109bool Scope::isActive() const
110bool Scope::isActive() const
110{
111{
111 return m_isActive;
112 return m_isActive;
@@ -135,6 +136,13 @@ void Scope::setActive(const bool active)
135 }
136 }
136}
137}
137
138
139+void Scope::setFavorite(const bool favorite)
140+{
141+ if (favorite != m_favorite) {
142+ m_favorite = favorite;
143+ Q_EMIT favoriteChanged();
144+ }
145+}
138void Scope::setSearchInProgress(const bool inProg)
146void Scope::setSearchInProgress(const bool inProg)
139{
147{
140 if (inProg != m_searching) {
148 if (inProg != m_searching) {
@@ -183,16 +191,31 @@ void Scope::closeScope(unity::shell::scopes::ScopeInterface* scope)
183 m_openScope = nullptr;
191 m_openScope = nullptr;
184}
192}
185
193
186−QString Scope::currentDepartmentId() const
194+QString Scope::currentNavigationId() const
195+{
196+ return m_currentNavigationId;
197+}
198+
199+bool Scope::hasNavigation() const
200+{
201+ return true;
202+}
203+
204+QString Scope::currentAltNavigationId() const
187{
205{
188− return m_currentDeparment;
206+ return m_currentAltNavigationId;
189}
207}
190
208
191−bool Scope::hasDepartments() const
209+bool Scope::hasAltNavigation() const
192{
210{
193 return true;
211 return true;
194}
212}
195
213
214+Scope::Status Scope::status() const
215+{
216+ return Status::Okay;
217+}
218+
196QVariantMap Scope::customizations() const
219QVariantMap Scope::customizations() const
197{
220{
198 QVariantMap m, h;
221 QVariantMap m, h;
@@ -209,7 +232,12 @@ QVariantMap Scope::customizations() const
209 return m;
232 return m;
210}
233}
211
234
235+void Scope::refresh()
236+{
237+ qDebug() << "Scope::refresh is currently not implmented in the fake scopes plugin";
238+}
239+
212−unity::shell::scopes::DepartmentInterface* Scope::getDepartment(const QString& id)
240+unity::shell::scopes::NavigationInterface* Scope::getNavigation(const QString& id)
213{
241{
214 if (id.isEmpty())
242 if (id.isEmpty())
215 return nullptr;
243 return nullptr;
@@ -223,11 +251,30 @@ unity::shell::scopes::DepartmentInterface* Scope::getDepartment(const QString& i
223 parentId = id.mid(5, 7);
251 parentId = id.mid(5, 7);
224 parentLabel = parentId;
252 parentLabel = parentId;
225 }
253 }
254+ return new Navigation(id, id, "all"+id, parentId, parentLabel, this);
255+}
256+
257+unity::shell::scopes::NavigationInterface* Scope::getAltNavigation(QString const& id)
258+{
259+ if (id.isEmpty())
260+ return nullptr;
261+
262+ QString parentId;
263+ QString parentLabel;
264+ if (id.startsWith("altmiddle")) {
265+ parentId = "altroot";
266+ parentLabel = "altroot";
267+ }
226− return new Department(id, id, "all"+id, parentId, parentLabel, this);
268+ return new Navigation(id, id, "all"+id, parentId, parentLabel, this);
227}
269}
228
270
229−void Scope::loadDepartment(const QString& id)
271+void Scope::setNavigationState(const QString &navigationId, bool isAltNavigation)
230{
272{
231− m_currentDeparment = id;
273+ if (isAltNavigation) {
232− Q_EMIT currentDepartmentIdChanged();
274+ m_currentAltNavigationId = navigationId;
275+ Q_EMIT currentAltNavigationIdChanged();
276+ } else {
277+ m_currentNavigationId = navigationId;
278+ Q_EMIT currentNavigationIdChanged();
279+ }
233}
280}
tests/mocks/Unity/fake_scope.h+16−8
@@ -32,7 +32,7 @@ class Scope : public unity::shell::scopes::ScopeInterface
32
32
33public:
33public:
34 Scope(Scopes* parent = 0);
34 Scope(Scopes* parent = 0);
35− Scope(QString const& id, QString const& name, bool visible, Scopes* parent = 0, int categories = 20);
35+ Scope(QString const& id, QString const& name, bool favorite, Scopes* parent = 0, int categories = 20);
36
36
37 /* getters */
37 /* getters */
38 QString id() const override;
38 QString id() const override;
@@ -40,9 +40,9 @@ public:
40 QString iconHint() const override;
40 QString iconHint() const override;
41 QString description() const override;
41 QString description() const override;
42 QString searchHint() const override;
42 QString searchHint() const override;
43− bool visible() const override;
44 QString shortcut() const override;
43 QString shortcut() const override;
45 bool searchInProgress() const override;
44 bool searchInProgress() const override;
45+ bool favorite() const override;
46 unity::shell::scopes::CategoriesInterface* categories() const override;
46 unity::shell::scopes::CategoriesInterface* categories() const override;
47 QString searchQuery() const override;
47 QString searchQuery() const override;
48 QString noResultsHint() const override;
48 QString noResultsHint() const override;
@@ -55,6 +55,7 @@ public:
55 void setNoResultsHint(const QString& hint) override;
55 void setNoResultsHint(const QString& hint) override;
56 void setFormFactor(const QString& form_factor) override;
56 void setFormFactor(const QString& form_factor) override;
57 void setActive(const bool) override;
57 void setActive(const bool) override;
58+ void setFavorite(const bool) override;
58 Q_INVOKABLE void setSearchInProgress(const bool inProg); // This is not invokable in the Interface, here for testing benefits
59 Q_INVOKABLE void setSearchInProgress(const bool inProg); // This is not invokable in the Interface, here for testing benefits
59
60
60 Q_INVOKABLE void activate(QVariant const& result) override;
61 Q_INVOKABLE void activate(QVariant const& result) override;
@@ -62,14 +63,20 @@ public:
62 Q_INVOKABLE void cancelActivation() override;
63 Q_INVOKABLE void cancelActivation() override;
63 Q_INVOKABLE void closeScope(unity::shell::scopes::ScopeInterface* scope) override;
64 Q_INVOKABLE void closeScope(unity::shell::scopes::ScopeInterface* scope) override;
64
65
65− QString currentDepartmentId() const override;
66+ QString currentNavigationId() const override;
66− bool hasDepartments() const override;
67+ bool hasNavigation() const override;
67− Q_INVOKABLE unity::shell::scopes::DepartmentInterface* getDepartment(const QString& id) override;
68+ QString currentAltNavigationId() const override;
69+ bool hasAltNavigation() const override;
70+ Q_INVOKABLE unity::shell::scopes::NavigationInterface* getNavigation(QString const& navigationId) override;
71+ Q_INVOKABLE unity::shell::scopes::NavigationInterface* getAltNavigation(QString const& altNavigationId) override;
68− Q_INVOKABLE void loadDepartment(const QString& id) override;
72+ Q_INVOKABLE void setNavigationState(const QString &navigationId, bool isAltNavigation) override;
69 Q_SIGNAL void performQuery(const QString& query) override;
73 Q_SIGNAL void performQuery(const QString& query) override;
70
74
75+ Status status() const override;
71 QVariantMap customizations() const override;
76 QVariantMap customizations() const override;
72
77
78+ Q_INVOKABLE void refresh() override;
79+
73protected:
80protected:
74
81
75 QString m_id;
82 QString m_id;
@@ -79,10 +86,11 @@ protected:
79 QString m_searchQuery;
86 QString m_searchQuery;
80 QString m_noResultsHint;
87 QString m_noResultsHint;
81 QString m_formFactor;
88 QString m_formFactor;
82− bool m_visible;
83 bool m_searching;
89 bool m_searching;
90+ bool m_favorite;
84 bool m_isActive;
91 bool m_isActive;
85− QString m_currentDeparment;
92+ QString m_currentNavigationId;
93+ QString m_currentAltNavigationId;
86
94
87 QString m_previewRendererName;
95 QString m_previewRendererName;
88
96
tests/mocks/Unity/fake_scopes.cpp+29−18
@@ -34,6 +34,11 @@ Scopes::Scopes(QObject *parent)
34 timer.setSingleShot(true);
34 timer.setSingleShot(true);
35 timer.setInterval(100);
35 timer.setInterval(100);
36 QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(updateScopes()));
36 QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(updateScopes()));
37+
38+ QObject::connect(this, SIGNAL(rowsInserted(const QModelIndex &, int, int)), this, SIGNAL(countChanged()));
39+ QObject::connect(this, SIGNAL(rowsRemoved(const QModelIndex &, int, int)), this, SIGNAL(countChanged()));
40+ QObject::connect(this, SIGNAL(modelReset()), this, SIGNAL(countChanged()));
41+
37 load();
42 load();
38}
43}
39
44
@@ -68,7 +73,8 @@ void Scopes::clear()
68 timer.stop();
73 timer.stop();
69 if (m_scopes.size() > 0) {
74 if (m_scopes.size() > 0) {
70 beginRemoveRows(QModelIndex(), 0, m_scopes.count()-1);
75 beginRemoveRows(QModelIndex(), 0, m_scopes.count()-1);
71− qDeleteAll(m_scopes);
76+ qDeleteAll(m_allScopes);
77+ m_allScopes.clear();
72 m_scopes.clear();
78 m_scopes.clear();
73 endRemoveRows();
79 endRemoveRows();
74 }
80 }
@@ -103,8 +109,6 @@ QVariant Scopes::data(const QModelIndex& index, int role) const
103 return QVariant::fromValue(scope);
109 return QVariant::fromValue(scope);
104 } else if (role == Scopes::RoleId) {
110 } else if (role == Scopes::RoleId) {
105 return QVariant::fromValue(scope->id());
111 return QVariant::fromValue(scope->id());
106− } else if (role == Scopes::RoleVisible) {
107− return QVariant::fromValue(scope->visible());
108 } else if (role == Scopes::RoleTitle) {
112 } else if (role == Scopes::RoleTitle) {
109 return QVariant::fromValue(scope->name());
113 return QVariant::fromValue(scope->name());
110 } else {
114 } else {
@@ -123,17 +127,17 @@ unity::shell::scopes::ScopeInterface* Scopes::getScope(int row) const
123
127
124unity::shell::scopes::ScopeInterface* Scopes::getScope(QString const &scope_id) const
128unity::shell::scopes::ScopeInterface* Scopes::getScope(QString const &scope_id) const
125{
129{
130+ // According to mh3 Scopes::getScope should only return favorite scopes (i.e the ones in the model)
126 for (Scope *scope : m_scopes) {
131 for (Scope *scope : m_scopes) {
127− // According to mh3 Scopes::getScope should only return non null for visible scopes
128− if (scope->id() == scope_id && scope->visible())
132+ if (scope->id() == scope_id)
129 return scope;
133 return scope;
130 }
134 }
131 return nullptr;
135 return nullptr;
132}
136}
133
137
134−unity::shell::scopes::ScopeInterface* Scopes::getScopeFromAll(const QString& scope_id) const
138+Scope* Scopes::getScopeFromAll(const QString& scope_id) const
135{
139{
136− for (Scope *scope : m_scopes) {
140+ for (Scope *scope : m_allScopes) {
137 if (scope->id() == scope_id)
141 if (scope->id() == scope_id)
138 return scope;
142 return scope;
139 }
143 }
@@ -150,26 +154,33 @@ bool Scopes::loaded() const
150 return m_loaded;
154 return m_loaded;
151}
155}
152
156
157+int Scopes::count() const
158+{
159+ return rowCount();
160+}
161+
153unity::shell::scopes::ScopeInterface* Scopes::overviewScope() const
162unity::shell::scopes::ScopeInterface* Scopes::overviewScope() const
154{
163{
155 return m_scopesOverview;
164 return m_scopesOverview;
156}
165}
157
166
158−QList<unity::shell::scopes::ScopeInterface *> Scopes::scopes(bool onlyVisible) const
167+QList<Scope*> Scopes::scopes() const
159{
168{
160− QList<unity::shell::scopes::ScopeInterface *> res;
169+ return m_scopes;
161− for (Scope *scope : m_scopes) {
170+}
162− if (!onlyVisible || scope->visible()) {
171+
163− res << scope;
172+QList<Scope*> Scopes::allScopes() const
164− }
173+{
165− }
166− return res;
174+ return m_allScopes;
167}
175}
168
176
169void Scopes::addScope(Scope* scope)
177void Scopes::addScope(Scope* scope)
170{
178{
171 int index = rowCount();
179 int index = rowCount();
180+ if (scope->favorite()) {
172− beginInsertRows(QModelIndex(), index, index);
181+ beginInsertRows(QModelIndex(), index, index);
173− m_scopes.append(scope);
182+ m_scopes.append(scope);
174− endInsertRows();
183+ endInsertRows();
184+ }
185+ m_allScopes.append(scope);
175}
186}
tests/mocks/Unity/fake_scopes.h+6−3
@@ -50,17 +50,20 @@ public:
50 QModelIndex parent ( const QModelIndex & index ) const;
50 QModelIndex parent ( const QModelIndex & index ) const;
51
51
52 bool loaded() const override;
52 bool loaded() const override;
53+ int count() const override;
53 unity::shell::scopes::ScopeInterface* overviewScope() const override;
54 unity::shell::scopes::ScopeInterface* overviewScope() const override;
54
55
55 // This is used as part of implementation of the other C++ code, not API
56 // This is used as part of implementation of the other C++ code, not API
56− QList<unity::shell::scopes::ScopeInterface *> scopes(bool onlyVisible) const;
57+ QList<Scope*> scopes() const;
58+ QList<Scope*> allScopes() const;
57− unity::shell::scopes::ScopeInterface* getScopeFromAll(const QString& scope_id) const;
59+ Scope* getScopeFromAll(const QString& scope_id) const;
58
60
59private Q_SLOTS:
61private Q_SLOTS:
60 void updateScopes();
62 void updateScopes();
61
63
62private:
64private:
63− QList<Scope*> m_scopes;
65+ QList<Scope*> m_scopes; // the favorite ones
66+ QList<Scope*> m_allScopes;
64 Scope *m_scopesOverview;
67 Scope *m_scopesOverview;
65 bool m_loaded;
68 bool m_loaded;
66 QTimer timer;
69 QTimer timer;
tests/mocks/Unity/fake_scopesoverview.cpp+4−3
@@ -81,7 +81,8 @@ ScopesOverviewCategories::data(const QModelIndex& index, int role) const
81 unity::shell::scopes::ResultsModelInterface *resultsModel = m_resultsModels[index.row()];
81 unity::shell::scopes::ResultsModelInterface *resultsModel = m_resultsModels[index.row()];
82 if (!resultsModel) {
82 if (!resultsModel) {
83 QObject *that = const_cast<ScopesOverviewCategories*>(this);
83 QObject *that = const_cast<ScopesOverviewCategories*>(this);
84− resultsModel = new ScopesOverviewResultsModel(m_scopes->scopes(index.row() == 0), categoryId, that);
84+ QList<Scope*> scopes = index.row() == 0 ? m_scopes->scopes() : m_scopes->allScopes();
85+ resultsModel = new ScopesOverviewResultsModel(scopes, categoryId, that);
85 m_resultsModels[index.row()] = resultsModel;
86 m_resultsModels[index.row()] = resultsModel;
86 }
87 }
87 switch (role) {
88 switch (role) {
@@ -158,7 +159,7 @@ ScopesOverviewSearchCategories::data(const QModelIndex& index, int role) const
158 unity::shell::scopes::ResultsModelInterface *resultsModel = m_resultsModels[index.row()];
159 unity::shell::scopes::ResultsModelInterface *resultsModel = m_resultsModels[index.row()];
159 if (!resultsModel) {
160 if (!resultsModel) {
160 QObject *that = const_cast<ScopesOverviewSearchCategories*>(this);
161 QObject *that = const_cast<ScopesOverviewSearchCategories*>(this);
161− QList<unity::shell::scopes::ScopeInterface *> scopes;
162+ QList<Scope *> scopes;
162 if (index.row() == 0) {
163 if (index.row() == 0) {
163 scopes << m_scopes->getScopeFromAll("clickscope") << nullptr << m_scopes->getScopeFromAll("MockScope2");
164 scopes << m_scopes->getScopeFromAll("clickscope") << nullptr << m_scopes->getScopeFromAll("MockScope2");
164 } else {
165 } else {
@@ -207,7 +208,7 @@ ScopesOverviewSearchCategories::data(const QModelIndex& index, int role) const
207}
208}
208
209
209
210
210−ScopesOverviewResultsModel::ScopesOverviewResultsModel(const QList<unity::shell::scopes::ScopeInterface *> &scopes, const QString &categoryId, QObject* parent)
211+ScopesOverviewResultsModel::ScopesOverviewResultsModel(const QList<Scope *> &scopes, const QString &categoryId, QObject* parent)
211 : unity::shell::scopes::ResultsModelInterface(parent)
212 : unity::shell::scopes::ResultsModelInterface(parent)
212 , m_scopes(scopes)
213 , m_scopes(scopes)
213 , m_categoryId(categoryId)
214 , m_categoryId(categoryId)
tests/mocks/Unity/fake_scopesoverview.h+2−2
@@ -80,7 +80,7 @@ class ScopesOverviewResultsModel : public unity::shell::scopes::ResultsModelInte
80 Q_OBJECT
80 Q_OBJECT
81
81
82public:
82public:
83− explicit ScopesOverviewResultsModel(const QList<unity::shell::scopes::ScopeInterface *> &scopes, const QString &categoryId, QObject* parent = 0);
83+ explicit ScopesOverviewResultsModel(const QList<Scope *> &scopes, const QString &categoryId, QObject* parent = 0);
84
84
85 int rowCount(const QModelIndex& parent = QModelIndex()) const override;
85 int rowCount(const QModelIndex& parent = QModelIndex()) const override;
86 QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
86 QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
@@ -97,7 +97,7 @@ public:
97 QHash<int, QByteArray> roleNames() const override;
97 QHash<int, QByteArray> roleNames() const override;
98
98
99private:
99private:
100− QList<unity::shell::scopes::ScopeInterface *> m_scopes;
100+ QList<Scope *> m_scopes;
101 QString m_categoryId;
101 QString m_categoryId;
102};
102};
103
103
tests/mocks/Unity/fake_unity_plugin.cpp+2−2
@@ -22,7 +22,7 @@
22// local
22// local
23#include "fake_scopes.h"
23#include "fake_scopes.h"
24#include "fake_categories.h"
24#include "fake_categories.h"
25−#include "fake_department.h"
25+#include "fake_navigation.h"
26#include "fake_previewmodel.h"
26#include "fake_previewmodel.h"
27#include "fake_previewwidgetmodel.h"
27#include "fake_previewwidgetmodel.h"
28#include "fake_resultsmodel.h"
28#include "fake_resultsmodel.h"
@@ -43,7 +43,7 @@ void FakeUnityPlugin::registerTypes(const char *uri)
43 qmlRegisterType<Scopes>(uri, 0, 2, "Scopes");
43 qmlRegisterType<Scopes>(uri, 0, 2, "Scopes");
44 qmlRegisterType<Scope>(uri, 0, 2, "MockScope");
44 qmlRegisterType<Scope>(uri, 0, 2, "MockScope");
45 qmlRegisterUncreatableType<unity::shell::scopes::ScopeInterface>(uri, 0, 2, "Scope", "Can't create Scope object in QML.");
45 qmlRegisterUncreatableType<unity::shell::scopes::ScopeInterface>(uri, 0, 2, "Scope", "Can't create Scope object in QML.");
46− qmlRegisterUncreatableType<unity::shell::scopes::DepartmentInterface>(uri, 0, 2, "Department", "Can't create Department object in QML.");
46+ qmlRegisterUncreatableType<unity::shell::scopes::NavigationInterface>(uri, 0, 2, "Navigation", "Can't create Navigation object in QML.");
47 qmlRegisterUncreatableType<unity::shell::scopes::CategoriesInterface>(uri, 0, 2, "Categories", "Can't create Categories object in QML.");
47 qmlRegisterUncreatableType<unity::shell::scopes::CategoriesInterface>(uri, 0, 2, "Categories", "Can't create Categories object in QML.");
48 qmlRegisterUncreatableType<unity::shell::scopes::PreviewModelInterface>(uri, 0, 2, "PreviewModel", "Can't create new PreviewModel in QML. Get them from PreviewStack instance.");
48 qmlRegisterUncreatableType<unity::shell::scopes::PreviewModelInterface>(uri, 0, 2, "PreviewModel", "Can't create new PreviewModel in QML. Get them from PreviewStack instance.");
49 qmlRegisterUncreatableType<ResultsModel>(uri, 0, 2, "ResultsModel", "Can't create ResultsModel object in QML.");
49 qmlRegisterUncreatableType<ResultsModel>(uri, 0, 2, "ResultsModel", "Can't create ResultsModel object in QML.");
tests/plugins/Dash/cardcreator/1.res+12−10
@@ -33,20 +33,15 @@ Item {
33 visible: image.status == Image.Ready;
33 visible: image.status == Image.Ready;
34 readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1;
34 readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1;
35 readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1;
35 readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1;
36− readonly property bool aspectSmallerThanImageAspect: aspect < image.aspect;
37− Component.onCompleted: { updateWidthHeightBindings(); if (artShapeBorderSource !== undefined) borderSource = artShapeBorderSource; }
36+ Component.onCompleted: { updateWidthHeightBindings(); if (artShapeBorderSource !== undefined) borderSource = artShapeBorderSource; }
38− onAspectSmallerThanImageAspectChanged: updateWidthHeightBindings();
39 Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); }
37 Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); }
40 function updateWidthHeightBindings() {
38 function updateWidthHeightBindings() {
41 if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) {
39 if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) {
42 width = root.fixedArtShapeSize.width;
40 width = root.fixedArtShapeSize.width;
43 height = root.fixedArtShapeSize.height;
41 height = root.fixedArtShapeSize.height;
44− } else if (aspectSmallerThanImageAspect) {
45− width = Qt.binding(function() { return !visible ? 0 : image.width });
46− height = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.height : width / image.aspect });
47 } else {
42 } else {
48− width = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.width : height * image.aspect });
43+ width = Qt.binding(function() { return !visible ? 0 : image.width });
49− height = Qt.binding(function() { return !visible ? 0 : image.height });
44+ height = Qt.binding(function() { return !visible ? 0 : image.height });
50 }
45 }
51 }
46 }
52 image: Image {
47 image: Image {
@@ -54,8 +49,7 @@ Item {
54 source: cardData && cardData["art"] || "";
49 source: cardData && cardData["art"] || "";
55 cache: true;
50 cache: true;
56 asynchronous: root.asynchronous;
51 asynchronous: root.asynchronous;
57− fillMode: components && components["art"]["fill-mode"] === "fit" ? Image.PreserveAspectFit: Image.PreserveAspectCrop;
52+ fillMode: Image.PreserveAspectCrop;
58− readonly property real aspect: implicitWidth / implicitHeight;
59 width: root.width;
53 width: root.width;
60 height: width / artShape.aspect;
54 height: width / artShape.aspect;
61 }
55 }
@@ -84,5 +78,13 @@ leftMargin: units.gu(1);
84 font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal;
78 font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal;
85 horizontalAlignment: root.headerAlignment;
79 horizontalAlignment: root.headerAlignment;
86 }
80 }
81+UbuntuShape {
82+ id: touchdown;
83+ objectName: "touchdown";
84+ anchors { fill: artShapeHolder }
85+ visible: root.pressed;
86+ radius: "medium";
87+ borderSource: "radius_pressed.sci"
88+}
87implicitHeight: titleLabel.y + titleLabel.height + units.gu(1);
89implicitHeight: titleLabel.y + titleLabel.height + units.gu(1);
88}
90}
tests/plugins/Dash/cardcreator/1.tst+1−1
@@ -1,3 +1,3 @@
1template: {"card-layout":"vertical","card-size":"small","category-layout":"grid","collapsed-rows":2}
1template: {"card-layout":"vertical","card-size":"small","category-layout":"grid","collapsed-rows":2}
2−components: {"art":{"aspect-ratio":1.6,"field":"art","fill-mode":"fit"},"title":{"field":"title"}}
2+components: {"art":{"aspect-ratio":1.6,"field":"art"},"title":{"field":"title"}}
3result: 1.res
3result: 1.res
tests/plugins/Dash/cardcreator/2.res+8
@@ -116,5 +116,13 @@ left: parent.left;
116
116
117 ]
117 ]
118 }
118 }
119+UbuntuShape {
120+ id: touchdown;
121+ objectName: "touchdown";
122+ anchors { fill: backgroundLoader }
123+ visible: root.pressed;
124+ radius: "medium";
125+ borderSource: "radius_pressed.sci"
126+}
119implicitHeight: row.y + row.height + units.gu(1);
127implicitHeight: row.y + row.height + units.gu(1);
120}
128}
tests/plugins/Dash/cardcreator/2.tst+1−1
@@ -1,3 +1,3 @@
1template: {"card-background":{"elements":["#E9E9E9"],"type":"color"},"card-layout":"vertical","card-size":"medium","category-layout":"grid","collapsed-rows":2}
1template: {"card-background":{"elements":["#E9E9E9"],"type":"color"},"card-layout":"vertical","card-size":"medium","category-layout":"grid","collapsed-rows":2}
2−components: {"art":{"aspect-ratio":1,"fill-mode":"crop"},"background":{"field":"background"},"mascot":{"field":"icon"},"subtitle":{"field":"author"},"title":{"field":"title"}}
2+components: {"art":{"aspect-ratio":1},"background":{"field":"background"},"mascot":{"field":"icon"},"subtitle":{"field":"author"},"title":{"field":"title"}}
3result: 2.res
3result: 2.res
tests/plugins/Dash/cardcreator/3.res+12−10
@@ -25,7 +25,7 @@ Item {
25 objectName: "artShapeLoader";
25 objectName: "artShapeLoader";
26 active: cardData && cardData["art"] || false;
26 active: cardData && cardData["art"] || false;
27 asynchronous: root.asynchronous;
27 asynchronous: root.asynchronous;
28− visible: status == Loader.Ready;
28+ visible: status == Loader.Ready;
29 sourceComponent: UbuntuShape {
29 sourceComponent: UbuntuShape {
30 id: artShape;
30 id: artShape;
31 objectName: "artShape";
31 objectName: "artShape";
@@ -33,20 +33,15 @@ Item {
33 visible: image.status == Image.Ready;
33 visible: image.status == Image.Ready;
34 readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1;
34 readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1;
35 readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1;
35 readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1;
36− readonly property bool aspectSmallerThanImageAspect: aspect < image.aspect;
37 Component.onCompleted: { updateWidthHeightBindings(); if (artShapeBorderSource !== undefined) borderSource = artShapeBorderSource; }
36 Component.onCompleted: { updateWidthHeightBindings(); if (artShapeBorderSource !== undefined) borderSource = artShapeBorderSource; }
38− onAspectSmallerThanImageAspectChanged: updateWidthHeightBindings();
39 Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); }
37 Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); }
40 function updateWidthHeightBindings() {
38 function updateWidthHeightBindings() {
41 if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) {
39 if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) {
42 width = root.fixedArtShapeSize.width;
40 width = root.fixedArtShapeSize.width;
43 height = root.fixedArtShapeSize.height;
41 height = root.fixedArtShapeSize.height;
44− } else if (aspectSmallerThanImageAspect) {
45− width = Qt.binding(function() { return !visible ? 0 : image.width });
46− height = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.height : width / image.aspect });
47 } else {
42 } else {
48− width = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.width : height * image.aspect });
43+ width = Qt.binding(function() { return !visible ? 0 : image.width });
49− height = Qt.binding(function() { return !visible ? 0 : image.height });
44+ height = Qt.binding(function() { return !visible ? 0 : image.height });
50 }
45 }
51 }
46 }
52 image: Image {
47 image: Image {
@@ -54,8 +49,7 @@ Item {
54 source: cardData && cardData["art"] || "";
49 source: cardData && cardData["art"] || "";
55 cache: true;
50 cache: true;
56 asynchronous: root.asynchronous;
51 asynchronous: root.asynchronous;
57− fillMode: components && components["art"]["fill-mode"] === "fit" ? Image.PreserveAspectFit: Image.PreserveAspectCrop;
52+ fillMode: Image.PreserveAspectCrop;
58− readonly property real aspect: implicitWidth / implicitHeight;
59 width: root.width;
53 width: root.width;
60 height: width / artShape.aspect;
54 height: width / artShape.aspect;
61 }
55 }
@@ -103,5 +97,13 @@ Label {
103 font.weight: Font.Light;
97 font.weight: Font.Light;
104 horizontalAlignment: root.headerAlignment;
98 horizontalAlignment: root.headerAlignment;
105 }
99 }
100+UbuntuShape {
101+ id: touchdown;
102+ objectName: "touchdown";
103+ anchors { fill: artShapeHolder }
104+ visible: root.pressed;
105+ radius: "medium";
106+ borderSource: "radius_pressed.sci"
107+}
106implicitHeight: subtitleLabel.y + subtitleLabel.height + units.gu(1);
108implicitHeight: subtitleLabel.y + subtitleLabel.height + units.gu(1);
107}
109}
tests/plugins/Dash/cardcreator/3.tst+1−1
@@ -1,3 +1,3 @@
1template: {"card-layout":"vertical","card-size":"small","category-layout":"grid","collapsed-rows":2}
1template: {"card-layout":"vertical","card-size":"small","category-layout":"grid","collapsed-rows":2}
2−components: {"art":{"aspect-ratio":0.75,"field":"art","fill-mode":"crop"},"subtitle":{"field":"price"},"title":{"field":"title"}}
2+components: {"art":{"aspect-ratio":0.75,"field":"art"},"subtitle":{"field":"price"},"title":{"field":"title"}}
3result: 3.res
3result: 3.res
tests/plugins/Dash/cardcreator/4.res+8
@@ -94,5 +94,13 @@ Label {
94}
94}
95]
95]
96}
96}
97+UbuntuShape {
98+ id: touchdown;
99+ objectName: "touchdown";
100+ anchors { fill: root }
101+ visible: root.pressed;
102+ radius: "medium";
103+ borderSource: "radius_pressed.sci"
104+}
97implicitHeight: row.y + row.height + units.gu(1);
105implicitHeight: row.y + row.height + units.gu(1);
98}
106}
tests/plugins/Dash/cardcreator/4.tst+1−1
@@ -1,3 +1,3 @@
1template: {"card-layout":"horizontal","card-size":"large","category-layout":"grid","collapsed-rows":2}
1template: {"card-layout":"horizontal","card-size":"large","category-layout":"grid","collapsed-rows":2}
2−components: {"art":{"aspect-ratio":1,"fill-mode":"crop"},"mascot":{"field":"mascot"},"subtitle":{"field":"domain"},"title":{"field":"title"}}
2+components: {"art":{"aspect-ratio":1},"mascot":{"field":"mascot"},"subtitle":{"field":"domain"},"title":{"field":"title"}}
3result: 4.res
3result: 4.res
tests/plugins/Dash/cardcreator/5.res+21−17
@@ -25,7 +25,7 @@ Item {
25 objectName: "artShapeLoader";
25 objectName: "artShapeLoader";
26 active: cardData && cardData["art"] || false;
26 active: cardData && cardData["art"] || false;
27 asynchronous: root.asynchronous;
27 asynchronous: root.asynchronous;
28− visible: status == Loader.Ready;
28+ visible: status == Loader.Ready;
29 sourceComponent: UbuntuShape {
29 sourceComponent: UbuntuShape {
30 id: artShape;
30 id: artShape;
31 objectName: "artShape";
31 objectName: "artShape";
@@ -33,20 +33,15 @@ Item {
33 visible: image.status == Image.Ready;
33 visible: image.status == Image.Ready;
34 readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1;
34 readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1;
35 readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1;
35 readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1;
36− readonly property bool aspectSmallerThanImageAspect: aspect < image.aspect;
37 Component.onCompleted: { updateWidthHeightBindings(); if (artShapeBorderSource !== undefined) borderSource = artShapeBorderSource; }
36 Component.onCompleted: { updateWidthHeightBindings(); if (artShapeBorderSource !== undefined) borderSource = artShapeBorderSource; }
38− onAspectSmallerThanImageAspectChanged: updateWidthHeightBindings();
39 Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); }
37 Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); }
40 function updateWidthHeightBindings() {
38 function updateWidthHeightBindings() {
41 if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) {
39 if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) {
42 width = root.fixedArtShapeSize.width;
40 width = root.fixedArtShapeSize.width;
43 height = root.fixedArtShapeSize.height;
41 height = root.fixedArtShapeSize.height;
44− } else if (aspectSmallerThanImageAspect) {
45− width = Qt.binding(function() { return !visible ? 0 : image.width });
46− height = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.height : width / image.aspect });
47 } else {
42 } else {
48− width = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.width : height * image.aspect });
43+ width = Qt.binding(function() { return !visible ? 0 : image.width });
49− height = Qt.binding(function() { return !visible ? 0 : image.height });
44+ height = Qt.binding(function() { return !visible ? 0 : image.height });
50 }
45 }
51 }
46 }
52 image: Image {
47 image: Image {
@@ -54,13 +49,12 @@ Item {
54 source: cardData && cardData["art"] || "";
49 source: cardData && cardData["art"] || "";
55 cache: true;
50 cache: true;
56 asynchronous: root.asynchronous;
51 asynchronous: root.asynchronous;
57− fillMode: components && components["art"]["fill-mode"] === "fit" ? Image.PreserveAspectFit: Image.PreserveAspectCrop;
52+ fillMode: Image.PreserveAspectCrop;
58− readonly property real aspect: implicitWidth / implicitHeight;
59 width: root.width;
53 width: root.width;
60 height: width / artShape.aspect;
54 height: width / artShape.aspect;
61 }
55 }
62 }
56 }
63− }
57+ }
64 }
58 }
65Loader {
59Loader {
66 id: overlayLoader;
60 id: overlayLoader;
@@ -69,13 +63,14 @@ Loader {
69 right: artShapeHolder.right;
63 right: artShapeHolder.right;
70 bottom: artShapeHolder.bottom;
64 bottom: artShapeHolder.bottom;
71 }
65 }
72− active: artShapeLoader.active && artShapeLoader.item && artShapeLoader.item.image.status === Image.Ready || false;
66+ active: artShapeLoader.active && artShapeLoader.item && artShapeLoader.item.image.status === Image.Ready || false;
73 asynchronous: root.asynchronous;
67 asynchronous: root.asynchronous;
74 visible: showHeader && status == Loader.Ready;
68 visible: showHeader && status == Loader.Ready;
75 sourceComponent: ShaderEffect {
69 sourceComponent: ShaderEffect {
76 id: overlay;
70 id: overlay;
77− height: (fixedHeaderHeight > 0 ? fixedHeaderHeight : headerHeight) + units.gu(2);
71+ height: (fixedHeaderHeight > 0 ? fixedHeaderHeight : headerHeight) + units.gu(2);
78− opacity: 0.6;
72+ property real luminance: 0.2126 * overlayColor.r + 0.7152 * overlayColor.g + 0.0722 * overlayColor.b;
73+ property color overlayColor: cardData && cardData["overlayColor"] || "#99000000";
79 property var source: ShaderEffectSource {
74 property var source: ShaderEffectSource {
80 id: shaderSource;
75 id: shaderSource;
81 sourceItem: artShapeLoader.item;
76 sourceItem: artShapeLoader.item;
@@ -96,9 +91,10 @@ Loader {
96 varying highp vec2 coord;
91 varying highp vec2 coord;
97 uniform sampler2D source;
92 uniform sampler2D source;
98 uniform lowp float qt_Opacity;
93 uniform lowp float qt_Opacity;
94+ uniform highp vec4 overlayColor;
99 void main() {
95 void main() {
100 lowp vec4 tex = texture2D(source, coord);
96 lowp vec4 tex = texture2D(source, coord);
101− gl_FragColor = vec4(0, 0, 0, tex.a) * qt_Opacity;
97+ gl_FragColor = vec4(overlayColor.r, overlayColor.g, overlayColor.b, 1) * qt_Opacity * overlayColor.a * tex.a;
102 }";
98 }";
103 }
99 }
104 }
100 }
@@ -118,7 +114,7 @@ Label {
118 wrapMode: Text.Wrap;
114 wrapMode: Text.Wrap;
119 maximumLineCount: 2;
115 maximumLineCount: 2;
120 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
116 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
121− color: "white";
117+ color: overlayLoader.item.luminance < (root.scopeStyle ? root.scopeStyle.threshold : 0.7) ? (root.scopeStyle ? root.scopeStyle.light : "white") : (root.scopeStyle ? root.scopeStyle.dark : "grey");
122 visible: showHeader && overlayLoader.active;
118 visible: showHeader && overlayLoader.active;
123 text: root.title;
119 text: root.title;
124 font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal;
120 font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal;
@@ -137,11 +133,19 @@ Label {
137 elide: Text.ElideRight;
133 elide: Text.ElideRight;
138 fontSize: "small";
134 fontSize: "small";
139 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
135 font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
140− color: "white";
136+ color: overlayLoader.item.luminance < (root.scopeStyle ? root.scopeStyle.threshold : 0.7) ? (root.scopeStyle ? root.scopeStyle.light : "white") : (root.scopeStyle ? root.scopeStyle.dark : "grey");
141 visible: titleLabel.visible && titleLabel.text;
137 visible: titleLabel.visible && titleLabel.text;
142 text: cardData && cardData["subtitle"] || "";
138 text: cardData && cardData["subtitle"] || "";
143 font.weight: Font.Light;
139 font.weight: Font.Light;
144 horizontalAlignment: root.headerAlignment;
140 horizontalAlignment: root.headerAlignment;
145 }
141 }
142+UbuntuShape {
143+ id: touchdown;
144+ objectName: "touchdown";
145+ anchors { fill: artShapeHolder }
146+ visible: root.pressed;
147+ radius: "medium";
148+ borderSource: "radius_pressed.sci"
149+}
146implicitHeight: subtitleLabel.y + subtitleLabel.height + units.gu(1);
150implicitHeight: subtitleLabel.y + subtitleLabel.height + units.gu(1);
147}
151}
tests/plugins/Dash/cardcreator/5.tst+1−1
@@ -1,3 +1,3 @@
1template: {"card-layout":"vertical","card-size":"medium","category-layout":"carousel","collapsed-rows":2,"overlay":true}
1template: {"card-layout":"vertical","card-size":"medium","category-layout":"carousel","collapsed-rows":2,"overlay":true}
2−components: {"art":{"aspect-ratio":1,"field":"art","fill-mode":"crop"},"subtitle":{"field":"artist"},"title":{"field":"title"}}
2+components: {"art":{"aspect-ratio":1,"field":"art"},"subtitle":{"field":"artist"},"title":{"field":"title"}}
3result: 5.res
3result: 5.res
tests/plugins/Dash/cardcreator/6.res+10−8
@@ -33,19 +33,14 @@ Item {
33 visible: image.status == Image.Ready;
33 visible: image.status == Image.Ready;
34 readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1;
34 readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1;
35 readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1;
35 readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1;
36− readonly property bool aspectSmallerThanImageAspect: aspect < image.aspect;
37 Component.onCompleted: { updateWidthHeightBindings(); if (artShapeBorderSource !== undefined) borderSource = artShapeBorderSource; }
36 Component.onCompleted: { updateWidthHeightBindings(); if (artShapeBorderSource !== undefined) borderSource = artShapeBorderSource; }
38− onAspectSmallerThanImageAspectChanged: updateWidthHeightBindings();
39 Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); }
37 Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); }
40 function updateWidthHeightBindings() {
38 function updateWidthHeightBindings() {
41 if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) {
39 if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) {
42 width = root.fixedArtShapeSize.width;
40 width = root.fixedArtShapeSize.width;
43 height = root.fixedArtShapeSize.height;
41 height = root.fixedArtShapeSize.height;
44− } else if (aspectSmallerThanImageAspect) {
45− width = Qt.binding(function() { return !visible ? 0 : image.width });
46− height = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.height : width / image.aspect });
47 } else {
42 } else {
48− width = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.width : height * image.aspect });
43+ width = Qt.binding(function() { return !visible ? 0 : image.width });
49 height = Qt.binding(function() { return !visible ? 0 : image.height });
44 height = Qt.binding(function() { return !visible ? 0 : image.height });
50 }
45 }
51 }
46 }
@@ -54,8 +49,7 @@ Item {
54 source: cardData && cardData["art"] || "";
49 source: cardData && cardData["art"] || "";
55 cache: true;
50 cache: true;
56 asynchronous: root.asynchronous;
51 asynchronous: root.asynchronous;
57− fillMode: components && components["art"]["fill-mode"] === "fit" ? Image.PreserveAspectFit: Image.PreserveAspectCrop;
52+ fillMode: Image.PreserveAspectCrop;
58− readonly property real aspect: implicitWidth / implicitHeight;
59 width: root.width;
53 width: root.width;
60 height: width / artShape.aspect;
54 height: width / artShape.aspect;
61 }
55 }
@@ -63,5 +57,13 @@ Item {
63 }
57 }
64 }
58 }
65readonly property int headerHeight: 0;
59readonly property int headerHeight: 0;
60+UbuntuShape {
61+ id: touchdown;
62+ objectName: "touchdown";
63+ anchors { fill: artShapeHolder }
64+ visible: root.pressed;
65+ radius: "medium";
66+ borderSource: "radius_pressed.sci"
67+}
66implicitHeight: artShapeHolder.height;
68implicitHeight: artShapeHolder.height;
67}
69}
tests/plugins/Dash/cardcreator/6.tst+1−1
@@ -1,3 +1,3 @@
1template: {"card-layout":"vertical","card-size":"small","category-layout":"grid","collapsed-rows":2}
1template: {"card-layout":"vertical","card-size":"small","category-layout":"grid","collapsed-rows":2}
2−components: {"art":{"aspect-ratio":1.6,"field":"art","fill-mode":"fit"}}
2+components: {"art":{"aspect-ratio":1.6,"field":"art"}}
3result: 6.res
3result: 6.res
tests/plugins/Dash/cardcreator/7.res+9−1
@@ -116,7 +116,7 @@ CardAttributes {
116 objectName: "attributesRow";
116 objectName: "attributesRow";
117 anchors { left: parent.left; right: parent.right }
117 anchors { left: parent.left; right: parent.right }
118 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");
118 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");
119− model: cardData && cardData["attributes"] || undefined;
119+ model: cardData["attributes"];
120 }
120 }
121
121
122 ]
122 ]
@@ -124,5 +124,13 @@ CardAttributes {
124
124
125 ]
125 ]
126 }
126 }
127+UbuntuShape {
128+ id: touchdown;
129+ objectName: "touchdown";
130+ anchors { fill: backgroundLoader }
131+ visible: root.pressed;
132+ radius: "medium";
133+ borderSource: "radius_pressed.sci"
134+}
127implicitHeight: row.y + row.height + units.gu(1);
135implicitHeight: row.y + row.height + units.gu(1);
128}
136}
tests/plugins/Dash/cardcreator/7.tst+1−1
@@ -1,3 +1,3 @@
1template: {"card-background":{"elements":["#E9E9E9"],"type":"color"},"card-layout":"vertical","card-size":"medium","category-layout":"grid","collapsed-rows":2}
1template: {"card-background":{"elements":["#E9E9E9"],"type":"color"},"card-layout":"vertical","card-size":"medium","category-layout":"grid","collapsed-rows":2}
2−components: {"art":{"aspect-ratio":1,"fill-mode":"crop"},"background":{"field":"background"},"mascot":{"field":"icon"},"subtitle":{"field":"author"},"title":{"field":"title"},"attributes":{"field":"attributes","max-count":2}}
2+components: {"art":{"aspect-ratio":1},"background":{"field":"background"},"mascot":{"field":"icon"},"subtitle":{"field":"author"},"title":{"field":"title"},"attributes":{"field":"attributes","max-count":2}}
3result: 7.res
3result: 7.res
tests/plugins/Dash/cardcreatortest.cpp+13−4
@@ -19,6 +19,7 @@
19#include <QQuickItem>
19#include <QQuickItem>
20#include <QQuickView>
20#include <QQuickView>
21#include <QtTestGui>
21#include <QtTestGui>
22+#include <QDebug>
22#include <QTemporaryFile>
23#include <QTemporaryFile>
23
24
24class CardCreatorTest : public QObject
25class CardCreatorTest : public QObject
@@ -74,15 +75,23 @@ private Q_SLOTS:
74 QFile testResultFile(testDirPath + resultFileName);
75 QFile testResultFile(testDirPath + resultFileName);
75 QVERIFY(testResultFile.open(QIODevice::ReadOnly));
76 QVERIFY(testResultFile.open(QIODevice::ReadOnly));
76 QTextStream ts2(&testResultFile);
77 QTextStream ts2(&testResultFile);
77− const QString expectedResult = ts2.readAll();
78+
78− const QString executedResult = cardStringResult.toString();
79 // Record failed results to /tmp
79 // Record failed results to /tmp
80+ const QString executedResult = cardStringResult.toString();
80 QTemporaryFile tmpFile(QDir::tempPath() + QDir::separator() + "testCardCreatorFailedResultXXXXXX");
81 QTemporaryFile tmpFile(QDir::tempPath() + QDir::separator() + "testCardCreatorFailedResultXXXXXX");
81 tmpFile.open();
82 tmpFile.open();
82 tmpFile.setAutoRemove(false);
83 tmpFile.setAutoRemove(false);
83 tmpFile.write(executedResult.toUtf8().constData());
84 tmpFile.write(executedResult.toUtf8().constData());
85+
86+ // Line by line comparison
87+ const QStringList expectedLines = ts2.readAll().trimmed().replace(QRegExp("\n\\s*\n"),"\n").split("\n");
88+ const QStringList cardStringResultLines = cardStringResult.toString().trimmed().replace(QRegExp("\n\\s*\n"),"\n").split("\n");
89+ for (int i = 0; i < expectedLines.size(); ++i) {
84− QCOMPARE(executedResult.simplified(), expectedResult.simplified());
90+ QCOMPARE(cardStringResultLines[i].simplified(), expectedLines[i].simplified());
91+ }
92+
85− tmpFile.setAutoRemove(true); // Remove the result if it passed
93+ // Remove the result if it passed
94+ tmpFile.setAutoRemove(true);
86
95
87 QVariant createCardComponentResult;
96 QVariant createCardComponentResult;
88 QMetaObject::invokeMethod(view->rootObject(), "createCardComponent", Q_RETURN_ARG(QVariant, createCardComponentResult), Q_ARG(QVariant, templateJSON), Q_ARG(QVariant, componentsJSON));
97 QMetaObject::invokeMethod(view->rootObject(), "createCardComponent", Q_RETURN_ARG(QVariant, createCardComponentResult), Q_ARG(QVariant, templateJSON), Q_ARG(QVariant, componentsJSON));
tests/plugins/Dash/tst_ScopeStyle.qml+14−7
@@ -54,6 +54,9 @@ Rectangle {
54 { tag: "lightgrey", luminance: 0.8275 },
54 { tag: "lightgrey", luminance: 0.8275 },
55 { tag: "grey", luminance: 0.5020 },
55 { tag: "grey", luminance: 0.5020 },
56 { tag: "darkgrey", luminance: 0.6627 },
56 { tag: "darkgrey", luminance: 0.6627 },
57+ { tag: "red", luminance: 0.2126 },
58+ { tag: "green", luminance: 0.3590 },
59+ { tag: "blue", luminance: 0.0722 },
57 ];
60 ];
58 }
61 }
59
62
@@ -64,10 +67,10 @@ Rectangle {
64
67
65 function test_foreground_data() {
68 function test_foreground_data() {
66 return [
69 return [
67− { tag: "default", index: 0, foreground: "grey" },
70+ { tag: "default", index: 0, foreground: "grey", luminance: 0.5020 },
68− { tag: "red on black", index: 1, foreground: "red" },
71+ { tag: "red on black", index: 1, foreground: "red", luminance: 0.2126 },
69− { tag: "green on white", index: 2, foreground: "green" },
72+ { tag: "green on white", index: 2, foreground: "green", luminance: 0.3590 },
70− { tag: "blue on darkgrey", index: 3, foreground: "blue" },
73+ { tag: "blue on darkgrey", index: 3, foreground: "blue", luminance: 0.0722 },
71 ];
74 ];
72 }
75 }
73
76
@@ -75,14 +78,15 @@ Rectangle {
75 tool.style = testCase.styles[data.index];
78 tool.style = testCase.styles[data.index];
76 verify(Qt.colorEqual(tool.foreground, data.foreground),
79 verify(Qt.colorEqual(tool.foreground, data.foreground),
77 "Foreground color not equal: %1 != %2".arg(tool.foreground).arg(data.foreground));
80 "Foreground color not equal: %1 != %2".arg(tool.foreground).arg(data.foreground));
81+ compare(tool.foregroundLuminance.toFixed(4), data.luminance.toFixed(4));
78 }
82 }
79
83
80 function test_background_data() {
84 function test_background_data() {
81 return [
85 return [
82 { tag: "default", index: 0, background: "transparent" },
86 { tag: "default", index: 0, background: "transparent" },
83− { tag: "red on black", index: 1, background: "black" },
87+ { tag: "red on black", index: 1, background: "black", luminance: 0 },
84− { tag: "green on white", index: 2, background: "white" },
88+ { tag: "green on white", index: 2, background: "white", luminance: 1 },
85− { tag: "blue on darkgrey", index: 3, background: "darkgrey" },
89+ { tag: "blue on darkgrey", index: 3, background: "darkgrey", luminance: 0.6627 },
86 ];
90 ];
87 }
91 }
88
92
@@ -90,6 +94,9 @@ Rectangle {
90 tool.style = testCase.styles[data.index];
94 tool.style = testCase.styles[data.index];
91 verify(Qt.colorEqual(tool.background, data.background),
95 verify(Qt.colorEqual(tool.background, data.background),
92 "Background color not equal: %1 != %2".arg(tool.background).arg(data.background));
96 "Background color not equal: %1 != %2".arg(tool.background).arg(data.background));
97+ if (data.hasOwnProperty("luminance")) {
98+ compare(tool.backgroundLuminance.toFixed(4), data.luminance.toFixed(4));
99+ }
93 }
100 }
94
101
95 function test_threshold_data() {
102 function test_threshold_data() {
tests/qmltests/CMakeLists.txt+1−1
@@ -30,7 +30,6 @@ add_qml_test(Components Rating)
30add_qml_test(Components ResponsiveFlowView)
30add_qml_test(Components ResponsiveFlowView)
31add_qml_test(Components ResponsiveGridView)
31add_qml_test(Components ResponsiveGridView)
32add_qml_test(Components ResponsiveVerticalJournal IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/plugins)
32add_qml_test(Components ResponsiveVerticalJournal IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/plugins)
33−add_qml_test(Components SeeMore)
34add_qml_test(Components Showable)
33add_qml_test(Components Showable)
35add_qml_test(Components PageHeader)
34add_qml_test(Components PageHeader)
36add_qml_test(Components ZoomableImage)
35add_qml_test(Components ZoomableImage)
@@ -43,6 +42,7 @@ add_qml_test(Dash GenericScopeView)
43add_qml_test(Dash/Previews Preview)
42add_qml_test(Dash/Previews Preview)
44add_qml_test(Dash/Previews PreviewActions)
43add_qml_test(Dash/Previews PreviewActions)
45add_qml_test(Dash/Previews PreviewAudioPlayback)
44add_qml_test(Dash/Previews PreviewAudioPlayback)
45+add_qml_test(Dash/Previews PreviewExpandable)
46add_qml_test(Dash/Previews PreviewHeader)
46add_qml_test(Dash/Previews PreviewHeader)
47add_qml_test(Dash/Previews PreviewImageGallery)
47add_qml_test(Dash/Previews PreviewImageGallery)
48add_qml_test(Dash/Previews PreviewPayments)
48add_qml_test(Dash/Previews PreviewPayments)
tests/qmltests/Components/tst_PageHeader.qml+21−23
@@ -119,29 +119,6 @@ Item {
119 compare(pageHeader.searchHistory.get(0).query, "humppa4")
119 compare(pageHeader.searchHistory.get(0).query, "humppa4")
120 }
120 }
121
121
122− function test_search_indicator() {
123− var searchIndicator = findChild(pageHeader, "searchIndicator")
124− var clearIcon = findChild(pageHeader, "clearIcon")
125−
126− pageHeader.triggerSearch()
127−
128− tryCompare(clearIcon, "visible", false)
129− pageHeader.searchQuery = "ubuntu"
130− tryCompare(clearIcon, "visible", true)
131−
132− pageHeader.searchInProgress = false
133− compare(searchIndicator.running, false, "Search indicator is running.")
134− tryCompare(clearIcon, "visible", true)
135−
136− pageHeader.searchInProgress = true
137− compare(searchIndicator.running, true, "Search indicator isn't running.")
138− tryCompare(clearIcon, "visible", false)
139−
140− pageHeader.searchInProgress = false;
141− compare(searchIndicator.running, false, "Search indicator is running.")
142− tryCompare(clearIcon, "visible", true)
143− }
144−
145 function test_titleImage() {
122 function test_titleImage() {
146
123
147 var titleImage = findChild(pageHeader, "titleImage");
124 var titleImage = findChild(pageHeader, "titleImage");
@@ -192,6 +169,27 @@ Item {
192 ];
169 ];
193 }
170 }
194
171
172+ function test_pagination() {
173+ var paginationRepeater = findChild(pageHeader, "paginationRepeater");
174+ tryCompare(paginationRepeater, "count", 0);
175+ pageHeader.paginationCount = 5;
176+ tryCompare(paginationRepeater, "count", 5);
177+ for (var i=0; i<pageHeader.paginationCount; i++) {
178+ pageHeader.paginationIndex = i;
179+ for (var j=0; j<paginationRepeater.count; j++) {
180+ var paginationDot = findChild(pageHeader, "paginationDots_"+j);
181+ if (i==j) {
182+ compare(paginationDot.source.toString().indexOf("pagination_dot_on") > -1, true);
183+ } else {
184+ compare(paginationDot.source.toString().indexOf("pagination_dot_off") > -1, true);
185+ }
186+ }
187+ }
188+ pageHeader.paginationIndex = -1;
189+ pageHeader.paginationCount = 0;
190+ tryCompare(paginationRepeater, "count", 0);
191+ }
192+
195 function test_popup_closing(data) {
193 function test_popup_closing(data) {
196 searchEnabled = true;
194 searchEnabled = true;
197 pageHeader.searchHistory.clear();
195 pageHeader.searchHistory.clear();
tests/qmltests/Components/tst_SeeMore.qmldeleted−52
@@ -1,52 +0,0 @@
1−/*
2− * Copyright 2014 Canonical Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−import QtQuick 2.0
18−import QtTest 1.0
19−import Ubuntu.Components 0.1
20−import "../../../qml/Components"
21−import Unity.Test 0.1 as UT
22−
23−Rectangle {
24− id: root
25− width: units.gu(40)
26− height: units.gu(10)
27− color: Theme.palette.selected.background
28−
29− SeeMore {
30− id: seeMore
31− anchors.fill: parent
32− more: false
33− }
34−
35− UT.UnityTestCase {
36− name: "SeeMoreTest"
37− when: windowShown
38−
39− function test_interaction() {
40− var seeMoreLabel = findChild(seeMore, "seeMoreLabel")
41− var seeLessLabel = findChild(seeMore, "seeLessLabel")
42−
43− compare(seeMore.more, false)
44−
45− mouseClick(seeMoreLabel, seeMoreLabel.width / 2, seeMoreLabel.height / 2)
46− compare(seeMore.more, true)
47−
48− mouseClick(seeLessLabel, seeLessLabel.width / 2, seeLessLabel.height / 2)
49− compare(seeMore.more, false)
50− }
51− }
52−}
tests/qmltests/Dash/CardHelpers.js+4−3
@@ -16,7 +16,7 @@
16
16
17.pragma library
17.pragma library
18
18
19−var components = ["title", "art", "subtitle", "mascot", "emblem", "old-price", "price", "alt-price", "rating", "alt-rating", "summary", "attributes"]
19+var components = ["title", "art", "subtitle", "mascot", "emblem", "old-price", "price", "alt-price", "rating", "alt-rating", "summary", "attributes", "overlayColor"]
20
20
21var defaultLayout = ' \
21var defaultLayout = ' \
22{ \
22{ \
@@ -31,10 +31,10 @@ var defaultLayout = ' \
31 "components": { \
31 "components": { \
32 "title": null, \
32 "title": null, \
33 "art": { \
33 "art": { \
34− "aspect-ratio": 1.0, \
34+ "aspect-ratio": 1.0 \
35− "fill-mode": "crop" \
36 }, \
35 }, \
37 "subtitle": null, \
36 "subtitle": null, \
37+ "overlayColor": null, \
38 "mascot": null, \
38 "mascot": null, \
39 "emblem": null, \
39 "emblem": null, \
40 "old-price": null, \
40 "old-price": null, \
@@ -60,6 +60,7 @@ var fullMapping = ' \
60 "art": "art", \
60 "art": "art", \
61 "subtitle": "subtitle", \
61 "subtitle": "subtitle", \
62 "mascot": "mascot", \
62 "mascot": "mascot", \
63+ "overlayColor": "overlayColor", \
63 "summary": "summary", \
64 "summary": "summary", \
64 "attributes": "attributes" \
65 "attributes": "attributes" \
65}'
66}'
tests/qmltests/Dash/Previews/tst_PreviewExpandable.qmlnew file+97
@@ -0,0 +1,97 @@
1+/*
2+ * Copyright 2014 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import QtTest 1.0
19+import Ubuntu.Components 0.1
20+import "../../../../qml/Dash/Previews"
21+import Unity.Test 0.1 as UT
22+
23+Rectangle {
24+ id: root
25+ width: units.gu(40)
26+ height: units.gu(80)
27+ color: Theme.palette.selected.background
28+
29+ property string longText: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.\nPhasellus a mi vitae augue rhoncus lobortis ut rutrum metus.\nCurabitur tortor leo, tristique sed mollis quis, condimentum venenatis nibh.\nLorem ipsum dolor sit amet, consectetur adipiscing elit.\nPhasellus a mi vitae augue rhoncus lobortis ut rutrum metus.\nCurabitur tortor leo, tristique sed mollis quis, condimentum venenatis nibh."
30+ property string longText2: "This is a very very very long text. 1 This is a very very very long text. 2 This is a very very very long text. 3 This is a very very very long text. 4 This is a very very very long text. 5 This is a very very very long text. 6 This is a very very very long text. 7 This is a very very very long text. 8 This is a very very very long text. 9 This is a very very very long text. 10 This is a very very very long text. 11 This is a very very very long text."
31+ property string shortText: "This is a short text :)"
32+
33+ property var widgetData: {
34+ "title": "Title here",
35+ "collapsed-widgets": 2,
36+ "widgets": [
37+ { "type": "text", "widgetId" : "text1", "properties" : { "text": longText } },
38+ { "type": "text", "widgetId" : "text2", "properties" : { "text": longText2 } },
39+ { "type": "text", "widgetId" : "text3", "properties" : { "text": shortText } },
40+ { "type": "text", "widgetId" : "text4", "properties" : { "text": longText } }
41+ ]
42+ }
43+
44+ PreviewExpandable {
45+ id: previewExpandable
46+ anchors { left: parent.left; right: parent.right }
47+ widgetData: root.widgetData
48+ }
49+
50+ UT.UnityTestCase {
51+ name: "PreviewExpandableTest"
52+ when: windowShown
53+
54+ function checkInitialState()
55+ {
56+ compare(previewExpandable.expanded, false);
57+
58+ var repeater = findChild(previewExpandable, "repeater")
59+ compare(repeater.count, 4)
60+
61+ compare (repeater.itemAt(0).visible, true);
62+ compare (repeater.itemAt(1).visible, true);
63+ compare (repeater.itemAt(2).visible, false);
64+ compare (repeater.itemAt(3).visible, false);
65+ compare (repeater.itemAt(0).expanded, false);
66+ compare (repeater.itemAt(1).expanded, false);
67+ }
68+
69+ function init() {
70+ }
71+
72+ function test_collapsed_by_default() {
73+ // Nothing init does this already
74+ }
75+
76+ function test_expand_collapse() {
77+ var expandButton = findChild(previewExpandable, "expandButton")
78+ mouseClick(expandButton, expandButton.width / 2, expandButton.height / 2);
79+
80+ var repeater = findChild(previewExpandable, "repeater")
81+ compare(repeater.count, 4)
82+
83+ compare (repeater.itemAt(0).visible, true);
84+ compare (repeater.itemAt(1).visible, true);
85+ compare (repeater.itemAt(2).visible, true);
86+ compare (repeater.itemAt(3).visible, true);
87+ compare (repeater.itemAt(0).expanded, true);
88+ compare (repeater.itemAt(1).expanded, true);
89+ compare (repeater.itemAt(2).expanded, true);
90+ compare (repeater.itemAt(3).expanded, true);
91+
92+ mouseClick(expandButton, expandButton.width / 2, expandButton.height / 2);
93+
94+ checkInitialState();
95+ }
96+ }
97+}
tests/qmltests/Dash/Previews/tst_PreviewTextSummary.qml+4−18
@@ -37,7 +37,7 @@ Rectangle {
37
37
38 property var widgetDataShortText: {
38 property var widgetDataShortText: {
39 "title": "Title here",
39 "title": "Title here",
40− "text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit.\nPhasellus a mi vitae augue rhoncus lobortis ut rutrum metus.\nCurabitur tortor leo, tristique sed mollis quis, condimentum venenatis nibh."
40+ "text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus a mi vitae augue rhoncus lobortis ut rutrum metus."
41 }
41 }
42
42
43 PreviewTextSummary {
43 PreviewTextSummary {
@@ -72,28 +72,14 @@ Rectangle {
72 tryCompare(textLabel, "y", 0)
72 tryCompare(textLabel, "y", 0)
73 }
73 }
74
74
75− function test_see_more() {
75+ function test_show_collapsed() {
76− var seeMore = findChild(previewTextSummary, "seeMore")
77−
78− // when it's more than textLabel.maximumCollapsedLineCount lines of text, show SeeMore component
79 verify(textLabel.lineCount > textLabel.maximumCollapsedLineCount)
76 verify(textLabel.lineCount > textLabel.maximumCollapsedLineCount)
80− compare(seeMore.visible, true)
81− verify(seeMore.more === false)
82− verify(textLabel.height < textLabel.contentHeight)
83
77
84− // test interactions with SeeMore
78+ previewTextSummary.expanded = false;
85− var seeMoreLabel = findChild(seeMore, "seeMoreLabel")
79+ tryCompareFunction(function() { return textLabel.height < textLabel.contentHeight; }, true)
86− var seeLessLabel = findChild(seeMore, "seeLessLabel")
87− var initialTextLabelHeight = textLabel.height
88− mouseClick(seeMoreLabel, seeMoreLabel.width / 2, seeMoreLabel.height / 2)
89− tryCompare(textLabel, "height", textLabel.contentHeight)
90− mouseClick(seeLessLabel, seeLessLabel.width / 2, seeLessLabel.height / 2)
91− tryCompare(textLabel, "height", initialTextLabelHeight)
92
80
93− // text SeeMore automatic hiding
94 previewTextSummary.widgetData = widgetDataShortText
81 previewTextSummary.widgetData = widgetDataShortText
95 verify(textLabel.lineCount <= textLabel.maximumCollapsedLineCount)
82 verify(textLabel.lineCount <= textLabel.maximumCollapsedLineCount)
96− compare(seeMore.visible, false)
97 tryCompare(textLabel, "height", textLabel.contentHeight)
83 tryCompare(textLabel, "height", textLabel.contentHeight)
98 tryCompare(previewTextSummary, "height", titleLabel.height + textLabel.height)
84 tryCompare(previewTextSummary, "height", titleLabel.height + textLabel.height)
99 }
85 }
tests/qmltests/Dash/Previews/tst_PreviewWidgetFactory.qml+1
@@ -77,6 +77,7 @@ Rectangle {
77 return [
77 return [
78 { tag: "Actions", type: "actions", source: "PreviewActions.qml" },
78 { tag: "Actions", type: "actions", source: "PreviewActions.qml" },
79 { tag: "Audio", type: "audio", source: "PreviewAudioPlayback.qml" },
79 { tag: "Audio", type: "audio", source: "PreviewAudioPlayback.qml" },
80+ { tag: "Expandable", type: "expandable", source: "PreviewExpandable.qml" },
80 { tag: "Gallery", type: "gallery", source: "PreviewImageGallery.qml" },
81 { tag: "Gallery", type: "gallery", source: "PreviewImageGallery.qml" },
81 { tag: "Header", type: "header", source: "PreviewHeader.qml" },
82 { tag: "Header", type: "header", source: "PreviewHeader.qml" },
82 { tag: "Image", type: "image", source: "PreviewZoomableImage.qml" },
83 { tag: "Image", type: "image", source: "PreviewZoomableImage.qml" },
tests/qmltests/Dash/tst_Card.qml+15−3
@@ -55,8 +55,8 @@ Rectangle {
55 "layout": { "components": Helpers.update(JSON.parse(Helpers.fullMapping), { "art": { "aspect-ratio": 2 } }) }
55 "layout": { "components": Helpers.update(JSON.parse(Helpers.fullMapping), { "art": { "aspect-ratio": 2 } }) }
56 },
56 },
57 {
57 {
58− "name": "Art, title - fitted",
58+ "name": "Art, title - tall",
59− "layout": { "components": Helpers.update(JSON.parse(Helpers.fullMapping), { "art": { "fill-mode": "fit" } }) }
59+ "layout": { "components": Helpers.update(JSON.parse(Helpers.fullMapping), { "art": { "aspect-ratio": 0.7 } }) }
60 },
60 },
61 {
61 {
62 "name": "Art, header, summary - horizontal",
62 "name": "Art, header, summary - horizontal",
@@ -269,7 +269,7 @@ Rectangle {
269 { tag: "Small", width: units.gu(12), index: 1 },
269 { tag: "Small", width: units.gu(12), index: 1 },
270 { tag: "Large", width: units.gu(38), index: 2 },
270 { tag: "Large", width: units.gu(38), index: 2 },
271 { tag: "Wide", height: units.gu(19), size: "large", index: 3 },
271 { tag: "Wide", height: units.gu(19), size: "large", index: 3 },
272− { tag: "Fit", height: units.gu(38), size: "large", width: units.gu(19), index: 4 },
272+ { tag: "Tall", height: units.gu(38) / 0.7, size: "large", width: units.gu(38), index: 4 },
273 { tag: "VerticalWidth", width: function() { return headerRow.width + units.gu(1) * 2 }, index: 0 },
273 { tag: "VerticalWidth", width: function() { return headerRow.width + units.gu(1) * 2 }, index: 0 },
274 { tag: "HorizontalHeight", height: function() { return headerRow.height + units.gu(1) * 2 }, index: 5 },
274 { tag: "HorizontalHeight", height: function() { return headerRow.height + units.gu(1) * 2 }, index: 5 },
275 { tag: "HorizontalWidth", width: function() { return headerRow.x - units.gu(1) }, index: 5 },
275 { tag: "HorizontalWidth", width: function() { return headerRow.x - units.gu(1) }, index: 5 },
@@ -475,5 +475,17 @@ Rectangle {
475 compare(shape !== null, data.shape);
475 compare(shape !== null, data.shape);
476 tryCompare(mascotImage, "visible", !data.shape);
476 tryCompare(mascotImage, "visible", !data.shape);
477 }
477 }
478+
479+ function test_touchdown_visibility() {
480+ selector.selectedIndex = 0;
481+
482+ var touchdown = findChild(card, "touchdown");
483+
484+ compare(touchdown.visible, false);
485+ mousePress(card, card.width/2, card.height/2);
486+ compare(touchdown.visible, true);
487+ mouseRelease(card, card.width/2, card.height/2);
488+ compare(touchdown.visible, false);
489+ }
478 }
490 }
479}
491}
tests/qmltests/Dash/tst_Dash.qml+35−15
@@ -43,12 +43,8 @@ Item {
43 name: "Dash"
43 name: "Dash"
44 when: windowShown
44 when: windowShown
45
45
46− property var scopes
47−
48− Component.onCompleted: {
49− var dashContent = findChild(dash, "dashContent");
46+ readonly property Item dashContent: findChild(dash, "dashContent");
50− scopes = dashContent.scopes;
47+ readonly property var scopes: dashContent.scopes
51− }
52
48
53 function init() {
49 function init() {
54 // clear and reload the scopes.
50 // clear and reload the scopes.
@@ -62,10 +58,10 @@ Item {
62
58
63 function get_scope_data() {
59 function get_scope_data() {
64 return [
60 return [
65− { tag: "MockScope1", visualIndex: 0, shouldBeVisible: true },
61+ { tag: "MockScope1", visualIndex: 0 },
66− { tag: "MockScope2", visualIndex: -1, shouldBeVisible: false },
62+ { tag: "MockScope2", visualIndex: -1 },
67− { tag: "clickscope", visualIndex: 1, shouldBeVisible: true },
63+ { tag: "clickscope", visualIndex: 1 },
68− { tag: "MockScope5", visualIndex: 2, shouldBeVisible: true },
64+ { tag: "MockScope5", visualIndex: 2 },
69 ]
65 ]
70 }
66 }
71
67
@@ -74,10 +70,6 @@ Item {
74 }
70 }
75
71
76 function test_show_scope_on_load(data) {
72 function test_show_scope_on_load(data) {
77− if (data.shouldBeVisible == false) {
78− console.log("Not testing " + data.tag + ": not visible");
79− return;
80− }
81 var dashContentList = findChild(dash, "dashContentList");
73 var dashContentList = findChild(dash, "dashContentList");
82
74
83 dash.showScopeOnLoaded = data.tag
75 dash.showScopeOnLoaded = data.tag
@@ -88,7 +80,14 @@ Item {
88 tryCompare(dashContentList, "count", 6);
80 tryCompare(dashContentList, "count", 6);
89
81
90 verify(dashContentList != undefined);
82 verify(dashContentList != undefined);
83+ if (data.visualIndex == -1) {
91− tryCompare(dashContentList, "currentIndex", data.visualIndex);
84+ tryCompare(dashContentList, "currentIndex", 0);
85+ expectFail(data.tag, "non favorite scopes should not be visble in the scopes model");
86+ compare(dashContentList.currentItem.scopeId, data.tag); // this should fail
87+ } else {
88+ tryCompare(dashContentList, "currentIndex", data.visualIndex);
89+ compare(dashContentList.currentItem.scopeId, data.tag);
90+ }
92 }
91 }
93
92
94 function test_dash_overview_show_select_same_favorite() {
93 function test_dash_overview_show_select_same_favorite() {
@@ -325,5 +324,26 @@ Item {
325 dashCommunicatorService.mockSetCurrentScope("clickscope", true, true);
324 dashCommunicatorService.mockSetCurrentScope("clickscope", true, true);
326 tryCompare(dashContentList, "currentIndex", 1)
325 tryCompare(dashContentList, "currentIndex", 1)
327 }
326 }
327+
328+ function test_processing_indicator() {
329+ tryCompare(scopes, "loaded", true);
330+
331+ var processingIndicator = findChild(dash, "processingIndicator");
332+ verify(processingIndicator, "Can't find the processing indicator.");
333+
334+ verify(!processingIndicator.visible, "Processing indicator should be visible.");
335+
336+ tryCompareFunction(function() {
337+ return scopes.getScope(dashContent.currentIndex) != null;
338+ }, true);
339+ var currentScope = scopes.getScope(dashContent.currentIndex);
340+ verify(currentScope, "Can't find the current scope.");
341+
342+ currentScope.setSearchInProgress(true);
343+ tryCompare(processingIndicator, "visible", true);
344+
345+ currentScope.setSearchInProgress(false);
346+ tryCompare(processingIndicator, "visible", false);
347+ }
328 }
348 }
329}
349}
tests/qmltests/Dash/tst_DashContent.qml+99−100
@@ -43,9 +43,6 @@ Item {
43 id: dashContent
43 id: dashContent
44 anchors.fill: parent
44 anchors.fill: parent
45
45
46− model: SortFilterProxyModel {
47− model: scopesModel
48− }
49 scopes : scopesModel
46 scopes : scopesModel
50 }
47 }
51
48
@@ -73,7 +70,7 @@ Item {
73 function loadScopes() {
70 function loadScopes() {
74 scopeLoadedSpy.clear();
71 scopeLoadedSpy.clear();
75 scopesModel.load();
72 scopesModel.load();
76− tryCompare(scopeLoadedSpy, "count", 10);
73+ tryCompare(scopeLoadedSpy, "count", 6);
77 }
74 }
78
75
79 function init() {
76 function init() {
@@ -117,7 +114,7 @@ Item {
117
114
118 loadScopes();
115 loadScopes();
119
116
120− compare(dashContentList.count, 10);
117+ compare(dashContentList.count, 6);
121 verify(dashContentList.currentIndex >= 0 && dashContentList.currentIndex < dashContentList.count);
118 verify(dashContentList.currentIndex >= 0 && dashContentList.currentIndex < dashContentList.count);
122 }
119 }
123
120
@@ -193,9 +190,9 @@ Item {
193 function test_scope_mapping_data() {
190 function test_scope_mapping_data() {
194 return [
191 return [
195 {tag: "index0", index: 0, objectName: "MockScope1"},
192 {tag: "index0", index: 0, objectName: "MockScope1"},
196− {tag: "index1", index: 1, objectName: "MockScope2"},
193+ {tag: "index1", index: 1, objectName: "clickscope"},
197− {tag: "index2", index: 2, objectName: "clickscope"},
194+ {tag: "index2", index: 2, objectName: "MockScope5"},
198− {tag: "index3", index: 3, objectName: "MockScope5"}
195+ {tag: "index3", index: 3, objectName: "SingleCategoryScope"}
199 ]
196 ]
200 }
197 }
201
198
@@ -269,117 +266,119 @@ Item {
269 verify(carouselLV.tileWidth / carouselLV.tileHeight == cardTool.components["art"]["aspect-ratio"]);
266 verify(carouselLV.tileWidth / carouselLV.tileHeight == cardTool.components["art"]["aspect-ratio"]);
270 }
267 }
271
268
272− function test_departments() {
269+ function test_navigations() {
273− var dashDepartments = findChild(dashContent, "dashDepartments");
270+ var dashContentList = findChild(dashContent, "dashContentList");
274− compare(dashDepartments.visible, true);
271+ tryCompareFunction(function() { return findChild(dashContentList.currentItem, "dashNavigation") != null; }, true);
272+ var dashNavigation = findChild(dashContentList.currentItem, "dashNavigation");
273+ tryCompare(dashNavigation, "visible", true);
275− compare(dashDepartments.showList, false);
274+ compare(dashNavigation.showList, false);
276− waitForRendering(dashDepartments);
275+ waitForRendering(dashNavigation);
277− mouseClick(dashDepartments, 0, 0);
276+ mouseClick(dashNavigation, 0, 0);
278− compare(dashDepartments.showList, true);
277+ compare(dashNavigation.showList, true);
279−
278+
280− var departmentListView = findChild(dashDepartments, "departmentListView");
279+ var navigationListView = findChild(dashNavigation, "navigationListView");
281− compare(departmentListView.count, 1);
280+ compare(navigationListView.count, 1);
282− tryCompare(departmentListView.currentItem.department, "loaded", true);
281+ tryCompare(navigationListView.currentItem.navigation, "loaded", true);
283−
282+
284− waitForRendering(departmentListView);
283+ waitForRendering(navigationListView);
285− waitForRendering(departmentListView.currentItem);
284+ waitForRendering(navigationListView.currentItem);
286−
285+
287− var allButton = findChild(dashDepartments, "allButton");
286+ var allButton = findChild(dashNavigation, "allButton");
288 compare(allButton.visible, false);
287 compare(allButton.visible, false);
289
288
290− var department = findChild(dashDepartments, "department0child3");
289+ var navigation = findChild(dashNavigation, "navigation0child3");
291− mouseClick(department, 0, 0);
290+ mouseClick(navigation, 0, 0);
292− compare(dashDepartments.showList, false);
291+ compare(dashNavigation.showList, false);
293− tryCompare(dashDepartments.currentDepartment, "departmentId", "middle3");
292+ tryCompare(dashNavigation.currentNavigation, "navigationId", "middle3");
294− tryCompare(departmentListView.currentItem.department, "departmentId", "root");
293+ tryCompare(navigationListView.currentItem.navigation, "navigationId", "root");
295
294
296− mouseClick(dashDepartments, 0, 0);
295+ mouseClick(dashNavigation, 0, 0);
297− compare(dashDepartments.showList, true);
296+ compare(dashNavigation.showList, true);
298− waitForRendering(departmentListView);
297+ waitForRendering(navigationListView);
299− waitForRendering(departmentListView.currentItem);
298+ waitForRendering(navigationListView.currentItem);
300 compare(allButton.visible, true);
299 compare(allButton.visible, true);
301
300
302 mouseClick(allButton, 0, 0);
301 mouseClick(allButton, 0, 0);
303− compare(dashDepartments.showList, false);
302+ compare(dashNavigation.showList, false);
304− tryCompare(dashDepartments.currentDepartment, "departmentId", "root");
303+ tryCompare(dashNavigation.currentNavigation, "navigationId", "root");
305− tryCompare(departmentListView.currentItem.department, "departmentId", "root");
304+ tryCompare(navigationListView.currentItem.navigation, "navigationId", "root");
306−
305+
307− mouseClick(dashDepartments, 0, 0);
306+ mouseClick(dashNavigation, 0, 0);
308− compare(dashDepartments.showList, true);
307+ compare(dashNavigation.showList, true);
309− waitForRendering(departmentListView);
308+ waitForRendering(navigationListView);
310− waitForRendering(departmentListView.currentItem);
309+ waitForRendering(navigationListView.currentItem);
311 compare(allButton.visible, false);
310 compare(allButton.visible, false);
312
311
313− department = findChild(dashDepartments, "department0child2");
312+ navigation = findChild(dashNavigation, "navigation0child2");
314− mouseClick(department, 0, 0);
313+ mouseClick(navigation, 0, 0);
315− compare(dashDepartments.showList, true);
314+ compare(dashNavigation.showList, true);
316− tryCompare(dashDepartments.currentDepartment, "departmentId", "middle2");
315+ tryCompare(dashNavigation.currentNavigation, "navigationId", "middle2");
317− tryCompare(departmentListView.currentItem.department, "departmentId", "middle2");
316+ tryCompare(navigationListView.currentItem.navigation, "navigationId", "middle2");
318
317
319− var departmentList1 = findChild(dashDepartments, "department1");
318+ var navigationList1 = findChild(dashNavigation, "navigation1");
320− allButton = findChild(departmentList1, "allButton");
319+ allButton = findChild(navigationList1, "allButton");
321− var backButton = findChild(findChild(departmentList1, "department1"), "backButton");
320+ var backButton = findChild(findChild(navigationList1, "navigation1"), "backButton");
322 compare(allButton.visible, true);
321 compare(allButton.visible, true);
323 compare(backButton.visible, true);
322 compare(backButton.visible, true);
324
323
325− tryCompare(departmentListView, "contentX", departmentList1.x);
324+ tryCompare(navigationListView, "contentX", navigationList1.x);
326− waitForRendering(departmentListView);
325+ waitForRendering(navigationListView);
327 mouseClick(allButton, 0, 0);
326 mouseClick(allButton, 0, 0);
328− compare(dashDepartments.showList, false);
327+ compare(dashNavigation.showList, false);
329− tryCompare(dashDepartments.currentDepartment, "departmentId", "middle2");
328+ tryCompare(dashNavigation.currentNavigation, "navigationId", "middle2");
330− tryCompare(departmentListView.currentItem.department, "departmentId", "middle2");
329+ tryCompare(navigationListView.currentItem.navigation, "navigationId", "middle2");
331−
330+
332− mouseClick(dashDepartments, 0, 0);
331+ mouseClick(dashNavigation, 0, 0);
333− compare(dashDepartments.showList, true);
332+ compare(dashNavigation.showList, true);
334− waitForRendering(departmentListView);
333+ waitForRendering(navigationListView);
335− waitForRendering(departmentListView.currentItem);
334+ waitForRendering(navigationListView.currentItem);
336 compare(allButton.visible, true);
335 compare(allButton.visible, true);
337 compare(backButton.visible, true);
336 compare(backButton.visible, true);
338
337
339− tryCompare(departmentList1.department, "loaded", true);
338+ tryCompare(navigationList1.navigation, "loaded", true);
340− department = findChild(dashDepartments, "department1child2");
339+ navigation = findChild(dashNavigation, "navigation1child2");
341− mouseClick(department, 0, 0);
340+ mouseClick(navigation, 0, 0);
342− compare(dashDepartments.showList, false);
341+ compare(dashNavigation.showList, false);
343− tryCompare(dashDepartments.currentDepartment, "departmentId", "childmiddle22");
342+ tryCompare(dashNavigation.currentNavigation, "navigationId", "childmiddle22");
344− tryCompare(departmentListView.currentItem.department, "departmentId", "middle2");
343+ tryCompare(navigationListView.currentItem.navigation, "navigationId", "middle2");
345−
344+
346− mouseClick(dashDepartments, 0, 0);
345+ mouseClick(dashNavigation, 0, 0);
347− compare(dashDepartments.showList, true);
346+ compare(dashNavigation.showList, true);
348− waitForRendering(departmentListView);
347+ waitForRendering(navigationListView);
349− waitForRendering(departmentListView.currentItem);
348+ waitForRendering(navigationListView.currentItem);
350−
349+
351− tryCompare(departmentList1.department, "loaded", true);
350+ tryCompare(navigationList1.navigation, "loaded", true);
352− department = findChild(dashDepartments, "department1child3");
351+ navigation = findChild(dashNavigation, "navigation1child3");
353− mouseClick(department, 0, 0);
352+ mouseClick(navigation, 0, 0);
354− compare(dashDepartments.showList, false);
353+ compare(dashNavigation.showList, false);
355− tryCompare(dashDepartments.currentDepartment, "departmentId", "childmiddle23");
354+ tryCompare(dashNavigation.currentNavigation, "navigationId", "childmiddle23");
356− tryCompare(departmentListView.currentItem.department, "departmentId", "middle2");
355+ tryCompare(navigationListView.currentItem.navigation, "navigationId", "middle2");
357−
356+
358− mouseClick(dashDepartments, 0, 0);
357+ mouseClick(dashNavigation, 0, 0);
359− compare(dashDepartments.showList, true);
358+ compare(dashNavigation.showList, true);
360− waitForRendering(departmentListView);
359+ waitForRendering(navigationListView);
361− waitForRendering(departmentListView.currentItem);
360+ waitForRendering(navigationListView.currentItem);
362 mouseClick(backButton, 0, 0);
361 mouseClick(backButton, 0, 0);
363
362
364− tryCompare(dashDepartments.currentDepartment, "departmentId", "root");
363+ tryCompare(dashNavigation.currentNavigation, "navigationId", "root");
365− tryCompare(departmentListView.currentItem.department, "departmentId", "root");
364+ tryCompare(navigationListView.currentItem.navigation, "navigationId", "root");
366− compare(dashDepartments.showList, true);
365+ compare(dashNavigation.showList, true);
367− mouseClick(dashDepartments, 0, 0);
366+ mouseClick(dashNavigation, 0, 0);
368− compare(dashDepartments.showList, false);
367+ compare(dashNavigation.showList, false);
369−
368+
370− mouseClick(dashDepartments, 0, 0);
369+ mouseClick(dashNavigation, 0, 0);
371− compare(dashDepartments.showList, true);
370+ compare(dashNavigation.showList, true);
372− tryCompare(departmentListView.currentItem.department, "loaded", true);
371+ tryCompare(navigationListView.currentItem.navigation, "loaded", true);
373− department = findChild(dashDepartments, "department0child2");
372+ navigation = findChild(dashNavigation, "navigation0child2");
374− mouseClick(department, 0, 0);
373+ mouseClick(navigation, 0, 0);
375− compare(dashDepartments.showList, true);
374+ compare(dashNavigation.showList, true);
376− departmentList1 = findChild(dashDepartments, "department1");
375+ navigationList1 = findChild(dashNavigation, "navigation1");
377− compare(departmentList1.department.loaded, false);
376+ compare(navigationList1.navigation.loaded, false);
378− tryCompare(dashDepartments.currentDepartment, "departmentId", "middle2");
377+ tryCompare(dashNavigation.currentNavigation, "navigationId", "middle2");
379− allButton = findChild(departmentList1, "allButton");
378+ allButton = findChild(navigationList1, "allButton");
380− tryCompare(dashDepartments.currentDepartment, "departmentId", "middle2");
379+ tryCompare(dashNavigation.currentNavigation, "navigationId", "middle2");
381 mouseClick(allButton, 0, 0);
380 mouseClick(allButton, 0, 0);
382− tryCompare(dashDepartments.currentDepartment, "departmentId", "middle2");
381+ tryCompare(dashNavigation.currentNavigation, "navigationId", "middle2");
383 }
382 }
384 }
383 }
385}
384}
tests/qmltests/Dash/tst_GenericScopeView.qml+15−11
@@ -61,8 +61,8 @@ Item {
61 property Item header: findChild(genericScopeView, "scopePageHeader")
61 property Item header: findChild(genericScopeView, "scopePageHeader")
62
62
63 function init() {
63 function init() {
64− genericScopeView.scope = scopes.getScope(1)
64+ genericScopeView.scope = scopes.getScope(2);
65− shell.width = units.gu(120)
65+ shell.width = units.gu(120);
66 genericScopeView.categoryView.positionAtBeginning();
66 genericScopeView.categoryView.positionAtBeginning();
67 waitForRendering(genericScopeView.categoryView);
67 waitForRendering(genericScopeView.categoryView);
68 }
68 }
@@ -88,13 +88,13 @@ Item {
88
88
89 function test_showDash() {
89 function test_showDash() {
90 testCase.previewListView.open = true;
90 testCase.previewListView.open = true;
91− scopes.getScope(1).showDash();
91+ genericScopeView.scope.showDash();
92 tryCompare(testCase.previewListView, "open", false);
92 tryCompare(testCase.previewListView, "open", false);
93 }
93 }
94
94
95 function test_hideDash() {
95 function test_hideDash() {
96 testCase.previewListView.open = true;
96 testCase.previewListView.open = true;
97− scopes.getScope(1).hideDash();
97+ genericScopeView.scope.hideDash();
98 tryCompare(testCase.previewListView, "open", false);
98 tryCompare(testCase.previewListView, "open", false);
99 }
99 }
100
100
@@ -111,8 +111,9 @@ Item {
111
111
112 function test_changeScope() {
112 function test_changeScope() {
113 genericScopeView.scope.searchQuery = "test"
113 genericScopeView.scope.searchQuery = "test"
114− genericScopeView.scope = scopes.getScope(2)
114+ var originalScopeId = genericScopeView.scope.id;
115− genericScopeView.scope = scopes.getScope(1)
115+ genericScopeView.scope = scopes.getScope(originalScopeId + 1)
116+ genericScopeView.scope = scopes.getScope(originalScopeId)
116 tryCompare(genericScopeView.scope, "searchQuery", "test")
117 tryCompare(genericScopeView.scope, "searchQuery", "test")
117 }
118 }
118
119
@@ -129,8 +130,9 @@ Item {
129 var initialHeight = category.height;
130 var initialHeight = category.height;
130 mouseClick(seeAll, seeAll.width / 2, seeAll.height / 2);
131 mouseClick(seeAll, seeAll.width / 2, seeAll.height / 2);
131 verify(category.expanded);
132 verify(category.expanded);
132− tryCompareFunction(function() { return category.height > initialHeight; }, true);
133+ tryCompare(category, "height", category.item.expandedHeight + seeAll.height);
133
134
135+ waitForRendering(seeAll);
134 mouseClick(seeAll, seeAll.width / 2, seeAll.height / 2);
136 mouseClick(seeAll, seeAll.width / 2, seeAll.height / 2);
135 verify(!category.expanded);
137 verify(!category.expanded);
136 }
138 }
@@ -197,6 +199,8 @@ Item {
197 openPreview(4, 0);
199 openPreview(4, 0);
198
200
199 compare(testCase.previewListView.count, 12, "There should only be 12 items in preview.");
201 compare(testCase.previewListView.count, 12, "There should only be 12 items in preview.");
202+
203+ closePreview();
200 }
204 }
201
205
202 function test_narrow_delegate_ranges_expand() {
206 function test_narrow_delegate_ranges_expand() {
@@ -231,7 +235,7 @@ Item {
231 }
235 }
232
236
233 function test_single_category_expansion() {
237 function test_single_category_expansion() {
234− genericScopeView.scope = scopes.getScope(4);
238+ genericScopeView.scope = scopes.getScope(3);
235
239
236 tryCompareFunction(function() { return findChild(genericScopeView, "dashCategory0") != undefined; }, true);
240 tryCompareFunction(function() { return findChild(genericScopeView, "dashCategory0") != undefined; }, true);
237 var category = findChild(genericScopeView, "dashCategory0")
241 var category = findChild(genericScopeView, "dashCategory0")
@@ -319,7 +323,7 @@ Item {
319 units.gu(2),
323 units.gu(2),
320 testCase.previewListView.height / 2);
324 testCase.previewListView.height / 2);
321 tryCompare(previewListViewList, "moving", false);
325 tryCompare(previewListViewList, "moving", false);
322− tryCompare(testCase.previewListView.currentItem, "objectName", "previewItem" + i);
326+ tryCompare(testCase.previewListView.currentItem, "objectName", "preview" + i);
323
327
324 }
328 }
325 closePreview();
329 closePreview();
@@ -328,8 +332,8 @@ Item {
328 function test_header_style_data() {
332 function test_header_style_data() {
329 return [
333 return [
330 { tag: "Default", index: 0, foreground: "grey", background: "", logo: "" },
334 { tag: "Default", index: 0, foreground: "grey", background: "", logo: "" },
331− { tag: "Foreground", index: 2, foreground: "yellow", background: "", logo: "" },
335+ { tag: "Foreground", index: 1, foreground: "yellow", background: "", logo: "" },
332− { tag: "Logo+Background", index: 3, foreground: "grey", background: "gradient:///lightgrey/grey",
336+ { tag: "Logo+Background", index: 2, foreground: "grey", background: "gradient:///lightgrey/grey",
333 logo: Qt.resolvedUrl("../Components/tst_PageHeader/logo-ubuntu-orange.svg") },
337 logo: Qt.resolvedUrl("../Components/tst_PageHeader/logo-ubuntu-orange.svg") },
334 ];
338 ];
335 }
339 }
tests/qmltests/Panel/Indicators/tst_MenuItemFactory.qml+47
@@ -112,6 +112,7 @@ Item {
112
112
113 { tag: 'wifisection', type: "unity.widgets.systemsettings.tablet.wifisection", objectName: "wifiSection" },
113 { tag: 'wifisection', type: "unity.widgets.systemsettings.tablet.wifisection", objectName: "wifiSection" },
114 { tag: 'accesspoint', type: "unity.widgets.systemsettings.tablet.accesspoint", objectName: "accessPoint" },
114 { tag: 'accesspoint', type: "unity.widgets.systemsettings.tablet.accesspoint", objectName: "accessPoint" },
115+ { tag: 'modeminfoitem', type: "com.canonical.indicator.network.modeminfoitem", objectName: "modemInfoItem" },
115
116
116 { tag: 'unknown', type: "", objectName: "standardMenu"}
117 { tag: 'unknown', type: "", objectName: "standardMenu"}
117 ];
118 ];
@@ -542,6 +543,52 @@ Item {
542 compare(loader.item.enabled, data.enabled, "Enabled does not match data");
543 compare(loader.item.enabled, data.enabled, "Enabled does not match data");
543 }
544 }
544
545
546+ function test_create_modemInfoItem_data() {
547+ // ModemInfoItem gets all it's data through the actions.
548+ return [
549+ {
550+ label: "",
551+ enabled: true,
552+ checked: false,
553+ statusLabelAction: "action::statusLabel",
554+ statusIconAction: "action::statusIcon",
555+ connectivityIconAction: "action::connectivityIcon",
556+ simIdentifierLabelAction: "action::simIdentifierLabel",
557+ roamingAction: "action::roaming",
558+ unlockAction: "action::unlock"
559+ }
560+ ];
561+ }
562+
563+ function test_create_modemInfoItem(data) {
564+ menuData.type = "com.canonical.indicator.network.modeminfoitem";
565+ menuData.label = data.label;
566+ menuData.sensitive = data.enabled;
567+ menuData.isToggled = data.checked;
568+ menuData.ext = {
569+ 'xCanonicalModemStatusLabelAction': data.statusLabelAction,
570+ 'xCanonicalModemStatusIconAction': data.statusIconAction,
571+ 'xCanonicalModemConnectivityIconAction': data.connectivityIconAction,
572+ 'xCanonicalModemSimIdentifierLabelAction': data.simIdentifierLabelAction,
573+ 'xCanonicalModemRoamingAction': data.roamingAction,
574+ 'xCanonicalModemLockedAction': data.unlockAction,
575+ };
576+
577+ loader.data = menuData;
578+ loader.sourceComponent = factory.load(menuData);
579+ tryCompareFunction(function() { return loader.item != undefined; }, true);
580+ compare(loader.item.objectName, "modemInfoItem", "Should have created a modem info item.");
581+ compare(loader.item.text, data.label, "Label does not match data");
582+
583+ compare(loader.item.statusLabelAction.name, data.statusLabelAction, "StatusLabel action incorrect");
584+ compare(loader.item.statusIconAction.name, data.statusIconAction, "StatusIcon action incorrect");
585+ compare(loader.item.connectivityIconAction.name, data.connectivityIconAction, "ConnectivityIcon action incorrect");
586+ compare(loader.item.simIdentifierLabelAction.name, data.simIdentifierLabelAction, " action incorrect");
587+ compare(loader.item.roamingAction.name, data.roamingAction, "Roaming action incorrect");
588+ compare(loader.item.unlockAction.name, data.unlockAction, "Unlock action incorrect");
589+ compare(loader.item.enabled, data.enabled, "Enabled does not match data");
590+ }
591+
545 function test_create_messageItem() {
592 function test_create_messageItem() {
546 menuData.type = "com.canonical.indicator.messages.messageitem";
593 menuData.type = "com.canonical.indicator.messages.messageitem";
547
594