on xenial help sign in
Merge
440b8d8Albert Astals
cmake/modules/QmlTest.cmake+2−2
@@ -135,7 +135,7 @@ macro(add_binary_qml_test CLASS_NAME LD_PATH DEPS)
135 set(testCommand
135 set(testCommand
136 LD_LIBRARY_PATH=${LD_PATH}
136 LD_LIBRARY_PATH=${LD_PATH}
137 ${CMAKE_CURRENT_BINARY_DIR}/${CLASS_NAME}TestExec
137 ${CMAKE_CURRENT_BINARY_DIR}/${CLASS_NAME}TestExec
138− -o ${CMAKE_BINARY_DIR}/${CLASS_NAME}Test.xml,xunitxml
138+ -o ${CMAKE_BINARY_DIR}/test${CLASS_NAME}.xml,xunitxml
139 -o -,txt)
139 -o -,txt)
140
140
141 add_qmltest_target(test${CLASS_NAME} "${testCommand}" FALSE TRUE)
141 add_qmltest_target(test${CLASS_NAME} "${testCommand}" FALSE TRUE)
@@ -151,7 +151,7 @@ macro(add_binary_qml_test CLASS_NAME LD_PATH DEPS)
151 LD_LIBRARY_PATH=${LD_PATH}
151 LD_LIBRARY_PATH=${LD_PATH}
152 xvfb-run --server-args "-screen 0 1024x768x24" --auto-servernum
152 xvfb-run --server-args "-screen 0 1024x768x24" --auto-servernum
153 ${CMAKE_CURRENT_BINARY_DIR}/${CLASS_NAME}TestExec
153 ${CMAKE_CURRENT_BINARY_DIR}/${CLASS_NAME}TestExec
154− -o ${CMAKE_BINARY_DIR}/${CLASS_NAME}Test.xml,xunitxml
154+ -o ${CMAKE_BINARY_DIR}/test${CLASS_NAME}.xml,xunitxml
155 -o -,txt)
155 -o -,txt)
156
156
157 add_qmltest_target(xvfbtest${CLASS_NAME} "${xvfbtestCommand}" FALSE TRUE)
157 add_qmltest_target(xvfbtest${CLASS_NAME} "${xvfbtestCommand}" FALSE TRUE)
debian/changelog+58
@@ -1,3 +1,61 @@
1+unity8 (8.00+14.10.20140806.1-0ubuntu1) utopic; urgency=low
2+
3+ [ Michal Hruby ]
4+ * Work with the scopes-v4 branch + departments->navigation renaming
5+
6+ [ Michał Sawicz ]
7+ * Hardcode art shape size for click scope local and predefined
8+ categories While at it, drop the fillmode of cards
9+ * Use the correct API in PageHeader. (LP: #1353048)
10+ * Refactor dash activity indicator. (LP: #1351539)
11+
12+ [ Albert Astals ]
13+ * Dash Departments fixes Update maxHeight manually since it depends on
14+ the position of the item and its parents and it can't know when the
15+ binding has to be updated Make parent stuff non interactive when the
16+ department list is shown
17+ * PageHeader: when on search clip y-coordinates otherwise the
18+ background spills out when on search (LP: #1350398)
19+ * Dash: Implement OverlayColor support in Cards
20+ * Hardcode art shape size for click scope local and predefined
21+ categories While at it, drop the fillmode of cards
22+ * Make test_departments test more stable There's various
23+ DashDepartments on the dash, make sure we're working over the one
24+ that is on screen, otherwise clicks don't end up where they should
25+ * Work with the scopes-v4 branch + departments->navigation renaming
26+ * Fixes for dash as app Load i18n catalog Process command line options
27+ Add the posibility to have a mouse touch adaptor (LP: #1353351)
28+ * Implement the Expandable Preview Widget Now TextSummary is not
29+ expandable by itself anymore, you have to use it inside an
30+ Expandable to get the behaviour
31+ * Add test prefix to xml output, seems CI needs it
32+
33+ [ Antti Kaijanmäki ]
34+ * Indicators: Adds new ModemInfoItem to be used with indicator-network
35+ (LP: #1329204)
36+
37+ [ Michael Terry ]
38+ * When the edge demo is running, don't show the greeter if the screen
39+ is turned off. This avoids an odd interaction where parts of the
40+ greeter are disabled but the edge demo isn't visible until you slide
41+ the greeter away. (LP: #1283425)
42+ * Don't hardcode the phablet password in our testing script.
43+
44+ [ Ying-Chun Liu ]
45+ * Add divider dots.
46+
47+ [ Mirco Müller ]
48+ * Make sure the TextField of a snap-decision notification has the
49+ active focus upon creation, thus the osk shows up right away. (LP:
50+ #1346867)
51+
52+ [ Andrea Cimitan ]
53+ * Add touchdown effect to dash cards.
54+ * Import Ubuntu.Components for preview image gallery to pick up
55+ default flicking speeds.
56+
57+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Wed, 06 Aug 2014 19:40:05 +0000
58+
1unity8 (8.00+14.10.20140805-0ubuntu1) utopic; urgency=low
59unity8 (8.00+14.10.20140805-0ubuntu1) utopic; urgency=low
2
60
3 [ Michael Zanetti ]
61 [ Michael Zanetti ]
plugins/Dash/CardCreator.js+26−12
@@ -71,19 +71,14 @@ var kArtShapeHolderCode = 'Item { \n\
71 visible: image.status == Image.Ready; \n\
71 visible: image.status == Image.Ready; \n\
72 readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1; \n\
72 readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1; \n\
73 readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1; \n\
73 readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1; \n\
74− readonly property bool aspectSmallerThanImageAspect: aspect < image.aspect; \n\
75 Component.onCompleted: { updateWidthHeightBindings(); if (artShapeBorderSource !== undefined) borderSource = artShapeBorderSource; } \n\
74 Component.onCompleted: { updateWidthHeightBindings(); if (artShapeBorderSource !== undefined) borderSource = artShapeBorderSource; } \n\
76− onAspectSmallerThanImageAspectChanged: updateWidthHeightBindings(); \n\
77 Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); } \n\
75 Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); } \n\
78 function updateWidthHeightBindings() { \n\
76 function updateWidthHeightBindings() { \n\
79 if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) { \n\
77 if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) { \n\
80 width = root.fixedArtShapeSize.width; \n\
78 width = root.fixedArtShapeSize.width; \n\
81 height = root.fixedArtShapeSize.height; \n\
79 height = root.fixedArtShapeSize.height; \n\
82− } else if (aspectSmallerThanImageAspect) { \n\
83− width = Qt.binding(function() { return !visible ? 0 : image.width }); \n\
84− height = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.height : width / image.aspect }); \n\
85 } else { \n\
80 } else { \n\
86− width = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.width : height * image.aspect }); \n\
81+ width = Qt.binding(function() { return !visible ? 0 : image.width }); \n\
87 height = Qt.binding(function() { return !visible ? 0 : image.height }); \n\
82 height = Qt.binding(function() { return !visible ? 0 : image.height }); \n\
88 } \n\
83 } \n\
89 } \n\
84 } \n\
@@ -92,8 +87,7 @@ var kArtShapeHolderCode = 'Item { \n\
92 source: cardData && cardData["art"] || ""; \n\
87 source: cardData && cardData["art"] || ""; \n\
93 cache: true; \n\
88 cache: true; \n\
94 asynchronous: root.asynchronous; \n\
89 asynchronous: root.asynchronous; \n\
95− fillMode: components && components["art"]["fill-mode"] === "fit" ? Image.PreserveAspectFit: Image.PreserveAspectCrop; \n\
90+ fillMode: Image.PreserveAspectCrop; \n\
96− readonly property real aspect: implicitWidth / implicitHeight; \n\
97 width: %2; \n\
91 width: %2; \n\
98 height: %3; \n\
92 height: %3; \n\
99 } \n\
93 } \n\
@@ -114,7 +108,7 @@ var kOverlayLoaderCode = 'Loader { \n\
114 sourceComponent: ShaderEffect { \n\
108 sourceComponent: ShaderEffect { \n\
115 id: overlay; \n\
109 id: overlay; \n\
116 height: (fixedHeaderHeight > 0 ? fixedHeaderHeight : headerHeight) + units.gu(2); \n\
110 height: (fixedHeaderHeight > 0 ? fixedHeaderHeight : headerHeight) + units.gu(2); \n\
117− opacity: 0.6; \n\
111+ property color overlayColor: cardData && cardData["overlayColor"] || "#99000000"; \n\
118 property var source: ShaderEffectSource { \n\
112 property var source: ShaderEffectSource { \n\
119 id: shaderSource; \n\
113 id: shaderSource; \n\
120 sourceItem: artShapeLoader.item; \n\
114 sourceItem: artShapeLoader.item; \n\
@@ -135,9 +129,10 @@ var kOverlayLoaderCode = 'Loader { \n\
135 varying highp vec2 coord; \n\
129 varying highp vec2 coord; \n\
136 uniform sampler2D source; \n\
130 uniform sampler2D source; \n\
137 uniform lowp float qt_Opacity; \n\
131 uniform lowp float qt_Opacity; \n\
132+ uniform highp vec4 overlayColor; \n\
138 void main() { \n\
133 void main() { \n\
139 lowp vec4 tex = texture2D(source, coord); \n\
134 lowp vec4 tex = texture2D(source, coord); \n\
140− gl_FragColor = vec4(0, 0, 0, tex.a) * qt_Opacity; \n\
135+ gl_FragColor = vec4(overlayColor.r, overlayColor.g, overlayColor.b, 1) * qt_Opacity * overlayColor.a * tex.a; \n\
141 }"; \n\
136 }"; \n\
142 } \n\
137 } \n\
143 }\n';
138 }\n';
@@ -257,6 +252,16 @@ var kTitleLabelCode = 'Label { \n\
257 horizontalAlignment: root.headerAlignment; \n\
252 horizontalAlignment: root.headerAlignment; \n\
258 }\n';
253 }\n';
259
254
255+// %1 is used as anchors of touchdown effect
256+var kTouchdownCode = 'UbuntuShape { \n\
257+ id: touchdown; \n\
258+ objectName: "touchdown"; \n\
259+ anchors { %1 } \n\
260+ visible: root.pressed; \n\
261+ radius: "medium"; \n\
262+ borderSource: "radius_pressed.sci" \n\
263+ }\n';
264+
260// %1 is used as anchors of subtitleLabel
265// %1 is used as anchors of subtitleLabel
261// %2 is used as color of subtitleLabel
266// %2 is used as color of subtitleLabel
262var kSubtitleLabelCode = 'Label { \n\
267var kSubtitleLabelCode = 'Label { \n\
@@ -279,7 +284,7 @@ var kAttributesRowCode = 'CardAttributes { \n\
279 objectName: "attributesRow"; \n\
284 objectName: "attributesRow"; \n\
280 anchors { %1 } \n\
285 anchors { %1 } \n\
281 color: %2; \n\
286 color: %2; \n\
282− model: cardData && cardData["attributes"] || undefined; \n\
287+ model: cardData["attributes"]; \n\
283 }\n';
288 }\n';
284
289
285// %1 is used as top anchor of summary
290// %1 is used as top anchor of summary
@@ -569,6 +574,16 @@ function cardString(template, components) {
569 code += kSummaryLabelCode.arg(summaryTopAnchor).arg(summaryTopMargin).arg(color);
574 code += kSummaryLabelCode.arg(summaryTopAnchor).arg(summaryTopMargin).arg(color);
570 }
575 }
571
576
577+ var touchdownAnchors;
578+ if (hasBackground) {
579+ touchdownAnchors = 'fill: backgroundLoader';
580+ } else if (hasArt && !hasMascot && !hasSummary) {
581+ touchdownAnchors = 'fill: artShapeHolder';
582+ } else {
583+ touchdownAnchors = 'fill: root'
584+ }
585+ code += kTouchdownCode.arg(touchdownAnchors);
586+
572 if (hasSummary) {
587 if (hasSummary) {
573 code += 'implicitHeight: summary.y + summary.height + (summary.text ? units.gu(1) : 0);\n';
588 code += 'implicitHeight: summary.y + summary.height + (summary.text ? units.gu(1) : 0);\n';
574 } else if (hasHeaderRow) {
589 } else if (hasHeaderRow) {
@@ -593,7 +608,6 @@ function cardString(template, components) {
593function createCardComponent(parent, template, components) {
608function createCardComponent(parent, template, components) {
594 var imports = 'import QtQuick 2.2; \n\
609 var imports = 'import QtQuick 2.2; \n\
595 import Ubuntu.Components 0.1; \n\
610 import Ubuntu.Components 0.1; \n\
596− import Ubuntu.Thumbnailer 0.1;\n\
597 import Dash 0.1;\n';
611 import Dash 0.1;\n';
598 var card = cardString(template, components);
612 var card = cardString(template, components);
599 var code = imports + 'Component {\n' + card + '}\n';
613 var code = imports + 'Component {\n' + card + '}\n';
plugins/Dash/ScopeStyle.qml+11−8
@@ -38,14 +38,20 @@ QtObject {
38 /// Color used for text and symbolic icons
38 /// Color used for text and symbolic icons
39 readonly property color foreground: "foreground-color" in style ? style["foreground-color"] : d.defaultDark
39 readonly property color foreground: "foreground-color" in style ? style["foreground-color"] : d.defaultDark
40
40
41+ /// Luminance of the foreground color
42+ readonly property real foregroundLuminance: foreground ? luminance(foreground) : d.defaultForegroundLuminance
43+
41 /// Color used for the overall background
44 /// Color used for the overall background
42 readonly property color background: "background-color" in style ? style["background-color"] : "transparent"
45 readonly property color background: "background-color" in style ? style["background-color"] : "transparent"
43
46
47+ /// Luminance of the foreground color
48+ readonly property real backgroundLuminance: background ? luminance(background) : d.defaultBackgroundLuminance
49+
44 /*! \brief Luminance threshold for switching between fore and background color
50 /*! \brief Luminance threshold for switching between fore and background color
45
51
46 \note If background colour is not fully opaque, it's not taken into account.
52 \note If background colour is not fully opaque, it's not taken into account.
47 */
53 */
48− readonly property real threshold: background.a !== 1.0 ? d.foregroundLuminance : (d.foregroundLuminance + d.backgroundLuminance) / 2
54+ readonly property real threshold: background.a !== 1.0 ? foregroundLuminance : (foregroundLuminance + backgroundLuminance) / 2
49
55
50 /*! \brief The lighter of foreground and background colors
56 /*! \brief The lighter of foreground and background colors
51
57
@@ -53,8 +59,8 @@ QtObject {
53 and defaults to the theme-provided light color.
59 and defaults to the theme-provided light color.
54 */
60 */
55 readonly property color light: {
61 readonly property color light: {
56− if (background.a !== 1.0) return d.foregroundLuminance > d.defaultLightLuminance ? foreground : d.defaultLight;
62+ if (background.a !== 1.0) return foregroundLuminance > d.defaultLightLuminance ? foreground : d.defaultLight;
57− return d.foregroundLuminance > d.backgroundLuminance ? foreground : background;
63+ return foregroundLuminance > backgroundLuminance ? foreground : background;
58 }
64 }
59
65
60 /*! \brief The darker of foreground and background colors
66 /*! \brief The darker of foreground and background colors
@@ -63,8 +69,8 @@ QtObject {
63 and defaults to the theme-provided dark color.
69 and defaults to the theme-provided dark color.
64 */
70 */
65 readonly property color dark: {
71 readonly property color dark: {
66− if (background.a !== 1.0) return d.foregroundLuminance < d.defaultDarkLuminance ? foreground : d.defaultDark;
72+ if (background.a !== 1.0) return foregroundLuminance < d.defaultDarkLuminance ? foreground : d.defaultDark;
67− return d.foregroundLuminance < d.backgroundLuminance ? foreground : background;
73+ return foregroundLuminance < backgroundLuminance ? foreground : background;
68 }
74 }
69
75
70 /// Source of the logo image for the header
76 /// Source of the logo image for the header
@@ -78,9 +84,6 @@ QtObject {
78
84
79 //! @cond
85 //! @cond
80 property var d: QtObject {
86 property var d: QtObject {
81− readonly property real foregroundLuminance: luminance(foreground)
82− readonly property real backgroundLuminance: luminance(background)
83−
84 // FIXME: should be taken from the theme
87 // FIXME: should be taken from the theme
85 readonly property color defaultLight: "white"
88 readonly property color defaultLight: "white"
86 readonly property color defaultDark: "grey"
89 readonly property color defaultDark: "grey"
po/es.po+5−5
@@ -8,14 +8,14 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2014-07-11 14:59+0200\n"
10"POT-Creation-Date: 2014-07-11 14:59+0200\n"
11−"PO-Revision-Date: 2014-07-26 06:22+0000\n"
11+"PO-Revision-Date: 2014-08-06 15:24+0000\n"
12−"Last-Translator: Paco Molinero <paco@byasl.com>\n"
12+"Last-Translator: Leo Arias <leo.arias@canonical.com>\n"
13"Language-Team: Spanish <es@li.org>\n"
13"Language-Team: Spanish <es@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2014-07-27 06:35+0000\n"
17+"X-Launchpad-Export-Date: 2014-08-07 06:27+0000\n"
18−"X-Generator: Launchpad (build 17131)\n"
18+"X-Generator: Launchpad (build 17147)\n"
19
19
20#: plugins/Unity/Launcher/launcheritem.cpp:43
20#: plugins/Unity/Launcher/launcheritem.cpp:43
21#: plugins/Unity/Launcher/launcheritem.cpp:73
21#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -116,7 +116,7 @@ msgstr "Recientes"
116
116
117#: qml/Dash/GenericScopeView.qml:330
117#: qml/Dash/GenericScopeView.qml:330
118msgid "See all"
118msgid "See all"
119−msgstr "Ver todo"
119+msgstr "Ver todas"
120
120
121#: qml/Dash/Previews/PreviewActionCombo.qml:34
121#: qml/Dash/Previews/PreviewActionCombo.qml:34
122msgid "More..."
122msgid "More..."
po/eu.po+7−6
@@ -8,14 +8,14 @@ msgstr ""
8"Project-Id-Version: unity8\n"
8"Project-Id-Version: unity8\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2014-07-11 14:59+0200\n"
10"POT-Creation-Date: 2014-07-11 14:59+0200\n"
11−"PO-Revision-Date: 2014-07-25 12:38+0000\n"
11+"PO-Revision-Date: 2014-08-06 22:51+0000\n"
12"Last-Translator: Ibai Oihanguren Sala <Unknown>\n"
12"Last-Translator: Ibai Oihanguren Sala <Unknown>\n"
13"Language-Team: Basque <eu@li.org>\n"
13"Language-Team: Basque <eu@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2014-07-26 07:16+0000\n"
17+"X-Launchpad-Export-Date: 2014-08-07 06:27+0000\n"
18−"X-Generator: Launchpad (build 17131)\n"
18+"X-Generator: Launchpad (build 17147)\n"
19
19
20#: plugins/Unity/Launcher/launcheritem.cpp:43
20#: plugins/Unity/Launcher/launcheritem.cpp:43
21#: plugins/Unity/Launcher/launcheritem.cpp:73
21#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -36,7 +36,8 @@ msgstr "Eskuineko ertza"
36
36
37#: qml/Components/EdgeDemo.qml:114
37#: qml/Components/EdgeDemo.qml:114
38msgid "Try swiping from the right edge to unlock the phone"
38msgid "Try swiping from the right edge to unlock the phone"
39+msgstr ""
39−msgstr "Probatu eskuineko ertzetik arrastatzen telefonoa desblokeatzeko"
40+"Pasatu hatza eskuineko ertzetik ezkerrerantz telefonoa desblokeatzeko"
40
41
41#: qml/Components/EdgeDemo.qml:145
42#: qml/Components/EdgeDemo.qml:145
42msgid "Top edge"
43msgid "Top edge"
@@ -44,7 +45,7 @@ msgstr "Goiko ertza"
44
45
45#: qml/Components/EdgeDemo.qml:146
46#: qml/Components/EdgeDemo.qml:146
46msgid "Try swiping from the top edge to access the indicators"
47msgid "Try swiping from the top edge to access the indicators"
47−msgstr "Probatu goiko ertzetik arrastatzen adierazleak ikusteko"
48+msgstr "Pasatu hatza goiko ertzetik beherantz adierazleak ikusteko"
48
49
49#: qml/Components/EdgeDemo.qml:171
50#: qml/Components/EdgeDemo.qml:171
50msgid "Close"
51msgid "Close"
@@ -52,7 +53,7 @@ msgstr "Itxi"
52
53
53#: qml/Components/EdgeDemo.qml:172
54#: qml/Components/EdgeDemo.qml:172
54msgid "Swipe up again to close the settings screen"
55msgid "Swipe up again to close the settings screen"
55−msgstr "Pasatu hatza gora berriro ezarpenen leihoa ixteko"
56+msgstr "Pasatu hatza berriro gora ezarpenen leihoa ixteko"
56
57
57#: qml/Components/EdgeDemo.qml:199
58#: qml/Components/EdgeDemo.qml:199
58msgid "Left edge"
59msgid "Left edge"
po/hu.po+3−3
@@ -8,13 +8,13 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2014-07-11 14:59+0200\n"
10"POT-Creation-Date: 2014-07-11 14:59+0200\n"
11−"PO-Revision-Date: 2014-08-04 09:10+0000\n"
11+"PO-Revision-Date: 2014-08-06 07:41+0000\n"
12"Last-Translator: Richard Somlói <ricsipontaz@gmail.com>\n"
12"Last-Translator: Richard Somlói <ricsipontaz@gmail.com>\n"
13"Language-Team: Hungarian <hu@li.org>\n"
13"Language-Team: Hungarian <hu@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2014-08-05 06:45+0000\n"
17+"X-Launchpad-Export-Date: 2014-08-07 06:27+0000\n"
18"X-Generator: Launchpad (build 17147)\n"
18"X-Generator: Launchpad (build 17147)\n"
19
19
20#: plugins/Unity/Launcher/launcheritem.cpp:43
20#: plugins/Unity/Launcher/launcheritem.cpp:43
@@ -91,7 +91,7 @@ msgstr "Üdv %1"
91
91
92#: qml/Components/PassphraseLockscreen.qml:60
92#: qml/Components/PassphraseLockscreen.qml:60
93msgid "Hello"
93msgid "Hello"
94−msgstr "Üdv"
94+msgstr "Üdvözöljük"
95
95
96#: qml/Components/PinLockscreen.qml:198
96#: qml/Components/PinLockscreen.qml:198
97msgid "CANCEL"
97msgid "CANCEL"
po/ja.po+11−11
@@ -8,14 +8,14 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2014-07-11 14:59+0200\n"
10"POT-Creation-Date: 2014-07-11 14:59+0200\n"
11−"PO-Revision-Date: 2014-01-18 07:01+0000\n"
11+"PO-Revision-Date: 2014-08-06 15:19+0000\n"
12"Last-Translator: Shushi Kurose <md81bird@hitaki.net>\n"
12"Last-Translator: Shushi Kurose <md81bird@hitaki.net>\n"
13"Language-Team: Japanese <ja@li.org>\n"
13"Language-Team: Japanese <ja@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2014-07-26 07:16+0000\n"
17+"X-Launchpad-Export-Date: 2014-08-07 06:27+0000\n"
18−"X-Generator: Launchpad (build 17131)\n"
18+"X-Generator: Launchpad (build 17147)\n"
19
19
20#: plugins/Unity/Launcher/launcheritem.cpp:43
20#: plugins/Unity/Launcher/launcheritem.cpp:43
21#: plugins/Unity/Launcher/launcheritem.cpp:73
21#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -28,7 +28,7 @@ msgstr ""
28
28
29#: qml/Components/EdgeDemoOverlay.qml:151
29#: qml/Components/EdgeDemoOverlay.qml:151
30msgid "Skip intro"
30msgid "Skip intro"
31−msgstr ""
31+msgstr "導入ガイドをスキップ"
32
32
33#: qml/Components/EdgeDemo.qml:113
33#: qml/Components/EdgeDemo.qml:113
34msgid "Right edge"
34msgid "Right edge"
@@ -44,7 +44,7 @@ msgstr "上端"
44
44
45#: qml/Components/EdgeDemo.qml:146
45#: qml/Components/EdgeDemo.qml:146
46msgid "Try swiping from the top edge to access the indicators"
46msgid "Try swiping from the top edge to access the indicators"
47−msgstr ""
47+msgstr "インジケーターにアクセスするには上端からスワイプしてみてください"
48
48
49#: qml/Components/EdgeDemo.qml:171
49#: qml/Components/EdgeDemo.qml:171
50msgid "Close"
50msgid "Close"
@@ -52,7 +52,7 @@ msgstr "閉じる"
52
52
53#: qml/Components/EdgeDemo.qml:172
53#: qml/Components/EdgeDemo.qml:172
54msgid "Swipe up again to close the settings screen"
54msgid "Swipe up again to close the settings screen"
55−msgstr ""
55+msgstr "設定画面を閉じるにはもう一度上にスワイプしてください"
56
56
57#: qml/Components/EdgeDemo.qml:199
57#: qml/Components/EdgeDemo.qml:199
58msgid "Left edge"
58msgid "Left edge"
@@ -60,11 +60,11 @@ msgstr "左端"
60
60
61#: qml/Components/EdgeDemo.qml:200
61#: qml/Components/EdgeDemo.qml:200
62msgid "Swipe from the left to reveal the launcher for quick access to apps"
62msgid "Swipe from the left to reveal the launcher for quick access to apps"
63−msgstr ""
63+msgstr "アプリに素早くアクセスできるLauncherを表示するには左からスワイプしてください"
64
64
65#: qml/Components/EdgeDemo.qml:227
65#: qml/Components/EdgeDemo.qml:227
66msgid "Well done"
66msgid "Well done"
67−msgstr ""
67+msgstr "よくできました!"
68
68
69#: qml/Components/EdgeDemo.qml:228
69#: qml/Components/EdgeDemo.qml:228
70msgid ""
70msgid ""
@@ -74,7 +74,7 @@ msgstr ""
74
74
75#: qml/Components/Lockscreen.qml:214
75#: qml/Components/Lockscreen.qml:214
76msgid "Emergency Call"
76msgid "Emergency Call"
77−msgstr ""
77+msgstr "緊急通報"
78
78
79#: qml/Components/Lockscreen.qml:231
79#: qml/Components/Lockscreen.qml:231
80msgid "OK"
80msgid "OK"
@@ -83,7 +83,7 @@ msgstr ""
83#: qml/Components/PassphraseLockscreen.qml:60
83#: qml/Components/PassphraseLockscreen.qml:60
84#, qt-format
84#, qt-format
85msgid "Hello %1"
85msgid "Hello %1"
86−msgstr ""
86+msgstr "こんにちは %1 さん"
87
87
88#: qml/Components/PassphraseLockscreen.qml:60
88#: qml/Components/PassphraseLockscreen.qml:60
89msgid "Hello"
89msgid "Hello"
@@ -127,7 +127,7 @@ msgstr ""
127
127
128#: qml/Dash/Previews/PreviewRatingInput.qml:126
128#: qml/Dash/Previews/PreviewRatingInput.qml:126
129msgid "Add a review"
129msgid "Add a review"
130−msgstr ""
130+msgstr "レビューを追加"
131
131
132#: qml/Dash/Previews/PreviewRatingInput.qml:166
132#: qml/Dash/Previews/PreviewRatingInput.qml:166
133msgid "Send"
133msgid "Send"
po/sl.po+4−4
@@ -8,14 +8,14 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2014-07-11 14:59+0200\n"
10"POT-Creation-Date: 2014-07-11 14:59+0200\n"
11−"PO-Revision-Date: 2014-07-28 12:32+0000\n"
11+"PO-Revision-Date: 2014-08-06 06:11+0000\n"
12"Last-Translator: Damir Jerovšek <Unknown>\n"
12"Last-Translator: Damir Jerovšek <Unknown>\n"
13"Language-Team: Slovenian <sl@li.org>\n"
13"Language-Team: Slovenian <sl@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2014-07-29 06:54+0000\n"
17+"X-Launchpad-Export-Date: 2014-08-07 06:27+0000\n"
18−"X-Generator: Launchpad (build 17131)\n"
18+"X-Generator: Launchpad (build 17147)\n"
19
19
20#: plugins/Unity/Launcher/launcheritem.cpp:43
20#: plugins/Unity/Launcher/launcheritem.cpp:43
21#: plugins/Unity/Launcher/launcheritem.cpp:73
21#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -115,7 +115,7 @@ msgstr "Nedavno"
115
115
116#: qml/Dash/GenericScopeView.qml:330
116#: qml/Dash/GenericScopeView.qml:330
117msgid "See all"
117msgid "See all"
118−msgstr ""
118+msgstr "Ogled vsega"
119
119
120#: qml/Dash/Previews/PreviewActionCombo.qml:34
120#: qml/Dash/Previews/PreviewActionCombo.qml:34
121msgid "More..."
121msgid "More..."
qml/Components/EdgeDemo.qml+15−15
@@ -24,13 +24,13 @@ Item {
24 property Item greeter
24 property Item greeter
25 property Item launcher
25 property Item launcher
26 property Item indicators
26 property Item indicators
27− property Item underlay
27+ property Item stages
28
28
29 property bool launcherEnabled: true
29 property bool launcherEnabled: true
30− property bool dashEnabled: true
30+ property bool stagesEnabled: true
31 property bool panelEnabled: true
31 property bool panelEnabled: true
32 property bool panelContentEnabled: true
32 property bool panelContentEnabled: true
33− property bool running: !launcherEnabled || !dashEnabled || !panelEnabled || !panelContentEnabled
33+ property bool running: !launcherEnabled || !stagesEnabled || !panelEnabled || !panelContentEnabled
34
34
35 property bool paused: false
35 property bool paused: false
36
36
@@ -58,7 +58,7 @@ Item {
58
58
59 function stopDemo() {
59 function stopDemo() {
60 launcherEnabled = true
60 launcherEnabled = true
61− dashEnabled = true
61+ stagesEnabled = true
62 panelEnabled = true
62 panelEnabled = true
63 panelContentEnabled = true
63 panelContentEnabled = true
64 if (d.rightEdgeDemo) d.rightEdgeDemo.destroy()
64 if (d.rightEdgeDemo) d.rightEdgeDemo.destroy()
@@ -74,11 +74,11 @@ Item {
74 }
74 }
75
75
76 launcherEnabled = false;
76 launcherEnabled = false;
77− dashEnabled = false;
77+ stagesEnabled = false;
78 panelEnabled = false;
78 panelEnabled = false;
79 panelContentEnabled = false;
79 panelContentEnabled = false;
80
80
81− // Begin with either greeter or dash, depending on which is visible
81+ // Begin with either greeter or top, depending on which is visible
82 if (greeter && greeter.shown) {
82 if (greeter && greeter.shown) {
83 startRightEdgeDemo()
83 startRightEdgeDemo()
84 } else {
84 } else {
@@ -138,12 +138,12 @@ Item {
138
138
139 function startTopEdgeDemo() {
139 function startTopEdgeDemo() {
140 demo.panelEnabled = true;
140 demo.panelEnabled = true;
141− if (demo.dash && demo.underlay) {
141+ if (demo.stages) {
142− d.topEdgeDemo = d.overlay.createObject(demo.underlay, {
142+ d.topEdgeDemo = d.overlay.createObject(demo.stages, {
143 "edge": "top",
143 "edge": "top",
144 "title": i18n.tr("Top edge"),
144 "title": i18n.tr("Top edge"),
145 "text": i18n.tr("Try swiping from the top edge to access the indicators"),
145 "text": i18n.tr("Try swiping from the top edge to access the indicators"),
146− "anchors.fill": demo.underlay,
146+ "anchors.fill": demo.stages,
147 });
147 });
148 }
148 }
149 if (d.topEdgeDemo) {
149 if (d.topEdgeDemo) {
@@ -192,12 +192,12 @@ Item {
192 function startLeftEdgeDemo() {
192 function startLeftEdgeDemo() {
193 demo.panelEnabled = false;
193 demo.panelEnabled = false;
194 demo.launcherEnabled = true;
194 demo.launcherEnabled = true;
195− if (demo.underlay) {
195+ if (demo.stages) {
196− d.leftEdgeDemo = d.overlay.createObject(demo.underlay, {
196+ d.leftEdgeDemo = d.overlay.createObject(demo.stages, {
197 "edge": "left",
197 "edge": "left",
198 "title": i18n.tr("Left edge"),
198 "title": i18n.tr("Left edge"),
199 "text": i18n.tr("Swipe from the left to reveal the launcher for quick access to apps"),
199 "text": i18n.tr("Swipe from the left to reveal the launcher for quick access to apps"),
200− "anchors.fill": demo.underlay,
200+ "anchors.fill": demo.stages,
201 });
201 });
202 }
202 }
203 if (d.leftEdgeDemo) {
203 if (d.leftEdgeDemo) {
@@ -220,12 +220,12 @@ Item {
220
220
221 function startFinalEdgeDemo() {
221 function startFinalEdgeDemo() {
222 demo.launcherEnabled = false;
222 demo.launcherEnabled = false;
223− if (demo.underlay) {
223+ if (demo.stages) {
224− d.finalEdgeDemo = d.overlay.createObject(demo.underlay, {
224+ d.finalEdgeDemo = d.overlay.createObject(demo.stages, {
225 "edge": "none",
225 "edge": "none",
226 "title": i18n.tr("Well done"),
226 "title": i18n.tr("Well done"),
227 "text": i18n.tr("You have now mastered the edge gestures and can start using the phone<br><br>Tap on the screen to start"),
227 "text": i18n.tr("You have now mastered the edge gestures and can start using the phone<br><br>Tap on the screen to start"),
228− "anchors.fill": demo.underlay,
228+ "anchors.fill": demo.stages,
229 "showSkip": false,
229 "showSkip": false,
230 });
230 });
231 }
231 }
qml/Components/PageHeader.qml+25−16
@@ -32,9 +32,10 @@ Item {
32 property bool searchEntryEnabled: false
32 property bool searchEntryEnabled: false
33 property ListModel searchHistory: SearchHistoryModel
33 property ListModel searchHistory: SearchHistoryModel
34 property alias searchQuery: searchTextField.text
34 property alias searchQuery: searchTextField.text
35− property bool searchInProgress: false
36
35
37 property alias bottomItem: bottomContainer.children
36 property alias bottomItem: bottomContainer.children
37+ property int paginationCount: 0
38+ property int paginationIndex: -1
38
39
39 // TODO We should use foreground for the icons
40 // TODO We should use foreground for the icons
40 // of the toolbar but unfortunately Action does not have
41 // of the toolbar but unfortunately Action does not have
@@ -125,7 +126,7 @@ Item {
125 Flickable {
126 Flickable {
126 id: headerContainer
127 id: headerContainer
127 objectName: "headerContainer"
128 objectName: "headerContainer"
128− clip: openSearchAnimation.running
129+ clip: contentY < height
129 anchors { left: parent.left; top: parent.top; right: parent.right }
130 anchors { left: parent.left; top: parent.top; right: parent.right }
130 height: units.gu(6.5)
131 height: units.gu(6.5)
131 contentHeight: headersColumn.height
132 contentHeight: headersColumn.height
@@ -169,6 +170,7 @@ Item {
169 property var styledItem: searchHeader
170 property var styledItem: searchHeader
170 property string title
171 property string title
171 property var config: PageHeadConfiguration {
172 property var config: PageHeadConfiguration {
173+ foregroundColor: root.scopeStyle ? root.scopeStyle.headerForeground : "grey"
172 backAction: Action {
174 backAction: Action {
173 iconName: "back"
175 iconName: "back"
174 onTriggered: {
176 onTriggered: {
@@ -200,25 +202,13 @@ Item {
200 anchors.fill: parent
202 anchors.fill: parent
201 anchors.margins: units.gu(.75)
203 anchors.margins: units.gu(.75)
202 source: "image://theme/clear"
204 source: "image://theme/clear"
203− opacity: searchTextField.text.length > 0 && !searchActivityIndicator.running
205+ opacity: searchTextField.text.length > 0
204 visible: opacity > 0
206 visible: opacity > 0
205 Behavior on opacity {
207 Behavior on opacity {
206 UbuntuNumberAnimation { duration: UbuntuAnimation.FastDuration }
208 UbuntuNumberAnimation { duration: UbuntuAnimation.FastDuration }
207 }
209 }
208 }
210 }
209
211
210− ActivityIndicator {
211− id: searchActivityIndicator
212− objectName: "searchIndicator"
213− anchors.fill: parent
214− anchors.margins: units.gu(.75)
215− running: root.searchInProgress
216− opacity: running ? 1 : 0
217− Behavior on opacity {
218− UbuntuNumberAnimation { duration: UbuntuAnimation.FastDuration }
219− }
220− }
221−
222 onClicked: {
212 onClicked: {
223 root.resetSearch(true);
213 root.resetSearch(true);
224 root.openSearchHistory();
214 root.openSearchHistory();
@@ -247,10 +237,10 @@ Item {
247 contentHeight: height
237 contentHeight: height
248 opacity: headerContainer.clip || !headerContainer.showSearch ? 1 : 0 // setting visible false cause column to relayout
238 opacity: headerContainer.clip || !headerContainer.showSearch ? 1 : 0 // setting visible false cause column to relayout
249 separatorSource: ""
239 separatorSource: ""
250− textColor: root.scopeStyle ? root.scopeStyle.headerForeground : "grey"
251 property var styledItem: header
240 property var styledItem: header
252 property string title: root.title
241 property string title: root.title
253 property var config: PageHeadConfiguration {
242 property var config: PageHeadConfiguration {
243+ foregroundColor: root.scopeStyle ? root.scopeStyle.headerForeground : "grey"
254 backAction: Action {
244 backAction: Action {
255 iconName: "back"
245 iconName: "back"
256 visible: root.showBackButton
246 visible: root.showBackButton
@@ -294,6 +284,25 @@ Item {
294 }
284 }
295 }
285 }
296
286
287+ Row {
288+ spacing: units.gu(.5)
289+ Repeater {
290+ objectName: "paginationRepeater"
291+ model: root.paginationCount
292+ Image {
293+ objectName: "paginationDots_" + index
294+ height: units.gu(1)
295+ width: height
296+ source: (index == root.paginationIndex) ? "graphics/pagination_dot_on.png" : "graphics/pagination_dot_off.png"
297+ }
298+ }
299+ anchors {
300+ top: headerContainer.bottom
301+ horizontalCenter: headerContainer.horizontalCenter
302+ topMargin: units.gu(.5)
303+ }
304+ }
305+
297 Component {
306 Component {
298 id: popoverComponent
307 id: popoverComponent
299 Popover {
308 Popover {
qml/Components/SeeMore.qmldeleted−70
@@ -1,70 +0,0 @@
1−/*
2− * Copyright (C) 2014 Canonical, Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1
19−
20−/*! Widget that can be used in combination with a text area to allow easy 'expand/collapse' functionality. */
21−
22−Item {
23− //! Boolean set to true when it suggests expanded functionality
24− property bool more: false
25−
26− implicitHeight: seeMoreLabel.height + units.gu(2)
27−
28− Row {
29− anchors.centerIn: parent
30− spacing: units.gu(2)
31−
32− Label {
33− id: seeMoreLabel
34− objectName: "seeMoreLabel"
35− text: i18n.tr("See more")
36− opacity: !more ? 0.8 : 0.4
37− // TODO: Fix requiring Palette update
38− color: "grey" //Theme.palette.selected.backgroundText
39− font.weight: Font.Bold
40−
41− MouseArea {
42− anchors.fill: parent
43− onClicked: more = true
44− }
45− }
46−
47− Image {
48− anchors {
49− top: parent.top
50− bottom: parent.bottom
51− }
52− width: units.dp(2)
53− source: "ListItems/graphics/ListItemDividerVertical.png"
54− }
55−
56− Label {
57− objectName: "seeLessLabel"
58− text: i18n.tr("See less")
59− opacity: more ? 0.8 : 0.4
60− // TODO: Fix requiring Palette update
61− color: "grey" //Theme.palette.selected.backgroundText
62− font.weight: Font.Bold
63−
64− MouseArea {
65− anchors.fill: parent
66− onClicked: more = false
67− }
68− }
69− }
70−}
qml/Components/graphics/pagination_dot_off@30.pngnew file

Binary file not shown.

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

Binary file not shown.

qml/Dash/CardTool.qml+1−1
@@ -126,7 +126,7 @@ Item {
126 type:real \brief Height of the card's header.
126 type:real \brief Height of the card's header.
127 */
127 */
128 readonly property int headerHeight: cardLoader.item ? cardLoader.item.headerHeight : 0
128 readonly property int headerHeight: cardLoader.item ? cardLoader.item.headerHeight : 0
129− readonly property size artShapeSize: cardLoader.item ? cardLoader.item.artShapeSize : 0
129+ property size artShapeSize: cardLoader.item ? cardLoader.item.artShapeSize : 0
130
130
131 /*!
131 /*!
132 \brief Desired alignment of header components.
132 \brief Desired alignment of header components.
qml/Dash/Dash.qml+76−1
@@ -14,7 +14,7 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
15 */
16
16
17−import QtQuick 2.0
17+import QtQuick 2.2
18import Ubuntu.Components 0.1
18import Ubuntu.Components 0.1
19import Unity 0.2
19import Unity 0.2
20import Utils 0.1
20import Utils 0.1
@@ -73,6 +73,14 @@ Showable {
73 id: scopes
73 id: scopes
74 }
74 }
75
75
76+ Image {
77+ anchors.fill: parent
78+ source: parent.width > parent.height ? "graphics/paper_landscape.png" : "graphics/paper_portrait.png"
79+ fillMode: Image.PreserveAspectCrop
80+ horizontalAlignment: Image.AlignRight
81+ verticalAlignment: Image.AlignTop
82+ }
83+
76 DashContent {
84 DashContent {
77 id: dashContent
85 id: dashContent
78 objectName: "dashContent"
86 objectName: "dashContent"
@@ -132,4 +140,71 @@ Showable {
132 }
140 }
133 }
141 }
134 }
142 }
143+
144+ Rectangle {
145+ id: indicator
146+ objectName: "processingIndicator"
147+ anchors {
148+ left: parent.left
149+ right: parent.right
150+ bottom: parent.bottom
151+ }
152+ height: units.dp(3)
153+ color: scopeStyle.backgroundLuminance > 0.7 ? "#50000000" : "#50ffffff"
154+ opacity: 0
155+ visible: opacity > 0
156+
157+ readonly property bool processing: dashContent.processing || scopeItem.processing
158+
159+ Behavior on opacity {
160+ UbuntuNumberAnimation { duration: UbuntuAnimation.FastDuration }
161+ }
162+
163+ onProcessingChanged: {
164+ if (processing) delay.start();
165+ else if (!persist.running) indicator.opacity = 0;
166+ }
167+
168+ Timer {
169+ id: delay
170+ interval: 200
171+ onTriggered: if (indicator.processing) {
172+ persist.restart();
173+ indicator.opacity = 1;
174+ }
175+ }
176+
177+ Timer {
178+ id: persist
179+ interval: 2 * UbuntuAnimation.SleepyDuration - UbuntuAnimation.FastDuration
180+ onTriggered: if (!indicator.processing) indicator.opacity = 0
181+ }
182+
183+ Rectangle {
184+ id: orange
185+ anchors { top: parent.top; bottom: parent.bottom }
186+ width: parent.width / 4
187+ color: Theme.palette.selected.foreground
188+
189+ SequentialAnimation {
190+ running: indicator.visible
191+ loops: Animation.Infinite
192+ XAnimator {
193+ from: -orange.width / 2
194+ to: indicator.width - orange.width / 2
195+ duration: UbuntuAnimation.SleepyDuration
196+ easing.type: Easing.InOutSine
197+ target: orange
198+ }
199+ XAnimator {
200+ from: indicator.width - orange.width / 2
201+ to: -orange.width / 2
202+ duration: UbuntuAnimation.SleepyDuration
203+ easing.type: Easing.InOutSine
204+ target: orange
205+ }
206+ }
207+ }
208+ }
209+
135}
210}
qml/Dash/DashApplication.qml+7
@@ -16,6 +16,7 @@
16
16
17import QtQuick 2.2
17import QtQuick 2.2
18import Ubuntu.Components 1.0
18import Ubuntu.Components 1.0
19+import Ubuntu.Thumbnailer 0.1 // Register support for image://thumbnailer/ and image://albumart/
19
20
20MainView {
21MainView {
21 width: units.gu(40)
22 width: units.gu(40)
@@ -23,6 +24,12 @@ MainView {
23
24
24 useDeprecatedToolbar: false
25 useDeprecatedToolbar: false
25
26
27+ Binding {
28+ target: i18n
29+ property: "domain"
30+ value: "unity8"
31+ }
32+
26 Dash {
33 Dash {
27 anchors.fill: parent
34 anchors.fill: parent
28 }
35 }
qml/Dash/DashContent.qml+6−1
@@ -25,6 +25,8 @@ Item {
25
25
26 property alias scopes: dashContentList.model
26 property alias scopes: dashContentList.model
27 readonly property alias currentIndex: dashContentList.currentIndex
27 readonly property alias currentIndex: dashContentList.currentIndex
28+ readonly property bool processing: dashContentList.currentItem && dashContentList.currentItem.item
29+ && dashContentList.currentItem.item.processing || false
28
30
29 signal scopeLoaded(string scopeId)
31 signal scopeLoaded(string scopeId)
30 signal gotoScope(string scopeId)
32 signal gotoScope(string scopeId)
@@ -88,7 +90,7 @@ Item {
88 id: dashContentList
90 id: dashContentList
89 objectName: "dashContentList"
91 objectName: "dashContentList"
90
92
91− interactive: dashContent.scopes.loaded && currentItem && !currentItem.moving
93+ interactive: dashContent.scopes.loaded && currentItem && !currentItem.moving && !currentItem.navigationShown
92
94
93 anchors.fill: parent
95 anchors.fill: parent
94 orientation: ListView.Horizontal
96 orientation: ListView.Horizontal
@@ -128,6 +130,7 @@ Item {
128 objectName: scope.id + " loader"
130 objectName: scope.id + " loader"
129
131
130 readonly property bool moving: item ? item.moving : false
132 readonly property bool moving: item ? item.moving : false
133+ readonly property bool navigationShown: item ? item.navigationShown : false
131 readonly property var categoryView: item ? item.categoryView : null
134 readonly property var categoryView: item ? item.categoryView : null
132 readonly property var theScope: scope
135 readonly property var theScope: scope
133
136
@@ -141,6 +144,8 @@ Item {
141 item.scope = Qt.binding(function() { return scope })
144 item.scope = Qt.binding(function() { return scope })
142 item.isCurrent = Qt.binding(function() { return visible && ListView.isCurrentItem })
145 item.isCurrent = Qt.binding(function() { return visible && ListView.isCurrentItem })
143 dashContent.scopeLoaded(item.scope.id)
146 dashContent.scopeLoaded(item.scope.id)
147+ item.paginationCount = Qt.binding(function() { return dashContentList.count } )
148+ item.paginationIndex = Qt.binding(function() { return dashContentList.currentIndex } )
144 }
149 }
145 Connections {
150 Connections {
146 target: isCurrent ? scope : null
151 target: isCurrent ? scope : null
qml/Dash/DashNavigationButton.qml+8−1
@@ -47,6 +47,7 @@ AbstractButton {
47 visible: root.currentNavigation != null
47 visible: root.currentNavigation != null
48
48
49 onClicked: {
49 onClicked: {
50+ navigationListView.updateMaxHeight();
50 root.showList = !root.showList;
51 root.showList = !root.showList;
51 }
52 }
52
53
@@ -83,7 +84,12 @@ AbstractButton {
83 // This is used to "clear" the delegate when going "right" on the tree
84 // This is used to "clear" the delegate when going "right" on the tree
84 }
85 }
85 anchors.top: root.bottom
86 anchors.top: root.bottom
87+ property int maxHeight: -1
88+ Component.onCompleted: updateMaxHeight();
89+ function updateMaxHeight()
90+ {
86− readonly property int maxHeight: (windowHeight - mapToItem(null, root.x, root.y).y) - units.gu(8)
91+ maxHeight = (windowHeight - mapToItem(null, 0, 0).y) - units.gu(8);
92+ }
87 property int prevHeight: maxHeight
93 property int prevHeight: maxHeight
88 height: currentItem ? currentItem.height : maxHeight
94 height: currentItem ? currentItem.height : maxHeight
89 onHeightChanged: {
95 onHeightChanged: {
@@ -101,6 +107,7 @@ AbstractButton {
101 if (root.showList) {
107 if (root.showList) {
102 if (navigation && navigation.loaded && x == navigationListView.contentX)
108 if (navigation && navigation.loaded && x == navigationListView.contentX)
103 {
109 {
110+ navigationListView.updateMaxHeight();
104 return Math.min(implicitHeight, navigationListView.maxHeight);
111 return Math.min(implicitHeight, navigationListView.maxHeight);
105 } else {
112 } else {
106 return navigationListView.prevHeight;
113 return navigationListView.prevHeight;
qml/Dash/DashNavigationList.qml+1−5
@@ -35,11 +35,6 @@ Item {
35 anchors.fill: parent
35 anchors.fill: parent
36 }
36 }
37
37
38− ActivityIndicator {
39− id: loadingIndicator
40− anchors.centerIn: parent
41− running: !(navigation && navigation.loaded)
42− }
43 clip: true
38 clip: true
44
39
45 Behavior on height {
40 Behavior on height {
@@ -54,6 +49,7 @@ Item {
54
49
55 anchors.fill: parent
50 anchors.fill: parent
56
51
52+ flickableDirection: Flickable.VerticalFlick
57 contentHeight: column.height
53 contentHeight: column.height
58 contentWidth: width
54 contentWidth: width
59
55
qml/Dash/GenericScopeView.qml+11−1
@@ -25,6 +25,7 @@ import "../Components/ListItems" as ListItems
25FocusScope {
25FocusScope {
26 id: scopeView
26 id: scopeView
27
27
28+ readonly property alias navigationShown: dashNavigation.showList
28 property var scope: null
29 property var scope: null
29 property SortFilterProxyModel categories: categoryFilter
30 property SortFilterProxyModel categories: categoryFilter
30 property bool isCurrent: false
31 property bool isCurrent: false
@@ -32,11 +33,15 @@ FocusScope {
32 property bool hasBackAction: false
33 property bool hasBackAction: false
33 property bool enableHeightBehaviorOnNextCreation: false
34 property bool enableHeightBehaviorOnNextCreation: false
34 property var categoryView: categoryView
35 property var categoryView: categoryView
36+ property alias paginationCount: pageHeader.paginationCount
37+ property alias paginationIndex: pageHeader.paginationIndex
35
38
36 property var scopeStyle: ScopeStyle {
39 property var scopeStyle: ScopeStyle {
37 style: scope ? scope.customizations : {}
40 style: scope ? scope.customizations : {}
38 }
41 }
39
42
43+ readonly property bool processing: scope ? scope.searchInProgress || previewListView.processing : false
44+
40 signal backClicked()
45 signal backClicked()
41
46
42 function positionAtBeginning() {
47 function positionAtBeginning() {
@@ -109,6 +114,7 @@ FocusScope {
109 model: scopeView.categories
114 model: scopeView.categories
110 forceNoClip: previewListView.open
115 forceNoClip: previewListView.open
111 pixelAligned: true
116 pixelAligned: true
117+ interactive: !dashNavigation.showList
112
118
113 property string expandedCategoryId: ""
119 property string expandedCategoryId: ""
114
120
@@ -201,6 +207,10 @@ FocusScope {
201 baseItem.expand(shouldExpand, false /*animate*/);
207 baseItem.expand(shouldExpand, false /*animate*/);
202 }
208 }
203 updateDelegateCreationRange();
209 updateDelegateCreationRange();
210+ if (scope && scope.id === "clickscope" && (categoryId === "predefined" || categoryId === "local")) {
211+ // Yeah, hackish :/
212+ cardTool.artShapeSize = Qt.size(units.gu(8), units.gu(7.5));
213+ }
204 item.cardTool = cardTool;
214 item.cardTool = cardTool;
205 }
215 }
206
216
@@ -377,10 +387,10 @@ FocusScope {
377 title: scopeView.scope ? scopeView.scope.name : ""
387 title: scopeView.scope ? scopeView.scope.name : ""
378 showBackButton: scopeView.hasBackAction
388 showBackButton: scopeView.hasBackAction
379 searchEntryEnabled: true
389 searchEntryEnabled: true
380− searchInProgress: scopeView.scope ? scopeView.scope.searchInProgress : false
381 scopeStyle: scopeView.scopeStyle
390 scopeStyle: scopeView.scopeStyle
382
391
383 bottomItem: DashNavigation {
392 bottomItem: DashNavigation {
393+ id: dashNavigation
384 scope: scopeView.scope
394 scope: scopeView.scope
385 width: parent.width <= units.gu(60) ? parent.width : units.gu(40)
395 width: parent.width <= units.gu(60) ? parent.width : units.gu(40)
386 anchors.right: parent.right
396 anchors.right: parent.right
qml/Dash/PreviewListView.qml+23−27
@@ -32,6 +32,9 @@ Item {
32 property alias currentItem: previewListView.currentItem
32 property alias currentItem: previewListView.currentItem
33 property alias count: previewListView.count
33 property alias count: previewListView.count
34
34
35+ readonly property bool processing: currentItem && (!currentItem.previewModel.loaded
36+ || currentItem.previewModel.processingAction)
37+
35 PageHeader {
38 PageHeader {
36 id: header
39 id: header
37 objectName: "pageHeader"
40 objectName: "pageHeader"
@@ -83,39 +86,32 @@ Item {
83 }
86 }
84 }
87 }
85
88
86− delegate: Item {
89+ delegate: Previews.Preview {
90+ id: preview
87− objectName: "previewItem" + index
91+ objectName: "preview" + index
88 height: previewListView.height
92 height: previewListView.height
89 width: previewListView.width
93 width: previewListView.width
90
94
91− readonly property bool ready: preview.previewModel.loaded
95+ isCurrent: ListView.isCurrentItem
92−
93− Previews.Preview {
94− id: preview
95− objectName: "preview" + index
96− anchors.fill: parent
97
96
98− isCurrent: parent.ListView.isCurrentItem
99−
100− previewModel: {
97+ previewModel: {
101− var previewStack = root.scope.preview(result);
98+ var previewStack = root.scope.preview(result);
102− return previewStack.getPreviewModel(0);
99+ return previewStack.getPreviewModel(0);
103− }
104− scopeStyle: root.scopeStyle
105 }
100 }
101+ scopeStyle: root.scopeStyle
102+ }
103+ }
106
104
107− MouseArea {
105+ MouseArea {
108− id: processingMouseArea
106+ id: processingMouseArea
109− objectName: "processingMouseArea"
107+ objectName: "processingMouseArea"
110− anchors.fill: parent
108+ anchors {
111− enabled: !preview.previewModel.loaded || preview.previewModel.processingAction
109+ left: parent.left
112−
110+ right: parent.right
113− ActivityIndicator {
111+ top: pageHeader.bottom
114− anchors.centerIn: parent
112+ bottom: parent.bottom
115− visible: root.open && parent.enabled
116− running: visible
117− }
118− }
119 }
113 }
114+
115+ enabled: root.processing
120 }
116 }
121}
117}
qml/Dash/Previews/PreviewExpandable.qmlnew file+101
@@ -0,0 +1,101 @@
1+/*
2+ * Copyright (C) 2014 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.3
18+import Ubuntu.Components 1.1
19+import "../../Components"
20+
21+/*! \brief Preview widget for expandable widgets.
22+
23+ This widget shows a list of widgets defined in widgetData["widgets"]
24+ Those widgets can be collapsed or uncollapsed. When uncollapsed
25+ all the widgets are shown, when collapsed only the first
26+ widgetData["collapsed-widgets"] are shown. It has a title that comes
27+ in via widgetData["title"]
28+ */
29+
30+PreviewWidget {
31+ id: root
32+ implicitHeight: childrenRect.height
33+
34+ expanded: false
35+
36+ Label {
37+ id: titleLabel
38+ objectName: "titleLabel"
39+ anchors {
40+ left: parent.left
41+ right: expandButton.left
42+ }
43+ fontSize: "large"
44+ color: root.scopeStyle ? root.scopeStyle.foreground : "grey"
45+ visible: text !== ""
46+ opacity: .8
47+ text: widgetData["title"] || ""
48+ wrapMode: Text.Wrap
49+ }
50+
51+ AbstractButton {
52+ id: expandButton
53+ objectName: "expandButton"
54+ width: titleLabel.height
55+ height: titleLabel.height
56+ anchors.right: parent.right
57+ onClicked: {
58+ root.expanded = !root.expanded;
59+ }
60+ Icon {
61+ anchors.fill: parent
62+ width: 64
63+ height: 64
64+ name: root.expanded ? "view-collapse" : "view-expand"
65+ }
66+ }
67+
68+ Column {
69+ anchors {
70+ top: titleLabel.bottom
71+ topMargin: units.gu(1)
72+ left: parent.left
73+ right: parent.right
74+ }
75+ spacing: units.gu(1)
76+ Repeater {
77+ id: repeater
78+ objectName: "repeater"
79+ model: widgetData["widgets"]
80+ delegate: PreviewWidgetFactory {
81+ height: visible ? implicitHeight : 0
82+ width: parent.width
83+ widgetId: modelData.widgetId
84+ widgetType: modelData.type
85+ widgetData: modelData.properties
86+ isCurrentPreview: root.isCurrentPreview
87+ scopeStyle: root.scopeStyle
88+ anchors {
89+ left: parent.left
90+ right: parent.right
91+ }
92+ expanded: root.expanded
93+ visible: root.expanded || index < root.widgetData["collapsed-widgets"]
94+
95+ onTriggered: {
96+ root.triggered(widgetId, actionId, data);
97+ }
98+ }
99+ }
100+ }
101+}
qml/Dash/Previews/PreviewImageGallery.qml+1
@@ -15,6 +15,7 @@
15 */
15 */
16
16
17import QtQuick 2.0
17import QtQuick 2.0
18+import Ubuntu.Components 1.1
18import "../../Components"
19import "../../Components"
19
20
20/*! This preview widget shows a horizontal list of images.
21/*! This preview widget shows a horizontal list of images.
qml/Dash/Previews/PreviewTextSummary.qml+3−16
@@ -23,7 +23,7 @@ import "../../Components"
23 This widget shows text contained in widgetData["text"]
23 This widget shows text contained in widgetData["text"]
24 along with a title that comes from widgetData["title"].
24 along with a title that comes from widgetData["title"].
25
25
26− In case the text does not fit in 7 lines a See More / Less widget is also shown.
26+ In case the widget is collapsed it only shows 3 lines of text.
27 */
27 */
28
28
29PreviewWidget {
29PreviewWidget {
@@ -50,14 +50,14 @@ PreviewWidget {
50 id: textLabel
50 id: textLabel
51 objectName: "textLabel"
51 objectName: "textLabel"
52
52
53− readonly property int maximumCollapsedLineCount: 7
53+ readonly property int maximumCollapsedLineCount: 3
54
54
55 anchors {
55 anchors {
56 left: parent.left
56 left: parent.left
57 right: parent.right
57 right: parent.right
58 top: titleLabel.visible ? titleLabel.bottom : parent.top
58 top: titleLabel.visible ? titleLabel.bottom : parent.top
59 }
59 }
60− height: (!seeMore.visible || seeMore.more) ? contentHeight : contentHeight / lineCount * (maximumCollapsedLineCount - 2)
60+ height: (lineCount <= maximumCollapsedLineCount || root.expanded) ? contentHeight : contentHeight / lineCount * maximumCollapsedLineCount
61 clip: true
61 clip: true
62 fontSize: "small"
62 fontSize: "small"
63 lineHeight: 1.2
63 lineHeight: 1.2
@@ -70,17 +70,4 @@ PreviewWidget {
70 UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration }
70 UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration }
71 }
71 }
72 }
72 }
73−
74− SeeMore {
75− id: seeMore
76− objectName: "seeMore"
77− anchors {
78− left: parent.left
79− right: parent.right
80− top: textLabel.bottom
81− topMargin: visible ? units.gu(1) : 0
82− }
83− height: visible ? implicitHeight : 0
84− visible: textLabel.lineCount > textLabel.maximumCollapsedLineCount
85− }
86}
73}
qml/Dash/Previews/PreviewWidget.qml+3
@@ -31,6 +31,9 @@ Item {
31 //! The ScopeStyle component.
31 //! The ScopeStyle component.
32 property var scopeStyle: null
32 property var scopeStyle: null
33
33
34+ //! Should the widget show in expanded mode (For those that support it)
35+ property bool expanded: true
36+
34 /*! \brief This signal should be emitted when a preview action was triggered.
37 /*! \brief This signal should be emitted when a preview action was triggered.
35 *
38 *
36 * \param widgetId, actionId Respective identifiers from widgetData.
39 * \param widgetId, actionId Respective identifiers from widgetData.
qml/Dash/Previews/PreviewWidgetFactory.qml+5
@@ -34,6 +34,9 @@ Loader {
34 //! The ScopeStyle component.
34 //! The ScopeStyle component.
35 property var scopeStyle: null
35 property var scopeStyle: null
36
36
37+ //! Should the widget show in expanded mode (For those that support it)
38+ property bool expanded: true
39+
37 //! Set to true if the parent preview is displayed.
40 //! Set to true if the parent preview is displayed.
38 property bool isCurrentPreview: false
41 property bool isCurrentPreview: false
39
42
@@ -47,6 +50,7 @@ Loader {
47 switch (widgetType) {
50 switch (widgetType) {
48 case "actions": return "PreviewActions.qml";
51 case "actions": return "PreviewActions.qml";
49 case "audio": return "PreviewAudioPlayback.qml";
52 case "audio": return "PreviewAudioPlayback.qml";
53+ case "expandable": return "PreviewExpandable.qml";
50 case "gallery": return "PreviewImageGallery.qml";
54 case "gallery": return "PreviewImageGallery.qml";
51 case "header": return "PreviewHeader.qml";
55 case "header": return "PreviewHeader.qml";
52 case "image": return "PreviewZoomableImage.qml";
56 case "image": return "PreviewZoomableImage.qml";
@@ -65,6 +69,7 @@ Loader {
65 item.widgetId = Qt.binding(function() { return root.widgetId } )
69 item.widgetId = Qt.binding(function() { return root.widgetId } )
66 item.widgetData = Qt.binding(function() { return root.widgetData } )
70 item.widgetData = Qt.binding(function() { return root.widgetData } )
67 item.isCurrentPreview = Qt.binding(function() { return root.isCurrentPreview } )
71 item.isCurrentPreview = Qt.binding(function() { return root.isCurrentPreview } )
72+ item.expanded = Qt.binding(function() { return root.expanded } )
68 if (item.hasOwnProperty("scopeStyle")) item.scopeStyle = root.scopeStyle;
73 if (item.hasOwnProperty("scopeStyle")) item.scopeStyle = root.scopeStyle;
69 }
74 }
70
75
qml/Greeter/Greeter.qml+1−1
@@ -70,7 +70,7 @@ Showable {
70 DraggingArea {
70 DraggingArea {
71 id: dragHandle
71 id: dragHandle
72 anchors.fill: parent
72 anchors.fill: parent
73− enabled: (greeter.narrowMode || !greeter.locked) && greeter.enabled
73+ enabled: (greeter.narrowMode || !greeter.locked) && greeter.enabled && greeter.shown
74 orientation: Qt.Horizontal
74 orientation: Qt.Horizontal
75 propagateComposedEvents: true
75 propagateComposedEvents: true
76
76
qml/Notifications/NotificationMenuItemFactory.qml+3
@@ -76,6 +76,9 @@ Loader {
76 }
76 }
77 echoMode: checkBox.checked ? TextInput.Normal : TextInput.Password
77 echoMode: checkBox.checked ? TextInput.Normal : TextInput.Password
78 height: units.gu(5)
78 height: units.gu(5)
79+ Component.onCompleted: {
80+ forceActiveFocus();
81+ }
79 onTextChanged: {
82 onTextChanged: {
80 menuModel.changeState(menuIndex, text);
83 menuModel.changeState(menuIndex, text);
81 }
84 }
qml/Panel/Indicators/MenuItemFactory.qml+74
@@ -57,6 +57,7 @@ Item {
57
57
58 "unity.widgets.systemsettings.tablet.wifisection" : wifiSection,
58 "unity.widgets.systemsettings.tablet.wifisection" : wifiSection,
59 "unity.widgets.systemsettings.tablet.accesspoint" : accessPoint,
59 "unity.widgets.systemsettings.tablet.accesspoint" : accessPoint,
60+ "com.canonical.indicator.network.modeminfoitem" : modeminfoitem,
60 }
61 }
61
62
62 function getExtendedProperty(object, propertyName, defaultValue) {
63 function getExtendedProperty(object, propertyName, defaultValue) {
@@ -374,6 +375,79 @@ Item {
374 }
375 }
375 }
376 }
376
377
378+ Component {
379+ id: modeminfoitem;
380+ ModemInfoItem {
381+ objectName: "modemInfoItem"
382+ property QtObject menuData: null
383+ property var menuModel: menuFactory.menuModel
384+ property int menuIndex: -1
385+ property var extendedData: menuData && menuData.ext || undefined
386+
387+ property var statusLabelAction: UnityMenuAction {
388+ model: menuModel
389+ index: menuIndex
390+ name: getExtendedProperty(extendedData, "xCanonicalModemStatusLabelAction", "")
391+ }
392+ statusText: statusLabelAction.valid ? statusLabelAction.state : ""
393+
394+ property var statusIconAction: UnityMenuAction {
395+ model: menuModel
396+ index: menuIndex
397+ name: getExtendedProperty(extendedData, "xCanonicalModemStatusIconAction", "")
398+ }
399+ statusIcon: statusIconAction.valid ? statusIconAction.state : ""
400+
401+ property var connectivityIconAction: UnityMenuAction {
402+ model: menuModel
403+ index: menuIndex
404+ name: getExtendedProperty(extendedData, "xCanonicalModemConnectivityIconAction", "")
405+ }
406+ connectivityIcon: connectivityIconAction.valid ? connectivityIconAction.state : ""
407+
408+ property var simIdentifierLabelAction: UnityMenuAction {
409+ model: menuModel
410+ index: menuIndex
411+ name: getExtendedProperty(extendedData, "xCanonicalModemSimIdentifierLabelAction", "")
412+ }
413+ simIdentifierText: simIdentifierLabelAction.valid ? simIdentifierLabelAction.state : ""
414+
415+ property var roamingAction: UnityMenuAction {
416+ model: menuModel
417+ index: menuIndex
418+ name: getExtendedProperty(extendedData, "xCanonicalModemRoamingAction", "")
419+ }
420+ roaming: roamingAction.valid ? roamingAction.state : false
421+
422+ property var unlockAction: UnityMenuAction {
423+ model: menuModel
424+ index: menuIndex
425+ name: getExtendedProperty(extendedData, "xCanonicalModemLockedAction", "")
426+ }
427+ onUnlock: {
428+ unlockAction.activate();
429+ }
430+ locked: unlockAction.valid ? unlockAction.state : false
431+
432+ onMenuModelChanged: {
433+ loadAttributes();
434+ }
435+ onMenuIndexChanged: {
436+ loadAttributes();
437+ }
438+
439+ function loadAttributes() {
440+ if (!menuModel || menuIndex == -1) return;
441+ menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-modem-status-label-action': 'string',
442+ 'x-canonical-modem-status-icon-action': 'string',
443+ 'x-canonical-modem-connectivity-icon-action': 'string',
444+ 'x-canonical-modem-sim-identifier-label-action': 'string',
445+ 'x-canonical-modem-roaming-action': 'string',
446+ 'x-canonical-modem-locked-action': 'string'});
447+ }
448+ }
449+ }
450+
377 Component {
451 Component {
378 id: messageItem
452 id: messageItem
379
453
qml/Panel/Indicators/ModemInfoItem.qmlnew file+111
@@ -0,0 +1,111 @@
1+/*
2+ * Copyright 2014 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import QtQuick.Layouts 1.1
19+import Ubuntu.Components 0.1
20+import Ubuntu.Components.ListItems 0.1 as ListItem
21+
22+ListItem.Empty {
23+ id: menu
24+ implicitHeight: mainColumn.implicitHeight
25+ + mainColumn.anchors.topMargin
26+ + mainColumn.anchors.bottomMargin
27+
28+ property alias statusIcon: statusIcon.name
29+ property alias statusText: labelStatus.text
30+ property alias connectivityIcon: iconConnectivity.name
31+ property alias simIdentifierText: labelSimIdentifier.text
32+ property bool locked : false
33+ property bool roaming: false
34+ signal unlock
35+
36+ ColumnLayout {
37+ id: mainColumn
38+ anchors.fill: parent
39+ anchors.margins: menu.__contentsMargins
40+ spacing: units.gu(0.5)
41+
42+ Label {
43+ id: labelSimIdentifier
44+ elide: Text.ElideRight
45+ visible: text !== ""
46+ font.bold: true
47+ opacity: menu.locked ? 0.6 : 1.0
48+ }
49+
50+ RowLayout {
51+ id: statusRow
52+ spacing: units.gu(1)
53+
54+ height: labelStatus.height
55+ width: parent.width
56+
57+ Label {
58+ id: labelStatus
59+ elide: Text.ElideRight
60+ opacity: 0.6
61+ }
62+
63+ RowLayout {
64+ spacing: 0.5
65+ height: parent.height
66+ Icon {
67+ id: statusIcon
68+ color: Theme.palette.selected.backgroundText
69+
70+ Layout.preferredHeight: parent.height
71+ Layout.preferredWidth: Layout.preferredHeight
72+
73+ visible: name !== ""
74+ }
75+
76+ Icon {
77+ id: iconConnectivity
78+ color: Theme.palette.selected.backgroundText
79+
80+ Layout.preferredHeight: parent.height
81+ Layout.preferredWidth: Layout.preferredHeight
82+
83+ visible: name !== ""
84+ }
85+ }
86+
87+ Item {
88+ // eat up all the excess space so that RoamingIndication
89+ // ends up to the far right
90+ Layout.fillWidth: true
91+ }
92+
93+ RoamingIndication {
94+ id: roamingIndication
95+ visible: menu.roaming
96+ Layout.fillHeight: true
97+ }
98+ }
99+
100+ Button {
101+ id: buttonUnlock
102+ objectName: "buttonUnlockSim"
103+ visible: menu.locked
104+
105+ text: i18n.tr("Unlock SIM")
106+ Layout.preferredWidth: implicitWidth + units.gu(5)
107+
108+ onTriggered: menu.unlock()
109+ }
110+ }
111+}
qml/Panel/Indicators/RoamingIndication.qmlnew file+40
@@ -0,0 +1,40 @@
1+/*
2+ * Copyright 2014 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import QtQuick.Layouts 1.1
19+import Ubuntu.Components 0.1
20+
21+RowLayout {
22+ spacing: units.gu(0.5)
23+ Label {
24+ id: labelRoaming
25+ elide: Text.ElideRight
26+ fontSize: "x-small"
27+ text: i18n.tr("Roaming")
28+ opacity: 0.6
29+ }
30+
31+ Icon {
32+ id: iconRoaming
33+ color: Theme.palette.selected.backgroundText
34+
35+ Layout.preferredHeight: parent.height
36+ Layout.preferredWidth: Layout.preferredHeight
37+
38+ name: "network-cellular-roaming"
39+ }
40+}
qml/ScopeTool.qml+1
@@ -17,6 +17,7 @@
17import QtQuick 2.0
17import QtQuick 2.0
18import Ubuntu.Components 0.1
18import Ubuntu.Components 0.1
19import Ubuntu.Components.Popups 0.1
19import Ubuntu.Components.Popups 0.1
20+import Ubuntu.Thumbnailer 0.1 // Register support for image://thumbnailer/ and image://albumart/
20import Utils 0.1
21import Utils 0.1
21import Unity 0.2
22import Unity 0.2
22import "Components"
23import "Components"
qml/Shell.qml+4−23
@@ -112,25 +112,6 @@ Item {
112 }
112 }
113 }
113 }
114
114
115− Item {
116− id: underlay
117− objectName: "underlay"
118− anchors.fill: parent
119−
120− // Whether the underlay is fully covered by opaque UI elements.
121− property bool fullyCovered: (panel.indicators.fullyOpened && shell.width <= panel.indicatorsMenuWidth)
122− || stages.fullyShown || greeterWrapper.fullyShown
123− visible: !fullyCovered
124−
125− Image {
126− anchors.fill: underlay
127− source: shell.width > shell.height ? "Dash/graphics/paper_landscape.png" : "Dash/graphics/paper_portrait.png"
128− fillMode: Image.PreserveAspectCrop
129− horizontalAlignment: Image.AlignRight
130− verticalAlignment: Image.AlignTop
131− }
132− }
133−
134 Item {
115 Item {
135 id: stages
116 id: stages
136 objectName: "stages"
117 objectName: "stages"
@@ -186,12 +167,12 @@ Item {
186 Binding {
167 Binding {
187 target: applicationsDisplayLoader.item
168 target: applicationsDisplayLoader.item
188 property: "interactive"
169 property: "interactive"
189− 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
190 }
171 }
191 Binding {
172 Binding {
192 target: applicationsDisplayLoader.item
173 target: applicationsDisplayLoader.item
193 property: "spreadEnabled"
174 property: "spreadEnabled"
194− value: greeter.fakeActiveForApp === "" // to support emergency dialer hack
175+ value: edgeDemo.stagesEnabled && greeter.fakeActiveForApp === "" // to support emergency dialer hack
195 }
176 }
196 Binding {
177 Binding {
197 target: applicationsDisplayLoader.item
178 target: applicationsDisplayLoader.item
@@ -400,7 +381,7 @@ Item {
400 onDisplayPowerStateChange: {
381 onDisplayPowerStateChange: {
401 // We ignore any display-off signals when the proximity sensor
382 // We ignore any display-off signals when the proximity sensor
402 // is active. This usually indicates something like a phone call.
383 // is active. This usually indicates something like a phone call.
403− if (status == Powerd.Off && reason != Powerd.Proximity) {
384+ if (status == Powerd.Off && reason != Powerd.Proximity && !edgeDemo.running) {
404 greeter.showNow();
385 greeter.showNow();
405 }
386 }
406
387
@@ -580,7 +561,7 @@ Item {
580 greeter: greeter
561 greeter: greeter
581 launcher: launcher
562 launcher: launcher
582 indicators: panel.indicators
563 indicators: panel.indicators
583− underlay: underlay
564+ stages: stages
584 }
565 }
585
566
586 Connections {
567 Connections {
run_on_device.sh+1−3
@@ -2,7 +2,6 @@
2CODE_DIR=shell
2CODE_DIR=shell
3USER=phablet
3USER=phablet
4USER_ID=32011
4USER_ID=32011
5−PASSWORD=phablet
6PACKAGE=unity8
5PACKAGE=unity8
7BINARY=unity8
6BINARY=unity8
8TARGET_IP=${TARGET_IP-127.0.0.1}
7TARGET_IP=${TARGET_IP-127.0.0.1}
@@ -13,7 +12,6 @@ SETUP=false
13GDB=false
12GDB=false
14PINLOCK=false
13PINLOCK=false
15KEYLOCK=false
14KEYLOCK=false
16−SUDO="echo $PASSWORD | sudo -S"
17NUM_JOBS='$(( `grep -c ^processor /proc/cpuinfo` + 1 ))'
15NUM_JOBS='$(( `grep -c ^processor /proc/cpuinfo` + 1 ))'
18FLIPPED=false
16FLIPPED=false
19CHROOT_PREFIX="/data/ubuntu"
17CHROOT_PREFIX="/data/ubuntu"
@@ -76,7 +74,7 @@ setup_adb_forwarding() {
76
74
77install_dependencies() {
75install_dependencies() {
78 exec_with_adb apt-get update
76 exec_with_adb apt-get update
79− exec_with_ssh $SUDO apt-get -y install build-essential rsync bzr ccache gdb ninja-build devscripts equivs unity-plugin-scopes
77+ exec_with_adb apt-get -y --force-yes install build-essential rsync bzr ccache gdb ninja-build devscripts equivs unity-plugin-scopes
80}
78}
81
79
82sync_code() {
80sync_code() {
src/Dash/CMakeLists.txt+1
@@ -1,5 +1,6 @@
1set(DASH_SRCS
1set(DASH_SRCS
2 main.cpp
2 main.cpp
3+ ../MouseTouchAdaptor.cpp
3)
4)
4
5
5add_executable(unity8-dash ${DASH_SRCS})
6add_executable(unity8-dash ${DASH_SRCS})
src/Dash/main.cpp+26−4
@@ -24,8 +24,10 @@
24#include <QDebug>
24#include <QDebug>
25#include <QCommandLineParser>
25#include <QCommandLineParser>
26#include <QLibrary>
26#include <QLibrary>
27+#include <libintl.h>
27
28
28#include <paths.h>
29#include <paths.h>
30+#include "../MouseTouchAdaptor.h"
29
31
30int main(int argc, const char *argv[])
32int main(int argc, const char *argv[])
31{
33{
@@ -35,11 +37,21 @@ int main(int argc, const char *argv[])
35 parser.setApplicationDescription("Description: Unity 8 Shell Dash");
37 parser.setApplicationDescription("Description: Unity 8 Shell Dash");
36 parser.addHelpOption();
38 parser.addHelpOption();
37
39
38− QCommandLineOption testabilityOption("testability",
40+ QCommandLineOption mousetouchOption("mousetouch",
39− "Load the testability driver (Alternatively export QT_LOAD_TESTABILITY");
41+ "Allow the mouse to provide touch input");
40− parser.addOption(testabilityOption);
42+ parser.addOption(mousetouchOption);
41
43
44+ // FIXME Remove once we drop the need of the hint
45+ QCommandLineOption desktopFileHintOption("desktop_file_hint",
46+ "The desktop_file_hint option for QtMir", "hint_file");
47+ parser.addOption(desktopFileHintOption);
48+
49+ // Treat args with single dashes the same as arguments with two dashes
50+ // Ex: -fullscreen == --fullscreen
51+ parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions);
52+ parser.process(*application);
53+
42− if (parser.isSet(testabilityOption) || getenv("QT_LOAD_TESTABILITY")) {
54+ if (getenv("QT_LOAD_TESTABILITY")) {
43 QLibrary testLib(QLatin1String("qttestability"));
55 QLibrary testLib(QLatin1String("qttestability"));
44 if (testLib.load()) {
56 if (testLib.load()) {
45 typedef void (*TasInitialize)(void);
57 typedef void (*TasInitialize)(void);
@@ -54,10 +66,20 @@ int main(int argc, const char *argv[])
54 }
66 }
55 }
67 }
56
68
69+ bindtextdomain("unity8", translationDirectory().toUtf8().data());
70+
57 QQuickView* view = new QQuickView();
71 QQuickView* view = new QQuickView();
58 view->setResizeMode(QQuickView::SizeRootObjectToView);
72 view->setResizeMode(QQuickView::SizeRootObjectToView);
59 view->setTitle("Unity Dash");
73 view->setTitle("Unity Dash");
60
74
75+ // You will need this if you want to interact with touch-only components using a mouse
76+ // Needed only when manually testing on a desktop.
77+ MouseTouchAdaptor *mouseTouchAdaptor = 0;
78+ if (parser.isSet(mousetouchOption)) {
79+ mouseTouchAdaptor = new MouseTouchAdaptor;
80+ application->installNativeEventFilter(mouseTouchAdaptor);
81+ }
82+
61 QUrl source(::qmlDirectory()+"Dash/DashApplication.qml");
83 QUrl source(::qmlDirectory()+"Dash/DashApplication.qml");
62 prependImportPaths(view->engine(), ::overrideImportPaths());
84 prependImportPaths(view->engine(), ::overrideImportPaths());
63 appendImportPaths(view->engine(), ::fallbackImportPaths());
85 appendImportPaths(view->engine(), ::fallbackImportPaths());
tests/autopilot/unity8/shell/emulators/dash.py+1−1
@@ -150,7 +150,7 @@ class Dash(emulators.UnityEmulatorBase):
150 headerContainer.contentY.wait_for(0)
150 headerContainer.contentY.wait_for(0)
151 search_text_field = self._get_search_text_field()
151 search_text_field = self._get_search_text_field()
152 search_text_field.write(query)
152 search_text_field.write(query)
153− current_header.select_single(objectName="searchIndicator").running.wait_for(False)
153+ self.select_single(objectName="processingIndicator").visible.wait_for(False)
154
154
155 def _get_search_text_field(self):
155 def _get_search_text_field(self):
156 page_header = self._get_current_page_header()
156 page_header = self._get_current_page_header()
tests/mocks/Unity/Unity.qmltypes+17−12
@@ -68,6 +68,10 @@ Module {
68 prototype: "unity::shell::scopes::ScopeInterface"
68 prototype: "unity::shell::scopes::ScopeInterface"
69 exports: ["Unity/MockScope 0.2"]
69 exports: ["Unity/MockScope 0.2"]
70 exportMetaObjectRevisions: [0]
70 exportMetaObjectRevisions: [0]
71+ Signal {
72+ name: "performQuery"
73+ Parameter { name: "query"; type: "string" }
74+ }
71 Method {
75 Method {
72 name: "setSearchInProgress"
76 name: "setSearchInProgress"
73 Parameter { name: "inProg"; type: "bool" }
77 Parameter { name: "inProg"; type: "bool" }
@@ -97,9 +101,11 @@ Module {
97 Parameter { name: "altNavigationId"; type: "string" }
101 Parameter { name: "altNavigationId"; type: "string" }
98 }
102 }
99 Method {
103 Method {
100− name: "performQuery"
104+ name: "setNavigationState"
101− Parameter { name: "query"; type: "string" }
105+ Parameter { name: "navigationId"; type: "string" }
106+ Parameter { name: "isAltNavigation"; type: "bool" }
102 }
107 }
108+ Method { name: "refresh" }
103 }
109 }
104 Component {
110 Component {
105 name: "Scopes"
111 name: "Scopes"
@@ -174,18 +180,15 @@ Module {
174 name: "Roles"
180 name: "Roles"
175 values: {
181 values: {
176 "RoleNavigationId": 0,
182 "RoleNavigationId": 0,
177− "RoleQuery": 1,
183+ "RoleLabel": 1,
178− "RoleLabel": 2,
184+ "RoleHasChildren": 2,
179− "RoleHasChildren": 3,
185+ "RoleIsActive": 3
180− "RoleIsActive": 4
181 }
186 }
182 }
187 }
183 Property { name: "navigationId"; type: "string"; isReadonly: true }
188 Property { name: "navigationId"; type: "string"; isReadonly: true }
184− Property { name: "query"; type: "string"; isReadonly: true }
185 Property { name: "label"; type: "string"; isReadonly: true }
189 Property { name: "label"; type: "string"; isReadonly: true }
186 Property { name: "allLabel"; type: "string"; isReadonly: true }
190 Property { name: "allLabel"; type: "string"; isReadonly: true }
187 Property { name: "parentNavigationId"; type: "string"; isReadonly: true }
191 Property { name: "parentNavigationId"; type: "string"; isReadonly: true }
188− Property { name: "parentQuery"; type: "string"; isReadonly: true }
189 Property { name: "parentLabel"; type: "string"; isReadonly: true }
192 Property { name: "parentLabel"; type: "string"; isReadonly: true }
190 Property { name: "loaded"; type: "bool"; isReadonly: true }
193 Property { name: "loaded"; type: "bool"; isReadonly: true }
191 Property { name: "isRoot"; type: "bool"; isReadonly: true }
194 Property { name: "isRoot"; type: "bool"; isReadonly: true }
@@ -334,10 +337,6 @@ Module {
334 name: "openScope"
337 name: "openScope"
335 Parameter { name: "scope"; type: "unity::shell::scopes::ScopeInterface"; isPointer: true }
338 Parameter { name: "scope"; type: "unity::shell::scopes::ScopeInterface"; isPointer: true }
336 }
339 }
337− Signal {
338− name: "activateApplication"
339− Parameter { name: "desktop"; type: "string" }
340− }
341 Method {
340 Method {
342 name: "activate"
341 name: "activate"
343 Parameter { name: "result"; type: "QVariant" }
342 Parameter { name: "result"; type: "QVariant" }
@@ -362,10 +361,16 @@ Module {
362 type: "unity::shell::scopes::NavigationInterface*"
361 type: "unity::shell::scopes::NavigationInterface*"
363 Parameter { name: "altNavigationId"; type: "string" }
362 Parameter { name: "altNavigationId"; type: "string" }
364 }
363 }
364+ Method {
365+ name: "setNavigationState"
366+ Parameter { name: "navId"; type: "string" }
367+ Parameter { name: "altNavigation"; type: "bool" }
368+ }
365 Method {
369 Method {
366 name: "performQuery"
370 name: "performQuery"
367 Parameter { name: "cannedQuery"; type: "string" }
371 Parameter { name: "cannedQuery"; type: "string" }
368 }
372 }
373+ Method { name: "refresh" }
369 }
374 }
370 Component {
375 Component {
371 name: "unity::shell::scopes::ScopesInterface"
376 name: "unity::shell::scopes::ScopesInterface"
tests/mocks/Unity/fake_scope.cpp+5
@@ -220,6 +220,11 @@ QVariantMap Scope::customizations() const
220 return m;
220 return m;
221}
221}
222
222
223+void Scope::refresh()
224+{
225+ qDebug() << "Scope::refresh is currently not implmented in the fake scopes plugin";
226+}
227+
223unity::shell::scopes::NavigationInterface* Scope::getNavigation(const QString& id)
228unity::shell::scopes::NavigationInterface* Scope::getNavigation(const QString& id)
224{
229{
225 if (id.isEmpty())
230 if (id.isEmpty())
tests/mocks/Unity/fake_scope.h+2
@@ -73,6 +73,8 @@ public:
73 Status status() const override;
73 Status status() const override;
74 QVariantMap customizations() const override;
74 QVariantMap customizations() const override;
75
75
76+ Q_INVOKABLE void refresh() override;
77+
76protected:
78protected:
77
79
78 QString m_id;
80 QString m_id;
tests/plugins/Dash/cardcreator/1.res+12−10
@@ -33,20 +33,15 @@ Item {
33 visible: image.status == Image.Ready;
33 visible: image.status == Image.Ready;
34 readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1;
34 readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1;
35 readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1;
35 readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1;
36− readonly property bool aspectSmallerThanImageAspect: aspect < image.aspect;
37− Component.onCompleted: { updateWidthHeightBindings(); if (artShapeBorderSource !== undefined) borderSource = artShapeBorderSource; }
36+ Component.onCompleted: { updateWidthHeightBindings(); if (artShapeBorderSource !== undefined) borderSource = artShapeBorderSource; }
38− onAspectSmallerThanImageAspectChanged: updateWidthHeightBindings();
39 Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); }
37 Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); }
40 function updateWidthHeightBindings() {
38 function updateWidthHeightBindings() {
41 if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) {
39 if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) {
42 width = root.fixedArtShapeSize.width;
40 width = root.fixedArtShapeSize.width;
43 height = root.fixedArtShapeSize.height;
41 height = root.fixedArtShapeSize.height;
44− } else if (aspectSmallerThanImageAspect) {
45− width = Qt.binding(function() { return !visible ? 0 : image.width });
46− height = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.height : width / image.aspect });
47 } else {
42 } else {
48− width = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.width : height * image.aspect });
43+ width = Qt.binding(function() { return !visible ? 0 : image.width });
49− height = Qt.binding(function() { return !visible ? 0 : image.height });
44+ height = Qt.binding(function() { return !visible ? 0 : image.height });
50 }
45 }
51 }
46 }
52 image: Image {
47 image: Image {
@@ -54,8 +49,7 @@ Item {
54 source: cardData && cardData["art"] || "";
49 source: cardData && cardData["art"] || "";
55 cache: true;
50 cache: true;
56 asynchronous: root.asynchronous;
51 asynchronous: root.asynchronous;
57− fillMode: components && components["art"]["fill-mode"] === "fit" ? Image.PreserveAspectFit: Image.PreserveAspectCrop;
52+ fillMode: Image.PreserveAspectCrop;
58− readonly property real aspect: implicitWidth / implicitHeight;
59 width: root.width;
53 width: root.width;
60 height: width / artShape.aspect;
54 height: width / artShape.aspect;
61 }
55 }
@@ -84,5 +78,13 @@ leftMargin: units.gu(1);
84 font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal;
78 font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal;
85 horizontalAlignment: root.headerAlignment;
79 horizontalAlignment: root.headerAlignment;
86 }
80 }
81+UbuntuShape {
82+ id: touchdown;
83+ objectName: "touchdown";
84+ anchors { fill: artShapeHolder }
85+ visible: root.pressed;
86+ radius: "medium";
87+ borderSource: "radius_pressed.sci"
88+}
87implicitHeight: titleLabel.y + titleLabel.height + units.gu(1);
89implicitHeight: titleLabel.y + titleLabel.height + units.gu(1);
88}
90}
tests/plugins/Dash/cardcreator/1.tst+1−1
@@ -1,3 +1,3 @@
1template: {"card-layout":"vertical","card-size":"small","category-layout":"grid","collapsed-rows":2}
1template: {"card-layout":"vertical","card-size":"small","category-layout":"grid","collapsed-rows":2}
2−components: {"art":{"aspect-ratio":1.6,"field":"art","fill-mode":"fit"},"title":{"field":"title"}}
2+components: {"art":{"aspect-ratio":1.6,"field":"art"},"title":{"field":"title"}}
3result: 1.res
3result: 1.res
tests/plugins/Dash/cardcreator/2.res+8
@@ -116,5 +116,13 @@ left: parent.left;
116
116
117 ]
117 ]
118 }
118 }
119+UbuntuShape {
120+ id: touchdown;
121+ objectName: "touchdown";
122+ anchors { fill: backgroundLoader }
123+ visible: root.pressed;
124+ radius: "medium";
125+ borderSource: "radius_pressed.sci"
126+}
119implicitHeight: row.y + row.height + units.gu(1);
127implicitHeight: row.y + row.height + units.gu(1);
120}
128}
tests/plugins/Dash/cardcreator/2.tst+1−1
@@ -1,3 +1,3 @@
1template: {"card-background":{"elements":["#E9E9E9"],"type":"color"},"card-layout":"vertical","card-size":"medium","category-layout":"grid","collapsed-rows":2}
1template: {"card-background":{"elements":["#E9E9E9"],"type":"color"},"card-layout":"vertical","card-size":"medium","category-layout":"grid","collapsed-rows":2}
2−components: {"art":{"aspect-ratio":1,"fill-mode":"crop"},"background":{"field":"background"},"mascot":{"field":"icon"},"subtitle":{"field":"author"},"title":{"field":"title"}}
2+components: {"art":{"aspect-ratio":1},"background":{"field":"background"},"mascot":{"field":"icon"},"subtitle":{"field":"author"},"title":{"field":"title"}}
3result: 2.res
3result: 2.res
tests/plugins/Dash/cardcreator/3.res+12−10
@@ -25,7 +25,7 @@ Item {
25 objectName: "artShapeLoader";
25 objectName: "artShapeLoader";
26 active: cardData && cardData["art"] || false;
26 active: cardData && cardData["art"] || false;
27 asynchronous: root.asynchronous;
27 asynchronous: root.asynchronous;
28− visible: status == Loader.Ready;
28+ visible: status == Loader.Ready;
29 sourceComponent: UbuntuShape {
29 sourceComponent: UbuntuShape {
30 id: artShape;
30 id: artShape;
31 objectName: "artShape";
31 objectName: "artShape";
@@ -33,20 +33,15 @@ Item {
33 visible: image.status == Image.Ready;
33 visible: image.status == Image.Ready;
34 readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1;
34 readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1;
35 readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1;
35 readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1;
36− readonly property bool aspectSmallerThanImageAspect: aspect < image.aspect;
37 Component.onCompleted: { updateWidthHeightBindings(); if (artShapeBorderSource !== undefined) borderSource = artShapeBorderSource; }
36 Component.onCompleted: { updateWidthHeightBindings(); if (artShapeBorderSource !== undefined) borderSource = artShapeBorderSource; }
38− onAspectSmallerThanImageAspectChanged: updateWidthHeightBindings();
39 Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); }
37 Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); }
40 function updateWidthHeightBindings() {
38 function updateWidthHeightBindings() {
41 if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) {
39 if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) {
42 width = root.fixedArtShapeSize.width;
40 width = root.fixedArtShapeSize.width;
43 height = root.fixedArtShapeSize.height;
41 height = root.fixedArtShapeSize.height;
44− } else if (aspectSmallerThanImageAspect) {
45− width = Qt.binding(function() { return !visible ? 0 : image.width });
46− height = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.height : width / image.aspect });
47 } else {
42 } else {
48− width = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.width : height * image.aspect });
43+ width = Qt.binding(function() { return !visible ? 0 : image.width });
49− height = Qt.binding(function() { return !visible ? 0 : image.height });
44+ height = Qt.binding(function() { return !visible ? 0 : image.height });
50 }
45 }
51 }
46 }
52 image: Image {
47 image: Image {
@@ -54,8 +49,7 @@ Item {
54 source: cardData && cardData["art"] || "";
49 source: cardData && cardData["art"] || "";
55 cache: true;
50 cache: true;
56 asynchronous: root.asynchronous;
51 asynchronous: root.asynchronous;
57− fillMode: components && components["art"]["fill-mode"] === "fit" ? Image.PreserveAspectFit: Image.PreserveAspectCrop;
52+ fillMode: Image.PreserveAspectCrop;
58− readonly property real aspect: implicitWidth / implicitHeight;
59 width: root.width;
53 width: root.width;
60 height: width / artShape.aspect;
54 height: width / artShape.aspect;
61 }
55 }
@@ -103,5 +97,13 @@ Label {
103 font.weight: Font.Light;
97 font.weight: Font.Light;
104 horizontalAlignment: root.headerAlignment;
98 horizontalAlignment: root.headerAlignment;
105 }
99 }
100+UbuntuShape {
101+ id: touchdown;
102+ objectName: "touchdown";
103+ anchors { fill: artShapeHolder }
104+ visible: root.pressed;
105+ radius: "medium";
106+ borderSource: "radius_pressed.sci"
107+}
106implicitHeight: subtitleLabel.y + subtitleLabel.height + units.gu(1);
108implicitHeight: subtitleLabel.y + subtitleLabel.height + units.gu(1);
107}
109}
tests/plugins/Dash/cardcreator/3.tst+1−1
@@ -1,3 +1,3 @@
1template: {"card-layout":"vertical","card-size":"small","category-layout":"grid","collapsed-rows":2}
1template: {"card-layout":"vertical","card-size":"small","category-layout":"grid","collapsed-rows":2}
2−components: {"art":{"aspect-ratio":0.75,"field":"art","fill-mode":"crop"},"subtitle":{"field":"price"},"title":{"field":"title"}}
2+components: {"art":{"aspect-ratio":0.75,"field":"art"},"subtitle":{"field":"price"},"title":{"field":"title"}}
3result: 3.res
3result: 3.res
tests/plugins/Dash/cardcreator/4.res+8
@@ -94,5 +94,13 @@ Label {
94}
94}
95]
95]
96}
96}
97+UbuntuShape {
98+ id: touchdown;
99+ objectName: "touchdown";
100+ anchors { fill: root }
101+ visible: root.pressed;
102+ radius: "medium";
103+ borderSource: "radius_pressed.sci"
104+}
97implicitHeight: row.y + row.height + units.gu(1);
105implicitHeight: row.y + row.height + units.gu(1);
98}
106}
tests/plugins/Dash/cardcreator/4.tst+1−1
@@ -1,3 +1,3 @@
1template: {"card-layout":"horizontal","card-size":"large","category-layout":"grid","collapsed-rows":2}
1template: {"card-layout":"horizontal","card-size":"large","category-layout":"grid","collapsed-rows":2}
2−components: {"art":{"aspect-ratio":1,"fill-mode":"crop"},"mascot":{"field":"mascot"},"subtitle":{"field":"domain"},"title":{"field":"title"}}
2+components: {"art":{"aspect-ratio":1},"mascot":{"field":"mascot"},"subtitle":{"field":"domain"},"title":{"field":"title"}}
3result: 4.res
3result: 4.res
tests/plugins/Dash/cardcreator/5.res+14−12
@@ -25,7 +25,7 @@ Item {
25 objectName: "artShapeLoader";
25 objectName: "artShapeLoader";
26 active: cardData && cardData["art"] || false;
26 active: cardData && cardData["art"] || false;
27 asynchronous: root.asynchronous;
27 asynchronous: root.asynchronous;
28− visible: status == Loader.Ready;
28+ visible: status == Loader.Ready;
29 sourceComponent: UbuntuShape {
29 sourceComponent: UbuntuShape {
30 id: artShape;
30 id: artShape;
31 objectName: "artShape";
31 objectName: "artShape";
@@ -33,20 +33,15 @@ Item {
33 visible: image.status == Image.Ready;
33 visible: image.status == Image.Ready;
34 readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1;
34 readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1;
35 readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1;
35 readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1;
36− readonly property bool aspectSmallerThanImageAspect: aspect < image.aspect;
37 Component.onCompleted: { updateWidthHeightBindings(); if (artShapeBorderSource !== undefined) borderSource = artShapeBorderSource; }
36 Component.onCompleted: { updateWidthHeightBindings(); if (artShapeBorderSource !== undefined) borderSource = artShapeBorderSource; }
38− onAspectSmallerThanImageAspectChanged: updateWidthHeightBindings();
39 Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); }
37 Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); }
40 function updateWidthHeightBindings() {
38 function updateWidthHeightBindings() {
41 if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) {
39 if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) {
42 width = root.fixedArtShapeSize.width;
40 width = root.fixedArtShapeSize.width;
43 height = root.fixedArtShapeSize.height;
41 height = root.fixedArtShapeSize.height;
44− } else if (aspectSmallerThanImageAspect) {
45− width = Qt.binding(function() { return !visible ? 0 : image.width });
46− height = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.height : width / image.aspect });
47 } else {
42 } else {
48− width = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.width : height * image.aspect });
43+ width = Qt.binding(function() { return !visible ? 0 : image.width });
49− height = Qt.binding(function() { return !visible ? 0 : image.height });
44+ height = Qt.binding(function() { return !visible ? 0 : image.height });
50 }
45 }
51 }
46 }
52 image: Image {
47 image: Image {
@@ -54,13 +49,12 @@ Item {
54 source: cardData && cardData["art"] || "";
49 source: cardData && cardData["art"] || "";
55 cache: true;
50 cache: true;
56 asynchronous: root.asynchronous;
51 asynchronous: root.asynchronous;
57− fillMode: components && components["art"]["fill-mode"] === "fit" ? Image.PreserveAspectFit: Image.PreserveAspectCrop;
52+ fillMode: Image.PreserveAspectCrop;
58− readonly property real aspect: implicitWidth / implicitHeight;
59 width: root.width;
53 width: root.width;
60 height: width / artShape.aspect;
54 height: width / artShape.aspect;
61 }
55 }
62 }
56 }
63− }
57+ }
64 }
58 }
65Loader {
59Loader {
66 id: overlayLoader;
60 id: overlayLoader;
@@ -69,7 +63,7 @@ Loader {
69 right: artShapeHolder.right;
63 right: artShapeHolder.right;
70 bottom: artShapeHolder.bottom;
64 bottom: artShapeHolder.bottom;
71 }
65 }
72− active: artShapeLoader.active && artShapeLoader.item && artShapeLoader.item.image.status === Image.Ready || false;
66+ active: artShapeLoader.active && artShapeLoader.item && artShapeLoader.item.image.status === Image.Ready || false;
73 asynchronous: root.asynchronous;
67 asynchronous: root.asynchronous;
74 visible: showHeader && status == Loader.Ready;
68 visible: showHeader && status == Loader.Ready;
75 sourceComponent: ShaderEffect {
69 sourceComponent: ShaderEffect {
@@ -143,5 +137,13 @@ Label {
143 font.weight: Font.Light;
137 font.weight: Font.Light;
144 horizontalAlignment: root.headerAlignment;
138 horizontalAlignment: root.headerAlignment;
145 }
139 }
140+UbuntuShape {
141+ id: touchdown;
142+ objectName: "touchdown";
143+ anchors { fill: artShapeHolder }
144+ visible: root.pressed;
145+ radius: "medium";
146+ borderSource: "radius_pressed.sci"
147+}
146implicitHeight: subtitleLabel.y + subtitleLabel.height + units.gu(1);
148implicitHeight: subtitleLabel.y + subtitleLabel.height + units.gu(1);
147}
149}
tests/plugins/Dash/cardcreator/5.tst+1−1
@@ -1,3 +1,3 @@
1template: {"card-layout":"vertical","card-size":"medium","category-layout":"carousel","collapsed-rows":2,"overlay":true}
1template: {"card-layout":"vertical","card-size":"medium","category-layout":"carousel","collapsed-rows":2,"overlay":true}
2−components: {"art":{"aspect-ratio":1,"field":"art","fill-mode":"crop"},"subtitle":{"field":"artist"},"title":{"field":"title"}}
2+components: {"art":{"aspect-ratio":1,"field":"art"},"subtitle":{"field":"artist"},"title":{"field":"title"}}
3result: 5.res
3result: 5.res
tests/plugins/Dash/cardcreator/6.res+10−8
@@ -33,19 +33,14 @@ Item {
33 visible: image.status == Image.Ready;
33 visible: image.status == Image.Ready;
34 readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1;
34 readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1;
35 readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1;
35 readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1;
36− readonly property bool aspectSmallerThanImageAspect: aspect < image.aspect;
37 Component.onCompleted: { updateWidthHeightBindings(); if (artShapeBorderSource !== undefined) borderSource = artShapeBorderSource; }
36 Component.onCompleted: { updateWidthHeightBindings(); if (artShapeBorderSource !== undefined) borderSource = artShapeBorderSource; }
38− onAspectSmallerThanImageAspectChanged: updateWidthHeightBindings();
39 Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); }
37 Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); }
40 function updateWidthHeightBindings() {
38 function updateWidthHeightBindings() {
41 if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) {
39 if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) {
42 width = root.fixedArtShapeSize.width;
40 width = root.fixedArtShapeSize.width;
43 height = root.fixedArtShapeSize.height;
41 height = root.fixedArtShapeSize.height;
44− } else if (aspectSmallerThanImageAspect) {
45− width = Qt.binding(function() { return !visible ? 0 : image.width });
46− height = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.height : width / image.aspect });
47 } else {
42 } else {
48− width = Qt.binding(function() { return !visible ? 0 : image.fillMode === Image.PreserveAspectCrop ? image.width : height * image.aspect });
43+ width = Qt.binding(function() { return !visible ? 0 : image.width });
49 height = Qt.binding(function() { return !visible ? 0 : image.height });
44 height = Qt.binding(function() { return !visible ? 0 : image.height });
50 }
45 }
51 }
46 }
@@ -54,8 +49,7 @@ Item {
54 source: cardData && cardData["art"] || "";
49 source: cardData && cardData["art"] || "";
55 cache: true;
50 cache: true;
56 asynchronous: root.asynchronous;
51 asynchronous: root.asynchronous;
57− fillMode: components && components["art"]["fill-mode"] === "fit" ? Image.PreserveAspectFit: Image.PreserveAspectCrop;
52+ fillMode: Image.PreserveAspectCrop;
58− readonly property real aspect: implicitWidth / implicitHeight;
59 width: root.width;
53 width: root.width;
60 height: width / artShape.aspect;
54 height: width / artShape.aspect;
61 }
55 }
@@ -63,5 +57,13 @@ Item {
63 }
57 }
64 }
58 }
65readonly property int headerHeight: 0;
59readonly property int headerHeight: 0;
60+UbuntuShape {
61+ id: touchdown;
62+ objectName: "touchdown";
63+ anchors { fill: artShapeHolder }
64+ visible: root.pressed;
65+ radius: "medium";
66+ borderSource: "radius_pressed.sci"
67+}
66implicitHeight: artShapeHolder.height;
68implicitHeight: artShapeHolder.height;
67}
69}
tests/plugins/Dash/cardcreator/6.tst+1−1
@@ -1,3 +1,3 @@
1template: {"card-layout":"vertical","card-size":"small","category-layout":"grid","collapsed-rows":2}
1template: {"card-layout":"vertical","card-size":"small","category-layout":"grid","collapsed-rows":2}
2−components: {"art":{"aspect-ratio":1.6,"field":"art","fill-mode":"fit"}}
2+components: {"art":{"aspect-ratio":1.6,"field":"art"}}
3result: 6.res
3result: 6.res
tests/plugins/Dash/cardcreator/7.res+9−1
@@ -116,7 +116,7 @@ CardAttributes {
116 objectName: "attributesRow";
116 objectName: "attributesRow";
117 anchors { left: parent.left; right: parent.right }
117 anchors { left: parent.left; right: parent.right }
118 color: backgroundLoader.active && backgroundLoader.item && backgroundLoader.item.luminance < 0.7 ? "white" : (root.scopeStyle ? root.scopeStyle.foreground : "grey");
118 color: backgroundLoader.active && backgroundLoader.item && backgroundLoader.item.luminance < 0.7 ? "white" : (root.scopeStyle ? root.scopeStyle.foreground : "grey");
119− model: cardData["attributes"]
119+ model: cardData["attributes"];
120 }
120 }
121
121
122 ]
122 ]
@@ -124,5 +124,13 @@ CardAttributes {
124
124
125 ]
125 ]
126 }
126 }
127+UbuntuShape {
128+ id: touchdown;
129+ objectName: "touchdown";
130+ anchors { fill: backgroundLoader }
131+ visible: root.pressed;
132+ radius: "medium";
133+ borderSource: "radius_pressed.sci"
134+}
127implicitHeight: row.y + row.height + units.gu(1);
135implicitHeight: row.y + row.height + units.gu(1);
128}
136}
tests/plugins/Dash/cardcreator/7.tst+1−1
@@ -1,3 +1,3 @@
1template: {"card-background":{"elements":["#E9E9E9"],"type":"color"},"card-layout":"vertical","card-size":"medium","category-layout":"grid","collapsed-rows":2}
1template: {"card-background":{"elements":["#E9E9E9"],"type":"color"},"card-layout":"vertical","card-size":"medium","category-layout":"grid","collapsed-rows":2}
2−components: {"art":{"aspect-ratio":1,"fill-mode":"crop"},"background":{"field":"background"},"mascot":{"field":"icon"},"subtitle":{"field":"author"},"title":{"field":"title"},"attributes":{"field":"attributes","max-count":2}}
2+components: {"art":{"aspect-ratio":1},"background":{"field":"background"},"mascot":{"field":"icon"},"subtitle":{"field":"author"},"title":{"field":"title"},"attributes":{"field":"attributes","max-count":2}}
3result: 7.res
3result: 7.res
tests/plugins/Dash/cardcreatortest.cpp+13−4
@@ -19,6 +19,7 @@
19#include <QQuickItem>
19#include <QQuickItem>
20#include <QQuickView>
20#include <QQuickView>
21#include <QtTestGui>
21#include <QtTestGui>
22+#include <QDebug>
22#include <QTemporaryFile>
23#include <QTemporaryFile>
23
24
24class CardCreatorTest : public QObject
25class CardCreatorTest : public QObject
@@ -74,15 +75,23 @@ private Q_SLOTS:
74 QFile testResultFile(testDirPath + resultFileName);
75 QFile testResultFile(testDirPath + resultFileName);
75 QVERIFY(testResultFile.open(QIODevice::ReadOnly));
76 QVERIFY(testResultFile.open(QIODevice::ReadOnly));
76 QTextStream ts2(&testResultFile);
77 QTextStream ts2(&testResultFile);
77− const QString expectedResult = ts2.readAll();
78+
78− const QString executedResult = cardStringResult.toString();
79 // Record failed results to /tmp
79 // Record failed results to /tmp
80+ const QString executedResult = cardStringResult.toString();
80 QTemporaryFile tmpFile(QDir::tempPath() + QDir::separator() + "testCardCreatorFailedResultXXXXXX");
81 QTemporaryFile tmpFile(QDir::tempPath() + QDir::separator() + "testCardCreatorFailedResultXXXXXX");
81 tmpFile.open();
82 tmpFile.open();
82 tmpFile.setAutoRemove(false);
83 tmpFile.setAutoRemove(false);
83 tmpFile.write(executedResult.toUtf8().constData());
84 tmpFile.write(executedResult.toUtf8().constData());
85+
86+ // Line by line comparison
87+ const QStringList expectedLines = ts2.readAll().trimmed().replace(QRegExp("\n\\s*\n"),"\n").split("\n");
88+ const QStringList cardStringResultLines = cardStringResult.toString().trimmed().replace(QRegExp("\n\\s*\n"),"\n").split("\n");
89+ for (int i = 0; i < expectedLines.size(); ++i) {
84− QCOMPARE(executedResult.simplified(), expectedResult.simplified());
90+ QCOMPARE(cardStringResultLines[i].simplified(), expectedLines[i].simplified());
91+ }
92+
85− tmpFile.setAutoRemove(true); // Remove the result if it passed
93+ // Remove the result if it passed
94+ tmpFile.setAutoRemove(true);
86
95
87 QVariant createCardComponentResult;
96 QVariant createCardComponentResult;
88 QMetaObject::invokeMethod(view->rootObject(), "createCardComponent", Q_RETURN_ARG(QVariant, createCardComponentResult), Q_ARG(QVariant, templateJSON), Q_ARG(QVariant, componentsJSON));
97 QMetaObject::invokeMethod(view->rootObject(), "createCardComponent", Q_RETURN_ARG(QVariant, createCardComponentResult), Q_ARG(QVariant, templateJSON), Q_ARG(QVariant, componentsJSON));
tests/plugins/Dash/tst_ScopeStyle.qml+14−7
@@ -54,6 +54,9 @@ Rectangle {
54 { tag: "lightgrey", luminance: 0.8275 },
54 { tag: "lightgrey", luminance: 0.8275 },
55 { tag: "grey", luminance: 0.5020 },
55 { tag: "grey", luminance: 0.5020 },
56 { tag: "darkgrey", luminance: 0.6627 },
56 { tag: "darkgrey", luminance: 0.6627 },
57+ { tag: "red", luminance: 0.2126 },
58+ { tag: "green", luminance: 0.3590 },
59+ { tag: "blue", luminance: 0.0722 },
57 ];
60 ];
58 }
61 }
59
62
@@ -64,10 +67,10 @@ Rectangle {
64
67
65 function test_foreground_data() {
68 function test_foreground_data() {
66 return [
69 return [
67− { tag: "default", index: 0, foreground: "grey" },
70+ { tag: "default", index: 0, foreground: "grey", luminance: 0.5020 },
68− { tag: "red on black", index: 1, foreground: "red" },
71+ { tag: "red on black", index: 1, foreground: "red", luminance: 0.2126 },
69− { tag: "green on white", index: 2, foreground: "green" },
72+ { tag: "green on white", index: 2, foreground: "green", luminance: 0.3590 },
70− { tag: "blue on darkgrey", index: 3, foreground: "blue" },
73+ { tag: "blue on darkgrey", index: 3, foreground: "blue", luminance: 0.0722 },
71 ];
74 ];
72 }
75 }
73
76
@@ -75,14 +78,15 @@ Rectangle {
75 tool.style = testCase.styles[data.index];
78 tool.style = testCase.styles[data.index];
76 verify(Qt.colorEqual(tool.foreground, data.foreground),
79 verify(Qt.colorEqual(tool.foreground, data.foreground),
77 "Foreground color not equal: %1 != %2".arg(tool.foreground).arg(data.foreground));
80 "Foreground color not equal: %1 != %2".arg(tool.foreground).arg(data.foreground));
81+ compare(tool.foregroundLuminance.toFixed(4), data.luminance.toFixed(4));
78 }
82 }
79
83
80 function test_background_data() {
84 function test_background_data() {
81 return [
85 return [
82 { tag: "default", index: 0, background: "transparent" },
86 { tag: "default", index: 0, background: "transparent" },
83− { tag: "red on black", index: 1, background: "black" },
87+ { tag: "red on black", index: 1, background: "black", luminance: 0 },
84− { tag: "green on white", index: 2, background: "white" },
88+ { tag: "green on white", index: 2, background: "white", luminance: 1 },
85− { tag: "blue on darkgrey", index: 3, background: "darkgrey" },
89+ { tag: "blue on darkgrey", index: 3, background: "darkgrey", luminance: 0.6627 },
86 ];
90 ];
87 }
91 }
88
92
@@ -90,6 +94,9 @@ Rectangle {
90 tool.style = testCase.styles[data.index];
94 tool.style = testCase.styles[data.index];
91 verify(Qt.colorEqual(tool.background, data.background),
95 verify(Qt.colorEqual(tool.background, data.background),
92 "Background color not equal: %1 != %2".arg(tool.background).arg(data.background));
96 "Background color not equal: %1 != %2".arg(tool.background).arg(data.background));
97+ if (data.hasOwnProperty("luminance")) {
98+ compare(tool.backgroundLuminance.toFixed(4), data.luminance.toFixed(4));
99+ }
93 }
100 }
94
101
95 function test_threshold_data() {
102 function test_threshold_data() {
tests/qmltests/CMakeLists.txt+1−1
@@ -30,7 +30,6 @@ add_qml_test(Components Rating)
30add_qml_test(Components ResponsiveFlowView)
30add_qml_test(Components ResponsiveFlowView)
31add_qml_test(Components ResponsiveGridView)
31add_qml_test(Components ResponsiveGridView)
32add_qml_test(Components ResponsiveVerticalJournal IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/plugins)
32add_qml_test(Components ResponsiveVerticalJournal IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/plugins)
33−add_qml_test(Components SeeMore)
34add_qml_test(Components Showable)
33add_qml_test(Components Showable)
35add_qml_test(Components PageHeader)
34add_qml_test(Components PageHeader)
36add_qml_test(Components ZoomableImage)
35add_qml_test(Components ZoomableImage)
@@ -43,6 +42,7 @@ add_qml_test(Dash GenericScopeView)
43add_qml_test(Dash/Previews Preview)
42add_qml_test(Dash/Previews Preview)
44add_qml_test(Dash/Previews PreviewActions)
43add_qml_test(Dash/Previews PreviewActions)
45add_qml_test(Dash/Previews PreviewAudioPlayback)
44add_qml_test(Dash/Previews PreviewAudioPlayback)
45+add_qml_test(Dash/Previews PreviewExpandable)
46add_qml_test(Dash/Previews PreviewHeader)
46add_qml_test(Dash/Previews PreviewHeader)
47add_qml_test(Dash/Previews PreviewImageGallery)
47add_qml_test(Dash/Previews PreviewImageGallery)
48add_qml_test(Dash/Previews PreviewPayments)
48add_qml_test(Dash/Previews PreviewPayments)
tests/qmltests/Components/tst_PageHeader.qml+21−23
@@ -119,29 +119,6 @@ Item {
119 compare(pageHeader.searchHistory.get(0).query, "humppa4")
119 compare(pageHeader.searchHistory.get(0).query, "humppa4")
120 }
120 }
121
121
122− function test_search_indicator() {
123− var searchIndicator = findChild(pageHeader, "searchIndicator")
124− var clearIcon = findChild(pageHeader, "clearIcon")
125−
126− pageHeader.triggerSearch()
127−
128− tryCompare(clearIcon, "visible", false)
129− pageHeader.searchQuery = "ubuntu"
130− tryCompare(clearIcon, "visible", true)
131−
132− pageHeader.searchInProgress = false
133− compare(searchIndicator.running, false, "Search indicator is running.")
134− tryCompare(clearIcon, "visible", true)
135−
136− pageHeader.searchInProgress = true
137− compare(searchIndicator.running, true, "Search indicator isn't running.")
138− tryCompare(clearIcon, "visible", false)
139−
140− pageHeader.searchInProgress = false;
141− compare(searchIndicator.running, false, "Search indicator is running.")
142− tryCompare(clearIcon, "visible", true)
143− }
144−
145 function test_titleImage() {
122 function test_titleImage() {
146
123
147 var titleImage = findChild(pageHeader, "titleImage");
124 var titleImage = findChild(pageHeader, "titleImage");
@@ -192,6 +169,27 @@ Item {
192 ];
169 ];
193 }
170 }
194
171
172+ function test_pagination() {
173+ var paginationRepeater = findChild(pageHeader, "paginationRepeater");
174+ tryCompare(paginationRepeater, "count", 0);
175+ pageHeader.paginationCount = 5;
176+ tryCompare(paginationRepeater, "count", 5);
177+ for (var i=0; i<pageHeader.paginationCount; i++) {
178+ pageHeader.paginationIndex = i;
179+ for (var j=0; j<paginationRepeater.count; j++) {
180+ var paginationDot = findChild(pageHeader, "paginationDots_"+j);
181+ if (i==j) {
182+ compare(paginationDot.source.toString().indexOf("pagination_dot_on") > -1, true);
183+ } else {
184+ compare(paginationDot.source.toString().indexOf("pagination_dot_off") > -1, true);
185+ }
186+ }
187+ }
188+ pageHeader.paginationIndex = -1;
189+ pageHeader.paginationCount = 0;
190+ tryCompare(paginationRepeater, "count", 0);
191+ }
192+
195 function test_popup_closing(data) {
193 function test_popup_closing(data) {
196 searchEnabled = true;
194 searchEnabled = true;
197 pageHeader.searchHistory.clear();
195 pageHeader.searchHistory.clear();
tests/qmltests/Components/tst_SeeMore.qmldeleted−52
@@ -1,52 +0,0 @@
1−/*
2− * Copyright 2014 Canonical Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−import QtQuick 2.0
18−import QtTest 1.0
19−import Ubuntu.Components 0.1
20−import "../../../qml/Components"
21−import Unity.Test 0.1 as UT
22−
23−Rectangle {
24− id: root
25− width: units.gu(40)
26− height: units.gu(10)
27− color: Theme.palette.selected.background
28−
29− SeeMore {
30− id: seeMore
31− anchors.fill: parent
32− more: false
33− }
34−
35− UT.UnityTestCase {
36− name: "SeeMoreTest"
37− when: windowShown
38−
39− function test_interaction() {
40− var seeMoreLabel = findChild(seeMore, "seeMoreLabel")
41− var seeLessLabel = findChild(seeMore, "seeLessLabel")
42−
43− compare(seeMore.more, false)
44−
45− mouseClick(seeMoreLabel, seeMoreLabel.width / 2, seeMoreLabel.height / 2)
46− compare(seeMore.more, true)
47−
48− mouseClick(seeLessLabel, seeLessLabel.width / 2, seeLessLabel.height / 2)
49− compare(seeMore.more, false)
50− }
51− }
52−}
tests/qmltests/Dash/CardHelpers.js+4−3
@@ -16,7 +16,7 @@
16
16
17.pragma library
17.pragma library
18
18
19−var components = ["title", "art", "subtitle", "mascot", "emblem", "old-price", "price", "alt-price", "rating", "alt-rating", "summary", "attributes"]
19+var components = ["title", "art", "subtitle", "mascot", "emblem", "old-price", "price", "alt-price", "rating", "alt-rating", "summary", "attributes", "overlayColor"]
20
20
21var defaultLayout = ' \
21var defaultLayout = ' \
22{ \
22{ \
@@ -31,10 +31,10 @@ var defaultLayout = ' \
31 "components": { \
31 "components": { \
32 "title": null, \
32 "title": null, \
33 "art": { \
33 "art": { \
34− "aspect-ratio": 1.0, \
34+ "aspect-ratio": 1.0 \
35− "fill-mode": "crop" \
36 }, \
35 }, \
37 "subtitle": null, \
36 "subtitle": null, \
37+ "overlayColor": null, \
38 "mascot": null, \
38 "mascot": null, \
39 "emblem": null, \
39 "emblem": null, \
40 "old-price": null, \
40 "old-price": null, \
@@ -60,6 +60,7 @@ var fullMapping = ' \
60 "art": "art", \
60 "art": "art", \
61 "subtitle": "subtitle", \
61 "subtitle": "subtitle", \
62 "mascot": "mascot", \
62 "mascot": "mascot", \
63+ "overlayColor": "overlayColor", \
63 "summary": "summary", \
64 "summary": "summary", \
64 "attributes": "attributes" \
65 "attributes": "attributes" \
65}'
66}'
tests/qmltests/Dash/Previews/tst_PreviewExpandable.qmlnew file+97
@@ -0,0 +1,97 @@
1+/*
2+ * Copyright 2014 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import QtTest 1.0
19+import Ubuntu.Components 0.1
20+import "../../../../qml/Dash/Previews"
21+import Unity.Test 0.1 as UT
22+
23+Rectangle {
24+ id: root
25+ width: units.gu(40)
26+ height: units.gu(80)
27+ color: Theme.palette.selected.background
28+
29+ property string longText: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.\nPhasellus a mi vitae augue rhoncus lobortis ut rutrum metus.\nCurabitur tortor leo, tristique sed mollis quis, condimentum venenatis nibh.\nLorem ipsum dolor sit amet, consectetur adipiscing elit.\nPhasellus a mi vitae augue rhoncus lobortis ut rutrum metus.\nCurabitur tortor leo, tristique sed mollis quis, condimentum venenatis nibh."
30+ property string longText2: "This is a very very very long text. 1 This is a very very very long text. 2 This is a very very very long text. 3 This is a very very very long text. 4 This is a very very very long text. 5 This is a very very very long text. 6 This is a very very very long text. 7 This is a very very very long text. 8 This is a very very very long text. 9 This is a very very very long text. 10 This is a very very very long text. 11 This is a very very very long text."
31+ property string shortText: "This is a short text :)"
32+
33+ property var widgetData: {
34+ "title": "Title here",
35+ "collapsed-widgets": 2,
36+ "widgets": [
37+ { "type": "text", "widgetId" : "text1", "properties" : { "text": longText } },
38+ { "type": "text", "widgetId" : "text2", "properties" : { "text": longText2 } },
39+ { "type": "text", "widgetId" : "text3", "properties" : { "text": shortText } },
40+ { "type": "text", "widgetId" : "text4", "properties" : { "text": longText } }
41+ ]
42+ }
43+
44+ PreviewExpandable {
45+ id: previewExpandable
46+ anchors { left: parent.left; right: parent.right }
47+ widgetData: root.widgetData
48+ }
49+
50+ UT.UnityTestCase {
51+ name: "PreviewExpandableTest"
52+ when: windowShown
53+
54+ function checkInitialState()
55+ {
56+ compare(previewExpandable.expanded, false);
57+
58+ var repeater = findChild(previewExpandable, "repeater")
59+ compare(repeater.count, 4)
60+
61+ compare (repeater.itemAt(0).visible, true);
62+ compare (repeater.itemAt(1).visible, true);
63+ compare (repeater.itemAt(2).visible, false);
64+ compare (repeater.itemAt(3).visible, false);
65+ compare (repeater.itemAt(0).expanded, false);
66+ compare (repeater.itemAt(1).expanded, false);
67+ }
68+
69+ function init() {
70+ }
71+
72+ function test_collapsed_by_default() {
73+ // Nothing init does this already
74+ }
75+
76+ function test_expand_collapse() {
77+ var expandButton = findChild(previewExpandable, "expandButton")
78+ mouseClick(expandButton, expandButton.width / 2, expandButton.height / 2);
79+
80+ var repeater = findChild(previewExpandable, "repeater")
81+ compare(repeater.count, 4)
82+
83+ compare (repeater.itemAt(0).visible, true);
84+ compare (repeater.itemAt(1).visible, true);
85+ compare (repeater.itemAt(2).visible, true);
86+ compare (repeater.itemAt(3).visible, true);
87+ compare (repeater.itemAt(0).expanded, true);
88+ compare (repeater.itemAt(1).expanded, true);
89+ compare (repeater.itemAt(2).expanded, true);
90+ compare (repeater.itemAt(3).expanded, true);
91+
92+ mouseClick(expandButton, expandButton.width / 2, expandButton.height / 2);
93+
94+ checkInitialState();
95+ }
96+ }
97+}
tests/qmltests/Dash/Previews/tst_PreviewTextSummary.qml+4−18
@@ -37,7 +37,7 @@ Rectangle {
37
37
38 property var widgetDataShortText: {
38 property var widgetDataShortText: {
39 "title": "Title here",
39 "title": "Title here",
40− "text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit.\nPhasellus a mi vitae augue rhoncus lobortis ut rutrum metus.\nCurabitur tortor leo, tristique sed mollis quis, condimentum venenatis nibh."
40+ "text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus a mi vitae augue rhoncus lobortis ut rutrum metus."
41 }
41 }
42
42
43 PreviewTextSummary {
43 PreviewTextSummary {
@@ -72,28 +72,14 @@ Rectangle {
72 tryCompare(textLabel, "y", 0)
72 tryCompare(textLabel, "y", 0)
73 }
73 }
74
74
75− function test_see_more() {
75+ function test_show_collapsed() {
76− var seeMore = findChild(previewTextSummary, "seeMore")
77−
78− // when it's more than textLabel.maximumCollapsedLineCount lines of text, show SeeMore component
79 verify(textLabel.lineCount > textLabel.maximumCollapsedLineCount)
76 verify(textLabel.lineCount > textLabel.maximumCollapsedLineCount)
80− compare(seeMore.visible, true)
81− verify(seeMore.more === false)
82− verify(textLabel.height < textLabel.contentHeight)
83
77
84− // test interactions with SeeMore
78+ previewTextSummary.expanded = false;
85− var seeMoreLabel = findChild(seeMore, "seeMoreLabel")
79+ tryCompareFunction(function() { return textLabel.height < textLabel.contentHeight; }, true)
86− var seeLessLabel = findChild(seeMore, "seeLessLabel")
87− var initialTextLabelHeight = textLabel.height
88− mouseClick(seeMoreLabel, seeMoreLabel.width / 2, seeMoreLabel.height / 2)
89− tryCompare(textLabel, "height", textLabel.contentHeight)
90− mouseClick(seeLessLabel, seeLessLabel.width / 2, seeLessLabel.height / 2)
91− tryCompare(textLabel, "height", initialTextLabelHeight)
92
80
93− // text SeeMore automatic hiding
94 previewTextSummary.widgetData = widgetDataShortText
81 previewTextSummary.widgetData = widgetDataShortText
95 verify(textLabel.lineCount <= textLabel.maximumCollapsedLineCount)
82 verify(textLabel.lineCount <= textLabel.maximumCollapsedLineCount)
96− compare(seeMore.visible, false)
97 tryCompare(textLabel, "height", textLabel.contentHeight)
83 tryCompare(textLabel, "height", textLabel.contentHeight)
98 tryCompare(previewTextSummary, "height", titleLabel.height + textLabel.height)
84 tryCompare(previewTextSummary, "height", titleLabel.height + textLabel.height)
99 }
85 }
tests/qmltests/Dash/Previews/tst_PreviewWidgetFactory.qml+1
@@ -77,6 +77,7 @@ Rectangle {
77 return [
77 return [
78 { tag: "Actions", type: "actions", source: "PreviewActions.qml" },
78 { tag: "Actions", type: "actions", source: "PreviewActions.qml" },
79 { tag: "Audio", type: "audio", source: "PreviewAudioPlayback.qml" },
79 { tag: "Audio", type: "audio", source: "PreviewAudioPlayback.qml" },
80+ { tag: "Expandable", type: "expandable", source: "PreviewExpandable.qml" },
80 { tag: "Gallery", type: "gallery", source: "PreviewImageGallery.qml" },
81 { tag: "Gallery", type: "gallery", source: "PreviewImageGallery.qml" },
81 { tag: "Header", type: "header", source: "PreviewHeader.qml" },
82 { tag: "Header", type: "header", source: "PreviewHeader.qml" },
82 { tag: "Image", type: "image", source: "PreviewZoomableImage.qml" },
83 { tag: "Image", type: "image", source: "PreviewZoomableImage.qml" },
tests/qmltests/Dash/tst_Card.qml+15−3
@@ -55,8 +55,8 @@ Rectangle {
55 "layout": { "components": Helpers.update(JSON.parse(Helpers.fullMapping), { "art": { "aspect-ratio": 2 } }) }
55 "layout": { "components": Helpers.update(JSON.parse(Helpers.fullMapping), { "art": { "aspect-ratio": 2 } }) }
56 },
56 },
57 {
57 {
58− "name": "Art, title - fitted",
58+ "name": "Art, title - tall",
59− "layout": { "components": Helpers.update(JSON.parse(Helpers.fullMapping), { "art": { "fill-mode": "fit" } }) }
59+ "layout": { "components": Helpers.update(JSON.parse(Helpers.fullMapping), { "art": { "aspect-ratio": 0.7 } }) }
60 },
60 },
61 {
61 {
62 "name": "Art, header, summary - horizontal",
62 "name": "Art, header, summary - horizontal",
@@ -269,7 +269,7 @@ Rectangle {
269 { tag: "Small", width: units.gu(12), index: 1 },
269 { tag: "Small", width: units.gu(12), index: 1 },
270 { tag: "Large", width: units.gu(38), index: 2 },
270 { tag: "Large", width: units.gu(38), index: 2 },
271 { tag: "Wide", height: units.gu(19), size: "large", index: 3 },
271 { tag: "Wide", height: units.gu(19), size: "large", index: 3 },
272− { tag: "Fit", height: units.gu(38), size: "large", width: units.gu(19), index: 4 },
272+ { tag: "Tall", height: units.gu(38) / 0.7, size: "large", width: units.gu(38), index: 4 },
273 { tag: "VerticalWidth", width: function() { return headerRow.width + units.gu(1) * 2 }, index: 0 },
273 { tag: "VerticalWidth", width: function() { return headerRow.width + units.gu(1) * 2 }, index: 0 },
274 { tag: "HorizontalHeight", height: function() { return headerRow.height + units.gu(1) * 2 }, index: 5 },
274 { tag: "HorizontalHeight", height: function() { return headerRow.height + units.gu(1) * 2 }, index: 5 },
275 { tag: "HorizontalWidth", width: function() { return headerRow.x - units.gu(1) }, index: 5 },
275 { tag: "HorizontalWidth", width: function() { return headerRow.x - units.gu(1) }, index: 5 },
@@ -475,5 +475,17 @@ Rectangle {
475 compare(shape !== null, data.shape);
475 compare(shape !== null, data.shape);
476 tryCompare(mascotImage, "visible", !data.shape);
476 tryCompare(mascotImage, "visible", !data.shape);
477 }
477 }
478+
479+ function test_touchdown_visibility() {
480+ selector.selectedIndex = 0;
481+
482+ var touchdown = findChild(card, "touchdown");
483+
484+ compare(touchdown.visible, false);
485+ mousePress(card, card.width/2, card.height/2);
486+ compare(touchdown.visible, true);
487+ mouseRelease(card, card.width/2, card.height/2);
488+ compare(touchdown.visible, false);
489+ }
478 }
490 }
479}
491}
tests/qmltests/Dash/tst_Dash.qml+28−15
@@ -45,12 +45,8 @@ Item {
45 name: "Dash"
45 name: "Dash"
46 when: windowShown
46 when: windowShown
47
47
48− property var scopes
49−
50− Component.onCompleted: {
51− var dashContent = findChild(dash, "dashContent");
48+ readonly property Item dashContent: findChild(dash, "dashContent");
52− scopes = dashContent.scopes;
49+ readonly property var scopes: dashContent.scopes
53− }
54
50
55 function init() {
51 function init() {
56 // clear and reload the scopes.
52 // clear and reload the scopes.
@@ -64,10 +60,10 @@ Item {
64
60
65 function get_scope_data() {
61 function get_scope_data() {
66 return [
62 return [
67− { tag: "MockScope1", visualIndex: 0, shouldBeVisible: true },
63+ { tag: "MockScope1", visualIndex: 0 },
68− { tag: "MockScope2", visualIndex: -1, shouldBeVisible: false },
64+ { tag: "MockScope2", visualIndex: 1 },
69− { tag: "clickscope", visualIndex: 1, shouldBeVisible: true },
65+ { tag: "clickscope", visualIndex: 2 },
70− { tag: "MockScope5", visualIndex: 2, shouldBeVisible: true },
66+ { tag: "MockScope5", visualIndex: 3 },
71 ]
67 ]
72 }
68 }
73
69
@@ -76,10 +72,6 @@ Item {
76 }
72 }
77
73
78 function test_show_scope_on_load(data) {
74 function test_show_scope_on_load(data) {
79− if (data.shouldBeVisible == false) {
80− console.log("Not testing " + data.tag + ": not visible");
81− return;
82− }
83 var dashContentList = findChild(dash, "dashContentList");
75 var dashContentList = findChild(dash, "dashContentList");
84
76
85 dash.showScopeOnLoaded = data.tag
77 dash.showScopeOnLoaded = data.tag
@@ -87,7 +79,7 @@ Item {
87 tryCompare(dashContentList, "count", 0);
79 tryCompare(dashContentList, "count", 0);
88 scopes.load();
80 scopes.load();
89 tryCompare(scopes, "loaded", true);
81 tryCompare(scopes, "loaded", true);
90− tryCompare(dashContentList, "count", 4);
82+ tryCompare(dashContentList, "count", 5);
91
83
92 verify(dashContentList != undefined);
84 verify(dashContentList != undefined);
93 tryCompare(dashContentList, "currentIndex", data.visualIndex);
85 tryCompare(dashContentList, "currentIndex", data.visualIndex);
@@ -110,5 +102,26 @@ Item {
110 dashCommunicatorService.mockSetCurrentScope("clickscope", true, true);
102 dashCommunicatorService.mockSetCurrentScope("clickscope", true, true);
111 tryCompare(dashContentList, "currentIndex", 1)
103 tryCompare(dashContentList, "currentIndex", 1)
112 }
104 }
105+
106+ function test_processing_indicator() {
107+ tryCompare(scopes, "loaded", true);
108+
109+ var processingIndicator = findChild(dash, "processingIndicator");
110+ verify(processingIndicator, "Can't find the processing indicator.");
111+
112+ verify(!processingIndicator.visible, "Processing indicator should be visible.");
113+
114+ tryCompareFunction(function() {
115+ return scopes.getScope(dashContent.currentIndex) != null;
116+ }, true);
117+ var currentScope = scopes.getScope(dashContent.currentIndex);
118+ verify(currentScope, "Can't find the current scope.");
119+
120+ currentScope.setSearchInProgress(true);
121+ tryCompare(processingIndicator, "visible", true);
122+
123+ currentScope.setSearchInProgress(false);
124+ tryCompare(processingIndicator, "visible", false);
125+ }
113 }
126 }
114}
127}
tests/qmltests/Dash/tst_GenericScopeView.qml+3−2
@@ -129,8 +129,9 @@ Item {
129 var initialHeight = category.height;
129 var initialHeight = category.height;
130 mouseClick(seeAll, seeAll.width / 2, seeAll.height / 2);
130 mouseClick(seeAll, seeAll.width / 2, seeAll.height / 2);
131 verify(category.expanded);
131 verify(category.expanded);
132− tryCompareFunction(function() { return category.height > initialHeight; }, true);
132+ tryCompare(category, "height", category.item.expandedHeight + seeAll.height);
133
133
134+ waitForRendering(seeAll);
134 mouseClick(seeAll, seeAll.width / 2, seeAll.height / 2);
135 mouseClick(seeAll, seeAll.width / 2, seeAll.height / 2);
135 verify(!category.expanded);
136 verify(!category.expanded);
136 }
137 }
@@ -319,7 +320,7 @@ Item {
319 units.gu(2),
320 units.gu(2),
320 testCase.previewListView.height / 2);
321 testCase.previewListView.height / 2);
321 tryCompare(previewListViewList, "moving", false);
322 tryCompare(previewListViewList, "moving", false);
322− tryCompare(testCase.previewListView.currentItem, "objectName", "previewItem" + i);
323+ tryCompare(testCase.previewListView.currentItem, "objectName", "preview" + i);
323
324
324 }
325 }
325 closePreview();
326 closePreview();
tests/qmltests/Panel/Indicators/tst_MenuItemFactory.qml+47
@@ -112,6 +112,7 @@ Item {
112
112
113 { tag: 'wifisection', type: "unity.widgets.systemsettings.tablet.wifisection", objectName: "wifiSection" },
113 { tag: 'wifisection', type: "unity.widgets.systemsettings.tablet.wifisection", objectName: "wifiSection" },
114 { tag: 'accesspoint', type: "unity.widgets.systemsettings.tablet.accesspoint", objectName: "accessPoint" },
114 { tag: 'accesspoint', type: "unity.widgets.systemsettings.tablet.accesspoint", objectName: "accessPoint" },
115+ { tag: 'modeminfoitem', type: "com.canonical.indicator.network.modeminfoitem", objectName: "modemInfoItem" },
115
116
116 { tag: 'unknown', type: "", objectName: "standardMenu"}
117 { tag: 'unknown', type: "", objectName: "standardMenu"}
117 ];
118 ];
@@ -542,6 +543,52 @@ Item {
542 compare(loader.item.enabled, data.enabled, "Enabled does not match data");
543 compare(loader.item.enabled, data.enabled, "Enabled does not match data");
543 }
544 }
544
545
546+ function test_create_modemInfoItem_data() {
547+ // ModemInfoItem gets all it's data through the actions.
548+ return [
549+ {
550+ label: "",
551+ enabled: true,
552+ checked: false,
553+ statusLabelAction: "action::statusLabel",
554+ statusIconAction: "action::statusIcon",
555+ connectivityIconAction: "action::connectivityIcon",
556+ simIdentifierLabelAction: "action::simIdentifierLabel",
557+ roamingAction: "action::roaming",
558+ unlockAction: "action::unlock"
559+ }
560+ ];
561+ }
562+
563+ function test_create_modemInfoItem(data) {
564+ menuData.type = "com.canonical.indicator.network.modeminfoitem";
565+ menuData.label = data.label;
566+ menuData.sensitive = data.enabled;
567+ menuData.isToggled = data.checked;
568+ menuData.ext = {
569+ 'xCanonicalModemStatusLabelAction': data.statusLabelAction,
570+ 'xCanonicalModemStatusIconAction': data.statusIconAction,
571+ 'xCanonicalModemConnectivityIconAction': data.connectivityIconAction,
572+ 'xCanonicalModemSimIdentifierLabelAction': data.simIdentifierLabelAction,
573+ 'xCanonicalModemRoamingAction': data.roamingAction,
574+ 'xCanonicalModemLockedAction': data.unlockAction,
575+ };
576+
577+ loader.data = menuData;
578+ loader.sourceComponent = factory.load(menuData);
579+ tryCompareFunction(function() { return loader.item != undefined; }, true);
580+ compare(loader.item.objectName, "modemInfoItem", "Should have created a modem info item.");
581+ compare(loader.item.text, data.label, "Label does not match data");
582+
583+ compare(loader.item.statusLabelAction.name, data.statusLabelAction, "StatusLabel action incorrect");
584+ compare(loader.item.statusIconAction.name, data.statusIconAction, "StatusIcon action incorrect");
585+ compare(loader.item.connectivityIconAction.name, data.connectivityIconAction, "ConnectivityIcon action incorrect");
586+ compare(loader.item.simIdentifierLabelAction.name, data.simIdentifierLabelAction, " action incorrect");
587+ compare(loader.item.roamingAction.name, data.roamingAction, "Roaming action incorrect");
588+ compare(loader.item.unlockAction.name, data.unlockAction, "Unlock action incorrect");
589+ compare(loader.item.enabled, data.enabled, "Enabled does not match data");
590+ }
591+
545 function test_create_messageItem() {
592 function test_create_messageItem() {
546 menuData.type = "com.canonical.indicator.messages.messageitem";
593 menuData.type = "com.canonical.indicator.messages.messageitem";
547
594