on xenial help sign in
Merge
commit5009a76c33ebaf52008d7caac8fe1f7234774a0c authorAlbert Astals <albert.astals@canonical.com> dateThu 7 Aug 2014, 17:33 (12 years ago) parentb250d96f9129df
78 files changed+1574−809
cmake/modules/QmlTest.cmake+2−2 debian/changelog+58 debian/control+2−2 plugins/Dash/CardCreator.js+28−13 plugins/Dash/ScopeStyle.qml+12−9 po/es.po+5−5 po/eu.po+7−6 po/hu.po+72−36 po/ja.po+11−11 po/sl.po+71−35 qml/Components/EdgeDemo.qml+15−15 qml/Components/PageHeader.qml+25−16 qml/Components/SeeMore.qml−70 qml/Components/graphics/pagination_dot_off@30.png qml/Components/graphics/pagination_dot_on@30.png qml/Dash/CardTool.qml+1−1 qml/Dash/Dash.qml+83−13 qml/Dash/DashApplication.qml+7 qml/Dash/DashContent.qml+7−4 qml/Dash/DashDepartments.qml → qml/Dash/DashNavigation.qml+50−43 qml/Dash/DashDepartmentsList.qml → qml/Dash/DashNavigationList.qml+14−18 qml/Dash/GenericScopeView.qml+13−12 qml/Dash/PreviewListView.qml+23−27 qml/Dash/Previews/PreviewExpandable.qml+101 qml/Dash/Previews/PreviewImageGallery.qml+1 qml/Dash/Previews/PreviewTextSummary.qml+3−16 qml/Dash/Previews/PreviewWidget.qml+3 qml/Dash/Previews/PreviewWidgetFactory.qml+5 qml/Dash/ScopesOverview.qml+10−4 qml/Greeter/Greeter.qml+1−1 qml/Notifications/NotificationMenuItemFactory.qml+3 qml/Panel/Indicators/MenuItemFactory.qml+74 qml/Panel/Indicators/ModemInfoItem.qml+111 qml/Panel/Indicators/RoamingIndication.qml+40 qml/ScopeTool.qml+2−11 qml/Shell.qml+4−4 run_on_device.sh+1−3 src/Dash/main.cpp+5−5 tests/autopilot/unity8/shell/emulators/dash.py+1−1 tests/mocks/Unity/CMakeLists.txt+3−3 tests/mocks/Unity/Unity.qmltypes+79−27 tests/mocks/Unity/fake_department.cpp → tests/mocks/Unity/fake_navigation.cpp+32−40 tests/mocks/Unity/fake_department.h → tests/mocks/Unity/fake_navigation.h+13−13 tests/mocks/Unity/fake_scope.cpp+64−17 tests/mocks/Unity/fake_scope.h+16−8 tests/mocks/Unity/fake_scopes.cpp+29−18 tests/mocks/Unity/fake_scopes.h+6−3 tests/mocks/Unity/fake_scopesoverview.cpp+4−3 tests/mocks/Unity/fake_scopesoverview.h+2−2 tests/mocks/Unity/fake_unity_plugin.cpp+2−2 tests/plugins/Dash/cardcreator/1.res+12−10 tests/plugins/Dash/cardcreator/1.tst+1−1 tests/plugins/Dash/cardcreator/2.res+8 tests/plugins/Dash/cardcreator/2.tst+1−1 tests/plugins/Dash/cardcreator/3.res+12−10 tests/plugins/Dash/cardcreator/3.tst+1−1 tests/plugins/Dash/cardcreator/4.res+8 tests/plugins/Dash/cardcreator/4.tst+1−1 tests/plugins/Dash/cardcreator/5.res+21−17 tests/plugins/Dash/cardcreator/5.tst+1−1 tests/plugins/Dash/cardcreator/6.res+10−8 tests/plugins/Dash/cardcreator/6.tst+1−1 tests/plugins/Dash/cardcreator/7.res+9−1 tests/plugins/Dash/cardcreator/7.tst+1−1 tests/plugins/Dash/cardcreatortest.cpp+13−4 tests/plugins/Dash/tst_ScopeStyle.qml+14−7 tests/qmltests/CMakeLists.txt+1−1 tests/qmltests/Components/tst_PageHeader.qml+21−23 tests/qmltests/Components/tst_SeeMore.qml−52 tests/qmltests/Dash/CardHelpers.js+4−3 tests/qmltests/Dash/Previews/tst_PreviewExpandable.qml+97 tests/qmltests/Dash/Previews/tst_PreviewTextSummary.qml+4−18 tests/qmltests/Dash/Previews/tst_PreviewWidgetFactory.qml+1 tests/qmltests/Dash/tst_Card.qml+15−3 tests/qmltests/Dash/tst_Dash.qml+35−15 tests/qmltests/Dash/tst_DashContent.qml+99−100 tests/qmltests/Dash/tst_GenericScopeView.qml+15−11 tests/qmltests/Panel/Indicators/tst_MenuItemFactory.qml+47
cmake/modules/QmlTest.cmake+2−2
@@ -135,7 +135,7 @@ macro(add_binary_qml_test CLASS_NAME LD_PATH DEPS)
135135 set(testCommand
136136 LD_LIBRARY_PATH=${LD_PATH}
137137 ${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
139139 -o -,txt)
140140
141141 add_qmltest_target(test${CLASS_NAME} "${testCommand}" FALSE TRUE)
@@ -151,7 +151,7 @@ macro(add_binary_qml_test CLASS_NAME LD_PATH DEPS)
151151 LD_LIBRARY_PATH=${LD_PATH}
152152 xvfb-run --server-args "-screen 0 1024x768x24" --auto-servernum
153153 ${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
155155 -o -,txt)
156156
157157 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+
159unity8 (8.00+14.10.20140805-0ubuntu1) utopic; urgency=low
260
361 [ Michael Zanetti ]
debian/control+2−2
@@ -24,7 +24,7 @@ Build-Depends: cmake,
2424 libpulse-dev,
2525 libqmenumodel-dev (>= 0.2.8),
2626 libqt5xmlpatterns5-dev,
27− libunity-api-dev (>= 7.87),
27+ libunity-api-dev (>= 7.88),
2828 libusermetricsoutput1-dev,
2929 libxcb1-dev,
3030 pkg-config,
@@ -112,7 +112,7 @@ Depends: qtdeclarative5-ubuntu-thumbnailer0.1 | ubuntu-thumbnailer-impl,
112112 unity-application-impl-2,
113113 unity-notifications-impl-3,
114114 unity-plugin-scopes | unity-scopes-impl,
115− unity-scopes-impl-3,
115+ unity-scopes-impl-4,
116116 unity8-fake-env | unity-application-impl,
117117 ${misc:Depends},
118118Breaks: unity8 (<< 7.86),
plugins/Dash/CardCreator.js+28−13
@@ -71,19 +71,14 @@ var kArtShapeHolderCode = 'Item { \n\
7171 visible: image.status == Image.Ready; \n\
7272 readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1; \n\
7373 readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1; \n\
74− readonly property bool aspectSmallerThanImageAspect: aspect < image.aspect; \n\
7574 Component.onCompleted: { updateWidthHeightBindings(); if (artShapeBorderSource !== undefined) borderSource = artShapeBorderSource; } \n\
76− onAspectSmallerThanImageAspectChanged: updateWidthHeightBindings(); \n\
7775 Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); } \n\
7876 function updateWidthHeightBindings() { \n\
7977 if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) { \n\
8078 width = root.fixedArtShapeSize.width; \n\
8179 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\
8580 } 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\
8782 height = Qt.binding(function() { return !visible ? 0 : image.height }); \n\
8883 } \n\
8984 } \n\
@@ -92,8 +87,7 @@ var kArtShapeHolderCode = 'Item { \n\
9287 source: cardData && cardData["art"] || ""; \n\
9388 cache: true; \n\
9489 asynchronous: root.asynchronous; \n\
95− fillMode: components && components["art"]["fill-mode"] === "fit" ? Image.PreserveAspectFit: Image.PreserveAspectCrop; \n\
96− readonly property real aspect: implicitWidth / implicitHeight; \n\
90+ fillMode: Image.PreserveAspectCrop; \n\
9791 width: %2; \n\
9892 height: %3; \n\
9993 } \n\
@@ -114,7 +108,8 @@ var kOverlayLoaderCode = 'Loader { \n\
114108 sourceComponent: ShaderEffect { \n\
115109 id: overlay; \n\
116110 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\
118113 property var source: ShaderEffectSource { \n\
119114 id: shaderSource; \n\
120115 sourceItem: artShapeLoader.item; \n\
@@ -135,9 +130,10 @@ var kOverlayLoaderCode = 'Loader { \n\
135130 varying highp vec2 coord; \n\
136131 uniform sampler2D source; \n\
137132 uniform lowp float qt_Opacity; \n\
133+ uniform highp vec4 overlayColor; \n\
138134 void main() { \n\
139135 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\
141137 }"; \n\
142138 } \n\
143139 }\n';
@@ -257,6 +253,16 @@ var kTitleLabelCode = 'Label { \n\
257253 horizontalAlignment: root.headerAlignment; \n\
258254 }\n';
259255
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+
260266// %1 is used as anchors of subtitleLabel
261267// %2 is used as color of subtitleLabel
262268var kSubtitleLabelCode = 'Label { \n\
@@ -279,7 +285,7 @@ var kAttributesRowCode = 'CardAttributes { \n\
279285 objectName: "attributesRow"; \n\
280286 anchors { %1 } \n\
281287 color: %2; \n\
282− model: cardData && cardData["attributes"] || undefined; \n\
288+ model: cardData["attributes"]; \n\
283289 }\n';
284290
285291// %1 is used as top anchor of summary
@@ -447,7 +453,7 @@ function cardString(template, components) {
447453 if (hasTitle) {
448454 var color;
449455 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")';
451457 } else if (hasSummary) {
452458 color = 'summary.color';
453459 } else if (hasBackground) {
@@ -569,6 +575,16 @@ function cardString(template, components) {
569575 code += kSummaryLabelCode.arg(summaryTopAnchor).arg(summaryTopMargin).arg(color);
570576 }
571577
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+
572588 if (hasSummary) {
573589 code += 'implicitHeight: summary.y + summary.height + (summary.text ? units.gu(1) : 0);\n';
574590 } else if (hasHeaderRow) {
@@ -593,7 +609,6 @@ function cardString(template, components) {
593609function createCardComponent(parent, template, components) {
594610 var imports = 'import QtQuick 2.2; \n\
595611 import Ubuntu.Components 0.1; \n\
596− import Ubuntu.Thumbnailer 0.1;\n\
597612 import Dash 0.1;\n';
598613 var card = cardString(template, components);
599614 var code = imports + 'Component {\n' + card + '}\n';
plugins/Dash/ScopeStyle.qml+12−9
@@ -38,15 +38,21 @@ QtObject {
3838 /// Color used for text and symbolic icons
3939 readonly property color foreground: "foreground-color" in style ? style["foreground-color"] : d.defaultDark
4040
41+ /// Luminance of the foreground color
42+ readonly property real foregroundLuminance: foreground ? luminance(foreground) : d.defaultForegroundLuminance
43+
4144 /// Color used for the overall background
4245 readonly property color background: "background-color" in style ? style["background-color"] : "transparent"
4346
47+ /// Luminance of the foreground color
48+ readonly property real backgroundLuminance: background ? luminance(background) : d.defaultBackgroundLuminance
49+
4450 /*! \brief Luminance threshold for switching between fore and background color
4551
4652 \note If background colour is not fully opaque, the defaultLightLuminance it's taken into account instead of it.
4753 */
48− readonly property real threshold: background.a !== 1.0 ? (d.foregroundLuminance + d.defaultLightLuminance) / 2
49− : (d.foregroundLuminance + d.backgroundLuminance) / 2
54+ readonly property real threshold: background.a !== 1.0 ? (foregroundLuminance + d.defaultLightLuminance) / 2
55+ : (foregroundLuminance + backgroundLuminance) / 2
5056
5157 /*! \brief The lighter of foreground and background colors
5258
@@ -54,8 +60,8 @@ QtObject {
5460 and defaults to the theme-provided light color.
5561 */
5662 readonly property color light: {
57− if (background.a !== 1.0) return d.foregroundLuminance > d.defaultLightLuminance ? foreground : d.defaultLight;
58− return d.foregroundLuminance > d.backgroundLuminance ? foreground : background;
63+ if (background.a !== 1.0) return foregroundLuminance > d.defaultLightLuminance ? foreground : d.defaultLight;
64+ return foregroundLuminance > backgroundLuminance ? foreground : background;
5965 }
6066
6167 /*! \brief The darker of foreground and background colors
@@ -64,8 +70,8 @@ QtObject {
6470 and defaults to the theme-provided dark color.
6571 */
6672 readonly property color dark: {
67− if (background.a !== 1.0) return d.foregroundLuminance < d.defaultDarkLuminance ? foreground : d.defaultDark;
68− return d.foregroundLuminance < d.backgroundLuminance ? foreground : background;
73+ if (background.a !== 1.0) return foregroundLuminance < d.defaultDarkLuminance ? foreground : d.defaultDark;
74+ return foregroundLuminance < backgroundLuminance ? foreground : background;
6975 }
7076
7177 /// Source of the logo image for the header
@@ -79,9 +85,6 @@ QtObject {
7985
8086 //! @cond
8187 property var d: QtObject {
82− readonly property real foregroundLuminance: luminance(foreground)
83− readonly property real backgroundLuminance: luminance(background)
84−
8588 // FIXME: should be taken from the theme
8689 readonly property color defaultLight: "white"
8790 readonly property color defaultDark: "grey"
po/es.po+5−5
@@ -8,14 +8,14 @@ msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2014-07-11 14:59+0200\n"
11−"PO-Revision-Date: 2014-07-26 06:22+0000\n"
12−"Last-Translator: Paco Molinero <paco@byasl.com>\n"
11+"PO-Revision-Date: 2014-08-06 15:24+0000\n"
12+"Last-Translator: Leo Arias <leo.arias@canonical.com>\n"
1313"Language-Team: Spanish <es@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2014-07-27 06:35+0000\n"
18−"X-Generator: Launchpad (build 17131)\n"
17+"X-Launchpad-Export-Date: 2014-08-07 06:27+0000\n"
18+"X-Generator: Launchpad (build 17147)\n"
1919
2020#: plugins/Unity/Launcher/launcheritem.cpp:43
2121#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -116,7 +116,7 @@ msgstr "Recientes"
116116
117117#: qml/Dash/GenericScopeView.qml:330
118118msgid "See all"
119−msgstr "Ver todo"
119+msgstr "Ver todas"
120120
121121#: qml/Dash/Previews/PreviewActionCombo.qml:34
122122msgid "More..."
po/eu.po+7−6
@@ -8,14 +8,14 @@ msgstr ""
88"Project-Id-Version: unity8\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"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"
1212"Last-Translator: Ibai Oihanguren Sala <Unknown>\n"
1313"Language-Team: Basque <eu@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2014-07-26 07:16+0000\n"
18−"X-Generator: Launchpad (build 17131)\n"
17+"X-Launchpad-Export-Date: 2014-08-07 06:27+0000\n"
18+"X-Generator: Launchpad (build 17147)\n"
1919
2020#: plugins/Unity/Launcher/launcheritem.cpp:43
2121#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -36,7 +36,8 @@ msgstr "Eskuineko ertza"
3636
3737#: qml/Components/EdgeDemo.qml:114
3838msgid "Try swiping from the right edge to unlock the phone"
39−msgstr "Probatu eskuineko ertzetik arrastatzen telefonoa desblokeatzeko"
39+msgstr ""
40+"Pasatu hatza eskuineko ertzetik ezkerrerantz telefonoa desblokeatzeko"
4041
4142#: qml/Components/EdgeDemo.qml:145
4243msgid "Top edge"
@@ -44,7 +45,7 @@ msgstr "Goiko ertza"
4445
4546#: qml/Components/EdgeDemo.qml:146
4647msgid "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"
4849
4950#: qml/Components/EdgeDemo.qml:171
5051msgid "Close"
@@ -52,7 +53,7 @@ msgstr "Itxi"
5253
5354#: qml/Components/EdgeDemo.qml:172
5455msgid "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"
5657
5758#: qml/Components/EdgeDemo.qml:199
5859msgid "Left edge"
po/hu.po+72−36
@@ -6,15 +6,16 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-07-11 14:59+0200\n"
11−"PO-Revision-Date: 2014-08-04 09:10+0000\n"
9+"Report-Msgid-Bugs-To: \n"
10+"POT-Creation-Date: 2014-08-05 19:54+0200\n"
11+"PO-Revision-Date: 2014-08-06 07:41+0000\n"
1212"Last-Translator: Richard Somlói <ricsipontaz@gmail.com>\n"
1313"Language-Team: Hungarian <hu@li.org>\n"
14+"Language: hu\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"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"
1819"X-Generator: Launchpad (build 17147)\n"
1920
2021#: plugins/Unity/Launcher/launcheritem.cpp:43
@@ -26,72 +27,88 @@ msgstr "Indító rögzítése"
2627msgid "Unpin shortcut"
2728msgstr "Indító feloldása"
2829
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+
2946#: qml/Components/EdgeDemoOverlay.qml:151
3047msgid "Skip intro"
3148msgstr "A bemutató kihagyása"
3249
33−#: qml/Components/EdgeDemo.qml:113
50+#: qml/Components/EdgeDemo.qml:112
3451msgid "Right edge"
3552msgstr "Jobb szél"
3653
37−#: qml/Components/EdgeDemo.qml:114
54+#: qml/Components/EdgeDemo.qml:113
3855msgid "Try swiping from the right edge to unlock the phone"
3956msgstr "A telefon feloldásához csúsztassa ujját a jobb szélről"
4057
41−#: qml/Components/EdgeDemo.qml:145
58+#: qml/Components/EdgeDemo.qml:144
4259msgid "Top edge"
4360msgstr "Felső szél"
4461
45−#: qml/Components/EdgeDemo.qml:146
62+#: qml/Components/EdgeDemo.qml:145
4663msgid "Try swiping from the top edge to access the indicators"
4764msgstr "Az állapotmenük eléréséhez csúsztassa ujját a felső szélről"
4865
49−#: qml/Components/EdgeDemo.qml:171
66+#: qml/Components/EdgeDemo.qml:170
5067msgid "Close"
5168msgstr "Bezárás"
5269
53−#: qml/Components/EdgeDemo.qml:172
70+#: qml/Components/EdgeDemo.qml:171
5471msgid "Swipe up again to close the settings screen"
5572msgstr "A beállítások bezárásához csúsztassa ujját újra felfelé"
5673
57−#: qml/Components/EdgeDemo.qml:199
74+#: qml/Components/EdgeDemo.qml:198
5875msgid "Left edge"
5976msgstr "Bal szél"
6077
61−#: qml/Components/EdgeDemo.qml:200
78+#: qml/Components/EdgeDemo.qml:199
6279msgid "Swipe from the left to reveal the launcher for quick access to apps"
6380msgstr ""
6481"Csúsztassa ujját a bal szélről az indítón található alkalmazások gyors "
6582"eléréséhez"
6683
67−#: qml/Components/EdgeDemo.qml:227
84+#: qml/Components/EdgeDemo.qml:226
6885msgid "Well done"
6986msgstr "Rendben"
7087
71−#: qml/Components/EdgeDemo.qml:228
88+#: qml/Components/EdgeDemo.qml:227
7289msgid ""
7390"You have now mastered the edge gestures and can start using the "
7491"phone<br><br>Tap on the screen to start"
7592msgstr ""
76−"Elsajátította a gesztusokat, és megkezdheti a telefon "
77−"használatát.<br><br>Koppintson a képernyőre a kezdéshez."
93+"Elsajátította a gesztusokat, és megkezdheti a telefon használatát."
94+"<br><br>Koppintson a képernyőre a kezdéshez."
7895
79−#: qml/Components/Lockscreen.qml:214
96+#: qml/Components/Lockscreen.qml:220
8097msgid "Emergency Call"
8198msgstr "Vészhívás"
8299
83−#: qml/Components/Lockscreen.qml:231
100+#: qml/Components/Lockscreen.qml:243
84101msgid "OK"
85102msgstr "Ok"
86103
87−#: qml/Components/PassphraseLockscreen.qml:60
104+#: qml/Components/PassphraseLockscreen.qml:62
88105#, qt-format
89106msgid "Hello %1"
90107msgstr "Üdv %1"
91108
92−#: qml/Components/PassphraseLockscreen.qml:60
109+#: qml/Components/PassphraseLockscreen.qml:62
93110msgid "Hello"
94−msgstr "Üdv"
111+msgstr "Üdvözöljük"
95112
96113#: qml/Components/PinLockscreen.qml:198
97114msgid "CANCEL"
@@ -105,15 +122,11 @@ msgstr "KÉSZ"
105122msgid "See more"
106123msgstr "Több"
107124
108−#: qml/Components/SeeMore.qml:58 qml/Dash/GenericScopeView.qml:330
125+#: qml/Components/SeeMore.qml:58 qml/Dash/GenericScopeView.qml:354
109126msgid "See less"
110127msgstr "Kevesebb"
111128
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
117130msgid "See all"
118131msgstr "Összes megtekintése"
119132
@@ -137,6 +150,26 @@ msgstr "Értékelés hozzáadása"
137150msgid "Send"
138151msgstr "Küldés"
139152
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+
140173#: qml/Greeter/Greeter.qml:157
141174msgid "Swipe to unlock"
142175msgstr "Csúsztasson a feloldáshoz"
@@ -161,11 +194,11 @@ msgstr "Most beszéljen…"
161194msgid "Speaking..."
162195msgstr "Beszéd…"
163196
164−#: qml/Notifications/NotificationMenuItemFactory.qml:91
197+#: qml/Notifications/NotificationMenuItemFactory.qml:97
165198msgid "Show password"
166199msgstr "Jelszó megjelenítése"
167200
168−#: qml/Notifications/NotificationMenuItemFactory.qml:103
201+#: qml/Notifications/NotificationMenuItemFactory.qml:112
169202msgid "Please enter SIM PIN"
170203msgstr "Adja meg a SIM PIN kódját"
171204
@@ -177,27 +210,27 @@ msgstr "Érintse meg, hogy visszatérjen a híváshoz..."
177210msgid "Conference"
178211msgstr "Konferencia"
179212
180−#: qml/Panel/Indicators/MenuItemFactory.qml:583
213+#: qml/Panel/Indicators/MenuItemFactory.qml:577
181214msgid "In queue…"
182215msgstr "Sorban…"
183216
184−#: qml/Panel/Indicators/MenuItemFactory.qml:587
217+#: qml/Panel/Indicators/MenuItemFactory.qml:581
185218msgid "Downloading"
186219msgstr "Letöltés"
187220
188−#: qml/Panel/Indicators/MenuItemFactory.qml:589
221+#: qml/Panel/Indicators/MenuItemFactory.qml:583
189222msgid "Paused, tap to resume"
190223msgstr "Szüneteltetve, koppintson a folytatáshoz"
191224
192−#: qml/Panel/Indicators/MenuItemFactory.qml:591
225+#: qml/Panel/Indicators/MenuItemFactory.qml:585
193226msgid "Canceled"
194227msgstr "Megszakítva"
195228
196−#: qml/Panel/Indicators/MenuItemFactory.qml:593
229+#: qml/Panel/Indicators/MenuItemFactory.qml:587
197230msgid "Finished"
198231msgstr "Befejeződött"
199232
200−#: qml/Panel/Indicators/MenuItemFactory.qml:595
233+#: qml/Panel/Indicators/MenuItemFactory.qml:589
201234msgid "Failed, tap to retry"
202235msgstr "Sikertelen, koppintson az újrapróbáláshoz"
203236
@@ -205,7 +238,10 @@ msgstr "Sikertelen, koppintson az újrapróbáláshoz"
205238msgid "Search"
206239msgstr "Keresés"
207240
208−#: qml/Shell.qml:359
241+#: qml/Shell.qml:256
209242#, qt-format
210243msgid "Please enter %1"
211244msgstr "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 ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"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"
1212"Last-Translator: Shushi Kurose <md81bird@hitaki.net>\n"
1313"Language-Team: Japanese <ja@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2014-07-26 07:16+0000\n"
18−"X-Generator: Launchpad (build 17131)\n"
17+"X-Launchpad-Export-Date: 2014-08-07 06:27+0000\n"
18+"X-Generator: Launchpad (build 17147)\n"
1919
2020#: plugins/Unity/Launcher/launcheritem.cpp:43
2121#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -28,7 +28,7 @@ msgstr ""
2828
2929#: qml/Components/EdgeDemoOverlay.qml:151
3030msgid "Skip intro"
31−msgstr ""
31+msgstr "導入ガイドをスキップ"
3232
3333#: qml/Components/EdgeDemo.qml:113
3434msgid "Right edge"
@@ -44,7 +44,7 @@ msgstr "上端"
4444
4545#: qml/Components/EdgeDemo.qml:146
4646msgid "Try swiping from the top edge to access the indicators"
47−msgstr ""
47+msgstr "インジケーターにアクセスするには上端からスワイプしてみてください"
4848
4949#: qml/Components/EdgeDemo.qml:171
5050msgid "Close"
@@ -52,7 +52,7 @@ msgstr "閉じる"
5252
5353#: qml/Components/EdgeDemo.qml:172
5454msgid "Swipe up again to close the settings screen"
55−msgstr ""
55+msgstr "設定画面を閉じるにはもう一度上にスワイプしてください"
5656
5757#: qml/Components/EdgeDemo.qml:199
5858msgid "Left edge"
@@ -60,11 +60,11 @@ msgstr "左端"
6060
6161#: qml/Components/EdgeDemo.qml:200
6262msgid "Swipe from the left to reveal the launcher for quick access to apps"
63−msgstr ""
63+msgstr "アプリに素早くアクセスできるLauncherを表示するには左からスワイプしてください"
6464
6565#: qml/Components/EdgeDemo.qml:227
6666msgid "Well done"
67−msgstr ""
67+msgstr "よくできました!"
6868
6969#: qml/Components/EdgeDemo.qml:228
7070msgid ""
@@ -74,7 +74,7 @@ msgstr ""
7474
7575#: qml/Components/Lockscreen.qml:214
7676msgid "Emergency Call"
77−msgstr ""
77+msgstr "緊急通報"
7878
7979#: qml/Components/Lockscreen.qml:231
8080msgid "OK"
@@ -83,7 +83,7 @@ msgstr ""
8383#: qml/Components/PassphraseLockscreen.qml:60
8484#, qt-format
8585msgid "Hello %1"
86−msgstr ""
86+msgstr "こんにちは %1 さん"
8787
8888#: qml/Components/PassphraseLockscreen.qml:60
8989msgid "Hello"
@@ -127,7 +127,7 @@ msgstr ""
127127
128128#: qml/Dash/Previews/PreviewRatingInput.qml:126
129129msgid "Add a review"
130−msgstr ""
130+msgstr "レビューを追加"
131131
132132#: qml/Dash/Previews/PreviewRatingInput.qml:166
133133msgid "Send"
po/sl.po+71−35
@@ -6,16 +6,17 @@
66msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
9−"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2014-07-11 14:59+0200\n"
11−"PO-Revision-Date: 2014-07-28 12:32+0000\n"
9+"Report-Msgid-Bugs-To: \n"
10+"POT-Creation-Date: 2014-08-05 19:54+0200\n"
11+"PO-Revision-Date: 2014-08-06 06:11+0000\n"
1212"Last-Translator: Damir Jerovšek <Unknown>\n"
1313"Language-Team: Slovenian <sl@li.org>\n"
14+"Language: sl\n"
1415"MIME-Version: 1.0\n"
1516"Content-Type: text/plain; charset=UTF-8\n"
1617"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2014-07-29 06:54+0000\n"
18−"X-Generator: Launchpad (build 17131)\n"
18+"X-Launchpad-Export-Date: 2014-08-07 06:27+0000\n"
19+"X-Generator: Launchpad (build 17147)\n"
1920
2021#: plugins/Unity/Launcher/launcheritem.cpp:43
2122#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -26,49 +27,65 @@ msgstr "Pripni bližnjico"
2627msgid "Unpin shortcut"
2728msgstr "Odpni bližnjico"
2829
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+
2946#: qml/Components/EdgeDemoOverlay.qml:151
3047msgid "Skip intro"
3148msgstr "Preskoči uvod"
3249
33−#: qml/Components/EdgeDemo.qml:113
50+#: qml/Components/EdgeDemo.qml:112
3451msgid "Right edge"
3552msgstr "Desni rob"
3653
37−#: qml/Components/EdgeDemo.qml:114
54+#: qml/Components/EdgeDemo.qml:113
3855msgid "Try swiping from the right edge to unlock the phone"
3956msgstr "Poskusite povleči od desnega roba za odklep telefona"
4057
41−#: qml/Components/EdgeDemo.qml:145
58+#: qml/Components/EdgeDemo.qml:144
4259msgid "Top edge"
4360msgstr "Zgornji rob"
4461
45−#: qml/Components/EdgeDemo.qml:146
62+#: qml/Components/EdgeDemo.qml:145
4663msgid "Try swiping from the top edge to access the indicators"
4764msgstr "Poskusite povleči od zgornjega roba za dostop do kazalnikov"
4865
49−#: qml/Components/EdgeDemo.qml:171
66+#: qml/Components/EdgeDemo.qml:170
5067msgid "Close"
5168msgstr "Zapri"
5269
53−#: qml/Components/EdgeDemo.qml:172
70+#: qml/Components/EdgeDemo.qml:171
5471msgid "Swipe up again to close the settings screen"
5572msgstr "Povlecite ponovno navzgor za zaprtje zaslona z nastavitvami"
5673
57−#: qml/Components/EdgeDemo.qml:199
74+#: qml/Components/EdgeDemo.qml:198
5875msgid "Left edge"
5976msgstr "Levi rob"
6077
61−#: qml/Components/EdgeDemo.qml:200
78+#: qml/Components/EdgeDemo.qml:199
6279msgid "Swipe from the left to reveal the launcher for quick access to apps"
6380msgstr ""
6481"Poskusite povleči od leve za razkritje zaganjalnika za hiter dostop do "
6582"programov"
6683
67−#: qml/Components/EdgeDemo.qml:227
84+#: qml/Components/EdgeDemo.qml:226
6885msgid "Well done"
6986msgstr "Odlično"
7087
71−#: qml/Components/EdgeDemo.qml:228
88+#: qml/Components/EdgeDemo.qml:227
7289msgid ""
7390"You have now mastered the edge gestures and can start using the "
7491"phone<br><br>Tap on the screen to start"
@@ -76,20 +93,20 @@ msgstr ""
7693"Sedaj, ko ste osvojili poteze robov, lahko začnete uporabljati "
7794"telefon<br><br>Tapnite na zaslon za začetek"
7895
79−#: qml/Components/Lockscreen.qml:214
96+#: qml/Components/Lockscreen.qml:220
8097msgid "Emergency Call"
8198msgstr "Klic v sili"
8299
83−#: qml/Components/Lockscreen.qml:231
100+#: qml/Components/Lockscreen.qml:243
84101msgid "OK"
85102msgstr "V REDU"
86103
87−#: qml/Components/PassphraseLockscreen.qml:60
104+#: qml/Components/PassphraseLockscreen.qml:62
88105#, qt-format
89106msgid "Hello %1"
90107msgstr "Pozdravljeni, %1"
91108
92−#: qml/Components/PassphraseLockscreen.qml:60
109+#: qml/Components/PassphraseLockscreen.qml:62
93110msgid "Hello"
94111msgstr "Pozdravljeni"
95112
@@ -105,17 +122,13 @@ msgstr "KONČANO"
105122msgid "See more"
106123msgstr "Pokaži več"
107124
108−#: qml/Components/SeeMore.qml:58 qml/Dash/GenericScopeView.qml:330
125+#: qml/Components/SeeMore.qml:58 qml/Dash/GenericScopeView.qml:354
109126msgid "See less"
110127msgstr "Pokaži manj"
111128
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
117130msgid "See all"
118−msgstr ""
131+msgstr "Ogled vsega"
119132
120133#: qml/Dash/Previews/PreviewActionCombo.qml:34
121134msgid "More..."
@@ -137,6 +150,26 @@ msgstr "Dodaj oceno"
137150msgid "Send"
138151msgstr "Pošlji"
139152
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+
140173#: qml/Greeter/Greeter.qml:157
141174msgid "Swipe to unlock"
142175msgstr "Podrsajte za odklenitev"
@@ -161,11 +194,11 @@ msgstr "Govorite zdaj ..."
161194msgid "Speaking..."
162195msgstr "Govorjenje ..."
163196
164−#: qml/Notifications/NotificationMenuItemFactory.qml:91
197+#: qml/Notifications/NotificationMenuItemFactory.qml:97
165198msgid "Show password"
166199msgstr "Pokaži geslo"
167200
168−#: qml/Notifications/NotificationMenuItemFactory.qml:103
201+#: qml/Notifications/NotificationMenuItemFactory.qml:112
169202msgid "Please enter SIM PIN"
170203msgstr "Vnesite PIN kartice SIM"
171204
@@ -177,27 +210,27 @@ msgstr "Tapnite za vrnitev v klic ..."
177210msgid "Conference"
178211msgstr "Konferenca"
179212
180−#: qml/Panel/Indicators/MenuItemFactory.qml:583
213+#: qml/Panel/Indicators/MenuItemFactory.qml:577
181214msgid "In queue…"
182215msgstr "V vrsti ..."
183216
184−#: qml/Panel/Indicators/MenuItemFactory.qml:587
217+#: qml/Panel/Indicators/MenuItemFactory.qml:581
185218msgid "Downloading"
186219msgstr "Prejemanje"
187220
188−#: qml/Panel/Indicators/MenuItemFactory.qml:589
221+#: qml/Panel/Indicators/MenuItemFactory.qml:583
189222msgid "Paused, tap to resume"
190223msgstr "Premor, tapnite za nadaljevanje"
191224
192−#: qml/Panel/Indicators/MenuItemFactory.qml:591
225+#: qml/Panel/Indicators/MenuItemFactory.qml:585
193226msgid "Canceled"
194227msgstr "Preklicano"
195228
196−#: qml/Panel/Indicators/MenuItemFactory.qml:593
229+#: qml/Panel/Indicators/MenuItemFactory.qml:587
197230msgid "Finished"
198231msgstr "Končano"
199232
200−#: qml/Panel/Indicators/MenuItemFactory.qml:595
233+#: qml/Panel/Indicators/MenuItemFactory.qml:589
201234msgid "Failed, tap to retry"
202235msgstr "Spodletelo, tapnite za ponovni poskus"
203236
@@ -205,7 +238,10 @@ msgstr "Spodletelo, tapnite za ponovni poskus"
205238msgid "Search"
206239msgstr "Iskanje"
207240
208−#: qml/Shell.qml:359
241+#: qml/Shell.qml:256
209242#, qt-format
210243msgid "Please enter %1"
211244msgstr "Vnesite %1"
245+
246+#~ msgid "Recent"
247+#~ msgstr "Nedavno"
qml/Components/EdgeDemo.qml+15−15
@@ -24,13 +24,13 @@ Item {
2424 property Item greeter
2525 property Item launcher
2626 property Item indicators
27− property Item underlay
27+ property Item stages
2828
2929 property bool launcherEnabled: true
30− property bool dashEnabled: true
30+ property bool stagesEnabled: true
3131 property bool panelEnabled: true
3232 property bool panelContentEnabled: true
33− property bool running: !launcherEnabled || !dashEnabled || !panelEnabled || !panelContentEnabled
33+ property bool running: !launcherEnabled || !stagesEnabled || !panelEnabled || !panelContentEnabled
3434
3535 property bool paused: false
3636
@@ -58,7 +58,7 @@ Item {
5858
5959 function stopDemo() {
6060 launcherEnabled = true
61− dashEnabled = true
61+ stagesEnabled = true
6262 panelEnabled = true
6363 panelContentEnabled = true
6464 if (d.rightEdgeDemo) d.rightEdgeDemo.destroy()
@@ -74,11 +74,11 @@ Item {
7474 }
7575
7676 launcherEnabled = false;
77− dashEnabled = false;
77+ stagesEnabled = false;
7878 panelEnabled = false;
7979 panelContentEnabled = false;
8080
81− // Begin with either greeter or dash, depending on which is visible
81+ // Begin with either greeter or top, depending on which is visible
8282 if (greeter && greeter.shown) {
8383 startRightEdgeDemo()
8484 } else {
@@ -138,12 +138,12 @@ Item {
138138
139139 function startTopEdgeDemo() {
140140 demo.panelEnabled = true;
141− if (demo.dash && demo.underlay) {
142− d.topEdgeDemo = d.overlay.createObject(demo.underlay, {
141+ if (demo.stages) {
142+ d.topEdgeDemo = d.overlay.createObject(demo.stages, {
143143 "edge": "top",
144144 "title": i18n.tr("Top edge"),
145145 "text": i18n.tr("Try swiping from the top edge to access the indicators"),
146− "anchors.fill": demo.underlay,
146+ "anchors.fill": demo.stages,
147147 });
148148 }
149149 if (d.topEdgeDemo) {
@@ -192,12 +192,12 @@ Item {
192192 function startLeftEdgeDemo() {
193193 demo.panelEnabled = false;
194194 demo.launcherEnabled = true;
195− if (demo.underlay) {
196− d.leftEdgeDemo = d.overlay.createObject(demo.underlay, {
195+ if (demo.stages) {
196+ d.leftEdgeDemo = d.overlay.createObject(demo.stages, {
197197 "edge": "left",
198198 "title": i18n.tr("Left edge"),
199199 "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,
201201 });
202202 }
203203 if (d.leftEdgeDemo) {
@@ -220,12 +220,12 @@ Item {
220220
221221 function startFinalEdgeDemo() {
222222 demo.launcherEnabled = false;
223− if (demo.underlay) {
224− d.finalEdgeDemo = d.overlay.createObject(demo.underlay, {
223+ if (demo.stages) {
224+ d.finalEdgeDemo = d.overlay.createObject(demo.stages, {
225225 "edge": "none",
226226 "title": i18n.tr("Well done"),
227227 "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,
229229 "showSkip": false,
230230 });
231231 }
qml/Components/PageHeader.qml+25−16
@@ -33,10 +33,11 @@ Item {
3333 property ListModel searchHistory: SearchHistoryModel
3434 property alias searchQuery: searchTextField.text
3535 property alias searchHint: searchTextField.placeholderText
36− property bool searchInProgress: false
3736 property alias showSignatureLine: bottomBorder.visible
3837
3938 property alias bottomItem: bottomContainer.children
39+ property int paginationCount: 0
40+ property int paginationIndex: -1
4041
4142 // TODO We should use foreground for the icons
4243 // of the toolbar but unfortunately Action does not have
@@ -127,7 +128,7 @@ Item {
127128 Flickable {
128129 id: headerContainer
129130 objectName: "headerContainer"
130− clip: openSearchAnimation.running
131+ clip: contentY < height
131132 anchors { left: parent.left; top: parent.top; right: parent.right }
132133 height: units.gu(6.5)
133134 contentHeight: headersColumn.height
@@ -171,6 +172,7 @@ Item {
171172 property var styledItem: searchHeader
172173 property string title
173174 property var config: PageHeadConfiguration {
175+ foregroundColor: root.scopeStyle ? root.scopeStyle.headerForeground : "grey"
174176 backAction: Action {
175177 iconName: "back"
176178 onTriggered: {
@@ -202,25 +204,13 @@ Item {
202204 anchors.fill: parent
203205 anchors.margins: units.gu(.75)
204206 source: "image://theme/clear"
205− opacity: searchTextField.text.length > 0 && !searchActivityIndicator.running
207+ opacity: searchTextField.text.length > 0
206208 visible: opacity > 0
207209 Behavior on opacity {
208210 UbuntuNumberAnimation { duration: UbuntuAnimation.FastDuration }
209211 }
210212 }
211213
212− ActivityIndicator {
213− id: searchActivityIndicator
214− objectName: "searchIndicator"
215− anchors.fill: parent
216− anchors.margins: units.gu(.75)
217− running: root.searchInProgress
218− opacity: running ? 1 : 0
219− Behavior on opacity {
220− UbuntuNumberAnimation { duration: UbuntuAnimation.FastDuration }
221− }
222− }
223−
224214 onClicked: {
225215 root.resetSearch(true);
226216 root.openSearchHistory();
@@ -249,10 +239,10 @@ Item {
249239 contentHeight: height
250240 opacity: headerContainer.clip || !headerContainer.showSearch ? 1 : 0 // setting visible false cause column to relayout
251241 separatorSource: ""
252− textColor: root.scopeStyle ? root.scopeStyle.headerForeground : "grey"
253242 property var styledItem: header
254243 property string title: root.title
255244 property var config: PageHeadConfiguration {
245+ foregroundColor: root.scopeStyle ? root.scopeStyle.headerForeground : "grey"
256246 backAction: Action {
257247 iconName: "back"
258248 visible: root.showBackButton
@@ -297,6 +287,25 @@ Item {
297287 }
298288 }
299289
290+ Row {
291+ spacing: units.gu(.5)
292+ Repeater {
293+ objectName: "paginationRepeater"
294+ model: root.paginationCount
295+ Image {
296+ objectName: "paginationDots_" + index
297+ height: units.gu(1)
298+ width: height
299+ source: (index == root.paginationIndex) ? "graphics/pagination_dot_on.png" : "graphics/pagination_dot_off.png"
300+ }
301+ }
302+ anchors {
303+ top: headerContainer.bottom
304+ horizontalCenter: headerContainer.horizontalCenter
305+ topMargin: units.gu(.5)
306+ }
307+ }
308+
300309 Component {
301310 id: popoverComponent
302311 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 {
126126 type:real \brief Height of the card's header.
127127 */
128128 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
130130
131131 /*!
132132 \brief Desired alignment of header components.
qml/Dash/Dash.qml+83−13
@@ -14,7 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.0
17+import QtQuick 2.2
1818import Ubuntu.Components 0.1
1919import Ubuntu.Gestures 0.1
2020import Unity 0.2
@@ -39,7 +39,13 @@ Showable {
3939 }
4040
4141 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+ }
4349
4450 if (scopeIndex == -1) {
4551 console.warn("No match for scope with id: %1".arg(scopeId))
@@ -64,15 +70,8 @@ Showable {
6470 }
6571 }
6672
67− SortFilterProxyModel {
68− id: filteredScopes
69− model: Scopes {
70− id: scopes
71− }
72− dynamicSortFilter: true
73−
74− filterRole: Scopes.RoleVisible
75− filterRegExp: RegExp("^true$")
73+ Scopes {
74+ id: scopes
7675 }
7776
7877 QtObject {
@@ -114,7 +113,13 @@ Showable {
114113 hide();
115114 }
116115 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+ }
118123 if (scopeIndex >= 0) {
119124 // Is a favorite one
120125 setCurrentScope(scopeId, false, false);
@@ -157,7 +162,6 @@ Showable {
157162 objectName: "dashContent"
158163 width: dash.width
159164 height: dash.height
160− model: filteredScopes
161165 scopes: scopes
162166 visible: !scopesOverview.showingNonFavoriteScope && x != -width
163167 onGotoScope: {
@@ -254,6 +258,72 @@ Showable {
254258 }
255259 }
256260
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+
257327 EdgeDragArea {
258328 id: overviewDragHandle
259329 objectName: "overviewDragHandle"
qml/Dash/DashApplication.qml+7
@@ -16,6 +16,7 @@
1616
1717import QtQuick 2.2
1818import Ubuntu.Components 1.0
19+import Ubuntu.Thumbnailer 0.1 // Register support for image://thumbnailer/ and image://albumart/
1920
2021MainView {
2122 width: units.gu(40)
@@ -23,6 +24,12 @@ MainView {
2324
2425 useDeprecatedToolbar: false
2526
27+ Binding {
28+ target: i18n
29+ property: "domain"
30+ value: "unity8"
31+ }
32+
2633 Dash {
2734 anchors.fill: parent
2835 }
qml/Dash/DashContent.qml+7−4
@@ -23,13 +23,14 @@ import "../Components"
2323Item {
2424 id: dashContent
2525
26− property var model: null
27− property var scopes: null
26+ property alias scopes: dashContentList.model
2827 readonly property alias currentIndex: dashContentList.currentIndex
2928 readonly property string currentScopeId: dashContentList.currentItem ? dashContentList.currentItem.scopeId : ""
3029 readonly property var currentScope: dashContentList.currentItem ? dashContentList.currentItem.theScope : null
3130 readonly property bool previewShown: dashContentList.currentItem && dashContentList.currentItem.item ?
3231 dashContentList.currentItem.item.previewShown : false
32+ readonly property bool processing: dashContentList.currentItem && dashContentList.currentItem.item
33+ && dashContentList.currentItem.item.processing || false
3334
3435 signal scopeLoaded(string scopeId)
3536 signal gotoScope(string scopeId)
@@ -93,10 +94,9 @@ Item {
9394 id: dashContentList
9495 objectName: "dashContentList"
9596
96− interactive: dashContent.scopes.loaded && currentItem && !currentItem.moving
97+ interactive: dashContent.scopes.loaded && currentItem && !currentItem.moving && !currentItem.navigationShown
9798
9899 anchors.fill: parent
99− model: dashContent.model
100100 orientation: ListView.Horizontal
101101 boundsBehavior: Flickable.DragAndOvershootBounds
102102 flickDeceleration: units.gu(625)
@@ -134,6 +134,7 @@ Item {
134134 objectName: scope.id + " loader"
135135
136136 readonly property bool moving: item ? item.moving : false
137+ readonly property bool navigationShown: item ? item.navigationShown : false
137138 readonly property var categoryView: item ? item.categoryView : null
138139 readonly property var theScope: scope
139140
@@ -147,6 +148,8 @@ Item {
147148 item.scope = Qt.binding(function() { return scope })
148149 item.isCurrent = Qt.binding(function() { return visible && ListView.isCurrentItem })
149150 dashContent.scopeLoaded(item.scope.id)
151+ item.paginationCount = Qt.binding(function() { return dashContentList.count } )
152+ item.paginationIndex = Qt.binding(function() { return dashContentList.currentIndex } )
150153 }
151154 Connections {
152155 target: isCurrent ? scope : null
qml/Dash/DashDepartments.qml → qml/Dash/DashNavigation.qmlrenamed+50−43
@@ -15,17 +15,17 @@
1515 */
1616
1717import QtQuick 2.2
18−import Ubuntu.Components 0.1
18+import Ubuntu.Components 1.1
1919
2020AbstractButton {
2121 id: root
22− objectName: "dashDepartments"
22+ objectName: "dashNavigation"
2323
2424 property var scope: null
2525
2626 property bool showList: false
2727
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
2929
3030 property alias windowWidth: blackRect.width
3131 property alias windowHeight: blackRect.height
@@ -34,20 +34,21 @@ AbstractButton {
3434 // Are we drilling down the tree or up?
3535 property bool isGoingBack: false
3636
37− visible: root.currentDepartment != null
37+ visible: root.currentNavigation != null
3838
3939 height: visible ? units.gu(5) : 0
4040
4141 onClicked: {
42+ navigationListView.updateMaxHeight();
4243 root.showList = !root.showList;
4344 }
4445
4546 Rectangle {
4647 id: blackRect
4748 color: "black"
48− opacity: departmentListView.currentItem && departmentListView.currentItem.visible ? 0.3 : 0
49+ opacity: navigationListView.currentItem && navigationListView.currentItem.visible ? 0.3 : 0
4950 Behavior on opacity { UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration } }
50− anchors.top: departmentListView.top
51+ anchors.top: navigationListView.top
5152 anchors.right: parent.right
5253 visible: opacity != 0
5354 }
@@ -78,7 +79,7 @@ AbstractButton {
7879 anchors.fill: parent
7980 anchors.margins: units.gu(2)
8081 verticalAlignment: Text.AlignVCenter
81− text: root.currentDepartment ? root.currentDepartment.label : ""
82+ text: root.currentNavigation ? root.currentNavigation.label : ""
8283 color: root.scopeStyle ? root.scopeStyle.foreground : "grey"
8384 }
8485
@@ -92,18 +93,18 @@ AbstractButton {
9293 color: root.scopeStyle ? root.scopeStyle.foreground : "grey"
9394 }
9495
95− // departmentListView is outside root
96+ // navigationListView is outside root
9697 ListView {
97− id: departmentListView
98− objectName: "departmentListView"
98+ id: navigationListView
99+ objectName: "navigationListView"
99100 orientation: ListView.Horizontal
100101 interactive: false
101102 clip: root.width != windowWidth
102103 model: ListModel {
103− id: departmentModel
104+ id: navigationModel
104105 // We have two roles
105− // departmentId: the department id of the department the list represents
106− // nullifyDepartment: overrides departmentId to be null
106+ // navigationId: the navigation id of the navigation the list represents
107+ // nullifyNavigation: overrides navigationId to be null
107108 // This is used to "clear" the delegate when going "right" on the tree
108109 }
109110 anchors {
@@ -111,7 +112,12 @@ AbstractButton {
111112 right: parent.right
112113 top: root.bottom
113114 }
114− readonly property int maxHeight: (windowHeight - mapToItem(null, root.x, root.y).y) - units.gu(8)
115+ property int maxHeight: -1
116+ Component.onCompleted: updateMaxHeight();
117+ function updateMaxHeight()
118+ {
119+ maxHeight = (windowHeight - mapToItem(null, 0, 0).y) - units.gu(8);
120+ }
115121 property int prevHeight: maxHeight
116122 height: currentItem ? currentItem.height : maxHeight
117123 onHeightChanged: {
@@ -120,83 +126,84 @@ AbstractButton {
120126 }
121127 }
122128 highlightMoveDuration: UbuntuAnimation.FastDuration
123− delegate: DashDepartmentsList {
124− objectName: "department" + index
129+ delegate: DashNavigationList {
130+ objectName: "navigation" + index
125131 visible: height != 0
126− width: departmentListView.width
132+ width: navigationListView.width
127133 scopeStyle: root.scopeStyle
128134 property real desiredHeight: {
129135 if (root.showList) {
130− if (department && department.loaded && x == departmentListView.contentX)
136+ if (navigation && navigation.loaded && x == navigationListView.contentX)
131137 {
132− return Math.min(implicitHeight, departmentListView.maxHeight);
138+ navigationListView.updateMaxHeight();
139+ return Math.min(implicitHeight, navigationListView.maxHeight);
133140 } else {
134− return departmentListView.prevHeight;
141+ return navigationListView.prevHeight;
135142 }
136143 } else {
137144 return 0;
138145 }
139146 }
140147 height: desiredHeight
141− department: (nullifyDepartment || !scope) ? null : scope.getDepartment(departmentId)
142− currentDepartment: root.currentDepartment
143− onEnterDepartment: {
144− scope.loadDepartment(newDepartmentId);
148+ navigation: (nullifyNavigation || !scope) ? null : scope.getNavigation(navigationId)
149+ currentNavigation: root.currentNavigation
150+ onEnterNavigation: {
151+ scope.setNavigationState(newNavigationId, false);
145152 // We only need to add a new item to the model
146153 // if we have children, otherwise just load it
147154 if (hasChildren) {
148155 isGoingBack = false;
149− departmentModel.append({"departmentId": newDepartmentId, "nullifyDepartment": false});
150− departmentListView.currentIndex++;
156+ navigationModel.append({"navigationId": newNavigationId, "nullifyNavigation": false});
157+ navigationListView.currentIndex++;
151158 } else {
152159 showList = false;
153160 }
154161 }
155162 onGoBackToParentClicked: {
156− scope.loadDepartment(department.parentDepartmentId);
163+ scope.setNavigationState(navigation.parentNavigationId, false);
157164 isGoingBack = true;
158− departmentModel.setProperty(departmentListView.currentIndex - 1, "nullifyDepartment", false);
159− departmentListView.currentIndex--;
165+ navigationModel.setProperty(navigationListView.currentIndex - 1, "nullifyNavigation", false);
166+ navigationListView.currentIndex--;
160167 }
161− onAllDepartmentClicked: {
168+ onAllNavigationClicked: {
162169 showList = false;
163− if (root.currentDepartment.parentDepartmentId == department.departmentId) {
170+ if (root.currentNavigation.parentNavigationId == navigation.navigationId) {
164171 // For leaves we have to go to the parent too
165− scope.loadDepartment(root.currentDepartment.parentDepartmentId);
172+ scope.setNavigationState(root.currentNavigation.parentNavigationId, false);
166173 }
167174 }
168175 }
169176 onContentXChanged: {
170− if (contentX == width * departmentListView.currentIndex) {
177+ if (contentX == width * navigationListView.currentIndex) {
171178 if (isGoingBack) {
172− departmentModel.remove(departmentListView.currentIndex + 1);
179+ navigationModel.remove(navigationListView.currentIndex + 1);
173180 } else {
174− departmentModel.setProperty(departmentListView.currentIndex - 1, "nullifyDepartment", true);
181+ navigationModel.setProperty(navigationListView.currentIndex - 1, "nullifyNavigation", true);
175182 }
176183 }
177184 }
178185 }
179186
180187 InverseMouseArea {
181− anchors.fill: departmentListView
188+ anchors.fill: navigationListView
182189 enabled: root.showList
183190 onClicked: root.showList = false
184191 }
185192
186193 onScopeChanged: {
187− departmentModel.clear();
188− if (scope && scope.hasDepartments) {
189− departmentModel.append({"departmentId": scope.currentDepartmentId, "nullifyDepartment": false});
194+ navigationModel.clear();
195+ if (scope && scope.hasNavigation) {
196+ navigationModel.append({"navigationId": scope.currentNavigationId, "nullifyNavigation": false});
190197 }
191198 }
192199
193200 Connections {
194201 target: scope
195− onHasDepartmentsChanged: {
196− if (scope.hasDepartments) {
197− departmentModel.append({"departmentId": scope.currentDepartmentId, "nullifyDepartment": false});
202+ onHasNavigationChanged: {
203+ if (scope.hasNavigation) {
204+ navigationModel.append({"navigationId": scope.currentNavigationId, "nullifyNavigation": false});
198205 } else {
199− departmentModel.clear();
206+ navigationModel.clear();
200207 }
201208 }
202209 }
qml/Dash/DashDepartmentsList.qml → qml/Dash/DashNavigationList.qmlrenamed+14−18
@@ -15,16 +15,16 @@
1515 */
1616
1717import QtQuick 2.2
18−import Ubuntu.Components 0.1
18+import Ubuntu.Components 1.1
1919
2020Item {
2121 id: root
22− property var department: null
23− property var currentDepartment: null
22+ property var navigation: null
23+ property var currentNavigation: null
2424 property var scopeStyle: null
25− signal enterDepartment(var newDepartmentId, bool hasChildren)
25+ signal enterNavigation(var newNavigationId, bool hasChildren)
2626 signal goBackToParentClicked()
27− signal allDepartmentClicked()
27+ signal allNavigationClicked()
2828
2929 readonly property int itemHeight: units.gu(5)
3030 readonly property color foregroundColor: root.scopeStyle ? root.scopeStyle.foreground : "grey"
@@ -35,11 +35,6 @@ Item {
3535 anchors.fill: parent
3636 }
3737
38− ActivityIndicator {
39− id: loadingIndicator
40− anchors.centerIn: parent
41− running: !(department && department.loaded)
42− }
4338 clip: true
4439
4540 Behavior on height {
@@ -54,6 +49,7 @@ Item {
5449
5550 anchors.fill: parent
5651
52+ flickableDirection: Flickable.VerticalFlick
5753 contentHeight: column.height
5854 contentWidth: width
5955
@@ -68,7 +64,7 @@ Item {
6864 id: backButton
6965 objectName: "backButton"
7066 width: parent.width
71− visible: department && !department.isRoot || false
67+ visible: navigation && !navigation.isRoot || false
7268 height: itemHeight
7369
7470 onClicked: root.goBackToParentClicked();
@@ -92,7 +88,7 @@ Item {
9288 left: backImage.right
9389 leftMargin: units.gu(0.5)
9490 }
95− text: department ? department.parentLabel : ""
91+ text: navigation ? navigation.parentLabel : ""
9692 color: root.foregroundColor
9793 }
9894
@@ -114,7 +110,7 @@ Item {
114110 id: allButton
115111 objectName: "allButton"
116112 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
118114 height: itemHeight
119115
120116 Label {
@@ -123,7 +119,7 @@ Item {
123119 left: parent.left
124120 leftMargin: units.gu(2)
125121 }
126− text: department ? (department.allLabel != "" ? department.allLabel : department.label) : ""
122+ text: navigation ? (navigation.allLabel != "" ? navigation.allLabel : navigation.label) : ""
127123 font.bold: true
128124 color: root.foregroundColor
129125 }
@@ -141,18 +137,18 @@ Item {
141137 height: units.dp(1)
142138 }
143139
144− onClicked: root.allDepartmentClicked();
140+ onClicked: root.allNavigationClicked();
145141 }
146142
147143 Repeater {
148− model: department && department.loaded ? department : null
144+ model: navigation && navigation.loaded ? navigation : null
149145 clip: true
150146 delegate: AbstractButton {
151147 objectName: root.objectName + "child" + index
152148 height: root.itemHeight
153149 width: root.width
154150
155− onClicked: root.enterDepartment(departmentId, hasChildren)
151+ onClicked: root.enterNavigation(navigationId, hasChildren)
156152
157153 Label {
158154 anchors {
@@ -188,7 +184,7 @@ Item {
188184 color: root.foregroundColor
189185 opacity: 0.1
190186 height: units.dp(1)
191− visible: index != department.count - 1
187+ visible: index != navigation.count - 1
192188 }
193189 }
194190 }
qml/Dash/GenericScopeView.qml+13−12
@@ -25,6 +25,7 @@ import "../Components/ListItems" as ListItems
2525FocusScope {
2626 id: scopeView
2727
28+ readonly property bool navigationShown: pageHeaderLoader.item ? pageHeaderLoader.item.bottomItem[0].showList : false
2829 property var scope: null
2930 property SortFilterProxyModel categories: categoryFilter
3031 property bool isCurrent: false
@@ -34,22 +35,16 @@ FocusScope {
3435 property var categoryView: categoryView
3536 property bool showPageHeader: true
3637 readonly property alias previewShown: previewListView.open
38+ property int paginationCount: 0
39+ property int paginationIndex: 0
3740
3841 property var scopeStyle: ScopeStyle {
3942 style: scope ? scope.customizations : {}
4043 }
4144
42− signal backClicked()
43−
44− onScopeChanged: {
45− if (scope) {
46− scope.activateApplication.connect(activateApp);
47− }
48− }
45+ readonly property bool processing: scope ? scope.searchInProgress || previewListView.processing : false
4946
50− function activateApp(appId) {
51− Qt.openUrlExternally(appId);
52− }
47+ signal backClicked()
5348
5449 function positionAtBeginning() {
5550 categoryView.positionAtBeginning()
@@ -153,6 +148,7 @@ FocusScope {
153148 model: scopeView.categories
154149 forceNoClip: previewListView.open
155150 pixelAligned: true
151+ interactive: !navigationShown
156152
157153 property string expandedCategoryId: ""
158154
@@ -245,6 +241,10 @@ FocusScope {
245241 baseItem.expand(shouldExpand, false /*animate*/);
246242 }
247243 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+ }
248248 item.cardTool = cardTool;
249249 }
250250
@@ -419,10 +419,11 @@ FocusScope {
419419 searchHint: scopeView.scope && scopeView.scope.searchHint || i18n.tr("Search")
420420 showBackButton: scopeView.hasBackAction
421421 searchEntryEnabled: true
422− searchInProgress: scopeView.scope ? scopeView.scope.searchInProgress : false
423422 scopeStyle: scopeView.scopeStyle
423+ paginationCount: scopeView.paginationCount
424+ paginationIndex: scopeView.paginationIndex
424425
425− bottomItem: DashDepartments {
426+ bottomItem: DashNavigation {
426427 scope: scopeView.scope
427428 width: parent.width <= units.gu(60) ? parent.width : units.gu(40)
428429 anchors.right: parent.right
qml/Dash/PreviewListView.qml+23−27
@@ -32,6 +32,9 @@ Item {
3232 property alias currentItem: previewListView.currentItem
3333 property alias count: previewListView.count
3434
35+ readonly property bool processing: currentItem && (!currentItem.previewModel.loaded
36+ || currentItem.previewModel.processingAction)
37+
3538 PageHeader {
3639 id: header
3740 objectName: "pageHeader"
@@ -83,39 +86,32 @@ Item {
8386 }
8487 }
8588
86− delegate: Item {
87− objectName: "previewItem" + index
89+ delegate: Previews.Preview {
90+ id: preview
91+ objectName: "preview" + index
8892 height: previewListView.height
8993 width: previewListView.width
9094
91− readonly property bool ready: preview.previewModel && preview.previewModel.loaded
92−
93− Previews.Preview {
94− id: preview
95− objectName: "preview" + index
96− anchors.fill: parent
95+ isCurrent: ListView.isCurrentItem
9796
98− isCurrent: parent.ListView.isCurrentItem
99−
100− previewModel: {
101− var previewStack = root.scope.preview(result);
102− return previewStack.getPreviewModel(0);
103− }
104− scopeStyle: root.scopeStyle
97+ previewModel: {
98+ var previewStack = root.scope.preview(result);
99+ return previewStack.getPreviewModel(0);
105100 }
101+ scopeStyle: root.scopeStyle
102+ }
103+ }
106104
107− MouseArea {
108− id: processingMouseArea
109− objectName: "processingMouseArea"
110− anchors.fill: parent
111− enabled: preview.previewModel && (!preview.previewModel.loaded || preview.previewModel.processingAction)
112−
113− ActivityIndicator {
114− anchors.centerIn: parent
115− visible: root.open && parent.enabled
116− running: visible
117− }
118− }
105+ MouseArea {
106+ id: processingMouseArea
107+ objectName: "processingMouseArea"
108+ anchors {
109+ left: parent.left
110+ right: parent.right
111+ top: header.bottom
112+ bottom: parent.bottom
119113 }
114+
115+ enabled: root.processing
120116 }
121117}
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 @@
1515 */
1616
1717import QtQuick 2.0
18+import Ubuntu.Components 1.1
1819import "../../Components"
1920
2021/*! This preview widget shows a horizontal list of images.
qml/Dash/Previews/PreviewTextSummary.qml+3−16
@@ -23,7 +23,7 @@ import "../../Components"
2323 This widget shows text contained in widgetData["text"]
2424 along with a title that comes from widgetData["title"].
2525
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.
2727 */
2828
2929PreviewWidget {
@@ -50,14 +50,14 @@ PreviewWidget {
5050 id: textLabel
5151 objectName: "textLabel"
5252
53− readonly property int maximumCollapsedLineCount: 7
53+ readonly property int maximumCollapsedLineCount: 3
5454
5555 anchors {
5656 left: parent.left
5757 right: parent.right
5858 top: titleLabel.visible ? titleLabel.bottom : parent.top
5959 }
60− height: (!seeMore.visible || seeMore.more) ? contentHeight : contentHeight / lineCount * (maximumCollapsedLineCount - 2)
60+ height: (lineCount <= maximumCollapsedLineCount || root.expanded) ? contentHeight : contentHeight / lineCount * maximumCollapsedLineCount
6161 clip: true
6262 fontSize: "small"
6363 lineHeight: 1.2
@@ -70,17 +70,4 @@ PreviewWidget {
7070 UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration }
7171 }
7272 }
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− }
8673}
qml/Dash/Previews/PreviewWidget.qml+3
@@ -31,6 +31,9 @@ Item {
3131 //! The ScopeStyle component.
3232 property var scopeStyle: null
3333
34+ //! Should the widget show in expanded mode (For those that support it)
35+ property bool expanded: true
36+
3437 /*! \brief This signal should be emitted when a preview action was triggered.
3538 *
3639 * \param widgetId, actionId Respective identifiers from widgetData.
qml/Dash/Previews/PreviewWidgetFactory.qml+5
@@ -34,6 +34,9 @@ Loader {
3434 //! The ScopeStyle component.
3535 property var scopeStyle: null
3636
37+ //! Should the widget show in expanded mode (For those that support it)
38+ property bool expanded: true
39+
3740 //! Set to true if the parent preview is displayed.
3841 property bool isCurrentPreview: false
3942
@@ -47,6 +50,7 @@ Loader {
4750 switch (widgetType) {
4851 case "actions": return "PreviewActions.qml";
4952 case "audio": return "PreviewAudioPlayback.qml";
53+ case "expandable": return "PreviewExpandable.qml";
5054 case "gallery": return "PreviewImageGallery.qml";
5155 case "header": return "PreviewHeader.qml";
5256 case "image": return "PreviewZoomableImage.qml";
@@ -65,6 +69,7 @@ Loader {
6569 item.widgetId = Qt.binding(function() { return root.widgetId } )
6670 item.widgetData = Qt.binding(function() { return root.widgetData } )
6771 item.isCurrentPreview = Qt.binding(function() { return root.isCurrentPreview } )
72+ item.expanded = Qt.binding(function() { return root.expanded } )
6873 if (item.hasOwnProperty("scopeStyle")) item.scopeStyle = root.scopeStyle;
6974 }
7075
qml/Dash/ScopesOverview.qml+10−4
@@ -84,6 +84,12 @@ Item {
8484 }
8585 }
8686
87+ Binding {
88+ target: scope
89+ property: "isActive"
90+ value: progress === 1
91+ }
92+
8793 function animateDashFromAll(scopeId) {
8894 var currentScopePos = allScopeCardPosition(scopeId);
8995 if (currentScopePos) {
@@ -188,7 +194,6 @@ Item {
188194 scopeStyle: overviewScopeStyle
189195 showSignatureLine: false
190196 searchEntryEnabled: true
191− searchInProgress: root.scope ? root.scope.searchInProgress : false
192197 }
193198
194199 ScopesOverviewTab {
@@ -334,6 +339,7 @@ Item {
334339 showPageHeader: false
335340 clip: true
336341 opacity: searchResultsViewer.scope ? 1 : 0
342+ isCurrent: true
337343 Behavior on opacity { UbuntuNumberAnimation { } }
338344
339345 function itemClicked(index, result, item, itemModel, resultsModel, limitedCategoryItemCount) {
@@ -357,10 +363,10 @@ Item {
357363 Rectangle {
358364 id: bottomBar
359365 color: "black"
360− height: units.gu(6)
366+ height: units.gu(8)
361367 width: parent.width
362− enabled: opacity == 0.4
363− opacity: scope && scope.searchQuery == "" ? 0.4 : 0
368+ enabled: opacity == 1
369+ opacity: scope && scope.searchQuery == "" ? 1 : 0
364370 Behavior on opacity { UbuntuNumberAnimation { } }
365371 y: {
366372 if (root.progress < 0.5) {
qml/Greeter/Greeter.qml+1−1
@@ -70,7 +70,7 @@ Showable {
7070 DraggingArea {
7171 id: dragHandle
7272 anchors.fill: parent
73− enabled: (greeter.narrowMode || !greeter.locked) && greeter.enabled
73+ enabled: (greeter.narrowMode || !greeter.locked) && greeter.enabled && greeter.shown
7474 orientation: Qt.Horizontal
7575 propagateComposedEvents: true
7676
qml/Notifications/NotificationMenuItemFactory.qml+3
@@ -76,6 +76,9 @@ Loader {
7676 }
7777 echoMode: checkBox.checked ? TextInput.Normal : TextInput.Password
7878 height: units.gu(5)
79+ Component.onCompleted: {
80+ forceActiveFocus();
81+ }
7982 onTextChanged: {
8083 menuModel.changeState(menuIndex, text);
8184 }
qml/Panel/Indicators/MenuItemFactory.qml+74
@@ -57,6 +57,7 @@ Item {
5757
5858 "unity.widgets.systemsettings.tablet.wifisection" : wifiSection,
5959 "unity.widgets.systemsettings.tablet.accesspoint" : accessPoint,
60+ "com.canonical.indicator.network.modeminfoitem" : modeminfoitem,
6061 }
6162
6263 function getExtendedProperty(object, propertyName, defaultValue) {
@@ -374,6 +375,79 @@ Item {
374375 }
375376 }
376377
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+
377451 Component {
378452 id: messageItem
379453
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 @@
1717import QtQuick 2.0
1818import Ubuntu.Components 0.1
1919import Ubuntu.Components.Popups 0.1
20+import Ubuntu.Thumbnailer 0.1 // Register support for image://thumbnailer/ and image://albumart/
2021import Utils 0.1
2122import Unity 0.2
2223import "Components"
@@ -45,16 +46,6 @@ Rectangle {
4546 signal searchClicked
4647 }
4748
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− }
5849
5950 Rectangle {
6051 anchors.fill: dashContent
@@ -72,8 +63,8 @@ Rectangle {
7263 DashContent {
7364 id: dashContent
7465
75− model: filteredScopes
7666 property var scope: scopes.getScope(currentIndex)
67+ scopes: Scopes { }
7768
7869 anchors {
7970 top: parent.top
qml/Shell.qml+4−4
@@ -167,12 +167,12 @@ Item {
167167 Binding {
168168 target: applicationsDisplayLoader.item
169169 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
171171 }
172172 Binding {
173173 target: applicationsDisplayLoader.item
174174 property: "spreadEnabled"
175− value: greeter.fakeActiveForApp === "" // to support emergency dialer hack
175+ value: edgeDemo.stagesEnabled && greeter.fakeActiveForApp === "" // to support emergency dialer hack
176176 }
177177 Binding {
178178 target: applicationsDisplayLoader.item
@@ -381,7 +381,7 @@ Item {
381381 onDisplayPowerStateChange: {
382382 // We ignore any display-off signals when the proximity sensor
383383 // 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) {
385385 greeter.showNow();
386386 }
387387
@@ -561,7 +561,7 @@ Item {
561561 greeter: greeter
562562 launcher: launcher
563563 indicators: panel.indicators
564− underlay: underlay
564+ stages: stages
565565 }
566566
567567 Connections {
run_on_device.sh+1−3
@@ -2,7 +2,6 @@
22CODE_DIR=shell
33USER=phablet
44USER_ID=32011
5−PASSWORD=phablet
65PACKAGE=unity8
76BINARY=unity8
87TARGET_IP=${TARGET_IP-127.0.0.1}
@@ -13,7 +12,6 @@ SETUP=false
1312GDB=false
1413PINLOCK=false
1514KEYLOCK=false
16−SUDO="echo $PASSWORD | sudo -S"
1715NUM_JOBS='$(( `grep -c ^processor /proc/cpuinfo` + 1 ))'
1816FLIPPED=false
1917CHROOT_PREFIX="/data/ubuntu"
@@ -76,7 +74,7 @@ setup_adb_forwarding() {
7674
7775install_dependencies() {
7876 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
8078}
8179
8280sync_code() {
src/Dash/main.cpp+5−5
@@ -24,6 +24,7 @@
2424#include <QDebug>
2525#include <QCommandLineParser>
2626#include <QLibrary>
27+#include <libintl.h>
2728
2829#include <paths.h>
2930#include "../MouseTouchAdaptor.h"
@@ -40,10 +41,7 @@ int main(int argc, const char *argv[])
4041 "Allow the mouse to provide touch input");
4142 parser.addOption(mousetouchOption);
4243
43− QCommandLineOption testabilityOption("testability",
44− "Load the testability driver (Alternatively export QT_LOAD_TESTABILITY");
45− parser.addOption(testabilityOption);
46−
44+ // FIXME Remove once we drop the need of the hint
4745 QCommandLineOption desktopFileHintOption("desktop_file_hint",
4846 "The desktop_file_hint option for QtMir", "hint_file");
4947 parser.addOption(desktopFileHintOption);
@@ -53,7 +51,7 @@ int main(int argc, const char *argv[])
5351 parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions);
5452 parser.process(*application);
5553
56− if (parser.isSet(testabilityOption) || getenv("QT_LOAD_TESTABILITY")) {
54+ if (getenv("QT_LOAD_TESTABILITY")) {
5755 QLibrary testLib(QLatin1String("qttestability"));
5856 if (testLib.load()) {
5957 typedef void (*TasInitialize)(void);
@@ -68,6 +66,8 @@ int main(int argc, const char *argv[])
6866 }
6967 }
7068
69+ bindtextdomain("unity8", translationDirectory().toUtf8().data());
70+
7171 QQuickView* view = new QQuickView();
7272 view->setResizeMode(QQuickView::SizeRootObjectToView);
7373 view->setTitle("Unity Dash");
tests/autopilot/unity8/shell/emulators/dash.py+1−1
@@ -150,7 +150,7 @@ class Dash(emulators.UnityEmulatorBase):
150150 headerContainer.contentY.wait_for(0)
151151 search_text_field = self._get_search_text_field()
152152 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)
154154
155155 def _get_search_text_field(self):
156156 page_header = self._get_current_page_header()
tests/mocks/Unity/CMakeLists.txt+3−3
@@ -7,7 +7,7 @@ add_subdirectory(DashCommunicator)
77pkg_search_module(DEE dee-1.0 REQUIRED)
88pkg_search_module(GOBJECT gobject-2.0 REQUIRED)
99pkg_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)
1111
1212include_directories(
1313 ${CMAKE_CURRENT_BINARY_DIR}
@@ -24,14 +24,14 @@ set(UnityQML_SOURCES
2424 fake_scopes.cpp
2525 fake_scopesoverview.cpp
2626 fake_categories.cpp
27− fake_department.cpp
27+ fake_navigation.cpp
2828 fake_resultsmodel.cpp
2929 fake_previewmodel.cpp
3030 fake_previewstack.cpp
3131 fake_previewwidgetmodel.cpp
3232 fake_unity_plugin.cpp
3333 ${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
3535 ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/PreviewModelInterface.h
3636 ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/PreviewStackInterface.h
3737 ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/PreviewWidgetModelInterface.h
tests/mocks/Unity/Unity.qmltypes+79−27
@@ -24,6 +24,12 @@ Module {
2424 Parameter { name: "categoryId"; type: "string" }
2525 Parameter { name: "json"; type: "string" }
2626 }
27+ Method {
28+ name: "data"
29+ type: "QVariant"
30+ Parameter { name: "row"; type: "int" }
31+ Parameter { name: "role"; type: "int" }
32+ }
2733 }
2834 Component {
2935 name: "PreviewModel"
@@ -62,6 +68,10 @@ Module {
6268 prototype: "unity::shell::scopes::ScopeInterface"
6369 exports: ["Unity/MockScope 0.2"]
6470 exportMetaObjectRevisions: [0]
71+ Signal {
72+ name: "performQuery"
73+ Parameter { name: "query"; type: "string" }
74+ }
6575 Method {
6676 name: "setSearchInProgress"
6777 Parameter { name: "inProg"; type: "bool" }
@@ -81,18 +91,21 @@ Module {
8191 Parameter { name: "scope"; type: "unity::shell::scopes::ScopeInterface"; isPointer: true }
8292 }
8393 Method {
84− name: "getDepartment"
85− type: "unity::shell::scopes::DepartmentInterface*"
86− Parameter { name: "id"; type: "string" }
94+ name: "getNavigation"
95+ type: "unity::shell::scopes::NavigationInterface*"
96+ Parameter { name: "navigationId"; type: "string" }
8797 }
8898 Method {
89− name: "loadDepartment"
90− Parameter { name: "id"; type: "string" }
99+ name: "getAltNavigation"
100+ type: "unity::shell::scopes::NavigationInterface*"
101+ Parameter { name: "altNavigationId"; type: "string" }
91102 }
92103 Method {
93− name: "performQuery"
94− Parameter { name: "query"; type: "string" }
104+ name: "setNavigationState"
105+ Parameter { name: "navigationId"; type: "string" }
106+ Parameter { name: "isAltNavigation"; type: "bool" }
95107 }
108+ Method { name: "refresh" }
96109 }
97110 Component {
98111 name: "Scopes"
@@ -137,6 +150,7 @@ Module {
137150 "RoleRawRendererTemplate": 3,
138151 "RoleRenderer": 4,
139152 "RoleComponents": 5,
153+ "RoleHeaderLink": 6,
140154 "RoleResults": 7,
141155 "RoleCount": 8
142156 }
@@ -157,27 +171,28 @@ Module {
157171 }
158172 }
159173 Component {
160− name: "unity::shell::scopes::DepartmentInterface"
174+ name: "unity::shell::scopes::NavigationInterface"
161175 prototype: "QAbstractListModel"
162− exports: ["Unity/Department 0.2"]
176+ exports: ["Unity/Navigation 0.2"]
163177 isCreatable: false
164178 exportMetaObjectRevisions: [0]
165179 Enum {
166180 name: "Roles"
167181 values: {
168− "RoleDepartmentId": 0,
182+ "RoleNavigationId": 0,
169183 "RoleLabel": 1,
170184 "RoleHasChildren": 2,
171185 "RoleIsActive": 3
172186 }
173187 }
174− Property { name: "departmentId"; type: "string"; isReadonly: true }
188+ Property { name: "navigationId"; type: "string"; isReadonly: true }
175189 Property { name: "label"; type: "string"; isReadonly: true }
176190 Property { name: "allLabel"; type: "string"; isReadonly: true }
177− Property { name: "parentDepartmentId"; type: "string"; isReadonly: true }
191+ Property { name: "parentNavigationId"; type: "string"; isReadonly: true }
178192 Property { name: "parentLabel"; type: "string"; isReadonly: true }
179193 Property { name: "loaded"; type: "bool"; isReadonly: true }
180194 Property { name: "isRoot"; type: "bool"; isReadonly: true }
195+ Property { name: "hidden"; type: "bool"; isReadonly: true }
181196 Property { name: "count"; type: "int"; isReadonly: true }
182197 }
183198 Component {
@@ -247,7 +262,8 @@ Module {
247262 "RoleEmblem": 8,
248263 "RoleSummary": 9,
249264 "RoleAttributes": 10,
250− "RoleBackground": 11
265+ "RoleBackground": 11,
266+ "RoleOverlayColor": 12
251267 }
252268 }
253269 Property { name: "categoryId"; type: "string" }
@@ -259,13 +275,22 @@ Module {
259275 exports: ["Unity/Scope 0.2"]
260276 isCreatable: false
261277 exportMetaObjectRevisions: [0]
278+ Enum {
279+ name: "Status"
280+ values: {
281+ "Okay": 0,
282+ "NoInternet": 1,
283+ "NoLocationData": 2,
284+ "Unknown": 3
285+ }
286+ }
262287 Property { name: "id"; type: "string"; isReadonly: true }
263288 Property { name: "name"; type: "string"; isReadonly: true }
264289 Property { name: "iconHint"; type: "string"; isReadonly: true }
265290 Property { name: "description"; type: "string"; isReadonly: true }
266291 Property { name: "searchHint"; type: "string"; isReadonly: true }
267292 Property { name: "searchInProgress"; type: "bool"; isReadonly: true }
268− Property { name: "visible"; type: "bool"; isReadonly: true }
293+ Property { name: "favorite"; type: "bool" }
269294 Property { name: "shortcut"; type: "string"; isReadonly: true }
270295 Property {
271296 name: "categories"
@@ -273,13 +298,27 @@ Module {
273298 isReadonly: true
274299 isPointer: true
275300 }
301+ Property {
302+ name: "settings"
303+ type: "unity::shell::scopes::SettingsModelInterface"
304+ isReadonly: true
305+ isPointer: true
306+ }
276307 Property { name: "searchQuery"; type: "string" }
277308 Property { name: "noResultsHint"; type: "string" }
278309 Property { name: "formFactor"; type: "string" }
279310 Property { name: "isActive"; type: "bool" }
280− Property { name: "currentDepartmentId"; type: "string"; isReadonly: true }
281− Property { name: "hasDepartments"; type: "bool"; isReadonly: true }
311+ Property { name: "currentNavigationId"; type: "string"; isReadonly: true }
312+ Property { name: "hasNavigation"; type: "bool"; isReadonly: true }
313+ Property { name: "currentAltNavigationId"; type: "string"; isReadonly: true }
314+ Property { name: "hasAltNavigation"; type: "bool"; isReadonly: true }
282315 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" }
283322 Signal { name: "showDash" }
284323 Signal { name: "hideDash" }
285324 Signal {
@@ -298,10 +337,6 @@ Module {
298337 name: "openScope"
299338 Parameter { name: "scope"; type: "unity::shell::scopes::ScopeInterface"; isPointer: true }
300339 }
301− Signal {
302− name: "activateApplication"
303− Parameter { name: "desktop"; type: "string" }
304− }
305340 Method {
306341 name: "activate"
307342 Parameter { name: "result"; type: "QVariant" }
@@ -317,14 +352,25 @@ Module {
317352 Parameter { name: "scope"; type: "unity::shell::scopes::ScopeInterface"; isPointer: true }
318353 }
319354 Method {
320− name: "getDepartment"
321− type: "unity::shell::scopes::DepartmentInterface*"
322− Parameter { name: "departmentId"; type: "string" }
355+ name: "getNavigation"
356+ type: "unity::shell::scopes::NavigationInterface*"
357+ Parameter { name: "navigationId"; type: "string" }
358+ }
359+ Method {
360+ name: "getAltNavigation"
361+ type: "unity::shell::scopes::NavigationInterface*"
362+ Parameter { name: "altNavigationId"; type: "string" }
323363 }
324364 Method {
325− name: "loadDepartment"
326− Parameter { name: "departmentId"; type: "string" }
365+ name: "setNavigationState"
366+ Parameter { name: "navId"; type: "string" }
367+ Parameter { name: "altNavigation"; type: "bool" }
327368 }
369+ Method {
370+ name: "performQuery"
371+ Parameter { name: "cannedQuery"; type: "string" }
372+ }
373+ Method { name: "refresh" }
328374 }
329375 Component {
330376 name: "unity::shell::scopes::ScopesInterface"
@@ -334,11 +380,17 @@ Module {
334380 values: {
335381 "RoleScope": 0,
336382 "RoleId": 1,
337− "RoleVisible": 2,
338− "RoleTitle": 3
383+ "RoleTitle": 2
339384 }
340385 }
341386 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+ }
342394 Method {
343395 name: "getScope"
344396 type: "unity::shell::scopes::ScopeInterface*"
tests/mocks/Unity/fake_department.cpp → tests/mocks/Unity/fake_navigation.cpprenamed+32−40
@@ -14,14 +14,15 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−#include "fake_department.h"
17+#include "fake_navigation.h"
1818
1919#include "fake_scope.h"
2020
21+#include <QDebug>
2122#include <QTimer>
2223
23−Department::Department(const QString& departmentId, const QString& label, const QString& allLabel, const QString& parentId, const QString& parentLabel, Scope* scope)
24− : m_departmentId(departmentId)
24+Navigation::Navigation(const QString& navigationId, const QString& label, const QString& allLabel, const QString& parentId, const QString& parentLabel, Scope* scope)
25+ : m_navigationId(navigationId)
2526 , m_label(label)
2627 , m_allLabel(allLabel)
2728 , m_parentId(parentId)
@@ -30,96 +31,87 @@ Department::Department(const QString& departmentId, const QString& label, const
3031 , m_scope(scope)
3132{
3233 QTimer::singleShot(1500, this, SLOT(slotLoaded()));
33− connect(scope, SIGNAL(currentDepartmentIdChanged()), this, SLOT(slotCurrentDepartmentChanged()));
34+ connect(scope, SIGNAL(currentNavigationIdChanged()), this, SLOT(slotCurrentNavigationChanged()));
3435}
3536
36−QString Department::departmentId() const
37+QString Navigation::navigationId() const
3738{
38− return m_departmentId;
39+ return m_navigationId;
3940}
4041
41−QString Department::label() const
42+QString Navigation::label() const
4243{
4344 return m_label;
4445}
4546
46−QString Department::allLabel() const
47+QString Navigation::allLabel() const
4748{
4849 return m_allLabel;
4950}
5051
51−QString Department::parentDepartmentId() const
52+QString Navigation::parentNavigationId() const
5253{
5354 return m_parentId;
5455}
5556
56−QString Department::parentLabel() const
57+QString Navigation::parentLabel() const
5758{
5859 return m_parentLabel;
5960}
6061
61−void Department::slotLoaded()
62+void Navigation::slotLoaded()
6263{
6364 m_loaded = true;
6465 Q_EMIT loadedChanged();
6566}
6667
67−bool Department::loaded() const
68+bool Navigation::loaded() const
6869{
6970 return m_loaded;
7071}
7172
72−int Department::count() const
73+int Navigation::count() const
7374{
7475 return rowCount();
7576}
7677
77−bool Department::isRoot() const
78+bool Navigation::isRoot() const
7879{
79− return m_departmentId == "root";
80+ return m_navigationId == "root" || m_navigationId == "altroot";
8081}
8182
82−int Department::rowCount(const QModelIndex & /*parent*/) const
83+bool Navigation::hidden() const
8384{
84− if (!m_loaded || m_departmentId.startsWith("child") || m_departmentId == "middle3")
85− return 0;
86− else
87− return 8;
85+ return m_navigationId == "altroot";
8886}
8987
90−QHash<int, QByteArray> Department::roleNames() const
88+int Navigation::rowCount(const QModelIndex & /*parent*/) const
9189{
92− QHash<int, QByteArray> res;
93− res[RoleDepartmentId] = "departmentId";
94− res[RoleLabel] = "label";
95− res[RoleHasChildren] = "hasChildren";
96− res[RoleIsActive] = "isActive";
97− return res;
90+ if (!m_loaded || m_navigationId.startsWith("child") || m_navigationId == "middle3")
91+ return 0;
92+ else
93+ return 8;
9894}
9995
100−QVariant Department::data(const QModelIndex &index, int role) const
96+QVariant Navigation::data(const QModelIndex &index, int role) const
10197{
10298 switch (role) {
103− case RoleDepartmentId:
104− if (m_departmentId == "root")
99+ case RoleNavigationId:
100+ if (m_navigationId == "root")
105101 return QString("middle%1").arg(index.row());
106− else if (m_departmentId.startsWith("middle"))
107− return QString("child%1%2").arg(m_departmentId).arg(index.row());
108− break;
102+ else if (m_navigationId.startsWith("middle"))
103+ return QString("child%1%2").arg(m_navigationId).arg(index.row());
109104 case RoleLabel:
110− return QString("%1Child%2").arg(m_departmentId).arg(index.row());
111− break;
105+ return QString("%1Child%2").arg(m_navigationId).arg(index.row());
112106 case RoleHasChildren:
113− return m_departmentId == "root" && index.row() != 3;
114− break;
107+ return m_navigationId == "root" && index.row() != 3;
115108 case RoleIsActive:
116− return m_scope->currentDepartmentId() == data(index, RoleDepartmentId);
117− break;
109+ return m_scope->currentNavigationId() == data(index, RoleNavigationId);
118110 }
119111 return QVariant();
120112}
121113
122−void Department::slotCurrentDepartmentChanged()
114+void Navigation::slotCurrentNavigationChanged()
123115{
124116 // This is wasteful, should only emit it if really something changed in this
125117 // 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 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−#ifndef FAKE_DEPARTMENT_H
18−#define FAKE_DEPARTMENT_H
17+#ifndef FAKE_NAVIGATION_H
18+#define FAKE_NAVIGATION_H
1919
20−#include <unity/shell/scopes/DepartmentInterface.h>
20+#include <unity/shell/scopes/NavigationInterface.h>
2121
2222class Scope;
2323
24−class Department : public unity::shell::scopes::DepartmentInterface
24+class Navigation : public unity::shell::scopes::NavigationInterface
2525{
2626 Q_OBJECT
2727
2828public:
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);
3030
31− QString departmentId() const override;
31+ QString navigationId() const override;
3232 QString label() const override;
3333 QString allLabel() const override;
34− QString parentDepartmentId() const override;
34+ QString parentNavigationId() const override;
3535 QString parentLabel() const override;
3636 bool loaded() const override;
37− int count() const override;
3837 bool isRoot() const override;
38+ bool hidden() const override;
39+ int count() const override;
3940
4041 int rowCount(const QModelIndex &parent = QModelIndex()) const override;
41− QHash<int, QByteArray> roleNames() const;
4242 QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
4343
4444public Q_SLOTS:
45− void slotCurrentDepartmentChanged();
45+ void slotCurrentNavigationChanged();
4646
4747private Q_SLOTS:
4848 void slotLoaded();
4949
5050private:
51− QString m_departmentId;
51+ QString m_navigationId;
5252 QString m_label;
5353 QString m_allLabel;
5454 QString m_parentId;
5555 QString m_parentLabel;
5656 bool m_loaded;
57− QString m_currentDepartment;
57+ QString m_currentNavigation;
5858 Scope *m_scope;
5959};
6060
61−#endif // FAKE_DEPARTMENT_H
61+#endif // FAKE_NAVIGATION_H
tests/mocks/Unity/fake_scope.cpp+64−17
@@ -19,7 +19,7 @@
1919
2020#include "fake_scope.h"
2121
22−#include "fake_department.h"
22+#include "fake_navigation.h"
2323#include "fake_resultsmodel.h"
2424#include "fake_scopes.h"
2525
@@ -27,14 +27,15 @@ Scope::Scope(Scopes* parent) : Scope(QString(), QString(), false, parent)
2727{
2828}
2929
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)
3131 : unity::shell::scopes::ScopeInterface(parent)
3232 , m_id(id)
3333 , m_name(name)
34− , m_visible(visible)
3534 , m_searching(false)
35+ , m_favorite(favorite)
3636 , m_isActive(false)
37− , m_currentDeparment("root")
37+ , m_currentNavigationId("root")
38+ , m_currentAltNavigationId("altroot")
3839 , m_previewRendererName("preview-generic")
3940 , m_categories(new Categories(categories, this))
4041 , m_openScope(nullptr)
@@ -81,6 +82,11 @@ bool Scope::searchInProgress() const
8182 return m_searching;
8283}
8384
85+bool Scope::favorite() const
86+{
87+ return m_favorite;
88+}
89+
8490unity::shell::scopes::CategoriesInterface* Scope::categories() const
8591{
8692 return m_categories;
@@ -101,11 +107,6 @@ QString Scope::formFactor() const
101107 return m_formFactor;
102108}
103109
104−bool Scope::visible() const
105−{
106− return m_visible;
107−}
108−
109110bool Scope::isActive() const
110111{
111112 return m_isActive;
@@ -135,6 +136,13 @@ void Scope::setActive(const bool active)
135136 }
136137}
137138
139+void Scope::setFavorite(const bool favorite)
140+{
141+ if (favorite != m_favorite) {
142+ m_favorite = favorite;
143+ Q_EMIT favoriteChanged();
144+ }
145+}
138146void Scope::setSearchInProgress(const bool inProg)
139147{
140148 if (inProg != m_searching) {
@@ -183,16 +191,31 @@ void Scope::closeScope(unity::shell::scopes::ScopeInterface* scope)
183191 m_openScope = nullptr;
184192}
185193
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
187205{
188− return m_currentDeparment;
206+ return m_currentAltNavigationId;
189207}
190208
191−bool Scope::hasDepartments() const
209+bool Scope::hasAltNavigation() const
192210{
193211 return true;
194212}
195213
214+Scope::Status Scope::status() const
215+{
216+ return Status::Okay;
217+}
218+
196219QVariantMap Scope::customizations() const
197220{
198221 QVariantMap m, h;
@@ -209,7 +232,12 @@ QVariantMap Scope::customizations() const
209232 return m;
210233}
211234
212−unity::shell::scopes::DepartmentInterface* Scope::getDepartment(const QString& id)
235+void Scope::refresh()
236+{
237+ qDebug() << "Scope::refresh is currently not implmented in the fake scopes plugin";
238+}
239+
240+unity::shell::scopes::NavigationInterface* Scope::getNavigation(const QString& id)
213241{
214242 if (id.isEmpty())
215243 return nullptr;
@@ -223,11 +251,30 @@ unity::shell::scopes::DepartmentInterface* Scope::getDepartment(const QString& i
223251 parentId = id.mid(5, 7);
224252 parentLabel = parentId;
225253 }
226− return new Department(id, id, "all"+id, parentId, parentLabel, this);
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+ }
268+ return new Navigation(id, id, "all"+id, parentId, parentLabel, this);
227269}
228270
229−void Scope::loadDepartment(const QString& id)
271+void Scope::setNavigationState(const QString &navigationId, bool isAltNavigation)
230272{
231− m_currentDeparment = id;
232− Q_EMIT currentDepartmentIdChanged();
273+ if (isAltNavigation) {
274+ m_currentAltNavigationId = navigationId;
275+ Q_EMIT currentAltNavigationIdChanged();
276+ } else {
277+ m_currentNavigationId = navigationId;
278+ Q_EMIT currentNavigationIdChanged();
279+ }
233280}
tests/mocks/Unity/fake_scope.h+16−8
@@ -32,7 +32,7 @@ class Scope : public unity::shell::scopes::ScopeInterface
3232
3333public:
3434 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);
3636
3737 /* getters */
3838 QString id() const override;
@@ -40,9 +40,9 @@ public:
4040 QString iconHint() const override;
4141 QString description() const override;
4242 QString searchHint() const override;
43− bool visible() const override;
4443 QString shortcut() const override;
4544 bool searchInProgress() const override;
45+ bool favorite() const override;
4646 unity::shell::scopes::CategoriesInterface* categories() const override;
4747 QString searchQuery() const override;
4848 QString noResultsHint() const override;
@@ -55,6 +55,7 @@ public:
5555 void setNoResultsHint(const QString& hint) override;
5656 void setFormFactor(const QString& form_factor) override;
5757 void setActive(const bool) override;
58+ void setFavorite(const bool) override;
5859 Q_INVOKABLE void setSearchInProgress(const bool inProg); // This is not invokable in the Interface, here for testing benefits
5960
6061 Q_INVOKABLE void activate(QVariant const& result) override;
@@ -62,14 +63,20 @@ public:
6263 Q_INVOKABLE void cancelActivation() override;
6364 Q_INVOKABLE void closeScope(unity::shell::scopes::ScopeInterface* scope) override;
6465
65− QString currentDepartmentId() const override;
66− bool hasDepartments() const override;
67− Q_INVOKABLE unity::shell::scopes::DepartmentInterface* getDepartment(const QString& id) override;
68− Q_INVOKABLE void loadDepartment(const QString& id) override;
66+ QString currentNavigationId() const override;
67+ bool hasNavigation() const 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;
72+ Q_INVOKABLE void setNavigationState(const QString &navigationId, bool isAltNavigation) override;
6973 Q_SIGNAL void performQuery(const QString& query) override;
7074
75+ Status status() const override;
7176 QVariantMap customizations() const override;
7277
78+ Q_INVOKABLE void refresh() override;
79+
7380protected:
7481
7582 QString m_id;
@@ -79,10 +86,11 @@ protected:
7986 QString m_searchQuery;
8087 QString m_noResultsHint;
8188 QString m_formFactor;
82− bool m_visible;
8389 bool m_searching;
90+ bool m_favorite;
8491 bool m_isActive;
85− QString m_currentDeparment;
92+ QString m_currentNavigationId;
93+ QString m_currentAltNavigationId;
8694
8795 QString m_previewRendererName;
8896
tests/mocks/Unity/fake_scopes.cpp+29−18
@@ -34,6 +34,11 @@ Scopes::Scopes(QObject *parent)
3434 timer.setSingleShot(true);
3535 timer.setInterval(100);
3636 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+
3742 load();
3843}
3944
@@ -68,7 +73,8 @@ void Scopes::clear()
6873 timer.stop();
6974 if (m_scopes.size() > 0) {
7075 beginRemoveRows(QModelIndex(), 0, m_scopes.count()-1);
71− qDeleteAll(m_scopes);
76+ qDeleteAll(m_allScopes);
77+ m_allScopes.clear();
7278 m_scopes.clear();
7379 endRemoveRows();
7480 }
@@ -103,8 +109,6 @@ QVariant Scopes::data(const QModelIndex& index, int role) const
103109 return QVariant::fromValue(scope);
104110 } else if (role == Scopes::RoleId) {
105111 return QVariant::fromValue(scope->id());
106− } else if (role == Scopes::RoleVisible) {
107− return QVariant::fromValue(scope->visible());
108112 } else if (role == Scopes::RoleTitle) {
109113 return QVariant::fromValue(scope->name());
110114 } else {
@@ -123,17 +127,17 @@ unity::shell::scopes::ScopeInterface* Scopes::getScope(int row) const
123127
124128unity::shell::scopes::ScopeInterface* Scopes::getScope(QString const &scope_id) const
125129{
130+ // According to mh3 Scopes::getScope should only return favorite scopes (i.e the ones in the model)
126131 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)
129133 return scope;
130134 }
131135 return nullptr;
132136}
133137
134−unity::shell::scopes::ScopeInterface* Scopes::getScopeFromAll(const QString& scope_id) const
138+Scope* Scopes::getScopeFromAll(const QString& scope_id) const
135139{
136− for (Scope *scope : m_scopes) {
140+ for (Scope *scope : m_allScopes) {
137141 if (scope->id() == scope_id)
138142 return scope;
139143 }
@@ -150,26 +154,33 @@ bool Scopes::loaded() const
150154 return m_loaded;
151155}
152156
157+int Scopes::count() const
158+{
159+ return rowCount();
160+}
161+
153162unity::shell::scopes::ScopeInterface* Scopes::overviewScope() const
154163{
155164 return m_scopesOverview;
156165}
157166
158−QList<unity::shell::scopes::ScopeInterface *> Scopes::scopes(bool onlyVisible) const
167+QList<Scope*> Scopes::scopes() const
159168{
160− QList<unity::shell::scopes::ScopeInterface *> res;
161− for (Scope *scope : m_scopes) {
162− if (!onlyVisible || scope->visible()) {
163− res << scope;
164− }
165− }
166− return res;
169+ return m_scopes;
170+}
171+
172+QList<Scope*> Scopes::allScopes() const
173+{
174+ return m_allScopes;
167175}
168176
169177void Scopes::addScope(Scope* scope)
170178{
171179 int index = rowCount();
172− beginInsertRows(QModelIndex(), index, index);
173− m_scopes.append(scope);
174− endInsertRows();
180+ if (scope->favorite()) {
181+ beginInsertRows(QModelIndex(), index, index);
182+ m_scopes.append(scope);
183+ endInsertRows();
184+ }
185+ m_allScopes.append(scope);
175186}
tests/mocks/Unity/fake_scopes.h+6−3
@@ -50,17 +50,20 @@ public:
5050 QModelIndex parent ( const QModelIndex & index ) const;
5151
5252 bool loaded() const override;
53+ int count() const override;
5354 unity::shell::scopes::ScopeInterface* overviewScope() const override;
5455
5556 // 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− unity::shell::scopes::ScopeInterface* getScopeFromAll(const QString& scope_id) const;
57+ QList<Scope*> scopes() const;
58+ QList<Scope*> allScopes() const;
59+ Scope* getScopeFromAll(const QString& scope_id) const;
5860
5961private Q_SLOTS:
6062 void updateScopes();
6163
6264private:
63− QList<Scope*> m_scopes;
65+ QList<Scope*> m_scopes; // the favorite ones
66+ QList<Scope*> m_allScopes;
6467 Scope *m_scopesOverview;
6568 bool m_loaded;
6669 QTimer timer;
tests/mocks/Unity/fake_scopesoverview.cpp+4−3
@@ -81,7 +81,8 @@ ScopesOverviewCategories::data(const QModelIndex& index, int role) const
8181 unity::shell::scopes::ResultsModelInterface *resultsModel = m_resultsModels[index.row()];
8282 if (!resultsModel) {
8383 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);
8586 m_resultsModels[index.row()] = resultsModel;
8687 }
8788 switch (role) {
@@ -158,7 +159,7 @@ ScopesOverviewSearchCategories::data(const QModelIndex& index, int role) const
158159 unity::shell::scopes::ResultsModelInterface *resultsModel = m_resultsModels[index.row()];
159160 if (!resultsModel) {
160161 QObject *that = const_cast<ScopesOverviewSearchCategories*>(this);
161− QList<unity::shell::scopes::ScopeInterface *> scopes;
162+ QList<Scope *> scopes;
162163 if (index.row() == 0) {
163164 scopes << m_scopes->getScopeFromAll("clickscope") << nullptr << m_scopes->getScopeFromAll("MockScope2");
164165 } else {
@@ -207,7 +208,7 @@ ScopesOverviewSearchCategories::data(const QModelIndex& index, int role) const
207208}
208209
209210
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)
211212 : unity::shell::scopes::ResultsModelInterface(parent)
212213 , m_scopes(scopes)
213214 , m_categoryId(categoryId)
tests/mocks/Unity/fake_scopesoverview.h+2−2
@@ -80,7 +80,7 @@ class ScopesOverviewResultsModel : public unity::shell::scopes::ResultsModelInte
8080 Q_OBJECT
8181
8282public:
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);
8484
8585 int rowCount(const QModelIndex& parent = QModelIndex()) const override;
8686 QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
@@ -97,7 +97,7 @@ public:
9797 QHash<int, QByteArray> roleNames() const override;
9898
9999private:
100− QList<unity::shell::scopes::ScopeInterface *> m_scopes;
100+ QList<Scope *> m_scopes;
101101 QString m_categoryId;
102102};
103103
tests/mocks/Unity/fake_unity_plugin.cpp+2−2
@@ -22,7 +22,7 @@
2222// local
2323#include "fake_scopes.h"
2424#include "fake_categories.h"
25−#include "fake_department.h"
25+#include "fake_navigation.h"
2626#include "fake_previewmodel.h"
2727#include "fake_previewwidgetmodel.h"
2828#include "fake_resultsmodel.h"
@@ -43,7 +43,7 @@ void FakeUnityPlugin::registerTypes(const char *uri)
4343 qmlRegisterType<Scopes>(uri, 0, 2, "Scopes");
4444 qmlRegisterType<Scope>(uri, 0, 2, "MockScope");
4545 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.");
4747 qmlRegisterUncreatableType<unity::shell::scopes::CategoriesInterface>(uri, 0, 2, "Categories", "Can't create Categories object in QML.");
4848 qmlRegisterUncreatableType<unity::shell::scopes::PreviewModelInterface>(uri, 0, 2, "PreviewModel", "Can't create new PreviewModel in QML. Get them from PreviewStack instance.");
4949 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 {
3333 visible: image.status == Image.Ready;
3434 readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1;
3535 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; }
38− onAspectSmallerThanImageAspectChanged: updateWidthHeightBindings();
36+ Component.onCompleted: { updateWidthHeightBindings(); if (artShapeBorderSource !== undefined) borderSource = artShapeBorderSource; }
3937 Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); }
4038 function updateWidthHeightBindings() {
4139 if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) {
4240 width = root.fixedArtShapeSize.width;
4341 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 });
4742 } else {
48− width = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.width : height * image.aspect });
49− height = Qt.binding(function() { return !visible ? 0 : image.height });
43+ width = Qt.binding(function() { return !visible ? 0 : image.width });
44+ height = Qt.binding(function() { return !visible ? 0 : image.height });
5045 }
5146 }
5247 image: Image {
@@ -54,8 +49,7 @@ Item {
5449 source: cardData && cardData["art"] || "";
5550 cache: true;
5651 asynchronous: root.asynchronous;
57− fillMode: components && components["art"]["fill-mode"] === "fit" ? Image.PreserveAspectFit: Image.PreserveAspectCrop;
58− readonly property real aspect: implicitWidth / implicitHeight;
52+ fillMode: Image.PreserveAspectCrop;
5953 width: root.width;
6054 height: width / artShape.aspect;
6155 }
@@ -84,5 +78,13 @@ leftMargin: units.gu(1);
8478 font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal;
8579 horizontalAlignment: root.headerAlignment;
8680 }
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+}
8789implicitHeight: titleLabel.y + titleLabel.height + units.gu(1);
8890}
tests/plugins/Dash/cardcreator/1.tst+1−1
@@ -1,3 +1,3 @@
11template: {"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"}}
33result: 1.res
tests/plugins/Dash/cardcreator/2.res+8
@@ -116,5 +116,13 @@ left: parent.left;
116116
117117 ]
118118 }
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+}
119127implicitHeight: row.y + row.height + units.gu(1);
120128}
tests/plugins/Dash/cardcreator/2.tst+1−1
@@ -1,3 +1,3 @@
11template: {"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"}}
33result: 2.res
tests/plugins/Dash/cardcreator/3.res+12−10
@@ -25,7 +25,7 @@ Item {
2525 objectName: "artShapeLoader";
2626 active: cardData && cardData["art"] || false;
2727 asynchronous: root.asynchronous;
28− visible: status == Loader.Ready;
28+ visible: status == Loader.Ready;
2929 sourceComponent: UbuntuShape {
3030 id: artShape;
3131 objectName: "artShape";
@@ -33,20 +33,15 @@ Item {
3333 visible: image.status == Image.Ready;
3434 readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1;
3535 readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1;
36− readonly property bool aspectSmallerThanImageAspect: aspect < image.aspect;
3736 Component.onCompleted: { updateWidthHeightBindings(); if (artShapeBorderSource !== undefined) borderSource = artShapeBorderSource; }
38− onAspectSmallerThanImageAspectChanged: updateWidthHeightBindings();
3937 Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); }
4038 function updateWidthHeightBindings() {
4139 if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) {
4240 width = root.fixedArtShapeSize.width;
4341 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 });
4742 } else {
48− width = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.width : height * image.aspect });
49− height = Qt.binding(function() { return !visible ? 0 : image.height });
43+ width = Qt.binding(function() { return !visible ? 0 : image.width });
44+ height = Qt.binding(function() { return !visible ? 0 : image.height });
5045 }
5146 }
5247 image: Image {
@@ -54,8 +49,7 @@ Item {
5449 source: cardData && cardData["art"] || "";
5550 cache: true;
5651 asynchronous: root.asynchronous;
57− fillMode: components && components["art"]["fill-mode"] === "fit" ? Image.PreserveAspectFit: Image.PreserveAspectCrop;
58− readonly property real aspect: implicitWidth / implicitHeight;
52+ fillMode: Image.PreserveAspectCrop;
5953 width: root.width;
6054 height: width / artShape.aspect;
6155 }
@@ -103,5 +97,13 @@ Label {
10397 font.weight: Font.Light;
10498 horizontalAlignment: root.headerAlignment;
10599 }
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+}
106108implicitHeight: subtitleLabel.y + subtitleLabel.height + units.gu(1);
107109}
tests/plugins/Dash/cardcreator/3.tst+1−1
@@ -1,3 +1,3 @@
11template: {"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"}}
33result: 3.res
tests/plugins/Dash/cardcreator/4.res+8
@@ -94,5 +94,13 @@ Label {
9494}
9595]
9696}
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+}
97105implicitHeight: row.y + row.height + units.gu(1);
98106}
tests/plugins/Dash/cardcreator/4.tst+1−1
@@ -1,3 +1,3 @@
11template: {"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"}}
33result: 4.res
tests/plugins/Dash/cardcreator/5.res+21−17
@@ -25,7 +25,7 @@ Item {
2525 objectName: "artShapeLoader";
2626 active: cardData && cardData["art"] || false;
2727 asynchronous: root.asynchronous;
28− visible: status == Loader.Ready;
28+ visible: status == Loader.Ready;
2929 sourceComponent: UbuntuShape {
3030 id: artShape;
3131 objectName: "artShape";
@@ -33,20 +33,15 @@ Item {
3333 visible: image.status == Image.Ready;
3434 readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1;
3535 readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1;
36− readonly property bool aspectSmallerThanImageAspect: aspect < image.aspect;
3736 Component.onCompleted: { updateWidthHeightBindings(); if (artShapeBorderSource !== undefined) borderSource = artShapeBorderSource; }
38− onAspectSmallerThanImageAspectChanged: updateWidthHeightBindings();
3937 Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); }
4038 function updateWidthHeightBindings() {
4139 if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) {
4240 width = root.fixedArtShapeSize.width;
4341 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 });
4742 } else {
48− width = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.width : height * image.aspect });
49− height = Qt.binding(function() { return !visible ? 0 : image.height });
43+ width = Qt.binding(function() { return !visible ? 0 : image.width });
44+ height = Qt.binding(function() { return !visible ? 0 : image.height });
5045 }
5146 }
5247 image: Image {
@@ -54,13 +49,12 @@ Item {
5449 source: cardData && cardData["art"] || "";
5550 cache: true;
5651 asynchronous: root.asynchronous;
57− fillMode: components && components["art"]["fill-mode"] === "fit" ? Image.PreserveAspectFit: Image.PreserveAspectCrop;
58− readonly property real aspect: implicitWidth / implicitHeight;
52+ fillMode: Image.PreserveAspectCrop;
5953 width: root.width;
6054 height: width / artShape.aspect;
6155 }
6256 }
63− }
57+ }
6458 }
6559Loader {
6660 id: overlayLoader;
@@ -69,13 +63,14 @@ Loader {
6963 right: artShapeHolder.right;
7064 bottom: artShapeHolder.bottom;
7165 }
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;
7367 asynchronous: root.asynchronous;
7468 visible: showHeader && status == Loader.Ready;
7569 sourceComponent: ShaderEffect {
7670 id: overlay;
77− height: (fixedHeaderHeight > 0 ? fixedHeaderHeight : headerHeight) + units.gu(2);
78− opacity: 0.6;
71+ height: (fixedHeaderHeight > 0 ? fixedHeaderHeight : headerHeight) + units.gu(2);
72+ property real luminance: 0.2126 * overlayColor.r + 0.7152 * overlayColor.g + 0.0722 * overlayColor.b;
73+ property color overlayColor: cardData && cardData["overlayColor"] || "#99000000";
7974 property var source: ShaderEffectSource {
8075 id: shaderSource;
8176 sourceItem: artShapeLoader.item;
@@ -96,9 +91,10 @@ Loader {
9691 varying highp vec2 coord;
9792 uniform sampler2D source;
9893 uniform lowp float qt_Opacity;
94+ uniform highp vec4 overlayColor;
9995 void main() {
10096 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;
10298 }";
10399 }
104100 }
@@ -118,7 +114,7 @@ Label {
118114 wrapMode: Text.Wrap;
119115 maximumLineCount: 2;
120116 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");
122118 visible: showHeader && overlayLoader.active;
123119 text: root.title;
124120 font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal;
@@ -137,11 +133,19 @@ Label {
137133 elide: Text.ElideRight;
138134 fontSize: "small";
139135 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");
141137 visible: titleLabel.visible && titleLabel.text;
142138 text: cardData && cardData["subtitle"] || "";
143139 font.weight: Font.Light;
144140 horizontalAlignment: root.headerAlignment;
145141 }
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+}
146150implicitHeight: subtitleLabel.y + subtitleLabel.height + units.gu(1);
147151}
tests/plugins/Dash/cardcreator/5.tst+1−1
@@ -1,3 +1,3 @@
11template: {"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"}}
33result: 5.res
tests/plugins/Dash/cardcreator/6.res+10−8
@@ -33,19 +33,14 @@ Item {
3333 visible: image.status == Image.Ready;
3434 readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1;
3535 readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1;
36− readonly property bool aspectSmallerThanImageAspect: aspect < image.aspect;
3736 Component.onCompleted: { updateWidthHeightBindings(); if (artShapeBorderSource !== undefined) borderSource = artShapeBorderSource; }
38− onAspectSmallerThanImageAspectChanged: updateWidthHeightBindings();
3937 Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); }
4038 function updateWidthHeightBindings() {
4139 if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) {
4240 width = root.fixedArtShapeSize.width;
4341 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 });
4742 } 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 });
4944 height = Qt.binding(function() { return !visible ? 0 : image.height });
5045 }
5146 }
@@ -54,8 +49,7 @@ Item {
5449 source: cardData && cardData["art"] || "";
5550 cache: true;
5651 asynchronous: root.asynchronous;
57− fillMode: components && components["art"]["fill-mode"] === "fit" ? Image.PreserveAspectFit: Image.PreserveAspectCrop;
58− readonly property real aspect: implicitWidth / implicitHeight;
52+ fillMode: Image.PreserveAspectCrop;
5953 width: root.width;
6054 height: width / artShape.aspect;
6155 }
@@ -63,5 +57,13 @@ Item {
6357 }
6458 }
6559readonly 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+}
6668implicitHeight: artShapeHolder.height;
6769}
tests/plugins/Dash/cardcreator/6.tst+1−1
@@ -1,3 +1,3 @@
11template: {"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"}}
33result: 6.res
tests/plugins/Dash/cardcreator/7.res+9−1
@@ -116,7 +116,7 @@ CardAttributes {
116116 objectName: "attributesRow";
117117 anchors { left: parent.left; right: parent.right }
118118 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"];
120120 }
121121
122122 ]
@@ -124,5 +124,13 @@ CardAttributes {
124124
125125 ]
126126 }
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+}
127135implicitHeight: row.y + row.height + units.gu(1);
128136}
tests/plugins/Dash/cardcreator/7.tst+1−1
@@ -1,3 +1,3 @@
11template: {"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}}
33result: 7.res
tests/plugins/Dash/cardcreatortest.cpp+13−4
@@ -19,6 +19,7 @@
1919#include <QQuickItem>
2020#include <QQuickView>
2121#include <QtTestGui>
22+#include <QDebug>
2223#include <QTemporaryFile>
2324
2425class CardCreatorTest : public QObject
@@ -74,15 +75,23 @@ private Q_SLOTS:
7475 QFile testResultFile(testDirPath + resultFileName);
7576 QVERIFY(testResultFile.open(QIODevice::ReadOnly));
7677 QTextStream ts2(&testResultFile);
77− const QString expectedResult = ts2.readAll();
78− const QString executedResult = cardStringResult.toString();
78+
7979 // Record failed results to /tmp
80+ const QString executedResult = cardStringResult.toString();
8081 QTemporaryFile tmpFile(QDir::tempPath() + QDir::separator() + "testCardCreatorFailedResultXXXXXX");
8182 tmpFile.open();
8283 tmpFile.setAutoRemove(false);
8384 tmpFile.write(executedResult.toUtf8().constData());
84− QCOMPARE(executedResult.simplified(), expectedResult.simplified());
85− tmpFile.setAutoRemove(true); // Remove the result if it passed
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) {
90+ QCOMPARE(cardStringResultLines[i].simplified(), expectedLines[i].simplified());
91+ }
92+
93+ // Remove the result if it passed
94+ tmpFile.setAutoRemove(true);
8695
8796 QVariant createCardComponentResult;
8897 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 {
5454 { tag: "lightgrey", luminance: 0.8275 },
5555 { tag: "grey", luminance: 0.5020 },
5656 { tag: "darkgrey", luminance: 0.6627 },
57+ { tag: "red", luminance: 0.2126 },
58+ { tag: "green", luminance: 0.3590 },
59+ { tag: "blue", luminance: 0.0722 },
5760 ];
5861 }
5962
@@ -64,10 +67,10 @@ Rectangle {
6467
6568 function test_foreground_data() {
6669 return [
67− { tag: "default", index: 0, foreground: "grey" },
68− { tag: "red on black", index: 1, foreground: "red" },
69− { tag: "green on white", index: 2, foreground: "green" },
70− { tag: "blue on darkgrey", index: 3, foreground: "blue" },
70+ { tag: "default", index: 0, foreground: "grey", luminance: 0.5020 },
71+ { tag: "red on black", index: 1, foreground: "red", luminance: 0.2126 },
72+ { tag: "green on white", index: 2, foreground: "green", luminance: 0.3590 },
73+ { tag: "blue on darkgrey", index: 3, foreground: "blue", luminance: 0.0722 },
7174 ];
7275 }
7376
@@ -75,14 +78,15 @@ Rectangle {
7578 tool.style = testCase.styles[data.index];
7679 verify(Qt.colorEqual(tool.foreground, data.foreground),
7780 "Foreground color not equal: %1 != %2".arg(tool.foreground).arg(data.foreground));
81+ compare(tool.foregroundLuminance.toFixed(4), data.luminance.toFixed(4));
7882 }
7983
8084 function test_background_data() {
8185 return [
8286 { tag: "default", index: 0, background: "transparent" },
83− { tag: "red on black", index: 1, background: "black" },
84− { tag: "green on white", index: 2, background: "white" },
85− { tag: "blue on darkgrey", index: 3, background: "darkgrey" },
87+ { tag: "red on black", index: 1, background: "black", luminance: 0 },
88+ { tag: "green on white", index: 2, background: "white", luminance: 1 },
89+ { tag: "blue on darkgrey", index: 3, background: "darkgrey", luminance: 0.6627 },
8690 ];
8791 }
8892
@@ -90,6 +94,9 @@ Rectangle {
9094 tool.style = testCase.styles[data.index];
9195 verify(Qt.colorEqual(tool.background, data.background),
9296 "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+ }
93100 }
94101
95102 function test_threshold_data() {
tests/qmltests/CMakeLists.txt+1−1
@@ -30,7 +30,6 @@ add_qml_test(Components Rating)
3030add_qml_test(Components ResponsiveFlowView)
3131add_qml_test(Components ResponsiveGridView)
3232add_qml_test(Components ResponsiveVerticalJournal IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/plugins)
33−add_qml_test(Components SeeMore)
3433add_qml_test(Components Showable)
3534add_qml_test(Components PageHeader)
3635add_qml_test(Components ZoomableImage)
@@ -43,6 +42,7 @@ add_qml_test(Dash GenericScopeView)
4342add_qml_test(Dash/Previews Preview)
4443add_qml_test(Dash/Previews PreviewActions)
4544add_qml_test(Dash/Previews PreviewAudioPlayback)
45+add_qml_test(Dash/Previews PreviewExpandable)
4646add_qml_test(Dash/Previews PreviewHeader)
4747add_qml_test(Dash/Previews PreviewImageGallery)
4848add_qml_test(Dash/Previews PreviewPayments)
tests/qmltests/Components/tst_PageHeader.qml+21−23
@@ -119,29 +119,6 @@ Item {
119119 compare(pageHeader.searchHistory.get(0).query, "humppa4")
120120 }
121121
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−
145122 function test_titleImage() {
146123
147124 var titleImage = findChild(pageHeader, "titleImage");
@@ -192,6 +169,27 @@ Item {
192169 ];
193170 }
194171
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+
195193 function test_popup_closing(data) {
196194 searchEnabled = true;
197195 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 @@
1616
1717.pragma library
1818
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"]
2020
2121var defaultLayout = ' \
2222{ \
@@ -31,10 +31,10 @@ var defaultLayout = ' \
3131 "components": { \
3232 "title": null, \
3333 "art": { \
34− "aspect-ratio": 1.0, \
35− "fill-mode": "crop" \
34+ "aspect-ratio": 1.0 \
3635 }, \
3736 "subtitle": null, \
37+ "overlayColor": null, \
3838 "mascot": null, \
3939 "emblem": null, \
4040 "old-price": null, \
@@ -60,6 +60,7 @@ var fullMapping = ' \
6060 "art": "art", \
6161 "subtitle": "subtitle", \
6262 "mascot": "mascot", \
63+ "overlayColor": "overlayColor", \
6364 "summary": "summary", \
6465 "attributes": "attributes" \
6566}'
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 {
3737
3838 property var widgetDataShortText: {
3939 "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."
4141 }
4242
4343 PreviewTextSummary {
@@ -72,28 +72,14 @@ Rectangle {
7272 tryCompare(textLabel, "y", 0)
7373 }
7474
75− function test_see_more() {
76− var seeMore = findChild(previewTextSummary, "seeMore")
77−
78− // when it's more than textLabel.maximumCollapsedLineCount lines of text, show SeeMore component
75+ function test_show_collapsed() {
7976 verify(textLabel.lineCount > textLabel.maximumCollapsedLineCount)
80− compare(seeMore.visible, true)
81− verify(seeMore.more === false)
82− verify(textLabel.height < textLabel.contentHeight)
8377
84− // test interactions with SeeMore
85− var seeMoreLabel = findChild(seeMore, "seeMoreLabel")
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)
78+ previewTextSummary.expanded = false;
79+ tryCompareFunction(function() { return textLabel.height < textLabel.contentHeight; }, true)
9280
93− // text SeeMore automatic hiding
9481 previewTextSummary.widgetData = widgetDataShortText
9582 verify(textLabel.lineCount <= textLabel.maximumCollapsedLineCount)
96− compare(seeMore.visible, false)
9783 tryCompare(textLabel, "height", textLabel.contentHeight)
9884 tryCompare(previewTextSummary, "height", titleLabel.height + textLabel.height)
9985 }
tests/qmltests/Dash/Previews/tst_PreviewWidgetFactory.qml+1
@@ -77,6 +77,7 @@ Rectangle {
7777 return [
7878 { tag: "Actions", type: "actions", source: "PreviewActions.qml" },
7979 { tag: "Audio", type: "audio", source: "PreviewAudioPlayback.qml" },
80+ { tag: "Expandable", type: "expandable", source: "PreviewExpandable.qml" },
8081 { tag: "Gallery", type: "gallery", source: "PreviewImageGallery.qml" },
8182 { tag: "Header", type: "header", source: "PreviewHeader.qml" },
8283 { tag: "Image", type: "image", source: "PreviewZoomableImage.qml" },
tests/qmltests/Dash/tst_Card.qml+15−3
@@ -55,8 +55,8 @@ Rectangle {
5555 "layout": { "components": Helpers.update(JSON.parse(Helpers.fullMapping), { "art": { "aspect-ratio": 2 } }) }
5656 },
5757 {
58− "name": "Art, title - fitted",
59− "layout": { "components": Helpers.update(JSON.parse(Helpers.fullMapping), { "art": { "fill-mode": "fit" } }) }
58+ "name": "Art, title - tall",
59+ "layout": { "components": Helpers.update(JSON.parse(Helpers.fullMapping), { "art": { "aspect-ratio": 0.7 } }) }
6060 },
6161 {
6262 "name": "Art, header, summary - horizontal",
@@ -269,7 +269,7 @@ Rectangle {
269269 { tag: "Small", width: units.gu(12), index: 1 },
270270 { tag: "Large", width: units.gu(38), index: 2 },
271271 { 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 },
273273 { tag: "VerticalWidth", width: function() { return headerRow.width + units.gu(1) * 2 }, index: 0 },
274274 { tag: "HorizontalHeight", height: function() { return headerRow.height + units.gu(1) * 2 }, index: 5 },
275275 { tag: "HorizontalWidth", width: function() { return headerRow.x - units.gu(1) }, index: 5 },
@@ -475,5 +475,17 @@ Rectangle {
475475 compare(shape !== null, data.shape);
476476 tryCompare(mascotImage, "visible", !data.shape);
477477 }
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+ }
478490 }
479491}
tests/qmltests/Dash/tst_Dash.qml+35−15
@@ -43,12 +43,8 @@ Item {
4343 name: "Dash"
4444 when: windowShown
4545
46− property var scopes
47−
48− Component.onCompleted: {
49− var dashContent = findChild(dash, "dashContent");
50− scopes = dashContent.scopes;
51− }
46+ readonly property Item dashContent: findChild(dash, "dashContent");
47+ readonly property var scopes: dashContent.scopes
5248
5349 function init() {
5450 // clear and reload the scopes.
@@ -62,10 +58,10 @@ Item {
6258
6359 function get_scope_data() {
6460 return [
65− { tag: "MockScope1", visualIndex: 0, shouldBeVisible: true },
66− { tag: "MockScope2", visualIndex: -1, shouldBeVisible: false },
67− { tag: "clickscope", visualIndex: 1, shouldBeVisible: true },
68− { tag: "MockScope5", visualIndex: 2, shouldBeVisible: true },
61+ { tag: "MockScope1", visualIndex: 0 },
62+ { tag: "MockScope2", visualIndex: -1 },
63+ { tag: "clickscope", visualIndex: 1 },
64+ { tag: "MockScope5", visualIndex: 2 },
6965 ]
7066 }
7167
@@ -74,10 +70,6 @@ Item {
7470 }
7571
7672 function test_show_scope_on_load(data) {
77− if (data.shouldBeVisible == false) {
78− console.log("Not testing " + data.tag + ": not visible");
79− return;
80− }
8173 var dashContentList = findChild(dash, "dashContentList");
8274
8375 dash.showScopeOnLoaded = data.tag
@@ -88,7 +80,14 @@ Item {
8880 tryCompare(dashContentList, "count", 6);
8981
9082 verify(dashContentList != undefined);
91− tryCompare(dashContentList, "currentIndex", data.visualIndex);
83+ if (data.visualIndex == -1) {
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+ }
9291 }
9392
9493 function test_dash_overview_show_select_same_favorite() {
@@ -325,5 +324,26 @@ Item {
325324 dashCommunicatorService.mockSetCurrentScope("clickscope", true, true);
326325 tryCompare(dashContentList, "currentIndex", 1)
327326 }
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+ }
328348 }
329349}
tests/qmltests/Dash/tst_DashContent.qml+99−100
@@ -43,9 +43,6 @@ Item {
4343 id: dashContent
4444 anchors.fill: parent
4545
46− model: SortFilterProxyModel {
47− model: scopesModel
48− }
4946 scopes : scopesModel
5047 }
5148
@@ -73,7 +70,7 @@ Item {
7370 function loadScopes() {
7471 scopeLoadedSpy.clear();
7572 scopesModel.load();
76− tryCompare(scopeLoadedSpy, "count", 10);
73+ tryCompare(scopeLoadedSpy, "count", 6);
7774 }
7875
7976 function init() {
@@ -117,7 +114,7 @@ Item {
117114
118115 loadScopes();
119116
120− compare(dashContentList.count, 10);
117+ compare(dashContentList.count, 6);
121118 verify(dashContentList.currentIndex >= 0 && dashContentList.currentIndex < dashContentList.count);
122119 }
123120
@@ -193,9 +190,9 @@ Item {
193190 function test_scope_mapping_data() {
194191 return [
195192 {tag: "index0", index: 0, objectName: "MockScope1"},
196− {tag: "index1", index: 1, objectName: "MockScope2"},
197− {tag: "index2", index: 2, objectName: "clickscope"},
198− {tag: "index3", index: 3, objectName: "MockScope5"}
193+ {tag: "index1", index: 1, objectName: "clickscope"},
194+ {tag: "index2", index: 2, objectName: "MockScope5"},
195+ {tag: "index3", index: 3, objectName: "SingleCategoryScope"}
199196 ]
200197 }
201198
@@ -269,117 +266,119 @@ Item {
269266 verify(carouselLV.tileWidth / carouselLV.tileHeight == cardTool.components["art"]["aspect-ratio"]);
270267 }
271268
272− function test_departments() {
273− var dashDepartments = findChild(dashContent, "dashDepartments");
274− compare(dashDepartments.visible, true);
275− compare(dashDepartments.showList, false);
276− waitForRendering(dashDepartments);
277− mouseClick(dashDepartments, 0, 0);
278− compare(dashDepartments.showList, true);
279−
280− var departmentListView = findChild(dashDepartments, "departmentListView");
281− compare(departmentListView.count, 1);
282− tryCompare(departmentListView.currentItem.department, "loaded", true);
283−
284− waitForRendering(departmentListView);
285− waitForRendering(departmentListView.currentItem);
286−
287− var allButton = findChild(dashDepartments, "allButton");
269+ function test_navigations() {
270+ var dashContentList = findChild(dashContent, "dashContentList");
271+ tryCompareFunction(function() { return findChild(dashContentList.currentItem, "dashNavigation") != null; }, true);
272+ var dashNavigation = findChild(dashContentList.currentItem, "dashNavigation");
273+ tryCompare(dashNavigation, "visible", true);
274+ compare(dashNavigation.showList, false);
275+ waitForRendering(dashNavigation);
276+ mouseClick(dashNavigation, 0, 0);
277+ compare(dashNavigation.showList, true);
278+
279+ var navigationListView = findChild(dashNavigation, "navigationListView");
280+ compare(navigationListView.count, 1);
281+ tryCompare(navigationListView.currentItem.navigation, "loaded", true);
282+
283+ waitForRendering(navigationListView);
284+ waitForRendering(navigationListView.currentItem);
285+
286+ var allButton = findChild(dashNavigation, "allButton");
288287 compare(allButton.visible, false);
289288
290− var department = findChild(dashDepartments, "department0child3");
291− mouseClick(department, 0, 0);
292− compare(dashDepartments.showList, false);
293− tryCompare(dashDepartments.currentDepartment, "departmentId", "middle3");
294− tryCompare(departmentListView.currentItem.department, "departmentId", "root");
289+ var navigation = findChild(dashNavigation, "navigation0child3");
290+ mouseClick(navigation, 0, 0);
291+ compare(dashNavigation.showList, false);
292+ tryCompare(dashNavigation.currentNavigation, "navigationId", "middle3");
293+ tryCompare(navigationListView.currentItem.navigation, "navigationId", "root");
295294
296− mouseClick(dashDepartments, 0, 0);
297− compare(dashDepartments.showList, true);
298− waitForRendering(departmentListView);
299− waitForRendering(departmentListView.currentItem);
295+ mouseClick(dashNavigation, 0, 0);
296+ compare(dashNavigation.showList, true);
297+ waitForRendering(navigationListView);
298+ waitForRendering(navigationListView.currentItem);
300299 compare(allButton.visible, true);
301300
302301 mouseClick(allButton, 0, 0);
303− compare(dashDepartments.showList, false);
304− tryCompare(dashDepartments.currentDepartment, "departmentId", "root");
305− tryCompare(departmentListView.currentItem.department, "departmentId", "root");
306−
307− mouseClick(dashDepartments, 0, 0);
308− compare(dashDepartments.showList, true);
309− waitForRendering(departmentListView);
310− waitForRendering(departmentListView.currentItem);
302+ compare(dashNavigation.showList, false);
303+ tryCompare(dashNavigation.currentNavigation, "navigationId", "root");
304+ tryCompare(navigationListView.currentItem.navigation, "navigationId", "root");
305+
306+ mouseClick(dashNavigation, 0, 0);
307+ compare(dashNavigation.showList, true);
308+ waitForRendering(navigationListView);
309+ waitForRendering(navigationListView.currentItem);
311310 compare(allButton.visible, false);
312311
313− department = findChild(dashDepartments, "department0child2");
314− mouseClick(department, 0, 0);
315− compare(dashDepartments.showList, true);
316− tryCompare(dashDepartments.currentDepartment, "departmentId", "middle2");
317− tryCompare(departmentListView.currentItem.department, "departmentId", "middle2");
312+ navigation = findChild(dashNavigation, "navigation0child2");
313+ mouseClick(navigation, 0, 0);
314+ compare(dashNavigation.showList, true);
315+ tryCompare(dashNavigation.currentNavigation, "navigationId", "middle2");
316+ tryCompare(navigationListView.currentItem.navigation, "navigationId", "middle2");
318317
319− var departmentList1 = findChild(dashDepartments, "department1");
320− allButton = findChild(departmentList1, "allButton");
321− var backButton = findChild(findChild(departmentList1, "department1"), "backButton");
318+ var navigationList1 = findChild(dashNavigation, "navigation1");
319+ allButton = findChild(navigationList1, "allButton");
320+ var backButton = findChild(findChild(navigationList1, "navigation1"), "backButton");
322321 compare(allButton.visible, true);
323322 compare(backButton.visible, true);
324323
325− tryCompare(departmentListView, "contentX", departmentList1.x);
326− waitForRendering(departmentListView);
324+ tryCompare(navigationListView, "contentX", navigationList1.x);
325+ waitForRendering(navigationListView);
327326 mouseClick(allButton, 0, 0);
328− compare(dashDepartments.showList, false);
329− tryCompare(dashDepartments.currentDepartment, "departmentId", "middle2");
330− tryCompare(departmentListView.currentItem.department, "departmentId", "middle2");
331−
332− mouseClick(dashDepartments, 0, 0);
333− compare(dashDepartments.showList, true);
334− waitForRendering(departmentListView);
335− waitForRendering(departmentListView.currentItem);
327+ compare(dashNavigation.showList, false);
328+ tryCompare(dashNavigation.currentNavigation, "navigationId", "middle2");
329+ tryCompare(navigationListView.currentItem.navigation, "navigationId", "middle2");
330+
331+ mouseClick(dashNavigation, 0, 0);
332+ compare(dashNavigation.showList, true);
333+ waitForRendering(navigationListView);
334+ waitForRendering(navigationListView.currentItem);
336335 compare(allButton.visible, true);
337336 compare(backButton.visible, true);
338337
339− tryCompare(departmentList1.department, "loaded", true);
340− department = findChild(dashDepartments, "department1child2");
341− mouseClick(department, 0, 0);
342− compare(dashDepartments.showList, false);
343− tryCompare(dashDepartments.currentDepartment, "departmentId", "childmiddle22");
344− tryCompare(departmentListView.currentItem.department, "departmentId", "middle2");
345−
346− mouseClick(dashDepartments, 0, 0);
347− compare(dashDepartments.showList, true);
348− waitForRendering(departmentListView);
349− waitForRendering(departmentListView.currentItem);
350−
351− tryCompare(departmentList1.department, "loaded", true);
352− department = findChild(dashDepartments, "department1child3");
353− mouseClick(department, 0, 0);
354− compare(dashDepartments.showList, false);
355− tryCompare(dashDepartments.currentDepartment, "departmentId", "childmiddle23");
356− tryCompare(departmentListView.currentItem.department, "departmentId", "middle2");
357−
358− mouseClick(dashDepartments, 0, 0);
359− compare(dashDepartments.showList, true);
360− waitForRendering(departmentListView);
361− waitForRendering(departmentListView.currentItem);
338+ tryCompare(navigationList1.navigation, "loaded", true);
339+ navigation = findChild(dashNavigation, "navigation1child2");
340+ mouseClick(navigation, 0, 0);
341+ compare(dashNavigation.showList, false);
342+ tryCompare(dashNavigation.currentNavigation, "navigationId", "childmiddle22");
343+ tryCompare(navigationListView.currentItem.navigation, "navigationId", "middle2");
344+
345+ mouseClick(dashNavigation, 0, 0);
346+ compare(dashNavigation.showList, true);
347+ waitForRendering(navigationListView);
348+ waitForRendering(navigationListView.currentItem);
349+
350+ tryCompare(navigationList1.navigation, "loaded", true);
351+ navigation = findChild(dashNavigation, "navigation1child3");
352+ mouseClick(navigation, 0, 0);
353+ compare(dashNavigation.showList, false);
354+ tryCompare(dashNavigation.currentNavigation, "navigationId", "childmiddle23");
355+ tryCompare(navigationListView.currentItem.navigation, "navigationId", "middle2");
356+
357+ mouseClick(dashNavigation, 0, 0);
358+ compare(dashNavigation.showList, true);
359+ waitForRendering(navigationListView);
360+ waitForRendering(navigationListView.currentItem);
362361 mouseClick(backButton, 0, 0);
363362
364− tryCompare(dashDepartments.currentDepartment, "departmentId", "root");
365− tryCompare(departmentListView.currentItem.department, "departmentId", "root");
366− compare(dashDepartments.showList, true);
367− mouseClick(dashDepartments, 0, 0);
368− compare(dashDepartments.showList, false);
369−
370− mouseClick(dashDepartments, 0, 0);
371− compare(dashDepartments.showList, true);
372− tryCompare(departmentListView.currentItem.department, "loaded", true);
373− department = findChild(dashDepartments, "department0child2");
374− mouseClick(department, 0, 0);
375− compare(dashDepartments.showList, true);
376− departmentList1 = findChild(dashDepartments, "department1");
377− compare(departmentList1.department.loaded, false);
378− tryCompare(dashDepartments.currentDepartment, "departmentId", "middle2");
379− allButton = findChild(departmentList1, "allButton");
380− tryCompare(dashDepartments.currentDepartment, "departmentId", "middle2");
363+ tryCompare(dashNavigation.currentNavigation, "navigationId", "root");
364+ tryCompare(navigationListView.currentItem.navigation, "navigationId", "root");
365+ compare(dashNavigation.showList, true);
366+ mouseClick(dashNavigation, 0, 0);
367+ compare(dashNavigation.showList, false);
368+
369+ mouseClick(dashNavigation, 0, 0);
370+ compare(dashNavigation.showList, true);
371+ tryCompare(navigationListView.currentItem.navigation, "loaded", true);
372+ navigation = findChild(dashNavigation, "navigation0child2");
373+ mouseClick(navigation, 0, 0);
374+ compare(dashNavigation.showList, true);
375+ navigationList1 = findChild(dashNavigation, "navigation1");
376+ compare(navigationList1.navigation.loaded, false);
377+ tryCompare(dashNavigation.currentNavigation, "navigationId", "middle2");
378+ allButton = findChild(navigationList1, "allButton");
379+ tryCompare(dashNavigation.currentNavigation, "navigationId", "middle2");
381380 mouseClick(allButton, 0, 0);
382− tryCompare(dashDepartments.currentDepartment, "departmentId", "middle2");
381+ tryCompare(dashNavigation.currentNavigation, "navigationId", "middle2");
383382 }
384383
385384 function test_searchHint() {
tests/qmltests/Dash/tst_GenericScopeView.qml+15−11
@@ -61,8 +61,8 @@ Item {
6161 property Item header: findChild(genericScopeView, "scopePageHeader")
6262
6363 function init() {
64− genericScopeView.scope = scopes.getScope(1)
65− shell.width = units.gu(120)
64+ genericScopeView.scope = scopes.getScope(2);
65+ shell.width = units.gu(120);
6666 genericScopeView.categoryView.positionAtBeginning();
6767 waitForRendering(genericScopeView.categoryView);
6868 }
@@ -88,13 +88,13 @@ Item {
8888
8989 function test_showDash() {
9090 testCase.previewListView.open = true;
91− scopes.getScope(1).showDash();
91+ genericScopeView.scope.showDash();
9292 tryCompare(testCase.previewListView, "open", false);
9393 }
9494
9595 function test_hideDash() {
9696 testCase.previewListView.open = true;
97− scopes.getScope(1).hideDash();
97+ genericScopeView.scope.hideDash();
9898 tryCompare(testCase.previewListView, "open", false);
9999 }
100100
@@ -111,8 +111,9 @@ Item {
111111
112112 function test_changeScope() {
113113 genericScopeView.scope.searchQuery = "test"
114− genericScopeView.scope = scopes.getScope(2)
115− genericScopeView.scope = scopes.getScope(1)
114+ var originalScopeId = genericScopeView.scope.id;
115+ genericScopeView.scope = scopes.getScope(originalScopeId + 1)
116+ genericScopeView.scope = scopes.getScope(originalScopeId)
116117 tryCompare(genericScopeView.scope, "searchQuery", "test")
117118 }
118119
@@ -129,8 +130,9 @@ Item {
129130 var initialHeight = category.height;
130131 mouseClick(seeAll, seeAll.width / 2, seeAll.height / 2);
131132 verify(category.expanded);
132− tryCompareFunction(function() { return category.height > initialHeight; }, true);
133+ tryCompare(category, "height", category.item.expandedHeight + seeAll.height);
133134
135+ waitForRendering(seeAll);
134136 mouseClick(seeAll, seeAll.width / 2, seeAll.height / 2);
135137 verify(!category.expanded);
136138 }
@@ -197,6 +199,8 @@ Item {
197199 openPreview(4, 0);
198200
199201 compare(testCase.previewListView.count, 12, "There should only be 12 items in preview.");
202+
203+ closePreview();
200204 }
201205
202206 function test_narrow_delegate_ranges_expand() {
@@ -231,7 +235,7 @@ Item {
231235 }
232236
233237 function test_single_category_expansion() {
234− genericScopeView.scope = scopes.getScope(4);
238+ genericScopeView.scope = scopes.getScope(3);
235239
236240 tryCompareFunction(function() { return findChild(genericScopeView, "dashCategory0") != undefined; }, true);
237241 var category = findChild(genericScopeView, "dashCategory0")
@@ -319,7 +323,7 @@ Item {
319323 units.gu(2),
320324 testCase.previewListView.height / 2);
321325 tryCompare(previewListViewList, "moving", false);
322− tryCompare(testCase.previewListView.currentItem, "objectName", "previewItem" + i);
326+ tryCompare(testCase.previewListView.currentItem, "objectName", "preview" + i);
323327
324328 }
325329 closePreview();
@@ -328,8 +332,8 @@ Item {
328332 function test_header_style_data() {
329333 return [
330334 { tag: "Default", index: 0, foreground: "grey", background: "", logo: "" },
331− { tag: "Foreground", index: 2, foreground: "yellow", background: "", logo: "" },
332− { tag: "Logo+Background", index: 3, foreground: "grey", background: "gradient:///lightgrey/grey",
335+ { tag: "Foreground", index: 1, foreground: "yellow", background: "", logo: "" },
336+ { tag: "Logo+Background", index: 2, foreground: "grey", background: "gradient:///lightgrey/grey",
333337 logo: Qt.resolvedUrl("../Components/tst_PageHeader/logo-ubuntu-orange.svg") },
334338 ];
335339 }
tests/qmltests/Panel/Indicators/tst_MenuItemFactory.qml+47
@@ -112,6 +112,7 @@ Item {
112112
113113 { tag: 'wifisection', type: "unity.widgets.systemsettings.tablet.wifisection", objectName: "wifiSection" },
114114 { tag: 'accesspoint', type: "unity.widgets.systemsettings.tablet.accesspoint", objectName: "accessPoint" },
115+ { tag: 'modeminfoitem', type: "com.canonical.indicator.network.modeminfoitem", objectName: "modemInfoItem" },
115116
116117 { tag: 'unknown', type: "", objectName: "standardMenu"}
117118 ];
@@ -542,6 +543,52 @@ Item {
542543 compare(loader.item.enabled, data.enabled, "Enabled does not match data");
543544 }
544545
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+
545592 function test_create_messageItem() {
546593 menuData.type = "com.canonical.indicator.messages.messageitem";
547594