diff --git a/src/libtomahawk/playlist/dynamic/echonest/EchonestControl.cpp b/src/libtomahawk/playlist/dynamic/echonest/EchonestControl.cpp index 0461a1d69..aea71a78e 100644 --- a/src/libtomahawk/playlist/dynamic/echonest/EchonestControl.cpp +++ b/src/libtomahawk/playlist/dynamic/echonest/EchonestControl.cpp @@ -25,6 +25,7 @@ #include #include #include +#include "EchonestGenerator.h" Tomahawk::EchonestControl::EchonestControl( const QString& selectedType, const QStringList& typeSelectors, QObject* parent ) @@ -315,6 +316,31 @@ Tomahawk::EchonestControl::updateWidgets() connect( combo, SIGNAL( activated( int ) ), this, SLOT( updateData() ) ); connect( combo, SIGNAL( activated( int ) ), this, SLOT( editingFinished() ) ); + match->hide(); + combo->hide(); + m_match = QWeakPointer< QWidget >( match ); + m_input = QWeakPointer< QWidget >( combo ); + } else if( selectedType() == "Mood" || selectedType() == "Style" ) { + if( selectedType() == "Mood" ) + m_currentType = Echonest::DynamicPlaylist::Mood; + else + m_currentType = Echonest::DynamicPlaylist::Style; + + QLabel* match = new QLabel( tr( "is" ) ); + + QComboBox* combo = new QComboBox; + QVector< QString > src = selectedType() == "Mood" ? EchonestGenerator::moods() : EchonestGenerator::styles(); + foreach( const QString& item, src ) { + combo->addItem( item, item ); + } + + m_matchString = match->text(); + m_matchData = match->text(); + + + connect( combo, SIGNAL( activated( int ) ), this, SLOT( updateData() ) ); + connect( combo, SIGNAL( activated( int ) ), this, SLOT( editingFinished() ) ); + match->hide(); combo->hide(); m_match = QWeakPointer< QWidget >( match ); @@ -384,7 +410,7 @@ Tomahawk::EchonestControl::updateData() updateFromComboAndSlider(); } else if( selectedType() == "Danceability" || selectedType() == "Energy" || selectedType() == "Artist Familiarity" || selectedType() == "Artist Hotttnesss" || selectedType() == "Song Hotttnesss" ) { updateFromComboAndSlider( true ); - } else if( selectedType() == "Mode" || selectedType() == "Key" ) { + } else if( selectedType() == "Mode" || selectedType() == "Key" || selectedType() == "Mood" || selectedType() == "Style" ) { updateFromLabelAndCombo(); } else if( selectedType() == "Sorting" ) { QComboBox* match = qobject_cast( m_match.data() ); @@ -453,7 +479,7 @@ Tomahawk::EchonestControl::updateWidgetsFromData() updateToComboAndSlider(); } else if( selectedType() == "Danceability" || selectedType() == "Energy" || selectedType() == "Artist Familiarity" || selectedType() == "Artist Hotttnesss" || selectedType() == "Song Hotttnesss" ) { updateToComboAndSlider( true ); - } else if( selectedType() == "Mode" || selectedType() == "Key" ) { + } else if( selectedType() == "Mode" || selectedType() == "Key" || selectedType() == "Mood" || selectedType() == "Style" ) { updateToLabelAndCombo(); } else if( selectedType() == "Sorting" ) { QComboBox* match = qobject_cast( m_match.data() ); @@ -564,6 +590,11 @@ Tomahawk::EchonestControl::calculateSummary() QString ascdesc = qobject_cast< QComboBox* >( m_match.data() )->currentText().toLower(); summary = QString( "sorted in %1 %2 order" ).arg( ascdesc ).arg( sortType ); + } else if( selectedType() == "Mood" || selectedType() == "Style" ) { + Q_ASSERT( !m_input.isNull() ); + Q_ASSERT( qobject_cast< QComboBox* >( m_input.data() ) ); + QString text = qobject_cast< QComboBox* >( m_input.data() )->currentText().toLower(); + summary = QString( "with %1 %2" ).arg( selectedType() == "Mood" ? "mood" : "style" ).arg( text ); } m_summary = summary; } diff --git a/src/libtomahawk/playlist/dynamic/echonest/EchonestGenerator.cpp b/src/libtomahawk/playlist/dynamic/echonest/EchonestGenerator.cpp index c4e22c61e..428364f15 100644 --- a/src/libtomahawk/playlist/dynamic/echonest/EchonestGenerator.cpp +++ b/src/libtomahawk/playlist/dynamic/echonest/EchonestGenerator.cpp @@ -24,6 +24,9 @@ using namespace Tomahawk; +QVector< QString > EchonestGenerator::s_moods = QVector< QString >(); +QVector< QString > EchonestGenerator::s_styles = QVector< QString >(); + EchonestFactory::EchonestFactory() {} @@ -42,7 +45,7 @@ EchonestFactory::createControl( const QString& controlType ) QStringList EchonestFactory::typeSelectors() const { - return QStringList() << "Artist" << "Artist Description" << "Variety" << "Tempo" << "Duration" << "Loudness" + return QStringList() << "Artist" << "Artist Description" << "Song" << "Mood" << "Style" << "Variety" << "Tempo" << "Duration" << "Loudness" << "Danceability" << "Energy" << "Artist Familiarity" << "Artist Hotttnesss" << "Song Hotttnesss" << "Longitude" << "Latitude" << "Mode" << "Key" << "Sorting"; } @@ -55,6 +58,14 @@ EchonestGenerator::EchonestGenerator ( QObject* parent ) m_type = "echonest"; m_mode = OnDemand; m_logo.load( RESPATH "/images/echonest_logo.png" ); + + // fetch style and moods + QNetworkReply* style = Echonest::Artist::listTerms( "style" ); + connect( style, SIGNAL( finished() ), this, SLOT( stylesReceived() ) ); + + QNetworkReply* moods = Echonest::Artist::listTerms( "mood" ); + connect( moods, SIGNAL( finished() ), this, SLOT( moodsReceived() ) ); + // qDebug() << "ECHONEST:" << m_logo.size(); } @@ -408,3 +419,40 @@ EchonestGenerator::sentenceSummary() return sentence; } +QVector< QString > +EchonestGenerator::moods() +{ + return s_moods; +} + +void +EchonestGenerator::moodsReceived() +{ + QNetworkReply* r = qobject_cast< QNetworkReply* >( sender() ); + Q_ASSERT( r ); + + try { + s_moods = Echonest::Artist::parseTermList( r ); + } catch( Echonest::ParseError& e ) { + qWarning() << "Echonest failed to parse moods list"; + } +} + +QVector< QString > +EchonestGenerator::styles() +{ + return s_styles; +} + +void +EchonestGenerator::stylesReceived() +{ + QNetworkReply* r = qobject_cast< QNetworkReply* >( sender() ); + Q_ASSERT( r ); + + try { + s_styles = Echonest::Artist::parseTermList( r ); + } catch( Echonest::ParseError& e ) { + qWarning() << "Echonest failed to parse styles list"; + } +} diff --git a/src/libtomahawk/playlist/dynamic/echonest/EchonestGenerator.h b/src/libtomahawk/playlist/dynamic/echonest/EchonestGenerator.h index 30fbfba73..2fb1d0ba4 100644 --- a/src/libtomahawk/playlist/dynamic/echonest/EchonestGenerator.h +++ b/src/libtomahawk/playlist/dynamic/echonest/EchonestGenerator.h @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -28,7 +28,7 @@ #include "dllmacro.h" -namespace Tomahawk +namespace Tomahawk { class EchonestSteerer; @@ -37,19 +37,19 @@ class DLLEXPORT EchonestFactory : public GeneratorFactoryInterface { public: EchonestFactory(); - + virtual GeneratorInterface* create(); virtual dyncontrol_ptr createControl( const QString& controlType = QString() ); virtual QStringList typeSelectors() const; }; - + class EchonestGenerator : public GeneratorInterface { Q_OBJECT public: explicit EchonestGenerator( QObject* parent = 0 ); virtual ~EchonestGenerator(); - + virtual dyncontrol_ptr createControl( const QString& type = QString() ); virtual QPixmap logo(); virtual void generate ( int number = -1 ); @@ -58,26 +58,34 @@ public: virtual QString sentenceSummary(); virtual bool onDemandSteerable() const { return true; } virtual QWidget* steeringWidget(); - + + static QVector< QString > styles(); + static QVector< QString > moods(); private slots: void staticFinished(); void dynamicStarted(); void dynamicFetched(); - + // steering controls void steerField( const QString& field ); void steerDescription( const QString& desc ); void resetSteering(); - + + void stylesReceived(); + void moodsReceived(); + private: Echonest::DynamicPlaylist::PlaylistParams getParams() const throw( std::runtime_error ); query_ptr queryFromSong( const Echonest::Song& song ); void appendRadioType( Echonest::DynamicPlaylist::PlaylistParams& params ) const throw( std::runtime_error ); bool onlyThisArtistType( Echonest::DynamicPlaylist::ArtistTypeEnum type ) const throw( std::runtime_error ); - + Echonest::DynamicPlaylist* m_dynPlaylist; QPixmap m_logo; - + + static QVector< QString > s_styles; + static QVector< QString > s_moods; + QWeakPointer m_steerer; bool m_steeredSinceLastTrack; Echonest::DynamicPlaylist::DynamicControl m_steerData;