1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-08-01 03:40:16 +02:00

Merge pull request #153 from tomahawk-player/genreradio

Implement genreradio
This commit is contained in:
Stefan Derkits
2013-02-11 15:00:05 -08:00
6 changed files with 277 additions and 113 deletions

View File

@@ -605,6 +605,13 @@ TomahawkSettings::doUpgrade( int oldVersion, int newVersion )
} }
} }
} }
else if ( oldVersion == 13 )
{
//Delete old echonest_stylesandmoods.dat file
QFile dataFile( TomahawkUtils::appDataDir().absoluteFilePath( "echonest_stylesandmoods.dat" ) );
const bool removed = dataFile.remove();
tDebug() << "Tried to remove echonest_stylesandmoods.dat, succeeded?" << removed;
}
} }

View File

@@ -28,7 +28,7 @@
#include <QtNetwork/QNetworkProxy> #include <QtNetwork/QNetworkProxy>
#include <QStringList> #include <QStringList>
#define TOMAHAWK_SETTINGS_VERSION 13 #define TOMAHAWK_SETTINGS_VERSION 14
/** /**
* Convenience wrapper around QSettings for tomahawk-specific config * Convenience wrapper around QSettings for tomahawk-specific config

View File

@@ -35,7 +35,7 @@
QHash< QString, QStringList > Tomahawk::EchonestControl::s_suggestCache = QHash< QString, QStringList >(); QHash< QString, QStringList > Tomahawk::EchonestControl::s_suggestCache = QHash< QString, QStringList >();
bool Tomahawk::EchonestControl::s_fetchingMoodsAndStyles = false; bool Tomahawk::EchonestControl::s_fetchingMoodsStylesAndGenres = false;
int Tomahawk::EchonestControl::s_stylePollCount = 0; int Tomahawk::EchonestControl::s_stylePollCount = 0;
@@ -72,7 +72,8 @@ Tomahawk::EchonestControl::matchSelector()
void void
Tomahawk::EchonestControl::setSelectedType ( const QString& type ) Tomahawk::EchonestControl::setSelectedType ( const QString& type )
{ {
if( type != selectedType() ) { if( type != selectedType() )
{
if( !m_input.isNull() ) if( !m_input.isNull() )
delete m_input.data(); delete m_input.data();
if( !m_match.isNull() ) if( !m_match.isNull() )
@@ -81,7 +82,7 @@ Tomahawk::EchonestControl::setSelectedType ( const QString& type )
Tomahawk::DynamicControl::setSelectedType ( type ); Tomahawk::DynamicControl::setSelectedType ( type );
updateWidgets(); updateWidgets();
updateData(); updateData();
// qDebug() << "Setting new type, set data to:" << m_data.first << m_data.second; //qDebug() << "Setting new type, set data to:" << m_data.first << m_data.second;
} }
} }
@@ -89,7 +90,8 @@ Tomahawk::EchonestControl::setSelectedType ( const QString& type )
Echonest::DynamicPlaylist::PlaylistParamData Echonest::DynamicPlaylist::PlaylistParamData
Tomahawk::EchonestControl::toENParam() const Tomahawk::EchonestControl::toENParam() const
{ {
if( m_overrideType != -1 ) { if( m_overrideType != -1 )
{
Echonest::DynamicPlaylist::PlaylistParamData newData = m_data; Echonest::DynamicPlaylist::PlaylistParamData newData = m_data;
newData.first = static_cast<Echonest::DynamicPlaylist::PlaylistParam>( m_overrideType ); newData.first = static_cast<Echonest::DynamicPlaylist::PlaylistParam>( m_overrideType );
return newData; return newData;
@@ -155,7 +157,8 @@ Tomahawk::EchonestControl::updateWidgets()
m_overrideType = -1; m_overrideType = -1;
// make sure the widgets are the proper kind for the selected type, and hook up to their slots // make sure the widgets are the proper kind for the selected type, and hook up to their slots
if( selectedType() == "Artist" ) { if( selectedType() == "Artist" )
{
m_currentType = Echonest::DynamicPlaylist::Artist; m_currentType = Echonest::DynamicPlaylist::Artist;
QComboBox* match = new QComboBox(); QComboBox* match = new QComboBox();
@@ -184,7 +187,9 @@ Tomahawk::EchonestControl::updateWidgets()
m_match = QPointer< QWidget >( match ); m_match = QPointer< QWidget >( match );
m_input = QPointer< QWidget >( input ); m_input = QPointer< QWidget >( input );
m_data.first = m_currentType; m_data.first = m_currentType;
} else if( selectedType() == "Artist Description" ) { }
else if( selectedType() == "Artist Description" )
{
m_currentType = Echonest::DynamicPlaylist::Description; m_currentType = Echonest::DynamicPlaylist::Description;
QLabel* match = new QLabel( tr( "is" ) ); QLabel* match = new QLabel( tr( "is" ) );
@@ -203,7 +208,9 @@ Tomahawk::EchonestControl::updateWidgets()
m_match = QPointer< QWidget >( match ); m_match = QPointer< QWidget >( match );
m_input = QPointer< QWidget >( input ); m_input = QPointer< QWidget >( input );
m_data.first = m_currentType; m_data.first = m_currentType;
} else if( selectedType() == "User Radio" ) { }
else if( selectedType() == "User Radio" )
{
m_currentType = Echonest::DynamicPlaylist::SourceCatalog; m_currentType = Echonest::DynamicPlaylist::SourceCatalog;
QLabel* match = new QLabel( tr( "from user" ) ); QLabel* match = new QLabel( tr( "from user" ) );
@@ -231,7 +238,9 @@ Tomahawk::EchonestControl::updateWidgets()
combo->hide(); combo->hide();
m_match = QPointer< QWidget >( match ); m_match = QPointer< QWidget >( match );
m_input = QPointer< QWidget >( combo ); m_input = QPointer< QWidget >( combo );
} else if( selectedType() == "Song" ) { }
else if( selectedType() == "Song" )
{
m_currentType = Echonest::DynamicPlaylist::SongId; m_currentType = Echonest::DynamicPlaylist::SongId;
QLabel* match = new QLabel( tr( "similar to" ) ); QLabel* match = new QLabel( tr( "similar to" ) );
@@ -251,7 +260,9 @@ Tomahawk::EchonestControl::updateWidgets()
m_match = QPointer< QWidget >( match ); m_match = QPointer< QWidget >( match );
m_input = QPointer< QWidget >( input ); m_input = QPointer< QWidget >( input );
m_data.first = m_currentType; m_data.first = m_currentType;
} else if( selectedType() == "Variety" ) { }
else if( selectedType() == "Variety" )
{
m_currentType = Echonest::DynamicPlaylist::Variety; m_currentType = Echonest::DynamicPlaylist::Variety;
QLabel* match = new QLabel( tr( "is" ) ); QLabel* match = new QLabel( tr( "is" ) );
@@ -272,7 +283,9 @@ Tomahawk::EchonestControl::updateWidgets()
m_match = QPointer< QWidget >( match ); m_match = QPointer< QWidget >( match );
m_input = QPointer< QWidget >( input ); m_input = QPointer< QWidget >( input );
m_data.first = m_currentType; m_data.first = m_currentType;
} else if( selectedType() == "Adventurousness" ) { }
else if( selectedType() == "Adventurousness" )
{
m_currentType = Echonest::DynamicPlaylist::Adventurousness; m_currentType = Echonest::DynamicPlaylist::Adventurousness;
QLabel* match = new QLabel( tr( "is" ) ); QLabel* match = new QLabel( tr( "is" ) );
@@ -294,50 +307,72 @@ Tomahawk::EchonestControl::updateWidgets()
m_match = QPointer< QWidget >( match ); m_match = QPointer< QWidget >( match );
m_input = QPointer< QWidget >( input ); m_input = QPointer< QWidget >( input );
m_data.first = m_currentType; m_data.first = m_currentType;
} else if( selectedType() == "Tempo" ) { }
else if( selectedType() == "Tempo" )
{
m_currentType = Echonest::DynamicPlaylist::MinTempo; m_currentType = Echonest::DynamicPlaylist::MinTempo;
setupMinMaxWidgets( Echonest::DynamicPlaylist::MinTempo, Echonest::DynamicPlaylist::MaxTempo, tr( "0 BPM" ), tr( "500 BPM" ), 500 ); setupMinMaxWidgets( Echonest::DynamicPlaylist::MinTempo, Echonest::DynamicPlaylist::MaxTempo, tr( "0 BPM" ), tr( "500 BPM" ), 500 );
} else if( selectedType() == "Duration" ) { }
else if( selectedType() == "Duration" )
{
m_currentType = Echonest::DynamicPlaylist::MinDuration; m_currentType = Echonest::DynamicPlaylist::MinDuration;
setupMinMaxWidgets( Echonest::DynamicPlaylist::MinDuration, Echonest::DynamicPlaylist::MaxDuration, tr( "0 secs" ), tr( "3600 secs" ), 3600 ); setupMinMaxWidgets( Echonest::DynamicPlaylist::MinDuration, Echonest::DynamicPlaylist::MaxDuration, tr( "0 secs" ), tr( "3600 secs" ), 3600 );
} else if( selectedType() == "Loudness" ) { }
else if( selectedType() == "Loudness" )
{
m_currentType = Echonest::DynamicPlaylist::MinLoudness; m_currentType = Echonest::DynamicPlaylist::MinLoudness;
setupMinMaxWidgets( Echonest::DynamicPlaylist::MinLoudness, Echonest::DynamicPlaylist::MaxLoudness, tr( "-100 dB" ), tr( "100 dB" ), 100 ); setupMinMaxWidgets( Echonest::DynamicPlaylist::MinLoudness, Echonest::DynamicPlaylist::MaxLoudness, tr( "-100 dB" ), tr( "100 dB" ), 100 );
qobject_cast< LabeledSlider* >( m_input.data() )->slider()->setMinimum( -100 ); qobject_cast< LabeledSlider* >( m_input.data() )->slider()->setMinimum( -100 );
} else if( selectedType() == "Danceability" ) { }
else if( selectedType() == "Danceability" )
{
m_currentType = Echonest::DynamicPlaylist::MinDanceability; m_currentType = Echonest::DynamicPlaylist::MinDanceability;
setupMinMaxWidgets( Echonest::DynamicPlaylist::MinDanceability, Echonest::DynamicPlaylist::MaxDanceability, tr( "Less" ), tr( "More" ), 10000 ); setupMinMaxWidgets( Echonest::DynamicPlaylist::MinDanceability, Echonest::DynamicPlaylist::MaxDanceability, tr( "Less" ), tr( "More" ), 10000 );
} else if( selectedType() == "Energy" ) { }
else if( selectedType() == "Energy" )
{
m_currentType = Echonest::DynamicPlaylist::MinEnergy; m_currentType = Echonest::DynamicPlaylist::MinEnergy;
setupMinMaxWidgets( Echonest::DynamicPlaylist::MinEnergy, Echonest::DynamicPlaylist::MaxEnergy, tr( "Less" ), tr( "More" ), 10000 ); setupMinMaxWidgets( Echonest::DynamicPlaylist::MinEnergy, Echonest::DynamicPlaylist::MaxEnergy, tr( "Less" ), tr( "More" ), 10000 );
} else if( selectedType() == "Artist Familiarity" ) { }
else if( selectedType() == "Artist Familiarity" )
{
m_currentType = Echonest::DynamicPlaylist::ArtistMinFamiliarity; m_currentType = Echonest::DynamicPlaylist::ArtistMinFamiliarity;
setupMinMaxWidgets( Echonest::DynamicPlaylist::ArtistMinFamiliarity, Echonest::DynamicPlaylist::ArtistMaxFamiliarity, tr( "Less" ), tr( "More" ), 10000 ); setupMinMaxWidgets( Echonest::DynamicPlaylist::ArtistMinFamiliarity, Echonest::DynamicPlaylist::ArtistMaxFamiliarity, tr( "Less" ), tr( "More" ), 10000 );
} else if( selectedType() == "Artist Hotttnesss" ) { }
else if( selectedType() == "Artist Hotttnesss" )
{
m_currentType = Echonest::DynamicPlaylist::ArtistMinHotttnesss; m_currentType = Echonest::DynamicPlaylist::ArtistMinHotttnesss;
setupMinMaxWidgets( Echonest::DynamicPlaylist::ArtistMinHotttnesss, Echonest::DynamicPlaylist::ArtistMaxHotttnesss, tr( "Less" ), tr( "More" ), 10000 ); setupMinMaxWidgets( Echonest::DynamicPlaylist::ArtistMinHotttnesss, Echonest::DynamicPlaylist::ArtistMaxHotttnesss, tr( "Less" ), tr( "More" ), 10000 );
} else if( selectedType() == "Song Hotttnesss" ) { }
else if( selectedType() == "Song Hotttnesss" )
{
m_currentType = Echonest::DynamicPlaylist::SongMinHotttnesss; m_currentType = Echonest::DynamicPlaylist::SongMinHotttnesss;
setupMinMaxWidgets( Echonest::DynamicPlaylist::SongMinHotttnesss, Echonest::DynamicPlaylist::SongMaxHotttnesss, tr( "Less" ), tr( "More" ), 10000 ); setupMinMaxWidgets( Echonest::DynamicPlaylist::SongMinHotttnesss, Echonest::DynamicPlaylist::SongMaxHotttnesss, tr( "Less" ), tr( "More" ), 10000 );
} else if( selectedType() == "Latitude" ) { }
else if( selectedType() == "Latitude" )
{
m_currentType = Echonest::DynamicPlaylist::ArtistMinLatitude; m_currentType = Echonest::DynamicPlaylist::ArtistMinLatitude;
QString deg = QString( QChar( 0x00B0 ) ); QString deg = QString( QChar( 0x00B0 ) );
setupMinMaxWidgets( Echonest::DynamicPlaylist::ArtistMinLatitude, Echonest::DynamicPlaylist::ArtistMaxLatitude, QString( "-180%1" ).arg( deg ), QString( "180%1" ).arg( deg ), 180 ); setupMinMaxWidgets( Echonest::DynamicPlaylist::ArtistMinLatitude, Echonest::DynamicPlaylist::ArtistMaxLatitude, QString( "-180%1" ).arg( deg ), QString( "180%1" ).arg( deg ), 180 );
qobject_cast< LabeledSlider* >( m_input.data() )->slider()->setMinimum( -180 ); qobject_cast< LabeledSlider* >( m_input.data() )->slider()->setMinimum( -180 );
} else if( selectedType() == "Longitude" ) { }
else if( selectedType() == "Longitude" )
{
m_currentType = Echonest::DynamicPlaylist::ArtistMinLongitude; m_currentType = Echonest::DynamicPlaylist::ArtistMinLongitude;
QString deg = QString( QChar( 0x00B0 ) ); QString deg = QString( QChar( 0x00B0 ) );
setupMinMaxWidgets( Echonest::DynamicPlaylist::ArtistMinLongitude, Echonest::DynamicPlaylist::ArtistMaxLongitude, QString( "-180%1" ).arg( deg ), QString( "180%1" ).arg( deg ), 180 ); setupMinMaxWidgets( Echonest::DynamicPlaylist::ArtistMinLongitude, Echonest::DynamicPlaylist::ArtistMaxLongitude, QString( "-180%1" ).arg( deg ), QString( "180%1" ).arg( deg ), 180 );
qobject_cast< LabeledSlider* >( m_input.data() )->slider()->setMinimum( -180 ); qobject_cast< LabeledSlider* >( m_input.data() )->slider()->setMinimum( -180 );
} else if( selectedType() == "Mode" ) { }
else if( selectedType() == "Mode" )
{
m_currentType = Echonest::DynamicPlaylist::Mode; m_currentType = Echonest::DynamicPlaylist::Mode;
QLabel* match = new QLabel( tr( "is" ) ); QLabel* match = new QLabel( tr( "is" ) );
@@ -356,7 +391,9 @@ Tomahawk::EchonestControl::updateWidgets()
combo->hide(); combo->hide();
m_match = QPointer< QWidget >( match ); m_match = QPointer< QWidget >( match );
m_input = QPointer< QWidget >( combo ); m_input = QPointer< QWidget >( combo );
} else if( selectedType() == "Key" ) { }
else if( selectedType() == "Key" )
{
m_currentType = Echonest::DynamicPlaylist::Key; m_currentType = Echonest::DynamicPlaylist::Key;
QLabel* match = new QLabel( tr( "is" ) ); QLabel* match = new QLabel( tr( "is" ) );
@@ -385,7 +422,9 @@ Tomahawk::EchonestControl::updateWidgets()
combo->hide(); combo->hide();
m_match = QPointer< QWidget >( match ); m_match = QPointer< QWidget >( match );
m_input = QPointer< QWidget >( combo ); m_input = QPointer< QWidget >( combo );
} else if( selectedType() == "Sorting" ) { }
else if( selectedType() == "Sorting" )
{
m_currentType = Echonest::DynamicPlaylist::Sort; m_currentType = Echonest::DynamicPlaylist::Sort;
QComboBox* match = new QComboBox(); QComboBox* match = new QComboBox();
@@ -418,11 +457,15 @@ Tomahawk::EchonestControl::updateWidgets()
combo->hide(); combo->hide();
m_match = QPointer< QWidget >( match ); m_match = QPointer< QWidget >( match );
m_input = QPointer< QWidget >( combo ); m_input = QPointer< QWidget >( combo );
} else if( selectedType() == "Mood" || selectedType() == "Style" ) { }
else if( selectedType() == "Mood" || selectedType() == "Style" || selectedType() == "Genre" )
{
if( selectedType() == "Mood" ) if( selectedType() == "Mood" )
m_currentType = Echonest::DynamicPlaylist::Mood; m_currentType = Echonest::DynamicPlaylist::Mood;
else else if ( selectedType() == "Style" )
m_currentType = Echonest::DynamicPlaylist::Style; m_currentType = Echonest::DynamicPlaylist::Style;
else
m_currentType = Echonest::DynamicPlaylist::Genre;
QLabel* match = new QLabel( tr( "is" ) ); QLabel* match = new QLabel( tr( "is" ) );
@@ -440,8 +483,10 @@ Tomahawk::EchonestControl::updateWidgets()
m_match = QPointer< QWidget >( match ); m_match = QPointer< QWidget >( match );
m_input = QPointer< QWidget >( combo ); m_input = QPointer< QWidget >( combo );
insertMoodsAndStyles(); insertMoodsStylesAndGenres();
} else if( selectedType() == "Song Type" ) { }
else if( selectedType() == "Song Type" )
{
m_currentType = Echonest::DynamicPlaylist::SongType; m_currentType = Echonest::DynamicPlaylist::SongType;
QComboBox* match = new QComboBox(); QComboBox* match = new QComboBox();
@@ -463,7 +508,9 @@ Tomahawk::EchonestControl::updateWidgets()
m_match = QPointer< QWidget >( match ); m_match = QPointer< QWidget >( match );
m_input = QPointer< QWidget >( combo ); m_input = QPointer< QWidget >( combo );
} else { }
else
{
m_match = QPointer<QWidget>( new QWidget ); m_match = QPointer<QWidget>( new QWidget );
m_input = QPointer<QWidget>( new QWidget ); m_input = QPointer<QWidget>( new QWidget );
} }
@@ -502,36 +549,53 @@ Tomahawk::EchonestControl::setupMinMaxWidgets( Echonest::DynamicPlaylist::Playli
void void
Tomahawk::EchonestControl::updateData() Tomahawk::EchonestControl::updateData()
{ {
if( selectedType() == "Artist" ) { if( selectedType() == "Artist" )
{
QComboBox* combo = qobject_cast<QComboBox*>( m_match.data() ); QComboBox* combo = qobject_cast<QComboBox*>( m_match.data() );
if( combo ) { if( combo )
{
m_matchString = combo->currentText(); m_matchString = combo->currentText();
m_matchData = combo->itemData( combo->currentIndex() ).toString(); m_matchData = combo->itemData( combo->currentIndex() ).toString();
} }
QLineEdit* edit = qobject_cast<QLineEdit*>( m_input.data() ); QLineEdit* edit = qobject_cast<QLineEdit*>( m_input.data() );
if( edit && !edit->text().isEmpty() ) { if( edit && !edit->text().isEmpty() )
{
m_data.first = m_currentType; m_data.first = m_currentType;
m_data.second = edit->text(); m_data.second = edit->text();
} }
} else if( selectedType() == "Artist Description" || selectedType() == "Song" ) { }
else if( selectedType() == "Artist Description" || selectedType() == "Song" )
{
QLineEdit* edit = qobject_cast<QLineEdit*>( m_input.data() ); QLineEdit* edit = qobject_cast<QLineEdit*>( m_input.data() );
if( edit && !edit->text().isEmpty() ) { if( edit && !edit->text().isEmpty() )
{
m_data.first = m_currentType; m_data.first = m_currentType;
m_data.second = edit->text(); m_data.second = edit->text();
} }
} else if( selectedType() == "Variety" || selectedType() == "Adventurousness" ) { }
else if( selectedType() == "Variety" || selectedType() == "Adventurousness" )
{
LabeledSlider* s = qobject_cast<LabeledSlider*>( m_input.data() ); LabeledSlider* s = qobject_cast<LabeledSlider*>( m_input.data() );
if( s ) { if( s )
{
m_data.first = m_currentType; m_data.first = m_currentType;
m_data.second = (qreal)s->slider()->value() / 10000.0; m_data.second = (qreal)s->slider()->value() / 10000.0;
} }
} else if( selectedType() == "Tempo" || selectedType() == "Duration" || selectedType() == "Loudness" || selectedType() == "Latitude" || selectedType() == "Longitude" ) { }
else if( selectedType() == "Tempo" || selectedType() == "Duration" || selectedType() == "Loudness" || selectedType() == "Latitude" || selectedType() == "Longitude" )
{
updateFromComboAndSlider(); updateFromComboAndSlider();
} else if( selectedType() == "Danceability" || selectedType() == "Energy" || selectedType() == "Artist Familiarity" || selectedType() == "Artist Hotttnesss" || selectedType() == "Song Hotttnesss" ) { }
else if( selectedType() == "Danceability" || selectedType() == "Energy" || selectedType() == "Artist Familiarity" || selectedType() == "Artist Hotttnesss" || selectedType() == "Song Hotttnesss" )
{
updateFromComboAndSlider( true ); updateFromComboAndSlider( true );
} else if( selectedType() == "Mode" || selectedType() == "Key" || selectedType() == "Mood" || selectedType() == "Style" || selectedType() == "User Radio" ) { }
else if( selectedType() == "Mode" || selectedType() == "Key" || selectedType() == "Mood" || selectedType() == "Style" || selectedType() == "Genre" || selectedType() == "User Radio" )
{
updateFromLabelAndCombo(); updateFromLabelAndCombo();
} else if( selectedType() == "Sorting" ) { }
else if( selectedType() == "Sorting" )
{
QComboBox* match = qobject_cast<QComboBox*>( m_match.data() ); QComboBox* match = qobject_cast<QComboBox*>( m_match.data() );
QComboBox* input = qobject_cast< QComboBox* >( m_input.data() ); QComboBox* input = qobject_cast< QComboBox* >( m_input.data() );
if( match && input ) { if( match && input ) {
@@ -544,10 +608,13 @@ Tomahawk::EchonestControl::updateData()
m_data.second = enumVal; m_data.second = enumVal;
// qDebug() << "SAVING" << input->currentIndex() << "AS" << enumVal << "(" << input->itemData( input->currentIndex() ).toInt() << "+" << m_matchData.toInt() << ")"; // qDebug() << "SAVING" << input->currentIndex() << "AS" << enumVal << "(" << input->itemData( input->currentIndex() ).toInt() << "+" << m_matchData.toInt() << ")";
} }
} else if( selectedType() == "Song Type" ) { }
else if( selectedType() == "Song Type" )
{
QComboBox* match = qobject_cast<QComboBox*>( m_match.data() ); QComboBox* match = qobject_cast<QComboBox*>( m_match.data() );
QComboBox* combo = qobject_cast< QComboBox* >( m_input.data() ); QComboBox* combo = qobject_cast< QComboBox* >( m_input.data() );
if ( match && combo ) { if ( match && combo )
{
m_matchString = match->currentText(); m_matchString = match->currentText();
m_matchData = match->itemData( match->currentIndex() ).toString(); m_matchData = match->itemData( match->currentIndex() ).toString();
@@ -569,12 +636,14 @@ void
Tomahawk::EchonestControl::updateFromComboAndSlider( bool smooth ) Tomahawk::EchonestControl::updateFromComboAndSlider( bool smooth )
{ {
QComboBox* combo = qobject_cast<QComboBox*>( m_match.data() ); QComboBox* combo = qobject_cast<QComboBox*>( m_match.data() );
if( combo ) { if( combo )
{
m_matchString = combo->currentText(); m_matchString = combo->currentText();
m_matchData = combo->itemData( combo->currentIndex() ).toString(); m_matchData = combo->itemData( combo->currentIndex() ).toString();
} }
LabeledSlider* ls = qobject_cast<LabeledSlider*>( m_input.data() ); LabeledSlider* ls = qobject_cast<LabeledSlider*>( m_input.data() );
if( ls && ls->slider() ) { if( ls && ls->slider() )
{
m_data.first = static_cast< Echonest::DynamicPlaylist::PlaylistParam >( combo->itemData( combo->currentIndex() ).toInt() ); m_data.first = static_cast< Echonest::DynamicPlaylist::PlaylistParam >( combo->itemData( combo->currentIndex() ).toInt() );
m_data.second = ls->slider()->value() / ( smooth ? 10000. : 1.0 ); m_data.second = ls->slider()->value() / ( smooth ? 10000. : 1.0 );
} }
@@ -585,7 +654,8 @@ void
Tomahawk::EchonestControl::updateFromLabelAndCombo() Tomahawk::EchonestControl::updateFromLabelAndCombo()
{ {
QComboBox* s = qobject_cast<QComboBox*>( m_input.data() ); QComboBox* s = qobject_cast<QComboBox*>( m_input.data() );
if( s ) { if( s )
{
m_data.first = m_currentType; m_data.first = m_currentType;
m_data.second = s->itemData( s->currentIndex() ); m_data.second = s->itemData( s->currentIndex() );
} }
@@ -596,18 +666,22 @@ Tomahawk::EchonestControl::updateFromLabelAndCombo()
void void
Tomahawk::EchonestControl::updateWidgetsFromData() Tomahawk::EchonestControl::updateWidgetsFromData()
{ {
if( selectedType() == "Artist" ) { if( selectedType() == "Artist" )
{
QComboBox* combo = qobject_cast<QComboBox*>( m_match.data() ); QComboBox* combo = qobject_cast<QComboBox*>( m_match.data() );
if( combo ) if( combo )
combo->setCurrentIndex( combo->findData( m_matchData ) ); combo->setCurrentIndex( combo->findData( m_matchData ) );
QLineEdit* edit = qobject_cast<QLineEdit*>( m_input.data() ); QLineEdit* edit = qobject_cast<QLineEdit*>( m_input.data() );
if( edit ) if( edit )
edit->setText( m_data.second.toString() ); edit->setText( m_data.second.toString() );
} else if( selectedType() == "Artist Description" || selectedType() == "Song" ) { }
else if( selectedType() == "Artist Description" || selectedType() == "Song" )
{
QLineEdit* edit = qobject_cast<QLineEdit*>( m_input.data() ); QLineEdit* edit = qobject_cast<QLineEdit*>( m_input.data() );
if( edit ) if( edit )
edit->setText( m_data.second.toString() ); edit->setText( m_data.second.toString() );
} else if ( selectedType() == "User Radio" ) }
else if ( selectedType() == "User Radio" )
{ {
QComboBox* combo = qobject_cast< QComboBox* >( m_input.data() ); QComboBox* combo = qobject_cast< QComboBox* >( m_input.data() );
if ( combo ) if ( combo )
@@ -627,17 +701,27 @@ Tomahawk::EchonestControl::updateWidgetsFromData()
combo->setCurrentIndex( combo->findData( m_data.second ) ); combo->setCurrentIndex( combo->findData( m_data.second ) );
} }
} else if( selectedType() == "Variety" || selectedType() == "Adventurousness" ) { }
else if( selectedType() == "Variety" || selectedType() == "Adventurousness" )
{
LabeledSlider* s = qobject_cast<LabeledSlider*>( m_input.data() ); LabeledSlider* s = qobject_cast<LabeledSlider*>( m_input.data() );
if( s ) if( s )
s->slider()->setValue( m_data.second.toDouble() * 10000 ); s->slider()->setValue( m_data.second.toDouble() * 10000 );
} else if( selectedType() == "Tempo" || selectedType() == "Duration" || selectedType() == "Loudness" || selectedType() == "Latitude" || selectedType() == "Longitude" ) { }
else if( selectedType() == "Tempo" || selectedType() == "Duration" || selectedType() == "Loudness" || selectedType() == "Latitude" || selectedType() == "Longitude" )
{
updateToComboAndSlider(); updateToComboAndSlider();
} else if( selectedType() == "Danceability" || selectedType() == "Energy" || selectedType() == "Artist Familiarity" || selectedType() == "Artist Hotttnesss" || selectedType() == "Song Hotttnesss" ) { }
else if( selectedType() == "Danceability" || selectedType() == "Energy" || selectedType() == "Artist Familiarity" || selectedType() == "Artist Hotttnesss" || selectedType() == "Song Hotttnesss" )
{
updateToComboAndSlider( true ); updateToComboAndSlider( true );
} else if( selectedType() == "Mode" || selectedType() == "Key" || selectedType() == "Mood" || selectedType() == "Style") { }
else if( selectedType() == "Mode" || selectedType() == "Key" || selectedType() == "Mood" || selectedType() == "Style" || selectedType() == "Genre" )
{
updateToLabelAndCombo(); updateToLabelAndCombo();
} else if( selectedType() == "Sorting" ) { }
else if( selectedType() == "Sorting" )
{
QComboBox* match = qobject_cast<QComboBox*>( m_match.data() ); QComboBox* match = qobject_cast<QComboBox*>( m_match.data() );
QComboBox* input = qobject_cast< QComboBox* >( m_input.data() ); QComboBox* input = qobject_cast< QComboBox* >( m_input.data() );
if( match && input ) { if( match && input ) {
@@ -646,9 +730,11 @@ Tomahawk::EchonestControl::updateWidgetsFromData()
// HACK alert. if it's odd, subtract 1 // HACK alert. if it's odd, subtract 1
int val = ( m_data.second.toInt() - ( m_data.second.toInt() % 2 ) ) / 2; int val = ( m_data.second.toInt() - ( m_data.second.toInt() % 2 ) ) / 2;
input->setCurrentIndex( val ); input->setCurrentIndex( val );
// qDebug() << "LOADING" << m_data.second.toInt() << "AS" << val; //qDebug() << "LOADING" << m_data.second.toInt() << "AS" << val;
} }
} else if( selectedType() == "Song Type" ) { }
else if( selectedType() == "Song Type" )
{
QComboBox* match = qobject_cast<QComboBox*>( m_match.data() ); QComboBox* match = qobject_cast<QComboBox*>( m_match.data() );
QComboBox* combo = qobject_cast< QComboBox* >( m_input.data() ); QComboBox* combo = qobject_cast< QComboBox* >( m_input.data() );
if ( match && combo ) { if ( match && combo ) {
@@ -678,9 +764,8 @@ void
Tomahawk::EchonestControl::updateToLabelAndCombo() Tomahawk::EchonestControl::updateToLabelAndCombo()
{ {
QComboBox* s = qobject_cast< QComboBox* >( m_input.data() ); QComboBox* s = qobject_cast< QComboBox* >( m_input.data() );
if( s ) { if( s )
s->setCurrentIndex( s->findData( m_data.second ) ); s->setCurrentIndex( s->findData( m_data.second ) );
}
} }
@@ -896,7 +981,16 @@ Tomahawk::EchonestControl::calculateSummary()
Q_ASSERT( qobject_cast< QComboBox* >( m_input.data() ) ); Q_ASSERT( qobject_cast< QComboBox* >( m_input.data() ) );
QString text = qobject_cast< QComboBox* >( m_input.data() )->currentText().toLower(); QString text = qobject_cast< QComboBox* >( m_input.data() )->currentText().toLower();
summary = tr( "in a %1 style" ).arg( text ); summary = tr( "in a %1 style" ).arg( text );
} else if( selectedType() == "Song Type" ) { }
else if ( selectedType() == "Genre" )
{
Q_ASSERT( !m_input.isNull() );
Q_ASSERT( qobject_cast< QComboBox* >( m_input.data() ) );
QString text = qobject_cast< QComboBox* >( m_input.data() )->currentText().toLower();
summary = tr( "where genre is %1" ).arg( text );
}
else if ( selectedType() == "Song Type" )
{
Q_ASSERT( !m_input.isNull() ); Q_ASSERT( !m_input.isNull() );
Q_ASSERT( qobject_cast< QComboBox* >( m_input.data() ) ); Q_ASSERT( qobject_cast< QComboBox* >( m_input.data() ) );
QString text = qobject_cast< QComboBox* >( m_input.data() )->currentText(); QString text = qobject_cast< QComboBox* >( m_input.data() )->currentText();
@@ -916,13 +1010,13 @@ Tomahawk::EchonestControl::calculateSummary()
void void
Tomahawk::EchonestControl::checkForMoodsOrStylesFetched() Tomahawk::EchonestControl::checkForMoodsStylesOrGenresFetched()
{ {
s_fetchingMoodsAndStyles = false; s_fetchingMoodsStylesAndGenres = false;
if( selectedType() == "Mood" || selectedType() == "Style" ) { if( selectedType() == "Mood" || selectedType() == "Style" || selectedType() == "Genre" ) {
QComboBox* cb = qobject_cast< QComboBox* >( m_input.data() ); QComboBox* cb = qobject_cast< QComboBox* >( m_input.data() );
if( cb && cb->count() == 0 ) { // got nothing, so lets populate if( cb && cb->count() == 0 ) { // got nothing, so lets populate
if( insertMoodsAndStyles() ) if( insertMoodsStylesAndGenres() )
updateWidgetsFromData(); updateWidgetsFromData();
} }
} }
@@ -930,9 +1024,22 @@ Tomahawk::EchonestControl::checkForMoodsOrStylesFetched()
bool bool
Tomahawk::EchonestControl::insertMoodsAndStyles() Tomahawk::EchonestControl::insertMoodsStylesAndGenres()
{ {
QStringList src = selectedType() == "Mood" ? EchonestGenerator::moods() : EchonestGenerator::styles(); QStringList src;
if ( selectedType() == "Mood" )
{
src = EchonestGenerator::moods();
}
else if ( selectedType() == "Style" )
{
src = EchonestGenerator::styles();
}
else
{
src = EchonestGenerator::genres();
}
QComboBox* combo = qobject_cast< QComboBox* >( m_input.data() ); QComboBox* combo = qobject_cast< QComboBox* >( m_input.data() );
if( !combo ) if( !combo )
return false; return false;
@@ -941,10 +1048,12 @@ Tomahawk::EchonestControl::insertMoodsAndStyles()
combo->addItem( item, item ); combo->addItem( item, item );
} }
if( src.isEmpty() && !combo->count() ) { if( src.isEmpty() && !combo->count() )
if( s_stylePollCount <= 20 && !s_fetchingMoodsAndStyles ) { // try for 20s to get the styles... {
s_fetchingMoodsAndStyles = true; if( s_stylePollCount <= 20 && !s_fetchingMoodsStylesAndGenres )
QTimer::singleShot( 1000, this, SLOT( checkForMoodsOrStylesFetched() ) ); { // try for 20s to get the styles...
s_fetchingMoodsStylesAndGenres = true;
QTimer::singleShot( 1000, this, SLOT( checkForMoodsStylesOrGenresFetched() ) );
} }
s_stylePollCount++; s_stylePollCount++;
return false; return false;

View File

@@ -61,7 +61,7 @@ private slots:
void artistTextEdited( const QString& ); void artistTextEdited( const QString& );
void suggestFinished(); void suggestFinished();
void checkForMoodsOrStylesFetched(); void checkForMoodsStylesOrGenresFetched();
private: private:
void updateWidgets(); void updateWidgets();
void updateWidgetsFromData(); void updateWidgetsFromData();
@@ -70,7 +70,7 @@ private:
void setupMinMaxWidgets( Echonest::DynamicPlaylist::PlaylistParam min, Echonest::DynamicPlaylist::PlaylistParam max, const QString& leftL, const QString& rightL, int maxRange ); void setupMinMaxWidgets( Echonest::DynamicPlaylist::PlaylistParam min, Echonest::DynamicPlaylist::PlaylistParam max, const QString& leftL, const QString& rightL, int maxRange );
void updateFromComboAndSlider( bool smooth = false ); void updateFromComboAndSlider( bool smooth = false );
void updateFromLabelAndCombo(); void updateFromLabelAndCombo();
bool insertMoodsAndStyles(); bool insertMoodsStylesAndGenres();
void updateToComboAndSlider( bool smooth = false ); void updateToComboAndSlider( bool smooth = false );
void updateToLabelAndCombo(); void updateToLabelAndCombo();
@@ -93,7 +93,7 @@ private:
Echonest::DynamicPlaylist::PlaylistParamData m_data; Echonest::DynamicPlaylist::PlaylistParamData m_data;
QVariant m_cacheData; QVariant m_cacheData;
static bool s_fetchingMoodsAndStyles; static bool s_fetchingMoodsStylesAndGenres;
static int s_stylePollCount; static int s_stylePollCount;
QSet< QNetworkReply* > m_suggestWorkers; QSet< QNetworkReply* > m_suggestWorkers;

View File

@@ -21,6 +21,7 @@
#include "playlist/dynamic/echonest/EchonestSteerer.h" #include "playlist/dynamic/echonest/EchonestSteerer.h"
#include "Query.h" #include "Query.h"
#include "utils/TomahawkUtils.h" #include "utils/TomahawkUtils.h"
#include "utils/TomahawkCache.h"
#include "TomahawkSettings.h" #include "TomahawkSettings.h"
#include "database/DatabaseCommand_CollectionAttributes.h" #include "database/DatabaseCommand_CollectionAttributes.h"
#include "database/Database.h" #include "database/Database.h"
@@ -35,8 +36,10 @@ using namespace Tomahawk;
QStringList EchonestGenerator::s_moods = QStringList(); QStringList EchonestGenerator::s_moods = QStringList();
QStringList EchonestGenerator::s_styles = QStringList(); QStringList EchonestGenerator::s_styles = QStringList();
QStringList EchonestGenerator::s_genres = QStringList();
QNetworkReply* EchonestGenerator::s_moodsJob = 0; QNetworkReply* EchonestGenerator::s_moodsJob = 0;
QNetworkReply* EchonestGenerator::s_stylesJob = 0; QNetworkReply* EchonestGenerator::s_stylesJob = 0;
QNetworkReply* EchonestGenerator::s_genresJob = 0;
CatalogManager* EchonestGenerator::s_catalogs = 0; CatalogManager* EchonestGenerator::s_catalogs = 0;
@@ -63,7 +66,7 @@ EchonestFactory::createControl( const QString& controlType )
QStringList QStringList
EchonestFactory::typeSelectors() const EchonestFactory::typeSelectors() const
{ {
QStringList types = QStringList() << "Artist" << "Artist Description" << "User Radio" << "Song" << "Mood" << "Style" << "Adventurousness" << "Variety" << "Tempo" << "Duration" << "Loudness" QStringList types = QStringList() << "Artist" << "Artist Description" << "User Radio" << "Song" << "Genre" << "Mood" << "Style" << "Adventurousness" << "Variety" << "Tempo" << "Duration" << "Loudness"
<< "Danceability" << "Energy" << "Artist Familiarity" << "Artist Hotttnesss" << "Song Hotttnesss" << "Danceability" << "Energy" << "Artist Familiarity" << "Artist Hotttnesss" << "Song Hotttnesss"
<< "Longitude" << "Latitude" << "Mode" << "Key" << "Sorting" << "Song Type"; << "Longitude" << "Latitude" << "Mode" << "Key" << "Sorting" << "Song Type";
@@ -126,7 +129,7 @@ EchonestGenerator::EchonestGenerator ( QObject* parent )
m_mode = OnDemand; m_mode = OnDemand;
m_logo.load( RESPATH "/images/echonest_logo.png" ); m_logo.load( RESPATH "/images/echonest_logo.png" );
loadStylesAndMoods(); loadStylesMoodsAndGenres();
connect( s_catalogs, SIGNAL( catalogsUpdated() ), this, SLOT( knownCatalogsChanged() ) ); connect( s_catalogs, SIGNAL( catalogsUpdated() ), this, SLOT( knownCatalogsChanged() ) );
} }
@@ -470,12 +473,17 @@ EchonestGenerator::appendRadioType( Echonest::DynamicPlaylist::PlaylistParams& p
/// 4. artist-radio: If all the artist entries are Similar To. If some were but not all, error out. /// 4. artist-radio: If all the artist entries are Similar To. If some were but not all, error out.
/// 5. song-radio: If all the artist entries are Similar To. If some were but not all, error out. /// 5. song-radio: If all the artist entries are Similar To. If some were but not all, error out.
bool someCatalog = false; bool someCatalog = false;
bool genreType = false;
foreach( const dyncontrol_ptr& control, m_controls ) { foreach( const dyncontrol_ptr& control, m_controls ) {
if ( control->selectedType() == "User Radio" ) if ( control->selectedType() == "User Radio" )
someCatalog = true; someCatalog = true;
else if ( control->selectedType() == "Genre" )
genreType = true;
} }
if( someCatalog ) if( someCatalog )
params.append( Echonest::DynamicPlaylist::PlaylistParamData( Echonest::DynamicPlaylist::Type, Echonest::DynamicPlaylist::CatalogRadioType ) ); params.append( Echonest::DynamicPlaylist::PlaylistParamData( Echonest::DynamicPlaylist::Type, Echonest::DynamicPlaylist::CatalogRadioType ) );
else if ( genreType )
params.append( Echonest::DynamicPlaylist::PlaylistParamData( Echonest::DynamicPlaylist::Type, Echonest::DynamicPlaylist::GenreRadioType ) );
else if( onlyThisArtistType( Echonest::DynamicPlaylist::ArtistType ) ) else if( onlyThisArtistType( Echonest::DynamicPlaylist::ArtistType ) )
params.append( Echonest::DynamicPlaylist::PlaylistParamData( Echonest::DynamicPlaylist::Type, Echonest::DynamicPlaylist::ArtistType ) ); params.append( Echonest::DynamicPlaylist::PlaylistParamData( Echonest::DynamicPlaylist::Type, Echonest::DynamicPlaylist::ArtistType ) );
else if( onlyThisArtistType( Echonest::DynamicPlaylist::ArtistDescriptionType ) ) else if( onlyThisArtistType( Echonest::DynamicPlaylist::ArtistDescriptionType ) )
@@ -603,50 +611,53 @@ EchonestGenerator::sentenceSummary()
} }
void void
EchonestGenerator::loadStylesAndMoods() EchonestGenerator::loadStylesMoodsAndGenres()
{ {
if( !s_styles.isEmpty() || !s_moods.isEmpty() ) if( !s_styles.isEmpty() && !s_moods.isEmpty() && !s_genres.isEmpty() )
return; return;
QFile dataFile( TomahawkUtils::appDataDir().absoluteFilePath( "echonest_stylesandmoods.dat" ) ); QVariant styles = TomahawkUtils::Cache::instance()->getData( "EchonesGenerator", "styles" );
if( !dataFile.exists() ) // load if ( styles.isValid() && styles.canConvert< QStringList >() )
{ {
s_styles = styles.toStringList();
}
else
{
tLog() << "Styles not in cache or too old, refetching styles ...";
s_stylesJob = Echonest::Artist::listTerms( "style" ); s_stylesJob = Echonest::Artist::listTerms( "style" );
connect( s_stylesJob, SIGNAL( finished() ), this, SLOT( stylesReceived() ) ); connect( s_stylesJob, SIGNAL( finished() ), this, SLOT( stylesReceived() ) );
}
QVariant moods = TomahawkUtils::Cache::instance()->getData( "EchonesGenerator", "moods" );
if ( moods.isValid() && moods.canConvert< QStringList >() ) {
s_moods = moods.toStringList();
}
else
{
tLog() << "Moods not in cache or too old, refetching moods ...";
s_moodsJob = Echonest::Artist::listTerms( "mood" ); s_moodsJob = Echonest::Artist::listTerms( "mood" );
connect( s_moodsJob, SIGNAL( finished() ), this, SLOT( moodsReceived() ) ); connect( s_moodsJob, SIGNAL( finished() ), this, SLOT( moodsReceived() ) );
} else }
{
if( !dataFile.open( QIODevice::ReadOnly ) )
{
tLog() << "Failed to open for reading styles/moods db file:" << dataFile.fileName();
return;
}
QString allData = QString::fromUtf8( dataFile.readAll() ); QVariant genres = TomahawkUtils::Cache::instance()->getData( "EchonesGenerator", "genres" );
QStringList parts = allData.split( "\n" ); if ( genres.isValid() && genres.canConvert< QStringList >() )
if( parts.size() != 2 ) {
{ s_genres = genres.toStringList();
tLog() << "Didn't get both moods and styles in file...:" << allData; }
return; else
} {
s_moods = parts[ 0 ].split( "|" ); tLog() << "Genres not in cache or too old, refetching genres ...";
s_styles = parts[ 1 ].split( "|" ); s_genresJob = Echonest::Artist::fetchGenres();
connect( s_genresJob, SIGNAL( finished() ), this, SLOT( genresReceived() ) );
} }
} }
void void
EchonestGenerator::saveStylesAndMoods() EchonestGenerator::saveStylesMoodsAndGenres()
{ {
QFile dataFile( TomahawkUtils::appDataDir().absoluteFilePath( "echonest_stylesandmoods.dat" ) ); TomahawkUtils::Cache::instance()->putData( "EchonesGenerator", 1209600000 /* 2 weeks */, "moods", QVariant::fromValue< QStringList >( s_moods ) );
if( !dataFile.open( QIODevice::WriteOnly ) ) TomahawkUtils::Cache::instance()->putData( "EchonesGenerator", 1209600000 /* 2 weeks */, "styles", QVariant::fromValue< QStringList >( s_styles ) );
{ TomahawkUtils::Cache::instance()->putData( "EchonesGenerator", 1209600000 /* 2 weeks */, "genres", QVariant::fromValue< QStringList >( s_genres ) );
tLog() << "Failed to open styles and moods data file for saving:" << dataFile.errorString() << dataFile.fileName();
return;
}
QByteArray data = QString( "%1\n%2" ).arg( s_moods.join( "|" ) ).arg( s_styles.join( "|" ) ).toUtf8();
dataFile.write( data );
} }
@@ -664,15 +675,18 @@ EchonestGenerator::moodsReceived()
QNetworkReply* r = qobject_cast< QNetworkReply* >( sender() ); QNetworkReply* r = qobject_cast< QNetworkReply* >( sender() );
Q_ASSERT( r ); Q_ASSERT( r );
try { try
{
s_moods = Echonest::Artist::parseTermList( r ).toList(); s_moods = Echonest::Artist::parseTermList( r ).toList();
} catch( Echonest::ParseError& e ) { }
catch( Echonest::ParseError& e )
{
qWarning() << "Echonest failed to parse moods list"; qWarning() << "Echonest failed to parse moods list";
} }
s_moodsJob = 0; s_moodsJob = 0;
if( !s_styles.isEmpty() ) if( !s_styles.isEmpty() && !s_genres.isEmpty() )
saveStylesAndMoods(); saveStylesMoodsAndGenres();
} }
@@ -689,13 +703,42 @@ EchonestGenerator::stylesReceived()
QNetworkReply* r = qobject_cast< QNetworkReply* >( sender() ); QNetworkReply* r = qobject_cast< QNetworkReply* >( sender() );
Q_ASSERT( r ); Q_ASSERT( r );
try { try
{
s_styles = Echonest::Artist::parseTermList( r ).toList(); s_styles = Echonest::Artist::parseTermList( r ).toList();
} catch( Echonest::ParseError& e ) { }
catch( Echonest::ParseError& e )
{
qWarning() << "Echonest failed to parse styles list"; qWarning() << "Echonest failed to parse styles list";
} }
s_stylesJob = 0; s_stylesJob = 0;
if( !s_moods.isEmpty() ) if( !s_moods.isEmpty() && !s_styles.isEmpty() )
saveStylesAndMoods(); saveStylesMoodsAndGenres();
}
QStringList
EchonestGenerator::genres()
{
return s_genres;
}
void
EchonestGenerator::genresReceived()
{
QNetworkReply* r = qobject_cast< QNetworkReply* >( sender() );
Q_ASSERT( r );
try
{
s_genres = Echonest::Artist::parseGenreList( r ).toList();
}
catch( Echonest::ParseError& e )
{
qWarning() << "Echonest failed to parse genres list";
}
s_genresJob = 0;
if( !s_moods.isEmpty() && !s_styles.isEmpty() )
saveStylesMoodsAndGenres();
} }

