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

* Added InfoSystem support to TreeModel.

* Added 'Official Releases Only' toggle-button on Artist Page.
* Cleaned up a few sources.
This commit is contained in:
Christian Muehlhaeuser 2011-09-09 10:27:37 +02:00
parent 20eeaf73ac
commit 92240b6e0c
18 changed files with 543 additions and 157 deletions

View File

@ -197,6 +197,7 @@ set( libSources
widgets/HeaderLabel.cpp
widgets/HeaderWidget.cpp
widgets/combobox.cpp
widgets/ToggleButton.cpp
widgets/SocialPlaylistWidget.cpp
widgets/infowidgets/sourceinfowidget.cpp
widgets/infowidgets/ArtistInfoWidget.cpp
@ -395,6 +396,7 @@ set( libHeaders
widgets/HeaderLabel.h
widgets/HeaderWidget.h
widgets/combobox.h
widgets/ToggleButton.h
widgets/SocialPlaylistWidget.h
widgets/infowidgets/sourceinfowidget.h
widgets/infowidgets/ArtistInfoWidget.h

View File

@ -419,20 +419,20 @@ LastFmPlugin::notInCacheSlot( uint requestId, QHash<QString, QString> criteria,
case InfoChartCapabilities:
{
QList<Chart> track_charts;
track_charts.append(Chart("chart.getTopTracks", "Top Tracks", "tracks"));
track_charts.append(Chart("chart.getLovedTracks", "Loved Tracks", "tracks"));
track_charts.append(Chart("chart.getHypedTracks", "Hyped Tracks", "tracks"));
track_charts.append( Chart( "chart.getTopTracks", "Top Tracks", "tracks" ) );
track_charts.append( Chart( "chart.getLovedTracks", "Loved Tracks", "tracks" ) );
track_charts.append( Chart( "chart.getHypedTracks", "Hyped Tracks", "tracks" ) );
QList<Chart> artist_charts;
artist_charts.append(Chart("chart.getTopArtists", "Top Artists", "artists"));
artist_charts.append(Chart("chart.getHypedArtists", "Hyped Artists", "artists"));
artist_charts.append( Chart( "chart.getTopArtists", "Top Artists", "artists" ) );
artist_charts.append( Chart( "chart.getHypedArtists", "Hyped Artists", "artists" ) );
QVariantMap charts;
charts.insert("Tracks", QVariant::fromValue<QList<Chart> >(track_charts));
charts.insert("Artists", QVariant::fromValue<QList<Chart> >(artist_charts));
charts.insert( "Tracks", QVariant::fromValue<QList<Chart> >( track_charts ) );
charts.insert( "Artists", QVariant::fromValue<QList<Chart> >( artist_charts ) );
QVariantMap result;
result.insert("Last.fm", QVariant::fromValue<QVariantMap>(charts));
result.insert( "Last.fm", QVariant::fromValue<QVariantMap>( charts ) );
emit info(
requestId,
@ -533,6 +533,7 @@ LastFmPlugin::similarArtistsReturned()
emit updateCache( criteria, 2419200000, requestData.type, returnedData );
}
void
LastFmPlugin::chartReturned()
{
@ -544,7 +545,8 @@ LastFmPlugin::chartReturned()
const QRegExp artists_rx( "chart\\.\\S+artists\\S*", Qt::CaseInsensitive );
const QString url = reply->url().toString();
if( url.contains( tracks_rx ) ) {
if ( url.contains( tracks_rx ) )
{
QList<lastfm::Track> tracks = parseTrackList( reply );
QList<ArtistTrackPair> top_tracks;
foreach( const lastfm::Track &t, tracks ) {
@ -557,7 +559,9 @@ LastFmPlugin::chartReturned()
returnedData["tracks"] = QVariant::fromValue( top_tracks );
returnedData["type"] = "tracks";
} else if( url.contains( artists_rx ) ) {
}
else if ( url.contains( artists_rx ) )
{
QList<lastfm::Artist> list = lastfm::Artist::list( reply );
QStringList al;
tDebug() << "LastFmPlugin:"<< "\tgot " << list.size() << " artists";
@ -565,7 +569,9 @@ LastFmPlugin::chartReturned()
al << a.toString();
returnedData["artists"] = al;
returnedData["type"] = "artists";
} else {
}
else
{
tDebug() << "LastfmPlugin:: got non tracks and non artists";
}
@ -579,6 +585,7 @@ LastFmPlugin::chartReturned()
// TODO update cache
}
void
LastFmPlugin::topTracksReturned()
{

View File

@ -31,7 +31,7 @@ MusicBrainzPlugin::MusicBrainzPlugin()
: InfoPlugin()
{
qDebug() << Q_FUNC_INFO;
m_supportedGetTypes << Tomahawk::InfoSystem::InfoArtistReleases;
m_supportedGetTypes << Tomahawk::InfoSystem::InfoArtistReleases << Tomahawk::InfoSystem::InfoAlbumSongs;
}
@ -44,7 +44,6 @@ MusicBrainzPlugin::~MusicBrainzPlugin()
void
MusicBrainzPlugin::namChangedSlot( QNetworkAccessManager *nam )
{
qDebug() << Q_FUNC_INFO;
if ( !nam )
return;
@ -55,8 +54,6 @@ MusicBrainzPlugin::namChangedSlot( QNetworkAccessManager *nam )
void
MusicBrainzPlugin::getInfo( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData )
{
qDebug() << Q_FUNC_INFO;
if ( !requestData.input.canConvert< Tomahawk::InfoSystem::InfoCriteriaHash >() )
{
emit info( requestId, requestData, QVariant() );
@ -69,16 +66,39 @@ MusicBrainzPlugin::getInfo( uint requestId, Tomahawk::InfoSystem::InfoRequestDat
return;
}
if ( requestData.type == InfoArtistReleases )
switch ( requestData.type )
{
QString requestString( "http://musicbrainz.org/ws/2/artist" );
QUrl url( requestString );
url.addQueryItem( "query", hash["artist"] );
QNetworkReply* reply = m_nam.data()->get( QNetworkRequest( url ) );
reply->setProperty( "requestId", requestId );
reply->setProperty( "requestData", QVariant::fromValue< Tomahawk::InfoSystem::InfoRequestData >( requestData ) );
case InfoArtistReleases:
{
QString requestString( "http://musicbrainz.org/ws/2/artist" );
QUrl url( requestString );
url.addQueryItem( "query", hash["artist"] );
QNetworkReply* reply = m_nam.data()->get( QNetworkRequest( url ) );
reply->setProperty( "requestId", requestId );
reply->setProperty( "requestData", QVariant::fromValue< Tomahawk::InfoSystem::InfoRequestData >( requestData ) );
connect( reply, SIGNAL( finished() ), SLOT( artistSearchSlot() ) );
connect( reply, SIGNAL( finished() ), SLOT( artistSearchSlot() ) );
break;
}
case InfoAlbumSongs:
{
QString requestString( "http://musicbrainz.org/ws/2/artist" );
QUrl url( requestString );
url.addQueryItem( "query", hash["artist"] );
QNetworkReply* reply = m_nam.data()->get( QNetworkRequest( url ) );
reply->setProperty( "requestId", requestId );
reply->setProperty( "requestData", QVariant::fromValue< Tomahawk::InfoSystem::InfoRequestData >( requestData ) );
connect( reply, SIGNAL( finished() ), SLOT( albumSearchSlot() ) );
break;
}
default:
{
Q_ASSERT( false );
break;
}
}
}
@ -86,7 +106,6 @@ MusicBrainzPlugin::getInfo( uint requestId, Tomahawk::InfoSystem::InfoRequestDat
bool
MusicBrainzPlugin::isValidTrackData( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData )
{
qDebug() << Q_FUNC_INFO;
if ( requestData.input.isNull() || !requestData.input.isValid() || !requestData.input.canConvert< QVariantMap >() )
{
emit info( requestId, requestData, QVariant() );
@ -113,7 +132,6 @@ MusicBrainzPlugin::isValidTrackData( uint requestId, Tomahawk::InfoSystem::InfoR
void
MusicBrainzPlugin::artistSearchSlot()
{
qDebug() << Q_FUNC_INFO;
QNetworkReply* oldReply = qobject_cast<QNetworkReply*>( sender() );
if ( !oldReply )
return; //timeout will handle it
@ -131,17 +149,89 @@ MusicBrainzPlugin::artistSearchSlot()
QString requestString( "http://musicbrainz.org/ws/2/release?status=official&type=album|ep" );
QUrl url( requestString );
url.addQueryItem( "artist", artist_id );
QNetworkReply* newReply = m_nam.data()->get( QNetworkRequest( url ) );
newReply->setProperty( "requestId", oldReply->property( "requestId" ) );
newReply->setProperty( "requestData", oldReply->property( "requestData" ) );
connect( newReply, SIGNAL( finished() ), SLOT( albumSearchSlot() ) );
connect( newReply, SIGNAL( finished() ), SLOT( albumFoundSlot() ) );
}
void
MusicBrainzPlugin::albumSearchSlot()
{
qDebug() << Q_FUNC_INFO;
QNetworkReply* oldReply = qobject_cast<QNetworkReply*>( sender() );
if ( !oldReply )
return; //timeout will handle it
QDomDocument doc;
doc.setContent( oldReply->readAll() );
QDomNodeList domNodeList = doc.elementsByTagName( "artist" );
if ( domNodeList.isEmpty() )
{
emit info( oldReply->property( "requestId" ).toUInt(), oldReply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >(), QVariant() );
return;
}
QString artist_id = domNodeList.at( 0 ).toElement().attribute( "id" );
QString requestString( "http://musicbrainz.org/ws/2/release?status=official&type=album|ep" );
QUrl url( requestString );
url.addQueryItem( "artist", artist_id );
QNetworkReply* newReply = m_nam.data()->get( QNetworkRequest( url ) );
newReply->setProperty( "requestId", oldReply->property( "requestId" ) );
newReply->setProperty( "requestData", oldReply->property( "requestData" ) );
connect( newReply, SIGNAL( finished() ), SLOT( tracksSearchSlot() ) );
}
void
MusicBrainzPlugin::tracksSearchSlot()
{
QNetworkReply* oldReply = qobject_cast<QNetworkReply*>( sender() );
if ( !oldReply )
return; //timeout will handle it
QDomDocument doc;
doc.setContent( oldReply->readAll() );
QDomNodeList domNodeList = doc.elementsByTagName( "release" );
if ( domNodeList.isEmpty() )
{
emit info( oldReply->property( "requestId" ).toUInt(), oldReply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >(), QVariant() );
return;
}
Tomahawk::InfoSystem::InfoRequestData requestData = oldReply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >();
InfoCriteriaHash hash = requestData.input.value< Tomahawk::InfoSystem::InfoCriteriaHash >();
QDomElement element;
for ( int i = 0; i < domNodeList.count(); i++ )
{
QDomNodeList albumNodeList = domNodeList.at( i ).toElement().elementsByTagName( "title" );
if ( albumNodeList.at( 0 ).toElement().text() == hash["album"] )
element = domNodeList.at( i ).toElement();
}
if ( element.isNull() )
{
emit info( oldReply->property( "requestId" ).toUInt(), oldReply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >(), QVariant() );
return;
}
QString release_id = element.attribute( "id" );
QString requestString = QString( "http://musicbrainz.org/ws/2/release/%1?inc=recordings" ).arg( release_id );
QUrl url( requestString );
QNetworkReply* newReply = m_nam.data()->get( QNetworkRequest( url ) );
newReply->setProperty( "requestId", oldReply->property( "requestId" ) );
newReply->setProperty( "requestData", oldReply->property( "requestData" ) );
connect( newReply, SIGNAL( finished() ), SLOT( tracksFoundSlot() ) );
}
void
MusicBrainzPlugin::albumFoundSlot()
{
QNetworkReply* reply = qobject_cast< QNetworkReply* >( sender() );
if ( !reply )
return; //timeout will handle it
@ -163,6 +253,55 @@ MusicBrainzPlugin::albumSearchSlot()
albums << album;
}
qDebug() << Q_FUNC_INFO << "Found albums:" << albums;
emit info( reply->property( "requestId" ).toUInt(), reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >(), QVariant( albums ) );
Tomahawk::InfoSystem::InfoRequestData requestData = reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >();
QVariantMap returnedData;
returnedData["albums"] = albums;
emit info( reply->property( "requestId" ).toUInt(), requestData, returnedData );
Tomahawk::InfoSystem::InfoCriteriaHash origData = requestData.input.value< Tomahawk::InfoSystem::InfoCriteriaHash>();
Tomahawk::InfoSystem::InfoCriteriaHash criteria;
criteria["artist"] = origData["artist"];
emit updateCache( criteria, 0, requestData.type, returnedData );
}
void
MusicBrainzPlugin::tracksFoundSlot()
{
QNetworkReply* reply = qobject_cast< QNetworkReply* >( sender() );
if ( !reply )
return; //timeout will handle it
QDomDocument doc;
doc.setContent( reply->readAll() );
QDomNodeList domNodeList = doc.elementsByTagName( "recording" );
if ( domNodeList.isEmpty() )
{
emit info( reply->property( "requestId" ).toUInt(), reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >(), QVariant() );
return;
}
QStringList tracks;
for ( int i = 0; i < domNodeList.count(); i++ )
{
QDomNodeList trackNodeList = domNodeList.at( i ).toElement().elementsByTagName( "title" );
for ( int j = 0; j < trackNodeList.count(); j++ )
{
QString track = trackNodeList.at( j ).toElement().text();
if ( !tracks.contains( track ) )
tracks << track;
}
}
Tomahawk::InfoSystem::InfoRequestData requestData = reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >();
QVariantMap returnedData;
returnedData["tracks"] = tracks;
emit info( reply->property( "requestId" ).toUInt(), requestData, returnedData );
Tomahawk::InfoSystem::InfoCriteriaHash origData = requestData.input.value< Tomahawk::InfoSystem::InfoCriteriaHash>();
Tomahawk::InfoSystem::InfoCriteriaHash criteria;
criteria["artist"] = origData["artist"];
criteria["album"] = origData["album"];
emit updateCache( criteria, 0, requestData.type, returnedData );
}

View File

@ -61,6 +61,10 @@ virtual void notInCacheSlot( uint requestId, Tomahawk::InfoSystem::InfoCriteriaH
private slots:
void artistSearchSlot();
void albumSearchSlot();
void tracksSearchSlot();
void albumFoundSlot();
void tracksFoundSlot();
private:
bool isValidTrackData( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData );

View File

@ -109,11 +109,7 @@ TrackModelItem::setupItem( const Tomahawk::query_ptr& query, TrackModelItem* par
m_isPlaying = false;
toberemoved = false;
m_query = query;
if ( query->numResults() )
{
// emit dataChanged();
}
else
if ( !query->numResults() )
{
connect( query.data(), SIGNAL( resultsAdded( QList<Tomahawk::result_ptr> ) ),
SIGNAL( dataChanged() ) );

View File

@ -69,9 +69,9 @@ TreeItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option,
{
text = item->album()->name();
}
else if ( !item->result().isNull() )
else if ( !item->result().isNull() || !item->query().isNull() )
{
float opacity = item->result()->score();
float opacity = item->result().isNull() ? 0.0 : item->result()->score();
opacity = qMax( (float)0.3, opacity );
QColor textColor = TomahawkUtils::alphaBlend( option.palette.color( QPalette::Foreground ), option.palette.color( QPalette::Background ), opacity );

View File

@ -29,15 +29,15 @@
#include "utils/tomahawkutils.h"
#include "utils/logger.h"
static QString s_tmInfoIdentifier = QString( "TREEMODEL" );
using namespace Tomahawk;
TreeModel::TreeModel( QObject* parent )
: QAbstractItemModel( parent )
, m_rootItem( new TreeModelItem( 0, this ) )
, m_infoId( uuid() )
, m_columnStyle( AllColumns )
, m_mode( Database )
{
setIcon( QPixmap( RESPATH "images/music-icon.png" ) );
@ -100,7 +100,7 @@ TreeModel::getCover( const QModelIndex& index )
trackInfo["pptr"] = QString::number( (qlonglong)item );
m_coverHash.insert( (qlonglong)item, index );
requestData.caller = s_tmInfoIdentifier;
requestData.caller = m_infoId;
requestData.input = QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo );
requestData.customData = QVariantMap();
Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( requestData );
@ -261,7 +261,7 @@ TreeModel::data( const QModelIndex& index, int role ) const
if ( role == Qt::SizeHintRole )
{
if ( !entry->result().isNull() )
if ( !entry->result().isNull() || !entry->query().isNull() )
{
return QSize( 128, 20 );
}
@ -288,7 +288,7 @@ TreeModel::data( const QModelIndex& index, int role ) const
{
return entry->album()->name();
}
else
else if ( !entry->result().isNull() )
{
const result_ptr& result = entry->result();
switch( index.column() )
@ -322,6 +322,10 @@ TreeModel::data( const QModelIndex& index, int role ) const
return QVariant();
}
}
else if ( !entry->query().isNull() && index.column() == Name )
{
return entry->query()->track();
}
return QVariant();
}
@ -408,7 +412,7 @@ TreeModel::mimeData( const QModelIndexList &indexes ) const
// lets try with album only
fail = false;
resultData.clear();
foreach ( const QModelIndex& i, indexes)
foreach ( const QModelIndex& i, indexes )
{
if ( i.column() > 0 || indexes.contains( i.parent() ) )
continue;
@ -436,11 +440,10 @@ TreeModel::mimeData( const QModelIndexList &indexes ) const
return mimeData;
}
// lets try with tracks only
fail = false;
resultData.clear();
foreach ( const QModelIndex& i, indexes)
foreach ( const QModelIndex& i, indexes )
{
if ( i.column() > 0 || indexes.contains( i.parent() ) )
continue;
@ -549,8 +552,6 @@ TreeModel::addAllCollections()
void
TreeModel::addArtists( const artist_ptr& artist )
{
qDebug() << Q_FUNC_INFO;
if ( artist.isNull() )
return;
@ -565,37 +566,70 @@ TreeModel::addArtists( const artist_ptr& artist )
void
TreeModel::addAlbums( const artist_ptr& artist, const QModelIndex& parent )
{
qDebug() << Q_FUNC_INFO;
emit loadingStarted();
DatabaseCommand_AllAlbums* cmd = new DatabaseCommand_AllAlbums( m_collection, artist );
cmd->setData( parent.row() );
connect( cmd, SIGNAL( albums( QList<Tomahawk::album_ptr>, QVariant ) ),
SLOT( onAlbumsAdded( QList<Tomahawk::album_ptr>, QVariant ) ) );
if ( m_mode == Database )
{
DatabaseCommand_AllAlbums* cmd = new DatabaseCommand_AllAlbums( m_collection, artist );
cmd->setData( parent.row() );
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>( cmd ) );
connect( cmd, SIGNAL( albums( QList<Tomahawk::album_ptr>, QVariant ) ),
SLOT( onAlbumsAdded( QList<Tomahawk::album_ptr>, QVariant ) ) );
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>( cmd ) );
}
else if ( m_mode == InfoSystem )
{
Tomahawk::InfoSystem::InfoCriteriaHash artistInfo;
artistInfo["artist"] = artist->name();
Tomahawk::InfoSystem::InfoRequestData requestData;
requestData.caller = m_infoId;
requestData.customData["row"] = parent.row();
requestData.input = QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( artistInfo );
requestData.type = Tomahawk::InfoSystem::InfoArtistReleases;
Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( requestData );
}
else
Q_ASSERT( false );
}
void
TreeModel::addTracks( const album_ptr& album, const QModelIndex& parent )
{
qDebug() << Q_FUNC_INFO;
emit loadingStarted();
DatabaseCommand_AllTracks* cmd = new DatabaseCommand_AllTracks( m_collection );
cmd->setAlbum( album.data() );
QList< QVariant > rows;
rows << parent.row();
rows << parent.parent().row();
cmd->setData( QVariant( rows ) );
connect( cmd, SIGNAL( tracks( QList<Tomahawk::query_ptr>, QVariant ) ),
SLOT( onTracksAdded( QList<Tomahawk::query_ptr>, QVariant ) ) );
if ( m_mode == Database )
{
DatabaseCommand_AllTracks* cmd = new DatabaseCommand_AllTracks( m_collection );
cmd->setAlbum( album.data() );
cmd->setData( QVariant( rows ) );
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>( cmd ) );
connect( cmd, SIGNAL( tracks( QList<Tomahawk::query_ptr>, QVariant ) ),
SLOT( onTracksAdded( QList<Tomahawk::query_ptr>, QVariant ) ) );
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>( cmd ) );
}
else if ( m_mode == InfoSystem )
{
Tomahawk::InfoSystem::InfoCriteriaHash artistInfo;
artistInfo["artist"] = album->artist()->name();
artistInfo["album"] = album->name();
Tomahawk::InfoSystem::InfoRequestData requestData;
requestData.caller = m_infoId;
requestData.customData["rows"] = QVariant( rows );
requestData.input = QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( artistInfo );
requestData.type = Tomahawk::InfoSystem::InfoAlbumSongs;
Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( requestData );
}
else
Q_ASSERT( false );
}
@ -714,6 +748,7 @@ TreeModel::onTracksAdded( const QList<Tomahawk::query_ptr>& tracks, const QVaria
return;
QList< QVariant > rows = data.toList();
tDebug() << "Adding to:" << rows;
QModelIndex parent = index( rows.first().toUInt(), 0, index( rows.at( 1 ).toUInt(), 0, QModelIndex() ) );
TreeModelItem* parentItem = itemFromIndex( parent );
@ -728,8 +763,11 @@ TreeModel::onTracksAdded( const QList<Tomahawk::query_ptr>& tracks, const QVaria
TreeModelItem* item = 0;
foreach( const query_ptr& query, tracks )
{
qDebug() << query->toString();
item = new TreeModelItem( query->results().first(), parentItem );
if ( query->numResults() )
item = new TreeModelItem( query->results().first(), parentItem );
else
item = new TreeModelItem( query, parentItem );
item->index = createIndex( parentItem->children.count() - 1, 0, item );
connect( item, SIGNAL( dataChanged() ), SLOT( onDataChanged() ) );
@ -742,35 +780,84 @@ TreeModel::onTracksAdded( const QList<Tomahawk::query_ptr>& tracks, const QVaria
void
TreeModel::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output )
{
if ( requestData.caller != s_tmInfoIdentifier ||
( requestData.type != Tomahawk::InfoSystem::InfoAlbumCoverArt && requestData.type != Tomahawk::InfoSystem::InfoArtistImages ) )
if ( requestData.caller != m_infoId )
{
return;
}
if ( !output.canConvert< QVariantMap >() )
switch ( requestData.type )
{
qDebug() << "Cannot convert fetched art from a QByteArray";
return;
}
case Tomahawk::InfoSystem::InfoAlbumCoverArt:
case Tomahawk::InfoSystem::InfoArtistImages:
{
Tomahawk::InfoSystem::InfoCriteriaHash pptr = requestData.input.value< Tomahawk::InfoSystem::InfoCriteriaHash >();
QVariantMap returnedData = output.value< QVariantMap >();
const QByteArray ba = returnedData["imgbytes"].toByteArray();
if ( ba.length() )
{
QPixmap pm;
pm.loadFromData( ba );
bool ok;
qlonglong p = pptr["pptr"].toLongLong( &ok );
TreeModelItem* ai = itemFromIndex( m_coverHash.take( p ) );
if ( !ai )
return;
Tomahawk::InfoSystem::InfoCriteriaHash pptr = requestData.input.value< Tomahawk::InfoSystem::InfoCriteriaHash >();
QVariantMap returnedData = output.value< QVariantMap >();
const QByteArray ba = returnedData["imgbytes"].toByteArray();
if ( ba.length() )
{
QPixmap pm;
pm.loadFromData( ba );
bool ok;
qlonglong p = pptr["pptr"].toLongLong( &ok );
TreeModelItem* ai = itemFromIndex( m_coverHash.take( p ) );
if ( !ai )
return;
if ( !pm.isNull() )
ai->cover = pm;
if ( !pm.isNull() )
ai->cover = pm;
emit dataChanged( ai->index, ai->index.sibling( ai->index.row(), columnCount( QModelIndex() ) - 1 ) );
}
emit dataChanged( ai->index, ai->index.sibling( ai->index.row(), columnCount( QModelIndex() ) - 1 ) );
break;
}
case Tomahawk::InfoSystem::InfoArtistReleases:
{
QVariantMap returnedData = output.value< QVariantMap >();
QStringList albums = returnedData[ "albums" ].toStringList();
QList<album_ptr> al;
InfoSystem::InfoCriteriaHash inputInfo;
inputInfo = requestData.input.value< InfoSystem::InfoCriteriaHash >();
artist_ptr artist = Artist::get( inputInfo[ "artist" ], false );
Q_ASSERT( !artist.isNull() );
foreach ( const QString& albumName, albums )
{
int albumId = 0;
Tomahawk::album_ptr album = Tomahawk::Album::get( albumId, albumName, artist );
al << album;
}
onAlbumsAdded( al, requestData.customData[ "row" ] );
break;
}
case Tomahawk::InfoSystem::InfoAlbumSongs:
{
QVariantMap returnedData = output.value< QVariantMap >();
QStringList tracks = returnedData[ "tracks" ].toStringList();
QList<query_ptr> ql;
InfoSystem::InfoCriteriaHash inputInfo;
inputInfo = requestData.input.value< InfoSystem::InfoCriteriaHash >();
foreach ( const QString& trackName, tracks )
{
query_ptr query = Query::get( inputInfo[ "artist" ], trackName, inputInfo[ "album" ], uuid() );
ql << query;
}
onTracksAdded( ql, requestData.customData[ "rows" ] );
break;
}
default:
{
Q_ASSERT( false );
break;
}
}
}
@ -779,7 +866,6 @@ void
TreeModel::infoSystemFinished( QString target )
{
Q_UNUSED( target );
// qDebug() << Q_FUNC_INFO;
}
@ -836,10 +922,3 @@ TreeModel::indexFromArtist( const Tomahawk::artist_ptr& artist ) const
return QModelIndex();
}
QModelIndex
TreeModel::indexFromAlbum( const Tomahawk::album_ptr& album ) const
{
return QModelIndex();
}

View File

@ -50,9 +50,12 @@ public:
AlbumPosition
};
enum ColumnStyle // Default style is AllColumns
enum ColumnStyle
{ AllColumns = 0, TrackOnly };
enum ModelMode
{ Database = 0, InfoSystem };
explicit TreeModel( QObject* parent = 0 );
virtual ~TreeModel();
@ -65,15 +68,16 @@ public:
virtual int albumCount() const { return rowCount( QModelIndex() ); }
virtual bool hasChildren( const QModelIndex& parent = QModelIndex() ) const;
virtual int rowCount( const QModelIndex& parent = QModelIndex() ) const;
virtual int columnCount( const QModelIndex& parent = QModelIndex() ) const;
virtual void clear();
virtual ModelMode mode() const { return m_mode; }
virtual void setMode( ModelMode mode ) { m_mode = mode; }
virtual QVariant data( const QModelIndex& index, int role = Qt::DisplayRole ) const;
virtual QVariant headerData( int section, Qt::Orientation orientation, int role ) const;
virtual void clear();
virtual void removeIndex( const QModelIndex& index );
virtual void removeIndexes( const QList<QModelIndex>& indexes );
@ -106,8 +110,6 @@ public:
virtual void setIcon( const QPixmap& pixmap ) { m_icon = pixmap; }
QModelIndex indexFromArtist( const Tomahawk::artist_ptr& artist ) const;
QModelIndex indexFromAlbum( const Tomahawk::album_ptr& album ) const;
TreeModelItem* itemFromIndex( const QModelIndex& index ) const
{
if ( index.isValid() )
@ -155,11 +157,13 @@ private slots:
private:
QPersistentModelIndex m_currentIndex;
TreeModelItem* m_rootItem;
QString m_infoId;
QString m_title;
QString m_description;
QPixmap m_icon;
ColumnStyle m_columnStyle;
ModelMode m_mode;
QList<Tomahawk::artist_ptr> m_artistsFilter;

View File

@ -135,3 +135,108 @@ TreeModelItem::TreeModelItem( const Tomahawk::result_ptr& result, TreeModelItem*
toberemoved = false;
}
TreeModelItem::TreeModelItem( const Tomahawk::query_ptr& query, TreeModelItem* parent, int row )
: QObject( parent )
, m_query( query )
{
this->parent = parent;
fetchingMore = false;
m_isPlaying = false;
if ( parent )
{
if ( row < 0 )
{
parent->children.append( this );
row = parent->children.count() - 1;
}
else
{
parent->children.insert( row, this );
}
this->model = parent->model;
}
toberemoved = false;
connect( query.data(), SIGNAL( resultsAdded( QList<Tomahawk::result_ptr> ) ),
SLOT( onResultsChanged() ) );
connect( query.data(), SIGNAL( resultsRemoved( Tomahawk::result_ptr ) ),
SLOT( onResultsChanged() ) );
connect( query.data(), SIGNAL( resultsChanged() ),
SLOT( onResultsChanged() ) );
}
void
TreeModelItem::onResultsChanged()
{
if ( m_query->numResults() )
m_result = m_query->results().first();
else
m_result = result_ptr();
emit dataChanged();
}
QString
TreeModelItem::name() const
{
if ( !m_artist.isNull() )
{
return m_artist->name();
}
else if ( !m_album.isNull() )
{
return m_album->name();
}
else if ( !m_result.isNull() )
{
return m_result->track();
}
else if ( !m_query.isNull() )
{
return m_query->track();
}
Q_ASSERT( false );
return QString();
}
QString
TreeModelItem::artistName() const
{
if ( !m_result.isNull() )
{
return m_result->artist()->name();
}
else if ( !m_query.isNull() )
{
return m_query->artist();
}
return QString();
}
QString
TreeModelItem::albumName() const
{
if ( !m_result.isNull() && !m_result->album().isNull() )
{
return m_result->album()->name();
}
else if ( !m_query.isNull() )
{
return m_query->album();
}
return QString();
}

View File

@ -39,16 +39,22 @@ public:
explicit TreeModelItem( const Tomahawk::artist_ptr& artist, TreeModelItem* parent = 0, int row = -1 );
explicit TreeModelItem( const Tomahawk::album_ptr& album, TreeModelItem* parent = 0, int row = -1 );
explicit TreeModelItem( const Tomahawk::result_ptr& result, TreeModelItem* parent = 0, int row = -1 );
explicit TreeModelItem( const Tomahawk::query_ptr& query, TreeModelItem* parent = 0, int row = -1 );
const Tomahawk::artist_ptr& artist() const { return m_artist; };
const Tomahawk::album_ptr& album() const { return m_album; };
const Tomahawk::result_ptr& result() const { return m_result; };
const Tomahawk::query_ptr& query() const { return m_query; };
bool isPlaying() { return m_isPlaying; }
void setIsPlaying( bool b ) { m_isPlaying = b; emit dataChanged(); }
void setCover( const QPixmap& cover ) { this->cover = cover; emit dataChanged(); }
QString name() const;
QString artistName() const;
QString albumName() const;
TreeModelItem* parent;
QList<TreeModelItem*> children;
QHash<QString, TreeModelItem*> hash;
@ -63,10 +69,14 @@ public:
signals:
void dataChanged();
private slots:
void onResultsChanged();
private:
Tomahawk::artist_ptr m_artist;
Tomahawk::album_ptr m_album;
Tomahawk::result_ptr m_result;
Tomahawk::query_ptr m_query;
bool m_isPlaying;
};

View File

@ -181,7 +181,7 @@ TreeProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex& sourceParent
TreeModelItem* pi = sourceModel()->itemFromIndex( sourceModel()->index( sourceRow, 0, sourceParent ) );
Q_ASSERT( pi );
if ( !pi->result().isNull() )
if ( m_model->mode() == TreeModel::Database && !pi->result().isNull() )
{
QList< Tomahawk::result_ptr > rl = m_cache.values( sourceParent );
foreach ( const Tomahawk::result_ptr& result, rl )
@ -201,7 +201,7 @@ TreeProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex& sourceParent
TreeModelItem* ti = sourceModel()->itemFromIndex( sourceModel()->index( i, 0, sourceParent ) );
if ( ti->result()->track() == pi->result()->track() &&
if ( ti->name() == pi->name() &&
( ti->result()->albumpos() == pi->result()->albumpos() || ti->result()->albumpos() == 0 ) )
{
if ( !pi->result()->isOnline() && ti->result()->isOnline() )
@ -227,13 +227,9 @@ TreeProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex& sourceParent
QStringList sl = m_filter.split( " ", QString::SkipEmptyParts );
foreach( const QString& s, sl )
{
QString album;
if ( !pi->result()->album().isNull() )
album = pi->result()->album()->name();
if ( !pi->result()->track().contains( s, Qt::CaseInsensitive ) &&
!album.contains( s, Qt::CaseInsensitive ) &&
!pi->result()->album()->artist()->name().contains( s, Qt::CaseInsensitive ) )
if ( !pi->name().contains( s, Qt::CaseInsensitive ) &&
!pi->albumName().contains( s, Qt::CaseInsensitive ) &&
!pi->artistName().contains( s, Qt::CaseInsensitive ) )
{
return false;
}
@ -254,6 +250,11 @@ TreeProxyModel::lessThan( const QModelIndex& left, const QModelIndex& right ) co
if ( !p2 )
return false;
if ( !p1->result().isNull() && p2->result().isNull() )
return true;
if ( p1->result().isNull() && !p2->result().isNull() )
return false;
const QString& lefts = textForItem( p1 );
const QString& rights = textForItem( p2 );
@ -370,6 +371,10 @@ TreeProxyModel::textForItem( TreeModelItem* item ) const
{
return DatabaseImpl::sortname( item->result()->track() );
}
else if ( !item->query().isNull() )
{
return item->query()->track();
}
return QString();
}

View File

@ -18,25 +18,29 @@
#include "HeaderWidget.h"
#include "utils/stylehelper.h"
#include <QStyle>
#include <QStylePainter>
#include <QStyleOption>
HeaderWidget::HeaderWidget(QWidget *parent) : QWidget(parent)
HeaderWidget::HeaderWidget( QWidget* parent )
: QWidget( parent )
{
}
HeaderWidget::~HeaderWidget()
{
}
void HeaderWidget::paintEvent(QPaintEvent *e)
void
HeaderWidget::paintEvent( QPaintEvent* e )
{
QStylePainter p(this);
QStylePainter p( this );
QRect r = e->rect();
StyleHelper::horizontalHeader(&p, r);
StyleHelper::horizontalHeader( &p, r );
}

View File

@ -25,7 +25,6 @@
#include "dllmacro.h"
/**
* \class HeaderWidget
* \brief A QWidget subclass with a background for use in headers.
@ -35,16 +34,10 @@ class DLLEXPORT HeaderWidget : public QWidget
Q_OBJECT
public:
HeaderWidget(QWidget *parent = 0);
HeaderWidget( QWidget* parent = 0 );
virtual ~HeaderWidget();
virtual void paintEvent(QPaintEvent *);
private:
virtual void paintEvent( QPaintEvent* );
};
#endif

View File

@ -18,7 +18,6 @@
#include "combobox.h"
#include "utils/stylehelper.h"
#include <QStyle>
@ -26,36 +25,41 @@
#include <QStylePainter>
#include <QStyleOptionComboBox>
ComboBox::ComboBox(QWidget *parent) : QComboBox(parent)
ComboBox::ComboBox( QWidget* parent )
: QComboBox( parent )
{
}
ComboBox::~ComboBox()
{
}
void ComboBox::paintEvent(QPaintEvent *)
void
ComboBox::paintEvent( QPaintEvent* )
{
QStylePainter p(this);
p.setPen(palette().color(QPalette::Text));
QStylePainter p( this );
p.setPen( palette().color( QPalette::Text ) );
QStyleOptionComboBox cb;
initStyleOption(&cb);
initStyleOption( &cb );
QRect r = cb.rect;
StyleHelper::horizontalHeader( &p, r );
StyleHelper::horizontalHeader(&p, r);
if( cb.state & QStyle::State_MouseOver ) {
QRect highlightRect(r);
QSize shrink(3,4);
QSize hS(highlightRect.size());
if ( cb.state & QStyle::State_MouseOver )
{
QRect highlightRect( r );
QSize shrink( 3, 4 );
QSize hS( highlightRect.size() );
hS -= shrink;
highlightRect.setSize(hS);
highlightRect.translate(0,2);
highlightRect.setSize( hS );
highlightRect.translate( 0, 2 );
p.save();
p.setRenderHint(QPainter::Antialiasing);
p.setRenderHint( QPainter::Antialiasing );
p.setBrush( StyleHelper::headerHighlightColor() );
p.drawRoundedRect(highlightRect, 10.0, 10.0);
p.drawRoundedRect( highlightRect, 10.0, 10.0 );
p.restore();
}
@ -65,15 +69,13 @@ void ComboBox::paintEvent(QPaintEvent *)
p.setBrush( StyleHelper::headerTextColor() );
p.drawText( r, cb.currentText, to );
bool reverse = cb.direction == Qt::RightToLeft;
int menuButtonWidth = 12;
int left = !reverse ? r.right() - menuButtonWidth : r.left();
int right = !reverse ? r.right() : r.left() + menuButtonWidth;
QRect arrowRect((left + right) / 2 + (reverse ? 6 : -6), r.center().y() - 3, 9, 9);
QRect arrowRect( ( left + right ) / 2 + ( reverse ? 6 : -6 ), r.center().y() - 3, 9, 9 ); //FIXME: no consts please
QStyleOption arrowOpt = cb;
arrowOpt.rect = arrowRect;
StyleHelper::drawArrow(QStyle::PE_IndicatorArrowDown, &p, &arrowOpt);
StyleHelper::drawArrow( QStyle::PE_IndicatorArrowDown, &p, &arrowOpt );
}

View File

@ -33,16 +33,10 @@ class DLLEXPORT ComboBox : public QComboBox
Q_OBJECT
public:
ComboBox(QWidget *parent = 0);
ComboBox( QWidget* parent = 0 );
virtual ~ComboBox();
virtual void paintEvent(QPaintEvent *);
private:
virtual void paintEvent( QPaintEvent* );
};
#endif

View File

@ -26,6 +26,7 @@
#include "database/databasecommand_alltracks.h"
#include "database/databasecommand_allalbums.h"
#include "utils/stylehelper.h"
#include "utils/tomahawkutils.h"
#include "utils/logger.h"
@ -52,8 +53,11 @@ ArtistInfoWidget::ArtistInfoWidget( const Tomahawk::artist_ptr& artist, QWidget*
TomahawkUtils::unmarginLayout( layout() );
TomahawkUtils::unmarginLayout( ui->layoutWidget->layout() );
TomahawkUtils::unmarginLayout( ui->layoutWidget1->layout() );
TomahawkUtils::unmarginLayout( ui->layoutWidget2->layout() );
TomahawkUtils::unmarginLayout( ui->albumHeader->layout() );
m_albumsModel = new TreeModel( ui->albums );
m_albumsModel->setMode( TreeModel::InfoSystem );
ui->albums->setTreeModel( m_albumsModel );
m_relatedModel = new TreeModel( ui->relatedArtists );
@ -64,8 +68,14 @@ ArtistInfoWidget::ArtistInfoWidget( const Tomahawk::artist_ptr& artist, QWidget*
m_topHitsModel->setStyle( TrackModel::Short );
ui->topHits->setTrackModel( m_topHitsModel );
ui->albumHeader->setContentsMargins( 0, 0, 4, 0 );
ui->button->setFixedWidth( 200 );
ui->button->setDown( true );
m_pixmap = QPixmap( RESPATH "images/no-album-art-placeholder.png" ).scaledToWidth( 48, Qt::SmoothTransformation );
connect( ui->button, SIGNAL( toggled( bool ) ), SLOT( onModeToggle( bool ) ) );
connect( Tomahawk::InfoSystem::InfoSystem::instance(),
SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ),
SLOT( infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ) );
@ -82,9 +92,19 @@ ArtistInfoWidget::~ArtistInfoWidget()
}
void
ArtistInfoWidget::onModeToggle( bool officialReleases )
{
m_albumsModel->setMode( officialReleases ? TreeModel::InfoSystem : TreeModel::Database );
m_albumsModel->clear();
m_albumsModel->addAlbums( m_artist, QModelIndex() );
}
void
ArtistInfoWidget::load( const artist_ptr& artist )
{
m_artist = artist;
m_title = artist->name();
m_albumsModel->addAlbums( artist, QModelIndex() );
@ -109,9 +129,6 @@ ArtistInfoWidget::load( const artist_ptr& artist )
requestData.type = Tomahawk::InfoSystem::InfoArtistSongs;
Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( requestData );
requestData.type = Tomahawk::InfoSystem::InfoArtistReleases;
Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( requestData );
}

View File

@ -90,6 +90,8 @@ private slots:
void infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output );
void infoSystemFinished( QString target );
void onModeToggle( bool officialReleases );
private:
Ui::ArtistInfoWidget *ui;

View File

@ -66,13 +66,26 @@
</layout>
</widget>
</widget>
<widget class="QWidget" name="">
<layout class="QVBoxLayout" name="verticalLayout">
<widget class="QWidget" name="layoutWidget2">
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<widget class="HeaderLabel" name="label_3">
<property name="text">
<string>Albums</string>
</property>
<widget class="HeaderWidget" name="albumHeader" native="true">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="HeaderLabel" name="label_3">
<property name="text">
<string>Albums</string>
</property>
</widget>
</item>
<item>
<widget class="ToggleButton" name="button">
<property name="text">
<string>Official Releases Only</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
@ -95,6 +108,16 @@
<extends>QLabel</extends>
<header location="global">widgets/HeaderLabel.h</header>
</customwidget>
<customwidget>
<class>HeaderWidget</class>
<extends>QWidget</extends>
<header location="global">widgets/HeaderWidget.h</header>
</customwidget>
<customwidget>
<class>ToggleButton</class>
<extends>QPushButton</extends>
<header location="global">widgets/ToggleButton.h</header>
</customwidget>
<customwidget>
<class>ArtistView</class>
<extends>QTreeView</extends>