mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-08-16 02:54:33 +02:00
Merge branch 'multipleupdaters'
This commit is contained in:
@@ -123,8 +123,18 @@ SpotifyAccount::aboutToShow( QAction* action, const playlist_ptr& playlist )
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// If it's not being synced, allow the option to sync
|
// If it's not being synced, allow the option to sync
|
||||||
SpotifyPlaylistUpdater* updater = qobject_cast< SpotifyPlaylistUpdater* >( playlist->updater() );
|
bool found = false;
|
||||||
if ( !updater || !updater->sync() )
|
QList<PlaylistUpdaterInterface*> updaters = playlist->updaters();
|
||||||
|
foreach ( PlaylistUpdaterInterface* updater, updaters )
|
||||||
|
{
|
||||||
|
if ( SpotifyPlaylistUpdater* spotifyUpdater = qobject_cast< SpotifyPlaylistUpdater* >( updater ) )
|
||||||
|
{
|
||||||
|
if ( spotifyUpdater->sync() )
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !found )
|
||||||
{
|
{
|
||||||
action->setText( tr( "Sync with Spotify" ) );
|
action->setText( tr( "Sync with Spotify" ) );
|
||||||
}
|
}
|
||||||
@@ -152,7 +162,15 @@ SpotifyAccount::syncActionTriggered( bool checked )
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SpotifyPlaylistUpdater* updater = qobject_cast< SpotifyPlaylistUpdater* >( playlist->updater() );
|
SpotifyPlaylistUpdater* updater = 0;
|
||||||
|
QList<PlaylistUpdaterInterface*> updaters = playlist->updaters();
|
||||||
|
foreach ( PlaylistUpdaterInterface* u, updaters )
|
||||||
|
{
|
||||||
|
if ( SpotifyPlaylistUpdater* spotifyUpdater = qobject_cast< SpotifyPlaylistUpdater* >( u ) )
|
||||||
|
{
|
||||||
|
updater = spotifyUpdater;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ( !updater )
|
if ( !updater )
|
||||||
{
|
{
|
||||||
|
@@ -32,7 +32,7 @@ QPixmap* SpotifyPlaylistUpdater::s_typePixmap = 0;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
Tomahawk::PlaylistUpdaterInterface*
|
Tomahawk::PlaylistUpdaterInterface*
|
||||||
SpotifyUpdaterFactory::create( const Tomahawk::playlist_ptr& pl, const QString &key )
|
SpotifyUpdaterFactory::create( const Tomahawk::playlist_ptr& pl, const QVariantHash &settings )
|
||||||
{
|
{
|
||||||
if ( !m_account )
|
if ( !m_account )
|
||||||
{
|
{
|
||||||
@@ -54,9 +54,9 @@ SpotifyUpdaterFactory::create( const Tomahawk::playlist_ptr& pl, const QString &
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Register the updater with the account
|
// Register the updater with the account
|
||||||
const QString spotifyId = TomahawkSettings::instance()->value( QString( "%1/spotifyId" ).arg( key ) ).toString();
|
const QString spotifyId = settings.value( "spotifyId" ).toString();
|
||||||
const QString latestRev = TomahawkSettings::instance()->value( QString( "%1/latestrev" ).arg( key ) ).toString();
|
const QString latestRev = settings.value( "latestrev" ).toString();
|
||||||
const bool sync = TomahawkSettings::instance()->value( QString( "%1/sync" ).arg( key ) ).toBool();
|
const bool sync = settings.value( "sync" ).toBool();
|
||||||
|
|
||||||
Q_ASSERT( !spotifyId.isEmpty() );
|
Q_ASSERT( !spotifyId.isEmpty() );
|
||||||
SpotifyPlaylistUpdater* updater = new SpotifyPlaylistUpdater( m_account.data(), latestRev, spotifyId, pl );
|
SpotifyPlaylistUpdater* updater = new SpotifyPlaylistUpdater( m_account.data(), latestRev, spotifyId, pl );
|
||||||
@@ -89,6 +89,8 @@ SpotifyPlaylistUpdater::init()
|
|||||||
connect( playlist().data(), SIGNAL( renamed( QString, QString ) ), this, SLOT( tomahawkPlaylistRenamed( QString, QString ) ) );
|
connect( playlist().data(), SIGNAL( renamed( QString, QString ) ), this, SLOT( tomahawkPlaylistRenamed( QString, QString ) ) );
|
||||||
connect( playlist().data(), SIGNAL( revisionLoaded( Tomahawk::PlaylistRevision ) ), this, SLOT( playlistRevisionLoaded() ), Qt::QueuedConnection ); // Queued so that in Playlist.cpp:443 we let the playlist clear its own queue first
|
connect( playlist().data(), SIGNAL( revisionLoaded( Tomahawk::PlaylistRevision ) ), this, SLOT( playlistRevisionLoaded() ), Qt::QueuedConnection ); // Queued so that in Playlist.cpp:443 we let the playlist clear its own queue first
|
||||||
// TODO reorders in a playlist
|
// TODO reorders in a playlist
|
||||||
|
|
||||||
|
saveToSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -122,12 +124,8 @@ SpotifyPlaylistUpdater::remove( bool askToDeletePlaylist )
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
SpotifyPlaylistUpdater::removeFromSettings( const QString& group ) const
|
SpotifyPlaylistUpdater::aboutToDelete()
|
||||||
{
|
{
|
||||||
TomahawkSettings::instance()->remove( QString( "%1/latestrev" ).arg( group ) );
|
|
||||||
TomahawkSettings::instance()->remove( QString( "%1/sync" ).arg( group ) );
|
|
||||||
TomahawkSettings::instance()->remove( QString( "%1/spotifyId" ).arg( group ) );
|
|
||||||
|
|
||||||
if ( m_sync )
|
if ( m_sync )
|
||||||
{
|
{
|
||||||
if ( QThread::currentThread() != QApplication::instance()->thread() )
|
if ( QThread::currentThread() != QApplication::instance()->thread() )
|
||||||
@@ -173,11 +171,15 @@ SpotifyPlaylistUpdater::playlistRevisionLoaded()
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
SpotifyPlaylistUpdater::saveToSettings( const QString& group ) const
|
SpotifyPlaylistUpdater::saveToSettings()
|
||||||
{
|
{
|
||||||
TomahawkSettings::instance()->setValue( QString( "%1/latestrev" ).arg( group ), m_latestRev );
|
QVariantHash s = settings();
|
||||||
TomahawkSettings::instance()->setValue( QString( "%1/sync" ).arg( group ), m_sync );
|
|
||||||
TomahawkSettings::instance()->setValue( QString( "%1/spotifyId" ).arg( group ), m_spotifyId );
|
s[ "latestrev" ] = m_latestRev;
|
||||||
|
s[ "sync" ] = m_sync;
|
||||||
|
s[ "spotifyId" ] = m_spotifyId;
|
||||||
|
|
||||||
|
saveSettings( s );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -214,6 +216,7 @@ SpotifyPlaylistUpdater::setSync( bool sync )
|
|||||||
|
|
||||||
m_sync = sync;
|
m_sync = sync;
|
||||||
|
|
||||||
|
saveToSettings();
|
||||||
emit changed();
|
emit changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -543,6 +546,9 @@ SpotifyPlaylistUpdater::onTracksInsertedReturn( const QString& msgType, const QV
|
|||||||
if ( changed.size() > 0 )
|
if ( changed.size() > 0 )
|
||||||
playlist()->updateEntries( uuid(), playlist()->currentrevision(), changed );
|
playlist()->updateEntries( uuid(), playlist()->currentrevision(), changed );
|
||||||
|
|
||||||
|
// Update with latest rev when/if we use it
|
||||||
|
// saveToSettings();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -67,9 +67,9 @@ public slots:
|
|||||||
void tomahawkTracksRemoved( const QList<Tomahawk::query_ptr>& );
|
void tomahawkTracksRemoved( const QList<Tomahawk::query_ptr>& );
|
||||||
void tomahawkTracksMoved( const QList<Tomahawk::plentry_ptr>& ,int );
|
void tomahawkTracksMoved( const QList<Tomahawk::plentry_ptr>& ,int );
|
||||||
void tomahawkPlaylistRenamed( const QString&, const QString& );
|
void tomahawkPlaylistRenamed( const QString&, const QString& );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void removeFromSettings(const QString& group) const;
|
void aboutToDelete();
|
||||||
virtual void saveToSettings(const QString& group) const;
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
// SpotifyResolver message handlers, all take msgtype, msg as argument
|
// SpotifyResolver message handlers, all take msgtype, msg as argument
|
||||||
@@ -82,6 +82,8 @@ private slots:
|
|||||||
void playlistRevisionLoaded();
|
void playlistRevisionLoaded();
|
||||||
private:
|
private:
|
||||||
void init();
|
void init();
|
||||||
|
void saveToSettings();
|
||||||
|
|
||||||
/// Finds the nearest spotify id from pos to the beginning of the playlist
|
/// Finds the nearest spotify id from pos to the beginning of the playlist
|
||||||
QString nearestSpotifyTrack( const QList< Tomahawk::plentry_ptr >& entries, int pos );
|
QString nearestSpotifyTrack( const QList< Tomahawk::plentry_ptr >& entries, int pos );
|
||||||
QVariantList plentryToVariant( const QList< Tomahawk::plentry_ptr >& entries );
|
QVariantList plentryToVariant( const QList< Tomahawk::plentry_ptr >& entries );
|
||||||
@@ -109,7 +111,7 @@ class SpotifyUpdaterFactory : public Tomahawk::PlaylistUpdaterFactory
|
|||||||
public:
|
public:
|
||||||
SpotifyUpdaterFactory() {}
|
SpotifyUpdaterFactory() {}
|
||||||
|
|
||||||
virtual Tomahawk::PlaylistUpdaterInterface* create( const Tomahawk::playlist_ptr& pl, const QString& key );
|
virtual Tomahawk::PlaylistUpdaterInterface* create( const Tomahawk::playlist_ptr& pl, const QVariantHash& settings );
|
||||||
virtual QString type() const { return "spotify"; }
|
virtual QString type() const { return "spotify"; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@@ -270,8 +270,11 @@ void
|
|||||||
Playlist::reportDeleted( const Tomahawk::playlist_ptr& self )
|
Playlist::reportDeleted( const Tomahawk::playlist_ptr& self )
|
||||||
{
|
{
|
||||||
Q_ASSERT( self.data() == this );
|
Q_ASSERT( self.data() == this );
|
||||||
if ( !m_updater.isNull() )
|
if ( !m_updaters.isEmpty() )
|
||||||
m_updater.data()->remove();
|
{
|
||||||
|
foreach( PlaylistUpdaterInterface* updater, m_updaters )
|
||||||
|
updater->remove();
|
||||||
|
}
|
||||||
|
|
||||||
m_deleted = true;
|
m_deleted = true;
|
||||||
m_source->collection()->deletePlaylist( self );
|
m_source->collection()->deletePlaylist( self );
|
||||||
@@ -280,24 +283,25 @@ Playlist::reportDeleted( const Tomahawk::playlist_ptr& self )
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Playlist::setUpdater( PlaylistUpdaterInterface* pluinterface )
|
Playlist::addUpdater( PlaylistUpdaterInterface* updater )
|
||||||
{
|
{
|
||||||
if ( !m_updater.isNull() )
|
m_updaters << updater;
|
||||||
disconnect( m_updater.data(), SIGNAL( changed() ), this, SIGNAL( changed() ) );
|
|
||||||
|
|
||||||
m_updater = QWeakPointer< PlaylistUpdaterInterface >( pluinterface );
|
connect( updater, SIGNAL( changed() ), this, SIGNAL( changed() ), Qt::UniqueConnection );
|
||||||
|
connect( updater, SIGNAL( destroyed( QObject* ) ), this, SIGNAL( changed() ), Qt::QueuedConnection );
|
||||||
connect( m_updater.data(), SIGNAL( changed() ), this, SIGNAL( changed() ), Qt::UniqueConnection );
|
|
||||||
connect( m_updater.data(), SIGNAL( destroyed( QObject* ) ), this, SLOT( updaterDestroyed() ), Qt::QueuedConnection );
|
|
||||||
|
|
||||||
emit changed();
|
emit changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Playlist::updaterDestroyed()
|
Playlist::removeUpdater( PlaylistUpdaterInterface* updater )
|
||||||
{
|
{
|
||||||
m_updater.clear();
|
m_updaters.removeAll( updater );
|
||||||
|
|
||||||
|
disconnect( updater, SIGNAL( changed() ), this, SIGNAL( changed() ) );
|
||||||
|
disconnect( updater, SIGNAL( destroyed( QObject* ) ), this, SIGNAL( changed() ) );
|
||||||
|
|
||||||
emit changed();
|
emit changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -188,8 +188,10 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
QList<plentry_ptr> entriesFromQueries( const QList<Tomahawk::query_ptr>& queries, bool clearFirst = false );
|
QList<plentry_ptr> entriesFromQueries( const QList<Tomahawk::query_ptr>& queries, bool clearFirst = false );
|
||||||
void setUpdater( PlaylistUpdaterInterface* pluinterface );
|
|
||||||
PlaylistUpdaterInterface* updater() const { return m_updater.data(); }
|
void addUpdater( PlaylistUpdaterInterface* updater );
|
||||||
|
void removeUpdater( PlaylistUpdaterInterface* updater );
|
||||||
|
QList<PlaylistUpdaterInterface*> updaters() const { return m_updaters; }
|
||||||
|
|
||||||
Tomahawk::playlistinterface_ptr playlistInterface();
|
Tomahawk::playlistinterface_ptr playlistInterface();
|
||||||
|
|
||||||
@@ -278,7 +280,6 @@ protected:
|
|||||||
private slots:
|
private slots:
|
||||||
void onResultsFound( const QList<Tomahawk::result_ptr>& results );
|
void onResultsFound( const QList<Tomahawk::result_ptr>& results );
|
||||||
void onResolvingFinished();
|
void onResolvingFinished();
|
||||||
void updaterDestroyed();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Playlist();
|
Playlist();
|
||||||
@@ -300,7 +301,7 @@ private:
|
|||||||
QQueue<RevisionQueueItem> m_revisionQueue;
|
QQueue<RevisionQueueItem> m_revisionQueue;
|
||||||
QQueue<RevisionQueueItem> m_updateQueue;
|
QQueue<RevisionQueueItem> m_updateQueue;
|
||||||
|
|
||||||
QWeakPointer<PlaylistUpdaterInterface> m_updater;
|
QList<PlaylistUpdaterInterface*> m_updaters;
|
||||||
|
|
||||||
bool m_locallyChanged;
|
bool m_locallyChanged;
|
||||||
bool m_deleted;
|
bool m_deleted;
|
||||||
|
@@ -30,11 +30,50 @@
|
|||||||
|
|
||||||
#include "database/DatabaseCommand_UpdateSearchIndex.h"
|
#include "database/DatabaseCommand_UpdateSearchIndex.h"
|
||||||
#include "database/Database.h"
|
#include "database/Database.h"
|
||||||
|
#include "PlaylistUpdaterInterface.h"
|
||||||
|
|
||||||
using namespace Tomahawk;
|
using namespace Tomahawk;
|
||||||
|
|
||||||
TomahawkSettings* TomahawkSettings::s_instance = 0;
|
TomahawkSettings* TomahawkSettings::s_instance = 0;
|
||||||
|
|
||||||
|
|
||||||
|
inline QDataStream&
|
||||||
|
operator<<(QDataStream& out, const PlaylistUpdaterInterface::SerializedUpdaters& updaters)
|
||||||
|
{
|
||||||
|
out << TOMAHAWK_SETTINGS_VERSION;
|
||||||
|
out << (quint32)updaters.count();
|
||||||
|
foreach( const QString& key, updaters.keys() )
|
||||||
|
{
|
||||||
|
PlaylistUpdaterInterface::SerializedUpdater updater = updaters[ key ];
|
||||||
|
out << key << updater.type << updater.customData;
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline QDataStream&
|
||||||
|
operator>>(QDataStream& in, PlaylistUpdaterInterface::SerializedUpdaters& updaters)
|
||||||
|
{
|
||||||
|
quint32 count = 0, version = 0;
|
||||||
|
in >> version;
|
||||||
|
in >> count;
|
||||||
|
|
||||||
|
for ( uint i = 0; i < count; i++ )
|
||||||
|
{
|
||||||
|
QString key, type;
|
||||||
|
bool sync;
|
||||||
|
QVariantHash customData;
|
||||||
|
qint32 state, userRating;
|
||||||
|
in >> key;
|
||||||
|
in >> type;
|
||||||
|
in >> customData;
|
||||||
|
updaters[ key ] = PlaylistUpdaterInterface::SerializedUpdater( type, customData );
|
||||||
|
}
|
||||||
|
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
TomahawkSettings*
|
TomahawkSettings*
|
||||||
TomahawkSettings::instance()
|
TomahawkSettings::instance()
|
||||||
{
|
{
|
||||||
@@ -444,6 +483,38 @@ TomahawkSettings::doUpgrade( int oldVersion, int newVersion )
|
|||||||
setValue( "allaccounts", allAccounts );
|
setValue( "allaccounts", allAccounts );
|
||||||
endGroup();
|
endGroup();
|
||||||
}
|
}
|
||||||
|
else if ( oldVersion == 9 )
|
||||||
|
{
|
||||||
|
// Upgrade single-updater-per-playlist to list-per-playlist
|
||||||
|
beginGroup( "playlistupdaters" );
|
||||||
|
const QStringList playlists = childGroups();
|
||||||
|
|
||||||
|
PlaylistUpdaterInterface::SerializedUpdaters updaters;
|
||||||
|
foreach ( const QString& playlist, playlists )
|
||||||
|
{
|
||||||
|
beginGroup( playlist );
|
||||||
|
const QString type = value( "type" ).toString();
|
||||||
|
|
||||||
|
QVariantHash extraData;
|
||||||
|
foreach ( const QString& key, childKeys() )
|
||||||
|
{
|
||||||
|
if ( key == "type" )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
extraData[ key ] = value( key );
|
||||||
|
}
|
||||||
|
|
||||||
|
updaters[ playlist ] = PlaylistUpdaterInterface::SerializedUpdater( type, extraData );
|
||||||
|
|
||||||
|
endGroup();
|
||||||
|
}
|
||||||
|
|
||||||
|
endGroup();
|
||||||
|
|
||||||
|
setPlaylistUpdaters( updaters );
|
||||||
|
|
||||||
|
remove( "playlistupdaters" );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1174,3 +1245,26 @@ TomahawkSettings::setImportXspfPath( const QString& path )
|
|||||||
{
|
{
|
||||||
setValue( "importXspfPath", path );
|
setValue( "importXspfPath", path );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PlaylistUpdaterInterface::SerializedUpdaters
|
||||||
|
TomahawkSettings::playlistUpdaters() const
|
||||||
|
{
|
||||||
|
return value( "playlist/updaters" ).value< PlaylistUpdaterInterface::SerializedUpdaters >();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TomahawkSettings::setPlaylistUpdaters( const PlaylistUpdaterInterface::SerializedUpdaters& updaters )
|
||||||
|
{
|
||||||
|
setValue( "playlist/updaters", QVariant::fromValue< PlaylistUpdaterInterface::SerializedUpdaters >( updaters ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TomahawkSettings::registerCustomSettingsHandlers()
|
||||||
|
{
|
||||||
|
qRegisterMetaType< Tomahawk::PlaylistUpdaterInterface::SerializedUpdater >( "Tomahawk::PlaylistUpdaterInterface::SerializedUpdater" );
|
||||||
|
qRegisterMetaType< Tomahawk::PlaylistUpdaterInterface::SerializedUpdaters >( "Tomahawk::PlaylistUpdaterInterface::SerializedUpdaters" );
|
||||||
|
qRegisterMetaTypeStreamOperators< Tomahawk::PlaylistUpdaterInterface::SerializedUpdaters >( "Tomahawk::PlaylistUpdaterInterface::SerializedUpdaters" );
|
||||||
|
}
|
||||||
|
@@ -23,12 +23,14 @@
|
|||||||
|
|
||||||
#include "Playlist.h"
|
#include "Playlist.h"
|
||||||
|
|
||||||
|
#include "playlist/PlaylistUpdaterInterface.h"
|
||||||
|
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include <QtNetwork/QNetworkProxy>
|
#include <QtNetwork/QNetworkProxy>
|
||||||
|
|
||||||
#include "DllMacro.h"
|
#include "DllMacro.h"
|
||||||
|
|
||||||
#define TOMAHAWK_SETTINGS_VERSION 9
|
#define TOMAHAWK_SETTINGS_VERSION 10
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenience wrapper around QSettings for tomahawk-specific config
|
* Convenience wrapper around QSettings for tomahawk-specific config
|
||||||
@@ -201,6 +203,11 @@ public:
|
|||||||
void setImportXspfPath( const QString& path );
|
void setImportXspfPath( const QString& path );
|
||||||
QString importXspfPath() const;
|
QString importXspfPath() const;
|
||||||
|
|
||||||
|
Tomahawk::PlaylistUpdaterInterface::SerializedUpdaters playlistUpdaters() const;
|
||||||
|
void setPlaylistUpdaters( const Tomahawk::PlaylistUpdaterInterface::SerializedUpdaters& updaters );
|
||||||
|
|
||||||
|
static void registerCustomSettingsHandlers();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void changed();
|
void changed();
|
||||||
void recentlyPlayedPlaylistAdded( const Tomahawk::playlist_ptr& playlist );
|
void recentlyPlayedPlaylistAdded( const Tomahawk::playlist_ptr& playlist );
|
||||||
|
@@ -23,6 +23,38 @@
|
|||||||
|
|
||||||
using namespace Tomahawk;
|
using namespace Tomahawk;
|
||||||
|
|
||||||
|
inline QDataStream& operator<<(QDataStream& out, const AtticaManager::StateHash& states)
|
||||||
|
{
|
||||||
|
out << TOMAHAWK_SETTINGS_VERSION;
|
||||||
|
out << (quint32)states.count();
|
||||||
|
foreach( const QString& key, states.keys() )
|
||||||
|
{
|
||||||
|
AtticaManager::Resolver resolver = states[ key ];
|
||||||
|
out << key << resolver.version << resolver.scriptPath << (qint32)resolver.state << resolver.userRating;
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline QDataStream& operator>>(QDataStream& in, AtticaManager::StateHash& states)
|
||||||
|
{
|
||||||
|
quint32 count = 0, version = 0;
|
||||||
|
in >> version;
|
||||||
|
in >> count;
|
||||||
|
for ( uint i = 0; i < count; i++ )
|
||||||
|
{
|
||||||
|
QString key, version, scriptPath;
|
||||||
|
qint32 state, userRating;
|
||||||
|
in >> key;
|
||||||
|
in >> version;
|
||||||
|
in >> scriptPath;
|
||||||
|
in >> state;
|
||||||
|
in >> userRating;
|
||||||
|
states[ key ] = AtticaManager::Resolver( version, scriptPath, userRating, (AtticaManager::ResolverState)state );
|
||||||
|
}
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
TomahawkSettingsGui*
|
TomahawkSettingsGui*
|
||||||
TomahawkSettingsGui::instanceGui()
|
TomahawkSettingsGui::instanceGui()
|
||||||
{
|
{
|
||||||
@@ -91,3 +123,11 @@ TomahawkSettingsGui::removeAtticaResolverState ( const QString& resolver )
|
|||||||
resolvers.remove( resolver );
|
resolvers.remove( resolver );
|
||||||
setValue( "script/atticaresolverstates", QVariant::fromValue< AtticaManager::StateHash >( resolvers ) );
|
setValue( "script/atticaresolverstates", QVariant::fromValue< AtticaManager::StateHash >( resolvers ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TomahawkSettingsGui::registerCustomSettingsHandlers()
|
||||||
|
{
|
||||||
|
qRegisterMetaType< AtticaManager::StateHash >( "AtticaManager::StateHash" );
|
||||||
|
qRegisterMetaTypeStreamOperators<AtticaManager::StateHash>("AtticaManager::StateHash");
|
||||||
|
}
|
||||||
|
@@ -47,6 +47,8 @@ public:
|
|||||||
|
|
||||||
void setAtticaResolverState( const QString& resolver, AtticaManager::ResolverState state );
|
void setAtticaResolverState( const QString& resolver, AtticaManager::ResolverState state );
|
||||||
void removeAtticaResolverState( const QString& resolver );
|
void removeAtticaResolverState( const QString& resolver );
|
||||||
|
|
||||||
|
static void registerCustomSettingsHandlers();
|
||||||
};
|
};
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(AtticaManager::StateHash);
|
Q_DECLARE_METATYPE(AtticaManager::StateHash);
|
||||||
|
@@ -745,7 +745,7 @@ ViewManager::updateView()
|
|||||||
m_infobar->setVisible( currentPage()->showInfoBar() );
|
m_infobar->setVisible( currentPage()->showInfoBar() );
|
||||||
m_infobar->setCaption( currentPage()->title() );
|
m_infobar->setCaption( currentPage()->title() );
|
||||||
|
|
||||||
m_infobar->setAutoUpdateInterface( currentPage()->autoUpdateInterface() );
|
m_infobar->setUpdaters( currentPage()->updaters() );
|
||||||
|
|
||||||
switch( currentPage()->descriptionType() )
|
switch( currentPage()->descriptionType() )
|
||||||
{
|
{
|
||||||
|
@@ -25,13 +25,13 @@
|
|||||||
#include "Artist.h"
|
#include "Artist.h"
|
||||||
#include "Album.h"
|
#include "Album.h"
|
||||||
#include "utils/TomahawkUtils.h"
|
#include "utils/TomahawkUtils.h"
|
||||||
|
#include "playlist/PlaylistUpdaterInterface.h"
|
||||||
|
|
||||||
#include <QtGui/QPixmap>
|
#include <QtGui/QPixmap>
|
||||||
|
|
||||||
namespace Tomahawk
|
namespace Tomahawk
|
||||||
{
|
{
|
||||||
|
|
||||||
class PlaylistUpdaterInterface;
|
|
||||||
|
|
||||||
class DLLEXPORT ViewPage
|
class DLLEXPORT ViewPage
|
||||||
{
|
{
|
||||||
@@ -69,8 +69,7 @@ public:
|
|||||||
virtual bool isTemporaryPage() const { return false; }
|
virtual bool isTemporaryPage() const { return false; }
|
||||||
virtual bool isBeingPlayed() const { return false; }
|
virtual bool isBeingPlayed() const { return false; }
|
||||||
|
|
||||||
virtual bool canAutoUpdate() const { return false; }
|
virtual QList<PlaylistUpdaterInterface*> updaters() const { return QList<PlaylistUpdaterInterface*>(); }
|
||||||
virtual PlaylistUpdaterInterface* autoUpdateInterface() const { return 0; }
|
|
||||||
|
|
||||||
/** subclasses implementing ViewPage can emit the following signals:
|
/** subclasses implementing ViewPage can emit the following signals:
|
||||||
* nameChanged( const QString& )
|
* nameChanged( const QString& )
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||||
*
|
*
|
||||||
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||||
|
* Copyright 2012, Leo Franchi <lfranchi@kde.org>
|
||||||
*
|
*
|
||||||
* Tomahawk is free software: you can redistribute it and/or modify
|
* Tomahawk is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -40,8 +41,6 @@ using namespace Tomahawk;
|
|||||||
InfoBar::InfoBar( QWidget* parent )
|
InfoBar::InfoBar( QWidget* parent )
|
||||||
: QWidget( parent )
|
: QWidget( parent )
|
||||||
, ui( new Ui::InfoBar )
|
, ui( new Ui::InfoBar )
|
||||||
, m_updaterInterface( 0 )
|
|
||||||
, m_updaterConfiguration( 0 )
|
|
||||||
, m_queryLabel( 0 )
|
, m_queryLabel( 0 )
|
||||||
{
|
{
|
||||||
ui->setupUi( this );
|
ui->setupUi( this );
|
||||||
@@ -202,21 +201,31 @@ InfoBar::setFilterAvailable( bool b )
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
InfoBar::setAutoUpdateInterface( PlaylistUpdaterInterface *interface )
|
InfoBar::setUpdaters( const QList<PlaylistUpdaterInterface*>& updaters )
|
||||||
{
|
{
|
||||||
if ( m_updaterConfiguration )
|
QList< QWidget* > newUpdaterWidgets;
|
||||||
m_updaterConfiguration->hide();
|
foreach ( PlaylistUpdaterInterface* updater, updaters )
|
||||||
|
{
|
||||||
|
if ( updater->configurationWidget() )
|
||||||
|
newUpdaterWidgets << updater->configurationWidget();
|
||||||
|
}
|
||||||
|
|
||||||
if ( m_updaterConfiguration && ( interface ? (m_updaterConfiguration != interface->configurationWidget()) : true ) )
|
|
||||||
ui->horizontalLayout->removeWidget( m_updaterConfiguration );
|
|
||||||
|
|
||||||
m_updaterInterface = interface;
|
foreach ( QWidget* updaterWidget, m_updaterConfigurations )
|
||||||
m_updaterConfiguration = interface ? interface->configurationWidget() : 0;
|
{
|
||||||
|
updaterWidget->hide();
|
||||||
|
|
||||||
if ( !m_updaterInterface || !m_updaterConfiguration )
|
if ( !newUpdaterWidgets.contains( updaterWidget ) )
|
||||||
return;
|
{
|
||||||
|
// Old config widget no longer present, remove it
|
||||||
|
ui->horizontalLayout->removeWidget( updaterWidget );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
m_updaterConfiguration->setPalette( m_whitePal );
|
m_updaters = updaters;
|
||||||
|
m_updaterConfigurations = newUpdaterWidgets;
|
||||||
|
|
||||||
|
// Display each new widget in the proper place
|
||||||
int insertIdx = -1; // Ugh, no indexOf for QSpacerItem*
|
int insertIdx = -1; // Ugh, no indexOf for QSpacerItem*
|
||||||
for ( int i = 0; i < ui->horizontalLayout->count(); i++ )
|
for ( int i = 0; i < ui->horizontalLayout->count(); i++ )
|
||||||
{
|
{
|
||||||
@@ -227,9 +236,40 @@ InfoBar::setAutoUpdateInterface( PlaylistUpdaterInterface *interface )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
insertIdx++;
|
insertIdx++;
|
||||||
ui->horizontalLayout->insertWidget( insertIdx, m_updaterConfiguration );
|
|
||||||
|
|
||||||
m_updaterConfiguration->show();
|
foreach ( QWidget* updaterWidget, m_updaterConfigurations )
|
||||||
|
{
|
||||||
|
updaterWidget->setPalette( m_whitePal );
|
||||||
|
ui->horizontalLayout->insertWidget( insertIdx, updaterWidget );
|
||||||
|
updaterWidget->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
// if ( m_updaterConfiguration )
|
||||||
|
// m_updaterConfiguration->hide();
|
||||||
|
//
|
||||||
|
// if ( m_updaterConfiguration && ( interface ? (m_updaterConfiguration != interface->configurationWidget()) : true ) )
|
||||||
|
// ui->horizontalLayout->removeWidget( m_updaterConfiguration );
|
||||||
|
//
|
||||||
|
// m_updaterInterface = interface;
|
||||||
|
// m_updaterConfiguration = interface ? interface->configurationWidget() : 0;
|
||||||
|
//
|
||||||
|
// if ( !m_updaterInterface || !m_updaterConfiguration )
|
||||||
|
// return;
|
||||||
|
//
|
||||||
|
// m_updaterConfiguration->setPalette( m_whitePal );
|
||||||
|
// int insertIdx = -1; // Ugh, no indexOf for QSpacerItem*
|
||||||
|
// for ( int i = 0; i < ui->horizontalLayout->count(); i++ )
|
||||||
|
// {
|
||||||
|
// if ( ui->horizontalLayout->itemAt( i )->spacerItem() == ui->horizontalSpacer_4 )
|
||||||
|
// {
|
||||||
|
// insertIdx = i;
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// insertIdx++;
|
||||||
|
// ui->horizontalLayout->insertWidget( insertIdx, m_updaterConfiguration );
|
||||||
|
//
|
||||||
|
// m_updaterConfiguration->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||||
*
|
*
|
||||||
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||||
|
* Copyright 2012, Leo Franchi <lfranchi@kde.org>
|
||||||
*
|
*
|
||||||
* Tomahawk is free software: you can redistribute it and/or modify
|
* Tomahawk is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -62,7 +63,7 @@ public slots:
|
|||||||
void setFilter( const QString& filter );
|
void setFilter( const QString& filter );
|
||||||
void setFilterAvailable( bool b );
|
void setFilterAvailable( bool b );
|
||||||
|
|
||||||
void setAutoUpdateInterface( Tomahawk::PlaylistUpdaterInterface* interface );
|
void setUpdaters( const QList<Tomahawk::PlaylistUpdaterInterface*>& updaters );
|
||||||
signals:
|
signals:
|
||||||
void filterTextChanged( const QString& filter );
|
void filterTextChanged( const QString& filter );
|
||||||
|
|
||||||
@@ -82,8 +83,8 @@ private:
|
|||||||
QPixmap m_bgTile;
|
QPixmap m_bgTile;
|
||||||
QPalette m_whitePal;
|
QPalette m_whitePal;
|
||||||
|
|
||||||
Tomahawk::PlaylistUpdaterInterface* m_updaterInterface;
|
QList<Tomahawk::PlaylistUpdaterInterface*> m_updaters;;
|
||||||
QWidget* m_updaterConfiguration;
|
QList<QWidget*> m_updaterConfigurations;
|
||||||
|
|
||||||
QSearchField* m_searchWidget;
|
QSearchField* m_searchWidget;
|
||||||
QueryLabel* m_queryLabel;
|
QueryLabel* m_queryLabel;
|
||||||
|
@@ -35,21 +35,22 @@ PlaylistUpdaterInterface*
|
|||||||
PlaylistUpdaterInterface::loadForPlaylist( const playlist_ptr& pl )
|
PlaylistUpdaterInterface::loadForPlaylist( const playlist_ptr& pl )
|
||||||
{
|
{
|
||||||
TomahawkSettings* s = TomahawkSettings::instance();
|
TomahawkSettings* s = TomahawkSettings::instance();
|
||||||
const QString key = QString( "playlistupdaters/%1" ).arg( pl->guid() );
|
|
||||||
if ( s->contains( QString( "%1/type" ).arg( key ) ) )
|
const SerializedUpdaters updaters = s->playlistUpdaters();
|
||||||
|
if ( updaters.contains( pl->guid() ) )
|
||||||
{
|
{
|
||||||
// Ok, we have one we can try to load
|
// Ok, we have one we can try to load
|
||||||
const QString type = s->value( QString( "%1/type" ).arg( key ) ).toString();
|
|
||||||
PlaylistUpdaterInterface* updater = 0;
|
PlaylistUpdaterInterface* updater = 0;
|
||||||
|
const SerializedUpdater info = updaters[ pl->guid() ];
|
||||||
|
|
||||||
if ( !s_factories.contains( type ) )
|
if ( !s_factories.contains( info.type ) )
|
||||||
{
|
{
|
||||||
Q_ASSERT( false );
|
Q_ASSERT( false );
|
||||||
// You forgot to register your new updater type with the factory....
|
// You forgot to register your new updater type with the factory....
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
updater = s_factories[ type ]->create( pl, key );
|
updater = s_factories[ info.type ]->create( pl, info.customData );
|
||||||
return updater;
|
return updater;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,22 +64,35 @@ PlaylistUpdaterInterface::PlaylistUpdaterInterface( const playlist_ptr& pl )
|
|||||||
{
|
{
|
||||||
Q_ASSERT( !m_playlist.isNull() );
|
Q_ASSERT( !m_playlist.isNull() );
|
||||||
|
|
||||||
m_playlist->setUpdater( this );
|
m_playlist->addUpdater( this );
|
||||||
|
|
||||||
QTimer::singleShot( 0, this, SLOT( save() ) );
|
QTimer::singleShot( 0, this, SLOT( save() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PlaylistUpdaterInterface::~PlaylistUpdaterInterface()
|
||||||
|
{
|
||||||
|
if ( !m_playlist.isNull() )
|
||||||
|
m_playlist->removeUpdater( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PlaylistUpdaterInterface::save()
|
PlaylistUpdaterInterface::save()
|
||||||
{
|
{
|
||||||
|
if ( m_playlist.isNull() )
|
||||||
|
return;
|
||||||
|
|
||||||
TomahawkSettings* s = TomahawkSettings::instance();
|
TomahawkSettings* s = TomahawkSettings::instance();
|
||||||
const QString key = QString( "playlistupdaters/%1" ).arg( m_playlist->guid() );
|
|
||||||
if ( !s->contains( QString( "%1/type" ).arg( key ) ) )
|
SerializedUpdaters updaters = s->playlistUpdaters();
|
||||||
{
|
|
||||||
s->setValue( QString( "%1/type" ).arg( key ), type() );
|
SerializedUpdater updater = updaters.value( m_playlist ->guid() );
|
||||||
}
|
updater.type = type();
|
||||||
saveToSettings( key );
|
updater.customData = m_extraData;
|
||||||
|
updaters[ m_playlist->guid() ] = updater;
|
||||||
|
|
||||||
|
s->setPlaylistUpdaters( updaters );
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -88,9 +102,27 @@ PlaylistUpdaterInterface::remove()
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
TomahawkSettings* s = TomahawkSettings::instance();
|
TomahawkSettings* s = TomahawkSettings::instance();
|
||||||
const QString key = QString( "playlistupdaters/%1" ).arg( m_playlist->guid() );
|
|
||||||
removeFromSettings( key );
|
SerializedUpdaters updaters = s->playlistUpdaters();
|
||||||
s->remove( QString( "%1/type" ).arg( key ) );
|
if ( updaters.remove( m_playlist->guid() ) )
|
||||||
|
s->setPlaylistUpdaters( updaters );
|
||||||
|
|
||||||
|
aboutToDelete();
|
||||||
|
|
||||||
deleteLater();
|
deleteLater();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QVariantHash
|
||||||
|
PlaylistUpdaterInterface::settings() const
|
||||||
|
{
|
||||||
|
return m_extraData;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PlaylistUpdaterInterface::saveSettings( const QVariantHash& settings )
|
||||||
|
{
|
||||||
|
m_extraData = settings;
|
||||||
|
save();
|
||||||
|
}
|
||||||
|
@@ -43,9 +43,20 @@ class DLLEXPORT PlaylistUpdaterInterface : public QObject
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
// used when loading/saving from settings
|
||||||
|
struct SerializedUpdater {
|
||||||
|
QString type;
|
||||||
|
QVariantHash customData;
|
||||||
|
|
||||||
|
SerializedUpdater( const QString& t, const QVariantHash cd ) : type( t ), customData( cd ) {}
|
||||||
|
SerializedUpdater() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef QHash< QString, SerializedUpdater > SerializedUpdaters;
|
||||||
|
|
||||||
explicit PlaylistUpdaterInterface( const playlist_ptr& pl );
|
explicit PlaylistUpdaterInterface( const playlist_ptr& pl );
|
||||||
|
|
||||||
virtual ~PlaylistUpdaterInterface(){}
|
virtual ~PlaylistUpdaterInterface();
|
||||||
|
|
||||||
// What type you are. If you add a new updater, add the creation code as well.
|
// What type you are. If you add a new updater, add the creation code as well.
|
||||||
virtual QString type() const = 0;
|
virtual QString type() const = 0;
|
||||||
@@ -78,11 +89,14 @@ public slots:
|
|||||||
void save();
|
void save();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void saveToSettings( const QString& group ) const = 0;
|
virtual void aboutToDelete() {}
|
||||||
virtual void removeFromSettings( const QString& group ) const = 0;
|
|
||||||
|
QVariantHash settings() const;
|
||||||
|
void saveSettings( const QVariantHash& settings );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
playlist_ptr m_playlist;
|
playlist_ptr m_playlist;
|
||||||
|
QVariantHash m_extraData;
|
||||||
|
|
||||||
static QMap< QString, PlaylistUpdaterFactory* > s_factories;
|
static QMap< QString, PlaylistUpdaterFactory* > s_factories;
|
||||||
};
|
};
|
||||||
@@ -95,9 +109,12 @@ public:
|
|||||||
virtual ~PlaylistUpdaterFactory() {}
|
virtual ~PlaylistUpdaterFactory() {}
|
||||||
|
|
||||||
virtual QString type() const = 0;
|
virtual QString type() const = 0;
|
||||||
virtual PlaylistUpdaterInterface* create( const playlist_ptr&, const QString& settingsKey ) = 0;
|
virtual PlaylistUpdaterInterface* create( const playlist_ptr&, const QVariantHash& settings ) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE( Tomahawk::PlaylistUpdaterInterface::SerializedUpdater );
|
||||||
|
Q_DECLARE_METATYPE( Tomahawk::PlaylistUpdaterInterface::SerializedUpdaters );
|
||||||
|
|
||||||
#endif // PLAYLISTUPDATERINTERFACE_H
|
#endif // PLAYLISTUPDATERINTERFACE_H
|
||||||
|
@@ -109,23 +109,13 @@ PlaylistView::deleteItems()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
QList<PlaylistUpdaterInterface*>
|
||||||
PlaylistView::canAutoUpdate() const
|
PlaylistView::updaters() const
|
||||||
{
|
{
|
||||||
if ( !m_model->playlist().isNull() && m_model->playlist()->updater() )
|
if ( !m_model->playlist().isNull() )
|
||||||
return true;
|
return m_model->playlist()->updaters();
|
||||||
|
|
||||||
return false;
|
return QList<PlaylistUpdaterInterface*>();
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PlaylistUpdaterInterface*
|
|
||||||
PlaylistView::autoUpdateInterface() const
|
|
||||||
{
|
|
||||||
if ( !m_model->playlist().isNull() && m_model->playlist()->updater() )
|
|
||||||
return m_model->playlist()->updater();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -43,8 +43,7 @@ public:
|
|||||||
|
|
||||||
virtual bool showFilter() const { return true; }
|
virtual bool showFilter() const { return true; }
|
||||||
|
|
||||||
virtual bool canAutoUpdate() const;
|
virtual QList<Tomahawk::PlaylistUpdaterInterface*> updaters() const;
|
||||||
virtual Tomahawk::PlaylistUpdaterInterface* autoUpdateInterface() const;
|
|
||||||
|
|
||||||
virtual QString title() const { return playlistModel()->title(); }
|
virtual QString title() const { return playlistModel()->title(); }
|
||||||
virtual QString description() const { return m_model->description(); }
|
virtual QString description() const { return m_model->description(); }
|
||||||
|
@@ -20,7 +20,6 @@
|
|||||||
|
|
||||||
#include "Playlist.h"
|
#include "Playlist.h"
|
||||||
#include "utils/XspfLoader.h"
|
#include "utils/XspfLoader.h"
|
||||||
#include "TomahawkSettings.h"
|
|
||||||
#include "Pipeline.h"
|
#include "Pipeline.h"
|
||||||
#include "utils/TomahawkUtils.h"
|
#include "utils/TomahawkUtils.h"
|
||||||
|
|
||||||
@@ -33,11 +32,11 @@
|
|||||||
using namespace Tomahawk;
|
using namespace Tomahawk;
|
||||||
|
|
||||||
PlaylistUpdaterInterface*
|
PlaylistUpdaterInterface*
|
||||||
XspfUpdaterFactory::create( const playlist_ptr &pl, const QString& settingsKey )
|
XspfUpdaterFactory::create( const playlist_ptr &pl, const QVariantHash& settings )
|
||||||
{
|
{
|
||||||
const bool autoUpdate = TomahawkSettings::instance()->value( QString( "%1/autoupdate" ).arg( settingsKey ) ).toBool();
|
const bool autoUpdate = settings.value( "autoupdate" ).toBool();
|
||||||
const int interval = TomahawkSettings::instance()->value( QString( "%1/interval" ).arg( settingsKey ) ).toInt();
|
const int interval = settings.value( "interval" ).toInt();
|
||||||
const QString url = TomahawkSettings::instance()->value( QString( "%1/xspfurl" ).arg( settingsKey ) ).toString();
|
const QString url = settings.value( "xspfurl" ).toString();
|
||||||
|
|
||||||
XspfUpdater* updater = new XspfUpdater( pl, interval, autoUpdate, url );
|
XspfUpdater* updater = new XspfUpdater( pl, interval, autoUpdate, url );
|
||||||
|
|
||||||
@@ -57,13 +56,19 @@ XspfUpdater::XspfUpdater( const playlist_ptr& pl, int interval, bool autoUpdate,
|
|||||||
|
|
||||||
#ifndef ENABLE_HEADLESS
|
#ifndef ENABLE_HEADLESS
|
||||||
m_toggleCheckbox = new QCheckBox( );
|
m_toggleCheckbox = new QCheckBox( );
|
||||||
m_toggleCheckbox->setText( tr( "Automatically update" ) );
|
m_toggleCheckbox->setText( tr( "Automatically update from XSPF" ) );
|
||||||
m_toggleCheckbox->setLayoutDirection( Qt::RightToLeft );
|
m_toggleCheckbox->setLayoutDirection( Qt::RightToLeft );
|
||||||
m_toggleCheckbox->setChecked( m_autoUpdate );
|
m_toggleCheckbox->setChecked( m_autoUpdate );
|
||||||
m_toggleCheckbox->hide();
|
m_toggleCheckbox->hide();
|
||||||
|
|
||||||
connect( m_toggleCheckbox, SIGNAL( toggled( bool ) ), this, SLOT( setAutoUpdate( bool ) ) );
|
connect( m_toggleCheckbox, SIGNAL( toggled( bool ) ), this, SLOT( setAutoUpdate( bool ) ) );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
QVariantHash s = settings();
|
||||||
|
s[ "autoupdate" ] = m_autoUpdate;
|
||||||
|
s[ "interval" ] = interval;
|
||||||
|
s[ "xspfurl" ] = xspfUrl;
|
||||||
|
saveSettings( s );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -113,24 +118,6 @@ XspfUpdater::playlistLoaded( const QList<Tomahawk::query_ptr>& newEntries )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
XspfUpdater::saveToSettings( const QString& group ) const
|
|
||||||
{
|
|
||||||
TomahawkSettings::instance()->setValue( QString( "%1/autoupdate" ).arg( group ), m_autoUpdate );
|
|
||||||
TomahawkSettings::instance()->setValue( QString( "%1/interval" ).arg( group ), m_timer->interval() );
|
|
||||||
TomahawkSettings::instance()->setValue( QString( "%1/xspfurl" ).arg( group ), m_url );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
XspfUpdater::removeFromSettings( const QString& group ) const
|
|
||||||
{
|
|
||||||
TomahawkSettings::instance()->remove( QString( "%1/autoupdate" ).arg( group ) );
|
|
||||||
TomahawkSettings::instance()->remove( QString( "%1/interval" ).arg( group ) );
|
|
||||||
TomahawkSettings::instance()->remove( QString( "%1/xspfurl" ).arg( group ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
XspfUpdater::setAutoUpdate( bool autoUpdate )
|
XspfUpdater::setAutoUpdate( bool autoUpdate )
|
||||||
{
|
{
|
||||||
@@ -141,8 +128,9 @@ XspfUpdater::setAutoUpdate( bool autoUpdate )
|
|||||||
else
|
else
|
||||||
m_timer->stop();
|
m_timer->stop();
|
||||||
|
|
||||||
const QString key = QString( "playlistupdaters/%1/autoupdate" ).arg( playlist()->guid() );
|
QVariantHash s = settings();
|
||||||
TomahawkSettings::instance()->setValue( key, m_autoUpdate );
|
s[ "autoupdate" ] = m_autoUpdate;
|
||||||
|
saveSettings( s );
|
||||||
|
|
||||||
// Update immediately as well
|
// Update immediately as well
|
||||||
if ( m_autoUpdate )
|
if ( m_autoUpdate )
|
||||||
@@ -152,8 +140,9 @@ XspfUpdater::setAutoUpdate( bool autoUpdate )
|
|||||||
void
|
void
|
||||||
XspfUpdater::setInterval( int intervalMsecs )
|
XspfUpdater::setInterval( int intervalMsecs )
|
||||||
{
|
{
|
||||||
const QString key = QString( "playlistupdaters/%1/interval" ).arg( playlist()->guid() );
|
QVariantHash s = settings();
|
||||||
TomahawkSettings::instance()->setValue( key, intervalMsecs );
|
s[ "interval" ] = intervalMsecs;
|
||||||
|
saveSettings( s );
|
||||||
|
|
||||||
if ( !m_timer )
|
if ( !m_timer )
|
||||||
m_timer = new QTimer( this );
|
m_timer = new QTimer( this );
|
||||||
|
@@ -52,10 +52,6 @@ public slots:
|
|||||||
void updateNow();
|
void updateNow();
|
||||||
void setAutoUpdate( bool autoUpdate );
|
void setAutoUpdate( bool autoUpdate );
|
||||||
|
|
||||||
protected:
|
|
||||||
void saveToSettings( const QString& group ) const;
|
|
||||||
void removeFromSettings(const QString& group) const;
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void playlistLoaded( const QList<Tomahawk::query_ptr> & );
|
void playlistLoaded( const QList<Tomahawk::query_ptr> & );
|
||||||
|
|
||||||
@@ -75,7 +71,7 @@ public:
|
|||||||
XspfUpdaterFactory() {}
|
XspfUpdaterFactory() {}
|
||||||
|
|
||||||
virtual QString type() const { return "xspf"; }
|
virtual QString type() const { return "xspf"; }
|
||||||
virtual PlaylistUpdaterInterface* create( const playlist_ptr& pl, const QString& settingsKey );
|
virtual PlaylistUpdaterInterface* create( const playlist_ptr& pl, const QVariantHash& settings );
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -55,6 +55,11 @@ private slots:
|
|||||||
* Exposed clear. This class doesn't have a QPtrList autodelete functionality
|
* Exposed clear. This class doesn't have a QPtrList autodelete functionality
|
||||||
* ever, so if people think that, they're really confused! -- Ian Monroe
|
* ever, so if people think that, they're really confused! -- Ian Monroe
|
||||||
*
|
*
|
||||||
|
* NOTE:
|
||||||
|
* This class is NOT implicitly shared like QList. Passing it around
|
||||||
|
* ***will*** cause it to iterate and copy all the elements in the copy
|
||||||
|
* constructor!
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
template <class T> class SmartPointerList : private QList<T*>
|
template <class T> class SmartPointerList : private QList<T*>
|
||||||
{
|
{
|
||||||
@@ -136,6 +141,11 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool operator==( const SmartPointerList& that )
|
||||||
|
{
|
||||||
|
return QList<T*>::operator==( that );
|
||||||
|
}
|
||||||
|
|
||||||
void push_back( T* o )
|
void push_back( T* o )
|
||||||
{
|
{
|
||||||
append( o );
|
append( o );
|
||||||
@@ -180,7 +190,7 @@ public:
|
|||||||
using QList<T*>::swap;
|
using QList<T*>::swap;
|
||||||
using QList<T*>::value;
|
using QList<T*>::value;
|
||||||
using QList<T*>::operator!=;
|
using QList<T*>::operator!=;
|
||||||
using QList<T*>::operator==;
|
// using QList<T*>::operator==;
|
||||||
|
|
||||||
// can't use using directive here since we only want the const versions
|
// can't use using directive here since we only want the const versions
|
||||||
typename QList<T*>::const_iterator begin() const { return QList<T*>::constBegin(); }
|
typename QList<T*>::const_iterator begin() const { return QList<T*>::constBegin(); }
|
||||||
|
@@ -191,6 +191,9 @@ RecentPlaylistsModel::updatePlaylist()
|
|||||||
|
|
||||||
for ( int i = 0; i < m_playlists.size(); i++ )
|
for ( int i = 0; i < m_playlists.size(); i++ )
|
||||||
{
|
{
|
||||||
|
if ( m_playlists[ i ].isNull() )
|
||||||
|
continue;
|
||||||
|
|
||||||
if ( m_playlists[ i ]->guid() == p->guid() )
|
if ( m_playlists[ i ]->guid() == p->guid() )
|
||||||
{
|
{
|
||||||
QModelIndex idx = index( i, 0, QModelIndex() );
|
QModelIndex idx = index( i, 0, QModelIndex() );
|
||||||
|
36
src/main.cpp
36
src/main.cpp
@@ -37,38 +37,6 @@
|
|||||||
#include "breakpad/BreakPad.h"
|
#include "breakpad/BreakPad.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
inline QDataStream& operator<<(QDataStream& out, const AtticaManager::StateHash& states)
|
|
||||||
{
|
|
||||||
out << TOMAHAWK_SETTINGS_VERSION;
|
|
||||||
out << (quint32)states.count();
|
|
||||||
foreach( const QString& key, states.keys() )
|
|
||||||
{
|
|
||||||
AtticaManager::Resolver resolver = states[ key ];
|
|
||||||
out << key << resolver.version << resolver.scriptPath << (qint32)resolver.state << resolver.userRating;
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline QDataStream& operator>>(QDataStream& in, AtticaManager::StateHash& states)
|
|
||||||
{
|
|
||||||
quint32 count = 0, version = 0;
|
|
||||||
in >> version;
|
|
||||||
in >> count;
|
|
||||||
for ( uint i = 0; i < count; i++ )
|
|
||||||
{
|
|
||||||
QString key, version, scriptPath;
|
|
||||||
qint32 state, userRating;
|
|
||||||
in >> key;
|
|
||||||
in >> version;
|
|
||||||
in >> scriptPath;
|
|
||||||
in >> state;
|
|
||||||
in >> userRating;
|
|
||||||
states[ key ] = AtticaManager::Resolver( version, scriptPath, userRating, (AtticaManager::ResolverState)state );
|
|
||||||
}
|
|
||||||
return in;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
#define argc __argc
|
#define argc __argc
|
||||||
@@ -115,8 +83,8 @@ main( int argc, char *argv[] )
|
|||||||
TomahawkApp a( argc, argv );
|
TomahawkApp a( argc, argv );
|
||||||
|
|
||||||
// MUST register StateHash ****before*** initing TomahawkSettingsGui as constructor of settings does upgrade before Gui subclass registers type
|
// MUST register StateHash ****before*** initing TomahawkSettingsGui as constructor of settings does upgrade before Gui subclass registers type
|
||||||
qRegisterMetaType< AtticaManager::StateHash >( "AtticaManager::StateHash" );
|
TomahawkSettings::registerCustomSettingsHandlers();
|
||||||
qRegisterMetaTypeStreamOperators<AtticaManager::StateHash>("AtticaManager::StateHash");
|
TomahawkSettingsGui::registerCustomSettingsHandlers();
|
||||||
|
|
||||||
#ifdef ENABLE_HEADLESS
|
#ifdef ENABLE_HEADLESS
|
||||||
new TomahawkSettings( &a );
|
new TomahawkSettings( &a );
|
||||||
|
@@ -52,7 +52,7 @@ PlaylistItem::PlaylistItem( SourcesModel* mdl, SourceTreeItem* parent, const pla
|
|||||||
if( ViewManager::instance()->pageForPlaylist( pl ) )
|
if( ViewManager::instance()->pageForPlaylist( pl ) )
|
||||||
model()->linkSourceItemToPage( this, ViewManager::instance()->pageForPlaylist( pl ) );
|
model()->linkSourceItemToPage( this, ViewManager::instance()->pageForPlaylist( pl ) );
|
||||||
|
|
||||||
if ( m_playlist->updater() && !m_playlist->updater()->typeIcon().isNull() )
|
if ( !m_playlist->updaters().isEmpty() )
|
||||||
createOverlay();
|
createOverlay();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -251,40 +251,66 @@ PlaylistItem::parsedDroppedTracks( const QList< query_ptr >& tracks )
|
|||||||
void
|
void
|
||||||
PlaylistItem::onUpdated()
|
PlaylistItem::onUpdated()
|
||||||
{
|
{
|
||||||
if ( m_playlist->updater() && !m_playlist->updater()->typeIcon().isNull() &&
|
// No work todo
|
||||||
m_overlaidIcon.isNull() ) // create overlay
|
if ( !m_overlaidIcon.isNull() && m_overlaidUpdaters.operator==( m_playlist->updaters() ) )
|
||||||
{
|
{
|
||||||
createOverlay();
|
emit updated();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else if ( !m_playlist->updater() || ( m_playlist->updater()->typeIcon().isNull() && !m_overlaidIcon.isNull() ) )
|
|
||||||
{
|
const bool newOverlay = createOverlay();
|
||||||
// No longer an updater with an icon
|
if ( !newOverlay && !m_overlaidIcon.isNull() )
|
||||||
m_overlaidIcon = QIcon();
|
m_overlaidIcon = QIcon();
|
||||||
}
|
|
||||||
|
|
||||||
emit updated();
|
emit updated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
bool
|
||||||
PlaylistItem::createOverlay()
|
PlaylistItem::createOverlay()
|
||||||
{
|
{
|
||||||
Q_ASSERT( !m_playlist.isNull() );
|
Q_ASSERT( !m_playlist.isNull() );
|
||||||
Q_ASSERT( m_playlist->updater() );
|
|
||||||
Q_ASSERT( !m_playlist->updater()->typeIcon().isNull() );
|
if ( m_playlist->updaters().isEmpty() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
QList< QPixmap > icons;
|
||||||
|
foreach ( PlaylistUpdaterInterface* updater, m_playlist->updaters() )
|
||||||
|
{
|
||||||
|
if ( !updater->typeIcon().isNull() )
|
||||||
|
icons << updater->typeIcon();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( icons.isEmpty() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// For now we only support up to 2 overlaid updater icons,
|
||||||
|
// we need to add smarter scaling etc to manage more at once
|
||||||
|
if ( icons.size() > 2 )
|
||||||
|
icons = icons.mid( 0, 2 );
|
||||||
|
|
||||||
m_overlaidIcon = QIcon();
|
m_overlaidIcon = QIcon();
|
||||||
|
m_overlaidUpdaters = m_playlist->updaters();
|
||||||
|
|
||||||
QPixmap base = m_icon.pixmap( 48, 48 );
|
QPixmap base = m_icon.pixmap( 48, 48 );
|
||||||
const QPixmap overlay = m_playlist->updater()->typeIcon();
|
|
||||||
|
|
||||||
QPainter p( &base );
|
QPainter p( &base );
|
||||||
const int w = base.width() / 2;
|
const int w = base.width() / 2;
|
||||||
const QRect overlayRect( base.rect().right() - w, base.rect().height() - w, w, w );
|
QRect overlayRect( base.rect().right() - w, base.rect().height() - w, w, w );
|
||||||
p.drawPixmap( overlayRect, overlay );
|
|
||||||
|
foreach ( const QPixmap& overlay, icons )
|
||||||
|
{
|
||||||
|
p.drawPixmap( overlayRect, overlay );
|
||||||
|
|
||||||
|
// NOTE only works if icons.size == 2 as ensured above
|
||||||
|
overlayRect.moveLeft( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
p.end();
|
p.end();
|
||||||
|
|
||||||
m_overlaidIcon.addPixmap( base );
|
m_overlaidIcon.addPixmap( base );
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -56,11 +56,12 @@ private slots:
|
|||||||
|
|
||||||
void onUpdated();
|
void onUpdated();
|
||||||
private:
|
private:
|
||||||
void createOverlay();
|
bool createOverlay();
|
||||||
|
|
||||||
bool m_loaded;
|
bool m_loaded;
|
||||||
Tomahawk::playlist_ptr m_playlist;
|
Tomahawk::playlist_ptr m_playlist;
|
||||||
QIcon m_icon, m_overlaidIcon;
|
QIcon m_icon, m_overlaidIcon;
|
||||||
|
QList<Tomahawk::PlaylistUpdaterInterface*> m_overlaidUpdaters;
|
||||||
};
|
};
|
||||||
Q_DECLARE_OPERATORS_FOR_FLAGS(PlaylistItem::DropTypes)
|
Q_DECLARE_OPERATORS_FOR_FLAGS(PlaylistItem::DropTypes)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user