Merge lp:~unity-team/unity8/app-preview-data into lp:unity8

Proposed by Michał Sawicz
Status: Merged
Approved by: Albert Astals Cid
Approved revision: 169
Merged at revision: 192
Proposed branch: lp:~unity-team/unity8/app-preview-data
Merge into: lp:unity8
Diff against target: 2319 lines (+1534/-252)
33 files modified
Dash/Apps/AppInfo.qml (+88/-0)
Dash/Apps/AppPreview.qml (+195/-0)
Dash/Apps/AppReviews.qml (+191/-0)
Dash/DashApps.qml (+91/-0)
Dash/DashPreview.qml (+0/-218)
Dash/Generic/GenericPreview.qml (+17/-3)
Dash/GenericScopeView.qml (+1/-1)
Dash/PreviewDelegateMapper.qml (+2/-0)
Dash/Video/VideoPreview.qml (+35/-3)
plugins/Ubuntu/CMakeLists.txt (+1/-0)
plugins/Ubuntu/DownloadDaemonListener/CMakeLists.txt (+22/-0)
plugins/Ubuntu/DownloadDaemonListener/DownloadTracker.cpp (+84/-0)
plugins/Ubuntu/DownloadDaemonListener/DownloadTracker.h (+69/-0)
plugins/Ubuntu/DownloadDaemonListener/interface/downloadtrackeradaptor.cpp (+25/-0)
plugins/Ubuntu/DownloadDaemonListener/interface/downloadtrackeradaptor.h (+125/-0)
plugins/Ubuntu/DownloadDaemonListener/interface/metatypes.h (+28/-0)
plugins/Ubuntu/DownloadDaemonListener/plugin.cpp (+39/-0)
plugins/Ubuntu/DownloadDaemonListener/plugin.h (+37/-0)
plugins/Ubuntu/DownloadDaemonListener/qmldir (+3/-0)
plugins/Unity/preview.cpp (+7/-0)
plugins/Unity/preview.h (+4/-0)
po/unity8.pot (+39/-4)
tests/mocks/Ubuntu/CMakeLists.txt (+1/-0)
tests/mocks/Ubuntu/DownloadDaemonListener/CMakeLists.txt (+18/-0)
tests/mocks/Ubuntu/DownloadDaemonListener/MockDownloadTracker.cpp (+67/-0)
tests/mocks/Ubuntu/DownloadDaemonListener/MockDownloadTracker.h (+66/-0)
tests/mocks/Ubuntu/DownloadDaemonListener/plugin.cpp (+28/-0)
tests/mocks/Ubuntu/DownloadDaemonListener/plugin.h (+30/-0)
tests/mocks/Ubuntu/DownloadDaemonListener/qmldir (+2/-0)
tests/qmltests/CMakeLists.txt (+2/-0)
tests/qmltests/Dash/Apps/tst_AppPreview.qml (+152/-0)
tests/qmltests/Dash/Video/tst_VideoPreview.qml (+63/-0)
tests/qmltests/Dash/tst_DashPreview.qml (+2/-23)
To merge this branch: bzr merge lp:~unity-team/unity8/app-preview-data
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Albert Astals Cid (community) Approve
Michał Sawicz Pending
Michael Zanetti Pending
Review via email: mp+179348@code.launchpad.net

This proposal supersedes a proposal from 2013-07-25.

Commit message

Add AppPreview.

Description of the change

Connect the AppPreview UI to the data from the click scope and Add the QML Plugin to track the progress of a particular download from the download daemon.

======

Resubmitted without the prerequisite, as it seemed too intertwined to merge separately in the end.

======

To enable the click scope:
phablet> dconf write /com/canonical/unity/dash/scopes "['mockmusicmaster.scope', \
'home.scope', 'applications.scope', 'click/click.scope', 'mockvideosmaster.scope']"

You should not need to reboot, but it might help if the scope does not show up. Tap on an app from the "Click" scope will show the preview. Rating and sending reviews doesn't work yet.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
Michał Sawicz (saviq) wrote : Posted in a previous version of this proposal

Hey Diego, something's really bad here. I think you didn't merge the latest changes from lp:~diegosarmentero/unity8/app-preview or something, as when I:

bzr branch lp:unity8
bzr merge lp:~diegosarmentero/unity8/app-preview
bzr commit -m tmp
bzr merge lp:~diegosarmentero/unity8/unity-scope-data

I get:

Text conflict in Dash/Apps/AppPreview.qml
Text conflict in Dash/Apps/AppReviews.qml
Text conflict in tests/qmltests/CMakeLists.txt
Contents conflict in tests/qmltests/Dash/Apps/tst_AppInfo.qml
Text conflict in tests/qmltests/Dash/Apps/tst_AppPreview.qml
Contents conflict in tests/qmltests/Dash/Apps/tst_AppReviews.qml
Conflict adding file tests/qmltests/Dash/Video. Moved existing file to tests/qmltests/Dash/Video.moved.
7 conflicts encountered.

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
Michael Zanetti (mzanetti) wrote : Posted in a previous version of this proposal

* Can't launch installed apps any more. I guess the preview should only appear for "Available for download".
* The splig for the OpenEffect is slightly off. If the row above contains letters like g,j,y etc you can see them cut.
* Tapping into the review field brings up the OSK which in turn covers the review field again which makes it nearly impossible to actually leave a review.
* Images in previews do not work
* Rating stars do not work

review: Needs Fixing (testing on nexus4)
Revision history for this message
Michael Zanetti (mzanetti) wrote : Posted in a previous version of this proposal
Download full text (3.5 KiB)

80 + root.previewData.execute(modelData.id, { })

Is the {} really needed? Haven't seen this before in 3 years of intensive QML coding and I kinda dislike it. Perhaps execute() lacks a default argument?

Please keep coding style for imperative code consistent with ; at the end.

writing some text into the review TextField and clicking on Send doesn't do anything on Desktop. Do I need to install something to make it work?

88 + id: progressComponent

How do I trigger this code to test it? Haven't managed to get a progress bar neither on Desktop nor on Phone.

462 +# Because this is an internal support library, we want
463 +# to expose all symbols in it. Consider changing this
464 +# either to a static library or just using the
465 +# files directly in targets.

Please add the string "FIXME" to make this easily discoverable when grepping for such things.

805 +typeinfo plugins.qmltypes

You do not generate the plugins.qmltypes file

470 +# copy qmldir file into build directory for shadow builds
471 +file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/qmldir"
472 + DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
473 + )
474 +
475 +install(TARGETS DownloadDaemonListener
476 + DESTINATION ${SHELL_APP_DIR}/plugins/Ubuntu/DownloadDaemonListener
477 + )
478 +
479 +install(FILES qmldir
480 + DESTINATION ${SHELL_APP_DIR}/plugins/Ubuntu/DownloadDaemonListener
481 + )

dandrader wrote a nice cmake makro to simplify this. Check out other plugins. Using that should also generate the plugins.qmltypes file for you.

500 +void BackendPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
501 +{
502 + QQmlExtensionPlugin::initializeEngine(engine, uri);
503 +}

Not needed as you don't do anything in here anyways.

