From 692bbf6590b16ff64c09eb7fab3a997f3310d623 Mon Sep 17 00:00:00 2001 From: "craig.p.drummond@gmail.com" Date: Tue, 12 Jun 2012 11:16:37 +0000 Subject: [PATCH] Show playlist files in library and album views. BUG:27 --- ChangeLog | 1 + devices/utils.cpp | 21 ++++-- devices/utils.h | 1 + gui/albumspage.cpp | 10 +-- gui/albumspage.h | 4 +- gui/librarypage.cpp | 10 +-- gui/librarypage.h | 4 +- models/albumsmodel.cpp | 20 +++--- models/albumsmodel.h | 4 +- models/albumsproxymodel.cpp | 3 + models/musiclibraryitemroot.cpp | 110 +++++++++++++++++------------- models/musiclibrarymodel.cpp | 45 ++++++------ models/musiclibrarymodel.h | 4 +- models/musiclibraryproxymodel.cpp | 3 + mpd/mpdconnection.cpp | 4 +- mpd/mpdparseutils.cpp | 20 +++++- mpd/song.cpp | 3 + mpd/song.h | 3 +- 18 files changed, 168 insertions(+), 102 deletions(-) diff --git a/ChangeLog b/ChangeLog index 316a7f2ed..3676897af 100644 --- a/ChangeLog +++ b/ChangeLog @@ -38,6 +38,7 @@ 23. Add option to show artist images in library view. 24. Dont allow selection to overlap tab-widget border lines in preferences dialog (Qt-only build). +25. Show playlists in library and album views (requires MPD 0.17) 0.7.1 ----- diff --git a/devices/utils.cpp b/devices/utils.cpp index 8143a4ea3..6d065baed 100644 --- a/devices/utils.cpp +++ b/devices/utils.cpp @@ -60,16 +60,16 @@ QString Utils::strippedText(QString s) QString Utils::dirSyntax(const QString &d) { - if(!d.isEmpty()) - { + if (!d.isEmpty()) { QString ds(d); ds.replace("//", "/"); int slashPos(ds.lastIndexOf('/')); - if(slashPos!=(((int)ds.length())-1)) + if (slashPos!=(((int)ds.length())-1)) { ds.append('/'); + } return ds; } @@ -82,12 +82,25 @@ QString Utils::getDir(const QString &file) QString d(file); int slashPos(d.lastIndexOf('/')); - if(slashPos!=-1) + if (-1!=slashPos) { d.remove(slashPos+1, d.length()); + } return dirSyntax(d); } +QString Utils::getFile(const QString &file) +{ + QString d(file); + int slashPos=d.lastIndexOf('/'); + + if (-1!=slashPos) { + d.remove(0, slashPos+1); + } + + return d; +} + QString Utils::changeExtension(const QString &file, const QString &extension) { if (extension.isEmpty()) { diff --git a/devices/utils.h b/devices/utils.h index 9b10ef9f7..12bd12aa8 100644 --- a/devices/utils.h +++ b/devices/utils.h @@ -41,6 +41,7 @@ namespace Utils extern QString strippedText(QString s); extern QString dirSyntax(const QString &d); extern QString getDir(const QString &file); + extern QString getFile(const QString &file); extern QString changeExtension(const QString &file, const QString &extension); extern void moveDir(const QString &from, const QString &to, const QString &base, const QString &coverFile); extern void cleanDir(const QString &dir, const QString &base, const QString &coverFile, int level=0); diff --git a/gui/albumspage.cpp b/gui/albumspage.cpp index 31a2b0250..884b9efa6 100644 --- a/gui/albumspage.cpp +++ b/gui/albumspage.cpp @@ -115,7 +115,7 @@ void AlbumsPage::setItemSize(int v) } } -QStringList AlbumsPage::selectedFiles() const +QStringList AlbumsPage::selectedFiles(bool allowPlaylists) const { QModelIndexList selected = view->selectedIndexes(); @@ -129,10 +129,10 @@ QStringList AlbumsPage::selectedFiles() const mapped.append(proxy.mapToSource(idx)); } - return AlbumsModel::self()->filenames(mapped); + return AlbumsModel::self()->filenames(mapped, allowPlaylists); } -QList AlbumsPage::selectedSongs() const +QList AlbumsPage::selectedSongs(bool allowPlaylists) const { QModelIndexList selected = view->selectedIndexes(); @@ -146,12 +146,12 @@ QList AlbumsPage::selectedSongs() const mapped.append(proxy.mapToSource(idx)); } - return AlbumsModel::self()->songs(mapped); + return AlbumsModel::self()->songs(mapped, allowPlaylists); } void AlbumsPage::addSelectionToPlaylist(const QString &name, bool replace) { - QStringList files=selectedFiles(); + QStringList files=selectedFiles(true); if (!files.isEmpty()) { if (name.isEmpty()) { diff --git a/gui/albumspage.h b/gui/albumspage.h index 0f62aef1d..66b03b800 100644 --- a/gui/albumspage.h +++ b/gui/albumspage.h @@ -38,8 +38,8 @@ public: virtual ~AlbumsPage(); void clear(); - QStringList selectedFiles() const; - QList selectedSongs() const; + QStringList selectedFiles(bool allowPlaylists=false) const; + QList selectedSongs(bool allowPlaylists=false) const; void addSelectionToPlaylist(const QString &name=QString(), bool replace=false); #ifdef ENABLE_DEVICES_SUPPORT void addSelectionToDevice(const QString &udi); diff --git a/gui/librarypage.cpp b/gui/librarypage.cpp index 6484976b3..8297bbe9e 100644 --- a/gui/librarypage.cpp +++ b/gui/librarypage.cpp @@ -139,7 +139,7 @@ void LibraryPage::clear() view->setLevel(0); } -QStringList LibraryPage::selectedFiles() const +QStringList LibraryPage::selectedFiles(bool allowPlaylists) const { QModelIndexList selected = view->selectedIndexes(); @@ -153,10 +153,10 @@ QStringList LibraryPage::selectedFiles() const mapped.append(proxy.mapToSource(idx)); } - return MusicLibraryModel::self()->filenames(mapped); + return MusicLibraryModel::self()->filenames(mapped, allowPlaylists); } -QList LibraryPage::selectedSongs() const +QList LibraryPage::selectedSongs(bool allowPlaylists) const { QModelIndexList selected = view->selectedIndexes(); @@ -170,12 +170,12 @@ QList LibraryPage::selectedSongs() const mapped.append(proxy.mapToSource(idx)); } - return MusicLibraryModel::self()->songs(mapped); + return MusicLibraryModel::self()->songs(mapped, allowPlaylists); } void LibraryPage::addSelectionToPlaylist(const QString &name, bool replace) { - QStringList files=selectedFiles(); + QStringList files=selectedFiles(true); if (!files.isEmpty()) { if (name.isEmpty()) { diff --git a/gui/librarypage.h b/gui/librarypage.h index 9c060c3f3..acff67c91 100644 --- a/gui/librarypage.h +++ b/gui/librarypage.h @@ -38,8 +38,8 @@ public: void refresh(); void clear(); - QStringList selectedFiles() const; - QList selectedSongs() const; + QStringList selectedFiles(bool allowPlaylists=false) const; + QList selectedSongs(bool allowPlaylists=false) const; void addSelectionToPlaylist(const QString &name=QString(), bool replace=false); #ifdef ENABLE_DEVICES_SUPPORT void addSelectionToDevice(const QString &udi); diff --git a/models/albumsmodel.cpp b/models/albumsmodel.cpp index e392c75c7..4affc3f0b 100644 --- a/models/albumsmodel.cpp +++ b/models/albumsmodel.cpp @@ -276,15 +276,19 @@ QVariant AlbumsModel::data(const QModelIndex &index, int role) const switch (role) { case Qt::DecorationRole: - return QIcon::fromTheme("audio-x-generic"); + return QIcon::fromTheme(Song::Playlist==si->type ? "view-media-playlist" : "audio-x-generic"); case Qt::ToolTipRole: { quint32 year=si->parent->songs.count() ? si->parent->songs.at(0)->year : 0; return si->parent->artist+QLatin1String("
")+ si->parent->album+(year>0 ? (QLatin1String(" (")+QString::number(year)+QChar(')')) : QString())+QLatin1String("
")+ data(index, Qt::DisplayRole).toString()+QLatin1String("
")+ - Song::formattedTime(si->time)+QLatin1String("
")+si->file+QLatin1String(""); + (Song::Playlist==si->type ? QString() : Song::formattedTime(si->time)+QLatin1String("
"))+ + QLatin1String("")+si->file+QLatin1String(""); } case Qt::DisplayRole: + if (Song::Playlist==si->type) { + return si->title; + } if (Song::SingleTracks==si->parent->type) { return si->artistSong(); } @@ -309,9 +313,9 @@ Qt::ItemFlags AlbumsModel::flags(const QModelIndex &index) const } } -QStringList AlbumsModel::filenames(const QModelIndexList &indexes) const +QStringList AlbumsModel::filenames(const QModelIndexList &indexes, bool allowPlaylists) const { - QList songList=songs(indexes); + QList songList=songs(indexes, allowPlaylists); QStringList fnames; foreach (const Song &s, songList) { fnames.append(s.file); @@ -319,7 +323,7 @@ QStringList AlbumsModel::filenames(const QModelIndexList &indexes) const return fnames; } -QList AlbumsModel::songs(const QModelIndexList &indexes) const +QList AlbumsModel::songs(const QModelIndexList &indexes, bool allowPlaylists) const { QList songs; foreach(QModelIndex index, indexes) { @@ -327,11 +331,11 @@ QList AlbumsModel::songs(const QModelIndexList &indexes) const if (item->isAlbum()) { foreach (const SongItem *s, static_cast(item)->songs) { - if (!songs.contains(*s)) { + if ((/*allowPlaylists || */Song::Playlist!=s->type) && !songs.contains(*s)) { songs << *s; } } - } else if (!songs.contains(*static_cast(item))) { + } else if ((allowPlaylists || Song::Playlist!=static_cast(item)->type) && !songs.contains(*static_cast(item))) { songs << *static_cast(item); } } @@ -341,7 +345,7 @@ QList AlbumsModel::songs(const QModelIndexList &indexes) const QMimeData * AlbumsModel::mimeData(const QModelIndexList &indexes) const { QMimeData *mimeData = new QMimeData(); - QStringList files=filenames(indexes); + QStringList files=filenames(indexes, true); PlayQueueModel::encode(*mimeData, PlayQueueModel::constFileNameMimeType, files); if (!MPDConnection::self()->getDetails().dir.isEmpty()) { QStringList paths; diff --git a/models/albumsmodel.h b/models/albumsmodel.h index 9da0ec0a7..bc9455b9c 100644 --- a/models/albumsmodel.h +++ b/models/albumsmodel.h @@ -111,8 +111,8 @@ public: QModelIndex index(int row, int column, const QModelIndex &parent) const; QVariant data(const QModelIndex &, int) const; Qt::ItemFlags flags(const QModelIndex &index) const; - QStringList filenames(const QModelIndexList &indexes) const; - QList songs(const QModelIndexList &indexes) const; + QStringList filenames(const QModelIndexList &indexes, bool allowPlaylists=false) const; + QList songs(const QModelIndexList &indexes, bool allowPlaylists=false) const; QMimeData * mimeData(const QModelIndexList &indexes) const; void clear(); bool isEnabled() const { return enabled; } diff --git a/models/albumsproxymodel.cpp b/models/albumsproxymodel.cpp index 0a91b2676..1ffac4c5b 100644 --- a/models/albumsproxymodel.cpp +++ b/models/albumsproxymodel.cpp @@ -98,6 +98,9 @@ bool AlbumsProxyModel::lessThan(const QModelIndex &left, const QModelIndex &righ if (0!=compare) { return compare<0; } + } + if (leftItem->type != rightItem->type) { + return leftItem->type < rightItem->type; } if (leftItem->disc != rightItem->disc) { return leftItem->disc < rightItem->disc; diff --git a/models/musiclibraryitemroot.cpp b/models/musiclibraryitemroot.cpp index 29f97b71a..002c6e965 100644 --- a/models/musiclibraryitemroot.cpp +++ b/models/musiclibraryitemroot.cpp @@ -287,9 +287,13 @@ void MusicLibraryItemRoot::toXML(QXmlStreamWriter &writer, const QDateTime &date foreach (const MusicLibraryItem *t, album->childItems()) { const MusicLibraryItemSong *track = static_cast(t); writer.writeEmptyElement("Track"); - writer.writeAttribute("name", track->song().title); + if (!track->song().title.isEmpty()) { + writer.writeAttribute("name", track->song().title); + } writer.writeAttribute("file", track->file()); - writer.writeAttribute("time", QString::number(track->time())); + if (0!=track->time()) { + writer.writeAttribute("time", QString::number(track->time())); + } //Only write track number if it is set if (track->track() != 0) { writer.writeAttribute("track", QString::number(track->track())); @@ -297,10 +301,10 @@ void MusicLibraryItemRoot::toXML(QXmlStreamWriter &writer, const QDateTime &date if (track->disc() != 0) { writer.writeAttribute("disc", QString::number(track->disc())); } - if (track->song().artist!=artist->data()) { + if (!track->song().artist.isEmpty() && track->song().artist!=artist->data()) { writer.writeAttribute("artist", track->song().artist); } - if (track->song().albumartist!=artist->data()) { + if (!track->song().albumartist.isEmpty() && track->song().albumartist!=artist->data()) { writer.writeAttribute("albumartist", track->song().albumartist); } // writer.writeAttribute("id", QString::number(track->song().id)); @@ -312,6 +316,9 @@ void MusicLibraryItemRoot::toXML(QXmlStreamWriter &writer, const QDateTime &date } else if (album->isMultipleArtists()) { writer.writeAttribute("artist", track->song().artist); } + if (Song::Playlist==track->song().type) { + writer.writeAttribute("playlist", "true"); + } } writer.writeEndElement(); } @@ -389,54 +396,61 @@ quint32 MusicLibraryItemRoot::fromXML(QXmlStreamReader &reader, const QDateTime else if (QLatin1String("Track")==element) { song.title=attributes.value("name").toString(); song.file=attributes.value("file").toString(); - if (!baseFolder.isEmpty() && song.file.startsWith(baseFolder)) { - song.file=song.file.mid(baseFolder.length()); - } - song.genre=attributes.value("genre").toString(); - if (attributes.hasAttribute("artist")) { - song.artist=attributes.value("artist").toString(); + if (QLatin1String("true")==attributes.value("playlist").toString()) { + song.type=Song::Playlist; + songItem = new MusicLibraryItemSong(song, albumItem); + albumItem->append(songItem); + song.type=Song::Standard; } else { - song.artist=artistItem->data(); - } - if (attributes.hasAttribute("albumartist")) { - song.albumartist=attributes.value("albumartist").toString(); - } else { - song.albumartist=artistItem->data(); - } - - // Fix cache error - where MusicLibraryItemSong::data() was saved as name instead of song.name!!!! - if (!song.albumartist.isEmpty() && !song.artist.isEmpty() && song.albumartist!=song.artist && - song.title.startsWith(song.artist+QLatin1String(" - "))) { - song.title=song.title.mid(song.artist.length()+3); - } - - QString str=attributes.value("track").toString(); - song.track=str.isEmpty() ? 0 : str.toUInt(); - str=attributes.value("disc").toString(); - song.disc=str.isEmpty() ? 0 : str.toUInt(); - str=attributes.value("time").toString(); - song.time=str.isEmpty() ? 0 : str.toUInt(); -// str=attributes.value("id").toString(); -// song.id=str.isEmpty() ? 0 : str.toUInt(); - - if (albumItem->isSingleTracks()) { - str=attributes.value("album").toString(); - if (!str.isEmpty()) { - song.album=str; + if (!baseFolder.isEmpty() && song.file.startsWith(baseFolder)) { + song.file=song.file.mid(baseFolder.length()); } - } else if (albumItem->isMultipleArtists()) { - str=attributes.value("artist").toString(); - if (!str.isEmpty()) { - song.artist=str; + song.genre=attributes.value("genre").toString(); + if (attributes.hasAttribute("artist")) { + song.artist=attributes.value("artist").toString(); + } else { + song.artist=artistItem->data(); + } + if (attributes.hasAttribute("albumartist")) { + song.albumartist=attributes.value("albumartist").toString(); + } else { + song.albumartist=artistItem->data(); } - } - song.fillEmptyFields(); - songItem = new MusicLibraryItemSong(song, albumItem); - albumItem->append(songItem); - albumItem->addGenre(song.genre); - artistItem->addGenre(song.genre); - addGenre(song.genre); + // Fix cache error - where MusicLibraryItemSong::data() was saved as name instead of song.name!!!! + if (!song.albumartist.isEmpty() && !song.artist.isEmpty() && song.albumartist!=song.artist && + song.title.startsWith(song.artist+QLatin1String(" - "))) { + song.title=song.title.mid(song.artist.length()+3); + } + + QString str=attributes.value("track").toString(); + song.track=str.isEmpty() ? 0 : str.toUInt(); + str=attributes.value("disc").toString(); + song.disc=str.isEmpty() ? 0 : str.toUInt(); + str=attributes.value("time").toString(); + song.time=str.isEmpty() ? 0 : str.toUInt(); + // str=attributes.value("id").toString(); + // song.id=str.isEmpty() ? 0 : str.toUInt(); + + if (albumItem->isSingleTracks()) { + str=attributes.value("album").toString(); + if (!str.isEmpty()) { + song.album=str; + } + } else if (albumItem->isMultipleArtists()) { + str=attributes.value("artist").toString(); + if (!str.isEmpty()) { + song.artist=str; + } + } + + song.fillEmptyFields(); + songItem = new MusicLibraryItemSong(song, albumItem); + albumItem->append(songItem); + albumItem->addGenre(song.genre); + artistItem->addGenre(song.genre); + addGenre(song.genre); + } } } } diff --git a/models/musiclibrarymodel.cpp b/models/musiclibrarymodel.cpp index 95ddd3516..9a5e31a9f 100644 --- a/models/musiclibrarymodel.cpp +++ b/models/musiclibrarymodel.cpp @@ -39,6 +39,7 @@ #include "mpdconnection.h" #include "network.h" #include "localize.h" +#include "utils.h" #include #include #include @@ -212,12 +213,15 @@ QVariant MusicLibraryModel::data(const QModelIndex &index, int role) const } else { return static_cast(item)->cover(); } - case MusicLibraryItem::Type_Song: return QIcon::fromTheme("audio-x-generic"); + case MusicLibraryItem::Type_Song: return QIcon::fromTheme(Song::Playlist==static_cast(item)->song().type ? "view-media-playlist" : "audio-x-generic"); default: return QVariant(); } case Qt::DisplayRole: if (MusicLibraryItem::Type_Song==item->itemType()) { MusicLibraryItemSong *song = static_cast(item); + if (Song::Playlist==song->song().type) { + return song->song().title; + } if (static_cast(song->parentItem())->isSingleTracks()) { return song->song().artistSong(); } else { @@ -256,8 +260,10 @@ QVariant MusicLibraryModel::data(const QModelIndex &index, int role) const ); case MusicLibraryItem::Type_Song: { return item->parentItem()->parentItem()->data()+QLatin1String("
")+item->parentItem()->data()+QLatin1String("
")+ - data(index, Qt::DisplayRole).toString()+QLatin1String("
")+Song::formattedTime(static_cast(item)->time())+ - QLatin1String("
")+static_cast(item)->song().file+QLatin1String(""); + data(index, Qt::DisplayRole).toString()+QLatin1String("
")+ + (Song::Playlist==static_cast(item)->song().type + ? QString() : Song::formattedTime(static_cast(item)->time())+QLatin1String("
"))+ + QLatin1String("")+static_cast(item)->song().file+QLatin1String(""); } default: return QVariant(); } @@ -641,9 +647,9 @@ Qt::ItemFlags MusicLibraryModel::flags(const QModelIndex &index) const } } -QStringList MusicLibraryModel::filenames(const QModelIndexList &indexes) const +QStringList MusicLibraryModel::filenames(const QModelIndexList &indexes, bool allowPlaylists) const { - QList songList=songs(indexes); + QList songList=songs(indexes, allowPlaylists); QStringList fnames; foreach (const Song &s, songList) { fnames.append(s.file); @@ -651,7 +657,17 @@ QStringList MusicLibraryModel::filenames(const QModelIndexList &indexes) const return fnames; } -QList MusicLibraryModel::songs(const QModelIndexList &indexes) const +static inline void addSong(const MusicLibraryItem *song, QList &songs, bool allowPlaylists) +{ + if (MusicLibraryItem::Type_Song==song->itemType() && + (allowPlaylists || Song::Playlist!=static_cast(song)->song().type) && + !songs.contains(static_cast(song)->song())) { + static_cast(song)->song().updateSize(MPDConnection::self()->getDetails().dir); + songs << static_cast(song)->song(); + } +} + +QList MusicLibraryModel::songs(const QModelIndexList &indexes, bool allowPlaylists) const { QList songs; @@ -662,26 +678,17 @@ QList MusicLibraryModel::songs(const QModelIndexList &indexes) const case MusicLibraryItem::Type_Artist: foreach (const MusicLibraryItem *album, static_cast(item)->childItems()) { foreach (const MusicLibraryItem *song, static_cast(album)->childItems()) { - if (MusicLibraryItem::Type_Song==song->itemType() && !songs.contains(static_cast(song)->song())) { - static_cast(song)->song().updateSize(MPDConnection::self()->getDetails().dir); - songs << static_cast(song)->song(); - } + addSong(song, songs, false); } } break; case MusicLibraryItem::Type_Album: foreach (const MusicLibraryItem *song, static_cast(item)->childItems()) { - if (MusicLibraryItem::Type_Song==song->itemType() && !songs.contains(static_cast(song)->song())) { - static_cast(song)->song().updateSize(MPDConnection::self()->getDetails().dir); - songs << static_cast(song)->song(); - } + addSong(song, songs, false); } break; case MusicLibraryItem::Type_Song: - if (!songs.contains(static_cast(item)->song())) { - static_cast(item)->song().updateSize(MPDConnection::self()->getDetails().dir); - songs << static_cast(item)->song(); - } + addSong(item, songs, allowPlaylists); break; default: break; @@ -720,7 +727,7 @@ QList MusicLibraryModel::songs(const QStringList &filenames) const QMimeData *MusicLibraryModel::mimeData(const QModelIndexList &indexes) const { QMimeData *mimeData = new QMimeData(); - QStringList files=filenames(indexes); + QStringList files=filenames(indexes, true); PlayQueueModel::encode(*mimeData, PlayQueueModel::constFileNameMimeType, files); if (!MPDConnection::self()->getDetails().dir.isEmpty()) { QStringList paths; diff --git a/models/musiclibrarymodel.h b/models/musiclibrarymodel.h index 7658b2e57..a551e517b 100644 --- a/models/musiclibrarymodel.h +++ b/models/musiclibrarymodel.h @@ -53,8 +53,8 @@ public: int columnCount(const QModelIndex &) const; QVariant data(const QModelIndex &, int) const; Qt::ItemFlags flags(const QModelIndex &index) const; - QStringList filenames(const QModelIndexList &indexes) const; - QList songs(const QModelIndexList &indexes) const; + QStringList filenames(const QModelIndexList &indexes, bool allowPlaylists=false) const; + QList songs(const QModelIndexList &indexes, bool allowPlaylists=false) const; QList songs(const QStringList &filenames) const; QMimeData *mimeData(const QModelIndexList &indexes) const; const MusicLibraryItemRoot * root() const { return rootItem; } diff --git a/models/musiclibraryproxymodel.cpp b/models/musiclibraryproxymodel.cpp index 23c3af921..698693dee 100644 --- a/models/musiclibraryproxymodel.cpp +++ b/models/musiclibraryproxymodel.cpp @@ -126,6 +126,9 @@ bool MusicLibraryProxyModel::lessThan(const QModelIndex &left, const QModelIndex return compare<0; } } + if (leftItem->song().type != rightItem->song().type) { + return leftItem->song().type < rightItem->song().type; + } if (leftItem->disc() != rightItem->disc()) { return leftItem->disc() < rightItem->disc(); } diff --git a/mpd/mpdconnection.cpp b/mpd/mpdconnection.cpp index d032e88bd..12f443647 100644 --- a/mpd/mpdconnection.cpp +++ b/mpd/mpdconnection.cpp @@ -417,10 +417,12 @@ void MPDConnection::add(const QStringList &files, bool replace) } QByteArray send = "command_list_begin\n"; + bool addedFile=false; for (int i = 0; i < files.size(); i++) { if (isPlaylist(files.at(i))) { send+="load "; } else { + addedFile=true; send += "add "; } send += encodeName(files.at(i)); @@ -429,7 +431,7 @@ void MPDConnection::add(const QStringList &files, bool replace) send += "command_list_end"; if (sendCommand(send).ok) { - if (replace && !files.isEmpty()) { + if (replace && addedFile && !files.isEmpty()) { startPlayingSong(); } emit added(files); diff --git a/mpd/mpdparseutils.cpp b/mpd/mpdparseutils.cpp index cd1b20e8b..1a5ecaec4 100644 --- a/mpd/mpdparseutils.cpp +++ b/mpd/mpdparseutils.cpp @@ -43,6 +43,7 @@ #include "output.h" #include "covers.h" #include "httpserver.h" +#include "utils.h" #include "debugtimer.h" QString MPDParseUtils::fixPath(const QString &f) @@ -227,10 +228,15 @@ Song MPDParseUtils::parseSong(const QByteArray &data) song.genre = value; } else if (element == QLatin1String("Name")) { song.name = value; + } else if (element == QLatin1String("playlist")) { + song.file = value; + song.file.replace("\"", "\\\""); + song.title=Utils::getFile(song.file); + song.type=Song::Playlist; } } - if (song.genre.isEmpty()) { + if (Song::Playlist!=song.type && song.genre.isEmpty()) { song.genre = i18n("Unknown"); } @@ -366,14 +372,22 @@ MusicLibraryItemRoot * MPDParseUtils::parseLibraryItems(const QByteArray &data) int amountOfLines = lines.size(); MusicLibraryItemArtist *artistItem = 0; MusicLibraryItemAlbum *albumItem = 0; + MusicLibraryItemSong *songItem = 0; for (int i = 0; i < amountOfLines; i++) { currentItem += lines.at(i); currentItem += "\n"; - if (i == lines.size() - 1 || lines.at(i + 1).startsWith("file:")) { + if (i == lines.size() - 1 || lines.at(i + 1).startsWith("file:") || lines.at(i + 1).startsWith("playlist:")) { Song currentSong = parseSong(currentItem); currentItem.clear(); + if (Song::Playlist==currentSong.type) { + if (songItem && Utils::getDir(songItem->file())==Utils::getDir(currentSong.file)) { + songItem = new MusicLibraryItemSong(currentSong, albumItem); + albumItem->append(songItem); + } + continue; + } if (currentSong.isEmpty()) { continue; } @@ -386,7 +400,7 @@ MusicLibraryItemRoot * MPDParseUtils::parseLibraryItems(const QByteArray &data) albumItem = artistItem->album(currentSong); } - MusicLibraryItemSong *songItem = new MusicLibraryItemSong(currentSong, albumItem); + songItem = new MusicLibraryItemSong(currentSong, albumItem); albumItem->append(songItem); albumItem->addGenre(currentSong.genre); artistItem->addGenre(currentSong.genre); diff --git a/mpd/song.cpp b/mpd/song.cpp index fa8150b30..8826b8ed4 100644 --- a/mpd/song.cpp +++ b/mpd/song.cpp @@ -95,6 +95,9 @@ bool Song::operator<(const Song &o) const if (disc!=o.disc) { return disc