diff --git a/src/libtomahawk/dropjob.h b/src/libtomahawk/dropjob.h index 369899e11..492267740 100644 --- a/src/libtomahawk/dropjob.h +++ b/src/libtomahawk/dropjob.h @@ -108,6 +108,7 @@ public: static bool canParseSpotifyPlaylists() { return s_canParseSpotifyPlaylists; } static void setCanParseSpotifyPlaylists( bool parseable ) { s_canParseSpotifyPlaylists = parseable; } + signals: /// QMimeData parsing results void tracks( const QList< Tomahawk::query_ptr >& tracks ); diff --git a/src/libtomahawk/playlist.cpp b/src/libtomahawk/playlist.cpp index a2193aff6..c813514a8 100644 --- a/src/libtomahawk/playlist.cpp +++ b/src/libtomahawk/playlist.cpp @@ -293,7 +293,7 @@ Playlist::loadRevision( const QString& rev ) void Playlist::createNewRevision( const QString& newrev, const QString& oldrev, const QList< plentry_ptr >& entries ) { - qDebug() << Q_FUNC_INFO << newrev << oldrev << entries.count(); + tDebug() << Q_FUNC_INFO << newrev << oldrev << entries.count(); if ( busy() ) { @@ -387,34 +387,32 @@ Playlist::setNewRevision( const QString& rev, bool is_newest_rev, const QMap< QString, Tomahawk::plentry_ptr >& addedmap ) { -// qDebug() << Q_FUNC_INFO << rev << is_newest_rev << m_title << addedmap.count() << neworderedguids.count() << oldorderedguids.count(); - // build up correctly ordered new list of plentry_ptrs from // existing ones, and the ones that have been added QMap entriesmap; - foreach( const plentry_ptr& p, m_entries ) + foreach ( const plentry_ptr& p, m_entries ) entriesmap.insert( p->guid(), p ); QList entries; - foreach( const QString& id, neworderedguids ) + foreach ( const QString& id, neworderedguids ) { - if( entriesmap.contains( id ) ) + if ( entriesmap.contains( id ) ) { entries.append( entriesmap.value( id ) ); } - else if( addedmap.contains( id ) ) + else if ( addedmap.contains( id ) ) { entries.append( addedmap.value( id ) ); - if( is_newest_rev ) + if ( is_newest_rev ) m_entries.append( addedmap.value( id ) ); } else { - /* qDebug() << "id:" << id; - * qDebug() << "newordered:" << neworderedguids.count() << neworderedguids; - * qDebug() << "entriesmap:" << entriesmap.count() << entriesmap; - * qDebug() << "addedmap:" << addedmap.count() << addedmap; - * qDebug() << "m_entries" << m_entries; */ + tDebug() << "id:" << id; + tDebug() << "newordered:" << neworderedguids.count() << neworderedguids; + tDebug() << "entriesmap:" << entriesmap.count() << entriesmap; + tDebug() << "addedmap:" << addedmap.count() << addedmap; + tDebug() << "m_entries" << m_entries; tLog() << "Playlist error for playlist with guid" << guid() << "from source" << author()->friendlyName(); Q_ASSERT( false ); // XXX @@ -428,19 +426,19 @@ Playlist::setNewRevision( const QString& rev, // entries that have been removed: QSet removedguids = oldorderedguids.toSet().subtract( neworderedguids.toSet() ); //qDebug() << "Removedguids:" << removedguids << "oldorederedguids" << oldorderedguids << "newog" << neworderedguids; - foreach( QString remid, removedguids ) + foreach ( QString remid, removedguids ) { // NB: entriesmap will contain old/removed entries only if the removal was done // in the same session - after a restart, history is not in memory. - if( entriesmap.contains( remid ) ) + if ( entriesmap.contains( remid ) ) { pr.removed << entriesmap.value( remid ); - if( is_newest_rev ) + if ( is_newest_rev ) { //qDebug() << "Removing from m_entries" << remid; - for( int k = 0 ; k < m_entries.length(); ++k ) + for ( int k = 0 ; k < m_entries.length(); ++k ) { - if( m_entries.at( k )->guid() == remid ) + if ( m_entries.at( k )->guid() == remid ) { //qDebug() << "removed at" << k; m_entries.removeAt( k ); @@ -452,8 +450,8 @@ Playlist::setNewRevision( const QString& rev, } pr.added = addedmap.values(); - pr.newlist = entries; + return pr; } diff --git a/src/libtomahawk/playlist/collectionflatmodel.cpp b/src/libtomahawk/playlist/collectionflatmodel.cpp index 9759ed1f8..7d94ba023 100644 --- a/src/libtomahawk/playlist/collectionflatmodel.cpp +++ b/src/libtomahawk/playlist/collectionflatmodel.cpp @@ -18,9 +18,6 @@ #include "collectionflatmodel.h" -#include -#include - #include "database/database.h" #include "sourcelist.h" #include "utils/logger.h" @@ -31,9 +28,6 @@ using namespace Tomahawk; CollectionFlatModel::CollectionFlatModel( QObject* parent ) : TrackModel( parent ) { - qDebug() << Q_FUNC_INFO; - - connect( SourceList::instance(), SIGNAL( sourceRemoved( Tomahawk::source_ptr ) ), SLOT( onSourceOffline( Tomahawk::source_ptr ) ) ); } @@ -45,7 +39,6 @@ CollectionFlatModel::~CollectionFlatModel() void CollectionFlatModel::addCollections( const QList< collection_ptr >& collections ) { - qDebug() << Q_FUNC_INFO << "Adding collections!"; foreach( const collection_ptr& col, collections ) { addCollection( col ); @@ -64,12 +57,7 @@ CollectionFlatModel::addCollection( const collection_ptr& collection, bool sendN << collection->source()->id() << collection->source()->userName(); - connect( collection.data(), SIGNAL( tracksAdded( QList ) ), - SLOT( onTracksAdded( QList ) ) ); - connect( collection.data(), SIGNAL( tracksRemoved( QList ) ), - SLOT( onTracksRemoved( QList ) ) ); - - if( sendNotifications ) + if ( sendNotifications ) emit loadingStarted(); DatabaseCommand_AllTracks* cmd = new DatabaseCommand_AllTracks( collection ); @@ -107,143 +95,32 @@ CollectionFlatModel::addFilteredCollection( const collection_ptr& collection, un } -void -CollectionFlatModel::removeCollection( const collection_ptr& collection ) -{ - return; // FIXME - - disconnect( collection.data(), SIGNAL( tracksAdded( QList ) ), - this, SLOT( onTracksAdded( QList ) ) ); - - QTime timer; - timer.start(); - -// QList plitems = m_collectionIndex.values( collection ); - QList< QPair< int, int > > rows; - QList< QPair< int, int > > sortrows; - QPair< int, int > row; - QPair< int, int > rowf; - rows = m_collectionRows.values( collection ); - - while ( rows.count() ) - { - int x = -1; - int j = 0; - foreach( row, rows ) - { - if ( x < 0 || row.first > rows.at( x ).first ) - x = j; - - j++; - } - - sortrows.append( rows.at( x ) ); - rows.removeAt( x ); - } - - foreach( row, sortrows ) - { - QMap< Tomahawk::collection_ptr, QPair< int, int > > newrows; - foreach ( const collection_ptr& col, m_collectionRows.uniqueKeys() ) - { - if ( col.data() == collection.data() ) - continue; - - foreach ( rowf, m_collectionRows.values( col ) ) - { - if ( rowf.first > row.first ) - { - rowf.first -= ( row.second - row.first ) + 1; - rowf.second -= ( row.second - row.first ) + 1; - } - newrows.insertMulti( col, rowf ); - } - } - m_collectionRows = newrows; - - qDebug() << "Removing rows:" << row.first << row.second; - emit beginRemoveRows( QModelIndex(), row.first, row.second ); - for ( int i = row.second; i >= row.first; i-- ) - { - TrackModelItem* item = itemFromIndex( index( i, 0, QModelIndex() ) ); - delete item; - } - emit endRemoveRows(); - } - - qDebug() << "Collection removed, time elapsed:" << timer.elapsed(); - -// emit trackCountChanged( rowCount( QModelIndex() ) ); -} - - void CollectionFlatModel::onTracksAdded( const QList& tracks ) { qDebug() << Q_FUNC_INFO << tracks.count() << rowCount( QModelIndex() ); - if( !m_loadingCollections.isEmpty() && sender() && qobject_cast< Collection* >( sender() ) ) + if ( !m_loadingCollections.isEmpty() && sender() && qobject_cast< Collection* >( sender() ) ) { // we are keeping track and are called as a slot m_loadingCollections.removeAll( qobject_cast< Collection* >( sender() ) ); } - bool kickOff = m_tracksToAdd.isEmpty(); - m_tracksToAdd << tracks; + append( tracks ); - emit trackCountChanged( trackCount() ); - - if ( m_tracksToAdd.count() && kickOff ) - processTracksToAdd(); - else if ( m_tracksToAdd.isEmpty() && m_loadingCollections.isEmpty() ) + if ( m_loadingCollections.isEmpty() ) emit loadingFinished(); } -void -CollectionFlatModel::processTracksToAdd() -{ - int chunkSize = 5000; - int maxc = qMin( chunkSize, m_tracksToAdd.count() ); - int c = rowCount( QModelIndex() ); - - emit beginInsertRows( QModelIndex(), c, c + maxc - 1 ); - //beginResetModel(); - - TrackModelItem* plitem; - QList< Tomahawk::query_ptr >::iterator iter = m_tracksToAdd.begin(); - - for( int i = 0; i < maxc; ++i ) - { - plitem = new TrackModelItem( *iter, m_rootItem ); - plitem->index = createIndex( m_rootItem->children.count() - 1, 0, plitem ); - - connect( plitem, SIGNAL( dataChanged() ), SLOT( onDataChanged() ) ); - - ++iter; - } - - m_tracksToAdd.erase( m_tracksToAdd.begin(), iter ); - - if ( m_tracksToAdd.isEmpty() && m_loadingCollections.isEmpty() ) - emit loadingFinished(); - - //endResetModel(); - emit endInsertRows(); - qDebug() << Q_FUNC_INFO << rowCount( QModelIndex() ); - - if ( m_tracksToAdd.count() ) - QTimer::singleShot( 250, this, SLOT( processTracksToAdd() ) ); -} - - void CollectionFlatModel::onTracksRemoved( const QList& tracks ) { QList t = tracks; for ( int i = rowCount( QModelIndex() ); i >= 0 && t.count(); i-- ) { - TrackModelItem* item = itemFromIndex( index( i, 0, QModelIndex() ) ); + QModelIndex idx = index( i, 0, QModelIndex() ); + TrackModelItem* item = itemFromIndex( idx ); if ( !item ) continue; @@ -252,11 +129,7 @@ CollectionFlatModel::onTracksRemoved( const QList& tracks ) { if ( item->query().data() == query.data() ) { - qDebug() << "Removing row:" << i << query->toString(); - emit beginRemoveRows( QModelIndex(), i, i ); - delete item; - emit endRemoveRows(); - + remove( idx ); t.removeAt( j ); break; } @@ -264,9 +137,6 @@ CollectionFlatModel::onTracksRemoved( const QList& tracks ) j++; } } - -// emit trackCountChanged( rowCount( QModelIndex() ) ); - qDebug() << Q_FUNC_INFO << rowCount( QModelIndex() ); } @@ -274,20 +144,7 @@ void CollectionFlatModel::onDataChanged() { TrackModelItem* p = (TrackModelItem*)sender(); -// emit itemSizeChanged( p->index ); if ( p ) emit dataChanged( p->index, p->index.sibling( p->index.row(), columnCount( QModelIndex() ) - 1 ) ); } - - -void -CollectionFlatModel::onSourceOffline( const Tomahawk::source_ptr& src ) -{ - qDebug() << Q_FUNC_INFO; - - if ( m_collectionRows.contains( src->collection() ) ) - { - removeCollection( src->collection() ); - } -} diff --git a/src/libtomahawk/playlist/collectionflatmodel.h b/src/libtomahawk/playlist/collectionflatmodel.h index 7a6e4e54f..0d2784b44 100644 --- a/src/libtomahawk/playlist/collectionflatmodel.h +++ b/src/libtomahawk/playlist/collectionflatmodel.h @@ -46,16 +46,9 @@ public: virtual int trackCount() const { return rowCount( QModelIndex() ) + m_tracksToAdd.count(); } void addCollections( const QList< Tomahawk::collection_ptr >& collections ); - void addCollection( const Tomahawk::collection_ptr& collection, bool sendNotifications = true ); - void removeCollection( const Tomahawk::collection_ptr& collection ); - void addFilteredCollection( const Tomahawk::collection_ptr& collection, unsigned int amount, DatabaseCommand_AllTracks::SortOrder order ); - virtual void append( const Tomahawk::query_ptr& /*query*/ ) {} - virtual void append( const Tomahawk::artist_ptr& /*artist*/ ) {} - virtual void append( const Tomahawk::album_ptr& /*album*/ ) {} - signals: void repeatModeChanged( Tomahawk::PlaylistInterface::RepeatMode mode ); void shuffleModeChanged( bool enabled ); @@ -70,10 +63,6 @@ private slots: void onTracksAdded( const QList& tracks ); void onTracksRemoved( const QList& tracks ); - void onSourceOffline( const Tomahawk::source_ptr& src ); - - void processTracksToAdd(); - private: QMap< Tomahawk::collection_ptr, QPair< int, int > > m_collectionRows; QList m_tracksToAdd; diff --git a/src/libtomahawk/playlist/dynamic/DynamicModel.cpp b/src/libtomahawk/playlist/dynamic/DynamicModel.cpp index c074b8f30..3146a6eb1 100644 --- a/src/libtomahawk/playlist/dynamic/DynamicModel.cpp +++ b/src/libtomahawk/playlist/dynamic/DynamicModel.cpp @@ -313,9 +313,9 @@ DynamicModel::removeIndex(const QModelIndex& idx, bool moreToCome) if( !moreToCome && idx == index( rowCount( QModelIndex() ) - 1, 0, QModelIndex() ) ) { // if the user is manually removing the last one, re-add as we're a station newTrackLoading(); } - TrackModel::removeIndex( idx ); + TrackModel::remove( idx ); } else - PlaylistModel::removeIndex( idx, moreToCome ); + PlaylistModel::remove( idx, moreToCome ); // don't call onPlaylistChanged. if( !moreToCome ) diff --git a/src/libtomahawk/playlist/dynamic/DynamicView.cpp b/src/libtomahawk/playlist/dynamic/DynamicView.cpp index 6fe7d0459..eda9a224b 100644 --- a/src/libtomahawk/playlist/dynamic/DynamicView.cpp +++ b/src/libtomahawk/playlist/dynamic/DynamicView.cpp @@ -264,7 +264,7 @@ DynamicView::collapseEntries( int startRow, int num, int numToKeep ) todel << proxyModel()->index( startRow + i, k ); } } - proxyModel()->removeIndexes( todel ); + proxyModel()->remove( todel ); } diff --git a/src/libtomahawk/playlist/playlistmodel.cpp b/src/libtomahawk/playlist/playlistmodel.cpp index 76829173e..f904cc423 100644 --- a/src/libtomahawk/playlist/playlistmodel.cpp +++ b/src/libtomahawk/playlist/playlistmodel.cpp @@ -39,9 +39,8 @@ using namespace Tomahawk; PlaylistModel::PlaylistModel( QObject* parent ) : TrackModel( parent ) , m_isTemporary( false ) + , m_changesOngoing( false ) { - qDebug() << Q_FUNC_INFO; - m_dropStorage.parent = QPersistentModelIndex(); m_dropStorage.row = -10; @@ -54,34 +53,9 @@ PlaylistModel::~PlaylistModel() } -int -PlaylistModel::columnCount( const QModelIndex& parent ) const -{ - return TrackModel::columnCount( parent ); -} - - -QVariant -PlaylistModel::data( const QModelIndex& index, int role ) const -{ - return TrackModel::data( index, role ); -} - - -QVariant -PlaylistModel::headerData( int section, Qt::Orientation orientation, int role ) const -{ - return TrackModel::headerData( section, orientation, role ); -} - - void PlaylistModel::loadPlaylist( const Tomahawk::playlist_ptr& playlist, bool loadEntries ) { - QString currentuuid; - if ( currentItem().isValid() ) - currentuuid = itemFromIndex( currentItem() )->query()->id(); - if ( !m_playlist.isNull() ) { disconnect( m_playlist.data(), SIGNAL( revisionLoaded( Tomahawk::PlaylistRevision ) ), this, SLOT( onRevisionLoaded( Tomahawk::PlaylistRevision ) ) ); @@ -89,10 +63,8 @@ PlaylistModel::loadPlaylist( const Tomahawk::playlist_ptr& playlist, bool loadEn disconnect( m_playlist.data(), SIGNAL( changed() ), this, SIGNAL( playlistChanged() ) ); } - if ( rowCount( QModelIndex() ) && loadEntries ) - { + if ( loadEntries ) clear(); - } m_playlist = playlist; connect( playlist.data(), SIGNAL( revisionLoaded( Tomahawk::PlaylistRevision ) ), SLOT( onRevisionLoaded( Tomahawk::PlaylistRevision ) ) ); @@ -109,45 +81,8 @@ PlaylistModel::loadPlaylist( const Tomahawk::playlist_ptr& playlist, bool loadEn if ( !loadEntries ) return; - TrackModelItem* plitem; QList entries = playlist->entries(); - if ( entries.count() ) - { - int c = rowCount( QModelIndex() ); - - qDebug() << "Starting loading" << playlist->title(); - emit beginInsertRows( QModelIndex(), c, c + entries.count() - 1 ); - - m_waitingForResolved.clear(); - foreach( const plentry_ptr& entry, entries ) - { -// qDebug() << entry->query()->toString(); - plitem = new TrackModelItem( entry, m_rootItem ); - plitem->index = createIndex( m_rootItem->children.count() - 1, 0, plitem ); - - connect( plitem, SIGNAL( dataChanged() ), SLOT( onDataChanged() ) ); - - if ( entry->query()->id() == currentuuid ) - setCurrentItem( plitem->index ); - - if ( !entry->query()->resolvingFinished() && !entry->query()->playable() ) - { - m_waitingForResolved.append( entry->query().data() ); - connect( entry->query().data(), SIGNAL( resolvingFinished( bool ) ), SLOT( trackResolved( bool ) ) ); - } - } - - emit endInsertRows(); - } - else - qDebug() << "Playlist seems empty:" << playlist->title(); - - if ( !m_waitingForResolved.isEmpty() ) - { - emit loadingStarted(); - } - - emit trackCountChanged( rowCount( QModelIndex() ) ); + append( entries ); } @@ -165,7 +100,7 @@ PlaylistModel::loadHistory( const Tomahawk::source_ptr& source, unsigned int amo cmd->setLimit( amount ); connect( cmd, SIGNAL( tracks( QList ) ), - SLOT( onTracksAdded( QList ) ), Qt::QueuedConnection ); + SLOT( append( QList ) ), Qt::QueuedConnection ); Database::instance()->enqueue( QSharedPointer( cmd ) ); } @@ -174,22 +109,23 @@ PlaylistModel::loadHistory( const Tomahawk::source_ptr& source, unsigned int amo void PlaylistModel::clear() { - if ( rowCount( QModelIndex() ) ) - { - emit loadingFinished(); + TrackModel::clear(); - emit beginResetModel(); - delete m_rootItem; - m_rootItem = 0; - m_rootItem = new TrackModelItem( 0, this ); - emit endResetModel(); - } + m_waitingForResolved.clear(); } + +void +PlaylistModel::append( const QList< plentry_ptr >& entries ) +{ + insert( entries, rowCount( QModelIndex() ) ); +} + + void PlaylistModel::append( const QList< query_ptr >& queries ) { - onTracksAdded( queries ); + insert( queries, rowCount( QModelIndex() ) ); } @@ -199,13 +135,10 @@ PlaylistModel::append( const Tomahawk::query_ptr& query ) if ( query.isNull() ) return; - QList< Tomahawk::query_ptr > ql; - ql << query; - if ( !query->resolvingFinished() ) Pipeline::instance()->resolve( query ); - onTracksAdded( ql ); + TrackModel::append( query ); } @@ -225,7 +158,7 @@ PlaylistModel::append( const Tomahawk::album_ptr& album ) m_isTemporary = true; } - onTracksAdded( album->tracks() ); + append( album->tracks() ); } @@ -245,20 +178,83 @@ PlaylistModel::append( const Tomahawk::artist_ptr& artist ) m_isTemporary = true; } - onTracksAdded( artist->tracks() ); + append( artist->tracks() ); } void -PlaylistModel::insert( unsigned int row, const Tomahawk::query_ptr& query ) +PlaylistModel::insert( const Tomahawk::query_ptr& query, int row ) { - if ( query.isNull() ) + TrackModel::insert( query, row ); +} + + +void +PlaylistModel::insert( const QList< Tomahawk::query_ptr >& queries, int row ) +{ + if ( !queries.count() ) return; - QList< Tomahawk::query_ptr > ql; - ql << query; + QList< Tomahawk::plentry_ptr > entries; + foreach( const query_ptr& query, queries ) + { + plentry_ptr entry = plentry_ptr( new PlaylistEntry() ); - onTracksInserted( row, ql ); + if ( query->results().count() ) + entry->setDuration( query->results().at( 0 )->duration() ); + else + entry->setDuration( 0 ); + + entry->setLastmodified( 0 ); + entry->setAnnotation( "" ); // FIXME + entry->setQuery( query ); + entry->setGuid( uuid() ); + + entries << entry; + } + + insert( entries, row ); +} + + +void +PlaylistModel::insert( const QList< Tomahawk::plentry_ptr >& entries, int row ) +{ + if ( !entries.count() ) + return; + + int c = row; + QPair< int, int > crows; + crows.first = c; + crows.second = c + entries.count() - 1; + + emit beginInsertRows( QModelIndex(), crows.first, crows.second ); + + int i = 0; + TrackModelItem* plitem; + foreach( const plentry_ptr& entry, entries ) + { + plitem = new TrackModelItem( entry, m_rootItem, row + i ); + plitem->index = createIndex( row + i, 0, plitem ); + i++; + + if ( entry->query()->id() == currentItemUuid() ) + setCurrentItem( plitem->index ); + + if ( !entry->query()->resolvingFinished() && !entry->query()->playable() ) + { + m_waitingForResolved.append( entry->query().data() ); + connect( entry->query().data(), SIGNAL( resolvingFinished( bool ) ), SLOT( trackResolved( bool ) ) ); + } + + connect( plitem, SIGNAL( dataChanged() ), SLOT( onDataChanged() ) ); + } + + if ( !m_waitingForResolved.isEmpty() ) + emit loadingStarted(); + + emit endInsertRows(); + emit trackCountChanged( rowCount( QModelIndex() ) ); } @@ -282,53 +278,9 @@ PlaylistModel::trackResolved( bool ) } -void -PlaylistModel::onTracksAdded( const QList& tracks ) -{ - onTracksInserted( rowCount( QModelIndex() ), tracks ); -} - - -void -PlaylistModel::onTracksInserted( unsigned int row, const QList& tracks ) -{ - if ( !tracks.count() ) - { - emit trackCountChanged( rowCount( QModelIndex() ) ); - return; - } - - int c = row; - QPair< int, int > crows; - crows.first = c; - crows.second = c + tracks.count() - 1; - - emit beginInsertRows( QModelIndex(), crows.first, crows.second ); - - int i = 0; - TrackModelItem* plitem; - foreach( const query_ptr& query, tracks ) - { - plentry_ptr entry = plentry_ptr( new PlaylistEntry() ); - entry->setQuery( query ); - - plitem = new TrackModelItem( entry, m_rootItem, row + i ); - plitem->index = createIndex( row + i, 0, plitem ); - - i++; - - connect( plitem, SIGNAL( dataChanged() ), SLOT( onDataChanged() ) ); - } - - emit endInsertRows(); - emit trackCountChanged( rowCount( QModelIndex() ) ); -} - - void PlaylistModel::onDataChanged() { - qDebug() << Q_FUNC_INFO; TrackModelItem* p = (TrackModelItem*)sender(); if ( p && p->index.isValid() ) emit dataChanged( p->index, p->index.sibling( p->index.row(), columnCount() - 1 ) ); @@ -384,14 +336,16 @@ PlaylistModel::dropMimeData( const QMimeData* data, Qt::DropAction action, int r // so check if the drag originated in this playlist to determine whether or not to copy #ifdef Q_WS_MAC if ( !data->hasFormat( "application/tomahawk.playlist.id" ) || - ( !m_playlist.isNull() && data->data( "application/tomahawk.playlist.id" ) != m_playlist->guid() ) ) + ( !m_playlist.isNull() && data->data( "application/tomahawk.playlist.id" ) != m_playlist->guid() ) ) + { dj->setDropAction( DropJob::Append ); + } #else if ( action & Qt::CopyAction ) dj->setDropAction( DropJob::Append ); #endif - connect( dj, SIGNAL( tracks( QList< Tomahawk::query_ptr > ) ), this, SLOT( parsedDroppedTracks( QList< Tomahawk::query_ptr > ) ) ); + connect( dj, SIGNAL( tracks( QList< Tomahawk::query_ptr > ) ), SLOT( parsedDroppedTracks( QList< Tomahawk::query_ptr > ) ) ); dj->tracksFromMimeData( data ); return true; @@ -412,44 +366,13 @@ PlaylistModel::parsedDroppedTracks( QList< query_ptr > tracks ) else beginRow = rowCount( QModelIndex() ); -// qDebug() << data->formats(); - QString currentuuid; - if ( currentItem().isValid() ) - currentuuid = itemFromIndex( currentItem() )->query()->id(); - if ( tracks.count() ) { - emit beginInsertRows( QModelIndex(), beginRow, beginRow + tracks.count() - 1 ); - foreach( const Tomahawk::query_ptr& query, tracks ) - { - plentry_ptr e( new PlaylistEntry() ); - e->setGuid( uuid() ); - - if ( query->results().count() ) - e->setDuration( query->results().at( 0 )->duration() ); - else - e->setDuration( 0 ); - - e->setLastmodified( 0 ); - e->setAnnotation( "" ); // FIXME - e->setQuery( query ); - - TrackModelItem* plitem = new TrackModelItem( e, m_rootItem, beginRow ); - plitem->index = createIndex( beginRow++, 0, plitem ); - - if ( query->id() == currentuuid ) - setCurrentItem( plitem->index ); - - connect( plitem, SIGNAL( dataChanged() ), SLOT( onDataChanged() ) ); - } - emit endInsertRows(); - - if ( m_dropStorage.action & Qt::CopyAction || m_dropStorage.action & Qt::MoveAction ) - { - onPlaylistChanged(); - emit trackCountChanged( rowCount( QModelIndex() ) ); - } + bool update = ( m_dropStorage.action & Qt::CopyAction || m_dropStorage.action & Qt::MoveAction ); + if ( update ) + beginPlaylistChanges(); + insert( tracks, beginRow ); } m_dropStorage.parent = QPersistentModelIndex(); @@ -458,8 +381,26 @@ PlaylistModel::parsedDroppedTracks( QList< query_ptr > tracks ) void -PlaylistModel::onPlaylistChanged() +PlaylistModel::beginPlaylistChanges() { + Q_ASSERT( !m_changesOngoing ); + m_changesOngoing = true; +} + + +void +PlaylistModel::endPlaylistChanges() +{ + if ( m_changesOngoing ) + { + m_changesOngoing = false; + } + else + { + tDebug() << "Called" << Q_FUNC_INFO << "unexpectedly!"; + Q_ASSERT( false ); + } + if ( m_playlist.isNull() ) return; @@ -505,16 +446,17 @@ PlaylistModel::playlistEntries() const void -PlaylistModel::remove( unsigned int row, bool moreToCome ) +PlaylistModel::remove( int row, bool moreToCome ) { - removeIndex( index( row, 0, QModelIndex() ), moreToCome ); + TrackModel::remove( row, moreToCome ); } void -PlaylistModel::removeIndex( const QModelIndex& index, bool moreToCome ) +PlaylistModel::remove( const QModelIndex& index, bool moreToCome ) { TrackModelItem* item = itemFromIndex( index ); + if ( item && m_waitingForResolved.contains( item->query().data() ) ) { m_waitingForResolved.removeAll( item->query().data() ); @@ -522,12 +464,27 @@ PlaylistModel::removeIndex( const QModelIndex& index, bool moreToCome ) emit loadingFinished(); } - TrackModel::removeIndex( index ); + if ( !m_changesOngoing ) + beginPlaylistChanges(); - if ( !moreToCome && !m_playlist.isNull() ) - { - onPlaylistChanged(); - } + TrackModel::remove( index, moreToCome ); + + if ( !moreToCome ) + endPlaylistChanges(); +} + + +void +PlaylistModel::remove( const QList& indexes ) +{ + TrackModel::remove( indexes ); +} + + +void +PlaylistModel::remove( const QList& indexes ) +{ + TrackModel::remove( indexes ); } diff --git a/src/libtomahawk/playlist/playlistmodel.h b/src/libtomahawk/playlist/playlistmodel.h index 4f4b031fd..1313cea2a 100644 --- a/src/libtomahawk/playlist/playlistmodel.h +++ b/src/libtomahawk/playlist/playlistmodel.h @@ -47,11 +47,6 @@ public: explicit PlaylistModel( QObject* parent = 0 ); ~PlaylistModel(); - int columnCount( const QModelIndex& parent = QModelIndex() ) const; - - QVariant data( const QModelIndex& index, int role ) const; - QVariant headerData( int section, Qt::Orientation orientation, int role ) const; - virtual QMimeData* mimeData ( const QModelIndexList& indexes ) const; virtual bool dropMimeData( const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent ); @@ -60,44 +55,47 @@ public: virtual void loadPlaylist( const Tomahawk::playlist_ptr& playlist, bool loadEntries = true ); void loadHistory( const Tomahawk::source_ptr& source, unsigned int amount = 50 ); - void clear(); - - void append( const Tomahawk::query_ptr& query ); - void append( const Tomahawk::album_ptr& album ); - void append( const Tomahawk::artist_ptr& artist ); - - void append( const QList< Tomahawk::query_ptr >& queries ); - - void insert( unsigned int row, const Tomahawk::query_ptr& query ); - - void remove( unsigned int row, bool moreToCome = false ); - virtual void removeIndex( const QModelIndex& index, bool moreToCome = false ); bool isTemporary() const; +public slots: + virtual void clear(); + + virtual void append( const Tomahawk::query_ptr& query ); + virtual void append( const Tomahawk::album_ptr& album ); + virtual void append( const Tomahawk::artist_ptr& artist ); + virtual void append( const QList< Tomahawk::query_ptr >& queries ); + virtual void append( const QList< Tomahawk::plentry_ptr >& entries ); + + virtual void insert( const Tomahawk::query_ptr& query, int row = 0 ); + virtual void insert( const QList< Tomahawk::query_ptr >& queries, int row = 0 ); + virtual void insert( const QList< Tomahawk::plentry_ptr >& entries, int row = 0 ); + + virtual void remove( int row, bool moreToCome = false ); + virtual void remove( const QModelIndex& index, bool moreToCome = false ); + virtual void remove( const QList& indexes ); + virtual void remove( const QList& indexes ); + signals: void repeatModeChanged( Tomahawk::PlaylistInterface::RepeatMode mode ); void shuffleModeChanged( bool enabled ); - void itemSizeChanged( const QModelIndex& index ); void playlistDeleted(); void playlistChanged(); private slots: void onDataChanged(); - void onRevisionLoaded( Tomahawk::PlaylistRevision revision ); - void onPlaylistChanged(); - - void onTracksAdded( const QList& tracks ); - void onTracksInserted( unsigned int row, const QList& tracks ); void parsedDroppedTracks( QList ); - void trackResolved( bool ); private: + void beginPlaylistChanges(); + void endPlaylistChanges(); + QList playlistEntries() const; Tomahawk::playlist_ptr m_playlist; bool m_isTemporary; + bool m_changesOngoing; QList< Tomahawk::Query* > m_waitingForResolved; QStringList m_waitForRevision; diff --git a/src/libtomahawk/playlist/playlistview.cpp b/src/libtomahawk/playlist/playlistview.cpp index 607db56f2..5582c8445 100644 --- a/src/libtomahawk/playlist/playlistview.cpp +++ b/src/libtomahawk/playlist/playlistview.cpp @@ -94,7 +94,7 @@ PlaylistView::keyPressEvent( QKeyEvent* event ) if ( ( event->key() == Qt::Key_Delete || event->key() == Qt::Key_Backspace ) && !model()->isReadOnly() ) { qDebug() << "Removing selected items"; - proxyModel()->removeIndexes( selectedIndexes() ); + proxyModel()->remove( selectedIndexes() ); } } @@ -102,9 +102,10 @@ PlaylistView::keyPressEvent( QKeyEvent* event ) void PlaylistView::deleteItems() { - proxyModel()->removeIndexes( selectedIndexes() ); + proxyModel()->remove( selectedIndexes() ); } + bool PlaylistView::canAutoUpdate() const { @@ -114,6 +115,7 @@ PlaylistView::canAutoUpdate() const return false; } + bool PlaylistView::autoUpdate() const { diff --git a/src/libtomahawk/playlist/queueproxymodel.cpp b/src/libtomahawk/playlist/queueproxymodel.cpp index 2f5864931..88129a57b 100644 --- a/src/libtomahawk/playlist/queueproxymodel.cpp +++ b/src/libtomahawk/playlist/queueproxymodel.cpp @@ -44,7 +44,7 @@ void QueueProxyModel::onIndexActivated( const QModelIndex& index ) { setCurrentIndex( QModelIndex() ); - removeIndex( index ); + remove( index ); } @@ -54,7 +54,7 @@ QueueProxyModel::siblingItem( int itemsAway ) setCurrentIndex( QModelIndex() ); Tomahawk::result_ptr res = PlaylistProxyModel::siblingItem( itemsAway ); - removeIndex( currentIndex() ); + remove( currentIndex() ); return res; } diff --git a/src/libtomahawk/playlist/trackmodel.cpp b/src/libtomahawk/playlist/trackmodel.cpp index f67f27c74..fe12526bc 100644 --- a/src/libtomahawk/playlist/trackmodel.cpp +++ b/src/libtomahawk/playlist/trackmodel.cpp @@ -230,6 +230,7 @@ QVariant TrackModel::headerData( int section, Qt::Orientation orientation, int role ) const { Q_UNUSED( orientation ); + QStringList headers; headers << tr( "Artist" ) << tr( "Title" ) << tr( "Album" ) << tr( "Track" ) << tr( "Duration" ) << tr( "Bitrate" ) << tr( "Age" ) << tr( "Year" ) << tr( "Size" ) << tr( "Origin" ) << tr( "Score" ); if ( role == Qt::DisplayRole && section >= 0 ) @@ -244,7 +245,6 @@ TrackModel::headerData( int section, Qt::Orientation orientation, int role ) con void TrackModel::setCurrentItem( const QModelIndex& index ) { - qDebug() << Q_FUNC_INFO; TrackModelItem* oldEntry = itemFromIndex( m_currentIndex ); if ( oldEntry ) { @@ -255,11 +255,13 @@ TrackModel::setCurrentItem( const QModelIndex& index ) if ( entry ) { m_currentIndex = index; + m_currentUuid = entry->query()->id(); entry->setIsPlaying( true ); } else { m_currentIndex = QModelIndex(); + m_currentUuid = QString(); } } @@ -322,16 +324,96 @@ TrackModel::mimeData( const QModelIndexList &indexes ) const void -TrackModel::removeIndex( const QModelIndex& index, bool moreToCome ) +TrackModel::clear() +{ + if ( rowCount( QModelIndex() ) ) + { + emit loadingFinished(); + + emit beginResetModel(); + delete m_rootItem; + m_rootItem = 0; + m_rootItem = new TrackModelItem( 0, this ); + emit endResetModel(); + } +} + + +void +TrackModel::append( const Tomahawk::query_ptr& query ) +{ + insert( query, rowCount( QModelIndex() ) ); +} + + +void +TrackModel::append( const QList< Tomahawk::query_ptr >& queries ) +{ + insert( queries, rowCount( QModelIndex() ) ); +} + + +void +TrackModel::insert( const Tomahawk::query_ptr& query, int row ) +{ + if ( query.isNull() ) + return; + + QList< Tomahawk::query_ptr > ql; + ql << query; + + insert( ql, row ); +} + + +void +TrackModel::insert( const QList< Tomahawk::query_ptr >& queries, int row ) +{ + if ( !queries.count() ) + return; + + int c = row; + QPair< int, int > crows; + crows.first = c; + crows.second = c + queries.count() - 1; + + emit beginInsertRows( QModelIndex(), crows.first, crows.second ); + + int i = 0; + TrackModelItem* plitem; + foreach( const query_ptr& query, queries ) + { + plitem = new TrackModelItem( query, m_rootItem, row + i ); + plitem->index = createIndex( row + i, 0, plitem ); + i++; + + if ( query->id() == currentItemUuid() ) + setCurrentItem( plitem->index ); + + connect( plitem, SIGNAL( dataChanged() ), SLOT( onDataChanged() ) ); + } + + emit endInsertRows(); + emit trackCountChanged( rowCount( QModelIndex() ) ); +} + + +void +TrackModel::remove( int row, bool moreToCome ) +{ + remove( index( row, 0, QModelIndex() ), moreToCome ); +} + + +void +TrackModel::remove( const QModelIndex& index, bool moreToCome ) { if ( QThread::currentThread() != thread() ) { -// qDebug() << "Reinvoking in correct thread:" << Q_FUNC_INFO; - QMetaObject::invokeMethod( this, "removeIndex", + QMetaObject::invokeMethod( this, "remove", Qt::QueuedConnection, Q_ARG(const QModelIndex, index), - Q_ARG(bool, moreToCome) - ); + Q_ARG(bool, moreToCome) ); return; } @@ -346,24 +428,49 @@ TrackModel::removeIndex( const QModelIndex& index, bool moreToCome ) emit endRemoveRows(); } - emit trackCountChanged( rowCount( QModelIndex() ) ); + if ( !moreToCome ) + emit trackCountChanged( rowCount( QModelIndex() ) ); } void -TrackModel::removeIndexes( const QList& indexes ) +TrackModel::remove( const QList& indexes ) { - foreach( const QModelIndex& idx, indexes ) + QList pil; + foreach ( const QModelIndex& idx, indexes ) { - removeIndex( idx ); + pil << idx; + } + + remove( pil ); +} + + +void +TrackModel::remove( const QList& indexes ) +{ + QList finalIndexes; + foreach ( const QPersistentModelIndex index, indexes ) + { + if ( index.column() > 0 ) + continue; + finalIndexes << index; + } + + for ( int i = 0; i < finalIndexes.count(); i++ ) + { + remove( finalIndexes.at( i ), i + 1 != finalIndexes.count() ); } } + TrackModelItem* TrackModel::itemFromIndex( const QModelIndex& index ) const { if ( index.isValid() ) + { return static_cast( index.internalPointer() ); + } else { return m_rootItem; diff --git a/src/libtomahawk/playlist/trackmodel.h b/src/libtomahawk/playlist/trackmodel.h index 99dc7fc8a..799f2c46f 100644 --- a/src/libtomahawk/playlist/trackmodel.h +++ b/src/libtomahawk/playlist/trackmodel.h @@ -23,6 +23,7 @@ #include "playlistinterface.h" #include "trackmodelitem.h" +#include "typedefs.h" #include "dllmacro.h" @@ -84,16 +85,13 @@ public: virtual Qt::ItemFlags flags( const QModelIndex& index ) const; virtual QPersistentModelIndex currentItem() { return m_currentIndex; } + virtual Tomahawk::QID currentItemUuid() { return m_currentUuid; } virtual Tomahawk::PlaylistInterface::RepeatMode repeatMode() const { return Tomahawk::PlaylistInterface::NoRepeat; } virtual bool shuffled() const { return false; } virtual void ensureResolved(); - virtual void append( const Tomahawk::query_ptr& query ) = 0; - virtual void append( const Tomahawk::artist_ptr& artist ) = 0; - virtual void append( const Tomahawk::album_ptr& album ) = 0; - TrackModelItem* itemFromIndex( const QModelIndex& index ) const; TrackModelItem* m_rootItem; @@ -109,8 +107,20 @@ signals: public slots: virtual void setCurrentItem( const QModelIndex& index ); - virtual void removeIndex( const QModelIndex& index, bool moreToCome = false ); - virtual void removeIndexes( const QList& indexes ); + virtual void clear(); + + virtual void append( const QList< Tomahawk::query_ptr >& queries ); + virtual void append( const Tomahawk::query_ptr& query ); + virtual void append( const Tomahawk::artist_ptr& artist ) { Q_UNUSED( artist ); } + virtual void append( const Tomahawk::album_ptr& album ) { Q_UNUSED( album ); } + + virtual void insert( const QList< Tomahawk::query_ptr >& queries, int row = 0 ); + virtual void insert( const Tomahawk::query_ptr& query, int row = 0 ); + + virtual void remove( int row, bool moreToCome = false ); + virtual void remove( const QModelIndex& index, bool moreToCome = false ); + virtual void remove( const QList& indexes ); + virtual void remove( const QList& indexes ); virtual void setRepeatMode( Tomahawk::PlaylistInterface::RepeatMode /*mode*/ ) {} virtual void setShuffled( bool /*shuffled*/ ) {} @@ -121,6 +131,8 @@ private slots: private: QPersistentModelIndex m_currentIndex; + Tomahawk::QID m_currentUuid; + bool m_readOnly; QString m_title; diff --git a/src/libtomahawk/playlist/trackproxymodel.cpp b/src/libtomahawk/playlist/trackproxymodel.cpp index 3c92699e9..e2753a04f 100644 --- a/src/libtomahawk/playlist/trackproxymodel.cpp +++ b/src/libtomahawk/playlist/trackproxymodel.cpp @@ -227,66 +227,48 @@ TrackProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex& sourceParen void -TrackProxyModel::removeIndex( const QModelIndex& index ) +TrackProxyModel::remove( const QModelIndex& index ) { - qDebug() << Q_FUNC_INFO; - if ( !sourceModel() ) return; if ( !index.isValid() ) return; - sourceModel()->removeIndex( mapToSource( index ) ); + sourceModel()->remove( mapToSource( index ) ); } void -TrackProxyModel::removeIndexes( const QModelIndexList& indexes ) +TrackProxyModel::remove( const QModelIndexList& indexes ) { if ( !sourceModel() ) return; QList pil; - foreach( const QModelIndex& idx, indexes ) + foreach ( const QModelIndex& idx, indexes ) { - if ( idx.isValid() && idx.column() == 0 ) + if ( idx.isValid() ) pil << mapToSource( idx ); } - bool b = true; - foreach( const QPersistentModelIndex& idx, pil ) - { - if ( idx == pil.last() ) - b = false; - - qDebug() << "b is:" << b; - sourceModel()->removeIndex( idx, b ); - } + sourceModel()->remove( pil ); } void -TrackProxyModel::removeIndexes( const QList& indexes ) +TrackProxyModel::remove( const QList< QPersistentModelIndex >& indexes ) { if ( !sourceModel() ) return; QList pil; - foreach( const QModelIndex& idx, indexes ) + foreach ( const QPersistentModelIndex& idx, indexes ) { - if ( idx.isValid() && idx.column() == 0 ) + if ( idx.isValid() ) pil << mapToSource( idx ); } - bool b = true; - foreach( const QPersistentModelIndex& idx, pil ) - { - if ( idx == pil.last() ) - b = false; - - qDebug() << "b is:" << b; - sourceModel()->removeIndex( idx, b ); - } + sourceModel()->remove( pil ); } diff --git a/src/libtomahawk/playlist/trackproxymodel.h b/src/libtomahawk/playlist/trackproxymodel.h index 76381b117..862929965 100644 --- a/src/libtomahawk/playlist/trackproxymodel.h +++ b/src/libtomahawk/playlist/trackproxymodel.h @@ -45,9 +45,9 @@ public: virtual int unfilteredTrackCount() const { return sourceModel()->trackCount(); } virtual int trackCount() const { return rowCount( QModelIndex() ); } - virtual void removeIndex( const QModelIndex& index ); - virtual void removeIndexes( const QModelIndexList& indexes ); - virtual void removeIndexes( const QList& indexes ); + virtual void remove( const QModelIndex& index ); + virtual void remove( const QModelIndexList& indexes ); + virtual void remove( const QList< QPersistentModelIndex >& indexes ); virtual Tomahawk::result_ptr currentItem() const; virtual Tomahawk::result_ptr siblingItem( int itemsAway ); @@ -75,7 +75,7 @@ signals: void filterChanged( const QString& filter ); void nextTrackReady(); - + public slots: virtual void setRepeatMode( RepeatMode mode ) { m_repeatMode = mode; emit repeatModeChanged( mode ); } virtual void setShuffled( bool enabled ) { m_shuffled = enabled; emit shuffleModeChanged( enabled ); } diff --git a/src/libtomahawk/playlist/trackview.cpp b/src/libtomahawk/playlist/trackview.cpp index 4d1ceabc4..613b62c95 100644 --- a/src/libtomahawk/playlist/trackview.cpp +++ b/src/libtomahawk/playlist/trackview.cpp @@ -411,7 +411,7 @@ TrackView::startDrag( Qt::DropActions supportedActions ) Qt::DropAction action = drag->exec( supportedActions, Qt::CopyAction ); if ( action == Qt::MoveAction ) { - m_proxyModel->removeIndexes( pindexes ); + m_proxyModel->remove( pindexes ); } }