1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-06-01 21:45:05 +02:00

Merge branch 'databasegenerator'

This commit is contained in:
Leo Franchi 2011-08-06 14:41:59 -04:00
commit d69b10c148
61 changed files with 1851 additions and 346 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

@ -0,0 +1,8 @@
-- Script to migate from db version 25 to 26.
-- Added the "autoload" column to dynamic_playlist
--
ALTER TABLE dynamic_playlist ADD COLUMN autoload BOOLEAN DEFAULT 1;
UPDATE settings SET v = '26' WHERE k == 'schema_version';

View File

@ -83,6 +83,7 @@
<file>./data/images/automatic-playlist.png</file>
<file>./data/images/station.png</file>
<file>./data/images/new-additions.png</file>
<file>./data/images/loved_playlist.png</file>
<file>./data/stylesheets/topbar-radiobuttons.css</file>
<file>./data/icons/tomahawk-icon-16x16.png</file>
<file>./data/icons/tomahawk-icon-32x32.png</file>
@ -99,6 +100,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
@ -83,6 +84,7 @@ set( libSources
database/databasecommand_clientauthvalid.cpp
database/databasecommand_socialaction.cpp
database/databasecommand_loadsocialactions.cpp
database/databasecommand_genericselect.cpp
database/database.cpp
infosystem/infosystemcache.cpp
@ -118,6 +120,7 @@ set( libSources
playlist/albumitemdelegate.cpp
playlist/albumview.cpp
playlist/artistview.cpp
playlist/customplaylistview.cpp
playlist/topbar/topbar.cpp
playlist/topbar/clearbutton.cpp
@ -144,6 +147,8 @@ set( libSources
playlist/dynamic/widgets/CollapsibleControls.cpp
playlist/dynamic/widgets/DynamicSetupWidget.cpp
playlist/dynamic/widgets/LoadingSpinner.cpp
playlist/dynamic/database/DatabaseControl.cpp
playlist/dynamic/database/DatabaseGenerator.cpp
network/bufferiodevice.cpp
network/msgprocessor.cpp
@ -177,6 +182,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 +258,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
@ -259,6 +266,7 @@ set( libHeaders
database/databasecommand_clientauthvalid.h
database/databasecommand_socialaction.h
database/databasecommand_loadsocialactions.h
database/databasecommand_genericselect.h
infosystem/infosystem.h
infosystem/infosystemworker.h
@ -303,6 +311,7 @@ set( libHeaders
playlist/albumitemdelegate.h
playlist/albumview.h
playlist/artistview.h
playlist/customplaylistview.h
playlist/topbar/topbar.h
playlist/topbar/clearbutton.h
@ -329,6 +338,8 @@ set( libHeaders
playlist/dynamic/widgets/CollapsibleControls.h
playlist/dynamic/widgets/DynamicSetupWidget.h
playlist/dynamic/widgets/LoadingSpinner.h
playlist/dynamic/database/DatabaseControl.h
playlist/dynamic/database/DatabaseGenerator.h
utils/querylabel.h
utils/elidedlabel.h
@ -350,6 +361,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 +384,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
@ -432,8 +445,8 @@ IF( APPLE )
utils/tomahawkutils_mac.mm )
SET( libHeaders ${libHeaders}
infosystem/infoplugins/mac/adiumplugin.h
widgets/maclineedit.h )
infosystem/infoplugins/mac/adium.h
infosystem/infoplugins/mac/adiumplugin.h )
SET( OS_SPECIFIC_LINK_LIBRARIES
${OS_SPECIFIC_LINK_LIBRARIES}

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

@ -31,7 +31,6 @@ DatabaseCommand_CreatePlaylist::DatabaseCommand_CreatePlaylist( QObject* parent
: DatabaseCommandLoggable( parent )
, m_report( true )
{
qDebug() << Q_FUNC_INFO << "def";
}
@ -41,7 +40,6 @@ DatabaseCommand_CreatePlaylist::DatabaseCommand_CreatePlaylist( const source_ptr
, m_playlist( playlist )
, m_report( false ) //this ctor used when creating locally, reporting done elsewhere
{
qDebug() << Q_FUNC_INFO;
}
@ -63,7 +61,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();
@ -83,7 +81,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() );
@ -124,7 +121,6 @@ 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();
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

@ -0,0 +1,115 @@
/* === 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_genericselect.h"
#include "databaseimpl.h"
#include "utils/logger.h"
#include <sourcelist.h>
#include <artist.h>
#include <album.h>
using namespace Tomahawk;
DatabaseCommand_GenericSelect::DatabaseCommand_GenericSelect( const QString& sqlSelect, QueryType type, int limit, QObject* parent )
: DatabaseCommand( parent )
, m_sqlSelect( sqlSelect )
, m_queryType( type )
, m_limit( limit )
{
}
void
DatabaseCommand_GenericSelect::exec( DatabaseImpl* dbi )
{
TomahawkSqlQuery query = dbi->newquery();
query.prepare( QString( "%1 %2;" ).arg( m_sqlSelect ).arg( m_limit > -1 ? QString( " LIMIT %1" ).arg( m_limit ) : QString() ) );
query.exec();
QList< query_ptr > queries;
QList< artist_ptr > arts;
QList< album_ptr > albs;
// Expecting
while ( query.next() )
{
query_ptr qry;
artist_ptr artist;
album_ptr album;
if ( m_queryType == Track )
{
QString artist, track;
track = query.value( 0 ).toString();
artist = query.value( 1 ).toString();
qry = Tomahawk::Query::get( artist, track, QString(), uuid(), true ); // Only auto-resolve non-local results
} else if ( m_queryType == Artist )
{
int artistId = query.value( 0 ).toInt();
QString artistName = query.value( 1 ).toString();
artist = Tomahawk::Artist::get( artistId, artistName );
} else if ( m_queryType == Album )
{
int albumId = query.value( 0 ).toInt();
QString albumName = query.value( 1 ).toString();
int artistId = query.value( 2 ).toInt();
QString artistName = query.value( 3 ).toString();
artist = Tomahawk::Artist::get( artistId, artistName );
album = Tomahawk::Album::get( albumId, albumName, artist );
}
QVariantList extraData;
int count = 2;
while ( query.value( count ).isValid() )
{
extraData << query.value( count );
count++;
}
if ( m_queryType == Track )
{
if ( !extraData.isEmpty() )
qry->setProperty( "data", extraData );
queries << qry;
} else if ( m_queryType == Artist )
{
if ( !extraData.isEmpty() )
artist->setProperty( "data", extraData );
arts << artist;
} else if ( m_queryType == Album )
{
if ( !extraData.isEmpty() )
album->setProperty( "data", extraData );
albs << album;
}
}
if ( m_queryType == Track )
emit tracks( queries );
else if ( m_queryType == Artist )
emit artists( arts );
else if ( m_queryType == Album )
emit albums( albs );
}

View File

@ -0,0 +1,80 @@
/* === 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_GENERICSELECT_H
#define DATABASECOMMAND_GENERICSELECT_H
#include <QVariantMap>
#include "databasecommand.h"
#include "source.h"
#include "typedefs.h"
#include "dllmacro.h"
/**
* This dbcmd takes a generic SELECT command that operates on the database and returns a list of query_ptrs
* that match.
*
* In order for the conversion to query_ptr to work, the SELECT command should select the following items:
*
* track query:
* track.name, artist.name [, optional extra values ]
*
* artist query:
* artist.id, artist.name [, optional extra values ]
*
* album query:
* album.id, album.name, artist.id, artist.name [, optional extra values ]
*
* Any extra values in the resultset will be returned as a QVariantList attached to the "data" property of each query_ptr
*
* Notes:
* * Do not trail your SQL command with ;
* * Do not use the LIMIT command if you pass limitResults > -1
*
*/
class DLLEXPORT DatabaseCommand_GenericSelect : public DatabaseCommand
{
Q_OBJECT
public:
enum QueryType {
Track,
Artist,
Album
};
explicit DatabaseCommand_GenericSelect( const QString& sqlSelect, QueryType type, int limitResults = -1, QObject* parent = 0 );
virtual void exec( DatabaseImpl* lib );
virtual bool doesMutates() const { return false; }
virtual QString commandname() const { return "genericselect"; }
signals:
void tracks( const QList< Tomahawk::query_ptr >& tracks );
void artists( const QList< Tomahawk::artist_ptr >& artists );
void albums( const QList< Tomahawk::album_ptr >& albums );
private:
QString m_sqlSelect;
QueryType m_queryType;
int m_limit;
};
#endif // DATABASECOMMAND_GENERICSELECT_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
@ -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
@ -40,6 +40,7 @@ DatabaseCommand_SetDynamicPlaylistRevision::DatabaseCommand_SetDynamicPlaylistRe
, m_type( type )
, m_mode( mode )
, m_controls( controls )
, m_playlist( 0 )
{
}
@ -56,6 +57,7 @@ DatabaseCommand_SetDynamicPlaylistRevision::DatabaseCommand_SetDynamicPlaylistRe
, m_type( type )
, m_mode( mode )
, m_controls( controls )
, m_playlist( 0 )
{
}
@ -82,10 +84,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,27 +96,34 @@ 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() );
if ( playlist.isNull() )
playlist = source()->collection()->station( playlistguid() );
// UGH we don't have a sharedptr from DynamicPlaylist+
DynamicPlaylist* rawPl = playlist.data();
if( playlist.isNull() ) // if it's neither an auto or station, it must not be auto-loaded, so we MUST have been told about it directly
rawPl = m_playlist;
// workaround a bug in pre-0.1.0 tomahawks. they created dynamic playlists in OnDemand mode *always*, and then set the mode to the real one.
// now that we separate them, if we get them as one and then get a changed mode, the playlist ends up in the wrong bucket in Collection.
// so here we fix it if we have to.
// HACK
qDebug() << "Does this need FIXING?" << playlist->mode() << source()->collection()->autoPlaylist( playlistguid() ).isNull() << source()->collection()->station( playlistguid() ).isNull();
if( playlist->mode() == Static && source()->collection()->autoPlaylist( playlistguid() ).isNull() ) // should be here
tDebug() << "Does this need the 0.3->0.1 playlist category hack fix?" << ( rawPl->mode() == Static && source()->collection()->autoPlaylist( playlistguid() ).isNull() )
<< ( rawPl->mode() == OnDemand && source()->collection()->station( playlistguid() ).isNull() )
<< rawPl->mode() << source()->collection()->autoPlaylist( playlistguid() ).isNull() << source()->collection()->station( playlistguid() ).isNull();
if( rawPl->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
else if ( rawPl->mode() == OnDemand && source()->collection()->station( playlistguid() ).isNull() ) // should be here
source()->collection()->moveAutoToStation( playlistguid() );
if ( playlist.isNull() )
if ( rawPl == 0 )
{
qDebug() <<"Got null playlist with guid:" << playlistguid() << "from source and collection:" << source()->friendlyName() << source()->collection()->name() << "and mode is static?:" << (m_mode == Static);
Q_ASSERT( !playlist.isNull() );
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( false );
return;
}
if ( !m_controlsV.isEmpty() && m_controls.isEmpty() )
@ -125,13 +133,13 @@ DatabaseCommand_SetDynamicPlaylistRevision::postCommitHook()
controlMap << v.toMap();
if ( m_mode == OnDemand )
playlist->setRevision( newrev(),
rawPl->setRevision( newrev(),
true, // this *is* the newest revision so far
m_type,
controlMap,
m_applied );
else
playlist->setRevision( newrev(),
rawPl->setRevision( newrev(),
orderedentriesguids,
m_previous_rev_orderedguids,
m_type,
@ -143,13 +151,13 @@ DatabaseCommand_SetDynamicPlaylistRevision::postCommitHook()
else
{
if ( m_mode == OnDemand )
playlist->setRevision( newrev(),
rawPl->setRevision( newrev(),
true, // this *is* the newest revision so far
m_type,
m_controls,
m_applied );
else
playlist->setRevision( newrev(),
rawPl->setRevision( newrev(),
orderedentriesguids,
m_previous_rev_orderedguids,
m_type,
@ -205,7 +213,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 +250,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 = ?" );
@ -252,3 +260,9 @@ DatabaseCommand_SetDynamicPlaylistRevision::exec( DatabaseImpl* lib )
query2.exec();
}
}
void
DatabaseCommand_SetDynamicPlaylistRevision::setPlaylist( DynamicPlaylist* pl )
{
m_playlist = pl;
}

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,31 +58,36 @@ 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; }
void setPlaylist( DynamicPlaylist* pl ); // raw pointer b/c we don't have the shared pointer from inside the shared pointer
private:
QString m_type;
GeneratorMode m_mode;
QList< dyncontrol_ptr > m_controls;
QList< QVariant > m_controlsV;
// ARG i hate sharedpointers sometimes
DynamicPlaylist* m_playlist; // Only used if setting revision of a non-autoloaded playlist, as those aren't able to be looked up by guid
};
#endif // DATABASECOMMAND_SETDYNAMICPLAYLISTREVISION_H

View File

@ -6,7 +6,7 @@
* 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
@ -20,7 +20,7 @@
#define DATABASECOMMAND_SOCIALACTION_H
#include <QDateTime>
#include "database/databasecommand.h"
#include "database/databasecommandloggable.h"
#include "sourcelist.h"
#include "typedefs.h"
@ -31,43 +31,45 @@
/**
* \class DatabaseCommand_SocialAction
* \brief Database command used to write social actions to database.
*
*
* This Database command allows Tomahawk to write social actions to
* the local database. These social actions can be interfaced with social
* networking API's such as LastFm, Facebook, or Twitter to allow the user
* to sync these actions with their accounts on these sites.
*
*
* \see DatabaseCommand_LoadSocialActions
*/
class DLLEXPORT DatabaseCommand_SocialAction : public DatabaseCommand
class DLLEXPORT DatabaseCommand_SocialAction : public DatabaseCommandLoggable
{
Q_OBJECT
Q_PROPERTY( QString action READ action WRITE setAction )
Q_PROPERTY( QString comment READ comment WRITE setComment )
Q_PROPERTY( int timestamp READ timestamp WRITE setTimestamp )
Q_OBJECT
Q_PROPERTY( QString action READ action WRITE setAction )
Q_PROPERTY( QString comment READ comment WRITE setComment )
Q_PROPERTY( int timestamp READ timestamp WRITE setTimestamp )
Q_PROPERTY( QString artist READ artist WRITE setArtist )
Q_PROPERTY( QString track READ track WRITE setTrack )
public:
/**
* \brief Default constructor for DatabaseCommand_SocialAction.
*
*
* Constructs an empty database command for a social action.
*/
explicit DatabaseCommand_SocialAction( QObject* parent = 0 )
: DatabaseCommand( parent )
: DatabaseCommandLoggable( parent )
{}
/**
* \brief Overloaded constructor for DatabaseCommand_SocialAction.
* \param result Pointer to a Tomahawk::Result.
* \param action Name of the social action to be written to the database.
* \param comment Comment associated with this social action.
* \param parent Parent class.
*
*
* Constructor which creates a new database command for the specified social action.
*/
explicit DatabaseCommand_SocialAction( const Tomahawk::result_ptr& result, QString action, QString comment="", QObject* parent = 0 )
: DatabaseCommand( parent ), m_result( result ), m_action( action )
: DatabaseCommandLoggable( parent ), m_result( result ), m_action( action )
{
setSource( SourceList::instance()->getLocal() );
@ -86,12 +88,12 @@ public:
/**
* \brief Executes the database command.
* \param dbi Database instance.
*
*
* This method prepares an sql query to write this social action
* into the local database.
*/
virtual void exec( DatabaseImpl* dbi );
/**
* \brief Triggers a Database Sync.
*/
@ -103,7 +105,7 @@ public:
* \see setArtist()
*/
QString artist() const { return m_artist; }
/**
* \brief Sets the artist name for this database command.
* \param s QString containing the artist name.
@ -117,49 +119,49 @@ public:
* \see setTrack()
*/
QString track() const { return m_track; }
/**
* \brief Sets the track name associated with this database command.
* \param track QString containing the track name.
* \see track()
*/
void setTrack( const QString& track ) { m_track = track; }
/**
* \brief Returns the social action for this database command instance.
* \return QString containing the action name.
* \see setAction()
*/
QString action() const { return m_action; }
/**
* \brief Sets the social actions
* \param a QString containing action to be set in this class.
* \see action()
*/
void setAction( QString a ) { m_action = a; }
/**
* \brief Returns comment associated with this social action.
* \return QString containing comment associated with this social action.
* \see setComment()
*/
QString comment() const { return m_comment; }
/**
* \brief Sets the comment associated with this social action.
* \param com Comment associated with this social action.
* \see comment()
*/
void setComment( const QString& com ) { m_comment = com; }
/**
* \brief Returns the timestamp associated with this social action.
* \return unsigned integer containing timestamp
* \see setTimesetamp()
*/
int timestamp() const { return m_timestamp; }
/**
* \brief Sets the timestamp associated with this social action.
* \param ts unsigned integer associated with this social action.
@ -167,6 +169,8 @@ public:
*/
void setTimestamp( const int ts ) { m_timestamp = ts; }
virtual bool doesMutates() const { return true; }
private:
Tomahawk::result_ptr m_result;

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

@ -59,7 +59,7 @@ public:
int e = t.elapsed();
if ( e >= TOMAHAWK_QUERY_THRESHOLD )
qDebug() << "TomahawkSqlQuery (" << lastQuery() << ") finished in" << t.elapsed() << "ms";
tLog() << "TomahawkSqlQuery (" << lastQuery() << ") finished in" << t.elapsed() << "ms";
return ret;
}
@ -67,11 +67,10 @@ public:
private:
void showError()
{
qDebug()
<< endl << "*** DATABASE ERROR ***" << endl
<< this->lastQuery() << endl
<< "boundValues:" << this->boundValues() << endl
<< this->lastError().text() << endl
tLog() << "\n" << "*** DATABASE ERROR ***" << "\n"
<< this->lastQuery() << "\n"
<< "boundValues:" << this->boundValues() << "\n"
<< this->lastError().text() << "\n"
;
Q_ASSERT( false );
}

View File

@ -20,7 +20,10 @@
#include <QApplication>
#include <QClipboard>
#include <QMimeData>
#include <QUrl>
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkReply>
#include "artist.h"
#include "album.h"
@ -40,10 +43,7 @@
#include "utils/logger.h"
#include "utils/tomahawkutils.h"
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkReply>
#include "utils/jspfloader.h"
#include <QMimeData>
#include "utils/spotifyparser.h"
#include "utils/shortenedlinkparser.h"
@ -205,6 +205,7 @@ GlobalActionManager::parseTomahawkLink( const QString& url )
} else if( u.hasQueryItem( "jspf" ) ) {
QUrl jspf = QUrl::fromUserInput( u.queryItemValue( "jspf" ) );
JSPFLoader* l = new JSPFLoader( true, this );
tDebug() << "Loading jspiff:" << jspf.toString();
l->load( jspf );
connect( l, SIGNAL( ok( Tomahawk::playlist_ptr ) ), ViewManager::instance(), SLOT( show( Tomahawk::playlist_ptr ) ) );

View File

@ -244,7 +244,7 @@ AlbumModel::addCollection( const collection_ptr& collection )
DatabaseCommand_AllAlbums* cmd = new DatabaseCommand_AllAlbums( collection );
connect( cmd, SIGNAL( albums( QList<Tomahawk::album_ptr>, QVariant ) ),
SLOT( onAlbumsAdded( QList<Tomahawk::album_ptr> ) ) );
SLOT( addAlbums( QList<Tomahawk::album_ptr> ) ) );
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>( cmd ) );
@ -266,7 +266,7 @@ AlbumModel::addFilteredCollection( const collection_ptr& collection, unsigned in
cmd->setSortDescending( true );
connect( cmd, SIGNAL( albums( QList<Tomahawk::album_ptr>, QVariant ) ),
SLOT( onAlbumsAdded( QList<Tomahawk::album_ptr> ) ) );
SLOT( addAlbums( QList<Tomahawk::album_ptr> ) ) );
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>( cmd ) );
@ -278,7 +278,7 @@ AlbumModel::addFilteredCollection( const collection_ptr& collection, unsigned in
void
AlbumModel::onAlbumsAdded( const QList<Tomahawk::album_ptr>& albums )
AlbumModel::addAlbums( const QList<Tomahawk::album_ptr>& albums )
{
if ( !albums.count() )
return;
@ -303,6 +303,15 @@ AlbumModel::onAlbumsAdded( const QList<Tomahawk::album_ptr>& albums )
qDebug() << rowCount( QModelIndex() );
}
void
AlbumModel::clear()
{
beginResetModel();
delete m_rootItem;
m_rootItem = new AlbumItem( 0, this );
endResetModel();
}
void
AlbumModel::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output )

View File

@ -66,6 +66,8 @@ public:
void addCollection( const Tomahawk::collection_ptr& collection );
void addFilteredCollection( const Tomahawk::collection_ptr& collection, unsigned int amount, DatabaseCommand_AllAlbums::SortOrder order );
void clear();
virtual QString title() const { return m_title; }
virtual QString description() const { return m_description; }
virtual void setTitle( const QString& title ) { m_title = title; }
@ -85,6 +87,8 @@ public slots:
virtual void setRepeatMode( Tomahawk::PlaylistInterface::RepeatMode /*mode*/ ) {}
virtual void setShuffled( bool /*shuffled*/ ) {}
void addAlbums( const QList<Tomahawk::album_ptr>& albums );
signals:
void repeatModeChanged( Tomahawk::PlaylistInterface::RepeatMode mode );
void shuffleModeChanged( bool enabled );
@ -94,7 +98,6 @@ signals:
protected:
private slots:
void onAlbumsAdded( const QList<Tomahawk::album_ptr>& albums );
void onDataChanged();
void infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output );

View File

@ -0,0 +1,107 @@
/* === 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 "customplaylistview.h"
#include "database/databasecommand_genericselect.h"
#include "database/database.h"
#include "utils/tomahawkutils.h"
using namespace Tomahawk;
CustomPlaylistView::CustomPlaylistView( CustomPlaylistView::PlaylistType type, const source_ptr& s, QWidget* parent )
: PlaylistView ( parent )
, m_type( type )
, m_source( s )
, m_model( new PlaylistModel( this ) )
{
// Generate the tracks, add them to the playlist
setFrameShape( QFrame::NoFrame );
setAttribute( Qt::WA_MacShowFocusRect, 0 );
setPlaylistModel( m_model );
generateTracks();
}
void
CustomPlaylistView::generateTracks()
{
QString sql;
switch ( m_type )
{
// TODO
case SourceLovedTracks:
sql = QString( "SELECT track.name, artist.name, COUNT(*) as counter "
"FROM social_attributes, track, artist "
"WHERE social_attributes.id = track.id AND artist.id = track.artist AND social_attributes.k = 'Love' AND source IS NULL "
"GROUP BY track.id "
"ORDER BY counter DESC " );
break;
case AllLovedTracks:
sql = QString( "SELECT track.name, artist.name, source, COUNT(*) as counter "
"FROM social_attributes, track, artist "
"WHERE social_attributes.id = track.id AND artist.id = track.artist AND social_attributes.k = 'Love' "
"GROUP BY track.id "
"ORDER BY counter DESC " );
break;
}
DatabaseCommand_GenericSelect* cmd = new DatabaseCommand_GenericSelect( sql, DatabaseCommand_GenericSelect::Track, 60, 0 );
connect( cmd, SIGNAL( tracks( QList<Tomahawk::query_ptr> ) ), this, SLOT( tracksGenerated( QList<Tomahawk::query_ptr> ) ) );
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>( cmd ) );
}
void
CustomPlaylistView::tracksGenerated( QList< query_ptr > tracks )
{
foreach ( const query_ptr& q, tracks )
m_model->append( q );
}
QString
CustomPlaylistView::title() const
{
if ( m_source.isNull() )
return tr( "Top Loved Tracks" );
else
return tr( "Your Loved Tracks" );
}
QString
CustomPlaylistView::description() const
{
if ( m_source.isNull() )
return tr( "The most loved tracks from all your friends" );
else
return tr( "Your top loved tracks" );
}
QString
CustomPlaylistView::longDescription() const
{
return QString();
}
QPixmap
CustomPlaylistView::pixmap() const
{
return QPixmap( RESPATH "images/loved_playlist.png" );
}

View File

@ -0,0 +1,64 @@
/* === 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 CUSTOMPLAYLISTVIEW_H
#define CUSTOMPLAYLISTVIEW_H
#include "playlistview.h"
#include "dllmacro.h"
namespace Tomahawk
{
class DLLEXPORT CustomPlaylistView : public PlaylistView
{
Q_OBJECT
public:
enum PlaylistType {
SourceLovedTracks,
AllLovedTracks
};
explicit CustomPlaylistView( PlaylistType type, const source_ptr& s, QWidget* parent = 0 );
virtual ~CustomPlaylistView() {}
virtual bool showFilter() const { return false; }
virtual bool showStatsBar() const { return false; }
virtual QString title() const;
virtual QPixmap pixmap() const;
virtual QString description() const;
virtual QString longDescription() const;
virtual bool isTemporaryPage() const { return false; }
private slots:
void tracksGenerated( QList<Tomahawk::query_ptr> tracks );
private:
void generateTracks();
PlaylistType m_type;
source_ptr m_source;
PlaylistModel* m_model;
};
}
#endif // CUSTOMPLAYLISTVIEW_H

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"
@ -59,6 +59,7 @@ DynamicPlaylist::DynamicPlaylist ( const Tomahawk::source_ptr& src,
int lastmod,
const QString& guid )
: Playlist( src, currentrevision, title, info, creator, createdOn, shared, lastmod, guid )
, m_autoLoad( false )
{
// qDebug() << "Creating Dynamic Playlist 1";
// TODO instantiate generator
@ -75,8 +76,10 @@ DynamicPlaylist::DynamicPlaylist ( const Tomahawk::source_ptr& author,
const QString& creator,
const QString& type,
GeneratorMode mode,
bool shared )
bool shared,
bool autoLoad )
: Playlist ( author, guid, title, info, creator, shared )
, m_autoLoad( autoLoad )
{
// qDebug() << "Creating Dynamic Playlist 2";
m_generator = geninterface_ptr( GeneratorFactory::create( type ) );
@ -127,14 +130,17 @@ DynamicPlaylist::create( const Tomahawk::source_ptr& author,
const QString& creator,
GeneratorMode mode,
bool shared,
const QString& type )
const QString& type,
bool autoLoad
)
{
dynplaylist_ptr dynplaylist = dynplaylist_ptr( new DynamicPlaylist( author, guid, title, info, creator, type, mode, shared ) );
dynplaylist_ptr dynplaylist = dynplaylist_ptr( new DynamicPlaylist( author, guid, title, info, creator, type, mode, shared, autoLoad ) );
DatabaseCommand_CreateDynamicPlaylist* cmd = new DatabaseCommand_CreateDynamicPlaylist( author, dynplaylist );
DatabaseCommand_CreateDynamicPlaylist* cmd = new DatabaseCommand_CreateDynamicPlaylist( author, dynplaylist, autoLoad );
connect( cmd, SIGNAL(finished()), dynplaylist.data(), SIGNAL(created()) );
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>(cmd) );
dynplaylist->reportCreated( dynplaylist );
if( autoLoad )
dynplaylist->reportCreated( dynplaylist );
return dynplaylist;
}
@ -192,6 +198,9 @@ DynamicPlaylist::createNewRevision( const QString& newrev,
type,
Static,
controls );
if( !m_autoLoad )
cmd->setPlaylist( this );
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>( cmd ) );
}
@ -222,6 +231,9 @@ DynamicPlaylist::createNewRevision( const QString& newrev,
type,
OnDemand,
controls );
if( !m_autoLoad )
cmd->setPlaylist( this );
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>( cmd ) );
}
@ -232,7 +244,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
@ -79,9 +81,11 @@ class DLLEXPORT DynamicPlaylist : public Playlist
// :-( int becuase qjson chokes on my enums
Q_PROPERTY( int mode WRITE setMode READ mode )
Q_PROPERTY( QString type WRITE setType READ type )
Q_PROPERTY( bool autoLoad READ autoLoad )
friend class ::DatabaseCommand_SetDynamicPlaylistRevision;
friend class ::DatabaseCommand_CreateDynamicPlaylist;
friend class Tomahawk::DatabaseCommand_LoadDynamicPlaylist;
friend class ::DatabaseCollection; /// :-(
public:
@ -95,7 +99,9 @@ public:
const QString& creator,
GeneratorMode mode,
bool shared,
const QString& type = QString() );
const QString& type = QString(),
bool autoLoad = true
);
static bool remove( const dynplaylist_ptr& playlist );
virtual void loadRevision( const QString& rev = "" );
@ -104,6 +110,7 @@ public:
int mode() const;
QString type() const;
geninterface_ptr generator() const;
bool autoLoad() const { return m_autoLoad; }
// Creates a new revision from the playlist in memory. Use this is you change the controls or
// mode of a playlist and want to save it to db/others.
@ -195,12 +202,15 @@ private:
const QString& creator,
const QString& type,
GeneratorMode mode,
bool shared );
bool shared,
bool autoLoad = true );
void checkRevisionQueue();
QList< dyncontrol_ptr > variantsToControl( const QList< QVariantMap >& controlsV );
geninterface_ptr m_generator;
bool m_autoLoad;
QQueue<DynQueueItem> m_revisionQueue;
};

View File

@ -0,0 +1,147 @@
/* === 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 "DatabaseControl.h"
using namespace Tomahawk;
DatabaseControl::DatabaseControl( const QString& selectedType, const QStringList& typeSelectors, QObject* parent )
: DynamicControl ( selectedType.isEmpty() ? "Artist" : selectedType, typeSelectors, parent )
{
setType( "database" );
m_editingTimer.setInterval( 500 ); //timeout to edits
m_editingTimer.setSingleShot( true );
connect( &m_editingTimer, SIGNAL( timeout() ), this, SLOT( editTimerFired() ) );
m_delayedEditTimer.setInterval( 250 ); // additional timer for "just typing" without enter or focus change
m_delayedEditTimer.setSingleShot( true );
connect( &m_delayedEditTimer, SIGNAL( timeout() ), &m_editingTimer, SLOT( start() ) );
}
DatabaseControl::DatabaseControl( const QString& sql, const QString& summary, const QStringList& typeSelectors, QObject* parent )
: DynamicControl ( "SQL", typeSelectors )
, m_sql( sql )
, m_sqlSummary( summary )
{
setType( "database" );
}
QString DatabaseControl::input() const
{
// TODO
return QString();
}
QWidget* DatabaseControl::inputField()
{
return 0;
}
QString DatabaseControl::match() const
{
return m_matchData;
}
QWidget* DatabaseControl::matchSelector()
{
return 0;
}
QString DatabaseControl::matchString() const
{
return m_matchString;
}
void DatabaseControl::setInput ( const QString& input )
{
// TODO
updateWidgets();
}
void DatabaseControl::setMatch ( const QString& match )
{
m_matchData = match;
updateWidgets();
}
void DatabaseControl::setSelectedType ( const QString& type )
{
if ( type != selectedType() ) {
if ( !m_input.isNull() )
delete m_input.data();
if ( !m_match.isNull() )
delete m_match.data();
Tomahawk::DynamicControl::setSelectedType ( type );
updateWidgets();
updateData();
// qDebug() << "Setting new type, set data to:" << m_data.first << m_data.second;
}
}
void DatabaseControl::editingFinished()
{
}
void DatabaseControl::editTimerFired()
{
}
void DatabaseControl::updateData()
{
}
void DatabaseControl::updateWidgets()
{
}
void DatabaseControl::updateWidgetsFromData()
{
}
void DatabaseControl::calculateSummary()
{
if( !m_sqlSummary.isEmpty() )
return;
}
QString
DatabaseControl::sql() const
{
return m_sql;
}
QString
DatabaseControl::summary() const
{
if( !m_sqlSummary.isEmpty() )
return m_sqlSummary;
return m_summary;
}

View File

@ -0,0 +1,81 @@
/* === 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 DATABASE_CONTROL_H
#define DATABASE_CONTROL_H
#include "dynamic/DynamicControl.h"
#include <QTimer>
namespace Tomahawk
{
class DatabaseControl : public DynamicControl
{
Q_OBJECT
public:
virtual QWidget* inputField();
virtual QWidget* matchSelector();
virtual QString input() const;
virtual QString match() const;
virtual QString matchString() const;
virtual QString summary() const;
virtual void setInput(const QString& input);
virtual void setMatch(const QString& match);
/// DO NOT USE IF YOU ARE NOT A DBCMD
DatabaseControl( const QString& type, const QStringList& typeSelectors, QObject* parent = 0 );
DatabaseControl( const QString& sql, const QString& summary, const QStringList& typeSelectors, QObject* parent = 0 );
QString sql() const;
public slots:
virtual void setSelectedType ( const QString& type );
private slots:
void updateData();
void editingFinished();
void editTimerFired();
private:
void updateWidgets();
void updateWidgetsFromData();
// utility
void calculateSummary();
QWeakPointer< QWidget > m_input;
QWeakPointer< QWidget > m_match;
QString m_matchData;
QString m_matchString;
QString m_summary;
QTimer m_editingTimer;
QTimer m_delayedEditTimer;
// SQL control
QString m_sql;
QString m_sqlSummary;
};
};
#endif

View File

@ -0,0 +1,181 @@
/* === 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 "DatabaseGenerator.h"
#include "DatabaseControl.h"
#include "utils/logger.h"
#include <database/databasecommand_genericselect.h>
#include <database/database.h>
using namespace Tomahawk;
GeneratorInterface*
DatabaseFactory::create()
{
return new DatabaseGenerator();
}
dyncontrol_ptr
DatabaseFactory::createControl ( const QString& controlType )
{
return dyncontrol_ptr( new DatabaseControl( controlType, typeSelectors() ) );
}
dyncontrol_ptr
DatabaseFactory::createControl ( const QString& sql, DatabaseCommand_GenericSelect::QueryType type, const QString& summary )
{
dyncontrol_ptr control = dyncontrol_ptr( new DatabaseControl( sql, summary, typeSelectors() ) );
control->setMatch( QString::number( type ) );
return control;
}
QStringList
DatabaseFactory::typeSelectors() const
{
return QStringList() << "SQL" << "Artist" << "Album" << "Title";
}
DatabaseGenerator::DatabaseGenerator ( QObject* parent )
: GeneratorInterface ( parent )
{
// defaults
m_type = "database";
m_mode = Static;
// m_logo.load( RESPATH "images )
}
DatabaseGenerator::~DatabaseGenerator()
{
}
QPixmap
DatabaseGenerator::logo()
{
return m_logo;
}
void
DatabaseGenerator::dynamicFetched()
{
}
void
DatabaseGenerator::dynamicStarted()
{
}
void
DatabaseGenerator::generate( int number )
{
tLog() << "Generating" << number << "tracks for this database dynamic playlist with" << m_controls.size() << "controls:";
if ( m_controls.isEmpty() )
{
qWarning() << "No controls, can't generate...!";
emit error( "Failed to generate tracks", "No controls!" );
return;
}
foreach ( const dyncontrol_ptr& ctrl, m_controls )
qDebug() << ctrl->selectedType() << ctrl->match() << ctrl->input();
// TODO for now, we just support the special "SQL" control, not meant to be shown to the user. Just does a raw query.
bool hasSql = false;
bool hasOther = false;
foreach ( const dyncontrol_ptr& ctrl, m_controls )
{
if ( ctrl->selectedType() == "SQL" )
hasSql = true;
else
hasOther = true;
}
if ( hasSql == hasOther )
{
qWarning() << "Cannot mix sql and non-sql controls!";
emit error( "Failed to generate tracks", "Cannot mix sql and non-sql controls" );
return;
}
// TODO for now we just support 1 sql query if we're a sql type
if ( hasSql )
{
dyncontrol_ptr control = m_controls.first();
tDebug() << "Generated sql query:" << control.dynamicCast< DatabaseControl >()->sql();
DatabaseCommand_GenericSelect* cmd = new DatabaseCommand_GenericSelect( control.dynamicCast< DatabaseControl >()->sql(),
static_cast< DatabaseCommand_GenericSelect::QueryType >( control->match().toInt() ),
number
);
connect( cmd, SIGNAL( tracks( QList<Tomahawk::query_ptr> ) ), this, SLOT( tracksGenerated( QList<Tomahawk::query_ptr> ) ) );
Database::instance()->enqueue( QSharedPointer< DatabaseCommand >( cmd ) );
return;
}
}
void
DatabaseGenerator::tracksGenerated ( const QList< query_ptr >& tracks )
{
emit generated( tracks );
}
dyncontrol_ptr
DatabaseGenerator::createControl( const QString& type )
{
m_controls << dyncontrol_ptr( new DatabaseControl( type, GeneratorFactory::typeSelectors( m_type ) ) );
return m_controls.last();
}
dyncontrol_ptr
DatabaseGenerator::createControl ( const QString& sql, DatabaseCommand_GenericSelect::QueryType type, const QString& summary )
{
m_controls << dyncontrol_ptr( new DatabaseControl( sql, summary, GeneratorFactory::typeSelectors( m_type ) ) );
m_controls.last()->setMatch( QString::number( type ) );
return m_controls.last();
}
void
DatabaseGenerator::fetchNext( int rating )
{
}
QString
DatabaseGenerator::sentenceSummary()
{
if( m_controls.count() && m_controls.first()->type() == "SQL" )
return m_controls.first()->summary();
// TODO
return QString();
}
void
DatabaseGenerator::startOnDemand()
{
}

View File

@ -0,0 +1,80 @@
/* === 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 DATABASE_GENERATOR_H
#define DATABASE_GENERATOR_H
#include <stdexcept>
#include "playlist/dynamic/GeneratorInterface.h"
#include "playlist/dynamic/GeneratorFactory.h"
#include "playlist/dynamic/DynamicControl.h"
#include "database/databasecommand_genericselect.h"
#include "dllmacro.h"
namespace Tomahawk
{
class DLLEXPORT DatabaseFactory : public GeneratorFactoryInterface
{
public:
DatabaseFactory() {}
virtual GeneratorInterface* create();
virtual dyncontrol_ptr createControl( const QString& controlType = QString() );
// TO create a special SQL resolver that consists of a pre-baked SQL query and a description of it
virtual dyncontrol_ptr createControl( const QString& sql, DatabaseCommand_GenericSelect::QueryType type, const QString& summary );
virtual QStringList typeSelectors() const;
};
/**
* Generator based on the database. Can filter the database based on some user-controllable options,
* or just be the front-facing part of any given SQL query to fake an interesting read-only playlist.
*/
class DatabaseGenerator : public GeneratorInterface
{
Q_OBJECT
public:
explicit DatabaseGenerator( QObject* parent = 0 );
virtual ~DatabaseGenerator();
virtual dyncontrol_ptr createControl( const QString& type = QString() );
virtual dyncontrol_ptr createControl( const QString& sql, DatabaseCommand_GenericSelect::QueryType type, const QString& summary );
virtual QPixmap logo();
virtual void generate ( int number = -1 );
virtual void startOnDemand();
virtual void fetchNext( int rating = -1 );
virtual QString sentenceSummary();
virtual bool onDemandSteerable() const { return false; }
virtual QWidget* steeringWidget() { return 0; }
private slots:
void tracksGenerated( const QList< Tomahawk::query_ptr >& tracks );
void dynamicStarted();
void dynamicFetched();
private:
QPixmap m_logo;
};
};
#endif

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

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

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
@ -30,22 +30,22 @@ class QVBoxLayout;
class QLineEdit;
class QHBoxLayout;
namespace Tomahawk
namespace Tomahawk
{
class EchonestSteerer : public QWidget
{
Q_OBJECT
Q_PROPERTY( qreal opacity READ opacity WRITE setOpacity )
public:
EchonestSteerer( QWidget* parent = 0 );
virtual void paintEvent(QPaintEvent* );
public slots:
void resetSteering( bool automatic = false );
void fadeIn();
void fadeOut();
qreal opacity() const { return m_opacity; }
@ -54,39 +54,39 @@ signals:
void steerField( const QString& field );
void steerDescription( const QString& desc );
void reset();
void resized();
private slots:
void changed();
void resizeFrame( int );
private:
QToolButton* initButton( QWidget* parent );
QHBoxLayout* m_layout;
QComboBox* m_amplifier;
QComboBox* m_field;
QLineEdit* m_description;
// text on the left
QVBoxLayout* m_textL;
QLabel* m_steerTop;
QLabel* m_steerBottom;
// icons on the right
QToolButton* m_reset;
// animations
QTimeLine m_resizeAnim;
bool m_expanding;
QPropertyAnimation* m_fadeAnim;
qreal m_opacity;
};
};
#endif

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
@ -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

@ -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
@ -36,44 +36,44 @@ namespace Tomahawk
class DynamicControlWrapper;
/**
* This widget encapsulates the list of dynamic controls. It can hide or show the controls.
*/
class DynamicControlList : public QWidget
{
Q_OBJECT
Q_OBJECT
public:
DynamicControlList( QWidget* parent = 0 );
explicit DynamicControlList( const geninterface_ptr& generator, const QList< dyncontrol_ptr >& controls, QWidget* parent = 0 );
virtual ~DynamicControlList();
void setControls( const geninterface_ptr& generator, const QList< dyncontrol_ptr >& controls );
QList< DynamicControlWrapper* > controls() const { return m_controls; }
signals:
void controlsChanged();
void controlChanged( const Tomahawk::dyncontrol_ptr& control );
void toggleCollapse();
public slots:
void addNewControl();
void removeControl();
void controlChanged();
private:
void init();
geninterface_ptr m_generator;
QGridLayout* m_layout;
QList< DynamicControlWrapper* > m_controls;
QHBoxLayout* m_collapseLayout;
QPushButton* m_collapse;
QToolButton* m_addControl;
};
};

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
@ -39,42 +39,42 @@ namespace Tomahawk
*/
class DynamicControlWrapper : public QObject
{
Q_OBJECT
Q_OBJECT
public:
explicit DynamicControlWrapper( const dyncontrol_ptr& control, QGridLayout* layout, int row, QWidget* parent = 0 );
virtual ~DynamicControlWrapper();
// virtual void enterEvent(QEvent* );
// virtual void leaveEvent(QEvent* );
dyncontrol_ptr control() const;
void removeFromLayout();
static QToolButton* initButton( QWidget* parent );
static QWidget* createDummy( QWidget* fromW, QWidget* parent );
signals:
void collapse();
void removeControl();
void changed();
private slots:
void typeSelectorChanged( const QString& selectedType, bool firstLoad = false );
private:
QWidget* m_parent;
int m_row;
QStackedLayout* m_plusL;
QToolButton* m_minusButton;
dyncontrol_ptr m_control;
QComboBox* m_typeSelector;
QWeakPointer<QWidget> m_matchSelector;
QWeakPointer<QWidget> m_entryWidget;
QWeakPointer<QGridLayout> m_layout;
};
};
#endif

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
@ -44,39 +44,39 @@ class DynamicSetupWidget : public QWidget
public:
DynamicSetupWidget( const Tomahawk::dynplaylist_ptr& playlist, QWidget* parent = 0 );
virtual ~DynamicSetupWidget();
void setPlaylist( const dynplaylist_ptr& playlist );
qreal opacity() const { return m_opacity; }
void setOpacity( qreal opacity );
virtual void paintEvent( QPaintEvent* );
public slots:
public slots:
void fadeIn();
void fadeOut();
signals:
void generatePressed( int num );
void typeChanged( const QString& playlistType );
private slots:
void generatePressed( bool );
private:
dynplaylist_ptr m_playlist;
QLabel* m_headerText;
QHBoxLayout* m_layout;
ReadOrWriteWidget* m_generatorCombo;
QLabel* m_logo;
QPushButton* m_generateButton;
QSpinBox* m_genNumber;
QPropertyAnimation* m_fadeAnim;
qreal m_opacity;
};
};
#endif

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

View File

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

View File

@ -0,0 +1,152 @@
/* === 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"
#include "dynamic/GeneratorInterface.h"
#include "dynamic/database/DatabaseGenerator.h"
#include "utils/logger.h"
#include "database/databasecommand_genericselect.h"
#include "widgets/overlaywidget.h"
using namespace Tomahawk;
QString SocialPlaylistWidget::s_popularAlbumsQuery = "SELECT * from album";
QString SocialPlaylistWidget::s_mostPlayedPlaylistsQuery = "asd";
QString SocialPlaylistWidget::s_topForeignTracksQuery = "select track.name, artist.name, count(*) as counter from (select track from playback_log group by track, source), track, artist where track not in (select track from playback_log where source is null group by track) and track.id = track and artist.id = track.artist group by track order by counter desc";
SocialPlaylistWidget::SocialPlaylistWidget ( QWidget* parent )
: QWidget ( parent )
, ui( new Ui_SocialPlaylistWidget )
, m_topForeignTracksModel( 0 )
, m_popularNewAlbumsModel( 0 )
{
ui->setupUi( this );
ui->splitter->setHandleWidth( 1 );
ui->splitter_2->setHandleWidth( 1 );
ui->splitter_2->setStretchFactor( 0, 2 );
ui->splitter_2->setStretchFactor( 0, 1 );
/*
WelcomePlaylistModel* model = new WelcomePlaylistModel( this );
model->setMaxPlaylists( HISTORY_PLAYLIST_ITEMS );
*/
ui->mostPlayedPlaylists->setFrameShape( QFrame::NoFrame );
ui->mostPlayedPlaylists->setAttribute( Qt::WA_MacShowFocusRect, 0 );
ui->newTracksView->setFrameShape( QFrame::NoFrame );
ui->newTracksView->setAttribute( Qt::WA_MacShowFocusRect, 0 );
ui->newAlbumsView->setFrameShape( QFrame::NoFrame );
ui->newAlbumsView->setAttribute( Qt::WA_MacShowFocusRect, 0 );
TomahawkUtils::unmarginLayout( layout() );
TomahawkUtils::unmarginLayout( ui->verticalLayout->layout() );
TomahawkUtils::unmarginLayout( ui->verticalLayout_2->layout() );
TomahawkUtils::unmarginLayout( ui->verticalLayout_3->layout() );
TomahawkUtils::unmarginLayout( ui->verticalLayout_4->layout() );
// ui->mostPlayedPlaylists->setItemDelegate( new PlaylistDelegate() );
// ui->mostPlayedPlaylists->setModel( model );
// ui->mostPlayedPlaylists->overlay()->resize( 380, 86 );
// connect( model, SIGNAL( emptinessChanged( bool) ), this, SLOT( updatePlaylists() ) );
m_topForeignTracksModel = new PlaylistModel( ui->newTracksView );
ui->newTracksView->setPlaylistModel( m_topForeignTracksModel );
m_topForeignTracksModel->setStyle( TrackModel::Short );
ui->newTracksView->overlay()->setEnabled( false );
m_popularNewAlbumsModel = new AlbumModel( ui->newAlbumsView );
ui->newAlbumsView->setAlbumModel( m_popularNewAlbumsModel );
// TODO run the genericselect command
// m_recentAlbumsModel->addFilteredCollection( collection_ptr(), 20, DatabaseCommand_AllAlbums::ModificationTime );
/*
m_timer = new QTimer( this );
connect( m_timer, SIGNAL( timeout() ), SLOT( checkQueries() ) );
connect( SourceList::instance(), SIGNAL( ready() ), SLOT( updateRecentTracks() ) );
connect( SourceList::instance(), SIGNAL( sourceAdded( Tomahawk::source_ptr ) ), SLOT( onSourceAdded( Tomahawk::source_ptr ) ) );
connect( ui->playlistWidget, SIGNAL( activated( QModelIndex ) ), SLOT( onPlaylistActivated( QModelIndex ) ) );
connect( AudioEngine::instance() ,SIGNAL( playlistChanged( Tomahawk::PlaylistInterface* ) ), this, SLOT( updatePlaylists() ), Qt::QueuedConnection );
*/
fetchFromDB();
}
SocialPlaylistWidget::~SocialPlaylistWidget()
{
}
void
SocialPlaylistWidget::fetchFromDB()
{
// Load the pre-baked custom playlists that we are going to show.
QSharedPointer<DatabaseCommand_GenericSelect> albumsCmd = QSharedPointer<DatabaseCommand_GenericSelect>( new DatabaseCommand_GenericSelect( s_popularAlbumsQuery, DatabaseCommand_GenericSelect::Album, 30, 0 ) );
connect( albumsCmd.data(), SIGNAL( albums( QList<Tomahawk::album_ptr> ) ), this, SLOT( popularAlbumsFetched( QList<Tomahawk::album_ptr> ) ) );
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>( albumsCmd ) );
// QSharedPointer<DatabaseCommand_GenericSelect> plCmd = QSharedPointer<DatabaseCommand_GenericSelect>( new DatabaseCommand_GenericSelect( s_mostPlayedPlaylistsQuery, DatabaseCommand_GenericSelect::, 30, 0 ) );
// connect( albumsCmd.data(), SIGNAL( albums( QList<Tomahawk::album_ptr> ) ), this, SLOT( popularAlbumsFetched( QList<Tomahawk::album_ptr> ) ) );
// Database::instance()->enqueue( QSharedPointer<DatabaseCommand>( albumsCmd ) );
QSharedPointer<DatabaseCommand_GenericSelect> trackCmd = QSharedPointer<DatabaseCommand_GenericSelect>( new DatabaseCommand_GenericSelect( s_topForeignTracksQuery, DatabaseCommand_GenericSelect::Track, 50, 0 ) );
connect( trackCmd.data(), SIGNAL( tracks( QList<Tomahawk::query_ptr> ) ), this, SLOT( topForeignTracksFetched( QList<Tomahawk::query_ptr> ) ) );
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>( trackCmd ) );
}
PlaylistInterface*
SocialPlaylistWidget::playlistInterface() const
{
return 0;
}
/*
void
SocialPlaylistWidget::createPlaylist()
{
// Ok, lets create our playlist
* select count(*) as counter, track.name, artist.name from (select track from playback_log group by track, source), track, artist where track.id = track and artist.id = track.artist group by track order by counter desc limit 0,20;
s elect count(*) as counter, playback_log.track, track.name, artist.name from playback_log, track, artist where track.id = playback_log.track and artist.id = track.artist group by playback_log.track order by counter desc limit 0,10; *
select count(*) as counter, track.name, artist.name from (select track from playback_log group by track, source), track, artist where track not in (select track from playback_log where source is null group by track) and track.id = track and artist.id = track.artist group by track order by counter desc limit 0,20;
select count(*) as counter, track.name, artist.name from (select track from playback_log where source > 0 group by track, source), track, artist where track.id = track and artist.id = track.artist group by track order by counter desc limit 0,20;
m_coolQuery1 = DynamicPlaylist::create( SourceList::instance()->getLocal(), COOLPLAYLIST_GUID, "Cool Playlist!", QString(), QString(), Static, false, "database", false );
connect( m_coolQuery1.data(), SIGNAL( created() ), this, SLOT( playlist1Created() ) );
}*/
void
SocialPlaylistWidget::popularAlbumsFetched( QList< album_ptr > albums )
{
m_popularNewAlbumsModel->clear();
m_popularNewAlbumsModel->addAlbums( albums );
}
void
SocialPlaylistWidget::topForeignTracksFetched( QList< query_ptr > tracks )
{
m_topForeignTracksModel->clear();
foreach( const query_ptr& q, tracks )
m_topForeignTracksModel->append( q );
}

