mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-03-20 07:49:42 +01:00
Merge pull request #242 from tomahawk-player/flat-collection
Flat collection
This commit is contained in:
commit
082ab83c7f
@ -148,7 +148,10 @@ Pipeline::removeResolver( Resolver* r )
|
||||
|
||||
tDebug() << "Removed resolver:" << r->name();
|
||||
d->resolvers.removeAll( r );
|
||||
emit resolverRemoved( r );
|
||||
if ( d->running ) {
|
||||
// Only notify if Pipeline is still active.
|
||||
emit resolverRemoved( r );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -212,7 +212,7 @@ void
|
||||
Query::refreshResults()
|
||||
{
|
||||
Q_D( Query );
|
||||
if ( d->resolveFinished )
|
||||
if ( d->resolveFinished && d->allowReresolve )
|
||||
{
|
||||
d->resolveFinished = false;
|
||||
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
|
||||
Query::clearResults()
|
||||
{
|
||||
@ -530,9 +546,9 @@ Query::howSimilar( const Tomahawk::result_ptr& r )
|
||||
{
|
||||
Q_D( Query );
|
||||
// result values
|
||||
const QString rArtistname = r->track()->artistSortname();
|
||||
const QString& rArtistname = r->track()->artistSortname();
|
||||
const QString rAlbumname = r->track()->albumSortname();
|
||||
const QString rTrackname = r->track()->trackSortname();
|
||||
const QString& rTrackname = r->track()->trackSortname();
|
||||
|
||||
QString qArtistname;
|
||||
QString qAlbumname;
|
||||
|
@ -82,6 +82,18 @@ public:
|
||||
|
||||
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 );
|
||||
bool saveHTTPResultHint() const;
|
||||
|
||||
|
@ -18,6 +18,7 @@ public:
|
||||
|
||||
QueryPrivate( Query* q, const track_ptr& track, const QID& _qid )
|
||||
: q_ptr( q )
|
||||
, allowReresolve( true )
|
||||
, qid( _qid )
|
||||
, queryTrack( track )
|
||||
{
|
||||
@ -25,6 +26,7 @@ public:
|
||||
|
||||
QueryPrivate( Query* q, const QString& query, const QID& _qid )
|
||||
: q_ptr( q )
|
||||
, allowReresolve( true )
|
||||
, qid( _qid )
|
||||
, fullTextQuery( query )
|
||||
{
|
||||
@ -40,6 +42,7 @@ private:
|
||||
bool solved;
|
||||
bool playable;
|
||||
bool resolveFinished;
|
||||
bool allowReresolve;
|
||||
mutable QID qid;
|
||||
|
||||
QString fullTextQuery;
|
||||
|
@ -281,11 +281,14 @@ Result::onOffline()
|
||||
|
||||
|
||||
void
|
||||
Result::setCollection( const Tomahawk::collection_ptr& collection )
|
||||
Result::setCollection( const Tomahawk::collection_ptr& collection , bool emitOnlineEvents )
|
||||
{
|
||||
m_collection = collection;
|
||||
connect( m_collection->source().data(), SIGNAL( online() ), SLOT( onOnline() ), Qt::QueuedConnection );
|
||||
connect( m_collection->source().data(), SIGNAL( offline() ), SLOT( onOffline() ), Qt::QueuedConnection );
|
||||
if ( emitOnlineEvents )
|
||||
{
|
||||
connect( m_collection->source().data(), SIGNAL( online() ), SLOT( onOnline() ), Qt::QueuedConnection );
|
||||
connect( m_collection->source().data(), SIGNAL( offline() ), SLOT( onOffline() ), Qt::QueuedConnection );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -92,7 +92,12 @@ public:
|
||||
void setScore( float score );
|
||||
void setFileId( unsigned int 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 setPurchaseUrl( const QString& u );
|
||||
void setLinkUrl( const QString& u );
|
||||
|
@ -49,9 +49,24 @@ static QMutex s_nameCacheMutex;
|
||||
inline QString
|
||||
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;
|
||||
QTextStream stream( &str );
|
||||
stream << artist << track << album << composer << duration << albumpos << discnumber;
|
||||
// Preallocate space so that we will only call malloc once.
|
||||
// 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;
|
||||
}
|
||||
|
||||
@ -195,11 +210,19 @@ Track::init()
|
||||
Q_D( Track );
|
||||
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( socialActionsLoaded() ), SIGNAL( socialActionsLoaded() ) );
|
||||
connect( d->trackData.data(), SIGNAL( statsLoaded() ), SIGNAL( statsLoaded() ) );
|
||||
connect( d->trackData.data(), SIGNAL( similarTracksLoaded() ), SIGNAL( similarTracksLoaded() ) );
|
||||
connect( d->trackData.data(), SIGNAL( lyricsLoaded() ), SIGNAL( lyricsLoaded() ) );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -381,7 +404,7 @@ Track::toQuery()
|
||||
}
|
||||
|
||||
|
||||
QString
|
||||
const QString&
|
||||
Track::composerSortname() const
|
||||
{
|
||||
Q_D( const Track );
|
||||
@ -389,7 +412,7 @@ Track::composerSortname() const
|
||||
}
|
||||
|
||||
|
||||
QString
|
||||
const QString&
|
||||
Track::albumSortname() const
|
||||
{
|
||||
Q_D( const Track );
|
||||
@ -749,7 +772,7 @@ Track::share( const Tomahawk::source_ptr& source )
|
||||
}
|
||||
|
||||
|
||||
QString
|
||||
const QString&
|
||||
Track::artistSortname() const
|
||||
{
|
||||
Q_D( const Track );
|
||||
@ -757,7 +780,7 @@ Track::artistSortname() const
|
||||
}
|
||||
|
||||
|
||||
QString
|
||||
const QString&
|
||||
Track::trackSortname() const
|
||||
{
|
||||
Q_D( const Track );
|
||||
|
@ -68,10 +68,10 @@ public:
|
||||
QString toString() const;
|
||||
Tomahawk::query_ptr toQuery();
|
||||
|
||||
QString composerSortname() const;
|
||||
QString albumSortname() const;
|
||||
QString artistSortname() const;
|
||||
QString trackSortname() const;
|
||||
const QString& composerSortname() const;
|
||||
const QString& albumSortname() const;
|
||||
const QString& artistSortname() const;
|
||||
const QString& trackSortname() const;
|
||||
|
||||
QString artist() const;
|
||||
QString track() const;
|
||||
|
@ -55,8 +55,8 @@ public:
|
||||
QString toString() const;
|
||||
Tomahawk::query_ptr toQuery();
|
||||
|
||||
QString artistSortname() const { return m_artistSortname; }
|
||||
QString trackSortname() const { return m_trackSortname; }
|
||||
const QString& artistSortname() const { return m_artistSortname; }
|
||||
const QString& trackSortname() const { return m_trackSortname; }
|
||||
|
||||
QWeakPointer< Tomahawk::TrackData > weakRef() { return m_ownRef; }
|
||||
void setWeakRef( QWeakPointer< Tomahawk::TrackData > weakRef ) { m_ownRef = weakRef; }
|
||||
|
@ -305,10 +305,13 @@ ViewManager::show( const Tomahawk::collection_ptr& collection )
|
||||
|
||||
view->columnView()->proxyModel()->setStyle( PlayableProxyModel::Collection );
|
||||
TreeModel* model = new TreeModel();
|
||||
PlayableModel* flatModel = new PlayableModel();
|
||||
|
||||
view->setTreeModel( model );
|
||||
view->setFlatModel( flatModel );
|
||||
|
||||
model->addCollection( collection );
|
||||
flatModel->appendTracks( collection );
|
||||
setPage( view );
|
||||
|
||||
if ( !collection.isNull() )
|
||||
|
@ -76,8 +76,7 @@ DatabaseCommand_AllTracks::exec( DatabaseImpl* dbi )
|
||||
QString sql = QString(
|
||||
"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.mimetype, file_join.discnumber, file_join.albumpos, artist.id, " //11
|
||||
"album.id, track.id, composer.id " //15
|
||||
"file.mimetype, file_join.discnumber, file_join.albumpos, track.id " //11
|
||||
"FROM file, artist, track, file_join "
|
||||
"LEFT OUTER JOIN album "
|
||||
"ON file_join.album = album.id "
|
||||
@ -99,10 +98,38 @@ DatabaseCommand_AllTracks::exec( DatabaseImpl* dbi )
|
||||
query.prepare( sql );
|
||||
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() )
|
||||
{
|
||||
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();
|
||||
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 )
|
||||
{
|
||||
Q_ASSERT( false );
|
||||
@ -111,30 +138,31 @@ DatabaseCommand_AllTracks::exec( DatabaseImpl* dbi )
|
||||
if ( !s->isLocal() )
|
||||
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::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() );
|
||||
t->loadAttributes();
|
||||
if ( m_album || m_artist ) {
|
||||
t->loadAttributes();
|
||||
}
|
||||
result->setTrack( t );
|
||||
|
||||
result->setSize( query.value( 5 ).toUInt() );
|
||||
result->setBitrate( query.value( 7 ).toUInt() );
|
||||
result->setModificationTime( query.value( 10 ).toUInt() );
|
||||
result->setMimetype( query.value( 11 ).toString() );
|
||||
result->setSize( size );
|
||||
result->setBitrate( bitrate );
|
||||
result->setModificationTime( modificationTime );
|
||||
result->setMimetype( mimetype );
|
||||
result->setScore( 1.0 );
|
||||
result->setCollection( s->dbCollection() );
|
||||
result->setCollection( s->dbCollection(), false );
|
||||
|
||||
QList<Tomahawk::result_ptr> results;
|
||||
results << result;
|
||||
qry->addResults( results );
|
||||
qry->setResolveFinished( true );
|
||||
// These tracks are fixed to the Source. Do not re-resolve.
|
||||
qry->disallowReresolve();
|
||||
|
||||
ql << qry;
|
||||
}
|
||||
|
@ -538,7 +538,7 @@ Tomahawk::DatabaseImpl::getTrackFids( int tid )
|
||||
QString
|
||||
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 " ) )
|
||||
{
|
||||
|
@ -48,14 +48,14 @@ FlexibleTreeView::FlexibleTreeView( QWidget* parent, QWidget* extraHeader )
|
||||
, m_modeHeader( new ModeHeader( this ) )
|
||||
, m_columnView( new ColumnView() )
|
||||
, m_treeView( new TreeView() )
|
||||
, m_trackView( 0 )
|
||||
, m_trackView( new TrackView() )
|
||||
, m_model( 0 )
|
||||
, m_flatModel( 0 )
|
||||
, m_temporary( false )
|
||||
{
|
||||
qRegisterMetaType< FlexibleTreeViewMode >( "FlexibleTreeViewMode" );
|
||||
|
||||
m_treeView->proxyModel()->setStyle( PlayableProxyModel::Collection );
|
||||
|
||||
m_treeView->proxyModel()->setPlaylistInterface( m_columnView->proxyModel()->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_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 ) ) );
|
||||
|
||||
@ -182,7 +181,6 @@ FlexibleTreeView::setTreeModel( TreeModel* model )
|
||||
// m_trackView->setPlayableModel( model );
|
||||
m_columnView->setTreeModel( model );
|
||||
m_treeView->setTreeModel( model );
|
||||
// m_gridView->setPlayableModel( model );
|
||||
|
||||
/* m_trackView->setSortingEnabled( false );
|
||||
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
|
||||
FlexibleTreeView::setCurrentMode( FlexibleTreeViewMode mode )
|
||||
{
|
||||
@ -224,7 +243,7 @@ FlexibleTreeView::setCurrentMode( FlexibleTreeViewMode mode )
|
||||
|
||||
case Albums:
|
||||
{
|
||||
// m_stack->setCurrentWidget( m_gridView );
|
||||
m_stack->setCurrentWidget( m_trackView );
|
||||
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!
|
||||
b = m_columnView->jumpToCurrentTrack() || b;
|
||||
// b = m_trackView->jumpToCurrentTrack() || b;
|
||||
b = m_trackView->jumpToCurrentTrack() || b;
|
||||
b = m_treeView->jumpToCurrentTrack() || b;
|
||||
|
||||
return b;
|
||||
@ -284,8 +303,7 @@ FlexibleTreeView::setFilter( const QString& pattern )
|
||||
|
||||
m_columnView->setFilter( pattern );
|
||||
m_treeView->proxyModel()->setFilter( pattern );
|
||||
/* m_gridView->setFilter( pattern );
|
||||
m_trackView->setFilter( pattern );*/
|
||||
m_trackView->setFilter( pattern );
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -318,8 +336,7 @@ FlexibleTreeView::setEmptyTip( const QString& tip )
|
||||
{
|
||||
m_columnView->setEmptyTip( tip );
|
||||
m_treeView->setEmptyTip( tip );
|
||||
/* m_gridView->setEmptyTip( tip );
|
||||
m_trackView->setEmptyTip( tip );*/
|
||||
m_trackView->setEmptyTip( tip );
|
||||
}
|
||||
|
||||
|
||||
|
@ -31,6 +31,7 @@ class TrackView;
|
||||
class TreeView;
|
||||
class ColumnView;
|
||||
class TreeModel;
|
||||
class PlayableModel;
|
||||
class ModeHeader;
|
||||
class PlaylistModel;
|
||||
class FilterHeader;
|
||||
@ -70,6 +71,7 @@ public:
|
||||
void setTrackView( TrackView* view );
|
||||
|
||||
void setTreeModel( TreeModel* model );
|
||||
void setFlatModel( PlayableModel* model );
|
||||
|
||||
void setPixmap( const QPixmap& pixmap );
|
||||
void setEmptyTip( const QString& tip );
|
||||
@ -97,6 +99,7 @@ private:
|
||||
TrackView* m_trackView;
|
||||
|
||||
TreeModel* m_model;
|
||||
PlayableModel* m_flatModel;
|
||||
QStackedWidget* m_stack;
|
||||
|
||||
FlexibleTreeViewMode m_mode;
|
||||
|
@ -682,8 +682,18 @@ PlayableModel::insertInternal( const QList< T >& items, int row, const QList< To
|
||||
plitem->index = createIndex( row + i, 0, plitem );
|
||||
if ( plitem->query() )
|
||||
{
|
||||
connect( plitem->query().data(), SIGNAL( playableStateChanged( bool ) ), SLOT( onQueryBecamePlayable( bool ) ), Qt::UniqueConnection );
|
||||
connect( plitem->query().data(), SIGNAL( resolvingFinished( bool ) ), SLOT( onQueryResolved( bool ) ), Qt::UniqueConnection );
|
||||
if ( !plitem->query()->playable() )
|
||||
{
|
||||
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 )
|
||||
@ -904,20 +914,26 @@ PlayableModel::onDataChanged()
|
||||
void
|
||||
PlayableModel::startLoading()
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO;
|
||||
Q_D( PlayableModel );
|
||||
d->loading = true;
|
||||
emit loadingStarted();
|
||||
if ( !d->loading )
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO;
|
||||
d->loading = true;
|
||||
emit loadingStarted();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PlayableModel::finishLoading()
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO;
|
||||
Q_D( PlayableModel );
|
||||
d->loading = false;
|
||||
emit loadingFinished();
|
||||
if ( d->loading )
|
||||
{
|
||||
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
|
||||
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
|
||||
PlayableModel::setTitle( const QString& title )
|
||||
{
|
||||
|
@ -158,6 +158,7 @@ public slots:
|
||||
virtual void appendQuery( const Tomahawk::query_ptr& query );
|
||||
virtual void appendArtist( const Tomahawk::artist_ptr& artist );
|
||||
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 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 insertArtist( const Tomahawk::artist_ptr& artist, 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 void remove( int row, bool moreToCome = false );
|
||||
@ -191,6 +193,8 @@ private slots:
|
||||
void onPlaybackStarted( const Tomahawk::result_ptr result );
|
||||
void onPlaybackStopped();
|
||||
|
||||
void onTracksAdded( const QList< Tomahawk::query_ptr >& queries );
|
||||
|
||||
private:
|
||||
void init();
|
||||
template <typename T>
|
||||
|
@ -295,52 +295,22 @@ PlayableProxyModel::setMaxVisibleItems( int items )
|
||||
bool
|
||||
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& t2 = q2->track();
|
||||
const QString artist1 = t1->artistSortname();
|
||||
const QString artist2 = t2->artistSortname();
|
||||
const QString album1 = t1->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 QString& artist1 = t1->artistSortname();
|
||||
const QString& artist2 = t2->artistSortname();
|
||||
const QString& album1 = t1->albumSortname();
|
||||
const QString& album2 = t2->albumSortname();
|
||||
const unsigned int albumpos1 = t1->albumpos();
|
||||
const unsigned int albumpos2 = t2->albumpos();
|
||||
const unsigned int discnumber1 = t1->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;
|
||||
|
||||
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.
|
||||
// FIXME: This always true.
|
||||
if ( id1 == id2 )
|
||||
{
|
||||
id1 = (qint64)&q1;
|
||||
@ -369,7 +339,11 @@ PlayableProxyModel::lessThan( int column, const Tomahawk::query_ptr& q1, const T
|
||||
|
||||
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 )
|
||||
{
|
||||
@ -391,7 +365,9 @@ PlayableProxyModel::lessThan( int column, const Tomahawk::query_ptr& q1, const T
|
||||
|
||||
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 )
|
||||
{
|
||||
@ -408,7 +384,38 @@ PlayableProxyModel::lessThan( int column, const Tomahawk::query_ptr& q1, const T
|
||||
|
||||
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 )
|
||||
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
|
||||
{
|
||||
unsigned int duration1 = t1->duration();
|
||||
unsigned int duration2 = t2->duration();
|
||||
|
||||
if ( duration1 == duration2 )
|
||||
return id1 < id2;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user