1
0
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:
Leo Franchi
2010-12-06 20:44:39 -05:00
parent 228cab7080
commit 6a4a4a18e9
44 changed files with 977 additions and 132 deletions

View File

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

View File

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

View File

@@ -6,7 +6,7 @@
#include <QList>
#include <QVariant>
#include "tomahawk/collection.h"
// #include "tomahawk/collection.h"
#include "tomahawk/result.h"
#include "tomahawk/typedefs.h"

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View 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();
}

View 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

View File

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

View 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 );
}
}

View 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

View File

@@ -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();
// qDebug() << "Entries:" << guids;
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;
}

View File

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

View 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";
} */
}

View 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

View File

@@ -13,11 +13,11 @@ DatabaseCommand_SetPlaylistRevision::DatabaseCommand_SetPlaylistRevision(
const QString& oldrev,
const QStringList& orderedguids,
const QList<plentry_ptr>& addedentries )
: DatabaseCommandLoggable( s )
: DatabaseCommandLoggable( s )
, m_applied( false )
, m_newrev( newrev )
, m_oldrev( oldrev )
, m_addedentries( addedentries )
, m_applied( false )
{
setPlaylistguid( playlistguid );

View File

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

View File

@@ -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"]');

View File

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

View 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 )
{
}

View File

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

View File

@@ -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 ) );
}

View File

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

View File

@@ -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();
}
}

View File

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

View File

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

View File

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

View File

@@ -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 );
}

View File

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

View 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()
{
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -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(); }

View File

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

View File

@@ -10,7 +10,6 @@
using namespace Tomahawk;
Source::Source( const QString &username, ControlConnection* cc )
: QObject()
, m_isLocal( false )

View File

@@ -3,6 +3,8 @@
#include <QWheelEvent>
#include "tomahawk/tomahawkapp.h"
#include "tomahawk/artist.h"
#include "audio/audioengine.h"
#include "tomahawkwindow.h"

View File

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

View File

@@ -4,6 +4,7 @@
#include <QVBoxLayout>
#include "tomahawk/tomahawkapp.h"
#include "tomahawk/artist.h"
#include "network/filetransferconnection.h"
#include "network/servent.h"