diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index a838ccf4e..e5ec1cf04 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -67,6 +67,7 @@ set( libSources database/databasecommand_playbackhistory.cpp database/databasecommand_setplaylistrevision.cpp database/databasecommand_loadallplaylists.cpp + database/databasecommand_loadallsortedplaylists.cpp database/databasecommand_loadallsources.cpp database/databasecommand_createplaylist.cpp database/databasecommand_deleteplaylist.cpp @@ -180,7 +181,8 @@ set( libSources widgets/SeekSlider.cpp widgets/playlisttypeselectordlg.cpp widgets/welcomewidget.cpp - widgets/welcomeplaylistmodel.cpp + widgets/RecentlyPlayedPlaylistsModel.cpp + widgets/RecentPlaylistsModel.cpp widgets/overlaywidget.cpp widgets/HeaderLabel.cpp widgets/SocialPlaylistWidget.cpp @@ -248,6 +250,7 @@ set( libHeaders database/databasecommand_playbackhistory.h database/databasecommand_setplaylistrevision.h database/databasecommand_loadallplaylists.h + database/databasecommand_loadallsortedplaylists.h database/databasecommand_loadallsources.h database/databasecommand_createplaylist.h database/databasecommand_deleteplaylist.h @@ -360,7 +363,8 @@ set( libHeaders widgets/SeekSlider.h widgets/playlisttypeselectordlg.h widgets/welcomewidget.h - widgets/welcomeplaylistmodel.h + widgets/RecentlyPlayedPlaylistsModel.h + widgets/RecentPlaylistsModel.h widgets/overlaywidget.h widgets/HeaderLabel.h widgets/SocialPlaylistWidget.h diff --git a/src/libtomahawk/database/databasecommand_loadallautoplaylists.cpp b/src/libtomahawk/database/databasecommand_loadallautoplaylists.cpp index 4abbb4d94..3eda9d501 100644 --- a/src/libtomahawk/database/databasecommand_loadallautoplaylists.cpp +++ b/src/libtomahawk/database/databasecommand_loadallautoplaylists.cpp @@ -31,11 +31,31 @@ void DatabaseCommand_LoadAllAutoPlaylists::exec( DatabaseImpl* dbi ) { TomahawkSqlQuery query = dbi->newquery(); + QString orderToken, sourceToken; + + switch ( m_sortOrder ) + { + case 0: + break; + + case DatabaseCommand_LoadAllPlaylists::ModificationTime: + orderToken = "playlist.createdOn"; + } + + if ( !source().isNull() ) + sourceToken = QString( "AND source %1 " ).arg( source()->isLocal() ? "IS NULL" : QString( "= %1" ).arg( source()->id() ) ); + 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 AND dynamic_playlist.autoload = 'true'" ) - .arg( source()->isLocal() ? "IS NULL" : QString( "=%1" ).arg( source()->id() ) ) - .arg( Static ) ); + "FROM playlist, dynamic_playlist WHERE dynplaylist = 'true' AND playlist.guid = dynamic_playlist.guid AND dynamic_playlist.plmode = %1 AND dynamic_playlist.autoload = 'true' " + "%2" + "%3 %4 %5" + ) + .arg( Static ) + .arg( sourceToken ) + .arg( m_sortOrder > 0 ? QString( "ORDER BY %1" ).arg( orderToken ) : QString() ) + .arg( m_sortDescending ? "DESC" : QString() ) + .arg( m_limitAmount > 0 ? QString( "LIMIT 0, %1" ).arg( m_limitAmount ) : QString() ) ); QList plists; while ( query.next() ) diff --git a/src/libtomahawk/database/databasecommand_loadallautoplaylists.h b/src/libtomahawk/database/databasecommand_loadallautoplaylists.h index 0bf9cd5be..7d270bf97 100644 --- a/src/libtomahawk/database/databasecommand_loadallautoplaylists.h +++ b/src/libtomahawk/database/databasecommand_loadallautoplaylists.h @@ -24,6 +24,7 @@ #include "databasecommand.h" #include "typedefs.h" +#include "databasecommand_loadallplaylists.h" class DatabaseCommand_LoadAllAutoPlaylists : public DatabaseCommand { @@ -32,15 +33,27 @@ class DatabaseCommand_LoadAllAutoPlaylists : public DatabaseCommand public: explicit DatabaseCommand_LoadAllAutoPlaylists( const Tomahawk::source_ptr& s, QObject* parent = 0 ) : DatabaseCommand( s, parent ) + , m_limitAmount( 0 ) + , m_sortOrder( DatabaseCommand_LoadAllPlaylists::None ) + , m_sortDescending( false ) {} virtual void exec( DatabaseImpl* ); virtual bool doesMutates() const { return false; } virtual QString commandname() const { return "loadallautoplaylists"; } + void setLimit( unsigned int limit ) { m_limitAmount = limit; } + void setSortOrder( DatabaseCommand_LoadAllPlaylists::SortOrder order ) { m_sortOrder = order; } + void setSortDescending( bool descending ) { m_sortDescending = descending; } + signals: void autoPlaylistLoaded( const Tomahawk::source_ptr& source, const QVariantList& data ); void done(); + +private: + unsigned int m_limitAmount; + DatabaseCommand_LoadAllPlaylists::SortOrder m_sortOrder; + bool m_sortDescending; }; #endif diff --git a/src/libtomahawk/database/databasecommand_loadallplaylists.cpp b/src/libtomahawk/database/databasecommand_loadallplaylists.cpp index 9ed6ddea3..b338f3444 100644 --- a/src/libtomahawk/database/databasecommand_loadallplaylists.cpp +++ b/src/libtomahawk/database/databasecommand_loadallplaylists.cpp @@ -1,6 +1,7 @@ /* === This file is part of Tomahawk Player - === * * Copyright 2010-2011, Christian Muehlhaeuser + * Copyright 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 @@ -31,12 +32,31 @@ void DatabaseCommand_LoadAllPlaylists::exec( DatabaseImpl* dbi ) { TomahawkSqlQuery query = dbi->newquery(); + QString orderToken, sourceToken; + + switch ( m_sortOrder ) + { + case 0: + break; + + case ModificationTime: + orderToken = "playlist.createdOn"; + } + + if ( !source().isNull() ) + sourceToken = QString( "AND source %1 " ).arg( source()->isLocal() ? "IS NULL" : QString( "= %1" ).arg( source()->id() ) ); + query.exec( QString( "SELECT guid, title, info, creator, lastmodified, shared, currentrevision, createdOn " - "FROM playlist WHERE source %1 AND dynplaylist = 'false'" ) - .arg( source()->isLocal() ? "IS NULL" : - QString( "= %1" ).arg( source()->id() ) - ) ); + "FROM playlist " + "WHERE dynplaylist = 'false' " + "%1 " + "%2 %3 %4" + ) + .arg( sourceToken ) + .arg( m_sortOrder > 0 ? QString( "ORDER BY %1" ).arg( orderToken ) : QString() ) + .arg( m_sortDescending ? "DESC" : QString() ) + .arg( m_limitAmount > 0 ? QString( "LIMIT 0, %1" ).arg( m_limitAmount ) : QString() ) ); QList plists; while ( query.next() ) diff --git a/src/libtomahawk/database/databasecommand_loadallplaylists.h b/src/libtomahawk/database/databasecommand_loadallplaylists.h index 4a2c6f66d..831a54044 100644 --- a/src/libtomahawk/database/databasecommand_loadallplaylists.h +++ b/src/libtomahawk/database/databasecommand_loadallplaylists.h @@ -1,6 +1,7 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser + * Copyright 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 @@ -29,19 +30,41 @@ class DLLEXPORT DatabaseCommand_LoadAllPlaylists : public DatabaseCommand { -Q_OBJECT + Q_OBJECT public: + enum SortOrder { + None = 0, + ModificationTime = 1 + }; + enum SortAscDesc { + NoOrder = 0, + Ascending = 1, + Descending = 2 + }; + explicit DatabaseCommand_LoadAllPlaylists( const Tomahawk::source_ptr& s, QObject* parent = 0 ) : DatabaseCommand( s, parent ) + , m_limitAmount( 0 ) + , m_sortOrder( None ) + , m_sortDescending( false ) {} virtual void exec( DatabaseImpl* ); virtual bool doesMutates() const { return false; } virtual QString commandname() const { return "loadallplaylists"; } + void setLimit( unsigned int limit ) { m_limitAmount = limit; } + void setSortOrder( SortOrder order ) { m_sortOrder = order; } + void setSortDescending( bool descending ) { m_sortDescending = descending; } + signals: void done( const QList& playlists ); + +private: + unsigned int m_limitAmount; + SortOrder m_sortOrder; + bool m_sortDescending; }; #endif // DATABASECOMMAND_LOADALLPLAYLIST_H diff --git a/src/libtomahawk/database/databasecommand_loadallsortedplaylists.cpp b/src/libtomahawk/database/databasecommand_loadallsortedplaylists.cpp new file mode 100644 index 000000000..3b0ae5e77 --- /dev/null +++ b/src/libtomahawk/database/databasecommand_loadallsortedplaylists.cpp @@ -0,0 +1,108 @@ +/* === 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_loadallsortedplaylists.h" +#include "databaseimpl.h" + +#include "playlist.h" +#include + +using namespace Tomahawk; + +void +DatabaseCommand_LoadAllSortedPlaylists::exec( DatabaseImpl* dbi ) +{ + TomahawkSqlQuery query = dbi->newquery(); + QString orderToken, sourceToken, ascDescToken; + + switch ( m_sortOrder ) + { + case 0: + break; + + case DatabaseCommand_LoadAllPlaylists::ModificationTime: + orderToken = "playlist.createdOn"; + } + + switch ( m_sortAscDesc ) + { + case DatabaseCommand_LoadAllPlaylists::NoOrder: + break; + case DatabaseCommand_LoadAllPlaylists::Ascending: + ascDescToken = "ASC"; + break; + case DatabaseCommand_LoadAllPlaylists::Descending: + ascDescToken = "DESC"; + break; + } + + if ( !source().isNull() ) + sourceToken = QString( "AND source %1 " ).arg( source()->isLocal() ? "IS NULL" : QString( "= %1" ).arg( source()->id() ) ); + + + query.exec( QString( "SELECT playlist.guid as guid, title, info, creator, lastmodified, shared, currentrevision, createdOn, dynplaylist, source, dynamic_playlist.pltype, dynamic_playlist.plmode " + "FROM playlist " + "LEFT JOIN dynamic_playlist ON playlist.guid = dynamic_playlist.guid " + "%1 " + "%2 %3 %4" + ) + .arg( sourceToken ) + .arg( m_sortOrder > 0 ? QString( "ORDER BY %1" ).arg( orderToken ) : QString() ) + .arg( ascDescToken ) + .arg( m_limitAmount > 0 ? QString( "LIMIT 0, %1" ).arg( m_limitAmount ) : QString() ) ); + + QList plists; + while ( query.next() ) + { + plists << QPair< int, QString >( query.value(9).toInt(), query.value(0).toString() ); +// playlist_ptr p; +// bool dynamic = query.value(8).toBool(); +// source_ptr s = SourceList::instance()->get( query.value(9).toInt() ); +// +// if ( dynamic ) +// { +// p = dynplaylist_ptr( new DynamicPlaylist( s, +// query.value(6).toString(), //current rev +// query.value(1).toString(), //title +// query.value(2).toString(), //info +// query.value(3).toString(), //creator +// query.value(7).toInt(), //createdOn +// query.value(10).toString(), //type +// (GeneratorMode)query.value(11).toInt(), // mode +// query.value(5).toBool(), //shared +// query.value(4).toInt(), //lastmod +// query.value(0).toString() //GUID +// ) ); +// } else +// { +// p = playlist_ptr( new Playlist( s, //src +// query.value(6).toString(), //current rev +// query.value(1).toString(), //title +// query.value(2).toString(), //info +// query.value(3).toString(), //creator +// query.value(7).toInt(), //createdOn +// query.value(5).toBool(), //shared +// query.value(4).toInt(), //lastmod +// query.value(0).toString() //GUID +// ) ); +// } +// plists.append( p ); + } + + emit done( plists ); +} diff --git a/src/libtomahawk/database/databasecommand_loadallsortedplaylists.h b/src/libtomahawk/database/databasecommand_loadallsortedplaylists.h new file mode 100644 index 000000000..ed82e487e --- /dev/null +++ b/src/libtomahawk/database/databasecommand_loadallsortedplaylists.h @@ -0,0 +1,65 @@ +/* === 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_LOADALLSORTEDPLAYLISTS_H +#define DATABASECOMMAND_LOADALLSORTEDPLAYLISTS_H + +#include "libtomahawk/database/databasecommand.h" +#include "databasecommand_loadallplaylists.h" + +/** + * Loads *all* playlists, automatic playlists, and stations. Another dbcmd because otherwise loading them all + * is fragmented across 3 dbcmds with a different interface. + * + * You probably want to limit / sort the output. + */ +class DatabaseCommand_LoadAllSortedPlaylists : public DatabaseCommand +{ + Q_OBJECT + +public: + // don't macros rock... not + typedef QPair SourcePlaylistPair; + explicit DatabaseCommand_LoadAllSortedPlaylists( const Tomahawk::source_ptr& s, QObject* parent = 0 ) + : DatabaseCommand( s, parent ) + , m_limitAmount( 0 ) + , m_sortOrder( DatabaseCommand_LoadAllPlaylists::None ) + , m_sortAscDesc( DatabaseCommand_LoadAllPlaylists::NoOrder ) + { + qRegisterMetaType >("QList"); + } + + virtual void exec( DatabaseImpl* ); + virtual bool doesMutates() const { return false; } + virtual QString commandname() const { return "loadallsortedplaylists"; } + + void setLimit( unsigned int limit ) { m_limitAmount = limit; } + void setSortOrder( DatabaseCommand_LoadAllPlaylists::SortOrder order ) { m_sortOrder = order; } + void setSortAscDesc( DatabaseCommand_LoadAllPlaylists::SortAscDesc asc ) { m_sortAscDesc = asc; } + +signals: + void done( const QList& playlistGuids ); // QPair< sourceid, playlistguid> + +private: + unsigned int m_limitAmount; + DatabaseCommand_LoadAllPlaylists::SortOrder m_sortOrder; + DatabaseCommand_LoadAllPlaylists::SortAscDesc m_sortAscDesc; +}; + +Q_DECLARE_METATYPE(QList) +#endif // DATABASECOMMAND_LOADALLSORTEDPLAYLISTS_H diff --git a/src/libtomahawk/database/databasecommand_loadallstations.cpp b/src/libtomahawk/database/databasecommand_loadallstations.cpp index 90edeeb16..2d627dc66 100644 --- a/src/libtomahawk/database/databasecommand_loadallstations.cpp +++ b/src/libtomahawk/database/databasecommand_loadallstations.cpp @@ -31,11 +31,32 @@ void DatabaseCommand_LoadAllStations::exec( DatabaseImpl* dbi ) { TomahawkSqlQuery query = dbi->newquery(); + QString orderToken, sourceToken; + + switch ( m_sortOrder ) + { + case 0: + break; + + case DatabaseCommand_LoadAllPlaylists::ModificationTime: + orderToken = "playlist.createdOn"; + } + + if ( !source().isNull() ) + sourceToken = QString( "AND source %1 " ).arg( source()->isLocal() ? "IS NULL" : QString( "= %1" ).arg( source()->id() ) ); + 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 AND dynamic_playlist.autoload = 'true'" ) - .arg( source()->isLocal() ? "IS NULL" : QString( "=%1" ).arg( source()->id() ) ) - .arg( OnDemand ) ); + "FROM playlist, dynamic_playlist WHERE " + "dynplaylist = 'true' AND playlist.guid = dynamic_playlist.guid AND dynamic_playlist.plmode = %1 AND dynamic_playlist.autoload = 'true' " + "%2" + "%3 %4 %5" + ) + .arg( OnDemand ) + .arg( sourceToken ) + .arg( m_sortOrder > 0 ? QString( "ORDER BY %1" ).arg( orderToken ) : QString() ) + .arg( m_sortDescending ? "DESC" : QString() ) + .arg( m_limitAmount > 0 ? QString( "LIMIT 0, %1" ).arg( m_limitAmount ) : QString() ) ); QList plists; while ( query.next() ) diff --git a/src/libtomahawk/database/databasecommand_loadallstations.h b/src/libtomahawk/database/databasecommand_loadallstations.h index 1e838d9c7..fe16ac7cc 100644 --- a/src/libtomahawk/database/databasecommand_loadallstations.h +++ b/src/libtomahawk/database/databasecommand_loadallstations.h @@ -24,6 +24,7 @@ #include "databasecommand.h" #include "typedefs.h" +#include "databasecommand_loadallplaylists.h" class DatabaseCommand_LoadAllStations : public DatabaseCommand { @@ -32,15 +33,27 @@ class DatabaseCommand_LoadAllStations : public DatabaseCommand public: explicit DatabaseCommand_LoadAllStations( const Tomahawk::source_ptr& s, QObject* parent = 0 ) : DatabaseCommand( s, parent ) + , m_limitAmount( 0 ) + , m_sortOrder( DatabaseCommand_LoadAllPlaylists::None ) + , m_sortDescending( false ) {} virtual void exec( DatabaseImpl* ); virtual bool doesMutates() const { return false; } virtual QString commandname() const { return "loadallstations"; } + void setLimit( unsigned int limit ) { m_limitAmount = limit; } + void setSortOrder( DatabaseCommand_LoadAllPlaylists::SortOrder order ) { m_sortOrder = order; } + void setSortDescending( bool descending ) { m_sortDescending = descending; } + signals: void stationLoaded( const Tomahawk::source_ptr& source, const QVariantList& data ); void done(); + +private: + unsigned int m_limitAmount; + DatabaseCommand_LoadAllPlaylists::SortOrder m_sortOrder; + bool m_sortDescending; }; #endif \ No newline at end of file diff --git a/src/libtomahawk/playlist.h b/src/libtomahawk/playlist.h index 7df3a942c..e97da070b 100644 --- a/src/libtomahawk/playlist.h +++ b/src/libtomahawk/playlist.h @@ -33,6 +33,7 @@ #include class DatabaseCommand_LoadAllPlaylists; +class DatabaseCommand_LoadAllSortedPlaylists; class DatabaseCommand_SetPlaylistRevision; class DatabaseCommand_CreatePlaylist; @@ -124,6 +125,7 @@ Q_PROPERTY( unsigned int createdon READ createdOn WRITE setCreatedOn ) Q_PROPERTY( bool shared READ shared WRITE setShared ) friend class ::DatabaseCommand_LoadAllPlaylists; +friend class ::DatabaseCommand_LoadAllSortedPlaylists; friend class ::DatabaseCommand_SetPlaylistRevision; friend class ::DatabaseCommand_CreatePlaylist; friend class DynamicPlaylist; diff --git a/src/libtomahawk/playlist/dynamic/DynamicPlaylist.h b/src/libtomahawk/playlist/dynamic/DynamicPlaylist.h index 35ed57ed9..655bef6f8 100644 --- a/src/libtomahawk/playlist/dynamic/DynamicPlaylist.h +++ b/src/libtomahawk/playlist/dynamic/DynamicPlaylist.h @@ -26,12 +26,14 @@ #include "playlist.h" #include "typedefs.h" #include "playlist/dynamic/DynamicControl.h" +#include "playlist/dynamic/DynamicPlaylistRevision.h" #include "dllmacro.h" class DatabaseCommand_LoadAllDynamicPlaylists; class DatabaseCommand_SetDynamicPlaylistRevision; class DatabaseCommand_CreateDynamicPlaylist; +class DatabaseCommand_LoadAllSortedPlaylists; class DatabaseCollection; namespace Tomahawk { @@ -43,27 +45,6 @@ class DatabaseCommand_LoadDynamicPlaylist; * It uses normal PlaylistEntries but also has a mode, a generator, and a list of controls */ -struct DLLEXPORT DynamicPlaylistRevision : PlaylistRevision -{ -public: - - QList< dyncontrol_ptr > controls; - Tomahawk::GeneratorMode mode; - QString type; - - DynamicPlaylistRevision( const PlaylistRevision& other ) - { - revisionguid = other.revisionguid; - oldrevisionguid = other.oldrevisionguid; - newlist = other.newlist; - added = other.added; - removed = other.removed; - applied = other.applied; - } - - DynamicPlaylistRevision() {} -}; - struct DynQueueItem : RevisionQueueItem { QString type; @@ -86,6 +67,7 @@ class DLLEXPORT DynamicPlaylist : public Playlist friend class ::DatabaseCommand_SetDynamicPlaylistRevision; friend class ::DatabaseCommand_CreateDynamicPlaylist; friend class Tomahawk::DatabaseCommand_LoadDynamicPlaylist; + friend class ::DatabaseCommand_LoadAllSortedPlaylists; friend class ::DatabaseCollection; /// :-( public: diff --git a/src/libtomahawk/playlist/dynamic/DynamicPlaylistRevision.h b/src/libtomahawk/playlist/dynamic/DynamicPlaylistRevision.h new file mode 100644 index 000000000..da89dc29e --- /dev/null +++ b/src/libtomahawk/playlist/dynamic/DynamicPlaylistRevision.h @@ -0,0 +1,51 @@ +/* === 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 DYNAMIC_PLAYLIST_REVISION_H +#define DYNAMIC_PLAYLIST_REVISION_H + +#include "playlist.h" +#include "dllmacro.h" + +namespace Tomahawk +{ + +struct DLLEXPORT DynamicPlaylistRevision : PlaylistRevision +{ +public: + + QList< dyncontrol_ptr > controls; + Tomahawk::GeneratorMode mode; + QString type; + + DynamicPlaylistRevision( const PlaylistRevision& other ) + { + revisionguid = other.revisionguid; + oldrevisionguid = other.oldrevisionguid; + newlist = other.newlist; + added = other.added; + removed = other.removed; + applied = other.applied; + } + + DynamicPlaylistRevision() {} +}; + +} + +#endif diff --git a/src/libtomahawk/playlist/dynamic/echonest/EchonestGenerator.cpp b/src/libtomahawk/playlist/dynamic/echonest/EchonestGenerator.cpp index 2b72fce03..4fa8eab12 100644 --- a/src/libtomahawk/playlist/dynamic/echonest/EchonestGenerator.cpp +++ b/src/libtomahawk/playlist/dynamic/echonest/EchonestGenerator.cpp @@ -524,12 +524,10 @@ EchonestGenerator::sentenceSummary() suffix = ", "; sentence += prefix + allcontrols.value( i ).dynamicCast< EchonestControl >()->summary() + suffix; } - qDebug() << "Got artists and contents:" << sentence; if( !sorting.isNull() ) { sentence += "and " + sorting.dynamicCast< EchonestControl >()->summary() + "."; } - qDebug() << "Got full summary:" << sentence; return sentence; } diff --git a/src/libtomahawk/playlist/dynamic/widgets/DynamicWidget.cpp b/src/libtomahawk/playlist/dynamic/widgets/DynamicWidget.cpp index 8da3b345a..5e1b4e0fa 100644 --- a/src/libtomahawk/playlist/dynamic/widgets/DynamicWidget.cpp +++ b/src/libtomahawk/playlist/dynamic/widgets/DynamicWidget.cpp @@ -105,6 +105,12 @@ DynamicWidget::~DynamicWidget() { } +dynplaylist_ptr +DynamicWidget::playlist() +{ + return m_playlist; +} + void DynamicWidget::loadDynamicPlaylist( const Tomahawk::dynplaylist_ptr& playlist ) @@ -427,6 +433,17 @@ DynamicWidget::paintRoundedFilledRect( QPainter& p, QPalette& /* pal */, QRect& p.drawRoundedRect( r, 10, 10 ); } +QString +DynamicWidget::description() const +{ + return m_model->description(); +} + +QString +DynamicWidget::title() const +{ + return m_model->title(); +} QPixmap DynamicWidget::pixmap() const diff --git a/src/libtomahawk/playlist/dynamic/widgets/DynamicWidget.h b/src/libtomahawk/playlist/dynamic/widgets/DynamicWidget.h index 26f61baae..26b0a43a6 100644 --- a/src/libtomahawk/playlist/dynamic/widgets/DynamicWidget.h +++ b/src/libtomahawk/playlist/dynamic/widgets/DynamicWidget.h @@ -23,10 +23,7 @@ #include "typedefs.h" #include "viewpage.h" - -#include "dynamic/DynamicPlaylist.h" -#include "dynamic/DynamicControl.h" -#include "dynamic/DynamicModel.h" +#include "playlist/dynamic/DynamicPlaylistRevision.h" class LoadingSpinner; class QShowEvent; @@ -45,10 +42,10 @@ class ReadOrWriteWidget; namespace Tomahawk { +class DynamicModel; + class DynamicSetupWidget; - class DynamicView; - class CollapsibleControls; @@ -63,7 +60,7 @@ public: virtual ~DynamicWidget(); void loadDynamicPlaylist( const dynplaylist_ptr& playlist ); - dynplaylist_ptr playlist() { return m_playlist; } + dynplaylist_ptr playlist(); virtual PlaylistInterface* playlistInterface() const; @@ -75,8 +72,8 @@ public: virtual QWidget* widget() { return this; } - virtual QString title() const { return m_model->title(); } - virtual QString description() const { return m_model->description(); } + virtual QString title() const; + virtual QString description() const; virtual QPixmap pixmap() const; virtual bool jumpToCurrentTrack(); diff --git a/src/libtomahawk/viewmanager.cpp b/src/libtomahawk/viewmanager.cpp index 033ad86ec..77a48dcd1 100644 --- a/src/libtomahawk/viewmanager.cpp +++ b/src/libtomahawk/viewmanager.cpp @@ -168,6 +168,19 @@ ViewManager::createPageForPlaylist( const playlist_ptr& pl ) return view; } +playlist_ptr +ViewManager::playlistForPage( ViewPage* page ) const +{ + playlist_ptr p; + if ( dynamic_cast< PlaylistView* >( page ) && dynamic_cast< PlaylistView* >( page )->playlistModel() && + !dynamic_cast< PlaylistView* >( page )->playlistModel()->playlist().isNull() ) + p = dynamic_cast< PlaylistView* >( page )->playlistModel()->playlist(); + else if ( dynamic_cast< DynamicWidget* >( page ) ) + p = dynamic_cast< DynamicWidget* >( page )->playlist(); + + return p; +} + Tomahawk::ViewPage* ViewManager::show( const Tomahawk::playlist_ptr& playlist ) diff --git a/src/libtomahawk/viewmanager.h b/src/libtomahawk/viewmanager.h index 8fd2320d4..9fcbc5a26 100644 --- a/src/libtomahawk/viewmanager.h +++ b/src/libtomahawk/viewmanager.h @@ -89,6 +89,10 @@ public: Tomahawk::ViewPage* pageForDynPlaylist( const Tomahawk::dynplaylist_ptr& pl ) const; Tomahawk::ViewPage* pageForCollection( const Tomahawk::collection_ptr& pl ) const; + /// Get a playlist (or dynamic playlist ) from a ViewPage* if the page is PlaylistView or DynamicWidget. + /// Lives here but used by SourcesModel + Tomahawk::playlist_ptr playlistForPage( Tomahawk::ViewPage* ) const; + // only use this is you need to create a playlist and show it directly and want it to be // linked to the sidebar. call it right after creating the playlist PlaylistView* createPageForPlaylist( const Tomahawk::playlist_ptr& pl ); diff --git a/src/libtomahawk/widgets/RecentPlaylistsModel.cpp b/src/libtomahawk/widgets/RecentPlaylistsModel.cpp new file mode 100644 index 000000000..919f7bce3 --- /dev/null +++ b/src/libtomahawk/widgets/RecentPlaylistsModel.cpp @@ -0,0 +1,243 @@ +/* + Copyright (C) 2011 Leo Franchi + + This program 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 2 of the License, or + (at your option) any later version. + + This program 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 this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + + +#include "RecentPlaylistsModel.h" + +#include "tomahawksettings.h" +#include "audio/audioengine.h" +#include "sourcelist.h" +#include "utils/logger.h" +#include "dynamic/DynamicPlaylist.h" +#include "database/database.h" +#include "database/databasecommand_loadallsortedplaylists.h" +#include "RecentlyPlayedPlaylistsModel.h" +#include + +using namespace Tomahawk; + + +RecentPlaylistsModel::RecentPlaylistsModel( unsigned int maxPlaylists, QObject* parent ) + : QAbstractListModel( parent ) + , m_maxPlaylists( maxPlaylists ) +{ + + if ( Servent::instance()->isReady() ) + onReady(); + else + connect( Servent::instance(), SIGNAL( ready() ), this, SLOT( onReady() ) ); + + // Load recent playlists initially + refresh(); +} + +void +RecentPlaylistsModel::refresh() +{ + DatabaseCommand_LoadAllSortedPlaylists* cmd = new DatabaseCommand_LoadAllSortedPlaylists( source_ptr() ); + cmd->setLimit( 15 ); + cmd->setSortOrder( DatabaseCommand_LoadAllPlaylists::ModificationTime ); + cmd->setSortAscDesc( DatabaseCommand_LoadAllPlaylists::Descending ); + connect( cmd, SIGNAL( done( QList ) ), this, SLOT( playlistsLoaded( QList ) ) ); + Database::instance()->enqueue( QSharedPointer< DatabaseCommand >( cmd ) ); +} + +void +RecentPlaylistsModel::onReady() +{ + foreach( const source_ptr& s, SourceList::instance()->sources() ) + onSourceAdded( s ); + + connect( SourceList::instance(), SIGNAL( sourceAdded( Tomahawk::source_ptr ) ), this, SLOT( onSourceAdded( Tomahawk::source_ptr ) ), Qt::QueuedConnection ); + refresh(); +} + + +void +RecentPlaylistsModel::playlistsLoaded ( const QList& playlistGuids ) +{ + beginResetModel(); + m_playlists.clear(); + + DatabaseCommand_LoadAllSortedPlaylists::SourcePlaylistPair plPair; + foreach ( plPair, playlistGuids ) + { + source_ptr s = SourceList::instance()->get( plPair.first ); + if ( s.isNull() ) + continue; + + if ( plPair.first == 0 ) + s = SourceList::instance()->getLocal(); + + playlist_ptr pl = s->collection()->playlist( plPair.second ); + if ( pl.isNull() ) + pl = s->collection()->autoPlaylist( plPair.second ); + if ( pl.isNull() ) + pl = s->collection()->station( plPair.second ); + + if ( pl.isNull() ) + { + qDebug() << "Found a playlist that is NOT LOADED FOR ANY SOURCE:" << plPair.first << plPair.second; + continue; + } + connect( pl.data(), SIGNAL( changed() ), this, SLOT( updatePlaylist() ) ); + m_playlists << pl; + } + + endResetModel(); +} + + +QVariant +RecentPlaylistsModel::data( const QModelIndex& index, int role ) const +{ + if( !index.isValid() || !hasIndex( index.row(), index.column(), index.parent() ) ) + return QVariant(); + + playlist_ptr pl = m_playlists[index.row()]; + switch( role ) + { + case Qt::DisplayRole: + return pl->title(); + case RecentlyPlayedPlaylistsModel::PlaylistRole: + return QVariant::fromValue< Tomahawk::playlist_ptr >( pl ); + case RecentlyPlayedPlaylistsModel::ArtistRole: + { + if( m_artists.value( pl ).isEmpty() ) + { + QStringList artists; + + foreach( const Tomahawk::plentry_ptr& entry, pl->entries() ) + { + if ( !artists.contains( entry->query()->artist() ) ) + artists << entry->query()->artist(); + } + + m_artists[pl] = artists.join( ", " ); + } + + return m_artists[pl]; + } + case RecentlyPlayedPlaylistsModel::PlaylistTypeRole: + { + if ( !pl.dynamicCast< Tomahawk::DynamicPlaylist >().isNull() ) + { + dynplaylist_ptr dynp = pl.dynamicCast< Tomahawk::DynamicPlaylist >(); + if ( dynp->mode() == Static ) + return RecentlyPlayedPlaylistsModel::AutoPlaylist; + else if ( dynp->mode() == OnDemand ) + return RecentlyPlayedPlaylistsModel::Station; + } else + { + return RecentlyPlayedPlaylistsModel::StaticPlaylist; + } + } + case RecentlyPlayedPlaylistsModel::DynamicPlaylistRole: + { + dynplaylist_ptr dynp = pl.dynamicCast< Tomahawk::DynamicPlaylist >(); + return QVariant::fromValue< Tomahawk::dynplaylist_ptr >( dynp ); + } + case RecentlyPlayedPlaylistsModel::TrackCountRole: + { + if ( !pl.dynamicCast< Tomahawk::DynamicPlaylist >().isNull() && pl.dynamicCast< Tomahawk::DynamicPlaylist >()->mode() == OnDemand ) + return QString( QChar( 0x221E ) ); + else + return pl->entries().count(); + } + default: + return QVariant(); + } +} + +void +RecentPlaylistsModel::updatePlaylist() +{ + Playlist* p = qobject_cast< Playlist* >( sender() ); + Q_ASSERT( p ); + + for ( int i = 0; i < m_playlists.size(); i++ ) + { + if ( m_playlists[ i ]->guid() == p->guid() ) + { + QModelIndex idx = index( i, 0, QModelIndex() ); + emit dataChanged( idx, idx ); + } + } +} + +void +RecentPlaylistsModel::onSourceAdded( const Tomahawk::source_ptr& source ) +{ + connect( source.data(), SIGNAL( online() ), this, SLOT( sourceOnline() ) ); + connect( source->collection().data(), SIGNAL( playlistsAdded( QList ) ), SLOT( refresh() ), Qt::QueuedConnection ); + connect( source->collection().data(), SIGNAL( autoPlaylistsAdded(QList)), SLOT( refresh() ), Qt::QueuedConnection ); + connect( source->collection().data(), SIGNAL( stationsAdded(QList)), SLOT( refresh() ), Qt::QueuedConnection ); + connect( source->collection().data(), SIGNAL( playlistsDeleted( QList ) ), SLOT( onPlaylistsRemoved( QList ) ) ); + connect( source->collection().data(), SIGNAL( autoPlaylistsDeleted(QList) ), SLOT( onDynPlaylistsRemoved( QList ) ) ); + connect( source->collection().data(), SIGNAL( stationsDeleted(QList) ), SLOT( onDynPlaylistsRemoved( QList ) ) ); +} + +void +RecentPlaylistsModel::sourceOnline() +{ + Source* s = qobject_cast< Source* >( sender() ); + Q_ASSERT( s ); + + for ( int i = 0; i < m_playlists.size(); i++ ) + { + if ( m_playlists[ i ]->author().data() == s ) + { + QModelIndex idx = index( i, 0, QModelIndex() ); + emit dataChanged( idx, idx ); + } + } +} + +void +RecentPlaylistsModel::onDynPlaylistsRemoved( QList< dynplaylist_ptr > playlists ) +{ + QList< playlist_ptr > pls; + foreach( const dynplaylist_ptr& p, playlists ) + pls << p; + onPlaylistsRemoved( pls ); +} + + +void +RecentPlaylistsModel::onPlaylistsRemoved( QList< playlist_ptr > playlists ) +{ + foreach( const playlist_ptr& pl, playlists ) { + if( m_playlists.contains( pl ) ) { + m_artists.remove( pl ); + + int idx = m_playlists.indexOf( pl ); + beginRemoveRows( QModelIndex(), idx, idx ); + m_playlists.removeAt( idx ); + endRemoveRows(); + } + } + + emit emptinessChanged( m_playlists.isEmpty() ); +} + + +int +RecentPlaylistsModel::rowCount( const QModelIndex& ) const +{ + return m_playlists.count(); +} diff --git a/src/libtomahawk/widgets/RecentPlaylistsModel.h b/src/libtomahawk/widgets/RecentPlaylistsModel.h new file mode 100644 index 000000000..7aea0e896 --- /dev/null +++ b/src/libtomahawk/widgets/RecentPlaylistsModel.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2011 Leo Franchi + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + + +#ifndef RECENTLPLAYLISTSMODEL_H +#define RECENTLPLAYLISTSMODEL_H + +#include + +#include "playlist.h" +#include "database/databasecommand_loadallsortedplaylists.h" + +class RecentPlaylistsModel : public QAbstractListModel +{ + Q_OBJECT +public: + explicit RecentPlaylistsModel( unsigned int maxPlaylists, QObject* parent = 0 ); + + virtual QVariant data( const QModelIndex& index, int role = Qt::DisplayRole ) const; + virtual int rowCount( const QModelIndex& parent = QModelIndex() ) const; + +public slots: + void refresh(); + void onReady(); + +signals: + void emptinessChanged( bool isEmpty ); + +private slots: + void playlistsLoaded( const QList& playlistGuids ); + + void onPlaylistsRemoved( QList< Tomahawk::playlist_ptr > playlists ); + void onDynPlaylistsRemoved( QList< Tomahawk::dynplaylist_ptr > playlists ); + void updatePlaylist(); + + void sourceOnline(); + void onSourceAdded( const Tomahawk::source_ptr& source ); +private: + QList< Tomahawk::playlist_ptr > m_playlists; + mutable QHash< Tomahawk::playlist_ptr, QString > m_artists; + unsigned int m_maxPlaylists; +}; + +#endif // RECENTLPLAYLISTSMODEL_H diff --git a/src/libtomahawk/widgets/welcomeplaylistmodel.cpp b/src/libtomahawk/widgets/RecentlyPlayedPlaylistsModel.cpp similarity index 90% rename from src/libtomahawk/widgets/welcomeplaylistmodel.cpp rename to src/libtomahawk/widgets/RecentlyPlayedPlaylistsModel.cpp index 618354562..f1f5147e3 100644 --- a/src/libtomahawk/widgets/welcomeplaylistmodel.cpp +++ b/src/libtomahawk/widgets/RecentlyPlayedPlaylistsModel.cpp @@ -17,7 +17,7 @@ */ -#include "welcomeplaylistmodel.h" +#include "RecentlyPlayedPlaylistsModel.h" #include "tomahawksettings.h" #include "audio/audioengine.h" @@ -28,7 +28,7 @@ using namespace Tomahawk; -WelcomePlaylistModel::WelcomePlaylistModel( QObject* parent ) +RecentlyPlayedPlaylistsModel::RecentlyPlayedPlaylistsModel( QObject* parent ) : QAbstractListModel( parent ) , m_maxPlaylists( 0 ) , m_waitingForSome( true ) @@ -44,7 +44,7 @@ WelcomePlaylistModel::WelcomePlaylistModel( QObject* parent ) void -WelcomePlaylistModel::loadFromSettings() +RecentlyPlayedPlaylistsModel::loadFromSettings() { // qDebug() << Q_FUNC_INFO; if( !m_waitingForSome ) @@ -87,7 +87,7 @@ WelcomePlaylistModel::loadFromSettings() QVariant -WelcomePlaylistModel::data( const QModelIndex& index, int role ) const +RecentlyPlayedPlaylistsModel::data( const QModelIndex& index, int role ) const { if( !index.isValid() || !hasIndex( index.row(), index.column(), index.parent() ) ) return QVariant(); @@ -148,7 +148,7 @@ WelcomePlaylistModel::data( const QModelIndex& index, int role ) const } void -WelcomePlaylistModel::playlistRevisionLoaded() +RecentlyPlayedPlaylistsModel::playlistRevisionLoaded() { Playlist* p = qobject_cast< Playlist* >( sender() ); Q_ASSERT( p ); @@ -165,7 +165,7 @@ WelcomePlaylistModel::playlistRevisionLoaded() void -WelcomePlaylistModel::onSourceAdded( const Tomahawk::source_ptr& source ) +RecentlyPlayedPlaylistsModel::onSourceAdded( const Tomahawk::source_ptr& source ) { connect( source.data(), SIGNAL( online() ), this, SLOT( sourceOnline() ) ); connect( source->collection().data(), SIGNAL( playlistsAdded( QList ) ), SLOT( loadFromSettings() ) ); @@ -173,7 +173,7 @@ WelcomePlaylistModel::onSourceAdded( const Tomahawk::source_ptr& source ) } void -WelcomePlaylistModel::sourceOnline() +RecentlyPlayedPlaylistsModel::sourceOnline() { Source* s = qobject_cast< Source* >( sender() ); Q_ASSERT( s ); @@ -190,7 +190,7 @@ WelcomePlaylistModel::sourceOnline() void -WelcomePlaylistModel::onPlaylistsRemoved( QList< playlist_ptr > playlists ) +RecentlyPlayedPlaylistsModel::onPlaylistsRemoved( QList< playlist_ptr > playlists ) { foreach( const playlist_ptr& pl, playlists ) { if( m_recplaylists.contains( pl ) ) { @@ -209,14 +209,14 @@ WelcomePlaylistModel::onPlaylistsRemoved( QList< playlist_ptr > playlists ) int -WelcomePlaylistModel::rowCount( const QModelIndex& ) const +RecentlyPlayedPlaylistsModel::rowCount( const QModelIndex& ) const { return m_recplaylists.count(); } void -WelcomePlaylistModel::plAdded( const playlist_ptr& pl ) +RecentlyPlayedPlaylistsModel::plAdded( const playlist_ptr& pl ) { onPlaylistsRemoved( QList< playlist_ptr >() << pl ); @@ -229,7 +229,7 @@ WelcomePlaylistModel::plAdded( const playlist_ptr& pl ) void -WelcomePlaylistModel::playlistChanged( Tomahawk::PlaylistInterface* pli ) +RecentlyPlayedPlaylistsModel::playlistChanged( Tomahawk::PlaylistInterface* pli ) { // ARG if( Playlist* pl = dynamic_cast< Playlist* >( pli ) ) { diff --git a/src/libtomahawk/widgets/welcomeplaylistmodel.h b/src/libtomahawk/widgets/RecentlyPlayedPlaylistsModel.h similarity index 88% rename from src/libtomahawk/widgets/welcomeplaylistmodel.h rename to src/libtomahawk/widgets/RecentlyPlayedPlaylistsModel.h index c30d83ea0..da271aea2 100644 --- a/src/libtomahawk/widgets/welcomeplaylistmodel.h +++ b/src/libtomahawk/widgets/RecentlyPlayedPlaylistsModel.h @@ -17,15 +17,15 @@ */ -#ifndef WELCOMEPLAYLISTMODEL_H -#define WELCOMEPLAYLISTMODEL_H +#ifndef RECENTLYPLAYEDPLAYLISTSMODEL_H +#define RECENTLYPLAYEDPLAYLISTSMODEL_H #include #include "playlist.h" -class WelcomePlaylistModel : public QAbstractListModel +class RecentlyPlayedPlaylistsModel : public QAbstractListModel { Q_OBJECT public: @@ -34,7 +34,7 @@ public: enum PlaylistTypes { StaticPlaylist, AutoPlaylist, Station }; - explicit WelcomePlaylistModel( QObject* parent = 0 ); + explicit RecentlyPlayedPlaylistsModel( QObject* parent = 0 ); void setMaxPlaylists( unsigned int max ) { m_maxPlaylists = max; } @@ -64,4 +64,4 @@ private: void sourceOnline(); }; -#endif // WELCOMEPLAYLISTMODEL_H +#endif // RECENTLYPLAYEDPLAYLISTSMODEL_H diff --git a/src/libtomahawk/widgets/welcomewidget.cpp b/src/libtomahawk/widgets/welcomewidget.cpp index 5e090f090..6223d14dc 100644 --- a/src/libtomahawk/widgets/welcomewidget.cpp +++ b/src/libtomahawk/widgets/welcomewidget.cpp @@ -24,7 +24,7 @@ #include "viewmanager.h" #include "sourcelist.h" #include "tomahawksettings.h" -#include "welcomeplaylistmodel.h" +#include "RecentPlaylistsModel.h" #include "audio/audioengine.h" #include "playlist/albummodel.h" @@ -33,6 +33,7 @@ #include "utils/tomahawkutils.h" #include "utils/logger.h" #include +#include "RecentlyPlayedPlaylistsModel.h" #define HISTORY_TRACK_ITEMS 25 #define HISTORY_PLAYLIST_ITEMS 10 @@ -52,8 +53,7 @@ WelcomeWidget::WelcomeWidget( QWidget* parent ) ui->splitter_2->setStretchFactor( 0, 2 ); ui->splitter_2->setStretchFactor( 0, 1 ); - WelcomePlaylistModel* model = new WelcomePlaylistModel( this ); - model->setMaxPlaylists( HISTORY_PLAYLIST_ITEMS ); + RecentPlaylistsModel* model = new RecentPlaylistsModel( HISTORY_PLAYLIST_ITEMS, this ); ui->playlistWidget->setFrameShape( QFrame::NoFrame ); ui->playlistWidget->setAttribute( Qt::WA_MacShowFocusRect, 0 ); @@ -180,7 +180,7 @@ WelcomeWidget::onPlaylistActivated( const QModelIndex& item ) { qDebug() << Q_FUNC_INFO; - Tomahawk::playlist_ptr pl = item.data( WelcomePlaylistModel::PlaylistRole ).value< Tomahawk::playlist_ptr >(); + Tomahawk::playlist_ptr pl = item.data( RecentlyPlayedPlaylistsModel::PlaylistRole ).value< Tomahawk::playlist_ptr >(); if( Tomahawk::dynplaylist_ptr dynplaylist = pl.dynamicCast< Tomahawk::DynamicPlaylist >() ) ViewManager::instance()->show( dynplaylist ); else @@ -240,12 +240,12 @@ PlaylistDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, boldFont.setBold( true ); QPixmap icon; - WelcomePlaylistModel::PlaylistTypes type = (WelcomePlaylistModel::PlaylistTypes)index.data( WelcomePlaylistModel::PlaylistTypeRole ).toInt(); - if( type == WelcomePlaylistModel::StaticPlaylist ) + RecentlyPlayedPlaylistsModel::PlaylistTypes type = (RecentlyPlayedPlaylistsModel::PlaylistTypes)index.data( RecentlyPlayedPlaylistsModel::PlaylistTypeRole ).toInt(); + if( type == RecentlyPlayedPlaylistsModel::StaticPlaylist ) icon = m_playlistIcon; - else if( type == WelcomePlaylistModel::AutoPlaylist ) + else if( type == RecentlyPlayedPlaylistsModel::AutoPlaylist ) icon = m_autoIcon; - else if( type == WelcomePlaylistModel::Station ) + else if( type == RecentlyPlayedPlaylistsModel::Station ) icon = m_stationIcon; QRect pixmapRect = option.rect.adjusted( 10, 13, -option.rect.width() + 48, -13 ); @@ -254,12 +254,12 @@ PlaylistDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, painter->drawPixmap( pixmapRect, icon ); QString descText; - if ( type == WelcomePlaylistModel::Station ) + if ( type == RecentlyPlayedPlaylistsModel::Station ) { - descText = index.data( WelcomePlaylistModel::DynamicPlaylistRole ).value< Tomahawk::dynplaylist_ptr >()->generator()->sentenceSummary(); + descText = index.data( RecentlyPlayedPlaylistsModel::DynamicPlaylistRole ).value< Tomahawk::dynplaylist_ptr >()->generator()->sentenceSummary(); } else { - descText = index.data( WelcomePlaylistModel::ArtistRole ).toString(); + descText = index.data( RecentlyPlayedPlaylistsModel::ArtistRole ).toString(); } QColor c = painter->pen().color(); painter->setPen( QColor( Qt::gray ).darker() ); @@ -278,10 +278,10 @@ PlaylistDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, painter->setPen( c ); painter->setFont( font ); - if ( type != WelcomePlaylistModel::Station ) + if ( type != RecentlyPlayedPlaylistsModel::Station ) { painter->save(); - QString tracks = index.data( WelcomePlaylistModel::TrackCountRole ).toString(); + QString tracks = index.data( RecentlyPlayedPlaylistsModel::TrackCountRole ).toString(); int width = painter->fontMetrics().width( tracks ); // int bottomEdge = pixmapRect // right edge 10px past right edge of pixmapRect @@ -300,7 +300,7 @@ PlaylistDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, painter->restore(); } - QPixmap avatar = index.data( WelcomePlaylistModel::PlaylistRole ).value< Tomahawk::playlist_ptr >()->author()->avatar( Source::FancyStyle ); + QPixmap avatar = index.data( RecentlyPlayedPlaylistsModel::PlaylistRole ).value< Tomahawk::playlist_ptr >()->author()->avatar( Source::FancyStyle ); if ( avatar.isNull() ) avatar = m_defaultAvatar; QRect r( option.rect.width() - avatar.width() - 10, option.rect.top() + option.rect.height()/2 - avatar.height()/2, avatar.width(), avatar.height() ); diff --git a/src/sourcetree/items/playlistitems.cpp b/src/sourcetree/items/playlistitems.cpp index 58570168c..c59f4258f 100644 --- a/src/sourcetree/items/playlistitems.cpp +++ b/src/sourcetree/items/playlistitems.cpp @@ -231,7 +231,7 @@ PlaylistItem::setData( const QVariant& v, bool role ) return false; } -bool +SourceTreeItem* PlaylistItem::activateCurrent() { if( ViewManager::instance()->pageForPlaylist( m_playlist ) == ViewManager::instance()->currentPage() ) @@ -239,10 +239,10 @@ PlaylistItem::activateCurrent() model()->linkSourceItemToPage( this, ViewManager::instance()->currentPage() ); emit selectRequest( this ); - return true; + return this; } - return false; + return 0; } @@ -386,7 +386,7 @@ DynamicPlaylistItem::icon() const } } -bool +SourceTreeItem* DynamicPlaylistItem::activateCurrent() { if( ViewManager::instance()->pageForDynPlaylist( m_dynplaylist ) == ViewManager::instance()->currentPage() ) @@ -394,9 +394,9 @@ DynamicPlaylistItem::activateCurrent() model()->linkSourceItemToPage( this, ViewManager::instance()->currentPage() ); emit selectRequest( this ); - return true; + return this; } - return false; + return 0; } diff --git a/src/sourcetree/items/playlistitems.h b/src/sourcetree/items/playlistitems.h index cc02e7bfb..8ab795bc3 100644 --- a/src/sourcetree/items/playlistitems.h +++ b/src/sourcetree/items/playlistitems.h @@ -41,7 +41,7 @@ public: virtual int peerSortValue() const; virtual int IDValue() const; - virtual bool activateCurrent(); + virtual SourceTreeItem* activateCurrent(); protected: void setLoaded( bool loaded ); @@ -73,7 +73,7 @@ public: virtual int IDValue() const; virtual QIcon icon() const; - virtual bool activateCurrent(); + virtual SourceTreeItem* activateCurrent(); private slots: void onDynamicPlaylistLoaded( Tomahawk::DynamicPlaylistRevision revision ); diff --git a/src/sourcetree/sourcesmodel.cpp b/src/sourcetree/sourcesmodel.cpp index d3f0af496..023a603ff 100644 --- a/src/sourcetree/sourcesmodel.cpp +++ b/src/sourcetree/sourcesmodel.cpp @@ -35,6 +35,8 @@ #include "globalactionmanager.h" #include "dropjob.h" #include "items/playlistitems.h" +#include "playlist/playlistview.h" +#include "playlist/dynamic/widgets/DynamicWidget.h" using namespace Tomahawk; @@ -274,6 +276,19 @@ SourcesModel::removeItem( const Tomahawk::source_ptr& source ) void SourcesModel::viewPageActivated( Tomahawk::ViewPage* page ) { + if ( !m_sourcesWithViewPage.isEmpty() ) + { + // Hide again any offline sources we exposed, since we're showing a different page now. they'll be re-shown if the user selects a playlist that is from an offline user + QList< source_ptr > temp = m_sourcesWithViewPage; + m_sourcesWithViewPage.clear(); + foreach ( const source_ptr& s, temp ) + { + QModelIndex idx = indexFromItem( m_sourcesWithViewPageItems.value( s ) ); + emit dataChanged( idx, idx ); + } + m_sourcesWithViewPageItems.clear(); + } + if ( m_sourceTreeLinks.contains( page ) ) { Q_ASSERT( m_sourceTreeLinks[ page ] ); @@ -287,32 +302,62 @@ SourcesModel::viewPageActivated( Tomahawk::ViewPage* page ) } else { + playlist_ptr p = ViewManager::instance()->playlistForPage( page ); // HACK // try to find it if it is a playlist. not pretty at all.... but this happens when ViewManager loads a playlist or dynplaylist NOT from the sidebar but from somewhere else // we don't know which sourcetreeitem is related to it, so we have to find it. we also don't know if this page is a playlist or dynplaylist or not, but we can't check as we can't // include DynamicWidget.h here (so can't dynamic_cast). // this could also be fixed by keeping a master list of playlists/sourcetreeitems... but that's even uglier i think. this is only called the first time a certain viewpage is clicked from external // sources. - activatePlaylistPage( page, m_rootItem ); + SourceTreeItem* item = activatePlaylistPage( page, m_rootItem ); m_viewPageDelayedCacheItem = page; + + if ( !p.isNull() ) + { + source_ptr s= p->author(); + if ( !s.isNull() && !s->isOnline() && item ) + { + m_sourcesWithViewPage << s; + + // show the collection now... yeah. + if ( !item->parent() || !item->parent()->parent() ) + { + tLog() << "Found playlist item with no category parent or collection parent!" << item->text(); + return; + } + + SourceTreeItem* collectionOfPlaylist = item->parent()->parent(); + if ( !m_rootItem->children().contains( collectionOfPlaylist ) ) // verification to make sure we're not stranded + { + tLog() << "Got what we assumed to be a parent col of a playlist not as a child of our root node...:" << collectionOfPlaylist; + return; + } + + QModelIndex idx = indexFromItem( collectionOfPlaylist ); + m_sourcesWithViewPageItems[ s ] = collectionOfPlaylist; + tDebug() << "Emitting dataChanged for offline source:" << idx << idx.isValid() << collectionOfPlaylist << collectionOfPlaylist->text(); + emit dataChanged( idx, idx ); + + } + } } } -bool +SourceTreeItem* SourcesModel::activatePlaylistPage( ViewPage* p, SourceTreeItem* i ) { if( !i ) - return false; + return 0; if( qobject_cast< PlaylistItem* >( i ) && qobject_cast< PlaylistItem* >( i )->activateCurrent() ) - return true; + return i; - bool ret = false; + SourceTreeItem* ret = 0; for( int k = 0; k < i->children().size(); k++ ) { - if( activatePlaylistPage( p, i->children().at( k ) ) ) - ret = true; + if( SourceTreeItem* retItem = activatePlaylistPage( p, i->children().at( k ) ) ) + ret = retItem; } return ret; diff --git a/src/sourcetree/sourcesmodel.h b/src/sourcetree/sourcesmodel.h index 7bf1c2ef0..d3f8d2f4b 100644 --- a/src/sourcetree/sourcesmodel.h +++ b/src/sourcetree/sourcesmodel.h @@ -93,6 +93,8 @@ public: QModelIndex indexFromItem( SourceTreeItem* item ) const; + QList< Tomahawk::source_ptr > sourcesWithViewPage() const { return m_sourcesWithViewPage; } + public slots: void loadSources(); @@ -120,10 +122,13 @@ private slots: private: SourceTreeItem* itemFromIndex( const QModelIndex& idx ) const; int rowForItem( SourceTreeItem* item ) const; - bool activatePlaylistPage( Tomahawk::ViewPage* p, SourceTreeItem* i ); + SourceTreeItem* activatePlaylistPage( Tomahawk::ViewPage* p, SourceTreeItem* i ); SourceTreeItem* m_rootItem; + QList< Tomahawk::source_ptr > m_sourcesWithViewPage; + QHash< Tomahawk::source_ptr, SourceTreeItem* > m_sourcesWithViewPageItems; + QHash< Tomahawk::ViewPage*, SourceTreeItem* > m_sourceTreeLinks; Tomahawk::ViewPage* m_viewPageDelayedCacheItem; }; diff --git a/src/sourcetree/sourcesproxymodel.cpp b/src/sourcetree/sourcesproxymodel.cpp index 3188cda77..b5d484c5e 100644 --- a/src/sourcetree/sourcesproxymodel.cpp +++ b/src/sourcetree/sourcesproxymodel.cpp @@ -63,6 +63,8 @@ SourcesProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex& sourcePar { if ( sti->source().isNull() || sti->source()->isOnline() ) return true; + else if ( m_model->sourcesWithViewPage().contains( sti->source() ) ) + return true; else return false; }