/* * Cantata * * Copyright (c) 2011-2015 Craig Drummond * * ---- * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "musiclibraryitemalbum.h" #include "musiclibraryitemartist.h" #include "musiclibraryitemsong.h" #include "musiclibraryitemroot.h" #include "multimusicmodel.h" #include MultiMusicModel::MultiMusicModel(QObject *parent) : MusicModel(parent) { } MultiMusicModel::~MultiMusicModel() { qDeleteAll(collections); } QModelIndex MultiMusicModel::index(int row, int column, const QModelIndex &parent) const { if (!hasIndex(row, column, parent)) { return QModelIndex(); } if (parent.isValid()) { MusicLibraryItem *p=static_cast(parent.internalPointer()); if (p) { return rowchildCount() ? createIndex(row, column, p->childItem(row)) : QModelIndex(); } } else { return row(index.internalPointer()); MusicLibraryItem *parentItem = childItem->parentItem(); if (parentItem) { return createIndex(parentItem->parentItem() ? parentItem->row() : row(parentItem), 0, parentItem); } else { return QModelIndex(); } } int MultiMusicModel::rowCount(const QModelIndex &parent) const { if (parent.column() > 0) { return 0; } return parent.isValid() ? static_cast(parent.internalPointer())->childCount() : collections.count(); } void MultiMusicModel::getDetails(QSet &artists, QSet &albumArtists, QSet &composers, QSet &albums, QSet &genres) { foreach (MusicLibraryItemRoot *col, collections) { col->getDetails(artists, albumArtists, composers, albums, genres); } } int MultiMusicModel::indexOf(const QString &id) { int i=0; foreach (MusicLibraryItemRoot *col, collections) { if (col->id()==id) { return i; } i++; } return -1; } QList MultiMusicModel::songs(const QModelIndexList &indexes, bool playableOnly, bool fullPath) const { QMap > colSongs; QMap > colFiles; foreach(QModelIndex index, indexes) { MusicLibraryItem *item = static_cast(index.internalPointer()); MusicLibraryItem *p=item; while (p->parentItem()) { p=p->parentItem(); } if (!p) { continue; } MusicLibraryItemRoot *parent=static_cast(p); if (playableOnly && !parent->canPlaySongs()) { continue; } switch (item->itemType()) { case MusicLibraryItem::Type_Root: { if (static_cast(parent)->flat()) { foreach (const MusicLibraryItem *song, static_cast(item)->childItems()) { if (MusicLibraryItem::Type_Song==song->itemType() && !colFiles[parent].contains(static_cast(song)->file())) { colSongs[parent] << parent->fixPath(static_cast(song)->song(), fullPath); colFiles[parent] << static_cast(song)->file(); } } } else { // First, sort all artists as they would appear in UI... QList artists=static_cast(item)->childItems(); if (artists.isEmpty()) { break; } qSort(artists.begin(), artists.end(), MusicLibraryItemArtist::lessThan); foreach (MusicLibraryItem *a, artists) { const MusicLibraryItemContainer *artist=static_cast(a); // Now sort all albums as they would appear in UI... QList artistAlbums=artist->childItems(); qSort(artistAlbums.begin(), artistAlbums.end(), MusicLibraryItemAlbum::lessThan); foreach (MusicLibraryItem *i, artistAlbums) { const MusicLibraryItemContainer *album=static_cast(i); foreach (const MusicLibraryItem *song, album->childItems()) { if (MusicLibraryItem::Type_Song==song->itemType() && !colFiles[parent].contains(static_cast(song)->file())) { colSongs[parent] << parent->fixPath(static_cast(song)->song(), fullPath); colFiles[parent] << static_cast(song)->file(); } } } } } break; } case MusicLibraryItem::Type_Artist: { // First, sort all albums as they would appear in UI... QList artistAlbums=static_cast(item)->childItems(); qSort(artistAlbums.begin(), artistAlbums.end(), MusicLibraryItemAlbum::lessThan); foreach (MusicLibraryItem *i, artistAlbums) { const MusicLibraryItemContainer *album=static_cast(i); foreach (const MusicLibraryItem *song, album->childItems()) { if (MusicLibraryItem::Type_Song==song->itemType() && !colFiles[parent].contains(static_cast(song)->file())) { colSongs[parent] << parent->fixPath(static_cast(song)->song(), fullPath); colFiles[parent] << static_cast(song)->file(); } } } break; } case MusicLibraryItem::Type_Album: foreach (const MusicLibraryItem *song, static_cast(item)->childItems()) { if (MusicLibraryItem::Type_Song==song->itemType() && !colFiles[parent].contains(static_cast(song)->file())) { colSongs[parent] << parent->fixPath(static_cast(song)->song(), fullPath); colFiles[parent] << static_cast(song)->file(); } } break; case MusicLibraryItem::Type_Song: if (!colFiles[parent].contains(static_cast(item)->file())) { colSongs[parent] << parent->fixPath(static_cast(item)->song(), fullPath); colFiles[parent] << static_cast(item)->file(); } break; default: break; } } QList songs; QMap >::Iterator it(colSongs.begin()); QMap >::Iterator end(colSongs.end()); for (; it!=end; ++it) { songs.append(it.value()); } return songs; } QStringList MultiMusicModel::filenames(const QModelIndexList &indexes, bool playableOnly, bool fullPath) const { QList songList=songs(indexes, playableOnly, fullPath); QStringList fnames; foreach (const Song &s, songList) { fnames.append(s.file); } return fnames; }