1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-07-31 19:30:21 +02:00

Add support for non-autoloaded dynamic playlists that can be used for custom displays

Add a SocialPlaylistWidget that will display some cool social stats and lists, but none right now
This commit is contained in:
Leo Franchi
2011-07-29 14:06:44 -04:00
parent 72bfeba65a
commit ca467fb5bc
32 changed files with 648 additions and 257 deletions

View File

@@ -1,7 +1,6 @@
-- Script to migate from db version 24 to 25.
-- Added the social_attributes table.
--
-- Separate each command with %%
ALTER TABLE dynamic_playlist RENAME TO tmp_dynamic_playlist;

View File

@@ -97,6 +97,7 @@
<file>./data/sql/dbmigrate-22_to_23.sql</file>
<file>./data/sql/dbmigrate-23_to_24.sql</file>
<file>./data/sql/dbmigrate-24_to_25.sql</file>
<file>./data/sql/dbmigrate-25_to_26.sql</file>
<file>./data/js/tomahawk.js</file>
</qresource>
</RCC>

View File

@@ -76,6 +76,7 @@ set( libSources
database/databasecommand_setdynamicplaylistrevision.cpp
database/databasecommand_createdynamicplaylist.cpp
database/databasecommand_loaddynamicplaylist.cpp
database/databasecommand_loaddynamicplaylistentries.cpp
database/databasecommand_loadallautoplaylists.cpp
database/databasecommand_loadallstations.cpp
database/databasecommand_deletedynamicplaylist.cpp
@@ -177,6 +178,7 @@ set( libSources
widgets/welcomeplaylistmodel.cpp
widgets/overlaywidget.cpp
widgets/HeaderLabel.cpp
widgets/SocialPlaylistWidget.cpp
widgets/infowidgets/sourceinfowidget.cpp
widgets/infowidgets/ArtistInfoWidget.cpp
@@ -252,6 +254,7 @@ set( libHeaders
database/databasecommand_setdynamicplaylistrevision.h
database/databasecommand_createdynamicplaylist.h
database/databasecommand_loaddynamicplaylist.h
database/databasecommand_loaddynamicplaylistentries.h
database/databasecommand_deletedynamicplaylist.h
database/databasecommand_loadallautoplaylists.h
database/databasecommand_loadallstations.h
@@ -350,6 +353,7 @@ set( libHeaders
widgets/welcomeplaylistmodel.h
widgets/overlaywidget.h
widgets/HeaderLabel.h
widgets/SocialPlaylistWidget.h
widgets/infowidgets/sourceinfowidget.h
widgets/infowidgets/ArtistInfoWidget.h
@@ -372,6 +376,7 @@ set( libUI ${libUI}
widgets/newplaylistwidget.ui
widgets/searchwidget.ui
widgets/welcomewidget.ui
widgets/SocialPlaylistWidget.ui
widgets/infowidgets/sourceinfowidget.ui
widgets/infowidgets/ArtistInfoWidget.ui
playlist/topbar/topbar.ui

View File

@@ -33,18 +33,20 @@ using namespace Tomahawk;
DatabaseCommand_CreateDynamicPlaylist::DatabaseCommand_CreateDynamicPlaylist( QObject* parent )
: DatabaseCommand_CreatePlaylist( parent )
: DatabaseCommand_CreatePlaylist( parent )
, m_autoLoad( true )
{
qDebug() << Q_FUNC_INFO << "creating dynamiccreatecommand 1";
tDebug() << Q_FUNC_INFO << "creating dynamiccreatecommand 1";
}
DatabaseCommand_CreateDynamicPlaylist::DatabaseCommand_CreateDynamicPlaylist( const source_ptr& author,
const dynplaylist_ptr& playlist )
const dynplaylist_ptr& playlist, bool autoLoad )
: DatabaseCommand_CreatePlaylist( author, playlist.staticCast<Playlist>() )
, m_playlist( playlist )
, m_autoLoad( autoLoad )
{
qDebug() << Q_FUNC_INFO << "creating dynamiccreatecommand 2";
tDebug() << Q_FUNC_INFO << "creating dynamiccreatecommand 2";
}
@@ -61,8 +63,8 @@ DatabaseCommand_CreateDynamicPlaylist::exec( DatabaseImpl* lib )
qDebug() << "Create dynamic execing!" << m_playlist << m_v;
TomahawkSqlQuery cre = lib->newquery();
cre.prepare( "INSERT INTO dynamic_playlist( guid, pltype, plmode ) "
"VALUES( ?, ?, ? )" );
cre.prepare( "INSERT INTO dynamic_playlist( guid, pltype, plmode, autoload ) "
"VALUES( ?, ?, ?, ? )" );
if( m_playlist.isNull() ) {
QVariantMap m = m_v.toMap();
@@ -74,6 +76,7 @@ DatabaseCommand_CreateDynamicPlaylist::exec( DatabaseImpl* lib )
cre.addBindValue( m_playlist->type() );
cre.addBindValue( m_playlist->mode() );
}
cre.addBindValue( m_autoLoad );
cre.exec();
}
@@ -88,7 +91,7 @@ DatabaseCommand_CreateDynamicPlaylist::postCommitHook()
return;
}
if( report() == false )
if( !DatabaseCommand_CreatePlaylist::report() || report() == false )
return;
qDebug() << Q_FUNC_INFO << "..reporting..";

View File

@@ -1,5 +1,5 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
*
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
*
* Tomahawk is free software: you can redistribute it and/or modify
@@ -24,21 +24,31 @@
#include "dynamic/DynamicPlaylist.h"
#include "typedefs.h"
/**
* Create a new dynamic playlist in the database, based on an existing playlist.
*
* If autoLoad is true, this playlist will *not* show up in the sidebar under the playlist tree, and
* it will *not* be replicated to peers. It is useful to show a "specially crafted" playlist in other places
*/
class DatabaseCommand_CreateDynamicPlaylist : public DatabaseCommand_CreatePlaylist
{
Q_OBJECT
Q_PROPERTY( QVariant playlist READ playlistV WRITE setPlaylistV )
public:
explicit DatabaseCommand_CreateDynamicPlaylist( QObject* parent = 0 );
explicit DatabaseCommand_CreateDynamicPlaylist( const Tomahawk::source_ptr& author, const Tomahawk::dynplaylist_ptr& playlist );
explicit DatabaseCommand_CreateDynamicPlaylist( const Tomahawk::source_ptr& author, const Tomahawk::dynplaylist_ptr& playlist, bool autoLoad = true );
QString commandname() const { return "createdynamicplaylist"; }
virtual void exec( DatabaseImpl* lib );
virtual void postCommitHook();
virtual bool doesMutates() const { return true; }
virtual bool loggable() const { return m_autoLoad; }
QVariant playlistV() const
{
if( m_v.isNull() )
@@ -46,14 +56,18 @@ public:
else
return m_v;
}
void setPlaylistV( const QVariant& v )
{
m_v = v;
}
protected:
virtual bool report() { return m_autoLoad; }
private:
Tomahawk::dynplaylist_ptr m_playlist;
bool m_autoLoad;
};
#endif // DATABASECOMMAND_CREATEDYNAMICPLAYLIST_H

View File

@@ -59,7 +59,7 @@ DatabaseCommand_CreatePlaylist::postCommitHook()
if ( m_report == false )
return;
qDebug() << Q_FUNC_INFO << "reporting...";
tDebug() << Q_FUNC_INFO << "reporting...";
if ( m_playlist.isNull() )
{
source_ptr src = source();
@@ -82,7 +82,6 @@ DatabaseCommand_CreatePlaylist::postCommitHook()
void
DatabaseCommand_CreatePlaylist::createPlaylist( DatabaseImpl* lib, bool dynamic)
{
qDebug() << Q_FUNC_INFO;
Q_ASSERT( !( m_playlist.isNull() && m_v.isNull() ) );
Q_ASSERT( !source().isNull() );
@@ -123,7 +122,7 @@ DatabaseCommand_CreatePlaylist::createPlaylist( DatabaseImpl* lib, bool dynamic)
cre.bindValue( ":creator", m.value( "creator" ) );
cre.bindValue( ":lastmodified", m.value( "lastmodified", 0 ) );
}
qDebug() << "CREATE PLAYLIST:" << cre.boundValues();
tDebug() << "CREATE PLAYLIST:" << cre.boundValues();
cre.exec();
}

View File

@@ -1,5 +1,5 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
*
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
*
* Tomahawk is free software: you can redistribute it and/or modify
@@ -53,13 +53,14 @@ public:
{
m_v = v;
}
protected:
void createPlaylist( DatabaseImpl* lib, bool dynamic = false );
bool report() { return m_report; }
virtual bool report() { return m_report; }
void setPlaylist( const Tomahawk::playlist_ptr& playlist ) { m_playlist = playlist; }
QVariant m_v;
private:
Tomahawk::playlist_ptr m_playlist;

View File

@@ -52,48 +52,11 @@ DatabaseCommand_GenericSelect::exec( DatabaseImpl* dbi )
Tomahawk::source_ptr s;
QString artist, track, album;
artist = query.value( 0 ).toString();
album = query.value( 1 ).toString();
track = query.value( 2 ).toString();
Tomahawk::query_ptr qry = Tomahawk::Query::get( artist, track, album, uuid(), (query.value( 7 ).toUInt() != 0) ); // Only auto-resolve non-local results
Tomahawk::artist_ptr artistptr = Tomahawk::Artist::get( query.value( 12 ).toUInt(), artist );
Tomahawk::album_ptr albumptr = Tomahawk::Album::get( query.value( 13 ).toUInt(), album, artistptr );
// If it's a local track, set to the local source and url in the result and we're done. otherwise, we get resolved
if( query.value( 7 ).toUInt() == 0 )
{
s = SourceList::instance()->getLocal();
result->setUrl( query.value( 7 ).toString() );
result->setId( query.value( 9 ).toUInt() );
result->setArtist( artistptr );
result->setAlbum( albumptr );
result->setTrack( query.value( 2 ).toString() );
result->setSize( query.value( 3 ).toUInt() );
result->setDuration( query.value( 4 ).toUInt() );
result->setBitrate( query.value( 5 ).toUInt() );
result->setMimetype( query.value( 8 ).toString() );
result->setScore( 1.0 );
result->setCollection( s->collection() );
TomahawkSqlQuery attrQuery = dbi->newquery();
QVariantMap attr;
attrQuery.prepare( "SELECT k, v FROM track_attributes WHERE id = ?" );
attrQuery.bindValue( 0, result->dbid() );
attrQuery.exec();
while ( attrQuery.next() )
{
attr[ attrQuery.value( 0 ).toString() ] = attrQuery.value( 1 ).toString();
}
result->setAttributes( attr );
qry->addResults( QList<Tomahawk::result_ptr>() << result );
qry->setResolveFinished( true );
}
track = query.value( 0 ).toString();
artist = query.value( 1 ).toString();
album = query.value( 2 ).toString();
Tomahawk::query_ptr qry = Tomahawk::Query::get( artist, track, album, uuid(), true ); // Only auto-resolve non-local results
queries << qry;
}

View File

@@ -32,7 +32,7 @@
* that match.
*
* In order for the conversion to query_ptr to work, the SELECT command should select the following items:
* artist.name, album.name, track.name, file.size, file.duration, file.bitrate, file.url, file.source, file.mimetype, track.id
* track.name, artist.name, album.name
*
*/
class DLLEXPORT DatabaseCommand_GenericSelect : public DatabaseCommand

View File

@@ -1,6 +1,6 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
*
* Tomahawk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -33,7 +33,7 @@ DatabaseCommand_LoadAllAutoPlaylists::exec( DatabaseImpl* dbi )
TomahawkSqlQuery query = dbi->newquery();
query.exec( QString( "SELECT playlist.guid as guid, title, info, creator, createdOn, lastmodified, shared, currentrevision, dynamic_playlist.pltype, dynamic_playlist.plmode "
"FROM playlist, dynamic_playlist WHERE source %1 AND dynplaylist = 'true' AND playlist.guid = dynamic_playlist.guid AND dynamic_playlist.plmode = %2" )
"FROM playlist, dynamic_playlist WHERE source %1 AND dynplaylist = 'true' AND playlist.guid = dynamic_playlist.guid AND dynamic_playlist.plmode = %2 AND dynamic_playlist.autoload = 'true'" )
.arg( source()->isLocal() ? "IS NULL" : QString( "=%1" ).arg( source()->id() ) )
.arg( Static ) );

View File

@@ -1,6 +1,6 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
*
* Tomahawk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@@ -1,6 +1,6 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
*
* Tomahawk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -33,7 +33,7 @@ DatabaseCommand_LoadAllStations::exec( DatabaseImpl* dbi )
TomahawkSqlQuery query = dbi->newquery();
query.exec( QString( "SELECT playlist.guid as guid, title, info, creator, createdOn, lastmodified, shared, currentrevision, dynamic_playlist.pltype, dynamic_playlist.plmode "
"FROM playlist, dynamic_playlist WHERE source %1 AND dynplaylist = 'true' AND playlist.guid = dynamic_playlist.guid AND dynamic_playlist.plmode = %2" )
"FROM playlist, dynamic_playlist WHERE source %1 AND dynplaylist = 'true' AND playlist.guid = dynamic_playlist.guid AND dynamic_playlist.plmode = %2 AND dynamic_playlist.autoload = 'true'" )
.arg( source()->isLocal() ? "IS NULL" : QString( "=%1" ).arg( source()->id() ) )
.arg( OnDemand ) );

View File

@@ -1,6 +1,6 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
*
* Tomahawk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@@ -1,6 +1,6 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
*
* Tomahawk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,102 +19,59 @@
#include "databasecommand_loaddynamicplaylist.h"
#include <QSqlQuery>
#include <QString>
#include "dynamic/DynamicPlaylist.h"
#include "databaseimpl.h"
#include "tomahawksqlquery.h"
#include "dynamic/DynamicControl.h"
#include "dynamic/GeneratorInterface.h"
#include <dynamic/GeneratorFactory.h>
#include "utils/logger.h"
using namespace Tomahawk;
Tomahawk::DatabaseCommand_LoadDynamicPlaylist::DatabaseCommand_LoadDynamicPlaylist( const source_ptr& s, const QString& guid, QObject* parent )
: DatabaseCommand( s, parent )
, m_plid( guid )
{
}
void
DatabaseCommand_LoadDynamicPlaylist::exec( DatabaseImpl* dbi )
Tomahawk::DatabaseCommand_LoadDynamicPlaylist::exec( DatabaseImpl* dbi )
{
// qDebug() << "Loading dynamic playlist guid" << guid();
// load the entries first
generateEntries( dbi );
TomahawkSqlQuery query = dbi->newquery();
// now load the controls etc
query.exec( QString( "SELECT playlist.guid as guid, title, info, creator, createdOn, lastmodified, shared, currentrevision, dynamic_playlist.pltype, dynamic_playlist.plmode "
"FROM playlist, dynamic_playlist WHERE source %1 AND dynplaylist = 'true' AND playlist.guid = dynamic_playlist.guid AND playlist.guid = '%2'" )
.arg( source()->isLocal() ? "IS NULL" : QString( "=%1" ).arg( source()->id() ) ).arg( m_plid ) );
TomahawkSqlQuery controlsQuery = dbi->newquery();
controlsQuery.prepare("SELECT playlist_revision.playlist, controls, plmode, pltype "
"FROM dynamic_playlist_revision, playlist_revision "
"WHERE dynamic_playlist_revision.guid = ? AND playlist_revision.guid = dynamic_playlist_revision.guid");
controlsQuery.addBindValue( revisionGuid() );
controlsQuery.exec();
QString type;
GeneratorMode mode;
QList< QVariantMap > controls;
QString playlist_guid;
// qDebug() << "Loading controls..." << revisionGuid();
// qDebug() << "SELECT playlist_revision.playlist, controls, plmode, pltype "
// "FROM dynamic_playlist_revision, playlist_revision "
// "WHERE dynamic_playlist_revision.guid = "<< revisionGuid() << " AND playlist_revision.guid = dynamic_playlist_revision.guid";
if( controlsQuery.first() )
QList<dynplaylist_ptr> plists;
if( query.next() )
{
playlist_guid = controlsQuery.value( 0 ).toString();
QJson::Parser parser;
bool ok;
QVariant v = parser.parse( controlsQuery.value(1).toByteArray(), &ok );
Q_ASSERT( ok && v.type() == QVariant::List ); //TODO
dynplaylist_ptr p( new DynamicPlaylist( source(),
query.value(7).toString(), //current rev
query.value(1).toString(), //title
query.value(2).toString(), //info
query.value(3).toString(), //creator
query.value(4).toUInt(), //createdOn
query.value(8).toString(), // dynamic type
static_cast<GeneratorMode>(query.value(9).toInt()), // dynamic mode
query.value(6).toBool(), //shared
query.value(5).toInt(), //lastmod
query.value(0).toString() ) ); //GUID
tLog() << "Loaded individual dynamic playlist:" << query.value(7).toString() //current rev
<< query.value(1).toString() //title
<< query.value(2).toString() //info
<< query.value(3).toString() //creator
<< query.value(4).toString() //createdOn
<< query.value(8).toString() // dynamic type
<< static_cast<GeneratorMode>(query.value(9).toInt()) // dynamic mode
<< query.value(6).toBool() //shared
<< query.value(5).toInt() //lastmod
<< query.value(0).toString(); //GUID
type = controlsQuery.value( 3 ).toString();
mode = static_cast<GeneratorMode>( controlsQuery.value( 2 ).toInt() );
QStringList controlIds = v.toStringList();
// qDebug() << "Got controls in dynamic playlist, loading:" << controlIds << controlsQuery.value(1);
foreach( const QString& controlId, controlIds )
{
TomahawkSqlQuery controlQuery = dbi->newquery();
controlQuery.prepare( "SELECT selectedType, match, input "
"FROM dynamic_playlist_controls "
"WHERE id = :id" );
controlQuery.bindValue( ":id", controlId );
controlQuery.exec();
if( controlQuery.next() )
{
QVariantMap c;
c[ "type" ] = type;
c[ "id" ] = controlId;
c[ "selectedType" ] = controlQuery.value( 0 ).toString();
c[ "match" ] = controlQuery.value( 1 ).toString();
c[ "input" ] = controlQuery.value( 2 ).toString();
controls << c;
}
}
}
else
{
// No controls, lets load the info we need directly from the playlist table
TomahawkSqlQuery info = dbi->newquery();
info.prepare( QString( "SELECT dynamic_playlist.pltype, dynamic_playlist.plmode FROM playlist, dynamic_playlist WHERE playlist.guid = \"%1\" AND playlist.guid = dynamic_playlist.guid" ).arg( playlist_guid ) );
if( !info.exec() ) {
qWarning() << "Failed to load dynplaylist info..";
return;
} else if( !info.first() ) {
qWarning() << "Noo results for queryL:" << info.lastQuery();
return;
}
type = info.value( 0 ).toString();
mode = static_cast<GeneratorMode>( info.value( 1 ).toInt() );
emit dynamicPlaylistLoaded( p );
}
if( mode == OnDemand )
{
Q_ASSERT( m_entrymap.isEmpty() ); // ondemand should have no entry
emit done( revisionGuid(), m_islatest, type, controls, true );
}
else
{
emit done( revisionGuid(), m_guids, m_oldentries, type, controls, m_islatest, m_entrymap, true );
}
emit done();
}

View File

@@ -1,6 +1,6 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
*
* Tomahawk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,45 +22,31 @@
#include <QObject>
#include <QVariantMap>
#include "typedefs.h"
#include "databasecommand.h"
#include "databasecommand_loadplaylistentries.h"
#include "playlist.h"
#include "dynamic/DynamicControl.h"
#include "typedefs.h"
class DatabaseCommand_LoadDynamicPlaylist : public DatabaseCommand_LoadPlaylistEntries
namespace Tomahawk
{
class DatabaseCommand_LoadDynamicPlaylist : public DatabaseCommand
{
Q_OBJECT
public:
explicit DatabaseCommand_LoadDynamicPlaylist( QString revision_guid, QObject* parent = 0 )
: DatabaseCommand_LoadPlaylistEntries( revision_guid, parent )
{
// qDebug() << "loaded with:" << revision_guid << guid();
}
explicit DatabaseCommand_LoadDynamicPlaylist( const source_ptr& s, const QString& guid, QObject* parent = 0 );
virtual void exec( DatabaseImpl* );
virtual bool doesMutates() const { return false; }
virtual QString commandname() const { return "loaddynamicplaylist"; }
virtual QString commandname() const { return "loadsingledynamicplaylist"; }
signals:
// used if loading an ondemand playlist
void done( QString,
bool,
QString,
QList< QVariantMap>,
bool );
// used when loading a static playlist
void done( QString,
QList< QString >,
QList< QString >,
QString,
QList< QVariantMap>,
bool,
QMap< QString, Tomahawk::plentry_ptr >,
bool );
void dynamicPlaylistLoaded( const Tomahawk::dynplaylist_ptr& pl );
void done();
private:
QString m_plid;
};
#endif // DATABASECOMMAND_LOADDYNAMICPLAYLIST_H
}
#endif

