Merge lp:~renatofilho/mediaplayer-app/use-cotent-hub into lp:mediaplayer-app

Proposed by Renato Araujo Oliveira Filho
Status: Merged
Approved by: Bill Filler
Approved revision: 454
Merged at revision: 441
Proposed branch: lp:~renatofilho/mediaplayer-app/use-cotent-hub
Merge into: lp:mediaplayer-app
Diff against target: 655 lines (+280/-119)
9 files modified
data/mediaplayer-app.desktop.in.in (+0/-1)
src/mediaplayer.cpp (+1/-46)
src/mediaplayer.h (+0/-4)
src/qml/VideoImport.qml (+40/-0)
src/qml/VideoImportDialog.qml (+98/-0)
src/qml/player.qml (+30/-18)
src/qml/player/Controls.qml (+27/-16)
src/qml/player/VideoPlayer.qml (+66/-33)
tests/unittest/tst_video_player.qml (+18/-1)
To merge this branch: bzr merge lp:~renatofilho/mediaplayer-app/use-cotent-hub
Reviewer Review Type Date Requested Status
system-apps-ci-bot continuous-integration Approve
Ubuntu Phablet Team Pending
Review via email: mp+320366@code.launchpad.net

Commit message

Open content peer selection in case of the app start without a video url.

To post a comment you must log in.
Revision history for this message
system-apps-ci-bot (system-apps-ci-bot) wrote :

PASSED: Continuous integration, rev:443
https://jenkins.canonical.com/system-apps/job/lp-mediaplayer-app-ci/3/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build/2328
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-0-fetch/2327
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=xenial+overlay/2149
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=xenial+overlay/2149/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=zesty/2149
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=zesty/2149/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=xenial+overlay/2149
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=xenial+overlay/2149/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=zesty/2149
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=zesty/2149/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=xenial+overlay/2149
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=xenial+overlay/2149/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=zesty/2149
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=zesty/2149/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/system-apps/job/lp-mediaplayer-app-ci/3/rebuild

review: Approve (continuous-integration)
444. By Renato Araujo Oliveira Filho

Added missing files.

445. By Renato Araujo Oliveira Filho

Fixed vide import using content-hub.

446. By Renato Araujo Oliveira Filho

add a option to switch to full screen.

447. By Renato Araujo Oliveira Filho

Fixed check for desktop mode on unity7.

448. By Renato Araujo Oliveira Filho

Ask to pick a video file if player is empty while clicking on "play" button.

449. By Renato Araujo Oliveira Filho

Added a open-file button.

450. By Renato Araujo Oliveira Filho

Always show quit an fullscreen button.
Does not pause video if the app loses focus.

451. By Renato Araujo Oliveira Filho

Show a empty state if the app was started without a URL.

452. By Renato Araujo Oliveira Filho

Fixed empty state on player startup.

453. By Renato Araujo Oliveira Filho

Use a different icon for open a new file.

454. By Renato Araujo Oliveira Filho

Pause video player if it is playing while picking a new file.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'data/mediaplayer-app.desktop.in.in'
--- data/mediaplayer-app.desktop.in.in 2016-11-23 22:58:39 +0000
+++ data/mediaplayer-app.desktop.in.in 2017-03-21 19:39:57 +0000
@@ -12,4 +12,3 @@
12X-Ubuntu-Gettext-Domain=mediaplayer-app12X-Ubuntu-Gettext-Domain=mediaplayer-app
13X-Ubuntu-Single-Instance=true13X-Ubuntu-Single-Instance=true
14X-Ubuntu-Default-Department-ID=sound-video14X-Ubuntu-Default-Department-ID=sound-video
15OnlyShowIn=Old
1615
=== modified file 'src/mediaplayer.cpp'
--- src/mediaplayer.cpp 2017-01-12 13:17:45 +0000
+++ src/mediaplayer.cpp 2017-03-21 19:39:57 +0000
@@ -47,7 +47,7 @@
47}47}
4848
49MediaPlayer::MediaPlayer(int &argc, char **argv)49MediaPlayer::MediaPlayer(int &argc, char **argv)
50 : QApplication(argc, argv), m_view(0), m_fileChooser(0)50 : QApplication(argc, argv), m_view(0)
51{51{
52}52}
5353
@@ -57,9 +57,6 @@
57 bool windowed = args.removeAll("-w") + args.removeAll("--windowed") > 0;57 bool windowed = args.removeAll("-w") + args.removeAll("--windowed") > 0;
58 bool testability = args.removeAll("-testability") > 0;58 bool testability = args.removeAll("-testability") > 0;
5959
60 // use windowed in desktop as default
61 windowed = windowed || isDesktopMode();
62
63 // The testability driver is only loaded by QApplication but not by60 // The testability driver is only loaded by QApplication but not by
64 // QGuiApplication.61 // QGuiApplication.
65 // However, QApplication depends on QWidget which would add some62 // However, QApplication depends on QWidget which would add some
@@ -155,10 +152,6 @@
155 if (m_view) {152 if (m_view) {
156 delete m_view;153 delete m_view;
157 }154 }
158 if (m_fileChooser) {
159 delete m_fileChooser;
160 m_fileChooser = 0;
161 }
162}155}
163156
164void157void
@@ -189,44 +182,6 @@
189 m_view->rootContext()->setContextProperty("screenHeight", height);182 m_view->rootContext()->setContextProperty("screenHeight", height);
190}183}
191184
192bool MediaPlayer::isDesktopMode() const
193{
194 // WORKAROUND: check unity profile
195 if (qgetenv("UNITY_INDICATOR_PROFILE") == "desktop")
196 return true;
197
198 // Assume that platformName (QtUbuntu) with ubuntu
199 // in name means it's running on device
200 // TODO: replace this check with SDK call for formfactor
201 QString platform = QGuiApplication::platformName();
202 return !((platform == "ubuntu") || (platform == "ubuntumirclient"));
203}
204
205QUrl MediaPlayer::chooseFile()
206{
207 QUrl fileName;
208 if (!m_fileChooser) {
209 m_fileChooser = new QFileDialog(0,
210 tr("Open Video"),
211 QStandardPaths::writableLocation(QStandardPaths::MoviesLocation),
212 tr("Video files (*.avi *.mov *.mp4 *.divx *.ogg *.ogv *.mpeg);;All files (*)"));
213 m_fileChooser->setModal(true);
214 int result = m_fileChooser->exec();
215 if (result == QDialog::Accepted) {
216 QStringList selectedFiles = m_fileChooser->selectedFiles();
217 if (selectedFiles.count() > 0) {
218 fileName = selectedFiles[0];
219 }
220 }
221 delete m_fileChooser;
222 m_fileChooser = 0;
223 } else {
224 m_fileChooser->raise();
225 }
226
227 return fileName;
228}
229
230QList<QUrl> MediaPlayer::copyFiles(const QList<QUrl> &urls)185QList<QUrl> MediaPlayer::copyFiles(const QList<QUrl> &urls)
231{186{
232 static QString moviesDir = QStandardPaths::writableLocation(QStandardPaths::MoviesLocation);187 static QString moviesDir = QStandardPaths::writableLocation(QStandardPaths::MoviesLocation);
233188
=== modified file 'src/mediaplayer.h'
--- src/mediaplayer.h 2016-01-20 15:44:22 +0000
+++ src/mediaplayer.h 2017-03-21 19:39:57 +0000
@@ -25,7 +25,6 @@
25class MediaPlayer : public QApplication25class MediaPlayer : public QApplication
26{26{
27 Q_OBJECT27 Q_OBJECT
28 Q_PROPERTY(bool desktopMode READ isDesktopMode CONSTANT)
2928
30public:29public:
31 MediaPlayer(int &argc, char **argv);30 MediaPlayer(int &argc, char **argv);
@@ -38,13 +37,10 @@
38 void leaveFullScreen();37 void leaveFullScreen();
39 void onWidthChanged(int);38 void onWidthChanged(int);
40 void onHeightChanged(int);39 void onHeightChanged(int);
41 bool isDesktopMode() const;
42 QUrl chooseFile();
43 QList<QUrl> copyFiles(const QList<QUrl> &urls);40 QList<QUrl> copyFiles(const QList<QUrl> &urls);
4441
45private:42private:
46 QQuickView *m_view;43 QQuickView *m_view;
47 QFileDialog *m_fileChooser;
48};44};
4945
50#endif // MEDIAPLAYER_H46#endif // MEDIAPLAYER_H
5147
=== added file 'src/qml/VideoImport.qml'
--- src/qml/VideoImport.qml 1970-01-01 00:00:00 +0000
+++ src/qml/VideoImport.qml 2017-03-21 19:39:57 +0000
@@ -0,0 +1,40 @@
1/*
2 * Copyright (C) 2012-2016 Canonical, Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17import QtQuick 2.4
18
19import Ubuntu.Components 1.3
20import Ubuntu.Components.Popups 1.3
21
22Item {
23 id: root
24
25 property var importDialog: null
26
27 signal videoReceived(string videoUrl)
28
29 function requestVideo()
30 {
31 if (!root.importDialog) {
32 root.importDialog = PopupUtils.open(Qt.resolvedUrl("VideoImportDialog.qml"), null)
33 root.importDialog.videoReceived.connect(root.videoReceived)
34 root.importDialog.destruction.connect(function () {root.importDialog = null})
35
36 } else {
37 console.warn("Import dialog already running")
38 }
39 }
40}
041
=== added file 'src/qml/VideoImportDialog.qml'
--- src/qml/VideoImportDialog.qml 1970-01-01 00:00:00 +0000
+++ src/qml/VideoImportDialog.qml 2017-03-21 19:39:57 +0000
@@ -0,0 +1,98 @@
1/*
2 * Copyright (C) 2016 Canonical, Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17import QtQuick 2.4
18
19import Ubuntu.Components 1.3
20import Ubuntu.Components.Popups 1.3
21import Ubuntu.Content 1.3
22
23PopupBase {
24 id: dialogue
25
26 property alias activeTransfer: signalConnections.target
27 signal videoReceived(string videoUrl)
28 signal destruction()
29
30 parent: QuickUtils.rootItem(this)
31 focus: true
32
33 Rectangle {
34 anchors.fill: parent
35
36 ContentTransferHint {
37 anchors.fill: parent
38 activeTransfer: dialogue.activeTransfer
39 }
40
41 ContentPeerPicker {
42 id: peerPicker
43
44 anchors.fill: parent
45 contentType: ContentType.Videos
46 handler: ContentHandler.Source
47
48 onPeerSelected: {
49 peer.selectionType = ContentTransfer.Single
50 dialogue.activeTransfer = peer.request()
51 }
52
53 onCancelPressed: {
54 PopupUtils.close(dialogue)
55 }
56 }
57 }
58
59 Connections {
60 id: signalConnections
61
62 onStateChanged: {
63 var done = ((dialogue.activeTransfer.state === ContentTransfer.Charged) ||
64 (dialogue.activeTransfer.state === ContentTransfer.Aborted))
65
66 if (dialogue.activeTransfer.state === ContentTransfer.Charged) {
67 if (dialogue.activeTransfer.items.length > 0) {
68 dialogue.videoReceived(dialogue.activeTransfer.items[0].url)
69 }
70 }
71
72 if (done) {
73 acceptTimer.restart()
74 }
75 }
76 }
77
78 // WORKAROUND: Work around for application becoming insensitive to touch events
79 // if the dialog is dismissed while the application is inactive.
80 // Just listening for changes to Qt.application.active doesn't appear
81 // to be enough to resolve this, so it seems that something else needs
82 // to be happening first. As such there's a potential for a race
83 // condition here, although as yet no problem has been encountered.
84 Timer {
85 id: acceptTimer
86
87 interval: 100
88 repeat: true
89 running: false
90 onTriggered: {
91 if(Qt.application.state === Qt.ApplicationActive) {
92 PopupUtils.close(dialogue)
93 }
94 }
95 }
96
97 Component.onDestruction: dialogue.destruction()
98}
099
=== modified file 'src/qml/player.qml'
--- src/qml/player.qml 2016-01-26 14:48:04 +0000
+++ src/qml/player.qml 2017-03-21 19:39:57 +0000
@@ -25,7 +25,7 @@
25import Ubuntu.Unity.Action 1.1 as UnityActions25import Ubuntu.Unity.Action 1.1 as UnityActions
26import Ubuntu.Components 1.326import Ubuntu.Components 1.3
27import Ubuntu.Components.Popups 1.0 as Popups27import Ubuntu.Components.Popups 1.0 as Popups
28import Ubuntu.Content 0.1 as ContentHub28import Ubuntu.Content 1.3
2929
30Item {30Item {
31 id: mediaPlayer31 id: mediaPlayer
@@ -38,15 +38,25 @@
38 property bool appActive: Qt.application.active38 property bool appActive: Qt.application.active
39 property variant nativeOrientation: Screen.primaryOrientation39 property variant nativeOrientation: Screen.primaryOrientation
4040
41 onAppActiveChanged: {41 function pickAFile()
42 if (!appActive &&42 {
43 !mpApplication.desktopMode &&43 if (playerLoader.item.playing)
44 playerLoader.item &&
45 playerLoader.item.playing) {
46 playerLoader.item.pause()44 playerLoader.item.pause()
47 }45 videoImport.requestVideo()
48 }46 }
4947
48// FIXME: For now keep the video playing even if the app is not active
49// Wait for a better app life cycle to inform if the app will be suspended or not
50//
51// onAppActiveChanged: {
52// if (!appActive &&
53// !mpApplication.desktopMode &&
54// playerLoader.item &&
55// playerLoader.item.playing) {
56// playerLoader.item.pause()
57// }
58// }
59
50 Screen.onOrientationChanged: {60 Screen.onOrientationChanged: {
51 // Rotate the UI when the device orientation changes61 // Rotate the UI when the device orientation changes
52 mediaPlayer.orientation = Screen.angleBetween(Screen.primaryOrientation, Screen.orientation)62 mediaPlayer.orientation = Screen.angleBetween(Screen.primaryOrientation, Screen.orientation)
@@ -170,6 +180,7 @@
170 playerLoader.item.controlsActive = true180 playerLoader.item.controlsActive = true
171 }181 }
172 }182 }
183 onPlayEmptyFile: mediaPlayer.pickAFile()
173 }184 }
174185
175 UnityActions.ActionManager {186 UnityActions.ActionManager {
@@ -225,10 +236,10 @@
225 }236 }
226237
227 Connections {238 Connections {
228 target: ContentHub.ContentHub239 target: ContentHub
229 onImportRequested: {240 onImportRequested: {
230 lateUrlCheck.stop()241 lateUrlCheck.stop()
231 if (transfer.state === ContentHub.ContentTransfer.Charged) {242 if (transfer.state === ContentTransfer.Charged) {
232 var urls = []243 var urls = []
233 for(var i=0; i < transfer.items.length; i++) {244 for(var i=0; i < transfer.items.length; i++) {
234 urls.push(transfer.items[i].url)245 urls.push(transfer.items[i].url)
@@ -241,6 +252,14 @@
241 }252 }
242 }253 }
243254
255 VideoImport {
256 id: videoImport
257
258 onVideoReceived: {
259 playerLoader.item.playUri(videoUrl)
260 }
261 }
262
244 Timer {263 Timer {
245 id: lateUrlCheck264 id: lateUrlCheck
246265
@@ -248,15 +267,8 @@
248 repeat: false267 repeat: false
249 running: true268 running: true
250 onTriggered: {269 onTriggered: {
251 if ((playUri == "") && !ContentHub.ContentHub.hasPending) {270 if (playerLoader.item && (playerLoader.item.source == "") && !ContentHub.hasPending) {
252 if (mpApplication.desktopMode) {271 mediaPlayer.pickAFile()
253 var videoFile = mpApplication.chooseFile()
254 if (videoFile != "") {
255 playerLoader.item.playUri(videoFile)
256 }
257 } else {
258 PopupUtils.open(dialogNoUrl, null)
259 }
260 }272 }
261 }273 }
262 }274 }
263275
=== modified file 'src/qml/player/Controls.qml'
--- src/qml/player/Controls.qml 2016-11-22 20:22:15 +0000
+++ src/qml/player/Controls.qml 2017-03-21 19:39:57 +0000
@@ -35,11 +35,12 @@
35 property variant playerStatus: MediaPlayer.NoMedia35 property variant playerStatus: MediaPlayer.NoMedia
3636
37 property alias finalSeekPosition: _timeline.finalSeekPosition37 property alias finalSeekPosition: _timeline.finalSeekPosition
38 property alias settingsEnabled: _settingsButton.enabled38 property alias openFileEnabled: _openFileButton.enabled
3939
40 signal fullscreenClicked40 signal fullscreenClicked
41 signal playbackClicked41 signal playbackClicked
42 signal settingsClicked42 signal settingsClicked
43 signal openFileClicked
43 signal shareClicked44 signal shareClicked
44 signal seekRequested(int time)45 signal seekRequested(int time)
45 signal startSeek46 signal startSeek
@@ -153,12 +154,7 @@
153 IconButton {154 IconButton {
154 id: _fullScreenButton155 id: _fullScreenButton
155156
156 //TODO: use the correct icon based on window state157 iconSource: Window.visibility === Window.FullScreen ? "image://theme/view-restore" : "image://theme/view-fullscreen"
157// visible: (mpApplication.desktopMode || (Window.visibility === Window.FullScreen))
158// iconSource: mpApplication.desktopMode ?
159// Window.visibility === Window.FullScreen ? "image://theme/view-restore" : "image://theme/view-fullscreen" :
160// "image://theme/close"
161 iconSource: mpApplication.desktopMode ? "image://theme/view-fullscreen" : "image://theme/close"
162 iconSize: units.gu(3)158 iconSize: units.gu(3)
163 anchors.verticalCenter: parent.verticalCenter159 anchors.verticalCenter: parent.verticalCenter
164 width: visible ? units.gu(8) : 0160 width: visible ? units.gu(8) : 0
@@ -184,7 +180,8 @@
184 _fullScreenButton.width -180 _fullScreenButton.width -
185 _timeLabel.width -181 _timeLabel.width -
186 _shareButton.width -182 _shareButton.width -
187 _settingsButton.width183 _openFileButton.width -
184 _quitButton.width
188185
189 height: units.gu(4)186 height: units.gu(4)
190 onClicked: controls.playbackClicked()187 onClicked: controls.playbackClicked()
@@ -206,9 +203,8 @@
206 playbackButton.width -203 playbackButton.width -
207 _timeLabel.width -204 _timeLabel.width -
208 _shareButton.width -205 _shareButton.width -
209 _settingsButton.width -206 _openFileButton.width -
210 units.gu(2) : 0207 _quitButton.width : 0
211
212208
213 TimeLine {209 TimeLine {
214 id: _timeline210 id: _timeline
@@ -297,14 +293,14 @@
297 }293 }
298294
299 VLine {295 VLine {
300 visible: _settingsButton.visible296 visible: _openFileButton.visible
301 }297 }
302298
303 IconButton {299 IconButton {
304 id: _settingsButton300 id: _openFileButton
305301
306 visible: false302 visible: enabled
307 iconSource: "artwork/icon_settings.png"303 iconSource: "image://theme/document-open"
308 iconSize: units.gu(3)304 iconSize: units.gu(3)
309 anchors {305 anchors {
310 top: parent.top306 top: parent.top
@@ -313,7 +309,22 @@
313 width: visible ? units.gu(7) : 0309 width: visible ? units.gu(7) : 0
314 enabled: false310 enabled: false
315 opacity: enabled ? 1.0 : 0.2311 opacity: enabled ? 1.0 : 0.2
316 onClicked: settingsClicked()312 onClicked: openFileClicked()
313 }
314
315 VLine {}
316
317 IconButton {
318 id: _quitButton
319
320 iconSource: "image://theme/close"
321 iconSize: units.gu(3)
322 anchors {
323 top: parent.top
324 bottom: parent.bottom
325 }
326 width: units.gu(7)
327 onClicked: Qt.quit()
317 }328 }
318 }329 }
319 }330 }
320331
=== modified file 'src/qml/player/VideoPlayer.qml'
--- src/qml/player/VideoPlayer.qml 2016-02-19 11:14:53 +0000
+++ src/qml/player/VideoPlayer.qml 2017-03-21 19:39:57 +0000
@@ -28,20 +28,21 @@
28AbstractPlayer {28AbstractPlayer {
29 id: player29 id: player
3030
31 property variant nfo31 property variant info
32 property int pressCount: 032 property int pressCount: 0
33 property bool wasPlaying: false33 property bool wasPlaying: false
34 property string uri
35 property bool rotating: false34 property bool rotating: false
36 property alias controlsActive: _controls.active35 property alias controlsActive: _controls.active
37 property bool componentLoaded: false36 property bool componentLoaded: false
38 readonly property int seekStep: 100037 readonly property int seekStep: 1000
38 readonly property bool isEmpty: source == ""
39 property var errorDialog: null39 property var errorDialog: null
4040
41 signal timeClicked41 signal timeClicked
42 signal playEmptyFile
4243
43 objectName: "player"44 objectName: "player"
44 nfo: VideoInfo {45 info: VideoInfo {
45 uri: source46 uri: source
46 }47 }
4748
@@ -134,8 +135,7 @@
134 player.video.seek(time)135 player.video.seek(time)
135 }136 }
136137
137 settingsEnabled: mpApplication.desktopMode138 openFileEnabled: true
138
139 objectName: "controls"139 objectName: "controls"
140 state: player.state140 state: player.state
141 video: player.video141 video: player.video
@@ -149,46 +149,79 @@
149 sceneSelectorHeight: units.gu(18)149 sceneSelectorHeight: units.gu(18)
150 playerStatus: player.status150 playerStatus: player.status
151151
152 onPlaybackClicked: player.playPause()152 onPlaybackClicked: {
153153 if (player.source == "") {
154 onFullscreenClicked: {154 player.playEmptyFile()
155 if (mpApplication.desktopMode) {
156 mpApplication.toggleFullscreen()
157 } else {155 } else {
158 Qt.quit()156 player.playPause()
159 }157 }
160 }158 }
161159
160 onFullscreenClicked: mpApplication.toggleFullscreen()
161 onOpenFileClicked: player.playEmptyFile()
162 onStartSeek: aboutToSeek()162 onStartSeek: aboutToSeek()
163 onEndSeek: seekDone()163 onEndSeek: seekDone()
164 onSeekRequested: seek(time)164 onSeekRequested: seek(time)
165
166 onSettingsClicked: {
167 if (mpApplication.desktopMode) {
168 var videoFile = mpApplication.chooseFile()
169 if (videoFile != "") {
170 player.stop()
171 item.playUri(videoFile)
172 }
173 }
174 }
175 }165 }
176 }166 }
177167
178 MouseArea {168 MouseArea {
179 id: _mouseArea169 id: _mouseArea
180170
181 objectName: "videoMouseArea"171 objectName: "videoMouseArea"
172 anchors {
173 left: parent.left
174 right: parent.right
175 top: parent.top
176 bottom: _controls.top
177 }
178 onClicked: _controls.active = !_controls.active
179 }
180
181 Item {
182 id: emptyState
183
184 anchors.fill: parent
185 visible: false
186 Icon {
187 id: emptyStateIcon
188
189 source: "image://theme/document-open"
190 color: "white"
191 anchors.centerIn: parent
192 width: units.gu(4)
193 }
194 Label {
195 text: i18n.tr("Please choose a file to open")
196 color: "white"
197 textSize: Label.Large
182 anchors {198 anchors {
183 left: parent.left199 horizontalCenter: parent.horizontalCenter
184 right: parent.right200 top: emptyStateIcon.bottom
185 top: parent.top201 topMargin: units.gu(2)
186 bottom: _controls.top202 }
187 }203 }
188204 }
189 onClicked: _controls.active = !_controls.active205
190 }206 state: player.isEmpty ? "empty" : ""
191207 states: [
208 State {
209 name: "empty"
210 PropertyChanges {
211 target: _controls
212 active: true
213 }
214 PropertyChanges {
215 target: emptyState
216 visible: true
217 }
218 PropertyChanges {
219 target: _mouseArea
220 enabled: false
221 }
222 }
223
224 ]
192225
193 Keys.onReleased:226 Keys.onReleased:
194 {227 {
195228
=== modified file 'tests/unittest/tst_video_player.qml'
--- tests/unittest/tst_video_player.qml 2016-09-26 23:12:42 +0000
+++ tests/unittest/tst_video_player.qml 2017-03-21 19:39:57 +0000
@@ -75,6 +75,21 @@
75 tryCompare(player, 'paused', false)75 tryCompare(player, 'paused', false)
76 tryCompare(player, 'playing', false)76 tryCompare(player, 'playing', false)
77 tryCompare(player, 'wasPlaying', false)77 tryCompare(player, 'wasPlaying', false)
78 tryCompare(player, 'isEmpty', true)
79 }
80
81 function test_empty_state()
82 {
83 tryCompare(player, 'isEmpty', true)
84 tryCompare(player, 'controlsActive', true)
85
86 // test if controls stay active after click on empty state
87 mouseClick(player)
88 tryCompare(player, 'controlsActive', true)
89
90 // play any uri should leave empty state
91 player.playUri(videUri)
92 tryCompare(player, 'isEmpty', false)
78 }93 }
7994
80 function test_open_video()95 function test_open_video()
@@ -87,6 +102,8 @@
87 function test_play_pause_video()102 function test_play_pause_video()
88 {103 {
89 player.playUri(videUri)104 player.playUri(videUri)
105
106 tryCompare(player, 'isEmpty', false)
90 tryCompare(player, 'playing', true)107 tryCompare(player, 'playing', true)
91 player.playPause()108 player.playPause()
92 tryCompare(player, 'paused', true)109 tryCompare(player, 'paused', true)
@@ -98,6 +115,7 @@
98 {115 {
99 player.playUri(videUri)116 player.playUri(videUri)
100 tryCompare(player, 'playing', true)117 tryCompare(player, 'playing', true)
118 tryCompare(player, 'controlsActive', false)
101119
102 mouseClick(player)120 mouseClick(player)
103 tryCompare(player, 'controlsActive', true)121 tryCompare(player, 'controlsActive', true)
@@ -126,7 +144,6 @@
126 tryCompare(player, 'paused', true)144 tryCompare(player, 'paused', true)
127 }145 }
128146
129
130 function test_play_after_pause()147 function test_play_after_pause()
131 {148 {
132 // play video149 // play video

Subscribers

People subscribed via source and target branches