mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-07-31 19:30:21 +02:00
first compiling+linking dynamic code. lots of forward declaring fixes so it touches a lot of headers
This commit is contained in:
@@ -14,9 +14,10 @@
|
||||
#include <QDebug>
|
||||
|
||||
#include "tomahawk/functimeout.h"
|
||||
#include "tomahawk/playlist.h"
|
||||
#include "tomahawk/source.h"
|
||||
#include "tomahawk/typedefs.h"
|
||||
#include "typedefs.h"
|
||||
#include "dynamic/dynamicplaylist.h"
|
||||
|
||||
namespace Tomahawk
|
||||
{
|
||||
@@ -33,12 +34,19 @@ public:
|
||||
|
||||
virtual void loadPlaylists() { qDebug() << Q_FUNC_INFO; }
|
||||
virtual void loadTracks() { qDebug() << Q_FUNC_INFO; }
|
||||
virtual void loadDynamicPlaylists() { qDebug() << Q_FUNC_INFO ; }
|
||||
|
||||
virtual Tomahawk::playlist_ptr playlist( const QString& guid );
|
||||
virtual Tomahawk::dynplaylist_ptr dynamicPlaylist( const QString& guid );
|
||||
|
||||
virtual void addPlaylist( const Tomahawk::playlist_ptr& p );
|
||||
virtual void deletePlaylist( const Tomahawk::playlist_ptr& p );
|
||||
|
||||
virtual void addDynamicPlaylist( const Tomahawk::dynplaylist_ptr& p );
|
||||
virtual void deleteDynamicPlaylist( const Tomahawk::dynplaylist_ptr& p );
|
||||
|
||||
virtual QList< Tomahawk::playlist_ptr > playlists() { return m_playlists; }
|
||||
virtual QList< Tomahawk::dynplaylist_ptr > dynamicPlaylists() { return m_dynplaylists; }
|
||||
virtual QList< Tomahawk::query_ptr > tracks() { return m_tracks; }
|
||||
|
||||
const source_ptr& source() const { return m_source; }
|
||||
@@ -52,6 +60,9 @@ signals:
|
||||
void playlistsAdded( const QList<Tomahawk::playlist_ptr>& );
|
||||
void playlistsDeleted( const QList<Tomahawk::playlist_ptr>& );
|
||||
|
||||
void dynamicPlaylistsAdded( const QList<Tomahawk::dynplaylist_ptr>& );
|
||||
void dynamicPlaylistsDeleted( const QList<Tomahawk::dynplaylist_ptr>& );
|
||||
|
||||
public slots:
|
||||
virtual void addTracks( const QList<QVariant> &newitems ) = 0;
|
||||
virtual void removeTracks( const QList<QVariant> &olditems ) = 0;
|
||||
@@ -59,6 +70,7 @@ public slots:
|
||||
void setPlaylists( const QList<Tomahawk::playlist_ptr>& plists );
|
||||
void setTracks( const QList<Tomahawk::query_ptr>& tracks, Tomahawk::collection_ptr collection );
|
||||
|
||||
void setDynamicPlaylistS( const QList< Tomahawk::dynplaylist_ptr >& dynplists );
|
||||
protected:
|
||||
QString m_name;
|
||||
unsigned int m_lastmodified; // unix time of last change to collection
|
||||
@@ -67,6 +79,7 @@ private:
|
||||
source_ptr m_source;
|
||||
QList< Tomahawk::playlist_ptr > m_playlists;
|
||||
QList< Tomahawk::query_ptr > m_tracks;
|
||||
QList< Tomahawk::dynplaylist_ptr > m_dynplaylists;
|
||||
};
|
||||
|
||||
}; // ns
|
||||
|
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <QObject>
|
||||
#include <QList>
|
||||
#include <QDebug>
|
||||
#include <QSharedPointer>
|
||||
|
||||
#include "tomahawk/query.h"
|
||||
@@ -119,12 +120,7 @@ public:
|
||||
// these need to exist and be public for the json serialization stuff
|
||||
// you SHOULD NOT call them. They are used for an alternate CTOR method from json.
|
||||
// maybe friend QObjectHelper and make them private?
|
||||
explicit Playlist( const source_ptr& author )
|
||||
: m_source( author )
|
||||
, m_lastmodified( 0 )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << "JSON";
|
||||
}
|
||||
explicit Playlist( const source_ptr& author );
|
||||
void setCurrentrevision( const QString& s ) { m_currentrevision = s; }
|
||||
void setTitle( const QString& s ) { m_title = s; }
|
||||
void setInfo( const QString& s ) { m_info = s; }
|
||||
@@ -182,6 +178,8 @@ protected:
|
||||
bool is_newest_rev,
|
||||
const QMap< QString, Tomahawk::plentry_ptr >& addedmap );
|
||||
private:
|
||||
Playlist();
|
||||
|
||||
source_ptr m_source;
|
||||
QString m_currentrevision;
|
||||
QString m_guid, m_title, m_info, m_creator;
|
||||
|
@@ -6,7 +6,7 @@
|
||||
#include <QList>
|
||||
#include <QVariant>
|
||||
|
||||
#include "tomahawk/collection.h"
|
||||
// #include "tomahawk/collection.h"
|
||||
#include "tomahawk/result.h"
|
||||
#include "tomahawk/typedefs.h"
|
||||
|
||||
|
@@ -1,12 +1,11 @@
|
||||
|
||||
#ifndef RESULT_H
|
||||
#define RESULT_H
|
||||
#include <qvariant.h>
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include <QVariant>
|
||||
#include "tomahawk/typedefs.h"
|
||||
#include "collection.h"
|
||||
#include "artist.h"
|
||||
#include "album.h"
|
||||
|
||||
namespace Tomahawk
|
||||
{
|
||||
@@ -17,14 +16,16 @@ Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit Result( const QVariant& v, const collection_ptr& collection );
|
||||
virtual ~Result();
|
||||
|
||||
QVariant toVariant() const { return m_v; }
|
||||
|
||||
float score() const;
|
||||
RID id() const;
|
||||
collection_ptr collection() const { return m_collection; }
|
||||
collection_ptr collection() const;
|
||||
|
||||
Tomahawk::artist_ptr artist() const { return m_artist; }
|
||||
Tomahawk::album_ptr album() const { return m_album; }
|
||||
Tomahawk::artist_ptr artist() const;
|
||||
Tomahawk::album_ptr album() const;
|
||||
QString track() const { return m_track; }
|
||||
QString url() const { return m_url; }
|
||||
QString mimetype() const { return m_mimetype; }
|
||||
|
@@ -21,7 +21,7 @@ Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit Source( const QString& username, ControlConnection* cc );
|
||||
explicit Source( const QString& username );
|
||||
explicit Source( const QString& username = QString() );
|
||||
virtual ~Source();
|
||||
|
||||
bool isLocal() const { return m_isLocal; }
|
||||
|
@@ -15,6 +15,8 @@ namespace Tomahawk
|
||||
class Query;
|
||||
class Result;
|
||||
class Source;
|
||||
class DynamicControl;
|
||||
class GeneratorInterface;
|
||||
|
||||
typedef QSharedPointer<Collection> collection_ptr;
|
||||
typedef QSharedPointer<Playlist> playlist_ptr;
|
||||
@@ -26,10 +28,19 @@ namespace Tomahawk
|
||||
typedef QSharedPointer<Artist> artist_ptr;
|
||||
typedef QSharedPointer<Album> album_ptr;
|
||||
|
||||
typedef QSharedPointer<DynamicControl> dyncontrol_ptr;
|
||||
typedef QSharedPointer<GeneratorInterface> geninterface_ptr;
|
||||
|
||||
// let's keep these typesafe, they are different kinds of GUID:
|
||||
typedef QString QID; //query id
|
||||
typedef QString RID; //result id
|
||||
|
||||
|
||||
enum GeneratorMode {
|
||||
OnDemand = 0,
|
||||
Static
|
||||
};
|
||||
|
||||
}; // ns
|
||||
|
||||
typedef int AudioErrorCode;
|
||||
|
@@ -89,10 +89,16 @@ SET( tomahawkSources ${tomahawkSources}
|
||||
database/databasecommand_renameplaylist.cpp
|
||||
database/databasecommand_loadops.cpp
|
||||
database/databasecommand_updatesearchindex.cpp
|
||||
database/databasecommand_loadallplaylists.cpp
|
||||
database/databasecommand_setdynamicplaylistrevision.cpp
|
||||
database/databasecommand_createdynamicplaylist.cpp
|
||||
database/databasecommand_loaddynamicplaylist.cpp
|
||||
database/databasecollection.cpp
|
||||
|
||||
dynamic/dynamicplaylist.cpp
|
||||
dynamic/dynamiccontrol.cpp
|
||||
dynamic/generatorfactory.cpp
|
||||
dynamic/generatorinterface.cpp
|
||||
dynamic/echonest/echonestgenerator.cpp
|
||||
dynamic/echonest/echonestcontrol.cpp
|
||||
|
||||
@@ -207,6 +213,9 @@ SET( tomahawkHeaders ${tomahawkHeaders}
|
||||
database/databasecommand_loadallplaylists.h
|
||||
database/databasecommand_createplaylist.h
|
||||
database/databasecommand_deleteplaylist.h
|
||||
database/databasecommand_setdynamicplaylistrevision.h
|
||||
database/databasecommand_createdynamicplaylist.h
|
||||
database/databasecommand_loaddynamicplaylist.h
|
||||
database/databasecommand_renameplaylist.h
|
||||
database/databasecommand_loadops.h
|
||||
database/databasecommand_updatesearchindex.h
|
||||
|
@@ -4,6 +4,7 @@
|
||||
#include <QGenericArgument>
|
||||
|
||||
#include "tomahawk/playlist.h"
|
||||
#include "dynamic/dynamicplaylist.h"
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
@@ -45,6 +46,20 @@ Collection::addPlaylist( const Tomahawk::playlist_ptr& p )
|
||||
emit playlistsAdded( toadd );
|
||||
}
|
||||
|
||||
void
|
||||
Collection::addDynamicPlaylist( const Tomahawk::dynplaylist_ptr& p )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
QList<dynplaylist_ptr> toadd;
|
||||
toadd << p;
|
||||
m_dynplaylists.append( toadd );
|
||||
|
||||
qDebug() << Q_FUNC_INFO << "Collection name" << name()
|
||||
<< "from source id" << source()->id()
|
||||
<< "numplaylists:" << m_playlists.length();
|
||||
emit dynamicPlaylistsAdded( toadd );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Collection::deletePlaylist( const Tomahawk::playlist_ptr& p )
|
||||
@@ -60,6 +75,20 @@ Collection::deletePlaylist( const Tomahawk::playlist_ptr& p )
|
||||
emit playlistsDeleted( todelete );
|
||||
}
|
||||
|
||||
void
|
||||
Collection::deleteDynamicPlaylist( const Tomahawk::dynplaylist_ptr& p )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
QList<dynplaylist_ptr> todelete;
|
||||
todelete << p;
|
||||
m_dynplaylists.removeAll( p );
|
||||
|
||||
qDebug() << Q_FUNC_INFO << "Collection name" << name()
|
||||
<< "from source id" << source()->id()
|
||||
<< "numplaylists:" << m_playlists.length();
|
||||
emit dynamicPlaylistsDeleted( todelete );
|
||||
}
|
||||
|
||||
|
||||
playlist_ptr
|
||||
Collection::playlist( const QString& guid )
|
||||
@@ -74,6 +103,19 @@ Collection::playlist( const QString& guid )
|
||||
}
|
||||
|
||||
|
||||
dynplaylist_ptr
|
||||
Collection::dynamicPlaylist( const QString& guid )
|
||||
{
|
||||
foreach( const dynplaylist_ptr& pp, m_dynplaylists )
|
||||
{
|
||||
if( pp->guid() == guid )
|
||||
return pp;
|
||||
}
|
||||
|
||||
return dynplaylist_ptr();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Collection::setPlaylists( const QList<Tomahawk::playlist_ptr>& plists )
|
||||
{
|
||||
@@ -83,6 +125,14 @@ Collection::setPlaylists( const QList<Tomahawk::playlist_ptr>& plists )
|
||||
emit playlistsAdded( plists );
|
||||
}
|
||||
|
||||
void
|
||||
Collection::setDynamicPlaylistS( const QList< Tomahawk::dynplaylist_ptr >& plists )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << plists.count();
|
||||
|
||||
m_dynplaylists.append( plists );
|
||||
emit dynamicPlaylistsAdded( plists );
|
||||
}
|
||||
|
||||
void
|
||||
Collection::setTracks( const QList<Tomahawk::query_ptr>& tracks, Tomahawk::collection_ptr collection )
|
||||
|
@@ -27,6 +27,19 @@ DatabaseCollection::loadPlaylists()
|
||||
TomahawkApp::instance()->database()->enqueue( QSharedPointer<DatabaseCommand>( cmd ) );
|
||||
}
|
||||
|
||||
void
|
||||
DatabaseCollection::loadDynamicPlaylists()
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
// DatabaseCommand_LoadAllDynamicPlaylists* cmd = new DatabaseCommand_LoadAllDynamicPlaylists( source() );
|
||||
//
|
||||
// connect( cmd, SIGNAL( done( const QList<Tomahawk::dynplaylist_ptr>& ) ),
|
||||
// SLOT( setDynamicPlaylists( const QList<Tomahawk::dynplaylist_ptr>& ) ) );
|
||||
//
|
||||
// TomahawkApp::instance()->database()->enqueue( QSharedPointer<DatabaseCommand>( cmd ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
DatabaseCollection::loadTracks()
|
||||
@@ -77,6 +90,19 @@ DatabaseCollection::playlists()
|
||||
return Collection::playlists();
|
||||
}
|
||||
|
||||
QList< dynplaylist_ptr > DatabaseCollection::dynamicPlaylists()
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
if ( Collection::dynamicPlaylists().isEmpty() )
|
||||
{
|
||||
loadDynamicPlaylists();
|
||||
}
|
||||
|
||||
return Collection::dynamicPlaylists();
|
||||
}
|
||||
|
||||
|
||||
|
||||
QList< Tomahawk::query_ptr >
|
||||
DatabaseCollection::tracks()
|
||||
|
@@ -17,9 +17,11 @@ public:
|
||||
|
||||
virtual void loadTracks();
|
||||
virtual void loadPlaylists();
|
||||
virtual void loadDynamicPlaylists();
|
||||
|
||||
virtual QList< Tomahawk::playlist_ptr > playlists();
|
||||
virtual QList< Tomahawk::query_ptr > tracks();
|
||||
virtual QList< Tomahawk::dynplaylist_ptr > dynamicPlaylists();
|
||||
|
||||
public slots:
|
||||
virtual void addTracks( const QList<QVariant> &newitems );
|
||||
|
79
src/database/databasecommand_createdynamicplaylist.cpp
Normal file
79
src/database/databasecommand_createdynamicplaylist.cpp
Normal file
@@ -0,0 +1,79 @@
|
||||
#include "databasecommand_createdynamicplaylist.h"
|
||||
|
||||
#include <QSqlQuery>
|
||||
|
||||
#include "tomahawk/tomahawkapp.h"
|
||||
#include "dynamic/dynamicplaylist.h"
|
||||
#include "dynamic/dynamiccontrol.h"
|
||||
#include "dynamic/generatorinterface.h"
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
|
||||
DatabaseCommand_CreateDynamicPlaylist::DatabaseCommand_CreateDynamicPlaylist( QObject* parent )
|
||||
: DatabaseCommand_CreatePlaylist( parent )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << "creating dynamiccreatecommand 1";
|
||||
}
|
||||
|
||||
|
||||
DatabaseCommand_CreateDynamicPlaylist::DatabaseCommand_CreateDynamicPlaylist( const source_ptr& author,
|
||||
const dynplaylist_ptr& playlist )
|
||||
: DatabaseCommand_CreatePlaylist( author, playlist.staticCast<Playlist>() )
|
||||
, m_playlist( playlist )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << "creating dynamiccreatecommand 2";
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DatabaseCommand_CreateDynamicPlaylist::exec( DatabaseImpl* lib )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
Q_ASSERT( !m_playlist.isNull() );
|
||||
Q_ASSERT( !source().isNull() );
|
||||
|
||||
DatabaseCommand_CreatePlaylist::exec( lib );
|
||||
|
||||
TomahawkSqlQuery cre = lib->newquery();
|
||||
cre.prepare( "INSERT INTO dynamic_playlist( guid, pltype, plmode) "
|
||||
"VALUES( :guid, :pltype, :plmode )" );
|
||||
cre.bindValue( ":guid", m_playlist->guid() );
|
||||
cre.bindValue( ":pltype", m_playlist->type() );
|
||||
cre.bindValue( ":plmode", m_playlist->mode() );
|
||||
|
||||
qDebug() << "CREATE DYNPLAYLIST:" << cre.boundValues();
|
||||
|
||||
cre.exec();
|
||||
|
||||
// save the controls
|
||||
cre = lib->newquery();
|
||||
cre.prepare( "INSERT INTO dynamic_playlist_controls( id, selectedType, match, input) "
|
||||
"VALUES( :id, :selectedType, :match, :input )" );
|
||||
foreach( const dyncontrol_ptr& control, m_playlist->generator()->controls() ) {
|
||||
|
||||
cre.bindValue( ":id", control->id() );
|
||||
cre.bindValue( ":selectedType", control->selectedType() );
|
||||
cre.bindValue( ":match", control->match() );
|
||||
cre.bindValue( ":input", control->input() );
|
||||
|
||||
qDebug() << "CREATE DYNPLAYLIST CONTROL:" << cre.boundValues();
|
||||
|
||||
cre.exec();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DatabaseCommand_CreateDynamicPlaylist::postCommitHook()
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
if( report() == false )
|
||||
return;
|
||||
|
||||
qDebug() << Q_FUNC_INFO << "..reporting..";
|
||||
m_playlist->reportCreated( m_playlist );
|
||||
|
||||
if( source()->isLocal() )
|
||||
APP->servent().triggerDBSync();
|
||||
}
|
43
src/database/databasecommand_createdynamicplaylist.h
Normal file
43
src/database/databasecommand_createdynamicplaylist.h
Normal file
@@ -0,0 +1,43 @@
|
||||
#ifndef DATABASECOMMAND_CREATEDYNAMICPLAYLIST_H
|
||||
#define DATABASECOMMAND_CREATEDYNAMICPLAYLIST_H
|
||||
|
||||
#include "databaseimpl.h"
|
||||
#include "databasecommand_createplaylist.h"
|
||||
#include "dynamic/dynamicplaylist.h"
|
||||
#include "tomahawk/typedefs.h"
|
||||
|
||||
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 );
|
||||
|
||||
QString commandname() const { return "createdynamicplaylist"; }
|
||||
|
||||
virtual void exec( DatabaseImpl* lib );
|
||||
virtual void postCommitHook();
|
||||
virtual bool doesMutates() const { return true; }
|
||||
|
||||
QVariant playlistV() const
|
||||
{
|
||||
return QJson::QObjectHelper::qobject2qvariant( (QObject*)m_playlist.data() );
|
||||
}
|
||||
|
||||
void setPlaylistV( const QVariant& v )
|
||||
{
|
||||
qDebug() << "***********" << Q_FUNC_INFO << v;
|
||||
using namespace Tomahawk;
|
||||
|
||||
DynamicPlaylist* p = new DynamicPlaylist( source() );
|
||||
QJson::QObjectHelper::qvariant2qobject( v.toMap(), p );
|
||||
m_playlist = dynplaylist_ptr( p );
|
||||
}
|
||||
|
||||
private:
|
||||
Tomahawk::dynplaylist_ptr m_playlist;
|
||||
};
|
||||
|
||||
#endif // DATABASECOMMAND_CREATEDYNAMICPLAYLIST_H
|
@@ -36,6 +36,9 @@ public:
|
||||
m_playlist = playlist_ptr( p );
|
||||
}
|
||||
|
||||
protected:
|
||||
bool report() { return m_report; }
|
||||
|
||||
private:
|
||||
Tomahawk::playlist_ptr m_playlist;
|
||||
bool m_report; // call Playlist::reportCreated?
|
||||
|
64
src/database/databasecommand_loaddynamicplaylist.cpp
Normal file
64
src/database/databasecommand_loaddynamicplaylist.cpp
Normal file
@@ -0,0 +1,64 @@
|
||||
#include "databasecommand_loaddynamicplaylist.h"
|
||||
|
||||
#include <QSqlQuery>
|
||||
#include <QString>
|
||||
|
||||
#include "databaseimpl.h"
|
||||
#include "tomahawksqlquery.h"
|
||||
#include "dynamic/dynamiccontrol.h"
|
||||
#include "dynamic/generatorinterface.h"
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
|
||||
void
|
||||
DatabaseCommand_LoadDynamicPlaylist::exec( DatabaseImpl* dbi )
|
||||
{
|
||||
qDebug() << "Loading dynamic playlist revision" << guid();
|
||||
// load the entries first
|
||||
generateEntries( dbi );
|
||||
|
||||
// now load the controls etc
|
||||
|
||||
TomahawkSqlQuery controlsQuery = dbi->newquery();
|
||||
controlsQuery.prepare("SELECT controls, plmode, pltype"
|
||||
"FROM dynamic_playlist_revision "
|
||||
"WHERE guid = :guid");
|
||||
controlsQuery.bindValue( ":guid", guid() );
|
||||
controlsQuery.exec();
|
||||
|
||||
QList< dyncontrol_ptr > controls;
|
||||
if( controlsQuery.next() )
|
||||
{
|
||||
QStringList controlIds = controlsQuery.value( 0 ).toStringList();
|
||||
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() )
|
||||
{
|
||||
dyncontrol_ptr c = dyncontrol_ptr( new DynamicControl );
|
||||
c->setId( controlId );
|
||||
c->setSelectedType( controlQuery.value( 0 ).toString() );
|
||||
c->setMatch( controlQuery.value( 1 ).toString() );
|
||||
c->setInput( controlQuery.value( 2 ).toString() );
|
||||
controls << c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QString type = controlsQuery.value( 2 ).toString();
|
||||
GeneratorMode mode = static_cast<GeneratorMode>( controlsQuery.value( 1 ).toInt() );
|
||||
if( mode == OnDemand ) {
|
||||
Q_ASSERT( m_entrymap.isEmpty() ); // ondemand should have no entry
|
||||
|
||||
emit done( guid(), m_islatest, type, controls, true );
|
||||
} else {
|
||||
emit done( guid(), m_guids, m_oldentries, type, controls, m_islatest, m_entrymap, true );
|
||||
}
|
||||
}
|
47
src/database/databasecommand_loaddynamicplaylist.h
Normal file
47
src/database/databasecommand_loaddynamicplaylist.h
Normal file
@@ -0,0 +1,47 @@
|
||||
#ifndef DATABASECOMMAND_LOADDYNAMICPLAYLIST_H
|
||||
#define DATABASECOMMAND_LOADDYNAMICPLAYLIST_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QVariantMap>
|
||||
|
||||
#include "tomahawk/typedefs.h"
|
||||
#include "databasecommand.h"
|
||||
#include "databasecommand_loadplaylistentries.h"
|
||||
#include "tomahawk/playlist.h"
|
||||
#include "dynamic/dynamiccontrol.h"
|
||||
|
||||
class DatabaseCommand_LoadDynamicPlaylist : public DatabaseCommand_LoadPlaylistEntries
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DatabaseCommand_LoadDynamicPlaylist( QString revision_guid, QObject* parent = 0 )
|
||||
: DatabaseCommand_LoadPlaylistEntries( revision_guid, parent )
|
||||
{}
|
||||
|
||||
|
||||
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,
|
||||
const QString,
|
||||
QList< Tomahawk::dyncontrol_ptr>,
|
||||
bool );
|
||||
// used when loading a static playlist
|
||||
void done( QString,
|
||||
QList< QString >,
|
||||
QList< QString >,
|
||||
QString,
|
||||
QList< Tomahawk::dyncontrol_ptr>,
|
||||
bool,
|
||||
const QMap< QString, Tomahawk::plentry_ptr >,
|
||||
bool );
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
#endif // DATABASECOMMAND_LOADDYNAMICPLAYLIST_H
|
@@ -11,7 +11,13 @@ void
|
||||
DatabaseCommand_LoadPlaylistEntries::exec( DatabaseImpl* dbi )
|
||||
{
|
||||
qDebug() << "Loading playlist entries for revision" << m_guid;
|
||||
generateEntries( dbi );
|
||||
|
||||
emit done( m_guid, m_guids, m_oldentries, m_islatest, m_entrymap, true );
|
||||
}
|
||||
|
||||
void DatabaseCommand_LoadPlaylistEntries::generateEntries( DatabaseImpl* dbi )
|
||||
{
|
||||
TomahawkSqlQuery query_entries = dbi->newquery();
|
||||
query_entries.prepare("SELECT entries, playlist, author, timestamp, previous_revision "
|
||||
"FROM playlist_revision "
|
||||
@@ -19,10 +25,6 @@ DatabaseCommand_LoadPlaylistEntries::exec( DatabaseImpl* dbi )
|
||||
query_entries.bindValue( ":guid", m_guid );
|
||||
query_entries.exec();
|
||||
|
||||
QStringList guids;
|
||||
QMap< QString, plentry_ptr > entrymap;
|
||||
bool islatest = true;
|
||||
QStringList oldentries;
|
||||
QString prevrev;
|
||||
QJson::Parser parser; bool ok;
|
||||
|
||||
@@ -31,10 +33,10 @@ DatabaseCommand_LoadPlaylistEntries::exec( DatabaseImpl* dbi )
|
||||
// entries should be a list of strings:
|
||||
QVariant v = parser.parse( query_entries.value(0).toByteArray(), &ok );
|
||||
Q_ASSERT( ok && v.type() == QVariant::List ); //TODO
|
||||
guids = v.toStringList();
|
||||
m_guids = v.toStringList();
|
||||
// qDebug() << "Entries:" << guids;
|
||||
|
||||
QString inclause = QString("('%1')").arg(guids.join("', '"));
|
||||
QString inclause = QString("('%1')").arg(m_guids.join("', '"));
|
||||
|
||||
TomahawkSqlQuery query = dbi->newquery();
|
||||
QString sql = QString("SELECT guid, trackname, artistname, albumname, annotation, "
|
||||
@@ -62,7 +64,7 @@ DatabaseCommand_LoadPlaylistEntries::exec( DatabaseImpl* dbi )
|
||||
Tomahawk::query_ptr q( new Tomahawk::Query( m ) );
|
||||
e->setQuery( q );
|
||||
|
||||
entrymap.insert( e->guid(), e );
|
||||
m_entrymap.insert( e->guid(), e );
|
||||
}
|
||||
|
||||
prevrev = query_entries.value( 4 ).toString();
|
||||
@@ -92,11 +94,9 @@ DatabaseCommand_LoadPlaylistEntries::exec( DatabaseImpl* dbi )
|
||||
|
||||
QVariant v = parser.parse( query_entries_old.value( 0 ).toByteArray(), &ok );
|
||||
Q_ASSERT( ok && v.type() == QVariant::List ); //TODO
|
||||
oldentries = v.toStringList();
|
||||
islatest = query_entries_old.value( 1 ).toBool();
|
||||
m_oldentries = v.toStringList();
|
||||
m_islatest = query_entries_old.value( 1 ).toBool();
|
||||
}
|
||||
|
||||
qDebug() << Q_FUNC_INFO << "entrymap:" << entrymap;
|
||||
|
||||
emit done( m_guid, guids, oldentries, islatest, entrymap, true );
|
||||
qDebug() << Q_FUNC_INFO << "entrymap:" << m_entrymap;
|
||||
}
|
||||
|
@@ -28,6 +28,14 @@ signals:
|
||||
const QMap< QString, Tomahawk::plentry_ptr >& added,
|
||||
bool applied );
|
||||
|
||||
protected:
|
||||
void generateEntries( DatabaseImpl* dbi );
|
||||
|
||||
QStringList m_guids;
|
||||
QMap< QString, Tomahawk::plentry_ptr > m_entrymap;
|
||||
bool m_islatest;
|
||||
QStringList m_oldentries;
|
||||
|
||||
private:
|
||||
QString m_guid;
|
||||
};
|
||||
|
212
src/database/databasecommand_setdynamicplaylistrevision.cpp
Normal file
212
src/database/databasecommand_setdynamicplaylistrevision.cpp
Normal file
@@ -0,0 +1,212 @@
|
||||
#include "databasecommand_setdynamicplaylistrevision.h"
|
||||
|
||||
#include <QSqlQuery>
|
||||
|
||||
#include "tomahawksqlquery.h"
|
||||
#include "dynamic/dynamicplaylist.h"
|
||||
#include "dynamic/dynamiccontrol.h"
|
||||
#include "tomahawk/tomahawkapp.h"
|
||||
|
||||
DatabaseCommand_SetDynamicPlaylistRevision::DatabaseCommand_SetDynamicPlaylistRevision(const Tomahawk::source_ptr& s,
|
||||
const QString& playlistguid,
|
||||
const QString& newrev,
|
||||
const QString& oldrev,
|
||||
const QStringList& orderedguids,
|
||||
const QList< plentry_ptr >& addedentries,
|
||||
const QString& type,
|
||||
GeneratorMode mode,
|
||||
const QList< dyncontrol_ptr >& controls )
|
||||
: DatabaseCommand_SetPlaylistRevision( s, playlistguid, newrev, oldrev, orderedguids, addedentries )
|
||||
, m_type( type )
|
||||
, m_mode( mode )
|
||||
, m_controls( controls )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
DatabaseCommand_SetDynamicPlaylistRevision::DatabaseCommand_SetDynamicPlaylistRevision(const Tomahawk::source_ptr& s,
|
||||
const QString& playlistguid,
|
||||
const QString& newrev,
|
||||
const QString& oldrev,
|
||||
const QString& type,
|
||||
GeneratorMode mode,
|
||||
const QList< dyncontrol_ptr >& controls )
|
||||
: DatabaseCommand_SetPlaylistRevision( s, playlistguid, newrev, oldrev, QStringList(), QList< plentry_ptr >() )
|
||||
, m_type( type )
|
||||
, m_mode( mode )
|
||||
, m_controls( controls )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QVariantList DatabaseCommand_SetDynamicPlaylistRevision::controlsV()
|
||||
{
|
||||
if( m_controls.isEmpty() )
|
||||
return m_controlsV;
|
||||
|
||||
if( !m_controls.isEmpty() && m_controlsV.isEmpty() )
|
||||
{
|
||||
foreach( const dyncontrol_ptr& control, m_controls )
|
||||
{
|
||||
m_controlsV << QJson::QObjectHelper::qobject2qvariant( control.data() );
|
||||
}
|
||||
}
|
||||
return m_controlsV;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DatabaseCommand_SetDynamicPlaylistRevision::postCommitHook()
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
QStringList orderedentriesguids;
|
||||
foreach( const QVariant& v, orderedguids() )
|
||||
orderedentriesguids << v.toString();
|
||||
|
||||
// private, but we are a friend. will recall itself in its own thread:
|
||||
dynplaylist_ptr playlist = source()->collection()->dynamicPlaylist( playlistguid() );
|
||||
|
||||
if ( playlist.isNull() )
|
||||
{
|
||||
qDebug() << playlistguid();
|
||||
Q_ASSERT( !playlist.isNull() );
|
||||
return;
|
||||
}
|
||||
|
||||
if( m_controls.isEmpty() && !m_controlsV.isEmpty() ) // we were creatd from JSON, not programmatically. construct the controls fromthe playlist now
|
||||
{
|
||||
foreach( const QVariant& contrl, m_controlsV ) {
|
||||
dyncontrol_ptr control = playlist->generator()->createControl( m_type );
|
||||
QJson::QObjectHelper::qvariant2qobject( contrl.toMap(), control.data( ));
|
||||
m_controls << control;
|
||||
}
|
||||
}
|
||||
|
||||
if( m_mode == OnDemand )
|
||||
playlist->setRevision( newrev(),
|
||||
true, // this *is* the newest revision so far
|
||||
m_type,
|
||||
m_controls,
|
||||
m_applied );
|
||||
else
|
||||
playlist->setRevision( newrev(),
|
||||
orderedentriesguids,
|
||||
m_previous_rev_orderedguids,
|
||||
m_type,
|
||||
m_controls,
|
||||
true, // this *is* the newest revision so far
|
||||
m_addedmap,
|
||||
m_applied );
|
||||
|
||||
if( source()->isLocal() )
|
||||
APP->servent().triggerDBSync();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DatabaseCommand_SetDynamicPlaylistRevision::exec( DatabaseImpl* lib )
|
||||
{
|
||||
/*using namespace Tomahawk;
|
||||
|
||||
QString currentrevision;
|
||||
|
||||
// get the current revision for this playlist
|
||||
// this also serves to check the playlist exists.
|
||||
TomahawkSqlQuery chkq = lib->newquery();
|
||||
chkq.prepare("SELECT currentrevision FROM playlist WHERE guid = ?");
|
||||
chkq.addBindValue( m_playlistguid );
|
||||
if( chkq.exec() && chkq.next() )
|
||||
{
|
||||
currentrevision = chkq.value( 0 ).toString();
|
||||
//qDebug() << Q_FUNC_INFO << "pl guid" << m_playlistguid << " curr rev" << currentrevision;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw "No such playlist, WTF?";
|
||||
return;
|
||||
}
|
||||
|
||||
QVariantList vlist = m_orderedguids;
|
||||
QJson::Serializer ser;
|
||||
const QByteArray entries = ser.serialize( vlist );
|
||||
|
||||
// add any new items:
|
||||
TomahawkSqlQuery adde = lib->newquery();
|
||||
|
||||
QString sql = "INSERT INTO playlist_item( guid, playlist, trackname, artistname, albumname, "
|
||||
"annotation, duration, addedon, addedby, result_hint ) "
|
||||
"VALUES( ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )";
|
||||
adde.prepare( sql );
|
||||
|
||||
qDebug() << "Num new playlist_items to add:" << m_addedentries.length();
|
||||
foreach( const plentry_ptr& e, m_addedentries )
|
||||
{
|
||||
m_addedmap.insert( e->guid(), e ); // needed in postcommithook
|
||||
|
||||
adde.bindValue( 0, e->guid() );
|
||||
adde.bindValue( 1, m_playlistguid );
|
||||
adde.bindValue( 2, e->query()->track() );
|
||||
adde.bindValue( 3, e->query()->artist() );
|
||||
adde.bindValue( 4, e->query()->album() );
|
||||
adde.bindValue( 5, e->annotation() );
|
||||
adde.bindValue( 6, (int) e->duration() );
|
||||
adde.bindValue( 7, e->lastmodified() );
|
||||
adde.bindValue( 8, source()->isLocal() ? QVariant(QVariant::Int) : source()->id() );
|
||||
adde.bindValue( 9, "" );
|
||||
adde.exec();
|
||||
}
|
||||
|
||||
// add the new revision:
|
||||
//qDebug() << "Adding new playlist revision, guid:" << m_newrev
|
||||
// << entries;
|
||||
TomahawkSqlQuery query = lib->newquery();
|
||||
sql = "INSERT INTO playlist_revision(guid, playlist, entries, author, timestamp, previous_revision) "
|
||||
"VALUES(?, ?, ?, ?, ?, ?)";
|
||||
|
||||
query.prepare( sql );
|
||||
query.addBindValue( m_newrev );
|
||||
query.addBindValue( m_playlistguid );
|
||||
query.addBindValue( entries );
|
||||
query.addBindValue( source()->isLocal() ? QVariant(QVariant::Int) : source()->id() );
|
||||
query.addBindValue( 0 ); //ts
|
||||
query.addBindValue( m_oldrev.isEmpty() ? QVariant(QVariant::String) : m_oldrev );
|
||||
query.exec();
|
||||
|
||||
qDebug() << "Currentrevision:" << currentrevision << "oldrev:" << m_oldrev;
|
||||
// if optimistic locking is ok, update current revision to this new one
|
||||
if( currentrevision == m_oldrev )
|
||||
{
|
||||
TomahawkSqlQuery query2 = lib->newquery();
|
||||
qDebug() << "updating current revision, optimistic locking ok";
|
||||
query2.prepare("UPDATE playlist SET currentrevision = ? WHERE guid = ?");
|
||||
query2.bindValue( 0, m_newrev );
|
||||
query2.bindValue( 1, m_playlistguid );
|
||||
query2.exec();
|
||||
|
||||
m_applied = true;
|
||||
|
||||
// load previous revision entries, which we need to pass on
|
||||
// so the change can be diffed
|
||||
TomahawkSqlQuery query_entries = lib->newquery();
|
||||
query_entries.prepare( "SELECT entries, playlist, author, timestamp, previous_revision "
|
||||
"FROM playlist_revision "
|
||||
"WHERE guid = :guid" );
|
||||
query_entries.bindValue( ":guid", m_oldrev );
|
||||
query_entries.exec();
|
||||
if( query_entries.next() )
|
||||
{
|
||||
// entries should be a list of strings:
|
||||
bool ok;
|
||||
QJson::Parser parser;
|
||||
QVariant v = parser.parse( query_entries.value(0).toByteArray(), &ok );
|
||||
Q_ASSERT( ok && v.type() == QVariant::List ); //TODO
|
||||
m_previous_rev_orderedguids = v.toStringList();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "Not updating current revision, optimistic locking fail";
|
||||
} */
|
||||
}
|
68
src/database/databasecommand_setdynamicplaylistrevision.h
Normal file
68
src/database/databasecommand_setdynamicplaylistrevision.h
Normal file
@@ -0,0 +1,68 @@
|
||||
#ifndef DATABASECOMMAND_SETDYNAMICPLAYLISTREVISION_H
|
||||
#define DATABASECOMMAND_SETDYNAMICPLAYLISTREVISION_H
|
||||
|
||||
#include "databasecommand_setplaylistrevision.h"
|
||||
#include "databaseimpl.h"
|
||||
#include "tomahawk/collection.h"
|
||||
#include "tomahawk/playlist.h"
|
||||
#include <generatorinterface.h>
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
class DatabaseCommand_SetDynamicPlaylistRevision : public DatabaseCommand_SetPlaylistRevision
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY( QString type READ type WRITE setType )
|
||||
Q_PROPERTY( GeneratorMode 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,
|
||||
const QString& oldrev,
|
||||
const QStringList& orderedguids,
|
||||
const QList<Tomahawk::plentry_ptr>& addedentries,
|
||||
const QString& type,
|
||||
GeneratorMode mode,
|
||||
const QList< dyncontrol_ptr >& controls );
|
||||
|
||||
explicit DatabaseCommand_SetDynamicPlaylistRevision( const source_ptr& s,
|
||||
const QString& playlistguid,
|
||||
const QString& newrev,
|
||||
const QString& oldrev,
|
||||
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; }
|
||||
GeneratorMode mode() const { return m_mode; }
|
||||
|
||||
void setType( const QString& type ) { m_type = type; }
|
||||
void setMode( GeneratorMode mode ) { m_mode = mode; }
|
||||
|
||||
private:
|
||||
QString m_type;
|
||||
GeneratorMode m_mode;
|
||||
QList< dyncontrol_ptr > m_controls;
|
||||
QList< QVariant > m_controlsV;
|
||||
};
|
||||
|
||||
#endif // DATABASECOMMAND_SETDYNAMICPLAYLISTREVISION_H
|
@@ -14,10 +14,10 @@ DatabaseCommand_SetPlaylistRevision::DatabaseCommand_SetPlaylistRevision(
|
||||
const QStringList& orderedguids,
|
||||
const QList<plentry_ptr>& addedentries )
|
||||
: DatabaseCommandLoggable( s )
|
||||
, m_applied( false )
|
||||
, m_newrev( newrev )
|
||||
, m_oldrev( oldrev )
|
||||
, m_addedentries( addedentries )
|
||||
, m_applied( false )
|
||||
{
|
||||
setPlaylistguid( playlistguid );
|
||||
|
||||
|
@@ -69,14 +69,16 @@ public:
|
||||
void setOrderedguids( const QVariantList& l ) { m_orderedguids = l; }
|
||||
QVariantList orderedguids() const { return m_orderedguids; }
|
||||
|
||||
protected:
|
||||
bool m_applied;
|
||||
QStringList m_previous_rev_orderedguids;
|
||||
QMap<QString, Tomahawk::plentry_ptr> m_addedmap;
|
||||
|
||||
private:
|
||||
QString m_playlistguid;
|
||||
QString m_newrev, m_oldrev;
|
||||
QVariantList m_orderedguids;
|
||||
QStringList m_previous_rev_orderedguids;
|
||||
QList<Tomahawk::plentry_ptr> m_addedentries;
|
||||
bool m_applied;
|
||||
QMap<QString, Tomahawk::plentry_ptr> m_addedmap;
|
||||
};
|
||||
|
||||
#endif // DATABASECOMMAND_SETPLAYLISTREVISION_H
|
||||
|
@@ -97,6 +97,28 @@ CREATE TABLE IF NOT EXISTS playlist_revision (
|
||||
previous_revision TEXT REFERENCES playlist_revision(guid) DEFERRABLE INITIALLY DEFERRED
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS dynamic_playlist {
|
||||
guid TEXT PRIMARY KEY,
|
||||
pltype TEXT, -- the generator type
|
||||
plmode INTEGER -- the mode of this playlist
|
||||
};
|
||||
|
||||
-- list of controls in each playlist. each control saves a selectedType, a match, and an input
|
||||
CREATE TABLE IF NOT EXISTS dynamic_playlist_controls {
|
||||
id TEXT PRIMARY KEY,
|
||||
playlist TEXT NOT NULL REFERENCES playlist(guid) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
|
||||
selectedType TEXT,
|
||||
match TEXT,
|
||||
input TEXT
|
||||
};
|
||||
|
||||
CREATE TABLE IF NOT EXISTS dynamic_playlist_revision {
|
||||
guid TEXT PRIMARY KEY,
|
||||
controls TEXT, -- qlist( id, id, id )
|
||||
plmode INTEGER REFERENCES dynamic_playlist( plmode ) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
|
||||
pltype TEXT REFERENCES dynamic_playlist( pltype ) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED
|
||||
};
|
||||
|
||||
--INSERT INTO playlist_revision(guid, playlist, entries)
|
||||
-- VALUES('revisionguid-1', 'playlistguid-1', '["itemguid-2","itemguid-1","itemguid-3"]');
|
||||
|
||||
|
@@ -3,6 +3,7 @@
|
||||
// subclass QSqlQuery so that it prints the error msg if a query fails
|
||||
|
||||
#include <QSqlQuery>
|
||||
#include <QSqlError>
|
||||
#include <QTime>
|
||||
|
||||
#define TOMAHAWK_QUERY_THRESHOLD 20
|
||||
|
34
src/dynamic/dynamiccontrol.cpp
Normal file
34
src/dynamic/dynamiccontrol.cpp
Normal file
@@ -0,0 +1,34 @@
|
||||
/****************************************************************************************
|
||||
* Copyright (c) 2010 Leo Franchi <lfranchi@kde.org> *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify it under *
|
||||
* the terms of the GNU General Public License as published by the Free Software *
|
||||
* Foundation; either version 2 of the License, or (at your option) any later *
|
||||
* version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY *
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE. See the GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License along with *
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include "dynamiccontrol.h"
|
||||
|
||||
Tomahawk::DynamicControl::DynamicControl()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Tomahawk::DynamicControl::~DynamicControl()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Tomahawk::DynamicControl::DynamicControl(const QString& selectedType, QObject* parent)
|
||||
: QObject(parent)
|
||||
, m_selectedType( selectedType )
|
||||
{
|
||||
|
||||
}
|
@@ -21,6 +21,7 @@
|
||||
#include <QtCore/QSharedPointer>
|
||||
#include <QStringList>
|
||||
#include <QtGui/QWidget>
|
||||
#include <tomahawk/typedefs.h>
|
||||
|
||||
namespace Tomahawk
|
||||
{
|
||||
@@ -38,40 +39,63 @@ namespace Tomahawk
|
||||
class DynamicControl : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY( QString id READ id WRITE setId )
|
||||
Q_PROPERTY( QString selectedType READ selectedType WRITE setSelectedType )
|
||||
Q_PROPERTY( QStringList typeSelectors READ typeSelectors )
|
||||
Q_PROPERTY( QString match READ match WRITE setMatch )
|
||||
Q_PROPERTY( QString input READ input WRITE setInput )
|
||||
|
||||
public:
|
||||
// eff this :P
|
||||
DynamicControl();
|
||||
virtual ~DynamicControl();
|
||||
|
||||
|
||||
/// The current type of this control
|
||||
QString selectedType() const { return m_selectedType; }
|
||||
/// The match selector widget based on this control's type
|
||||
virtual QWidget* matchSelector() { return 0; }
|
||||
virtual QWidget* matchSelector() { Q_ASSERT( false ); return 0; }
|
||||
/// The input field widget that is associated with this type
|
||||
virtual QWidget* inputField() { return 0; }
|
||||
virtual QWidget* inputField() { Q_ASSERT( false ); return 0; }
|
||||
|
||||
/// the serializable value of the match
|
||||
QString match() const { Q_ASSERT( false ); return QString(); }
|
||||
/// the serializable value of the input
|
||||
QString input() const { Q_ASSERT( false ); return QString(); }
|
||||
|
||||
// used by JSON serialization
|
||||
void setMatch( const QString& match ) { m_match = match; }
|
||||
void setInput( const QString& input ) { m_input = input; }
|
||||
|
||||
/// 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; }
|
||||
|
||||
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& type ) { m_selectedType = type; }
|
||||
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& type, const QStringList& typeSelectors, QObject* parent = 0 ) : QObject( parent ), m_selectedType( type ), m_typeSelectors( typeSelectors ) {}
|
||||
explicit DynamicControl( const QString& selectedType, QObject* parent = 0 );
|
||||
|
||||
QString m_match;
|
||||
QString m_input;
|
||||
|
||||
private:
|
||||
QString m_selectedType;
|
||||
QStringList m_typeSelectors;
|
||||
QString m_id;
|
||||
};
|
||||
|
||||
typedef QSharedPointer<DynamicControl> dyncontrol_ptr;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@@ -20,9 +20,24 @@
|
||||
#include "generatorfactory.h"
|
||||
#include "database.h"
|
||||
#include "databasecommand.h"
|
||||
#include "databasecommand_createdynamicplaylist.h"
|
||||
#include "databasecommand_setdynamicplaylistrevision.h"
|
||||
#include "databasecommand_loaddynamicplaylist.h"
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
DynamicPlaylist::DynamicPlaylist(const Tomahawk::source_ptr& author)
|
||||
: Playlist(author)
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << "JSON";
|
||||
}
|
||||
|
||||
|
||||
DynamicPlaylist::~DynamicPlaylist()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// Called by loadAllPlaylists command
|
||||
DynamicPlaylist::DynamicPlaylist ( const Tomahawk::source_ptr& src,
|
||||
const QString& currentrevision,
|
||||
@@ -54,6 +69,33 @@ DynamicPlaylist::DynamicPlaylist ( const Tomahawk::source_ptr& author,
|
||||
// TODO instantiate generator
|
||||
}
|
||||
|
||||
geninterface_ptr DynamicPlaylist::generator() const
|
||||
{
|
||||
return m_generator;
|
||||
}
|
||||
|
||||
GeneratorMode DynamicPlaylist::mode() const
|
||||
{
|
||||
return m_generator->mode();
|
||||
}
|
||||
|
||||
void DynamicPlaylist::setGenerator(const Tomahawk::geninterface_ptr& gen_ptr)
|
||||
{
|
||||
m_generator = gen_ptr;
|
||||
}
|
||||
|
||||
QString DynamicPlaylist::type() const
|
||||
{
|
||||
return m_generator->type();
|
||||
}
|
||||
|
||||
void DynamicPlaylist::setMode(GeneratorMode mode)
|
||||
{
|
||||
m_generator->setMode( mode );
|
||||
}
|
||||
|
||||
|
||||
|
||||
dynplaylist_ptr DynamicPlaylist::create( const Tomahawk::source_ptr& author,
|
||||
const QString& guid,
|
||||
const QString& title,
|
||||
@@ -129,8 +171,7 @@ void DynamicPlaylist::loadRevision( const QString& rev )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
DatabaseCommand_LoadDynamicPlaylist* cmd =
|
||||
new DatabaseCommand_LoadDynamicPlaylist( rev.isEmpty() ? currentrevision() : rev, m_generator->mode() );
|
||||
DatabaseCommand_LoadDynamicPlaylist* cmd = new DatabaseCommand_LoadDynamicPlaylist( rev.isEmpty() ? currentrevision() : rev );
|
||||
|
||||
if( m_generator->mode() == OnDemand ) {
|
||||
connect( cmd, SIGNAL( done( QString,
|
||||
@@ -238,6 +279,18 @@ void DynamicPlaylist::setRevision( const QString& rev,
|
||||
const QList< dyncontrol_ptr>& controls,
|
||||
bool applied )
|
||||
{
|
||||
if( QThread::currentThread() != thread() )
|
||||
{
|
||||
QMetaObject::invokeMethod( this,
|
||||
"setRevision",
|
||||
Qt::BlockingQueuedConnection,
|
||||
Q_ARG( QString, rev ),
|
||||
Q_ARG( bool, is_newest_rev ),
|
||||
Q_ARG( QString, type ),
|
||||
QGenericArgument( "QList< dyncontrol_ptr >" , (const void*)&controls ),
|
||||
Q_ARG( bool, applied ) );
|
||||
return;
|
||||
}
|
||||
if( m_generator->type() != type ) { // new generator needed
|
||||
m_generator = geninterface_ptr( GeneratorFactory::create( type ) );
|
||||
}
|
||||
|
@@ -22,7 +22,8 @@
|
||||
#include <QSharedPointer>
|
||||
|
||||
#include "tomahawk/playlist.h"
|
||||
#include "dynamic/generatorinterface.h"
|
||||
#include "tomahawk/typedefs.h"
|
||||
#include "dynamic/dynamiccontrol.h"
|
||||
|
||||
namespace Tomahawk {
|
||||
|
||||
@@ -42,6 +43,8 @@ struct DynamicPlaylistRevision : PlaylistRevision
|
||||
revisionguid = other.revisionguid;
|
||||
oldrevisionguid = other.oldrevisionguid;
|
||||
newlist = other.newlist;
|
||||
added = other.added;
|
||||
removed = other.removed;
|
||||
applied = other.applied;
|
||||
}
|
||||
|
||||
@@ -56,6 +59,8 @@ class DynamicPlaylist : public Playlist
|
||||
Q_PROPERTY( QString type WRITE setType READ type )
|
||||
|
||||
public:
|
||||
virtual ~DynamicPlaylist();
|
||||
|
||||
/// Generate an empty dynamic playlist with default generator
|
||||
static Tomahawk::dynplaylist_ptr create( const source_ptr& author,
|
||||
const QString& guid,
|
||||
@@ -68,22 +73,18 @@ public:
|
||||
|
||||
virtual void loadRevision( const QString& rev = "" );
|
||||
|
||||
GeneratorMode mode() const { return m_generator->mode(); }
|
||||
QString type() const { return m_generator->type(); }
|
||||
geninterface_ptr generator() const { return m_generator; }
|
||||
GeneratorMode mode() const;
|
||||
QString type() const;
|
||||
geninterface_ptr generator() const;
|
||||
|
||||
// <IGNORE hack="true">
|
||||
// these need to exist and be public for the json serialization stuff
|
||||
// you SHOULD NOT call them. They are used for an alternate CTOR method from json.
|
||||
// maybe friend QObjectHelper and make them private?
|
||||
explicit DynamicPlaylist( const source_ptr& author )
|
||||
: Playlist( author )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << "JSON";
|
||||
}
|
||||
void setMode( GeneratorMode mode ) { m_generator->setMode( mode ); }
|
||||
explicit DynamicPlaylist( const source_ptr& author );
|
||||
void setMode( GeneratorMode mode );
|
||||
void setType( const QString& type ) { /** TODO */; }
|
||||
void setGenerator( const geninterface_ptr& gen_ptr ) { m_generator = gen_ptr; }
|
||||
void setGenerator( const geninterface_ptr& gen_ptr );
|
||||
// </IGNORE>
|
||||
|
||||
signals:
|
||||
@@ -140,6 +141,7 @@ private:
|
||||
bool shared );
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(DynamicPlaylist)
|
||||
geninterface_ptr m_generator;
|
||||
};
|
||||
|
||||
|
@@ -22,8 +22,8 @@
|
||||
#include <QLineEdit>
|
||||
|
||||
|
||||
Tomahawk::EchonestControl::EchonestControl( const QString& type, const QStringList& typeSelectors, QObject* parent )
|
||||
: DynamicControl ( type, typeSelectors, parent )
|
||||
Tomahawk::EchonestControl::EchonestControl( const QString& type, QObject* parent )
|
||||
: DynamicControl ( type, parent )
|
||||
{
|
||||
updateWidgets();
|
||||
}
|
||||
@@ -76,11 +76,11 @@ Tomahawk::EchonestControl::updateWidgets()
|
||||
void Tomahawk::EchonestControl::updateData()
|
||||
{
|
||||
if( selectedType() == "Artist" ) {
|
||||
QWeakPointer<QComboBox> combo = qWeakPointerCast( m_match );
|
||||
QWeakPointer<QComboBox> combo = qWeakPointerCast<QComboBox, QWidget>( m_match );
|
||||
if( !combo.isNull() )
|
||||
m_data.first = static_cast<Echonest::DynamicPlaylist::PlaylistParam>( combo.data()->itemData( combo->currentIndex() ) );
|
||||
QWeakPointer<QLineEdit> edit = qWeakPointerCast( m_input );
|
||||
m_data.first = static_cast<Echonest::DynamicPlaylist::PlaylistParam>( combo.data()->itemData( combo.data()->currentIndex() ).toInt() );
|
||||
QWeakPointer<QLineEdit> edit = qWeakPointerCast<QLineEdit, QWidget>( m_input );
|
||||
if( !edit.isNull() )
|
||||
m_data.second = qWeakPointerCast->text();
|
||||
m_data.second = edit.data()->text();
|
||||
}
|
||||
}
|
||||
|
@@ -37,12 +37,12 @@ public:
|
||||
public slots:
|
||||
virtual void setSelectedType ( const QString& type );
|
||||
|
||||
protected:
|
||||
explicit EchonestControl( const QString& type, const QStringList& typeSelectors, QObject* parent = 0 );
|
||||
|
||||
private slots:
|
||||
void updateData();
|
||||
|
||||
protected:
|
||||
explicit EchonestControl( const QString& type, QObject* parent = 0 );
|
||||
|
||||
private:
|
||||
void updateWidgets();
|
||||
|
||||
@@ -50,6 +50,8 @@ private:
|
||||
QWeakPointer< QWidget > m_match;
|
||||
|
||||
Echonest::DynamicPlaylist::PlaylistParamData m_data;
|
||||
|
||||
friend class EchonestGenerator;
|
||||
};
|
||||
|
||||
typedef QSharedPointer<EchonestControl> encontrol_ptr;
|
||||
|
@@ -16,12 +16,12 @@
|
||||
|
||||
#include "echonest/echonestgenerator.h"
|
||||
#include "echonest/echonestcontrol.h"
|
||||
#include "query.h"
|
||||
#include "tomahawk/query.h"
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
|
||||
EchonestFactory::GeneratorFactoryInterface()
|
||||
EchonestFactory::EchonestFactory()
|
||||
{}
|
||||
|
||||
GeneratorInterface*
|
||||
@@ -32,12 +32,12 @@ EchonestFactory::create()
|
||||
|
||||
EchonestGenerator::EchonestGenerator ( QObject* parent )
|
||||
: GeneratorInterface ( parent )
|
||||
, m_type( "echonest" )
|
||||
, m_mode( OnDemand )
|
||||
{
|
||||
m_typeSelectors << "Variety" << "Artist" << "Description" << "Tempo" << "Duration" << "Loudness"
|
||||
<< "Danceability" << "Energy" << "Artist Familiarity" << "Artist Hotttnesss" << "Song Familiarity"
|
||||
<< "Longitude" << "Latitude" << "Mode" << "Key" << "Sorting";
|
||||
m_type = "echonest";
|
||||
m_mode = OnDemand;
|
||||
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ EchonestGenerator::~EchonestGenerator()
|
||||
dyncontrol_ptr
|
||||
EchonestGenerator::createControl( const QString& type ) const
|
||||
{
|
||||
return dyncontrol_ptr( new EchonestControl( type, m_typeSelectors ) );
|
||||
return dyncontrol_ptr( new EchonestControl( type ) );
|
||||
}
|
||||
|
||||
void
|
||||
|
@@ -39,7 +39,7 @@ class EchonestGenerator : public GeneratorInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit EchonestGenerator( QObject* parent );
|
||||
explicit EchonestGenerator( QObject* parent = 0 );
|
||||
virtual ~EchonestGenerator();
|
||||
|
||||
virtual dyncontrol_ptr createControl( const QString& type = QString() ) const;
|
||||
|
@@ -1,24 +1,19 @@
|
||||
#include "dynamic/generatorfactory.h"
|
||||
#include "dynamic/generatorinterface.h"
|
||||
|
||||
Tomahawk::GeneratorFactory::GeneratorFactory()
|
||||
{
|
||||
}
|
||||
using namespace Tomahawk;
|
||||
|
||||
Tomahawk::GeneratorFactory::~GeneratorFactory()
|
||||
{
|
||||
qDeleteAll( m_factories.values() );
|
||||
}
|
||||
QHash< QString, GeneratorFactoryInterface* > GeneratorFactory::s_factories = QHash< QString, GeneratorFactoryInterface* >();
|
||||
|
||||
generatorinterface_ptr Tomahawk::GeneratorFactory::create ( const QString& type )
|
||||
geninterface_ptr GeneratorFactory::create ( const QString& type )
|
||||
{
|
||||
if( !m_factories.contains( type ) )
|
||||
if( !s_factories.contains( type ) )
|
||||
return geninterface_ptr();
|
||||
|
||||
return geninterface_ptr( m_factories.value( type )->create() );
|
||||
return geninterface_ptr( s_factories.value( type )->create() );
|
||||
}
|
||||
|
||||
void Tomahawk::GeneratorFactory::registerFactory ( const QString& type, Tomahawk::GeneratorFactoryInterface* interface )
|
||||
void GeneratorFactory::registerFactory ( const QString& type, GeneratorFactoryInterface* interface )
|
||||
{
|
||||
m_factories.insert( type, interface );
|
||||
s_factories.insert( type, interface );
|
||||
}
|
||||
|
@@ -29,7 +29,7 @@ public:
|
||||
static void registerFactory( const QString& type, GeneratorFactoryInterface* interface );
|
||||
|
||||
private:
|
||||
static QHash<QString, GeneratorFactoryInterface*> m_factories;
|
||||
static QHash<QString, GeneratorFactoryInterface*> s_factories;
|
||||
|
||||
};
|
||||
|
||||
|
33
src/dynamic/generatorinterface.cpp
Normal file
33
src/dynamic/generatorinterface.cpp
Normal file
@@ -0,0 +1,33 @@
|
||||
/****************************************************************************************
|
||||
* Copyright (c) 2010 Leo Franchi <lfranchi@kde.org> *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify it under *
|
||||
* the terms of the GNU General Public License as published by the Free Software *
|
||||
* Foundation; either version 2 of the License, or (at your option) any later *
|
||||
* version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY *
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE. See the GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License along with *
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include "dynamic/generatorinterface.h"
|
||||
|
||||
// lame
|
||||
Tomahawk::GeneratorInterface::GeneratorInterface()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Tomahawk::GeneratorInterface::GeneratorInterface( QObject* parent ): QObject( parent )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Tomahawk::GeneratorInterface::~GeneratorInterface()
|
||||
{
|
||||
|
||||
}
|
@@ -25,11 +25,6 @@
|
||||
|
||||
namespace Tomahawk {
|
||||
|
||||
enum GeneratorMode {
|
||||
OnDemand = 0,
|
||||
Static
|
||||
};
|
||||
|
||||
/**
|
||||
* The abstract interface for Dynamic Playlist Generators. Generators have the following features:
|
||||
* - They create new DynamicControls that are appropriate for the generator
|
||||
@@ -43,11 +38,12 @@ class GeneratorInterface : public QObject
|
||||
Q_OBJECT
|
||||
Q_PROPERTY( QString type READ type )
|
||||
Q_PROPERTY( GeneratorMode mode READ mode WRITE setMode );
|
||||
Q_ENUMS( GeneratorMode )
|
||||
|
||||
public:
|
||||
explicit GeneratorInterface( QObject* parent = 0 ) : QObject( parent ) {}
|
||||
virtual ~GeneratorInterface() {}
|
||||
// can't inline constructors/destructors for forward declared shared pointer types
|
||||
GeneratorInterface();
|
||||
explicit GeneratorInterface( QObject* parent = 0 );
|
||||
virtual ~GeneratorInterface();
|
||||
|
||||
// Can't make it pure otherwise we can't shove it in QVariants :-/
|
||||
// empty QString means use default
|
||||
@@ -85,6 +81,9 @@ protected:
|
||||
GeneratorMode m_mode;
|
||||
QList< dyncontrol_ptr > m_controls;
|
||||
QStringList m_typeSelectors;
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(GeneratorInterface)
|
||||
};
|
||||
|
||||
typedef QSharedPointer<GeneratorInterface> geninterface_ptr;
|
||||
|
@@ -1,3 +1,4 @@
|
||||
|
||||
#ifndef FILETRANSFERCONNECTION_H
|
||||
#define FILETRANSFERCONNECTION_H
|
||||
|
||||
@@ -7,6 +8,7 @@
|
||||
|
||||
#include "connection.h"
|
||||
#include "tomahawk/result.h"
|
||||
#include "tomahawk/source.h"
|
||||
|
||||
class ControlConnection;
|
||||
class BufferIODevice;
|
||||
|
@@ -28,6 +28,13 @@ PlaylistEntry::queryvariant() const
|
||||
}
|
||||
|
||||
|
||||
Playlist::Playlist( const source_ptr& author )
|
||||
: m_source( author )
|
||||
, m_lastmodified( 0 )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << "JSON";
|
||||
}
|
||||
|
||||
// used when loading from DB:
|
||||
Playlist::Playlist( const source_ptr& src,
|
||||
const QString& currentrevision,
|
||||
|
@@ -1,6 +1,7 @@
|
||||
#include "plitem.h"
|
||||
|
||||
#include "utils/tomahawkutils.h"
|
||||
#include "tomahawk/playlist.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
@@ -66,6 +67,18 @@ PlItem::PlItem( const Tomahawk::plentry_ptr& entry, PlItem* parent, int row )
|
||||
setupItem( entry->query(), parent, row );
|
||||
}
|
||||
|
||||
const Tomahawk::plentry_ptr&
|
||||
PlItem::entry() const
|
||||
{
|
||||
return m_entry;
|
||||
}
|
||||
|
||||
const Tomahawk::query_ptr&
|
||||
PlItem::query() const
|
||||
{
|
||||
if ( !m_entry.isNull() ) return m_entry->query(); else return m_query;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PlItem::setupItem( const Tomahawk::query_ptr& query, PlItem* parent, int row )
|
||||
|
@@ -2,11 +2,11 @@
|
||||
#define PLITEM_H
|
||||
|
||||
#include <QHash>
|
||||
#include <QVector>
|
||||
#include <QPersistentModelIndex>
|
||||
#include <QAbstractItemModel>
|
||||
|
||||
#include "tomahawk/query.h"
|
||||
|
||||
#include "tomahawk/result.h"
|
||||
#include "tomahawk/typedefs.h"
|
||||
|
||||
class PlItem : public QObject
|
||||
@@ -14,15 +14,15 @@ class PlItem : public QObject
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
~PlItem();
|
||||
virtual ~PlItem();
|
||||
|
||||
explicit PlItem( PlItem* parent = 0, QAbstractItemModel* model = 0 );
|
||||
explicit PlItem( const QString& caption, PlItem* parent = 0 );
|
||||
explicit PlItem( const Tomahawk::query_ptr& query, PlItem* parent = 0, int row = -1 );
|
||||
explicit PlItem( const Tomahawk::plentry_ptr& entry, PlItem* parent = 0, int row = -1 );
|
||||
|
||||
const Tomahawk::plentry_ptr& entry() const { return m_entry; };
|
||||
const Tomahawk::query_ptr& query() const { if ( !m_entry.isNull() ) return m_entry->query(); else return m_query; };
|
||||
const Tomahawk::plentry_ptr& entry() const;
|
||||
const Tomahawk::query_ptr& query() const;
|
||||
|
||||
bool isPlaying() { return m_isPlaying; }
|
||||
void setIsPlaying( bool b ) { m_isPlaying = b; emit dataChanged(); }
|
||||
|
@@ -30,6 +30,25 @@ Result::Result( const QVariant& v, const collection_ptr& collection )
|
||||
connect( m_collection->source().data(), SIGNAL( offline() ), SIGNAL( becomingUnavailable() ), Qt::QueuedConnection );
|
||||
}
|
||||
|
||||
Result::~Result() {}
|
||||
|
||||
artist_ptr
|
||||
Result::artist() const
|
||||
{
|
||||
return m_artist;
|
||||
}
|
||||
|
||||
album_ptr
|
||||
Result::album() const
|
||||
{
|
||||
return m_album;
|
||||
}
|
||||
|
||||
collection_ptr
|
||||
Result::collection() const
|
||||
{
|
||||
return m_collection;
|
||||
}
|
||||
|
||||
float
|
||||
Result::score() const
|
||||
|
@@ -10,7 +10,6 @@
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
|
||||
Source::Source( const QString &username, ControlConnection* cc )
|
||||
: QObject()
|
||||
, m_isLocal( false )
|
||||
|
@@ -3,6 +3,8 @@
|
||||
#include <QWheelEvent>
|
||||
|
||||
#include "tomahawk/tomahawkapp.h"
|
||||
#include "tomahawk/artist.h"
|
||||
|
||||
#include "audio/audioengine.h"
|
||||
#include "tomahawkwindow.h"
|
||||
|
||||
|
@@ -16,6 +16,7 @@
|
||||
#include "tomahawk/functimeout.h"
|
||||
#include "tomahawk/playlist.h"
|
||||
#include "tomahawk/query.h"
|
||||
#include "tomahawk/artist.h"
|
||||
|
||||
#include "database/databasecommand_collectionstats.h"
|
||||
#include "topbar/topbar.h"
|
||||
|
@@ -4,6 +4,7 @@
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include "tomahawk/tomahawkapp.h"
|
||||
#include "tomahawk/artist.h"
|
||||
#include "network/filetransferconnection.h"
|
||||
#include "network/servent.h"
|
||||
|
||||
|
Reference in New Issue
Block a user