diff --git a/data/sql/dbmigrate-24_to_25.sql b/data/sql/dbmigrate-24_to_25.sql index 181df2705..2afabdbc0 100644 --- a/data/sql/dbmigrate-24_to_25.sql +++ b/data/sql/dbmigrate-24_to_25.sql @@ -1,7 +1,6 @@ -- Script to migate from db version 24 to 25. -- Added the social_attributes table. -- --- Separate each command with %% ALTER TABLE dynamic_playlist RENAME TO tmp_dynamic_playlist; diff --git a/resources.qrc b/resources.qrc index 763a4d08e..50f1b79d7 100644 --- a/resources.qrc +++ b/resources.qrc @@ -97,6 +97,7 @@ ./data/sql/dbmigrate-22_to_23.sql ./data/sql/dbmigrate-23_to_24.sql ./data/sql/dbmigrate-24_to_25.sql + ./data/sql/dbmigrate-25_to_26.sql ./data/js/tomahawk.js diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index 2cdbf7731..0f874d26b 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -76,6 +76,7 @@ set( libSources database/databasecommand_setdynamicplaylistrevision.cpp database/databasecommand_createdynamicplaylist.cpp database/databasecommand_loaddynamicplaylist.cpp + database/databasecommand_loaddynamicplaylistentries.cpp database/databasecommand_loadallautoplaylists.cpp database/databasecommand_loadallstations.cpp database/databasecommand_deletedynamicplaylist.cpp @@ -177,6 +178,7 @@ set( libSources widgets/welcomeplaylistmodel.cpp widgets/overlaywidget.cpp widgets/HeaderLabel.cpp + widgets/SocialPlaylistWidget.cpp widgets/infowidgets/sourceinfowidget.cpp widgets/infowidgets/ArtistInfoWidget.cpp @@ -252,6 +254,7 @@ set( libHeaders database/databasecommand_setdynamicplaylistrevision.h database/databasecommand_createdynamicplaylist.h database/databasecommand_loaddynamicplaylist.h + database/databasecommand_loaddynamicplaylistentries.h database/databasecommand_deletedynamicplaylist.h database/databasecommand_loadallautoplaylists.h database/databasecommand_loadallstations.h @@ -350,6 +353,7 @@ set( libHeaders widgets/welcomeplaylistmodel.h widgets/overlaywidget.h widgets/HeaderLabel.h + widgets/SocialPlaylistWidget.h widgets/infowidgets/sourceinfowidget.h widgets/infowidgets/ArtistInfoWidget.h @@ -372,6 +376,7 @@ set( libUI ${libUI} widgets/newplaylistwidget.ui widgets/searchwidget.ui widgets/welcomewidget.ui + widgets/SocialPlaylistWidget.ui widgets/infowidgets/sourceinfowidget.ui widgets/infowidgets/ArtistInfoWidget.ui playlist/topbar/topbar.ui diff --git a/src/libtomahawk/database/databasecommand_createdynamicplaylist.cpp b/src/libtomahawk/database/databasecommand_createdynamicplaylist.cpp index 12b459c0a..ebf79af55 100644 --- a/src/libtomahawk/database/databasecommand_createdynamicplaylist.cpp +++ b/src/libtomahawk/database/databasecommand_createdynamicplaylist.cpp @@ -33,18 +33,20 @@ using namespace Tomahawk; DatabaseCommand_CreateDynamicPlaylist::DatabaseCommand_CreateDynamicPlaylist( QObject* parent ) -: DatabaseCommand_CreatePlaylist( parent ) + : DatabaseCommand_CreatePlaylist( parent ) + , m_autoLoad( true ) { - qDebug() << Q_FUNC_INFO << "creating dynamiccreatecommand 1"; + tDebug() << Q_FUNC_INFO << "creating dynamiccreatecommand 1"; } DatabaseCommand_CreateDynamicPlaylist::DatabaseCommand_CreateDynamicPlaylist( const source_ptr& author, - const dynplaylist_ptr& playlist ) + const dynplaylist_ptr& playlist, bool autoLoad ) : DatabaseCommand_CreatePlaylist( author, playlist.staticCast() ) , m_playlist( playlist ) + , m_autoLoad( autoLoad ) { - qDebug() << Q_FUNC_INFO << "creating dynamiccreatecommand 2"; + tDebug() << Q_FUNC_INFO << "creating dynamiccreatecommand 2"; } @@ -61,8 +63,8 @@ DatabaseCommand_CreateDynamicPlaylist::exec( DatabaseImpl* lib ) qDebug() << "Create dynamic execing!" << m_playlist << m_v; TomahawkSqlQuery cre = lib->newquery(); - cre.prepare( "INSERT INTO dynamic_playlist( guid, pltype, plmode ) " - "VALUES( ?, ?, ? )" ); + cre.prepare( "INSERT INTO dynamic_playlist( guid, pltype, plmode, autoload ) " + "VALUES( ?, ?, ?, ? )" ); if( m_playlist.isNull() ) { QVariantMap m = m_v.toMap(); @@ -74,6 +76,7 @@ DatabaseCommand_CreateDynamicPlaylist::exec( DatabaseImpl* lib ) cre.addBindValue( m_playlist->type() ); cre.addBindValue( m_playlist->mode() ); } + cre.addBindValue( m_autoLoad ); cre.exec(); } @@ -88,7 +91,7 @@ DatabaseCommand_CreateDynamicPlaylist::postCommitHook() return; } - if( report() == false ) + if( !DatabaseCommand_CreatePlaylist::report() || report() == false ) return; qDebug() << Q_FUNC_INFO << "..reporting.."; diff --git a/src/libtomahawk/database/databasecommand_createdynamicplaylist.h b/src/libtomahawk/database/databasecommand_createdynamicplaylist.h index 2c2183b61..f0ad2369d 100644 --- a/src/libtomahawk/database/databasecommand_createdynamicplaylist.h +++ b/src/libtomahawk/database/databasecommand_createdynamicplaylist.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 @@ -24,21 +24,31 @@ #include "dynamic/DynamicPlaylist.h" #include "typedefs.h" +/** + * Create a new dynamic playlist in the database, based on an existing playlist. + * + * If autoLoad is true, this playlist will *not* show up in the sidebar under the playlist tree, and + * it will *not* be replicated to peers. It is useful to show a "specially crafted" playlist in other places + */ + class DatabaseCommand_CreateDynamicPlaylist : public DatabaseCommand_CreatePlaylist { Q_OBJECT Q_PROPERTY( QVariant playlist READ playlistV WRITE setPlaylistV ) - + public: explicit DatabaseCommand_CreateDynamicPlaylist( QObject* parent = 0 ); - explicit DatabaseCommand_CreateDynamicPlaylist( const Tomahawk::source_ptr& author, const Tomahawk::dynplaylist_ptr& playlist ); - + explicit DatabaseCommand_CreateDynamicPlaylist( const Tomahawk::source_ptr& author, const Tomahawk::dynplaylist_ptr& playlist, bool autoLoad = true ); + QString commandname() const { return "createdynamicplaylist"; } - + virtual void exec( DatabaseImpl* lib ); virtual void postCommitHook(); virtual bool doesMutates() const { return true; } - + + virtual bool loggable() const { return m_autoLoad; } + + QVariant playlistV() const { if( m_v.isNull() ) @@ -46,14 +56,18 @@ public: else return m_v; } - + void setPlaylistV( const QVariant& v ) { m_v = v; } - + +protected: + virtual bool report() { return m_autoLoad; } + private: Tomahawk::dynplaylist_ptr m_playlist; + bool m_autoLoad; }; #endif // DATABASECOMMAND_CREATEDYNAMICPLAYLIST_H diff --git a/src/libtomahawk/database/databasecommand_createplaylist.cpp b/src/libtomahawk/database/databasecommand_createplaylist.cpp index 516197ab7..b451394be 100644 --- a/src/libtomahawk/database/databasecommand_createplaylist.cpp +++ b/src/libtomahawk/database/databasecommand_createplaylist.cpp @@ -59,7 +59,7 @@ DatabaseCommand_CreatePlaylist::postCommitHook() if ( m_report == false ) return; - qDebug() << Q_FUNC_INFO << "reporting..."; + tDebug() << Q_FUNC_INFO << "reporting..."; if ( m_playlist.isNull() ) { source_ptr src = source(); @@ -82,7 +82,6 @@ DatabaseCommand_CreatePlaylist::postCommitHook() void DatabaseCommand_CreatePlaylist::createPlaylist( DatabaseImpl* lib, bool dynamic) { - qDebug() << Q_FUNC_INFO; Q_ASSERT( !( m_playlist.isNull() && m_v.isNull() ) ); Q_ASSERT( !source().isNull() ); @@ -123,7 +122,7 @@ DatabaseCommand_CreatePlaylist::createPlaylist( DatabaseImpl* lib, bool dynamic) cre.bindValue( ":creator", m.value( "creator" ) ); cre.bindValue( ":lastmodified", m.value( "lastmodified", 0 ) ); } - qDebug() << "CREATE PLAYLIST:" << cre.boundValues(); + tDebug() << "CREATE PLAYLIST:" << cre.boundValues(); cre.exec(); } diff --git a/src/libtomahawk/database/databasecommand_createplaylist.h b/src/libtomahawk/database/databasecommand_createplaylist.h index ec3aa14a3..a6fe0c437 100644 --- a/src/libtomahawk/database/databasecommand_createplaylist.h +++ b/src/libtomahawk/database/databasecommand_createplaylist.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 @@ -53,13 +53,14 @@ public: { m_v = v; } - + protected: void createPlaylist( DatabaseImpl* lib, bool dynamic = false ); - - bool report() { return m_report; } + + virtual bool report() { return m_report; } + void setPlaylist( const Tomahawk::playlist_ptr& playlist ) { m_playlist = playlist; } - + QVariant m_v; private: Tomahawk::playlist_ptr m_playlist; diff --git a/src/libtomahawk/database/databasecommand_genericselect.cpp b/src/libtomahawk/database/databasecommand_genericselect.cpp index 905b5e039..63c439b9c 100644 --- a/src/libtomahawk/database/databasecommand_genericselect.cpp +++ b/src/libtomahawk/database/databasecommand_genericselect.cpp @@ -52,48 +52,11 @@ DatabaseCommand_GenericSelect::exec( DatabaseImpl* dbi ) Tomahawk::source_ptr s; QString artist, track, album; - artist = query.value( 0 ).toString(); - album = query.value( 1 ).toString(); - track = query.value( 2 ).toString(); - - Tomahawk::query_ptr qry = Tomahawk::Query::get( artist, track, album, uuid(), (query.value( 7 ).toUInt() != 0) ); // Only auto-resolve non-local results - Tomahawk::artist_ptr artistptr = Tomahawk::Artist::get( query.value( 12 ).toUInt(), artist ); - Tomahawk::album_ptr albumptr = Tomahawk::Album::get( query.value( 13 ).toUInt(), album, artistptr ); - - // If it's a local track, set to the local source and url in the result and we're done. otherwise, we get resolved - if( query.value( 7 ).toUInt() == 0 ) - { - s = SourceList::instance()->getLocal(); - result->setUrl( query.value( 7 ).toString() ); - - result->setId( query.value( 9 ).toUInt() ); - result->setArtist( artistptr ); - result->setAlbum( albumptr ); - result->setTrack( query.value( 2 ).toString() ); - result->setSize( query.value( 3 ).toUInt() ); - result->setDuration( query.value( 4 ).toUInt() ); - result->setBitrate( query.value( 5 ).toUInt() ); - result->setMimetype( query.value( 8 ).toString() ); - result->setScore( 1.0 ); - result->setCollection( s->collection() ); - - TomahawkSqlQuery attrQuery = dbi->newquery(); - QVariantMap attr; - - attrQuery.prepare( "SELECT k, v FROM track_attributes WHERE id = ?" ); - attrQuery.bindValue( 0, result->dbid() ); - attrQuery.exec(); - while ( attrQuery.next() ) - { - attr[ attrQuery.value( 0 ).toString() ] = attrQuery.value( 1 ).toString(); - } - - result->setAttributes( attr ); - - qry->addResults( QList() << result ); - qry->setResolveFinished( true ); - } + track = query.value( 0 ).toString(); + artist = query.value( 1 ).toString(); + album = query.value( 2 ).toString(); + Tomahawk::query_ptr qry = Tomahawk::Query::get( artist, track, album, uuid(), true ); // Only auto-resolve non-local results queries << qry; } diff --git a/src/libtomahawk/database/databasecommand_genericselect.h b/src/libtomahawk/database/databasecommand_genericselect.h index e054f9faa..931f452e9 100644 --- a/src/libtomahawk/database/databasecommand_genericselect.h +++ b/src/libtomahawk/database/databasecommand_genericselect.h @@ -32,7 +32,7 @@ * that match. * * In order for the conversion to query_ptr to work, the SELECT command should select the following items: - * artist.name, album.name, track.name, file.size, file.duration, file.bitrate, file.url, file.source, file.mimetype, track.id + * track.name, artist.name, album.name * */ class DLLEXPORT DatabaseCommand_GenericSelect : public DatabaseCommand diff --git a/src/libtomahawk/database/databasecommand_loadallautoplaylists.cpp b/src/libtomahawk/database/databasecommand_loadallautoplaylists.cpp index 378dd0d9d..4abbb4d94 100644 --- a/src/libtomahawk/database/databasecommand_loadallautoplaylists.cpp +++ b/src/libtomahawk/database/databasecommand_loadallautoplaylists.cpp @@ -1,6 +1,6 @@ /* === This file is part of Tomahawk Player - === * - * Copyright 2010-2011, Christian Muehlhaeuser + * Copyright 2010-2011, Leo Franchi * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -33,7 +33,7 @@ DatabaseCommand_LoadAllAutoPlaylists::exec( DatabaseImpl* dbi ) TomahawkSqlQuery query = dbi->newquery(); query.exec( QString( "SELECT playlist.guid as guid, title, info, creator, createdOn, lastmodified, shared, currentrevision, dynamic_playlist.pltype, dynamic_playlist.plmode " - "FROM playlist, dynamic_playlist WHERE source %1 AND dynplaylist = 'true' AND playlist.guid = dynamic_playlist.guid AND dynamic_playlist.plmode = %2" ) + "FROM playlist, dynamic_playlist WHERE source %1 AND dynplaylist = 'true' AND playlist.guid = dynamic_playlist.guid AND dynamic_playlist.plmode = %2 AND dynamic_playlist.autoload = 'true'" ) .arg( source()->isLocal() ? "IS NULL" : QString( "=%1" ).arg( source()->id() ) ) .arg( Static ) ); diff --git a/src/libtomahawk/database/databasecommand_loadallautoplaylists.h b/src/libtomahawk/database/databasecommand_loadallautoplaylists.h index 6352ff360..0bf9cd5be 100644 --- a/src/libtomahawk/database/databasecommand_loadallautoplaylists.h +++ b/src/libtomahawk/database/databasecommand_loadallautoplaylists.h @@ -1,6 +1,6 @@ /* === This file is part of Tomahawk Player - === * - * Copyright 2010-2011, Christian Muehlhaeuser + * Copyright 2010-2011, Leo Franchi * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/libtomahawk/database/databasecommand_loadallstations.cpp b/src/libtomahawk/database/databasecommand_loadallstations.cpp index bd5b6e488..90edeeb16 100644 --- a/src/libtomahawk/database/databasecommand_loadallstations.cpp +++ b/src/libtomahawk/database/databasecommand_loadallstations.cpp @@ -1,6 +1,6 @@ /* === This file is part of Tomahawk Player - === * - * Copyright 2010-2011, Christian Muehlhaeuser + * Copyright 2010-2011, Leo Franchi * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -33,7 +33,7 @@ DatabaseCommand_LoadAllStations::exec( DatabaseImpl* dbi ) TomahawkSqlQuery query = dbi->newquery(); query.exec( QString( "SELECT playlist.guid as guid, title, info, creator, createdOn, lastmodified, shared, currentrevision, dynamic_playlist.pltype, dynamic_playlist.plmode " - "FROM playlist, dynamic_playlist WHERE source %1 AND dynplaylist = 'true' AND playlist.guid = dynamic_playlist.guid AND dynamic_playlist.plmode = %2" ) + "FROM playlist, dynamic_playlist WHERE source %1 AND dynplaylist = 'true' AND playlist.guid = dynamic_playlist.guid AND dynamic_playlist.plmode = %2 AND dynamic_playlist.autoload = 'true'" ) .arg( source()->isLocal() ? "IS NULL" : QString( "=%1" ).arg( source()->id() ) ) .arg( OnDemand ) ); diff --git a/src/libtomahawk/database/databasecommand_loadallstations.h b/src/libtomahawk/database/databasecommand_loadallstations.h index 4cb29dc2a..1e838d9c7 100644 --- a/src/libtomahawk/database/databasecommand_loadallstations.h +++ b/src/libtomahawk/database/databasecommand_loadallstations.h @@ -1,6 +1,6 @@ /* === This file is part of Tomahawk Player - === * - * Copyright 2010-2011, Christian Muehlhaeuser + * Copyright 2010-2011, Leo Franchi * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/libtomahawk/database/databasecommand_loaddynamicplaylist.cpp b/src/libtomahawk/database/databasecommand_loaddynamicplaylist.cpp index 9039db1a9..729408cbd 100644 --- a/src/libtomahawk/database/databasecommand_loaddynamicplaylist.cpp +++ b/src/libtomahawk/database/databasecommand_loaddynamicplaylist.cpp @@ -1,6 +1,6 @@ /* === This file is part of Tomahawk Player - === * - * Copyright 2010-2011, Christian Muehlhaeuser + * Copyright 2010-2011, Leo Franchi * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,102 +19,59 @@ #include "databasecommand_loaddynamicplaylist.h" #include -#include +#include "dynamic/DynamicPlaylist.h" #include "databaseimpl.h" -#include "tomahawksqlquery.h" -#include "dynamic/DynamicControl.h" -#include "dynamic/GeneratorInterface.h" -#include #include "utils/logger.h" using namespace Tomahawk; +Tomahawk::DatabaseCommand_LoadDynamicPlaylist::DatabaseCommand_LoadDynamicPlaylist( const source_ptr& s, const QString& guid, QObject* parent ) + : DatabaseCommand( s, parent ) + , m_plid( guid ) +{ + +} + void -DatabaseCommand_LoadDynamicPlaylist::exec( DatabaseImpl* dbi ) +Tomahawk::DatabaseCommand_LoadDynamicPlaylist::exec( DatabaseImpl* dbi ) { -// qDebug() << "Loading dynamic playlist guid" << guid(); - // load the entries first - generateEntries( dbi ); + TomahawkSqlQuery query = dbi->newquery(); - // now load the controls etc + query.exec( QString( "SELECT playlist.guid as guid, title, info, creator, createdOn, lastmodified, shared, currentrevision, dynamic_playlist.pltype, dynamic_playlist.plmode " + "FROM playlist, dynamic_playlist WHERE source %1 AND dynplaylist = 'true' AND playlist.guid = dynamic_playlist.guid AND playlist.guid = '%2'" ) + .arg( source()->isLocal() ? "IS NULL" : QString( "=%1" ).arg( source()->id() ) ).arg( m_plid ) ); - TomahawkSqlQuery controlsQuery = dbi->newquery(); - controlsQuery.prepare("SELECT playlist_revision.playlist, controls, plmode, pltype " - "FROM dynamic_playlist_revision, playlist_revision " - "WHERE dynamic_playlist_revision.guid = ? AND playlist_revision.guid = dynamic_playlist_revision.guid"); - controlsQuery.addBindValue( revisionGuid() ); - controlsQuery.exec(); - - QString type; - GeneratorMode mode; - - QList< QVariantMap > controls; - QString playlist_guid; -// qDebug() << "Loading controls..." << revisionGuid(); -// qDebug() << "SELECT playlist_revision.playlist, controls, plmode, pltype " -// "FROM dynamic_playlist_revision, playlist_revision " -// "WHERE dynamic_playlist_revision.guid = "<< revisionGuid() << " AND playlist_revision.guid = dynamic_playlist_revision.guid"; - - if( controlsQuery.first() ) + QList plists; + if( query.next() ) { - playlist_guid = controlsQuery.value( 0 ).toString(); - QJson::Parser parser; - bool ok; - QVariant v = parser.parse( controlsQuery.value(1).toByteArray(), &ok ); - Q_ASSERT( ok && v.type() == QVariant::List ); //TODO + dynplaylist_ptr p( new DynamicPlaylist( source(), + query.value(7).toString(), //current rev + query.value(1).toString(), //title + query.value(2).toString(), //info + query.value(3).toString(), //creator + query.value(4).toUInt(), //createdOn + query.value(8).toString(), // dynamic type + static_cast(query.value(9).toInt()), // dynamic mode + query.value(6).toBool(), //shared + query.value(5).toInt(), //lastmod + query.value(0).toString() ) ); //GUID + tLog() << "Loaded individual dynamic playlist:" << query.value(7).toString() //current rev + << query.value(1).toString() //title + << query.value(2).toString() //info + << query.value(3).toString() //creator + << query.value(4).toString() //createdOn + << query.value(8).toString() // dynamic type + << static_cast(query.value(9).toInt()) // dynamic mode + << query.value(6).toBool() //shared + << query.value(5).toInt() //lastmod + << query.value(0).toString(); //GUID - type = controlsQuery.value( 3 ).toString(); - mode = static_cast( controlsQuery.value( 2 ).toInt() ); - - QStringList controlIds = v.toStringList(); -// qDebug() << "Got controls in dynamic playlist, loading:" << controlIds << controlsQuery.value(1); - foreach( const QString& controlId, controlIds ) - { - TomahawkSqlQuery controlQuery = dbi->newquery(); - controlQuery.prepare( "SELECT selectedType, match, input " - "FROM dynamic_playlist_controls " - "WHERE id = :id" ); - controlQuery.bindValue( ":id", controlId ); - controlQuery.exec(); - if( controlQuery.next() ) - { - QVariantMap c; - c[ "type" ] = type; - c[ "id" ] = controlId; - c[ "selectedType" ] = controlQuery.value( 0 ).toString(); - c[ "match" ] = controlQuery.value( 1 ).toString(); - c[ "input" ] = controlQuery.value( 2 ).toString(); - controls << c; - } - } - } - else - { - // No controls, lets load the info we need directly from the playlist table - TomahawkSqlQuery info = dbi->newquery(); - info.prepare( QString( "SELECT dynamic_playlist.pltype, dynamic_playlist.plmode FROM playlist, dynamic_playlist WHERE playlist.guid = \"%1\" AND playlist.guid = dynamic_playlist.guid" ).arg( playlist_guid ) ); - if( !info.exec() ) { - qWarning() << "Failed to load dynplaylist info.."; - return; - } else if( !info.first() ) { - qWarning() << "Noo results for queryL:" << info.lastQuery(); - return; - } - type = info.value( 0 ).toString(); - mode = static_cast( info.value( 1 ).toInt() ); + emit dynamicPlaylistLoaded( p ); } - if( mode == OnDemand ) - { - Q_ASSERT( m_entrymap.isEmpty() ); // ondemand should have no entry - - emit done( revisionGuid(), m_islatest, type, controls, true ); - } - else - { - emit done( revisionGuid(), m_guids, m_oldentries, type, controls, m_islatest, m_entrymap, true ); - } + emit done(); } + diff --git a/src/libtomahawk/database/databasecommand_loaddynamicplaylist.h b/src/libtomahawk/database/databasecommand_loaddynamicplaylist.h index 08c831b6f..a21bb8140 100644 --- a/src/libtomahawk/database/databasecommand_loaddynamicplaylist.h +++ b/src/libtomahawk/database/databasecommand_loaddynamicplaylist.h @@ -1,6 +1,6 @@ /* === This file is part of Tomahawk Player - === * - * Copyright 2010-2011, Christian Muehlhaeuser + * Copyright 2010-2011, Leo Franchi * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,45 +22,31 @@ #include #include -#include "typedefs.h" #include "databasecommand.h" -#include "databasecommand_loadplaylistentries.h" -#include "playlist.h" -#include "dynamic/DynamicControl.h" +#include "typedefs.h" -class DatabaseCommand_LoadDynamicPlaylist : public DatabaseCommand_LoadPlaylistEntries +namespace Tomahawk +{ + +class DatabaseCommand_LoadDynamicPlaylist : public DatabaseCommand { Q_OBJECT public: - explicit DatabaseCommand_LoadDynamicPlaylist( QString revision_guid, QObject* parent = 0 ) - : DatabaseCommand_LoadPlaylistEntries( revision_guid, parent ) - { -// qDebug() << "loaded with:" << revision_guid << guid(); - } + explicit DatabaseCommand_LoadDynamicPlaylist( const source_ptr& s, const QString& guid, QObject* parent = 0 ); virtual void exec( DatabaseImpl* ); virtual bool doesMutates() const { return false; } - virtual QString commandname() const { return "loaddynamicplaylist"; } + virtual QString commandname() const { return "loadsingledynamicplaylist"; } signals: - // used if loading an ondemand playlist - void done( QString, - bool, - QString, - QList< QVariantMap>, - bool ); - // used when loading a static playlist - void done( QString, - QList< QString >, - QList< QString >, - QString, - QList< QVariantMap>, - bool, - QMap< QString, Tomahawk::plentry_ptr >, - bool ); + void dynamicPlaylistLoaded( const Tomahawk::dynplaylist_ptr& pl ); + void done(); private: + QString m_plid; }; -#endif // DATABASECOMMAND_LOADDYNAMICPLAYLIST_H +} + +#endif diff --git a/src/libtomahawk/database/databasecommand_loaddynamicplaylistentries.cpp b/src/libtomahawk/database/databasecommand_loaddynamicplaylistentries.cpp new file mode 100644 index 000000000..d76399e9a --- /dev/null +++ b/src/libtomahawk/database/databasecommand_loaddynamicplaylistentries.cpp @@ -0,0 +1,120 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Leo Franchi + * + * 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 "databasecommand_loaddynamicplaylistentries.h" + +#include +#include + +#include "databaseimpl.h" +#include "tomahawksqlquery.h" +#include "dynamic/DynamicControl.h" +#include "dynamic/GeneratorInterface.h" +#include +#include "utils/logger.h" + +using namespace Tomahawk; + + +void +DatabaseCommand_LoadDynamicPlaylistEntries::exec( DatabaseImpl* dbi ) +{ +// qDebug() << "Loading dynamic playlist guid" << guid(); + // load the entries first + generateEntries( dbi ); + + // now load the controls etc + + TomahawkSqlQuery controlsQuery = dbi->newquery(); + controlsQuery.prepare("SELECT playlist_revision.playlist, controls, plmode, pltype " + "FROM dynamic_playlist_revision, playlist_revision " + "WHERE dynamic_playlist_revision.guid = ? AND playlist_revision.guid = dynamic_playlist_revision.guid"); + controlsQuery.addBindValue( revisionGuid() ); + controlsQuery.exec(); + + QString type; + GeneratorMode mode; + + QList< QVariantMap > controls; + QString playlist_guid; +// qDebug() << "Loading controls..." << revisionGuid(); +// qDebug() << "SELECT playlist_revision.playlist, controls, plmode, pltype " +// "FROM dynamic_playlist_revision, playlist_revision " +// "WHERE dynamic_playlist_revision.guid = "<< revisionGuid() << " AND playlist_revision.guid = dynamic_playlist_revision.guid"; + + if( controlsQuery.first() ) + { + playlist_guid = controlsQuery.value( 0 ).toString(); + QJson::Parser parser; + bool ok; + QVariant v = parser.parse( controlsQuery.value(1).toByteArray(), &ok ); + Q_ASSERT( ok && v.type() == QVariant::List ); //TODO + + + type = controlsQuery.value( 3 ).toString(); + mode = static_cast( controlsQuery.value( 2 ).toInt() ); + + QStringList controlIds = v.toStringList(); +// qDebug() << "Got controls in dynamic playlist, loading:" << controlIds << controlsQuery.value(1); + foreach( const QString& controlId, controlIds ) + { + TomahawkSqlQuery controlQuery = dbi->newquery(); + controlQuery.prepare( "SELECT selectedType, match, input " + "FROM dynamic_playlist_controls " + "WHERE id = :id" ); + controlQuery.bindValue( ":id", controlId ); + controlQuery.exec(); + if( controlQuery.next() ) + { + QVariantMap c; + c[ "type" ] = type; + c[ "id" ] = controlId; + c[ "selectedType" ] = controlQuery.value( 0 ).toString(); + c[ "match" ] = controlQuery.value( 1 ).toString(); + c[ "input" ] = controlQuery.value( 2 ).toString(); + controls << c; + } + } + } + else + { + // No controls, lets load the info we need directly from the playlist table + TomahawkSqlQuery info = dbi->newquery(); + info.prepare( QString( "SELECT dynamic_playlist.pltype, dynamic_playlist.plmode FROM playlist, dynamic_playlist WHERE playlist.guid = \"%1\" AND playlist.guid = dynamic_playlist.guid" ).arg( playlist_guid ) ); + if( !info.exec() ) { + qWarning() << "Failed to load dynplaylist info.."; + return; + } else if( !info.first() ) { + qWarning() << "Noo results for queryL:" << info.lastQuery(); + return; + } + type = info.value( 0 ).toString(); + mode = static_cast( info.value( 1 ).toInt() ); + } + + if( mode == OnDemand ) + { + Q_ASSERT( m_entrymap.isEmpty() ); // ondemand should have no entry + + emit done( revisionGuid(), m_islatest, type, controls, true ); + } + else + { + emit done( revisionGuid(), m_guids, m_oldentries, type, controls, m_islatest, m_entrymap, true ); + } +} diff --git a/src/libtomahawk/database/databasecommand_loaddynamicplaylistentries.h b/src/libtomahawk/database/databasecommand_loaddynamicplaylistentries.h new file mode 100644 index 000000000..ab6571c8b --- /dev/null +++ b/src/libtomahawk/database/databasecommand_loaddynamicplaylistentries.h @@ -0,0 +1,66 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Leo Franchi + * + * 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 DATABASECOMMAND_LOADDYNAMICPLAYLISTENTRIES_H +#define DATABASECOMMAND_LOADDYNAMICPLAYLISTENTRIES_H + +#include +#include + +#include "typedefs.h" +#include "databasecommand.h" +#include "databasecommand_loadplaylistentries.h" +#include "playlist.h" +#include "dynamic/DynamicControl.h" + +class DatabaseCommand_LoadDynamicPlaylistEntries : public DatabaseCommand_LoadPlaylistEntries +{ + Q_OBJECT + +public: + explicit DatabaseCommand_LoadDynamicPlaylistEntries( QString revision_guid, QObject* parent = 0 ) + : DatabaseCommand_LoadPlaylistEntries( revision_guid, parent ) + { +// qDebug() << "loaded with:" << revision_guid << guid(); + } + + virtual void exec( DatabaseImpl* ); + virtual bool doesMutates() const { return false; } + virtual QString commandname() const { return "loaddynamicplaylist"; } + +signals: + // used if loading an ondemand playlist + void done( QString, + bool, + QString, + QList< QVariantMap>, + bool ); + // used when loading a static playlist + void done( QString, + QList< QString >, + QList< QString >, + QString, + QList< QVariantMap>, + bool, + QMap< QString, Tomahawk::plentry_ptr >, + bool ); + +private: +}; + +#endif // DATABASECOMMAND_LOADDYNAMICPLAYLIST_H diff --git a/src/libtomahawk/database/databasecommand_setdynamicplaylistrevision.cpp b/src/libtomahawk/database/databasecommand_setdynamicplaylistrevision.cpp index f18011933..6a7aa6b1b 100644 --- a/src/libtomahawk/database/databasecommand_setdynamicplaylistrevision.cpp +++ b/src/libtomahawk/database/databasecommand_setdynamicplaylistrevision.cpp @@ -1,6 +1,6 @@ /* === This file is part of Tomahawk Player - === * - * Copyright 2010-2011, Christian Muehlhaeuser + * Copyright 2010-2011, Leo Franchi * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -82,10 +82,9 @@ DatabaseCommand_SetDynamicPlaylistRevision::controlsV() void DatabaseCommand_SetDynamicPlaylistRevision::postCommitHook() { - qDebug() << Q_FUNC_INFO; if ( source().isNull() || source()->collection().isNull() ) { - qDebug() << "Source has gone offline, not emitting to GUI."; + tDebug() << "Source has gone offline, not emitting to GUI."; return; } @@ -95,7 +94,7 @@ DatabaseCommand_SetDynamicPlaylistRevision::postCommitHook() Q_ASSERT( !source().isNull() ); Q_ASSERT( !source()->collection().isNull() ); - qDebug() << "Postcommitting this playlist:" << playlistguid() << source().isNull() << source().data(); + tLog() << "Postcommitting this playlist:" << playlistguid() << source().isNull(); // private, but we are a friend. will recall itself in its own thread: dynplaylist_ptr playlist = source()->collection()->autoPlaylist( playlistguid() ); @@ -106,7 +105,7 @@ DatabaseCommand_SetDynamicPlaylistRevision::postCommitHook() // now that we separate them, if we get them as one and then get a changed mode, the playlist ends up in the wrong bucket in Collection. // so here we fix it if we have to. // HACK - qDebug() << "Does this need FIXING?" << playlist->mode() << source()->collection()->autoPlaylist( playlistguid() ).isNull() << source()->collection()->station( playlistguid() ).isNull(); + tDebug() << "Does this need FIXING?" << playlist->mode() << source()->collection()->autoPlaylist( playlistguid() ).isNull() << source()->collection()->station( playlistguid() ).isNull(); if( playlist->mode() == Static && source()->collection()->autoPlaylist( playlistguid() ).isNull() ) // should be here source()->collection()->moveStationToAuto( playlistguid() ); else if ( playlist->mode() == OnDemand && source()->collection()->station( playlistguid() ).isNull() ) // should be here @@ -114,7 +113,7 @@ DatabaseCommand_SetDynamicPlaylistRevision::postCommitHook() if ( playlist.isNull() ) { - qDebug() <<"Got null playlist with guid:" << playlistguid() << "from source and collection:" << source()->friendlyName() << source()->collection()->name() << "and mode is static?:" << (m_mode == Static); + tLog() <<"Got null playlist with guid:" << playlistguid() << "from source and collection:" << source()->friendlyName() << source()->collection()->name() << "and mode is static?:" << (m_mode == Static); Q_ASSERT( !playlist.isNull() ); return; } @@ -205,7 +204,7 @@ DatabaseCommand_SetDynamicPlaylistRevision::exec( DatabaseImpl* lib ) delQuery.prepare( "DELETE FROM dynamic_playlist_controls WHERE playlist = ?" ); delQuery.addBindValue( m_playlistguid ); if ( !delQuery.exec() ) - qWarning() << "Failed to delete controls from dynamic playlist controls table"; + tLog() << "Failed to delete controls from dynamic playlist controls table"; TomahawkSqlQuery controlsQuery = lib->newquery(); controlsQuery.prepare( "INSERT INTO dynamic_playlist_controls( id, playlist, selectedType, match, input ) " @@ -242,7 +241,7 @@ DatabaseCommand_SetDynamicPlaylistRevision::exec( DatabaseImpl* lib ) } if ( m_applied ) { - qDebug() << "updating dynamic playlist, optimistic locking okay"; + tLog() << "updating dynamic playlist, optimistic locking okay"; TomahawkSqlQuery query2 = lib->newquery(); query2.prepare( "UPDATE dynamic_playlist SET pltype = ?, plmode = ? WHERE guid = ?" ); diff --git a/src/libtomahawk/database/databasecommand_setdynamicplaylistrevision.h b/src/libtomahawk/database/databasecommand_setdynamicplaylistrevision.h index 238aa163f..f9f9c1a63 100644 --- a/src/libtomahawk/database/databasecommand_setdynamicplaylistrevision.h +++ b/src/libtomahawk/database/databasecommand_setdynamicplaylistrevision.h @@ -1,6 +1,6 @@ /* === This file is part of Tomahawk Player - === - * - * Copyright 2010-2011, Christian Muehlhaeuser + * + * Copyright 2010-2011, Leo Franchi * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -34,12 +34,12 @@ class DatabaseCommand_SetDynamicPlaylistRevision : public DatabaseCommand_SetPla Q_PROPERTY( QString type READ type WRITE setType ) Q_PROPERTY( int mode READ mode WRITE setMode ) Q_PROPERTY( QVariantList controls READ controlsV WRITE setControlsV ) - + public: explicit DatabaseCommand_SetDynamicPlaylistRevision( QObject* parent = 0 ) : DatabaseCommand_SetPlaylistRevision( parent ) {} - + explicit DatabaseCommand_SetDynamicPlaylistRevision( const source_ptr& s, const QString& playlistguid, const QString& newrev, @@ -50,7 +50,7 @@ public: const QString& type, GeneratorMode mode, const QList< dyncontrol_ptr >& controls ); - + explicit DatabaseCommand_SetDynamicPlaylistRevision( const source_ptr& s, const QString& playlistguid, const QString& newrev, @@ -58,26 +58,26 @@ public: const QString& type, GeneratorMode mode, const QList< dyncontrol_ptr >& controls ); - + QString commandname() const { return "setdynamicplaylistrevision"; } - + virtual void exec( DatabaseImpl* lib ); virtual void postCommitHook(); virtual bool doesMutates() const { return true; } - + void setControlsV( const QVariantList& vlist ) { m_controlsV = vlist; } - + QVariantList controlsV(); - + QString type() const { return m_type; } int mode() const { return (int)m_mode; } - + void setType( const QString& type ) { m_type = type; } void setMode( int mode ) { m_mode = (GeneratorMode)mode; } - + private: QString m_type; GeneratorMode m_mode; diff --git a/src/libtomahawk/database/databaseimpl.cpp b/src/libtomahawk/database/databaseimpl.cpp index 389838e3a..b8490ee2d 100644 --- a/src/libtomahawk/database/databaseimpl.cpp +++ b/src/libtomahawk/database/databaseimpl.cpp @@ -39,7 +39,7 @@ */ #include "schema.sql.h" -#define CURRENT_SCHEMA_VERSION 25 +#define CURRENT_SCHEMA_VERSION 26 DatabaseImpl::DatabaseImpl( const QString& dbname, Database* parent ) @@ -54,11 +54,11 @@ DatabaseImpl::DatabaseImpl( const QString& dbname, Database* parent ) if ( version > 0 && version != CURRENT_SCHEMA_VERSION ) { QString newname = QString( "%1.v%2" ).arg( dbname ).arg( version ); - qDebug() << endl << "****************************" << endl; - qDebug() << "Schema version too old: " << version << ". Current version is:" << CURRENT_SCHEMA_VERSION; - qDebug() << "Moving" << dbname << newname; - qDebug() << "If the migration fails, you can recover your DB by copying" << newname << "back to" << dbname; - qDebug() << endl << "****************************" << endl; + tLog() << endl << "****************************" << endl; + tLog() << "Schema version too old: " << version << ". Current version is:" << CURRENT_SCHEMA_VERSION; + tLog() << "Moving" << dbname << newname; + tLog() << "If the migration fails, you can recover your DB by copying" << newname << "back to" << dbname; + tLog() << endl << "****************************" << endl; QFile::copy( dbname, newname ); { @@ -84,7 +84,7 @@ DatabaseImpl::DatabaseImpl( const QString& dbname, Database* parent ) db.setDatabaseName( dbname ); if ( !db.open() ) { - qDebug() << "Failed to open database" << dbname; + tLog() << "Failed to open database" << dbname; throw "failed to open db"; // TODO } @@ -103,7 +103,7 @@ DatabaseImpl::DatabaseImpl( const QString& dbname, Database* parent ) m_dbid = uuid(); query.exec( QString( "INSERT INTO settings(k,v) VALUES('dbid','%1')" ).arg( m_dbid ) ); } - qDebug() << "Database ID:" << m_dbid; + tLog() << "Database ID:" << m_dbid; // make sqlite behave how we want: query.exec( "PRAGMA synchronous = ON" ); @@ -145,7 +145,7 @@ DatabaseImpl::updateSchema( int oldVersion ) // we are called here with the old database. we must migrate it to the CURRENT_SCHEMA_VERSION from the oldVersion if ( oldVersion == 0 ) // empty database, so create our tables and stuff { - qDebug() << "Create tables... old version is" << oldVersion; + tLog() << "Create tables... old version is" << oldVersion; QString sql( get_tomahawk_sql() ); QStringList statements = sql.split( ";", QString::SkipEmptyParts ); db.transaction(); @@ -156,7 +156,7 @@ DatabaseImpl::updateSchema( int oldVersion ) if ( s.length() == 0 ) continue; - qDebug() << "Executing:" << s; + tLog() << "Executing:" << s; TomahawkSqlQuery query = newquery(); query.exec( s ); } @@ -176,7 +176,7 @@ DatabaseImpl::updateSchema( int oldVersion ) QFile script( path ); if ( !script.exists() || !script.open( QIODevice::ReadOnly ) ) { - qWarning() << "Failed to find or open upgrade script from" << (cur-1) << "to" << cur << " (" << path << ")! Aborting upgrade..."; + tLog() << "Failed to find or open upgrade script from" << (cur-1) << "to" << cur << " (" << path << ")! Aborting upgrade..."; return false; } @@ -188,13 +188,13 @@ DatabaseImpl::updateSchema( int oldVersion ) if ( clean.isEmpty() ) continue; - qDebug() << "Executing upgrade statement:" << clean; + tLog() << "Executing upgrade statement:" << clean; TomahawkSqlQuery q = newquery(); q.exec( clean ); } } db.commit(); - qDebug() << "DB Upgrade successful!"; + tLog() << "DB Upgrade successful!"; return true; } } @@ -299,7 +299,7 @@ DatabaseImpl::artistId( const QString& name_orig, bool& autoCreate ) query.addBindValue( sortname ); if ( !query.exec() ) { - qDebug() << "Failed to insert artist:" << name_orig; + tDebug() << "Failed to insert artist:" << name_orig; return 0; } @@ -345,7 +345,7 @@ DatabaseImpl::trackId( int artistid, const QString& name_orig, bool& isnew ) query.addBindValue( sortname ); if( !query.exec() ) { - qDebug() << "Failed to insert track:" << name_orig ; + tDebug() << "Failed to insert track:" << name_orig ; return 0; } @@ -396,7 +396,7 @@ DatabaseImpl::albumId( int artistid, const QString& name_orig, bool& isnew ) query.addBindValue( sortname ); if( !query.exec() ) { - qDebug() << "Failed to insert album: " << name_orig ; + tDebug() << "Failed to insert album: " << name_orig ; return 0; } @@ -533,7 +533,7 @@ DatabaseImpl::resultFromHint( const Tomahawk::query_ptr& origquery ) else { // Q_ASSERT( false ); - qDebug() << "We don't support non-servent / non-file result-hints yet."; + tDebug() << "We don't support non-servent / non-file result-hints yet."; /* res = Tomahawk::result_ptr( new Tomahawk::Result() ); s = SourceList::instance()->webSource(); res->setUrl( url ); @@ -630,7 +630,7 @@ DatabaseImpl::getDatabaseVersion( const QString& dbname ) db.setDatabaseName( dbname ); if ( !db.open() ) { - qDebug() << "Failed to open database" << dbname; + tLog() << "Failed to open database" << dbname; throw "failed to open db"; // TODO } @@ -639,7 +639,7 @@ DatabaseImpl::getDatabaseVersion( const QString& dbname ) if ( qry.next() ) { version = qry.value( 0 ).toInt(); - qDebug() << "Database schema of" << dbname << "is" << version; + tLog() << "Database schema of" << dbname << "is" << version; } } diff --git a/src/libtomahawk/database/schema.sql b/src/libtomahawk/database/schema.sql index 723943106..7e2ff8daa 100644 --- a/src/libtomahawk/database/schema.sql +++ b/src/libtomahawk/database/schema.sql @@ -108,7 +108,8 @@ CREATE TABLE IF NOT EXISTS playlist_revision ( CREATE TABLE IF NOT EXISTS dynamic_playlist ( guid TEXT NOT NULL REFERENCES playlist(guid) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED, pltype TEXT, -- the generator type - plmode INTEGER -- the mode of this playlist + plmode INTEGER, -- the mode of this playlist + autoload BOOLEAN DEFAULT true -- if this playlist should be autoloaded or not. true except for the case of special playlists we want to display elsewhere ); --INSERT INTO dynamic_playlist(guid, pltype, plmode) @@ -282,4 +283,4 @@ CREATE TABLE IF NOT EXISTS settings ( v TEXT NOT NULL DEFAULT '' ); -INSERT INTO settings(k,v) VALUES('schema_version', '25'); +INSERT INTO settings(k,v) VALUES('schema_version', '26'); diff --git a/src/libtomahawk/database/schema.sql.h b/src/libtomahawk/database/schema.sql.h index b9ff40493..22168f55e 100644 --- a/src/libtomahawk/database/schema.sql.h +++ b/src/libtomahawk/database/schema.sql.h @@ -1,5 +1,5 @@ /* - This file was automatically generated from ./schema.sql on Fri Jun 24 09:10:23 CEST 2011. + This file was automatically generated from schema.sql on Mon Jul 25 20:38:55 EDT 2011. */ static const char * tomahawk_schema_sql = @@ -78,7 +78,8 @@ static const char * tomahawk_schema_sql = "CREATE TABLE IF NOT EXISTS dynamic_playlist (" " guid TEXT NOT NULL REFERENCES playlist(guid) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED," " pltype TEXT, " -" plmode INTEGER " +" plmode INTEGER, " +" autoload BOOLEAN DEFAULT true " ");" "CREATE TABLE IF NOT EXISTS dynamic_playlist_controls (" " id TEXT PRIMARY KEY," @@ -183,7 +184,7 @@ static const char * tomahawk_schema_sql = " k TEXT NOT NULL PRIMARY KEY," " v TEXT NOT NULL DEFAULT ''" ");" -"INSERT INTO settings(k,v) VALUES('schema_version', '25');" +"INSERT INTO settings(k,v) VALUES('schema_version', '26');" ; const char * get_tomahawk_sql() diff --git a/src/libtomahawk/playlist/dynamic/DynamicControl.h b/src/libtomahawk/playlist/dynamic/DynamicControl.h index c03d386fd..99d1f5371 100644 --- a/src/libtomahawk/playlist/dynamic/DynamicControl.h +++ b/src/libtomahawk/playlist/dynamic/DynamicControl.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 @@ -25,7 +25,7 @@ #include #include "typedefs.h" -namespace Tomahawk +namespace Tomahawk { /** @@ -34,11 +34,11 @@ namespace Tomahawk * - Type (string selector for what this control is matching) * - Match selector (how to match the type to the input) * - Input field (the user input field). - * + * * Each control also has a list of TypeSelectors that comes from the generator, and only one is selected at once. - * + * */ -class DynamicControl : public QObject +class DynamicControl : public QObject { Q_OBJECT Q_PROPERTY( QString type READ type WRITE setType ) // the generator type associated with this control @@ -47,67 +47,67 @@ class DynamicControl : public QObject Q_PROPERTY( QString match READ match WRITE setMatch ) Q_PROPERTY( QString input READ input WRITE setInput ) Q_PROPERTY( QString summary READ summary ) // a summary of the control in phrase form - + public: DynamicControl( const QStringList& typeSelectors = QStringList() ); virtual ~DynamicControl(); - - + + /// The current type of this control QString selectedType() const { return m_selectedType; } /** * The match selector widget based on this control's type - * + * * The control manages the lifetime of the widget. */ virtual QWidget* matchSelector() { Q_ASSERT( false ); return 0; } /** * The input field widget that is associated with this type - * + * * The control manages the lifetime of the widget. */ virtual QWidget* inputField() { Q_ASSERT( false ); return 0; } - + /// The user-readable match value, for showing in read-only playlists virtual QString matchString() const { Q_ASSERT( false ); return QString(); } - + /// the serializable value of the match virtual QString match() const { Q_ASSERT( false ); return QString(); } /// the serializable value of the input virtual QString input() const { Q_ASSERT( false ); return QString(); } /// the user-readable summary phrase virtual QString summary() const { Q_ASSERT( false ); return QString(); } - + // used by JSON serialization virtual void setMatch( const QString& /*match*/ ) { Q_ASSERT( false ); } virtual void setInput( const QString& /*input*/ ) { Q_ASSERT( false ); } /// All the potential type selectors for this control QStringList typeSelectors() const { return m_typeSelectors; } - + QString id() { if( m_id.isEmpty() ) m_id = uuid(); return m_id; }; void setId( const QString& id ) { m_id = id; } - + void setType( const QString& type ) { m_type = type; } QString type() const { return m_type; } - + signals: void changed(); - + public slots: /** * Sets the type to the newly specified one. Note that this will update the matchSelector * and inputField widgets, so you should fetch the new widgets for use immediately. */ virtual void setSelectedType( const QString& selectedType ) { m_selectedType = selectedType; } - + protected: // Private constructor, you can't make one. Get it from your Generator. explicit DynamicControl( const QString& selectedType, const QStringList& typeSelectors, QObject* parent = 0 ); - + private: QString m_type; QString m_selectedType; diff --git a/src/libtomahawk/playlist/dynamic/DynamicPlaylist.cpp b/src/libtomahawk/playlist/dynamic/DynamicPlaylist.cpp index c456fc1c5..aa32ad200 100644 --- a/src/libtomahawk/playlist/dynamic/DynamicPlaylist.cpp +++ b/src/libtomahawk/playlist/dynamic/DynamicPlaylist.cpp @@ -24,7 +24,7 @@ #include "database/databasecommand.h" #include "database/databasecommand_createdynamicplaylist.h" #include "database/databasecommand_setdynamicplaylistrevision.h" -#include "database/databasecommand_loaddynamicplaylist.h" +#include "database/databasecommand_loaddynamicplaylistentries.h" #include "database/databasecommand_deletedynamicplaylist.h" #include "tomahawksettings.h" #include "utils/logger.h" @@ -221,7 +221,7 @@ DynamicPlaylist::loadRevision( const QString& rev ) // qDebug() << Q_FUNC_INFO << "Loading with:" << ( rev.isEmpty() ? currentrevision() : rev ); setBusy( true ); - DatabaseCommand_LoadDynamicPlaylist* cmd = new DatabaseCommand_LoadDynamicPlaylist( rev.isEmpty() ? currentrevision() : rev ); + DatabaseCommand_LoadDynamicPlaylistEntries* cmd = new DatabaseCommand_LoadDynamicPlaylistEntries( rev.isEmpty() ? currentrevision() : rev ); if( m_generator->mode() == OnDemand ) { connect( cmd, SIGNAL( done( QString, diff --git a/src/libtomahawk/playlist/dynamic/DynamicPlaylist.h b/src/libtomahawk/playlist/dynamic/DynamicPlaylist.h index e8ab3cc0a..dad43c38c 100644 --- a/src/libtomahawk/playlist/dynamic/DynamicPlaylist.h +++ b/src/libtomahawk/playlist/dynamic/DynamicPlaylist.h @@ -36,6 +36,8 @@ class DatabaseCollection; namespace Tomahawk { +class DatabaseCommand_LoadDynamicPlaylist; + /** * Subclass of playlist that adds the information needed to store a dynamic playlist. * It uses normal PlaylistEntries but also has a mode, a generator, and a list of controls @@ -70,6 +72,7 @@ class DLLEXPORT DynamicPlaylist : public Playlist friend class ::DatabaseCommand_SetDynamicPlaylistRevision; friend class ::DatabaseCommand_CreateDynamicPlaylist; + friend class Tomahawk::DatabaseCommand_LoadDynamicPlaylist; friend class ::DatabaseCollection; /// :-( public: diff --git a/src/libtomahawk/playlist/dynamic/widgets/CollapsibleControls.h b/src/libtomahawk/playlist/dynamic/widgets/CollapsibleControls.h index a242769d0..68b9cc646 100644 --- a/src/libtomahawk/playlist/dynamic/widgets/CollapsibleControls.h +++ b/src/libtomahawk/playlist/dynamic/widgets/CollapsibleControls.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 @@ -20,6 +20,7 @@ #define COLLAPSIBLE_CONTROLS_H #include "typedefs.h" +#include "source.h" #include @@ -42,35 +43,35 @@ public: CollapsibleControls( QWidget* parent ); CollapsibleControls( const dynplaylist_ptr& playlist, bool isLocal, QWidget* parent = 0 ); virtual ~CollapsibleControls(); - + void setControls( const dynplaylist_ptr& playlist, bool isLocal ); QList< DynamicControlWrapper* > controls() const; - + virtual QSize sizeHint() const; signals: void controlsChanged(); void controlChanged( const Tomahawk::dyncontrol_ptr& control ); - + private slots: void toggleCollapse(); - + void onAnimationStep( int ); void onAnimationFinished(); - + private: void init(); - + dynplaylist_ptr m_dynplaylist; QStackedLayout* m_layout; DynamicControlList* m_controls; bool m_isLocal; - + QWidget* m_summaryWidget; QHBoxLayout* m_summaryLayout; ElidedLabel* m_summary; QStackedLayout* m_expandL; QToolButton* m_summaryExpand; - + // animations! QTimeLine* m_timeline; int m_animHeight; diff --git a/src/libtomahawk/playlist/trackview.h b/src/libtomahawk/playlist/trackview.h index 4b47d2d0d..b7cc34b8f 100644 --- a/src/libtomahawk/playlist/trackview.h +++ b/src/libtomahawk/playlist/trackview.h @@ -24,6 +24,7 @@ #include "contextMenu.h" #include "playlistitemdelegate.h" +#include "album.h" #include "dllmacro.h" diff --git a/src/libtomahawk/widgets/SocialPlaylistWidget.cpp b/src/libtomahawk/widgets/SocialPlaylistWidget.cpp new file mode 100644 index 000000000..8f7d39da8 --- /dev/null +++ b/src/libtomahawk/widgets/SocialPlaylistWidget.cpp @@ -0,0 +1,94 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Leo Franchi + * + * 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 "SocialPlaylistWidget.h" +#include "ui_SocialPlaylistWidget.h" + +#include "database/databasecommand_loaddynamicplaylist.h" +#include "database/database.h" +#include "sourcelist.h" + +#define COOLPLAYLIST_GUID "TOMAHAWK_COOLPLAYLISTOHAI_GUID" + +using namespace Tomahawk; + +SocialPlaylistWidget::SocialPlaylistWidget ( QWidget* parent ) + : QWidget ( parent ) + , ui( new Ui_SocialPlaylistWidget ) + , m_coolQuery1Model( new PlaylistModel( this ) ) +{ + ui->setupUi( this ); + + ui->playlistView->setPlaylistModel( m_coolQuery1Model ); + + load(); +} + +SocialPlaylistWidget::~SocialPlaylistWidget() +{ + +} + +void +SocialPlaylistWidget::load() +{ + // Load the pre-baked custom playlists that we are going to show. + // They also might not exist yet if this the first time this is shown, so then we create them. + DatabaseCommand_LoadDynamicPlaylist* cmd = new DatabaseCommand_LoadDynamicPlaylist( SourceList::instance()->getLocal(), COOLPLAYLIST_GUID, 0 ); + connect( cmd, SIGNAL( dynamicPlaylistLoaded( Tomahawk::dynplaylist_ptr ) ), this, SLOT( dynamicPlaylistLoaded( Tomahawk::dynplaylist_ptr ) ) ); + connect( cmd, SIGNAL( done() ), this, SLOT( dynamicPlaylistLoadDone() ) ); + + Database::instance()->enqueue( QSharedPointer( cmd ) ); +} + +PlaylistInterface* +SocialPlaylistWidget::playlistInterface() const +{ + return ui->playlistView->proxyModel(); +} + +void +SocialPlaylistWidget::dynamicPlaylistLoaded ( const dynplaylist_ptr& ptr ) +{ + m_coolQuery1 = ptr; + tLog() << "SocialPlaylistWidget got dynplaylist loaded with currev: " << m_coolQuery1->currentrevision(); + connect( m_coolQuery1.data(), SIGNAL( dynamicRevisionLoaded( Tomahawk::DynamicPlaylistRevision ) ), this, SLOT( playlistRevisionLoaded( Tomahawk::DynamicPlaylistRevision ) ) ); + m_coolQuery1->loadRevision( m_coolQuery1->currentrevision() ); +} + +void +SocialPlaylistWidget::playlistRevisionLoaded( Tomahawk::DynamicPlaylistRevision ) +{ + m_coolQuery1Model->loadPlaylist( m_coolQuery1 ); +} + +void +SocialPlaylistWidget::dynamicPlaylistLoadDone() +{ + if ( m_coolQuery1.isNull() ) /// Load failed so we need to create the playlist, doesn't exist yet + { + tLog() << "SocialPlaylistWidget didn't find the magic dynamic playlist, creating!"; + createPlaylist(); + } +} + +void +SocialPlaylistWidget::createPlaylist() +{ + // TODO +} diff --git a/src/libtomahawk/widgets/SocialPlaylistWidget.h b/src/libtomahawk/widgets/SocialPlaylistWidget.h new file mode 100644 index 000000000..30acd72b0 --- /dev/null +++ b/src/libtomahawk/widgets/SocialPlaylistWidget.h @@ -0,0 +1,96 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Leo Franchi + * + * 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 . + */ + +/** + * \class SocialPlaylistWidget + * \brief ViewPage, which displays some interesting lists of songs mined from the database + * + * This Tomahawk ViewPage displays various interesting database searches that expose cool + * lists of songs. It is accessed from the sidebar, and contains a few custom-created DatabaseGenerator-backed + * playlists. + * + */ + +#ifndef SOCIALPLAYLISTWIDGET_H +#define SOCIALPLAYLISTWIDGET_H + +#include + +#include "viewpage.h" + +#include "dllmacro.h" +#include "typedefs.h" +#include "playlist/dynamic/DynamicPlaylist.h" +#include "source.h" + +class PlaylistModel; +class TreeModel; + +class Ui_SocialPlaylistWidget; + +namespace Tomahawk +{ + +class DLLEXPORT SocialPlaylistWidget : public QWidget, public Tomahawk::ViewPage +{ + Q_OBJECT + +public: + SocialPlaylistWidget( QWidget* parent = 0 ); + ~SocialPlaylistWidget(); + + virtual QWidget* widget() { return this; } + virtual Tomahawk::PlaylistInterface* playlistInterface() const; + + virtual QString title() const { return m_title; } + virtual QString description() const { return m_description; } + virtual QString longDescription() const { return m_longDescription; } + virtual QPixmap pixmap() const { if ( m_pixmap.isNull() ) return Tomahawk::ViewPage::pixmap(); else return m_pixmap; } + + virtual bool showStatsBar() const { return false; } + + virtual bool jumpToCurrentTrack() { return false; } + +signals: + void longDescriptionChanged( const QString& description ); + void descriptionChanged( const QString& description ); + void pixmapChanged( const QPixmap& pixmap ); + +private slots: + void dynamicPlaylistLoaded( const Tomahawk::dynplaylist_ptr& ptr ); + void playlistRevisionLoaded ( Tomahawk::DynamicPlaylistRevision ); + void dynamicPlaylistLoadDone(); + +private: + void load(); + void createPlaylist(); + + Ui_SocialPlaylistWidget *ui; + + Tomahawk::dynplaylist_ptr m_coolQuery1; + PlaylistModel* m_coolQuery1Model; + + QString m_title; + QString m_description; + QString m_longDescription; + QPixmap m_pixmap; +}; + +} + +#endif // SOCIALPLAYLISTWIDGET_H diff --git a/src/libtomahawk/widgets/SocialPlaylistWidget.ui b/src/libtomahawk/widgets/SocialPlaylistWidget.ui new file mode 100644 index 000000000..bd3748bff --- /dev/null +++ b/src/libtomahawk/widgets/SocialPlaylistWidget.ui @@ -0,0 +1,46 @@ + + + SocialPlaylistWidget + + + + 0 + 0 + 400 + 300 + + + + Form + + + + 4 + + + + + Social Stuff! + + + + + + + + + + + PlaylistView + QTreeView +
playlist/playlistview.h
+
+ + HeaderLabel + QLabel +
widgets/HeaderLabel.h
+
+
+ + +
diff --git a/src/sourcetree/items/collectionitem.cpp b/src/sourcetree/items/collectionitem.cpp index 1fd27bdf9..ece973e6f 100644 --- a/src/sourcetree/items/collectionitem.cpp +++ b/src/sourcetree/items/collectionitem.cpp @@ -23,6 +23,7 @@ #include "genericpageitems.h" #include "utils/tomahawkutils.h" #include "utils/logger.h" +#include /// CollectionItem @@ -35,12 +36,21 @@ CollectionItem::CollectionItem( SourcesModel* mdl, SourceTreeItem* parent, cons , m_stations( 0 ) , m_tempItem( 0 ) , m_sourceInfoItem( 0 ) + , m_coolPlaylistsItem( 0 ) , m_curTempPage( 0 ) , m_sourceInfoPage( 0 ) + , m_coolPlaylistsPage( 0 ) { if( m_source.isNull() ) { // super collection connect( ViewManager::instance(), SIGNAL( tempPageActivated( Tomahawk::ViewPage*) ), this, SLOT( tempPageActivated( Tomahawk::ViewPage* ) ) ); + m_coolPlaylistsItem = new GenericPageItem( model(), this, tr( "Cool Stuff" ), QIcon( RESPATH "images/new-additions.png" ), + boost::bind( &CollectionItem::coolPlaylistsClicked, this ), + boost::bind( &CollectionItem::getCoolPlaylistsPage, this ) + ); + m_coolPlaylistsItem->setSortValue( 200 ); + + return; } @@ -50,6 +60,8 @@ CollectionItem::CollectionItem( SourcesModel* mdl, SourceTreeItem* parent, cons ); m_sourceInfoItem->setSortValue( -300 ); + + // create category items if there are playlists to show, or stations to show QList< playlist_ptr > playlists = source->collection()->playlists(); QList< dynplaylist_ptr > autoplaylists = source->collection()->autoPlaylists(); @@ -338,3 +350,20 @@ CollectionItem::getSourceInfoPage() const { return m_sourceInfoPage; } + +ViewPage* +CollectionItem::coolPlaylistsClicked() +{ + if( !m_source.isNull() ) + return 0; + + m_coolPlaylistsPage = new SocialPlaylistWidget( ViewManager::instance()->widget() ); + ViewManager::instance()->show( m_coolPlaylistsPage ); + return m_coolPlaylistsPage; +} + +ViewPage* +CollectionItem::getCoolPlaylistsPage() const +{ + return m_coolPlaylistsPage; +} diff --git a/src/sourcetree/items/collectionitem.h b/src/sourcetree/items/collectionitem.h index 90615dac0..5737cbb9e 100644 --- a/src/sourcetree/items/collectionitem.h +++ b/src/sourcetree/items/collectionitem.h @@ -58,6 +58,9 @@ private slots: Tomahawk::ViewPage* sourceInfoClicked(); Tomahawk::ViewPage* getSourceInfoPage() const; + Tomahawk::ViewPage* coolPlaylistsClicked(); + Tomahawk::ViewPage* getCoolPlaylistsPage() const; + private: void playlistsAddedInternal( SourceTreeItem* parent, const QList< Tomahawk::dynplaylist_ptr >& playlists ); template< typename T > @@ -69,8 +72,11 @@ private: GenericPageItem* m_tempItem; GenericPageItem* m_sourceInfoItem; + GenericPageItem* m_coolPlaylistsItem; + Tomahawk::ViewPage* m_curTempPage; Tomahawk::ViewPage* m_sourceInfoPage; + Tomahawk::ViewPage* m_coolPlaylistsPage; };