Merge lp:~renatofilho/mediaplayer-app/pocket-pc into lp:mediaplayer-app
- pocket-pc
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Bill Filler |
Approved revision: | 398 |
Merged at revision: | 386 |
Proposed branch: | lp:~renatofilho/mediaplayer-app/pocket-pc |
Merge into: | lp:mediaplayer-app |
Diff against target: |
558 lines (+322/-54) 9 files modified
data/CMakeLists.txt (+5/-0) data/mediaplayer-app-content.json (+5/-0) debian/mediaplayer-app.install (+1/-0) src/mediaplayer.cpp (+55/-0) src/mediaplayer.h (+1/-0) src/qml/player.qml (+42/-16) src/qml/player/Controls.qml (+6/-3) src/qml/player/ToolBar.qml (+122/-0) src/qml/player/VideoPlayer.qml (+85/-35) |
To merge this branch: | bzr merge lp:~renatofilho/mediaplayer-app/pocket-pc |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot | continuous-integration | Needs Fixing | |
Ubuntu Phablet Team | Pending | ||
Review via email: mp+283299@code.launchpad.net |
Commit message
*Implement support for content hub.
*Use themed icons for full screen button.
Description of the change
PS Jenkins bot (ps-jenkins) wrote : | # |
- 384. By Renato Araujo Oliveira Filho
-
Implement support for content hub.
Copy imported files to user video dir and play the video.
- 385. By Renato Araujo Oliveira Filho
-
Does not show the empty ulr dialgo if the app was launched by content hub.
- 386. By Renato Araujo Oliveira Filho
-
Does not set the app visibility to defaul on app startup.
- 387. By Renato Araujo Oliveira Filho
-
Pause video before start sekking to avoid problems with the player.
- 388. By Renato Araujo Oliveira Filho
-
Wait the app full load before check for empty url.
Avoid problems with content hub hasPending property.
- 389. By Renato Araujo Oliveira Filho
-
Fixed wrong return for copyFiles function.
Apped the newFile path into the result list.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:386
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 390. By Renato Araujo Oliveira Filho
-
Check if the app was launched by content hub a bit late, to give it some time to load.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:389
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 391. By Renato Araujo Oliveira Filho
-
Fixed seek with media-hub.
Keep track of seek position to use in consecutives seek operation.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:390
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:391
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 392. By Renato Araujo Oliveira Filho
-
Created a toolbar component to allow us to control the hide/show animation.
Make sure that the controls are visible before start seeking.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:392
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 393. By Renato Araujo Oliveira Filho
-
Remove unecessary mouser area.
- 394. By Renato Araujo Oliveira Filho
-
Remove debug message.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:394
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 395. By Renato Araujo Oliveira Filho
-
Reduce controls timeout.
Fix control dissapearing after a seek.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:395
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 396. By Renato Araujo Oliveira Filho
-
Updated toolbar behaviour.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:396
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 397. By Renato Araujo Oliveira Filho
-
Trunk merged.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:397
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 398. By Renato Araujo Oliveira Filho
-
Revert changes on play/pause behavior.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:398
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Preview Diff
1 | === modified file 'data/CMakeLists.txt' | |||
2 | --- data/CMakeLists.txt 2014-10-02 13:42:17 +0000 | |||
3 | +++ data/CMakeLists.txt 2016-01-26 22:05:58 +0000 | |||
4 | @@ -2,6 +2,7 @@ | |||
5 | 2 | set(MEDIAPLAYER_APP_ICON mediaplayer-app.png) | 2 | set(MEDIAPLAYER_APP_ICON mediaplayer-app.png) |
6 | 3 | set(MEDIAPLAYER_APP_SYMBOLIC_ICON mediaplayer-app-symbolic.svg) | 3 | set(MEDIAPLAYER_APP_SYMBOLIC_ICON mediaplayer-app-symbolic.svg) |
7 | 4 | set(MEDIAPLAYER_URL_DISPATCHER mediaplayer-app.url-dispatcher) | 4 | set(MEDIAPLAYER_URL_DISPATCHER mediaplayer-app.url-dispatcher) |
8 | 5 | set(MEDIAPLAYER_CONTENT_HUB mediaplayer-app-content.json) | ||
9 | 5 | 6 | ||
10 | 6 | configure_file(${DESKTOP_FILE}.in.in ${DESKTOP_FILE}.in) | 7 | configure_file(${DESKTOP_FILE}.in.in ${DESKTOP_FILE}.in) |
11 | 7 | add_custom_target(${DESKTOP_FILE} ALL | 8 | add_custom_target(${DESKTOP_FILE} ALL |
12 | @@ -20,3 +21,7 @@ | |||
13 | 20 | install(FILES ${MEDIAPLAYER_URL_DISPATCHER} | 21 | install(FILES ${MEDIAPLAYER_URL_DISPATCHER} |
14 | 21 | DESTINATION ${CMAKE_INSTALL_DATADIR}/url-dispatcher/urls | 22 | DESTINATION ${CMAKE_INSTALL_DATADIR}/url-dispatcher/urls |
15 | 22 | ) | 23 | ) |
16 | 24 | |||
17 | 25 | install(FILES ${MEDIAPLAYER_CONTENT_HUB} | ||
18 | 26 | DESTINATION ${CMAKE_INSTALL_DATADIR}/content-hub/peers | ||
19 | 27 | RENAME mediaplayer-app) | ||
20 | 23 | 28 | ||
21 | === added file 'data/mediaplayer-app-content.json' | |||
22 | --- data/mediaplayer-app-content.json 1970-01-01 00:00:00 +0000 | |||
23 | +++ data/mediaplayer-app-content.json 2016-01-26 22:05:58 +0000 | |||
24 | @@ -0,0 +1,5 @@ | |||
25 | 1 | { | ||
26 | 2 | "destination": [ | ||
27 | 3 | "videos" | ||
28 | 4 | ] | ||
29 | 5 | } | ||
30 | 0 | 6 | ||
31 | === modified file 'debian/mediaplayer-app.install' | |||
32 | --- debian/mediaplayer-app.install 2014-09-29 20:53:44 +0000 | |||
33 | +++ debian/mediaplayer-app.install 2016-01-26 22:05:58 +0000 | |||
34 | @@ -5,3 +5,4 @@ | |||
35 | 5 | /usr/share/mediaplayer-app/qml/* | 5 | /usr/share/mediaplayer-app/qml/* |
36 | 6 | /usr/share/locale/*/LC_MESSAGES/mediaplayer-app.mo | 6 | /usr/share/locale/*/LC_MESSAGES/mediaplayer-app.mo |
37 | 7 | /usr/share/url-dispatcher/urls/* | 7 | /usr/share/url-dispatcher/urls/* |
38 | 8 | /usr/share/content-hub/peers/mediaplayer-app | ||
39 | 8 | 9 | ||
40 | === modified file 'src/mediaplayer.cpp' | |||
41 | --- src/mediaplayer.cpp 2016-01-05 15:12:20 +0000 | |||
42 | +++ src/mediaplayer.cpp 2016-01-26 22:05:58 +0000 | |||
43 | @@ -25,6 +25,7 @@ | |||
44 | 25 | #include <QtCore/QLibrary> | 25 | #include <QtCore/QLibrary> |
45 | 26 | #include <QtCore/QTimer> | 26 | #include <QtCore/QTimer> |
46 | 27 | #include <QtCore/QStandardPaths> | 27 | #include <QtCore/QStandardPaths> |
47 | 28 | #include <QtCore/QMimeDatabase> | ||
48 | 28 | #include <QtWidgets/QFileDialog> | 29 | #include <QtWidgets/QFileDialog> |
49 | 29 | #include <QtQml/QQmlContext> | 30 | #include <QtQml/QQmlContext> |
50 | 30 | #include <QtQml/QQmlEngine> | 31 | #include <QtQml/QQmlEngine> |
51 | @@ -216,3 +217,57 @@ | |||
52 | 216 | 217 | ||
53 | 217 | return fileName; | 218 | return fileName; |
54 | 218 | } | 219 | } |
55 | 220 | |||
56 | 221 | QList<QUrl> MediaPlayer::copyFiles(const QList<QUrl> &urls) | ||
57 | 222 | { | ||
58 | 223 | static QString moviesDir = QStandardPaths::writableLocation(QStandardPaths::MoviesLocation); | ||
59 | 224 | |||
60 | 225 | QList<QUrl> result; | ||
61 | 226 | |||
62 | 227 | Q_FOREACH(const QUrl &url, urls) { | ||
63 | 228 | if (!url.isLocalFile()) { | ||
64 | 229 | qWarning() << "Remote files not supported:" << url; | ||
65 | 230 | continue; | ||
66 | 231 | } | ||
67 | 232 | |||
68 | 233 | QFileInfo originalFile(url.toLocalFile()); | ||
69 | 234 | |||
70 | 235 | QString filename = originalFile.fileName(); | ||
71 | 236 | QString suffix = originalFile.completeSuffix(); | ||
72 | 237 | QString filenameWithoutSuffix; | ||
73 | 238 | if (suffix.isEmpty()) { | ||
74 | 239 | QMimeDatabase mdb; | ||
75 | 240 | QMimeType mt = mdb.mimeTypeForFile(originalFile.absoluteFilePath()); | ||
76 | 241 | |||
77 | 242 | // If the filename doesn't have an extension add one from the | ||
78 | 243 | // detected mimetype | ||
79 | 244 | if(!mt.preferredSuffix().isEmpty()) { | ||
80 | 245 | suffix = mt.preferredSuffix(); | ||
81 | 246 | } | ||
82 | 247 | filenameWithoutSuffix = filename; | ||
83 | 248 | } else { | ||
84 | 249 | filenameWithoutSuffix = originalFile.baseName(); | ||
85 | 250 | } | ||
86 | 251 | |||
87 | 252 | QFileInfo newFile(moviesDir, QString("%1.%2").arg(filenameWithoutSuffix).arg(suffix)); | ||
88 | 253 | if (newFile.exists()) { | ||
89 | 254 | // find a alternative name | ||
90 | 255 | int index = 1; | ||
91 | 256 | do { | ||
92 | 257 | newFile = QFileInfo(moviesDir, | ||
93 | 258 | QString("%1(%2).%3") | ||
94 | 259 | .arg(filenameWithoutSuffix) | ||
95 | 260 | .arg(index) | ||
96 | 261 | .arg(suffix)); | ||
97 | 262 | index++; | ||
98 | 263 | } while (newFile.exists()); | ||
99 | 264 | } | ||
100 | 265 | |||
101 | 266 | if (QFile::copy(originalFile.absoluteFilePath(), newFile.absoluteFilePath())) { | ||
102 | 267 | result << QUrl::fromLocalFile(newFile.absoluteFilePath()); | ||
103 | 268 | } else { | ||
104 | 269 | qWarning() << "Fail to copy file from:" << originalFile.absoluteFilePath() << "to" << newFile.absoluteFilePath(); | ||
105 | 270 | } | ||
106 | 271 | } | ||
107 | 272 | return result; | ||
108 | 273 | } | ||
109 | 219 | 274 | ||
110 | === modified file 'src/mediaplayer.h' | |||
111 | --- src/mediaplayer.h 2014-02-13 18:26:52 +0000 | |||
112 | +++ src/mediaplayer.h 2016-01-26 22:05:58 +0000 | |||
113 | @@ -40,6 +40,7 @@ | |||
114 | 40 | void onHeightChanged(int); | 40 | void onHeightChanged(int); |
115 | 41 | bool isDesktopMode() const; | 41 | bool isDesktopMode() const; |
116 | 42 | QUrl chooseFile(); | 42 | QUrl chooseFile(); |
117 | 43 | QList<QUrl> copyFiles(const QList<QUrl> &urls); | ||
118 | 43 | 44 | ||
119 | 44 | private: | 45 | private: |
120 | 45 | QQuickView *m_view; | 46 | QQuickView *m_view; |
121 | 46 | 47 | ||
122 | === modified file 'src/qml/player.qml' | |||
123 | --- src/qml/player.qml 2015-04-28 18:56:10 +0000 | |||
124 | +++ src/qml/player.qml 2016-01-26 22:05:58 +0000 | |||
125 | @@ -25,6 +25,7 @@ | |||
126 | 25 | import Ubuntu.Unity.Action 1.1 as UnityActions | 25 | import Ubuntu.Unity.Action 1.1 as UnityActions |
127 | 26 | import Ubuntu.Components 1.1 | 26 | import Ubuntu.Components 1.1 |
128 | 27 | import Ubuntu.Components.Popups 1.0 as Popups | 27 | import Ubuntu.Components.Popups 1.0 as Popups |
129 | 28 | import Ubuntu.Content 0.1 as ContentHub | ||
130 | 28 | 29 | ||
131 | 29 | Item { | 30 | Item { |
132 | 30 | id: mediaPlayer | 31 | id: mediaPlayer |
133 | @@ -35,7 +36,6 @@ | |||
134 | 35 | property string formFactor: "phone" | 36 | property string formFactor: "phone" |
135 | 36 | property real volume: playerLoader.item.volume | 37 | property real volume: playerLoader.item.volume |
136 | 37 | property bool appActive: Qt.application.active | 38 | property bool appActive: Qt.application.active |
137 | 38 | |||
138 | 39 | property variant nativeOrientation: Screen.primaryOrientation | 39 | property variant nativeOrientation: Screen.primaryOrientation |
139 | 40 | 40 | ||
140 | 41 | onAppActiveChanged: { | 41 | onAppActiveChanged: { |
141 | @@ -84,16 +84,8 @@ | |||
142 | 84 | item.focus = true | 84 | item.focus = true |
143 | 85 | item.rotating = Qt.binding(function () { return rotatingTransition.running } ) | 85 | item.rotating = Qt.binding(function () { return rotatingTransition.running } ) |
144 | 86 | if (playUri != "") { | 86 | if (playUri != "") { |
145 | 87 | lateUrlCheck.stop() | ||
146 | 87 | item.playUri(playUri) | 88 | item.playUri(playUri) |
147 | 88 | } else { | ||
148 | 89 | if (mpApplication.desktopMode) { | ||
149 | 90 | var videoFile = mpApplication.chooseFile() | ||
150 | 91 | if (videoFile != "") { | ||
151 | 92 | item.playUri(videoFile) | ||
152 | 93 | } | ||
153 | 94 | } else { | ||
154 | 95 | PopupUtils.open(dialogNoUrl, null) | ||
155 | 96 | } | ||
156 | 97 | } | 89 | } |
157 | 98 | } | 90 | } |
158 | 99 | 91 | ||
159 | @@ -212,14 +204,10 @@ | |||
160 | 212 | } | 204 | } |
161 | 213 | 205 | ||
162 | 214 | Keys.onReleased: { | 206 | Keys.onReleased: { |
168 | 215 | if (!event.isAutoRepeat | 207 | if (!event.isAutoRepeat && event.key === Qt.Key_BracketLeft) { |
164 | 216 | && (event.key == Qt.Key_F11 || event.key == Qt.Key_F)) { | ||
165 | 217 | event.accepted = true | ||
166 | 218 | application.toggleFullscreen(); | ||
167 | 219 | } else if (!event.isAutoRepeat && event.key == Qt.Key_BracketLeft) { | ||
169 | 220 | event.accepted = true | 208 | event.accepted = true |
170 | 221 | rotateClockwise() | 209 | rotateClockwise() |
172 | 222 | } else if (!event.isAutoRepeat && event.key == Qt.Key_BracketRight) { | 210 | } else if (!event.isAutoRepeat && event.key === Qt.Key_BracketRight) { |
173 | 223 | event.accepted = true | 211 | event.accepted = true |
174 | 224 | rotateCounterClockwise() | 212 | rotateCounterClockwise() |
175 | 225 | } | 213 | } |
176 | @@ -229,9 +217,47 @@ | |||
177 | 229 | target: UriHandler | 217 | target: UriHandler |
178 | 230 | onOpened: { | 218 | onOpened: { |
179 | 231 | for (var i = 0; i < uris.length; ++i) { | 219 | for (var i = 0; i < uris.length; ++i) { |
180 | 220 | lateUrlCheck.stop() | ||
181 | 232 | var videoUri = uris[i].replace("video://", "file://") | 221 | var videoUri = uris[i].replace("video://", "file://") |
182 | 233 | playerLoader.item.playUri(videoUri) | 222 | playerLoader.item.playUri(videoUri) |
183 | 234 | } | 223 | } |
184 | 235 | } | 224 | } |
185 | 236 | } | 225 | } |
186 | 226 | |||
187 | 227 | Connections { | ||
188 | 228 | target: ContentHub.ContentHub | ||
189 | 229 | onImportRequested: { | ||
190 | 230 | lateUrlCheck.stop() | ||
191 | 231 | if (transfer.state === ContentHub.ContentTransfer.Charged) { | ||
192 | 232 | var urls = [] | ||
193 | 233 | for(var i=0; i < transfer.items.length; i++) { | ||
194 | 234 | urls.push(transfer.items[i].url) | ||
195 | 235 | } | ||
196 | 236 | |||
197 | 237 | var result = mpApplication.copyFiles(urls); | ||
198 | 238 | if (result.length > 0) | ||
199 | 239 | playerLoader.item.playUri(result[result.length - 1]) | ||
200 | 240 | } | ||
201 | 241 | } | ||
202 | 242 | } | ||
203 | 243 | |||
204 | 244 | Timer { | ||
205 | 245 | id: lateUrlCheck | ||
206 | 246 | |||
207 | 247 | interval: 1000 | ||
208 | 248 | repeat: false | ||
209 | 249 | running: true | ||
210 | 250 | onTriggered: { | ||
211 | 251 | if ((playUri == "") && !ContentHub.ContentHub.hasPending) { | ||
212 | 252 | if (mpApplication.desktopMode) { | ||
213 | 253 | var videoFile = mpApplication.chooseFile() | ||
214 | 254 | if (videoFile != "") { | ||
215 | 255 | playerLoader.item.playUri(videoFile) | ||
216 | 256 | } | ||
217 | 257 | } else { | ||
218 | 258 | PopupUtils.open(dialogNoUrl, null) | ||
219 | 259 | } | ||
220 | 260 | } | ||
221 | 261 | } | ||
222 | 262 | } | ||
223 | 237 | } | 263 | } |
224 | 238 | 264 | ||
225 | === modified file 'src/qml/player/Controls.qml' | |||
226 | --- src/qml/player/Controls.qml 2015-03-20 17:34:56 +0000 | |||
227 | +++ src/qml/player/Controls.qml 2016-01-26 22:05:58 +0000 | |||
228 | @@ -19,6 +19,7 @@ | |||
229 | 19 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | 19 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
230 | 20 | */ | 20 | */ |
231 | 21 | import QtQuick 2.0 | 21 | import QtQuick 2.0 |
232 | 22 | import QtQuick.Window 2.2 | ||
233 | 22 | import QtMultimedia 5.0 | 23 | import QtMultimedia 5.0 |
234 | 23 | import Ubuntu.Components 1.1 | 24 | import Ubuntu.Components 1.1 |
235 | 24 | 25 | ||
236 | @@ -152,13 +153,16 @@ | |||
237 | 152 | id: _fullScreenButton | 153 | id: _fullScreenButton |
238 | 153 | 154 | ||
239 | 154 | //TODO: use the correct icon based on window state | 155 | //TODO: use the correct icon based on window state |
241 | 155 | iconSource: mpApplication.desktopMode ? "artwork/icon_exitfscreen.png" : "image://theme/back" | 156 | iconSource: mpApplication.desktopMode ? |
242 | 157 | Window.visibility === Window.FullScreen ? "image://theme/view-restore" : "image://theme/view-fullscreen" : | ||
243 | 158 | "image://theme/close" | ||
244 | 156 | iconSize: units.gu(3) | 159 | iconSize: units.gu(3) |
245 | 157 | anchors.verticalCenter: parent.verticalCenter | 160 | anchors.verticalCenter: parent.verticalCenter |
247 | 158 | width: units.gu(8) | 161 | width: visible ? units.gu(8) : 0 |
248 | 159 | height: units.gu(4) | 162 | height: units.gu(4) |
249 | 160 | onClicked: controls.fullscreenClicked() | 163 | onClicked: controls.fullscreenClicked() |
250 | 161 | leftAlignment: true | 164 | leftAlignment: true |
251 | 165 | visible: (mpApplication.desktopMode || (Window.visibility === Window.FullScreen)) | ||
252 | 162 | } | 166 | } |
253 | 163 | 167 | ||
254 | 164 | VLine { | 168 | VLine { |
255 | @@ -341,7 +345,6 @@ | |||
256 | 341 | Connections { | 345 | Connections { |
257 | 342 | target: controls | 346 | target: controls |
258 | 343 | onPlayerStatusChanged: { | 347 | onPlayerStatusChanged: { |
259 | 344 | console.debug("onPlayerStatusChanged") | ||
260 | 345 | _timeline.playerStatus = controls.playerStatus | 348 | _timeline.playerStatus = controls.playerStatus |
261 | 346 | } | 349 | } |
262 | 347 | } | 350 | } |
263 | 348 | 351 | ||
264 | === added file 'src/qml/player/ToolBar.qml' | |||
265 | --- src/qml/player/ToolBar.qml 1970-01-01 00:00:00 +0000 | |||
266 | +++ src/qml/player/ToolBar.qml 2016-01-26 22:05:58 +0000 | |||
267 | @@ -0,0 +1,122 @@ | |||
268 | 1 | /* | ||
269 | 2 | * Copyright (C) 2013 Canonical, Ltd. | ||
270 | 3 | * | ||
271 | 4 | * Authors: | ||
272 | 5 | * Renato Araujo Oliveira Filho <renato@canonical.com> | ||
273 | 6 | * | ||
274 | 7 | * This program is free software; you can redistribute it and/or modify | ||
275 | 8 | * it under the terms of the GNU General Public License as published by | ||
276 | 9 | * the Free Software Foundation; version 3. | ||
277 | 10 | * | ||
278 | 11 | * This program is distributed in the hope that it will be useful, | ||
279 | 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
280 | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
281 | 14 | * GNU General Public License for more details. | ||
282 | 15 | * | ||
283 | 16 | * You should have received a copy of the GNU General Public License | ||
284 | 17 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
285 | 18 | */ | ||
286 | 19 | |||
287 | 20 | import QtQuick 2.0 | ||
288 | 21 | import Ubuntu.Components 1.1 | ||
289 | 22 | |||
290 | 23 | |||
291 | 24 | MouseArea { | ||
292 | 25 | id: root | ||
293 | 26 | |||
294 | 27 | property bool active: false | ||
295 | 28 | readonly property alias aboutToDismiss: dismissControls.running | ||
296 | 29 | default property alias controls: contents.children | ||
297 | 30 | readonly property bool fullVisible: (spacer.height === 0) | ||
298 | 31 | |||
299 | 32 | function dismiss() | ||
300 | 33 | { | ||
301 | 34 | dismissControls.restart() | ||
302 | 35 | } | ||
303 | 36 | |||
304 | 37 | function abortDismiss() | ||
305 | 38 | { | ||
306 | 39 | dismissControls.stop() | ||
307 | 40 | active = true | ||
308 | 41 | } | ||
309 | 42 | |||
310 | 43 | onActiveChanged: dismissControls.stop() | ||
311 | 44 | |||
312 | 45 | hoverEnabled: true | ||
313 | 46 | onExited: dismiss() | ||
314 | 47 | onEntered: { | ||
315 | 48 | abortDismiss() | ||
316 | 49 | active = true | ||
317 | 50 | } | ||
318 | 51 | |||
319 | 52 | Timer { | ||
320 | 53 | id: dismissControls | ||
321 | 54 | |||
322 | 55 | running: false | ||
323 | 56 | interval: 3000 | ||
324 | 57 | repeat: false | ||
325 | 58 | onTriggered: root.active = false | ||
326 | 59 | } | ||
327 | 60 | |||
328 | 61 | Column { | ||
329 | 62 | anchors.fill: parent | ||
330 | 63 | Item { | ||
331 | 64 | id: spacer | ||
332 | 65 | anchors { | ||
333 | 66 | left: parent.left | ||
334 | 67 | right: parent.right | ||
335 | 68 | } | ||
336 | 69 | height: root.active ? 0 : contents.height | ||
337 | 70 | } | ||
338 | 71 | Item { | ||
339 | 72 | id: contents | ||
340 | 73 | anchors { | ||
341 | 74 | left: parent.left | ||
342 | 75 | right: parent.right | ||
343 | 76 | } | ||
344 | 77 | height: childrenRect.height | ||
345 | 78 | } | ||
346 | 79 | } | ||
347 | 80 | |||
348 | 81 | states: [ | ||
349 | 82 | State { | ||
350 | 83 | name: "active" | ||
351 | 84 | when: root.active | ||
352 | 85 | PropertyChanges { | ||
353 | 86 | target: spacer | ||
354 | 87 | height: 0 | ||
355 | 88 | enabled: false | ||
356 | 89 | } | ||
357 | 90 | }, | ||
358 | 91 | State { | ||
359 | 92 | name: "deActive" | ||
360 | 93 | when: !root.active | ||
361 | 94 | PropertyChanges { | ||
362 | 95 | target: spacer | ||
363 | 96 | height: contents.height | ||
364 | 97 | enabled: true | ||
365 | 98 | } | ||
366 | 99 | } | ||
367 | 100 | ] | ||
368 | 101 | |||
369 | 102 | transitions: [ | ||
370 | 103 | Transition { | ||
371 | 104 | from: "deActive" | ||
372 | 105 | to: "active" | ||
373 | 106 | UbuntuNumberAnimation { | ||
374 | 107 | target: spacer | ||
375 | 108 | property: "height" | ||
376 | 109 | duration: UbuntuAnimation.FastDuration | ||
377 | 110 | } | ||
378 | 111 | }, | ||
379 | 112 | Transition { | ||
380 | 113 | from: "active" | ||
381 | 114 | to: "deActive" | ||
382 | 115 | UbuntuNumberAnimation { | ||
383 | 116 | target: spacer | ||
384 | 117 | property: "height" | ||
385 | 118 | duration: UbuntuAnimation.SlowDuration | ||
386 | 119 | } | ||
387 | 120 | } | ||
388 | 121 | ] | ||
389 | 122 | } | ||
390 | 0 | 123 | ||
391 | === modified file 'src/qml/player/VideoPlayer.qml' | |||
392 | --- src/qml/player/VideoPlayer.qml 2015-05-01 20:10:32 +0000 | |||
393 | +++ src/qml/player/VideoPlayer.qml 2016-01-26 22:05:58 +0000 | |||
394 | @@ -78,7 +78,8 @@ | |||
395 | 78 | // videoOutput: player.videoOutput | 78 | // videoOutput: player.videoOutput |
396 | 79 | // } | 79 | // } |
397 | 80 | 80 | ||
399 | 81 | GenericToolbar { | 81 | |
400 | 82 | ToolBar { | ||
401 | 82 | id: _controls | 83 | id: _controls |
402 | 83 | 84 | ||
403 | 84 | objectName: "toolbar" | 85 | objectName: "toolbar" |
404 | @@ -89,11 +90,48 @@ | |||
405 | 89 | } | 90 | } |
406 | 90 | 91 | ||
407 | 91 | height: _controlsContents.height | 92 | height: _controlsContents.height |
408 | 92 | |||
409 | 93 | Controls { | 93 | Controls { |
410 | 94 | id: _controlsContents | 94 | id: _controlsContents |
411 | 95 | 95 | ||
413 | 96 | property bool isPaused: false | 96 | property bool wasPausedBeforeSeek: false |
414 | 97 | property bool wasVisibleBeforeSeek: false | ||
415 | 98 | property int seekPosition: 0 | ||
416 | 99 | |||
417 | 100 | function aboutToSeek() | ||
418 | 101 | { | ||
419 | 102 | wasPausedBeforeSeek = (state == "paused") | ||
420 | 103 | wasVisibleBeforeSeek = _controls.active && !_controls.aboutToDismiss | ||
421 | 104 | _controls.abortDismiss() | ||
422 | 105 | player.pause() | ||
423 | 106 | _controls.active = true | ||
424 | 107 | _controlsContents.seekPosition = video.position | ||
425 | 108 | } | ||
426 | 109 | |||
427 | 110 | function seekDone() | ||
428 | 111 | { | ||
429 | 112 | // Only automatically resume playing after a seek that is not to the | ||
430 | 113 | // end of stream (i.e. position == duration) | ||
431 | 114 | if (player.status !== MediaPlayer.EndOfMedia && !_controlsContents.wasPausedBeforeSeek) { | ||
432 | 115 | player.play() | ||
433 | 116 | } | ||
434 | 117 | |||
435 | 118 | if (!_controlsContents.wasVisibleBeforeSeek) { | ||
436 | 119 | _controls.dismiss() | ||
437 | 120 | } | ||
438 | 121 | |||
439 | 122 | _controlsContents.seekPosition = -1 | ||
440 | 123 | _controlsContents.wasPausedBeforeSeek = false | ||
441 | 124 | _controlsContents.wasVisibleBeforeSeek = false | ||
442 | 125 | } | ||
443 | 126 | |||
444 | 127 | function seek(time) | ||
445 | 128 | { | ||
446 | 129 | //keep trak of last seek position in case of the last seek does not complete in time | ||
447 | 130 | //sometimes the seek is too fast and we can not rely on the video position to calculate | ||
448 | 131 | //the next seek position. | ||
449 | 132 | _controlsContents.seekPosition = time | ||
450 | 133 | player.video.seek(time) | ||
451 | 134 | } | ||
452 | 97 | 135 | ||
453 | 98 | settingsEnabled: mpApplication.desktopMode | 136 | settingsEnabled: mpApplication.desktopMode |
454 | 99 | 137 | ||
455 | @@ -120,22 +158,9 @@ | |||
456 | 120 | } | 158 | } |
457 | 121 | } | 159 | } |
458 | 122 | 160 | ||
475 | 123 | onSeekRequested: { | 161 | onStartSeek: aboutToSeek() |
476 | 124 | player.video.seek(time) | 162 | onEndSeek: seekDone() |
477 | 125 | } | 163 | onSeekRequested: seek(time) |
462 | 126 | |||
463 | 127 | onStartSeek: { | ||
464 | 128 | isPaused = (state == "paused") | ||
465 | 129 | player.pause() | ||
466 | 130 | } | ||
467 | 131 | |||
468 | 132 | onEndSeek: { | ||
469 | 133 | // Only automatically resume playing after a seek that is not to the | ||
470 | 134 | // end of stream (i.e. position == duration) | ||
471 | 135 | if (player.status != MediaPlayer.EndOfMedia && !isPaused) { | ||
472 | 136 | player.play() | ||
473 | 137 | } | ||
474 | 138 | } | ||
478 | 139 | 164 | ||
479 | 140 | onSettingsClicked: { | 165 | onSettingsClicked: { |
480 | 141 | if (mpApplication.desktopMode) { | 166 | if (mpApplication.desktopMode) { |
481 | @@ -150,17 +175,34 @@ | |||
482 | 150 | } | 175 | } |
483 | 151 | 176 | ||
484 | 152 | MouseArea { | 177 | MouseArea { |
496 | 153 | id: _mouseArea | 178 | id: _mouseArea |
497 | 154 | 179 | ||
498 | 155 | objectName: "videoMouseArea" | 180 | objectName: "videoMouseArea" |
499 | 156 | anchors { | 181 | anchors { |
500 | 157 | left: parent.left | 182 | left: parent.left |
501 | 158 | right: parent.right | 183 | right: parent.right |
502 | 159 | top: parent.top | 184 | top: parent.top |
503 | 160 | bottom: _controls.top | 185 | bottom: _controls.top |
504 | 161 | } | 186 | } |
505 | 162 | 187 | ||
506 | 163 | onClicked: _controls.active = !_controls.active | 188 | onClicked: _controls.active = !_controls.active |
507 | 189 | } | ||
508 | 190 | |||
509 | 191 | |||
510 | 192 | Keys.onReleased: | ||
511 | 193 | { | ||
512 | 194 | if (event.isAutoRepeat) { | ||
513 | 195 | return | ||
514 | 196 | } | ||
515 | 197 | |||
516 | 198 | switch(event.key) { | ||
517 | 199 | case Qt.Key_Right: | ||
518 | 200 | case Qt.Key_Left: | ||
519 | 201 | _controlsContents.seekDone() | ||
520 | 202 | break; | ||
521 | 203 | default: | ||
522 | 204 | break | ||
523 | 205 | } | ||
524 | 164 | } | 206 | } |
525 | 165 | 207 | ||
526 | 166 | Keys.onPressed: { | 208 | Keys.onPressed: { |
527 | @@ -171,9 +213,17 @@ | |||
528 | 171 | case Qt.Key_Right: | 213 | case Qt.Key_Right: |
529 | 172 | case Qt.Key_Left: | 214 | case Qt.Key_Left: |
530 | 173 | { | 215 | { |
534 | 174 | var currentPos = (video ? video.position : 0) | 216 | if (!event.isAutoRepeat) { |
535 | 175 | var nextPos = currentPos | 217 | _controlsContents.aboutToSeek() |
536 | 176 | if (event.key == Qt.Key_Right) { | 218 | } |
537 | 219 | // wait controls be fully visbile | ||
538 | 220 | if (!_controls.fullVisible) | ||
539 | 221 | return | ||
540 | 222 | |||
541 | 223 | var nextPos = _controlsContents.seekPosition >= 0 ? | ||
542 | 224 | _controlsContents.seekPosition : 0 | ||
543 | 225 | |||
544 | 226 | if (event.key === Qt.Key_Right) { | ||
545 | 177 | var maxPos = (video ? video.duration : 0) | 227 | var maxPos = (video ? video.duration : 0) |
546 | 178 | nextPos += player.seekStep | 228 | nextPos += player.seekStep |
547 | 179 | if (nextPos > maxPos) { | 229 | if (nextPos > maxPos) { |
548 | @@ -186,8 +236,8 @@ | |||
549 | 186 | } | 236 | } |
550 | 187 | } | 237 | } |
551 | 188 | 238 | ||
554 | 189 | if (nextPos != -1) { | 239 | if (nextPos !== -1) { |
555 | 190 | player.video.seek(nextPos) | 240 | _controlsContents.seek(nextPos) |
556 | 191 | } | 241 | } |
557 | 192 | break; | 242 | break; |
558 | 193 | } | 243 | } |
FAILED: Continuous integration, rev:384 jenkins. qa.ubuntu. com/job/ mediaplayer- app-ci/ 278/ jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- vivid-touch/ 6086/console jenkins. qa.ubuntu. com/job/ mediaplayer- app-vivid- amd64-ci/ 36/console jenkins. qa.ubuntu. com/job/ mediaplayer- app-vivid- armhf-ci/ 36/console jenkins. qa.ubuntu. com/job/ mediaplayer- app-vivid- i386-ci/ 36/console jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- vivid-armhf/ 6097/console
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/mediaplayer -app-ci/ 278/rebuild
http://