Merge lp:~ahayzen/music-app/remix-confinement-back-001 into lp:music-app/trusty

Proposed by Andrew Hayzen
Status: Superseded
Proposed branch: lp:~ahayzen/music-app/remix-confinement-back-001
Merge into: lp:music-app/trusty
Diff against target: 4986 lines (+1651/-1875) (has conflicts)
26 files modified
MusicAlbums.qml (+21/-123)
MusicArtists.qml (+37/-87)
MusicNowPlaying.qml (+381/-219)
MusicPlaylists.qml (+3/-2)
MusicSettings.qml (+0/-11)
MusicToolbar.qml (+169/-951)
MusicTracks.qml (+14/-15)
MusicaddtoPlaylist.qml (+0/-1)
Player.qml (+5/-1)
Style.qml (+2/-2)
click/apparmor.json (+14/-2)
com.ubuntu.music_music.desktop.in.in (+3/-0)
common/AlbumsPage.qml (+0/-2)
common/BlurredBackground.qml (+11/-9)
common/Card.qml (+151/-0)
common/CardView.qml (+42/-0)
common/ColumnFlow.qml (+159/-0)
common/CoverGrid.qml (+71/-0)
common/MusicPage.qml (+4/-0)
common/MusicRow.qml (+34/-5)
common/SongsPage.qml (+139/-118)
music-app.qml (+24/-33)
po/com.ubuntu.music.pot (+95/-81)
po/pt_BR.po (+111/-84)
tests/autopilot/music_app/__init__.py (+101/-83)
tests/autopilot/music_app/tests/test_music.py (+60/-46)
Text conflict in po/pt_BR.po
To merge this branch: bzr merge lp:~ahayzen/music-app/remix-confinement-back-001
Reviewer Review Type Date Requested Status
Music App Developers Pending
Review via email: mp+238220@code.launchpad.net

Commit message

* Add back confinement

Description of the change

* Add back confinement

Please test thoroughly, especially content-hub, url-dispatcher, thumbnailer.

To post a comment you must log in.
658. By Andrew Hayzen

* Reduce read paths

659. By Andrew Hayzen

* Merge of trunk

Unmerged revisions

659. By Andrew Hayzen

* Merge of trunk

658. By Andrew Hayzen

* Reduce read paths

657. By Andrew Hayzen

* Merge of lp:music-app/remix

656. By Andrew Hayzen

* Add back confinement

655. By Andrew Hayzen

* Remove legacy toolbar code
* Make full (non listview) now playing default
* Fix header disappearing in full now playing.

Approved by Victor Thompson, Ubuntu Phone Apps Jenkins Bot.

654. By Victor Thompson

* Use model.art property in AlbumsPage. Fixes: https://bugs.launchpad.net/bugs/1378157.

Approved by Andrew Hayzen, Ubuntu Phone Apps Jenkins Bot.

653. By Andrew Hayzen

* Add CardView and Card
* Implement in Albums tab.

Approved by Victor Thompson, Ubuntu Phone Apps Jenkins Bot.

652. By Victor Thompson

* Make the Ubuntu Slider leftColor UbuntuColors.blue.

Approved by Andrew Hayzen, Ubuntu Phone Apps Jenkins Bot.

651. By Victor Thompson

* Fix elide in Songs Page header
* Fix elide in MusicRow for Songs Page items.

Approved by Andrew Hayzen, Ubuntu Phone Apps Jenkins Bot.

650. By Victor Thompson

Used new desktop entries to show a fake application page during the startup. Fixes: https://bugs.launchpad.net/bugs/1377638.

