Merge lp:~verzegnassi-stefano/ubuntu-docviewer-app/add-empty-state into lp:ubuntu-docviewer-app/trunk

Proposed by Stefano Verzegnassi on 2015-01-16
Status: Merged
Approved by: Stefano Verzegnassi on 2015-01-21
Approved revision: 49
Merged at revision: 51
Proposed branch: lp:~verzegnassi-stefano/ubuntu-docviewer-app/add-empty-state
Merge into: lp:ubuntu-docviewer-app/trunk
Diff against target: 319 lines (+154/-87)
5 files modified
src/app/main.cpp (+10/-26)
src/app/qml/ContentHubPicker.qml (+55/-0)
src/app/qml/EmptyState.qml (+59/-0)
src/app/qml/WelcomePage.qml (+20/-45)
src/app/qml/ubuntu-docviewer-app.qml (+10/-16)
To merge this branch: bzr merge lp:~verzegnassi-stefano/ubuntu-docviewer-app/add-empty-state
Reviewer Review Type Date Requested Status
Andrew Hayzen (community) argument code 2015-01-16 Approve on 2015-01-21
Nekhelesh Ramananthan (community) empty state code Approve on 2015-01-21
Ubuntu Phone Apps Jenkins Bot continuous-integration Approve on 2015-01-16
Review via email: mp+246744@code.launchpad.net

Commit Message

Added Empty State in Welcome screen

Description of the Change

- An Empty State item is shown when DocViewer is loaded with no specified document.
ContentHub source picker has been moved in a different page.

- Removed Ubuntu.Components Arguments[1] from ubuntu-docviewer-app.qml. The current release of the app uses two argument parsers, which is not an ideal scenario. This MP solves this issue.

- In the current release, when an user runs ubuntu-docviewer-app with no arguments, a warning is shown in CMD. That's because we use "defaultArgument" property of QML Arguments.
For some reason, the application works anyway, but it looks more a workaround based on an issue in UITK (music-app has a similar issue[2]).

- Removed "tablet" and "phone" arguments from main.cpp.
They came from reminders-app, but we don't use it.

- Removed "QML import directory" argument.

NOTES:
- EmptyState.qml comes from ubuntu-clock-app
- The code included in ContentHubPicker.qml is the code removed from WelcomePage.qml

[1]: http://developer.ubuntu.com/api/qml/sdk-14.10/Ubuntu.Components.Arguments/
[2] line 125-126: http://bazaar.launchpad.net/~music-app-dev/music-app/remix/view/head:/music-app.qml

To post a comment you must log in.
Nekhelesh Ramananthan (nik90) wrote :

Thanks for the MP. IMHO, I would recommend that a MP fixes/adds only one thing to make it easier to spot regressions if any. In this MP I notice the arguments being changed and empty state. I have reviewed the empty state code and it looks and works as expected.

I haven't reviewed the arguments code since I am not too familiar with it and am actually looking for a implementation that I can copy to the clock app as well. So I would recommend you find another person to review that part of this MP or move that to a separate MP in itself.

review: Approve (empty state code)

Ok, thank you again!
The issue was that I wasn't able to add the Empty State code if I hadn't changed the arguments code. For some strange reason, adding an image on the Page used to make the application instable...

Andrew Hayzen (ahayzen) wrote :

The args code looks OK and I've tested it locally on my machine to ensure that passing an arg loads that document.

review: Approve (argument code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/app/main.cpp'
2--- src/app/main.cpp 2014-10-31 16:25:17 +0000
3+++ src/app/main.cpp 2015-01-16 17:05:43 +0000
4@@ -1,5 +1,5 @@
5 /*
6- * Copyright: 2013 - 2014 Canonical, Ltd
7+ * Copyright: 2013 - 2015 Canonical, Ltd
8 *
9 * This file is part of docviewer
10 *
11@@ -19,6 +19,7 @@
12 * Authors: Michael Zanetti <michael.zanetti@canonical.com>
13 * Riccardo Padovani <rpadovani@ubuntu.com>
14 * David Planella <david.planella@ubuntu.com>
15+ * Stefano Verzegnassi <stefano92.100@gmail.com>
16 */
17
18 #include <QtGui/QGuiApplication>
19@@ -44,24 +45,20 @@
20
21 QStringList args = a.arguments();
22 if (args.contains("-h") || args.contains("--help")) {
23- qDebug() << "usage: " + args.at(0) + " [-p|--phone] [-t|--tablet] [-h|--help] [-I <path>]";
24- qDebug() << " -p|--phone If running on Desktop, start in a phone sized window.";
25- qDebug() << " -t|--tablet If running on Desktop, start in a tablet sized window.";
26+ qDebug() << "usage: " + args.at(0) + " [-h|--help] <path>";
27 qDebug() << " -h|--help Print this help.";
28- qDebug() << " -I <path> Give a path for an additional QML import directory. May be used multiple times.";
29+ qDebug() << " <path> Path of the document to load.";
30 return 0;
31 }
32
33- for (int i = 0; i < args.count(); i++) {
34- if (args.at(i) == "-I" && args.count() > i + 1) {
35- QString addedPath = args.at(i+1);
36- if (addedPath.startsWith('.')) {
37- addedPath = addedPath.right(addedPath.length() - 1);
38- addedPath.prepend(QDir::currentPath());
39- }
40- importPathList.append(addedPath);
41+ // Check if the path of the document has been specified.
42+ QString docPath;
43+ for (int i = 1; i < args.count(); i++) {
44+ if (args.at(i) != "-h" && args.at(i) != "--h") {
45+ docPath = args.at(i);
46 }
47 }
48+ view.engine()->rootContext()->setContextProperty("documentPath", docPath);
49
50 if (args.contains(QLatin1String("-testability")) || getenv("QT_LOAD_TESTABILITY")) {
51 QLibrary testLib(QLatin1String("qttestability"));
52@@ -78,19 +75,6 @@
53 }
54 }
55
56- view.engine()->rootContext()->setContextProperty("tablet", QVariant(false));
57- view.engine()->rootContext()->setContextProperty("phone", QVariant(false));
58- if (args.contains("-t") || args.contains("--tablet")) {
59- qDebug() << "running in tablet mode";
60- view.engine()->rootContext()->setContextProperty("tablet", QVariant(true));
61- } else if (args.contains("-p") || args.contains("--phone")){
62- qDebug() << "running in phone mode";
63- view.engine()->rootContext()->setContextProperty("phone", QVariant(true));
64- } else if (qgetenv("QT_QPA_PLATFORM") != "ubuntumirclient") {
65- // Default to tablet size on X11
66- view.engine()->rootContext()->setContextProperty("tablet", QVariant(true));
67- }
68-
69 view.engine()->setImportPathList(importPathList);
70
71 QString qmlfile;
72
73=== added file 'src/app/qml/ContentHubPicker.qml'
74--- src/app/qml/ContentHubPicker.qml 1970-01-01 00:00:00 +0000
75+++ src/app/qml/ContentHubPicker.qml 2015-01-16 17:05:43 +0000
76@@ -0,0 +1,55 @@
77+import QtQuick 2.0
78+import Ubuntu.Components 1.1
79+import Ubuntu.Content 1.1
80+
81+Page {
82+ id: picker
83+ title: i18n.tr("Open with...")
84+
85+ property var activeTransfer
86+
87+ head.sections.model: [i18n.tr("Documents"), i18n.tr("Pictures"), i18n.tr("Other")]
88+ head.backAction: Action {
89+ iconName: "back"
90+ text: i18n.tr("Back")
91+ onTriggered: pageStack.pop()
92+ }
93+
94+ ContentPeerPicker {
95+ // Do not show ContentPeerPicker header, since we need head.sections.
96+ showTitle: false
97+
98+ contentType: {
99+ switch (picker.head.sections.selectedIndex) {
100+ case 0:
101+ return ContentType.Documents
102+ case 1:
103+ return ContentType.Pictures
104+ case 2:
105+ return ContentType.Unknown
106+ }
107+ }
108+ handler: ContentHandler.Source
109+
110+ onPeerSelected: picker.activeTransfer = peer.request();
111+ }
112+
113+ ContentTransferHint {
114+ id: transferHint
115+ anchors.fill: parent
116+ activeTransfer: picker.activeTransfer
117+ }
118+
119+ Connections {
120+ target: picker.activeTransfer ? picker.activeTransfer : null
121+ onStateChanged: {
122+ if (picker.activeTransfer.state === ContentTransfer.Charged) {
123+ // Close ContentHubPicker page.
124+ pageStack.pop();
125+
126+ file.path = picker.activeTransfer.items[0].url.toString().replace("file://", "")
127+ console.log("[CONTENT-HUB] Content imported!")
128+ }
129+ }
130+ }
131+}
132
133=== added file 'src/app/qml/EmptyState.qml'
134--- src/app/qml/EmptyState.qml 1970-01-01 00:00:00 +0000
135+++ src/app/qml/EmptyState.qml 2015-01-16 17:05:43 +0000
136@@ -0,0 +1,59 @@
137+/*
138+ * Copyright (C) 2014 Canonical Ltd
139+ *
140+ * This file is part of Ubuntu Clock App
141+ *
142+ * Ubuntu Clock App is free software: you can redistribute it and/or modify
143+ * it under the terms of the GNU General Public License version 3 as
144+ * published by the Free Software Foundation.
145+ *
146+ * Ubuntu Clock App is distributed in the hope that it will be useful,
147+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
148+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
149+ * GNU General Public License for more details.
150+ *
151+ * You should have received a copy of the GNU General Public License
152+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
153+ */
154+
155+import QtQuick 2.3
156+import Ubuntu.Components 1.1
157+
158+/*
159+ Component which displays an empty state (approved by design). It offers an
160+ icon, title and subtitle to describe the empty state.
161+*/
162+
163+Item {
164+ id: emptyState
165+
166+ // Public APIs
167+ property alias iconName: emptyIcon.name
168+ property alias title: emptyLabel.text
169+ property alias subTitle: emptySublabel.text
170+
171+ height: childrenRect.height
172+
173+ Icon {
174+ id: emptyIcon
175+ anchors.horizontalCenter: parent.horizontalCenter
176+ height: units.gu(10)
177+ width: height
178+ color: "#BBBBBB"
179+ }
180+
181+ Label {
182+ id: emptyLabel
183+ anchors.top: emptyIcon.bottom
184+ anchors.topMargin: units.gu(5)
185+ anchors.horizontalCenter: parent.horizontalCenter
186+ fontSize: "large"
187+ font.bold: true
188+ }
189+
190+ Label {
191+ id: emptySublabel
192+ anchors.top: emptyLabel.bottom
193+ anchors.horizontalCenter: parent.horizontalCenter
194+ }
195+}
196
197=== modified file 'src/app/qml/WelcomePage.qml'
198--- src/app/qml/WelcomePage.qml 2014-11-08 08:02:44 +0000
199+++ src/app/qml/WelcomePage.qml 2015-01-16 17:05:43 +0000
200@@ -1,51 +1,26 @@
201 import QtQuick 2.0
202 import Ubuntu.Components 1.1
203-import Ubuntu.Content 1.1
204
205 Page {
206- id: picker
207-
208- property var activeTransfer
209-
210- ContentTransferHint {
211- id: transferHint
212- anchors.fill: parent
213- activeTransfer: picker.activeTransfer
214- }
215-
216- title: i18n.tr("Open with...")
217- head.sections.model: [i18n.tr("Documents"), i18n.tr("Pictures"), i18n.tr("Other")]
218- head.backAction: Action {
219- iconName: "close"
220- text: i18n.tr("Close")
221- onTriggered: Qt.quit()
222- }
223-
224- ContentPeerPicker {
225- showTitle: false
226-
227- contentType: {
228- switch (picker.head.sections.selectedIndex) {
229- case 0:
230- return ContentType.Documents
231- case 1:
232- return ContentType.Pictures
233- case 2:
234- return ContentType.Unknown
235- }
236- }
237- handler: ContentHandler.Source
238-
239- onPeerSelected: picker.activeTransfer = peer.request();
240- }
241-
242- Connections {
243- target: picker.activeTransfer ? picker.activeTransfer : null
244- onStateChanged: {
245- if (picker.activeTransfer.state === ContentTransfer.Charged) {
246- file.path = picker.activeTransfer.items[0].url.toString().replace("file://", "")
247- console.log("[CONTENT-HUB] Content imported!")
248- }
249- }
250+ id: welcomePage
251+
252+ title: i18n.tr("Document Viewer")
253+ head.actions: [ openAction ]
254+
255+ EmptyState {
256+ title: i18n.tr("No opened documents")
257+ subTitle: i18n.tr("Tap the + icon to open a document")
258+
259+ iconName: "edit-copy"
260+
261+ anchors.centerIn: parent
262+ }
263+
264+ Action {
265+ id: openAction
266+ text: i18n.tr("Open a file...")
267+ iconName: "add"
268+
269+ onTriggered: pageStack.push(Qt.resolvedUrl("ContentHubPicker.qml"))
270 }
271 }
272
273=== modified file 'src/app/qml/ubuntu-docviewer-app.qml'
274--- src/app/qml/ubuntu-docviewer-app.qml 2014-11-04 18:54:38 +0000
275+++ src/app/qml/ubuntu-docviewer-app.qml 2015-01-16 17:05:43 +0000
276@@ -15,15 +15,6 @@
277 width: units.gu(50)
278 height: units.gu(75)
279
280- Arguments {
281- id: args
282-
283- // It returns "expected argument" message when not specified a path.
284- // It works anyway, but it may be worth to use Argument{} in future
285- defaultArgument.help: "Path of the document"
286- defaultArgument.valueNames: ["path"]
287- }
288-
289 File {
290 objectName: "fileObject"
291 id: file
292@@ -33,18 +24,21 @@
293 }
294
295 Component.onCompleted: {
296- // Check if a value has been specified for "path" argument
297- if (args.defaultArgument.at(0)) {
298- // If so, send the path to the File plugin
299- console.log("Path argument is:", args.defaultArgument.at(0))
300- file.path = args.defaultArgument.at(0)
301+ // Check if a value has been specified for "documentPath" argument.
302+ // The value for the argument is parsed in main.cpp.
303+
304+ if (documentPath) {
305+ // If so, send the path to the File plugin and load the document.
306+ console.log("Path argument is:", documentPath);
307+ file.path = documentPath;
308 } else {
309- // Otherwise, push a welcome screen in the stack
310- pageStack.push(Qt.resolvedUrl("WelcomePage.qml"))
311+ // Otherwise, push a welcome screen in the stack.
312+ pageStack.push(Qt.resolvedUrl("WelcomePage.qml"));
313 }
314 }
315
316 // Content Importer
317+ // Used when user asks to open a document from ContentHub.
318 Loader {
319 id: contentHubLoader
320

Subscribers

People subscribed via source and target branches