on xenial help sign in
Merged with trunk.
commitd6b3cbf4053c60367f71f2b3634f9bfde6da55b5 authorLeo Arias <leo.arias@canonical.com> dateSat 1 Mar 2014, 21:23 (13 years ago) parentc646febb8b0c82
37 files changed+474−126
cmake/modules/autopilot.cmake+10−1 data/unity8.conf+5 debian/changelog+33 debian/control+8−1 debian/rules+2−2 plugins/Ubuntu/Gestures/DirectionalDragArea.cpp+9 plugins/Ubuntu/Gestures/DirectionalDragArea.h+1 po/ar.po+6−6 po/el.po+10−8 po/fi.po+4−4 po/sl.po+10−8 qml/Dash/Card.qml+2 qml/Dash/CardHeader.qml+2 qml/Dash/Dash.qml−1 qml/Dash/DashContent.qml−8 qml/Dash/GenericScopeView.qml+1−5 qml/Dash/Previews/PreviewRatingDisplay.qml+101 qml/Dash/Previews/PreviewRating.qml → qml/Dash/Previews/PreviewRatingInput.qml qml/Dash/Previews/PreviewWidgetFactory.qml+2−1 qml/Panel/Indicators.qml+1−1 src/main.cpp+6 tests/autopilot/unity8/__init__.py+5−2 tests/autopilot/unity8/process_helpers.py+1−1 tests/autopilot/unity8/shell/emulators/create_interactive_notification.py+2−1 tests/autopilot/unity8/shell/tests/__init__.py+12−13 tests/autopilot/unity8/shell/tests/test_emulators.py+4−1 tests/autopilot/unity8/shell/tests/test_lock_screen.py+18−3 tests/autopilot/unity8/shell/tests/test_notifications.py+8−1 tests/autopilot/unity8/shell/tests/test_upstart.py+6−1 tests/plugins/Ubuntu/Gestures/tst_DirectionalDragArea.cpp+46 tests/qmltests/CMakeLists.txt+2−1 tests/qmltests/Dash/Previews/tst_PreviewRatingDisplay.qml+112 tests/qmltests/Dash/Previews/tst_PreviewRating.qml → tests/qmltests/Dash/Previews/tst_PreviewRatingInput.qml+15−15 tests/qmltests/Dash/Previews/tst_PreviewWidgetFactory.qml+2−1 tests/qmltests/Dash/qml/FakeScopeView.qml−5 tests/qmltests/Dash/tst_Card.qml+14 tests/qmltests/Dash/tst_DashContent.qml+14−35
cmake/modules/autopilot.cmake+10−1
@@ -2,7 +2,7 @@ add_custom_target(autopilot)
22
33function(declare_autopilot_test TEST_NAME TEST_SUITE WORKING_DIR)
44 add_custom_target(autopilot-${TEST_NAME}
5− COMMAND LANG=C UBUNTU_ICON_THEME=ubuntu-mobile QML2_IMPORT_PATH=${SHELL_INSTALL_QML}/mocks autopilot run ${TEST_SUITE}
5+ COMMAND LANG=C UBUNTU_ICON_THEME=ubuntu-mobile QML2_IMPORT_PATH=${SHELL_INSTALL_QML}/mocks python3 -m autopilot.run run ${TEST_SUITE}
66 WORKING_DIRECTORY ${WORKING_DIR}
77 DEPENDS fake_install
88 )
@@ -12,4 +12,13 @@ function(declare_autopilot_test TEST_NAME TEST_SUITE WORKING_DIR)
1212 )
1313
1414 add_dependencies(autopilot autopilot-${TEST_NAME})
15+
16+ add_custom_target(autopilot2-${TEST_NAME}
17+ COMMAND LANG=C UBUNTU_ICON_THEME=ubuntu-mobile QML2_IMPORT_PATH=${SHELL_INSTALL_QML}/mocks python2 -m autopilot.run run ${TEST_SUITE}
18+ WORKING_DIRECTORY ${WORKING_DIR}
19+ DEPENDS fake_install
20+ )
21+
22+ add_dependencies(autopilot autopilot2-${TEST_NAME})
23+
1524endfunction()
data/unity8.conf+5
@@ -28,6 +28,11 @@ pre-start script
2828 initctl set-env --global MIR_SOCKET=$MIR_SERVER_FILE
2929 gdbus call --session --dest org.freedesktop.DBus --object-path /org/freedesktop/DBus --method org.freedesktop.DBus.UpdateActivationEnvironment "@a{ss} {'MIR_SOCKET': '$MIR_SERVER_FILE'}"
3030 fi
31+
32+ # Remove the socket if still there
33+ if [ -S "$MIR_SERVER_FILE" ]; then
34+ rm "$MIR_SERVER_FILE"
35+ fi
3136end script
3237
3338exec ${BINARY:-unity8} $ARGS
debian/changelog+33
@@ -1,3 +1,36 @@
1+unity8 (7.84+14.04.20140228-0ubuntu1) trusty; urgency=low
2+
3+ [ Michał Sawicz ]
4+ * Fix CardHeader title font weight.
5+ * Delete stale sockets. (LP: #1285215)
6+
7+ [ Dmitrijs Ledkovs ]
8+ * Ship python3 autopilot modules.
9+
10+ [ Albert Astals ]
11+ * Cleanup DashContent Remove unused signals and properties
12+
13+ [ Michał Karnicki ]
14+ * Take it easy on the logging.
15+ * Fix CardHeader title font weight.
16+
17+ [ Nick Dedekind ]
18+ * Added ability to change indicator profile in shell (env
19+ UNITY_INDICATOR_PROFILE)
20+
21+ [ Andrea Cimitan ]
22+ * Rename PreviewRating to PreviewRatingInput
23+ * Adds PreviewRatingDisplay
24+
25+ [ Daniel d'Andrada ]
26+ * DirectionalDragArea: Reset status if disabled while dragging (LP:
27+ #1276122)
28+
29+ [ Dimitri John Ledkov ]
30+ * Ship python3 autopilot modules.
31+
32+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Fri, 28 Feb 2014 10:48:06 +0000
33+
134unity8 (7.84+14.04.20140221-0ubuntu1) trusty; urgency=low
235
336 [ Michał Sawicz ]
debian/control+8−1
@@ -28,7 +28,8 @@ Build-Depends: cmake,
2828 pkg-config,
2929 python:any (>= 2.7),
3030 python-setuptools,
31− python3:any,
31+ python3-all:any,
32+ python3-setuptools,
3233 qt5-default,
3334 qtbase5-dev,
3435 qtbase5-dev-tools,
@@ -107,16 +108,22 @@ Depends: gir1.2-glib-2.0,
107108 libautopilot-qt (>= 1.4),
108109 libqt5test5,
109110 libqt5widgets5,
111+ python-autopilot,
110112 python-evdev,
111113 python-fixtures,
112114 python-gi,
113115 python-mock,
116+ python3-autopilot,
117+ python3-evdev,
118+ python3-fixtures,
119+ python3-gi,
114120 ubuntu-ui-toolkit-autopilot,
115121 unity8 (>= ${source:Version}),
116122 unity8-fake-env (>= ${source:Version}),
117123 url-dispatcher-tools,
118124 ${misc:Depends},
119125 ${python:Depends},
126+ ${python3:Depends},
120127 ${shlibs:Depends},
121128Description: Test package for Unity 8 shell
122129 Autopilot tests for the unity8 package
debian/rules+2−2
@@ -10,7 +10,7 @@ SCOPES_RECOMMENDS := $(shell perl debian/scopes-recommends-generator /usr/share/
1010
1111.PHONY: build
1212build %:
13− dh $@ --parallel --fail-missing --with python2
13+ dh $@ --parallel --fail-missing --with python2,python3
1414
1515override_dh_auto_clean:
1616 dh_auto_clean
@@ -28,7 +28,7 @@ override_dh_auto_build:
2828override_dh_install:
2929 # install autopilot tests
3030 cd tests/autopilot; \
31− set -ex; for python in $(shell pyversions -r); do \
31+ set -ex; for python in $(shell pyversions -r) $(shell py3versions -r); do \
3232 $$python setup.py install --root=$(CURDIR)/debian/tmp --install-layout=deb; \
3333 done; \
3434 cd $(CURDIR)
plugins/Ubuntu/Gestures/DirectionalDragArea.cpp+9
@@ -129,6 +129,8 @@ DirectionalDragArea::DirectionalDragArea(QQuickItem *parent)
129129 m_recognitionTimer->setInterval(60);
130130
131131 m_velocityCalculator = new AxisVelocityCalculator(this);
132+
133+ connect(this, &QQuickItem::enabledChanged, this, &DirectionalDragArea::onEnabledChanged);
132134}
133135
134136Direction::Type DirectionalDragArea::direction() const
@@ -528,6 +530,13 @@ void DirectionalDragArea::checkSpeed()
528530 m_numSamplesOnLastSpeedCheck = m_velocityCalculator->numSamples();
529531}
530532
533+void DirectionalDragArea::onEnabledChanged()
534+{
535+ if (!isEnabled() && m_status != WaitingForTouch) {
536+ setStatus(WaitingForTouch);
537+ }
538+}
539+
531540void DirectionalDragArea::setStatus(DirectionalDragArea::Status newStatus)
532541{
533542 if (newStatus == m_status)
plugins/Ubuntu/Gestures/DirectionalDragArea.h+1
@@ -218,6 +218,7 @@ protected:
218218
219219private Q_SLOTS:
220220 void checkSpeed();
221+ void onEnabledChanged();
221222
222223private:
223224 void touchEvent_absent(QTouchEvent *event);
po/ar.po+6−6
@@ -8,7 +8,7 @@ msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2014-02-13 18:37+0000\n"
11−"PO-Revision-Date: 2014-02-16 09:56+0000\n"
11+"PO-Revision-Date: 2014-02-21 11:19+0000\n"
1212"Last-Translator: Ibrahim Saed <ibraheem5000@gmail.com>\n"
1313"Language-Team: Arabic <ar@li.org>\n"
1414"MIME-Version: 1.0\n"
@@ -16,8 +16,8 @@ msgstr ""
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n % 100 >= "
1818"3 && n % 100 <= 10 ? 3 : n % 100 >= 11 && n % 100 <= 99 ? 4 : 5;\n"
19−"X-Launchpad-Export-Date: 2014-02-19 05:44+0000\n"
20−"X-Generator: Launchpad (build 16916)\n"
19+"X-Launchpad-Export-Date: 2014-02-22 07:40+0000\n"
20+"X-Generator: Launchpad (build 16926)\n"
2121
2222#: plugins/Unity/Launcher/launcheritem.cpp:43
2323#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -113,11 +113,11 @@ msgstr[5] "%1 تعليق"
113113
114114#: qml/Dash/Previews/PreviewActionCombo.qml:34
115115msgid "More..."
116−msgstr ""
116+msgstr "المزيد..."
117117
118118#: qml/Dash/Previews/PreviewActionCombo.qml:34
119119msgid "Less..."
120−msgstr ""
120+msgstr "أقل..."
121121
122122#: qml/Dash/Previews/PreviewRating.qml:114 qml/Dash/Previews/Reviews.qml:74
123123msgid "Add a review"
@@ -174,7 +174,7 @@ msgstr "عرض كلمة السر"
174174
175175#: qml/Notifications/NotificationMenuItemFactory.qml:103
176176msgid "Please enter SIM PIN"
177−msgstr ""
177+msgstr "من فضلك أدخِل رقم التعريف الشخصي لبطاقة SIM"
178178
179179#: qml/Panel/SearchIndicator.qml:27
180180msgid "Search"
po/el.po+10−8
@@ -8,15 +8,15 @@ msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2014-02-13 18:37+0000\n"
11−"PO-Revision-Date: 2014-01-15 16:34+0000\n"
12−"Last-Translator: Filippos Kolyvas <Unknown>\n"
11+"PO-Revision-Date: 2014-02-26 09:58+0000\n"
12+"Last-Translator: j3lc <x_nikos@yahoo.gr>\n"
1313"Language-Team: Greek <el@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2014-02-19 05:44+0000\n"
19−"X-Generator: Launchpad (build 16916)\n"
18+"X-Launchpad-Export-Date: 2014-02-27 06:34+0000\n"
19+"X-Generator: Launchpad (build 16935)\n"
2020
2121#: plugins/Unity/Launcher/launcheritem.cpp:43
2222#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -74,6 +74,8 @@ msgid ""
7474"You have now mastered the edge gestures and can start using the "
7575"phone<br><br>Tap on the screen to start"
7676msgstr ""
77+"Πλέον γνωρίζετε τις χειρονομίες από τα άκρα και μπορείτε να ξεκινήσετε να "
78+"χρησιμοποιείτε το τηλέφωνο<br><br>Αγγίξτε την οθόνη για να ξεκινήσετε"
7779
7880#: qml/Components/PageHeader.qml:340
7981msgid "Recent searches"
@@ -81,11 +83,11 @@ msgstr "Πρόσφατες αναζητήσεις"
8183
8284#: qml/Components/SeeMore.qml:35
8385msgid "See more"
84−msgstr ""
86+msgstr "Περρισότερα"
8587
8688#: qml/Components/SeeMore.qml:57
8789msgid "See less"
88−msgstr ""
90+msgstr "Λιγότερα"
8991
9092#: qml/Dash/Apps/AppPreview.qml:136 qml/Dash/Previews/PreviewRating.qml:70
9193msgid "Rate this"
@@ -152,7 +154,7 @@ msgstr "Πληκτρολογήστε ή πείτε μια εντολή"
152154
153155#: qml/Hud/Hud.qml:84
154156msgid "Loading. Please Wait..."
155−msgstr "Γίνεται φόρτωση, παρακαλώ περιμένετε..."
157+msgstr "Γίνεται φόρτωση. Παρακαλώ περιμένετε..."
156158
157159#: qml/Hud/Hud.qml:89
158160msgid "Speak Now..."
@@ -168,7 +170,7 @@ msgstr "Εμφάνιση κωδικού"
168170
169171#: qml/Notifications/NotificationMenuItemFactory.qml:103
170172msgid "Please enter SIM PIN"
171−msgstr ""
173+msgstr "Παρακαλώ εισάγετε το PIN της κάρτας SIM"
172174
173175#: qml/Panel/SearchIndicator.qml:27
174176msgid "Search"
po/fi.po+4−4
@@ -8,15 +8,15 @@ msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2014-02-13 18:37+0000\n"
11−"PO-Revision-Date: 2014-02-14 13:28+0000\n"
11+"PO-Revision-Date: 2014-02-21 19:36+0000\n"
1212"Last-Translator: Jiri Grönroos <Unknown>\n"
1313"Language-Team: Finnish <fi@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2014-02-19 05:44+0000\n"
19−"X-Generator: Launchpad (build 16916)\n"
18+"X-Launchpad-Export-Date: 2014-02-22 07:40+0000\n"
19+"X-Generator: Launchpad (build 16926)\n"
2020
2121#: plugins/Unity/Launcher/launcheritem.cpp:43
2222#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -105,7 +105,7 @@ msgstr[1] "%1 arvostelua"
105105
106106#: qml/Dash/Previews/PreviewActionCombo.qml:34
107107msgid "More..."
108−msgstr ""
108+msgstr "Lisää..."
109109
110110#: qml/Dash/Previews/PreviewActionCombo.qml:34
111111msgid "Less..."
po/sl.po+10−8
@@ -8,7 +8,7 @@ msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2014-02-13 18:37+0000\n"
11−"PO-Revision-Date: 2013-11-30 08:20+0000\n"
11+"PO-Revision-Date: 2014-02-21 16:38+0000\n"
1212"Last-Translator: Damir Jerovšek <Unknown>\n"
1313"Language-Team: Slovenian <sl@li.org>\n"
1414"MIME-Version: 1.0\n"
@@ -16,8 +16,8 @@ msgstr ""
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=4; plural=(n%100==1 ? 1 : n%100==2 ? 2 : n%100==3 || "
1818"n%100==4 ? 3 : 0);\n"
19−"X-Launchpad-Export-Date: 2014-02-19 05:44+0000\n"
20−"X-Generator: Launchpad (build 16916)\n"
19+"X-Launchpad-Export-Date: 2014-02-22 07:40+0000\n"
20+"X-Generator: Launchpad (build 16926)\n"
2121
2222#: plugins/Unity/Launcher/launcheritem.cpp:43
2323#: plugins/Unity/Launcher/launcheritem.cpp:73
@@ -75,6 +75,8 @@ msgid ""
7575"You have now mastered the edge gestures and can start using the "
7676"phone<br><br>Tap on the screen to start"
7777msgstr ""
78+"Sedaj, ko ste osvojili poteze robov, lahko začnete uporabljati "
79+"telefon<br><br>Tapnite na zaslon za začetek"
7880
7981#: qml/Components/PageHeader.qml:340
8082msgid "Recent searches"
@@ -82,11 +84,11 @@ msgstr "Nedavna iskanja"
8284
8385#: qml/Components/SeeMore.qml:35
8486msgid "See more"
85−msgstr ""
87+msgstr "Pokaži več"
8688
8789#: qml/Components/SeeMore.qml:57
8890msgid "See less"
89−msgstr ""
91+msgstr "Pokaži manj"
9092
9193#: qml/Dash/Apps/AppPreview.qml:136 qml/Dash/Previews/PreviewRating.qml:70
9294msgid "Rate this"
@@ -110,11 +112,11 @@ msgstr[3] "%1 ocene"
110112
111113#: qml/Dash/Previews/PreviewActionCombo.qml:34
112114msgid "More..."
113−msgstr ""
115+msgstr "Več ..."
114116
115117#: qml/Dash/Previews/PreviewActionCombo.qml:34
116118msgid "Less..."
117−msgstr ""
119+msgstr "Manj ..."
118120
119121#: qml/Dash/Previews/PreviewRating.qml:114 qml/Dash/Previews/Reviews.qml:74
120122msgid "Add a review"
@@ -171,7 +173,7 @@ msgstr "Pokaži geslo"
171173
172174#: qml/Notifications/NotificationMenuItemFactory.qml:103
173175msgid "Please enter SIM PIN"
174−msgstr ""
176+msgstr "Vnesite PIN kartice SIM"
175177
176178#: qml/Panel/SearchIndicator.qml:27
177179msgid "Search"
qml/Dash/Card.qml+2
@@ -160,6 +160,8 @@ Item {
160160 title: cardData && cardData["title"] || ""
161161 subtitle: cardData && cardData["subtitle"] || ""
162162
163+ titleWeight: components && components["subtitle"] ? Font.DemiBold : Font.Normal
164+
163165 opacity: showHeader ? 1 : 0
164166
165167 Behavior on opacity { NumberAnimation { duration: UbuntuAnimation.SnapDuration } }
qml/Dash/CardHeader.qml+2
@@ -26,6 +26,8 @@ Item {
2626 property alias oldPrice: oldPriceLabel.text
2727 property alias altPrice: altPriceLabel.text
2828
29+ property alias titleWeight: titleLabel.font.weight
30+
2931 // FIXME: Saviq, used to scale fonts down in Carousel
3032 property real fontScale: 1.0
3133
qml/Dash/Dash.qml−1
@@ -28,7 +28,6 @@ Showable {
2828
2929 property ListModel searchHistory: SearchHistoryModel {}
3030
31− property alias contentProgress: dashContent.contentProgress
3231 property string showScopeOnLoaded: "home.scope"
3332 property real contentScale: 1.0
3433
qml/Dash/DashContent.qml−8
@@ -24,7 +24,6 @@ Item {
2424
2525 property var model: null
2626 property var scopes: null
27− property real contentProgress: Math.max(0, Math.min(dashContentList.contentX / (dashContentList.contentWidth - dashContentList.width), units.dp(1)))
2827 property alias currentIndex: dashContentList.currentIndex
2928
3029 property ScopeDelegateMapper scopeMapper : ScopeDelegateMapper {}
@@ -32,8 +31,6 @@ Item {
3231
3332 signal movementStarted()
3433 signal movementEnded()
35− signal contentFlickStarted()
36− signal contentEndReached()
3734 signal scopeLoaded(string scopeId)
3835 signal positionedAtBeginning()
3936
@@ -144,11 +141,6 @@ Item {
144141 dashContent.positionedAtBeginning.connect(item.positionedAtBeginning)
145142 dashContent.scopeLoaded(item.scope.id)
146143 }
147− Connections {
148− target: item
149− ignoreUnknownSignals: true
150− onEndReached: contentEndReached()
151− }
152144
153145 Component.onDestruction: active = false
154146 }
qml/Dash/GenericScopeView.qml+1−5
@@ -33,7 +33,6 @@ FocusScope {
3333 property OpenEffect openEffect: null
3434 property Item previewListView: null
3535
36− signal endReached
3736 signal movementStarted
3837 signal positionedAtBeginning
3938
@@ -118,9 +117,6 @@ FocusScope {
118117 model: scopeView.categories
119118 forceNoClip: previewListView.onScreen
120119
121− onAtYEndChanged: if (atYEnd) endReached()
122− onMovingChanged: if (moving && atYEnd) endReached()
123−
124120 property string expandedCategoryId: ""
125121 signal correctExpandedCategory();
126122
@@ -287,7 +283,7 @@ FocusScope {
287283
288284 sectionProperty: "name"
289285 sectionDelegate: ListItems.Header {
290− objectName: "dashSectionHeader" + delegate.category
286+ objectName: "dashSectionHeader" + (delegate ? delegate.category : "")
291287 property var delegate: categoryView.item(delegateIndex)
292288 width: categoryView.width
293289 text: section
qml/Dash/Previews/PreviewRatingDisplay.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.0
18+import Ubuntu.Components 0.1
19+import "../../Components"
20+
21+/*! \brief Preview widget for rating display.
22+
23+ The widget can show a rating widget and a field showing a comment.
24+ The icons used in the rating widget can be customised with
25+ widgetData["rating-icon-empty"], widgetData["rating-icon-full"]
26+ and widgetData["rating-icon-half"].
27+
28+ This widget shows reviews contained in widgetData["reviews"], each of which should be of the form:
29+
30+ \code{.json}
31+ {
32+ "rating": null,
33+ "review": null,
34+ "author": null
35+ }
36+ \endcode
37+ */
38+
39+PreviewWidget {
40+ id: root
41+ height: childrenRect.height
42+
43+ Column {
44+ anchors { left: parent.left; right: parent.right; }
45+ visible: reviewsRepeater.count > 0
46+
47+ Repeater {
48+ id: reviewsRepeater
49+ objectName: "reviewsRepeater"
50+ model: root.widgetData["reviews"]
51+
52+ delegate: Column {
53+ id: reviewItem
54+ objectName: "reviewItem" + index
55+ anchors { left: parent.left; right: parent.right;}
56+ spacing: units.gu(1)
57+
58+ Rating {
59+ id: rating
60+ objectName: "rating"
61+ size: 5
62+ value: modelData["rating"] || -1
63+ visible: value >= 0
64+
65+ property var urlIconEmpty: widgetData["rating-icon-empty"]
66+ property var urlIconFull: widgetData["rating-icon-full"]
67+ property var urlIconHalf: widgetData["rating-icon-half"]
68+ }
69+
70+ Label {
71+ id: authorLabel
72+ objectName: "authorLabel"
73+ anchors { left: parent.left; right: parent.right }
74+ color: Theme.palette.selected.backgroundText
75+ opacity: .8
76+ text: modelData["author"] || ""
77+ visible: text !== ""
78+ wrapMode: Text.Wrap
79+ }
80+
81+ Label {
82+ id: reviewLabel
83+ objectName: "reviewLabel"
84+ anchors { left: parent.left; right: parent.right }
85+ color: Theme.palette.selected.backgroundText
86+ opacity: .8
87+ text: modelData["review"] || ""
88+ visible: text !== ""
89+ wrapMode: Text.Wrap
90+ }
91+
92+ Item {
93+ id: spacing
94+ anchors { left: parent.left; right: parent.right }
95+ height: units.gu(2)
96+ visible: rating.visible || authorLabel.visible || reviewLabel.visible
97+ }
98+ }
99+ }
100+ }
101+}
qml/Dash/Previews/PreviewRating.qml → qml/Dash/Previews/PreviewRatingInput.qmlrenamed

The content is the same.

qml/Dash/Previews/PreviewWidgetFactory.qml+2−1
@@ -48,7 +48,8 @@ Loader {
4848 case "header": return "PreviewHeader.qml";
4949 case "image": return "PreviewZoomableImage.qml"
5050 case "progress": return "PreviewProgress.qml";
51− case "rating-input": return "PreviewRating.qml";
51+ case "rating-input": return "PreviewRatingInput.qml";
52+ case "reviews": return "PreviewRatingDisplay.qml";
5253 case "text": return "PreviewTextSummary.qml";
5354 case "video": return "PreviewVideoPlayback.qml";
5455 default: return "";
qml/Panel/Indicators.qml+1−1
@@ -32,7 +32,7 @@ Showable {
3232 property alias overFlowWidth: indicatorRow.overFlowWidth
3333 property alias showAll: indicatorRow.showAll
3434 // TODO: This should be sourced by device type (eg "desktop", "tablet", "phone"...)
35− property string profile: "phone"
35+ property string profile: indicatorProfile
3636
3737 readonly property real hintValue: panelHeight + menuContent.headerHeight
3838 readonly property int lockThreshold: openedHeight / 2
src/main.cpp+6
@@ -59,6 +59,11 @@ int startShell(int argc, const char** argv, void* server)
5959 application = new QGuiApplication(argc, (char**)argv);
6060 }
6161
62+ QString indicatorProfile = qgetenv("UNITY_INDICATOR_PROFILE");
63+ if (indicatorProfile.isEmpty()) {
64+ indicatorProfile = "phone";
65+ }
66+
6267 resolveIconTheme();
6368
6469 QStringList args = application->arguments();
@@ -88,6 +93,7 @@ int startShell(int argc, const char** argv, void* server)
8893 view->setTitle("Qml Phone Shell");
8994 view->engine()->setBaseUrl(QUrl::fromLocalFile(::qmlDirectory()));
9095 view->rootContext()->setContextProperty("applicationArguments", &qmlArgs);
96+ view->rootContext()->setContextProperty("indicatorProfile", indicatorProfile);
9197 if (args.contains(QLatin1String("-frameless"))) {
9298 view->setFlags(Qt::FramelessWindowHint);
9399 }
tests/autopilot/unity8/__init__.py+5−2
@@ -82,7 +82,10 @@ def get_binary_path(binary="unity8"):
8282 )
8383 if not os.path.exists(binary_path):
8484 try:
85− binary_path = subprocess.check_output(['which', binary]).strip()
85+ binary_path = subprocess.check_output(
86+ ['which', binary],
87+ universal_newlines=True,
88+ ).strip()
8689 except subprocess.CalledProcessError as e:
8790 raise RuntimeError("Unable to locate %s binary: %r" % (binary, e))
8891 return binary_path
@@ -128,7 +131,7 @@ def _get_xdg_upstart_env():
128131 "get-env",
129132 "--global",
130133 "XDG_DATA_DIRS"
131− ]).rstrip()
134+ ], universal_newlines=True).rstrip()
132135 except subprocess.CalledProcessError:
133136 return None
134137
tests/autopilot/unity8/process_helpers.py+1−1
@@ -142,7 +142,7 @@ def _get_unity_status():
142142 '/sbin/initctl',
143143 'status',
144144 'unity8'
145− ])
145+ ], universal_newlines=True)
146146 except subprocess.CalledProcessError as e:
147147 raise CannotAccessUnity("Unable to get unity's status: %s" % str(e))
148148
tests/autopilot/unity8/shell/emulators/create_interactive_notification.py+2−1
@@ -1,4 +1,5 @@
11#!/usr/bin/env python
2+from __future__ import print_function
23
34# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
45#
@@ -25,7 +26,7 @@ import signal
2526
2627
2728def action_callback(notification, action_id, data):
28− print action_id
29+ print(action_id)
2930
3031
3132def quit_callback(notification):
tests/autopilot/unity8/shell/tests/__init__.py+12−13
@@ -85,12 +85,12 @@ class UnityTestCase(AutopilotTestCase):
8585 @classmethod
8686 def setUpClass(cls):
8787 try:
88− output = subprocess.check_output([
89− "/sbin/initctl",
90− "status",
91− "unity8"
92− ], stderr=subprocess.STDOUT)
93− except subprocess.CalledProcessError, e:
88+ output = subprocess.check_output(
89+ ["/sbin/initctl", "status", "unity8"],
90+ stderr=subprocess.STDOUT,
91+ universal_newlines=True,
92+ )
93+ except subprocess.CalledProcessError as e:
9494 sys.stderr.write(
9595 "Error: `initctl status unity8` failed, most probably the "
9696 "unity8 session could not be found:\n\n"
@@ -218,12 +218,11 @@ class UnityTestCase(AutopilotTestCase):
218218 def _patch_environment(self, key, value):
219219 """Wrapper for patching env for upstart environment."""
220220 try:
221− current_value = subprocess.check_output([
222− "/sbin/initctl",
223− "get-env",
224− "--global",
225− key
226− ], stderr=subprocess.STDOUT).rstrip()
221+ current_value = subprocess.check_output(
222+ ["/sbin/initctl", "get-env", "--global", key],
223+ stderr=subprocess.STDOUT,
224+ universal_newlines=True,
225+ ).rstrip()
227226 except subprocess.CalledProcessError:
228227 current_value = None
229228
@@ -305,7 +304,7 @@ class UnityTestCase(AutopilotTestCase):
305304
306305 binary_arg = "BINARY=%s" % binary_path
307306 extra_args = "ARGS=%s" % " ".join(args)
308− env_args = ["%s=%s" % (k, v) for k, v in self._environment.iteritems()]
307+ env_args = ["%s=%s" % (k, v) for k, v in self._environment.items()]
309308 all_args = [binary_arg, extra_args] + env_args
310309
311310 self.addCleanup(self._cleanup_launching_upstart_unity)
tests/autopilot/unity8/shell/tests/test_emulators.py+4−1
@@ -27,7 +27,10 @@ don't break them for those external projects.
2727
2828"""
2929
30−import mock
30+try:
31+ from unittest import mock
32+except ImportError:
33+ import mock
3134
3235from testtools.matchers import Contains, HasLength
3336
tests/autopilot/unity8/shell/tests/test_lock_screen.py+18−3
@@ -26,12 +26,18 @@ from unity8.shell.tests import UnityTestCase, _get_device_emulation_scenarios
2626
2727from autopilot.matchers import Eventually
2828from autopilot.platform import model
29+import sys
2930from testtools import skipUnless
3031from testtools.matchers import Equals
3132import logging
3233
3334logger = logging.getLogger(__name__)
3435
36+# py2 compatible alias for py3
37+if sys.version >= '3':
38+ basestring = str
39+
40+
3541class TestLockscreen(UnityTestCase):
3642
3743 """Tests for the lock screen."""
@@ -125,7 +131,10 @@ class TestLockscreen(UnityTestCase):
125131 """
126132
127133 if not isinstance(code, basestring):
128− raise TypeError("'code' parameter must be a string.")
134+ raise TypeError(
135+ "'code' parameter must be a string, not %r."
136+ % type(passphrase)
137+ )
129138 for num in code:
130139 if not num.isdigit():
131140 raise ValueError(
@@ -142,7 +151,10 @@ class TestLockscreen(UnityTestCase):
142151
143152 """
144153 if not isinstance(passphrase, basestring):
145− raise TypeError("'passphrase' parameter must be a string.")
154+ raise TypeError(
155+ "'passphrase' parameter must be a string, not %r."
156+ % type(passphrase)
157+ )
146158
147159 pinentryField = self.main_window.get_pinentryField()
148160 self.touch.tap_object(pinentryField)
@@ -161,7 +173,10 @@ class TestLockscreen(UnityTestCase):
161173
162174 """
163175 if not isinstance(passphrase, basestring):
164− raise TypeError("'passphrase' parameter must be a string.")
176+ raise TypeError(
177+ "'passphrase' parameter must be a string, not %r."
178+ % type(passphrase)
179+ )
165180
166181 prompt = self.main_window.get_greeter().get_prompt()
167182 self.touch.tap_object(prompt)
tests/autopilot/unity8/shell/tests/test_notifications.py+8−1
@@ -33,9 +33,15 @@ import os
3333import logging
3434import signal
3535import subprocess
36+import sys
3637
3738logger = logging.getLogger(__name__)
3839
40+# from __future__ import range
41+# (python3's range, is same as python2's xrange)
42+if sys.version_info < (3,):
43+ range = xrange
44+
3945
4046class NotificationsBase(UnityTestCase):
4147 """Base class for all notification tests that provides helper methods."""
@@ -261,6 +267,7 @@ class InteractiveNotificationBase(NotificationsBase):
261267 stdout=subprocess.PIPE,
262268 stderr=subprocess.PIPE,
263269 close_fds=True,
270+ universal_newlines=True,
264271 )
265272
266273 self.addCleanup(self._tidy_up_script_process)
@@ -298,7 +305,7 @@ class InteractiveNotificationBase(NotificationsBase):
298305 if self._notify_proc is None:
299306 raise AssertionError("No interactive notification was created.")
300307
301− for i in xrange(timeout):
308+ for i in range(timeout):
302309 self._notify_proc.poll()
303310 if self._notify_proc.returncode is not None:
304311 output = self._notify_proc.communicate()
tests/autopilot/unity8/shell/tests/test_upstart.py+6−1
@@ -36,6 +36,11 @@ import logging
3636
3737logger = logging.getLogger(__name__)
3838
39+# from __future__ import range
40+# (python3's range, is same as python2's xrange)
41+import sys
42+if sys.version_info < (3,):
43+ range = xrange
3944
4045class UpstartIntegrationTests(UnityTestCase):
4146
@@ -52,7 +57,7 @@ class UpstartIntegrationTests(UnityTestCase):
5257 self.process = subprocess.Popen([get_binary_path()] + self.unity_geometry_args)
5358 def ensure_stopped():
5459 self.process.terminate()
55− for i in xrange(10):
60+ for i in range(10):
5661 try:
5762 self._get_status()
5863 except OSError:
tests/plugins/Ubuntu/Gestures/tst_DirectionalDragArea.cpp+46
@@ -86,6 +86,7 @@ private Q_SLOTS:
8686 void rotated();
8787 void sceneDistance();
8888 void sceneDistance_data();
89+ void disabledWhileDragging();
8990
9091private:
9192 void passTime(qint64 timeSpan);
@@ -795,6 +796,51 @@ void tst_DirectionalDragArea::sceneDistance_data()
795796 QTest::newRow("rotated by 90 degrees") << 90. << QPointF(0., 1.);
796797}
797798
799+/*
800+ Regression test for https://bugs.launchpad.net/unity8/+bug/1276122
801+
802+ The bug:
803+ If setting "enabled: false" while the DirectionalDragArea's (DDA) dragging
804+ property is true, the DDA stays in that state and doesn't recover any more.
805+*/
806+void tst_DirectionalDragArea::disabledWhileDragging()
807+{
808+ DirectionalDragArea *edgeDragArea =
809+ m_view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea");
810+ Q_ASSERT(edgeDragArea != 0);
811+ edgeDragArea->setRecognitionTimer(fakeTimer);
812+ edgeDragArea->setTimeSource(fakeTimeSource);
813+
814+ QPointF touchPoint = calculateInitialTouchPos(edgeDragArea);
815+
816+ qreal desiredDragDistance = edgeDragArea->distanceThreshold()*2.0f;
817+ QPointF dragDirectionVector(1., 0.); // horizontal positive
818+
819+ qreal movementStepDistance = edgeDragArea->distanceThreshold() * 0.1f;
820+ QPointF touchMovement = dragDirectionVector * movementStepDistance;
821+ int totalMovementSteps = qCeil(desiredDragDistance / movementStepDistance);
822+ int movementTimeStepMs = (edgeDragArea->compositionTime() * 1.5f) / totalMovementSteps;
823+
824+ QTest::touchEvent(m_view, m_device).press(0, touchPoint.toPoint());
825+
826+ for (int i = 0; i < totalMovementSteps; ++i) {
827+ touchPoint += touchMovement;
828+ passTime(movementTimeStepMs);
829+ QTest::touchEvent(m_view, m_device).move(0, touchPoint.toPoint());
830+ }
831+
832+ QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Recognized);
833+ QCOMPARE(edgeDragArea->dragging(), true);
834+
835+ // disable the dragArea while it's being dragged.
836+ edgeDragArea->setEnabled(false);
837+
838+ QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::WaitingForTouch);
839+ QCOMPARE(edgeDragArea->dragging(), false);
840+
841+ QTest::touchEvent(m_view, m_device).release(0, touchPoint.toPoint());
842+}
843+
798844QTEST_MAIN(tst_DirectionalDragArea)
799845
800846#include "tst_DirectionalDragArea.moc"
tests/qmltests/CMakeLists.txt+2−1
@@ -62,7 +62,8 @@ add_qml_test(Dash/Previews PreviewAudioPlayback IMPORT_PATHS ${qmltest_DEFAULT_I
6262add_qml_test(Dash/Previews PreviewHeader IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/tests/mocks)
6363add_qml_test(Dash/Previews PreviewImageGallery IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/tests/mocks)
6464add_qml_test(Dash/Previews PreviewProgress IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/tests/mocks)
65−add_qml_test(Dash/Previews PreviewRating IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/tests/mocks)
65+add_qml_test(Dash/Previews PreviewRatingDisplay IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/tests/mocks)
66+add_qml_test(Dash/Previews PreviewRatingInput IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/tests/mocks)
6667add_qml_test(Dash/Previews PreviewTextSummary IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/tests/mocks)
6768add_qml_test(Dash/Previews PreviewVideoPlayback IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/tests/mocks)
6869add_qml_test(Dash/Previews PreviewWidgetFactory IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/tests/mocks)
tests/qmltests/Dash/Previews/tst_PreviewRatingDisplay.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 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 reviewsModel0: {
30+ "reviews": [ ]
31+ }
32+
33+ property var reviewsModel1: {
34+ "reviews": [ { author: "Some dude", rating: 4.5, review: "Very cool app" },
35+ { author: "Yet Another dude", rating: 5, review: "Very cool app" }, ]
36+ }
37+
38+ property var reviewsModel2: {
39+ "reviews": [ { author: "Some dude", rating: 4.5, review: "Very cool app" },
40+ { author: "Another dude", rating: 3, review: "Average app. 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." },
41+ { author: "Yet Another dude", rating: 5, review: "Very cool app" }, ]
42+ }
43+
44+ property var reviewsModelMixed: {
45+ "reviews": [ { author: "Some dude", review: "Very cool app" },
46+ { author: "" },
47+ { rating: 3, review: "Average app. 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." },
48+ { author: "Yet Another dude", rating: 5 }, ]
49+ }
50+
51+ PreviewRatingDisplay {
52+ id: previewRatingDisplay
53+ anchors.left: parent.left
54+ anchors.right: parent.right
55+ widgetData: reviewsModelMixed
56+ }
57+
58+ UT.UnityTestCase {
59+ name: "PreviewRatingDisplayTest"
60+ when: windowShown
61+
62+ function test_reviews_data() {
63+ return [
64+ {tag: "0 reviews", reviewsModel: reviewsModel0},
65+ {tag: "1 review", reviewsModel: reviewsModel1},
66+ {tag: "3 reviews", reviewsModel: reviewsModel2},
67+ {tag: "3 mixed reviews", reviewsModel: reviewsModelMixed}
68+ ];
69+ }
70+
71+ function test_reviews(data) {
72+ previewRatingDisplay.widgetData = data.reviewsModel;
73+
74+ var reviewsRepeater = findChild(previewRatingDisplay, "reviewsRepeater");
75+ compare(reviewsRepeater.count, data.reviewsModel["reviews"].length);
76+
77+ for (var i = 0; i < data.reviewsModel["reviews"].length; ++i) {
78+ var reviewItem = findChild(previewRatingDisplay, "reviewItem" + i);
79+
80+ var rating = findChild(reviewItem, "rating");
81+ if (data.reviewsModel["reviews"][i]["rating"] >= 0) {
82+ compare(rating.visible, true);
83+ compare(rating.value, data.reviewsModel["reviews"][i]["rating"]);
84+ } else {
85+ compare(rating.visible, false);
86+ }
87+
88+ var authorLabel = findChild(reviewItem, "authorLabel");
89+ if (data.reviewsModel["reviews"][i]["author"] &&
90+ data.reviewsModel["reviews"][i]["author"] !== "") {
91+ compare(authorLabel.visible, true);
92+ compare(authorLabel.text, data.reviewsModel["reviews"][i]["author"]);
93+ } else {
94+ compare(authorLabel.visible, false);
95+ }
96+
97+ var reviewLabel = findChild(reviewItem, "reviewLabel");
98+ if (data.reviewsModel["reviews"][i]["review"] &&
99+ data.reviewsModel["reviews"][i]["review"] !== "") {
100+ compare(reviewLabel.visible, true);
101+ compare(reviewLabel.text, data.reviewsModel["reviews"][i]["review"]);
102+ } else {
103+ compare(reviewLabel.visible, false);
104+ }
105+
106+ if (!rating.visible && !authorLabel.visible && !reviewLabel.visible) {
107+ verify(reviewItem.height === 0);
108+ }
109+ }
110+ }
111+ }
112+}
tests/qmltests/Dash/Previews/tst_PreviewRating.qml → tests/qmltests/Dash/Previews/tst_PreviewRatingInput.qmlrenamed+15−15
@@ -43,12 +43,12 @@ Rectangle {
4343
4444 property var widgetDataNewLabels: { "visible": "both", "required": "both", "rating-label": "TestRatingLabel", "review-label": "TestReviewLabel", "submit-label": "TestSubmitLabel" }
4545
46− PreviewRating {
47− id: previewRating
46+ PreviewRatingInput {
47+ id: previewRatingInput
4848 anchors.left: parent.left
4949 anchors.right: parent.right
5050 widgetData: widgetDataBoth
51− widgetId: "previewRating"
51+ widgetId: "previewRatingInput"
5252 }
5353
5454 SignalSpy {
@@ -57,12 +57,12 @@ Rectangle {
5757 }
5858
5959 UT.UnityTestCase {
60− name: "PreviewRatingTest"
60+ name: "PreviewRatingInputTest"
6161 when: windowShown
6262
63− property var rating: findChild(previewRating, "rating")
64− property var reviewTextArea: findChild(previewRating, "reviewTextArea")
65− property var submitButton: findChild(previewRating, "submitButton")
63+ property var rating: findChild(previewRatingInput, "rating")
64+ property var reviewTextArea: findChild(previewRatingInput, "reviewTextArea")
65+ property var submitButton: findChild(previewRatingInput, "submitButton")
6666
6767 function init() {
6868 rating.value = -1;
@@ -70,10 +70,10 @@ Rectangle {
7070 }
7171
7272 function test_labels() {
73− var ratingLabel = findChild(previewRating, "ratingLabel");
74− var reviewLabel = findChild(previewRating, "reviewLabel");
73+ var ratingLabel = findChild(previewRatingInput, "ratingLabel");
74+ var reviewLabel = findChild(previewRatingInput, "reviewLabel");
7575
76− previewRating.widgetData = widgetDataNewLabels;
76+ previewRatingInput.widgetData = widgetDataNewLabels;
7777 compare(ratingLabel.text, widgetDataNewLabels["rating-label"]);
7878 compare(reviewLabel.text, widgetDataNewLabels["review-label"]);
7979 compare(submitButton.text, widgetDataNewLabels["submit-label"]);
@@ -106,9 +106,9 @@ Rectangle {
106106
107107 function test_submit_and_visibility(data) {
108108 spy.clear();
109− spy.target = previewRating;
109+ spy.target = previewRatingInput;
110110
111− previewRating.widgetData = data.widgetData;
111+ previewRatingInput.widgetData = data.widgetData;
112112
113113 if (data.widgetData["visible"] !== "review") {
114114 verify(rating.visible === true);
@@ -161,9 +161,9 @@ Rectangle {
161161
162162 function test_triggered(data) {
163163 spy.clear();
164− spy.target = previewRating;
164+ spy.target = previewRatingInput;
165165
166− previewRating.widgetData = data.widgetData;
166+ previewRatingInput.widgetData = data.widgetData;
167167
168168 if (data.inputRating > 0) rating.value = data.inputRating;
169169 if (data.inputText !== "") {
@@ -173,7 +173,7 @@ Rectangle {
173173
174174 compare(spy.count, 1);
175175 var args = spy.signalArguments[0];
176− compare(args[0], previewRating.widgetId);
176+ compare(args[0], previewRatingInput.widgetId);
177177 compare(args[1], data.widgetData["required"]);
178178 compare(args[2]["rating"], data.triggeredData["rating"]);
179179 compare(args[2]["review"], data.triggeredData["review"]);
tests/qmltests/Dash/Previews/tst_PreviewWidgetFactory.qml+2−1
@@ -81,7 +81,8 @@ Rectangle {
8181 { tag: "Header", type: "header", source: "PreviewHeader.qml" },
8282 { tag: "Image", type: "image", source: "PreviewZoomableImage.qml" },
8383 { tag: "Progress", type: "progress", source: "PreviewProgress.qml" },
84− { tag: "Rating Input", type: "rating-input", source: "PreviewRating.qml" },
84+ { tag: "Rating Input", type: "rating-input", source: "PreviewRatingInput.qml" },
85+ { tag: "Rating Display", type: "reviews", source: "PreviewRatingDisplay.qml" },
8586 { tag: "Text", type: "text", source: "PreviewTextSummary.qml" },
8687 { tag: "Video", type: "video", source: "PreviewVideoPlayback.qml" },
8788 ];
tests/qmltests/Dash/qml/FakeScopeView.qml−5
@@ -25,11 +25,6 @@ GenericScopeView {
2525 property alias backColor : back.color
2626 property var categoryView: null
2727
28− onEndReached: {
29− if (scope != undefined && shell != undefined && shell.scopeStatus != undefined) {
30− shell.scopeStatus[scope.id].endReached++;
31− }
32− }
3328 onMovementStarted: {
3429 if (shell != undefined && shell.scopeStatus != undefined) {
3530 shell.scopeStatus[scope.id].movementStarted++;
tests/qmltests/Dash/tst_Card.qml+14
@@ -182,6 +182,7 @@ Rectangle {
182182 when: windowShown
183183
184184 property Item header: findChild(card, "cardHeader")
185+ property Item title: findChild(header, "titleLabel")
185186 property Item art: findChild(card, "artShape")
186187 property Item artImage: findChild(card, "artImage")
187188 property Item summary: findChild(card, "summaryLabel")
@@ -413,5 +414,18 @@ Rectangle {
413414 tryCompare(backgroundImage, "source", data.image);
414415 }
415416 }
417+
418+ function test_font_weights_data() {
419+ return [
420+ { tag: "Title only", index: 8, weight: Font.Normal },
421+ { tag: "Title, subtitle", index: 0, weight: Font.DemiBold },
422+ ]
423+ }
424+
425+ function test_font_weights(data) {
426+ selector.selectedIndex = data.index;
427+
428+ tryCompare(testCase.title.font, "weight", data.weight);
429+ }
416430 }
417431}
tests/qmltests/Dash/tst_DashContent.qml+14−35
@@ -105,25 +105,19 @@ Item {
105105 signalName: "movementStarted"
106106 }
107107
108− SignalSpy {
109− id: contentEndReachedSpy
110− target: dashContent
111− signalName: "contentEndReached"
112− }
113−
114108 UT.UnityTestCase {
115109 name: "DashContent"
116110 when: scopesModel.loaded
117111
118112 function init() {
119113 scopesModel.clear();
114+ scopeLoadedSpy.clear();
120115 scopesModel.load();
116+ tryCompare(scopeLoadedSpy, "count", 5);
121117 }
122118
123119 function cleanup() {
124− scopeLoadedSpy.clear();
125120 movementStartedSpy.clear();
126− contentEndReachedSpy.clear();
127121 clear_scope_status();
128122 dashContent.visible = true;
129123
@@ -132,17 +126,18 @@ Item {
132126 scopesModel.clear();
133127 // wait for dash to empty scopes.
134128 tryCompare(dashContentList, "count", 0);
135− // this is the default state for empty model
136− dashContentList.currentIndex = -1;
137129 }
138130
139131 function test_current_index() {
140132 var dashContentList = findChild(dashContent, "dashContentList");
141133 verify(dashContentList != undefined)
142134
135+ scopesModel.clear();
143136 compare(dashContentList.count, 0, "DashContent should have 0 items when it starts");
144− compare(dashContentList.currentIndex, -1, "DashContent's currentIndex should be -1 while there have been no items in the model");
137+ tryCompare(dashContentList, "currentIndex", -1);
145138
139+ scopeLoadedSpy.clear();
140+ scopesModel.load();
146141 tryCompare(scopeLoadedSpy, "count", 5);
147142
148143 verify(dashContentList.currentIndex >= 0);
@@ -152,10 +147,13 @@ Item {
152147 var dashContentList = findChild(dashContent, "dashContentList");
153148 verify(dashContentList != undefined)
154149
155− compare(dashContentList.count, 0, "DashContent should have 0 items when it starts");
150+ scopesModel.clear();
151+ compare(dashContentList.count, 0, "DashContent should have 0 items after clearing");
156152 // pretend we're running after a model reset
157153 dashContentList.currentIndex = 27;
158154
155+ scopeLoadedSpy.clear();
156+ scopesModel.load();
159157 tryCompare(scopeLoadedSpy, "count", 5);
160158
161159 verify(dashContentList.currentIndex >= 0 && dashContentList.currentIndex < 5);
@@ -167,8 +165,6 @@ Item {
167165 var dashContentList = findChild(dashContent, "dashContentList");
168166 verify(dashContentList != undefined)
169167
170− tryCompare(scopeLoadedSpy, "count", 5);
171−
172168 dashContentList.movementStarted();
173169
174170 compare(movementStartedSpy.count, 1, "DashContent should have emitted movementStarted signal when content list did.");
@@ -182,8 +178,6 @@ Item {
182178 function test_positioned_at_beginning_signal() {
183179 dashContent.setCurrentScopeAtIndex(3, true, false);
184180
185− tryCompare(scopeLoadedSpy, "count", 5);
186−
187181 dashContent.positionedAtBeginning();
188182 compare(scopeStatus["MockScope1"].positionedAtBeginning, 1, "MockScope1 should have emitted positionedAtBeginning signal when DashContent did.");
189183 compare(scopeStatus["MockScope2"].positionedAtBeginning, 1, "MockScope2 should have emitted positionedAtBeginning signal when DashContent did.");
@@ -192,30 +186,17 @@ Item {
192186 compare(scopeStatus["MockScope5"].positionedAtBeginning, 1, "MockScope5 should have emitted positionedAtBeginning signal when DashContent did.");
193187 }
194188
195− function test_scope_loaded() {
196− tryCompare(scopeLoadedSpy, "count", 5);
197− }
198−
199− function test_content_end_reached() {
200− var dashContentList = findChild(dashContent, "dashContentList");
201− verify(dashContentList != undefined);
202−
203− tryCompare(scopeLoadedSpy, "count", 5);
204− dashContent.setCurrentScopeAtIndex(0, true, false);
205− dashContentList.currentItem.item.endReached();
206−
207− compare(contentEndReachedSpy.count, 1);
208− }
209−
210189 // This tests that setting the current scope index will end up at the correct index even if
211190 // the scopes are loaded asynchrounsly.
212191 function test_set_current_scope_index_async() {
192+ scopesModel.clear();
213193 verify(scopesModel.loaded == false);
214194
215− // next index is 1 if current is -1, otherwise it's current + 1
216− var next_index = ((dashContent.currentIndex == -1 ? 0 : dashContent.currentIndex) + 1) % 5
195+ tryCompare(dashContent, "currentIndex", -1);
196+ var next_index = 1
217197
218198 dashContent.setCurrentScopeAtIndex(next_index, true, false);
199+ scopesModel.load();
219200 tryCompare(dashContent, "currentIndex", next_index);
220201 verify(scopesModel.loaded == true);
221202
@@ -265,8 +246,6 @@ Item {
265246 function test_is_active(data) {
266247 var dashContentList = findChild(dashContent, "dashContentList");
267248
268− tryCompare(scopeLoadedSpy, "count", 5);
269−
270249 dashContent.setCurrentScopeAtIndex(data.select, true, false);
271250 dashContent.visible = data.visible;
272251