Approved by Andrew Hayzen, Ubuntu Phone Apps Jenkins Bot.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'MusicAlbums.qml'
2--- MusicAlbums.qml 2014-09-20 15:41:33 +0000
3+++ MusicAlbums.qml 2014-10-14 00:24:55 +0000
4@@ -19,37 +19,17 @@
5
6 import QtQuick 2.3
7 import Ubuntu.Components 1.1
8-import Ubuntu.Components.Popups 1.0
9 import Ubuntu.MediaScanner 0.1
10-import Ubuntu.Thumbnailer 0.1
11-import QtMultimedia 5.0
12-import QtQuick.LocalStorage 2.0
13-import QtGraphicalEffects 1.0
14-import "settings.js" as Settings
15-import "playlists.js" as Playlists
16 import "common"
17
18+
19 MusicPage {
20- id: mainpage
21+ id: albumsPage
22 objectName: "albumsPage"
23 title: i18n.tr("Albums")
24
25- // TODO: This ListView is empty and causes the header to get painted with the desired background color because the
26- // page is now vertically flickable.
27- ListView {
28- anchors.fill: parent
29- anchors.bottomMargin: musicToolbar.mouseAreaOffset + musicToolbar.minimizedHeight
30- }
31-
32- GridView {
33- id: albumlist
34- anchors.fill: parent
35- anchors.leftMargin: units.gu(1)
36- anchors.top: parent.top
37- anchors.topMargin: mainView.header.height + units.gu(1)
38- anchors.bottomMargin: units.gu(1)
39- cellHeight: height/3
40- cellWidth: height/3
41+ CardView {
42+ id: albumCardView
43 model: SortFilterModel {
44 id: albumsModelFilter
45 property alias rowCount: albumsModel.rowCount
46@@ -60,106 +40,24 @@
47 sort.property: "title"
48 sort.order: Qt.AscendingOrder
49 }
50-
51- delegate: albumDelegate
52- flow: GridView.TopToBottom
53-
54- Component {
55- id: albumDelegate
56- Item {
57- property string artist: model.artist
58- property string album: model.title
59- property var covers: [{art: model.art}]
60-
61- id: albumItem
62- height: albumlist.cellHeight - units.gu(1)
63- objectName: "albumsPageGridItem" + index
64- width: albumlist.cellHeight - units.gu(1)
65- anchors.margins: units.gu(1)
66-
67- CoverRow {
68- id: albumShape
69- anchors {
70- top: parent.top
71- left: parent.left
72- verticalCenter: parent.verticalCenter
73- }
74- count: albumItem.covers.length
75- size: albumItem.width
76- covers: albumItem.covers
77- spacing: units.gu(2)
78- }
79- Item { // Background so can see text in current state
80- id: albumBg
81- anchors {
82- bottom: parent.bottom
83- left: parent.left
84- right: parent.right
85- }
86- height: units.gu(6)
87- clip: true
88- UbuntuShape{
89- anchors {
90- bottom: parent.bottom
91- left: parent.left
92- right: parent.right
93- }
94- height: albumShape.height
95- radius: "medium"
96- color: styleMusic.common.black
97- opacity: 0.6
98- }
99- }
100- Label {
101- id: albumArtist
102- objectName: "albums-albumartist"
103- anchors.bottom: parent.bottom
104- anchors.bottomMargin: units.gu(1)
105- anchors.left: parent.left
106- anchors.leftMargin: units.gu(1)
107- anchors.right: parent.right
108- anchors.rightMargin: units.gu(1)
109- color: styleMusic.common.white
110- elide: Text.ElideRight
111- text: model.artist
112- fontSize: "x-small"
113- }
114- Label {
115- id: albumLabel
116- anchors.bottom: parent.bottom
117- anchors.bottomMargin: units.gu(3)
118- anchors.left: parent.left
119- anchors.leftMargin: units.gu(1)
120- anchors.right: parent.right
121- anchors.rightMargin: units.gu(1)
122- color: styleMusic.common.white
123- elide: Text.ElideRight
124- text: model.title
125- fontSize: "small"
126- font.weight: Font.DemiBold
127- }
128-
129-
130- MouseArea {
131- anchors.fill: parent
132- onClicked: {
133- songsPage.album = model.title;
134- songsPage.covers = [{art: model.art}]
135- songsPage.genre = undefined
136- songsPage.isAlbum = true
137- songsPage.line1 = model.artist
138- songsPage.line2 = model.title
139- songsPage.title = i18n.tr("Album")
140-
141- mainPageStack.push(songsPage)
142- }
143-
144- // TODO: If http://pad.lv/1354753 is fixed to expose whether the Shape should appear pressed, update this as well.
145- onPressedChanged: albumShape.pressed = pressed
146- }
147+ delegate: Card {
148+ id: albumCard
149+ coverSources: [{art: model.art}]
150+ objectName: "albumsPageGridItem" + index
151+ primaryText: model.title
152+ secondaryText: model.artist
153+
154+ onClicked: {
155+ songsPage.album = model.title;
156+ songsPage.covers = [{art: model.art}]
157+ songsPage.genre = undefined
158+ songsPage.isAlbum = true
159+ songsPage.line1 = model.artist
160+ songsPage.line2 = model.title
161+ songsPage.title = i18n.tr("Album")
162+
163+ mainPageStack.push(songsPage)
164 }
165 }
166 }
167 }
168-
169-
170
171=== modified file 'MusicArtists.qml'
172--- MusicArtists.qml 2014-09-20 15:41:33 +0000
173+++ MusicArtists.qml 2014-10-14 00:24:55 +0000
174@@ -36,98 +36,48 @@
175 objectName: "artistsPage"
176 title: i18n.tr("Artists")
177
178- ListView {
179- id: artistlist
180- anchors.fill: parent
181- anchors.bottomMargin: musicToolbar.mouseAreaOffset + musicToolbar.minimizedHeight
182+ CardView {
183+ id: artistCardView
184+ itemWidth: units.gu(12)
185 model: ArtistsModel {
186 id: artistsModel
187 albumArtists: true
188 store: musicStore
189 }
190-
191- delegate: artistDelegate
192-
193- Component {
194- id: artistDelegate
195-
196- ListItem.Standard {
197- id: track
198- objectName: "artistsPageListItem" + index
199- height: styleMusic.common.itemHeight
200-
201- AlbumsModel {
202- id: albumArtistModel
203- albumArtist: model.artist
204- store: musicStore
205- }
206-
207- Repeater {
208- id: albumArtistModelRepeater
209- model: albumArtistModel
210- delegate: Item {
211- property string art: model.art
212- }
213- property var covers: []
214- signal finished()
215-
216- onFinished: {
217- musicRow.covers = covers
218- }
219- onItemAdded: {
220- covers.push({art: item.art});
221-
222- if (index === count - 1) {
223- finished();
224- }
225- }
226- }
227-
228- SongsModel {
229- id: songArtistModel
230- albumArtist: model.artist
231- store: musicStore
232- }
233-
234- MusicRow {
235- id: musicRow
236- column: Column {
237- spacing: units.gu(1)
238- Label {
239- id: trackArtistAlbum
240- color: styleMusic.common.music
241- fontSize: "medium"
242- objectName: "artists-artist"
243- text: model.artist
244- }
245- Label {
246- id: trackArtistAlbums
247- color: styleMusic.common.subtitle
248- fontSize: "x-small"
249- text: i18n.tr("%1 album", "%1 albums", albumArtistModel.rowCount).arg(albumArtistModel.rowCount)
250- }
251- Label {
252- id: trackArtistAlbumTracks
253- color: styleMusic.common.subtitle
254- fontSize: "x-small"
255- text: i18n.tr("%1 song", "%1 songs", songArtistModel.rowCount).arg(songArtistModel.rowCount)
256- }
257- }
258- }
259-
260- MouseArea {
261- anchors.fill: parent
262- onClicked: {
263- albumsPage.artist = model.artist
264- albumsPage.covers = musicRow.covers
265- albumsPage.title = i18n.tr("Artist")
266-
267- mainPageStack.push(albumsPage)
268- }
269-
270- // TODO: If http://pad.lv/1354753 is fixed to expose whether the Shape should appear pressed, update this as well.
271- onPressedChanged: musicRow.pressed = pressed
272- }
273+ delegate: Card {
274+ id: artistCard
275+ coverSources: [{art: "image://artistart/artist=" + model.artist + "&album=" + artistCard.album}]
276+ objectName: "artistsPageGridItem" + index
277+ primaryText: model.artist
278+ secondaryTextVisible: false
279+
280+ property string album: ""
281+
282+ AlbumsModel {
283+ id: albumArtistModel
284+ albumArtist: model.artist
285+ store: musicStore
286+ }
287+
288+ Repeater {
289+ id: albumArtistModelRepeater
290+ model: albumArtistModel
291+ delegate: Item {
292+ property string album: model.title
293+ }
294+
295+ onItemAdded: {
296+ artistCard.album = item.album
297+ }
298+ }
299+
300+
301+ onClicked: {
302+ albumsPage.artist = model.artist;
303+ albumsPage.covers = [{art: artistCard.imageSource}]
304+ albumsPage.title = i18n.tr("Artist")
305+
306+ mainPageStack.push(albumsPage)
307 }
308 }
309 }
310
311=== modified file 'MusicNowPlaying.qml'
312--- MusicNowPlaying.qml 2014-09-20 15:41:33 +0000
313+++ MusicNowPlaying.qml 2014-10-14 00:24:55 +0000
314@@ -17,7 +17,6 @@
315 * along with this program. If not, see <http://www.gnu.org/licenses/>.
316 */
317
318-
319 import QtMultimedia 5.0
320 import QtQuick 2.3
321 import QtQuick.LocalStorage 2.0
322@@ -29,65 +28,367 @@
323
324 MusicPage {
325 id: nowPlaying
326+ flickable: isListView ? queuelist : null // Ensures that the header is shown in fullview
327 objectName: "nowPlayingPage"
328- title: i18n.tr("Now Playing")
329+ title: isListView ? i18n.tr("Queue") : i18n.tr("Now playing")
330 visible: false
331
332- property int ensureVisibleIndex: 0 // ensure first index is visible at startup
333+ property bool isListView: false
334+
335+ onIsListViewChanged: {
336+ if (isListView) {
337+ positionAt(player.currentIndex);
338+ }
339+ }
340+
341+ head.backAction: Action {
342+ iconName: "back";
343+ objectName: "backButton"
344+ onTriggered: {
345+ mainPageStack.pop();
346+
347+ while (mainPageStack.depth > 1) { // jump back to the tab layer if via SongsPage
348+ mainPageStack.pop();
349+ }
350+ }
351+ }
352+
353+ head {
354+ actions: [
355+ Action {
356+ objectName: "clearQueue"
357+ iconName: "delete"
358+ visible: isListView
359+ onTriggered: {
360+ head.backAction.trigger()
361+ trackQueue.model.clear()
362+ }
363+ },
364+ Action {
365+ objectName: "toggleView"
366+ iconName: "media-playlist"
367+ onTriggered: {
368+ isListView = !isListView
369+ }
370+ }
371+ ]
372+ }
373+
374+ function positionAt(index) {
375+ queuelist.positionViewAtIndex(index, ListView.Center);
376+ }
377
378 Rectangle {
379+ id: fullview
380 anchors.fill: parent
381- color: styleMusic.nowPlaying.backgroundColor
382- opacity: 0.75 // change later
383- MouseArea { // Block events to lower layers
384- anchors.fill: parent
385- }
386- }
387-
388- Component.onCompleted: {
389- onToolbarShownChanged.connect(jumpToCurrent)
390- }
391-
392- Connections {
393- target: player
394- onCurrentIndexChanged: {
395- if (player.source === "") {
396- return;
397- }
398-
399- queuelist.currentIndex = player.currentIndex;
400-
401- customdebug("MusicQueue update currentIndex: " + player.source);
402-
403- // Always jump to current track
404- nowPlaying.jumpToCurrent(musicToolbar.opened, nowPlaying, musicToolbar.currentTab)
405-
406- }
407- }
408-
409- function jumpToCurrent(shown, currentPage, currentTab)
410- {
411- // If the toolbar is shown, the page is now playing and snaptrack is enabled
412- if (shown && currentPage === nowPlaying && Settings.getSetting("snaptrack") === "1")
413- {
414- // Then position the view at the current index
415- queuelist.positionViewAtIndex(queuelist.currentIndex, ListView.Beginning);
416- }
417- }
418-
419- function positionAt(index) {
420- queuelist.positionViewAtIndex(index, ListView.Beginning);
421- queuelist.contentY -= header.height;
422+ color: "transparent"
423+ visible: !isListView
424+
425+ BlurredBackground {
426+ id: blurredBackground
427+ anchors.top: parent.top
428+ anchors.topMargin: mainView.header.height
429+ height: units.gu(27)
430+ art: albumImage.source
431+
432+ Image {
433+ id: albumImage
434+ anchors.centerIn: parent
435+ width: units.gu(18)
436+ height: width
437+ smooth: true
438+ source: player.currentMetaArt === "" ?
439+ decodeURIComponent("image://albumart/artist=" +
440+ player.currentMetaArtist +
441+ "&album=" + player.currentMetaAlbum)
442+ : player.currentMetaArt
443+ }
444+ }
445+
446+ /* Full toolbar */
447+ Item {
448+ id: musicToolbarFullContainer
449+ anchors.top: blurredBackground.bottom
450+ anchors.topMargin: units.gu(4)
451+ width: blurredBackground.width
452+
453+ /* Column for labels in wideAspect */
454+ Column {
455+ id: nowPlayingWideAspectLabels
456+ spacing: units.gu(1)
457+ anchors {
458+ left: parent.left
459+ leftMargin: units.gu(2)
460+ right: parent.right
461+ rightMargin: units.gu(2)
462+ }
463+
464+ /* Title of track */
465+ Label {
466+ id: nowPlayingWideAspectTitle
467+ anchors {
468+ left: parent.left
469+ leftMargin: units.gu(1)
470+ right: parent.right
471+ rightMargin: units.gu(1)
472+ }
473+ color: styleMusic.playerControls.labelColor
474+ elide: Text.ElideRight
475+ fontSize: "x-large"
476+ objectName: "playercontroltitle"
477+ text: trackQueue.model.count === 0 ? "" : player.currentMetaTitle === "" ? player.currentMetaFile : player.currentMetaTitle
478+ }
479+
480+ /* Artist of track */
481+ Label {
482+ id: nowPlayingWideAspectArtist
483+ anchors {
484+ left: parent.left
485+ leftMargin: units.gu(1)
486+ right: parent.right
487+ rightMargin: units.gu(1)
488+ }
489+ color: styleMusic.nowPlaying.labelSecondaryColor
490+ elide: Text.ElideRight
491+ fontSize: "small"
492+ text: trackQueue.model.count === 0 ? "" : player.currentMetaArtist
493+ }
494+ }
495+
496+ /* Progress bar component */
497+ MouseArea {
498+ id: musicToolbarFullProgressContainer
499+ anchors.left: parent.left
500+ anchors.leftMargin: units.gu(3)
501+ anchors.right: parent.right
502+ anchors.rightMargin: units.gu(3)
503+ anchors.top: nowPlayingWideAspectLabels.bottom
504+ anchors.topMargin: units.gu(3)
505+ height: units.gu(3)
506+ width: parent.width
507+
508+ /* Position label */
509+ Label {
510+ id: musicToolbarFullPositionLabel
511+ anchors.top: progressSliderMusic.bottom
512+ anchors.topMargin: units.gu(-2)
513+ anchors.left: parent.left
514+ color: styleMusic.nowPlaying.labelSecondaryColor
515+ fontSize: "small"
516+ height: parent.height
517+ horizontalAlignment: Text.AlignHCenter
518+ text: durationToString(player.position)
519+ verticalAlignment: Text.AlignVCenter
520+ width: units.gu(3)
521+ }
522+
523+ Slider {
524+ id: progressSliderMusic
525+ anchors.left: parent.left
526+ anchors.right: parent.right
527+ objectName: "progressSliderShape"
528+
529+ function formatValue(v) {
530+ if (seeking) { // update position label while dragging
531+ musicToolbarFullPositionLabel.text = durationToString(v)
532+ }
533+
534+ return durationToString(v)
535+ }
536+
537+ property bool seeking: false
538+ property bool seeked: false
539+
540+ onSeekingChanged: {
541+ if (seeking === false) {
542+ musicToolbarFullPositionLabel.text = durationToString(player.position)
543+ }
544+ }
545+
546+ Component.onCompleted: {
547+ Theme.palette.selected.foreground = UbuntuColors.blue
548+ }
549+
550+ onPressedChanged: {
551+ seeking = pressed
552+ if (!pressed) {
553+ seeked = true
554+ player.seek(value)
555+ }
556+ }
557+
558+ Connections {
559+ target: player
560+ onDurationChanged: {
561+ musicToolbarFullDurationLabel.text = durationToString(player.duration)
562+ progressSliderMusic.maximumValue = player.duration
563+ }
564+ onPositionChanged: {
565+ // seeked is a workaround for bug 1310706 as the first position after a seek is sometimes invalid (0)
566+ if (progressSliderMusic.seeking === false && !progressSliderMusic.seeked) {
567+ progressSliderMusic.value = player.position
568+ musicToolbarFullPositionLabel.text = durationToString(player.position)
569+ musicToolbarFullDurationLabel.text = durationToString(player.duration)
570+ }
571+
572+ progressSliderMusic.seeked = false;
573+ }
574+ onStopped: {
575+ musicToolbarFullPositionLabel.text = durationToString(0);
576+ musicToolbarFullDurationLabel.text = durationToString(0);
577+ }
578+ }
579+ }
580+
581+ /* Duration label */
582+ Label {
583+ id: musicToolbarFullDurationLabel
584+ anchors.top: progressSliderMusic.bottom
585+ anchors.topMargin: units.gu(-2)
586+ anchors.right: parent.right
587+ color: styleMusic.nowPlaying.labelSecondaryColor
588+ fontSize: "small"
589+ height: parent.height
590+ horizontalAlignment: Text.AlignHCenter
591+ text: durationToString(player.duration)
592+ verticalAlignment: Text.AlignVCenter
593+ width: units.gu(3)
594+ }
595+ }
596+
597+ /* Repeat button */
598+ MouseArea {
599+ id: nowPlayingRepeatButton
600+ anchors.right: nowPlayingPreviousButton.left
601+ anchors.rightMargin: units.gu(1)
602+ anchors.verticalCenter: nowPlayingPlayButton.verticalCenter
603+ height: units.gu(6)
604+ opacity: player.repeat && !emptyPage.noMusic ? 1 : .4
605+ width: height
606+ onClicked: player.repeat = !player.repeat
607+
608+ Icon {
609+ id: repeatIcon
610+ height: units.gu(3)
611+ width: height
612+ anchors.verticalCenter: parent.verticalCenter
613+ anchors.horizontalCenter: parent.horizontalCenter
614+ color: "white"
615+ name: "media-playlist-repeat"
616+ objectName: "repeatShape"
617+ opacity: player.repeat && !emptyPage.noMusic ? 1 : .4
618+ }
619+ }
620+
621+ /* Previous button */
622+ MouseArea {
623+ id: nowPlayingPreviousButton
624+ anchors.right: nowPlayingPlayButton.left
625+ anchors.rightMargin: units.gu(1)
626+ anchors.verticalCenter: nowPlayingPlayButton.verticalCenter
627+ height: units.gu(6)
628+ opacity: trackQueue.model.count === 0 ? .4 : 1
629+ width: height
630+ onClicked: player.previousSong()
631+
632+ Icon {
633+ id: nowPlayingPreviousIndicator
634+ height: units.gu(3)
635+ width: height
636+ anchors.verticalCenter: parent.verticalCenter
637+ anchors.horizontalCenter: parent.horizontalCenter
638+ color: "white"
639+ name: "media-skip-backward"
640+ objectName: "previousShape"
641+ opacity: 1
642+ }
643+ }
644+
645+ /* Play/Pause button */
646+ MouseArea {
647+ id: nowPlayingPlayButton
648+ anchors.horizontalCenter: parent.horizontalCenter
649+ anchors.top: musicToolbarFullProgressContainer.bottom
650+ anchors.topMargin: units.gu(2)
651+ height: units.gu(12)
652+ width: height
653+ onClicked: player.toggle()
654+
655+ Icon {
656+ id: nowPlayingPlayIndicator
657+ height: units.gu(6)
658+ width: height
659+ anchors.verticalCenter: parent.verticalCenter
660+ anchors.horizontalCenter: parent.horizontalCenter
661+ opacity: emptyPage.noMusic ? .4 : 1
662+ color: "white"
663+ name: player.playbackState === MediaPlayer.PlayingState ? "media-playback-pause" : "media-playback-start"
664+ objectName: "playShape"
665+ }
666+ }
667+
668+ /* Next button */
669+ MouseArea {
670+ id: nowPlayingNextButton
671+ anchors.left: nowPlayingPlayButton.right
672+ anchors.leftMargin: units.gu(1)
673+ anchors.verticalCenter: nowPlayingPlayButton.verticalCenter
674+ height: units.gu(6)
675+ opacity: trackQueue.model.count === 0 ? .4 : 1
676+ width: height
677+ onClicked: player.nextSong()
678+
679+ Icon {
680+ id: nowPlayingNextIndicator
681+ height: units.gu(3)
682+ width: height
683+ anchors.verticalCenter: parent.verticalCenter
684+ anchors.horizontalCenter: parent.horizontalCenter
685+ color: "white"
686+ name: "media-skip-forward"
687+ objectName: "forwardShape"
688+ opacity: 1
689+ }
690+ }
691+
692+ /* Shuffle button */
693+ MouseArea {
694+ id: nowPlayingShuffleButton
695+ anchors.left: nowPlayingNextButton.right
696+ anchors.leftMargin: units.gu(1)
697+ anchors.verticalCenter: nowPlayingPlayButton.verticalCenter
698+ height: units.gu(6)
699+ opacity: player.shuffle && !emptyPage.noMusic ? 1 : .4
700+ width: height
701+ onClicked: player.shuffle = !player.shuffle
702+
703+ Icon {
704+ id: shuffleIcon
705+ height: units.gu(3)
706+ width: height
707+ anchors.verticalCenter: parent.verticalCenter
708+ anchors.horizontalCenter: parent.horizontalCenter
709+ color: "white"
710+ name: "media-playlist-shuffle"
711+ objectName: "shuffleShape"
712+ opacity: player.shuffle && !emptyPage.noMusic ? 1 : .4
713+ }
714+ }
715+ }
716 }
717
718 ListView {
719 id: queuelist
720- objectName: "nowPlayingQueueList"
721- anchors.fill: parent
722- anchors.bottomMargin: musicToolbar.mouseAreaOffset + musicToolbar.minimizedHeight
723+ anchors {
724+ fill: parent
725+ topMargin: units.gu(2)
726+ }
727 delegate: queueDelegate
728+ footer: Item {
729+ height: mainView.height - (styleMusic.common.expandHeight + queuelist.currentHeight) + units.gu(8)
730+ }
731 model: trackQueue.model
732- highlightFollowsCurrentItem: false
733+ objectName: "nowPlayingQueueList"
734 state: "normal"
735 states: [
736 State {
737@@ -105,33 +406,29 @@
738 }
739 }
740 ]
741- footer: Item {
742- height: mainView.height - (styleMusic.common.expandHeight + queuelist.currentHeight) + units.gu(8)
743- }
744+ visible: isListView
745
746- property int normalHeight: units.gu(12)
747- property int currentHeight: units.gu(40)
748+ property int normalHeight: units.gu(6)
749 property int transitionDuration: 250 // transition length of animations
750
751 onCountChanged: {
752 customdebug("Queue: Now has: " + queuelist.count + " tracks")
753 }
754
755- onMovementStarted: {
756- musicToolbar.hideToolbar();
757- }
758-
759 Component {
760 id: queueDelegate
761 ListItemWithActions {
762 id: queueListItem
763- color: "transparent"
764+ color: player.currentIndex === index ? "#2c2c34" : "transparent"
765 height: queuelist.normalHeight
766 objectName: "nowPlayingListItem" + index
767- state: queuelist.currentIndex == index && !reordering ? "current" : ""
768+ showDivider: false
769+ state: ""
770
771 leftSideAction: Remove {
772 onTriggered: {
773+ var removedIndex = index
774+
775 if (queuelist.count === 1) {
776 player.stop()
777 musicToolbar.goBack()
778@@ -139,12 +436,12 @@
779 player.nextSong(player.isPlaying);
780 }
781
782- if (index < player.currentIndex) {
783+ queuelist.model.remove(index);
784+
785+ if (removedIndex < player.currentIndex) {
786 // update index as the old has been removed
787 player.currentIndex -= 1;
788 }
789-
790- queuelist.model.remove(index);
791 }
792 }
793 reorderable: true
794@@ -177,14 +474,10 @@
795 }
796 }
797
798- // TODO: If http://pad.lv/1354753 is fixed to expose whether the Shape should appear pressed, update this as well.
799- onPressedChanged: trackImage.pressed = pressed
800-
801 Rectangle {
802 id: trackContainer;
803 anchors {
804 fill: parent
805- margins: units.gu(1)
806 }
807 color: "transparent"
808
809@@ -204,159 +497,28 @@
810 to: units.gu(0.5)
811 }
812
813- CoverRow {
814- id: trackImage
815-
816- anchors {
817- top: parent.top
818- left: parent.left
819- leftMargin: units.gu(1.5)
820- }
821- count: 1
822- size: (queueListItem.state === "current"
823- ? (mainView.wideAspect
824- ? queuelist.currentHeight
825- : mainView.width - (trackImage.anchors.leftMargin * 2))
826- : queuelist.normalHeight) - units.gu(2)
827- covers: [{art: model.art}]
828-
829- spacing: units.gu(2)
830-
831- Item { // Background so can see text in current state
832- id: albumBg
833- visible: false
834- anchors {
835- bottom: parent.bottom
836- left: parent.left
837- right: parent.right
838- }
839- height: units.gu(9)
840- clip: true
841- UbuntuShape{
842- anchors {
843- bottom: parent.bottom
844- left: parent.left
845- right: parent.right
846- }
847- height: trackImage.height
848- radius: "medium"
849- color: styleMusic.common.black
850- opacity: 0.6
851- }
852- }
853-
854- function calcAnchors() {
855- if (trackImage.height > queuelist.normalHeight && mainView.wideAspect) {
856- trackImage.anchors.left = undefined
857- trackImage.anchors.horizontalCenter = trackImage.parent.horizontalCenter
858- } else {
859- trackImage.anchors.left = trackImage.parent.left
860- trackImage.anchors.horizontalCenter = undefined
861- }
862-
863- trackImage.width = trackImage.height; // force width to match height
864- }
865-
866- Connections {
867- target: mainView
868- onWideAspectChanged: trackImage.calcAnchors()
869- }
870-
871- onHeightChanged: {
872- calcAnchors()
873- }
874- Behavior on height {
875- NumberAnimation {
876- target: trackImage;
877- property: "height";
878- duration: queuelist.transitionDuration;
879- }
880- }
881- }
882- Label {
883- id: nowPlayingArtist
884- objectName: "artistLabel"
885- color: styleMusic.nowPlaying.labelSecondaryColor
886- elide: Text.ElideRight
887- height: units.gu(1)
888- text: model.author
889- fontSize: 'small'
890- width: parent.width - trackImage.width - units.gu(3.5)
891- x: trackImage.x + trackImage.width + units.gu(1)
892- y: trackImage.y + units.gu(1)
893- }
894- Label {
895- id: nowPlayingTitle
896- objectName: "titleLabel"
897- color: styleMusic.common.white
898- elide: Text.ElideRight
899- height: units.gu(1)
900- text: model.title
901- fontSize: 'medium'
902- width: parent.width - trackImage.width - units.gu(3.5)
903- x: trackImage.x + trackImage.width + units.gu(1)
904- y: nowPlayingArtist.y + nowPlayingArtist.height + units.gu(1.25)
905- }
906- Label {
907- id: nowPlayingAlbum
908- objectName: "albumLabel"
909- color: styleMusic.nowPlaying.labelSecondaryColor
910- elide: Text.ElideRight
911- height: units.gu(1)
912- text: model.album
913- fontSize: 'x-small'
914- width: parent.width - trackImage.width - units.gu(3.5)
915- x: trackImage.x + trackImage.width + units.gu(1)
916- y: nowPlayingTitle.y + nowPlayingTitle.height + units.gu(1.25)
917- }
918- }
919-
920- states: State {
921- name: "current"
922- PropertyChanges {
923- target: queueListItem
924- height: trackImage.size + (trackContainer.anchors.margins * 2)
925- }
926- PropertyChanges {
927- target: nowPlayingArtist
928- width: trackImage.width - units.gu(4)
929- x: trackImage.x + units.gu(2)
930- y: trackImage.y + trackImage.height - albumBg.height + units.gu(1)
931- color: styleMusic.common.white
932- }
933- PropertyChanges {
934- target: nowPlayingTitle
935- width: trackImage.width - units.gu(4)
936- x: trackImage.x + units.gu(2)
937- y: nowPlayingArtist.y + nowPlayingArtist.height + units.gu(1.25)
938- color: styleMusic.common.white
939- font.weight: Font.DemiBold
940- }
941- PropertyChanges {
942- target: nowPlayingAlbum
943- width: trackImage.width - units.gu(4)
944- x: trackImage.x + units.gu(2)
945- y: nowPlayingTitle.y + nowPlayingTitle.height + units.gu(1.25)
946- color: styleMusic.common.white
947- }
948- PropertyChanges {
949- target: albumBg
950- visible: true
951- }
952- }
953- transitions: Transition {
954- from: ",current"
955- to: "current,"
956- NumberAnimation {
957- duration: queuelist.transitionDuration
958- properties: "height,opacity,width,x,y"
959- }
960-
961- onRunningChanged: {
962- if (running === false && ensureVisibleIndex != -1)
963- {
964- queuelist.positionViewAtIndex(ensureVisibleIndex, ListView.Beginning);
965- ensureVisibleIndex = -1;
966+ MusicRow {
967+ id: musicRow
968+ covers: [{art: model.art, album: model.album, author: model.author}]
969+ showCovers: false
970+ coverSize: units.gu(6)
971+ column: Column {
972+ Label {
973+ id: trackTitle
974+ color: player.currentIndex === index ? UbuntuColors.blue
975+ : styleMusic.common.music
976+ fontSize: "small"
977+ objectName: "titleLabel"
978+ text: model.title
979+ }
980+
981+ Label {
982+ id: trackArtist
983+ color: styleMusic.common.subtitle
984+ fontSize: "x-small"
985+ objectName: "artistLabel"
986+ text: model.author
987+ }
988 }
989 }
990 }
991
992=== modified file 'MusicPlaylists.qml'
993--- MusicPlaylists.qml 2014-09-20 10:50:45 +0000
994+++ MusicPlaylists.qml 2014-10-14 00:24:55 +0000
995@@ -116,8 +116,9 @@
996 ListView {
997 id: playlistslist
998 objectName: "playlistsListView"
999- anchors.fill: parent
1000- anchors.bottomMargin: musicToolbar.mouseAreaOffset + musicToolbar.minimizedHeight
1001+ anchors {
1002+ fill: parent
1003+ }
1004 model: playlistModel.model
1005 delegate: playlistDelegate
1006 onCountChanged: {
1007
1008=== modified file 'MusicSettings.qml'
1009--- MusicSettings.qml 2014-09-20 10:50:45 +0000
1010+++ MusicSettings.qml 2014-10-14 00:24:55 +0000
1011@@ -30,17 +30,6 @@
1012 title: i18n.tr("Settings")
1013 contentsHeight: parent.height;
1014
1015- onVisibleChanged: {
1016- if (visible === true)
1017- {
1018- musicToolbar.disableToolbar()
1019- }
1020- else
1021- {
1022- musicToolbar.enableToolbar()
1023- }
1024- }
1025-
1026 onCancelClicked: PopupUtils.close(musicSettings)
1027 onConfirmClicked: {
1028 PopupUtils.close(musicSettings)
1029
1030=== modified file 'MusicToolbar.qml'
1031--- MusicToolbar.qml 2014-09-23 20:45:41 +0000
1032+++ MusicToolbar.qml 2014-10-14 00:24:55 +0000
1033@@ -35,59 +35,13 @@
1034 property var currentPage: null
1035 property var currentSheet: []
1036 property var currentTab: null
1037- property var previousPage: null
1038
1039 // Properties and signals for the toolbar
1040- property var cachedStates: []
1041- property bool shown: false
1042- property int transitionDuration: 100
1043-
1044 property alias currentHeight: musicToolbarPanel.height
1045- property alias minimizedHeight: musicToolbarPanel.minimizedHeight
1046- property alias expandedHeight: musicToolbarPanel.expandedHeight
1047- property alias fullHeight: musicToolbarPanel.fullHeight
1048- property alias mouseAreaOffset: musicToolbarPanel.hintSize
1049-
1050- property alias animating: musicToolbarPanel.animating
1051 property alias opened: musicToolbarPanel.opened
1052
1053- // Alias for autopilot
1054- property alias currentMode: musicToolbarPanel.currentMode
1055-
1056- Connections {
1057- id: pageStackConn
1058- target: mainPageStack
1059-
1060- onCurrentPageChanged: {
1061- previousPage = currentPage;
1062-
1063- // If going back from nowPlaying jump back to tabs
1064- if (previousPage === nowPlaying && mainPageStack.currentPage !== nowPlaying) {
1065- while (mainPageStack.depth > 1) {
1066- mainPageStack.pop(mainPageStack.currentPage)
1067- }
1068- }
1069- }
1070- }
1071-
1072 /* Helper functions */
1073
1074- // Disable the toolbar for this page/view (eg a dialog)
1075- function disableToolbar()
1076- {
1077- cachedStates.push(state);
1078- musicToolbarPanel.state = "hidden";
1079- }
1080-
1081- // Enable the toolbar (run when closing a page that disabled it)
1082- function enableToolbar()
1083- {
1084- if (cachedStates.length > 0)
1085- {
1086- musicToolbarPanel.state = cachedStates.pop();
1087- }
1088- }
1089-
1090 // Back button has been pressed, jump up pageStack or back to parent page
1091 function goBack()
1092 {
1093@@ -98,18 +52,6 @@
1094 else if (mainPageStack !== null && mainPageStack.depth > 1) {
1095 mainPageStack.pop(currentPage)
1096 }
1097-
1098- startAutohideTimer()
1099- }
1100-
1101- // Hide the toolbar
1102- function hideToolbar()
1103- {
1104- if (!wideAspect) {
1105- musicToolbarPanel.close();
1106- }
1107-
1108- toolbarAutoHideTimer.stop(); // cancel any autohide
1109 }
1110
1111 // Remove sheet as it has been closed
1112@@ -126,8 +68,6 @@
1113 function setPage(childPage)
1114 {
1115 currentPage = childPage;
1116- // note: If pageStack tracking is needed readd here
1117- //currentPageStack = pageStack === undefined ? null : pageStack;
1118 }
1119
1120 // Set the current sheet (overrides page)
1121@@ -135,32 +75,6 @@
1122 currentSheet.push(sheet)
1123 }
1124
1125- // Show the toolbar
1126- function showToolbar()
1127- {
1128- startAutohideTimer(); // always attempt to autohide toolbar
1129-
1130- if (!musicToolbarPanel.opened) {
1131- musicToolbarPanel.open();
1132- }
1133- }
1134-
1135- // Start the autohidetimer
1136- function startAutohideTimer()
1137- {
1138- toolbarAutoHideTimer.restart();
1139- }
1140-
1141- Connections {
1142- target: mainView
1143- onWideAspectChanged: {
1144- // Force toolbar to show if in wideAspect
1145- if (wideAspect && !opened) {
1146- showToolbar();
1147- }
1148- }
1149- }
1150-
1151 Panel {
1152 id: musicToolbarPanel
1153 anchors {
1154@@ -168,543 +82,9 @@
1155 right: parent.right
1156 bottom: parent.bottom
1157 }
1158- height: currentMode === "full" ? fullHeight : expandedHeight
1159- locked: wideAspect
1160-
1161- __closeOnContentsClicks: false // TODO: fix bug 1295720
1162-
1163- // The current mode of the controls
1164- property string currentMode: wideAspect || (currentPage === nowPlaying)
1165- ? "full" : "expanded"
1166-
1167- // Properties for the different heights
1168- property int minimizedHeight: units.gu(0.5)
1169- property int expandedHeight: units.gu(8)
1170- property int fullHeight: units.gu(11)
1171-
1172- onCurrentModeChanged: {
1173- musicToolbarFullProgressMouseArea.enabled = currentMode === "full"
1174- }
1175-
1176- onOpenedChanged: {
1177- onToolbarShownChanged(opened, currentPage, currentTab);
1178-
1179- if (opened) {
1180- startAutohideTimer();
1181- }
1182- }
1183-
1184- /* Full toolbar */
1185- Rectangle {
1186- id: musicToolbarFullContainer
1187- anchors {
1188- fill: parent
1189- }
1190- color: styleMusic.toolbar.fullBackgroundColor
1191- visible: musicToolbarPanel.currentMode === "full"
1192-
1193- /* Buttons component */
1194- Rectangle {
1195- id: musicToolbarFullButtonsContainer
1196- anchors.left: parent.left
1197- anchors.top: musicToolbarFullProgressContainer.bottom
1198- color: "transparent"
1199- height: parent.height - musicToolbarFullProgressContainer.height
1200- width: parent.width
1201-
1202- /* Column for labels in wideAspect */
1203- Column {
1204- id: nowPlayingWideAspectLabels
1205- anchors {
1206- left: parent.left
1207- leftMargin: units.gu(1)
1208- right: nowPlayingRepeatButton.left
1209- rightMargin: units.gu(1)
1210- verticalCenter: parent.verticalCenter
1211- }
1212- visible: wideAspect
1213-
1214- /* Clicking in the area shows the queue */
1215- function trigger() {
1216- if (trackQueue.model.count !== 0 && currentPage !== nowPlaying) {
1217- tabs.pushNowPlaying();
1218- }
1219- else if (currentPage === nowPlaying) {
1220- musicToolbar.goBack();
1221- }
1222- }
1223-
1224- /* Title of track */
1225- Label {
1226- id: nowPlayingWideAspectTitle
1227- anchors {
1228- left: parent.left
1229- leftMargin: units.gu(1)
1230- right: parent.right
1231- rightMargin: units.gu(1)
1232- }
1233- color: styleMusic.playerControls.labelColor
1234- elide: Text.ElideRight
1235- fontSize: "medium"
1236- objectName: "playercontroltitle"
1237- text: trackQueue.model.count === 0 ? "" : player.currentMetaTitle === "" ? player.currentMetaFile : player.currentMetaTitle
1238- }
1239-
1240- /* Artist of track */
1241- Label {
1242- id: nowPlayingWideAspectArtist
1243- anchors {
1244- left: parent.left
1245- leftMargin: units.gu(1)
1246- right: parent.right
1247- rightMargin: units.gu(1)
1248- }
1249- color: styleMusic.playerControls.labelColor
1250- elide: Text.ElideRight
1251- fontSize: "small"
1252- text: trackQueue.model.count === 0 ? "" : player.currentMetaArtist
1253- }
1254-
1255- /* Album of track */
1256- Label {
1257- id: nowPlayingWideAspectAlbum
1258- anchors {
1259- left: parent.left
1260- leftMargin: units.gu(1)
1261- right: parent.right
1262- rightMargin: units.gu(1)
1263- }
1264- color: styleMusic.playerControls.labelColor
1265- elide: Text.ElideRight
1266- fontSize: "small"
1267- text: trackQueue.model.count === 0 ? "" : player.currentMetaAlbum
1268- }
1269- }
1270-
1271- /* Repeat button */
1272- Item {
1273- id: nowPlayingRepeatButton
1274- objectName: "repeatShape"
1275- anchors.right: nowPlayingPreviousButton.left
1276- anchors.rightMargin: units.gu(1)
1277- anchors.verticalCenter: parent.verticalCenter
1278- height: units.gu(6)
1279- opacity: player.repeat && !emptyPage.noMusic ? 1 : .4
1280- width: height
1281-
1282- function trigger() {
1283- if (emptyPage.noMusic) {
1284- return;
1285- }
1286-
1287- // Invert repeat settings
1288- player.repeat = !player.repeat
1289- }
1290-
1291- Image {
1292- id: repeatIcon
1293- height: units.gu(3)
1294- width: height
1295- anchors.verticalCenter: parent.verticalCenter
1296- anchors.horizontalCenter: parent.horizontalCenter
1297- source: Qt.resolvedUrl("images/media-playlist-repeat.svg")
1298- verticalAlignment: Text.AlignVCenter
1299- opacity: player.repeat && !emptyPage.noMusic ? 1 : .4
1300- }
1301- }
1302-
1303- /* Previous button */
1304- Item {
1305- id: nowPlayingPreviousButton
1306- anchors.right: nowPlayingPlayButton.left
1307- anchors.rightMargin: units.gu(1)
1308- anchors.verticalCenter: parent.verticalCenter
1309- height: units.gu(6)
1310- objectName: "previousShape"
1311- opacity: trackQueue.model.count === 0 ? .4 : 1
1312- width: height
1313-
1314- function trigger() {
1315- if (trackQueue.model.count === 0) {
1316- return;
1317- }
1318-
1319- player.previousSong()
1320- }
1321-
1322- Image {
1323- id: nowPlayingPreviousIndicator
1324- height: units.gu(3)
1325- width: height
1326- anchors.horizontalCenter: parent.horizontalCenter
1327- anchors.verticalCenter: parent.verticalCenter
1328- source: Qt.resolvedUrl("images/media-skip-backward.svg")
1329- opacity: 1
1330- }
1331- }
1332-
1333- /* Play/Pause button */
1334- Rectangle {
1335- id: nowPlayingPlayButton
1336- anchors.horizontalCenter: parent.horizontalCenter
1337- anchors.verticalCenter: parent.verticalCenter
1338- antialiasing: true
1339- color: styleMusic.toolbar.fullOuterPlayCircleColor
1340- height: units.gu(12)
1341- radius: height / 2
1342- width: height
1343-
1344- // draws the outter shadow/highlight
1345- Rectangle {
1346- id: sourceOutterFull
1347- anchors { fill: parent; margins: -units.gu(0.1) }
1348- radius: (width / 2)
1349- antialiasing: true
1350- gradient: Gradient {
1351- GradientStop { position: 0.0; color: "black" }
1352- GradientStop { position: 0.5; color: "transparent" }
1353- GradientStop { position: 1.0; color: UbuntuColors.warmGrey }
1354- }
1355-
1356- Rectangle {
1357- anchors.horizontalCenter: parent.horizontalCenter
1358- anchors.verticalCenter: parent.verticalCenter
1359- antialiasing: true
1360- color: styleMusic.toolbar.fullOuterPlayCircleColor
1361- height: nowPlayingPlayButton.height - units.gu(.1)
1362- radius: height / 2
1363- width: height
1364-
1365- Rectangle {
1366- id: nowPlayingPlayButtonInner
1367- anchors.horizontalCenter: parent.horizontalCenter
1368- anchors.verticalCenter: parent.verticalCenter
1369- antialiasing: true
1370- color: styleMusic.toolbar.fullInnerPlayCircleColor
1371- height: units.gu(7)
1372- radius: height / 2
1373- width: height
1374-
1375- // draws the inner shadow/highlight
1376- Rectangle {
1377- id: sourceInnerFull
1378- anchors { fill: parent; margins: -units.gu(0.1) }
1379- radius: (width / 2)
1380- antialiasing: true
1381- gradient: Gradient {
1382- GradientStop { position: 0.0; color: UbuntuColors.warmGrey }
1383- GradientStop { position: 0.5; color: "transparent" }
1384- GradientStop { position: 1.0; color: "black" }
1385- }
1386-
1387- Rectangle {
1388- anchors.horizontalCenter: parent.horizontalCenter
1389- anchors.verticalCenter: parent.verticalCenter
1390- antialiasing: true
1391- color: styleMusic.toolbar.fullInnerPlayCircleColor
1392- height: nowPlayingPlayButtonInner.height - units.gu(.1)
1393- objectName: "playShape"
1394- radius: height / 2
1395- width: height
1396-
1397- function trigger() {
1398- if (emptyPage.noMusic) {
1399- return;
1400- }
1401-
1402- if (trackQueue.model.count === 0) {
1403- playRandomSong();
1404- }
1405- else {
1406- player.toggle();
1407- }
1408- }
1409-
1410- Image {
1411- id: nowPlayingPlayIndicator
1412- height: units.gu(6)
1413- width: height
1414- anchors.horizontalCenter: parent.horizontalCenter
1415- anchors.verticalCenter: parent.verticalCenter
1416- opacity: emptyPage.noMusic ? .4 : 1
1417- source: player.playbackState === MediaPlayer.PlayingState ?
1418- Qt.resolvedUrl("images/media-playback-pause.svg") : Qt.resolvedUrl("images/media-playback-start.svg")
1419- }
1420- }
1421- }
1422- }
1423- }
1424- }
1425- }
1426-
1427- /* Next button */
1428- Item {
1429- id: nowPlayingNextButton
1430- anchors.left: nowPlayingPlayButton.right
1431- anchors.leftMargin: units.gu(1)
1432- anchors.verticalCenter: parent.verticalCenter
1433- height: units.gu(6)
1434- objectName: "forwardShape"
1435- opacity: trackQueue.model.count === 0 ? .4 : 1
1436- width: height
1437-
1438- function trigger() {
1439- if (trackQueue.model.count === 0 || emptyPage.noMusic) {
1440- return;
1441- }
1442-
1443- player.nextSong()
1444- }
1445-
1446- Image {
1447- id: nowPlayingNextIndicator
1448- height: units.gu(3)
1449- width: height
1450- anchors.horizontalCenter: parent.horizontalCenter
1451- anchors.verticalCenter: parent.verticalCenter
1452- source: Qt.resolvedUrl("images/media-skip-forward.svg")
1453- opacity: 1
1454- }
1455- }
1456-
1457- /* Shuffle button */
1458- Item {
1459- id: nowPlayingShuffleButton
1460- objectName: "shuffleShape"
1461- anchors.left: nowPlayingNextButton.right
1462- anchors.leftMargin: units.gu(1)
1463- anchors.verticalCenter: parent.verticalCenter
1464- height: units.gu(6)
1465- opacity: player.shuffle && !emptyPage.noMusic ? 1 : .4
1466- width: height
1467-
1468- function trigger() {
1469- if (emptyPage.noMusic) {
1470- return;
1471- }
1472-
1473- // Invert shuffle settings
1474- player.shuffle = !player.shuffle
1475- }
1476-
1477- Image {
1478- id: shuffleIcon
1479- height: units.gu(3)
1480- width: height
1481- anchors.verticalCenter: parent.verticalCenter
1482- anchors.horizontalCenter: parent.horizontalCenter
1483- source: Qt.resolvedUrl("images/media-playlist-shuffle.svg")
1484- opacity: player.shuffle && !emptyPage.noMusic ? 1 : .4
1485- }
1486- }
1487-
1488- /* Search button in wideAspect */
1489- Item {
1490- id: nowPlayingSearchButton
1491- objectName: "searchShape"
1492- anchors {
1493- right: parent.right
1494- rightMargin: units.gu(1)
1495- verticalCenter: parent.verticalCenter
1496- }
1497- height: units.gu(6)
1498- opacity: !emptyPage.noMusic ? 1 : .4
1499- width: height
1500- visible: wideAspect
1501-
1502- function trigger() {
1503- if (emptyPage.noMusic) {
1504- return;
1505- }
1506-
1507- if (!searchSheet.sheetVisible) {
1508- PopupUtils.open(searchSheet.sheet,
1509- mainView, { title: i18n.tr("Search")} )
1510- }
1511- }
1512-
1513- Image {
1514- id: searchIcon
1515- anchors {
1516- horizontalCenter: parent.horizontalCenter
1517- verticalCenter: parent.verticalCenter
1518- }
1519- height: units.gu(3)
1520- opacity: !emptyPage.noMusic ? 1 : .4
1521- source: Qt.resolvedUrl("images/search.svg")
1522- width: height
1523- }
1524- }
1525- }
1526-
1527- /* Progress bar component */
1528- Rectangle {
1529- id: musicToolbarFullProgressContainer
1530- anchors.left: parent.left
1531- anchors.top: parent.top
1532- color: styleMusic.toolbar.fullBackgroundColor
1533- height: units.gu(3)
1534- width: parent.width
1535-
1536- /* Position label */
1537- Label {
1538- id: musicToolbarFullPositionLabel
1539- anchors.left: parent.left
1540- anchors.leftMargin: units.gu(2)
1541- anchors.top: parent.top
1542- color: styleMusic.nowPlaying.labelColor
1543- fontSize: "x-small"
1544- height: parent.height
1545- horizontalAlignment: Text.AlignHCenter
1546- text: durationToString(player.position)
1547- verticalAlignment: Text.AlignVCenter
1548- width: units.gu(3)
1549- }
1550-
1551- /* Progress bar */
1552- Rectangle {
1553- id: musicToolbarFullProgressBarContainer
1554- objectName: "progressBarShape"
1555- anchors.left: musicToolbarFullPositionLabel.right
1556- anchors.leftMargin: units.gu(2)
1557- anchors.right: musicToolbarFullDurationLabel.left
1558- anchors.rightMargin: units.gu(2)
1559- anchors.verticalCenter: parent.verticalCenter
1560- color: "transparent"
1561- height: units.gu(1);
1562- state: trackQueue.model.count === 0 ? "disabled" : "enabled"
1563-
1564- states: [
1565- State {
1566- name: "disabled"
1567- PropertyChanges {
1568- target: musicToolbarFullProgressMouseArea
1569- enabled: false
1570- }
1571- PropertyChanges {
1572- target: musicToolbarFullProgressTrough
1573- visible: false
1574- }
1575- PropertyChanges {
1576- target: musicToolbarFullProgressHandle
1577- visible: false
1578- }
1579- },
1580- State {
1581- name: "enabled"
1582- PropertyChanges {
1583- target: musicToolbarFullProgressMouseArea
1584- enabled: true
1585- }
1586- PropertyChanges {
1587- target: musicToolbarFullProgressTrough
1588- visible: true
1589- }
1590- PropertyChanges {
1591- target: musicToolbarFullProgressHandle
1592- visible: true
1593- }
1594- }
1595- ]
1596-
1597- property bool seeking: false
1598-
1599- onSeekingChanged: {
1600- if (seeking === false) {
1601- musicToolbarFullPositionLabel.text = durationToString(player.position)
1602- }
1603- }
1604-
1605- Connections {
1606- target: player
1607- onDurationChanged: {
1608- console.debug("Duration changed: " + player.duration)
1609- musicToolbarFullDurationLabel.text = durationToString(player.duration)
1610- }
1611- onPositionChanged: {
1612- if (musicToolbarFullProgressBarContainer.seeking === false)
1613- {
1614- musicToolbarFullPositionLabel.text = durationToString(player.position)
1615- musicToolbarFullDurationLabel.text = durationToString(player.duration)
1616- musicToolbarFullProgressHandle.x = (player.position / player.duration) * musicToolbarFullProgressBarContainer.width
1617- - musicToolbarFullProgressHandle.width / 2;
1618- }
1619- }
1620- onStopped: {
1621- musicToolbarFullProgressHandle.x = -musicToolbarFullProgressHandle.width / 2;
1622-
1623- musicToolbarFullPositionLabel.text = durationToString(0);
1624- musicToolbarFullDurationLabel.text = durationToString(0);
1625- }
1626- }
1627-
1628- // Black background behind the progress bar
1629- Rectangle {
1630- id: musicToolbarFullProgressBackground
1631- anchors.verticalCenter: parent.verticalCenter;
1632- color: styleMusic.toolbar.fullProgressBackgroundColor;
1633- height: parent.height;
1634- radius: units.gu(0.5)
1635- width: parent.width;
1636- }
1637-
1638- // The orange fill of the progress bar
1639- Rectangle {
1640- id: musicToolbarFullProgressTrough
1641- anchors.verticalCenter: parent.verticalCenter;
1642- antialiasing: true
1643- color: styleMusic.toolbar.fullProgressTroughColor;
1644- height: parent.height;
1645- radius: units.gu(0.5)
1646- width: musicToolbarFullProgressHandle.x + (height / 2); // +radius
1647- }
1648-
1649- // The current position (handle) of the progress bar
1650- Rectangle {
1651- id: musicToolbarFullProgressHandle
1652- anchors.verticalCenter: musicToolbarFullProgressBackground.verticalCenter
1653- antialiasing: true
1654- color: styleMusic.nowPlaying.progressHandleColor
1655- height: units.gu(1.5)
1656- radius: height / 2
1657- width: height
1658-
1659- // On X change update the position string
1660- onXChanged: {
1661- if (musicToolbarFullProgressBarContainer.seeking) {
1662- var fraction = (x + (width / 2)) / parent.width;
1663- musicToolbarFullPositionLabel.text = durationToString(fraction * player.duration)
1664- }
1665- }
1666- }
1667- }
1668-
1669- /* Duration label */
1670- Label {
1671- id: musicToolbarFullDurationLabel
1672- anchors.right: parent.right
1673- anchors.rightMargin: units.gu(2)
1674- anchors.top: parent.top
1675- color: styleMusic.nowPlaying.labelColor
1676- fontSize: "x-small"
1677- height: parent.height
1678- horizontalAlignment: Text.AlignHCenter
1679- text: durationToString(player.duration)
1680- verticalAlignment: Text.AlignVCenter
1681- width: units.gu(3)
1682- }
1683-
1684- /* Border at the bottom */
1685- Rectangle {
1686- anchors.bottom: parent.bottom
1687- anchors.left: parent.left
1688- anchors.right: parent.right
1689- color: styleMusic.common.white
1690- height: units.gu(0.1)
1691- opacity: 0.1
1692- }
1693- }
1694- }
1695+ height: units.gu(7.25)
1696+ locked: true
1697+ opened: true
1698
1699 /* Expanded toolbar */
1700 Rectangle {
1701@@ -713,12 +93,13 @@
1702 fill: parent
1703 }
1704 color: "transparent"
1705- visible: musicToolbarPanel.currentMode === "expanded"
1706
1707 Rectangle {
1708 id: musicToolbarPlayerControls
1709- anchors.fill: parent
1710- color: styleMusic.playerControls.backgroundColor
1711+ anchors {
1712+ fill: parent
1713+ }
1714+ color: "#000"
1715 state: trackQueue.model.count === 0 ? "disabled" : "enabled"
1716 states: [
1717 State {
1718@@ -745,39 +126,55 @@
1719 }
1720 ]
1721
1722+ /* Disabled (empty state) controls */
1723 Rectangle {
1724 id: disabledPlayerControlsGroup
1725- anchors.fill: parent
1726+ anchors {
1727+ bottom: playerControlsProgressBar.top
1728+ left: parent.left
1729+ right: parent.right
1730+ top: parent.top
1731+ }
1732 color: "transparent"
1733- visible: trackQueue.model.count === 0
1734
1735 Label {
1736 id: noSongsInQueueLabel
1737 anchors {
1738 left: parent.left
1739+ leftMargin: units.gu(2)
1740 right: disabledPlayerControlsPlayButton.left
1741- margins: units.gu(1)
1742- top: parent.top
1743+ rightMargin: units.gu(2)
1744+ verticalCenter: parent.verticalCenter
1745 }
1746 color: styleMusic.playerControls.labelColor
1747- text: i18n.tr("Tap play to shuffle music")
1748+ text: i18n.tr("Tap to shuffle music")
1749 fontSize: "large"
1750 wrapMode: Text.WordWrap
1751 maximumLineCount: 2
1752 }
1753
1754- Rectangle {
1755+ /* Play/Pause button */
1756+ Icon {
1757 id: disabledPlayerControlsPlayButton
1758- anchors.right: parent.right
1759- anchors.rightMargin: units.gu(1)
1760- anchors.verticalCenter: parent.verticalCenter
1761- antialiasing: true
1762- color: "#444"
1763- height: units.gu(7)
1764- radius: height / 2
1765+ anchors {
1766+ right: parent.right
1767+ rightMargin: units.gu(3)
1768+ verticalCenter: parent.verticalCenter
1769+ }
1770+ color: "#FFF"
1771+ height: units.gu(2.5)
1772+ name: player.playbackState === MediaPlayer.PlayingState ?
1773+ "media-playback-pause" : "media-playback-start"
1774+ objectName: "disabledSmallPlayShape"
1775 width: height
1776+ }
1777
1778- function trigger() {
1779+ /* Click to shuffle music */
1780+ MouseArea {
1781+ anchors {
1782+ fill: parent
1783+ }
1784+ onClicked: {
1785 if (emptyPage.noMusic) {
1786 return;
1787 }
1788@@ -789,230 +186,65 @@
1789 player.toggle();
1790 }
1791 }
1792-
1793- // draws the outer shadow/highlight
1794- Rectangle {
1795- id: disabledSourceOutter
1796- anchors { fill: parent; margins: -units.gu(0.1) }
1797- radius: (width / 2)
1798- antialiasing: true
1799- gradient: Gradient {
1800- GradientStop { position: 0.0; color: "black" }
1801- GradientStop { position: 0.5; color: "transparent" }
1802- GradientStop { position: 1.0; color: UbuntuColors.warmGrey }
1803- }
1804-
1805- Rectangle {
1806- anchors.verticalCenter: parent.verticalCenter
1807- anchors.horizontalCenter: parent.horizontalCenter
1808- antialiasing: true
1809- color: "#444"
1810- height: playerControlsPlayButton.height - units.gu(.1)
1811- radius: height / 2
1812- width: height
1813-
1814- Rectangle {
1815- id: disabledPlayerControlsPlayInnerCircle
1816- anchors.horizontalCenter: parent.horizontalCenter
1817- anchors.verticalCenter: parent.verticalCenter
1818- antialiasing: true
1819- height: units.gu(4.5)
1820- radius: height / 2
1821- width: height
1822- color: styleMusic.toolbar.fullInnerPlayCircleColor
1823-
1824- // draws the inner shadow/highlight
1825- Rectangle {
1826- id: disabledSourceInner
1827- anchors { fill: parent; margins: -units.gu(0.1) }
1828- radius: (width / 2)
1829- antialiasing: true
1830- gradient: Gradient {
1831- GradientStop { position: 0.0; color: UbuntuColors.warmGrey }
1832- GradientStop { position: 0.5; color: "transparent" }
1833- GradientStop { position: 1.0; color: "black" }
1834- }
1835-
1836- Rectangle {
1837- anchors.verticalCenter: parent.verticalCenter
1838- anchors.horizontalCenter: parent.horizontalCenter
1839- antialiasing: true
1840- height: playerControlsPlayInnerCircle.height - units.gu(.1)
1841- radius: height / 2
1842- width: height
1843- color: styleMusic.toolbar.fullInnerPlayCircleColor
1844-
1845- Image {
1846- id: disabledPlayIndicator
1847- height: units.gu(4)
1848- width: height
1849- anchors.horizontalCenter: parent.horizontalCenter
1850- anchors.verticalCenter: parent.verticalCenter
1851- opacity: emptyPage.noMusic ? .4 : 1
1852- source: player.playbackState === MediaPlayer.PlayingState ?
1853- Qt.resolvedUrl("images/media-playback-pause.svg") : Qt.resolvedUrl("images/media-playback-start.svg")
1854- }
1855- }
1856- }
1857- }
1858- }
1859- }
1860 }
1861 }
1862
1863+ /* Enabled (queue > 0) controls */
1864 Rectangle {
1865 id: enabledPlayerControlsGroup
1866- anchors.fill: parent
1867+ anchors {
1868+ bottom: playerControlsProgressBar.top
1869+ left: parent.left
1870+ right: parent.right
1871+ top: parent.top
1872+ }
1873 color: "transparent"
1874- visible: trackQueue.model.count !== 0
1875-
1876- /* Settings button */
1877- // TODO: Enable settings when it is practical
1878- /* Rectangle {
1879- id: playerControlsSettings
1880- anchors.right: parent.right
1881- anchors.verticalCenter: parent.verticalCenter
1882- width: units.gu(6)
1883- height: width
1884- color: "transparent"
1885-
1886- Image {
1887- anchors.horizontalCenter: parent.horizontalCenter
1888- anchors.verticalCenter: parent.verticalCenter
1889- height: units.gu(3)
1890- source: Qt.resolvedUrl("images/settings.png")
1891- width: height
1892- }
1893-
1894- MouseArea {
1895- anchors.fill: parent
1896- onClicked: {
1897- console.debug('Debug: Show settings')
1898- PopupUtils.open(Qt.resolvedUrl("MusicSettings.qml"), mainView,
1899- {
1900- title: i18n.tr("Settings")
1901- } )
1902- }
1903- }
1904- } */
1905-
1906- /* Play/Pause button TODO: image and colours needs updating */
1907- Rectangle {
1908- id: playerControlsPlayButton
1909- anchors.right: parent.right
1910- anchors.rightMargin: units.gu(1)
1911- anchors.verticalCenter: parent.verticalCenter
1912- antialiasing: true
1913- color: "#444"
1914- height: units.gu(7)
1915- objectName: "smallPlayShape"
1916- radius: height / 2
1917- width: height
1918-
1919- function trigger() {
1920- if (emptyPage.noMusic) {
1921- return;
1922- }
1923-
1924- if (trackQueue.model.count === 0) {
1925- playRandomSong();
1926- }
1927- else {
1928- player.toggle();
1929- }
1930- }
1931-
1932- // draws the outer shadow/highlight
1933- Rectangle {
1934- id: sourceOutter
1935- anchors { fill: parent; margins: -units.gu(0.1) }
1936- radius: (width / 2)
1937- antialiasing: true
1938- gradient: Gradient {
1939- GradientStop { position: 0.0; color: "black" }
1940- GradientStop { position: 0.5; color: "transparent" }
1941- GradientStop { position: 1.0; color: UbuntuColors.warmGrey }
1942- }
1943-
1944- Rectangle {
1945- anchors.verticalCenter: parent.verticalCenter
1946- anchors.horizontalCenter: parent.horizontalCenter
1947- antialiasing: true
1948- color: "#444"
1949- height: playerControlsPlayButton.height - units.gu(.1)
1950- radius: height / 2
1951- width: height
1952-
1953- Rectangle {
1954- id: playerControlsPlayInnerCircle
1955- anchors.horizontalCenter: parent.horizontalCenter
1956- anchors.verticalCenter: parent.verticalCenter
1957- antialiasing: true
1958- height: units.gu(4.5)
1959- radius: height / 2
1960- width: height
1961- color: styleMusic.toolbar.fullInnerPlayCircleColor
1962-
1963- // draws the inner shadow/highlight
1964- Rectangle {
1965- id: sourceInner
1966- anchors { fill: parent; margins: -units.gu(0.1) }
1967- radius: (width / 2)
1968- antialiasing: true
1969- gradient: Gradient {
1970- GradientStop { position: 0.0; color: UbuntuColors.warmGrey }
1971- GradientStop { position: 0.5; color: "transparent" }
1972- GradientStop { position: 1.0; color: "black" }
1973- }
1974-
1975- Rectangle {
1976- anchors.verticalCenter: parent.verticalCenter
1977- anchors.horizontalCenter: parent.horizontalCenter
1978- antialiasing: true
1979- height: playerControlsPlayInnerCircle.height - units.gu(.1)
1980- radius: height / 2
1981- width: height
1982- color: styleMusic.toolbar.fullInnerPlayCircleColor
1983-
1984- Image {
1985- id: playindicator
1986- height: units.gu(4)
1987- width: height
1988- anchors.horizontalCenter: parent.horizontalCenter
1989- anchors.verticalCenter: parent.verticalCenter
1990- opacity: emptyPage.noMusic ? .4 : 1
1991- source: player.playbackState === MediaPlayer.PlayingState ?
1992- Qt.resolvedUrl("images/media-playback-pause.svg") : Qt.resolvedUrl("images/media-playback-start.svg")
1993- }
1994- }
1995- }
1996- }
1997+
1998+ /* Album art in player controls */
1999+ Image {
2000+ id: playerControlsImage
2001+ anchors {
2002+ bottom: parent.bottom
2003+ left: parent.left
2004+ top: parent.top
2005+ }
2006+ smooth: true
2007+ source: player.currentMetaArt === "" ?
2008+ decodeURIComponent("image://albumart/artist=" +
2009+ player.currentMetaArtist +
2010+ "&album=" + player.currentMetaAlbum)
2011+ : player.currentMetaArt
2012+ width: parent.height
2013+
2014+ onStatusChanged: {
2015+ if (status === Image.Error) {
2016+ source = Qt.resolvedUrl("../images/music-app-cover@30.png")
2017 }
2018 }
2019 }
2020
2021- /* Container holding the labels for the toolbar */
2022- Rectangle {
2023- id: playerControlLabelContainer
2024- anchors.bottom: parent.bottom
2025- anchors.left: parent.left
2026- anchors.right: playerControlsPlayButton.left
2027- anchors.top: parent.top
2028- color: "transparent"
2029+ /* Column of meta labels */
2030+ Column {
2031+ id: playerControlsLabels
2032+ anchors {
2033+ left: playerControlsImage.right
2034+ leftMargin: units.gu(1.5)
2035+ right: playerControlsPlayButton.left
2036+ rightMargin: units.gu(1)
2037+ verticalCenter: parent.verticalCenter
2038+ }
2039
2040 /* Title of track */
2041 Label {
2042 id: playerControlsTitle
2043- anchors.left: parent.left
2044- anchors.leftMargin: units.gu(1)
2045- anchors.right: parent.right
2046- anchors.rightMargin: units.gu(1)
2047- anchors.top: parent.top
2048- anchors.topMargin: units.gu(1)
2049- color: styleMusic.playerControls.labelColor
2050+ anchors {
2051+ left: parent.left
2052+ right: parent.right
2053+ }
2054+ color: "#FFF"
2055 elide: Text.ElideRight
2056- fontSize: "medium"
2057- objectName: "playercontroltitle"
2058+ fontSize: "small"
2059+ font.weight: Font.DemiBold
2060 text: player.currentMetaTitle === ""
2061 ? player.source : player.currentMetaTitle
2062 }
2063@@ -1020,119 +252,105 @@
2064 /* Artist of track */
2065 Label {
2066 id: playerControlsArtist
2067- anchors.left: parent.left
2068- anchors.leftMargin: units.gu(1)
2069- anchors.right: parent.right
2070- anchors.rightMargin: units.gu(1)
2071- anchors.top: playerControlsTitle.bottom
2072- color: styleMusic.playerControls.labelColor
2073+ anchors {
2074+ left: parent.left
2075+ right: parent.right
2076+ }
2077+ color: "#FFF"
2078 elide: Text.ElideRight
2079 fontSize: "small"
2080+ opacity: 0.4
2081 text: player.currentMetaArtist
2082 }
2083-
2084- /* Album of track */
2085- Label {
2086- id: playerControlsAlbum
2087- anchors.left: parent.left
2088- anchors.leftMargin: units.gu(1)
2089- anchors.right: parent.right
2090- anchors.rightMargin: units.gu(1)
2091- anchors.top: playerControlsArtist.bottom
2092- color: styleMusic.playerControls.labelColor
2093- elide: Text.ElideRight
2094- fontSize: "small"
2095- text: player.currentMetaAlbum
2096- }
2097- }
2098-
2099+ }
2100+
2101+ /* Play/Pause button */
2102+ Icon {
2103+ id: playerControlsPlayButton
2104+ anchors {
2105+ right: parent.right
2106+ rightMargin: units.gu(3)
2107+ verticalCenter: parent.verticalCenter
2108+ }
2109+ color: "#FFF"
2110+ height: units.gu(2.5)
2111+ name: player.playbackState === MediaPlayer.PlayingState ?
2112+ "media-playback-pause" : "media-playback-start"
2113+ objectName: "playShape"
2114+ width: height
2115+ }
2116+
2117+ MouseArea {
2118+ anchors {
2119+ bottom: parent.bottom
2120+ horizontalCenter: playerControlsPlayButton.horizontalCenter
2121+ top: parent.top
2122+ }
2123+ onClicked: player.toggle()
2124+ width: units.gu(8)
2125+
2126+ Rectangle {
2127+ anchors {
2128+ fill: parent
2129+ }
2130+ color: "#FFF"
2131+ opacity: parent.pressed ? 0.1 : 0
2132+
2133+ Behavior on opacity {
2134+ UbuntuNumberAnimation {
2135+ duration: UbuntuAnimation.FastDuration
2136+ }
2137+ }
2138+ }
2139+ }
2140+
2141+ /* Mouse area to jump to now playing */
2142 Rectangle {
2143- anchors.fill: playerControlLabelContainer
2144+ anchors {
2145+ bottom: parent.bottom
2146+ left: parent.left
2147+ right: playerControlsLabels.right
2148+ top: parent.top
2149+ }
2150 color: "transparent"
2151+ objectName: "jumpNowPlaying"
2152 function trigger() {
2153 tabs.pushNowPlaying();
2154 }
2155 }
2156 }
2157- }
2158- }
2159-
2160- /* Object which provides the progress bar when toolbar is minimized */
2161- Rectangle {
2162- id: musicToolbarSmallProgressBackground
2163- anchors {
2164- bottom: parent.top
2165- left: parent.left
2166- right: parent.right
2167- }
2168- color: styleMusic.common.black
2169- height: musicToolbarPanel.minimizedHeight
2170- visible: (!musicToolbarPanel.animating &&
2171- !musicToolbarPanel.opened)
2172- || musicToolbarPanel.currentMode == "expanded"
2173-
2174- Rectangle {
2175- id: musicToolbarSmallProgressHint
2176- anchors.left: parent.left
2177- anchors.top: parent.top
2178- color: styleMusic.nowPlaying.progressForegroundColor
2179- height: parent.height
2180- width: 0
2181-
2182- Connections {
2183- target: player
2184- onPositionChanged: {
2185- musicToolbarSmallProgressHint.width = (player.position / player.duration) * musicToolbarSmallProgressBackground.width
2186- }
2187- onStopped: {
2188- musicToolbarSmallProgressHint.width = 0;
2189- }
2190- }
2191- }
2192- }
2193-
2194- /* Mouse events for the progress bar
2195- is after musicToolbarMouseArea so that it captures mouse events for dragging */
2196- MouseArea {
2197- id: musicToolbarFullProgressMouseArea
2198- height: units.gu(2)
2199- width: musicToolbarFullProgressBarContainer.width
2200- x: musicToolbarFullProgressBarContainer.x
2201- y: musicToolbarFullProgressBarContainer.y
2202-
2203- drag.axis: Drag.XAxis
2204- drag.minimumX: -(musicToolbarFullProgressHandle.width / 2)
2205- drag.maximumX: musicToolbarFullProgressBarContainer.width - (musicToolbarFullProgressHandle.width / 2)
2206- drag.target: musicToolbarFullProgressHandle
2207-
2208- onPressed: {
2209- musicToolbarFullProgressBarContainer.seeking = true;
2210-
2211- // Jump the handle to the current mouse position
2212- musicToolbarFullProgressHandle.x = mouse.x - (musicToolbarFullProgressHandle.width / 2);
2213- }
2214-
2215- onReleased: {
2216- var fraction = mouse.x / musicToolbarFullProgressBarContainer.width;
2217-
2218- // Limit the bounds of the fraction
2219- fraction = fraction < 0 ? 0 : fraction
2220- fraction = fraction > 1 ? 1 : fraction
2221-
2222- player.seek((fraction) * player.duration);
2223- musicToolbarFullProgressBarContainer.seeking = false;
2224- }
2225- }
2226-
2227- // Timer for autohide
2228- Timer {
2229- id: toolbarAutoHideTimer
2230- interval: 5000
2231- repeat: false
2232- running: false
2233- onTriggered: {
2234- if (currentPage !== nowPlaying) { // don't autohide on now playing
2235- hideToolbar();
2236+
2237+ /* Object which provides the progress bar when toolbar is minimized */
2238+ Rectangle {
2239+ id: playerControlsProgressBar
2240+ anchors {
2241+ bottom: parent.bottom
2242+ left: parent.left
2243+ right: parent.right
2244+ }
2245+ color: styleMusic.common.black
2246+ height: units.gu(0.25)
2247+
2248+ Rectangle {
2249+ id: playerControlsProgressBarHint
2250+ anchors {
2251+ left: parent.left
2252+ top: parent.top
2253+ }
2254+ color: UbuntuColors.blue
2255+ height: parent.height
2256+ width: 0
2257+
2258+ Connections {
2259+ target: player
2260+ onPositionChanged: {
2261+ playerControlsProgressBarHint.width = (player.position / player.duration) * playerControlsProgressBar.width
2262+ }
2263+ onStopped: {
2264+ playerControlsProgressBarHint.width = 0;
2265+ }
2266+ }
2267+ }
2268 }
2269 }
2270 }
2271
2272=== modified file 'MusicTracks.qml'
2273--- MusicTracks.qml 2014-09-20 15:41:33 +0000
2274+++ MusicTracks.qml 2014-10-14 00:24:55 +0000
2275@@ -36,8 +36,10 @@
2276
2277 ListView {
2278 id: tracklist
2279- anchors.fill: parent
2280- anchors.bottomMargin: musicToolbar.mouseAreaOffset + musicToolbar.minimizedHeight
2281+ anchors {
2282+ fill: parent
2283+ topMargin: units.gu(2)
2284+ }
2285 highlightFollowsCurrentItem: false
2286 objectName: "trackstab-listview"
2287 model: SortFilterModel {
2288@@ -59,7 +61,8 @@
2289 color: "transparent"
2290 objectName: "tracksPageListItem" + index
2291 width: parent.width
2292- height: styleMusic.common.itemHeight
2293+ height: units.gu(7)
2294+ showDivider: false
2295
2296 rightSideActions: [
2297 AddToQueue {
2298@@ -77,29 +80,25 @@
2299
2300 MusicRow {
2301 id: musicRow
2302+ anchors.verticalCenter: parent.verticalCenter
2303 covers: [{art: model.art}]
2304+ isSquare: true
2305+ coverSize: units.gu(6)
2306+ spacing: units.gu(2)
2307 column: Column {
2308- spacing: units.gu(1)
2309- Label {
2310- id: trackArtist
2311- color: styleMusic.common.subtitle
2312- fontSize: "x-small"
2313- text: model.author
2314- }
2315-
2316 Label {
2317 id: trackTitle
2318 color: styleMusic.common.music
2319- fontSize: "medium"
2320+ fontSize: "small"
2321 objectName: "tracktitle"
2322 text: model.title
2323 }
2324
2325 Label {
2326- id: trackAlbum
2327+ id: trackArtist
2328 color: styleMusic.common.subtitle
2329- fontSize: "xx-small"
2330- text: model.album
2331+ fontSize: "x-small"
2332+ text: model.author
2333 }
2334 }
2335 }
2336
2337=== modified file 'MusicaddtoPlaylist.qml'
2338--- MusicaddtoPlaylist.qml 2014-09-20 10:50:45 +0000
2339+++ MusicaddtoPlaylist.qml 2014-10-14 00:24:55 +0000
2340@@ -65,7 +65,6 @@
2341 ListView {
2342 id: addtoPlaylistView
2343 anchors {
2344- bottomMargin: musicToolbar.mouseAreaOffset + musicToolbar.minimizedHeight
2345 fill: parent
2346 }
2347 clip: true
2348
2349=== modified file 'Player.qml'
2350--- Player.qml 2014-09-20 15:41:33 +0000
2351+++ Player.qml 2014-10-14 00:24:55 +0000
2352@@ -187,7 +187,11 @@
2353 else {
2354 var obj = trackQueue.model.get(player.currentIndex);
2355 currentMetaAlbum = obj.album;
2356- currentMetaArt = obj.art;
2357+
2358+ if (obj.art !== undefined) { // FIXME: protect against not art property in playlists
2359+ currentMetaArt = obj.art;
2360+ }
2361+
2362 currentMetaArtist = obj.author;
2363 currentMetaFile = obj.filename;
2364 currentMetaTitle = obj.title;
2365
2366=== modified file 'Style.qml'
2367--- Style.qml 2014-09-20 10:50:45 +0000
2368+++ Style.qml 2014-10-14 00:24:55 +0000
2369@@ -34,8 +34,8 @@
2370 property QtObject common: QtObject {
2371 property color black: "#000000";
2372 property color white: "#FFFFFF";
2373- property color music: "#333333";
2374- property color subtitle: "#666666";
2375+ property color music: "#FFFFFF";
2376+ property color subtitle: "#999999";
2377 property color expandedColor: "#000000";
2378 property int albumSize: units.gu(10);
2379 property int itemHeight: units.gu(12);
2380
2381=== modified file 'click/apparmor.json'
2382--- click/apparmor.json 2014-07-01 23:13:50 +0000
2383+++ click/apparmor.json 2014-10-14 00:24:55 +0000
2384@@ -1,7 +1,19 @@
2385 {
2386 "policy_version": 1.2,
2387- "template": "unconfined",
2388 "policy_groups": [
2389- "content_exchange"
2390+ "audio",
2391+ "content_exchange",
2392+ "music_files_read",
2393+ "networking",
2394+ "usermetrics"
2395+ ],
2396+ "read_path": [
2397+ "/etc/fstab",
2398+ "/proc/[0-9]*/mounts",
2399+ "@{HOME}/.cache/media-art/",
2400+ "@{HOME}/.cache/mediascanner-2.0/"
2401+ ],
2402+ "write_path": [
2403+ "@{HOME}/Music/Imported/"
2404 ]
2405 }
2406
2407=== modified file 'com.ubuntu.music_music.desktop.in.in'
2408--- com.ubuntu.music_music.desktop.in.in 2014-07-21 14:49:14 +0000
2409+++ com.ubuntu.music_music.desktop.in.in 2014-10-14 00:24:55 +0000
2410@@ -9,4 +9,7 @@
2411 StartupNotify=true
2412 X-Ubuntu-Touch=true
2413 X-Ubuntu-Single-Instance=true
2414+X-Ubuntu-Splash-Show-Header=true
2415+_X-Ubuntu-Splash-Title=Music
2416+X-Ubuntu-Splash-Color=#1e1e23
2417 X-Ubuntu-Default-Department-ID=sound-video
2418
2419=== modified file 'common/AlbumsPage.qml'
2420--- common/AlbumsPage.qml 2014-10-07 02:15:06 +0000
2421+++ common/AlbumsPage.qml 2014-10-14 00:24:55 +0000
2422@@ -28,7 +28,6 @@
2423
2424 MusicPage {
2425 id: albumStackPage
2426- anchors.bottomMargin: units.gu(.5)
2427 objectName: "albumsArtistPage"
2428 visible: false
2429
2430@@ -38,7 +37,6 @@
2431 ListView {
2432 id: albumtrackslist
2433 anchors {
2434- bottomMargin: wideAspect ? musicToolbar.fullHeight : musicToolbar.mouseAreaOffset + musicToolbar.minimizedHeight
2435 fill: parent
2436 }
2437 delegate: albumTracksDelegate
2438
2439=== modified file 'common/BlurredBackground.qml'
2440--- common/BlurredBackground.qml 2014-09-20 15:41:33 +0000
2441+++ common/BlurredBackground.qml 2014-10-14 00:24:55 +0000
2442@@ -23,8 +23,14 @@
2443
2444 // Blurred background
2445 Rectangle {
2446- anchors.fill: parent
2447- property string art: player.currentMetaFile === "" ? Qt.resolvedUrl("../images/music-app-cover@30.png") : player.currentMetaArt
2448+ width: parent.width
2449+ property string art // : player.currentMetaFile === "" ? Qt.resolvedUrl("../images/music-app-cover@30.png") : player.currentMetaArt
2450+
2451+ // dark layer
2452+ Rectangle {
2453+ anchors.fill: parent
2454+ color: "black"
2455+ }
2456
2457 // the album art
2458 Image {
2459@@ -32,7 +38,8 @@
2460 anchors.horizontalCenter: parent.horizontalCenter
2461 anchors.verticalCenter: parent.verticalCenter
2462 source: art // this has to be fixed for the default cover art to work - cant find in this dir
2463- height: Math.max(parent.height, parent.width)
2464+ fillMode: Image.PreserveAspectCrop
2465+ height: parent.height
2466 width: Math.max(parent.height, parent.width)
2467 visible: false
2468 onStatusChanged: {
2469@@ -47,12 +54,7 @@
2470 anchors.fill: backgroundImage
2471 source: backgroundImage
2472 radius: units.dp(42)
2473- }
2474- // transparent white layer
2475- Rectangle {
2476- anchors.fill: parent
2477- color: "white"
2478- opacity: 0.7
2479+ opacity: 0.2
2480 }
2481 onArtChanged: {
2482 // TODO: This is a work around for LP:1261078 and LP:1306845. Ideally,
2483
2484=== added file 'common/Card.qml'
2485--- common/Card.qml 1970-01-01 00:00:00 +0000
2486+++ common/Card.qml 2014-10-14 00:24:55 +0000
2487@@ -0,0 +1,151 @@
2488+/*
2489+ * Copyright (C) 2014
2490+ * Andrew Hayzen <ahayzen@gmail.com>
2491+ *
2492+ * This program is free software; you can redistribute it and/or modify
2493+ * it under the terms of the GNU General Public License as published by
2494+ * the Free Software Foundation; version 3.
2495+ *
2496+ * This program is distributed in the hope that it will be useful,
2497+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2498+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2499+ * GNU General Public License for more details.
2500+ *
2501+ * You should have received a copy of the GNU General Public License
2502+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2503+ */
2504+
2505+import QtQuick 2.3
2506+import Ubuntu.Components 1.1
2507+
2508+
2509+Rectangle {
2510+ id: card
2511+ color: "transparent"
2512+ height: cardColumn.childrenRect.height + 2 * bg.anchors.margins
2513+
2514+ property alias coverSources: coverGrid.covers
2515+ property alias primaryText: primaryLabel.text
2516+ property alias secondaryText: secondaryLabel.text
2517+ property alias secondaryTextVisible: secondaryLabel.visible
2518+
2519+ signal clicked(var mouse)
2520+ signal pressAndHold(var mouse)
2521+
2522+ /* Animations */
2523+ Behavior on height {
2524+ UbuntuNumberAnimation {
2525+
2526+ }
2527+ }
2528+
2529+ Behavior on width {
2530+ UbuntuNumberAnimation {
2531+
2532+ }
2533+ }
2534+
2535+ Behavior on x {
2536+ UbuntuNumberAnimation {
2537+
2538+ }
2539+ }
2540+
2541+ Behavior on y {
2542+ UbuntuNumberAnimation {
2543+
2544+ }
2545+ }
2546+
2547+ /* Background for card */
2548+ Rectangle {
2549+ id: bg
2550+ anchors {
2551+ fill: parent
2552+ margins: units.gu(1)
2553+ }
2554+ color: "#2c2c34"
2555+ }
2556+
2557+ /* Column containing image and labels */
2558+ Column {
2559+ id: cardColumn
2560+ anchors {
2561+ fill: bg
2562+ }
2563+ spacing: units.gu(0.5)
2564+
2565+ CoverGrid {
2566+ id: coverGrid
2567+ size: parent.width
2568+ }
2569+
2570+ Rectangle {
2571+ color: "transparent"
2572+ height: units.gu(1)
2573+ width: units.gu(1)
2574+ }
2575+
2576+ Label {
2577+ id: primaryLabel
2578+ anchors {
2579+ left: parent.left
2580+ leftMargin: units.gu(1)
2581+ right: parent.right
2582+ rightMargin: units.gu(1)
2583+ }
2584+ color: "#FFF"
2585+ elide: Text.ElideRight
2586+ fontSize: "small"
2587+ opacity: 1.0
2588+ wrapMode: Text.WordWrap
2589+ }
2590+
2591+ Label {
2592+ id: secondaryLabel
2593+ anchors {
2594+ left: parent.left
2595+ leftMargin: units.gu(1)
2596+ right: parent.right
2597+ rightMargin: units.gu(1)
2598+ }
2599+ color: "#FFF"
2600+ elide: Text.ElideRight
2601+ fontSize: "small"
2602+ opacity: 0.4
2603+ wrapMode: Text.WordWrap
2604+ }
2605+
2606+ Rectangle {
2607+ color: "transparent"
2608+ height: units.gu(1.5)
2609+ width: units.gu(1)
2610+ }
2611+ }
2612+
2613+ /* Overlay for when card is pressed */
2614+ Rectangle {
2615+ id: overlay
2616+ anchors {
2617+ fill: bg
2618+ }
2619+ color: "#000"
2620+ opacity: 0
2621+
2622+ Behavior on opacity {
2623+ UbuntuNumberAnimation {
2624+
2625+ }
2626+ }
2627+ }
2628+
2629+ /* Capture mouse events */
2630+ MouseArea {
2631+ anchors {
2632+ fill: parent
2633+ }
2634+ onClicked: card.clicked(mouse)
2635+ onPressAndHold: card.pressAndHold(mouse)
2636+ onPressedChanged: overlay.opacity = pressed ? 0.3 : 0
2637+ }
2638+}
2639
2640=== added file 'common/CardView.qml'
2641--- common/CardView.qml 1970-01-01 00:00:00 +0000
2642+++ common/CardView.qml 2014-10-14 00:24:55 +0000
2643@@ -0,0 +1,42 @@
2644+/*
2645+ * Copyright (C) 2014
2646+ * Andrew Hayzen <ahayzen@gmail.com>
2647+ *
2648+ * This program is free software; you can redistribute it and/or modify
2649+ * it under the terms of the GNU General Public License as published by
2650+ * the Free Software Foundation; version 3.
2651+ *
2652+ * This program is distributed in the hope that it will be useful,
2653+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2654+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2655+ * GNU General Public License for more details.
2656+ *
2657+ * You should have received a copy of the GNU General Public License
2658+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2659+ */
2660+
2661+import QtQuick 2.3
2662+import Ubuntu.Components 1.1
2663+
2664+
2665+Flickable {
2666+ anchors {
2667+ fill: parent
2668+ margins: units.gu(1)
2669+ }
2670+
2671+ // dont use flow.contentHeight as it is inaccurate due to height of labels
2672+ // changing as they load
2673+ contentHeight: flow.childrenRect.height
2674+ contentWidth: width
2675+
2676+ property alias delegate: flow.delegate
2677+ property alias model: flow.model
2678+ property real itemWidth: units.gu(15)
2679+
2680+ ColumnFlow {
2681+ id: flow
2682+ columns: parseInt(width / itemWidth)
2683+ width: parent.width
2684+ }
2685+}
2686
2687=== added file 'common/ColumnFlow.qml'
2688--- common/ColumnFlow.qml 1970-01-01 00:00:00 +0000
2689+++ common/ColumnFlow.qml 2014-10-14 00:24:55 +0000
2690@@ -0,0 +1,159 @@
2691+/*
2692+ * Copyright (C) 2014
2693+ * Andrew Hayzen <ahayzen@gmail.com>
2694+ * Michael Spencer <sonrisesoftware@gmail.com>
2695+ *
2696+ * This program is free software; you can redistribute it and/or modify
2697+ * it under the terms of the GNU General Public License as published by
2698+ * the Free Software Foundation; version 3.
2699+ *
2700+ * This program is distributed in the hope that it will be useful,
2701+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2702+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2703+ * GNU General Public License for more details.
2704+ *
2705+ * You should have received a copy of the GNU General Public License
2706+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2707+ *
2708+ * Upstream location:
2709+ * https://github.com/iBeliever/ubuntu-ui-extras/blob/master/ColumnFlow.qml
2710+ */
2711+
2712+import QtQuick 2.3
2713+
2714+
2715+Item {
2716+ id: columnFlow
2717+ property int columns: 1
2718+ property bool repeaterCompleted: false
2719+ property alias model: repeater.model
2720+ property alias delegate: repeater.delegate
2721+ property int contentHeight: 0
2722+
2723+ onColumnsChanged: reEvalColumns()
2724+ onModelChanged: reEvalColumns()
2725+ onWidthChanged: updateWidths()
2726+
2727+ function updateWidths() {
2728+ if (repeaterCompleted) {
2729+ var count = 0
2730+
2731+ //add the first <column> elements
2732+ for (var i = 0; count < columns && i < columnFlow.children.length; i++) {
2733+ //print(i, count)
2734+ if (!columnFlow.children[i] || String(columnFlow.children[i]).indexOf("QQuickRepeater") == 0)
2735+ //|| !columnFlow.children[i].visible) // CUSTOM - view is invisible at start
2736+ continue
2737+
2738+ columnFlow.children[i].width = width / columns
2739+
2740+ count++
2741+ }
2742+ }
2743+ }
2744+
2745+ function reEvalColumns() {
2746+ if (columnFlow.repeaterCompleted === false)
2747+ return
2748+
2749+ if (columns === 0) {
2750+ contentHeight = 0
2751+ return
2752+ }
2753+
2754+ var i, j
2755+ var columnHeights = new Array(columns);
2756+ var lastItem = new Array(columns)
2757+ var lastI = -1
2758+ var count = 0
2759+
2760+ //add the first <column> elements
2761+ for (i = 0; count < columns && i < columnFlow.children.length; i++) {
2762+ // CUSTOM - ignore if has just been removed
2763+ if (i === repeater.removeHintIndex && columnFlow.children[i] === repeater.removeHintItem) {
2764+ continue
2765+ }
2766+
2767+ if (!columnFlow.children[i] || String(columnFlow.children[i]).indexOf("QQuickRepeater") == 0)
2768+ //|| !columnFlow.children[i].visible) // CUSTOM - view is invisible at start
2769+ continue
2770+
2771+ lastItem[count] = i
2772+
2773+ columnHeights[count] = columnFlow.children[i].height
2774+ columnFlow.children[i].anchors.top = columnFlow.top
2775+ columnFlow.children[i].anchors.left = (lastI === -1 ? columnFlow.left : columnFlow.children[lastI].right)
2776+ columnFlow.children[i].anchors.right = undefined
2777+ columnFlow.children[i].width = columnFlow.width / columns
2778+
2779+ lastI = i
2780+ count++
2781+ }
2782+
2783+ //add the other elements
2784+ for (i = i; i < columnFlow.children.length; i++) {
2785+ var highestHeight = Number.MAX_VALUE
2786+ var newColumn = 0
2787+
2788+ // CUSTOM - ignore if has just been removed
2789+ if (i === repeater.removeHintIndex && columnFlow.children[i] === repeater.removeHintItem) {
2790+ continue
2791+ }
2792+
2793+ if (!columnFlow.children[i] || String(columnFlow.children[i]).indexOf("QQuickRepeater") == 0)
2794+ //|| !columnFlow.children[i].visible) // CUSTOM - view is invisible at start
2795+ continue
2796+
2797+ // find the shortest column
2798+ for (j = 0; j < columns; j++) {
2799+ if (columnHeights[j] !== null && columnHeights[j] < highestHeight) {
2800+ newColumn = j
2801+ highestHeight = columnHeights[j]
2802+ }
2803+ }
2804+
2805+ // add the element to the shortest column
2806+ columnFlow.children[i].anchors.top = columnFlow.children[lastItem[newColumn]].bottom
2807+ columnFlow.children[i].anchors.left = columnFlow.children[lastItem[newColumn]].left
2808+ columnFlow.children[i].anchors.right = columnFlow.children[lastItem[newColumn]].right
2809+
2810+ lastItem[newColumn] = i
2811+ columnHeights[newColumn] += columnFlow.children[i].height
2812+ }
2813+
2814+ var cHeight = 0
2815+
2816+ for (i = 0; i < columnHeights.length; i++) {
2817+ if (columnHeights[i])
2818+ cHeight = Math.max(cHeight, columnHeights[i])
2819+ }
2820+
2821+ contentHeight = cHeight
2822+ updateWidths()
2823+ }
2824+
2825+ Repeater {
2826+ id: repeater
2827+ model: columnFlow.model
2828+ Component.onCompleted: {
2829+ columnFlow.repeaterCompleted = true
2830+ columnFlow.reEvalColumns()
2831+ }
2832+
2833+ // Provide a hint of the removed item
2834+ property int removeHintIndex: -1 // CUSTOM
2835+ property var removeHintItem // CUSTOM
2836+
2837+ onItemAdded: columnFlow.reEvalColumns() // CUSTOM - ms2 models are live
2838+ onItemRemoved: {
2839+ removeHintIndex = index
2840+ removeHintItem = item
2841+
2842+ columnFlow.reEvalColumns() // CUSTOM - ms2 models are live
2843+
2844+ // Set back to null to allow freeing of memory
2845+ removeHintIndex = -1
2846+ removeHintItem = undefined
2847+ }
2848+ }
2849+}
2850
2851=== added file 'common/CoverGrid.qml'
2852--- common/CoverGrid.qml 1970-01-01 00:00:00 +0000
2853+++ common/CoverGrid.qml 2014-10-14 00:24:55 +0000
2854@@ -0,0 +1,71 @@
2855+/*
2856+ * Copyright (C) 2013, 2014
2857+ * Andrew Hayzen <ahayzen@gmail.com>
2858+ * Nekhelesh Ramananthan <krnekhelesh@gmail.com>
2859+ * Victor Thompson <victor.thompson@gmail.com>
2860+ *
2861+ * This program is free software; you can redistribute it and/or modify
2862+ * it under the terms of the GNU General Public License as published by
2863+ * the Free Software Foundation; version 3.
2864+ *
2865+ * This program is distributed in the hope that it will be useful,
2866+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2867+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2868+ * GNU General Public License for more details.
2869+ *
2870+ * You should have received a copy of the GNU General Public License
2871+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2872+ */
2873+
2874+import QtQuick 2.3
2875+import Ubuntu.Components 1.1
2876+
2877+Rectangle {
2878+ id: coverGrid
2879+ color: "transparent"
2880+ height: size
2881+ width: size
2882+
2883+ // Property (array) to store the cover images
2884+ property var covers
2885+
2886+ // Property to set the size of the cover image
2887+ property int size
2888+
2889+ onCoversChanged: {
2890+ if (covers !== undefined) {
2891+ while (covers.length > 4) { // remove any covers after 4
2892+ covers.pop()
2893+ }
2894+ }
2895+ }
2896+
2897+ // Flow of the cover arts in either 1, 1x1, 2x1, 2x2
2898+ Flow {
2899+ id: imageRow
2900+ anchors {
2901+ fill: parent
2902+ }
2903+
2904+ Repeater {
2905+ id: repeat
2906+ model: coverGrid.covers.length === 0 ? 1 : coverGrid.covers.length
2907+ delegate: Image {
2908+ fillMode: Image.PreserveAspectCrop
2909+ height: coverGrid.size / (coverGrid.covers.length > 1 ? 2 : 1)
2910+ width: coverGrid.size / (coverGrid.covers.length > 2 && !(coverGrid.covers.length === 3 && index === 2) ? 2 : 1)
2911+ source: coverGrid.covers.length !== 0 && coverGrid.covers[index] !== "" && coverGrid.covers[index] !== undefined
2912+ ? (coverGrid.covers[index].art !== undefined
2913+ ? coverGrid.covers[index].art
2914+ : "image://albumart/artist=" + coverGrid.covers[index].author + "&album=" + coverGrid.covers[index].album)
2915+ : Qt.resolvedUrl("../images/music-app-cover@30.png")
2916+ onStatusChanged: {
2917+ if (status === Image.Error) {
2918+ source = Qt.resolvedUrl("../images/music-app-cover@30.png")
2919+ }
2920+ }
2921+ }
2922+ }
2923+ }
2924+}
2925+
2926
2927=== modified file 'common/MusicPage.qml'
2928--- common/MusicPage.qml 2014-08-20 17:35:52 +0000
2929+++ common/MusicPage.qml 2014-10-14 00:24:55 +0000
2930@@ -23,6 +23,10 @@
2931 // generic page for music, could be useful for bottomedge implementation
2932 Page {
2933 id: thisPage
2934+ anchors {
2935+ bottomMargin: musicToolbar.visible ? musicToolbar.currentHeight : 0
2936+ fill: parent
2937+ }
2938
2939 onVisibleChanged: {
2940 if (visible) {
2941
2942=== modified file 'common/MusicRow.qml'
2943--- common/MusicRow.qml 2014-09-20 10:50:45 +0000
2944+++ common/MusicRow.qml 2014-10-14 00:24:55 +0000
2945@@ -24,35 +24,64 @@
2946 Row {
2947 anchors {
2948 left: parent.left
2949- leftMargin: units.gu(1)
2950+ leftMargin: units.gu(2)
2951 right: parent.right
2952- rightMargin: units.gu(1)
2953+ rightMargin: units.gu(2)
2954 }
2955
2956 property alias covers: coverRow.covers
2957+ property bool showCovers: true
2958+ property bool isSquare: false
2959 property alias pressed: coverRow.pressed
2960 property alias column: columnComponent.sourceComponent
2961+ property real coverSize: styleMusic.common.albumSize
2962
2963 spacing: units.gu(1)
2964
2965 CoverRow {
2966 id: coverRow
2967+ visible: showCovers && !isSquare
2968 anchors {
2969 top: parent.top
2970 topMargin: units.gu(1)
2971 }
2972 count: covers.length
2973 covers: []
2974- size: styleMusic.common.albumSize
2975+ size: coverSize
2976+ }
2977+
2978+ Image {
2979+ id: coverSquare
2980+ visible: showCovers && isSquare
2981+ width: coverSize
2982+ height: coverSize
2983+ anchors {
2984+ verticalCenter: parent.verticalCenter
2985+ topMargin: units.gu(0.5)
2986+ bottomMargin: units.gu(0.5)
2987+ leftMargin: units.gu(2)
2988+ }
2989+ source: coverRow.count !== 0 && coverRow.covers[0] !== "" && coverRow.covers[0] !== undefined
2990+ ? (coverRow.covers[0].art !== undefined
2991+ ? coverRow.covers[0].art
2992+ : "image://albumart/artist=" + coverRow.covers[0].author + "&album=" + coverRow.covers[0].album)
2993+ : Qt.resolvedUrl("../images/music-app-cover@30.png")
2994+ onStatusChanged: {
2995+ if (status === Image.Error) {
2996+ source = Qt.resolvedUrl("../images/music-app-cover@30.png")
2997+ }
2998+ }
2999 }
3000
3001 Loader {
3002 id: columnComponent
3003 anchors {
3004 top: parent.top
3005- topMargin: units.gu(2)
3006+ topMargin: units.gu(1)
3007 }
3008- width: parent.width - coverRow.width - parent.spacing
3009+ width: !showCovers ? parent.width - parent.spacing
3010+ : (isSquare ? parent.width - coverSquare.width - parent.spacing
3011+ : parent.width - coverRow.width - parent.spacing)
3012
3013 onSourceComponentChanged: {
3014 for (var i=0; i < item.children.length; i++) {
3015
3016=== modified file 'common/SongsPage.qml'
3017--- common/SongsPage.qml 2014-09-20 15:41:33 +0000
3018+++ common/SongsPage.qml 2014-10-14 00:24:55 +0000
3019@@ -29,7 +29,6 @@
3020
3021 MusicPage {
3022 id: songStackPage
3023- anchors.bottomMargin: units.gu(.5)
3024 objectName: "songsPage"
3025 visible: false
3026
3027@@ -52,7 +51,6 @@
3028 ListView {
3029 id: albumtrackslist
3030 anchors {
3031- bottomMargin: wideAspect ? musicToolbar.fullHeight : musicToolbar.mouseAreaOffset + musicToolbar.minimizedHeight
3032 fill: parent
3033 }
3034 delegate: albumTracksDelegate
3035@@ -61,19 +59,47 @@
3036 width: parent.width
3037 header: ListItem.Standard {
3038 id: albumInfo
3039- height: units.gu(22)
3040-
3041- CoverRow {
3042- id: albumImage
3043+ height: albumArtist.visible ? units.gu(33) : units.gu(30)
3044+
3045+ BlurredBackground {
3046+ id: blurredBackground
3047+ height: parent.height
3048+ art: coversImage.covers.length > 0
3049+ ? (coversImage.covers[0].art !== undefined
3050+ ? coversImage.covers[0].art
3051+ : decodeURIComponent("image://albumart/artist=" + coversImage.covers[0].author + "&album=" + coversImage.covers[0].album))
3052+ : Qt.resolvedUrl("../images/music-app-cover@30.png")
3053+ }
3054+
3055+ CoverGrid {
3056+ id: coversImage
3057 anchors {
3058 top: parent.top
3059 left: parent.left
3060- margins: units.gu(1)
3061+ topMargin: units.gu(3)
3062+ bottomMargin: units.gu(2)
3063+ leftMargin: units.gu(2)
3064+ rightMargin: units.gu(2)
3065 }
3066- count: songStackPage.covers.length
3067- size: units.gu(20)
3068 covers: songStackPage.covers
3069- spacing: units.gu(2)
3070+ size: units.gu(18)
3071+ }
3072+
3073+ Label {
3074+ id: albumLabel
3075+ wrapMode: Text.NoWrap
3076+ maximumLineCount: 1
3077+ fontSize: "x-large"
3078+ color: styleMusic.common.music
3079+ anchors {
3080+ top: coversImage.bottom
3081+ topMargin: units.gu(1)
3082+ left: coversImage.left
3083+ right: parent.right
3084+ rightMargin: units.gu(2)
3085+ }
3086+ elide: Text.ElideRight
3087+ text: line2
3088 }
3089
3090 Label {
3091@@ -83,77 +109,115 @@
3092 maximumLineCount: 1
3093 fontSize: "small"
3094 color: styleMusic.common.subtitle
3095- anchors.left: albumImage.right
3096- anchors.leftMargin: units.gu(1)
3097- anchors.top: parent.top
3098- anchors.topMargin: units.gu(1.5)
3099- anchors.right: parent.right
3100- anchors.rightMargin: units.gu(1.5)
3101+ visible: text !== i18n.tr("Playlist") &&
3102+ text !== i18n.tr("Genre")
3103+ anchors {
3104+ top: albumLabel.bottom
3105+ topMargin: units.gu(0.75)
3106+ left: coversImage.left
3107+ right: parent.right
3108+ rightMargin: units.gu(2)
3109+ }
3110 elide: Text.ElideRight
3111 text: line1
3112 }
3113- Label {
3114- id: albumLabel
3115- wrapMode: Text.NoWrap
3116- maximumLineCount: 2
3117- fontSize: "medium"
3118- color: styleMusic.common.music
3119- anchors.left: albumImage.right
3120- anchors.leftMargin: units.gu(1)
3121- anchors.top: albumArtist.bottom
3122- anchors.topMargin: units.gu(0.8)
3123- anchors.right: parent.right
3124- anchors.rightMargin: units.gu(1.5)
3125- elide: Text.ElideRight
3126- text: line2
3127- }
3128+
3129 Label {
3130 id: albumYear
3131 wrapMode: Text.NoWrap
3132 maximumLineCount: 1
3133- fontSize: "x-small"
3134+ fontSize: "small"
3135 color: styleMusic.common.subtitle
3136- anchors.left: albumImage.right
3137- anchors.leftMargin: units.gu(1)
3138- anchors.top: albumLabel.bottom
3139- anchors.topMargin: units.gu(2)
3140- anchors.right: parent.right
3141- anchors.rightMargin: units.gu(1.5)
3142+ anchors {
3143+ top: albumArtist.visible ? albumArtist.bottom
3144+ : albumLabel.bottom
3145+ topMargin: units.gu(1)
3146+ left: coversImage.left
3147+ right: parent.right
3148+ rightMargin: units.gu(2)
3149+ }
3150 elide: Text.ElideRight
3151 text: isAlbum && line1 !== i18n.tr("Genre") ? year + " | " + i18n.tr("%1 song", "%1 songs", albumtrackslist.count).arg(albumtrackslist.count)
3152 : i18n.tr("%1 song", "%1 songs", albumtrackslist.count).arg(albumtrackslist.count)
3153
3154 }
3155
3156+ // Shuffle
3157+ Button {
3158+ id: shuffleRow
3159+ anchors {
3160+ bottom: queueAllRow.top
3161+ bottomMargin: units.gu(2)
3162+ left: coversImage.right
3163+ leftMargin: units.gu(2)
3164+ }
3165+ strokeColor: UbuntuColors.green
3166+ height: units.gu(4)
3167+ width: units.gu(15)
3168+ Text {
3169+ anchors {
3170+ centerIn: parent
3171+ }
3172+ color: "white"
3173+ text: i18n.tr("Shuffle")
3174+ }
3175+ MouseArea {
3176+ anchors.fill: parent
3177+ onClicked: {
3178+ shuffleModel(albumtrackslist.model) // play track
3179+
3180+ if (isAlbum && songStackPage.line1 !== i18n.tr("Genre")) {
3181+ Library.addRecent(songStackPage.line2, songStackPage.line1, songStackPage.covers[0], songStackPage.line2, "album")
3182+ mainView.hasRecent = true
3183+ recentModel.filterRecent()
3184+ } else if (songStackPage.line1 === i18n.tr("Playlist")) {
3185+ Library.addRecent(songStackPage.line2, "Playlist", songStackPage.covers[0], songStackPage.line2, "playlist")
3186+ mainView.hasRecent = true
3187+ recentModel.filterRecent()
3188+ }
3189+ }
3190+ }
3191+ }
3192+
3193+ // Queue
3194+ Button {
3195+ id: queueAllRow
3196+ anchors {
3197+ bottom: playRow.top
3198+ bottomMargin: units.gu(2)
3199+ left: coversImage.right
3200+ leftMargin: units.gu(2)
3201+ }
3202+ strokeColor: UbuntuColors.green
3203+ height: units.gu(4)
3204+ width: units.gu(15)
3205+ Text {
3206+ anchors {
3207+ centerIn: parent
3208+ }
3209+ color: "white"
3210+ text: i18n.tr("Queue all")
3211+ }
3212+ MouseArea {
3213+ anchors.fill: parent
3214+ onClicked: {
3215+ addQueueFromModel(albumtrackslist.model)
3216+ }
3217+ }
3218+ }
3219+
3220 // Play
3221- Rectangle {
3222+ Button {
3223 id: playRow
3224- anchors.top: albumYear.bottom
3225- anchors.topMargin: units.gu(1)
3226- anchors.left: albumImage.right
3227- anchors.leftMargin: units.gu(1)
3228- color: "transparent"
3229+ anchors {
3230+ bottom: coversImage.bottom
3231+ left: coversImage.right
3232+ leftMargin: units.gu(2)
3233+ }
3234+ color: UbuntuColors.green
3235 height: units.gu(4)
3236 width: units.gu(15)
3237- Icon {
3238- id: playTrack
3239- objectName: "songspage-playtrack"
3240- anchors.verticalCenter: parent.verticalCenter
3241- name: "media-playback-start"
3242- height: styleMusic.common.expandedItem
3243- width: styleMusic.common.expandedItem
3244- }
3245- Label {
3246- anchors.left: playTrack.right
3247- anchors.leftMargin: units.gu(0.5)
3248- anchors.verticalCenter: parent.verticalCenter
3249- fontSize: "small"
3250- color: styleMusic.common.subtitle
3251- width: parent.width - playTrack.width - units.gu(1)
3252- text: i18n.tr("Play all")
3253- wrapMode: Text.WordWrap
3254- maximumLineCount: 3
3255- }
3256+ text: i18n.tr("Play all")
3257 MouseArea {
3258 anchors.fill: parent
3259 onClicked: {
3260@@ -171,43 +235,6 @@
3261 }
3262 }
3263 }
3264-
3265- // Queue
3266- Rectangle {
3267- id: queueAllRow
3268- anchors.top: playRow.bottom
3269- anchors.topMargin: units.gu(1)
3270- anchors.left: albumImage.right
3271- anchors.leftMargin: units.gu(1)
3272- color: "transparent"
3273- height: units.gu(4)
3274- width: units.gu(15)
3275- Icon {
3276- id: queueAll
3277- objectName: "songspage-queue-all"
3278- anchors.verticalCenter: parent.verticalCenter
3279- name: "add"
3280- height: styleMusic.common.expandedItem
3281- width: styleMusic.common.expandedItem
3282- }
3283- Label {
3284- anchors.left: queueAll.right
3285- anchors.leftMargin: units.gu(0.5)
3286- anchors.verticalCenter: parent.verticalCenter
3287- fontSize: "small"
3288- color: styleMusic.common.subtitle
3289- width: parent.width - queueAll.width - units.gu(1)
3290- text: i18n.tr("Add to queue")
3291- wrapMode: Text.WordWrap
3292- maximumLineCount: 3
3293- }
3294- MouseArea {
3295- anchors.fill: parent
3296- onClicked: {
3297- addQueueFromModel(albumtrackslist.model)
3298- }
3299- }
3300- }
3301 }
3302
3303 Component {
3304@@ -219,7 +246,8 @@
3305 objectName: "songsPageListItem" + index
3306 iconFrame: false
3307 progression: false
3308- height: styleMusic.common.itemHeight
3309+ showDivider: false
3310+ height: units.gu(6)
3311
3312 leftSideAction: songStackPage.line1 === i18n.tr("Playlist")
3313 ? playlistRemoveAction.item : null
3314@@ -272,30 +300,23 @@
3315
3316 MusicRow {
3317 id: musicRow
3318- covers: model.art !== undefined ? [{art: model.art}] : [{author: model.author, album: model.album}]
3319+ covers: []
3320+ showCovers: false
3321 column: Column {
3322- spacing: units.gu(1)
3323+ Label {
3324+ id: trackTitle
3325+ color: styleMusic.common.music
3326+ fontSize: "small"
3327+ objectName: "songspage-tracktitle"
3328+ text: model.title
3329+ }
3330+
3331 Label {
3332 id: trackArtist
3333 color: styleMusic.common.subtitle
3334 fontSize: "x-small"
3335 text: model.author
3336 }
3337-
3338- Label {
3339- id: trackTitle
3340- color: styleMusic.common.subtitle
3341- fontSize: "medium"
3342- objectName: "songspage-tracktitle"
3343- text: model.title
3344- }
3345-
3346- Label {
3347- id: trackAlbum
3348- color: styleMusic.common.subtitle
3349- fontSize: "xx-small"
3350- text: model.album
3351- }
3352 }
3353 }
3354
3355
3356=== modified file 'music-app.qml'
3357--- music-app.qml 2014-09-23 15:59:28 +0000
3358+++ music-app.qml 2014-10-14 00:24:55 +0000
3359@@ -40,18 +40,13 @@
3360 id: mainView
3361 useDeprecatedToolbar: false
3362
3363- // Use toolbar color for header
3364- headerColor: styleMusic.toolbar.fullBackgroundColor
3365- backgroundColor: styleMusic.toolbar.fullBackgroundColor
3366+ backgroundColor: "#1e1e23"
3367+ headerColor: "#1e1e23"
3368
3369 // Global keyboard shortcuts
3370 focus: true
3371 Keys.onPressed: {
3372- if (event.key === Qt.Key_Alt) {
3373- // On alt key press show toolbar and start autohide timer
3374- musicToolbar.showToolbar();
3375- }
3376- else if(event.key === Qt.Key_Escape) {
3377+ if(event.key === Qt.Key_Escape) {
3378 musicToolbar.goBack(); // Esc Go back
3379 }
3380 else if(event.modifiers === Qt.AltModifier) {
3381@@ -94,13 +89,11 @@
3382 }
3383 break;
3384 case Qt.Key_J: // Ctrl+J Jump to playing song
3385- nowPlaying.visible = true;
3386- nowPlaying.positionAt(player.currentIndex);
3387- musicToolbar.showToolbar();
3388+ tabs.pushNowPlaying()
3389+ nowPlaying.isListView = true;
3390 break;
3391 case Qt.Key_N: // Ctrl+N Show now playing
3392- nowPlaying.visible = true;
3393- musicToolbar.showToolbar();
3394+ tabs.pushNowPlaying()
3395 break;
3396 case Qt.Key_P: // Ctrl+P Toggle playing state
3397 player.toggle();
3398@@ -577,12 +570,6 @@
3399 if (args.values.url) {
3400 uriHandler.process(args.values.url, true);
3401 }
3402-
3403- // Show toolbar and start timer if there is music
3404- if (!emptyPage.noMusic) {
3405- musicToolbar.showToolbar();
3406- musicToolbar.startAutohideTimer();
3407- }
3408 }
3409
3410 // VARIABLES
3411@@ -594,11 +581,10 @@
3412 property string lastfmpassword
3413 property string timestamp // used to scrobble
3414 property var chosenElement: null
3415- property bool toolbarShown: musicToolbar.shown
3416+ property bool toolbarShown: musicToolbar.visible
3417 property bool selectedAlbum: false
3418
3419 signal listItemSwiping(int i)
3420- signal onToolbarShownChanged(bool shown, var currentPage, var currentTab)
3421
3422 property bool wideAspect: width >= units.gu(70) && loadedUI
3423 property bool loadedUI: false // property to detect if the UI has finished
3424@@ -679,9 +665,6 @@
3425
3426 // Show the Now Playing page and make sure the track is visible
3427 tabs.pushNowPlaying();
3428- nowPlaying.ensureVisibleIndex = index;
3429-
3430- musicToolbar.showToolbar();
3431 }
3432 else {
3433 player.source = file;
3434@@ -697,10 +680,9 @@
3435 }
3436
3437 // Show the Now Playing page and make sure the track is visible
3438- tabs.pushNowPlaying();
3439- nowPlaying.ensureVisibleIndex = index;
3440-
3441- musicToolbar.showToolbar();
3442+ if (!nowPlaying.isListView) {
3443+ tabs.pushNowPlaying();
3444+ }
3445 }
3446
3447 function playRandomSong(shuffle)
3448@@ -716,6 +698,17 @@
3449 trackClicked(allSongsModel, index, true)
3450 }
3451
3452+ function shuffleModel(model)
3453+ {
3454+ var now = new Date();
3455+ var seed = now.getSeconds();
3456+ var index = Math.floor(model.count * Math.random(seed));
3457+
3458+ player.shuffle = true;
3459+
3460+ trackClicked(model, index, true)
3461+ }
3462+
3463 // Load mediascanner store
3464 MediaStore {
3465 id: musicStore
3466@@ -867,10 +860,6 @@
3467 id: searchSheet
3468 }
3469
3470- // Blurred background
3471- BlurredBackground {
3472- }
3473-
3474 // Popover for tracks, queue and add to playlist, for example
3475 Component {
3476 id: trackPopoverComponent
3477@@ -973,6 +962,7 @@
3478
3479 MusicToolbar {
3480 id: musicToolbar
3481+ visible: nowPlaying.isListView || !nowPlaying.visible
3482 objectName: "musicToolbarObject"
3483 z: 200 // put on top of everything else
3484 }
3485@@ -983,7 +973,6 @@
3486 Tabs {
3487 id: tabs
3488 anchors {
3489- bottomMargin: wideAspect ? musicToolbar.fullHeight : undefined
3490 fill: parent
3491 }
3492
3493@@ -1110,6 +1099,8 @@
3494 if (mainPageStack.currentPage !== nowPlaying) {
3495 mainPageStack.push(nowPlaying);
3496 }
3497+
3498+ nowPlaying.isListView = false; // ensure full view
3499 }
3500
3501 Component.onCompleted: musicToolbar.currentTab = selectedTab
3502
3503=== modified file 'po/com.ubuntu.music.pot'
3504--- po/com.ubuntu.music.pot 2014-09-23 12:44:36 +0000
3505+++ po/com.ubuntu.music.pot 2014-10-14 00:24:55 +0000
3506@@ -8,7 +8,7 @@
3507 msgstr ""
3508 "Project-Id-Version: music-app\n"
3509 "Report-Msgid-Bugs-To: \n"
3510-"POT-Creation-Date: 2014-09-23 13:43+0100\n"
3511+"POT-Creation-Date: 2014-10-08 20:48-0500\n"
3512 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
3513 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
3514 "Language-Team: LANGUAGE <LL@li.org>\n"
3515@@ -18,7 +18,7 @@
3516 "Content-Transfer-Encoding: 8bit\n"
3517 "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
3518
3519-#: ../LoginLastFM.qml:48 ../MusicSettings.qml:145 ../MusicSettings.qml:153
3520+#: ../LoginLastFM.qml:48 ../MusicSettings.qml:134 ../MusicSettings.qml:142
3521 msgid "Last.fm"
3522 msgstr ""
3523
3524@@ -54,12 +54,12 @@
3525 msgid "You forgot to set your username and/or password"
3526 msgstr ""
3527
3528-#: ../MusicAlbums.qml:35 ../MusicStart.qml:392
3529+#: ../MusicAlbums.qml:29 ../MusicStart.qml:392
3530 msgid "Albums"
3531 msgstr ""
3532
3533-#: ../MusicAlbums.qml:152 ../MusicStart.qml:200 ../MusicStart.qml:454
3534-#: ../common/AlbumsPage.qml:264
3535+#: ../MusicAlbums.qml:57 ../MusicStart.qml:200 ../MusicStart.qml:454
3536+#: ../common/AlbumsPage.qml:262
3537 msgid "Album"
3538 msgstr ""
3539
3540@@ -67,28 +67,32 @@
3541 msgid "Artists"
3542 msgstr ""
3543
3544-#: ../MusicArtists.qml:107 ../common/AlbumsPage.qml:112
3545+#: ../MusicArtists.qml:108 ../common/AlbumsPage.qml:110
3546 #, qt-format
3547 msgid "%1 album"
3548 msgid_plural "%1 albums"
3549 msgstr[0] ""
3550 msgstr[1] ""
3551
3552-#: ../MusicArtists.qml:113 ../MusicPlaylists.qml:180 ../MusicStart.qml:371
3553-#: ../MusicaddtoPlaylist.qml:106 ../common/AlbumsPage.qml:331
3554-#: ../common/SongsPage.qml:123 ../common/SongsPage.qml:124
3555+#: ../MusicArtists.qml:114 ../MusicPlaylists.qml:181 ../MusicStart.qml:371
3556+#: ../MusicaddtoPlaylist.qml:105 ../common/AlbumsPage.qml:329
3557+#: ../common/SongsPage.qml:142 ../common/SongsPage.qml:143
3558 #, qt-format
3559 msgid "%1 song"
3560 msgid_plural "%1 songs"
3561 msgstr[0] ""
3562 msgstr[1] ""
3563
3564-#: ../MusicArtists.qml:123
3565+#: ../MusicArtists.qml:124
3566 msgid "Artist"
3567 msgstr ""
3568
3569 #: ../MusicNowPlaying.qml:33
3570-msgid "Now Playing"
3571+msgid "Queue"
3572+msgstr ""
3573+
3574+#: ../MusicNowPlaying.qml:33
3575+msgid "Now playing"
3576 msgstr ""
3577
3578 #. TRANSLATORS: this is the name of the playlists page shown in the tab header.
3579@@ -114,117 +118,118 @@
3580 msgid "Change"
3581 msgstr ""
3582
3583-#: ../MusicPlaylists.qml:96 ../music-app.qml:956
3584+#: ../MusicPlaylists.qml:96 ../music-app.qml:945
3585 msgid "Playlist already exists"
3586 msgstr ""
3587
3588-#: ../MusicPlaylists.qml:100 ../music-app.qml:961
3589+#: ../MusicPlaylists.qml:100 ../music-app.qml:950
3590 msgid "Please type in a name."
3591 msgstr ""
3592
3593-#: ../MusicPlaylists.qml:105 ../music-app.qml:493 ../music-app.qml:967
3594+#: ../MusicPlaylists.qml:105 ../music-app.qml:486 ../music-app.qml:956
3595 msgid "Cancel"
3596 msgstr ""
3597
3598-#: ../MusicPlaylists.qml:159 ../MusicPlaylists.qml:163 ../MusicStart.qml:118
3599-#: ../MusicStart.qml:200 ../common/SongsPage.qml:166
3600-#: ../common/SongsPage.qml:224 ../common/SongsPage.qml:226
3601-#: ../common/SongsPage.qml:244
3602+#: ../MusicPlaylists.qml:160 ../MusicPlaylists.qml:164 ../MusicStart.qml:118
3603+#: ../MusicStart.qml:200 ../common/SongsPage.qml:114
3604+#: ../common/SongsPage.qml:175 ../common/SongsPage.qml:232
3605+#: ../common/SongsPage.qml:254 ../common/SongsPage.qml:256
3606+#: ../common/SongsPage.qml:274
3607 msgid "Playlist"
3608 msgstr ""
3609
3610-#: ../MusicSearch.qml:44 ../MusicSearch.qml:75 ../MusicToolbar.qml:519
3611-#: ../music-app.qml:93 ../music-app.qml:141 ../music-app.qml:147
3612+#: ../MusicSearch.qml:44 ../MusicSearch.qml:75 ../music-app.qml:88
3613+#: ../music-app.qml:134 ../music-app.qml:140
3614 msgid "Search"
3615 msgstr ""
3616
3617-#: ../MusicSettings.qml:30 ../music-app.qml:191
3618+#: ../MusicSettings.qml:30 ../music-app.qml:184
3619 msgid "Settings"
3620 msgstr ""
3621
3622-#: ../MusicSettings.qml:81
3623+#: ../MusicSettings.qml:70
3624 msgid "Equaliser"
3625 msgstr ""
3626
3627-#: ../MusicSettings.qml:82
3628+#: ../MusicSettings.qml:71
3629 msgid "Default"
3630 msgstr ""
3631
3632-#: ../MusicSettings.qml:83
3633+#: ../MusicSettings.qml:72
3634 msgid "Acoustic"
3635 msgstr ""
3636
3637-#: ../MusicSettings.qml:84
3638+#: ../MusicSettings.qml:73
3639 msgid "Classical"
3640 msgstr ""
3641
3642-#: ../MusicSettings.qml:85
3643+#: ../MusicSettings.qml:74
3644 msgid "Electronic"
3645 msgstr ""
3646
3647-#: ../MusicSettings.qml:86
3648+#: ../MusicSettings.qml:75
3649 msgid "Flat"
3650 msgstr ""
3651
3652-#: ../MusicSettings.qml:87
3653+#: ../MusicSettings.qml:76
3654 msgid "Hip Hop"
3655 msgstr ""
3656
3657-#: ../MusicSettings.qml:88
3658+#: ../MusicSettings.qml:77
3659 msgid "Jazz"
3660 msgstr ""
3661
3662-#: ../MusicSettings.qml:89
3663+#: ../MusicSettings.qml:78
3664 msgid "Metal"
3665 msgstr ""
3666
3667-#: ../MusicSettings.qml:90
3668+#: ../MusicSettings.qml:79
3669 msgid "Pop"
3670 msgstr ""
3671
3672-#: ../MusicSettings.qml:91
3673+#: ../MusicSettings.qml:80
3674 msgid "Rock"
3675 msgstr ""
3676
3677-#: ../MusicSettings.qml:92
3678+#: ../MusicSettings.qml:81
3679 msgid "Custom"
3680 msgstr ""
3681
3682-#: ../MusicSettings.qml:112
3683+#: ../MusicSettings.qml:101
3684 msgid ""
3685 "Snap to current song \n"
3686 "when opening toolbar"
3687 msgstr ""
3688
3689-#: ../MusicSettings.qml:132
3690+#: ../MusicSettings.qml:121
3691 msgid "Accounts"
3692 msgstr ""
3693
3694-#: ../MusicSettings.qml:146
3695+#: ../MusicSettings.qml:135
3696 msgid "Login to scrobble and import playlists"
3697 msgstr ""
3698
3699-#: ../MusicSettings.qml:169
3700+#: ../MusicSettings.qml:158
3701 msgid "Music Streaming"
3702 msgstr ""
3703
3704-#: ../MusicSettings.qml:179
3705+#: ../MusicSettings.qml:168
3706 msgid "Ubuntu One"
3707 msgstr ""
3708
3709-#: ../MusicSettings.qml:180
3710+#: ../MusicSettings.qml:169
3711 msgid "Sign in to stream your cloud music"
3712 msgstr ""
3713
3714-#: ../MusicSettings.qml:196
3715+#: ../MusicSettings.qml:185
3716 msgid "Stream only on Wi-Fi"
3717 msgstr ""
3718
3719-#: ../MusicSettings.qml:230
3720+#: ../MusicSettings.qml:219
3721 msgid "Clean everything!"
3722 msgstr ""
3723
3724-#: ../MusicStart.qml:35 ../music-app.qml:589 ../music-app.qml:1150
3725+#: ../MusicStart.qml:35 ../music-app.qml:576 ../music-app.qml:1141
3726 #: com.ubuntu.music_music.desktop.in.in.h:1
3727 msgid "Music"
3728 msgstr ""
3729@@ -241,13 +246,14 @@
3730 msgid "Genres"
3731 msgstr ""
3732
3733-#: ../MusicStart.qml:316 ../MusicStart.qml:318 ../common/SongsPage.qml:123
3734-#: ../common/SongsPage.qml:162 ../common/SongsPage.qml:240
3735+#: ../MusicStart.qml:316 ../MusicStart.qml:318 ../common/SongsPage.qml:115
3736+#: ../common/SongsPage.qml:142 ../common/SongsPage.qml:171
3737+#: ../common/SongsPage.qml:228 ../common/SongsPage.qml:270
3738 msgid "Genre"
3739 msgstr ""
3740
3741-#: ../MusicToolbar.qml:760
3742-msgid "Tap play to shuffle music"
3743+#: ../MusicToolbar.qml:150
3744+msgid "Tap to shuffle music"
3745 msgstr ""
3746
3747 #: ../MusicTracks.qml:35
3748@@ -258,17 +264,17 @@
3749 msgid "Select playlist"
3750 msgstr ""
3751
3752-#: ../common/AlbumsPage.qml:167 ../common/AlbumsPage.qml:360
3753-#: ../common/SongsPage.qml:153
3754+#: ../common/AlbumsPage.qml:165 ../common/AlbumsPage.qml:358
3755+#: ../common/SongsPage.qml:222
3756 msgid "Play all"
3757 msgstr ""
3758
3759-#: ../common/AlbumsPage.qml:211 ../common/AlbumsPage.qml:400
3760-#: ../common/SongsPage.qml:200 ../music-app.qml:888
3761+#: ../common/AlbumsPage.qml:209 ../common/AlbumsPage.qml:398
3762+#: ../music-app.qml:877
3763 msgid "Add to queue"
3764 msgstr ""
3765
3766-#: ../common/ListItemActions/AddToPlaylist.qml:25 ../music-app.qml:902
3767+#: ../common/ListItemActions/AddToPlaylist.qml:25 ../music-app.qml:891
3768 msgid "Add to playlist"
3769 msgstr ""
3770
3771@@ -294,6 +300,14 @@
3772 msgid "Loading..."
3773 msgstr ""
3774
3775+#: ../common/SongsPage.qml:164
3776+msgid "Shuffle"
3777+msgstr ""
3778+
3779+#: ../common/SongsPage.qml:201
3780+msgid "Queue all"
3781+msgstr ""
3782+
3783 #: ../common/SwipeDelete.qml:52 ../common/SwipeDelete.qml:88
3784 msgid "Clear"
3785 msgstr ""
3786@@ -306,127 +320,127 @@
3787 msgid "Unknown Artist"
3788 msgstr ""
3789
3790-#: ../music-app.qml:142
3791+#: ../music-app.qml:135
3792 msgid "Search Track"
3793 msgstr ""
3794
3795-#: ../music-app.qml:154
3796+#: ../music-app.qml:147
3797 msgid "Next"
3798 msgstr ""
3799
3800-#: ../music-app.qml:155
3801+#: ../music-app.qml:148
3802 msgid "Next Track"
3803 msgstr ""
3804
3805-#: ../music-app.qml:161
3806+#: ../music-app.qml:154
3807 msgid "Pause"
3808 msgstr ""
3809
3810-#: ../music-app.qml:161
3811+#: ../music-app.qml:154
3812 msgid "Play"
3813 msgstr ""
3814
3815-#: ../music-app.qml:163
3816+#: ../music-app.qml:156
3817 msgid "Pause Playback"
3818 msgstr ""
3819
3820-#: ../music-app.qml:163
3821+#: ../music-app.qml:156
3822 msgid "Continue or start playback"
3823 msgstr ""
3824
3825-#: ../music-app.qml:168
3826+#: ../music-app.qml:161
3827 msgid "Back"
3828 msgstr ""
3829
3830-#: ../music-app.qml:169
3831+#: ../music-app.qml:162
3832 msgid "Go back to last page"
3833 msgstr ""
3834
3835-#: ../music-app.qml:177
3836+#: ../music-app.qml:170
3837 msgid "Previous"
3838 msgstr ""
3839
3840-#: ../music-app.qml:178
3841+#: ../music-app.qml:171
3842 msgid "Previous Track"
3843 msgstr ""
3844
3845-#: ../music-app.qml:183
3846+#: ../music-app.qml:176
3847 msgid "Stop"
3848 msgstr ""
3849
3850-#: ../music-app.qml:184
3851+#: ../music-app.qml:177
3852 msgid "Stop Playback"
3853 msgstr ""
3854
3855-#: ../music-app.qml:192
3856+#: ../music-app.qml:185
3857 msgid "Music Settings"
3858 msgstr ""
3859
3860 #. TRANSLATORS: This string represents that the target destination filepath does not start with ~/Music/Imported/
3861-#: ../music-app.qml:338
3862+#: ../music-app.qml:331
3863 msgid "Filepath must start with"
3864 msgstr ""
3865
3866 #. TRANSLATORS: This string represents that a blank filepath destination has been used
3867-#: ../music-app.qml:364
3868+#: ../music-app.qml:357
3869 msgid "Filepath must be a file"
3870 msgstr ""
3871
3872 #. TRANSLATORS: This string represents that there was failure moving the file to the target destination
3873-#: ../music-app.qml:370
3874+#: ../music-app.qml:363
3875 msgid "Failed to move file"
3876 msgstr ""
3877
3878-#: ../music-app.qml:447
3879+#: ../music-app.qml:440
3880 msgid "Waiting for file(s)..."
3881 msgstr ""
3882
3883-#: ../music-app.qml:466
3884+#: ../music-app.qml:459
3885 msgid "OK"
3886 msgstr ""
3887
3888-#: ../music-app.qml:479
3889+#: ../music-app.qml:472
3890 msgid "Imported file not found"
3891 msgstr ""
3892
3893-#: ../music-app.qml:483
3894+#: ../music-app.qml:476
3895 msgid "Wait"
3896 msgstr ""
3897
3898 #. TRANSLATORS: this refers to a number of songs greater than one. The actual number will be prepended to the string automatically (plural forms are not yet fully supported in usermetrics, the library that displays that string)
3899-#: ../music-app.qml:504
3900+#: ../music-app.qml:497
3901 msgid "songs played today"
3902 msgstr ""
3903
3904-#: ../music-app.qml:505
3905+#: ../music-app.qml:498
3906 msgid "No songs played today"
3907 msgstr ""
3908
3909-#: ../music-app.qml:613
3910+#: ../music-app.qml:599
3911 msgid "Debug: "
3912 msgstr ""
3913
3914-#: ../music-app.qml:925
3915+#: ../music-app.qml:914
3916 msgid "New Playlist"
3917 msgstr ""
3918
3919-#: ../music-app.qml:926
3920+#: ../music-app.qml:915
3921 msgid "Name your playlist."
3922 msgstr ""
3923
3924-#: ../music-app.qml:930
3925+#: ../music-app.qml:919
3926 msgid "Name"
3927 msgstr ""
3928
3929-#: ../music-app.qml:940
3930+#: ../music-app.qml:929
3931 msgid "Create"
3932 msgstr ""
3933
3934-#: ../music-app.qml:1176
3935+#: ../music-app.qml:1167
3936 msgid "No music found"
3937 msgstr ""
3938
3939-#: ../music-app.qml:1183
3940+#: ../music-app.qml:1174
3941 msgid "Please import music"
3942 msgstr ""
3943
3944
3945=== modified file 'po/pt_BR.po'
3946--- po/pt_BR.po 2014-10-01 06:25:24 +0000
3947+++ po/pt_BR.po 2014-10-14 00:24:55 +0000
3948@@ -1,24 +1,34 @@
3949 # Brazilian Portuguese translation for music-app
3950-# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
3951+# Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014
3952 # This file is distributed under the same license as the music-app package.
3953-# FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
3954+# FIRST AUTHOR <EMAIL@ADDRESS>, 2014.
3955 #
3956 msgid ""
3957 msgstr ""
3958 "Project-Id-Version: music-app\n"
3959 "Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
3960+<<<<<<< TREE
3961 "POT-Creation-Date: 2014-09-23 13:43+0100\n"
3962 "PO-Revision-Date: 2014-09-30 17:34+0000\n"
3963 "Last-Translator: Rafael Neri <Unknown>\n"
3964+=======
3965+"POT-Creation-Date: 2014-10-08 20:48-0500\n"
3966+"PO-Revision-Date: 2014-09-30 18:07+0000\n"
3967+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
3968+>>>>>>> MERGE-SOURCE
3969 "Language-Team: Brazilian Portuguese <pt_BR@li.org>\n"
3970 "MIME-Version: 1.0\n"
3971 "Content-Type: text/plain; charset=UTF-8\n"
3972 "Content-Transfer-Encoding: 8bit\n"
3973 "Plural-Forms: nplurals=2; plural=n > 1;\n"
3974+<<<<<<< TREE
3975 "X-Launchpad-Export-Date: 2014-10-01 06:25+0000\n"
3976+=======
3977+"X-Launchpad-Export-Date: 2014-10-11 05:18+0000\n"
3978+>>>>>>> MERGE-SOURCE
3979 "X-Generator: Launchpad (build 17196)\n"
3980
3981-#: ../LoginLastFM.qml:48 ../MusicSettings.qml:145 ../MusicSettings.qml:153
3982+#: ../LoginLastFM.qml:48 ../MusicSettings.qml:134 ../MusicSettings.qml:142
3983 msgid "Last.fm"
3984 msgstr "Last.fm"
3985
3986@@ -54,12 +64,12 @@
3987 msgid "You forgot to set your username and/or password"
3988 msgstr "Você esqueceu de definir seu usuário e/ou senha"
3989
3990-#: ../MusicAlbums.qml:35 ../MusicStart.qml:392
3991+#: ../MusicAlbums.qml:29 ../MusicStart.qml:392
3992 msgid "Albums"
3993 msgstr "Álbuns"
3994
3995-#: ../MusicAlbums.qml:152 ../MusicStart.qml:200 ../MusicStart.qml:454
3996-#: ../common/AlbumsPage.qml:264
3997+#: ../MusicAlbums.qml:57 ../MusicStart.qml:200 ../MusicStart.qml:454
3998+#: ../common/AlbumsPage.qml:262
3999 msgid "Album"
4000 msgstr "Álbum"
4001
4002@@ -67,29 +77,33 @@
4003 msgid "Artists"
4004 msgstr "Artistas"
4005
4006-#: ../MusicArtists.qml:107 ../common/AlbumsPage.qml:112
4007+#: ../MusicArtists.qml:108 ../common/AlbumsPage.qml:110
4008 #, qt-format
4009 msgid "%1 album"
4010 msgid_plural "%1 albums"
4011 msgstr[0] "%1 álbum"
4012 msgstr[1] "%1 álbuns"
4013
4014-#: ../MusicArtists.qml:113 ../MusicPlaylists.qml:180 ../MusicStart.qml:371
4015-#: ../MusicaddtoPlaylist.qml:106 ../common/AlbumsPage.qml:331
4016-#: ../common/SongsPage.qml:123 ../common/SongsPage.qml:124
4017+#: ../MusicArtists.qml:114 ../MusicPlaylists.qml:181 ../MusicStart.qml:371
4018+#: ../MusicaddtoPlaylist.qml:105 ../common/AlbumsPage.qml:329
4019+#: ../common/SongsPage.qml:142 ../common/SongsPage.qml:143
4020 #, qt-format
4021 msgid "%1 song"
4022 msgid_plural "%1 songs"
4023 msgstr[0] "%1 música"
4024 msgstr[1] "%1 músicas"
4025
4026-#: ../MusicArtists.qml:123
4027+#: ../MusicArtists.qml:124
4028 msgid "Artist"
4029 msgstr "Artista"
4030
4031 #: ../MusicNowPlaying.qml:33
4032-msgid "Now Playing"
4033-msgstr "Reproduzindo agora"
4034+msgid "Queue"
4035+msgstr ""
4036+
4037+#: ../MusicNowPlaying.qml:33
4038+msgid "Now playing"
4039+msgstr ""
4040
4041 #. TRANSLATORS: this is the name of the playlists page shown in the tab header.
4042 #. Remember to keep the translation short to fit the screen width
4043@@ -114,83 +128,84 @@
4044 msgid "Change"
4045 msgstr "Alterar"
4046
4047-#: ../MusicPlaylists.qml:96 ../music-app.qml:956
4048+#: ../MusicPlaylists.qml:96 ../music-app.qml:945
4049 msgid "Playlist already exists"
4050 msgstr "Lista de reprodução já existe"
4051
4052-#: ../MusicPlaylists.qml:100 ../music-app.qml:961
4053+#: ../MusicPlaylists.qml:100 ../music-app.qml:950
4054 msgid "Please type in a name."
4055 msgstr "Por favor, informe um nome."
4056
4057-#: ../MusicPlaylists.qml:105 ../music-app.qml:493 ../music-app.qml:967
4058+#: ../MusicPlaylists.qml:105 ../music-app.qml:486 ../music-app.qml:956
4059 msgid "Cancel"
4060 msgstr "Cancelar"
4061
4062-#: ../MusicPlaylists.qml:159 ../MusicPlaylists.qml:163 ../MusicStart.qml:118
4063-#: ../MusicStart.qml:200 ../common/SongsPage.qml:166
4064-#: ../common/SongsPage.qml:224 ../common/SongsPage.qml:226
4065-#: ../common/SongsPage.qml:244
4066+#: ../MusicPlaylists.qml:160 ../MusicPlaylists.qml:164 ../MusicStart.qml:118
4067+#: ../MusicStart.qml:200 ../common/SongsPage.qml:114
4068+#: ../common/SongsPage.qml:175 ../common/SongsPage.qml:232
4069+#: ../common/SongsPage.qml:254 ../common/SongsPage.qml:256
4070+#: ../common/SongsPage.qml:274
4071 msgid "Playlist"
4072 msgstr "Lista de reprodução"
4073
4074-#: ../MusicSearch.qml:44 ../MusicSearch.qml:75 ../MusicToolbar.qml:519
4075-#: ../music-app.qml:93 ../music-app.qml:141 ../music-app.qml:147
4076+#: ../MusicSearch.qml:44 ../MusicSearch.qml:75 ../music-app.qml:88
4077+#: ../music-app.qml:134 ../music-app.qml:140
4078 msgid "Search"
4079 msgstr "Pesquisar"
4080
4081-#: ../MusicSettings.qml:30 ../music-app.qml:191
4082+#: ../MusicSettings.qml:30 ../music-app.qml:184
4083 msgid "Settings"
4084 msgstr "Configurações"
4085
4086-#: ../MusicSettings.qml:81
4087+#: ../MusicSettings.qml:70
4088 msgid "Equaliser"
4089 msgstr "Equalizador"
4090
4091-#: ../MusicSettings.qml:82
4092+#: ../MusicSettings.qml:71
4093 msgid "Default"
4094 msgstr "Padrão"
4095
4096-#: ../MusicSettings.qml:83
4097+#: ../MusicSettings.qml:72
4098 msgid "Acoustic"
4099 msgstr "Acústico"
4100
4101-#: ../MusicSettings.qml:84
4102+#: ../MusicSettings.qml:73
4103 msgid "Classical"
4104 msgstr "Clássica"
4105
4106-#: ../MusicSettings.qml:85
4107+#: ../MusicSettings.qml:74
4108 msgid "Electronic"
4109 msgstr "Eletrônica"
4110
4111-#: ../MusicSettings.qml:86
4112+#: ../MusicSettings.qml:75
4113 msgid "Flat"
4114 msgstr "Flat"
4115
4116-#: ../MusicSettings.qml:87
4117+#: ../MusicSettings.qml:76
4118 msgid "Hip Hop"
4119 msgstr "Hip Hop"
4120
4121-#: ../MusicSettings.qml:88
4122+#: ../MusicSettings.qml:77
4123 msgid "Jazz"
4124 msgstr "Jazz"
4125
4126-#: ../MusicSettings.qml:89
4127+#: ../MusicSettings.qml:78
4128 msgid "Metal"
4129 msgstr "Metal"
4130
4131-#: ../MusicSettings.qml:90
4132+#: ../MusicSettings.qml:79
4133 msgid "Pop"
4134 msgstr "Pop"
4135
4136-#: ../MusicSettings.qml:91
4137+#: ../MusicSettings.qml:80
4138 msgid "Rock"
4139 msgstr "Rock"
4140
4141-#: ../MusicSettings.qml:92
4142+#: ../MusicSettings.qml:81
4143 msgid "Custom"
4144 msgstr "Personalizado"
4145
4146-#: ../MusicSettings.qml:112
4147+#: ../MusicSettings.qml:101
4148 msgid ""
4149 "Snap to current song \n"
4150 "when opening toolbar"
4151@@ -198,35 +213,35 @@
4152 "Ajustar a música atual \n"
4153 "quando abrir a barra de ferramentas"
4154
4155-#: ../MusicSettings.qml:132
4156+#: ../MusicSettings.qml:121
4157 msgid "Accounts"
4158 msgstr "Contas"
4159
4160-#: ../MusicSettings.qml:146
4161+#: ../MusicSettings.qml:135
4162 msgid "Login to scrobble and import playlists"
4163 msgstr "Fazer login no scrobble e importar as listas de reprodução"
4164
4165-#: ../MusicSettings.qml:169
4166+#: ../MusicSettings.qml:158
4167 msgid "Music Streaming"
4168 msgstr "Streaming de música"
4169
4170-#: ../MusicSettings.qml:179
4171+#: ../MusicSettings.qml:168
4172 msgid "Ubuntu One"
4173 msgstr "Ubuntu One"
4174
4175-#: ../MusicSettings.qml:180
4176+#: ../MusicSettings.qml:169
4177 msgid "Sign in to stream your cloud music"
4178 msgstr "Fazer login para transmitir suas músicas armazenadas em nuvem"
4179
4180-#: ../MusicSettings.qml:196
4181+#: ../MusicSettings.qml:185
4182 msgid "Stream only on Wi-Fi"
4183 msgstr "Transmitir apenas através de Wi-Fi"
4184
4185-#: ../MusicSettings.qml:230
4186+#: ../MusicSettings.qml:219
4187 msgid "Clean everything!"
4188 msgstr "Limpar tudo!"
4189
4190-#: ../MusicStart.qml:35 ../music-app.qml:589 ../music-app.qml:1150
4191+#: ../MusicStart.qml:35 ../music-app.qml:576 ../music-app.qml:1141
4192 #: com.ubuntu.music_music.desktop.in.in.h:1
4193 msgid "Music"
4194 msgstr "Música"
4195@@ -243,14 +258,15 @@
4196 msgid "Genres"
4197 msgstr "Gêneros"
4198
4199-#: ../MusicStart.qml:316 ../MusicStart.qml:318 ../common/SongsPage.qml:123
4200-#: ../common/SongsPage.qml:162 ../common/SongsPage.qml:240
4201+#: ../MusicStart.qml:316 ../MusicStart.qml:318 ../common/SongsPage.qml:115
4202+#: ../common/SongsPage.qml:142 ../common/SongsPage.qml:171
4203+#: ../common/SongsPage.qml:228 ../common/SongsPage.qml:270
4204 msgid "Genre"
4205 msgstr "Gênero"
4206
4207-#: ../MusicToolbar.qml:760
4208-msgid "Tap play to shuffle music"
4209-msgstr "Toque em reproduzir para embaralhar músicas"
4210+#: ../MusicToolbar.qml:150
4211+msgid "Tap to shuffle music"
4212+msgstr ""
4213
4214 #: ../MusicTracks.qml:35
4215 msgid "Songs"
4216@@ -260,17 +276,17 @@
4217 msgid "Select playlist"
4218 msgstr "Selecione uma lista de reprodução"
4219
4220-#: ../common/AlbumsPage.qml:167 ../common/AlbumsPage.qml:360
4221-#: ../common/SongsPage.qml:153
4222+#: ../common/AlbumsPage.qml:165 ../common/AlbumsPage.qml:358
4223+#: ../common/SongsPage.qml:222
4224 msgid "Play all"
4225 msgstr "Tocar tudo"
4226
4227-#: ../common/AlbumsPage.qml:211 ../common/AlbumsPage.qml:400
4228-#: ../common/SongsPage.qml:200 ../music-app.qml:888
4229+#: ../common/AlbumsPage.qml:209 ../common/AlbumsPage.qml:398
4230+#: ../music-app.qml:877
4231 msgid "Add to queue"
4232 msgstr "Adicionar à fila"
4233
4234-#: ../common/ListItemActions/AddToPlaylist.qml:25 ../music-app.qml:902
4235+#: ../common/ListItemActions/AddToPlaylist.qml:25 ../music-app.qml:891
4236 msgid "Add to playlist"
4237 msgstr "Adicionar à lista de reprodução"
4238
4239@@ -296,6 +312,14 @@
4240 msgid "Loading..."
4241 msgstr "Carregando..."
4242
4243+#: ../common/SongsPage.qml:164
4244+msgid "Shuffle"
4245+msgstr ""
4246+
4247+#: ../common/SongsPage.qml:201
4248+msgid "Queue all"
4249+msgstr ""
4250+
4251 #: ../common/SwipeDelete.qml:52 ../common/SwipeDelete.qml:88
4252 msgid "Clear"
4253 msgstr "Limpar"
4254@@ -308,127 +332,127 @@
4255 msgid "Unknown Artist"
4256 msgstr "Artista desconhecido"
4257
4258-#: ../music-app.qml:142
4259+#: ../music-app.qml:135
4260 msgid "Search Track"
4261 msgstr "Pesquisar faixa"
4262
4263-#: ../music-app.qml:154
4264+#: ../music-app.qml:147
4265 msgid "Next"
4266 msgstr "Próximo"
4267
4268-#: ../music-app.qml:155
4269+#: ../music-app.qml:148
4270 msgid "Next Track"
4271 msgstr "Próxima faixa"
4272
4273-#: ../music-app.qml:161
4274+#: ../music-app.qml:154
4275 msgid "Pause"
4276 msgstr "Pausar"
4277
4278-#: ../music-app.qml:161
4279+#: ../music-app.qml:154
4280 msgid "Play"
4281 msgstr "Tocar"
4282
4283-#: ../music-app.qml:163
4284+#: ../music-app.qml:156
4285 msgid "Pause Playback"
4286 msgstr "Pausar Reprodução"
4287
4288-#: ../music-app.qml:163
4289+#: ../music-app.qml:156
4290 msgid "Continue or start playback"
4291 msgstr "Continuar ou iniciar reprodução"
4292
4293-#: ../music-app.qml:168
4294+#: ../music-app.qml:161
4295 msgid "Back"
4296 msgstr "Voltar"
4297
4298-#: ../music-app.qml:169
4299+#: ../music-app.qml:162
4300 msgid "Go back to last page"
4301 msgstr "Voltar para a última página"
4302
4303-#: ../music-app.qml:177
4304+#: ../music-app.qml:170
4305 msgid "Previous"
4306 msgstr "Anterior"
4307
4308-#: ../music-app.qml:178
4309+#: ../music-app.qml:171
4310 msgid "Previous Track"
4311 msgstr "Faixa anterior"
4312
4313-#: ../music-app.qml:183
4314+#: ../music-app.qml:176
4315 msgid "Stop"
4316 msgstr "Parar"
4317
4318-#: ../music-app.qml:184
4319+#: ../music-app.qml:177
4320 msgid "Stop Playback"
4321 msgstr "Parar reprodução"
4322
4323-#: ../music-app.qml:192
4324+#: ../music-app.qml:185
4325 msgid "Music Settings"
4326 msgstr "Configurações de Música"
4327
4328 #. TRANSLATORS: This string represents that the target destination filepath does not start with ~/Music/Imported/
4329-#: ../music-app.qml:338
4330+#: ../music-app.qml:331
4331 msgid "Filepath must start with"
4332 msgstr "O caminho do arquivo deve começar com"
4333
4334 #. TRANSLATORS: This string represents that a blank filepath destination has been used
4335-#: ../music-app.qml:364
4336+#: ../music-app.qml:357
4337 msgid "Filepath must be a file"
4338 msgstr "O caminho deve ser de um arquivo"
4339
4340 #. TRANSLATORS: This string represents that there was failure moving the file to the target destination
4341-#: ../music-app.qml:370
4342+#: ../music-app.qml:363
4343 msgid "Failed to move file"
4344 msgstr "Falhou ao mover arquivo"
4345
4346-#: ../music-app.qml:447
4347+#: ../music-app.qml:440
4348 msgid "Waiting for file(s)..."
4349 msgstr "Aguardando pelo(s) arquivo(s)"
4350
4351-#: ../music-app.qml:466
4352+#: ../music-app.qml:459
4353 msgid "OK"
4354 msgstr "OK"
4355
4356-#: ../music-app.qml:479
4357+#: ../music-app.qml:472
4358 msgid "Imported file not found"
4359 msgstr "O arquivo importado não foi encontrado"
4360
4361-#: ../music-app.qml:483
4362+#: ../music-app.qml:476
4363 msgid "Wait"
4364 msgstr "Aguardando"
4365
4366 #. TRANSLATORS: this refers to a number of songs greater than one. The actual number will be prepended to the string automatically (plural forms are not yet fully supported in usermetrics, the library that displays that string)
4367-#: ../music-app.qml:504
4368+#: ../music-app.qml:497
4369 msgid "songs played today"
4370 msgstr "músicas tocadas hoje"
4371
4372-#: ../music-app.qml:505
4373+#: ../music-app.qml:498
4374 msgid "No songs played today"
4375 msgstr "Nenhuma música tocada hoje"
4376
4377-#: ../music-app.qml:613
4378+#: ../music-app.qml:599
4379 msgid "Debug: "
4380 msgstr "Debug: "
4381
4382-#: ../music-app.qml:925
4383+#: ../music-app.qml:914
4384 msgid "New Playlist"
4385 msgstr "Nova lista de reprodução"
4386
4387-#: ../music-app.qml:926
4388+#: ../music-app.qml:915
4389 msgid "Name your playlist."
4390 msgstr "Nomear sua lista de reprodução."
4391
4392-#: ../music-app.qml:930
4393+#: ../music-app.qml:919
4394 msgid "Name"
4395 msgstr "Nome"
4396
4397-#: ../music-app.qml:940
4398+#: ../music-app.qml:929
4399 msgid "Create"
4400 msgstr "Criar"
4401
4402-#: ../music-app.qml:1176
4403+#: ../music-app.qml:1167
4404 msgid "No music found"
4405 msgstr "Nenhuma música encontrada"
4406
4407-#: ../music-app.qml:1183
4408+#: ../music-app.qml:1174
4409 msgid "Please import music"
4410 msgstr "Por favor, importar músicas"
4411
4412@@ -439,3 +463,6 @@
4413 #: com.ubuntu.music_music.desktop.in.in.h:3
4414 msgid "music;songs;play;tracks;player;tunes;"
4415 msgstr "música;músicas;tocar;faixas;player;tons;"
4416+
4417+#~ msgid "Now Playing"
4418+#~ msgstr "Reproduzindo agora"
4419
4420=== modified file 'tests/autopilot/music_app/__init__.py'
4421--- tests/autopilot/music_app/__init__.py 2014-09-25 17:58:55 +0000
4422+++ tests/autopilot/music_app/__init__.py 2014-10-14 00:24:55 +0000
4423@@ -21,11 +21,22 @@
4424 return func_wrapper
4425
4426
4427-def ensure_toolbar_visible(func):
4428- """Wrapper which ensures the toolbar is shown before clicking"""
4429- def func_wrapper(self, *args, **kwargs):
4430- if not self.opened:
4431- self.show()
4432+def ensure_now_playing_full(func):
4433+ """Wrapper which ensures the now playing is full before clicking"""
4434+ def func_wrapper(self, *args, **kwargs):
4435+ if self.isListView:
4436+ self.click_toggle_view()
4437+
4438+ return func(self, *args, **kwargs)
4439+
4440+ return func_wrapper
4441+
4442+
4443+def ensure_now_playing_list(func):
4444+ """Wrapper which ensures the now playing is list before clicking"""
4445+ def func_wrapper(self, *args, **kwargs):
4446+ if not self.isListView:
4447+ self.click_toggle_view()
4448
4449 return func(self, *args, **kwargs)
4450
4451@@ -147,8 +158,8 @@
4452
4453 @click_object
4454 def click_artist(self, i):
4455- return (self.wait_select_single("Standard",
4456- objectName="artistsPageListItem" + str(i)))
4457+ return (self.wait_select_single("Card",
4458+ objectName="artistsPageGridItem" + str(i)))
4459
4460
4461 class MusicTracks(MusicPage):
4462@@ -221,96 +232,54 @@
4463 def __init__(self, *args):
4464 super(MusicPage, self).__init__(*args)
4465
4466- def get_count(self):
4467- return self.select_single("QQuickListView",
4468- objectName="nowPlayingQueueList").count
4469-
4470- def get_track(self, i):
4471- return (self.wait_select_single(ListItemWithActions,
4472- objectName="nowPlayingListItem" + str(i)))
4473-
4474-
4475-class AlbumsPage(MusicPage):
4476- """ Autopilot helper for the albums page """
4477- def __init__(self, *args):
4478- super(MusicPage, self).__init__(*args)
4479-
4480- self.visible.wait_for(True)
4481-
4482- @click_object
4483- def click_artist(self, i):
4484- return self.wait_select_single("Standard",
4485- objectName="albumsArtistListItem"
4486- + str(i))
4487-
4488- def get_artist(self):
4489- return self.wait_select_single("Label", objectName="artistLabel").text
4490-
4491-
4492-class SongsPage(MusicPage):
4493- """ Autopilot helper for the songs page """
4494- def __init__(self, *args):
4495- super(MusicPage, self).__init__(*args)
4496-
4497- self.visible.wait_for(True)
4498-
4499- @click_object
4500- def click_track(self, i):
4501- return self.get_track(i)
4502-
4503- def get_header_artist_label(self):
4504- return self.wait_select_single("Label",
4505- objectName="songsPageHeaderAlbumArtist")
4506-
4507- def get_track(self, i):
4508- return (self.wait_select_single(ListItemWithActions,
4509- objectName="songsPageListItem" + str(i)))
4510-
4511-
4512-class MusicToolbar(UbuntuUIToolkitCustomProxyObjectBase):
4513- """Autopilot helper for the toolbar
4514-
4515- expanded - refers to things when the toolbar is in its smaller state
4516- full - refers to things when the toolbar is in its larger state
4517- """
4518- def __init__(self, *args):
4519- super(MusicToolbar, self).__init__(*args)
4520-
4521 root = self.get_root_instance()
4522 self.player = root.select_single(Player, objectName="player")
4523
4524- @ensure_toolbar_visible
4525+ @ensure_now_playing_full
4526 @click_object
4527 def click_forward_button(self):
4528 return self.wait_select_single("*", objectName="forwardShape")
4529
4530- @ensure_toolbar_visible
4531+ @ensure_now_playing_full
4532 @click_object
4533 def click_play_button(self):
4534- if self.currentMode == "full":
4535- return self.wait_select_single("*", objectName="playShape")
4536- else:
4537- return self.wait_select_single("*", objectName="smallPlayShape")
4538+ return self.wait_select_single("*", objectName="playShape")
4539
4540- @ensure_toolbar_visible
4541+ @ensure_now_playing_full
4542 @click_object
4543 def click_previous_button(self):
4544 return self.wait_select_single("*", objectName="previousShape")
4545
4546- @ensure_toolbar_visible
4547+ @ensure_now_playing_full
4548 @click_object
4549 def click_repeat_button(self):
4550 return self.wait_select_single("*", objectName="repeatShape")
4551
4552- @ensure_toolbar_visible
4553+ @ensure_now_playing_full
4554 @click_object
4555 def click_shuffle_button(self):
4556 return self.wait_select_single("*", objectName="shuffleShape")
4557
4558- @ensure_toolbar_visible
4559+ def click_toggle_view(self):
4560+ self.main_view.get_header().click_action_button("toggleView")
4561+
4562+ def get_count(self):
4563+ return self.select_single("QQuickListView",
4564+ objectName="nowPlayingQueueList").count
4565+
4566+ def go_back(self):
4567+ """Use custom back button to go back"""
4568+ self.main_view.get_header().click_custom_back_button()
4569+
4570+ @ensure_now_playing_list
4571+ def get_track(self, i):
4572+ return (self.wait_select_single(ListItemWithActions,
4573+ objectName="nowPlayingListItem" + str(i)))
4574+
4575+ @ensure_now_playing_full
4576 def seek_to(self, percentage):
4577 progress_bar = self.wait_select_single(
4578- "*", objectName="progressBarShape")
4579+ "*", objectName="progressSliderShape")
4580
4581 x1, y1, width, height = progress_bar.globalRect
4582 y1 += height // 2
4583@@ -319,28 +288,77 @@
4584
4585 self.pointing_device.drag(x1, y1, x2, y1)
4586
4587- @ensure_toolbar_visible
4588 def set_repeat(self, state):
4589 if self.player.repeat != state:
4590 self.click_repeat_button()
4591
4592 self.player.repeat.wait_for(state)
4593
4594- @ensure_toolbar_visible
4595 def set_shuffle(self, state):
4596 if self.player.shuffle != state:
4597 self.click_shuffle_button()
4598
4599 self.player.shuffle.wait_for(state)
4600
4601- def show(self):
4602- self.pointing_device.move_to_object(self)
4603-
4604- x1, y1 = self.pointing_device.position()
4605-
4606- y1 -= (self.height / 2) + 1 # get position at top of toolbar
4607-
4608- self.pointing_device.drag(x1, y1, x1, y1 - self.fullHeight)
4609+
4610+class AlbumsPage(MusicPage):
4611+ """ Autopilot helper for the albums page """
4612+ def __init__(self, *args):
4613+ super(MusicPage, self).__init__(*args)
4614+
4615+ self.visible.wait_for(True)
4616+
4617+ @click_object
4618+ def click_artist(self, i):
4619+ return self.wait_select_single("Standard",
4620+ objectName="albumsArtistListItem"
4621+ + str(i))
4622+
4623+ def get_artist(self):
4624+ return self.wait_select_single("Label", objectName="artistLabel").text
4625+
4626+
4627+class SongsPage(MusicPage):
4628+ """ Autopilot helper for the songs page """
4629+ def __init__(self, *args):
4630+ super(MusicPage, self).__init__(*args)
4631+
4632+ self.visible.wait_for(True)
4633+
4634+ @click_object
4635+ def click_track(self, i):
4636+ return self.get_track(i)
4637+
4638+ def get_header_artist_label(self):
4639+ return self.wait_select_single("Label",
4640+ objectName="songsPageHeaderAlbumArtist")
4641+
4642+ def get_track(self, i):
4643+ return (self.wait_select_single(ListItemWithActions,
4644+ objectName="songsPageListItem" + str(i)))
4645+
4646+
4647+class MusicToolbar(UbuntuUIToolkitCustomProxyObjectBase):
4648+ """Autopilot helper for the toolbar"""
4649+ def __init__(self, *args):
4650+ super(MusicToolbar, self).__init__(*args)
4651+
4652+ @click_object
4653+ def click_play_button(self):
4654+ return self.wait_select_single("*", objectName="playShape")
4655+
4656+ @click_object
4657+ def click_jump_to_now_playing(self):
4658+ return self.wait_select_single("*", objectName="jumpNowPlaying")
4659+
4660+ def switch_to_now_playing(self):
4661+ self.click_jump_to_now_playing()
4662+
4663+ root = self.get_root_instance()
4664+ now_playing_page = root.wait_select_single(MusicNowPlaying,
4665+ objectName="nowPlayingPage")
4666+
4667+ now_playing_page.visible.wait_for(True)
4668
4669
4670 class ListItemWithActions(UbuntuUIToolkitCustomProxyObjectBase):
4671
4672=== modified file 'tests/autopilot/music_app/tests/test_music.py'
4673--- tests/autopilot/music_app/tests/test_music.py 2014-09-23 20:45:41 +0000
4674+++ tests/autopilot/music_app/tests/test_music.py 2014-10-14 00:24:55 +0000
4675@@ -91,6 +91,11 @@
4676 Eventually(NotEquals(end_tracks_count)))
4677 self.assertThat(self.player.isPlaying, Eventually(Equals(False)))
4678
4679+ toolbar.switch_to_now_playing() # Switch to the now playing page
4680+
4681+ # Re get now playing page as it has changed
4682+ now_playing_page = self.app.get_now_playing_page()
4683+
4684 # verify song's metadata matches the item added to the Now Playing view
4685 current_track = now_playing_page.get_track(self.player.currentIndex)
4686
4687@@ -99,14 +104,14 @@
4688 self.assertThat(current_track.get_label_text("titleLabel"),
4689 Equals(self.tracks[0]["title"]))
4690
4691- # click on close button to close the page
4692- self.app.main_view.go_back()
4693+ # click on close button to close the page and now playing page
4694+ now_playing_page.go_back()
4695
4696- # click the play button to start playing
4697+ # click the play button (toolbar) to start playing
4698 toolbar.click_play_button()
4699 self.assertThat(self.player.isPlaying, Eventually(Equals(True)))
4700
4701- # click the play button to stop playing
4702+ # click the play button (toolbar) to stop playing
4703 toolbar.click_play_button()
4704 self.assertThat(self.player.isPlaying, Eventually(Equals(False)))
4705
4706@@ -115,15 +120,15 @@
4707
4708 self.app.populate_queue() # populate queue
4709
4710- toolbar = self.app.get_toolbar()
4711+ now_playing_page = self.app.get_now_playing_page()
4712
4713 # check that the player is playing and then select pause
4714 self.assertThat(self.player.isPlaying, Eventually(Equals(True)))
4715- toolbar.click_play_button()
4716+ now_playing_page.click_play_button()
4717
4718 # check that the player is paused and then select play
4719 self.assertThat(self.player.isPlaying, Eventually(Equals(False)))
4720- toolbar.click_play_button()
4721+ now_playing_page.click_play_button()
4722
4723 # check that the player is playing
4724 self.assertThat(self.player.isPlaying, Eventually(Equals(True)))
4725@@ -133,7 +138,7 @@
4726
4727 self.app.populate_queue() # populate queue
4728
4729- toolbar = self.app.get_toolbar()
4730+ now_playing_page = self.app.get_now_playing_page()
4731
4732 # save original song data for later
4733 org_title = self.player.currentMetaTitle
4734@@ -144,17 +149,17 @@
4735 logger.debug("Original Song %s, %s" % (org_title, org_artist))
4736
4737 # select pause and check the player has stopped
4738- toolbar.click_play_button()
4739+ now_playing_page.click_play_button()
4740 self.assertThat(self.player.isPlaying, Eventually(Equals(False)))
4741
4742- toolbar.set_shuffle(False) # ensure shuffe is off
4743+ now_playing_page.set_shuffle(False) # ensure shuffe is off
4744
4745 # goal is to go back and forth and ensure 2 different songs
4746- toolbar.click_forward_button()
4747+ now_playing_page.click_forward_button()
4748 self.assertThat(self.player.isPlaying, Eventually(Equals(True)))
4749
4750 # select pause and check the player has stopped
4751- toolbar.click_play_button()
4752+ now_playing_page.click_play_button()
4753 self.assertThat(self.player.isPlaying, Eventually(Equals(False)))
4754
4755 # ensure different song
4756@@ -166,14 +171,14 @@
4757 logger.debug("Next Song %s, %s" % (self.player.currentMetaTitle,
4758 self.player.currentMetaArtist))
4759
4760- toolbar.seek_to(0) # seek to 0 (start)
4761+ now_playing_page.seek_to(0) # seek to 0 (start)
4762
4763 # select previous and ensure the track is playing
4764- toolbar.click_previous_button()
4765+ now_playing_page.click_previous_button()
4766 self.assertThat(self.player.isPlaying, Eventually(Equals(True)))
4767
4768 # select pause and check the player has stopped
4769- toolbar.click_play_button()
4770+ now_playing_page.click_play_button()
4771 self.assertThat(self.player.isPlaying, Eventually(Equals(False)))
4772
4773 # ensure we're back to original song
4774@@ -207,13 +212,13 @@
4775 self.assertThat(self.player.source.endswith("mp3"),
4776 Equals(True))
4777
4778- # Start playing the track
4779+ # Start playing the track (click from toolbar)
4780 toolbar.click_play_button()
4781
4782 # Check that the track is playing
4783 self.assertThat(self.player.isPlaying, Eventually(Equals(True)))
4784
4785- # Stop playing the track
4786+ # Stop playing the track (click from toolbar)
4787 toolbar.click_play_button()
4788
4789 # Check current meta data is correct
4790@@ -229,15 +234,15 @@
4791
4792 # at this point the track is playing and shuffle is enabled
4793
4794- toolbar = self.app.get_toolbar()
4795+ now_playing_page = self.app.get_now_playing_page()
4796
4797 # pause the track if it is playing
4798 if self.player.isPlaying:
4799- toolbar.click_play_button()
4800+ now_playing_page.click_play_button()
4801
4802 self.player.isPlaying.wait_for(False)
4803
4804- toolbar.set_shuffle(True) # enable shuffle
4805+ now_playing_page.set_shuffle(True) # enable shuffle
4806
4807 # save original song metadata
4808 org_title = self.player.currentMetaTitle
4809@@ -256,11 +261,11 @@
4810 self.assertThat(count, LessThan(100))
4811
4812 # select next track
4813- toolbar.click_forward_button()
4814+ now_playing_page.click_forward_button()
4815
4816 # pause the track if it is playing
4817 if self.player.isPlaying:
4818- toolbar.click_play_button()
4819+ now_playing_page.click_play_button()
4820
4821 # check it is paused
4822 self.assertThat(self.player.isPlaying, Eventually(Equals(False)))
4823@@ -270,11 +275,11 @@
4824
4825 # select previous track while will break if this previous track
4826 # is different and therefore a shuffle has occurred
4827- toolbar.click_previous_button()
4828+ now_playing_page.click_previous_button()
4829
4830 # pause the track if it is playing
4831 if self.player.isPlaying:
4832- toolbar.click_play_button()
4833+ now_playing_page.click_play_button()
4834
4835 # check it is paused
4836 self.assertThat(self.player.isPlaying, Eventually(Equals(False)))
4837@@ -314,6 +319,7 @@
4838 """tests navigating to the Albums tab and adding a song to queue"""
4839
4840 now_playing_page = self.app.get_now_playing_page()
4841+ toolbar = self.app.get_toolbar()
4842
4843 # get number of tracks in queue before queuing a track
4844 initial_tracks_count = now_playing_page.get_count()
4845@@ -341,6 +347,11 @@
4846 # Assert that the song added to the list is not playing
4847 self.assertThat(self.player.isPlaying, Eventually(Equals(False)))
4848
4849+ toolbar.switch_to_now_playing() # Switch to the now playing page
4850+
4851+ # Re get now playing page as it has changed
4852+ now_playing_page = self.app.get_now_playing_page()
4853+
4854 # verify song's metadata matches the item added to the Now Playing view
4855 current_track = now_playing_page.get_track(self.player.currentIndex)
4856
4857@@ -349,8 +360,8 @@
4858 self.assertThat(current_track.get_label_text("titleLabel"),
4859 Equals(tracks[0]["title"]))
4860
4861- # click on close button to close songs page
4862- self.app.main_view.go_back()
4863+ # click on close button to close nowplaying and songs page
4864+ now_playing_page.go_back()
4865
4866 # check that the albums page is now visible
4867 self.assertThat(albums_page.visible, Eventually(Equals(True)))
4868@@ -391,6 +402,7 @@
4869 to the queue via the expandable list view item. """
4870
4871 now_playing_page = self.app.get_now_playing_page()
4872+ toolbar = self.app.get_toolbar()
4873
4874 # get number of tracks in queue before queuing a track
4875 initial_tracks_count = now_playing_page.get_count()
4876@@ -413,6 +425,11 @@
4877 Eventually(NotEquals(now_playing_page.get_count())))
4878 self.assertThat(self.player.isPlaying, Eventually(Equals(False)))
4879
4880+ toolbar.switch_to_now_playing() # Switch to the now playing page
4881+
4882+ # Re get now playing page as it has changed
4883+ now_playing_page = self.app.get_now_playing_page()
4884+
4885 # verify song's metadata matches the item added to the Now Playing view
4886 current_track = now_playing_page.get_track(self.player.currentIndex)
4887
4888@@ -552,14 +569,13 @@
4889 self.app.populate_queue() # populate queue
4890
4891 now_playing_page = self.app.get_now_playing_page()
4892- toolbar = self.app.get_toolbar()
4893
4894- toolbar.set_shuffle(False)
4895- toolbar.set_repeat(False)
4896+ now_playing_page.set_shuffle(False)
4897+ now_playing_page.set_repeat(False)
4898
4899 # Skip through all songs in queue, stopping on last one.
4900 for count in range(0, now_playing_page.get_count() - 1):
4901- toolbar.click_forward_button()
4902+ now_playing_page.click_forward_button()
4903
4904 # When the last song ends, playback should stop
4905 self.assertThat(self.player.isPlaying, Eventually(Equals(False)))
4906@@ -570,14 +586,13 @@
4907 self.app.populate_queue() # populate queue
4908
4909 now_playing_page = self.app.get_now_playing_page()
4910- toolbar = self.app.get_toolbar()
4911
4912- toolbar.set_shuffle(False)
4913- toolbar.set_repeat(True)
4914+ now_playing_page.set_shuffle(False)
4915+ now_playing_page.set_repeat(True)
4916
4917 # Skip through all songs in queue, stopping on last one.
4918 for count in range(0, now_playing_page.get_count() - 1):
4919- toolbar.click_forward_button()
4920+ now_playing_page.click_forward_button()
4921
4922 # Make sure we loop back to first song after last song ends
4923 self.assertThat(self.player.currentMetaTitle,
4924@@ -590,14 +605,13 @@
4925 self.app.populate_queue() # populate queue
4926
4927 now_playing_page = self.app.get_now_playing_page()
4928- toolbar = self.app.get_toolbar()
4929
4930- toolbar.set_shuffle(False)
4931- toolbar.set_repeat(True)
4932+ now_playing_page.set_shuffle(False)
4933+ now_playing_page.set_repeat(True)
4934
4935 # Skip through all songs in queue, INCLUDING last one.
4936 for count in range(0, now_playing_page.get_count() - 1):
4937- toolbar.click_forward_button()
4938+ now_playing_page.click_forward_button()
4939
4940 # Make sure we loop back to first song after last song ends
4941 self.assertThat(self.player.currentMetaTitle,
4942@@ -609,19 +623,19 @@
4943
4944 self.app.populate_queue() # populate queue
4945
4946- toolbar = self.app.get_toolbar()
4947+ now_playing_page = self.app.get_now_playing_page()
4948
4949- toolbar.set_shuffle(False)
4950- toolbar.set_repeat(True)
4951+ now_playing_page.set_shuffle(False)
4952+ now_playing_page.set_repeat(True)
4953
4954 initial_song = self.player.currentMetaTitle
4955- toolbar.click_previous_button()
4956+ now_playing_page.click_previous_button()
4957
4958 # If we're far enough into a song, pressing prev just takes us to the
4959 # beginning of that track. In that case, hit prev again to actually
4960 # skip over the track.
4961 if self.player.currentMetaTitle == initial_song:
4962- toolbar.click_previous_button()
4963+ now_playing_page.click_previous_button()
4964
4965 self.assertThat(self.player.currentMetaTitle,
4966 Eventually(Equals(self.tracks[-1]["title"])))
4967@@ -632,17 +646,17 @@
4968
4969 self.app.populate_queue() # populate queue
4970
4971- toolbar = self.app.get_toolbar()
4972+ now_playing_page = self.app.get_now_playing_page()
4973
4974 self.player.isPlaying.wait_for(True) # ensure the track is playing
4975 self.player.position.wait_for(GreaterThan(5000)) # wait until > 5s
4976
4977- toolbar.click_play_button() # pause the track
4978+ now_playing_page.click_play_button() # pause the track
4979 self.player.isPlaying.wait_for(False) # ensure the track has paused
4980
4981 source = self.player.source # store current source
4982
4983- toolbar.click_previous_button() # click previous
4984+ now_playing_page.click_previous_button() # click previous
4985
4986 self.player.position.wait_for(LessThan(5000)) # wait until < 5s
4987

Subscribers

People subscribed via source and target branches

to status/vote changes: