1
0
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:
Uwe L. Korn 2014-07-17 02:06:48 +02:00
commit 082ab83c7f
17 changed files with 269 additions and 97 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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