diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index ca48502c7..d778e762c 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -73,7 +73,8 @@ set( libSources database/databasecommand_setdynamicplaylistrevision.cpp database/databasecommand_createdynamicplaylist.cpp database/databasecommand_loaddynamicplaylist.cpp - database/databasecommand_loadalldynamicplaylists.cpp + database/databasecommand_loadallautoplaylists.cpp + database/databasecommand_loadallstations.cpp database/databasecommand_deletedynamicplaylist.cpp database/databasecommand_addclientauth.cpp database/databasecommand_clientauthvalid.cpp @@ -233,7 +234,8 @@ set( libHeaders database/databasecommand_createdynamicplaylist.h database/databasecommand_loaddynamicplaylist.h database/databasecommand_deletedynamicplaylist.h - database/databasecommand_loadalldynamicplaylists.h + database/databasecommand_loadallautoplaylists.h + database/databasecommand_loadallstations.h database/databasecommand_addclientauth.h database/databasecommand_clientauthvalid.h diff --git a/src/libtomahawk/collection.cpp b/src/libtomahawk/collection.cpp index d9f265d12..b22e1b105 100644 --- a/src/libtomahawk/collection.cpp +++ b/src/libtomahawk/collection.cpp @@ -64,6 +64,7 @@ Collection::addPlaylist( const Tomahawk::playlist_ptr& p ) qDebug() << Q_FUNC_INFO; QList toadd; toadd << p; + qDebug() << "Inserted playlist with guid:" << p->guid(); m_playlists.insert( p->guid(), p ); qDebug() << Q_FUNC_INFO << "Collection name" << name() @@ -74,19 +75,36 @@ Collection::addPlaylist( const Tomahawk::playlist_ptr& p ) void -Collection::addDynamicPlaylist( const Tomahawk::dynplaylist_ptr& p ) +Collection::addAutoPlaylist( const Tomahawk::dynplaylist_ptr& p ) { qDebug() << Q_FUNC_INFO; QList toadd; toadd << p; - m_dynplaylists.insert( p->guid(), p ); + qDebug() << "Inserted dynamic playlist with guid:" << p->guid(); + m_autoplaylists.insert( p->guid(), p ); qDebug() << Q_FUNC_INFO << "Collection name" << name() << "from source id" << source()->id() << "numplaylists:" << m_playlists.count(); - emit dynamicPlaylistsAdded( toadd ); + emit autoPlaylistsAdded( toadd ); } +void +Collection::addStation( const dynplaylist_ptr& s ) +{ + qDebug() << Q_FUNC_INFO; + QList toadd; + toadd << s; + qDebug() << "Inserted station with guid:" << s->guid(); + m_stations.insert( s->guid(), s ); + + qDebug() << Q_FUNC_INFO << "Collection name" << name() + << "from source id" << source()->id() + << "numplaylists:" << m_playlists.count(); + emit stationsAdded( toadd ); +} + + void Collection::deletePlaylist( const Tomahawk::playlist_ptr& p ) @@ -104,32 +122,55 @@ Collection::deletePlaylist( const Tomahawk::playlist_ptr& p ) void -Collection::deleteDynamicPlaylist( const Tomahawk::dynplaylist_ptr& p ) +Collection::deleteAutoPlaylist( const Tomahawk::dynplaylist_ptr& p ) { qDebug() << Q_FUNC_INFO; QList todelete; todelete << p; - m_dynplaylists.remove( p->guid() ); + m_autoplaylists.remove( p->guid() ); qDebug() << Q_FUNC_INFO << "Collection name" << name() << "from source id" << source()->id() << "numplaylists:" << m_playlists.count(); - emit dynamicPlaylistsDeleted( todelete ); + emit autoPlaylistsDeleted( todelete ); +} + +void +Collection::deleteStation( const dynplaylist_ptr& s ) +{ + qDebug() << Q_FUNC_INFO; + QList todelete; + todelete << s; + m_stations.remove( s->guid() ); + + qDebug() << Q_FUNC_INFO << "Collection name" << name() + << "from source id" << source()->id() + << "numplaylists:" << m_playlists.count(); + emit stationsDeleted( todelete ); } playlist_ptr Collection::playlist( const QString& guid ) { + qDebug() << "Returning playlist for guid:" << guid << "found?" << m_playlists.contains( guid ); return m_playlists.value( guid, playlist_ptr() ); } dynplaylist_ptr -Collection::dynamicPlaylist( const QString& guid ) +Collection::autoPlaylist( const QString& guid ) +{ + qDebug() << "Returning auto playlist for guid:" << guid << "found?" << m_autoplaylists.contains( guid ); + return m_autoplaylists.value( guid, dynplaylist_ptr() ); +} + +dynplaylist_ptr +Collection::station( const QString& guid ) { - return m_dynplaylists.value( guid, dynplaylist_ptr() ); + qDebug() << "Returning station for guid:" << guid << "found?" << m_stations.contains( guid ); + return m_stations.value( guid, dynplaylist_ptr() ); } @@ -137,23 +178,37 @@ void Collection::setPlaylists( const QList& plists ) { qDebug() << Q_FUNC_INFO << plists.count(); - foreach ( const playlist_ptr& p, plists ) + foreach ( const playlist_ptr& p, plists ) { + qDebug() << "Batch inserting playlist:" << p->guid(); m_playlists.insert( p->guid(), p ); - + } emit playlistsAdded( plists ); } void -Collection::setDynamicPlaylists( const QList< Tomahawk::dynplaylist_ptr >& plists ) +Collection::setAutoPlaylists( const QList< Tomahawk::dynplaylist_ptr >& plists ) { qDebug() << Q_FUNC_INFO << plists.count(); - foreach ( const dynplaylist_ptr& p, plists ) - m_dynplaylists.insert( p->guid(), p ); -// emit dynamicPlaylistsAdded( plists ); + foreach ( const dynplaylist_ptr& p, plists ) { + qDebug() << "Batch inserting dynamic playlist:" << p->guid(); + m_autoplaylists.insert( p->guid(), p ); + } + emit autoPlaylistsAdded( plists ); } +void +Collection::setStations( const QList< dynplaylist_ptr >& stations ) +{ + qDebug() << Q_FUNC_INFO << stations.count(); + + foreach ( const dynplaylist_ptr& s, stations ) { + qDebug() << "Batch inserting station:" << s->guid(); + m_stations.insert( s->guid(), s ); + } + emit autoPlaylistsAdded( stations ); +} void Collection::setTracks( const QList& tracks ) @@ -193,3 +248,18 @@ Collection::delTracks( const QStringList& files ) emit tracksRemoved( tracks ); } + +void +Collection::moveAutoToStation( const QString& guid ) +{ + + if( m_autoplaylists.contains( guid ) ) + m_stations.insert( guid, m_autoplaylists.take( guid ) ); +} + +void +Collection::moveStationToAuto( const QString& guid ) +{ + if( m_stations.contains( guid ) ) + m_autoplaylists.insert( guid, m_stations.take( guid ) ); +} diff --git a/src/libtomahawk/collection.h b/src/libtomahawk/collection.h index 64f553b6e..fd496cc3a 100644 --- a/src/libtomahawk/collection.h +++ b/src/libtomahawk/collection.h @@ -57,19 +57,25 @@ public: virtual void loadPlaylists() { qDebug() << Q_FUNC_INFO; } virtual void loadTracks() { qDebug() << Q_FUNC_INFO; } - virtual void loadDynamicPlaylists() { qDebug() << Q_FUNC_INFO ; } + virtual void loadAutoPlaylists() { qDebug() << Q_FUNC_INFO ; } + virtual void loadStations() { qDebug() << Q_FUNC_INFO ; } virtual Tomahawk::playlist_ptr playlist( const QString& guid ); - virtual Tomahawk::dynplaylist_ptr dynamicPlaylist( const QString& guid ); + virtual Tomahawk::dynplaylist_ptr autoPlaylist( const QString& guid ); + virtual Tomahawk::dynplaylist_ptr station( const QString& guid ); virtual void addPlaylist( const Tomahawk::playlist_ptr& p ); virtual void deletePlaylist( const Tomahawk::playlist_ptr& p ); - virtual void addDynamicPlaylist( const Tomahawk::dynplaylist_ptr& p ); - virtual void deleteDynamicPlaylist( const Tomahawk::dynplaylist_ptr& p ); + virtual void addAutoPlaylist( const Tomahawk::dynplaylist_ptr& p ); + virtual void deleteAutoPlaylist( const Tomahawk::dynplaylist_ptr& p ); + + virtual void addStation( const Tomahawk::dynplaylist_ptr& s ); + virtual void deleteStation( const Tomahawk::dynplaylist_ptr& s ); virtual QList< Tomahawk::playlist_ptr > playlists() { return m_playlists.values(); } - virtual QList< Tomahawk::dynplaylist_ptr > dynamicPlaylists() { return m_dynplaylists.values(); } + virtual QList< Tomahawk::dynplaylist_ptr > autoPlaylists() { return m_autoplaylists.values(); } + virtual QList< Tomahawk::dynplaylist_ptr > stations() { return m_stations.values(); } virtual QList< Tomahawk::query_ptr > tracks() { return m_tracks; } const source_ptr& source() const; @@ -82,17 +88,19 @@ signals: void playlistsAdded( const QList& ); void playlistsDeleted( const QList& ); - void dynamicPlaylistsAdded( const QList& ); - void dynamicPlaylistsDeleted( const QList& ); -// void stationsAdded( const QList& ); -// void stationsDeleted( const QList& ); + void autoPlaylistsAdded( const QList& ); + void autoPlaylistsDeleted( const QList& ); + + void stationsAdded( const QList& ); + void stationsDeleted( const QList& ); public slots: virtual void addTracks( const QList& newitems ) = 0; virtual void removeTracks( const QDir& dir ) = 0; void setPlaylists( const QList& plists ); - void setDynamicPlaylists( const QList< Tomahawk::dynplaylist_ptr >& dynplists ); + void setAutoPlaylists( const QList< Tomahawk::dynplaylist_ptr >& autoplists ); + void setStations( const QList< Tomahawk::dynplaylist_ptr >& stations ); void setTracks( const QList& tracks ); void delTracks( const QStringList& files ); @@ -108,7 +116,13 @@ private: source_ptr m_source; QList< Tomahawk::query_ptr > m_tracks; QHash< QString, Tomahawk::playlist_ptr > m_playlists; - QHash< QString, Tomahawk::dynplaylist_ptr > m_dynplaylists; + QHash< QString, Tomahawk::dynplaylist_ptr > m_autoplaylists; + QHash< QString, Tomahawk::dynplaylist_ptr > m_stations; + + // HACK see line 99 in the dbcmd for why we need this for backwards-compatibility + void moveAutoToStation( const QString& guid ); + void moveStationToAuto( const QString& guid ); + friend class ::DatabaseCommand_SetDynamicPlaylistRevision; }; }; // ns diff --git a/src/libtomahawk/database/databasecollection.cpp b/src/libtomahawk/database/databasecollection.cpp index 0348cd5e6..45537610d 100644 --- a/src/libtomahawk/database/databasecollection.cpp +++ b/src/libtomahawk/database/databasecollection.cpp @@ -23,7 +23,8 @@ #include "databasecommand_addfiles.h" #include "databasecommand_deletefiles.h" #include "databasecommand_loadallplaylists.h" -#include "databasecommand_loadalldynamicplaylists.h" +#include "databasecommand_loadallautoplaylists.h" +#include "databasecommand_loadallstations.h" using namespace Tomahawk; @@ -48,21 +49,28 @@ DatabaseCollection::loadPlaylists() void -DatabaseCollection::loadDynamicPlaylists() +DatabaseCollection::loadAutoPlaylists() { qDebug() << Q_FUNC_INFO; - DatabaseCommand_LoadAllDynamicPlaylists* cmd = new DatabaseCommand_LoadAllDynamicPlaylists( source() ); + DatabaseCommand_LoadAllAutoPlaylists* cmd = new DatabaseCommand_LoadAllAutoPlaylists( source() ); - connect( cmd, SIGNAL( dynamicPlaylistLoaded( Tomahawk::source_ptr, QVariantList ) ), - SLOT( dynamicPlaylistCreated( const Tomahawk::source_ptr&, const QVariantList& ) ) );/* connect( cmd, SIGNAL( autoPlaylistLoaded( Tomahawk::source_ptr, QVariantList ) ), - SLOT( dynamicPlaylistCreated( const Tomahawk::source_ptr&, const QVariantList& ) ) ); - connect( cmd, SIGNAL( stationLoaded( Tomahawk::source_ptr, QVariantList ) ), - SLOT( dynamicPlaylistCreated( const Tomahawk::source_ptr&, const QVariantList& ) ) );*/ + SLOT( autoPlaylistCreated( const Tomahawk::source_ptr&, const QVariantList& ) ) ); Database::instance()->enqueue( QSharedPointer( cmd ) ); } +void +DatabaseCollection::loadStations() +{ + qDebug() << Q_FUNC_INFO; + DatabaseCommand_LoadAllStations* cmd = new DatabaseCommand_LoadAllStations( source() ); + + connect( cmd, SIGNAL( stationLoaded( Tomahawk::source_ptr, QVariantList ) ), + SLOT( stationCreated( const Tomahawk::source_ptr&, const QVariantList& ) ) ); + + Database::instance()->enqueue( QSharedPointer( cmd ) );} + void DatabaseCollection::loadTracks() @@ -113,16 +121,30 @@ DatabaseCollection::playlists() } -QList< dynplaylist_ptr > DatabaseCollection::dynamicPlaylists() +QList< dynplaylist_ptr > +DatabaseCollection::autoPlaylists() { qDebug() << Q_FUNC_INFO; - if ( Collection::dynamicPlaylists().isEmpty() ) + if ( Collection::autoPlaylists().isEmpty() ) { - loadDynamicPlaylists(); + loadAutoPlaylists(); } - return Collection::dynamicPlaylists(); + return Collection::autoPlaylists(); +} + +QList< dynplaylist_ptr > +DatabaseCollection::stations() +{ + qDebug() << Q_FUNC_INFO; + + if ( Collection::stations().isEmpty() ) + { + loadStations(); + } + + return Collection::stations(); } @@ -139,8 +161,7 @@ DatabaseCollection::tracks() return Collection::tracks(); } - -void DatabaseCollection::dynamicPlaylistCreated( const source_ptr& source, const QVariantList& data ) +void DatabaseCollection::autoPlaylistCreated( const source_ptr& source, const QVariantList& data ) { dynplaylist_ptr p( new DynamicPlaylist( source, //src data[0].toString(), //current rev @@ -153,6 +174,23 @@ void DatabaseCollection::dynamicPlaylistCreated( const source_ptr& source, const data[7].toBool(), //shared data[8].toInt(), //lastmod data[9].toString() ) ); //GUID - addDynamicPlaylist( p ); + addAutoPlaylist( p ); } +void DatabaseCollection::stationCreated( const source_ptr& source, const QVariantList& data ) +{ + dynplaylist_ptr p( new DynamicPlaylist( source, //src + data[0].toString(), //current rev + data[1].toString(), //title + data[2].toString(), //info + data[3].toString(), //creator + data[4].toUInt(), // createdOn + data[5].toString(), // dynamic type + static_cast(data[6].toInt()), // dynamic mode + data[7].toBool(), //shared + data[8].toInt(), //lastmod + data[9].toString() ) ); //GUID + addStation( p ); +} + + diff --git a/src/libtomahawk/database/databasecollection.h b/src/libtomahawk/database/databasecollection.h index 5b15913c0..d20480d6d 100644 --- a/src/libtomahawk/database/databasecollection.h +++ b/src/libtomahawk/database/databasecollection.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 @@ -40,18 +40,21 @@ public: virtual void loadTracks(); virtual void loadPlaylists(); - virtual void loadDynamicPlaylists(); + virtual void loadAutoPlaylists(); + virtual void loadStations(); virtual QList< Tomahawk::playlist_ptr > playlists(); virtual QList< Tomahawk::query_ptr > tracks(); - virtual QList< Tomahawk::dynplaylist_ptr > dynamicPlaylists(); + virtual QList< Tomahawk::dynplaylist_ptr > autoPlaylists(); + virtual QList< Tomahawk::dynplaylist_ptr > stations(); public slots: virtual void addTracks( const QList& newitems ); virtual void removeTracks( const QDir& dir ); private slots: - void dynamicPlaylistCreated( const Tomahawk::source_ptr& source, const QVariantList& data ); + void stationCreated( const Tomahawk::source_ptr& source, const QVariantList& data ); + void autoPlaylistCreated( const Tomahawk::source_ptr& source, const QVariantList& data ); }; #endif // DATABASECOLLECTION_H diff --git a/src/libtomahawk/database/databasecommand_createdynamicplaylist.cpp b/src/libtomahawk/database/databasecommand_createdynamicplaylist.cpp index b0aa81b3b..597f0c07d 100644 --- a/src/libtomahawk/database/databasecommand_createdynamicplaylist.cpp +++ b/src/libtomahawk/database/databasecommand_createdynamicplaylist.cpp @@ -57,6 +57,7 @@ DatabaseCommand_CreateDynamicPlaylist::exec( DatabaseImpl* lib ) DatabaseCommand_CreatePlaylist::createPlaylist( lib, true ); qDebug() << "Created normal playlist, now creating additional dynamic info!"; + qDebug() << "Create dynamic execing!" << m_playlist << m_v; TomahawkSqlQuery cre = lib->newquery(); cre.prepare( "INSERT INTO dynamic_playlist( guid, pltype, plmode ) " diff --git a/src/libtomahawk/database/databasecommand_deletedynamicplaylist.cpp b/src/libtomahawk/database/databasecommand_deletedynamicplaylist.cpp index 34c5defbd..718fcfc03 100644 --- a/src/libtomahawk/database/databasecommand_deletedynamicplaylist.cpp +++ b/src/libtomahawk/database/databasecommand_deletedynamicplaylist.cpp @@ -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 @@ -18,9 +18,11 @@ #include "databasecommand_deletedynamicplaylist.h" -#include +#include "dynamic/DynamicPlaylist.h" #include "network/servent.h" - + +#include + using namespace Tomahawk; @@ -37,10 +39,10 @@ DatabaseCommand_DeleteDynamicPlaylist::exec( DatabaseImpl* lib ) qDebug() << "deleting dynamic playlist:" << m_playlistguid; DatabaseCommand_DeletePlaylist::exec( lib ); TomahawkSqlQuery cre = lib->newquery(); - + cre.prepare( "DELETE FROM dynamic_playlist WHERE guid = :id" ); cre.bindValue( ":id", m_playlistguid ); - + cre.exec(); } @@ -54,12 +56,16 @@ DatabaseCommand_DeleteDynamicPlaylist::postCommitHook() qDebug() << "Source has gone offline, not emitting to GUI."; return; } - - dynplaylist_ptr playlist = source()->collection()->dynamicPlaylist( m_playlistguid ); + // we arent sure which it is, but it can't be more th an one. so try both + dynplaylist_ptr playlist = source()->collection()->autoPlaylist( m_playlistguid ); + if( playlist.isNull() ) + playlist = source()->collection()->station( m_playlistguid ); + + qDebug() << "Just tried to load playlist for deletion:" << m_playlistguid << "Did we get a null one?" << playlist.isNull() << "is it a station?" << (playlist->mode() == OnDemand); Q_ASSERT( !playlist.isNull() ); - + playlist->reportDeleted( playlist ); - + if( source()->isLocal() ) Servent::instance()->triggerDBSync(); } diff --git a/src/libtomahawk/database/databasecommand_loadalldynamicplaylists.cpp b/src/libtomahawk/database/databasecommand_loadallautoplaylists.cpp similarity index 81% rename from src/libtomahawk/database/databasecommand_loadalldynamicplaylists.cpp rename to src/libtomahawk/database/databasecommand_loadallautoplaylists.cpp index b85c19dba..7278db812 100644 --- a/src/libtomahawk/database/databasecommand_loadalldynamicplaylists.cpp +++ b/src/libtomahawk/database/databasecommand_loadallautoplaylists.cpp @@ -16,7 +16,7 @@ * along with Tomahawk. If not, see . */ -#include "databasecommand_loadalldynamicplaylists.h" +#include "databasecommand_loadallautoplaylists.h" #include @@ -26,15 +26,14 @@ using namespace Tomahawk; -void DatabaseCommand_LoadAllDynamicPlaylists::exec( DatabaseImpl* dbi ) +void 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" ) - .arg( source()->isLocal() ? "IS NULL" : - QString( "=%1" ).arg( source()->id() ) - ) ); + "FROM playlist, dynamic_playlist WHERE source %1 AND dynplaylist = 'true' AND playlist.guid = dynamic_playlist.guid AND dynamic_playlist.plmode = %2" ) + .arg( source()->isLocal() ? "IS NULL" : QString( "=%1" ).arg( source()->id() ) ) + .arg( Static ) ); QList plists; while ( query.next() ) @@ -49,12 +48,7 @@ void DatabaseCommand_LoadAllDynamicPlaylists::exec( DatabaseImpl* dbi ) << query.value(6).toBool() //shared << query.value(5).toInt() //lastmod << query.value(0).toString(); //GUID - emit dynamicPlaylistLoaded( source(), data ); - /* - if( static_cast( query.value(8).toInt() ) == Static ) - emit autoPlaylistLoaded( source(), data ); - else - emit stationLoaded( source(), data );*/ + emit autoPlaylistLoaded( source(), data ); } emit done(); diff --git a/src/libtomahawk/database/databasecommand_loadalldynamicplaylists.h b/src/libtomahawk/database/databasecommand_loadallautoplaylists.h similarity index 68% rename from src/libtomahawk/database/databasecommand_loadalldynamicplaylists.h rename to src/libtomahawk/database/databasecommand_loadallautoplaylists.h index eb56239a9..6352ff360 100644 --- a/src/libtomahawk/database/databasecommand_loadalldynamicplaylists.h +++ b/src/libtomahawk/database/databasecommand_loadallautoplaylists.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 @@ -16,8 +16,8 @@ * along with Tomahawk. If not, see . */ -#ifndef DATABASECOMMAND_LOADALLDYNAMICPLAYLISTS_H -#define DATABASECOMMAND_LOADALLDYNAMICPLAYLISTS_H +#ifndef DATABASECOMMAND_LOADALLAUTOPLAYLISTS_H +#define DATABASECOMMAND_LOADALLAUTOPLAYLISTS_H #include #include @@ -25,22 +25,22 @@ #include "databasecommand.h" #include "typedefs.h" -class DatabaseCommand_LoadAllDynamicPlaylists : public DatabaseCommand +class DatabaseCommand_LoadAllAutoPlaylists : public DatabaseCommand { Q_OBJECT - + public: - explicit DatabaseCommand_LoadAllDynamicPlaylists( const Tomahawk::source_ptr& s, QObject* parent = 0 ) + explicit DatabaseCommand_LoadAllAutoPlaylists( const Tomahawk::source_ptr& s, QObject* parent = 0 ) : DatabaseCommand( s, parent ) {} - + virtual void exec( DatabaseImpl* ); virtual bool doesMutates() const { return false; } - virtual QString commandname() const { return "loadalldynamicplaylists"; } - + virtual QString commandname() const { return "loadallautoplaylists"; } + signals: - void dynamicPlaylistLoaded( const Tomahawk::source_ptr& source, const QVariantList& data ); + void autoPlaylistLoaded( const Tomahawk::source_ptr& source, const QVariantList& data ); void done(); }; -#endif // DATABASECOMMAND_ADDFILES_H +#endif diff --git a/src/libtomahawk/database/databasecommand_loadallstations.cpp b/src/libtomahawk/database/databasecommand_loadallstations.cpp new file mode 100644 index 000000000..9f75c7f2e --- /dev/null +++ b/src/libtomahawk/database/databasecommand_loadallstations.cpp @@ -0,0 +1,56 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Christian Muehlhaeuser + * + * 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_loadallstations.h" + +#include + +#include "dynamic/DynamicPlaylist.h" +#include "databaseimpl.h" + +using namespace Tomahawk; + + +void 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" ) + .arg( source()->isLocal() ? "IS NULL" : QString( "=%1" ).arg( source()->id() ) ) + .arg( OnDemand ) ); + + QList plists; + while ( query.next() ) + { + QVariantList data = QVariantList() << 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 + emit stationLoaded( source(), data ); + } + + emit done(); +} + diff --git a/src/libtomahawk/database/databasecommand_loadallstations.h b/src/libtomahawk/database/databasecommand_loadallstations.h new file mode 100644 index 000000000..4cb29dc2a --- /dev/null +++ b/src/libtomahawk/database/databasecommand_loadallstations.h @@ -0,0 +1,46 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Christian Muehlhaeuser + * + * 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_LOADALLSTATIONS_H +#define DATABASECOMMAND_LOADALLSTATIONS_H + +#include +#include + +#include "databasecommand.h" +#include "typedefs.h" + +class DatabaseCommand_LoadAllStations : public DatabaseCommand +{ + Q_OBJECT + +public: + explicit DatabaseCommand_LoadAllStations( const Tomahawk::source_ptr& s, QObject* parent = 0 ) + : DatabaseCommand( s, parent ) + {} + + virtual void exec( DatabaseImpl* ); + virtual bool doesMutates() const { return false; } + virtual QString commandname() const { return "loadallstations"; } + +signals: + void stationLoaded( const Tomahawk::source_ptr& source, const QVariantList& data ); + void done(); +}; + +#endif \ No newline at end of file diff --git a/src/libtomahawk/database/databasecommand_renameplaylist.cpp b/src/libtomahawk/database/databasecommand_renameplaylist.cpp index 4187ae27e..2912068f8 100644 --- a/src/libtomahawk/database/databasecommand_renameplaylist.cpp +++ b/src/libtomahawk/database/databasecommand_renameplaylist.cpp @@ -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 @@ -21,6 +21,7 @@ #include #include "network/servent.h" +#include "collection.h" using namespace Tomahawk; @@ -62,8 +63,14 @@ DatabaseCommand_RenamePlaylist::postCommitHook() qDebug() << "Source has gone offline, not emitting to GUI."; return; } - + playlist_ptr playlist = source()->collection()->playlist( m_playlistguid ); + // fallback, check for auto and stations too + if( playlist.isNull() ) + playlist = source()->collection()->autoPlaylist( m_playlistguid ); + if( playlist.isNull() ) + playlist = source()->collection()->station( m_playlistguid ); + Q_ASSERT( !playlist.isNull() ); qDebug() << "Renaming old playlist" << playlist->title() << "to" << m_playlistTitle << m_playlistguid; diff --git a/src/libtomahawk/database/databasecommand_setdynamicplaylistrevision.cpp b/src/libtomahawk/database/databasecommand_setdynamicplaylistrevision.cpp index 39494f3fd..728af40a9 100644 --- a/src/libtomahawk/database/databasecommand_setdynamicplaylistrevision.cpp +++ b/src/libtomahawk/database/databasecommand_setdynamicplaylistrevision.cpp @@ -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,15 +24,15 @@ #include "dynamic/DynamicPlaylist.h" #include "dynamic/DynamicControl.h" -DatabaseCommand_SetDynamicPlaylistRevision::DatabaseCommand_SetDynamicPlaylistRevision(const Tomahawk::source_ptr& s, - const QString& playlistguid, - const QString& newrev, - const QString& oldrev, - const QStringList& orderedguids, - const QList< plentry_ptr >& addedentries, +DatabaseCommand_SetDynamicPlaylistRevision::DatabaseCommand_SetDynamicPlaylistRevision(const Tomahawk::source_ptr& s, + const QString& playlistguid, + const QString& newrev, + const QString& oldrev, + const QStringList& orderedguids, + const QList< plentry_ptr >& addedentries, const QList& entries, - const QString& type, - GeneratorMode mode, + const QString& type, + GeneratorMode mode, const QList< dyncontrol_ptr >& controls ) : DatabaseCommand_SetPlaylistRevision( s, playlistguid, newrev, oldrev, orderedguids, addedentries, entries ) , m_type( type ) @@ -42,12 +42,12 @@ DatabaseCommand_SetDynamicPlaylistRevision::DatabaseCommand_SetDynamicPlaylistRe } -DatabaseCommand_SetDynamicPlaylistRevision::DatabaseCommand_SetDynamicPlaylistRevision(const Tomahawk::source_ptr& s, - const QString& playlistguid, - const QString& newrev, - const QString& oldrev, - const QString& type, - GeneratorMode mode, +DatabaseCommand_SetDynamicPlaylistRevision::DatabaseCommand_SetDynamicPlaylistRevision(const Tomahawk::source_ptr& s, + const QString& playlistguid, + const QString& newrev, + const QString& oldrev, + const QString& type, + GeneratorMode mode, const QList< dyncontrol_ptr >& controls ) : DatabaseCommand_SetPlaylistRevision( s, playlistguid, newrev, oldrev, QStringList(), QList< plentry_ptr >(), QList< plentry_ptr >() ) , m_type( type ) @@ -61,16 +61,16 @@ QVariantList DatabaseCommand_SetDynamicPlaylistRevision::controlsV() { if( m_controls.isEmpty() ) return m_controlsV; - + if( !m_controls.isEmpty() && m_controlsV.isEmpty() ) { - foreach( const dyncontrol_ptr& control, m_controls ) + foreach( const dyncontrol_ptr& control, m_controls ) { m_controlsV << QJson::QObjectHelper::qobject2qvariant( control.data() ); } } return m_controlsV; - + } void @@ -82,20 +82,32 @@ DatabaseCommand_SetDynamicPlaylistRevision::postCommitHook() qDebug() << "Source has gone offline, not emitting to GUI."; return; } - + QStringList orderedentriesguids; foreach( const QVariant& v, orderedguids() ) orderedentriesguids << v.toString(); - + Q_ASSERT( !source().isNull() ); Q_ASSERT( !source()->collection().isNull() ); qDebug() << "Postcommitting this playlist:" << playlistguid() << source().isNull() << source().data(); + // private, but we are a friend. will recall itself in its own thread: - dynplaylist_ptr playlist = source()->collection()->dynamicPlaylist( playlistguid() ); - + dynplaylist_ptr playlist = source()->collection()->autoPlaylist( playlistguid() ); + if( playlist.isNull() ) + playlist = source()->collection()->station( playlistguid() ); + + // workaround a bug in pre-0.1.0 tomahawks. they created dynamic playlists in OnDemand mode *always*, and then set the mode to the real one. + // 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(); + 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 + source()->collection()->moveAutoToStation( playlistguid() ); if ( playlist.isNull() ) { - qDebug() <<"Got null playlist with guid:" << playlistguid() << "from source and collection:" << source()->friendlyName() << source()->collection()->name(); + qDebug() <<"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; } @@ -103,7 +115,7 @@ DatabaseCommand_SetDynamicPlaylistRevision::postCommitHook() QList controlMap; foreach( const QVariant& v, m_controlsV ) controlMap << v.toMap(); - + if( m_mode == OnDemand ) playlist->setRevision( newrev(), true, // this *is* the newest revision so far @@ -145,7 +157,7 @@ void DatabaseCommand_SetDynamicPlaylistRevision::exec( DatabaseImpl* lib ) { DatabaseCommand_SetPlaylistRevision::exec( lib ); - + QVariantList newcontrols; if( m_controlsV.isEmpty() && !m_controls.isEmpty() ) { foreach( const dyncontrol_ptr& control, m_controls ) { @@ -156,21 +168,21 @@ DatabaseCommand_SetDynamicPlaylistRevision::exec( DatabaseImpl* lib ) newcontrols << v.toMap().value( "id" ); } } - + QJson::Serializer ser; const QByteArray newcontrols_data = ser.serialize( newcontrols ); - + TomahawkSqlQuery query = lib->newquery(); QString sql = "INSERT INTO dynamic_playlist_revision (guid, controls, plmode, pltype) " "VALUES(?, ?, ?, ?)"; - + query.prepare( sql ); query.addBindValue( m_newrev ); query.addBindValue( newcontrols_data ); query.addBindValue( QString::number( (int) m_mode ) ); query.addBindValue( m_type ); query.exec(); - + // delete all the old controls, replace with new onws qDebug() << "Deleting controls with playlist id" << m_playlistguid; TomahawkSqlQuery delQuery = lib->newquery(); @@ -178,7 +190,7 @@ DatabaseCommand_SetDynamicPlaylistRevision::exec( DatabaseImpl* lib ) delQuery.addBindValue( m_playlistguid ); if( !delQuery.exec() ) qWarning() << "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 ) " "VALUES( ?, ?, ?, ?, ? )" ); @@ -191,7 +203,7 @@ DatabaseCommand_SetDynamicPlaylistRevision::exec( DatabaseImpl* lib ) controlsQuery.addBindValue( control->selectedType() ); controlsQuery.addBindValue( control->match() ); controlsQuery.addBindValue( control->input() ); - + controlsQuery.exec(); } } else { @@ -203,23 +215,23 @@ DatabaseCommand_SetDynamicPlaylistRevision::exec( DatabaseImpl* lib ) controlsQuery.addBindValue( control.value( "selectedType" ) ); controlsQuery.addBindValue( control.value( "match" ) ); controlsQuery.addBindValue( control.value( "input" ) ); - + controlsQuery.exec(); } - + } if( m_applied ) { qDebug() << "updating dynamic playlist, optimistic locking okay"; - + TomahawkSqlQuery query2 = lib->newquery(); query2.prepare( "UPDATE dynamic_playlist SET pltype = ?, plmode = ? WHERE guid = ?" ); query2.bindValue( 0, m_type ); query2.bindValue( 1, m_mode ); query2.bindValue( 2, m_playlistguid ); query2.exec(); - + } - - + + } diff --git a/src/libtomahawk/playlist/dynamic/DynamicPlaylist.cpp b/src/libtomahawk/playlist/dynamic/DynamicPlaylist.cpp index d81c27324..5122f8260 100644 --- a/src/libtomahawk/playlist/dynamic/DynamicPlaylist.cpp +++ b/src/libtomahawk/playlist/dynamic/DynamicPlaylist.cpp @@ -70,11 +70,13 @@ DynamicPlaylist::DynamicPlaylist ( const Tomahawk::source_ptr& author, const QString& info, const QString& creator, const QString& type, + GeneratorMode mode, bool shared ) : Playlist ( author, guid, title, info, creator, shared ) { qDebug() << "Creating Dynamic Playlist 2"; m_generator = geninterface_ptr( GeneratorFactory::create( type ) ); + m_generator->setMode( mode ); } geninterface_ptr @@ -115,11 +117,12 @@ DynamicPlaylist::create( const Tomahawk::source_ptr& author, const QString& title, const QString& info, const QString& creator, + GeneratorMode mode, bool shared ) { // default generator QString type = ""; - dynplaylist_ptr dynplaylist = dynplaylist_ptr( new DynamicPlaylist( author, guid, title, info, creator, type, shared ) ); + dynplaylist_ptr dynplaylist = dynplaylist_ptr( new DynamicPlaylist( author, guid, title, info, creator, type, mode, shared ) ); DatabaseCommand_CreateDynamicPlaylist* cmd = new DatabaseCommand_CreateDynamicPlaylist( author, dynplaylist ); connect( cmd, SIGNAL(finished()), dynplaylist.data(), SIGNAL(created()) ); @@ -256,7 +259,10 @@ DynamicPlaylist::reportCreated( const Tomahawk::dynplaylist_ptr& self ) // will emit Collection::playlistCreated(...) // qDebug() << "Creating dynplaylist belonging to:" << author().data() << author().isNull(); // qDebug() << "REPORTING DYNAMIC PLAYLIST CREATED:" << this << author()->friendlyName(); - author()->collection()->addDynamicPlaylist( self ); + if( self->mode() == Static ) + author()->collection()->addAutoPlaylist( self ); + else + author()->collection()->addStation( self ); } void @@ -265,7 +271,10 @@ DynamicPlaylist::reportDeleted( const Tomahawk::dynplaylist_ptr& self ) qDebug() << Q_FUNC_INFO; Q_ASSERT( self.data() == this ); // will emit Collection::playlistDeleted(...) - author()->collection()->deleteDynamicPlaylist( self ); + if( self->mode() == Static ) + author()->collection()->deleteAutoPlaylist( self ); + else + author()->collection()->deleteStation( self ); emit deleted( self ); } diff --git a/src/libtomahawk/playlist/dynamic/DynamicPlaylist.h b/src/libtomahawk/playlist/dynamic/DynamicPlaylist.h index 4312d67b9..7db146fd1 100644 --- a/src/libtomahawk/playlist/dynamic/DynamicPlaylist.h +++ b/src/libtomahawk/playlist/dynamic/DynamicPlaylist.h @@ -81,6 +81,7 @@ public: const QString& title, const QString& info, const QString& creator, + GeneratorMode mode, bool shared ); static bool remove( const dynplaylist_ptr& playlist ); @@ -180,6 +181,7 @@ private: const QString& info, const QString& creator, const QString& type, + GeneratorMode mode, bool shared ); private: diff --git a/src/sourcetree/sourcesmodel.cpp b/src/sourcetree/sourcesmodel.cpp index 6f4f72653..ddd2af04f 100644 --- a/src/sourcetree/sourcesmodel.cpp +++ b/src/sourcetree/sourcesmodel.cpp @@ -377,14 +377,14 @@ SourcesModel::indexFromItem( SourceTreeItem* item ) const curItem = curItem->parent(); } - qDebug() << "build child index list:" << childIndexList; +// qDebug() << "build child index list:" << childIndexList; // now rebuild the qmodelindex we need QModelIndex idx; for( int i = childIndexList.size() - 1; i >= 0 ; i-- ) { idx = index( childIndexList[ i ], 0, idx ); } - qDebug() << "Got index from item:" << idx << idx.data( Qt::DisplayRole ).toString(); - qDebug() << "parent:" << idx.parent(); +// qDebug() << "Got index from item:" << idx << idx.data( Qt::DisplayRole ).toString(); +// qDebug() << "parent:" << idx.parent(); return idx; } diff --git a/src/sourcetree/sourcesmodel.h b/src/sourcetree/sourcesmodel.h index eb3111b8b..accd8c40f 100644 --- a/src/sourcetree/sourcesmodel.h +++ b/src/sourcetree/sourcesmodel.h @@ -48,7 +48,7 @@ public: StaticPlaylist = 3, AutomaticPlaylist = 4, - Stations = 5, + Station = 5, GenericPage = 6 }; diff --git a/src/sourcetree/sourcetreeitem.cpp b/src/sourcetree/sourcetreeitem.cpp index 50c22f2a2..aa6a25e28 100644 --- a/src/sourcetree/sourcetreeitem.cpp +++ b/src/sourcetree/sourcetreeitem.cpp @@ -197,6 +197,111 @@ PlaylistItem::setData(const QVariant& v, bool role) return false; } +DynamicPlaylistItem::DynamicPlaylistItem( SourcesModel* mdl, SourceTreeItem* parent, const dynplaylist_ptr& pl, int index ) + : PlaylistItem( mdl, parent, pl.staticCast< Playlist >(), index ) + , m_dynplaylist( pl ) +{ + setRowType( m_dynplaylist->mode() == Static ? SourcesModel::AutomaticPlaylist : SourcesModel::Station ); + + connect( pl.data(), SIGNAL( dynamicRevisionLoaded( Tomahawk::DynamicPlaylistRevision ) ), + SLOT( onDynamicPlaylistLoaded( Tomahawk::DynamicPlaylistRevision ) ), Qt::QueuedConnection ); + + if( ViewManager::instance()->pageForDynPlaylist( pl ) ) + model()->linkSourceItemToPage( this, ViewManager::instance()->pageForDynPlaylist( pl ) ); +} + +DynamicPlaylistItem::~DynamicPlaylistItem() +{ +} + +void +DynamicPlaylistItem::activate() +{ + ViewPage* p = ViewManager::instance()->show( m_dynplaylist ); + model()->linkSourceItemToPage( this, p ); +} + +void +DynamicPlaylistItem::onDynamicPlaylistLoaded( DynamicPlaylistRevision revision ) +{ + setLoaded( true ); + checkReparentHackNeeded( revision ); + // END HACK + emit updated(); +} + +void +DynamicPlaylistItem::checkReparentHackNeeded( const DynamicPlaylistRevision& revision ) +{ + // HACK HACK HACK workaround for an ugly hack where we have to be compatible with older tomahawks (pre-0.1.0) that created dynplaylists as OnDemand then changed them to Static if they were static. + // we need to reparent this playlist to the correct category :-/. + CategoryItem* cat = qobject_cast< CategoryItem* >( parent() ); + qDebug() << "with category" << cat; + if( cat ) qDebug() << "and cat type:" << cat->categoryType(); + if( cat ) { + CategoryItem* from = cat; + CategoryItem* to = 0; + if( cat->categoryType() == SourcesModel::PlaylistsCategory && revision.mode == OnDemand ) { // WRONG + CollectionItem* col = qobject_cast< CollectionItem* >( cat->parent() ); + to = col->stationsCategory(); + if( !to ) { // you have got to be fucking kidding me + int fme = col->children().count(); + col->beginRowsAdded( fme, fme ); + to = new CategoryItem( model(), col, SourcesModel::StationsCategory, false ); + col->appendChild( to ); // we f'ing know it's not local b/c we're not getting into this mess ourselves + col->endRowsAdded(); + col->setStationsCategory( to ); + } + } else if( cat->categoryType() == SourcesModel::StationsCategory && revision.mode == Static ) { // WRONG + CollectionItem* col = qobject_cast< CollectionItem* >( cat->parent() ); + to = col->playlistsCategory(); + qDebug() << "TRYING TO HACK TO:" << to; + if( !to ) { // you have got to be fucking kidding me + int fme = col->children().count(); + col->beginRowsAdded( fme, fme ); + to = new CategoryItem( model(), col, SourcesModel::PlaylistsCategory, false ); + col->appendChild( to ); // we f'ing know it's not local b/c we're not getting into this mess ourselves + col->endRowsAdded(); + col->setPlaylistsCategory( to ); + } + } + if( to ) { + qDebug() << "HACKING! moving dynamic playlist from" << from->text() << "to:" << to->text(); + // remove and add + int idx = from->children().indexOf( this ); + from->beginRowsRemoved( idx, idx ); + from->removeChild( this ); + from->endRowsRemoved(); + + idx = to->children().count(); + to->beginRowsAdded( idx, idx ); + to->appendChild( this ); + to->endRowsAdded(); + + setParentItem( to ); + } + } +} + + +dynplaylist_ptr +DynamicPlaylistItem::dynPlaylist() const +{ + return m_dynplaylist; +} + +QString +DynamicPlaylistItem::text() const +{ + return m_dynplaylist->title(); +} + +bool +DynamicPlaylistItem::willAcceptDrag( const QMimeData* data ) const +{ + return false; +} + /// Dynamic Playlist Item /* @@ -272,7 +377,8 @@ CategoryAddItem::text() const void CategoryAddItem::activate() { - switch( m_categoryType ) { + switch( m_categoryType ) + { case SourcesModel::PlaylistsCategory: // only show if none is shown yet if( !ViewManager::instance()->isNewPlaylistPageVisible() ) { @@ -281,7 +387,7 @@ CategoryAddItem::activate() } break; case SourcesModel::StationsCategory: - // TODO + APP->mainWindow()->createStation(); break; } } @@ -289,7 +395,15 @@ CategoryAddItem::activate() Qt::ItemFlags CategoryAddItem::flags() const { - return Qt::ItemIsEnabled | Qt::ItemIsSelectable; + switch( m_categoryType ) + { + case SourcesModel::PlaylistsCategory: + return Qt::ItemIsEnabled | Qt::ItemIsSelectable; + case SourcesModel::StationsCategory: + default: + return Qt::ItemIsEnabled; + break; + } } QIcon @@ -349,23 +463,23 @@ CollectionItem::CollectionItem( SourcesModel* mdl, SourceTreeItem* parent, cons } // 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(); + QList< dynplaylist_ptr > stations = source->collection()->stations(); - if( !playlists.isEmpty() || source->isLocal() ) { + if( !playlists.isEmpty() || !autoplaylists.isEmpty() || source->isLocal() ) { m_playlists = new CategoryItem( model(), this, SourcesModel::PlaylistsCategory, source->isLocal() ); - // ugh :( we're being added by the model, no need to notify for added rows now -// m_playlists->blockSignals( true ); onPlaylistsAdded( playlists ); -// m_playlists->blockSignals( false ); + onAutoPlaylistsAdded( autoplaylists ); + } + if( !stations.isEmpty() || source->isLocal() ) { + m_stations = new CategoryItem( model(), this, SourcesModel::StationsCategory, source->isLocal() ); + onStationsAdded( stations ); } - - // TODO always show for now, till we actually support stations -// m_stations = new CategoryItem( model(), this, SourcesModel::StationsCategory, source->isLocal() ); if( ViewManager::instance()->pageForCollection( source->collection() ) ) model()->linkSourceItemToPage( this, ViewManager::instance()->pageForCollection( source->collection() ) ); - // HACK to load only for now - source->collection()->dynamicPlaylists(); + // load auto playlists and stations! connect( source.data(), SIGNAL( stats( QVariantMap ) ), this, SIGNAL( updated() ) ); connect( source.data(), SIGNAL( playbackStarted( Tomahawk::query_ptr ) ), this, SIGNAL( updated() ) ); @@ -377,6 +491,16 @@ CollectionItem::CollectionItem( SourcesModel* mdl, SourceTreeItem* parent, cons SLOT( onPlaylistsAdded( QList ) ), Qt::QueuedConnection ); connect( source->collection().data(), SIGNAL( playlistsDeleted( QList ) ), SLOT( onPlaylistsDeleted( QList ) ), Qt::QueuedConnection ); + + connect( source->collection().data(), SIGNAL( autoPlaylistsAdded( QList< Tomahawk::dynplaylist_ptr > ) ), + SLOT( onAutoPlaylistsAdded( QList ) ), Qt::QueuedConnection ); + connect( source->collection().data(), SIGNAL( autoPlaylistsDeleted( QList ) ), + SLOT( onAutoPlaylistsDeleted( QList ) ), Qt::QueuedConnection ); + + connect( source->collection().data(), SIGNAL( stationsAdded( QList ) ), + SLOT( onStationsAdded( QList ) ), Qt::QueuedConnection ); + connect( source->collection().data(), SIGNAL( stationsDeleted( QList ) ), + SLOT( onStationsDeleted( QList ) ), Qt::QueuedConnection ); } Tomahawk::source_ptr @@ -412,6 +536,44 @@ CollectionItem::icon() const return QIcon( RESPATH "images/user-avatar.png" ); } +void +CollectionItem::playlistsAddedInternal( SourceTreeItem* parent, const QList< dynplaylist_ptr >& playlists ) +{ + QList< SourceTreeItem* > items; + int addOffset = playlists.first()->author()->isLocal() ? 1 : 0; + + int from = parent->children().count() - addOffset; + parent->beginRowsAdded( from, from + playlists.count() - 1 ); + foreach( const dynplaylist_ptr& p, playlists ) + { + DynamicPlaylistItem* plItem = new DynamicPlaylistItem( model(), parent, p, parent->children().count() - addOffset ); + qDebug() << "Dynamic Playlist added:" << p->title() << p->creator() << p->info(); + p->loadRevision(); + items << plItem; + } + parent->endRowsAdded(); +} + +template< typename T > +void +CollectionItem::playlistsDeletedInternal( SourceTreeItem* parent, const QList< T >& playlists ) +{ + Q_ASSERT( parent ); // How can we delete playlists if we have none? + QList< SourceTreeItem* > items; + foreach( const T& playlist, playlists ) { + int curCount = parent->children().count(); + for( int i = 0; i < curCount; i++ ) { + PlaylistItem* pl = qobject_cast< PlaylistItem* >( parent->children().at( i ) ); + if( pl && pl->playlist() == playlist ) { + parent->beginRowsRemoved( i, i ); + parent->removeChild( pl ); + parent->endRowsRemoved(); + break; + } + } + } +} + void CollectionItem::onPlaylistsAdded( const QList< playlist_ptr >& playlists ) @@ -420,7 +582,10 @@ CollectionItem::onPlaylistsAdded( const QList< playlist_ptr >& playlists ) return; if( !m_playlists ) { // add the category too + int cur = children().count(); + beginRowsAdded( cur, cur ); m_playlists = new CategoryItem( model(), this, SourcesModel::PlaylistsCategory, source()->isLocal() ); + endRowsAdded(); } QList< SourceTreeItem* > items; @@ -441,22 +606,57 @@ CollectionItem::onPlaylistsAdded( const QList< playlist_ptr >& playlists ) void CollectionItem::onPlaylistsDeleted( const QList< playlist_ptr >& playlists ) { - Q_ASSERT( m_playlists ); // How can we delete playlists if we have none? - QList< SourceTreeItem* > items; - foreach( const playlist_ptr& playlist, playlists ) { - int curCount = m_playlists->children().count(); - for( int i = 0; i < curCount; i++ ) { - PlaylistItem* pl = qobject_cast< PlaylistItem* >( m_playlists->children().at( i ) ); - if( pl && pl->playlist() == playlist ) { - m_playlists->beginRowsRemoved( i, i ); - m_playlists->removeChild( pl ); - m_playlists->endRowsRemoved(); - break; - } - } - } + playlistsDeletedInternal( m_playlists, playlists ); } +void +CollectionItem::onAutoPlaylistsAdded( const QList< dynplaylist_ptr >& playlists ) +{ + if( playlists.isEmpty() ) + return; + + if( !m_playlists ) { // add the category too + int cur = children().count(); + beginRowsAdded( cur, cur ); + m_playlists = new CategoryItem( model(), this, SourcesModel::PlaylistsCategory, source()->isLocal() ); + endRowsAdded(); + } + + playlistsAddedInternal( m_playlists, playlists ); +} + +void +CollectionItem::onAutoPlaylistsDeleted( const QList< dynplaylist_ptr >& playlists ) +{ + if( !m_playlists ) + qDebug() << "NO playlist category item for a deleting playlist.."; + + playlistsDeletedInternal( m_playlists, playlists ); +} + +void +CollectionItem::onStationsAdded( const QList< dynplaylist_ptr >& stations ) +{ + if( stations.isEmpty() ) + return; + + if( !m_stations ) { // add the category too + int cur = children().count(); + beginRowsAdded( cur, cur ); + m_stations = new CategoryItem( model(), this, SourcesModel::StationsCategory, source()->isLocal() ); + endRowsAdded(); + } + + playlistsAddedInternal( m_stations, stations ); +} + +void +CollectionItem::onStationsDeleted( const QList< dynplaylist_ptr >& stations ) +{ + playlistsDeletedInternal( m_stations, stations ); +} + + /// Generic page item GenericPageItem::GenericPageItem( SourcesModel* model, SourceTreeItem* parent, const QString& text, const QIcon& icon ) : SourceTreeItem( model, parent, SourcesModel::GenericPage ) diff --git a/src/sourcetree/sourcetreeitem.h b/src/sourcetree/sourcetreeitem.h index fbd08eed1..fe433da9e 100644 --- a/src/sourcetree/sourcetreeitem.h +++ b/src/sourcetree/sourcetreeitem.h @@ -58,6 +58,7 @@ public: void endRowsAdded() { emit childRowsAdded(); } void beginRowsRemoved( int from, int to ) { emit beginChildRowsRemoved( from, to ); } void endRowsRemoved() { emit childRowsRemoved(); } + signals: void updated(); @@ -66,6 +67,10 @@ signals: void beginChildRowsRemoved( int fromRow, int toRow ); void childRowsRemoved(); + +protected: + void setRowType( SourcesModel::RowType t ) { m_type = t; } + void setParentItem( SourceTreeItem* item ) { m_parent = item; } private: SourcesModel::RowType m_type; @@ -133,13 +138,24 @@ public: Tomahawk::source_ptr source() const; + CategoryItem* stationsCategory() const { return m_stations; } + CategoryItem* playlistsCategory() const { return m_playlists; } + void setStationsCategory( CategoryItem* item ) { m_stations = item; } + void setPlaylistsCategory( CategoryItem* item ) { m_playlists = item; } private slots: void onPlaylistsAdded( const QList& playlists ); void onPlaylistsDeleted( const QList& playlists ); + void onAutoPlaylistsAdded( const QList& playlists ); + void onAutoPlaylistsDeleted( const QList& playlists ); + void onStationsAdded( const QList& stations ); + void onStationsDeleted( const QList& stations ); private: - Tomahawk::source_ptr m_source; + void playlistsAddedInternal( SourceTreeItem* parent, const QList< Tomahawk::dynplaylist_ptr >& playlists ); + template< typename T > + void playlistsDeletedInternal( SourceTreeItem* parent, const QList< T >& playlists ); + Tomahawk::source_ptr m_source; CategoryItem* m_playlists; CategoryItem* m_stations; }; @@ -171,24 +187,27 @@ private: Tomahawk::playlist_ptr m_playlist; }; -/* -class DynPlaylistItem : public PlaylistItem +// can be a station or an auto playlist +class DynamicPlaylistItem : public PlaylistItem { Q_OBJECT public: - DynPlaylistItem( SourcesModel* model, SourceTreeItem* parent, const Tomahawk::dynplaylist_ptr& pl ); + DynamicPlaylistItem( SourcesModel* model, SourceTreeItem* parent, const Tomahawk::dynplaylist_ptr& pl, int index = -1 ); + virtual ~DynamicPlaylistItem(); virtual QString text() const; - virtual Tomahawk::playlist_ptr playlist() const; -// Tomahawk::dynplaylist_ptr playlist() const; + Tomahawk::dynplaylist_ptr dynPlaylist() const; + virtual bool willAcceptDrag( const QMimeData* data ) const; virtual void activate(); private slots: void onDynamicPlaylistLoaded( Tomahawk::DynamicPlaylistRevision revision ); private: + void checkReparentHackNeeded( const DynamicPlaylistRevision& rev ); + Tomahawk::dynplaylist_ptr m_dynplaylist; -};*/ +}; // generic item that has some name, some text, and calls a certain slot when activated. badabing! class GenericPageItem : public SourceTreeItem diff --git a/src/sourcetree/sourcetreeview.cpp b/src/sourcetree/sourcetreeview.cpp index 5a3688894..b4d9ef18f 100644 --- a/src/sourcetree/sourcetreeview.cpp +++ b/src/sourcetree/sourcetreeview.cpp @@ -105,19 +105,6 @@ SourceTreeView::SourceTreeView( QWidget* parent ) // connect( selectionModel(), SIGNAL( selectionChanged( QItemSelection, QItemSelection ) ), SLOT( onSelectionChanged() ) ); hideOfflineSources(); - - connect( ViewManager::instance(), SIGNAL( playlistActivated( Tomahawk::playlist_ptr ) ), - SLOT( onPlaylistActivated( Tomahawk::playlist_ptr ) ) ); -// connect( PlaylistManager::instance(), SIGNAL( dynamicPlaylistActivated( Tomahawk::dynplaylist_ptr ) ), -// SLOT( onDynamicPlaylistActivated( Tomahawk::dynplaylist_ptr ) ) ); - connect( ViewManager::instance(), SIGNAL( collectionActivated( Tomahawk::collection_ptr ) ), - SLOT( onCollectionActivated( Tomahawk::collection_ptr ) ) ); - connect( ViewManager::instance(), SIGNAL( superCollectionActivated() ), - SLOT( onSuperCollectionActivated() ) ); - connect( ViewManager::instance(), SIGNAL( tempPageActivated() ), - SLOT( onTempPageActivated() ) ); - connect( ViewManager::instance(), SIGNAL( newPlaylistActivated() ), - SLOT( onNewPlaylistPageActivated() ) ); } @@ -133,7 +120,7 @@ SourceTreeView::setupMenus() bool readonly = true; SourcesModel::RowType type = ( SourcesModel::RowType )model()->data( m_contextMenuIndex, SourcesModel::SourceTreeItemTypeRole ).toInt(); - if ( type == SourcesModel::StaticPlaylist ) + if ( type == SourcesModel::StaticPlaylist || type == SourcesModel::AutomaticPlaylist || type == SourcesModel::Station ) { PlaylistItem* item = itemFromIndex< PlaylistItem >( m_contextMenuIndex ); @@ -166,65 +153,6 @@ SourceTreeView::hideOfflineSources() m_proxyModel->hideOfflineSources(); } - -void -SourceTreeView::onPlaylistActivated( const Tomahawk::playlist_ptr& playlist ) -{ -// QModelIndex idx = m_proxyModel->mapFromSource( m_model->indexFromPlaylist( playlist ) ); -// if ( idx.isValid() ) -// { -// selectionModel()->select( idx, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Current ); -// setCurrentIndex( idx ); -// } -} - -/* -void -SourceTreeView::onDynamicPlaylistActivated( const Tomahawk::dynplaylist_ptr& playlist ) -{ - QModelIndex idx = m_proxyModel->mapFromSource( m_model->dynamicPlaylistToIndex( playlist ) ); - if ( idx.isValid() ) - { - setCurrentIndex( idx ); - } -}*/ - - -void -SourceTreeView::onCollectionActivated( const Tomahawk::collection_ptr& collection ) -{ -// QModelIndex idx = m_proxyModel->mapFromSource( m_model->collectionToIndex( collection ) ); -// if ( idx.isValid() ) -// { -// setCurrentIndex( idx ); -// } -} - - -void -SourceTreeView::onSuperCollectionActivated() -{ -// QModelIndex idx = m_proxyModel->index( 0, 0 ); -// if ( idx.isValid() ) -// { -// setCurrentIndex( idx ); -// } -} - - -void -SourceTreeView::onTempPageActivated() -{ - clearSelection(); -} - -void -SourceTreeView::onNewPlaylistPageActivated() -{ - // nothing atm -} - - void SourceTreeView::onItemActivated( const QModelIndex& index ) { @@ -278,6 +206,11 @@ SourceTreeView::deletePlaylist() PlaylistItem* item = itemFromIndex< PlaylistItem >( m_contextMenuIndex ); playlist_ptr playlist = item->playlist(); Playlist::remove( playlist ); + } else if( type == SourcesModel::AutomaticPlaylist || type == SourcesModel::Station ) + { + DynamicPlaylistItem* item = itemFromIndex< DynamicPlaylistItem >( m_contextMenuIndex ); + dynplaylist_ptr playlist = item->dynPlaylist(); + DynamicPlaylist::remove( playlist ); } } @@ -300,7 +233,9 @@ SourceTreeView::onCustomContextMenu( const QPoint& pos ) setupMenus(); - if ( model()->data( m_contextMenuIndex, SourcesModel::SourceTreeItemTypeRole ) == SourcesModel::StaticPlaylist ) + if ( model()->data( m_contextMenuIndex, SourcesModel::SourceTreeItemTypeRole ) == SourcesModel::StaticPlaylist || + model()->data( m_contextMenuIndex, SourcesModel::SourceTreeItemTypeRole ) == SourcesModel::AutomaticPlaylist || + model()->data( m_contextMenuIndex, SourcesModel::SourceTreeItemTypeRole ) == SourcesModel::Station ) { PlaylistItem* item = itemFromIndex< PlaylistItem >( m_contextMenuIndex ); if( item->playlist()->author()->isLocal() ) diff --git a/src/sourcetree/sourcetreeview.h b/src/sourcetree/sourcetreeview.h index 9952ddfa1..83a5d5fc4 100644 --- a/src/sourcetree/sourcetreeview.h +++ b/src/sourcetree/sourcetreeview.h @@ -46,14 +46,6 @@ signals: void onOffline( const QModelIndex& index ); private slots: - void onPlaylistActivated( const Tomahawk::playlist_ptr& playlist ); -// void onDynamicPlaylistActivated( const Tomahawk::dynplaylist_ptr& playlist ); - - void onCollectionActivated( const Tomahawk::collection_ptr& collection ); - void onSuperCollectionActivated(); - void onTempPageActivated(); - void onNewPlaylistPageActivated(); - void onItemExpanded( const QModelIndex& idx ); void onItemActivated( const QModelIndex& index ); void selectRequest( const QModelIndex& idx ); diff --git a/src/tomahawkwindow.cpp b/src/tomahawkwindow.cpp index 1c7877d68..b4c95a7e2 100644 --- a/src/tomahawkwindow.cpp +++ b/src/tomahawkwindow.cpp @@ -400,7 +400,7 @@ TomahawkWindow::createAutomaticPlaylist() QString id = uuid(); QString info = ""; // FIXME QString creator = "someone"; // FIXME - dynplaylist_ptr playlist = DynamicPlaylist::create( author, id, name, info, creator, false ); + dynplaylist_ptr playlist = DynamicPlaylist::create( author, id, name, info, creator, Static, false ); playlist->setMode( Static ); playlist->createNewRevision( uuid(), playlist->currentrevision(), playlist->type(), playlist->generator()->controls(), playlist->entries() ); ViewManager::instance()->show( playlist ); @@ -419,7 +419,7 @@ TomahawkWindow::createStation() QString id = uuid(); QString info = ""; // FIXME QString creator = "someone"; // FIXME - dynplaylist_ptr playlist = DynamicPlaylist::create( author, id, name, info, creator, false ); + dynplaylist_ptr playlist = DynamicPlaylist::create( author, id, name, info, creator, OnDemand, false ); playlist->setMode( OnDemand ); playlist->createNewRevision( uuid(), playlist->currentrevision(), playlist->type(), playlist->generator()->controls() ); ViewManager::instance()->show( playlist );