View File

@@ -0,0 +1,120 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "databasecommand_loaddynamicplaylistentries.h"
#include <QSqlQuery>
#include <QString>
#include "databaseimpl.h"
#include "tomahawksqlquery.h"
#include "dynamic/DynamicControl.h"
#include "dynamic/GeneratorInterface.h"
#include <dynamic/GeneratorFactory.h>
#include "utils/logger.h"
using namespace Tomahawk;
void
DatabaseCommand_LoadDynamicPlaylistEntries::exec( DatabaseImpl* dbi )
{
// qDebug() << "Loading dynamic playlist guid" << guid();
// load the entries first
generateEntries( dbi );
// now load the controls etc
TomahawkSqlQuery controlsQuery = dbi->newquery();
controlsQuery.prepare("SELECT playlist_revision.playlist, controls, plmode, pltype "
"FROM dynamic_playlist_revision, playlist_revision "
"WHERE dynamic_playlist_revision.guid = ? AND playlist_revision.guid = dynamic_playlist_revision.guid");
controlsQuery.addBindValue( revisionGuid() );
controlsQuery.exec();
QString type;
GeneratorMode mode;
QList< QVariantMap > controls;
QString playlist_guid;
// qDebug() << "Loading controls..." << revisionGuid();
// qDebug() << "SELECT playlist_revision.playlist, controls, plmode, pltype "
// "FROM dynamic_playlist_revision, playlist_revision "
// "WHERE dynamic_playlist_revision.guid = "<< revisionGuid() << " AND playlist_revision.guid = dynamic_playlist_revision.guid";
if( controlsQuery.first() )
{
playlist_guid = controlsQuery.value( 0 ).toString();
QJson::Parser parser;
bool ok;
QVariant v = parser.parse( controlsQuery.value(1).toByteArray(), &ok );
Q_ASSERT( ok && v.type() == QVariant::List ); //TODO
type = controlsQuery.value( 3 ).toString();
mode = static_cast<GeneratorMode>( controlsQuery.value( 2 ).toInt() );
QStringList controlIds = v.toStringList();
// qDebug() << "Got controls in dynamic playlist, loading:" << controlIds << controlsQuery.value(1);
foreach( const QString& controlId, controlIds )
{
TomahawkSqlQuery controlQuery = dbi->newquery();
controlQuery.prepare( "SELECT selectedType, match, input "
"FROM dynamic_playlist_controls "
"WHERE id = :id" );
controlQuery.bindValue( ":id", controlId );
controlQuery.exec();
if( controlQuery.next() )
{
QVariantMap c;
c[ "type" ] = type;
c[ "id" ] = controlId;
c[ "selectedType" ] = controlQuery.value( 0 ).toString();
c[ "match" ] = controlQuery.value( 1 ).toString();
c[ "input" ] = controlQuery.value( 2 ).toString();
controls << c;
}
}
}
else
{
// No controls, lets load the info we need directly from the playlist table
TomahawkSqlQuery info = dbi->newquery();
info.prepare( QString( "SELECT dynamic_playlist.pltype, dynamic_playlist.plmode FROM playlist, dynamic_playlist WHERE playlist.guid = \"%1\" AND playlist.guid = dynamic_playlist.guid" ).arg( playlist_guid ) );
if( !info.exec() ) {
qWarning() << "Failed to load dynplaylist info..";
return;
} else if( !info.first() ) {
qWarning() << "Noo results for queryL:" << info.lastQuery();
return;
}
type = info.value( 0 ).toString();
mode = static_cast<GeneratorMode>( info.value( 1 ).toInt() );
}
if( mode == OnDemand )
{
Q_ASSERT( m_entrymap.isEmpty() ); // ondemand should have no entry
emit done( revisionGuid(), m_islatest, type, controls, true );
}
else
{
emit done( revisionGuid(), m_guids, m_oldentries, type, controls, m_islatest, m_entrymap, true );
}
}

View File

@@ -0,0 +1,66 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef DATABASECOMMAND_LOADDYNAMICPLAYLISTENTRIES_H
#define DATABASECOMMAND_LOADDYNAMICPLAYLISTENTRIES_H
#include <QObject>
#include <QVariantMap>
#include "typedefs.h"
#include "databasecommand.h"
#include "databasecommand_loadplaylistentries.h"
#include "playlist.h"
#include "dynamic/DynamicControl.h"
class DatabaseCommand_LoadDynamicPlaylistEntries : public DatabaseCommand_LoadPlaylistEntries
{
Q_OBJECT
public:
explicit DatabaseCommand_LoadDynamicPlaylistEntries( QString revision_guid, QObject* parent = 0 )
: DatabaseCommand_LoadPlaylistEntries( revision_guid, parent )
{
// qDebug() << "loaded with:" << revision_guid << guid();
}
virtual void exec( DatabaseImpl* );
virtual bool doesMutates() const { return false; }
virtual QString commandname() const { return "loaddynamicplaylist"; }
signals:
// used if loading an ondemand playlist
void done( QString,
bool,
QString,
QList< QVariantMap>,
bool );
// used when loading a static playlist
void done( QString,
QList< QString >,
QList< QString >,
QString,
QList< QVariantMap>,
bool,
QMap< QString, Tomahawk::plentry_ptr >,
bool );
private:
};
#endif // DATABASECOMMAND_LOADDYNAMICPLAYLIST_H

View File

