1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-03-23 01:09:42 +01:00

* Refactored Track-, Collection-, PlaylistModel.

This commit is contained in:
Christian Muehlhaeuser 2011-11-21 05:00:46 +01:00
parent 3f139addc3
commit d650ea45b5
15 changed files with 343 additions and 440 deletions

View File

@ -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 );

View File

@ -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<QString, plentry_ptr> entriesmap;
foreach( const plentry_ptr& p, m_entries )
foreach ( const plentry_ptr& p, m_entries )
entriesmap.insert( p->guid(), p );
QList<plentry_ptr> 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<QString> 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;
}

View File

@ -18,9 +18,6 @@
#include "collectionflatmodel.h"
#include <QMimeData>
#include <QTreeView>
#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<Tomahawk::query_ptr> ) ),
SLOT( onTracksAdded( QList<Tomahawk::query_ptr> ) ) );
connect( collection.data(), SIGNAL( tracksRemoved( QList<Tomahawk::query_ptr> ) ),
SLOT( onTracksRemoved( QList<Tomahawk::query_ptr> ) ) );
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<Tomahawk::query_ptr> ) ),
this, SLOT( onTracksAdded( QList<Tomahawk::query_ptr> ) ) );
QTime timer;
timer.start();
// QList<TrackModelItem*> 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<Tomahawk::query_ptr>& 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<Tomahawk::query_ptr>& tracks )
{
QList<Tomahawk::query_ptr> 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<Tomahawk::query_ptr>& 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<Tomahawk::query_ptr>& 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() );
}
}

View File

@ -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<Tomahawk::query_ptr>& tracks );
void onTracksRemoved( const QList<Tomahawk::query_ptr>& tracks );
void onSourceOffline( const Tomahawk::source_ptr& src );
void processTracksToAdd();
private:
QMap< Tomahawk::collection_ptr, QPair< int, int > > m_collectionRows;
QList<Tomahawk::query_ptr> m_tracksToAdd;

View File

@ -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 )

View File

@ -264,7 +264,7 @@ DynamicView::collapseEntries( int startRow, int num, int numToKeep )
todel << proxyModel()->index( startRow + i, k );
}
}
proxyModel()->removeIndexes( todel );
proxyModel()->remove( todel );
}

View File

@ -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<plentry_ptr> 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<Tomahawk::query_ptr> ) ),
SLOT( onTracksAdded( QList<Tomahawk::query_ptr> ) ), Qt::QueuedConnection );
SLOT( append( QList<Tomahawk::query_ptr> ) ), Qt::QueuedConnection );
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>( 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<Tomahawk::query_ptr>& tracks )
{
onTracksInserted( rowCount( QModelIndex() ), tracks );
}
void
PlaylistModel::onTracksInserted( unsigned int row, const QList<Tomahawk::query_ptr>& 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<QModelIndex>& indexes )
{
TrackModel::remove( indexes );
}
void
PlaylistModel::remove( const QList<QPersistentModelIndex>& indexes )
{
TrackModel::remove( indexes );
}

View File

@ -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<QModelIndex>& indexes );
virtual void remove( const QList<QPersistentModelIndex>& 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<Tomahawk::query_ptr>& tracks );
void onTracksInserted( unsigned int row, const QList<Tomahawk::query_ptr>& tracks );
void parsedDroppedTracks( QList<Tomahawk::query_ptr> );
void trackResolved( bool );
private:
void beginPlaylistChanges();
void endPlaylistChanges();
QList<Tomahawk::plentry_ptr> playlistEntries() const;
Tomahawk::playlist_ptr m_playlist;
bool m_isTemporary;
bool m_changesOngoing;
QList< Tomahawk::Query* > m_waitingForResolved;
QStringList m_waitForRevision;

View File

@ -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
{

View File

@ -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;
}

View File

@ -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<QModelIndex>& indexes )
TrackModel::remove( const QList<QModelIndex>& indexes )
{
foreach( const QModelIndex& idx, indexes )
QList<QPersistentModelIndex> pil;
foreach ( const QModelIndex& idx, indexes )
{
removeIndex( idx );
pil << idx;
}
remove( pil );
}
void
TrackModel::remove( const QList<QPersistentModelIndex>& indexes )
{
QList<QPersistentModelIndex> 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<TrackModelItem*>( index.internalPointer() );
}
else
{
return m_rootItem;

View File

@ -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<QModelIndex>& 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<QModelIndex>& indexes );
virtual void remove( const QList<QPersistentModelIndex>& 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;

View File

@ -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<QPersistentModelIndex> 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<QPersistentModelIndex>& indexes )
TrackProxyModel::remove( const QList< QPersistentModelIndex >& indexes )
{
if ( !sourceModel() )
return;
QList<QPersistentModelIndex> 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 );
}

View File

@ -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<QPersistentModelIndex>& 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 ); }

View File

@ -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 );
}
}