diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 782244ba3..3f34b0255 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -75,6 +75,7 @@ SET( tomahawkSourcesGui ${tomahawkSourcesGui} settingslistdelegate.cpp resolversmodel.cpp tomahawkwindow.cpp + LoadXSPFDialog.cpp ) SET( tomahawkHeaders ${tomahawkHeaders} @@ -124,6 +125,7 @@ SET( tomahawkHeadersGui ${tomahawkHeadersGui} resolversmodel.h delegateconfigwrapper.h tomahawkwindow.h + LoadXSPFDialog.h ) SET( tomahawkUI ${tomahawkUI} @@ -135,6 +137,7 @@ SET( tomahawkUI ${tomahawkUI} audiocontrols.ui GetNewStuffDialog.ui + LoadXSPFDialog.ui ) INCLUDE_DIRECTORIES( diff --git a/src/LoadXSPFDialog.cpp b/src/LoadXSPFDialog.cpp new file mode 100644 index 000000000..cb1fd917e --- /dev/null +++ b/src/LoadXSPFDialog.cpp @@ -0,0 +1,56 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Leo Franchi + * + * Tomahawk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Tomahawk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + +#include "LoadXSPFDialog.h" + +#include "ui_LoadXSPFDialog.h" +#include + +LoadXSPFDialog::LoadXSPFDialog( QWidget* parent, Qt::WindowFlags f ) + : QDialog( parent, f ) + , m_ui( new Ui_LoadXSPF ) +{ + m_ui->setupUi( this ); + + connect( m_ui->buttonBox, SIGNAL( accepted() ), SLOT( accept() ) ); + connect( m_ui->buttonBox, SIGNAL( rejected() ), SLOT( reject() ) ); + + connect( m_ui->navigateButton, SIGNAL( clicked( bool ) ), this, SLOT( getLocalFile() ) ); +} + +LoadXSPFDialog::~LoadXSPFDialog() +{ +} + +void +LoadXSPFDialog::getLocalFile() +{ + QString url = QFileDialog::getOpenFileName( this, tr( "Load XSPF File" ), QDir::homePath(), ".xspf" ); + m_ui->lineEdit->setText( url ); +} + +QString LoadXSPFDialog::xspfUrl() const +{ + return m_ui->lineEdit->text(); +} + +bool +LoadXSPFDialog::autoUpdate() const +{ + return m_ui->autoUpdate->isChecked(); +} diff --git a/src/LoadXSPFDialog.h b/src/LoadXSPFDialog.h new file mode 100644 index 000000000..47066286c --- /dev/null +++ b/src/LoadXSPFDialog.h @@ -0,0 +1,43 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Leo Franchi + * + * Tomahawk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Tomahawk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + +#ifndef LOADXSPFDIALOG_H +#define LOADXSPFDIALOG_H + +#include + +class Ui_LoadXSPF; + +class LoadXSPFDialog : public QDialog +{ + Q_OBJECT +public: + explicit LoadXSPFDialog( QWidget* parent = 0, Qt::WindowFlags f = 0 ); + virtual ~LoadXSPFDialog(); + + QString xspfUrl() const; + bool autoUpdate() const; + +public slots: + void getLocalFile(); + +private: + Ui_LoadXSPF* m_ui; +}; + +#endif // LOADXSPFDIALOG_H diff --git a/src/LoadXSPFDialog.ui b/src/LoadXSPFDialog.ui new file mode 100644 index 000000000..5eb30260a --- /dev/null +++ b/src/LoadXSPFDialog.ui @@ -0,0 +1,102 @@ + + + LoadXSPF + + + + 0 + 0 + 332 + 86 + + + + Load XSPF + + + + + + + + Playlist Url + + + + + + + Enter URL... + + + + + + + + 0 + 0 + + + + ... + + + + + + + + + Automatically update + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + LoadXSPF + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + LoadXSPF + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index 92651881c..d8d676f0b 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -140,6 +140,7 @@ set( libSources playlist/artistview.cpp playlist/customplaylistview.cpp playlist/ViewHeader.cpp + playlist/PlaylistUpdaterInterface.cpp playlist/XspfUpdater.cpp playlist/topbar/topbar.cpp diff --git a/src/libtomahawk/collection.cpp b/src/libtomahawk/collection.cpp index bce7851c0..fef020495 100644 --- a/src/libtomahawk/collection.cpp +++ b/src/libtomahawk/collection.cpp @@ -24,6 +24,7 @@ #include "source.h" #include "utils/logger.h" +#include using namespace Tomahawk; @@ -185,6 +186,8 @@ Collection::setPlaylists( const QList& plists ) { // qDebug() << "Batch inserting playlist:" << p->guid(); m_playlists.insert( p->guid(), p ); + if ( !m_source.isNull() && m_source->isLocal() ) + PlaylistUpdaterInterface::loadForPlaylist( p ); } emit playlistsAdded( plists ); } diff --git a/src/libtomahawk/infobar/infobar.cpp b/src/libtomahawk/infobar/infobar.cpp index 3053fe7d1..c441292cf 100644 --- a/src/libtomahawk/infobar/infobar.cpp +++ b/src/libtomahawk/infobar/infobar.cpp @@ -26,6 +26,7 @@ #include "thirdparty/Qocoa/qsearchfield.h" #include "utils/tomahawkutils.h" #include "utils/logger.h" +#include #define ANIMATION_TIME 400 #define IMAGE_HEIGHT 64 @@ -70,6 +71,14 @@ InfoBar::InfoBar( QWidget* parent ) ui->longDescriptionLabel->setText( QString() ); ui->imageLabel->setText( QString() ); + m_autoUpdate = new QCheckBox( this ); + m_autoUpdate->setText( tr( "Automatically update" ) ); + m_autoUpdate->setLayoutDirection( Qt::RightToLeft ); + m_autoUpdate->setPalette( whitePal ); + connect( m_autoUpdate, SIGNAL( stateChanged( int ) ), this, SIGNAL( autoUpdateChanged( int ) ) ); + + ui->horizontalLayout->addWidget( m_autoUpdate ); + m_searchWidget = new QSearchField( this ); m_searchWidget->setPlaceholderText( tr( "Filter..." ) ); m_searchWidget->setMinimumWidth( 180 ); @@ -87,6 +96,7 @@ InfoBar::InfoBar( QWidget* parent ) setAutoFillBackground( true ); connect( ViewManager::instance(), SIGNAL( filterAvailable( bool ) ), SLOT( setFilterAvailable( bool ) ) ); + connect( ViewManager::instance(), SIGNAL( autoUpdateAvailable( bool ) ), SLOT( setAutoUpdateAvailable( bool ) ) ); } @@ -147,6 +157,15 @@ InfoBar::setFilterAvailable( bool b ) m_searchWidget->setVisible( b ); } +void +InfoBar::setAutoUpdateAvailable( bool b ) +{ + if ( b ) + m_autoUpdate->setChecked( ViewManager::instance()->currentPage()->autoUpdate() ); + + m_autoUpdate->setVisible( b ); +} + void InfoBar::onFilterEdited() @@ -154,7 +173,6 @@ InfoBar::onFilterEdited() emit filterTextChanged( m_searchWidget->text() ); } - void InfoBar::changeEvent( QEvent* e ) { diff --git a/src/libtomahawk/infobar/infobar.h b/src/libtomahawk/infobar/infobar.h index 0e6353600..a718a32a3 100644 --- a/src/libtomahawk/infobar/infobar.h +++ b/src/libtomahawk/infobar/infobar.h @@ -23,6 +23,7 @@ #include "dllmacro.h" +class QCheckBox; class QTimeLine; class QSearchField; class ContextWidget; @@ -49,8 +50,10 @@ public slots: void setFilter( const QString& filter ); void setFilterAvailable( bool b ); + void setAutoUpdateAvailable( bool b ); signals: void filterTextChanged( const QString& filter ); + void autoUpdateChanged( int state ); protected: void changeEvent( QEvent* e ); @@ -62,6 +65,7 @@ private: Ui::InfoBar* ui; QSearchField* m_searchWidget; + QCheckBox* m_autoUpdate; }; #endif // INFOBAR_H diff --git a/src/libtomahawk/playlist.cpp b/src/libtomahawk/playlist.cpp index 7c8ec7de7..2d59dcb25 100644 --- a/src/libtomahawk/playlist.cpp +++ b/src/libtomahawk/playlist.cpp @@ -116,6 +116,7 @@ Playlist::Playlist( const source_ptr& src, , m_lastmodified( lastmod ) , m_createdOn( createdOn ) , m_shared( shared ) + , m_updater( 0 ) { init(); } @@ -138,6 +139,7 @@ Playlist::Playlist( const source_ptr& author, , m_createdOn( 0 ) // will be set by db command , m_shared( shared ) , m_initEntries( entries ) + , m_updater( 0 ) { init(); } @@ -511,9 +513,12 @@ Playlist::addEntries( const QList& queries, const QString& oldrev ) QList -Playlist::entriesFromQueries( const QList& queries ) +Playlist::entriesFromQueries( const QList& queries, bool clearFirst ) { - QList el = entries(); + QList el; + if ( !clearFirst ) + el = entries(); + foreach( const query_ptr& query, queries ) { plentry_ptr e( new PlaylistEntry() ); diff --git a/src/libtomahawk/playlist.h b/src/libtomahawk/playlist.h index 2302554cc..43b55fa8e 100644 --- a/src/libtomahawk/playlist.h +++ b/src/libtomahawk/playlist.h @@ -36,10 +36,11 @@ class DatabaseCommand_LoadAllPlaylists; class DatabaseCommand_LoadAllSortedPlaylists; class DatabaseCommand_SetPlaylistRevision; class DatabaseCommand_CreatePlaylist; - namespace Tomahawk { +class PlaylistUpdaterInterface; + class DLLEXPORT PlaylistEntry : public QObject { Q_OBJECT @@ -196,7 +197,10 @@ public: virtual void setFilter( const QString& /*pattern*/ ) {} - QList entriesFromQueries( const QList& queries ); + QList entriesFromQueries( const QList& queries, bool clearFirst = false ); + void setUpdater( PlaylistUpdaterInterface* interface ) { m_updater = interface; } + PlaylistUpdaterInterface* updater() const { return m_updater; } + signals: /// emitted when the playlist revision changes (whenever the playlist changes) void revisionLoaded( Tomahawk::PlaylistRevision ); @@ -293,6 +297,8 @@ private: QQueue m_revisionQueue; + PlaylistUpdaterInterface* m_updater; + bool m_locallyChanged; bool m_deleted; bool m_busy; diff --git a/src/libtomahawk/playlist/PlaylistUpdaterInterface.cpp b/src/libtomahawk/playlist/PlaylistUpdaterInterface.cpp new file mode 100644 index 000000000..288889963 --- /dev/null +++ b/src/libtomahawk/playlist/PlaylistUpdaterInterface.cpp @@ -0,0 +1,104 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Leo Franchi + * + * Tomahawk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Tomahawk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + +#include "PlaylistUpdaterInterface.h" +#include "tomahawksettings.h" +#include "XspfUpdater.h" + +using namespace Tomahawk; + +PlaylistUpdaterInterface* +PlaylistUpdaterInterface::loadForPlaylist( const playlist_ptr& pl ) +{ + TomahawkSettings* s = TomahawkSettings::instance(); + const QString key = QString( "playlistupdaters/%1" ).arg( pl->guid() ); + if ( s->contains( QString( "%1/type" ).arg( key ) ) ) + { + // Ok, we have one we can try to load + const QString type = s->value( QString( "%1/type" ).arg( key ) ).toString(); + PlaylistUpdaterInterface* updater = 0; + if ( type == "xspf" ) + updater = new XspfUpdater( pl ); + + // You forgot to register your new updater type with the factory above. 00ps. + if ( !updater ) + { + Q_ASSERT( false ); + return 0; + } + updater->setAutoUpdate( s->value( QString( "%1/autoupdate" ).arg( key ) ).toBool() ); + updater->setInterval( s->value( QString( "%1/interval" ).arg( key ) ).toInt() ); + updater->loadFromSettings( key ); + + return updater; + } + + return 0; +} + + +PlaylistUpdaterInterface::PlaylistUpdaterInterface( const playlist_ptr& pl ) + : QObject( 0 ) + , m_timer( new QTimer( this ) ) + , m_autoUpdate( true ) + , m_playlist( pl ) +{ + Q_ASSERT( !m_playlist.isNull() ); + + m_playlist->setUpdater( this ); + connect( m_timer, SIGNAL( timeout() ), this, SLOT( updateNow() ) ); + + QTimer::singleShot( 0, this, SLOT( doSave() ) ); +} + +void +PlaylistUpdaterInterface::doSave() +{ + TomahawkSettings* s = TomahawkSettings::instance(); + const QString key = QString( "playlistupdaters/%1" ).arg( m_playlist->guid() ); + if ( !s->contains( QString( "%1/type" ).arg( key ) ) ) + { + s->setValue( QString( "%1/type" ).arg( key ), type() ); + s->setValue( QString( "%1/autoupdate" ).arg( key ), m_autoUpdate ); + s->setValue( QString( "%1/interval" ).arg( key ), m_timer->interval() ); + saveToSettings( key ); + } +} + +void +PlaylistUpdaterInterface::setAutoUpdate( bool autoUpdate ) +{ + m_autoUpdate = autoUpdate; + if ( m_autoUpdate ) + m_timer->start(); + else + m_timer->stop(); + + const QString key = QString( "playlistupdaters/%1/autoupdate" ).arg( m_playlist->guid() ); + TomahawkSettings::instance()->setValue( key, m_autoUpdate ); +} + +void +PlaylistUpdaterInterface::setInterval( int intervalMsecs ) +{ + const QString key = QString( "playlistupdaters/%1/interval" ).arg( m_playlist->guid() ); + TomahawkSettings::instance()->setValue( key, intervalMsecs ); + + m_timer->setInterval( intervalMsecs ); +} + diff --git a/src/libtomahawk/playlist/PlaylistUpdaterInterface.h b/src/libtomahawk/playlist/PlaylistUpdaterInterface.h index e31a5c425..2a92b3a34 100644 --- a/src/libtomahawk/playlist/PlaylistUpdaterInterface.h +++ b/src/libtomahawk/playlist/PlaylistUpdaterInterface.h @@ -22,6 +22,7 @@ #include "dllmacro.h" #include "typedefs.h" #include "playlist.h" +#include namespace Tomahawk { @@ -35,21 +36,37 @@ class DLLEXPORT PlaylistUpdaterInterface : public QObject { Q_OBJECT public: - PlaylistUpdaterInterface( const playlist_ptr& pl, QObject* parent ) - : QObject( parent ) - , m_autoUpdate( true ) - , m_playlist( pl ) - {} + 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. + virtual QString type() const = 0; - void setAutoUpdate( bool autoUpdate ) { m_autoUpdate = autoUpdate; } bool autoUpdate() const { return m_autoUpdate; } + void setAutoUpdate( bool autoUpdate ); + + void setInterval( int intervalMsecs ) ; + int intervalMsecs() const { return m_timer->interval(); } playlist_ptr playlist() const { return m_playlist; } -signals: + + /// If you want to try to load a updater from the settings. Returns a valid + /// updater if one was saved + static PlaylistUpdaterInterface* loadForPlaylist( const playlist_ptr& pl ); + +public slots: + virtual void updateNow() {} + +private slots: + void doSave(); + +protected: + virtual void loadFromSettings( const QString& group ) = 0; + virtual void saveToSettings( const QString& group ) const = 0; private: + QTimer* m_timer; bool m_autoUpdate; playlist_ptr m_playlist; }; diff --git a/src/libtomahawk/playlist/XspfUpdater.cpp b/src/libtomahawk/playlist/XspfUpdater.cpp index 949d5a943..f63c3d87d 100644 --- a/src/libtomahawk/playlist/XspfUpdater.cpp +++ b/src/libtomahawk/playlist/XspfUpdater.cpp @@ -22,26 +22,31 @@ #include "utils/xspfloader.h" #include +#include using namespace Tomahawk; -XspfUpdater::XspfUpdater( const playlist_ptr& pl, const QString& xUrl, QObject *parent ) - : PlaylistUpdaterInterface( pl, parent ) +XspfUpdater::XspfUpdater( const playlist_ptr& pl, const QString& xUrl ) + : PlaylistUpdaterInterface( pl ) , m_url( xUrl ) - , m_timer( new QTimer( this ) ) { - // for now refresh every 60min - m_timer->setInterval( 60 * 60 * 1000); - connect( m_timer, SIGNAL( timeout() ), this, SLOT( update() ) ); } +XspfUpdater::XspfUpdater( const playlist_ptr& pl ) + : PlaylistUpdaterInterface( pl ) +{ + +} + + XspfUpdater::~XspfUpdater() {} void -XspfUpdater::update() +XspfUpdater::updateNow() { - XSPFLoader* l = new XSPFLoader( false ); + XSPFLoader* l = new XSPFLoader( false, false ); + l->load( m_url ); connect( l, SIGNAL( ok ( Tomahawk::playlist_ptr ) ), this, SLOT( playlistLoaded() ) ); } @@ -52,7 +57,7 @@ XspfUpdater::playlistLoaded() Q_ASSERT( loader ); QList< query_ptr > queries = loader->entries(); - QList el = playlist()->entriesFromQueries( queries ); + QList el = playlist()->entriesFromQueries( queries, true ); playlist()->createNewRevision( uuid(), playlist()->currentrevision(), el ); // // if there are any different from the current playlist, clear and use the new one, update @@ -65,3 +70,15 @@ XspfUpdater::playlistLoaded() // } // } } + +void +XspfUpdater::saveToSettings( const QString& group ) const +{ + TomahawkSettings::instance()->setValue( QString( "%1/xspfurl" ).arg( group ), m_url ); +} + +void +XspfUpdater::loadFromSettings( const QString& group ) +{ + m_url = TomahawkSettings::instance()->value( QString( "%1/xspfurl" ).arg( group ) ).toString(); +} diff --git a/src/libtomahawk/playlist/XspfUpdater.h b/src/libtomahawk/playlist/XspfUpdater.h index 59d7d5cd1..8ddb6e6dc 100644 --- a/src/libtomahawk/playlist/XspfUpdater.h +++ b/src/libtomahawk/playlist/XspfUpdater.h @@ -30,16 +30,24 @@ class XspfUpdater : public PlaylistUpdaterInterface { Q_OBJECT public: - explicit XspfUpdater( const playlist_ptr& pl, const QString& xspfUrl, QObject *parent = 0 ); + XspfUpdater( const playlist_ptr& pl, const QString& xspfUrl ); + explicit XspfUpdater( const playlist_ptr& pl ); // used by factory + virtual ~XspfUpdater(); + virtual QString type() const { return "xspf"; } +public slots: + void updateNow(); + +protected: + void loadFromSettings( const QString& group ); + void saveToSettings( const QString& group ) const; + private slots: - void update(); void playlistLoaded(); private: QString m_url; - QTimer* m_timer; }; } diff --git a/src/libtomahawk/playlist/dynamic/echonest/EchonestGenerator.cpp b/src/libtomahawk/playlist/dynamic/echonest/EchonestGenerator.cpp index 8a60edde1..69595447d 100644 --- a/src/libtomahawk/playlist/dynamic/echonest/EchonestGenerator.cpp +++ b/src/libtomahawk/playlist/dynamic/echonest/EchonestGenerator.cpp @@ -480,6 +480,8 @@ EchonestGenerator::appendRadioType( Echonest::DynamicPlaylist::PlaylistParams& p } if( someCatalog ) params.append( Echonest::DynamicPlaylist::PlaylistParamData( Echonest::DynamicPlaylist::Type, Echonest::DynamicPlaylist::CatalogRadioType ) ); + else if( onlyThisArtistType( Echonest::DynamicPlaylist::ArtistType ) ) + params.append( Echonest::DynamicPlaylist::PlaylistParamData( Echonest::DynamicPlaylist::Type, Echonest::DynamicPlaylist::ArtistType ) ); else if( onlyThisArtistType( Echonest::DynamicPlaylist::ArtistDescriptionType ) ) params.append( Echonest::DynamicPlaylist::PlaylistParamData( Echonest::DynamicPlaylist::Type, Echonest::DynamicPlaylist::ArtistDescriptionType ) ); else if( onlyThisArtistType( Echonest::DynamicPlaylist::ArtistRadioType ) ) diff --git a/src/libtomahawk/playlist/playlistview.cpp b/src/libtomahawk/playlist/playlistview.cpp index 36a964420..607db56f2 100644 --- a/src/libtomahawk/playlist/playlistview.cpp +++ b/src/libtomahawk/playlist/playlistview.cpp @@ -25,6 +25,7 @@ #include "widgets/overlaywidget.h" #include "viewmanager.h" #include "utils/logger.h" +#include "PlaylistUpdaterInterface.h" using namespace Tomahawk; @@ -104,6 +105,34 @@ PlaylistView::deleteItems() proxyModel()->removeIndexes( selectedIndexes() ); } +bool +PlaylistView::canAutoUpdate() const +{ + if ( !m_model->playlist().isNull() && m_model->playlist()->updater() ) + return true; + + return false; +} + +bool +PlaylistView::autoUpdate() const +{ + if ( canAutoUpdate() ) + return m_model->playlist()->updater()->autoUpdate(); + + return false; +} + + +void +PlaylistView::setAutoUpdate( bool autoUpdate ) +{ + if ( !canAutoUpdate() ) + return; + + m_model->playlist()->updater()->setAutoUpdate( autoUpdate ); +} + void PlaylistView::onTrackCountChanged( unsigned int tracks ) diff --git a/src/libtomahawk/playlist/playlistview.h b/src/libtomahawk/playlist/playlistview.h index 57065e1a3..63424eef9 100644 --- a/src/libtomahawk/playlist/playlistview.h +++ b/src/libtomahawk/playlist/playlistview.h @@ -42,6 +42,10 @@ public: virtual bool showFilter() const { return true; } + virtual bool canAutoUpdate() const; + virtual void setAutoUpdate( bool autoUpdate ); + virtual bool autoUpdate() const; + virtual QString title() const { return playlistModel()->title(); } virtual QString description() const { return m_model->description(); } virtual QPixmap pixmap() const { return QPixmap( RESPATH "images/playlist-icon.png" ); } diff --git a/src/libtomahawk/utils/xspfloader.cpp b/src/libtomahawk/utils/xspfloader.cpp index ac0f32100..d4430a6ad 100644 --- a/src/libtomahawk/utils/xspfloader.cpp +++ b/src/libtomahawk/utils/xspfloader.cpp @@ -26,12 +26,14 @@ #include "sourcelist.h" #include "playlist.h" +#include using namespace Tomahawk; -XSPFLoader::XSPFLoader( bool autoCreate, QObject *parent ) +XSPFLoader::XSPFLoader( bool autoCreate, bool autoUpdate, QObject *parent ) : QObject( parent ) , m_autoCreate( autoCreate ) + , m_autoUpdate( autoUpdate ) , m_NS("http://xspf.org/ns/0/") { qRegisterMetaType< XSPFErrorCode >("XSPFErrorCode"); @@ -60,10 +62,11 @@ void XSPFLoader::load( const QUrl& url ) { QNetworkRequest request( url ); + m_url = url; + Q_ASSERT( TomahawkUtils::nam() != 0 ); QNetworkReply* reply = TomahawkUtils::nam()->get( request ); - // isn't there a race condition here? something could happen before we connect() connect( reply, SIGNAL( finished() ), SLOT( networkLoadFinished() ) ); @@ -219,6 +222,9 @@ XSPFLoader::gotBody() false, m_entries ); + Tomahawk::XspfUpdater* updater = new Tomahawk::XspfUpdater( m_playlist, m_url.toString() ); + updater->setInterval( 60000 ); + updater->setAutoUpdate( m_autoUpdate ); deleteLater(); } diff --git a/src/libtomahawk/utils/xspfloader.h b/src/libtomahawk/utils/xspfloader.h index b6f0aa429..54b11ad74 100644 --- a/src/libtomahawk/utils/xspfloader.h +++ b/src/libtomahawk/utils/xspfloader.h @@ -40,7 +40,7 @@ Q_OBJECT public: enum XSPFErrorCode { ParseError, InvalidTrackError, FetchError }; - explicit XSPFLoader( bool autoCreate = true, QObject* parent = 0 ); + explicit XSPFLoader( bool autoCreate = true, bool autoUpdate = false, QObject* parent = 0 ); virtual ~XSPFLoader(); QList< Tomahawk::query_ptr > entries() const; @@ -63,11 +63,12 @@ private: void reportError(); void gotBody(); - bool m_autoCreate; + bool m_autoCreate, m_autoUpdate; QString m_NS,m_overrideTitle; QList< Tomahawk::query_ptr > m_entries; QString m_title, m_info, m_creator; + QUrl m_url; QByteArray m_body; Tomahawk::playlist_ptr m_playlist; }; diff --git a/src/libtomahawk/viewmanager.cpp b/src/libtomahawk/viewmanager.cpp index 5ee170ef5..8822d5602 100644 --- a/src/libtomahawk/viewmanager.cpp +++ b/src/libtomahawk/viewmanager.cpp @@ -109,6 +109,7 @@ ViewManager::ViewManager( QObject* parent ) connect( &m_filterTimer, SIGNAL( timeout() ), SLOT( applyFilter() ) ); connect( m_infobar, SIGNAL( filterTextChanged( QString ) ), SLOT( setFilter( QString ) ) ); + connect( m_infobar, SIGNAL( autoUpdateChanged( int ) ), SLOT( autoUpdateChanged( int ) ) ); /* connect( m_infobar, SIGNAL( flatMode() ), SLOT( setTableMode() ) ); connect( m_infobar, SIGNAL( artistMode() ), SLOT( setTreeMode() ) ); connect( m_infobar, SIGNAL( albumMode() ), SLOT( setAlbumMode() ) );*/ @@ -506,6 +507,13 @@ ViewManager::applyFilter() } +void +ViewManager::autoUpdateChanged( int state ) +{ + currentPage()->setAutoUpdate( state == Qt::Checked ); +} + + void ViewManager::setPage( ViewPage* page, bool trackHistory ) { @@ -656,6 +664,8 @@ ViewManager::updateView() emit modesAvailable( currentPage()->showModes() ); emit filterAvailable( currentPage()->showFilter() ); + emit autoUpdateAvailable( currentPage()->canAutoUpdate() ); + /* if ( !currentPage()->showStatsBar() && !currentPage()->showModes() && !currentPage()->showFilter() ) m_topbar->setVisible( false ); else diff --git a/src/libtomahawk/viewmanager.h b/src/libtomahawk/viewmanager.h index e5c238e86..38820b63b 100644 --- a/src/libtomahawk/viewmanager.h +++ b/src/libtomahawk/viewmanager.h @@ -117,6 +117,7 @@ signals: void statsAvailable( bool b ); void modesAvailable( bool b ); void filterAvailable( bool b ); + void autoUpdateAvailable( bool b ); void modeChanged( Tomahawk::PlaylistInterface::ViewMode mode ); void playClicked(); @@ -165,6 +166,8 @@ private slots: void setFilter( const QString& filter ); void applyFilter(); + void autoUpdateChanged( int ); + void onWidgetDestroyed( QWidget* widget ); private: diff --git a/src/libtomahawk/viewpage.h b/src/libtomahawk/viewpage.h index 629fb66dc..4cf5f0a61 100644 --- a/src/libtomahawk/viewpage.h +++ b/src/libtomahawk/viewpage.h @@ -54,6 +54,10 @@ public: virtual bool isTemporaryPage() const { return false; } + virtual bool canAutoUpdate() const { return false; } + virtual void setAutoUpdate( bool ) {} + virtual bool autoUpdate() const { return false; } + /** subclasses implementing ViewPage can emit the following signals: * nameChanged( const QString& ) * descriptionChanged( const QString& ) @@ -63,7 +67,6 @@ public: * * See DynamicWidget for an example */ -private: }; }; // ns diff --git a/src/tomahawkwindow.cpp b/src/tomahawkwindow.cpp index e01807765..80069e55a 100644 --- a/src/tomahawkwindow.cpp +++ b/src/tomahawkwindow.cpp @@ -68,6 +68,7 @@ #include "utils/logger.h" #include "jobview/JobStatusModel.h" +#include "LoadXSPFDialog.h" using namespace Tomahawk; @@ -488,16 +489,44 @@ TomahawkWindow::showOfflineSources() void TomahawkWindow::loadSpiff() { - bool ok; - QString urlstr = QInputDialog::getText( this, tr( "Load XSPF" ), tr( "Path:" ), QLineEdit::Normal, "http://ws.audioscrobbler.com/1.0/tag/metal/toptracks.xspf", &ok ); - if ( !ok || urlstr.isEmpty() ) - return; + LoadXSPFDialog* diag = new LoadXSPFDialog( this, Qt::Sheet ); +#ifdef Q_WS_MAC + connect( diag, SIGNAL( finished( int ) ), this, SLOT( loadXspfFinished( int ) ) ); + diag->show(); +#else + QWeakPointer< LoadXSPFDialog > safe( diag ); - XSPFLoader* loader = new XSPFLoader; - connect( loader, SIGNAL( error( XSPFLoader::XSPFErrorCode ) ), SLOT( onXSPFError( XSPFLoader::XSPFErrorCode ) ) ); - loader->load( QUrl::fromUserInput( urlstr ) ); + int ret = diag->exec(); + if ( !safe.isNull() && ret == QDialog::Accepted ) + { + QUrl url = QUrl::fromUserInput( safe.data()->xspfUrl() ); + bool autoUpdate = safe.data()->autoUpdate(); + + XSPFLoader* loader = new XSPFLoader( true, autoUpdate ); + connect( loader, SIGNAL( error( XSPFLoader::XSPFErrorCode ) ), SLOT( onXSPFError( XSPFLoader::XSPFErrorCode ) ) ); + loader->load( url ); + } +#endif } +void +TomahawkWindow::loadXspfFinished( int ret ) +{ + LoadXSPFDialog* d = qobject_cast< LoadXSPFDialog* >( sender() ); + Q_ASSERT( d ); + if ( ret == QDialog::Accepted ) + { + QUrl url = QUrl::fromUserInput( d->xspfUrl() ); + bool autoUpdate = d->autoUpdate(); + + XSPFLoader* loader = new XSPFLoader( true, autoUpdate ); + connect( loader, SIGNAL( error( XSPFLoader::XSPFErrorCode ) ), SLOT( onXSPFError( XSPFLoader::XSPFErrorCode ) ) ); + loader->load( url ); + } + d->deleteLater(); +} + + void TomahawkWindow::onXSPFError( XSPFLoader::XSPFErrorCode error ) diff --git a/src/tomahawkwindow.h b/src/tomahawkwindow.h index ee62cb161..f91874246 100644 --- a/src/tomahawkwindow.h +++ b/src/tomahawkwindow.h @@ -102,6 +102,8 @@ private slots: void onSearch( const QString& search ); void onFilterEdited(); + void loadXspfFinished( int ); + void showQueue(); void hideQueue();