@@ -1,6 +1,6 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
*
* Tomahawk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -82,10 +82,9 @@ DatabaseCommand_SetDynamicPlaylistRevision::controlsV()
void
DatabaseCommand_SetDynamicPlaylistRevision::postCommitHook()
{
qDebug() << Q_FUNC_INFO;
if ( source().isNull() || source()->collection().isNull() )
{
qDebug() << "Source has gone offline, not emitting to GUI.";
tDebug() << "Source has gone offline, not emitting to GUI.";
return;
}
@@ -95,7 +94,7 @@ DatabaseCommand_SetDynamicPlaylistRevision::postCommitHook()
Q_ASSERT( !source().isNull() );
Q_ASSERT( !source()->collection().isNull() );
qDebug() << "Postcommitting this playlist:" << playlistguid() << source().isNull() << source().data();
tLog() << "Postcommitting this playlist:" << playlistguid() << source().isNull();
// private, but we are a friend. will recall itself in its own thread:
dynplaylist_ptr playlist = source()->collection()->autoPlaylist( playlistguid() );
@@ -106,7 +105,7 @@ DatabaseCommand_SetDynamicPlaylistRevision::postCommitHook()
// now that we separate them, if we get them as one and then get a changed mode, the playlist ends up in the wrong bucket in Collection.
// so here we fix it if we have to.
// HACK
qDebug() << "Does this need FIXING?" << playlist->mode() << source()->collection()->autoPlaylist( playlistguid() ).isNull() << source()->collection()->station( playlistguid() ).isNull();
tDebug() << "Does this need FIXING?" << playlist->mode() << source()->collection()->autoPlaylist( playlistguid() ).isNull() << source()->collection()->station( playlistguid() ).isNull();
if( playlist->mode() == Static && source()->collection()->autoPlaylist( playlistguid() ).isNull() ) // should be here
source()->collection()->moveStationToAuto( playlistguid() );
else if ( playlist->mode() == OnDemand && source()->collection()->station( playlistguid() ).isNull() ) // should be here
@@ -114,7 +113,7 @@ DatabaseCommand_SetDynamicPlaylistRevision::postCommitHook()
if ( playlist.isNull() )
{
qDebug() <<"Got null playlist with guid:" << playlistguid() << "from source and collection:" << source()->friendlyName() << source()->collection()->name() << "and mode is static?:" << (m_mode == Static);
tLog() <<"Got null playlist with guid:" << playlistguid() << "from source and collection:" << source()->friendlyName() << source()->collection()->name() << "and mode is static?:" << (m_mode == Static);
Q_ASSERT( !playlist.isNull() );
return;
}
@@ -205,7 +204,7 @@ DatabaseCommand_SetDynamicPlaylistRevision::exec( DatabaseImpl* lib )
delQuery.prepare( "DELETE FROM dynamic_playlist_controls WHERE playlist = ?" );
delQuery.addBindValue( m_playlistguid );
if ( !delQuery.exec() )
qWarning() << "Failed to delete controls from dynamic playlist controls table";
tLog() << "Failed to delete controls from dynamic playlist controls table";
TomahawkSqlQuery controlsQuery = lib->newquery();
controlsQuery.prepare( "INSERT INTO dynamic_playlist_controls( id, playlist, selectedType, match, input ) "
@@ -242,7 +241,7 @@ DatabaseCommand_SetDynamicPlaylistRevision::exec( DatabaseImpl* lib )
}
if ( m_applied )
{
qDebug() << "updating dynamic playlist, optimistic locking okay";
tLog() << "updating dynamic playlist, optimistic locking okay";
TomahawkSqlQuery query2 = lib->newquery();
query2.prepare( "UPDATE dynamic_playlist SET pltype = ?, plmode = ? WHERE guid = ?" );

View File

@@ -1,6 +1,6 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
*
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
*
* Tomahawk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -34,12 +34,12 @@ class DatabaseCommand_SetDynamicPlaylistRevision : public DatabaseCommand_SetPla
Q_PROPERTY( QString type READ type WRITE setType )
Q_PROPERTY( int mode READ mode WRITE setMode )
Q_PROPERTY( QVariantList controls READ controlsV WRITE setControlsV )
public:
explicit DatabaseCommand_SetDynamicPlaylistRevision( QObject* parent = 0 )
: DatabaseCommand_SetPlaylistRevision( parent )
{}
explicit DatabaseCommand_SetDynamicPlaylistRevision( const source_ptr& s,
const QString& playlistguid,
const QString& newrev,
@@ -50,7 +50,7 @@ public:
const QString& type,
GeneratorMode mode,
const QList< dyncontrol_ptr >& controls );
explicit DatabaseCommand_SetDynamicPlaylistRevision( const source_ptr& s,
const QString& playlistguid,
const QString& newrev,
@@ -58,26 +58,26 @@ public:
const QString& type,
GeneratorMode mode,
const QList< dyncontrol_ptr >& controls );
QString commandname() const { return "setdynamicplaylistrevision"; }
virtual void exec( DatabaseImpl* lib );
virtual void postCommitHook();
virtual bool doesMutates() const { return true; }
void setControlsV( const QVariantList& vlist )
{
m_controlsV = vlist;
}
QVariantList controlsV();
QString type() const { return m_type; }
int mode() const { return (int)m_mode; }
void setType( const QString& type ) { m_type = type; }
void setMode( int mode ) { m_mode = (GeneratorMode)mode; }
private:
QString m_type;
GeneratorMode m_mode;

View File

@@ -39,7 +39,7 @@
*/
#include "schema.sql.h"
#define CURRENT_SCHEMA_VERSION 25
#define CURRENT_SCHEMA_VERSION 26
DatabaseImpl::DatabaseImpl( const QString& dbname, Database* parent )
@@ -54,11 +54,11 @@ DatabaseImpl::DatabaseImpl( const QString& dbname, Database* parent )
if ( version > 0 && version != CURRENT_SCHEMA_VERSION )
{
QString newname = QString( "%1.v%2" ).arg( dbname ).arg( version );
qDebug() << endl << "****************************" << endl;
qDebug() << "Schema version too old: " << version << ". Current version is:" << CURRENT_SCHEMA_VERSION;
qDebug() << "Moving" << dbname << newname;
qDebug() << "If the migration fails, you can recover your DB by copying" << newname << "back to" << dbname;
qDebug() << endl << "****************************" << endl;
tLog() << endl << "****************************" << endl;
tLog() << "Schema version too old: " << version << ". Current version is:" << CURRENT_SCHEMA_VERSION;
tLog() << "Moving" << dbname << newname;
tLog() << "If the migration fails, you can recover your DB by copying" << newname << "back to" << dbname;
tLog() << endl << "****************************" << endl;
QFile::copy( dbname, newname );
{
@@ -84,7 +84,7 @@ DatabaseImpl::DatabaseImpl( const QString& dbname, Database* parent )
db.setDatabaseName( dbname );
if ( !db.open() )
{
qDebug() << "Failed to open database" << dbname;
tLog() << "Failed to open database" << dbname;
throw "failed to open db"; // TODO
}
@@ -103,7 +103,7 @@ DatabaseImpl::DatabaseImpl( const QString& dbname, Database* parent )
m_dbid = uuid();
query.exec( QString( "INSERT INTO settings(k,v) VALUES('dbid','%1')" ).arg( m_dbid ) );
}
qDebug() << "Database ID:" << m_dbid;
tLog() << "Database ID:" << m_dbid;
// make sqlite behave how we want:
query.exec( "PRAGMA synchronous = ON" );
@@ -145,7 +145,7 @@ DatabaseImpl::updateSchema( int oldVersion )
// we are called here with the old database. we must migrate it to the CURRENT_SCHEMA_VERSION from the oldVersion
if ( oldVersion == 0 ) // empty database, so create our tables and stuff
{
qDebug() << "Create tables... old version is" << oldVersion;
tLog() << "Create tables... old version is" << oldVersion;
QString sql( get_tomahawk_sql() );
QStringList statements = sql.split( ";", QString::SkipEmptyParts );
db.transaction();
@@ -156,7 +156,7 @@ DatabaseImpl::updateSchema( int oldVersion )
if ( s.length() == 0 )
continue;
qDebug() << "Executing:" << s;
tLog() << "Executing:" << s;
TomahawkSqlQuery query = newquery();
query.exec( s );
}
@@ -176,7 +176,7 @@ DatabaseImpl::updateSchema( int oldVersion )
QFile script( path );
if ( !script.exists() || !script.open( QIODevice::ReadOnly ) )
{
qWarning() << "Failed to find or open upgrade script from" << (cur-1) << "to" << cur << " (" << path << ")! Aborting upgrade...";
tLog() << "Failed to find or open upgrade script from" << (cur-1) << "to" << cur << " (" << path << ")! Aborting upgrade...";
return false;
}
@@ -188,13 +188,13 @@ DatabaseImpl::updateSchema( int oldVersion )
if ( clean.isEmpty() )
continue;
qDebug() << "Executing upgrade statement:" << clean;
tLog() << "Executing upgrade statement:" << clean;
TomahawkSqlQuery q = newquery();
q.exec( clean );
}
}
db.commit();
qDebug() << "DB Upgrade successful!";
tLog() << "DB Upgrade successful!";
return true;
}
}
@@ -299,7 +299,7 @@ DatabaseImpl::artistId( const QString& name_orig, bool& autoCreate )
query.addBindValue( sortname );
if ( !query.exec() )
{
qDebug() << "Failed to insert artist:" << name_orig;
tDebug() << "Failed to insert artist:" << name_orig;
return 0;
}
@@ -345,7 +345,7 @@ DatabaseImpl::trackId( int artistid, const QString& name_orig, bool& isnew )
query.addBindValue( sortname );
if( !query.exec() )
{
qDebug() << "Failed to insert track:" << name_orig ;
tDebug() << "Failed to insert track:" << name_orig ;
return 0;
}
@@ -396,7 +396,7 @@ DatabaseImpl::albumId( int artistid, const QString& name_orig, bool& isnew )
query.addBindValue( sortname );
if( !query.exec() )
{
qDebug() << "Failed to insert album: " << name_orig ;
tDebug() << "Failed to insert album: " << name_orig ;
return 0;
}
@@ -533,7 +533,7 @@ DatabaseImpl::resultFromHint( const Tomahawk::query_ptr& origquery )
else
{
// Q_ASSERT( false );
qDebug() << "We don't support non-servent / non-file result-hints yet.";
tDebug() << "We don't support non-servent / non-file result-hints yet.";
/* res = Tomahawk::result_ptr( new Tomahawk::Result() );
s = SourceList::instance()->webSource();
res->setUrl( url );
@@ -630,7 +630,7 @@ DatabaseImpl::getDatabaseVersion( const QString& dbname )
db.setDatabaseName( dbname );
if ( !db.open() )
{
qDebug() << "Failed to open database" << dbname;
tLog() << "Failed to open database" << dbname;
throw "failed to open db"; // TODO
}
@@ -639,7 +639,7 @@ DatabaseImpl::getDatabaseVersion( const QString& dbname )
if ( qry.next() )
{
version = qry.value( 0 ).toInt();
qDebug() << "Database schema of" << dbname << "is" << version;
tLog() << "Database schema of" << dbname << "is" << version;
}
}

View File

@@ -108,7 +108,8 @@ CREATE TABLE IF NOT EXISTS playlist_revision (
CREATE TABLE IF NOT EXISTS dynamic_playlist (
guid TEXT NOT NULL REFERENCES playlist(guid) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
pltype TEXT, -- the generator type
plmode INTEGER -- the mode of this playlist
plmode INTEGER, -- the mode of this playlist
autoload BOOLEAN DEFAULT true -- if this playlist should be autoloaded or not. true except for the case of special playlists we want to display elsewhere
);
--INSERT INTO dynamic_playlist(guid, pltype, plmode)
@@ -282,4 +283,4 @@ CREATE TABLE IF NOT EXISTS settings (
v TEXT NOT NULL DEFAULT ''
);
INSERT INTO settings(k,v) VALUES('schema_version', '25');
INSERT INTO settings(k,v) VALUES('schema_version', '26');

View File

@@ -1,5 +1,5 @@
/*
This file was automatically generated from ./schema.sql on Fri Jun 24 09:10:23 CEST 2011.
This file was automatically generated from schema.sql on Mon Jul 25 20:38:55 EDT 2011.
*/
static const char * tomahawk_schema_sql =
@@ -78,7 +78,8 @@ static const char * tomahawk_schema_sql =
"CREATE TABLE IF NOT EXISTS dynamic_playlist ("
" guid TEXT NOT NULL REFERENCES playlist(guid) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,"
" pltype TEXT, "
" plmode INTEGER "
" plmode INTEGER, "
" autoload BOOLEAN DEFAULT true "
");"
"CREATE TABLE IF NOT EXISTS dynamic_playlist_controls ("
" id TEXT PRIMARY KEY,"
@@ -183,7 +184,7 @@ static const char * tomahawk_schema_sql =
" k TEXT NOT NULL PRIMARY KEY,"
" v TEXT NOT NULL DEFAULT ''"
");"
"INSERT INTO settings(k,v) VALUES('schema_version', '25');"
"INSERT INTO settings(k,v) VALUES('schema_version', '26');"
;
const char * get_tomahawk_sql()

View File

@@ -1,5 +1,5 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
*
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
*
* Tomahawk is free software: you can redistribute it and/or modify
@@ -25,7 +25,7 @@
#include <QtGui/QWidget>
#include "typedefs.h"
namespace Tomahawk
namespace Tomahawk
{
/**
@@ -34,11 +34,11 @@ namespace Tomahawk
* - Type (string selector for what this control is matching)
* - Match selector (how to match the type to the input)
* - Input field (the user input field).
*
*
* Each control also has a list of TypeSelectors that comes from the generator, and only one is selected at once.
*
*
*/
class DynamicControl : public QObject
class DynamicControl : public QObject
{
Q_OBJECT
Q_PROPERTY( QString type READ type WRITE setType ) // the generator type associated with this control
@@ -47,67 +47,67 @@ class DynamicControl : public QObject
Q_PROPERTY( QString match READ match WRITE setMatch )
Q_PROPERTY( QString input READ input WRITE setInput )
Q_PROPERTY( QString summary READ summary ) // a summary of the control in phrase form
public:
DynamicControl( const QStringList& typeSelectors = QStringList() );
virtual ~DynamicControl();
/// The current type of this control
QString selectedType() const { return m_selectedType; }
/**
* The match selector widget based on this control's type
*
*
* The control manages the lifetime of the widget.
*/
virtual QWidget* matchSelector() { Q_ASSERT( false ); return 0; }
/**
* The input field widget that is associated with this type
*
*
* The control manages the lifetime of the widget.
*/
virtual QWidget* inputField() { Q_ASSERT( false ); return 0; }
/// The user-readable match value, for showing in read-only playlists
virtual QString matchString() const { Q_ASSERT( false ); return QString(); }
/// the serializable value of the match
virtual QString match() const { Q_ASSERT( false ); return QString(); }
/// the serializable value of the input
virtual QString input() const { Q_ASSERT( false ); return QString(); }
/// the user-readable summary phrase
virtual QString summary() const { Q_ASSERT( false ); return QString(); }
// used by JSON serialization
virtual void setMatch( const QString& /*match*/ ) { Q_ASSERT( false ); }
virtual void setInput( const QString& /*input*/ ) { Q_ASSERT( false ); }
/// All the potential type selectors for this control
QStringList typeSelectors() const { return m_typeSelectors; }
QString id() {
if( m_id.isEmpty() )
m_id = uuid();
return m_id;
};
void setId( const QString& id ) { m_id = id; }
void setType( const QString& type ) { m_type = type; }
QString type() const { return m_type; }
signals:
void changed();
public slots:
/**
* Sets the type to the newly specified one. Note that this will update the matchSelector
* and inputField widgets, so you should fetch the new widgets for use immediately.
*/
virtual void setSelectedType( const QString& selectedType ) { m_selectedType = selectedType; }
protected:
// Private constructor, you can't make one. Get it from your Generator.
explicit DynamicControl( const QString& selectedType, const QStringList& typeSelectors, QObject* parent = 0 );
private:
QString m_type;
QString m_selectedType;

View File

@@ -24,7 +24,7 @@
#include "database/databasecommand.h"
#include "database/databasecommand_createdynamicplaylist.h"
#include "database/databasecommand_setdynamicplaylistrevision.h"
#include "database/databasecommand_loaddynamicplaylist.h"
#include "database/databasecommand_loaddynamicplaylistentries.h"
#include "database/databasecommand_deletedynamicplaylist.h"
#include "tomahawksettings.h"
#include "utils/logger.h"
@@ -221,7 +221,7 @@ DynamicPlaylist::loadRevision( const QString& rev )
// qDebug() << Q_FUNC_INFO << "Loading with:" << ( rev.isEmpty() ? currentrevision() : rev );
setBusy( true );
DatabaseCommand_LoadDynamicPlaylist* cmd = new DatabaseCommand_LoadDynamicPlaylist( rev.isEmpty() ? currentrevision() : rev );
DatabaseCommand_LoadDynamicPlaylistEntries* cmd = new DatabaseCommand_LoadDynamicPlaylistEntries( rev.isEmpty() ? currentrevision() : rev );
if( m_generator->mode() == OnDemand ) {
connect( cmd, SIGNAL( done( QString,

View File

@@ -36,6 +36,8 @@ class DatabaseCollection;
namespace Tomahawk {
class DatabaseCommand_LoadDynamicPlaylist;
/**
* Subclass of playlist that adds the information needed to store a dynamic playlist.
* It uses normal PlaylistEntries but also has a mode, a generator, and a list of controls
@@ -70,6 +72,7 @@ class DLLEXPORT DynamicPlaylist : public Playlist
friend class ::DatabaseCommand_SetDynamicPlaylistRevision;
friend class ::DatabaseCommand_CreateDynamicPlaylist;
friend class Tomahawk::DatabaseCommand_LoadDynamicPlaylist;
friend class ::DatabaseCollection; /// :-(
public:

View File

@@ -1,5 +1,5 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
*
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
*
* Tomahawk is free software: you can redistribute it and/or modify
@@ -20,6 +20,7 @@
#define COLLAPSIBLE_CONTROLS_H
#include "typedefs.h"
#include "source.h"
#include <QWidget>
@@ -42,35 +43,35 @@ public:
CollapsibleControls( QWidget* parent );
CollapsibleControls( const dynplaylist_ptr& playlist, bool isLocal, QWidget* parent = 0 );
virtual ~CollapsibleControls();
void setControls( const dynplaylist_ptr& playlist, bool isLocal );
QList< DynamicControlWrapper* > controls() const;
virtual QSize sizeHint() const;
signals:
void controlsChanged();
void controlChanged( const Tomahawk::dyncontrol_ptr& control );
private slots:
void toggleCollapse();
void onAnimationStep( int );
void onAnimationFinished();
private:
void init();
dynplaylist_ptr m_dynplaylist;
QStackedLayout* m_layout;
DynamicControlList* m_controls;
bool m_isLocal;
QWidget* m_summaryWidget;
QHBoxLayout* m_summaryLayout;
ElidedLabel* m_summary;
QStackedLayout* m_expandL;
QToolButton* m_summaryExpand;
// animations!
QTimeLine* m_timeline;
int m_animHeight;

View File

@@ -24,6 +24,7 @@
#include "contextMenu.h"
#include "playlistitemdelegate.h"
#include "album.h"
#include "dllmacro.h"

View File

@@ -0,0 +1,94 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "SocialPlaylistWidget.h"
#include "ui_SocialPlaylistWidget.h"
#include "database/databasecommand_loaddynamicplaylist.h"
#include "database/database.h"
#include "sourcelist.h"
#define COOLPLAYLIST_GUID "TOMAHAWK_COOLPLAYLISTOHAI_GUID"
using namespace Tomahawk;
SocialPlaylistWidget::SocialPlaylistWidget ( QWidget* parent )
: QWidget ( parent )
, ui( new Ui_SocialPlaylistWidget )
, m_coolQuery1Model( new PlaylistModel( this ) )
{
ui->setupUi( this );
ui->playlistView->setPlaylistModel( m_coolQuery1Model );
load();
}
SocialPlaylistWidget::~SocialPlaylistWidget()
{
}
void
SocialPlaylistWidget::load()
{
// Load the pre-baked custom playlists that we are going to show.
// They also might not exist yet if this the first time this is shown, so then we create them.
DatabaseCommand_LoadDynamicPlaylist* cmd = new DatabaseCommand_LoadDynamicPlaylist( SourceList::instance()->getLocal(), COOLPLAYLIST_GUID, 0 );
connect( cmd, SIGNAL( dynamicPlaylistLoaded( Tomahawk::dynplaylist_ptr ) ), this, SLOT( dynamicPlaylistLoaded( Tomahawk::dynplaylist_ptr ) ) );
connect( cmd, SIGNAL( done() ), this, SLOT( dynamicPlaylistLoadDone() ) );
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>( cmd ) );
}
PlaylistInterface*
SocialPlaylistWidget::playlistInterface() const
{
return ui->playlistView->proxyModel();
}
void
SocialPlaylistWidget::dynamicPlaylistLoaded ( const dynplaylist_ptr& ptr )
{
m_coolQuery1 = ptr;
tLog() << "SocialPlaylistWidget got dynplaylist loaded with currev: " << m_coolQuery1->currentrevision();
connect( m_coolQuery1.data(), SIGNAL( dynamicRevisionLoaded( Tomahawk::DynamicPlaylistRevision ) ), this, SLOT( playlistRevisionLoaded( Tomahawk::DynamicPlaylistRevision ) ) );
m_coolQuery1->loadRevision( m_coolQuery1->currentrevision() );
}
void
SocialPlaylistWidget::playlistRevisionLoaded( Tomahawk::DynamicPlaylistRevision )
{
m_coolQuery1Model->loadPlaylist( m_coolQuery1 );
}
void
SocialPlaylistWidget::dynamicPlaylistLoadDone()
{
if ( m_coolQuery1.isNull() ) /// Load failed so we need to create the playlist, doesn't exist yet
{
tLog() << "SocialPlaylistWidget didn't find the magic dynamic playlist, creating!";
createPlaylist();
}
}
void
SocialPlaylistWidget::createPlaylist()
{
// TODO
}

View File

@@ -0,0 +1,96 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
/**
* \class SocialPlaylistWidget
* \brief ViewPage, which displays some interesting lists of songs mined from the database
*
* This Tomahawk ViewPage displays various interesting database searches that expose cool
* lists of songs. It is accessed from the sidebar, and contains a few custom-created DatabaseGenerator-backed
* playlists.
*
*/
#ifndef SOCIALPLAYLISTWIDGET_H
#define SOCIALPLAYLISTWIDGET_H
#include <QWidget>
#include "viewpage.h"
#include "dllmacro.h"
#include "typedefs.h"
#include "playlist/dynamic/DynamicPlaylist.h"
#include "source.h"
class PlaylistModel;
class TreeModel;
class Ui_SocialPlaylistWidget;
namespace Tomahawk
{
class DLLEXPORT SocialPlaylistWidget : public QWidget, public Tomahawk::ViewPage
{
Q_OBJECT
public:
SocialPlaylistWidget( QWidget* parent = 0 );
~SocialPlaylistWidget();
virtual QWidget* widget() { return this; }
virtual Tomahawk::PlaylistInterface* playlistInterface() const;
virtual QString title() const { return m_title; }
virtual QString description() const { return m_description; }
virtual QString longDescription() const { return m_longDescription; }
virtual QPixmap pixmap() const { if ( m_pixmap.isNull() ) return Tomahawk::ViewPage::pixmap(); else return m_pixmap; }
virtual bool showStatsBar() const { return false; }
virtual bool jumpToCurrentTrack() { return false; }
signals:
void longDescriptionChanged( const QString& description );
void descriptionChanged( const QString& description );
void pixmapChanged( const QPixmap& pixmap );
private slots:
void dynamicPlaylistLoaded( const Tomahawk::dynplaylist_ptr& ptr );
void playlistRevisionLoaded ( Tomahawk::DynamicPlaylistRevision );
void dynamicPlaylistLoadDone();
private:
void load();
void createPlaylist();
Ui_SocialPlaylistWidget *ui;
Tomahawk::dynplaylist_ptr m_coolQuery1;
PlaylistModel* m_coolQuery1Model;
QString m_title;
QString m_description;
QString m_longDescription;
QPixmap m_pixmap;
};
}
#endif // SOCIALPLAYLISTWIDGET_H

View File

@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SocialPlaylistWidget</class>
<widget class="QWidget" name="SocialPlaylistWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="margin">
<number>4</number>
</property>
<item>
<widget class="HeaderLabel" name="socialLabel">
<property name="text">
<string>Social Stuff!</string>
</property>
</widget>
</item>
<item>
<widget class="PlaylistView" name="playlistView"/>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>PlaylistView</class>
<extends>QTreeView</extends>
<header>playlist/playlistview.h</header>
</customwidget>
<customwidget>
<class>HeaderLabel</class>
<extends>QLabel</extends>
<header location="global">widgets/HeaderLabel.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View File

@@ -23,6 +23,7 @@
#include "genericpageitems.h"
#include "utils/tomahawkutils.h"
#include "utils/logger.h"
#include <widgets/SocialPlaylistWidget.h>
/// CollectionItem
@@ -35,12 +36,21 @@ CollectionItem::CollectionItem( SourcesModel* mdl, SourceTreeItem* parent, cons
, m_stations( 0 )
, m_tempItem( 0 )
, m_sourceInfoItem( 0 )
, m_coolPlaylistsItem( 0 )
, m_curTempPage( 0 )
, m_sourceInfoPage( 0 )
, m_coolPlaylistsPage( 0 )
{
if( m_source.isNull() ) { // super collection
connect( ViewManager::instance(), SIGNAL( tempPageActivated( Tomahawk::ViewPage*) ), this, SLOT( tempPageActivated( Tomahawk::ViewPage* ) ) );
m_coolPlaylistsItem = new GenericPageItem( model(), this, tr( "Cool Stuff" ), QIcon( RESPATH "images/new-additions.png" ),
boost::bind( &CollectionItem::coolPlaylistsClicked, this ),
boost::bind( &CollectionItem::getCoolPlaylistsPage, this )
);
m_coolPlaylistsItem->setSortValue( 200 );
return;
}
@@ -50,6 +60,8 @@ CollectionItem::CollectionItem( SourcesModel* mdl, SourceTreeItem* parent, cons
);
m_sourceInfoItem->setSortValue( -300 );
// create category items if there are playlists to show, or stations to show
QList< playlist_ptr > playlists = source->collection()->playlists();
QList< dynplaylist_ptr > autoplaylists = source->collection()->autoPlaylists();
@@ -338,3 +350,20 @@ CollectionItem::getSourceInfoPage() const
{
return m_sourceInfoPage;
}
ViewPage*
CollectionItem::coolPlaylistsClicked()
{
if( !m_source.isNull() )
return 0;
m_coolPlaylistsPage = new SocialPlaylistWidget( ViewManager::instance()->widget() );
ViewManager::instance()->show( m_coolPlaylistsPage );
return m_coolPlaylistsPage;
}
ViewPage*
CollectionItem::getCoolPlaylistsPage() const
{
return m_coolPlaylistsPage;
}

View File

@@ -58,6 +58,9 @@ private slots:
Tomahawk::ViewPage* sourceInfoClicked();
Tomahawk::ViewPage* getSourceInfoPage() const;
Tomahawk::ViewPage* coolPlaylistsClicked();
Tomahawk::ViewPage* getCoolPlaylistsPage() const;
private:
void playlistsAddedInternal( SourceTreeItem* parent, const QList< Tomahawk::dynplaylist_ptr >& playlists );
template< typename T >
@@ -69,8 +72,11 @@ private:
GenericPageItem* m_tempItem;
GenericPageItem* m_sourceInfoItem;
GenericPageItem* m_coolPlaylistsItem;
Tomahawk::ViewPage* m_curTempPage;
Tomahawk::ViewPage* m_sourceInfoPage;
Tomahawk::ViewPage* m_coolPlaylistsPage;
};