1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-08-06 14:16:32 +02:00

Merge pull request #242 from tomahawk-player/flat-collection

Flat collection
This commit is contained in:
Uwe L. Korn
2014-07-17 02:06:48 +02:00
17 changed files with 269 additions and 97 deletions

View File

@@ -148,7 +148,10 @@ Pipeline::removeResolver( Resolver* r )
tDebug() << "Removed resolver:" << r->name(); tDebug() << "Removed resolver:" << r->name();
d->resolvers.removeAll( r ); d->resolvers.removeAll( r );
emit resolverRemoved( r ); if ( d->running ) {
// Only notify if Pipeline is still active.
emit resolverRemoved( r );
}
} }

View File

@@ -212,7 +212,7 @@ void
Query::refreshResults() Query::refreshResults()
{ {
Q_D( Query ); Q_D( Query );
if ( d->resolveFinished ) if ( d->resolveFinished && d->allowReresolve )
{ {
d->resolveFinished = false; d->resolveFinished = false;
query_ptr q = d->ownRef.toStrongRef(); query_ptr q = d->ownRef.toStrongRef();
@@ -420,6 +420,22 @@ Query::setResolveFinished( bool resolved )
} }
void
Query::allowReresolve()
{
Q_D( Query );
d->allowReresolve = true;
}
void
Query::disallowReresolve()
{
Q_D( Query );
d->allowReresolve = false;
}
void void
Query::clearResults() Query::clearResults()
{ {
@@ -530,9 +546,9 @@ Query::howSimilar( const Tomahawk::result_ptr& r )
{ {
Q_D( Query ); Q_D( Query );
// result values // result values
const QString rArtistname = r->track()->artistSortname(); const QString& rArtistname = r->track()->artistSortname();
const QString rAlbumname = r->track()->albumSortname(); const QString rAlbumname = r->track()->albumSortname();
const QString rTrackname = r->track()->trackSortname(); const QString& rTrackname = r->track()->trackSortname();
QString qArtistname; QString qArtistname;
QString qAlbumname; QString qAlbumname;

View File

@@ -82,6 +82,18 @@ public:
void setResolveFinished( bool resolved ); void setResolveFinished( bool resolved );
/**
* Allow contacting the Pipeline if the state of this Query changes to
* not solved.
*/
void allowReresolve();
/**
* Disallow contacting the Pipeline if the state of this Query changes to
* not solved.
*/
void disallowReresolve();
void setSaveHTTPResultHint( bool saveResultHint ); void setSaveHTTPResultHint( bool saveResultHint );
bool saveHTTPResultHint() const; bool saveHTTPResultHint() const;

View File

@@ -18,6 +18,7 @@ public:
QueryPrivate( Query* q, const track_ptr& track, const QID& _qid ) QueryPrivate( Query* q, const track_ptr& track, const QID& _qid )
: q_ptr( q ) : q_ptr( q )
, allowReresolve( true )
, qid( _qid ) , qid( _qid )
, queryTrack( track ) , queryTrack( track )
{ {
@@ -25,6 +26,7 @@ public:
QueryPrivate( Query* q, const QString& query, const QID& _qid ) QueryPrivate( Query* q, const QString& query, const QID& _qid )
: q_ptr( q ) : q_ptr( q )
, allowReresolve( true )
, qid( _qid ) , qid( _qid )
, fullTextQuery( query ) , fullTextQuery( query )
{ {
@@ -40,6 +42,7 @@ private:
bool solved; bool solved;
bool playable; bool playable;
bool resolveFinished; bool resolveFinished;
bool allowReresolve;
mutable QID qid; mutable QID qid;
QString fullTextQuery; QString fullTextQuery;

View File

@@ -281,11 +281,14 @@ Result::onOffline()
void void
Result::setCollection( const Tomahawk::collection_ptr& collection ) Result::setCollection( const Tomahawk::collection_ptr& collection , bool emitOnlineEvents )
{ {
m_collection = collection; m_collection = collection;
connect( m_collection->source().data(), SIGNAL( online() ), SLOT( onOnline() ), Qt::QueuedConnection ); if ( emitOnlineEvents )
connect( m_collection->source().data(), SIGNAL( offline() ), SLOT( onOffline() ), Qt::QueuedConnection ); {
connect( m_collection->source().data(), SIGNAL( online() ), SLOT( onOnline() ), Qt::QueuedConnection );
connect( m_collection->source().data(), SIGNAL( offline() ), SLOT( onOffline() ), Qt::QueuedConnection );
}
} }
void void

View File

@@ -92,7 +92,12 @@ public:
void setScore( float score ); void setScore( float score );
void setFileId( unsigned int id ); void setFileId( unsigned int id );
void setRID( RID id ) { m_rid = id; } void setRID( RID id ) { m_rid = id; }
void setCollection( const Tomahawk::collection_ptr& collection ); /**
* Associate the used collection for this result.
*
* @param emitOnlineEvents disableing this will not emit statusChanged anymore thus the query will not update (use with care!, only when this is the sole result)
*/
void setCollection( const Tomahawk::collection_ptr& collection, bool emitOnlineEvents = true );
void setFriendlySource( const QString& s ); void setFriendlySource( const QString& s );
void setPurchaseUrl( const QString& u ); void setPurchaseUrl( const QString& u );
void setLinkUrl( const QString& u ); void setLinkUrl( const QString& u );

View File

@@ -49,9 +49,24 @@ static QMutex s_nameCacheMutex;
inline QString inline QString
cacheKey( const QString& artist, const QString& track, const QString& album, int duration, const QString& composer, unsigned int albumpos, unsigned int discnumber ) cacheKey( const QString& artist, const QString& track, const QString& album, int duration, const QString& composer, unsigned int albumpos, unsigned int discnumber )
{ {
const QString durationStr = QString::number( duration );
const QString albumposStr = QString::number( albumpos );
const QString discnumberStr = QString::number( discnumber );
QString str; QString str;
QTextStream stream( &str ); // Preallocate space so that we will only call malloc once.
stream << artist << track << album << composer << duration << albumpos << discnumber; // With Qt5 we can possibly revert back to just "+" these strings.
// The "+" implementation in Qt4 differs slighty depending on compile
// options which could drastically reduce the performance.
str.reserve( artist.size() + track.size() + album.size()
+ composer.size() + durationStr.size()
+ albumposStr.size() + discnumberStr.size() );
str += artist;
str += track;
str += album;
str += composer;
str += durationStr;
str += albumposStr;
str += discnumberStr;
return str; return str;
} }
@@ -195,11 +210,19 @@ Track::init()
Q_D( Track ); Q_D( Track );
updateSortNames(); updateSortNames();
#if QT_VERSION >= QT_VERSION_CHECK( 5, 0, 0 )
QObject::connect( d->trackData.data(), &TrackData::attributesLoaded, this, &Track::attributesLoaded );
QObject::connect( d->trackData.data(), &TrackData::socialActionsLoaded, this, &Track::socialActionsLoaded );
QObject::connect( d->trackData.data(), &TrackData::statsLoaded, this, &Track::statsLoaded );
QObject::connect( d->trackData.data(), &TrackData::similarTracksLoaded, this, &Track::similarTracksLoaded );
QObject::connect( d->trackData.data(), &TrackData::lyricsLoaded, this, &Track::lyricsLoaded );
#else
connect( d->trackData.data(), SIGNAL( attributesLoaded() ), SIGNAL( attributesLoaded() ) ); connect( d->trackData.data(), SIGNAL( attributesLoaded() ), SIGNAL( attributesLoaded() ) );
connect( d->trackData.data(), SIGNAL( socialActionsLoaded() ), SIGNAL( socialActionsLoaded() ) ); connect( d->trackData.data(), SIGNAL( socialActionsLoaded() ), SIGNAL( socialActionsLoaded() ) );
connect( d->trackData.data(), SIGNAL( statsLoaded() ), SIGNAL( statsLoaded() ) ); connect( d->trackData.data(), SIGNAL( statsLoaded() ), SIGNAL( statsLoaded() ) );
connect( d->trackData.data(), SIGNAL( similarTracksLoaded() ), SIGNAL( similarTracksLoaded() ) ); connect( d->trackData.data(), SIGNAL( similarTracksLoaded() ), SIGNAL( similarTracksLoaded() ) );
connect( d->trackData.data(), SIGNAL( lyricsLoaded() ), SIGNAL( lyricsLoaded() ) ); connect( d->trackData.data(), SIGNAL( lyricsLoaded() ), SIGNAL( lyricsLoaded() ) );
#endif
} }
@@ -381,7 +404,7 @@ Track::toQuery()
} }
QString const QString&
Track::composerSortname() const Track::composerSortname() const
{ {
Q_D( const Track ); Q_D( const Track );
@@ -389,7 +412,7 @@ Track::composerSortname() const
} }
QString const QString&
Track::albumSortname() const Track::albumSortname() const
{ {
Q_D( const Track ); Q_D( const Track );
@@ -749,7 +772,7 @@ Track::share( const Tomahawk::source_ptr& source )
} }
QString const QString&
Track::artistSortname() const Track::artistSortname() const
{ {
Q_D( const Track ); Q_D( const Track );
@@ -757,7 +780,7 @@ Track::artistSortname() const
} }
QString const QString&
Track::trackSortname() const Track::trackSortname() const
{ {
Q_D( const Track ); Q_D( const Track );

View File

@@ -68,10 +68,10 @@ public:
QString toString() const; QString toString() const;
Tomahawk::query_ptr toQuery(); Tomahawk::query_ptr toQuery();
QString composerSortname() const; const QString& composerSortname() const;
QString albumSortname() const; const QString& albumSortname() const;
QString artistSortname() const; const QString& artistSortname() const;
QString trackSortname() const; const QString& trackSortname() const;
QString artist() const; QString artist() const;
QString track() const; QString track() const;

View File

@@ -55,8 +55,8 @@ public:
QString toString() const; QString toString() const;
Tomahawk::query_ptr toQuery(); Tomahawk::query_ptr toQuery();
QString artistSortname() const { return m_artistSortname; } const QString& artistSortname() const { return m_artistSortname; }
QString trackSortname() const { return m_trackSortname; } const QString& trackSortname() const { return m_trackSortname; }
QWeakPointer< Tomahawk::TrackData > weakRef() { return m_ownRef; } QWeakPointer< Tomahawk::TrackData > weakRef() { return m_ownRef; }
void setWeakRef( QWeakPointer< Tomahawk::TrackData > weakRef ) { m_ownRef = weakRef; } void setWeakRef( QWeakPointer< Tomahawk::TrackData > weakRef ) { m_ownRef = weakRef; }

View File

@@ -305,10 +305,13 @@ ViewManager::show( const Tomahawk::collection_ptr& collection )
view->columnView()->proxyModel()->setStyle( PlayableProxyModel::Collection ); view->columnView()->proxyModel()->setStyle( PlayableProxyModel::Collection );
TreeModel* model = new TreeModel(); TreeModel* model = new TreeModel();
PlayableModel* flatModel = new PlayableModel();
view->setTreeModel( model ); view->setTreeModel( model );
view->setFlatModel( flatModel );
model->addCollection( collection ); model->addCollection( collection );
flatModel->appendTracks( collection );
setPage( view ); setPage( view );
if ( !collection.isNull() ) if ( !collection.isNull() )

View File

@@ -76,8 +76,7 @@ DatabaseCommand_AllTracks::exec( DatabaseImpl* dbi )
QString sql = QString( QString sql = QString(
"SELECT file.id, artist.name, album.name, track.name, composer.name, file.size, " //0 "SELECT file.id, artist.name, album.name, track.name, composer.name, file.size, " //0
"file.duration, file.bitrate, file.url, file.source, file.mtime, " //6 "file.duration, file.bitrate, file.url, file.source, file.mtime, " //6
"file.mimetype, file_join.discnumber, file_join.albumpos, artist.id, " //11 "file.mimetype, file_join.discnumber, file_join.albumpos, track.id " //11
"album.id, track.id, composer.id " //15
"FROM file, artist, track, file_join " "FROM file, artist, track, file_join "
"LEFT OUTER JOIN album " "LEFT OUTER JOIN album "
"ON file_join.album = album.id " "ON file_join.album = album.id "
@@ -99,10 +98,38 @@ DatabaseCommand_AllTracks::exec( DatabaseImpl* dbi )
query.prepare( sql ); query.prepare( sql );
query.exec(); query.exec();
// Small cache to keep already created source objects.
// This saves some mutex locking.
std::map<uint, Tomahawk::source_ptr> sourceCache;
while( query.next() ) while( query.next() )
{ {
QString artist = query.value( 1 ).toString();
QString album = query.value( 2 ).toString();
QString track = query.value( 3 ).toString();
QString composer = query.value( 4 ).toString();
uint size = query.value( 5 ).toUInt();
uint duration = query.value( 6 ).toUInt();
uint bitrate = query.value( 7 ).toUInt();
QString url = query.value( 8 ).toString(); QString url = query.value( 8 ).toString();
Tomahawk::source_ptr s = SourceList::instance()->get( query.value( 9 ).toUInt() ); uint sourceId = query.value( 9 ).toUInt();
uint modificationTime = query.value( 10 ).toUInt();
QString mimetype = query.value( 11 ).toString();
uint discnumber = query.value( 12 ).toUInt();
uint albumpos = query.value( 13 ).toUInt();
uint trackId = query.value( 14 ).toUInt();
std::map<uint, Tomahawk::source_ptr>::const_iterator _s = sourceCache.find( sourceId );
Tomahawk::source_ptr s;
if ( _s == sourceCache.end() )
{
s = SourceList::instance()->get( sourceId );
sourceCache[sourceId] = s;
}
else
{
s = _s->second;
}
if ( !s ) if ( !s )
{ {
Q_ASSERT( false ); Q_ASSERT( false );
@@ -111,30 +138,31 @@ DatabaseCommand_AllTracks::exec( DatabaseImpl* dbi )
if ( !s->isLocal() ) if ( !s->isLocal() )
url = QString( "servent://%1\t%2" ).arg( s->nodeId() ).arg( url ); url = QString( "servent://%1\t%2" ).arg( s->nodeId() ).arg( url );
QString artist, track, album, composer;
artist = query.value( 1 ).toString();
album = query.value( 2 ).toString();
track = query.value( 3 ).toString();
composer = query.value( 4 ).toString();
Tomahawk::result_ptr result = Tomahawk::Result::get( url ); Tomahawk::result_ptr result = Tomahawk::Result::get( url );
Tomahawk::query_ptr qry = Tomahawk::Query::get( artist, track, album ); Tomahawk::track_ptr t = Tomahawk::Track::get( trackId,
artist, track, album,
duration, composer,
albumpos, discnumber );
Tomahawk::query_ptr qry = Tomahawk::Query::get( t );
Tomahawk::track_ptr t = Tomahawk::Track::get( query.value( 16 ).toUInt(), artist, track, album, query.value( 6 ).toUInt(), composer, query.value( 13 ).toUInt(), query.value( 12 ).toUInt() ); if ( m_album || m_artist ) {
t->loadAttributes(); t->loadAttributes();
}
result->setTrack( t ); result->setTrack( t );
result->setSize( query.value( 5 ).toUInt() ); result->setSize( size );
result->setBitrate( query.value( 7 ).toUInt() ); result->setBitrate( bitrate );
result->setModificationTime( query.value( 10 ).toUInt() ); result->setModificationTime( modificationTime );
result->setMimetype( query.value( 11 ).toString() ); result->setMimetype( mimetype );
result->setScore( 1.0 ); result->setScore( 1.0 );
result->setCollection( s->dbCollection() ); result->setCollection( s->dbCollection(), false );
QList<Tomahawk::result_ptr> results; QList<Tomahawk::result_ptr> results;
results << result; results << result;
qry->addResults( results ); qry->addResults( results );
qry->setResolveFinished( true ); qry->setResolveFinished( true );
// These tracks are fixed to the Source. Do not re-resolve.
qry->disallowReresolve();
ql << qry; ql << qry;
} }

View File

@@ -538,7 +538,7 @@ Tomahawk::DatabaseImpl::getTrackFids( int tid )
QString QString
Tomahawk::DatabaseImpl::sortname( const QString& str, bool replaceArticle ) Tomahawk::DatabaseImpl::sortname( const QString& str, bool replaceArticle )
{ {
QString s = str.toLower().trimmed().replace( QRegExp( "[\\s]{2,}" ), " " ); QString s = str.simplified().toLower();
if ( replaceArticle && s.startsWith( "the " ) ) if ( replaceArticle && s.startsWith( "the " ) )
{ {

View File

@@ -48,14 +48,14 @@ FlexibleTreeView::FlexibleTreeView( QWidget* parent, QWidget* extraHeader )
, m_modeHeader( new ModeHeader( this ) ) , m_modeHeader( new ModeHeader( this ) )
, m_columnView( new ColumnView() ) , m_columnView( new ColumnView() )
, m_treeView( new TreeView() ) , m_treeView( new TreeView() )
, m_trackView( 0 ) , m_trackView( new TrackView() )
, m_model( 0 ) , m_model( 0 )
, m_flatModel( 0 )
, m_temporary( false ) , m_temporary( false )
{ {
qRegisterMetaType< FlexibleTreeViewMode >( "FlexibleTreeViewMode" ); qRegisterMetaType< FlexibleTreeViewMode >( "FlexibleTreeViewMode" );
m_treeView->proxyModel()->setStyle( PlayableProxyModel::Collection ); m_treeView->proxyModel()->setStyle( PlayableProxyModel::Collection );
m_treeView->proxyModel()->setPlaylistInterface( m_columnView->proxyModel()->playlistInterface() ); m_treeView->proxyModel()->setPlaylistInterface( m_columnView->proxyModel()->playlistInterface() );
// m_trackView->setPlaylistInterface( m_playlistInterface ); // m_trackView->setPlaylistInterface( m_playlistInterface );
@@ -93,8 +93,7 @@ FlexibleTreeView::FlexibleTreeView( QWidget* parent, QWidget* extraHeader )
m_stack->addWidget( m_columnView ); m_stack->addWidget( m_columnView );
m_stack->addWidget( m_treeView ); m_stack->addWidget( m_treeView );
/* m_stack->addWidget( m_gridView ); m_stack->addWidget( m_trackView );
m_stack->addWidget( m_trackView );*/
connect( m_header, SIGNAL( filterTextChanged( QString ) ), SLOT( setFilter( QString ) ) ); connect( m_header, SIGNAL( filterTextChanged( QString ) ), SLOT( setFilter( QString ) ) );
@@ -182,7 +181,6 @@ FlexibleTreeView::setTreeModel( TreeModel* model )
// m_trackView->setPlayableModel( model ); // m_trackView->setPlayableModel( model );
m_columnView->setTreeModel( model ); m_columnView->setTreeModel( model );
m_treeView->setTreeModel( model ); m_treeView->setTreeModel( model );
// m_gridView->setPlayableModel( model );
/* m_trackView->setSortingEnabled( false ); /* m_trackView->setSortingEnabled( false );
m_trackView->sortByColumn( -1 ); m_trackView->sortByColumn( -1 );
@@ -195,6 +193,27 @@ FlexibleTreeView::setTreeModel( TreeModel* model )
} }
void
FlexibleTreeView::setFlatModel( PlayableModel* model )
{
if ( m_flatModel )
{
// disconnect( m_flatModel, SIGNAL( changed() ), this, SLOT( onModelChanged() ) );
delete m_flatModel;
}
m_flatModel = model;
m_trackView->setPlayableModel( model );
m_trackView->setSortingEnabled( true );
m_trackView->sortByColumn( 0 );
/* connect( model, SIGNAL( changed() ), SLOT( onModelChanged() ), Qt::UniqueConnection );
onModelChanged();*/
}
void void
FlexibleTreeView::setCurrentMode( FlexibleTreeViewMode mode ) FlexibleTreeView::setCurrentMode( FlexibleTreeViewMode mode )
{ {
@@ -224,7 +243,7 @@ FlexibleTreeView::setCurrentMode( FlexibleTreeViewMode mode )
case Albums: case Albums:
{ {
// m_stack->setCurrentWidget( m_gridView ); m_stack->setCurrentWidget( m_trackView );
break; break;
} }
} }
@@ -270,7 +289,7 @@ FlexibleTreeView::jumpToCurrentTrack()
// note: the order of comparison is important here, if we'd write "b || foo" then foo will not be executed if b is already true! // note: the order of comparison is important here, if we'd write "b || foo" then foo will not be executed if b is already true!
b = m_columnView->jumpToCurrentTrack() || b; b = m_columnView->jumpToCurrentTrack() || b;
// b = m_trackView->jumpToCurrentTrack() || b; b = m_trackView->jumpToCurrentTrack() || b;
b = m_treeView->jumpToCurrentTrack() || b; b = m_treeView->jumpToCurrentTrack() || b;
return b; return b;
@@ -284,8 +303,7 @@ FlexibleTreeView::setFilter( const QString& pattern )
m_columnView->setFilter( pattern ); m_columnView->setFilter( pattern );
m_treeView->proxyModel()->setFilter( pattern ); m_treeView->proxyModel()->setFilter( pattern );
/* m_gridView->setFilter( pattern ); m_trackView->setFilter( pattern );
m_trackView->setFilter( pattern );*/
return true; return true;
} }
@@ -318,8 +336,7 @@ FlexibleTreeView::setEmptyTip( const QString& tip )
{ {
m_columnView->setEmptyTip( tip ); m_columnView->setEmptyTip( tip );
m_treeView->setEmptyTip( tip ); m_treeView->setEmptyTip( tip );
/* m_gridView->setEmptyTip( tip ); m_trackView->setEmptyTip( tip );
m_trackView->setEmptyTip( tip );*/
} }

View File

@@ -31,6 +31,7 @@ class TrackView;
class TreeView; class TreeView;
class ColumnView; class ColumnView;
class TreeModel; class TreeModel;
class PlayableModel;
class ModeHeader; class ModeHeader;
class PlaylistModel; class PlaylistModel;
class FilterHeader; class FilterHeader;
@@ -70,6 +71,7 @@ public:
void setTrackView( TrackView* view ); void setTrackView( TrackView* view );
void setTreeModel( TreeModel* model ); void setTreeModel( TreeModel* model );
void setFlatModel( PlayableModel* model );
void setPixmap( const QPixmap& pixmap ); void setPixmap( const QPixmap& pixmap );
void setEmptyTip( const QString& tip ); void setEmptyTip( const QString& tip );
@@ -97,6 +99,7 @@ private:
TrackView* m_trackView; TrackView* m_trackView;
TreeModel* m_model; TreeModel* m_model;
PlayableModel* m_flatModel;
QStackedWidget* m_stack; QStackedWidget* m_stack;
FlexibleTreeViewMode m_mode; FlexibleTreeViewMode m_mode;

View File

@@ -682,8 +682,18 @@ PlayableModel::insertInternal( const QList< T >& items, int row, const QList< To
plitem->index = createIndex( row + i, 0, plitem ); plitem->index = createIndex( row + i, 0, plitem );
if ( plitem->query() ) if ( plitem->query() )
{ {
connect( plitem->query().data(), SIGNAL( playableStateChanged( bool ) ), SLOT( onQueryBecamePlayable( bool ) ), Qt::UniqueConnection ); if ( !plitem->query()->playable() )
connect( plitem->query().data(), SIGNAL( resolvingFinished( bool ) ), SLOT( onQueryResolved( bool ) ), Qt::UniqueConnection ); {
connect( plitem->query().data(), SIGNAL( playableStateChanged( bool ) ),
SLOT( onQueryBecamePlayable( bool ) ),
Qt::UniqueConnection );
}
if ( !plitem->query()->resolvingFinished() )
{
connect( plitem->query().data(), SIGNAL( resolvingFinished( bool ) ),
SLOT( onQueryResolved( bool ) ),
Qt::UniqueConnection );
}
} }
if ( logs.count() > i ) if ( logs.count() > i )
@@ -904,20 +914,26 @@ PlayableModel::onDataChanged()
void void
PlayableModel::startLoading() PlayableModel::startLoading()
{ {
tDebug() << Q_FUNC_INFO;
Q_D( PlayableModel ); Q_D( PlayableModel );
d->loading = true; if ( !d->loading )
emit loadingStarted(); {
tDebug() << Q_FUNC_INFO;
d->loading = true;
emit loadingStarted();
}
} }
void void
PlayableModel::finishLoading() PlayableModel::finishLoading()
{ {
tDebug() << Q_FUNC_INFO;
Q_D( PlayableModel ); Q_D( PlayableModel );
d->loading = false; if ( d->loading )
emit loadingFinished(); {
tDebug() << Q_FUNC_INFO;
d->loading = false;
emit loadingFinished();
}
} }
@@ -1000,6 +1016,13 @@ PlayableModel::appendTracks( const QList< Tomahawk::track_ptr >& tracks, const Q
} }
void
PlayableModel::appendTracks( const Tomahawk::collection_ptr& collection )
{
insertTracks( collection, rowCount( QModelIndex() ) );
}
void void
PlayableModel::insertArtist( const Tomahawk::artist_ptr& artist, int row ) PlayableModel::insertArtist( const Tomahawk::artist_ptr& artist, int row )
{ {
@@ -1053,6 +1076,25 @@ PlayableModel::insertQueries( const QList< Tomahawk::query_ptr >& queries, int r
} }
void
PlayableModel::insertTracks( const Tomahawk::collection_ptr& collection, int row )
{
Tomahawk::TracksRequest* req = collection->requestTracks( Tomahawk::album_ptr() );
connect( dynamic_cast< QObject* >( req ), SIGNAL( tracks( QList< Tomahawk::query_ptr > ) ),
this, SLOT( onTracksAdded( QList< Tomahawk::query_ptr > ) ), Qt::UniqueConnection );
req->enqueue();
// connect( collection.data(), SIGNAL( changed() ), SLOT( onCollectionChanged() ), Qt::UniqueConnection );
}
void
PlayableModel::onTracksAdded( const QList< Tomahawk::query_ptr >& queries )
{
appendQueries( queries );
}
void void
PlayableModel::setTitle( const QString& title ) PlayableModel::setTitle( const QString& title )
{ {

View File

@@ -158,6 +158,7 @@ public slots:
virtual void appendQuery( const Tomahawk::query_ptr& query ); virtual void appendQuery( const Tomahawk::query_ptr& query );
virtual void appendArtist( const Tomahawk::artist_ptr& artist ); virtual void appendArtist( const Tomahawk::artist_ptr& artist );
virtual void appendAlbum( const Tomahawk::album_ptr& album ); virtual void appendAlbum( const Tomahawk::album_ptr& album );
virtual void appendTracks( const Tomahawk::collection_ptr& collection );
virtual void insertQueries( const QList< Tomahawk::query_ptr >& queries, int row = 0, const QList< Tomahawk::PlaybackLog >& logs = QList< Tomahawk::PlaybackLog >() ); virtual void insertQueries( const QList< Tomahawk::query_ptr >& queries, int row = 0, const QList< Tomahawk::PlaybackLog >& logs = QList< Tomahawk::PlaybackLog >() );
virtual void insertArtists( const QList< Tomahawk::artist_ptr >& artists, int row = 0 ); virtual void insertArtists( const QList< Tomahawk::artist_ptr >& artists, int row = 0 );
@@ -165,6 +166,7 @@ public slots:
virtual void insertQuery( const Tomahawk::query_ptr& query, int row = 0, const Tomahawk::PlaybackLog& log = Tomahawk::PlaybackLog() ); virtual void insertQuery( const Tomahawk::query_ptr& query, int row = 0, const Tomahawk::PlaybackLog& log = Tomahawk::PlaybackLog() );
virtual void insertArtist( const Tomahawk::artist_ptr& artist, int row = 0 ); virtual void insertArtist( const Tomahawk::artist_ptr& artist, int row = 0 );
virtual void insertAlbum( const Tomahawk::album_ptr& album, int row = 0 ); virtual void insertAlbum( const Tomahawk::album_ptr& album, int row = 0 );
virtual void insertTracks( const Tomahawk::collection_ptr& collection, int row = 0 );
virtual bool removeRows( int row, int count, const QModelIndex& parent = QModelIndex() ); virtual bool removeRows( int row, int count, const QModelIndex& parent = QModelIndex() );
virtual void remove( int row, bool moreToCome = false ); virtual void remove( int row, bool moreToCome = false );
@@ -191,6 +193,8 @@ private slots:
void onPlaybackStarted( const Tomahawk::result_ptr result ); void onPlaybackStarted( const Tomahawk::result_ptr result );
void onPlaybackStopped(); void onPlaybackStopped();
void onTracksAdded( const QList< Tomahawk::query_ptr >& queries );
private: private:
void init(); void init();
template <typename T> template <typename T>

View File

@@ -295,52 +295,22 @@ PlayableProxyModel::setMaxVisibleItems( int items )
bool bool
PlayableProxyModel::lessThan( int column, const Tomahawk::query_ptr& q1, const Tomahawk::query_ptr& q2 ) const PlayableProxyModel::lessThan( int column, const Tomahawk::query_ptr& q1, const Tomahawk::query_ptr& q2 ) const
{ {
// Attention: This function may be called very often!
// So be aware of its performance.
const Tomahawk::track_ptr& t1 = q1->track(); const Tomahawk::track_ptr& t1 = q1->track();
const Tomahawk::track_ptr& t2 = q2->track(); const Tomahawk::track_ptr& t2 = q2->track();
const QString artist1 = t1->artistSortname(); const QString& artist1 = t1->artistSortname();
const QString artist2 = t2->artistSortname(); const QString& artist2 = t2->artistSortname();
const QString album1 = t1->albumSortname(); const QString& album1 = t1->albumSortname();
const QString album2 = t2->albumSortname(); const QString& album2 = t2->albumSortname();
const QString track1 = t1->trackSortname();
const QString track2 = t2->trackSortname();
const QString composer1 = t1->composerSortname();
const QString composer2 = t2->composerSortname();
const unsigned int albumpos1 = t1->albumpos(); const unsigned int albumpos1 = t1->albumpos();
const unsigned int albumpos2 = t2->albumpos(); const unsigned int albumpos2 = t2->albumpos();
const unsigned int discnumber1 = t1->discnumber(); const unsigned int discnumber1 = t1->discnumber();
const unsigned int discnumber2 = t2->discnumber(); const unsigned int discnumber2 = t2->discnumber();
unsigned int duration1 = t1->duration(), duration2 = t2->duration();
unsigned int bitrate1 = 0, bitrate2 = 0;
unsigned int mtime1 = 0, mtime2 = 0;
unsigned int size1 = 0, size2 = 0;
unsigned int year1 = 0, year2 = 0;
float score1 = 0, score2 = 0;
QString origin1;
QString origin2;
qint64 id1 = 0, id2 = 0; qint64 id1 = 0, id2 = 0;
if ( !q1->results().isEmpty() )
{
Tomahawk::result_ptr r = q1->results().first();
bitrate1 = r->bitrate();
mtime1 = r->modificationTime();
size1 = r->size();
year1 = r->track()->year();
score1 = r->score();
origin1 = r->friendlySource().toLower();
}
if ( !q2->results().isEmpty() )
{
Tomahawk::result_ptr r = q2->results().first();
bitrate2 = r->bitrate();
mtime2 = r->modificationTime();
size2 = r->size();
year2 = r->track()->year();
score2 = r->score();
origin2 = r->friendlySource().toLower();
}
// This makes it a stable sorter and prevents items from randomly jumping about. // This makes it a stable sorter and prevents items from randomly jumping about.
// FIXME: This always true.
if ( id1 == id2 ) if ( id1 == id2 )
{ {
id1 = (qint64)&q1; id1 = (qint64)&q1;
@@ -369,7 +339,11 @@ PlayableProxyModel::lessThan( int column, const Tomahawk::query_ptr& q1, const T
return QString::localeAwareCompare( artist1, artist2 ) < 0; return QString::localeAwareCompare( artist1, artist2 ) < 0;
} }
else if ( column == PlayableModel::Composer ) // sort by composer
// Sort by Composer
const QString& composer1 = t1->composerSortname();
const QString& composer2 = t2->composerSortname();
if ( column == PlayableModel::Composer )
{ {
if ( composer1 == composer2 ) if ( composer1 == composer2 )
{ {
@@ -391,7 +365,9 @@ PlayableProxyModel::lessThan( int column, const Tomahawk::query_ptr& q1, const T
return QString::localeAwareCompare( composer1, composer2 ) < 0; return QString::localeAwareCompare( composer1, composer2 ) < 0;
} }
else if ( column == PlayableModel::Album ) // sort by album
// Sort by Album
if ( column == PlayableModel::Album ) // sort by album
{ {
if ( album1 == album2 ) if ( album1 == album2 )
{ {
@@ -408,7 +384,38 @@ PlayableProxyModel::lessThan( int column, const Tomahawk::query_ptr& q1, const T
return QString::localeAwareCompare( album1, album2 ) < 0; return QString::localeAwareCompare( album1, album2 ) < 0;
} }
else if ( column == PlayableModel::Bitrate ) // sort by bitrate
// Lazy load these variables, they are not used before.
unsigned int bitrate1 = 0, bitrate2 = 0;
unsigned int mtime1 = 0, mtime2 = 0;
unsigned int size1 = 0, size2 = 0;
unsigned int year1 = 0, year2 = 0;
float score1 = 0, score2 = 0;
QString origin1;
QString origin2;
if ( !q1->results().isEmpty() )
{
Tomahawk::result_ptr r = q1->results().first();
bitrate1 = r->bitrate();
mtime1 = r->modificationTime();
size1 = r->size();
year1 = r->track()->year();
score1 = r->score();
origin1 = r->friendlySource().toLower();
}
if ( !q2->results().isEmpty() )
{
Tomahawk::result_ptr r = q2->results().first();
bitrate2 = r->bitrate();
mtime2 = r->modificationTime();
size2 = r->size();
year2 = r->track()->year();
score2 = r->score();
origin2 = r->friendlySource().toLower();
}
// Sort by bitrate
if ( column == PlayableModel::Bitrate )
{ {
if ( bitrate1 == bitrate2 ) if ( bitrate1 == bitrate2 )
return id1 < id2; return id1 < id2;
@@ -417,6 +424,9 @@ PlayableProxyModel::lessThan( int column, const Tomahawk::query_ptr& q1, const T
} }
else if ( column == PlayableModel::Duration ) // sort by duration else if ( column == PlayableModel::Duration ) // sort by duration
{ {
unsigned int duration1 = t1->duration();
unsigned int duration2 = t2->duration();
if ( duration1 == duration2 ) if ( duration1 == duration2 )
return id1 < id2; return id1 < id2;