From 687ed02df0fad8e6cf1afde4323502642232186c Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Fri, 7 Oct 2011 18:08:13 -0400 Subject: [PATCH 1/4] Updater work --- src/CMakeLists.txt | 3 + src/LoadXSPFDialog.cpp | 56 ++++++++++ src/LoadXSPFDialog.h | 43 ++++++++ src/LoadXSPFDialog.ui | 102 ++++++++++++++++++ src/libtomahawk/playlist.cpp | 9 +- src/libtomahawk/playlist.h | 10 +- .../playlist/PlaylistUpdaterInterface.h | 30 +++++- src/libtomahawk/playlist/XspfUpdater.cpp | 15 ++- src/libtomahawk/playlist/XspfUpdater.h | 7 +- src/libtomahawk/utils/xspfloader.cpp | 13 ++- src/libtomahawk/utils/xspfloader.h | 5 +- src/tomahawkwindow.cpp | 51 +++++++-- src/tomahawkwindow.h | 2 + 13 files changed, 314 insertions(+), 32 deletions(-) create mode 100644 src/LoadXSPFDialog.cpp create mode 100644 src/LoadXSPFDialog.h create mode 100644 src/LoadXSPFDialog.ui 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(); From 31a9c75c08ee83c0c929ced525ee5979b11194b8 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Wed, 12 Oct 2011 08:48:31 -0400 Subject: [PATCH 2/4] Fix artist limit to --- src/libtomahawk/playlist/dynamic/echonest/EchonestGenerator.cpp | 2 ++ 1 file changed, 2 insertions(+) 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 ) ) From 9556414bf51111ce80faae329db082bbc7162229 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Wed, 12 Oct 2011 10:20:55 -0400 Subject: [PATCH 3/4] Add UI to auto-update and save/restore state --- src/LoadXSPFDialog.ui | 2 +- src/libtomahawk/CMakeLists.txt | 1 + src/libtomahawk/collection.cpp | 3 + src/libtomahawk/infobar/infobar.cpp | 20 +++- src/libtomahawk/infobar/infobar.h | 4 + src/libtomahawk/playlist.h | 2 +- .../playlist/PlaylistUpdaterInterface.cpp | 104 ++++++++++++++++++ .../playlist/PlaylistUpdaterInterface.h | 37 +++---- src/libtomahawk/playlist/XspfUpdater.cpp | 20 ++++ src/libtomahawk/playlist/XspfUpdater.h | 9 +- src/libtomahawk/playlist/playlistview.cpp | 29 +++++ src/libtomahawk/playlist/playlistview.h | 4 + src/libtomahawk/utils/xspfloader.cpp | 9 +- src/libtomahawk/viewmanager.cpp | 10 ++ src/libtomahawk/viewmanager.h | 3 + src/libtomahawk/viewpage.h | 5 +- 16 files changed, 231 insertions(+), 31 deletions(-) create mode 100644 src/libtomahawk/playlist/PlaylistUpdaterInterface.cpp diff --git a/src/LoadXSPFDialog.ui b/src/LoadXSPFDialog.ui index 9120aaedc..5eb30260a 100644 --- a/src/LoadXSPFDialog.ui +++ b/src/LoadXSPFDialog.ui @@ -19,7 +19,7 @@ - XSPF Url: + Playlist Url 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.h b/src/libtomahawk/playlist.h index 30ec5dff9..43b55fa8e 100644 --- a/src/libtomahawk/playlist.h +++ b/src/libtomahawk/playlist.h @@ -198,7 +198,7 @@ public: virtual void setFilter( const QString& /*pattern*/ ) {} QList entriesFromQueries( const QList& queries, bool clearFirst = false ); - void setUpdater( PlaylistUpdaterInterface* interface ) const { m_updater = interface; } + void setUpdater( PlaylistUpdaterInterface* interface ) { m_updater = interface; } PlaylistUpdaterInterface* updater() const { return m_updater; } signals: 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 d88699e79..2a92b3a34 100644 --- a/src/libtomahawk/playlist/PlaylistUpdaterInterface.h +++ b/src/libtomahawk/playlist/PlaylistUpdaterInterface.h @@ -36,38 +36,35 @@ class DLLEXPORT PlaylistUpdaterInterface : public QObject { Q_OBJECT public: - PlaylistUpdaterInterface( const playlist_ptr& pl ) - : QObject( pl.data() ) - , m_timer( new QTimer( this ) ) - , m_autoUpdate( true ) - , m_playlist( pl ) - { - Q_ASSERT( !m_playlist.isNull() ); + PlaylistUpdaterInterface( const playlist_ptr& pl ); - m_playlist->setUpdater( this ); - connect( m_timer, SIGNAL( timeout() ), this, SLOT( updateNow() ) ); - } + virtual ~PlaylistUpdaterInterface(){} - virtual ~PlaylistUpdaterInterface() {} - - void setAutoUpdate( bool autoUpdate ) { - m_autoUpdate = autoUpdate; - if ( m_autoUpdate ) - m_timer->start(); - else - m_timer->stop(); - } + // What type you are. If you add a new updater, add the creation code as well. + virtual QString type() const = 0; bool autoUpdate() const { return m_autoUpdate; } + void setAutoUpdate( bool autoUpdate ); - void setInterval( int intervalMsecs ) { m_timer->setInterval( intervalMsecs ); } + void setInterval( int intervalMsecs ) ; int intervalMsecs() const { return m_timer->interval(); } playlist_ptr playlist() const { return m_playlist; } + /// 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; diff --git a/src/libtomahawk/playlist/XspfUpdater.cpp b/src/libtomahawk/playlist/XspfUpdater.cpp index 6dc51693a..f63c3d87d 100644 --- a/src/libtomahawk/playlist/XspfUpdater.cpp +++ b/src/libtomahawk/playlist/XspfUpdater.cpp @@ -22,6 +22,7 @@ #include "utils/xspfloader.h" #include +#include using namespace Tomahawk; @@ -31,6 +32,13 @@ XspfUpdater::XspfUpdater( const playlist_ptr& pl, const QString& xUrl ) { } +XspfUpdater::XspfUpdater( const playlist_ptr& pl ) + : PlaylistUpdaterInterface( pl ) +{ + +} + + XspfUpdater::~XspfUpdater() {} @@ -62,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 ea0652bd4..8ddb6e6dc 100644 --- a/src/libtomahawk/playlist/XspfUpdater.h +++ b/src/libtomahawk/playlist/XspfUpdater.h @@ -30,12 +30,19 @@ class XspfUpdater : public PlaylistUpdaterInterface { Q_OBJECT public: - explicit XspfUpdater( const playlist_ptr& pl, const QString& xspfUrl ); + 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 playlistLoaded(); 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 0cfe91461..d4430a6ad 100644 --- a/src/libtomahawk/utils/xspfloader.cpp +++ b/src/libtomahawk/utils/xspfloader.cpp @@ -222,12 +222,9 @@ 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 ); - } + Tomahawk::XspfUpdater* updater = new Tomahawk::XspfUpdater( m_playlist, m_url.toString() ); + updater->setInterval( 60000 ); + updater->setAutoUpdate( m_autoUpdate ); deleteLater(); } 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 From bb0d82aa103619c7b51a60d555dfdac86ba99516 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Wed, 12 Oct 2011 10:21:39 -0400 Subject: [PATCH 4/4] remote debug --- src/tomahawkwindow.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/tomahawkwindow.cpp b/src/tomahawkwindow.cpp index e443b74ee..80069e55a 100644 --- a/src/tomahawkwindow.cpp +++ b/src/tomahawkwindow.cpp @@ -489,14 +489,6 @@ 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; -// -// 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 ) ) );