Test fail:
mzanetti@noneyet ~/Development/unity-scope-data/builddir $ make testAppPreview
file:///home/mzanetti/Development/unity-scope-data/tests/qmltests/Dash/Apps/tst_AppPreview.qml:90:5: Type AppPreview unavailable
         AppPreview {
         ^
file:///home/mzanetti/Development/unity-scope-data/Dash/Apps/AppPreview.qml:20:1: module "Ubuntu.DownloadDaemonListener" is not installed
     import Ubuntu.DownloadDaemonListener 0.1
     ^
********* Start testing of qmltestrunner *********
Config: Using QTest library 5.0.2, Qt 5.0.2
QWARN : qmltestrunner::tst_AppPreview::compile()
  /home/mzanetti/Development/unity-scope-data/tests/qmltests/Dash/Apps/tst_AppPreview.qml produced 2 error(s):
    /home/mzanetti/Development/unity-scope-data/tests/qmltests/Dash/Apps/tst_AppPreview.qml:90,5: Type AppPreview unavailable
    /home/mzanetti/Development/unity-scope-data/Dash/Apps/AppPreview.qml:20,1: module "Ubuntu.DownloadDaemonListener" is not installed
  Working directory: /home/mzanetti/Development/unity-scope-data/builddir/tests/qmltests
  View: QQuickView, import paths:
    '/home/mzanetti/Development/unity-scope-data/builddir/tests/mocks'
    '/home/mzanetti/Development/unity-scope-data/builddir/tests/utils/modules'
    '/usr/lib/x86_64-linux-gnu/qt5/bin'
    '/usr/lib/x86_64-linux-gnu/qt5/qml'
  Plugin paths:
    '.'

FAIL! : qmltestrunner::tst_AppPreview::compile() Type AppPreview unavailable
   Loc: [/home/mzanetti/Development/unity-scope-data/tests/qmlt...

Read more...

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
Michał Sawicz (saviq) wrote : Posted in a previous version of this proposal

download_tracker.h:13: Warning: Property declaration dbusPath has no READ accessor function. The property will be invalid.

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
Michał Sawicz (saviq) wrote : Posted in a previous version of this proposal

plugins/Ubuntu/DownloadDaemonListener/backend.h UNKNOWN *No copyright*
plugins/Ubuntu/DownloadDaemonListener/download_tracker.h UNKNOWN *No copyright*
plugins/Ubuntu/DownloadDaemonListener/download_tracker.cpp UNKNOWN *No copyright*
plugins/Ubuntu/DownloadDaemonListener/backend.cpp UNKNOWN *No copyright*

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
Michał Sawicz (saviq) wrote : Posted in a previous version of this proposal

  /tmp/buildd/unity8-7.81.3+13.10.20130726ubuntu.unity.next/tests/qmltests/Dash/Apps/tst_AppPreview.qml produced 2 error(s):
    /tmp/buildd/unity8-7.81.3+13.10.20130726ubuntu.unity.next/tests/qmltests/Dash/Apps/tst_AppPreview.qml:90,5: Type AppPreview unavailable
    /tmp/buildd/unity8-7.81.3+13.10.20130726ubuntu.unity.next/Dash/Apps/AppPreview.qml:20,1: module "Ubuntu.DownloadDaemonListener" is not installed

You need to mock a minimal DownloadDaemonListener (and we need to find a better name for it...) to be used in the isolated tests.

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
Michał Sawicz (saviq) wrote : Posted in a previous version of this proposal

There's some issue with the AppInfo and AppReviews tests:

'/tmp/buildd/unity8-7.81.3+13.10.20130806/tests/qmltests/Dash/Apps/tst_AppInfo.qml' does not exist under '/tmp/buildd/unity8-7.81.3+13.10.20130806/obj-x86_64-linux-gnu/tests/qmltests'.

'/tmp/buildd/unity8-7.81.3+13.10.20130806/tests/qmltests/Dash/Apps/tst_AppReviews.qml' does not exist under '/tmp/buildd/unity8-7.81.3+13.10.20130806/obj-x86_64-linux-gnu/tests/qmltests'.

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
159. By Michał Sawicz

Make the grid of buttons non-interactive.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Albert Astals Cid (aacid) wrote :

i think isServiceReady() should be const

setDbusPath(QString& path) -> setDbusPath(const QString& path)
setService(QString& service) -> setService(const QString& service)

Why the comparison against "" in setDbusPath and setService?

Who deletes m_adaptor in DownloadTracker?

serviceReady as a property doesn't seem much useful without a notify signal

downloadtrackeradaptor.* seems to be autogenerated code, can we just run qdbusxml2cpp on build time?

QVariantMap Preview::infoHintsHash() should probably be const too

In the download_tracker.cpp mock:
 * if(path != ""){ should probably be if(!path.isEmpty != ""){
 * the use of this-> seems a bit weird

review: Needs Fixing
160. By Michał Sawicz

Fix MockDownloadTracker.

161. By Michał Sawicz

Make some members/arguments const and add serviceReadyChanged signal.

162. By Michał Sawicz

Allow setting empty path and service.

Revision history for this message
Michał Sawicz (saviq) wrote :

Hmm from [1]:

"The qdbusxml2cpp tool is not meant to be run every time you compile your application. Instead, it's meant to be used when developing the code or when the interface changes.".

All the other points were addressed.

[1] http://qt-project.org/doc/qt-5.0/qtdbus/qdbusxml2cpp.html

163. By Michał Sawicz

Make infoHintsHash const.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Albert Astals Cid (aacid) wrote :

The use of i18n.tr in the test code feels a bit weird (tst_AppPreview.qml:115)

As far as i can see we are not loading any catalog in the tests at all, so can't we just write
compare(rated.text, "8 reviews", "Reviews don't match");
there?

review: Needs Fixing
Revision history for this message
Albert Astals Cid (aacid) wrote :

Some CMakeLists.txt nitpicking

Remove the unneeded set(CMAKE_AUTOMOC ON) two times

And remove once include(FindPkgConfig) and the find_package

We already set/require those at a higher level

review: Needs Fixing
Revision history for this message
Albert Astals Cid (aacid) wrote :

A spinner after clicking on one of the apps would be great, here it takes around 2 seconds and i am left wondering i did click wrong or if it's just "slow".

review: Needs Fixing
Revision history for this message
Albert Astals Cid (aacid) wrote :

Besides the "FIXME" mentioned on the code and the other three small things (well the spinner may be a bit harder) it looks ok to me.

Revision history for this message
Albert Astals Cid (aacid) wrote :

I can click install 10 times if i want, that feels a bit weird, probably needs a spinner too to black/fade/block the screen/button

review: Needs Fixing
Revision history for this message
Albert Astals Cid (aacid) wrote :

m_adaptor is not initialized, so doing

if(m_adaptor != nullptr) {

won't work

review: Needs Fixing
Revision history for this message
Albert Astals Cid (aacid) wrote :

Q_EMIT serviceReadyChanged(m_adaptor->isValid());
should be probably changed to something like
Q_EMIT serviceReadyChanged(m_adaptor && m_adaptor->isValid());
otherwise it'll crash if m_adaptor is null

review: Needs Fixing
164. By Michał Sawicz

Clean up CMakeLists.txt files.

165. By Michał Sawicz

Initialize m_adaptor and fix a potential crash.

166. By Michał Sawicz

Use initializer list to initialize m_active.

167. By Michał Sawicz

Don't use i18n in tests, we're not loading any catalogs anyway.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
168. By Michał Sawicz

The toolkit has a progress label now.

169. By Michał Sawicz

Merge trunk.

Revision history for this message
Albert Astals Cid (aacid) wrote :

Code looks good, there's two comments on the approval:
 * We are desperately missing some spinners for the previews, this will come later as a generic solution for all previews
 * Installing stuff still doesn't work, seems to be backend related. Holding off the top-approval until we find out what's going on

review: Approve (with comments)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Albert Astals Cid (aacid) wrote :

Ok, decision is to approve the UI, helps backend guys to try their backend in "real life" and gives them some pressure ;-)

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'Dash/Apps/AppInfo.qml'
2--- Dash/Apps/AppInfo.qml 1970-01-01 00:00:00 +0000
3+++ Dash/Apps/AppInfo.qml 2013-08-13 09:51:04 +0000
4@@ -0,0 +1,88 @@
5+/*
6+ * Copyright (C) 2013 Canonical, Ltd.
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+import QtQuick 2.0
22+import Ubuntu.Components 0.1
23+import "../../Components"
24+
25+Row {
26+ id: root
27+ property alias icon: image.source
28+ property alias appName: appNameLabel.text
29+ property alias rating: ratingStars.rating
30+ property int rated: 0
31+ property int reviews: 0
32+
33+ spacing: units.gu(2)
34+
35+ UbuntuShape {
36+ id: imageShape
37+ width: units.gu(6)
38+ height: units.gu(6)
39+ image: Image {
40+ id: image
41+ sourceSize { width: imageShape.width; height: imageShape.height }
42+ asynchronous: true
43+ fillMode: Image.PreserveAspectFit
44+ }
45+ }
46+
47+ Column {
48+ spacing: units.gu(1)
49+
50+ Label {
51+ id: appNameLabel
52+ fontSize: "large"
53+ color: "white"
54+ style: Text.Raised
55+ styleColor: "black"
56+ opacity: .9
57+ }
58+
59+ Row {
60+ spacing: units.gu(1)
61+
62+ RatingStars {
63+ id: ratingStars
64+ maximumRating: 10
65+ }
66+
67+ Label {
68+ id: ratedLabel
69+ objectName: "ratedLabel"
70+ fontSize: "medium"
71+ color: "white"
72+ style: Text.Raised
73+ styleColor: "black"
74+ opacity: .6
75+ //TRANSLATORS: Number of persons who rated this app
76+ text: i18n.tr("(%1)").arg(root.rated)
77+ }
78+
79+ Label {
80+ id: reviewsLabel
81+ objectName: "reviewsLabel"
82+ fontSize: "medium"
83+ color: "white"
84+ style: Text.Raised
85+ styleColor: "black"
86+ opacity: .6
87+ //TRANSLATORS: Number of persons who wrote reviews for this app
88+ text: i18n.tr("%1 review", "%1 reviews", root.reviews).arg(root.reviews)
89+ }
90+ }
91+ }
92+}
93
94=== added file 'Dash/Apps/AppPreview.qml'
95--- Dash/Apps/AppPreview.qml 1970-01-01 00:00:00 +0000
96+++ Dash/Apps/AppPreview.qml 2013-08-13 09:51:04 +0000
97@@ -0,0 +1,195 @@
98+/*
99+ * Copyright (C) 2013 Canonical, Ltd.
100+ *
101+ * This program is free software; you can redistribute it and/or modify
102+ * it under the terms of the GNU General Public License as published by
103+ * the Free Software Foundation; version 3.
104+ *
105+ * This program is distributed in the hope that it will be useful,
106+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
107+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
108+ * GNU General Public License for more details.
109+ *
110+ * You should have received a copy of the GNU General Public License
111+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
112+ */
113+
114+import QtQuick 2.0
115+import Ubuntu.Components 0.1
116+import Ubuntu.Components.ListItems 0.1 as ListItem
117+import Ubuntu.DownloadDaemonListener 0.1
118+import ".."
119+import "../../Components"
120+import "../../Components/IconUtil.js" as IconUtil
121+
122+DashPreview {
123+ id: root
124+
125+ signal sendUserReview(string review)
126+
127+ title: root.previewData.title
128+
129+ header: ListView {
130+ spacing: units.gu(1)
131+ orientation: ListView.Horizontal
132+ height: units.gu(22)
133+ anchors {
134+ left: parent.left
135+ right: parent.right
136+ margins: units.gu(1)
137+ }
138+ model: previewData.infoMap["more-screenshots"].value
139+
140+ delegate: UbuntuShape {
141+ id: shape
142+ anchors {
143+ top: parent.top
144+ bottom: parent.bottom
145+ }
146+ width: units.gu(12)
147+ radius: "medium"
148+ borderSource: ""
149+ image: Image {
150+ asynchronous: true
151+ sourceSize { width: shape.width; height: shape.height }
152+ source: modelData ? modelData : ""
153+ fillMode: Image.PreserveAspectCrop
154+ }
155+ }
156+ }
157+
158+ Component {
159+ id: buttonsComponent
160+
161+ GridView {
162+ id: buttonsGrid
163+ objectName: "gridButtons"
164+
165+ property int numOfRows: (count + 1) / 2
166+ property int spacing: units.gu(1)
167+ height: Math.max(units.gu(5), units.gu(5)*numOfRows + spacing*(numOfRows - 1))
168+
169+ interactive: false
170+ cellWidth: Math.max(units.gu(9), width / 2)
171+ cellHeight: buttonHeight + spacing
172+ property int buttonWidth: count > 1 ? Math.max(0, width / 2 - spacing) : width
173+ property int buttonHeight: units.gu(5)
174+
175+ delegate: Button {
176+ width: Math.max(units.gu(4), buttonsGrid.buttonWidth)
177+ height: buttonsGrid.buttonHeight
178+ color: Theme.palette.selected.foreground
179+ text: modelData.displayName
180+ iconSource: modelData.iconHint
181+ iconPosition: "right"
182+ onClicked: root.previewData.execute(modelData.id, { })
183+ }
184+ }
185+ }
186+
187+ Component {
188+ id: progressComponent
189+
190+ ProgressBar {
191+ id: progressBar
192+ objectName: "progressBar"
193+ value: 0
194+ maximumValue: 100
195+ height: units.gu(5)
196+
197+ property var model
198+
199+ DownloadTracker {
200+ service: "com.canonical.applications.Downloader"
201+ dbusPath: root.previewData.infoMap["progressbar_source"] ? root.previewData.infoMap["progressbar_source"].value : ""
202+
203+ onProgress: {
204+ var percentage = parseInt(received * 100 / total);
205+ progressBar.value = percentage;
206+ }
207+
208+ onFinished: {
209+ root.previewData.execute(progressBar.model[0].id, { })
210+ }
211+ }
212+
213+ }
214+ }
215+
216+ buttons: Loader {
217+ anchors {
218+ left: parent.left
219+ right: parent.right
220+ }
221+
222+ sourceComponent: root.previewData.infoMap["show_progressbar"] ? progressComponent : buttonsComponent
223+
224+ onLoaded: {
225+ item.model = root.previewData.actions;
226+ }
227+ }
228+
229+ body: Column {
230+ spacing: units.gu(1)
231+
232+ AppInfo {
233+ objectName: "appInfo"
234+ anchors { left: parent.left; right: parent.right }
235+
236+ appName: root.previewData.title
237+ icon: IconUtil.from_gicon(root.previewData.appIcon)
238+ rating: root.previewData.infoMap["rating"] ? root.previewData.infoMap["rating"].value : 0
239+ rated: root.previewData.infoMap["rated"] ? root.previewData.infoMap["rated"].value : 0
240+ reviews: root.previewData.infoMap["reviews"] ? root.previewData.infoMap["reviews"].value : 0
241+ }
242+
243+ Label {
244+ anchors { left: parent.left; right: parent.right }
245+ text: root.previewData.description
246+ fontSize: "medium"
247+ color: Theme.palette.selected.backgroundText
248+ opacity: .6
249+ wrapMode: Text.WordWrap
250+ style: Text.Raised
251+ styleColor: "black"
252+ }
253+
254+ ListItem.ThinDivider {}
255+
256+ Item {
257+ anchors { left: parent.left; right: parent.right }
258+ height: rateLabel.height
259+
260+ Label {
261+ id: rateLabel
262+ fontSize: "medium"
263+ color: "white"
264+ style: Text.Raised
265+ styleColor: "black"
266+ opacity: .9
267+ text: i18n.tr("Rate this")
268+
269+ anchors.left: parent.left
270+ anchors.verticalCenter: parent.verticalCenter
271+ }
272+
273+ // FIXME these need to be made interactive and connected to the scope
274+ RatingStars {
275+ anchors.right: parent.right
276+ anchors.verticalCenter: parent.verticalCenter
277+ }
278+ }
279+
280+ ListItem.ThinDivider {}
281+
282+ AppReviews {
283+ objectName: "appReviews"
284+ anchors { left: parent.left; right: parent.right }
285+
286+ model: root.previewData.infoMap["comments"] ? root.previewData.infoMap["comments"].value : undefined
287+
288+ onSendReview: root.sendUserReview(review);
289+ }
290+
291+ }
292+}
293
294=== added file 'Dash/Apps/AppReviews.qml'
295--- Dash/Apps/AppReviews.qml 1970-01-01 00:00:00 +0000
296+++ Dash/Apps/AppReviews.qml 2013-08-13 09:51:04 +0000
297@@ -0,0 +1,191 @@
298+/*
299+ * Copyright (C) 2013 Canonical, Ltd.
300+ *
301+ * This program is free software; you can redistribute it and/or modify
302+ * it under the terms of the GNU General Public License as published by
303+ * the Free Software Foundation; version 3.
304+ *
305+ * This program is distributed in the hope that it will be useful,
306+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
307+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
308+ * GNU General Public License for more details.
309+ *
310+ * You should have received a copy of the GNU General Public License
311+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
312+ */
313+
314+import QtQuick 2.0
315+import Ubuntu.Components 0.1
316+import Ubuntu.Components.ListItems 0.1 as ListItem
317+import "../../Components"
318+
319+Column {
320+ id: root
321+
322+ property var model
323+
324+ signal sendReview(string review)
325+
326+ spacing: units.gu(2)
327+ state: ""
328+
329+ states: [
330+ State {
331+ name: ""
332+ PropertyChanges { target: reviewField; width: root.width }
333+ PropertyChanges { target: sendButton; opacity: 0 }
334+ PropertyChanges { target: inverseArea; enabled: false }
335+ },
336+ State {
337+ name: "editing"
338+ PropertyChanges { target: reviewField; width: (root.width - row.spacing - sendButton.width) }
339+ PropertyChanges { target: sendButton; opacity: 1 }
340+ PropertyChanges { target: inverseArea; enabled: true }
341+ }
342+ ]
343+
344+ transitions: [
345+ Transition {
346+ from: ""
347+ to: "editing"
348+ SequentialAnimation {
349+ UbuntuNumberAnimation { target: reviewField; properties: "width"; duration: UbuntuAnimation.SlowDuration }
350+ UbuntuNumberAnimation { target: sendButton; properties: "opacity"; duration: UbuntuAnimation.SlowDuration }
351+ }
352+ },
353+ Transition {
354+ from: "editing"
355+ to: ""
356+ SequentialAnimation {
357+ UbuntuNumberAnimation { target: sendButton; properties: "opacity"; duration: UbuntuAnimation.SlowDuration }
358+ UbuntuNumberAnimation { target: reviewField; properties: "width"; duration: UbuntuAnimation.SlowDuration }
359+ }
360+ }
361+ ]
362+
363+ Label {
364+ fontSize: "medium"
365+ color: "white"
366+ style: Text.Raised
367+ styleColor: "black"
368+ opacity: .9
369+ text: i18n.tr("Add a review")
370+ }
371+
372+ Row {
373+ id: row
374+ spacing: units.gu(1)
375+ width: root.width
376+
377+ // FIXME: needs to react to Qt.inputMethod geometry
378+ TextArea {
379+ id: reviewField
380+ objectName: "reviewField"
381+ placeholderText: i18n.tr("Review")
382+ width: parent.width
383+ verticalAlignment: Text.AlignVCenter
384+ autoSize: true
385+ maximumLineCount: 5
386+
387+ Behavior on height { UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration } }
388+
389+ onFocusChanged: {
390+ if(reviewField.focus){
391+ root.state = "editing";
392+ reviewField.selectAll();
393+ }
394+ }
395+
396+ // FIXME: not active when in wide mode
397+ InverseMouseArea {
398+ id: inverseArea
399+ anchors.fill: parent
400+ enabled: false
401+ onPressed: {
402+ reviewField.focus = false;
403+ root.state = "";
404+ }
405+ }
406+ }
407+
408+ Button {
409+ id: sendButton
410+ objectName: "sendButton"
411+ width: units.gu(10)
412+ height: units.gu(4)
413+ anchors.bottom: reviewField.bottom
414+ color: Theme.palette.selected.foreground
415+ text: i18n.tr("Send")
416+ opacity: 0
417+
418+ onClicked: {
419+ root.sendReview(reviewField.text);
420+ reviewField.text = ""
421+ }
422+ }
423+ }
424+
425+ ListItem.ThinDivider {}
426+
427+ Label {
428+ fontSize: "medium"
429+ color: "white"
430+ style: Text.Raised
431+ styleColor: "black"
432+ opacity: .9
433+ text: i18n.tr("Comments:")
434+ }
435+
436+ Repeater {
437+ objectName: "commentsArea"
438+ model: root.model
439+
440+ Column {
441+ anchors { left: parent.left; right: parent.right }
442+
443+ Column {
444+ anchors { left: parent.left; right: parent.right }
445+
446+ Label {
447+ anchors { left: parent.left; right: parent.right }
448+ text: modelData[0]
449+ fontSize: "medium"
450+ color: "white"
451+ opacity: .8
452+ wrapMode: Text.WordWrap
453+ style: Text.Raised
454+ styleColor: "black"
455+ }
456+
457+ Row {
458+ spacing: units.gu(1)
459+
460+ RatingStars {
461+ maximumRating: 10
462+ rating: modelData[1]
463+ }
464+
465+ Label {
466+ text: modelData[2]
467+ fontSize: "medium"
468+ color: Theme.palette.selected.backgroundText
469+ opacity: .6
470+ style: Text.Raised
471+ styleColor: "black"
472+ }
473+ }
474+ }
475+
476+ Label {
477+ anchors { left: parent.left; right: parent.right }
478+ text: modelData[3]
479+ fontSize: "medium"
480+ color: Theme.palette.selected.backgroundText
481+ opacity: .6
482+ wrapMode: Text.WordWrap
483+ style: Text.Raised
484+ styleColor: "black"
485+ }
486+ }
487+ }
488+}
489
490=== modified file 'Dash/DashApps.qml'
491--- Dash/DashApps.qml 2013-08-02 16:16:31 +0000
492+++ Dash/DashApps.qml 2013-08-13 09:51:04 +0000
493@@ -170,4 +170,95 @@
494 searchHistory: scopeView.searchHistory
495 }
496 }
497+
498+ OpenEffect {
499+ id: effect
500+ anchors {
501+ fill: parent
502+ bottomMargin: -bottomOverflow
503+ }
504+ sourceItem: categoryView
505+
506+ enabled: gap > 0.0
507+
508+ topGapPx: (1 - gap) * positionPx
509+ topOpacity: (1 - gap * 1.2)
510+ bottomGapPx: positionPx + gap * (targetBottomGapPx - positionPx)
511+ bottomOverflow: units.gu(20)
512+ bottomOpacity: 1 - (gap * 0.8)
513+
514+ property int targetBottomGapPx: height - units.gu(8) - bottomOverflow
515+ property real gap: previewLoader.open ? 1.0 : 0.0
516+
517+ Behavior on gap {
518+ NumberAnimation {
519+ duration: 200
520+ easing.type: Easing.InOutQuad
521+ onRunningChanged: {
522+ if (!previewLoader.open && !running) {
523+ previewLoader.onScreen = false
524+ }
525+ }
526+ }
527+ }
528+ }
529+
530+ Connections {
531+ target: scopeView.scope
532+ onPreviewReady: {
533+ previewLoader.previewData = preview
534+ previewLoader.open = true
535+ }
536+ }
537+
538+ Connections {
539+ ignoreUnknownSignals: true
540+ target: previewLoader.valid ? previewLoader.item : null
541+ onClose: {
542+ previewLoader.open = false
543+ }
544+ }
545+
546+ PreviewDelegateMapper {
547+ id: previewDelegateMapper
548+ }
549+
550+ Loader {
551+ id: previewLoader
552+ property var previewData
553+ height: effect.bottomGapPx - effect.topGapPx
554+ anchors {
555+ top: parent.top
556+ topMargin: effect.topGapPx
557+ left: parent.left
558+ right: parent.right
559+ }
560+ source: onScreen ? previewDelegateMapper.map("preview-application") : ""
561+
562+ property bool open: false
563+ property bool onScreen: false
564+ property bool valid: item !== null
565+
566+ onOpenChanged: {
567+ if (open) {
568+ onScreen = true
569+ }
570+ }
571+
572+ onLoaded: {
573+ item.previewData = previewLoader.previewData
574+ }
575+ }
576+
577+ // TODO: Move as InverseMouseArea to DashPreview
578+ MouseArea {
579+ enabled: previewLoader.onScreen
580+ anchors {
581+ fill: parent
582+ topMargin: effect.bottomGapPx
583+ }
584+ onClicked: {
585+ previewLoader.open = false;
586+ }
587+ }
588 }
589
590=== added file 'Dash/DashPreview.qml'
591--- Dash/DashPreview.qml 1970-01-01 00:00:00 +0000
592+++ Dash/DashPreview.qml 2013-08-13 09:51:04 +0000
593@@ -0,0 +1,188 @@
594+/*
595+ * Copyright (C) 2013 Canonical, Ltd.
596+ *
597+ * This program is free software; you can redistribute it and/or modify
598+ * it under the terms of the GNU General Public License as published by
599+ * the Free Software Foundation; version 3.
600+ *
601+ * This program is distributed in the hope that it will be useful,
602+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
603+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
604+ * GNU General Public License for more details.
605+ *
606+ * You should have received a copy of the GNU General Public License
607+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
608+ */
609+
610+import QtQuick 2.0
611+import Ubuntu.Components 0.1
612+
613+Rectangle {
614+ id: root
615+
616+ property var previewData
617+
618+ property string title: ""
619+ property real previewWidthRatio: 0.5
620+
621+ property Component header
622+ property Component buttons
623+ property Component body
624+
625+ readonly property bool narrowMode: width <= height
626+ readonly property int contentSpacing: units.gu(3)
627+
628+ signal close()
629+ signal previewImageClicked()
630+
631+ color: Qt.rgba(0, 0, 0, .3)
632+ clip: true
633+
634+ Connections {
635+ target: shell.applicationManager
636+ onMainStageFocusedApplicationChanged: {
637+ root.close();
638+ }
639+ onSideStageFocusedApplicationChanged: {
640+ root.close();
641+ }
642+ }
643+
644+ MouseArea {
645+ anchors.fill: parent
646+ }
647+
648+ Item {
649+ id: headerRow
650+ height: units.gu(4)
651+ anchors {
652+ top: parent.top
653+ left: parent.left
654+ right: parent.right
655+ margins: root.contentSpacing
656+ }
657+
658+ MouseArea {
659+ anchors {
660+ fill: parent
661+ leftMargin: -root.contentSpacing
662+ rightMargin: -root.contentSpacing
663+ topMargin: -root.contentSpacing
664+ }
665+
666+ onClicked: root.close();
667+ }
668+
669+ Item {
670+ id: labelItem
671+ anchors {
672+ fill: parent
673+ rightMargin: closePreviewImage.width + spacing
674+ }
675+
676+ property int spacing: units.gu(2)
677+
678+ Label {
679+ id: title
680+ objectName: "titleLabel"
681+ anchors {
682+ left: parent.left
683+ right: parent.right
684+ }
685+
686+ elide: Text.ElideRight
687+ fontSize: "x-large"
688+ font.weight: Font.Light
689+ color: Theme.palette.selected.backgroundText
690+ opacity: 0.9
691+ text: root.title
692+ style: Text.Raised
693+ styleColor: "black"
694+ }
695+ Image {
696+ id: closePreviewImage
697+ source: "graphics/tablet/icon_close_preview.png"
698+ width: units.gu(4)
699+ height: units.gu(1.5)
700+ anchors {
701+ bottom: title.bottom
702+ bottomMargin: units.dp(7)
703+ left: parent.left
704+ leftMargin: title.paintedWidth + labelItem.spacing
705+ }
706+ }
707+ }
708+ }
709+
710+ Row {
711+ id: contentRow
712+ anchors {
713+ left: parent.left
714+ right: parent.right
715+ top: headerRow.bottom
716+ bottom: parent.bottom
717+ margins: root.contentSpacing
718+ }
719+
720+ spacing: units.gu(2)
721+
722+ Flickable {
723+ id: leftFlickable
724+ anchors.top: parent.top
725+ anchors.bottom: parent.bottom
726+ width: root.narrowMode ? contentRow.width : contentRow.width * root.previewWidthRatio
727+ contentHeight: leftColumn.height
728+ clip: true
729+
730+ Column {
731+ id: leftColumn
732+ objectName: "leftColumn"
733+ anchors {
734+ left: parent.left
735+ right: parent.right
736+ }
737+ height: childrenRect.height
738+ spacing: units.gu(1)
739+
740+ Loader {
741+ id: headerLoader
742+ anchors.left: parent.left
743+ anchors.right: parent.right
744+ sourceComponent: root.header
745+ }
746+ Loader {
747+ id: buttonLoader
748+ anchors.left: parent.left
749+ anchors.right: parent.right
750+ sourceComponent: root.buttons
751+ }
752+ }
753+ }
754+
755+ Flickable {
756+ id: rightFlickable
757+ anchors.top: parent.top
758+ anchors.bottom: parent.bottom
759+ width: narrowMode ? 0 : (contentRow.width - leftColumn.width - contentRow.spacing)
760+ contentHeight: rightColumn.height
761+ clip: true
762+
763+ Column {
764+ id: rightColumn
765+ objectName: "rightColumn"
766+ height: childrenRect.height
767+ anchors {
768+ left: parent.left
769+ right: parent.right
770+ }
771+ }
772+ }
773+ }
774+
775+ Loader {
776+ parent: root.narrowMode ? leftColumn : rightColumn
777+ anchors.left: parent.left
778+ anchors.right: parent.right
779+ sourceComponent: root.body
780+ }
781+}
782
783=== removed file 'Dash/DashPreview.qml'
784--- Dash/DashPreview.qml 2013-07-12 16:07:42 +0000
785+++ Dash/DashPreview.qml 1970-01-01 00:00:00 +0000
786@@ -1,218 +0,0 @@
787-/*
788- * Copyright (C) 2013 Canonical, Ltd.
789- *
790- * This program is free software; you can redistribute it and/or modify
791- * it under the terms of the GNU General Public License as published by
792- * the Free Software Foundation; version 3.
793- *
794- * This program is distributed in the hope that it will be useful,
795- * but WITHOUT ANY WARRANTY; without even the implied warranty of
796- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
797- * GNU General Public License for more details.
798- *
799- * You should have received a copy of the GNU General Public License
800- * along with this program. If not, see <http://www.gnu.org/licenses/>.
801- */
802-
803-import QtQuick 2.0
804-import Ubuntu.Components 0.1
805-
806-Rectangle {
807- id: root
808- property string title: ""
809- property url url: ""
810- property real previewWidthRatio: 0.5
811- property bool playable: false
812- property bool forceSquare: false
813- property Component buttons
814- property Component caption
815- property Component description
816-
817- readonly property bool narrowMode: width <= height
818- readonly property int contentSpacing: units.gu(3)
819-
820- signal close()
821- signal previewImageClicked()
822-
823- color: Qt.rgba(0, 0, 0, .3)
824- clip: true
825-
826- Connections {
827- target: shell.applicationManager
828- onMainStageFocusedApplicationChanged: {
829- root.close();
830- }
831- onSideStageFocusedApplicationChanged: {
832- root.close();
833- }
834- }
835-
836- MouseArea {
837- anchors.fill: parent
838- }
839-
840- Item {
841- id: headerRow
842- height: units.gu(4)
843- anchors {
844- top: parent.top
845- left: parent.left
846- right: parent.right
847- margins: root.contentSpacing
848- }
849-
850- MouseArea {
851- anchors {
852- fill: parent
853- leftMargin: -root.contentSpacing
854- rightMargin: -root.contentSpacing
855- topMargin: -root.contentSpacing
856- }
857-
858- onClicked: root.close();
859- }
860-
861- Item {
862- id: labelItem
863- anchors {
864- fill: parent
865- rightMargin: closePreviewImage.width + spacing
866- }
867-
868- property int spacing: units.gu(2)
869-
870- Label {
871- id: title
872- objectName: "titleLabel"
873- anchors {
874- left: parent.left
875- right: parent.right
876- }
877-
878- elide: Text.ElideRight
879- fontSize: "x-large"
880- font.weight: Font.Light
881- color: Theme.palette.selected.backgroundText
882- opacity: 0.9
883- text: root.title
884- style: Text.Raised
885- styleColor: "black"
886- }
887- Image {
888- id: closePreviewImage
889- source: "graphics/tablet/icon_close_preview.png"
890- width: units.gu(4)
891- height: units.gu(1.5)
892- anchors {
893- bottom: title.bottom
894- bottomMargin: units.dp(7)
895- left: parent.left
896- leftMargin: title.paintedWidth + labelItem.spacing
897- }
898- }
899- }
900- }
901-
902- Row {
903- id: contentRow
904- anchors {
905- left: parent.left
906- right: parent.right
907- top: headerRow.bottom
908- bottom: parent.bottom
909- margins: root.contentSpacing
910- }
911-
912- spacing: units.gu(2)
913-
914- Flickable {
915- id: leftFlickable
916- anchors.top: parent.top
917- anchors.bottom: parent.bottom
918- width: root.narrowMode ? contentRow.width : contentRow.width * root.previewWidthRatio
919- contentHeight: leftColumn.height
920- clip: true
921-
922- Column {
923- id: leftColumn
924- objectName: "leftColumn"
925- anchors {
926- left: parent.left
927- right: parent.right
928- }
929- height: childrenRect.height
930- spacing: root.contentSpacing
931-
932- // TODO: replace this UbuntuShape with the Video component once that lands
933- // with the player.
934- UbuntuShape {
935- id: urlLoader
936- anchors.left: parent.left
937- anchors.right: parent.right
938- height: root.forceSquare ? width : width * previewImage.sourceSize.height / previewImage.sourceSize.width
939- radius: "medium"
940- image: Image {
941- id: previewImage
942- asynchronous: true
943- source: root.url
944- fillMode: Image.PreserveAspectCrop
945- }
946-
947- Image {
948- objectName: "playButton"
949- anchors.centerIn: parent
950- visible: root.playable
951- readonly property bool bigButton: parent.width > units.gu(40)
952- width: bigButton ? units.gu(8) : units.gu(4.5)
953- height: width
954- source: "graphics/play_button%1%2.png".arg(previewImageMouseArea.pressed ? "_active" : "").arg(bigButton ? "_big" : "")
955- }
956-
957- MouseArea {
958- id: previewImageMouseArea
959- anchors.fill: parent
960- onClicked: root.previewImageClicked()
961- }
962- }
963- Loader {
964- id: buttonLoader
965- anchors.left: parent.left
966- anchors.right: parent.right
967- sourceComponent: root.buttons
968- }
969- Loader {
970- id: captionLoader
971- anchors.left: parent.left
972- anchors.right: parent.right
973- sourceComponent: root.caption
974- }
975- }
976- }
977-
978- Flickable {
979- id: rightFlickable
980- anchors.top: parent.top
981- anchors.bottom: parent.bottom
982- width: narrowMode ? 0 : (contentRow.width - leftColumn.width - contentRow.spacing)
983- contentHeight: rightColumn.height
984- clip: true
985-
986- Column {
987- id: rightColumn
988- objectName: "rightColumn"
989- height: childrenRect.height
990- anchors {
991- left: parent.left
992- right: parent.right
993- }
994- }
995- }
996- }
997-
998- Loader {
999- parent: root.narrowMode ? leftColumn : rightColumn
1000- anchors.left: parent.left
1001- anchors.right: parent.right
1002- sourceComponent: root.description
1003- }
1004-}
1005
1006=== modified file 'Dash/Generic/GenericPreview.qml'
1007--- Dash/Generic/GenericPreview.qml 2013-07-10 13:33:47 +0000
1008+++ Dash/Generic/GenericPreview.qml 2013-08-13 09:51:04 +0000
1009@@ -23,12 +23,26 @@
1010
1011 DashPreview {
1012 id: genericPreview
1013- property var previewData
1014
1015 title: previewData.title
1016- url: IconUtil.from_gicon(previewData.image)
1017 previewWidthRatio: 0.6
1018
1019+ property url url: IconUtil.from_gicon(previewData.image)
1020+
1021+ header: UbuntuShape {
1022+ id: urlLoader
1023+ anchors.left: parent.left
1024+ anchors.right: parent.right
1025+ height: width * previewImage.sourceSize.height / previewImage.sourceSize.width
1026+ radius: "medium"
1027+ image: Image {
1028+ id: previewImage
1029+ asynchronous: true
1030+ source: genericPreview.url
1031+ fillMode: Image.PreserveAspectCrop
1032+ }
1033+ }
1034+
1035 buttons: GridView {
1036 id: buttons
1037 model: genericPreview.previewData.actions
1038@@ -56,7 +70,7 @@
1039 }
1040 focus: false
1041 }
1042- description: Column {
1043+ body: Column {
1044 spacing: units.gu(2)
1045
1046 Label {
1047
1048=== modified file 'Dash/GenericScopeView.qml'
1049--- Dash/GenericScopeView.qml 2013-07-25 16:05:52 +0000
1050+++ Dash/GenericScopeView.qml 2013-08-13 09:51:04 +0000
1051@@ -211,7 +211,7 @@
1052 }
1053
1054 onLoaded: {
1055- item.previewData = previewLoader.previewData
1056+ item.previewData = Qt.binding(function() { return previewLoader.previewData })
1057 }
1058 }
1059
1060
1061=== modified file 'Dash/PreviewDelegateMapper.qml'
1062--- Dash/PreviewDelegateMapper.qml 2013-07-10 12:58:58 +0000
1063+++ Dash/PreviewDelegateMapper.qml 2013-08-13 09:51:04 +0000
1064@@ -19,7 +19,9 @@
1065 QtObject {
1066 property var d: QtObject {
1067 readonly property string genericPreview: "Generic/GenericPreview.qml"
1068+ readonly property string appPreview: "Apps/AppPreview.qml"
1069 property var previewDelegateMapping: {"preview-generic": genericPreview,
1070+ "preview-application": appPreview,
1071 }
1072 }
1073
1074
1075=== modified file 'Dash/Video/VideoPreview.qml'
1076--- Dash/Video/VideoPreview.qml 2013-07-12 16:07:42 +0000
1077+++ Dash/Video/VideoPreview.qml 2013-08-13 09:51:04 +0000
1078@@ -24,7 +24,9 @@
1079
1080 property var item
1081 property alias ready: nfo.ready
1082+ property bool playable: fileUri != ""
1083 readonly property url fileUri: item ? item.fileUri : ""
1084+ property url url: item ? item.nfoUri.replace(/\.nfo$/, "-fanart.jpg") : ""
1085
1086 VideoInfo {
1087 id: nfo
1088@@ -32,9 +34,7 @@
1089 }
1090
1091 title: nfo.ready ? nfo.video.title : ""
1092- url: item ? item.nfoUri.replace(/\.nfo$/, "-fanart.jpg") : ""
1093 previewWidthRatio: 0.6
1094- playable: fileUri != ""
1095
1096 onPreviewImageClicked: {
1097 if (playable) {
1098@@ -42,6 +42,38 @@
1099 }
1100 }
1101
1102+ // TODO: replace this UbuntuShape with the Video component once that lands
1103+ // with the player.
1104+ header: UbuntuShape {
1105+ id: urlLoader
1106+ anchors.left: parent.left
1107+ anchors.right: parent.right
1108+ height: width * previewImage.sourceSize.height / previewImage.sourceSize.width
1109+ radius: "medium"
1110+ image: Image {
1111+ id: previewImage
1112+ asynchronous: true
1113+ source: root.url
1114+ fillMode: Image.PreserveAspectCrop
1115+ }
1116+
1117+ Image {
1118+ objectName: "playButton"
1119+ anchors.centerIn: parent
1120+ visible: root.playable
1121+ readonly property bool bigButton: parent.width > units.gu(40)
1122+ width: bigButton ? units.gu(8) : units.gu(4.5)
1123+ height: width
1124+ source: "../graphics/play_button%1%2.png".arg(previewImageMouseArea.pressed ? "_active" : "").arg(bigButton ? "_big" : "")
1125+ }
1126+
1127+ MouseArea {
1128+ id: previewImageMouseArea
1129+ anchors.fill: parent
1130+ onClicked: root.previewImageClicked()
1131+ }
1132+ }
1133+
1134 buttons: Row {
1135 spacing: units.gu(2)
1136
1137@@ -64,7 +96,7 @@
1138 }
1139 }
1140
1141- description: Column {
1142+ body: Column {
1143 spacing: units.gu(2)
1144 RatingStars {
1145 maximumRating: 10 // FIXME: this should happen on the backend side
1146
1147=== modified file 'plugins/Ubuntu/CMakeLists.txt'
1148--- plugins/Ubuntu/CMakeLists.txt 2013-06-05 22:03:08 +0000
1149+++ plugins/Ubuntu/CMakeLists.txt 2013-08-13 09:51:04 +0000
1150@@ -1,1 +1,2 @@
1151 add_subdirectory(Gestures)
1152+add_subdirectory(DownloadDaemonListener)
1153
1154=== added directory 'plugins/Ubuntu/DownloadDaemonListener'
1155=== added file 'plugins/Ubuntu/DownloadDaemonListener/CMakeLists.txt'
1156--- plugins/Ubuntu/DownloadDaemonListener/CMakeLists.txt 1970-01-01 00:00:00 +0000
1157+++ plugins/Ubuntu/DownloadDaemonListener/CMakeLists.txt 2013-08-13 09:51:04 +0000
1158@@ -0,0 +1,22 @@
1159+# export_qmlplugin macro
1160+include(Plugins)
1161+
1162+include_directories(
1163+ ${CMAKE_CURRENT_SOURCE_DIR}
1164+ ${CMAKE_CURRENT_BINARY_DIR}
1165+ ${Qt5Gui_PRIVATE_INCLUDE_DIRS}
1166+)
1167+
1168+set(DOWNLOADDAEMONLISTENER_SOURCES
1169+ plugin.cpp
1170+ DownloadTracker.cpp
1171+ interface/downloadtrackeradaptor.cpp
1172+ )
1173+
1174+add_library(DownloadDaemonListener MODULE ${DOWNLOADDAEMONLISTENER_SOURCES})
1175+
1176+qt5_use_modules(DownloadDaemonListener Qml Quick DBus Core)
1177+
1178+# export the qmldir qmltypes and plugin files
1179+export_qmlfiles(Ubuntu.DownloadDaemonListener Ubuntu/DownloadDaemonListener)
1180+export_qmlplugin(Ubuntu.DownloadDaemonListener 0.1 Ubuntu/DownloadDaemonListener TARGETS DownloadDaemonListener)
1181
1182=== added file 'plugins/Ubuntu/DownloadDaemonListener/DownloadTracker.cpp'
1183--- plugins/Ubuntu/DownloadDaemonListener/DownloadTracker.cpp 1970-01-01 00:00:00 +0000
1184+++ plugins/Ubuntu/DownloadDaemonListener/DownloadTracker.cpp 2013-08-13 09:51:04 +0000
1185@@ -0,0 +1,84 @@
1186+/*
1187+ * Copyright (C) 2013 - Canonical Ltd.
1188+ *
1189+ * This program is free software: you can redistribute it and/or modify it
1190+ * under the terms of the GNU Lesser General Public License, as
1191+ * published by the Free Software Foundation; either version 2.1 or 3.0
1192+ * of the License.
1193+ *
1194+ * This program is distributed in the hope that it will be useful, but
1195+ * WITHOUT ANY WARRANTY; without even the implied warranties of
1196+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
1197+ * PURPOSE. See the applicable version of the GNU Lesser General Public
1198+ * License for more details.
1199+ *
1200+ * You should have received a copy of both the GNU Lesser General Public
1201+ * License along with this program. If not, see <http://www.gnu.org/licenses/>
1202+ *
1203+ * Authored by: Diego Sarmentero <diego.sarmentero@canonical.com>
1204+ */
1205+
1206+
1207+#include "DownloadTracker.h"
1208+
1209+DownloadTracker::DownloadTracker(QObject *parent)
1210+ : QObject(parent)
1211+ , m_adaptor(nullptr)
1212+{
1213+}
1214+
1215+bool DownloadTracker::isServiceReady() const
1216+{
1217+ bool ready = false;
1218+ if(m_adaptor != nullptr) {
1219+ ready = m_adaptor->isValid();
1220+ }
1221+
1222+ return ready;
1223+}
1224+
1225+QString DownloadTracker::dbusPath() const
1226+{
1227+ return m_dbusPath;
1228+}
1229+
1230+void DownloadTracker::setDbusPath(const QString& path)
1231+{
1232+ if(m_dbusPath != path){
1233+ m_dbusPath = path;
1234+ startService();
1235+ Q_EMIT dbusPathChanged(m_dbusPath);
1236+ }
1237+}
1238+
1239+QString DownloadTracker::service() const
1240+{
1241+ return m_service;
1242+}
1243+
1244+void DownloadTracker::setService(const QString& service)
1245+{
1246+ if(m_service != service){
1247+ m_service = service;
1248+ startService();
1249+ Q_EMIT serviceChanged(m_service);
1250+ }
1251+}
1252+
1253+void DownloadTracker::startService()
1254+{
1255+ // FIXME update dbus path and service on changes
1256+ if(!m_service.isEmpty() && !m_dbusPath.isEmpty()) {
1257+ m_adaptor = new DownloadTrackerAdaptor(m_service, m_dbusPath, QDBusConnection::sessionBus(), this);
1258+
1259+ connect(m_adaptor, SIGNAL(canceled(bool)), this, SIGNAL(canceled(bool)));
1260+ connect(m_adaptor, SIGNAL(error(const QString &)), this, SIGNAL(error(const QString &)));
1261+ connect(m_adaptor, SIGNAL(finished(const QString &)), this, SIGNAL(finished(const QString &)));
1262+ connect(m_adaptor, SIGNAL(paused(bool)), this, SIGNAL(paused(bool)));
1263+ connect(m_adaptor, SIGNAL(progress(qulonglong, qulonglong)), this, SIGNAL(progress(qulonglong, qulonglong)));
1264+ connect(m_adaptor, SIGNAL(resumed(bool)), this, SIGNAL(resumed(bool)));
1265+ connect(m_adaptor, SIGNAL(started(bool)), this, SIGNAL(started(bool)));
1266+ }
1267+ // FIXME find a better way of determining if the service is ready
1268+ Q_EMIT serviceReadyChanged(m_adaptor && m_adaptor->isValid());
1269+}
1270
1271=== added file 'plugins/Ubuntu/DownloadDaemonListener/DownloadTracker.h'
1272--- plugins/Ubuntu/DownloadDaemonListener/DownloadTracker.h 1970-01-01 00:00:00 +0000
1273+++ plugins/Ubuntu/DownloadDaemonListener/DownloadTracker.h 2013-08-13 09:51:04 +0000
1274@@ -0,0 +1,69 @@
1275+/*
1276+ * Copyright (C) 2013 - Canonical Ltd.
1277+ *
1278+ * This program is free software: you can redistribute it and/or modify it
1279+ * under the terms of the GNU Lesser General Public License, as
1280+ * published by the Free Software Foundation; either version 2.1 or 3.0
1281+ * of the License.
1282+ *
1283+ * This program is distributed in the hope that it will be useful, but
1284+ * WITHOUT ANY WARRANTY; without even the implied warranties of
1285+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
1286+ * PURPOSE. See the applicable version of the GNU Lesser General Public
1287+ * License for more details.
1288+ *
1289+ * You should have received a copy of both the GNU Lesser General Public
1290+ * License along with this program. If not, see <http://www.gnu.org/licenses/>
1291+ *
1292+ * Authored by: Diego Sarmentero <diego.sarmentero@canonical.com>
1293+ */
1294+
1295+
1296+#ifndef DOWNLOADTRACKER_H
1297+#define DOWNLOADTRACKER_H
1298+
1299+#include <interface/downloadtrackeradaptor.h>
1300+
1301+#include <QObject>
1302+#include <QDBusObjectPath>
1303+
1304+class DownloadTracker : public QObject
1305+{
1306+ Q_OBJECT
1307+ Q_DISABLE_COPY(DownloadTracker)
1308+ Q_PROPERTY(QString service READ service WRITE setService NOTIFY serviceChanged)
1309+ Q_PROPERTY(QString dbusPath READ dbusPath WRITE setDbusPath NOTIFY dbusPathChanged)
1310+ Q_PROPERTY(bool serviceReady READ isServiceReady NOTIFY serviceReadyChanged)
1311+
1312+public:
1313+ explicit DownloadTracker(QObject *parent = 0);
1314+
1315+ QString service() const;
1316+ QString dbusPath() const;
1317+ bool isServiceReady() const;
1318+
1319+ void setDbusPath(const QString& path);
1320+ void setService(const QString& service);
1321+
1322+Q_SIGNALS:
1323+ void serviceChanged(const QString &service);
1324+ void dbusPathChanged(const QString &dbusPath);
1325+ void serviceReadyChanged(const bool &serviceReady);
1326+
1327+ void canceled(bool success);
1328+ void error(const QString &error);
1329+ void finished(const QString &path);
1330+ void paused(bool success);
1331+ void progress(qulonglong received, qulonglong total);
1332+ void resumed(bool success);
1333+ void started(bool success);
1334+
1335+private:
1336+ QString m_dbusPath;
1337+ QString m_service;
1338+ DownloadTrackerAdaptor* m_adaptor;
1339+
1340+ void startService();
1341+};
1342+
1343+#endif // DOWNLOADTRACKER_H
1344
1345=== added directory 'plugins/Ubuntu/DownloadDaemonListener/interface'
1346=== added file 'plugins/Ubuntu/DownloadDaemonListener/interface/downloadtrackeradaptor.cpp'
1347--- plugins/Ubuntu/DownloadDaemonListener/interface/downloadtrackeradaptor.cpp 1970-01-01 00:00:00 +0000
1348+++ plugins/Ubuntu/DownloadDaemonListener/interface/downloadtrackeradaptor.cpp 2013-08-13 09:51:04 +0000
1349@@ -0,0 +1,25 @@
1350+/*
1351+ * This file was generated by qdbusxml2cpp version 0.8
1352+ * Command line was: qdbusxml2cpp -v -c DownloadTrackerAdaptor -p downloadtrackeradaptor.h:downloadtrackeradaptor.cpp -i metatypes.h com.canonical.applications.download.xml
1353+ *
1354+ * qdbusxml2cpp is Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
1355+ *
1356+ * This is an auto-generated file.
1357+ * This file may have been hand-edited. Look for HAND-EDIT comments
1358+ * before re-generating it.
1359+ */
1360+
1361+#include "downloadtrackeradaptor.h"
1362+
1363+/*
1364+ * Implementation of interface class DownloadTrackerAdaptor
1365+ */
1366+
1367+DownloadTrackerAdaptor::DownloadTrackerAdaptor(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)
1368+ : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent)
1369+{
1370+}
1371+
1372+DownloadTrackerAdaptor::~DownloadTrackerAdaptor()
1373+{
1374+}
1375
1376=== added file 'plugins/Ubuntu/DownloadDaemonListener/interface/downloadtrackeradaptor.h'
1377--- plugins/Ubuntu/DownloadDaemonListener/interface/downloadtrackeradaptor.h 1970-01-01 00:00:00 +0000
1378+++ plugins/Ubuntu/DownloadDaemonListener/interface/downloadtrackeradaptor.h 2013-08-13 09:51:04 +0000
1379@@ -0,0 +1,125 @@
1380+/*
1381+ * This file was generated by qdbusxml2cpp version 0.8
1382+ * Command line was: qdbusxml2cpp -v -c DownloadTrackerAdaptor -p downloadtrackeradaptor.h:downloadtrackeradaptor.cpp -i metatypes.h com.canonical.applications.download.xml
1383+ *
1384+ * qdbusxml2cpp is Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
1385+ *
1386+ * This is an auto-generated file.
1387+ * Do not edit! All changes made to it will be lost.
1388+ */
1389+
1390+#ifndef DOWNLOADTRACKERADAPTOR_H_1374434371
1391+#define DOWNLOADTRACKERADAPTOR_H_1374434371
1392+
1393+#include <QtCore/QObject>
1394+#include <QtCore/QByteArray>
1395+#include <QtCore/QList>
1396+#include <QtCore/QMap>
1397+#include <QtCore/QString>
1398+#include <QtCore/QStringList>
1399+#include <QtCore/QVariant>
1400+#include <QtDBus/QtDBus>
1401+#include "metatypes.h"
1402+
1403+/*
1404+ * Proxy class for interface com.canonical.applications.Download
1405+ */
1406+class DownloadTrackerAdaptor: public QDBusAbstractInterface
1407+{
1408+ Q_OBJECT
1409+public:
1410+ static inline const char *staticInterfaceName()
1411+ { return "com.canonical.applications.Download"; }
1412+
1413+public:
1414+ DownloadTrackerAdaptor(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0);
1415+
1416+ ~DownloadTrackerAdaptor();
1417+
1418+public Q_SLOTS: // METHODS
1419+ inline QDBusPendingReply<> allowGSMDownload(bool allowed)
1420+ {
1421+ QList<QVariant> argumentList;
1422+ argumentList << QVariant::fromValue(allowed);
1423+ return asyncCallWithArgumentList(QLatin1String("allowGSMDownload"), argumentList);
1424+ }
1425+
1426+ inline QDBusPendingReply<> cancel()
1427+ {
1428+ QList<QVariant> argumentList;
1429+ return asyncCallWithArgumentList(QLatin1String("cancel"), argumentList);
1430+ }
1431+
1432+ inline QDBusPendingReply<bool> isGSMDownloadAllowed()
1433+ {
1434+ QList<QVariant> argumentList;
1435+ return asyncCallWithArgumentList(QLatin1String("isGSMDownloadAllowed"), argumentList);
1436+ }
1437+
1438+ inline QDBusPendingReply<QVariantMap> metadata()
1439+ {
1440+ QList<QVariant> argumentList;
1441+ return asyncCallWithArgumentList(QLatin1String("metadata"), argumentList);
1442+ }
1443+
1444+ inline QDBusPendingReply<> pause()
1445+ {
1446+ QList<QVariant> argumentList;
1447+ return asyncCallWithArgumentList(QLatin1String("pause"), argumentList);
1448+ }
1449+
1450+ inline QDBusPendingReply<qulonglong> progress()
1451+ {
1452+ QList<QVariant> argumentList;
1453+ return asyncCallWithArgumentList(QLatin1String("progress"), argumentList);
1454+ }
1455+
1456+ inline QDBusPendingReply<> resume()
1457+ {
1458+ QList<QVariant> argumentList;
1459+ return asyncCallWithArgumentList(QLatin1String("resume"), argumentList);
1460+ }
1461+
1462+ inline QDBusPendingReply<> setThrottle(qulonglong speed)
1463+ {
1464+ QList<QVariant> argumentList;
1465+ argumentList << QVariant::fromValue(speed);
1466+ return asyncCallWithArgumentList(QLatin1String("setThrottle"), argumentList);
1467+ }
1468+
1469+ inline QDBusPendingReply<> start()
1470+ {
1471+ QList<QVariant> argumentList;
1472+ return asyncCallWithArgumentList(QLatin1String("start"), argumentList);
1473+ }
1474+
1475+ inline QDBusPendingReply<qulonglong> throttle()
1476+ {
1477+ QList<QVariant> argumentList;
1478+ return asyncCallWithArgumentList(QLatin1String("throttle"), argumentList);
1479+ }
1480+
1481+ inline QDBusPendingReply<qulonglong> totalSize()
1482+ {
1483+ QList<QVariant> argumentList;
1484+ return asyncCallWithArgumentList(QLatin1String("totalSize"), argumentList);
1485+ }
1486+
1487+Q_SIGNALS: // SIGNALS
1488+ void canceled(bool success);
1489+ void error(const QString &error);
1490+ void finished(const QString &path);
1491+ void paused(bool success);
1492+ void progress(qulonglong received, qulonglong total);
1493+ void resumed(bool success);
1494+ void started(bool success);
1495+};
1496+
1497+namespace com {
1498+ namespace canonical {
1499+ namespace applications {
1500+ typedef ::DownloadTrackerAdaptor Download;
1501+ }
1502+ }
1503+}
1504+#endif
1505
1506=== added file 'plugins/Ubuntu/DownloadDaemonListener/interface/metatypes.h'
1507--- plugins/Ubuntu/DownloadDaemonListener/interface/metatypes.h 1970-01-01 00:00:00 +0000
1508+++ plugins/Ubuntu/DownloadDaemonListener/interface/metatypes.h 2013-08-13 09:51:04 +0000
1509@@ -0,0 +1,28 @@
1510+/*
1511+ * Copyright 2013 2013 Canonical Ltd.
1512+ *
1513+ * This library is free software; you can redistribute it and/or
1514+ * modify it under the terms of version 3 of the GNU Lesser General Public
1515+ * License as published by the Free Software Foundation.
1516+ *
1517+ * This program is distributed in the hope that it will be useful,
1518+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1519+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1520+ * General Public License for more details.
1521+ *
1522+ * You should have received a copy of the GNU Lesser General Public
1523+ * License along with this library; if not, write to the
1524+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
1525+ * Boston, MA 02110-1301, USA.
1526+ */
1527+
1528+#ifndef DOWNLOADER_LIB_APP_METATYPES_H
1529+#define DOWNLOADER_LIB_APP_METATYPES_H
1530+
1531+#include <QMap>
1532+
1533+typedef QMap<QString, QString> StringMap;
1534+
1535+Q_DECLARE_METATYPE(StringMap)
1536+
1537+#endif // METATYPES_H
1538
1539=== added file 'plugins/Ubuntu/DownloadDaemonListener/plugin.cpp'
1540--- plugins/Ubuntu/DownloadDaemonListener/plugin.cpp 1970-01-01 00:00:00 +0000
1541+++ plugins/Ubuntu/DownloadDaemonListener/plugin.cpp 2013-08-13 09:51:04 +0000
1542@@ -0,0 +1,39 @@
1543+/*
1544+ * Copyright (C) 2013 - Canonical Ltd.
1545+ *
1546+ * This program is free software: you can redistribute it and/or modify it
1547+ * under the terms of the GNU Lesser General Public License, as
1548+ * published by the Free Software Foundation; either version 2.1 or 3.0
1549+ * of the License.
1550+ *
1551+ * This program is distributed in the hope that it will be useful, but
1552+ * WITHOUT ANY WARRANTY; without even the implied warranties of
1553+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
1554+ * PURPOSE. See the applicable version of the GNU Lesser General Public
1555+ * License for more details.
1556+ *
1557+ * You should have received a copy of both the GNU Lesser General Public
1558+ * License along with this program. If not, see <http://www.gnu.org/licenses/>
1559+ *
1560+ * Authored by: Diego Sarmentero <diego.sarmentero@canonical.com>
1561+ */
1562+
1563+
1564+#include "plugin.h"
1565+#include "DownloadTracker.h"
1566+
1567+#include <QtQml>
1568+#include <QtQml/QQmlContext>
1569+
1570+
1571+void BackendPlugin::registerTypes(const char *uri)
1572+{
1573+ Q_ASSERT(uri == QLatin1String("Ubuntu.DownloadDaemonListener"));
1574+
1575+ qmlRegisterType<DownloadTracker>(uri, 0, 1, "DownloadTracker");
1576+}
1577+
1578+void BackendPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
1579+{
1580+ QQmlExtensionPlugin::initializeEngine(engine, uri);
1581+}
1582
1583=== added file 'plugins/Ubuntu/DownloadDaemonListener/plugin.h'
1584--- plugins/Ubuntu/DownloadDaemonListener/plugin.h 1970-01-01 00:00:00 +0000
1585+++ plugins/Ubuntu/DownloadDaemonListener/plugin.h 2013-08-13 09:51:04 +0000
1586@@ -0,0 +1,37 @@
1587+/*
1588+ * Copyright (C) 2013 - Canonical Ltd.
1589+ *
1590+ * This program is free software: you can redistribute it and/or modify it
1591+ * under the terms of the GNU Lesser General Public License, as
1592+ * published by the Free Software Foundation; either version 2.1 or 3.0
1593+ * of the License.
1594+ *
1595+ * This program is distributed in the hope that it will be useful, but
1596+ * WITHOUT ANY WARRANTY; without even the implied warranties of
1597+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
1598+ * PURPOSE. See the applicable version of the GNU Lesser General Public
1599+ * License for more details.
1600+ *
1601+ * You should have received a copy of both the GNU Lesser General Public
1602+ * License along with this program. If not, see <http://www.gnu.org/licenses/>
1603+ *
1604+ * Authored by: Diego Sarmentero <diego.sarmentero@canonical.com>
1605+ */
1606+
1607+
1608+#ifndef BACKEND_PLUGIN_H
1609+#define BACKEND_PLUGIN_H
1610+
1611+#include <QQmlEngine>
1612+#include <QQmlExtensionPlugin>
1613+
1614+class BackendPlugin : public QQmlExtensionPlugin
1615+{
1616+ Q_OBJECT
1617+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
1618+
1619+public:
1620+ void registerTypes(const char *uri);
1621+ void initializeEngine(QQmlEngine *engine, const char *uri);
1622+};
1623+#endif // BACKEND_PLUGIN_H
1624
1625=== added file 'plugins/Ubuntu/DownloadDaemonListener/qmldir'
1626--- plugins/Ubuntu/DownloadDaemonListener/qmldir 1970-01-01 00:00:00 +0000
1627+++ plugins/Ubuntu/DownloadDaemonListener/qmldir 2013-08-13 09:51:04 +0000
1628@@ -0,0 +1,3 @@
1629+module Ubuntu.DownloadDaemonListener
1630+plugin DownloadDaemonListener
1631+typeinfo plugins.qmltypes
1632
1633=== modified file 'plugins/Unity/preview.cpp'
1634--- plugins/Unity/preview.cpp 2013-07-04 14:53:21 +0000
1635+++ plugins/Unity/preview.cpp 2013-08-13 09:51:04 +0000
1636@@ -94,6 +94,11 @@
1637 return QVariant::fromValue(m_infoHints);
1638 }
1639
1640+QVariantMap Preview::infoHintsHash() const
1641+{
1642+ return m_infoHintsHash;
1643+}
1644+
1645 QString Preview::image() const
1646 {
1647 if (m_unityPreview) {
1648@@ -145,6 +150,7 @@
1649
1650 qDeleteAll(m_infoHints);
1651 m_infoHints.clear();
1652+ m_infoHintsHash.clear();
1653 qDeleteAll(m_actions);
1654 m_actions.clear();
1655
1656@@ -152,6 +158,7 @@
1657 auto hint = new PreviewInfoHint(this);
1658 hint->setUnityInfoHint(unityInfoHint);
1659 m_infoHints.append(hint);
1660+ m_infoHintsHash[hint->id()] = QVariant::fromValue(hint);
1661 }
1662
1663 for (auto unityAction: m_unityPreview->GetActions()) {
1664
1665=== modified file 'plugins/Unity/preview.h'
1666--- plugins/Unity/preview.h 2013-07-02 10:57:33 +0000
1667+++ plugins/Unity/preview.h 2013-08-13 09:51:04 +0000
1668@@ -25,6 +25,7 @@
1669 #include <QString>
1670 #include <QMetaType>
1671 #include <QList>
1672+#include <QVariantMap>
1673
1674 // libunity-core
1675 #include <UnityCore/Preview.h>
1676@@ -42,6 +43,7 @@
1677 Q_PROPERTY(QString description READ description NOTIFY previewChanged)
1678 Q_PROPERTY(QVariant actions READ actions NOTIFY previewChanged)
1679 Q_PROPERTY(QVariant infoHints READ infoHints NOTIFY previewChanged)
1680+ Q_PROPERTY(QVariantMap infoMap READ infoHintsHash NOTIFY previewChanged)
1681 Q_PROPERTY(QString image READ image NOTIFY previewChanged)
1682 Q_PROPERTY(QString imageSourceUri READ imageSourceUri NOTIFY previewChanged)
1683
1684@@ -55,6 +57,7 @@
1685 QString description() const;
1686 QVariant actions();
1687 QVariant infoHints();
1688+ QVariantMap infoHintsHash() const;
1689 QString image() const;
1690 QString imageSourceUri() const;
1691
1692@@ -73,6 +76,7 @@
1693
1694 QList<QObject *> m_actions;
1695 QList<QObject *> m_infoHints;
1696+ QVariantMap m_infoHintsHash;
1697 };
1698
1699 Q_DECLARE_METATYPE(Preview *)
1700
1701=== modified file 'po/unity8.pot'
1702--- po/unity8.pot 2013-08-09 08:13:00 +0000
1703+++ po/unity8.pot 2013-08-13 09:51:04 +0000
1704@@ -8,7 +8,7 @@
1705 msgstr ""
1706 "Project-Id-Version: unity8\n"
1707 "Report-Msgid-Bugs-To: \n"
1708-"POT-Creation-Date: 2013-08-09 10:12+0200\n"
1709+"POT-Creation-Date: 2013-08-09 12:18+0200\n"
1710 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
1711 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1712 "Language-Team: LANGUAGE <LL@li.org>\n"
1713@@ -16,6 +16,7 @@
1714 "MIME-Version: 1.0\n"
1715 "Content-Type: text/plain; charset=CHARSET\n"
1716 "Content-Transfer-Encoding: 8bit\n"
1717+"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
1718
1719 #: Applications/applications.js:23
1720 msgid "Phone"
1721@@ -89,6 +90,40 @@
1722 msgid "Recent searches"
1723 msgstr ""
1724
1725+#. TRANSLATORS: Number of persons who rated this app
1726+#: Dash/Apps/AppInfo.qml:72
1727+#, qt-format
1728+msgid "(%1)"
1729+msgstr ""
1730+
1731+#. TRANSLATORS: Number of persons who wrote reviews for this app
1732+#: Dash/Apps/AppInfo.qml:84 tests/qmltests/Dash/Apps/tst_AppPreview.qml:115
1733+#, qt-format
1734+msgid "%1 review"
1735+msgid_plural "%1 reviews"
1736+msgstr[0] ""
1737+msgstr[1] ""
1738+
1739+#: Dash/Apps/AppPreview.qml:181
1740+msgid "Rate this"
1741+msgstr ""
1742+
1743+#: Dash/Apps/AppReviews.qml:72
1744+msgid "Add a review"
1745+msgstr ""
1746+
1747+#: Dash/Apps/AppReviews.qml:84
1748+msgid "Review"
1749+msgstr ""
1750+
1751+#: Dash/Apps/AppReviews.qml:118
1752+msgid "Send"
1753+msgstr ""
1754+
1755+#: Dash/Apps/AppReviews.qml:136
1756+msgid "Comments:"
1757+msgstr ""
1758+
1759 #: Dash/DashApps.qml:65
1760 msgid "Running apps"
1761 msgstr ""
1762@@ -153,15 +188,15 @@
1763 msgid "Videos"
1764 msgstr ""
1765
1766-#: Dash/Video/VideoPreview.qml:98
1767+#: Dash/Video/VideoPreview.qml:130
1768 msgid "Directed by:"
1769 msgstr ""
1770
1771-#: Dash/Video/VideoPreview.qml:121
1772+#: Dash/Video/VideoPreview.qml:153
1773 msgid "Starring:"
1774 msgstr ""
1775
1776-#: Dash/Video/VideoPreview.qml:144
1777+#: Dash/Video/VideoPreview.qml:176
1778 msgid "Author:"
1779 msgstr ""
1780
1781
1782=== modified file 'tests/mocks/Ubuntu/CMakeLists.txt'
1783--- tests/mocks/Ubuntu/CMakeLists.txt 2013-07-04 14:47:47 +0000
1784+++ tests/mocks/Ubuntu/CMakeLists.txt 2013-08-13 09:51:04 +0000
1785@@ -1,1 +1,2 @@
1786 add_subdirectory(Application)
1787+add_subdirectory(DownloadDaemonListener)
1788
1789=== added directory 'tests/mocks/Ubuntu/DownloadDaemonListener'
1790=== added file 'tests/mocks/Ubuntu/DownloadDaemonListener/CMakeLists.txt'
1791--- tests/mocks/Ubuntu/DownloadDaemonListener/CMakeLists.txt 1970-01-01 00:00:00 +0000
1792+++ tests/mocks/Ubuntu/DownloadDaemonListener/CMakeLists.txt 2013-08-13 09:51:04 +0000
1793@@ -0,0 +1,18 @@
1794+set(FakeUbuntuDownloadDaemonListenerQml_SOURCES
1795+ plugin.cpp
1796+ MockDownloadTracker.cpp
1797+)
1798+
1799+add_library(FakeUbuntuDownloadDaemonListenerQml MODULE ${FakeUbuntuDownloadDaemonListenerQml_SOURCES})
1800+
1801+qt5_use_modules(FakeUbuntuDownloadDaemonListenerQml Core Quick)
1802+
1803+# copy files into build directory for shadow builds
1804+add_custom_target(UbuntuDownloadQmlDirFile ALL
1805+ COMMAND cp "${CMAKE_CURRENT_SOURCE_DIR}/qmldir" ${CMAKE_CURRENT_BINARY_DIR}
1806+ DEPENDS qmldir
1807+)
1808+
1809+install(TARGETS FakeUbuntuDownloadDaemonListenerQml
1810+ DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/mocks/Ubuntu/DownloadDaemonListener
1811+ )
1812
1813=== added file 'tests/mocks/Ubuntu/DownloadDaemonListener/MockDownloadTracker.cpp'
1814--- tests/mocks/Ubuntu/DownloadDaemonListener/MockDownloadTracker.cpp 1970-01-01 00:00:00 +0000
1815+++ tests/mocks/Ubuntu/DownloadDaemonListener/MockDownloadTracker.cpp 2013-08-13 09:51:04 +0000
1816@@ -0,0 +1,67 @@
1817+/*
1818+ * Copyright (C) 2013 - Canonical Ltd.
1819+ *
1820+ * This program is free software: you can redistribute it and/or modify it
1821+ * under the terms of the GNU Lesser General Public License, as
1822+ * published by the Free Software Foundation; either version 2.1 or 3.0
1823+ * of the License.
1824+ *
1825+ * This program is distributed in the hope that it will be useful, but
1826+ * WITHOUT ANY WARRANTY; without even the implied warranties of
1827+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
1828+ * PURPOSE. See the applicable version of the GNU Lesser General Public
1829+ * License for more details.
1830+ *
1831+ * You should have received a copy of both the GNU Lesser General Public
1832+ * License along with this program. If not, see <http://www.gnu.org/licenses/>
1833+ *
1834+ * Authored by: Diego Sarmentero <diego.sarmentero@canonical.com>
1835+ */
1836+
1837+
1838+#include "MockDownloadTracker.h"
1839+
1840+MockDownloadTracker::MockDownloadTracker(QObject *parent)
1841+ : QObject(parent)
1842+ , m_active(false)
1843+{
1844+}
1845+
1846+bool MockDownloadTracker::isServiceReady() const
1847+{
1848+ return m_active;
1849+}
1850+
1851+QString MockDownloadTracker::dbusPath() const
1852+{
1853+ return m_dbusPath;
1854+}
1855+
1856+void MockDownloadTracker::setDbusPath(const QString& path)
1857+{
1858+ if(m_dbusPath != path){
1859+ m_dbusPath = path;
1860+ startService();
1861+ }
1862+}
1863+
1864+QString MockDownloadTracker::service() const
1865+{
1866+ return m_service;
1867+}
1868+
1869+void MockDownloadTracker::setService(const QString& service)
1870+{
1871+ if(m_service != service){
1872+ m_service = service;
1873+ startService();
1874+ }
1875+}
1876+
1877+void MockDownloadTracker::startService()
1878+{
1879+ if(!m_service.isEmpty() && !m_dbusPath.isEmpty()) {
1880+ m_active = true;
1881+ Q_EMIT serviceReadyChanged(m_active);
1882+ }
1883+}
1884
1885=== added file 'tests/mocks/Ubuntu/DownloadDaemonListener/MockDownloadTracker.h'
1886--- tests/mocks/Ubuntu/DownloadDaemonListener/MockDownloadTracker.h 1970-01-01 00:00:00 +0000
1887+++ tests/mocks/Ubuntu/DownloadDaemonListener/MockDownloadTracker.h 2013-08-13 09:51:04 +0000
1888@@ -0,0 +1,66 @@
1889+/*
1890+ * Copyright (C) 2013 - Canonical Ltd.
1891+ *
1892+ * This program is free software: you can redistribute it and/or modify it
1893+ * under the terms of the GNU Lesser General Public License, as
1894+ * published by the Free Software Foundation; either version 2.1 or 3.0
1895+ * of the License.
1896+ *
1897+ * This program is distributed in the hope that it will be useful, but
1898+ * WITHOUT ANY WARRANTY; without even the implied warranties of
1899+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
1900+ * PURPOSE. See the applicable version of the GNU Lesser General Public
1901+ * License for more details.
1902+ *
1903+ * You should have received a copy of both the GNU Lesser General Public
1904+ * License along with this program. If not, see <http://www.gnu.org/licenses/>
1905+ *
1906+ * Authored by: Diego Sarmentero <diego.sarmentero@canonical.com>
1907+ */
1908+
1909+
1910+#ifndef MOCKDOWNLOADTRACKER_H
1911+#define MOCKDOWNLOADTRACKER_H
1912+
1913+#include <QObject>
1914+
1915+class MockDownloadTracker : public QObject
1916+{
1917+ Q_OBJECT
1918+ Q_DISABLE_COPY(MockDownloadTracker)
1919+ Q_PROPERTY(QString service READ service WRITE setService NOTIFY serviceChanged)
1920+ Q_PROPERTY(QString dbusPath READ dbusPath WRITE setDbusPath NOTIFY dbusPathChanged)
1921+ Q_PROPERTY(bool serviceReady READ isServiceReady NOTIFY serviceReadyChanged)
1922+
1923+public:
1924+ explicit MockDownloadTracker(QObject *parent = 0);
1925+
1926+ QString service() const;
1927+ QString dbusPath() const;
1928+ bool isServiceReady() const;
1929+
1930+ void setDbusPath(const QString& path);
1931+ void setService(const QString& service);
1932+
1933+Q_SIGNALS:
1934+ void serviceChanged(const QString &service);
1935+ void dbusPathChanged(const QString &dbusPath);
1936+ void serviceReadyChanged(const bool &serviceReady);
1937+
1938+ void canceled(bool success);
1939+ void error(const QString &error);
1940+ void finished(const QString &path);
1941+ void paused(bool success);
1942+ void progress(qulonglong received, qulonglong total);
1943+ void resumed(bool success);
1944+ void started(bool success);
1945+
1946+private:
1947+ QString m_dbusPath;
1948+ QString m_service;
1949+ bool m_active;
1950+
1951+ void startService();
1952+};
1953+
1954+#endif // MOCKDOWNLOADTRACKER_H
1955
1956=== added file 'tests/mocks/Ubuntu/DownloadDaemonListener/plugin.cpp'
1957--- tests/mocks/Ubuntu/DownloadDaemonListener/plugin.cpp 1970-01-01 00:00:00 +0000
1958+++ tests/mocks/Ubuntu/DownloadDaemonListener/plugin.cpp 2013-08-13 09:51:04 +0000
1959@@ -0,0 +1,28 @@
1960+/*
1961+ * Copyright (C) 2013 Canonical, Ltd.
1962+ *
1963+ * This program is free software; you can redistribute it and/or modify
1964+ * it under the terms of the GNU General Public License as published by
1965+ * the Free Software Foundation; version 3.
1966+ *
1967+ * This program is distributed in the hope that it will be useful,
1968+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1969+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1970+ * GNU General Public License for more details.
1971+ *
1972+ * You should have received a copy of the GNU General Public License
1973+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1974+ */
1975+
1976+#include "plugin.h"
1977+#include "MockDownloadTracker.h"
1978+
1979+#include <QtQml>
1980+#include <QtQml/QQmlContext>
1981+#include <qqml.h>
1982+
1983+
1984+void FakeUbuntuDownloadDaemonListenerQmlPlugin::registerTypes(const char *uri)
1985+{
1986+ qmlRegisterType<MockDownloadTracker>(uri, 0, 1, "DownloadTracker");
1987+}
1988
1989=== added file 'tests/mocks/Ubuntu/DownloadDaemonListener/plugin.h'
1990--- tests/mocks/Ubuntu/DownloadDaemonListener/plugin.h 1970-01-01 00:00:00 +0000
1991+++ tests/mocks/Ubuntu/DownloadDaemonListener/plugin.h 2013-08-13 09:51:04 +0000
1992@@ -0,0 +1,30 @@
1993+/*
1994+ * Copyright (C) 2013 Canonical, Ltd.
1995+ *
1996+ * This program is free software; you can redistribute it and/or modify
1997+ * it under the terms of the GNU General Public License as published by
1998+ * the Free Software Foundation; version 3.
1999+ *
2000+ * This program is distributed in the hope that it will be useful,
2001+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2002+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2003+ * GNU General Public License for more details.
2004+ *
2005+ * You should have received a copy of the GNU General Public License
2006+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2007+ */
2008+
2009+#ifndef PLUGIN_H
2010+#define PLUGIN_H
2011+
2012+#include <QQmlExtensionPlugin>
2013+
2014+class FakeUbuntuDownloadDaemonListenerQmlPlugin : public QQmlExtensionPlugin
2015+{
2016+ Q_OBJECT
2017+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
2018+public:
2019+ void registerTypes(const char *uri);
2020+};
2021+
2022+#endif
2023
2024=== added file 'tests/mocks/Ubuntu/DownloadDaemonListener/qmldir'
2025--- tests/mocks/Ubuntu/DownloadDaemonListener/qmldir 1970-01-01 00:00:00 +0000
2026+++ tests/mocks/Ubuntu/DownloadDaemonListener/qmldir 2013-08-13 09:51:04 +0000
2027@@ -0,0 +1,2 @@
2028+module Ubuntu.DownloadDaemonListener
2029+plugin FakeUbuntuDownloadDaemonListenerQml
2030
2031=== modified file 'tests/qmltests/CMakeLists.txt'
2032--- tests/qmltests/CMakeLists.txt 2013-08-06 15:14:29 +0000
2033+++ tests/qmltests/CMakeLists.txt 2013-08-13 09:51:04 +0000
2034@@ -49,6 +49,8 @@
2035 add_qml_test(Dash FilterGrids IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/plugins ${CMAKE_CURRENT_SOURCE_DIR}/plugins
2036 ${CMAKE_BINARY_DIR}/tests/mocks)
2037 add_qml_test(Dash/Apps RunningApplicationsGrid IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/tests/mocks)
2038+add_qml_test(Dash/Apps AppPreview IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/tests/mocks)
2039+add_qml_test(Dash/Video VideoPreview IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/tests/mocks)
2040 add_qml_test(Greeter Lockscreen IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS}
2041 PROPERTIES ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/libusermetrics:${CMAKE_BINARY_DIR}/tests/mocks/LightDM/full")
2042 add_qml_test(Greeter Tablet IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS}
2043
2044=== added file 'tests/qmltests/Dash/Apps/tst_AppPreview.qml'
2045--- tests/qmltests/Dash/Apps/tst_AppPreview.qml 1970-01-01 00:00:00 +0000
2046+++ tests/qmltests/Dash/Apps/tst_AppPreview.qml 2013-08-13 09:51:04 +0000
2047@@ -0,0 +1,152 @@
2048+/*
2049+ * Copyright 2013 Canonical Ltd.
2050+ *
2051+ * This program is free software; you can redistribute it and/or modify
2052+ * it under the terms of the GNU General Public License as published by
2053+ * the Free Software Foundation; version 3.
2054+ *
2055+ * This program is distributed in the hope that it will be useful,
2056+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2057+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2058+ * GNU General Public License for more details.
2059+ *
2060+ * You should have received a copy of the GNU General Public License
2061+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2062+ */
2063+
2064+import QtQuick 2.0
2065+import QtTest 1.0
2066+import Ubuntu.Components 0.1
2067+import "../../../../Dash/Apps"
2068+import Unity.Test 0.1 as UT
2069+
2070+Item {
2071+ id: root
2072+ width: units.gu(60)
2073+ height: units.gu(80)
2074+
2075+ property var calls: []
2076+
2077+ SignalSpy {
2078+ id: sendPreviewSpy
2079+ target: appPreview
2080+ signalName: "sendUserReview"
2081+ }
2082+
2083+ property string commentary: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus a mi vitae augue rhoncus lobortis ut rutrum metus. Curabitur tortor leo, tristique sed mollis quis, condimentum venenatis nibh.";
2084+ QtObject { id: screenshots; property var value: ["fake_image1.png", "fake_image2.png", "fake_image3.png"] }
2085+ QtObject { id: rating; property int value: 8 }
2086+ QtObject { id: rated; property int value: 120 }
2087+ QtObject { id: reviews; property int value: 8 }
2088+ QtObject { id: progress; property string value: "source" }
2089+ QtObject { id: comments; property var value: [
2090+ ["Unity User", 4, "08/20/2013", root.commentary],
2091+ ["Unity User", 8, "01/15/2013", root.commentary],
2092+ ["Unity User", 10, "10/02/2013", root.commentary],
2093+ ]
2094+ }
2095+
2096+ QtObject {
2097+ id: data
2098+ property string title: "Unity App"
2099+ property string appIcon: "fake_image.png"
2100+ property string description: "This is an Application description"
2101+ property var execute: root.fake_call
2102+ property var infoMap: {
2103+ "more-screenshots": screenshots,
2104+ "rating": rating,
2105+ "rated": rated,
2106+ "reviews": reviews,
2107+ "comments": comments
2108+ }
2109+ property var actions: [
2110+ { "id": 123, "displayName": "action1" },
2111+ { "id": 456, "displayName": "action2" },
2112+ { "id": 789, "displayName": "action3" },
2113+ ]
2114+ }
2115+
2116+ function fake_call(id, data){
2117+ root.calls[root.calls.length] = id;
2118+ }
2119+
2120+ // The component under test
2121+ AppPreview {
2122+ id: appPreview
2123+ anchors.fill: parent
2124+
2125+ previewData: data
2126+ }
2127+
2128+ UT.UnityTestCase {
2129+ name: "AppPreview"
2130+ when: windowShown
2131+
2132+ function cleanup() {
2133+ root.calls = new Array();
2134+ sendPreviewSpy.clear();
2135+ var reviewField = findChild(appPreview, "reviewField");
2136+ reviewField.focus = false;
2137+ reviewField.text = "";
2138+ }
2139+
2140+ function test_actions() {
2141+ var buttons = findChild(appPreview, "gridButtons");
2142+ compare(buttons.count, 3, "Not the proper amount of actions detected.");
2143+
2144+ for(var i = 0; i < buttons.count; i++) {
2145+ buttons.currentIndex = i;
2146+ buttons.currentItem.clicked();
2147+ }
2148+
2149+ var actions = data.actions;
2150+ for(var i = 0; i < actions.length; i++) {
2151+ compare(root.calls[i], actions[i].id, "Id of action not found.");
2152+ }
2153+ }
2154+
2155+ function test_rated() {
2156+ var rated = findChild(appPreview, "ratedLabel");
2157+ compare(rated.text, "(120)", "Rates not equal");
2158+ }
2159+
2160+ function test_reviews() {
2161+ var rated = findChild(appPreview, "reviewsLabel");
2162+ compare(rated.text, "8 reviews", "Reviews don't match");
2163+ }
2164+
2165+ function test_send_review() {
2166+ var appReviews = findChild(appPreview, "appReviews");
2167+ appReviews.sendReview("review");
2168+ sendPreviewSpy.wait();
2169+ }
2170+
2171+ function test_review_focus() {
2172+ var appReviews = findChild(appPreview, "appReviews");
2173+ var sendButton = findChild(appReviews, "sendButton");
2174+ var reviewField = findChild(appReviews, "reviewField");
2175+
2176+ compare(reviewField.focus, false, "ReviewField shouldn't have focus");
2177+ compare(appReviews.state, "", "State should be empty");
2178+
2179+ mouseClick(reviewField, reviewField.width/2, reviewField.height/2);
2180+ compare(reviewField.focus, true, "Review Field should have focus");
2181+ compare(appReviews.state, "editing", "State should be 'editing'");
2182+ }
2183+
2184+ function test_comments() {
2185+ var commentsArea = findChild(appPreview, "commentsArea");
2186+ compare(commentsArea.count, 3);
2187+ for(var i = 0; i < 3; i++) {
2188+ var username = commentsArea.itemAt(i).children[0].children[0].text
2189+ var rate = commentsArea.itemAt(i).children[0].children[1].children[0].rating
2190+ var date = commentsArea.itemAt(i).children[0].children[1].children[1].text
2191+ var comment = commentsArea.itemAt(i).children[1].text
2192+ compare(username, comments.value[i][0], "Username don't match");
2193+ compare(rate, comments.value[i][1], "Rating don't match");
2194+ compare(date, comments.value[i][2], "Date don't match");
2195+ compare(comment, comments.value[i][3], "Comment don't match");
2196+ }
2197+ }
2198+ }
2199+}
2200
2201=== added directory 'tests/qmltests/Dash/Video'
2202=== added file 'tests/qmltests/Dash/Video/tst_VideoPreview.qml'
2203--- tests/qmltests/Dash/Video/tst_VideoPreview.qml 1970-01-01 00:00:00 +0000
2204+++ tests/qmltests/Dash/Video/tst_VideoPreview.qml 2013-08-13 09:51:04 +0000
2205@@ -0,0 +1,63 @@
2206+/*
2207+ * Copyright 2013 Canonical Ltd.
2208+ *
2209+ * This program is free software; you can redistribute it and/or modify
2210+ * it under the terms of the GNU General Public License as published by
2211+ * the Free Software Foundation; version 3.
2212+ *
2213+ * This program is distributed in the hope that it will be useful,
2214+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2215+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2216+ * GNU General Public License for more details.
2217+ *
2218+ * You should have received a copy of the GNU General Public License
2219+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2220+ */
2221+
2222+import QtQuick 2.0
2223+import QtTest 1.0
2224+import "../../../../Dash/Video"
2225+import Unity.Test 0.1 as UT
2226+
2227+Item {
2228+ id: root
2229+ width: units.gu(60)
2230+ height: units.gu(80)
2231+
2232+ SignalSpy {
2233+ id: previewClickedSpy
2234+ target: preview
2235+ signalName: "previewImageClicked"
2236+ }
2237+
2238+ // The component under test
2239+ VideoPreview {
2240+ id: preview
2241+ anchors.fill: parent
2242+ }
2243+
2244+ UT.UnityTestCase {
2245+ name: "VideoPreview"
2246+ when: windowShown
2247+
2248+ function test_play_button_data() {
2249+ return [
2250+ {tag: "playable", playable: true},
2251+ {tag: "not playable", playable: false}
2252+ ]
2253+ }
2254+
2255+ function test_play_button(data) {
2256+ var playButton = findChild(preview, "playButton")
2257+ preview.playable = data.playable
2258+ compare(playButton.visible, data.playable)
2259+ }
2260+
2261+ function test_play_button_click() {
2262+ preview.playable = true
2263+ var playButton = findChild(preview, "playButton")
2264+ mouseClick(playButton, 1, 1)
2265+ tryCompare(previewClickedSpy, "count", 1)
2266+ }
2267+ }
2268+}
2269
2270=== modified file 'tests/qmltests/Dash/tst_DashPreview.qml'
2271--- tests/qmltests/Dash/tst_DashPreview.qml 2013-06-05 22:03:08 +0000
2272+++ tests/qmltests/Dash/tst_DashPreview.qml 2013-08-13 09:51:04 +0000
2273@@ -32,7 +32,6 @@
2274 id: preview
2275 anchors.fill: parent
2276 title: "Testing rocks, debugging sucks!"
2277- forceSquare: true
2278
2279 buttons: Row {
2280 width: parent.width
2281@@ -55,9 +54,9 @@
2282 }
2283 }
2284
2285- caption: Label { text: "Caption label" }
2286+ header: Label { text: "Caption label" }
2287
2288- description: Column {
2289+ body: Column {
2290 id: testContent
2291 objectName: "testContent"
2292 width: parent.width
2293@@ -102,26 +101,6 @@
2294 compare(closeSpy.count, 1, "Close signal not emitted")
2295 }
2296
2297- function test_play_button_data() {
2298- return [
2299- {tag: "playable", playable: true},
2300- {tag: "not playable", playable: false}
2301- ]
2302- }
2303-
2304- function test_play_button(data) {
2305- var playButton = findChild(preview, "playButton")
2306- preview.playable = data.playable
2307- compare(playButton.visible, data.playable)
2308- }
2309-
2310- function test_play_button_click() {
2311- preview.playable = true
2312- var playButton = findChild(preview, "playButton")
2313- mouseClick(playButton, 1, 1)
2314- tryCompare(previewClickedSpy, "count", 1)
2315- }
2316-
2317 function test_columns_data() {
2318 return [
2319 {tag: "1 columns", width: units.gu(5), height: units.gu(10), columns: 1},

Subscribers

People subscribed via source and target branches