PageRenderTime 262ms CodeModel.GetById 103ms app.highlight 69ms RepoModel.GetById 69ms app.codeStats 0ms

/src/libtomahawk/widgets/RecentlyPlayedPlaylistsModel.cpp

http://github.com/tomahawk-player/tomahawk
C++ | 277 lines | 206 code | 48 blank | 23 comment | 34 complexity | 9f8de9621a8d94119e4f0521f9db565e MD5 | raw file
  1/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
  2 *
  3 *   Copyright 2011, Leo Franchi <lfranchi@kde.org>
  4 *   Copyright 2011, Jeff Mitchell <jeff@tomahawk-player.org>
  5 *   Copyright 2013, Christian Muehlhaeuser <muesli@tomahawk-player.org>
  6 *
  7 *   Tomahawk is free software: you can redistribute it and/or modify
  8 *   it under the terms of the GNU General Public License as published by
  9 *   the Free Software Foundation, either version 3 of the License, or
 10 *   (at your option) any later version.
 11 *
 12 *   Tomahawk is distributed in the hope that it will be useful,
 13 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 14 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 15 *   GNU General Public License for more details.
 16 *
 17 *   You should have received a copy of the GNU General Public License
 18 *   along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
 19 */
 20
 21#include "RecentlyPlayedPlaylistsModel.h"
 22
 23#include "audio/AudioEngine.h"
 24#include "collection/Collection.h"
 25#include "playlist/dynamic/DynamicPlaylist.h"
 26#include "utils/Logger.h"
 27
 28#include "Playlist.h"
 29#include "PlaylistEntry.h"
 30#include "PlaylistInterface.h"
 31#include "SourceList.h"
 32#include "TomahawkSettings.h"
 33#include "Track.h"
 34
 35using namespace Tomahawk;
 36
 37
 38RecentlyPlayedPlaylistsModel::RecentlyPlayedPlaylistsModel( QObject* parent )
 39    : QAbstractListModel( parent )
 40    , m_maxPlaylists( 0 )
 41    , m_waitingForSome( true )
 42{
 43    loadFromSettings();
 44
 45    connect( SourceList::instance(), SIGNAL( sourceAdded( Tomahawk::source_ptr ) ), this, SLOT( onSourceAdded( Tomahawk::source_ptr ) ), Qt::QueuedConnection );
 46    connect( TomahawkSettings::instance(), SIGNAL( recentlyPlayedPlaylistAdded( QString, int ) ), this, SLOT( plAdded( QString, int ) ) );
 47    connect( AudioEngine::instance(),SIGNAL( playlistChanged( Tomahawk::playlistinterface_ptr ) ), this, SLOT( playlistChanged( Tomahawk::playlistinterface_ptr ) ), Qt::QueuedConnection );
 48
 49    emit emptinessChanged( m_recplaylists.isEmpty() );
 50}
 51
 52
 53void
 54RecentlyPlayedPlaylistsModel::loadFromSettings()
 55{
 56//    qDebug() << Q_FUNC_INFO;
 57    if ( !m_waitingForSome )
 58        return;
 59
 60    beginResetModel();
 61    m_recplaylists.clear();
 62    m_waitingForSome = false;
 63
 64    QStringList playlist_guids = TomahawkSettings::instance()->recentlyPlayedPlaylistGuids( m_maxPlaylists );
 65
 66    for( int i = playlist_guids.size() - 1; i >= 0; i-- )
 67    {
 68//        qDebug() << "loading playlist" << playlist_guids[i];
 69
 70        playlist_ptr pl = m_cached.value( playlist_guids[i], Tomahawk::playlist_ptr() );
 71        if ( !pl )
 72            pl = Tomahawk::Playlist::get( playlist_guids[i] );
 73        if ( !pl )
 74            pl = Tomahawk::DynamicPlaylist::get( playlist_guids[i] );
 75
 76        if ( pl )
 77        {
 78            m_recplaylists << pl;
 79
 80            if ( !m_cached.contains( playlist_guids[i] ) )
 81            {
 82                if ( pl.dynamicCast< DynamicPlaylist >().isNull() )
 83                    connect( pl.data(), SIGNAL(revisionLoaded(Tomahawk::PlaylistRevision)), this, SLOT(playlistRevisionLoaded()) );
 84                else
 85                    connect( pl.data(), SIGNAL(dynamicRevisionLoaded(Tomahawk::DynamicPlaylistRevision)), this, SLOT(playlistRevisionLoaded()) );
 86                m_cached[playlist_guids[i]] = pl;
 87            }
 88        } else
 89            m_waitingForSome = true;
 90    }
 91    endResetModel();
 92
 93    emit emptinessChanged( m_recplaylists.isEmpty() );
 94}
 95
 96
 97QVariant
 98RecentlyPlayedPlaylistsModel::data( const QModelIndex& index, int role ) const
 99{
100    if ( !index.isValid() || !hasIndex( index.row(), index.column(), index.parent() ) )
101        return QVariant();
102
103    playlist_ptr pl = m_recplaylists[index.row()];
104    switch( role )
105    {
106    case Qt::DisplayRole:
107        return pl->title();
108    case PlaylistRole:
109        return QVariant::fromValue< Tomahawk::playlist_ptr >( pl );
110    case ArtistRole:
111    {
112        if ( m_artists.value( pl ).isEmpty() )
113        {
114            QStringList artists;
115
116            foreach ( const Tomahawk::plentry_ptr& entry, pl->entries() )
117            {
118                if ( !artists.contains( entry->query()->track()->artist() ) )
119                    artists << entry->query()->track()->artist();
120            }
121
122            m_artists[pl] = artists.join( ", " );
123        }
124
125        return m_artists[pl];
126    }
127    case PlaylistTypeRole:
128    {
129        if ( !pl.dynamicCast< Tomahawk::DynamicPlaylist >().isNull() )
130        {
131            dynplaylist_ptr dynp = pl.dynamicCast< Tomahawk::DynamicPlaylist >();
132            if ( dynp->mode() == Static )
133                return AutoPlaylist;
134            else if ( dynp->mode() == OnDemand )
135                return Station;
136        } else
137        {
138            return StaticPlaylist;
139        }
140    }
141    case DynamicPlaylistRole:
142    {
143        dynplaylist_ptr dynp = pl.dynamicCast< Tomahawk::DynamicPlaylist >();
144        return QVariant::fromValue< Tomahawk::dynplaylist_ptr >( dynp );
145    }
146    case TrackCountRole:
147    {
148        if ( !pl.dynamicCast< Tomahawk::DynamicPlaylist >().isNull() && pl.dynamicCast< Tomahawk::DynamicPlaylist >()->mode() == OnDemand )
149            return QString( QChar( 0x221E ) );
150        else
151            return pl->entries().count();
152    }
153    default:
154        return QVariant();
155    }
156}
157
158
159void
160RecentlyPlayedPlaylistsModel::playlistRevisionLoaded()
161{
162    Playlist* p = qobject_cast< Playlist* >( sender() );
163    Q_ASSERT( p );
164
165    for ( int i = 0; i < m_recplaylists.size(); i++ )
166    {
167        if ( m_recplaylists[ i ]->guid() == p->guid() )
168        {
169            QModelIndex idx = index( i, 0, QModelIndex() );
170            emit dataChanged( idx, idx );
171        }
172    }
173}
174
175
176void
177RecentlyPlayedPlaylistsModel::onSourceAdded( const Tomahawk::source_ptr& source )
178{
179    connect( source.data(), SIGNAL( online() ),
180                              SLOT( sourceOnline() ) );
181
182    connect( source->dbCollection().data(), SIGNAL( playlistsAdded( QList<Tomahawk::playlist_ptr> ) ),
183                                              SLOT( loadFromSettings() ) );
184    connect( source->dbCollection().data(), SIGNAL( playlistsDeleted( QList<Tomahawk::playlist_ptr> ) ),
185                                              SLOT( onPlaylistsRemoved( QList<Tomahawk::playlist_ptr> ) ) );
186}
187
188
189void
190RecentlyPlayedPlaylistsModel::sourceOnline()
191{
192    Source* s = qobject_cast< Source* >( sender() );
193    Q_ASSERT( s );
194
195    for ( int i = 0; i < m_recplaylists.size(); i++ )
196    {
197        if ( m_recplaylists[ i ]->author().data() == s )
198        {
199            QModelIndex idx = index( i, 0, QModelIndex() );
200            emit dataChanged( idx, idx );
201        }
202    }
203}
204
205
206void
207RecentlyPlayedPlaylistsModel::onPlaylistsRemoved( QList< playlist_ptr > playlists )
208{
209    foreach ( const playlist_ptr& pl, playlists )
210    {
211        if ( m_recplaylists.contains( pl ) )
212        {
213            m_artists.remove( pl );
214            m_cached.remove( pl->guid() );
215
216            int idx = m_recplaylists.indexOf( pl );
217            beginRemoveRows( QModelIndex(), idx, idx );
218            m_recplaylists.removeAt( idx );
219            endRemoveRows();
220        }
221    }
222
223    emit emptinessChanged( m_recplaylists.isEmpty() );
224}
225
226
227int
228RecentlyPlayedPlaylistsModel::rowCount( const QModelIndex& ) const
229{
230    return m_recplaylists.count();
231}
232
233
234void
235RecentlyPlayedPlaylistsModel::plAdded( const QString& plguid, int sourceId )
236{
237    Q_UNUSED( sourceId );
238    const playlist_ptr& pl = Playlist::get( plguid );
239    if ( !pl )
240        return;
241
242    onPlaylistsRemoved( QList< playlist_ptr >() << pl );
243
244    beginInsertRows( QModelIndex(), 0, 0 );
245    m_recplaylists.prepend( pl );;
246    endInsertRows();
247
248    emit emptinessChanged( m_recplaylists.isEmpty() );
249}
250
251
252void
253RecentlyPlayedPlaylistsModel::playlistChanged( Tomahawk::playlistinterface_ptr pli )
254{
255    // ARG
256    if ( !pli )
257        return;
258
259    if ( Playlist *pl = dynamic_cast< Playlist* >( pli.data() ) )
260    {
261        // look for it, qsharedpointer fail
262        playlist_ptr ptr;
263        foreach ( const playlist_ptr& test, m_recplaylists )
264        {
265            if ( test.data() == pl )
266                ptr = test;
267        }
268
269        if ( ptr && m_artists.contains( ptr ) )
270        {
271            m_artists[ ptr ] = QString();
272        }
273
274        QModelIndex idx = index( m_recplaylists.indexOf( ptr ), 0, QModelIndex() );
275        emit dataChanged( idx, idx );
276    }
277}