View File

@@ -82,6 +82,7 @@ public:
static QStringList styles(); static QStringList styles();
static QStringList moods(); static QStringList moods();
static QStringList genres();
static QStringList userCatalogs(); static QStringList userCatalogs();
static QByteArray catalogId( const QString& collectionId ); static QByteArray catalogId( const QString& collectionId );
@@ -99,6 +100,7 @@ private slots:
void stylesReceived(); void stylesReceived();
void moodsReceived(); void moodsReceived();
void genresReceived();
void knownCatalogsChanged(); void knownCatalogsChanged();
void songLookupFinished(); void songLookupFinished();
@@ -110,16 +112,18 @@ private:
Echonest::DynamicPlaylist::ArtistTypeEnum appendRadioType( Echonest::DynamicPlaylist::PlaylistParams& params ) const throw( std::runtime_error ); Echonest::DynamicPlaylist::ArtistTypeEnum appendRadioType( Echonest::DynamicPlaylist::PlaylistParams& params ) const throw( std::runtime_error );
bool onlyThisArtistType( Echonest::DynamicPlaylist::ArtistTypeEnum type ) const throw( std::runtime_error ); bool onlyThisArtistType( Echonest::DynamicPlaylist::ArtistTypeEnum type ) const throw( std::runtime_error );
void loadStylesAndMoods(); void loadStylesMoodsAndGenres();
void saveStylesAndMoods(); void saveStylesMoodsAndGenres();
Echonest::DynamicPlaylist* m_dynPlaylist; Echonest::DynamicPlaylist* m_dynPlaylist;
QPixmap m_logo; QPixmap m_logo;
static QStringList s_styles; static QStringList s_styles;
static QStringList s_moods; static QStringList s_moods;
static QStringList s_genres;
static QNetworkReply* s_stylesJob; static QNetworkReply* s_stylesJob;
static QNetworkReply* s_moodsJob; static QNetworkReply* s_moodsJob;
static QNetworkReply* s_genresJob;
static CatalogManager* s_catalogs; static CatalogManager* s_catalogs;
@@ -131,3 +135,4 @@ private:
}; };
#endif #endif