123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278 |
- #include <QtCore/qfileinfo.h>
- #include <QtCore/qurl.h>
- #include <QDateTime>
- #include <QDebug>
- #include <QMap>
- #include <QMessageBox>
- #include <QMultiMap>
- #include <qmediaplaylist.h>
- #include "playlistmodel.h"
- #include "abstractmetadataloader.h"
- #include "urlutils.h"
- #include "mainwindow.h"
- using namespace Abstract;
- PlaylistModel::PlaylistModel(QObject *parent)
- : QAbstractListModel(parent)
- , m_playlist(0)
- {
- m_isFetched = false;
- QHash<int, QByteArray> roles;
- roles[NameRole] = "name";
- roles[PictureRole] = "picture";
- roles[UrlRole] = "url";
- roles[ArtistRole] = "artist";
- roles[LastModifiedRole] = "lastModified";
- roles[GenreRole] = "genre";
- roles[AlbumRole] = "album";
- roles[TrackNumberRole] = "trackNr";
- roles[CommentRole] = "comment";
- roles[DurationRole] = "duration";
- // m_isSorted = false;
- setRoleNames(roles);
- connect (MetaDataLoader::instance(), SIGNAL(fetched(MetaDataValue)),
- this, SLOT(fetched(MetaDataValue)), Qt::UniqueConnection);
- }
- int PlaylistModel::rowCount(const QModelIndex &) const
- {
- return m_playlist ? m_playlist->mediaCount() : 0;
- }
- QVariant PlaylistModel::data(const QModelIndex &index, int role) const
- {
- if (!index.isValid()) return QVariant();
- if ((index.row() < 0) || (index.row() >= rowCount())) return QVariant();
- QMediaContent mc = m_playlist->media(index.row());
- QUrl location = mc.canonicalUrl();
- MetaDataValue mdv;
- if (m_values.contains(location) )
- mdv = m_values[location];
- else {
- mdv.setUrl(location);
- QString path = UrlUtils::toLocalFile(location);
- QFileInfo finfo(path);
- mdv.setTrackTitle(UrlUtils::baseName(finfo));
- }
- if ((role == Qt::DisplayRole) || (role == NameRole)) {
- if (mdv.artist().isEmpty())
- return mdv.trackTitle();
- else return QString("%2 - %1").arg(mdv.artist()).arg(mdv.trackTitle());
- }
- if (role == TrackNumberRole) {
- return mdv.trackNumber();
- }
- if (role == DurationRole) {
- return mdv.trackTime();
- }
- if (role == GenreRole) {
- return mdv.genre();
- }
- if (role == ArtistRole) {
- return mdv.artist();
- }
- if (role == CommentRole) {
- return mdv.comment();
- }
- if (role == AlbumRole) {
- return mdv.albumTitle();
- }
- if (role == LastModifiedRole) {
- return mdv.lastModified();
- }
- if ((role == Qt::ToolTipRole) || (role == UrlRole) || (role == Qt::StatusTipRole)) {
- return mdv.url();
- }
- // TODO - handle decoration role
- return QVariant();
- }
- QMediaPlaylist *PlaylistModel::playlist() const
- {
- return m_playlist;
- }
- void PlaylistModel::setPlaylist(QMediaPlaylist *playlist)
- {
- if (m_playlist) {
- disconnect(m_playlist, SIGNAL(mediaAboutToBeInserted(int,int)), this, SLOT(beginInsertItems(int,int)));
- disconnect(m_playlist, SIGNAL(mediaInserted(int,int)), this, SLOT(endInsertItems()));
- disconnect(m_playlist, SIGNAL(mediaAboutToBeRemoved(int,int)), this, SLOT(beginRemoveItems(int,int)));
- disconnect(m_playlist, SIGNAL(mediaRemoved(int,int)), this, SLOT(endRemoveItems()));
- disconnect(m_playlist, SIGNAL(mediaChanged(int,int)), this, SLOT(changeItems(int,int)));
- }
- m_playlist = playlist;
- if (m_playlist) {
- connect(m_playlist, SIGNAL(mediaAboutToBeInserted(int,int)), this, SLOT(beginInsertItems(int,int)));
- connect(m_playlist, SIGNAL(mediaInserted(int,int)), this, SLOT(endInsertItems()));
- connect(m_playlist, SIGNAL(mediaAboutToBeRemoved(int,int)), this, SLOT(beginRemoveItems(int,int)));
- connect(m_playlist, SIGNAL(mediaRemoved(int,int)), this, SLOT(endRemoveItems()));
- connect(m_playlist, SIGNAL(mediaChanged(int,int)), this, SLOT(changeItems(int,int)));
- }
- reset();
- }
- void PlaylistModel::beginInsertItems(int start, int end) {
- m_indexes.clear();
- beginInsertRows(QModelIndex(), start, end);
- }
- void PlaylistModel::endInsertItems() {
- endInsertRows();
- }
- void PlaylistModel::beginRemoveItems(int start, int end) {
- m_indexes.clear();
- beginRemoveRows(QModelIndex(), start, end);
- }
- void PlaylistModel::endRemoveItems() {
- endInsertRows();
- }
- void PlaylistModel::changeItems(int start, int end) {
- m_indexes.clear();
- emit dataChanged(index(start,0), index(end,1));
- }
- int PlaylistModel::findRow(QUrl key) {
- if (m_indexes.contains(key)) return m_indexes[key];
- int retval = -1;
- for (int r=0; r<rowCount(); ++r) {
- QUrl u = data(index(r,0), UrlRole).toString();
- m_indexes[u] = r;
- if (u == key) retval = r;
- }
- return retval;
- }
- void PlaylistModel::shuffle() {
- m_playlist->shuffle();
- reset();
- }
- void PlaylistModel::fetched(MetaDataValue mdv) {
- m_values[mdv.url()]=mdv;
- // qDebug() << "fetched: " << mdv.url();
- int r = findRow(mdv.url());
- if (r != -1) {
- QModelIndex tl = index(r,0, QModelIndex());
- emit dataChanged(tl, tl);
- }
- }
- void PlaylistModel::clear() {
- m_playlist->clear();
- m_isFetched=false;
- reset();
- }
- void PlaylistModel::sortByRole(PlayListRoles role) {
- if (!m_isFetched) {
- fetchAll();
- return;
- }
- m_indexes.clear();
- if (role == LastModifiedRole) {
- QMultiMap<QDateTime, QUrl> mapping;
- for (int i=0; i<rowCount(); ++i) {
- QUrl url = m_playlist->media(i).canonicalUrl();
- MetaDataValue mdv = m_values[url];
- mapping.insert(mdv.lastModified(), url);
- }
- m_playlist->clear();
- QMultiMap<QDateTime, QUrl>::const_iterator itr = mapping.constEnd();
- while (itr != mapping.constBegin()) {
- --itr;
- QUrl url = itr.value();
- m_playlist->addMedia(QMediaContent(url));
- }
- reset();
- return;
- }
- QMultiMap<QString, QUrl> mapping;
- QRegExp rx("(\\d+).*");
- for (int i=0; i<rowCount(); ++i) {
- QUrl url = m_playlist->media(i).canonicalUrl();
- MetaDataValue mdv = m_values[url];
- QString key = mdv.trackTitle();
- if (role == AlbumRole) {
- QString tn = mdv.trackNumber();
- if (rx.exactMatch(tn))
- tn = rx.cap();
- int trackNumber = tn.toInt();
- if (trackNumber > 0)
- key = QString("%1-%2").arg(mdv.albumTitle()).arg(trackNumber, 4, QChar('0'));
- else key = QString("%1-%2").arg(mdv.albumTitle()).arg(mdv.trackTitle());
- }
- else if (role == ArtistRole) {
- key = QString("%1-%2").arg(mdv.artist()).arg(mdv.trackTitle());
- }
- else if (role == NameRole) {
- key = mdv.trackTitle();
- }
- mapping.insert(key, url);
- }
- m_playlist->clear();
- QMultiMap<QString, QUrl>::const_iterator itr = mapping.constBegin();
- while (itr != mapping.constEnd()) {
- QUrl url = itr.value();
- m_playlist->addMedia(QMediaContent(url));
- itr++;
- }
- reset();
- }
- void PlaylistModel::setFetched(bool f) {
- m_isFetched = f;
- if (f == true)
- MetaDataLoader::instance()->disconnect(this, SLOT(setFetched()));
- }
- void PlaylistModel::deleteTrack(int i) {
- beginRemoveItems(i, i);
- QMediaContent mc = m_playlist->media(i);
- QString fileName = UrlUtils::toLocalFile(mc.canonicalUrl());
- int response = QMessageBox::question(MainWindow::instance(),
- tr("Delete File"), tr("delete ") + fileName, QMessageBox::No, QMessageBox::Yes);
- if (response == QMessageBox::Yes) {
- m_playlist->removeMedia(i, i);
- QFile f(fileName);
- f.remove();
- }
- endRemoveItems();
- reset();
- }
- void PlaylistModel::fetchAll() {
- MetaDataLoader *mdl = MetaDataLoader::instance();
- connect (mdl, SIGNAL(finished()), this, SLOT(setFetched()));
- int r = rowCount();
- int c = 0;
- for (int i=0; i<r; ++i) {
- QMediaContent mc = m_playlist->media(i);
- QUrl url = mc.canonicalUrl();
- if (m_values.contains(url)) continue;
- mdl->get(url);
- c++;
- }
- if (c == 0) m_isFetched = true;
- }
- void PlaylistModel::fetch(int i) {
- MetaDataLoader *mdl = MetaDataLoader::instance();
- QMediaContent mc = m_playlist->media(i);
- mdl->get(mc.canonicalUrl());
- }
|