Merge lp:~vthompson/music-app/remix-add-to-playlist-001 into lp:music-app/trusty

Proposed by Victor Thompson
Status: Superseded
Proposed branch: lp:~vthompson/music-app/remix-add-to-playlist-001
Merge into: lp:music-app/trusty
Diff against target: 6294 lines (+2571/-2211) (has conflicts)
30 files modified
MusicAlbums.qml (+21/-123)
MusicArtists.qml (+37/-87)
MusicNowPlaying.qml (+377/-219)
MusicPlaylists.qml (+34/-10)
MusicSettings.qml (+0/-11)
MusicToolbar.qml (+161/-953)
MusicTracks.qml (+13/-18)
MusicaddtoPlaylist.qml (+1/-4)
Player.qml (+5/-1)
Style.qml (+2/-2)
com.ubuntu.music_music.desktop.in.in (+3/-0)
common/AlbumsPage.qml (+117/-7)
common/BlurredBackground.qml (+12/-14)
common/BlurredHeader.qml (+69/-0)
common/Card.qml (+151/-0)
common/CardView.qml (+61/-0)
common/ColumnFlow.qml (+160/-0)
common/CoverGrid.qml (+78/-0)
common/CoverRow.qml (+0/-91)
common/ListItemActions/DeletePlaylist.qml (+0/-29)
common/ListItemActions/EditPlaylist.qml (+0/-35)
common/MusicPage.qml (+4/-0)
common/MusicRow.qml (+16/-12)
common/SongsPage.qml (+280/-163)
music-app.qml (+24/-33)
po/ca@valencia.po (+465/-0)
po/com.ubuntu.music.pot (+147/-133)
po/pt_BR.po (+169/-136)
tests/autopilot/music_app/__init__.py (+104/-84)
tests/autopilot/music_app/tests/test_music.py (+60/-46)
Text conflict in MusicPlaylists.qml
Text conflict in common/AlbumsPage.qml
Conflict adding file po/ca@valencia.po.  Moved existing file to po/ca@valencia.po.moved.
Text conflict in po/pt_BR.po
To merge this branch: bzr merge lp:~vthompson/music-app/remix-add-to-playlist-001
Reviewer Review Type Date Requested Status
Music App Developers Pending
Review via email: mp+238976@code.launchpad.net

This proposal has been superseded by a proposal from 2014-10-20.

Commit message

* Remove CoverRow
* Remove isPressedChanged workaround
* Remove MusicRow isSquare specialization

Description of the change

* Remove CoverRow
* Remove isPressedChanged workaround
* Remove MusicRow isSquare specialization

To post a comment you must log in.
682. By Victor Thompson

Merge of remix

683. By Victor Thompson

Update header icon to use newer property

684. By Victor Thompson

Change listview to covergrid

685. By Victor Thompson

Update to fix Autopilot test

686. By Victor Thompson

Resolve conflicts and merge of remix

687. By Victor Thompson

Remove MusicRow

Unmerged revisions

687. By Victor Thompson

Remove MusicRow

686. By Victor Thompson

Resolve conflicts and merge of remix

685. By Victor Thompson

Update to fix Autopilot test

684. By Victor Thompson

Change listview to covergrid

683. By Victor Thompson

Update header icon to use newer property

682. By Victor Thompson

Merge of remix

681. By Victor Thompson

Remove onPressed workaround

680. By Victor Thompson

Update to remove remaining isSquare properties

679. By Victor Thompson

Remove CoverRow

678. By Andrew Hayzen

* Set sourceSize of images.

Approved by Ubuntu Phone Apps Jenkins Bot, Victor Thompson.

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

Subscribers

People subscribed via source and target branches

to status/vote changes: