Merge lp:~music-app-dev/music-app/frankenstein-merge into lp:music-app/trusty

Proposed by Victor Thompson
Status: Merged
Approved by: Victor Thompson
Approved revision: 33
Merged at revision: 24
Proposed branch: lp:~music-app-dev/music-app/frankenstein-merge
Merge into: lp:music-app/trusty
Diff against target: 1700 lines (+780/-705)
9 files modified
FirstRun.qml (+0/-54)
MusicSettings.qml (+13/-7)
MusicTracks.qml (+627/-96)
QueueDialog.qml (+4/-4)
Toolbar.qml (+0/-103)
debian/changelog (+7/-1)
debian/install (+9/-1)
music-app.qml (+86/-439)
playing-list.js (+34/-0)
To merge this branch: bzr merge lp:~music-app-dev/music-app/frankenstein-merge
Reviewer Review Type Date Requested Status
Ubuntu Phone Apps Jenkins Bot continuous-integration Approve
Martin Mrazik (community) Approve
Daniel Holm Approve
Review via email: mp+167199@code.launchpad.net

Commit message

Merged my existing lp:ubuntu-music-app code into the trunk.
* Replaced current UI
* Replaced playback functionality and managment
* Added some UI (that wasn't in my upstream) so we can do context switching from a tracks view to a playlist view or artists/albums.
* Fixed shuffling behavoir and retrieving/setting of the shuffle parameter setting
* Currently the Queue will add items on "press and hold", but the tracks are not playable. As we move forward, the Queue should just be another ListView. The same will go for playlists.

Description of the change

Merged my existing lp:ubuntu-music-app code into the trunk.
* Replaced current UI
* Replaced playback functionality and managment
* Added some UI (that wasn't in my upstream) so we can do context switching from a tracks view to a playlist view or artists/albums.
* Fixed shuffling behavoir and retrieving/setting of the shuffle parameter setting
* Currently the Queue will add items on "press and hold", but the tracks are not playable. As we move forward, the Queue should just be another ListView. The same will go for playlists.

To post a comment you must log in.
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Daniel Holm (danielholm) :
review: Approve
Revision history for this message
Daniel Holm (danielholm) wrote :

I think I've fixed the error. Trying again.

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Martin Mrazik (mrazik) wrote :

Mhm... This fails to land in a weird way but it looks like the changelog is badly formatted:
----snip----
bzrlib.plugins.builddeb.errors.UnparseableChangelog: There was an error parsing the changelog: Could not parse changelog: Badly formatted trailer line: -- Victor Thompson <email address hidden> Tue, 04 June 2013 11:45:00 -0400
-------

AFAICS there is a missing space after e-mail address:
      -- maintainer name <email address>[two spaces] date

It is weird the CI build passes but apparently that check is missing there.

review: Needs Fixing
Revision history for this message
Victor Thompson (vthompson) wrote :

Issue has been fixed. Maybe someone needs to put Jenkins in "needs review"

Revision history for this message
Martin Mrazik (mrazik) wrote :

Feel free to approve. Jenkins should pick it up now. Sorry for the hassle.

review: Approve
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== removed file 'FirstRun.qml'
--- FirstRun.qml 2013-05-31 13:58:43 +0000
+++ FirstRun.qml 1970-01-01 00:00:00 +0000
@@ -1,54 +0,0 @@
1/*
2 * Copyleft Daniel Holm.
3 *
4 * Authors:
5 * Daniel Holm <d.holmen@gmail.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 3.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20import QtQuick 2.0
21import Ubuntu.Components 0.1
22import Ubuntu.Components.ListItems 0.1 as ListItem
23import Ubuntu.Components.Popups 0.1
24import QtQuick.LocalStorage 2.0
25import "settings.js" as Settings
26
27Dialog {
28 id: root
29 title: i18n.tr("First Run")
30 text: i18n.tr("This appears to be your first run. Please set your music directory.")
31
32 Row {
33 spacing: units.gu(2)
34 TextField {
35 id: musicDirField
36 placeholderText: "/home/username/Music"
37 hasClearButton: false
38 text: musicDir
39 }
40 }
41
42 Button {
43 text: i18n.tr("Save")
44 color: "green"
45 onClicked: {
46 PopupUtils.close(root)
47 // set new music dir
48 Settings.initialize()
49 Settings.setSetting("currentfolder", musicDirField.text)
50 console.debug("Debug: Set new music dir to: "+musicDirField.text)
51 }
52 }
53
54}
550
=== modified file 'MusicSettings.qml'
--- MusicSettings.qml 2013-05-31 14:58:23 +0000
+++ MusicSettings.qml 2013-06-05 04:48:28 +0000
@@ -3,6 +3,7 @@
3 *3 *
4 * Authors:4 * Authors:
5 * Daniel Holm <d.holmen@gmail.com>5 * Daniel Holm <d.holmen@gmail.com>
6 * Victor Thompson <victor.thompson@gmail.com>
6 *7 *
7 * This program is free software; you can redistribute it and/or modify8 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by9 * it under the terms of the GNU General Public License as published by
@@ -31,9 +32,13 @@
31 spacing: units.gu(2)32 spacing: units.gu(2)
32 TextField {33 TextField {
33 id: musicDirField34 id: musicDirField
34 placeholderText: "/home/username/Music"35 placeholderText: folderModel.homePath() + "/Music"
35 hasClearButton: false36 hasClearButton: false
36 text: musicDir37 text: Settings.getSetting("currentfolder")
38
39 onTextChanged: {
40 Settings.setSetting("currentfolder", text)
41 }
37 }42 }
38 }43 }
3944
@@ -45,8 +50,8 @@
45 width: units.gu(20)50 width: units.gu(20)
46 }51 }
47 Switch {52 Switch {
48 id: scrobbleSwitch53 id: shuffleSwitch
49 checked: shuffleState54 checked: Settings.getSetting("shuffle") === "1"
50 }55 }
51 }56 }
5257
@@ -97,7 +102,7 @@
97 Row {102 Row {
98 ListItem.Subtitled {103 ListItem.Subtitled {
99 text: "Music "+appVersion104 text: "Music "+appVersion
100 subText: i18n.tr("By Daniel Holm, Sweden")105 subText: i18n.tr("By Daniel Holm (Sweden) and\nVictor Thompson (USA)")
101 }106 }
102 }107 }
103108
@@ -142,9 +147,10 @@
142 // set new music dir147 // set new music dir
143 Settings.initialize()148 Settings.initialize()
144 Settings.setSetting("currentfolder", musicDirField.text) // save music dir149 Settings.setSetting("currentfolder", musicDirField.text) // save music dir
145 Settings.setSetting("shuffle", scrobbleSwitch.checked) // save shuffle state150 Settings.setSetting("shuffle", shuffleSwitch.checked) // save shuffle state
151 random = shuffleSwitch.checked
146 console.debug("Debug: Set new music dir to: "+musicDirField.text)152 console.debug("Debug: Set new music dir to: "+musicDirField.text)
147 console.debug("Debug: Shuffle: "+scrobbleSwitch.checked)153 console.debug("Debug: Shuffle: "+ shuffleSwitch.checked)
148 }154 }
149 }155 }
150156
151157
=== modified file 'MusicTracks.qml'
--- MusicTracks.qml 2013-05-31 14:58:23 +0000
+++ MusicTracks.qml 2013-06-05 04:48:28 +0000
@@ -3,6 +3,7 @@
3 *3 *
4 * Authors:4 * Authors:
5 * Daniel Holm <d.holmen@gmail.com>5 * Daniel Holm <d.holmen@gmail.com>
6 * Victor Thompson <victor.thompson@gmail.com>
6 *7 *
7 * This program is free software; you can redistribute it and/or modify8 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by9 * it under the terms of the GNU General Public License as published by
@@ -22,119 +23,649 @@
22import Ubuntu.Components.ListItems 0.123import Ubuntu.Components.ListItems 0.1
23import Ubuntu.Components.Popups 0.124import Ubuntu.Components.Popups 0.1
24import Ubuntu.Components.ListItems 0.1 as ListItem25import Ubuntu.Components.ListItems 0.1 as ListItem
25import Qt.labs.folderlistmodel 1.026import org.nemomobile.folderlistmodel 1.0
26import QtMultimedia 5.027import QtMultimedia 5.0
27import QtQuick.LocalStorage 2.028import QtQuick.LocalStorage 2.0
28import "settings.js" as Settings29import "settings.js" as Settings
29import "meta-database.js" as MetaDB30import "meta-database.js" as Library
31import "playing-list.js" as PlayingList
32
3033
3134
32PageStack {35PageStack {
33 id: singleTracksPageStack36 id: pageStack
34 anchors.fill: parent37 anchors.fill: parent
3538
39 property bool needsUpdate: false
40 property int filelistCurrentIndex: 0
41 property int filelistCount: 0
42
43 onFilelistCurrentIndexChanged: {
44 filelist.currentIndex = filelistCurrentIndex
45 }
46
47 onNeedsUpdateChanged: {
48 if (needsUpdate === true) {
49 needsUpdate = false
50 fileDurationProgressBackground.visible = true
51 fileDurationProgressBackground_nowplaying.visible = true
52 fileDurationProgress.width = units.gu(Math.floor((player.position*100)/player.duration) * .2) // 20 max
53 fileDurationProgress_nowplaying.width = units.gu(Math.floor((player.position*100)/player.duration) * .4) // 40 max
54 fileDurationBottom.text = Math.floor((player.position/1000) / 60).toString() + ":" + (
55 Math.floor((player.position/1000) % 60)<10 ? "0"+Math.floor((player.position/1000) % 60).toString() :
56 Math.floor((player.position/1000) % 60).toString())
57 fileDurationBottom.text += " / "
58 fileDurationBottom.text += Math.floor((player.duration/1000) / 60).toString() + ":" + (
59 Math.floor((player.duration/1000) % 60)<10 ? "0"+Math.floor((player.duration/1000) % 60).toString() :
60 Math.floor((player.duration/1000) % 60).toString())
61 fileDurationBottom_nowplaying.text = fileDurationBottom.text
62 }
63 }
64
36 Component.onCompleted: {65 Component.onCompleted: {
37 // initialize settings db66 pageStack.push(mainpage)
38 Settings.initialize()67 Settings.initialize()
39 console.debug("INITIALIZED Settings")68 console.debug("INITIALIZED")
40
41 // If there were no database
42 if (Settings.getSetting("initialized") !== "true") {69 if (Settings.getSetting("initialized") !== "true") {
43 // initialize settings70 // initialize settings
44 console.debug("reset settings")71 console.debug("reset settings")
45 Settings.setSetting("initialized", "true") // set that settings exists72 Settings.setSetting("initialized", "true")
46 Settings.setSetting("shuffle", "false") // set to not shuffle as default73 Settings.setSetting("currentfolder", folderModel.homePath() + "/Music")
47 Settings.setSetting("scrobble", "false") // no scrobble yet74 }
48 Settings.setSetting("currentfolder", "/") // Music dir75 random = Settings.getSetting("shuffle") == "1"
49 // show dialog so that user can set the music dir manually, untill later76 filelist.currentIndex = -1
50 PopupUtils.open(Qt.resolvedUrl("FirstRun.qml"), pageLayout,77 }
51 {78
52 title: i18n.tr("First Run")79 Page {
53 } )80 id: mainpage
54 }81
5582 title: i18n.tr("Music")
56 // Run as usual83
57 else {84 Component {
58 musicDir = Settings.getSetting("currentfolder")85 id: highlight
59 shuffleState = Settings.getSetting("shuffle")86 Rectangle {
60 console.debug("Debug: Music dir set to: "+musicDir)87 width: 5; height: 40
61 console.debug("Debug: Shuffle state is: "+shuffleState)88 color: "#DD4814";
62 //console.debug("Debug: Scrobble state is: "+scrobbleState)89 Behavior on y {
63 }90 SpringAnimation {
6491 spring: 3
65 // then go on to meta data db92 damping: 0.2
66 MetaDB.initialize() // also create the metaDB93 }
67 console.debug("INITIALIZED Meta data")94 }
68 /*95 }
69 if (Settings.getSetting("initialized") !== "true") {96 }
70 // start adding tracks to db97
71 title = getTrackInfo(file, title)98 ListView {
72 album = getTrackInfo(file, album)99 id: filelist
73 year = getTrackInfo(file, year)100 width: parent.width
74 tracknr = getTrackInfo(file, tracknr)101 height: parent.height - units.gu(8)
75 length = getTrackInfo(file, length)102 anchors.top: tracksContext.bottom
76 console.debug("file", "title", "artist", "album", "year", "tracknr", "length")103 highlight: highlight
77 //MetaDB.setSetting("file", "title", "artist", "album", "year", "tracknr", "length")104 highlightFollowsCurrentItem: true
78 }*/105 model: folderModel
79 }106 delegate: fileDelegate
80107 onCountChanged: {
81108 filelistCount = filelist.count
82 width: units.gu(50)109 }
83 height: units.gu(75)110 onCurrentIndexChanged: {
84111 filelistCurrentIndex = filelist.currentIndex
85 Page {112 console.log("filelist.currentIndex = " + filelist.currentIndex)
86 id: singleTracksPage113 }
87114
88 // toolbar115 Component {
89 tools: defaultToolbar116 id: fileDelegate
90117 ListItem.Standard {
91 Column {118 id: file
92 anchors.centerIn: parent119 progression: model.isDir
120 icon: !model.isDir ? (trackCover === "" ? (fileName.match("\\.mp3") ? Qt.resolvedUrl("images/audio-x-mpeg.png") : Qt.resolvedUrl("images/audio-x-vorbis+ogg.png")) : "image://cover-art/"+filePath) : Qt.resolvedUrl("images/folder.png")
121 iconFrame: false
122 Label {
123 id: fileTitle
124 width: 400
125 wrapMode: Text.Wrap
126 maximumLineCount: 1
127 font.pixelSize: 16
128 anchors.left: parent.left
129 anchors.leftMargin: 75
130 anchors.top: parent.top
131 anchors.topMargin: 5
132 text: trackTitle == "" ? fileName : trackTitle
133 }
134 Label {
135 id: fileArtistAlbum
136 width: 400
137 wrapMode: Text.Wrap
138 maximumLineCount: 2
139 font.pixelSize: 12
140 anchors.left: parent.left
141 anchors.leftMargin: 75
142 anchors.top: fileTitle.bottom
143 text: trackArtist == "" ? "" : trackArtist + " - " + trackAlbum
144 }
145 Label {
146 id: fileDuration
147 width: 400
148 wrapMode: Text.Wrap
149 maximumLineCount: 2
150 font.pixelSize: 12
151 anchors.left: parent.left
152 anchors.leftMargin: 75
153 anchors.top: fileArtistAlbum.bottom
154 visible: false
155 text: ""
156 }
157
158 onFocusChanged: {
159 if (focus == false) {
160 selected = false
161 } else if (file.progression == false){
162 selected = false
163 fileArtistAlbumBottom.text = fileArtistAlbum.text
164 fileTitleBottom.text = fileTitle.text
165 fileArtistAlbumBottom_nowplaying.text = trackArtist == "" ? "" : trackArtist + "\n" + trackAlbum
166 fileTitleBottom_nowplaying.text = fileTitle.text
167 iconbottom.source = file.icon
168 iconbottom_nowplaying.source = !model.isDir && trackCover !== "" ? "image://cover-art-full/" + filePath : "images/Blank_album.jpg"
169 }
170 }
171 MouseArea {
172 anchors.fill: parent
173 onDoubleClicked: {
174 }
175 onPressAndHold: {
176 if (!model.isDir) {
177 trackQueue.append({"title": trackTitle, "artist": trackArtist, "file": filePath})
178 }
179 }
180 onClicked: {
181 if (focus == false) {
182 focus = true
183 }
184 if (model.isDir) {
185 PlayingList.clear()
186 filelist.currentIndex = -1
187 itemnum = 0
188 playing = filelist.currentIndex
189 console.log("Stored:" + Settings.getSetting("currentfolder"))
190 folderModel.path = filePath
191 } else {
192 console.log("fileName: " + fileName)
193 if (filelist.currentIndex == index) {
194 if (player.playbackState === MediaPlayer.PlayingState) {
195 playindicator.source = "images/play.png"
196 player.pause()
197 } else if (player.playbackState === MediaPlayer.PausedState) {
198 playindicator.source = "images/pause.png"
199 player.play()
200 }
201 } else {
202 player.stop()
203 player.source = Qt.resolvedUrl(filePath)
204 filelist.currentIndex = index
205 playing = PlayingList.indexOf(filePath)
206 console.log("Playing click: "+player.source)
207 console.log("Index: " + filelist.currentIndex)
208 player.play()
209 playindicator.source = "images/pause.png"
210 }
211 console.log("Source: " + player.source.toString())
212 console.log("Length: " + trackLength.toString())
213 }
214 playindicator_nowplaying.source = playindicator.source
215 }
216 }
217 Component.onCompleted: {
218 if (!PlayingList.contains(filePath) && !model.isDir) {
219 console.log("Adding file:" + filePath)
220 PlayingList.addItem(filePath, itemnum)
221 console.log(itemnum)
222 }
223 itemnum++
224 }
225 }
226 }
227 }
228
229 // context: albums? tracks?
230 Rectangle {
231 id: appContext
232 anchors.top: mainpage.top
233 height: units.gu(5)
234 width: parent.width
235 color: "#333333"
236 MouseArea {
237 id: tracksContextArea
238 anchors.verticalCenter: parent.verticalCenter
239 anchors.left: parent.left
240 width: units.gu(10)
241 height: units.gu(5)
242 onClicked: {
243 tracksContext.font.underline = true
244 artistsContext.font.underline = false
245 albumsContext.font.underline = false
246 listsContext.font.underline = false
247 }
248 Label {
249 id: tracksContext
250 width: units.gu(15)
251 wrapMode: Text.Wrap
252 color: "#FFFFFF"
253 maximumLineCount: 1
254 font.pixelSize: 20
255 anchors.verticalCenter: parent.verticalCenter
256 anchors.left: parent.left
257 anchors.leftMargin: units.gu(1)
258 text: "Music"
259 font.underline: true
260 }
261 }
262 MouseArea {
263 id: artistsContextArea
264 anchors.verticalCenter: parent.verticalCenter
265 anchors.left: tracksContextArea.right
266 width: units.gu(10)
267 height: units.gu(5)
268 onClicked: {
269 tracksContext.font.underline = false
270 artistsContext.font.underline = true
271 albumsContext.font.underline = false
272 listsContext.font.underline = false
273 }
274 Label {
275 id: artistsContext
276 width: units.gu(10)
277 wrapMode: Text.Wrap
278 color: "#FFFFFF"
279 maximumLineCount: 1
280 font.pixelSize: 20
281 anchors.verticalCenter: parent.verticalCenter
282 anchors.left: parent.left
283 text: "Artists"
284 }
285 }
286 MouseArea {
287 id: albumsContextArea
288 anchors.verticalCenter: parent.verticalCenter
289 anchors.left: artistsContextArea.right
290 width: units.gu(10)
291 height: units.gu(5)
292 onClicked: {
293 tracksContext.font.underline = false
294 artistsContext.font.underline = false
295 albumsContext.font.underline = true
296 listsContext.font.underline = false
297 }
298 Label {
299 id: albumsContext
300 width: units.gu(15)
301 wrapMode: Text.Wrap
302 color: "#FFFFFF"
303 maximumLineCount: 1
304 font.pixelSize: 20
305 anchors.verticalCenter: parent.verticalCenter
306 anchors.left: parent.left
307 text: "Albums"
308 }
309 }
310 MouseArea {
311 id: listsContextArea
312 anchors.verticalCenter: parent.verticalCenter
313 anchors.left: albumsContextArea.right
314 width: units.gu(10)
315 height: units.gu(5)
316 onClicked: {
317
318 PopupUtils.open(Qt.resolvedUrl("QueueDialog.qml"), settingsArea,
319 {
320 title: i18n.tr("Queue")
321 } )
322 }
323 Label {
324 id: listsContext
325 width: units.gu(15)
326 wrapMode: Text.Wrap
327 color: "#FFFFFF"
328 maximumLineCount: 1
329 font.pixelSize: 20
330 anchors.verticalCenter: parent.verticalCenter
331 anchors.left: parent.left
332 text: "Queue"
333 }
334 }
335 MouseArea {
336 id: settingsArea
337 anchors.verticalCenter: parent.verticalCenter
338 anchors.left: listsContextArea.right
339 anchors.right: parent.right
340 height: units.gu(5)
341 onClicked: {
342 PopupUtils.open(Qt.resolvedUrl("MusicSettings.qml"), settingsArea,
343 {
344 title: i18n.tr("Settings")
345 } )
346 }
347 Image {
348 id: settingsImage
349 source: "images/settings.png"
350 anchors.left: parent.left
351 anchors.verticalCenter: parent.verticalCenter
352 anchors.leftMargin: units.gu(1)
353 }
354 }
355
356 }
357
358 Rectangle {
359 id: playerControls
360 anchors.top: filelist.bottom
361 height: units.gu(8)
362 width: parent.width
363 color: "#333333"
364 UbuntuShape {
365 id: forwardshape
366 height: units.gu(5)
367 width: units.gu(5)
368 anchors.verticalCenter: parent.verticalCenter
369 anchors.right: parent.right
370 anchors.rightMargin: units.gu(2)
371 radius: "none"
372 image: Image {
373 id: forwardindicator
374 source: "images/forward.png"
375 anchors.right: parent.right
376 anchors.centerIn: parent
377 opacity: .7
378 }
379 MouseArea {
380 anchors.fill: parent
381 onClicked: {
382 playindicator.source = "images/pause.png"
383 playindicator_nowplaying.source = playindicator.source
384 nextSong()
385 }
386 }
387 }
388 UbuntuShape {
389 id: playshape
390 height: units.gu(5)
391 width: units.gu(5)
392 anchors.verticalCenter: parent.verticalCenter
393 anchors.right: forwardshape.left
394 anchors.rightMargin: units.gu(1)
395 radius: "none"
396 image: Image {
397 id: playindicator
398 source: "images/play.png"
399 anchors.right: parent.right
400 anchors.centerIn: parent
401 opacity: .7
402 }
403 MouseArea {
404 anchors.fill: parent
405 onClicked: {
406 if (player.playbackState === MediaPlayer.PlayingState) {
407 playindicator.source = "images/play.png"
408 player.pause()
409 } else {
410 playindicator.source = "images/pause.png"
411 player.play()
412 }
413 playindicator_nowplaying.source = playindicator.source
414 }
415 }
416 }
417 Image {
418 id: iconbottom
419 source: ""
420 anchors.left: parent.left
421 anchors.top: parent.top
422 anchors.topMargin: units.gu(1)
423 anchors.leftMargin: units.gu(1)
424
425 MouseArea {
426 anchors.fill: parent
427 onClicked: {
428 pageStack.push(nowPlaying)
429 }
430 }
431 }
432 Label {
433 id: fileTitleBottom
434 width: units.gu(30)
435 wrapMode: Text.Wrap
436 color: "#FFFFFF"
437 maximumLineCount: 1
438 font.pixelSize: 16
439 anchors.left: iconbottom.right
440 anchors.top: parent.top
441 anchors.topMargin: units.gu(1)
442 anchors.leftMargin: units.gu(1)
443 text: ""
444 }
445 Label {
446 id: fileArtistAlbumBottom
447 width: units.gu(30)
448 wrapMode: Text.Wrap
449 color: "#FFFFFF"
450 maximumLineCount: 1
451 font.pixelSize: 12
452 anchors.left: iconbottom.right
453 anchors.top: fileTitleBottom.bottom
454 anchors.leftMargin: units.gu(1)
455 text: ""
456 }
457 Rectangle {
458 id: fileDurationProgressContainer
459 anchors.top: fileArtistAlbumBottom.bottom
460 anchors.left: iconbottom.right
461 anchors.topMargin: 2
462 anchors.leftMargin: units.gu(1)
463 width: units.gu(20)
464 color: "#333333"
465
466 Rectangle {
467 id: fileDurationProgressBackground
468 anchors.top: parent.top
469 anchors.topMargin: 2
470 height: 1
471 width: units.gu(20)
472 color: "#FFFFFF"
473 visible: false
474 }
475 Rectangle {
476 id: fileDurationProgress
477 anchors.top: parent.top
478 height: 5
479 width: 0
480 color: "#DD4814"
481 }
482 }
483 Label {
484 id: fileDurationBottom
485 anchors.top: fileArtistAlbumBottom.bottom
486 anchors.left: fileDurationProgressContainer.right
487 anchors.leftMargin: units.gu(1)
488 width: units.gu(30)
489 wrapMode: Text.Wrap
490 color: "#FFFFFF"
491 maximumLineCount: 1
492 font.pixelSize: 12
493 text: ""
494 }
495 }
496 }
497
498 Page {
499 id: nowPlaying
500 visible: false
501
502 Rectangle {
93 anchors.fill: parent503 anchors.fill: parent
94 ListView {504 height: units.gu(10)
95 id: musicFolder505 color: "#333333"
96 width: parent.width506 Column {
97 height: parent.height507 anchors.fill: parent
98 model: folderModel508 anchors.bottomMargin: units.gu(10)
99 //delegate: databaseDelegate509
100 delegate: ListItem.Subtitled {510 UbuntuShape {
101 text: fileName511 id: forwardshape_nowplaying
102 subText: "Artist: " // this should be selected from metaDB512 height: 50
103 Loader {513 width: 50
104 id: trackLoad514 anchors.bottom: parent.bottom
105 //onLoaded:515 anchors.left: playshape_nowplaying.right
106 Component.onCompleted: {516 anchors.leftMargin: units.gu(2)
107 console.debug("This one was found: "+index+"; "+fileName)517 radius: "none"
108 trackQueue.append({"title": playMusic.metaData.title, "artist": playMusic.metaData.albumArtist, "file": filePath}) // just for dev518 image: Image {
109 /* Insert them to database519 id: forwardindicator_nowplaying
110 // start adding tracks to db520 source: "images/forward.png"
111 title = getTrackInfo(file, title)521 anchors.right: parent.right
112 album = getTrackInfo(file, album)522 anchors.bottom: parent.bottom
113 year = getTrackInfo(file, year)523 opacity: .7
114 tracknr = getTrackInfo(file, tracknr)524 }
115 length = getTrackInfo(file, length)525 MouseArea {
116 console.debug("file", "title", "artist", "album", "year", "tracknr", "length")526 anchors.fill: parent
117 //MetaDB.setSetting("file", "title", "artist", "album", "year", "tracknr", "length")527 onClicked: {
118 */528 playindicator.source = "images/pause.png"
529 playindicator_nowplaying.source = playindicator.source
530 nextSong()
531 }
532 }
533 }
534 UbuntuShape {
535 id: playshape_nowplaying
536 height: 50
537 width: 50
538 anchors.bottom: parent.bottom
539 anchors.horizontalCenter: parent.horizontalCenter
540 radius: "none"
541 image: Image {
542 id: playindicator_nowplaying
543 source: "images/play.png"
544 anchors.right: parent.right
545 anchors.bottom: parent.bottom
546 opacity: .7
547 }
548 MouseArea {
549 anchors.fill: parent
550 onClicked: {
551 if (player.playbackState === MediaPlayer.PlayingState) {
552 playindicator.source = "images/play.png"
553 player.pause()
554 } else {
555 playindicator.source = "images/pause.png"
556 player.play()
119 }557 }
120 }558 playindicator_nowplaying.source = playindicator.source
121559 }
122 onClicked: {560 }
123 playMusic.source = filePath561 }
124 playMusic.play()562 UbuntuShape {
125 console.debug('Debug: User pressed '+filePath)563 id: backshape_nowplaying
126 trackInfo.text = playMusic.metaData.albumArtist+" - "+playMusic.metaData.title // show track meta data564 height: 50
127 // cool animation565 width: 50
128 }566 anchors.bottom: parent.bottom
129 onPressAndHold: {567 anchors.right: playshape_nowplaying.left
130 console.debug('Debug: '+filePath+' added to queue.')568 anchors.rightMargin: units.gu(2)
131 trackQueue.append({"title": playMusic.metaData.title, "artist": playMusic.metaData.albumArtist, "file": filePath})569 radius: "none"
132 // cool animation570 image: Image {
133 }571 id: backindicator_nowplaying
572 source: "images/back.png"
573 anchors.right: parent.right
574 anchors.bottom: parent.bottom
575 opacity: .7
576 }
577 MouseArea {
578 anchors.fill: parent
579 onClicked: {
580 playindicator.source = "images/pause.png"
581 playindicator_nowplaying.source = playindicator.source
582 getSong(-1)
583 }
584 }
585 }
586
587 Image {
588 id: iconbottom_nowplaying
589 source: ""
590 width: 300
591 height: 300
592 anchors.horizontalCenter: parent.horizontalCenter
593 anchors.top: parent.top
594 anchors.topMargin: units.gu(1)
595 anchors.leftMargin: units.gu(1)
596
597 MouseArea {
598 anchors.fill: parent
599 onClicked: {
600 pageStack.pop(nowPlaying)
601 }
602 }
603 }
604 Label {
605 id: fileTitleBottom_nowplaying
606 width: units.gu(30)
607 wrapMode: Text.Wrap
608 color: "#FFFFFF"
609 maximumLineCount: 1
610 font.pixelSize: 24
611 anchors.top: iconbottom_nowplaying.bottom
612 anchors.topMargin: units.gu(2)
613 anchors.left: parent.left
614 anchors.leftMargin: units.gu(2)
615 text: ""
616 }
617 Label {
618 id: fileArtistAlbumBottom_nowplaying
619 width: units.gu(30)
620 wrapMode: Text.Wrap
621 color: "#FFFFFF"
622 maximumLineCount: 2
623 font.pixelSize: 16
624 anchors.left: parent.left
625 anchors.top: fileTitleBottom_nowplaying.bottom
626 anchors.leftMargin: units.gu(2)
627 text: ""
628 }
629 Rectangle {
630 id: fileDurationProgressContainer_nowplaying
631 anchors.top: fileArtistAlbumBottom_nowplaying.bottom
632 anchors.left: parent.left
633 anchors.topMargin: units.gu(2)
634 anchors.leftMargin: units.gu(2)
635 width: units.gu(40)
636 color: "#333333"
637
638 Rectangle {
639 id: fileDurationProgressBackground_nowplaying
640 anchors.top: parent.top
641 anchors.topMargin: 4
642 height: 1
643 width: units.gu(40)
644 color: "#FFFFFF"
645 visible: false
646 }
647 Rectangle {
648 id: fileDurationProgress_nowplaying
649 anchors.top: parent.top
650 height: 8
651 width: 0
652 color: "#DD4814"
653 }
654 }
655 Label {
656 id: fileDurationBottom_nowplaying
657 anchors.top: fileDurationProgressContainer_nowplaying.bottom
658 anchors.left: parent.left
659 anchors.topMargin: units.gu(2)
660 anchors.leftMargin: units.gu(2)
661 width: units.gu(30)
662 wrapMode: Text.Wrap
663 color: "#FFFFFF"
664 maximumLineCount: 1
665 font.pixelSize: 16
666 text: ""
134 }667 }
135 }668 }
136 }669 }
137
138 }670 }
139
140}671}
141672
=== modified file 'QueueDialog.qml'
--- QueueDialog.qml 2013-05-31 14:58:23 +0000
+++ QueueDialog.qml 2013-06-05 04:48:28 +0000
@@ -3,6 +3,7 @@
3 *3 *
4 * Authors:4 * Authors:
5 * Daniel Holm <d.holmen@gmail.com>5 * Daniel Holm <d.holmen@gmail.com>
6 * Victor Thompson <victor.thompson@gmail.com>
6 *7 *
7 * This program is free software; you can redistribute it and/or modify8 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by9 * it under the terms of the GNU General Public License as published by
@@ -32,8 +33,7 @@
32 height: units.gu(50)33 height: units.gu(50)
33 model: trackQueue34 model: trackQueue
34 delegate: ListItem.Standard {35 delegate: ListItem.Standard {
35 //text: artist+" - "+title36 text: artist+" - "+title
36 text: file
37 removable: true37 removable: true
38 onClicked: {38 onClicked: {
39 console.debug("Debug: Play "+file+" instead - now.")39 console.debug("Debug: Play "+file+" instead - now.")
@@ -50,7 +50,7 @@
50 // Clean whole queue button50 // Clean whole queue button
51 Button {51 Button {
52 text: i18n.tr("Clear")52 text: i18n.tr("Clear")
53 color: "orange"53 color: "#DD4814"
54 onClicked: {54 onClicked: {
55 console.debug("Debug: Track queue cleared.")55 console.debug("Debug: Track queue cleared.")
56 trackQueue.clear()56 trackQueue.clear()
@@ -61,7 +61,7 @@
61 // close dialog button61 // close dialog button
62 Button {62 Button {
63 text: i18n.tr("Close")63 text: i18n.tr("Close")
64 color: "red"64 color: "#DD4814"
65 onClicked: {65 onClicked: {
66 PopupUtils.close(queueDialog)66 PopupUtils.close(queueDialog)
67 }67 }
6868
=== removed file 'Toolbar.qml'
--- Toolbar.qml 2013-05-08 21:53:49 +0000
+++ Toolbar.qml 1970-01-01 00:00:00 +0000
@@ -1,103 +0,0 @@
1/*
2 * Copyleft Daniel Holm.
3 *
4 * Authors:
5 * Daniel Holm <d.holmen@gmail.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 3.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20import QtQuick 2.0
21import Ubuntu.Components 0.1
22import Ubuntu.Components.ListItems 0.1 as ListItem
23import Ubuntu.Components.Popups 0.1
24
25Component {
26 // Share
27 Action {
28 id: shareTrack
29 objectName: "share"
30
31 iconSource: Qt.resolvedUrl("images/icon_share@20.png")
32 text: i18n.tr("Share")
33
34 onTriggered: {
35 console.debug('Debug: Share pressed')
36 }
37 }
38
39 // prevous track
40 Action {
41 id: prevTrack
42 objectName: "prev"
43
44 iconSource: Qt.resolvedUrl("images/prev.png")
45 text: i18n.tr("Previous")
46
47 onTriggered: {
48 console.debug('Debug: Prev track pressed')
49 }
50 }
51
52 // Play
53 Action {
54 id: playTrack
55 objectName: "play"
56
57 iconSource: Qt.resolvedUrl("images/icon_play@20.png")
58 text: i18n.tr("Play")
59
60 onTriggered: {
61 //trackStatus: 'pause' // this changes on press
62 onTrackStatusChange(playTrack.text)
63 }
64 }
65
66 // Next track
67 Action {
68 id: nextTrack
69 objectName: "next"
70
71 iconSource: Qt.resolvedUrl("images/next.png")
72 text: i18n.tr("Next")
73
74 onTriggered: {
75 console.debug('Debug: next track pressed')
76 }
77 }
78
79 // Queue
80 Action {
81 id: trackQueue
82 objectName: "queuelist"
83 iconSource: Qt.resolvedUrl("images/icon_settings@20.png")
84 text: i18n.tr("Queue")
85 onTriggered: {
86 PopupUtils.open(queueDialog, trackQueue)
87 }
88 }
89
90 // Settings
91 Action {
92 objectName: "settings"
93
94 iconSource: Qt.resolvedUrl("images/icon_settings@20.png")
95 text: i18n.tr("Settings")
96
97 onTriggered: {
98 console.debug('Debug: Settings pressed')
99 // show settings page
100 //page: MusicSettings { id: musicSettings }
101 }
102 }
103}
1040
=== modified file 'debian/changelog'
--- debian/changelog 2013-06-01 01:05:45 +0000
+++ debian/changelog 2013-06-05 04:48:28 +0000
@@ -1,5 +1,11 @@
1music-app (0.2) raring; urgency=low
2
3 * Merge of Daniel's and Victor's code
4
5 -- Victor Thompson <victor.thompson@gmail.com> Tue, 04 June 2013 11:45:00 -0400
6
1music-app (0.1) raring; urgency=low7music-app (0.1) raring; urgency=low
28
3 * Initial Release.9 * Initial Release.
410
5 -- "Michael <mhall119@ubuntu.com> Thu, 23 May 2013 17:10:45 -040011 -- Michael <mhall119@ubuntu.com> Thu, 23 May 2013 17:10:45 -0400
612
=== modified file 'debian/install'
--- debian/install 2013-06-03 17:43:53 +0000
+++ debian/install 2013-06-05 04:48:28 +0000
@@ -1,4 +1,3 @@
1Toolbar.qml /usr/share/music-app
2MusicSettings.qml /usr/share/music-app1MusicSettings.qml /usr/share/music-app
3music-app.qml /usr/share/music-app2music-app.qml /usr/share/music-app
4QueueDialog.qml /usr/share/music-app3QueueDialog.qml /usr/share/music-app
@@ -16,5 +15,14 @@
16images/icon_settings@20.png /usr/share/music-app15images/icon_settings@20.png /usr/share/music-app
17images/music.png /usr/share/music-app16images/music.png /usr/share/music-app
18images/icon_play@20.png /usr/share/music-app17images/icon_play@20.png /usr/share/music-app
18images/settings@8.png /usr/share/music-app
19images/play.png /usr/share/music-app
20images/pause.png /usr/share/music-app
21images/forward.png /usr/share/music-app
22images/Blank_album.jpg /usr/share/music-app
23images/back.png /usr/share/music-app
24images/audio-x-mpeg.png /usr/share/music-app
25images/audio-x-vorbis+ogg.png /usr/share/music-app
26playing-list.js /usr/share/music-app
19meta-database.js /usr/share/music-app27meta-database.js /usr/share/music-app
20music-app.desktop /usr/share/applications28music-app.desktop /usr/share/applications
2129
=== added file 'images/Blank_album.jpg'
22Binary files images/Blank_album.jpg 1970-01-01 00:00:00 +0000 and images/Blank_album.jpg 2013-06-05 04:48:28 +0000 differ30Binary files images/Blank_album.jpg 1970-01-01 00:00:00 +0000 and images/Blank_album.jpg 2013-06-05 04:48:28 +0000 differ
=== added file 'images/audio-x-mpeg.png'
23Binary files images/audio-x-mpeg.png 1970-01-01 00:00:00 +0000 and images/audio-x-mpeg.png 2013-06-05 04:48:28 +0000 differ31Binary files images/audio-x-mpeg.png 1970-01-01 00:00:00 +0000 and images/audio-x-mpeg.png 2013-06-05 04:48:28 +0000 differ
=== added file 'images/audio-x-vorbis+ogg.png'
24Binary files images/audio-x-vorbis+ogg.png 1970-01-01 00:00:00 +0000 and images/audio-x-vorbis+ogg.png 2013-06-05 04:48:28 +0000 differ32Binary files images/audio-x-vorbis+ogg.png 1970-01-01 00:00:00 +0000 and images/audio-x-vorbis+ogg.png 2013-06-05 04:48:28 +0000 differ
=== added file 'images/back.png'
25Binary files images/back.png 1970-01-01 00:00:00 +0000 and images/back.png 2013-06-05 04:48:28 +0000 differ33Binary files images/back.png 1970-01-01 00:00:00 +0000 and images/back.png 2013-06-05 04:48:28 +0000 differ
=== added file 'images/forward.png'
26Binary files images/forward.png 1970-01-01 00:00:00 +0000 and images/forward.png 2013-06-05 04:48:28 +0000 differ34Binary files images/forward.png 1970-01-01 00:00:00 +0000 and images/forward.png 2013-06-05 04:48:28 +0000 differ
=== added file 'images/pause.png'
27Binary files images/pause.png 1970-01-01 00:00:00 +0000 and images/pause.png 2013-06-05 04:48:28 +0000 differ35Binary files images/pause.png 1970-01-01 00:00:00 +0000 and images/pause.png 2013-06-05 04:48:28 +0000 differ
=== added file 'images/play.png'
28Binary files images/play.png 1970-01-01 00:00:00 +0000 and images/play.png 2013-06-05 04:48:28 +0000 differ36Binary files images/play.png 1970-01-01 00:00:00 +0000 and images/play.png 2013-06-05 04:48:28 +0000 differ
=== added file 'images/settings@8.png'
29Binary files images/settings@8.png 1970-01-01 00:00:00 +0000 and images/settings@8.png 2013-06-05 04:48:28 +0000 differ37Binary files images/settings@8.png 1970-01-01 00:00:00 +0000 and images/settings@8.png 2013-06-05 04:48:28 +0000 differ
=== modified file 'music-app.qml'
--- music-app.qml 2013-06-03 17:43:53 +0000
+++ music-app.qml 2013-06-05 04:48:28 +0000
@@ -3,6 +3,7 @@
3 *3 *
4 * Authors:4 * Authors:
5 * Daniel Holm <d.holmen@gmail.com>5 * Daniel Holm <d.holmen@gmail.com>
6 * Victor Thompson <victor.thompson@gmail.com>
6 *7 *
7 * This program is free software; you can redistribute it and/or modify8 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by9 * it under the terms of the GNU General Public License as published by
@@ -22,11 +23,12 @@
22import Ubuntu.Components.ListItems 0.123import Ubuntu.Components.ListItems 0.1
23import Ubuntu.Components.Popups 0.124import Ubuntu.Components.Popups 0.1
24import Ubuntu.Components.ListItems 0.1 as ListItem25import Ubuntu.Components.ListItems 0.1 as ListItem
25import Qt.labs.folderlistmodel 1.026import org.nemomobile.folderlistmodel 1.0
26import QtMultimedia 5.027import QtMultimedia 5.0
27import QtQuick.LocalStorage 2.028import QtQuick.LocalStorage 2.0
28import "settings.js" as Settings29import "settings.js" as Settings
29import "meta-database.js" as MetaDatabase30import "meta-database.js" as Library
31import "playing-list.js" as PlayingList
3032
31MainView {33MainView {
32 objectName: i18n.tr("mainView")34 objectName: i18n.tr("mainView")
@@ -34,156 +36,76 @@
3436
35 width: units.gu(50)37 width: units.gu(50)
36 height: units.gu(75)38 height: units.gu(75)
39 Component.onCompleted: {
40 header.visible = false
41 }
42
3743
38 // VARIABLES44 // VARIABLES
39 property string musicName: i18n.tr("Music")45 property string musicName: i18n.tr("Music")
40 property string musicDir: ""46 property string musicDir: ""
41 property string shuffleState: ""
42 property string trackStatus: "stopped"
43 property string appVersion: '0.5.2'47 property string appVersion: '0.5.2'
48 property int playing: 0
49 property int itemnum: 0
50 property bool random: false
51 property string artist
52 property string album
53 property string song
54 property string tracktitle
4455
45 // FUNCTIONS56 // FUNCTIONS
4657 function previousSong() {
47 // digg deeper in the music folder58 getSong(-1)
48 function subDirCheck(directory) {59 }
49 // populate listmodel with meta data of tracks60 function nextSong() {
50 }61 getSong(1)
5162 }
52 // What is the state of the playback?63
53 function stateChange() {64 function getSong(direction) {
54 // state was stopped (0)65 if (random) {
55 if (playMusic.playbackState == "0") {66 var now = new Date();
56 console.debug("Debug: Music was stopped. Playing")67 var seed = now.getSeconds();
57 beenStopped() // run stop function68 do {
58 playMusic.play() // then play69 var num = (Math.floor((PlayingList.size()) * Math.random(seed)));
59 }70 console.log(num)
6071 console.log(playing)
61 // if state was playing (1)72 } while (num == playing && PlayingList.size() > 0)
62 else if (playMusic.playbackState == "1") {73 player.source = Qt.resolvedUrl(PlayingList.getList()[num])
63 console.debug("Debug: Track was playing. Pause")74 musicTracksPage.filelistCurrentIndex = PlayingList.at(num)
64 playMusic.pause() // pause the music then75 playing = num
65 }76 console.log("MediaPlayer statusChanged, currentIndex: " + musicTracksPage.filelistCurrentIndex)
6677 } else {
67 // if state is paused (2)78 if ((playing < PlayingList.size() - 1 && direction === 1 )
68 else if (playMusic.playbackState == "2") {79 || (playing > 0 && direction === -1)) {
69 console.debug("Debug: Track was paused. Playing")80 console.log("playing: " + playing)
70 playMusic.play() // resume then81 console.log("filelistCount: " + musicTracksPage.filelistCount)
71 }82 console.log("PlayingList.size(): " + PlayingList.size())
7283 playing += direction
73 updateUI()84 if (playing === 0) {
74 }85 musicTracksPage.filelistCurrentIndex = playing + (itemnum - PlayingList.size())
7586 } else {
76 // stop function87 musicTracksPage.filelistCurrentIndex += direction
77 function beenStopped() {88 }
78 console.debug("Debug: has a track been played before or did I just start?")89 player.source = Qt.resolvedUrl(PlayingList.getList()[playing])
7990 } else if(direction === 1) {
80 // track was just paused or stopped. Resume previous track91 console.log("playing: " + playing)
81 if (playMusic.source != "") {92 console.log("filelistCount: " + musicTracksPage.filelistCount)
82 console.debug("Debug: Resume previous song: "+playMusic.source)93 console.log("PlayingList.size(): " + PlayingList.size())
8394 playing = 0
84 updateUI()95 musicTracksPage.filelistCurrentIndex = playing + (musicTracksPage.filelistCount - PlayingList.size())
85 }96 player.source = Qt.resolvedUrl(PlayingList.getList()[playing])
8697 } else if(direction === -1) {
87 // app just started, play random or first track in list, depending on shuffle on or off98 console.log("playing: " + playing)
88 else {99 console.log("filelistCount: " + musicTracksPage.filelistCount)
89 // is shuffle on?100 console.log("PlayingList.size(): " + PlayingList.size())
90 // if shuffle on {101 playing = PlayingList.size() - 1
91 //}102 musicTracksPage.filelistCurrentIndex = playing + (musicTracksPage.filelistCount - PlayingList.size())
92 // Shuffle not activated103 player.source = Qt.resolvedUrl(PlayingList.getList()[playing])
93 //else {104 }
94 playMusic.source = trackQueue.get(0).file // this should play a dynamic track105 console.log("MediaPlayer statusChanged, currentIndex: " + musicTracksPage.filelistCurrentIndex)
95 console.debug("Debug: First song is "+trackQueue.get(0).file)106 }
96 console.debug("Debug: I was just started. Play random track: "+playMusic.source)107 console.log("Playing: "+player.source)
97108 player.play()
98 updateUI()
99 //}
100 }
101 }
102
103 // previous and next track function
104 function nextTrack() {
105 //check if any queued songs
106 // if there are, play them
107 if (trackQueue > 1) {
108 console.debug() // print next songs filename
109 playMusic.source = trackQueue.get(0).file
110 playMusic.play()
111 removedTrackQueue.append({"title": trackQueue.get(0).title, "artist": trackQueue.get(0).artist, "file": trackQueue.get(0).file}) // move the track to a list of preious tracks
112 trackQueue.remove(index) // remove the track from queue
113
114 updateUI()
115 }
116
117 // if not, play another
118 else {
119
120 // if shuffle, play random
121 if (settings.shuffle == 1) {
122 updateUI()
123 }
124
125 // if not shuffle, play next
126 else {
127 console.debug() // print next songs filename
128 playMusic.source = trackQueue.get(0).file
129 playMusic.play()
130 removedTrackQueue.append({"title": trackQueue.get(0).title, "artist": trackQueue.get(0).artist, "file": trackQueue.get(0).file}) // move the track to a list of preious tracks
131 trackQueue.remove(index) // remove the track from queue
132
133 updateUI()
134 }
135 }
136 }
137
138 function previousTrack() {
139 console.debug("Debug: Previous track was "+removedTrackQueue.get(removedTrackQueue.count).file)
140 // play the previous track
141 playMusic.source = removedTrackQueue.get(removedTrackQueue.count).file
142 playMusic.play()
143
144 updateUI()
145 }
146
147 // Get song title
148 function getTrackInfo(source, type) {
149 console.debug('Debug: Got it. Trying to get meta data from: '+source) // debug
150 musicInfo.source = source
151 musicInfo.pause()
152
153 // if title
154 if (type == "title") {
155 return musicInfo.metaData.title
156 }
157
158 // if artist
159 else if (type == "artist") {
160 return musicInfo.metaData.albumArtist
161 }
162
163 // if album
164 else if (type == "album") {
165 return musicInfo.metaData.albumTitle
166 }
167
168 // year
169 else if (type == "year") {
170 return musicInfo.metaData.year
171 }
172
173 // cover
174 else if (type == "cover") {
175 // download cover art from last.fm
176 // save the file in a app dir in HOME
177 // return the value of the cover art file
178 }
179
180 // tracknr
181 else if (type == "tracknr") {
182 }
183
184 // lenght
185 else if (type == "length") {
186 }
187 }109 }
188110
189 // add track to database111 // add track to database
@@ -198,67 +120,30 @@
198 //length =120 //length =
199121
200 // push to database122 // push to database
201 MetaDatabase.setMetadata(track, title, artist, album, cover, year, tracknr, length)123 Library.setMetadata(track, title, artist, album, cover, year, tracknr, length)
202 }124 }
203125
204 // progressbar126 MediaPlayer {
205 function setProgressbar() {127 id: player
206 console.debug("Debug: change progressvalue to "+playMusic.duration)128 muted: false
207 trackProgress.maximumValue = playMusic.duration
208 }
209
210 // update the UI things with meta data from track
211 function updateUI() {
212 playinTab.title = playMusic.metaData.title // show track title in tab header
213 playTrack.iconSource = Qt.resolvedUrl("images/icon_pause@20.png") // change toolbar icon
214 playTrack.text = i18n.tr("Pause") // change toolbar text
215 trackInfo.text = playMusic.metaData.albumArtist+" - "+playMusic.metaData.title // show track meta data
216// coverArt.source = "HOMEDIR/.music-app/coverart/"+MetaDatabase.getMetadata(playMusic.source,"cover") // get cover art filename
217
218 setProgressbar() // set progressbar
219
220 console.debug("Debug: UI updated.")
221 }
222
223 // Music stuff
224 Audio {
225 id: playMusic
226 source: ""
227 /*
228 onStatusChanged: {129 onStatusChanged: {
229 if (status === Audio.EndOfMedia || 7 ) {130 if (status == MediaPlayer.EndOfMedia) {
230 console.log("Debug: Track ended. Play next.") //debug131 nextSong()
231 //nextTrack()
232 }
233 else {
234 console.log("the Music Players status = " + playMusic.status)
235 }132 }
236 }*/133 }
237 }134
238135 onPositionChanged: {
239 // while playing136 musicTracksPage.needsUpdate = true
240 Connections {137 }
241 target: playMusic
242 onPlaying: {
243 trackProgress.value = playMusic.position
244 console.debug("Debug: change position to "+playMusic.position)
245 }
246 }
247
248 // get file meta data
249 Audio {
250 id: musicInfo
251 source: ""
252 volume: 0.0
253 //Keys.onSpacePressed: stateChange()
254 }138 }
255139
256 // set the folder from where the music is140 // set the folder from where the music is
257 FolderListModel {141 FolderListModel {
258 id: folderModel142 id: folderModel
259 folder: musicDir143 showDirectories: false
260 showDirs: false144 filterDirectories: false
261 nameFilters: ["*.ogg","*.mp3","*.oga","*.wav"]145 nameFilters: ["*.mp3", "*.ogg", "*.flac", "*.wav", "*.oga"]
146 path: Settings.getSetting("initialized") === "true" && Settings.getSetting("currentfolder") !== "" ? Settings.getSetting("currentfolder") : homePath() + "/Music"
262 }147 }
263148
264 /* this is how a queue looks like149 /* this is how a queue looks like
@@ -283,244 +168,6 @@
283 id: singleTracks168 id: singleTracks
284 }169 }
285170
286 // reusable toolbar171 MusicTracks { id: musicTracksPage }
287 ToolbarActions {172
288 id: defaultToolbar
289
290 // Share
291 Action {
292 id: shareTrack
293 objectName: "share"
294
295 iconSource: Qt.resolvedUrl("images/icon_share@20.png")
296 text: i18n.tr("Share")
297
298 onTriggered: {
299 console.debug('Debug: Share pressed')
300 // just to debug other stuff for a while
301 console.debug("Debug: change progress to "+playMusic.position)
302 trackProgress.value = playMusic.position
303 }
304 }
305
306 // prevous track
307 Action {
308 id: prevTrack
309 objectName: "prev"
310
311 iconSource: Qt.resolvedUrl("images/icon_prev@20.png")
312 text: i18n.tr("Previous")
313
314 onTriggered: {
315 console.debug('Debug: Prev track pressed')
316 //console.debug(removedTrackQueue.get(0).file) // print next songs filename
317 //playMusic.source = removedTrackQueue.get(0).file
318 //playMusic.play()
319 previousTrack()
320 }
321 }
322
323 // Play
324 Action {
325 id: playTrack
326 objectName: "play"
327
328 iconSource: Qt.resolvedUrl("images/icon_play@20.png")
329 text: i18n.tr("Play")
330
331 onTriggered: {
332 console.debug("Debug: "+trackStatus+" pressed in toolbar.")
333 console.debug(playMusic.playbackState)
334 stateChange()
335 }
336 }
337
338 // Next track
339 Action {
340 id: nextTrack
341 objectName: "next"
342
343 iconSource: Qt.resolvedUrl("images/icon_next@20.png")
344 text: i18n.tr("Next")
345
346 onTriggered: {
347 console.debug('Debug: next track pressed')
348 console.debug(trackQueue.get(0).file) // print next songs filename
349 playMusic.source = trackQueue.get(0).file
350 playMusic.play()
351
352 // move track, which has been played from queue, to old queue so that prev button works
353 removedTrackQueue.append({"title": trackQueue.get(0).title, "artist": trackQueue.get(0).artist, "file": trackQueue.get(0).file})
354 trackQueue.remove(0)
355 }
356 }
357
358 // Queue
359 Action {
360 id: trackQueueAction
361 objectName: "queuelist"
362 iconSource: Qt.resolvedUrl("images/icon_settings@20.png")
363 text: i18n.tr("Queue")
364 onTriggered: {
365 PopupUtils.open(Qt.resolvedUrl("QueueDialog.qml"), pageLayout,
366 {
367 title: i18n.tr("Queue")
368 } )
369 }
370 }
371
372 // Settings
373 Action {
374 id: settingsAction
375 objectName: "settings"
376
377 iconSource: Qt.resolvedUrl("images/icon_settings@20.png")
378 text: i18n.tr("Settings")
379
380 onTriggered: {
381 console.debug('Debug: Settings pressed')
382 // show settings page (not yet implemented)
383 //dialog
384 PopupUtils.open(Qt.resolvedUrl("MusicSettings.qml"), pageLayout,
385 {
386 title: i18n.tr("Settings")
387 } )
388 }
389 }
390 }
391
392 Tabs {
393 id: tabs
394 anchors.fill: parent
395
396 // First tab begins here - should be the primary tab
397 Tab {
398 id: playinTab
399 objectName: "Tab1"
400
401 title: musicName
402
403 // Tab content begins here
404 page: Page {
405 id: playingPage
406
407 // toolbar
408 tools: defaultToolbar
409
410 Column {
411 id: pageLayout
412
413 spacing: units.gu(1)
414
415 Column {
416 spacing: units.gu(1)
417 // Album cover here
418 UbuntuShape {
419 id: trackCoverArt
420 width: units.gu(50)
421 height: units.gu(50)
422 gradientColor: "blue" // test
423 image: Image {
424 id: coverArt
425 source: "images/music.png"
426 }
427 }
428 /*onClicked: {
429 playMusic.pause()
430 }
431 onDoubbleTap: {
432 nextTrack()
433 }
434 onPressAndHold: {
435 playMusic.stop()
436 }*/
437 }
438
439 // track progress
440 Column {
441 width: units.gu(50)
442 ProgressBar {
443 id: trackProgress
444 minimumValue: 0
445 maximumValue: 100
446 value: 0
447 }
448 }
449
450 // Track info
451 Column {
452 spacing: units.gu(1)
453 Label {
454 id: trackInfo
455 text: "Stopped. Press play."
456 //subText: "Artist: + Year:"
457 }
458 }
459 }
460
461
462 }
463 }
464
465
466 // Second tab begins here - artists here
467 Tab {
468 objectName: "Artists Tab"
469
470 title: i18n.tr("Artists")
471 page: Page {
472 anchors.margins: units.gu(2)
473
474 // foreach artist:
475 ListItem.Standard {
476 height: units.gu(4)
477 // when pressed on this row, change to albums of artist
478 Row {
479 Label {
480 text: i18n.tr("Artist 1")
481 }
482 }
483 }
484
485 // toolbar
486 tools: defaultToolbar
487
488 Column {
489 anchors.centerIn: parent
490 anchors.fill: parent
491 }
492 }
493 }
494
495 // Third tab begins here - albums here
496 Tab {
497 objectName: "Albums Tab"
498
499 title: i18n.tr("Albums")
500 page: Page {
501 anchors.margins: units.gu(2)
502
503 Column {
504 anchors.centerIn: parent
505 anchors.fill: parent
506 }
507
508 // toolbar
509 tools: defaultToolbar
510
511 Column {
512 anchors.centerIn: parent
513 }
514 }
515 }
516
517 // Fourth tab - tracks in ~/Music
518 Tab {
519 objectName: "Tracks Tab"
520
521 title: i18n.tr("Tracks")
522 page: MusicTracks { id: musicTracksPage }
523 } // 4th tab
524
525 } // tabs
526} // main view173} // main view
527174
=== added file 'playing-list.js'
--- playing-list.js 1970-01-01 00:00:00 +0000
+++ playing-list.js 2013-06-05 04:48:28 +0000
@@ -0,0 +1,34 @@
1//playing-list.js
2.pragma library
3var myArray = new Array()
4var myLocation = new Array()
5
6function getList() {
7 return myArray
8}
9
10function at(index) {
11 return myLocation[index]
12}
13
14function addItem(item, index) {
15 myArray.push(item)
16 myLocation.push(index)
17}
18
19function contains(item) {
20 return myArray.indexOf(item) !== -1
21}
22
23function indexOf(item) {
24 return myArray.indexOf(item)
25}
26
27function size() {
28 return myArray.length
29}
30
31function clear() {
32 myArray = []
33 myLocation = []
34}

Subscribers

People subscribed via source and target branches

to status/vote changes: