diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index 6d64c0d0b..515866eb4 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -110,6 +110,7 @@ set( libSources infosystem/infosystemworker.cpp infosystem/infoplugins/generic/echonestplugin.cpp infosystem/infoplugins/generic/lastfmplugin.cpp + infosystem/infoplugins/generic/chartsplugin.cpp infosystem/infoplugins/generic/musixmatchplugin.cpp infosystem/infoplugins/generic/musicbrainzPlugin.cpp @@ -335,6 +336,7 @@ set( libHeaders infosystem/infosystemcache.h infosystem/infoplugins/generic/echonestplugin.h infosystem/infoplugins/generic/lastfmplugin.h + infosystem/infoplugins/generic/chartsplugin.h infosystem/infoplugins/generic/musixmatchplugin.h infosystem/infoplugins/generic/musicbrainzPlugin.h diff --git a/src/libtomahawk/infosystem/infoplugins/generic/chartsplugin.cpp b/src/libtomahawk/infosystem/infoplugins/generic/chartsplugin.cpp new file mode 100644 index 000000000..429e5c376 --- /dev/null +++ b/src/libtomahawk/infosystem/infoplugins/generic/chartsplugin.cpp @@ -0,0 +1,482 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Hugo Lindström + * + * Tomahawk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Tomahawk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + +#include "chartsplugin.h" + +#include +#include +#include +#include +#include +#include + +#include "album.h" +#include "typedefs.h" +#include "audio/audioengine.h" +#include "tomahawksettings.h" +#include "utils/tomahawkutils.h" +#include "utils/logger.h" + +#define CHART_URL "http://charts.tomahawk-player.org:10080/" +//#define CHART_URL "http://localhost:8080/" +#include +#include + +using namespace Tomahawk::InfoSystem; + +static QString +md5( const QByteArray& src ) +{ + QByteArray const digest = QCryptographicHash::hash( src, QCryptographicHash::Md5 ); + return QString::fromLatin1( digest.toHex() ).rightJustified( 32, '0' ); +} + + +ChartsPlugin::ChartsPlugin() + : InfoPlugin() +{ + + + /// Add resources here + m_chartResources << "last.fm" << "billboard" << "itunes"; + m_supportedGetTypes << InfoChart << InfoChartCapabilities; + +} + + +ChartsPlugin::~ChartsPlugin() +{ + qDebug() << Q_FUNC_INFO; +} + + +void +ChartsPlugin::namChangedSlot( QNetworkAccessManager *nam ) +{ + tDebug() << "ChartsPlugin: namChangedSLot"; + + qDebug() << Q_FUNC_INFO; + if( !nam ) + return; + + m_nam = QWeakPointer< QNetworkAccessManager >( nam ); + + /// Then get each chart from resource + if( !m_chartResources.isEmpty() && m_nam && m_chartTypes.isEmpty() ){ + tDebug() << "ChartsPlugin: InfoChart fetching possible resources"; + + foreach(QVariant resource, m_chartResources) + { + QUrl url = QUrl( QString( CHART_URL "source/%1" ).arg(resource.toString() ) ); + QNetworkReply* reply = m_nam.data()->get( QNetworkRequest( url ) ); + connect( reply, SIGNAL( finished() ), SLOT( chartTypes() ) ); + } + + } +} + + +void +ChartsPlugin::dataError( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData ) +{ + emit info( requestId, requestData, QVariant() ); + return; +} + + +void +ChartsPlugin::getInfo( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData ) +{ + qDebug() << Q_FUNC_INFO << requestData.caller; + qDebug() << Q_FUNC_INFO << requestData.customData; + + switch ( requestData.type ) + { + + case InfoChart: + fetchChart( requestId, requestData ); + break; + + case InfoChartCapabilities: + fetchChartCapabilities( requestId, requestData ); + break; + default: + dataError( requestId, requestData ); + } +} + + +void +ChartsPlugin::pushInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input ) +{ + Q_UNUSED( caller ) + Q_UNUSED( type) + Q_UNUSED( input ) +} + + +void +ChartsPlugin::fetchChart( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData ) +{ + + if ( !requestData.input.canConvert< Tomahawk::InfoSystem::InfoCriteriaHash >() ) + { + dataError( requestId, requestData ); + return; + } + + InfoCriteriaHash hash = requestData.input.value< Tomahawk::InfoSystem::InfoCriteriaHash >(); + Tomahawk::InfoSystem::InfoCriteriaHash criteria; + + /// Each request needs to contain both a id and source + if ( !hash.contains( "chart_id" ) && !hash.contains( "chart_source" ) ) + { + dataError( requestId, requestData ); + return; + + } + /// Set the criterias for current chart + criteria["chart_id"] = hash["chart_id"]; + criteria["chart_source"] = hash["chart_source"]; + + emit getCachedInfo( requestId, criteria, 0, requestData ); +} + +void +ChartsPlugin::fetchChartCapabilities( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData ) +{ + if ( !requestData.input.canConvert< Tomahawk::InfoSystem::InfoCriteriaHash >() ) + { + dataError( requestId, requestData ); + return; + } + + //InfoCriteriaHash hash = requestData.input.value< Tomahawk::InfoSystem::InfoCriteriaHash >(); + Tomahawk::InfoSystem::InfoCriteriaHash criteria; + + emit getCachedInfo( requestId, criteria, 0, requestData ); +} + +void +ChartsPlugin::notInCacheSlot( uint requestId, QHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData ) +{ + if ( !m_nam.data() ) + { + tLog() << "Have a null QNAM, uh oh"; + emit info( requestId, requestData, QVariant() ); + return; + } + + + switch ( requestData.type ) + { + case InfoChart: + { + + /// Fetch the chart, we need source and id + QUrl url = QUrl( QString( CHART_URL "/source/%1/chart/%2" ).arg( criteria["chart_source"] ).arg( criteria["chart_id"] ) ); + qDebug() << Q_FUNC_INFO << "Getting chart url" << url; + + 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( chartReturned() ) ); + return; + } + + case InfoChartCapabilities: + { + + QVariantMap result; + + /// Itunes have alot of country specified charts, + /// Get those for later use + QList geos; + foreach( QVariant type, m_chartTypes ) + { + + if( type.toMap().value( "geo" ).isValid() ) + { + geos.append( type.toMap().value( "geo" ).toString() ); + } + } + /// We only need a unique list + geos = QSet::fromList(geos).toList(); + + foreach( QVariant chartResource, m_chartResources ) + { + + QList album_charts; + QList track_charts; + QList artist_charts; + QVariantMap charts; + + if( chartResource.toString() == "last.fm") + { + + 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" ) ); + + artist_charts.append( Chart( "chart.getTopArtists", "Top Artists", "artists" ) ); + artist_charts.append( Chart( "chart.getHypedArtists", "Hyped Artists", "artists" ) ); + + charts.insert( "Tracks", QVariant::fromValue >( track_charts ) ); + charts.insert( "Artists", QVariant::fromValue >( artist_charts ) ); + + + } + else if( chartResource.toString() == "itunes") + { + QVariantMap geoCharts; + + foreach(QVariant country, geos) + { + QList geoAlbum_charts; + QList geoTrack_charts; + + foreach( QVariant type, m_chartTypes ) + { + + /// Itunes supplys charts based on geo, create breadcrumb for each of them + + if( type.toMap().value( "source" ).toString() == chartResource.toString() + && type.toMap().value( "geo" ).isValid() ) + { + + if( type.toMap().value( "geo" ).toString() == country.toString() ) + { + QString countryString = "Geo: " + type.toMap().value( "geo" ).toString().toUpper(); + + if( type.toMap().value( "type" ).toString() == "Album" ) + { + geoAlbum_charts.append( Chart( type.toMap().value("id").toString(), type.toMap().value("name").toString() , "album" ) ); + geoCharts.insert( "Albums", QVariant::fromValue >( geoAlbum_charts ) ); + charts.insert( countryString, QVariant::fromValue( geoCharts ) ); + } + + if( type.toMap().value( "type" ).toString() == "Track" ) + { + + geoTrack_charts.append( Chart( type.toMap().value("id").toString(), type.toMap().value("name").toString(), "tracks" ) ); + geoCharts.insert( "Tracks", QVariant::fromValue >( geoTrack_charts ) ); + charts.insert( countryString, QVariant::fromValue( geoCharts ) ); + + } + } + } + } + } + + }else{ + /// Billboard, and maybe others + foreach( QVariant type, m_chartTypes ) + { + + /// Append each type to its parent source + /// @todo Add chartType enum + if( type.toMap().value( "source" ).toString() == chartResource.toString() ) + { + if( type.toMap().value( "type" ).toString() == "Album" ) + { + album_charts.append( Chart( type.toMap().value("id").toString(), type.toMap().value("name").toString(), "album" ) ); + charts.insert( "Albums", QVariant::fromValue >( album_charts ) ); + } + + if( type.toMap().value( "type" ).toString() == "Track" ) + { + track_charts.append( Chart( type.toMap().value("id").toString(), type.toMap().value("name").toString(), "tracks" ) ); + charts.insert( "Tracks", QVariant::fromValue >( track_charts ) ); + } + } + } + } + + /// @note For displaying purposes, upper the first letter + /// @note Remeber to lower it when fetching this! + QString chartName = chartResource.toString(); + chartName[0] = chartName[0].toUpper(); + + /// Add the possible charts and its types to breadcrumb + result.insert( chartName , QVariant::fromValue( charts ) ); + } + emit info( + requestId, + requestData, + result + ); + return; + } + + default: + { + tLog() << "Couldn't figure out what to do with this type of request after cache miss"; + emit info( requestId, requestData, QVariant() ); + return; + } + } +} + + +void +ChartsPlugin::chartTypes() +{ + /// Get possible chart type for specific chart source + tDebug() << "ChartsPlugin: InfoChart types returned!"; + QNetworkReply* reply = qobject_cast( sender() ); + + if ( reply->error() == QNetworkReply::NoError ) + { + QJson::Parser p; + bool ok; + QVariantMap res = p.parse( reply, &ok ).toMap(); + + if ( !ok ) + { + tLog() << "Failed to parse resources" << p.errorString() << "On line" << p.errorLine(); + + return; + } + + /// Got types, append! + foreach(QVariant chart, res.value( "charts" ).toMap() ){ + m_chartTypes.append(chart); + + } + } + +} + +void +ChartsPlugin::chartReturned() +{ + + /// Chart request returned something! Woho + QNetworkReply* reply = qobject_cast( sender() ); + QVariantMap returnedData; + + if ( reply->error() == QNetworkReply::NoError ) + { + QJson::Parser p; + bool ok; + QVariantMap res = p.parse( reply, &ok ).toMap(); + + if ( !ok ) + { + tLog() << "Failed to parse json from chart lookup:" << p.errorString() << "On line" << p.errorLine(); + return; + } + + /// SO we have a result, parse it! + QVariantList chartResponse = res.value( "list" ).toList(); + QList top_tracks; + QList top_albums; + + /// Deside what type, we need to handle it differently + /// @todo: We allready know the type, append it to breadcrumb hash + + if( res.value( "type" ).toString() == "Album" ) + setChartType( Album ); + else if( res.value( "type" ).toString() == "Track" ) + setChartType( Track ); + else + setChartType( None ); + + + foreach ( QVariant chartR, chartResponse ) + { + QString title, artist, album; + QVariantMap chartMap = chartR.toMap(); + + if( !chartMap.isEmpty() ) + { + + title = chartMap.value( "track" ).toString(); + album = chartMap.value( "album" ).toString(); + artist = chartMap.value( "artist" ).toString(); + /// Maybe we can use rank later on, to display something nice + /// rank = chartMap.value( "rank" ).toString(); + + if( chartType() == Album ) + { + /** HACK, billboard chart returns wrong typename **/ + if( res.value( "source" ).toString() == "billboard" ) + album = chartMap.value( "track" ).toString(); + + if ( album.isEmpty() && artist.isEmpty() ) // don't have enough... + { + tLog() << "Didn't get an artist and album name from chart, not enough to build a query on. Aborting" << title << album << artist; + + }else + { + qDebug() << Q_FUNC_INFO << album << artist; + ArtistAlbumPair pair; + pair.artist = artist; + pair.album = album; + top_albums << pair; + + } + } + + else if( chartType() == Track ) + { + + if ( title.isEmpty() && artist.isEmpty() ) // don't have enough... + { + tLog() << "Didn't get an artist and track name from charts, not enough to build a query on. Aborting" << title << artist << album; + + }else{ + + ArtistTrackPair pair; + pair.artist = artist; + pair.track = title; + top_tracks << pair; + + } + } + } + } + + if( chartType() == Track ) + { + tDebug() << "ChartsPlugin:" << "\tgot " << top_tracks.size() << " tracks"; + returnedData["tracks"] = QVariant::fromValue( top_tracks ); + returnedData["type"] = "tracks"; + } + + if( chartType() == Album ) + { + tDebug() << "ChartsPlugin:" << "\tgot " << top_albums.size() << " albums"; + returnedData["albums"] = QVariant::fromValue( top_albums ); + returnedData["type"] = "albums"; + } + + Tomahawk::InfoSystem::InfoRequestData requestData = reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >(); + + emit info( + reply->property( "requestId" ).toUInt(), + requestData, + returnedData + ); + // TODO update cache + + }else qDebug() << "Network error"; + +} + diff --git a/src/libtomahawk/infosystem/infoplugins/generic/chartsplugin.h b/src/libtomahawk/infosystem/infoplugins/generic/chartsplugin.h new file mode 100644 index 000000000..32d0f2bd2 --- /dev/null +++ b/src/libtomahawk/infosystem/infoplugins/generic/chartsplugin.h @@ -0,0 +1,83 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Hugo Lindström + * + * Tomahawk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Tomahawk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + +#ifndef ChartsPlugin_H +#define ChartsPlugin_H + +#include "infosystem/infosystem.h" +#include "infosystem/infosystemworker.h" +#include +#include + +class QNetworkReply; + +namespace Tomahawk +{ + +namespace InfoSystem +{ + +class ChartsPlugin : public InfoPlugin +{ + Q_OBJECT + +public: + ChartsPlugin(); + virtual ~ChartsPlugin(); + + enum ChartType { + None = 0x00, + Track = 0x01, + Album = 0x02, + Artist = 0x04 + + }; + void setChartType( ChartType type ) { m_chartType = type; } + ChartType chartType() const { return m_chartType; } + +public slots: + void chartReturned(); + void chartTypes(); + void namChangedSlot( QNetworkAccessManager *nam ); + +protected slots: + virtual void getInfo( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData ); + virtual void notInCacheSlot( uint requestId, Tomahawk::InfoSystem::InfoCriteriaHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData ); + + virtual void pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant data ); + +private: + void fetchChart( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData ); + void fetchChartCapabilities( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData ); + void dataError( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData ); + + QVariantList m_chartResources; + QVariantList m_chartTypes; + QList m_charts; + ChartType m_chartType; + + QVariantMap m_chartResult; + bool chartHasReturned; + QWeakPointer< QNetworkAccessManager > m_nam; +}; + +} + +} + +#endif // ChartsPlugin_H diff --git a/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.cpp b/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.cpp index 55d08df0a..aa47e9e6c 100644 --- a/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.cpp +++ b/src/libtomahawk/infosystem/infoplugins/generic/lastfmplugin.cpp @@ -416,32 +416,6 @@ LastFmPlugin::notInCacheSlot( uint requestId, QHash criteria, return; } - case InfoChartCapabilities: - { - QList 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" ) ); - - QList artist_charts; - 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 >( track_charts ) ); - charts.insert( "Artists", QVariant::fromValue >( artist_charts ) ); - - QVariantMap result; - result.insert( "Last.fm", QVariant::fromValue( charts ) ); - - emit info( - requestId, - requestData, - result - ); - return; - } - case InfoArtistSimilars: { lastfm::Artist a( criteria["artist"] ); @@ -495,7 +469,7 @@ LastFmPlugin::notInCacheSlot( uint requestId, QHash criteria, default: { - tLog() << "Couldn't figure out what to do with this type of request after cache miss"; + tLog() << Q_FUNC_INFO << "Couldn't figure out what to do with this type of request after cache miss"; emit info( requestId, requestData, QVariant() ); return; } diff --git a/src/libtomahawk/infosystem/infosystem.h b/src/libtomahawk/infosystem/infosystem.h index 4de22ea6d..23ea52246 100644 --- a/src/libtomahawk/infosystem/infosystem.h +++ b/src/libtomahawk/infosystem/infosystem.h @@ -135,6 +135,11 @@ struct ArtistTrackPair { QString track; }; +struct ArtistAlbumPair { + QString artist; + QString album; +}; + struct Chart { Chart(){} Chart(const QString _id, const QString _label, const QString _type) { @@ -284,8 +289,10 @@ Q_DECLARE_METATYPE( Tomahawk::InfoSystem::InfoGenericMap ); Q_DECLARE_METATYPE( Tomahawk::InfoSystem::InfoCriteriaHash ); Q_DECLARE_METATYPE( QWeakPointer< Tomahawk::InfoSystem::InfoSystemCache > ); Q_DECLARE_METATYPE( Tomahawk::InfoSystem::ArtistTrackPair ); +Q_DECLARE_METATYPE( Tomahawk::InfoSystem::ArtistAlbumPair ); Q_DECLARE_METATYPE( Tomahawk::InfoSystem::Chart ); Q_DECLARE_METATYPE( QList ); +Q_DECLARE_METATYPE( QList ); Q_DECLARE_METATYPE( QList ); #endif // TOMAHAWK_INFOSYSTEM_H diff --git a/src/libtomahawk/infosystem/infosystemworker.cpp b/src/libtomahawk/infosystem/infosystemworker.cpp index b868503cf..872d4f9b9 100644 --- a/src/libtomahawk/infosystem/infosystemworker.cpp +++ b/src/libtomahawk/infosystem/infosystemworker.cpp @@ -25,6 +25,7 @@ #include "infosystemcache.h" #include "infoplugins/generic/echonestplugin.h" #include "infoplugins/generic/musixmatchplugin.h" +#include "infoplugins/generic/chartsplugin.h" #include "infoplugins/generic/lastfmplugin.h" #include "infoplugins/generic/musicbrainzPlugin.h" #include "utils/tomahawkutils.h" @@ -85,10 +86,16 @@ InfoSystemWorker::init( QWeakPointer< Tomahawk::InfoSystem::InfoSystemCache> cac InfoPluginPtr mbptr( new MusicBrainzPlugin() ); m_plugins.append( mbptr ); registerInfoTypes( mbptr, mbptr.data()->supportedGetTypes(), mbptr.data()->supportedPushTypes() ); + + InfoPluginPtr sptr( new ChartsPlugin() ); + m_plugins.append( sptr ); + registerInfoTypes( sptr, sptr.data()->supportedGetTypes(), sptr.data()->supportedPushTypes() ); + InfoPluginPtr lfmptr( new LastFmPlugin() ); m_plugins.append( lfmptr ); registerInfoTypes( lfmptr, lfmptr.data()->supportedGetTypes(), lfmptr.data()->supportedPushTypes() ); + #ifdef Q_WS_MAC InfoPluginPtr admptr( new AdiumPlugin() ); m_plugins.append( admptr ); diff --git a/src/libtomahawk/widgets/whatshotwidget.cpp b/src/libtomahawk/widgets/whatshotwidget.cpp index 54833f90e..b1bf9f9b4 100644 --- a/src/libtomahawk/widgets/whatshotwidget.cpp +++ b/src/libtomahawk/widgets/whatshotwidget.cpp @@ -53,12 +53,15 @@ WhatsHotWidget::WhatsHotWidget( QWidget* parent ) { ui->setupUi( this ); + ui->additionsView->setFrameShape( QFrame::NoFrame ); + ui->additionsView->setAttribute( Qt::WA_MacShowFocusRect, 0 ); + TomahawkUtils::unmarginLayout( layout() ); TomahawkUtils::unmarginLayout( ui->stackLeft->layout() ); TomahawkUtils::unmarginLayout( ui->horizontalLayout->layout() ); TomahawkUtils::unmarginLayout( ui->horizontalLayout_2->layout() ); TomahawkUtils::unmarginLayout( ui->breadCrumbLeft->layout() ); - + TomahawkUtils::unmarginLayout( ui->verticalLayout->layout() ); //set crumb widgets SiblingCrumbButtonFactory * crumbFactory = new SiblingCrumbButtonFactory; @@ -68,19 +71,15 @@ WhatsHotWidget::WhatsHotWidget( QWidget* parent ) ui->breadCrumbLeft->setButtonFactory(crumbFactory); ui->breadCrumbLeft->setModel(m_crumbModelLeft); ui->breadCrumbLeft->setRootIcon(QIcon( RESPATH "images/charts.png" )); - //ui->breadCrumbLeft->setSelectionModel(selectionModelLeft); ui->breadCrumbLeft->setUseAnimation(true); connect(ui->breadCrumbLeft, SIGNAL(currentIndexChanged(QModelIndex)), SLOT(leftCrumbIndexChanged(QModelIndex))); - /*ui->breadCrumbRight->setButtonFactory(crumbFactory); - ui->breadCrumbRight->setRootIcon(QIcon( RESPATH "images/charts.png" )); - ui->breadCrumbRight->setModel(m_crumbModelLeft); - ui->breadCrumbRight->setUseAnimation(true);*/ - + m_albumsModel = new AlbumModel( ui->additionsView ); + ui->additionsView->setAlbumModel( m_albumsModel ); m_tracksModel = new PlaylistModel( ui->tracksViewLeft ); - m_tracksModel->setStyle( TrackModel::Short ); + m_tracksModel->setStyle( TrackModel::ShortWithAvatars ); ui->tracksViewLeft->setFrameShape( QFrame::NoFrame ); ui->tracksViewLeft->setAttribute( Qt::WA_MacShowFocusRect, 0 ); @@ -108,6 +107,7 @@ WhatsHotWidget::WhatsHotWidget( QWidget* parent ) ui->artistsViewLeft->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff ); ui->artistsViewLeft->header()->setVisible( false ); + m_timer = new QTimer( this ); connect( m_timer, SIGNAL( timeout() ), SLOT( checkQueries() ) ); @@ -118,8 +118,8 @@ WhatsHotWidget::WhatsHotWidget( QWidget* parent ) connect( Tomahawk::InfoSystem::InfoSystem::instance(), SIGNAL( finished( QString ) ), SLOT( infoSystemFinished( QString ) ) ); - - QTimer::singleShot( 0, this, SLOT( fetchData() ) ); + /// Itunes response is big, so maybe wait for it here? + QTimer::singleShot( 1000, this, SLOT( fetchData() ) ); } @@ -184,7 +184,7 @@ WhatsHotWidget::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestDat //ui->breadCrumbRight->setSelectionModel(selectionModelLeft); //HACK ALERT - we want the second crumb to expand right away, so we //force it here. We should find a more elegant want to do this - ui->breadCrumbLeft->currentChangedTriggered(m_crumbModelLeft->index(0,0).child(0,0)); + ui->breadCrumbLeft->currentChangedTriggered(m_crumbModelLeft->index(0,0).child(0,0).child(0,0)); break; } case InfoSystem::InfoChart: @@ -206,6 +206,27 @@ WhatsHotWidget::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestDat foreach ( const QString& artist, artists ) m_artistsModel->addArtists( Artist::get( artist ) ); } + else if( type == "albums" ) + { + setLeftViewAlbums(); + m_albumsModel->clear(); + QList al; + const QList albums = returnedData["albums"].value >(); + tDebug( LOGVERBOSE ) << "WhatsHot: got albums! " << albums.size(); + + foreach ( const Tomahawk::InfoSystem::ArtistAlbumPair& album, albums ) + { + qDebug() << "Getting album" << album.album << "By" << album.artist; + album_ptr albumPtr = Album::get(Artist::get( album.artist, true ), album.album ); + + if(!albumPtr.isNull()) + al << albumPtr; + + } + qDebug() << "Adding albums to model"; + m_albumsModel->addAlbums( al ); + + } else if( type == "tracks" ) { setLeftViewTracks(); @@ -249,10 +270,20 @@ WhatsHotWidget::leftCrumbIndexChanged( QModelIndex index ) return; + QList indexes; + while (index.parent().isValid()) + { + indexes.prepend(index); + index = index.parent(); + } + + const QString chartId = item->data().toString(); Tomahawk::InfoSystem::InfoCriteriaHash criteria; criteria.insert("chart_id", chartId); + /// Remember to lower the source! + criteria.insert("chart_source", index.data().toString().toLower()); Tomahawk::InfoSystem::InfoRequestData requestData; QVariantMap customData; @@ -325,6 +356,13 @@ WhatsHotWidget::parseNode(QStandardItem* parentItem, const QString &label, const } +void +WhatsHotWidget::setLeftViewAlbums() +{ + ui->stackLeft->setCurrentIndex(2); +} + + void WhatsHotWidget::setLeftViewArtists() { diff --git a/src/libtomahawk/widgets/whatshotwidget.h b/src/libtomahawk/widgets/whatshotwidget.h index d6d0b6a0f..e3dd0ff37 100644 --- a/src/libtomahawk/widgets/whatshotwidget.h +++ b/src/libtomahawk/widgets/whatshotwidget.h @@ -37,6 +37,7 @@ class TreeModel; class PlaylistModel; class OverlayWidget; class TreeProxyModel; +class AlbumModel; namespace Ui { @@ -83,7 +84,10 @@ private slots: private: void setLeftViewArtists(); + void setLeftViewAlbums(); void setLeftViewTracks(); + + QStandardItem* parseNode( QStandardItem* parentItem, const QString &label, const QVariant &data ); Ui::WhatsHotWidget *ui; @@ -91,6 +95,7 @@ private: TreeModel* m_artistsModel; TreeProxyModel* m_artistsProxy; QStandardItemModel* m_crumbModelLeft; + AlbumModel* m_albumsModel; QTimer* m_timer; }; diff --git a/src/libtomahawk/widgets/whatshotwidget.ui b/src/libtomahawk/widgets/whatshotwidget.ui index 902455cfb..4caa5e32b 100644 --- a/src/libtomahawk/widgets/whatshotwidget.ui +++ b/src/libtomahawk/widgets/whatshotwidget.ui @@ -10,7 +10,7 @@ 513 - + @@ -44,20 +44,39 @@ + + + + + + true + + + QAbstractItemView::ExtendedSelection + + + + + - PlaylistView - QTreeView -
playlist/playlistview.h
+ AlbumView + QListView +
playlist/albumview.h
ArtistView QTreeView -
artistview.h
+
artistview.h
+
+ + PlaylistView + QTreeView +
playlist/playlistview.h
HeaderBreadCrumb diff --git a/src/tomahawkapp.cpp b/src/tomahawkapp.cpp index 22f36aeb8..4b78abd85 100644 --- a/src/tomahawkapp.cpp +++ b/src/tomahawkapp.cpp @@ -407,7 +407,9 @@ TomahawkApp::registerMetaTypes() qRegisterMetaType< DirLister::Mode >("DirLister::Mode"); qRegisterMetaType< Tomahawk::InfoSystem::ArtistTrackPair >("Tomahawk::InfoSystem::ArtistTrackPair"); + qRegisterMetaType< Tomahawk::InfoSystem::ArtistAlbumPair >("Tomahawk::InfoSystem::ArtistAlbumPair"); qRegisterMetaType< QList >("QList"); + qRegisterMetaType< QList >("QList"); qRegisterMetaType< Tomahawk::InfoSystem::Chart>("Tomahawk::InfoSystem::Chart"); qRegisterMetaType< QList >("QList"); qRegisterMetaType< QPersistentModelIndex >( "QPersistentModelIndex" );