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:
@@ -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 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -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;
|
||||||
|
@@ -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;
|
||||||
|
|
||||||
|
@@ -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;
|
||||||
|
@@ -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
|
||||||
|
@@ -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 );
|
||||||
|
@@ -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 );
|
||||||
|
@@ -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;
|
||||||
|
@@ -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; }
|
||||||
|
@@ -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() )
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
@@ -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 " ) )
|
||||||
{
|
{
|
||||||
|
@@ -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 );*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -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;
|
||||||
|
@@ -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 )
|
||||||
{
|
{
|
||||||
|
@@ -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>
|
||||||
|
@@ -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;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user