View File

@ -0,0 +1,99 @@
/* === 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 AlbumModel;
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 popularAlbumsFetched( QList<Tomahawk::album_ptr> );
void topForeignTracksFetched( QList<Tomahawk::query_ptr> );
private:
void fetchFromDB();
Ui_SocialPlaylistWidget *ui;
PlaylistModel* m_topForeignTracksModel;
AlbumModel* m_popularNewAlbumsModel;
QString m_title;
QString m_description;
QString m_longDescription;
QPixmap m_pixmap;
static QString s_popularAlbumsQuery;
static QString s_mostPlayedPlaylistsQuery;
static QString s_topForeignTracksQuery;
};
}
#endif // SOCIALPLAYLISTWIDGET_H

View File

@ -0,0 +1,101 @@
<?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>875</width>
<height>513</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QSplitter" name="splitter_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<widget class="QSplitter" name="splitter">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<widget class="QWidget" name="layoutWidget1">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="HeaderLabel" name="label_4">
<property name="text">
<string>Popular New Albums From Your Friends</string>
</property>
</widget>
</item>
<item>
<widget class="AlbumView" name="newAlbumsView"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="layoutWidget2">
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="HeaderLabel" name="label_2">
<property name="text">
<string>Most Played Playlists</string>
</property>
</widget>
</item>
<item>
<widget class="PlaylistWidget" name="mostPlayedPlaylists"/>
</item>
</layout>
</widget>
</widget>
<widget class="QWidget" name="layoutWidget">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="HeaderLabel" name="label_3">
<property name="text">
<string>Most Played Tracks You Don't Have</string>
</property>
</widget>
</item>
<item>
<widget class="PlaylistView" name="newTracksView">
<property name="minimumSize">
<size>
<width>320</width>
<height>0</height>
</size>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</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>
<customwidget>
<class>AlbumView</class>
<extends>QListView</extends>
<header location="global">playlist/albumview.h</header>
</customwidget>
<customwidget>
<class>PlaylistWidget</class>
<extends>QListWidget</extends>
<header>widgets/welcomewidget.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View File

@ -23,6 +23,8 @@
#include "genericpageitems.h"
#include "utils/tomahawkutils.h"
#include "utils/logger.h"
#include <widgets/SocialPlaylistWidget.h>
#include <playlist/customplaylistview.h>
/// CollectionItem
@ -35,12 +37,39 @@ CollectionItem::CollectionItem( SourcesModel* mdl, SourceTreeItem* parent, cons
, m_stations( 0 )
, m_tempItem( 0 )
, m_sourceInfoItem( 0 )
, m_coolPlaylistsItem( 0 )
, m_lovedTracksItem()
, m_curTempPage( 0 )
, m_sourceInfoPage( 0 )
, m_coolPlaylistsPage( 0 )
, m_lovedTracksPage( 0 )
{
m_lovedTracksItem = new GenericPageItem( model(), this, ( m_source.isNull() ? tr( "Top Loved Tracks" ) : tr( "Loved Tracks" ) ), QIcon( RESPATH "images/loved_playlist.png" ),
boost::bind( &CollectionItem::lovedTracksClicked, this ),
boost::bind( &CollectionItem::getLovedTracksPage, this )
);
m_lovedTracksItem->setSortValue( -250 );
if( m_source.isNull() ) { // super collection
connect( ViewManager::instance(), SIGNAL( tempPageActivated( Tomahawk::ViewPage*) ), this, SLOT( tempPageActivated( Tomahawk::ViewPage* ) ) );
// add misc children of root node
GenericPageItem* recent = new GenericPageItem( model(), this, tr( "Recently Played" ), QIcon( RESPATH "images/recently-played.png" ),
boost::bind( &ViewManager::showWelcomePage, ViewManager::instance() ),
boost::bind( &ViewManager::welcomeWidget, ViewManager::instance() )
);
recent->setSortValue( -300 );
// TODO finish implementing and making pretty
// 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;
}
@ -368,3 +397,38 @@ CollectionItem::getSourceInfoPage() const
{
return m_sourceInfoPage;
}
ViewPage*
CollectionItem::coolPlaylistsClicked()
{
if( !m_source.isNull() )
return 0;
if( !m_coolPlaylistsPage )
m_coolPlaylistsPage = new SocialPlaylistWidget( ViewManager::instance()->widget() );
ViewManager::instance()->show( m_coolPlaylistsPage );
return m_coolPlaylistsPage;
}
ViewPage*
CollectionItem::getCoolPlaylistsPage() const
{
return m_coolPlaylistsPage;
}
ViewPage*
CollectionItem::lovedTracksClicked()
{
if( !m_lovedTracksPage )
m_lovedTracksPage = new CustomPlaylistView( m_source.isNull() ? CustomPlaylistView::AllLovedTracks : CustomPlaylistView::SourceLovedTracks, m_source, ViewManager::instance()->widget() );
ViewManager::instance()->show( m_lovedTracksPage );
return m_lovedTracksPage;
}
ViewPage*
CollectionItem::getLovedTracksPage() const
{
return m_lovedTracksPage;
}

View File

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

View File

@ -46,12 +46,6 @@ SourcesModel::SourcesModel( QObject* parent )
appendItem( source_ptr() );
// add misc children of root node
new GenericPageItem( this, m_rootItem->children().at( 0 ), tr( "Recently Played" ), QIcon( RESPATH "images/recently-played.png" ),
boost::bind( &ViewManager::showWelcomePage, ViewManager::instance() ),
boost::bind( &ViewManager::welcomeWidget, ViewManager::instance() )
);
onSourcesAdded( SourceList::instance()->sources() );
connect( SourceList::instance(), SIGNAL( sourceAdded( Tomahawk::source_ptr ) ), SLOT( onSourceAdded( Tomahawk::source_ptr ) ) );

View File

@ -40,6 +40,7 @@
#include "sip/SipHandler.h"
#include "playlist/dynamic/GeneratorFactory.h"
#include "playlist/dynamic/echonest/EchonestGenerator.h"
#include "playlist/dynamic/database/DatabaseGenerator.h"
#include "web/api_v1.h"
#include "resolvers/scriptresolver.h"
#include "resolvers/qtscriptresolver.h"
@ -176,6 +177,8 @@ TomahawkApp::init()
tDebug() << "Init Echonest Factory.";
GeneratorFactory::registerFactory( "echonest", new EchonestFactory );
tDebug() << "Init Database Factory.";
GeneratorFactory::registerFactory( "database", new DatabaseFactory );
// Register shortcut handler for this platform
#ifdef Q_WS_MAC