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..9120aaedc --- /dev/null +++ b/src/LoadXSPFDialog.ui @@ -0,0 +1,102 @@ + + + LoadXSPF + + + + 0 + 0 + 332 + 86 + + + + Load XSPF + + + + + + + + XSPF 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/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..30ec5dff9 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 ) const { 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.h b/src/libtomahawk/playlist/PlaylistUpdaterInterface.h index e31a5c425..d88699e79 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,40 @@ class DLLEXPORT PlaylistUpdaterInterface : public QObject { Q_OBJECT public: - PlaylistUpdaterInterface( const playlist_ptr& pl, QObject* parent ) - : QObject( parent ) + PlaylistUpdaterInterface( const playlist_ptr& pl ) + : QObject( pl.data() ) + , 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() ) ); + } virtual ~PlaylistUpdaterInterface() {} - void setAutoUpdate( bool autoUpdate ) { m_autoUpdate = autoUpdate; } + void setAutoUpdate( bool autoUpdate ) { + m_autoUpdate = autoUpdate; + if ( m_autoUpdate ) + m_timer->start(); + else + m_timer->stop(); + } + bool autoUpdate() const { return m_autoUpdate; } + void setInterval( int intervalMsecs ) { m_timer->setInterval( intervalMsecs ); } + int intervalMsecs() const { return m_timer->interval(); } + playlist_ptr playlist() const { return m_playlist; } -signals: + +public slots: + virtual void updateNow() {} 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..6dc51693a 100644 --- a/src/libtomahawk/playlist/XspfUpdater.cpp +++ b/src/libtomahawk/playlist/XspfUpdater.cpp @@ -25,23 +25,20 @@ 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() {} 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 +49,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 diff --git a/src/libtomahawk/playlist/XspfUpdater.h b/src/libtomahawk/playlist/XspfUpdater.h index 59d7d5cd1..ea0652bd4 100644 --- a/src/libtomahawk/playlist/XspfUpdater.h +++ b/src/libtomahawk/playlist/XspfUpdater.h @@ -30,16 +30,17 @@ class XspfUpdater : public PlaylistUpdaterInterface { Q_OBJECT public: - explicit XspfUpdater( const playlist_ptr& pl, const QString& xspfUrl, QObject *parent = 0 ); + explicit XspfUpdater( const playlist_ptr& pl, const QString& xspfUrl ); virtual ~XspfUpdater(); +public slots: + void updateNow(); + private slots: - void update(); void playlistLoaded(); private: QString m_url; - QTimer* m_timer; }; } diff --git a/src/libtomahawk/utils/xspfloader.cpp b/src/libtomahawk/utils/xspfloader.cpp index ac0f32100..0cfe91461 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,12 @@ XSPFLoader::gotBody() false, m_entries ); + if ( m_autoUpdate ) + { + Tomahawk::XspfUpdater* updater = new Tomahawk::XspfUpdater( m_playlist, m_url.toString() ); + updater->setInterval( 60000 ); + updater->setAutoUpdate( true ); + } 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/tomahawkwindow.cpp b/src/tomahawkwindow.cpp index e01807765..e443b74ee 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,52 @@ 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; +// 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; +// +// XSPFLoader* loader = new XSPFLoader; +// connect( loader, SIGNAL( error( XSPFLoader::XSPFErrorCode ) ), SLOT( onXSPFError( XSPFLoader::XSPFErrorCode ) ) ); +// loader->load( QUrl::fromUserInput( urlstr ) ); + 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();