on xenial help sign in
Merged with trunk.
commit21d558e6a59ec071c5a953592e83dc6e9135c6ef authorLeo Arias <leo.arias@canonical.com> dateWed 12 Feb 2014, 00:11 (13 years ago) parent2ad46e7491e0f7
39 files changed+1896−456
debian/changelog+32 po/unity8.pot+52−40 qml/Components/EdgeDemo.qml+1−1 qml/Components/SeeMore.qml+68 qml/Dash/Card.qml+64−3 qml/Dash/CardHeader.qml+8−1 qml/Dash/CardTool.qml+5−1 qml/Dash/Previews/Preview.qml+103 tests/mocks/LightDM/single/InfographicModelPrivate.cpp → qml/Dash/Previews/PreviewActionButton.qml+12−10 qml/Dash/Previews/PreviewActionCombo.qml+66 qml/Dash/Previews/PreviewActions.qml+64 qml/Dash/Previews/PreviewAudioPlayback.qml+204 qml/Dash/Previews/PreviewImageGallery.qml+58 qml/Dash/Previews/PreviewTextSummary.qml+83 qml/Dash/Previews/PreviewWidget.qml+39 qml/Dash/Previews/PreviewWidgetFactory.qml+64 qml/Dash/Music/graphics/music_progress_bg.png → qml/Dash/Previews/graphics/music_progress_bg.png tests/autopilot/unity8/shell/emulators/main_window.py+1−1 tests/mocks/LightDM/demo/GreeterPrivate.cpp+2 tests/mocks/LightDM/demo/InfographicModelPrivate.cpp−91 tests/mocks/LightDM/demo/UsersModelPrivate.cpp+11−3 tests/mocks/LightDM/full/InfographicModelPrivate.cpp−182 tests/mocks/LightDM/single-passphrase/InfographicModelPrivate.cpp−61 tests/mocks/LightDM/single-pin/InfographicModelPrivate.cpp−61 tests/mocks/Unity/CMakeLists.txt+1 tests/mocks/Unity/fake_unity_plugin.cpp+5 tests/mocks/Unity/scopes-ng/fake_preview_model.cpp+96 tests/mocks/Unity/scopes-ng/fake_preview_model.h+68 tests/qmltests/CMakeLists.txt+7 tests/qmltests/Components/tst_SeeMore.qml+52 tests/qmltests/Dash/Previews/MockPreviewWidget.qml+27 tests/qmltests/Dash/Previews/tst_Preview.qml+112 tests/qmltests/Dash/Previews/tst_PreviewActions.qml+148 tests/qmltests/Dash/Previews/tst_PreviewAudioPlayback.qml+179 tests/qmltests/Dash/Previews/tst_PreviewImageGallery.qml+56 tests/qmltests/Dash/Previews/tst_PreviewTextSummary.qml+101 tests/qmltests/Dash/Previews/tst_PreviewWidgetFactory.qml+92 tests/qmltests/Dash/tst_Card.qml+8 tests/qmltests/Dash/tst_CardTool.qml+7−1
debian/changelog+32
@@ -1,3 +1,35 @@
1+unity8 (7.84+14.04.20140207.1-0ubuntu1) trusty; urgency=low
2+
3+ [ Ted Gould ]
4+ * You can't tap anywhere
5+
6+ [ Michał Sawicz ]
7+ * Wait for the indicator to appear.
8+ * Add CardTool to determine category-wide card properties based on the
9+ category template. Clean up test configurations, too.
10+ * Actions Preview Widget
11+ * Add Preview for new generation scopes.
12+ * Add overlay to card. Fix implicit card height. .
13+
14+ [ Albert Astals ]
15+ * Basic ImageGallery widget for Previews Mostly a copy of the code
16+ used in AppPreview.qml but without the MouseArea hack that I'll wait
17+ to introduce until we start using this somewhere were it is needed
18+ * Actions Preview Widget
19+
20+ [ Andrea Cimitan ]
21+ * First audio player widget for previews, with tests
22+ * Adds TextSummary preview widget
23+
24+ [ Michał Karnicki ]
25+ * Add overlay to card. Fix implicit card height. .
26+
27+ [ Michael Terry ]
28+ * Expand greeter demo support to include listing multiple users and
29+ specifying individual passwords and names.
30+
31+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Fri, 07 Feb 2014 10:46:46 +0000
32+
133unity8 (7.84+14.04.20140204-0ubuntu1) trusty; urgency=low
234
335 [ Michael Terry ]
po/unity8.pot+52−40
@@ -8,7 +8,7 @@ msgid ""
88msgstr ""
99"Project-Id-Version: unity8\n"
1010"Report-Msgid-Bugs-To: \n"
11−"POT-Creation-Date: 2013-11-29 09:21+0100\n"
11+"POT-Creation-Date: 2014-02-04 15:43+0000\n"
1212"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
1313"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1414"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -18,141 +18,153 @@ msgstr ""
1818"Content-Transfer-Encoding: 8bit\n"
1919"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
2020
21−#: Components/EdgeDemoOverlay.qml:151
21+#: plugins/Unity/Launcher/launcheritem.cpp:43
22+#: plugins/Unity/Launcher/launcheritem.cpp:73
23+msgid "Lock to Launcher"
24+msgstr ""
25+
26+#: plugins/Unity/Launcher/launcheritem.cpp:73
27+msgid "Unlock from Launcher"
28+msgstr ""
29+
30+#: qml/Components/EdgeDemoOverlay.qml:151
2231msgid "Skip intro"
2332msgstr ""
2433
25−#: Components/EdgeDemo.qml:112
34+#: qml/Components/EdgeDemo.qml:113
2635msgid "Right edge"
2736msgstr ""
2837
29−#: Components/EdgeDemo.qml:113
38+#: qml/Components/EdgeDemo.qml:114
3039msgid "Try swiping from the right edge to unlock the phone"
3140msgstr ""
3241
33−#: Components/EdgeDemo.qml:144
42+#: qml/Components/EdgeDemo.qml:145
3443msgid "Top edge"
3544msgstr ""
3645
37−#: Components/EdgeDemo.qml:145
46+#: qml/Components/EdgeDemo.qml:146
3847msgid "Try swiping from the top edge to access the indicators"
3948msgstr ""
4049
41−#: Components/EdgeDemo.qml:170
50+#: qml/Components/EdgeDemo.qml:171
4251msgid "Close"
4352msgstr ""
4453
45−#: Components/EdgeDemo.qml:171
54+#: qml/Components/EdgeDemo.qml:172
4655msgid "Swipe up again to close the settings screen"
4756msgstr ""
4857
49−#: Components/EdgeDemo.qml:198
58+#: qml/Components/EdgeDemo.qml:199
5059msgid "Left edge"
5160msgstr ""
5261
53−#: Components/EdgeDemo.qml:199
62+#: qml/Components/EdgeDemo.qml:200
5463msgid "Swipe from the left to reveal the launcher for quick access to apps"
5564msgstr ""
5665
57−#: Components/EdgeDemo.qml:226
66+#: qml/Components/EdgeDemo.qml:227
5867msgid "Well done"
5968msgstr ""
6069
61−#: Components/EdgeDemo.qml:227
70+#: qml/Components/EdgeDemo.qml:228
6271msgid ""
6372"You have now mastered the edge gestures and can start using the "
64−"phone<br><br>Tap anywhere to start"
73+"phone<br><br>Tap on the screen to start"
6574msgstr ""
6675
67−#: Components/PageHeader.qml:364
76+#: qml/Components/PageHeader.qml:339
6877msgid "Recent searches"
6978msgstr ""
7079
71−#: Dash/Apps/AppPreview.qml:135
80+#: qml/Components/SeeMore.qml:32
81+msgid "See more"
82+msgstr ""
83+
84+#: qml/Components/SeeMore.qml:61
85+msgid "See less"
86+msgstr ""
87+
88+#: qml/Dash/Apps/AppPreview.qml:136
7289msgid "Rate this"
7390msgstr ""
7491
7592#. TRANSLATORS: Number of persons who rated this app/video/whatever
76−#: Dash/Previews/Header.qml:93
93+#: qml/Dash/Previews/Header.qml:93
7794#, qt-format
7895msgid "(%1)"
7996msgstr ""
8097
8198#. TRANSLATORS: Number of persons who wrote reviews for this app/video/whatever
82−#: Dash/Previews/Header.qml:105
99+#: qml/Dash/Previews/Header.qml:105
83100#, qt-format
84101msgid "%1 review"
85102msgid_plural "%1 reviews"
86103msgstr[0] ""
87104msgstr[1] ""
88105
89−#: Dash/Previews/Reviews.qml:74
106+#: qml/Dash/Previews/Reviews.qml:74
90107msgid "Add a review"
91108msgstr ""
92109
93−#: Dash/Previews/Reviews.qml:86
110+#: qml/Dash/Previews/Reviews.qml:86
94111msgid "Review"
95112msgstr ""
96113
97−#: Dash/Previews/Reviews.qml:121
114+#: qml/Dash/Previews/Reviews.qml:121
98115msgid "Send"
99116msgstr ""
100117
101−#: Dash/Previews/Reviews.qml:139
118+#: qml/Dash/Previews/Reviews.qml:139
102119msgid "Comments:"
103120msgstr ""
104121
105−#: Greeter/Lockscreen.qml:149
122+#: qml/Greeter/Lockscreen.qml:149
106123msgid "Emergency Call"
107124msgstr ""
108125
109−#: Greeter/PassphraseLockscreen.qml:59
126+#: qml/Greeter/PassphraseLockscreen.qml:59
110127#, qt-format
111128msgid "Hello %1"
112129msgstr ""
113130
114−#: Greeter/PassphraseLockscreen.qml:59
131+#: qml/Greeter/PassphraseLockscreen.qml:59
115132msgid "Hello"
116133msgstr ""
117134
118−#: Hud/HudParametrizedActionsPage.qml:132
135+#: qml/Hud/HudParametrizedActionsPage.qml:132
119136msgid "Confirm"
120137msgstr ""
121138
122−#: Hud/Hud.qml:61 Hud/Hud.qml:99 Hud/Hud.qml:372
139+#: qml/Hud/Hud.qml:61 qml/Hud/Hud.qml:99 qml/Hud/Hud.qml:372
123140msgid "Type or say a command"
124141msgstr ""
125142
126−#: Hud/Hud.qml:84
143+#: qml/Hud/Hud.qml:84
127144msgid "Loading. Please Wait..."
128145msgstr ""
129146
130−#: Hud/Hud.qml:89
147+#: qml/Hud/Hud.qml:89
131148msgid "Speak Now..."
132149msgstr ""
133150
134−#: Hud/Hud.qml:94
151+#: qml/Hud/Hud.qml:94
135152msgid "Speaking..."
136153msgstr ""
137154
138−#: Notifications/NotificationMenuItemFactory.qml:89
155+#: qml/Notifications/NotificationMenuItemFactory.qml:91
139156msgid "Show password"
140157msgstr ""
141158
142−#: Panel/SearchIndicator.qml:27
143−msgid "Search"
159+#: qml/Notifications/NotificationMenuItemFactory.qml:103
160+msgid "Please enter SIM PIN"
144161msgstr ""
145162
146−#: plugins/Unity/Launcher/launcheritem.cpp:43
147−#: plugins/Unity/Launcher/launcheritem.cpp:73
148−msgid "Lock to Launcher"
149−msgstr ""
150−
151−#: plugins/Unity/Launcher/launcheritem.cpp:73
152−msgid "Unlock from Launcher"
163+#: qml/Panel/SearchIndicator.qml:27
164+msgid "Search"
153165msgstr ""
154166
155−#: Shell.qml:439
167+#: qml/Shell.qml:440
156168#, qt-format
157169msgid "Please enter %1"
158170msgstr ""
qml/Components/EdgeDemo.qml+1−1
@@ -225,7 +225,7 @@ Item {
225225 d.finalEdgeDemo = d.overlay.createObject(demo.underlay, {
226226 "edge": "none",
227227 "title": i18n.tr("Well done"),
228− "text": i18n.tr("You have now mastered the edge gestures and can start using the phone<br><br>Tap anywhere to start"),
228+ "text": i18n.tr("You have now mastered the edge gestures and can start using the phone<br><br>Tap on the screen to start"),
229229 "anchors.fill": demo.dash,
230230 "showSkip": false,
231231 });
qml/Components/SeeMore.qmlnew file+68
@@ -0,0 +1,68 @@
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+ color: Theme.palette.selected.backgroundText
38+ font.weight: Font.Bold
39+
40+ MouseArea {
41+ anchors.fill: parent
42+ onClicked: more = true
43+ }
44+ }
45+
46+ Image {
47+ anchors {
48+ top: parent.top
49+ bottom: parent.bottom
50+ }
51+ width: units.dp(2)
52+ source: "ListItems/graphics/ListItemDividerVertical.png"
53+ }
54+
55+ Label {
56+ objectName: "seeLessLabel"
57+ text: i18n.tr("See less")
58+ opacity: more ? 0.8 : 0.4
59+ color: Theme.palette.selected.backgroundText
60+ font.weight: Font.Bold
61+
62+ MouseArea {
63+ anchors.fill: parent
64+ onClicked: more = false
65+ }
66+ }
67+ }
68+}
qml/Dash/Card.qml+64−3
@@ -23,8 +23,13 @@ Item {
2323 property var components
2424 property var cardData
2525
26+ property alias fontScale: header.fontScale
27+ readonly property alias headerHeight: header.height
28+
29+ property bool showHeader: true
30+
2631 implicitWidth: childrenRect.width
27− implicitHeight: childrenRect.height
32+ implicitHeight: summary.y + summary.height
2833
2934 UbuntuShape {
3035 id: artShape
@@ -58,21 +63,77 @@ Item {
5863 }
5964 }
6065
66+ ShaderEffect {
67+ id: overlay
68+ anchors {
69+ left: artShape.left
70+ right: artShape.right
71+ bottom: artShape.bottom
72+ }
73+
74+ height: header.height
75+ opacity: header.opacity * 0.6
76+ visible: template && template["overlay"] && artShape.visible && artShape.image.status === Image.Ready || false
77+
78+ property var source: ShaderEffectSource {
79+ id: shaderSource
80+ sourceItem: artShape
81+ onVisibleChanged: if (visible) scheduleUpdate()
82+ live: false
83+ sourceRect: Qt.rect(0, artShape.height - overlay.height, artShape.width, overlay.height)
84+ }
85+
86+ vertexShader: "
87+ uniform highp mat4 qt_Matrix;
88+ attribute highp vec4 qt_Vertex;
89+ attribute highp vec2 qt_MultiTexCoord0;
90+ varying highp vec2 coord;
91+ void main() {
92+ coord = qt_MultiTexCoord0;
93+ gl_Position = qt_Matrix * qt_Vertex;
94+ }"
95+
96+ fragmentShader: "
97+ varying highp vec2 coord;
98+ uniform sampler2D source;
99+ uniform lowp float qt_Opacity;
100+ void main() {
101+ lowp vec4 tex = texture2D(source, coord);
102+ gl_FragColor = vec4(0, 0, 0, tex.a) * qt_Opacity;
103+ }"
104+ }
105+
61106 CardHeader {
62107 id: header
63108 objectName: "cardHeader"
64109 anchors {
65− top: template && template["card-layout"] === "horizontal" ? artShape.top : artShape.bottom
66− left: template && template["card-layout"] === "horizontal" ? artShape.right : parent.left
110+ top: {
111+ if (template) {
112+ if (template["overlay"]) return overlay.top;
113+ if (template["card-layout"] === "horizontal") return artShape.top;
114+ }
115+ return artShape.bottom;
116+ }
117+ left: {
118+ if (template) {
119+ if (!template["overlay"] && template["card-layout"] === "horizontal") return artShape.right;
120+ }
121+ return parent.left;
122+ }
67123 right: parent.right
68124 }
69125
70126 mascot: cardData && cardData["mascot"] || ""
71127 title: cardData && cardData["title"] || ""
72128 subtitle: cardData && cardData["subtitle"] || ""
129+
130+ opacity: showHeader ? 1 : 0
131+
132+ Behavior on opacity { NumberAnimation { duration: UbuntuAnimation.SnapDuration } }
73133 }
74134
75135 Label {
136+ id: summary
76137 objectName: "summaryLabel"
77138 anchors { top: header.visible ? header.bottom : artShape.bottom; left: parent.left; right: parent.right }
78139 wrapMode: Text.Wrap
qml/Dash/CardHeader.qml+8−1
@@ -26,6 +26,9 @@ Item {
2626 property alias oldPrice: oldPriceLabel.text
2727 property alias altPrice: altPriceLabel.text
2828
29+ // FIXME: Saviq, used to scale fonts down in Carousel
30+ property real fontScale: 1.0
31+
2932 visible: mascotImage.status === Image.Ready || title || price
3033 height: row.height > 0 ? row.height + row.margins * 2 : 0
3134
@@ -41,7 +44,7 @@ Item {
4144 leftMargin: spacing
4245 rightMargin: spacing
4346 }
44− spacing: mascotShape.visible ? margins : 0
47+ spacing: mascotShape.visible || (template && template["overlay"]) ? margins : 0
4548
4649 UbuntuShape {
4750 id: mascotShape
@@ -77,6 +80,8 @@ Item {
7780 wrapMode: Text.Wrap
7881 maximumLineCount: 2
7982 fontSize: "small"
83+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale)
84+ color: template["overlay"] === true ? "white" : Theme.palette.selected.backgroundText
8085 }
8186
8287 Label {
@@ -87,6 +92,8 @@ Item {
8792 font.weight: Font.Light
8893 visible: titleLabel.text && text
8994 fontSize: "x-small"
95+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale)
96+ color: template["overlay"] === true ? "white" : Theme.palette.selected.backgroundText
9097 }
9198
9299 Row {
qml/Dash/CardTool.qml+5−1
@@ -100,10 +100,14 @@ Item {
100100 }
101101 }
102102
103− readonly property QtObject priv: card
103+ /*!
104+ type:real \brief Height of the card's header.
105+ */
106+ readonly property alias headerHeight: card.headerHeight
104107
105108 Card {
106109 id: card
110+ objectName: "card"
107111 template: cardTool.template
108112 components: cardTool.components
109113
qml/Dash/Previews/Preview.qmlnew file+103
@@ -0,0 +1,103 @@
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+/*! \brief This component constructs the Preview UI.
21+ *
22+ * Currently it displays all the widgets in a flickable column.
23+ */
24+
25+Item {
26+ id: root
27+
28+ /*! \brief Model containing preview widgets.
29+ *
30+ * The model should expose "widgetId", "type" and "properties" roles, as well as
31+ * have a triggered(QString widgetId, QString actionId, QVariantMap data) method,
32+ * that's called when actions are executed in widgets.
33+ */
34+ property var previewModel
35+
36+ //! \brief Should be set to true if this preview is currently displayed.
37+ property bool isCurrent: false
38+
39+ clip: true
40+
41+ Connections {
42+ target: shell.applicationManager
43+ onMainStageFocusedApplicationChanged: {
44+ root.close();
45+ }
46+ onSideStageFocusedApplicationChanged: {
47+ root.close();
48+ }
49+ }
50+
51+ onPreviewModelChanged: processingMouseArea.enabled = false
52+
53+ MouseArea {
54+ anchors.fill: parent
55+ }
56+
57+ Row {
58+ id: row
59+
60+ spacing: units.gu(1)
61+ anchors { fill: parent; margins: spacing }
62+
63+ Repeater {
64+ model: 1
65+
66+ delegate: ListView {
67+ id: column
68+ anchors { top: parent.top; bottom: parent.bottom }
69+ width: row.width
70+ spacing: row.spacing
71+ bottomMargin: Qt.inputMethod.visible ? Qt.inputMethod.keyboardRectangle.height : 0
72+
73+ model: previewModel
74+
75+ Behavior on contentY { UbuntuNumberAnimation { } }
76+
77+ delegate: PreviewWidgetFactory {
78+ widgetId: model.widgetId
79+ widgetType: model.type
80+ widgetData: model.properties
81+ isCurrentPreview: root.isCurrent
82+ anchors { left: parent.left; right: parent.right }
83+
84+ onTriggered: {
85+ processingMouseArea.enabled = true;
86+ previewModel.triggered(widgetId, actionId, data);
87+ }
88+
89+ onFocusChanged: if (focus) column.positionViewAtIndex(index, ListView.Contain)
90+
91+ onHeightChanged: if (focus) column.positionViewAtIndex(index, ListView.Contain)
92+ }
93+ }
94+ }
95+ }
96+
97+ MouseArea {
98+ id: processingMouseArea
99+ objectName: "processingMouseArea"
100+ anchors.fill: parent
101+ enabled: false
102+ }
103+}
tests/mocks/LightDM/single/InfographicModelPrivate.cpp → qml/Dash/Previews/PreviewActionButton.qmlrenamed+12−10
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2013 Canonical, Ltd.
2+ * Copyright (C) 2014 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -12,17 +12,19 @@
1212 *
1313 * You should have received a copy of the GNU General Public License
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− *
16− * Author: Pete Woods <pete.woods@canonical.com>
1715 */
1816
19−#include "../InfographicModelPrivate.h"
20−
21−namespace QLightDM
22−{
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
2319
24−void InfographicModelPrivate::generateFakeData()
25−{
26−}
20+Button {
21+ signal triggeredAction(string id)
2722
23+ property var data: null
24+ objectName: "button" + (data && data.id || "")
25+ color: Theme.palette.selected.foreground
26+ text: data && data.label || ""
27+ iconSource: data && data.icon || ""
28+ iconPosition: "left"
29+ onClicked: triggeredAction(data.id)
2830}
qml/Dash/Previews/PreviewActionCombo.qmlnew file+66
@@ -0,0 +1,66 @@
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+Item {
21+ id: root
22+
23+ implicitHeight: childrenRect.height
24+
25+ signal triggeredAction(string id)
26+
27+ property alias model: actionRepeater.model
28+
29+ Button {
30+ id: moreButton
31+ property bool expanded: false
32+
33+ objectName: "moreLessButton"
34+ text: !expanded ? i18n.tr("More...") : i18n.tr("Less...")
35+ color: Theme.palette.selected.foreground
36+ onClicked: expanded = !expanded
37+ width: parent.width
38+ }
39+
40+ Column {
41+ anchors {
42+ top: moreButton.bottom
43+ topMargin: height > 0 ? spacing : 0
44+ }
45+ objectName: "buttonColumn"
46+ spacing: units.gu(1)
47+ width: parent.width
48+ height: moreButton.expanded ? implicitHeight : 0
49+ clip: true
50+ Behavior on height {
51+ UbuntuNumberAnimation {
52+ duration: UbuntuAnimation.SnapDuration
53+ }
54+ }
55+
56+ Repeater {
57+ id: actionRepeater
58+
59+ delegate: PreviewActionButton {
60+ data: modelData
61+ width: implicitWidth < parent.width ? parent.width : implicitWidth
62+ onClicked: root.triggeredAction(modelData.id)
63+ }
64+ }
65+ }
66+}
qml/Dash/Previews/PreviewActions.qmlnew file+64
@@ -0,0 +1,64 @@
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.1
18+
19+/*! This preview widget shows either one button, two buttons or one button
20+ * and a combo button depending on the number of items in widgetData["actions"].
21+ * For each of the items we recognize the fields "label", "icon" and "id".
22+ */
23+
24+PreviewWidget {
25+ id: root
26+
27+ height: row.height
28+
29+ Row {
30+ id: row
31+ readonly property var actions: root.widgetData ? root.widgetData["actions"] : null
32+ anchors.right: parent.right
33+
34+ spacing: units.gu(1)
35+
36+ Loader {
37+ id: loader
38+ readonly property bool button: row.actions && row.actions.length == 2
39+ readonly property bool combo: row.actions && row.actions.length > 2
40+ source: button ? "PreviewActionButton.qml" : (combo ? "PreviewActionCombo.qml" : "")
41+ width: (root.width - units.gu(1)) / 2
42+ onLoaded: {
43+ if (button) {
44+ item.data = row.actions[1];
45+ } else if (combo) {
46+ item.model = row.actions.slice(1);
47+ }
48+ }
49+ Connections {
50+ target: loader.item
51+ onTriggeredAction: {
52+ root.triggered(root.widgetId, id, null);
53+ }
54+ }
55+ }
56+
57+ PreviewActionButton {
58+ data: visible ? row.actions[0] : null
59+ visible: row.actions && row.actions.length > 0
60+ onTriggeredAction: root.triggered(root.widgetId, id, null)
61+ width: (root.width - units.gu(1)) / 2
62+ }
63+ }
64+}
qml/Dash/Previews/PreviewAudioPlayback.qmlnew file+204
@@ -0,0 +1,204 @@
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 QtMultimedia 5.0
19+import Ubuntu.Components 0.1
20+
21+/*! \brief Preview widget for audio tracks.
22+
23+ This widget shows tracks contained in widgetData["tracks"], each of which should be of the form:
24+
25+ \code{.json}
26+ {
27+ "source" "uri://to/file",
28+ "title": "Title",
29+ "subtitle": "Subtitle", // optional
30+ "length": 125 // in seconds
31+ }
32+ \endcode
33+ */
34+
35+PreviewWidget {
36+ id: root
37+ height: childrenRect.height
38+
39+ onIsCurrentPreviewChanged: if (!isCurrentPreview) audio.stop()
40+
41+ Audio {
42+ id: audio
43+ objectName: "audio"
44+
45+ property real progress: audio.position / audio.duration
46+ property Item playingItem
47+
48+ Component.onDestruction: {
49+ // destroying the component doesn't automatically send stop to the media service, probably a bug in QtMultimedia
50+ audio.stop();
51+ }
52+
53+ onErrorStringChanged: console.warn("Audio player error:", errorString)
54+
55+ function lengthToString(s) {
56+ if (typeof(s) !== "number" || s <= 0) return "";
57+
58+ var sec = "" + s % 60;
59+ if (sec.length == 1) sec = "0" + sec;
60+ var hour = Math.floor(s / 3600);
61+ if (hour < 1) {
62+ return Math.floor(s / 60) + ":" + sec;
63+ } else {
64+ var min = "" + Math.floor(s / 60) % 60;
65+ if (min.length == 1) min = "0" + min;
66+ return hour + ":" + min + ":" + sec;
67+ }
68+ }
69+ }
70+
71+ Column {
72+ anchors { left: parent.left; right: parent.right }
73+ visible: trackRepeater.count > 0
74+
75+ Repeater {
76+ id: trackRepeater
77+ objectName: "trackRepeater"
78+ model: root.widgetData["tracks"]
79+
80+ function play(item, source) {
81+ audio.stop();
82+ // Make sure we change the source, even if two items point to the same uri location
83+ audio.source = "";
84+ audio.source = source;
85+ audio.playingItem = item;
86+ audio.play();
87+ }
88+
89+ delegate: Item {
90+ id: trackItem
91+ objectName: "trackItem" + index
92+
93+ property bool isPlayingItem: audio.playingItem == trackItem
94+
95+ anchors { left: parent.left; right: parent.right }
96+ height: units.gu(5)
97+
98+ Row {
99+ id: trackRow
100+
101+ property int column1Width: units.gu(3)
102+ property int column2Width: width - (2 * spacing) - column1Width - column3Width
103+ property int column3Width: units.gu(4)
104+
105+ anchors.verticalCenter: parent.verticalCenter
106+ width: parent.width
107+ spacing: units.gu(1)
108+
109+ Button {
110+ objectName: "playButton"
111+ width: trackRow.column1Width
112+ height: width
113+ iconSource: audio.playbackState == Audio.PlayingState && trackItem.isPlayingItem ? "image://theme/media-playback-pause" : "image://theme/media-playback-start"
114+
115+ // Can't be "transparent" or "#00xxxxxx" as the button optimizes away the surrounding shape
116+ // FIXME when this is resolved: https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1251685
117+ color: "#01000000"
118+
119+ onClicked: {
120+ if (trackItem.isPlayingItem) {
121+ if (audio.playbackState == Audio.PlayingState) {
122+ audio.pause();
123+ } else if (audio.playbackState == Audio.PausedState) {
124+ audio.play();
125+ }
126+ } else {
127+ trackRepeater.play(trackItem, modelData["source"]);
128+ }
129+ }
130+ }
131+
132+ Item {
133+ anchors.verticalCenter: parent.verticalCenter
134+ width: parent.column2Width
135+ height: trackSubtitleLabel.visible ? trackTitleLabel.height + trackSubtitleLabel.height : trackTitleLabel.height
136+
137+ Label {
138+ id: trackTitleLabel
139+ objectName: "trackTitleLabel"
140+ anchors { top: parent.top; left: parent.left; right: parent.right }
141+ opacity: 0.9
142+ color: Theme.palette.selected.backgroundText
143+ fontSize: "small"
144+ horizontalAlignment: Text.AlignLeft
145+ text: modelData["title"]
146+ elide: Text.ElideRight
147+ }
148+
149+ Label {
150+ id: trackSubtitleLabel
151+ objectName: "trackSubtitleLabel"
152+ anchors { top: trackTitleLabel.bottom; left: parent.left; right: parent.right }
153+ visible: text !== ""
154+ opacity: 0.9
155+ color: Theme.palette.selected.backgroundText
156+ fontSize: "small"
157+ horizontalAlignment: Text.AlignLeft
158+ text: modelData["subtitle"] || ""
159+ elide: Text.ElideRight
160+ }
161+
162+ UbuntuShape {
163+ id: progressBarFill
164+ objectName: "progressBarFill"
165+
166+ property int maxWidth: progressBarImage.width - units.dp(4)
167+
168+ anchors {
169+ left: progressBarImage.left
170+ right: progressBarImage.right
171+ verticalCenter: progressBarImage.verticalCenter
172+ margins: units.dp(2)
173+ rightMargin: maxWidth - (maxWidth * audio.progress) + units.dp(2)
174+ }
175+ height: units.dp(2)
176+ visible: progressBarImage.visible
177+ color: UbuntuColors.orange
178+ }
179+
180+ Image {
181+ id: progressBarImage
182+ anchors { left: parent.left; top: parent.bottom; right: parent.right }
183+ height: units.dp(6)
184+ visible: audio.playbackState != Audio.StoppedState && trackItem.isPlayingItem && modelData["length"] > 0
185+ source: "graphics/music_progress_bg.png"
186+ }
187+ }
188+
189+ Label {
190+ id: timeLabel
191+ objectName: "timeLabel"
192+ anchors.verticalCenter: parent.verticalCenter
193+ width: parent.column3Width
194+ opacity: 0.9
195+ color: Theme.palette.selected.backgroundText
196+ fontSize: "small"
197+ horizontalAlignment: Text.AlignRight
198+ text: audio.lengthToString(modelData["length"])
199+ }
200+ }
201+ }
202+ }
203+ }
204+}
qml/Dash/Previews/PreviewImageGallery.qmlnew file+58
@@ -0,0 +1,58 @@
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 "../../Components"
19+
20+/*! This preview widget shows a horizontal list of images.
21+ * The URIs for the images should be an array in widgetData["sources"].
22+ */
23+
24+PreviewWidget {
25+ id: root
26+ implicitHeight: units.gu(22)
27+
28+ ListView {
29+ id: previewImageListView
30+ spacing: units.gu(1)
31+ anchors.fill: parent
32+ orientation: ListView.Horizontal
33+ cacheBuffer: width * 3
34+ model: root.widgetData["sources"]
35+
36+ LazyImage {
37+ objectName: "placeholderScreenshot"
38+ anchors {
39+ top: parent.top
40+ bottom: parent.bottom
41+ }
42+ scaleTo: "height"
43+ source: "broken_image"
44+ initialWidth: units.gu(13)
45+ visible: previewImageListView.count == 0
46+ }
47+
48+ delegate: LazyImage {
49+ anchors {
50+ top: parent.top
51+ bottom: parent.bottom
52+ }
53+ source: modelData ? modelData : ""
54+ scaleTo: "height"
55+ initialWidth: units.gu(13)
56+ }
57+ }
58+}
qml/Dash/Previews/PreviewTextSummary.qmlnew file+83
@@ -0,0 +1,83 @@
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+import "../../Components"
20+
21+/*! \brief Preview widget for text.
22+
23+ This widget shows text contained in widgetData["text"]
24+ along with a title that comes from widgetData["title"].
25+
26+ In case the text does not fit in 7 lines a See More / Less widget is also shown.
27+ */
28+
29+PreviewWidget {
30+ id: root
31+ implicitHeight: childrenRect.height
32+
33+ Label {
34+ id: titleLabel
35+ objectName: "titleLabel"
36+ anchors {
37+ left: parent.left
38+ right: parent.right
39+ }
40+ fontSize: "large"
41+ color: Theme.palette.selected.backgroundText
42+ visible: text !== ""
43+ opacity: .8
44+ text: widgetData["title"] || ""
45+ wrapMode: Text.Wrap
46+ }
47+
48+ Label {
49+ id: textLabel
50+ objectName: "textLabel"
51+
52+ readonly property int maximumCollapsedLineCount: 7
53+
54+ anchors {
55+ left: parent.left
56+ right: parent.right
57+ top: titleLabel.visible ? titleLabel.bottom : parent.top
58+ }
59+ height: (!seeMore.visible || seeMore.more) ? contentHeight : contentHeight / lineCount * (maximumCollapsedLineCount - 2)
60+ clip: true
61+ fontSize: "medium"
62+ color: Theme.palette.selected.backgroundText
63+ opacity: .8
64+ text: widgetData["text"]
65+ wrapMode: Text.Wrap
66+
67+ Behavior on height {
68+ UbuntuNumberAnimation {}
69+ }
70+ }
71+
72+ SeeMore {
73+ id: seeMore
74+ objectName: "seeMore"
75+ anchors {
76+ left: parent.left
77+ right: parent.right
78+ top: textLabel.bottom
79+ topMargin: units.gu(1)
80+ }
81+ visible: textLabel.lineCount > textLabel.maximumCollapsedLineCount
82+ }
83+}
qml/Dash/Previews/PreviewWidget.qmlnew file+39
@@ -0,0 +1,39 @@
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+
19+/*! Interface for preview widgets. */
20+
21+Item {
22+ //! Specifies the preview widget being currently used or not
23+ property bool isCurrentPreview: true
24+
25+ //! The widget identifier
26+ property string widgetId
27+
28+ //! Variable used to contain widget's data
29+ property var widgetData
30+
31+ /*! \brief This signal should be emitted when a preview action was triggered.
32+ *
33+ * \param widgetId,actionId Respective identifiers from widgetData.
34+ * \param data Optional widget-specific data sent to the scope.
35+ */
36+ signal triggered(string widgetId, string actionId, var data)
37+
38+ objectName: widgetId
39+}
qml/Dash/Previews/PreviewWidgetFactory.qmlnew file+64
@@ -0,0 +1,64 @@
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+
18+import QtQuick 2.0
19+
20+//! \brief This component loads the widgets based on widgetData["type"].
21+
22+Loader {
23+ id: root
24+
25+ //! Identifier of the widget.
26+ property string widgetId: ""
27+
28+ //! Type of the widget to display.
29+ property string widgetType: ""
30+
31+ //! Widget data, forwarded to the widget as is.
32+ property var widgetData: null
33+
34+ //! Set to true if the parent preview is displayed.
35+ property bool isCurrentPreview: false
36+
37+ //! Triggered signal forwarded from the widgets.
38+ signal triggered(string widgetId, string actionId, var data)
39+
40+ source: widgetSource
41+
42+ //! \cond private
43+ property url widgetSource: {
44+ switch (widgetType) {
45+ case "audio": return "PreviewAudioPlayback.qml";
46+ case "text": return "PreviewTextSummary.qml";
47+ case "gallery": return "PreviewImageGallery.qml";
48+ case "actions": return "PreviewActions.qml";
49+ default: return "";
50+ }
51+ }
52+ //! \endcond
53+
54+ onLoaded: {
55+ item.widgetId = Qt.binding(function() { return root.widgetId } )
56+ item.widgetData = Qt.binding(function() { return root.widgetData } )
57+ item.isCurrentPreview = Qt.binding(function() { return root.isCurrentPreview } )
58+ }
59+
60+ Connections {
61+ target: root.item
62+ onTriggered: root.triggered(widgetId, actionId, data)
63+ }
64+}
qml/Dash/Music/graphics/music_progress_bg.png → qml/Dash/Previews/graphics/music_progress_bg.pngrenamed

Binary file not shown.

tests/autopilot/unity8/shell/emulators/main_window.py+1−1
@@ -92,7 +92,7 @@ class QQuickView(emulators.UnityEmulatorBase):
9292 return self.select_single(objectName="pinentryField")
9393
9494 def get_indicator(self, indicator_name):
95− return self.select_single(
95+ return self.wait_select_single(
9696 'DefaultIndicatorWidget',
9797 objectName=indicator_name+'-widget'
9898 )
tests/mocks/LightDM/demo/GreeterPrivate.cpp+2
@@ -36,6 +36,7 @@ void GreeterPrivate::handleAuthenticate()
3636 Q_Q(Greeter);
3737
3838 QSettings settings(QDir::homePath() + "/.unity8-greeter-demo", QSettings::NativeFormat);
39+ settings.beginGroup(authenticationUser);
3940 QVariant password = settings.value("password", "none");
4041
4142 if (password == "pin") {
@@ -53,6 +54,7 @@ void GreeterPrivate::handleRespond(const QString &response)
5354 Q_Q(Greeter);
5455
5556 QSettings settings(QDir::homePath() + "/.unity8-greeter-demo", QSettings::NativeFormat);
57+ settings.beginGroup(authenticationUser);
5658 QVariant password = settings.value("password", "none");
5759
5860 QString passwordValue;
tests/mocks/LightDM/demo/InfographicModelPrivate.cppdeleted−91
@@ -1,91 +0,0 @@
1−/*
2− * Copyright (C) 2013 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− * Author: Pete Woods <pete.woods@canonical.com>
17− */
18−
19−#include "../InfographicModelPrivate.h"
20−
21−namespace QLightDM
22−{
23−
24−void InfographicModelPrivate::generateFakeData()
25−{
26− std::default_random_engine generator;
27− std::normal_distribution<qreal> distribution(0.5, 0.2);
28− auto rand = std::bind(distribution, generator);
29−
30− QColor orange(QColor::fromRgbF(0.9, 0.3, 0.1, 1.0));
31− QColor yellow(QColor::fromRgbF(1.0, 0.6, 0.0, 1.0));
32− QColor red(QColor::fromRgbF(0.8, 0.0, 0.0, 1.0));
33− QColor darkPurple(QColor::fromRgbF(0.5, 0.2, 0.3, 1.0));
34− QColor lightPurple(QColor::fromRgbF(0.8, 0.1, 0.8, 1.0));
35− QColor pink(QColor::fromRgbF(0.75, 0.13, 0.75));
36−
37− InfographicColorTheme orangeTheme(yellow, orange, red);
38− InfographicColorTheme yellowTheme(orange, yellow, orange);
39− InfographicColorTheme redTheme(red, red, red);
40− InfographicColorTheme darkPurpleTheme(lightPurple, darkPurple, pink);
41− InfographicColorTheme lightPurpleTheme(lightPurple, lightPurple,
42− lightPurple);
43− InfographicColorTheme pinkTheme(lightPurple, pink, darkPurple);
44−
45− {
46− QVariantList firstMonth;
47− while (firstMonth.size() < 17)
48− firstMonth.push_back(QVariant(rand()));
49− while (firstMonth.size() < 31)
50− firstMonth.push_back(QVariant());
51− QVariantList secondMonth;
52− while (secondMonth.size() < 31)
53− secondMonth.push_back(QVariant(rand()));
54− QSharedPointer<InfographicData> data(
55− new InfographicData("<b>52km</b> travelled", yellowTheme, firstMonth,
56− orangeTheme, secondMonth, this));
57− m_fakeData.insert("phablet", data);
58− }
59−
60− {
61− QVariantList firstMonth;
62− while (firstMonth.size() < 17)
63− firstMonth.push_back(QVariant(rand()));
64− while (firstMonth.size() < 31)
65− firstMonth.push_back(QVariant());
66− QVariantList secondMonth;
67− while (secondMonth.size() < 31)
68− secondMonth.push_back(QVariant(rand()));
69− QSharedPointer<InfographicData> data(
70− new InfographicData("<b>33</b> messages today", pinkTheme,
71− firstMonth, orangeTheme, secondMonth, this));
72− m_fakeData.insert("phablet", data);
73− }
74−
75− {
76− QVariantList firstMonth;
77− while (firstMonth.size() < 17)
78− firstMonth.push_back(QVariant(rand()));
79− while (firstMonth.size() < 31)
80− firstMonth.push_back(QVariant());
81− QVariantList secondMonth;
82− while (secondMonth.size() < 31)
83− secondMonth.push_back(QVariant(rand()));
84− QSharedPointer<InfographicData> data(
85− new InfographicData("<b>69</b> minutes talk time", darkPurpleTheme,
86− firstMonth, redTheme, secondMonth, this));
87− m_fakeData.insert("phablet", data);
88− }
89−}
90−
91−}
tests/mocks/LightDM/demo/UsersModelPrivate.cpp+11−3
@@ -18,16 +18,24 @@
1818
1919#include "../UsersModelPrivate.h"
2020
21+#include <QDir>
22+#include <QSettings>
23+#include <QStringList>
24+
2125namespace QLightDM
2226{
2327
2428UsersModelPrivate::UsersModelPrivate(UsersModel* parent)
2529 : q_ptr(parent)
2630{
27− entries =
31+ QSettings settings(QDir::homePath() + "/.unity8-greeter-demo", QSettings::NativeFormat);
32+ QStringList users = settings.value("users", QStringList() << "phablet").toStringList();
33+
34+ Q_FOREACH(const QString &user, users)
2835 {
29− { "phablet", "Guest", 0, 0, false, false, 0, 0 },
30− };
36+ QString name = settings.value(user + "/name", user[0].toUpper() + user.mid(1)).toString();
37+ entries.append({user, name, 0, 0, false, false, 0, 0});
38+ }
3139}
3240
3341}
tests/mocks/LightDM/full/InfographicModelPrivate.cppdeleted−182
@@ -1,182 +0,0 @@
1−/*
2− * Copyright (C) 2013 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− * Author: Pete Woods <pete.woods@canonical.com>
17− */
18−
19−#include "../InfographicModelPrivate.h"
20−
21−namespace QLightDM
22−{
23−
24−void InfographicModelPrivate::generateFakeData()
25−{
26− std::default_random_engine generator;
27− std::normal_distribution<qreal> distribution(0.5, 0.2);
28− auto rand = std::bind(distribution, generator);
29−
30− QColor orange = QColor::fromRgbF(0.9, 0.3, 0.1, 1.0);
31− QColor yellow = QColor::fromRgbF(1.0, 0.6, 0.0, 1.0);
32− QColor red = QColor::fromRgbF(0.8, 0.0, 0.0, 1.0);
33− QColor darkPurple = QColor::fromRgbF(0.5, 0.2, 0.3, 1.0);
34− QColor lightPurple = QColor::fromRgbF(0.8, 0.1, 0.8, 1.0);
35− QColor pink(QColor::fromRgbF(0.75, 0.13, 0.75));
36−
37− InfographicColorTheme orangeTheme(orange, orange, orange);
38− InfographicColorTheme yellowTheme(yellow, yellow, yellow);
39− InfographicColorTheme redTheme(red, red, red);
40− InfographicColorTheme darkPurpleTheme(darkPurple, darkPurple, darkPurple);
41− InfographicColorTheme lightPurpleTheme(lightPurple, lightPurple,
42− lightPurple);
43− InfographicColorTheme pinkTheme(pink, pink, pink);
44−
45− {
46− QVariantList firstMonth;
47− while (firstMonth.size() < 17)
48− firstMonth.push_back(QVariant(rand()));
49− while (firstMonth.size() < 31)
50− firstMonth.push_back(QVariant());
51− QVariantList secondMonth;
52− while (secondMonth.size() < 31)
53− secondMonth.push_back(QVariant(rand()));
54− QSharedPointer<InfographicData> data(
55− new InfographicData("<b>5km</b> travelled", yellowTheme,
56− firstMonth, orangeTheme, secondMonth, this));
57− m_fakeData.insert("has-password", data);
58− }
59−
60− {
61− QVariantList firstMonth;
62− while (firstMonth.size() < 17)
63− firstMonth.push_back(QVariant(rand()));
64− while (firstMonth.size() < 31)
65− firstMonth.push_back(QVariant());
66− QVariantList secondMonth;
67− while (secondMonth.size() < 31)
68− secondMonth.push_back(QVariant(rand()));
69− QSharedPointer<InfographicData> data(
70− new InfographicData("<b>33</b> messages today", pinkTheme,
71− firstMonth, orangeTheme, secondMonth, this));
72− m_fakeData.insert("has-password", data);
73− }
74−
75− {
76− QVariantList firstMonth;
77− while (firstMonth.size() < 17)
78− firstMonth.push_back(QVariant(rand()));
79− while (firstMonth.size() < 31)
80− firstMonth.push_back(QVariant());
81− QVariantList secondMonth;
82− while (secondMonth.size() < 31)
83− secondMonth.push_back(QVariant(rand()));
84− QSharedPointer<InfographicData> data(
85− new InfographicData("<b>19</b> minutes talk time", orangeTheme,
86− firstMonth, redTheme, secondMonth, this));
87− m_fakeData.insert("has-password", data);
88− }
89−
90− {
91− QVariantList firstMonth;
92− while (firstMonth.size() < 17)
93− firstMonth.push_back(QVariant(rand()));
94− while (firstMonth.size() < 31)
95− firstMonth.push_back(QVariant());
96− QVariantList secondMonth;
97− while (secondMonth.size() < 31)
98− secondMonth.push_back(QVariant(rand()));
99− QSharedPointer<InfographicData> data(
100− new InfographicData("<b>5km</b> travelled", redTheme,
101− firstMonth, darkPurpleTheme, secondMonth, this));
102− m_fakeData.insert("no-password", data);
103− }
104−
105− {
106− QVariantList firstMonth;
107− while (firstMonth.size() < 17)
108− firstMonth.push_back(QVariant(rand()));
109− while (firstMonth.size() < 31)
110− firstMonth.push_back(QVariant());
111− QVariantList secondMonth;
112− while (secondMonth.size() < 31)
113− secondMonth.push_back(QVariant(rand()));
114− QSharedPointer<InfographicData> data(
115− new InfographicData("<b>33</b> messages today",
116− lightPurpleTheme, firstMonth, darkPurpleTheme,
117− secondMonth, this));
118− m_fakeData.insert("no-password", data);
119− }
120−
121− {
122− QVariantList firstMonth;
123− while (firstMonth.size() < 17)
124− firstMonth.push_back(QVariant(rand()));
125− while (firstMonth.size() < 31)
126− firstMonth.push_back(QVariant());
127− QVariantList secondMonth;
128− while (secondMonth.size() < 31)
129− secondMonth.push_back(QVariant());
130− QSharedPointer<InfographicData> data(
131− new InfographicData("<b>19</b> minutes talk time", orangeTheme,
132− firstMonth, redTheme, secondMonth, this));
133− m_fakeData.insert("no-password", data);
134− }
135−
136− {
137− QVariantList firstMonth;
138− while (firstMonth.size() < 29)
139− firstMonth.push_back(QVariant(rand()));
140− while (firstMonth.size() < 31)
141− firstMonth.push_back(QVariant());
142− QVariantList secondMonth;
143− while (secondMonth.size() < 31)
144− secondMonth.push_back(QVariant(rand()));
145− QSharedPointer<InfographicData> data(
146− new InfographicData("<b>5km</b> travelled", redTheme,
147− firstMonth, darkPurpleTheme, secondMonth, this));
148− m_fakeData.insert("empty-name", data);
149− }
150−
151− {
152− QVariantList firstMonth;
153− while (firstMonth.size() < 29)
154− firstMonth.push_back(QVariant(rand()));
155− while (firstMonth.size() < 31)
156− firstMonth.push_back(QVariant());
157− QVariantList secondMonth;
158− while (secondMonth.size() < 31)
159− secondMonth.push_back(QVariant(rand()));
160− QSharedPointer<InfographicData> data(
161− new InfographicData("<b>33</b> messages today", yellowTheme,
162− firstMonth, orangeTheme, secondMonth, this));
163− m_fakeData.insert("empty-name", data);
164− }
165−
166− {
167− QVariantList firstMonth;
168− while (firstMonth.size() < 29)
169− firstMonth.push_back(QVariant(rand()));
170− while (firstMonth.size() < 31)
171− firstMonth.push_back(QVariant());
172− QVariantList secondMonth;
173− while (secondMonth.size() < 31)
174− secondMonth.push_back(QVariant());
175− QSharedPointer<InfographicData> data(
176− new InfographicData("<b>19</b> minutes talk time", pinkTheme,
177− firstMonth, orangeTheme, secondMonth, this));
178− m_fakeData.insert("empty-name", data);
179− }
180−}
181−
182−}
tests/mocks/LightDM/single-passphrase/InfographicModelPrivate.cppdeleted−61
@@ -1,61 +0,0 @@
1−/*
2− * Copyright (C) 2013 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− * Author: Pete Woods <pete.woods@canonical.com>
17− */
18−
19−#include "../InfographicModelPrivate.h"
20−
21−namespace QLightDM
22−{
23−
24−void InfographicModelPrivate::generateFakeData()
25−{
26− std::default_random_engine generator;
27− std::normal_distribution<qreal> distribution(0.5, 0.2);
28− auto rand = std::bind(distribution, generator);
29−
30− QColor orange = QColor::fromRgbF(0.9, 0.3, 0.1, 1.0);
31− QColor yellow = QColor::fromRgbF(1.0, 0.6, 0.0, 1.0);
32− QColor red = QColor::fromRgbF(0.8, 0.0, 0.0, 1.0);
33− QColor darkPurple = QColor::fromRgbF(0.5, 0.2, 0.3, 1.0);
34− QColor lightPurple = QColor::fromRgbF(0.8, 0.1, 0.8, 1.0);
35− QColor pink(QColor::fromRgbF(0.75, 0.13, 0.75));
36−
37− InfographicColorTheme orangeTheme(orange, orange, orange);
38− InfographicColorTheme yellowTheme(yellow, yellow, yellow);
39− InfographicColorTheme redTheme(red, red, red);
40− InfographicColorTheme darkPurpleTheme(darkPurple, darkPurple, darkPurple);
41− InfographicColorTheme lightPurpleTheme(lightPurple, lightPurple,
42− lightPurple);
43− InfographicColorTheme pinkTheme(pink, pink, pink);
44−
45− {
46− QVariantList firstMonth;
47− while (firstMonth.size() < 17)
48− firstMonth.push_back(QVariant(rand()));
49− while (firstMonth.size() < 31)
50− firstMonth.push_back(QVariant());
51− QVariantList secondMonth;
52− while (secondMonth.size() < 31)
53− secondMonth.push_back(QVariant(rand()));
54− QSharedPointer<InfographicData> data(
55− new InfographicData("<b>5km</b> travelled", yellowTheme,
56− firstMonth, orangeTheme, secondMonth, this));
57− m_fakeData.insert("has-pin", data);
58− }
59−}
60−
61−}
tests/mocks/LightDM/single-pin/InfographicModelPrivate.cppdeleted−61
@@ -1,61 +0,0 @@
1−/*
2− * Copyright (C) 2013 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− * Author: Pete Woods <pete.woods@canonical.com>
17− */
18−
19−#include "../InfographicModelPrivate.h"
20−
21−namespace QLightDM
22−{
23−
24−void InfographicModelPrivate::generateFakeData()
25−{
26− std::default_random_engine generator;
27− std::normal_distribution<qreal> distribution(0.5, 0.2);
28− auto rand = std::bind(distribution, generator);
29−
30− QColor orange = QColor::fromRgbF(0.9, 0.3, 0.1, 1.0);
31− QColor yellow = QColor::fromRgbF(1.0, 0.6, 0.0, 1.0);
32− QColor red = QColor::fromRgbF(0.8, 0.0, 0.0, 1.0);
33− QColor darkPurple = QColor::fromRgbF(0.5, 0.2, 0.3, 1.0);
34− QColor lightPurple = QColor::fromRgbF(0.8, 0.1, 0.8, 1.0);
35− QColor pink(QColor::fromRgbF(0.75, 0.13, 0.75));
36−
37− InfographicColorTheme orangeTheme(orange, orange, orange);
38− InfographicColorTheme yellowTheme(yellow, yellow, yellow);
39− InfographicColorTheme redTheme(red, red, red);
40− InfographicColorTheme darkPurpleTheme(darkPurple, darkPurple, darkPurple);
41− InfographicColorTheme lightPurpleTheme(lightPurple, lightPurple,
42− lightPurple);
43− InfographicColorTheme pinkTheme(pink, pink, pink);
44−
45− {
46− QVariantList firstMonth;
47− while (firstMonth.size() < 17)
48− firstMonth.push_back(QVariant(rand()));
49− while (firstMonth.size() < 31)
50− firstMonth.push_back(QVariant());
51− QVariantList secondMonth;
52− while (secondMonth.size() < 31)
53− secondMonth.push_back(QVariant(rand()));
54− QSharedPointer<InfographicData> data(
55− new InfographicData("<b>5km</b> travelled", yellowTheme,
56− firstMonth, orangeTheme, secondMonth, this));
57− m_fakeData.insert("has-pin", data);
58− }
59−}
60−
61−}
tests/mocks/Unity/CMakeLists.txt+1
@@ -25,6 +25,7 @@ set(UnityQML_SOURCES
2525 fake_scope.cpp
2626 fake_scopes.cpp
2727 fake_categories.cpp
28+ scopes-ng/fake_preview_model.cpp
2829 fake_unity_plugin.cpp
2930)
3031
tests/mocks/Unity/fake_unity_plugin.cpp+5
@@ -25,6 +25,9 @@
2525#include "fake_preview.h"
2626#include "categoryresults.h"
2727
28+// scopes-ng
29+#include "scopes-ng/fake_preview_model.h"
30+
2831// External
2932#include <glib-object.h>
3033
@@ -44,4 +47,6 @@ void FakeUnityPlugin::registerTypes(const char *uri)
4447 qmlRegisterType<Categories>(uri, 0, 1, "Categories");
4548 qmlRegisterUncreatableType<CategoryResults>(uri, 0, 1, "CategoryResults", "Can't create");
4649 qmlRegisterType<DeeListModel>(uri, 0, 1, "DeeListModel");
50+
51+ qmlRegisterType<scopes_ng::PreviewModel>(uri, 0, 1, "FakePreviewModel");
4752}
tests/mocks/Unity/scopes-ng/fake_preview_model.cppnew file+96
@@ -0,0 +1,96 @@
1+/*
2+ * Copyright (C) 2014 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Michał Sawicz <michal.sawicz@canonical.com>
6+ * Michal Hruby <michal.hruby@canonical.com>
7+ *
8+ * This program is free software; you can redistribute it and/or modify
9+ * it under the terms of the GNU General Public License as published by
10+ * the Free Software Foundation; version 3.
11+ *
12+ * This program is distributed in the hope that it will be useful,
13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+ * GNU General Public License for more details.
16+ *
17+ * You should have received a copy of the GNU General Public License
18+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
19+ */
20+
21+// self
22+#include "fake_preview_model.h"
23+
24+// Qt
25+#include <QVariantMap>
26+
27+namespace scopes_ng
28+{
29+
30+struct PreviewData
31+{
32+ QString id;
33+ QString type;
34+ QVariantMap data;
35+
36+ PreviewData(QString const& id_, QString const& type_, QVariantMap const& data_): id(id_), type(type_), data(data_)
37+ {
38+ }
39+};
40+
41+PreviewModel::PreviewModel(QObject* parent) : QAbstractListModel(parent)
42+{
43+ m_roles[Roles::RoleWidgetId] = "widgetId";
44+ m_roles[Roles::RoleType] = "type";
45+ m_roles[Roles::RoleProperties] = "properties";
46+
47+ populateWidgets();
48+}
49+
50+void PreviewModel::populateWidgets()
51+{
52+ beginResetModel();
53+ m_previewWidgets.clear();
54+ for (int i = 0; i <= 20; i++) {
55+ // FIXME: the API will expose nicer getters soon, use those!
56+ QVariantMap attributes;
57+ attributes["text"] = QVariant::fromValue(QString("Widget %1").arg(i));
58+ attributes["title"] = QVariant::fromValue(QString("Title %1").arg(i));
59+ PreviewData* preview_data = new PreviewData(QString("widget-%1").arg(i), QString("text"), attributes);
60+ m_previewWidgets.append(QSharedPointer<PreviewData>(preview_data));
61+ }
62+ endResetModel();
63+
64+}
65+
66+void PreviewModel::triggered(QString widgetId, QString actionId, QVariantMap data)
67+{
68+ Q_EMIT actionTriggered(widgetId, actionId, data);
69+}
70+
71+QHash<int, QByteArray> PreviewModel::roleNames() const
72+{
73+ return m_roles;
74+}
75+
76+int PreviewModel::rowCount(const QModelIndex&) const
77+{
78+ return m_previewWidgets.size();
79+}
80+
81+QVariant PreviewModel::data(const QModelIndex& index, int role) const
82+{
83+ auto widget_data = m_previewWidgets.at(index.row());
84+ switch (role) {
85+ case RoleWidgetId:
86+ return widget_data->id;
87+ case RoleType:
88+ return widget_data->type;
89+ case RoleProperties:
90+ return widget_data->data;
91+ default:
92+ return QVariant();
93+ }
94+}
95+
96+} // namespace scopes_ng
tests/mocks/Unity/scopes-ng/fake_preview_model.hnew file+68
@@ -0,0 +1,68 @@
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+
18+#ifndef NG_FAKE_PREVIEW_H
19+#define NG_FAKE_PREVIEW_H
20+
21+#include <QAbstractListModel>
22+#include <QSharedPointer>
23+#include <QVariantMap>
24+
25+namespace scopes_ng
26+{
27+
28+class PreviewData;
29+
30+class Q_DECL_EXPORT PreviewModel : public QAbstractListModel
31+{
32+ Q_OBJECT
33+
34+ Q_ENUMS(Roles)
35+
36+public:
37+ explicit PreviewModel(QObject* parent = 0);
38+
39+ enum Roles {
40+ RoleWidgetId,
41+ RoleType,
42+ RoleProperties
43+ };
44+
45+ QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
46+ QHash<int, QByteArray> roleNames() const override;
47+ int rowCount(const QModelIndex& parent = QModelIndex()) const override;
48+
49+Q_SIGNALS:
50+ void actionTriggered(QString widgetId, QString actionId, QVariantMap data);
51+
52+public Q_SLOTS:
53+ void triggered(QString widgetId, QString actionId, QVariantMap data);
54+
55+private:
56+ QHash<int, QByteArray> m_roles;
57+ QList<QSharedPointer<PreviewData>> m_previewWidgets;
58+
59+ void populateWidgets();
60+
61+};
62+
63+} // namespace scopes_ng
64+
65+
66+Q_DECLARE_METATYPE(scopes_ng::PreviewModel*)
67+
68+#endif // NG_FAKE_PREVIW_H
tests/qmltests/CMakeLists.txt+7
@@ -32,6 +32,7 @@ add_qml_test(Components LazyImage)
3232add_qml_test(Components ResponsiveFlowView)
3333add_qml_test(Components ResponsiveGridView)
3434add_qml_test(Components Revealer)
35+add_qml_test(Components SeeMore)
3536add_qml_test(Components Showable)
3637add_qml_test(Components Stage IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS}
3738 ${CMAKE_BINARY_DIR}/tests/mocks
@@ -54,6 +55,12 @@ add_qml_test(Dash/Apps RunningApplicationsGrid IMPORT_PATHS ${qmltest_DEFAULT_IM
5455add_qml_test(Dash/Apps AppPreview IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/tests/mocks)
5556add_qml_test(Dash/Movie MoviePreview IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/tests/mocks)
5657add_qml_test(Dash/Music MusicPreview IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/tests/mocks)
58+add_qml_test(Dash/Previews Preview IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/tests/mocks)
59+add_qml_test(Dash/Previews PreviewWidgetFactory IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/tests/mocks)
60+add_qml_test(Dash/Previews PreviewActions IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/tests/mocks)
61+add_qml_test(Dash/Previews PreviewAudioPlayback IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/tests/mocks)
62+add_qml_test(Dash/Previews PreviewImageGallery IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/tests/mocks)
63+add_qml_test(Dash/Previews PreviewTextSummary IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/tests/mocks)
5764add_qml_test(Greeter Lockscreen IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS}
5865 PROPERTIES ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/libusermetrics:${CMAKE_BINARY_DIR}/tests/mocks/LightDM/full")
5966add_qml_test(Greeter Tablet IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS}
tests/qmltests/Components/tst_SeeMore.qmlnew file+52
@@ -0,0 +1,52 @@
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/Previews/MockPreviewWidget.qmlnew file+27
@@ -0,0 +1,27 @@
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+
18+import QtQuick 2.0
19+import "../../../../qml/Dash/Previews"
20+
21+PreviewWidget {
22+ objectName: "mockPreviewWidget"
23+
24+ function trigger() {
25+ triggered("mockWidget", "mockAction", {"mock": "data"})
26+ }
27+}
tests/qmltests/Dash/Previews/tst_Preview.qmlnew file+112
@@ -0,0 +1,112 @@
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 "../../../../qml/Dash/Previews"
20+import Unity.Test 0.1 as UT
21+import Unity 0.1 as Unity
22+
23+Rectangle {
24+ id: root
25+ width: units.gu(60)
26+ height: units.gu(80)
27+ color: Theme.palette.selected.background
28+
29+ Item {
30+ id: shell
31+
32+ anchors.fill: parent
33+ property var applicationManager: null
34+ }
35+
36+ Unity.FakePreviewModel {
37+ id: mockPreviewModel
38+ }
39+
40+ Preview {
41+ id: preview
42+ anchors.fill: parent
43+
44+ previewModel: mockPreviewModel
45+ }
46+
47+ SignalSpy {
48+ id: triggeredSpy
49+ target: mockPreviewModel
50+ signalName: "actionTriggered"
51+ }
52+
53+ UT.UnityTestCase {
54+ name: "Preview"
55+ when: windowShown
56+
57+ function test_triggered() {
58+ waitForRendering(preview);
59+ var widget = findChild(preview, "widget-3");
60+
61+ compare(typeof widget, "object", "Could not find the widget object.");
62+
63+ widget.triggered(widget.widgetId, "mockAction", {"mock": "data"});
64+
65+ triggeredSpy.wait();
66+
67+ var args = triggeredSpy.signalArguments[0];
68+
69+ compare(args[0], "widget-3", "Widget id not passed correctly.");
70+ compare(args[1], "mockAction", "Action id not passed correctly.");
71+ compare(args[2]["mock"], "data", "Data not passed correctly.");
72+ }
73+
74+ function test_showProcessing() {
75+ waitForRendering(preview);
76+ var widget = findChild(preview, "widget-3");
77+ widget.triggered(widget.widgetId, "mockAction", {"mock": "data"});
78+
79+ var processing = findChild(preview, "processingMouseArea");
80+
81+ tryCompare(processing, "enabled", true);
82+
83+ preview.previewModelChanged();
84+
85+ tryCompare(processing, "enabled", false);
86+ }
87+
88+ function test_containOnFocus() {
89+ waitForRendering(preview);
90+ var widget = findChild(preview, "widget-13");
91+
92+ widget.forceActiveFocus();
93+
94+ var bottomLeft = preview.mapFromItem(widget, 0, widget.height);
95+
96+ tryCompareFunction(function () { return bottomLeft.y <= preview.height }, true);
97+ }
98+
99+ function test_containOnGrow() {
100+ waitForRendering(preview);
101+ var widget = findChild(preview, "widget-13");
102+
103+ widget.forceActiveFocus();
104+ widget.height += 200;
105+
106+ tryCompareFunction(function () {
107+ var bottomLeft = preview.mapFromItem(widget, 0, widget.height);
108+ return bottomLeft.y <= preview.height
109+ }, true);
110+ }
111+ }
112+}
tests/qmltests/Dash/Previews/tst_PreviewActions.qmlnew file+148
@@ -0,0 +1,148 @@
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 "../../../../qml/Dash/Previews"
20+import Unity.Test 0.1 as UT
21+import Ubuntu.Components 0.1
22+
23+
24+Rectangle {
25+ id: root
26+ width: units.gu(60)
27+ height: units.gu(80)
28+
29+ property var actionDataOneAction: {
30+ "actions": [{"label": "Some Label", "icon": "../graphics/play_button.png", "id": "someid"}]
31+ }
32+
33+ property var actionDataTwoActions: {
34+ "actions": [{"label": "Some Label A", "icon": "../graphics/icon_clear.png", "id": "someid1"},
35+ {"label": "Some Label B", "icon": "../graphics/play_button.png", "id": "someid2"}
36+ ]
37+ }
38+
39+ property var actionDataFiveActions: {
40+ "actions": [{"label": "Some Label C", "icon": "../graphics/play_button.png", "id": "someid3"},
41+ {"label": "Some Label D", "icon": "../graphics/icon_clear.png", "id": "someid4"},
42+ {"label": "Some Label E", "icon": "../graphics/play_button.png", "id": "someid5"},
43+ {"label": "Some Label F", "icon": "../graphics/icon_clear.png", "id": "someid6"},
44+ {"label": "Some Label G", "icon": "../graphics/play_button.png", "id": "someid7"}
45+ ]
46+ }
47+
48+ SignalSpy {
49+ id: spy
50+ signalName: "triggered"
51+ }
52+
53+ Column {
54+ spacing: units.gu(1)
55+
56+ PreviewActions {
57+ id: oneAction
58+ widgetId: "button"
59+ widgetData: actionDataOneAction
60+ onTriggered: console.log("triggered", widgetId, actionId);
61+ width: units.gu(50)
62+
63+ Rectangle {
64+ anchors.fill: parent
65+ color: "red"
66+ opacity: 0.1
67+ }
68+ }
69+
70+ PreviewActions {
71+ id: buttonAndCombo
72+ widgetId: "buttonAndCombo"
73+ widgetData: actionDataFiveActions
74+ onTriggered: console.log("triggered", widgetId, actionId);
75+ width: units.gu(40)
76+
77+ Rectangle {
78+ anchors.fill: parent
79+ color: "red"
80+ opacity: 0.1
81+ }
82+ }
83+
84+ PreviewActions {
85+ id: twoActions
86+ widgetId: "2buttons"
87+ widgetData: actionDataTwoActions
88+ onTriggered: console.log("triggered", widgetId, actionId);
89+ width: units.gu(60)
90+ }
91+ }
92+
93+ UT.UnityTestCase {
94+ name: "PreviewActionTest"
95+ when: windowShown
96+
97+ function cleanup()
98+ {
99+ spy.clear();
100+ }
101+
102+ function checkButtonPressSignal(target, id)
103+ {
104+ var button = findChild(root, "button" + id);
105+ verify(button != null);
106+ spy.target = target;
107+ mouseClick(button, button.width / 2, button.height / 2);
108+ compare(spy.count, 1);
109+ compare(spy.signalArguments[0][0], target.widgetId);
110+ compare(spy.signalArguments[0][1], id);
111+ }
112+
113+ function test_checkButtons_data() {
114+ return [
115+ {tag: "oneActionButton", target: oneAction, id: "someid" },
116+ {tag: "twobuttonsButton0", target: twoActions, id: "someid1" },
117+ {tag: "twobuttonsButton1", target: twoActions, id: "someid2" },
118+ {tag: "buttonAndComboButton0", target: buttonAndCombo, id: "someid3" }
119+ ]
120+ }
121+
122+ function test_checkButtons(data) {
123+ checkButtonPressSignal(data.target, data.id, data.buttonNumber)
124+ }
125+
126+ function test_comboButton_data() {
127+ return [
128+ {tag: "button1", id: "someid4" },
129+ {tag: "button2", id: "someid5" },
130+ {tag: "button3", id: "someid6" },
131+ {tag: "button4", id: "someid7" }
132+ ]
133+ }
134+
135+ function test_comboButton(data) {
136+ var button = findChild(root, "moreLessButton");
137+ var buttonColumn = findChild(root, "buttonColumn");
138+ verify(button != null);
139+ var twoActionsY = twoActions.y
140+ mouseClick(button, button.width / 2, button.height / 2);
141+ tryCompareFunction(function () { return twoActions.y <= twoActionsY; }, false);
142+ tryCompare(buttonColumn, "height", buttonColumn.implicitHeight);
143+ checkButtonPressSignal(buttonAndCombo, data.id, data.buttonNumber);
144+ mouseClick(button, button.width / 2, button.height / 2);
145+ tryCompare(twoActions, "y", twoActionsY);
146+ }
147+ }
148+}
tests/qmltests/Dash/Previews/tst_PreviewAudioPlayback.qmlnew file+179
@@ -0,0 +1,179 @@
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+import QtMultimedia 5.0
23+
24+Rectangle {
25+ id: root
26+ width: units.gu(60)
27+ height: units.gu(80)
28+ color: Theme.palette.selected.background
29+
30+ property var tracksModel0: {
31+ "tracks": [ ]
32+ }
33+
34+ property var tracksModel1: {
35+ "tracks": [ { title: "Some track name", length: "30", source: "/not/existing/path/testsound1" } ]
36+ }
37+
38+ property var tracksModel2: {
39+ "tracks": [ { title: "Some track name", length: "30", source: "/not/existing/path/testsound1" },
40+ { title: "Some other track name", subtitle: "Subtitle", length: "83", source: "/not/existing/path/testsound2" },
41+ { title: "And another one", length: "7425", source: "/not/existing/path/testsound3" } ]
42+ }
43+
44+ PreviewAudioPlayback {
45+ id: previewAudioPlayback
46+ anchors.fill: parent
47+ widgetData: tracksModel2
48+ }
49+
50+ UT.UnityTestCase {
51+ name: "PreviewAudioPlaybackTest"
52+ when: windowShown
53+
54+ function init() {
55+ waitForRendering(previewAudioPlayback);
56+ }
57+
58+ function test_time_formatter_data() {
59+ return [
60+ { tag: "NaN", value: "not a number", result: "" },
61+ { tag: "0", value: 0, result: "" },
62+ { tag: "-1", value: -1, result: "" },
63+ { tag: "30", value: 30, result: "0:30" },
64+ { tag: "60", value: 60, result: "1:00" },
65+ { tag: "3600", value: 3600, result: "1:00:00" }
66+ ];
67+ }
68+
69+ function test_time_formatter(data) {
70+ var audio = findInvisibleChild(previewAudioPlayback, "audio");
71+ compare(audio.lengthToString(data.value), data.result)
72+ }
73+
74+ function test_tracks_data() {
75+ return [
76+ {tag: "0 tracks", tracksModel: tracksModel0},
77+ {tag: "1 track", tracksModel: tracksModel1},
78+ {tag: "3 tracks", tracksModel: tracksModel2}
79+ ];
80+ }
81+
82+ function test_tracks(data) {
83+ previewAudioPlayback.widgetData = data.tracksModel;
84+ waitForRendering(previewAudioPlayback);
85+
86+ var trackRepeater = findChild(previewAudioPlayback, "trackRepeater");
87+ compare(trackRepeater.count, data.tracksModel["tracks"].length)
88+
89+ for (var i = 0; i < data.tracksModel["tracks"].length; ++i) {
90+ var trackItem = findChild(previewAudioPlayback, "trackItem" + i);
91+ var titleLabel = findChild(trackItem, "trackTitleLabel");
92+ compare(titleLabel.text, data.tracksModel["tracks"][i]["title"])
93+ var subtitleLabel = findChild(trackItem, "trackSubtitleLabel");
94+ if (data.tracksModel["tracks"][i]["subtitle"] !== undefined) {
95+ compare(subtitleLabel.text, data.tracksModel["tracks"][i]["subtitle"])
96+ } else {
97+ compare(subtitleLabel.visible, false)
98+ }
99+ // not checking time label because it's formatted, the model only contains seconds
100+ }
101+ }
102+
103+ function checkPlayerSource(index) {
104+ var modelFilename = previewAudioPlayback.widgetData["tracks"][index]["source"].replace(/^.*[\\\/]/, '');
105+ var playerFilename = findInvisibleChild(previewAudioPlayback, "audio").source.toString().replace(/^.*[\\\/]/, '');
106+
107+ compare(modelFilename, playerFilename, "Player source is not set correctly.");
108+ }
109+
110+ function test_playback() {
111+ previewAudioPlayback.widgetData = tracksModel2;
112+ waitForRendering(previewAudioPlayback);
113+
114+ var track0Item = findChild(previewAudioPlayback, "trackItem0");
115+ var track1Item = findChild(previewAudioPlayback, "trackItem1");
116+ var track2Item = findChild(previewAudioPlayback, "trackItem2");
117+
118+ var track0ProgressBar = findChild(track0Item, "progressBarFill");
119+ var track1ProgressBar = findChild(track1Item, "progressBarFill");
120+ var track2ProgressBar = findChild(track2Item, "progressBarFill");
121+
122+ var track0PlayButton = findChild(track0Item, "playButton");
123+ var track1PlayButton = findChild(track1Item, "playButton");
124+ var track2PlayButton = findChild(track2Item, "playButton");
125+
126+ var audio = findInvisibleChild(previewAudioPlayback, "audio");
127+
128+ // All progress bars must be hidden in the beginning
129+ compare(track0ProgressBar.visible, false);
130+ compare(track1ProgressBar.visible, false);
131+ compare(track2ProgressBar.visible, false);
132+
133+ // Playing track 0 should make progress bar 0 visible
134+ mouseClick(track0PlayButton, track0PlayButton.width / 2, track0PlayButton.height / 2);
135+
136+ tryCompare(audio, "playbackState", Audio.PlayingState);
137+ checkPlayerSource(0);
138+
139+ tryCompare(track0ProgressBar, "visible", true);
140+ tryCompare(track1ProgressBar, "visible", false);
141+ tryCompare(track2ProgressBar, "visible", false);
142+
143+ // Clicking the button again should pause it. The progress bar should stay visible
144+ mouseClick(track0PlayButton, track0PlayButton.width / 2, track0PlayButton.height / 2);
145+ tryCompare(audio, "playbackState", Audio.PausedState);
146+ checkPlayerSource(0);
147+ tryCompare(track0ProgressBar, "visible", true);
148+
149+ // Continue playback
150+ mouseClick(track0PlayButton, track0PlayButton.width / 2, track0PlayButton.height / 2);
151+ tryCompare(audio, "playbackState", Audio.PlayingState);
152+ checkPlayerSource(0);
153+
154+ // Playing track 1 should make progress bar 1 visible and hide progress bar 0 again
155+ mouseClick(track1PlayButton, track1PlayButton.width / 2, track1PlayButton.height / 2);
156+
157+ tryCompare(audio, "playbackState", Audio.PlayingState);
158+ checkPlayerSource(1);
159+
160+ tryCompare(track0ProgressBar, "visible", false);
161+ tryCompare(track1ProgressBar, "visible", true);
162+ tryCompare(track2ProgressBar, "visible", false);
163+
164+ // Playing track 2 should make progress bar 1 visible and hide progress bar 0 again
165+ mouseClick(track2PlayButton, track2PlayButton.width / 2, track2PlayButton.height / 2);
166+
167+ tryCompare(audio, "playbackState", Audio.PlayingState);
168+ checkPlayerSource(2);
169+
170+ tryCompare(track0ProgressBar, "visible", false);
171+ tryCompare(track1ProgressBar, "visible", false);
172+ tryCompare(track2ProgressBar, "visible", true);
173+
174+ // Changing preview should make all players shut up!
175+ previewAudioPlayback.isCurrentPreview = false
176+ tryCompare(audio, "playbackState", Audio.StoppedState);
177+ }
178+ }
179+}
tests/qmltests/Dash/Previews/tst_PreviewImageGallery.qmlnew file+56
@@ -0,0 +1,56 @@
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 "../../../../qml/Dash/Previews"
20+import Unity.Test 0.1 as UT
21+
22+Rectangle {
23+ id: root
24+ width: units.gu(60)
25+ height: units.gu(80)
26+ color: "grey"
27+
28+ property var sourcesModel0: {
29+ "sources": []
30+ }
31+
32+ property var sourcesModel1: {
33+ "sources": [
34+ "../../graphics/phone_background.jpg",
35+ "../../graphics/tablet_background.jpg",
36+ "../../graphics/clock@18.png"
37+ ]
38+ }
39+
40+ PreviewImageGallery {
41+ id: imageGallery
42+ width: parent.width
43+ widgetData: sourcesModel1
44+ }
45+
46+ UT.UnityTestCase {
47+ name: "ImageGalleryTest"
48+ when: windowShown
49+
50+ function test_changeEmptyModel() {
51+ imageGallery.widgetData = sourcesModel0;
52+ var placeholderScreenshot = findChild(imageGallery, "placeholderScreenshot");
53+ compare(placeholderScreenshot.visible, true);
54+ }
55+ }
56+}
tests/qmltests/Dash/Previews/tst_PreviewTextSummary.qmlnew file+101
@@ -0,0 +1,101 @@
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 var widgetDataComplete: {
30+ "title": "Title here",
31+ "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.\n\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."
32+ }
33+
34+ property var widgetDataNoTitle: {
35+ "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.\n\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."
36+ }
37+
38+ property var widgetDataShortText: {
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."
41+ }
42+
43+ PreviewTextSummary {
44+ id: previewTextSummary
45+ anchors.fill: parent
46+ widgetData: widgetDataComplete
47+ }
48+
49+ UT.UnityTestCase {
50+ name: "PreviewTextSummaryTest"
51+ when: windowShown
52+
53+ property var textLabel: findChild(previewTextSummary, "textLabel")
54+
55+ function init() {
56+ verify(typeof textLabel === "object", "TextLabel object could not be found.")
57+ }
58+
59+ function cleanup() {
60+ previewTextSummary.widgetData = widgetDataComplete
61+ }
62+
63+ function test_optional_title() {
64+ var titleLabel = findChild(previewTextSummary, "titleLabel")
65+
66+ // verify titleLabel is visible and textLabel is anchored below it
67+ compare(titleLabel.visible, true)
68+ compare(textLabel.y, titleLabel.height)
69+
70+ // verify titleLabel disappears and textLabel moves up
71+ previewTextSummary.widgetData = widgetDataNoTitle
72+ compare(titleLabel.visible, false)
73+ compare(textLabel.y, 0)
74+ }
75+
76+ function test_see_more() {
77+ var seeMore = findChild(previewTextSummary, "seeMore")
78+
79+ // when it's more than textLabel.maximumCollapsedLineCount lines of text, show SeeMore component
80+ verify(textLabel.lineCount > textLabel.maximumCollapsedLineCount)
81+ compare(seeMore.visible, true)
82+ verify(seeMore.more === false)
83+ verify(textLabel.height < textLabel.contentHeight)
84+
85+ // test interactions with SeeMore
86+ var seeMoreLabel = findChild(seeMore, "seeMoreLabel")
87+ var seeLessLabel = findChild(seeMore, "seeLessLabel")
88+ var initialTextLabelHeight = textLabel.height
89+ mouseClick(seeMoreLabel, seeMoreLabel.width / 2, seeMoreLabel.height / 2)
90+ tryCompare(textLabel, "height", textLabel.contentHeight)
91+ mouseClick(seeLessLabel, seeLessLabel.width / 2, seeLessLabel.height / 2)
92+ tryCompare(textLabel, "height", initialTextLabelHeight)
93+
94+ // text SeeMore automatic hiding
95+ previewTextSummary.widgetData = widgetDataShortText
96+ verify(textLabel.lineCount <= textLabel.maximumCollapsedLineCount)
97+ compare(seeMore.visible, false)
98+ tryCompare(textLabel, "height", textLabel.contentHeight)
99+ }
100+ }
101+}
tests/qmltests/Dash/Previews/tst_PreviewWidgetFactory.qmlnew file+92
@@ -0,0 +1,92 @@
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 "../../../../qml/Dash/Previews"
20+import Unity.Test 0.1 as UT
21+
22+Rectangle {
23+ id: root
24+ width: units.gu(60)
25+ height: units.gu(80)
26+ color: Theme.palette.selected.background
27+
28+ PreviewWidgetFactory {
29+ id: factory
30+ anchors {
31+ left: parent.left
32+ right: parent.right
33+ }
34+ }
35+
36+ SignalSpy {
37+ id: triggeredSpy
38+ target: factory
39+ signalName: "triggered"
40+ }
41+
42+ UT.UnityTestCase {
43+ name: "PreviewWidgetFactory"
44+ when: windowShown
45+
46+ property Item mockWidget: findChild(factory, "mockPreviewWidget")
47+
48+ function cleanup() {
49+ factory.source = Qt.binding(function() { return factory.widgetSource });
50+ }
51+
52+ function test_previewData() {
53+ factory.source = Qt.resolvedUrl("MockPreviewWidget.qml");
54+
55+ verify(typeof mockWidget === "object", "Could not find the mock preview widget.");
56+
57+ tryCompare(mockWidget, "widgetData", factory.widgetData);
58+ }
59+
60+ function test_triggered() {
61+ factory.source = Qt.resolvedUrl("MockPreviewWidget.qml");
62+
63+ verify(typeof mockWidget === "object", "Could not find the mock preview widget.");
64+
65+ mockWidget.trigger();
66+
67+ triggeredSpy.wait();
68+
69+ var args = triggeredSpy.signalArguments[0];
70+
71+ compare(args[0], "mockWidget", "Widget id not passed correctly.");
72+ compare(args[1], "mockAction", "Action id not passed correctly.");
73+ compare(args[2]["mock"], "data", "Data not passed correctly.");
74+ }
75+
76+ function test_mapping_data() {
77+ return [
78+ { tag: "Audio", type: "audio", source: "PreviewAudioPlayback.qml" },
79+ { tag: "Text", type: "text", source: "PreviewTextSummary.qml" },
80+ { tag: "Gallery", type: "gallery", source: "PreviewImageGallery.qml" },
81+ { tag: "Actions", type: "actions", source: "PreviewActions.qml" },
82+ ];
83+ }
84+
85+ function test_mapping(data) {
86+ factory.widgetData = { type: data.type };
87+ factory.widgetType = data.type;
88+
89+ verify(("" + factory.source).indexOf(data.source) != -1);
90+ }
91+ }
92+}
tests/qmltests/Dash/tst_Card.qml+8
@@ -74,6 +74,11 @@ Rectangle {
7474 "name": "Header title only",
7575 "layout": { "components": { "title": "title" } }
7676 },
77+ {
78+ "name": "Art, header, summary - overlaid",
79+ "layout": { "template": { "overlay": true },
80+ "components": JSON.parse(Helpers.fullMapping) }
81+ },
7782 ]
7883
7984 CardTool {
@@ -224,6 +229,7 @@ Rectangle {
224229 }
225230
226231 function test_card_size(data) {
232+ waitForRendering(card);
227233 selector.selectedIndex = data.index;
228234
229235 if (data.hasOwnProperty("size")) {
@@ -314,6 +320,8 @@ Rectangle {
314320 left: function() { return art.x }, index: 0 },
315321 { tag: "Horizontal", top: function() { return art.y },
316322 left: function() { return art.x + art.width }, index: 5 },
323+ { tag: "Overlay", top: function() { return art.y + art.height - header.height },
324+ left: function() { return art.x }, index: 9 },
317325 ]
318326 }
319327
tests/qmltests/Dash/tst_CardTool.qml+7−1
@@ -209,7 +209,7 @@ Rectangle {
209209 id: dataArea
210210 anchors { left: parent.left; right: parent.right }
211211 height: units.gu(25)
212− text: JSON.stringify(cardTool.priv.cardData, undefined, 2)
212+ text: JSON.stringify(testCase.internalCard.cardData, undefined, 2)
213213 }
214214
215215 Label {
@@ -239,8 +239,14 @@ Rectangle {
239239 id: testCase
240240 name: "Card"
241241
242+ property Card internalCard: findChild(cardTool, "card")
243+
242244 when: windowShown
243245
246+ function init() {
247+ verify(typeof testCase.internalCard === "object", "Couldn't find internal card object.");
248+ }
249+
244250 function cleanup() {
245251 selector.selectedIndex = -1;
246252 layoutSelector.selectedIndex = -1;