diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index 52d714ad2..b9d636d73 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -77,6 +77,7 @@ set( libGuiSources playlist/artistview.cpp playlist/customplaylistview.cpp playlist/ViewHeader.cpp + playlist/RecentlyPlayedModel.cpp playlist/dynamic/DynamicPlaylist.cpp playlist/dynamic/DynamicView.cpp diff --git a/src/libtomahawk/playlist/RecentlyPlayedModel.cpp b/src/libtomahawk/playlist/RecentlyPlayedModel.cpp new file mode 100644 index 000000000..db41f2766 --- /dev/null +++ b/src/libtomahawk/playlist/RecentlyPlayedModel.cpp @@ -0,0 +1,140 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2012, Christian Muehlhaeuser + * + * 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 "RecentlyPlayedModel.h" + +#include +#include + +#include "source.h" +#include "sourcelist.h" +#include "database/database.h" +#include "database/databasecommand_playbackhistory.h" +#include "utils/tomahawkutils.h" +#include "utils/logger.h" + +#define HISTORY_TRACK_ITEMS 25 + +using namespace Tomahawk; + + +RecentlyPlayedModel::RecentlyPlayedModel( const source_ptr& source, QObject* parent ) + : PlaylistModel( parent ) + , m_source( source ) + , m_limit( HISTORY_TRACK_ITEMS ) +{ + if ( source.isNull() ) + { + connect( SourceList::instance(), SIGNAL( ready() ), SLOT( onSourcesReady() ) ); + connect( SourceList::instance(), SIGNAL( sourceAdded( Tomahawk::source_ptr ) ), SLOT( onSourceAdded( Tomahawk::source_ptr ) ) ); + } + else + { + onSourceAdded( source ); + loadHistory(); + } +} + + +RecentlyPlayedModel::~RecentlyPlayedModel() +{ +} + + +void +RecentlyPlayedModel::loadHistory() +{ + if ( rowCount( QModelIndex() ) ) + { + clear(); + } + + DatabaseCommand_PlaybackHistory* cmd = new DatabaseCommand_PlaybackHistory( m_source ); + cmd->setLimit( m_limit ); + + connect( cmd, SIGNAL( tracks( QList ) ), + SLOT( append( QList ) ), Qt::QueuedConnection ); + + Database::instance()->enqueue( QSharedPointer( cmd ) ); +} + + +void +RecentlyPlayedModel::onSourcesReady() +{ + Q_ASSERT( m_source.isNull() ); + + loadHistory(); + + foreach ( const source_ptr& source, SourceList::instance()->sources() ) + onSourceAdded( source ); +} + + +void +RecentlyPlayedModel::onSourceAdded( const Tomahawk::source_ptr& source ) +{ + connect( source.data(), SIGNAL( playbackFinished( Tomahawk::query_ptr ) ), SLOT( onPlaybackFinished( Tomahawk::query_ptr ) ), Qt::UniqueConnection ); +} + + +void +RecentlyPlayedModel::onPlaybackFinished( const Tomahawk::query_ptr& query ) +{ + int count = trackCount(); + unsigned int playtime = query->playedBy().second; + + if ( count ) + { + TrackModelItem* oldestItem = itemFromIndex( index( count - 1, 0, QModelIndex() ) ); + if ( oldestItem->query()->playedBy().second >= playtime ) + return; + + TrackModelItem* youngestItem = itemFromIndex( index( 0, 0, QModelIndex() ) ); + if ( youngestItem->query()->playedBy().second <= playtime ) + insert( query, 0 ); + else + { + for ( int i = 0; i < count - 1; i++ ) + { + TrackModelItem* item1 = itemFromIndex( index( i, 0, QModelIndex() ) ); + TrackModelItem* item2 = itemFromIndex( index( i + 1, 0, QModelIndex() ) ); + + if ( item1->query()->playedBy().second >= playtime && item2->query()->playedBy().second <= playtime ) + { + insert( query, i + 1 ); + break; + } + } + } + } + else + insert( query, 0 ); + + if ( trackCount() > (int)m_limit ) + remove( m_limit ); + + ensureResolved(); +} + + +bool +RecentlyPlayedModel::isTemporary() const +{ + return true; +} diff --git a/src/libtomahawk/playlist/RecentlyPlayedModel.h b/src/libtomahawk/playlist/RecentlyPlayedModel.h new file mode 100644 index 000000000..748535905 --- /dev/null +++ b/src/libtomahawk/playlist/RecentlyPlayedModel.h @@ -0,0 +1,55 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Christian Muehlhaeuser + * + * 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 RECENTLYPLAYEDMODEL_H +#define RECENTLYPLAYEDMODEL_H + +#include +#include + +#include "typedefs.h" +#include "playlistmodel.h" + +#include "dllmacro.h" + +class DLLEXPORT RecentlyPlayedModel : public PlaylistModel +{ +Q_OBJECT + +public: + explicit RecentlyPlayedModel( const Tomahawk::source_ptr& source, QObject* parent = 0 ); + ~RecentlyPlayedModel(); + + unsigned int limit() const { return m_limit; } + void setLimit( unsigned int limit ) { m_limit = limit; } + + bool isTemporary() const; + +private slots: + void onSourcesReady(); + void onSourceAdded( const Tomahawk::source_ptr& source ); + + void onPlaybackFinished( const Tomahawk::query_ptr& query ); + void loadHistory(); + +private: + Tomahawk::source_ptr m_source; + unsigned int m_limit; +}; + +#endif // RECENTLYPLAYEDMODEL_H diff --git a/src/libtomahawk/playlist/playlistmodel.cpp b/src/libtomahawk/playlist/playlistmodel.cpp index 4cd5a2b59..6d5d28392 100644 --- a/src/libtomahawk/playlist/playlistmodel.cpp +++ b/src/libtomahawk/playlist/playlistmodel.cpp @@ -86,26 +86,6 @@ PlaylistModel::loadPlaylist( const Tomahawk::playlist_ptr& playlist, bool loadEn } -void -PlaylistModel::loadHistory( const Tomahawk::source_ptr& source, unsigned int amount ) -{ - if ( rowCount( QModelIndex() ) ) - { - clear(); - } - - m_playlist.clear(); - - DatabaseCommand_PlaybackHistory* cmd = new DatabaseCommand_PlaybackHistory( source ); - cmd->setLimit( amount ); - - connect( cmd, SIGNAL( tracks( QList ) ), - SLOT( append( QList ) ), Qt::QueuedConnection ); - - Database::instance()->enqueue( QSharedPointer( cmd ) ); -} - - void PlaylistModel::clear() { diff --git a/src/libtomahawk/playlist/playlistmodel.h b/src/libtomahawk/playlist/playlistmodel.h index 95d4dddaf..f5586e043 100644 --- a/src/libtomahawk/playlist/playlistmodel.h +++ b/src/libtomahawk/playlist/playlistmodel.h @@ -47,14 +47,12 @@ public: explicit PlaylistModel( QObject* parent = 0 ); ~PlaylistModel(); - virtual QMimeData* mimeData ( const QModelIndexList& indexes ) const; + virtual QMimeData* mimeData( const QModelIndexList& indexes ) const; virtual bool dropMimeData( const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent ); Tomahawk::playlist_ptr playlist() const { return m_playlist; } virtual void loadPlaylist( const Tomahawk::playlist_ptr& playlist, bool loadEntries = true ); - void loadHistory( const Tomahawk::source_ptr& source, unsigned int amount = 50 ); - bool isTemporary() const; public slots: diff --git a/src/libtomahawk/widgets/infowidgets/sourceinfowidget.cpp b/src/libtomahawk/widgets/infowidgets/sourceinfowidget.cpp index 6f133872e..9a67ce08d 100644 --- a/src/libtomahawk/widgets/infowidgets/sourceinfowidget.cpp +++ b/src/libtomahawk/widgets/infowidgets/sourceinfowidget.cpp @@ -24,7 +24,7 @@ #include "playlist/albummodel.h" #include "playlist/collectionflatmodel.h" -#include "playlist/playlistmodel.h" +#include "playlist/RecentlyPlayedModel.h" #include "database/database.h" #include "database/databasecommand_alltracks.h" @@ -66,10 +66,9 @@ SourceInfoWidget::SourceInfoWidget( const Tomahawk::source_ptr& source, QWidget* ui->recentCollectionView->setTrackModel( m_recentCollectionModel ); ui->recentCollectionView->sortByColumn( TrackModel::Age, Qt::DescendingOrder ); - m_historyModel = new PlaylistModel( ui->historyView ); + m_historyModel = new RecentlyPlayedModel( source, ui->historyView ); m_historyModel->setStyle( TrackModel::Short ); ui->historyView->setPlaylistModel( m_historyModel ); - m_historyModel->loadHistory( source, 25 ); m_recentAlbumModel = new AlbumModel( ui->recentAlbumView ); ui->recentAlbumView->setAlbumModel( m_recentAlbumModel ); @@ -78,7 +77,6 @@ SourceInfoWidget::SourceInfoWidget( const Tomahawk::source_ptr& source, QWidget* onCollectionChanged(); connect( source->collection().data(), SIGNAL( changed() ), SLOT( onCollectionChanged() ) ); - connect( source.data(), SIGNAL( playbackFinished( Tomahawk::query_ptr ) ), SLOT( onPlaybackFinished( Tomahawk::query_ptr ) ) ); m_title = tr( "New Additions" ); if ( source->isLocal() ) @@ -138,13 +136,6 @@ SourceInfoWidget::onLoadedTrackHistory( const QList& querie } -void -SourceInfoWidget::onPlaybackFinished( const Tomahawk::query_ptr& query ) -{ - m_historyModel->insert( query, 0 ); -} - - void SourceInfoWidget::changeEvent( QEvent* e ) { diff --git a/src/libtomahawk/widgets/infowidgets/sourceinfowidget.h b/src/libtomahawk/widgets/infowidgets/sourceinfowidget.h index eb1817aba..1c5f67da9 100644 --- a/src/libtomahawk/widgets/infowidgets/sourceinfowidget.h +++ b/src/libtomahawk/widgets/infowidgets/sourceinfowidget.h @@ -28,7 +28,7 @@ class AlbumModel; class CollectionFlatModel; -class PlaylistModel; +class RecentlyPlayedModel; namespace Ui { @@ -62,14 +62,13 @@ private slots: void loadRecentAdditions(); void onCollectionChanged(); - void onPlaybackFinished( const Tomahawk::query_ptr& query ); void onLoadedTrackHistory( const QList& queries ); private: Ui::SourceInfoWidget *ui; CollectionFlatModel* m_recentCollectionModel; - PlaylistModel* m_historyModel; + RecentlyPlayedModel* m_historyModel; AlbumModel* m_recentAlbumModel; Tomahawk::source_ptr m_source; diff --git a/src/libtomahawk/widgets/welcomewidget.cpp b/src/libtomahawk/widgets/welcomewidget.cpp index 145771d1c..3235a2371 100644 --- a/src/libtomahawk/widgets/welcomewidget.cpp +++ b/src/libtomahawk/widgets/welcomewidget.cpp @@ -29,16 +29,14 @@ #include "audio/audioengine.h" #include "playlist/albummodel.h" -#include "playlist/playlistmodel.h" +#include "playlist/RecentlyPlayedModel.h" #include "widgets/overlaywidget.h" #include "utils/tomahawkutils.h" #include "utils/logger.h" #include "dynamic/GeneratorInterface.h" #include "RecentlyPlayedPlaylistsModel.h" -#define HISTORY_TRACK_ITEMS 25 #define HISTORY_PLAYLIST_ITEMS 10 -#define HISTORY_RESOLVING_TIMEOUT 2500 using namespace Tomahawk; @@ -72,7 +70,7 @@ WelcomeWidget::WelcomeWidget( QWidget* parent ) ui->playlistWidget->setVerticalScrollMode( QAbstractItemView::ScrollPerPixel ); updatePlaylists(); - m_tracksModel = new PlaylistModel( ui->tracksView ); + m_tracksModel = new RecentlyPlayedModel( source_ptr(), ui->tracksView ); m_tracksModel->setStyle( TrackModel::ShortWithAvatars ); ui->tracksView->overlay()->setEnabled( false ); ui->tracksView->setPlaylistModel( m_tracksModel ); @@ -81,9 +79,6 @@ WelcomeWidget::WelcomeWidget( QWidget* parent ) ui->additionsView->setAlbumModel( m_recentAlbumsModel ); ui->additionsView->proxyModel()->sort( -1 ); - m_timer = new QTimer( this ); - connect( m_timer, SIGNAL( timeout() ), SLOT( checkQueries() ) ); - connect( SourceList::instance(), SIGNAL( ready() ), SLOT( onSourcesReady() ) ); connect( SourceList::instance(), SIGNAL( sourceAdded( Tomahawk::source_ptr ) ), SLOT( onSourceAdded( Tomahawk::source_ptr ) ) ); connect( ui->playlistWidget, SIGNAL( activated( QModelIndex ) ), SLOT( onPlaylistActivated( QModelIndex ) ) ); @@ -129,13 +124,18 @@ WelcomeWidget::isBeingPlayed() const void WelcomeWidget::onSourcesReady() { - m_tracksModel->loadHistory( Tomahawk::source_ptr(), HISTORY_TRACK_ITEMS ); - foreach ( const source_ptr& source, SourceList::instance()->sources() ) onSourceAdded( source ); } +void +WelcomeWidget::onSourceAdded( const Tomahawk::source_ptr& source ) +{ + connect( source->collection().data(), SIGNAL( changed() ), SLOT( updateRecentAdditions() ), Qt::UniqueConnection ); +} + + void WelcomeWidget::updateRecentAdditions() { @@ -157,66 +157,6 @@ WelcomeWidget::updatePlaylists() } -void -WelcomeWidget::onSourceAdded( const Tomahawk::source_ptr& source ) -{ - connect( source->collection().data(), SIGNAL( changed() ), SLOT( updateRecentAdditions() ), Qt::UniqueConnection ); - connect( source.data(), SIGNAL( playbackFinished( Tomahawk::query_ptr ) ), SLOT( onPlaybackFinished( Tomahawk::query_ptr ) ), Qt::UniqueConnection ); -} - - -void -WelcomeWidget::checkQueries() -{ - if ( m_timer->isActive() ) - m_timer->stop(); - - m_tracksModel->ensureResolved(); -} - - -void -WelcomeWidget::onPlaybackFinished( const Tomahawk::query_ptr& query ) -{ - int count = m_tracksModel->trackCount(); - unsigned int playtime = query->playedBy().second; - - if ( count ) - { - TrackModelItem* oldestItem = m_tracksModel->itemFromIndex( m_tracksModel->index( count - 1, 0, QModelIndex() ) ); - if ( oldestItem->query()->playedBy().second >= playtime ) - return; - - TrackModelItem* youngestItem = m_tracksModel->itemFromIndex( m_tracksModel->index( 0, 0, QModelIndex() ) ); - if ( youngestItem->query()->playedBy().second <= playtime ) - m_tracksModel->insert( query, 0 ); - else - { - for ( int i = 0; i < count - 1; i++ ) - { - TrackModelItem* item1 = m_tracksModel->itemFromIndex( m_tracksModel->index( i, 0, QModelIndex() ) ); - TrackModelItem* item2 = m_tracksModel->itemFromIndex( m_tracksModel->index( i + 1, 0, QModelIndex() ) ); - - if ( item1->query()->playedBy().second >= playtime && item2->query()->playedBy().second <= playtime ) - { - m_tracksModel->insert( query, i + 1 ); - break; - } - } - } - } - else - m_tracksModel->insert( query, 0 ); - - if ( m_tracksModel->trackCount() > HISTORY_TRACK_ITEMS ) - m_tracksModel->remove( HISTORY_TRACK_ITEMS ); - - if ( m_timer->isActive() ) - m_timer->stop(); - m_timer->start( HISTORY_RESOLVING_TIMEOUT ); -} - - void WelcomeWidget::onPlaylistActivated( const QModelIndex& item ) { diff --git a/src/libtomahawk/widgets/welcomewidget.h b/src/libtomahawk/widgets/welcomewidget.h index dc4e9250c..6b5c7a929 100644 --- a/src/libtomahawk/widgets/welcomewidget.h +++ b/src/libtomahawk/widgets/welcomewidget.h @@ -34,7 +34,7 @@ #include "dllmacro.h" class AlbumModel; -class PlaylistModel; +class RecentlyPlayedModel; class OverlayWidget; namespace Ui @@ -106,21 +106,17 @@ public slots: void updateRecentAdditions(); void loadData(); + private slots: void onSourcesReady(); void onSourceAdded( const Tomahawk::source_ptr& source ); void onPlaylistActivated( const QModelIndex& ); - void onPlaybackFinished( const Tomahawk::query_ptr& query ); - - void checkQueries(); private: Ui::WelcomeWidget *ui; - PlaylistModel* m_tracksModel; + RecentlyPlayedModel* m_tracksModel; AlbumModel* m_recentAlbumsModel; - - QTimer* m_timer; }; #endif // WELCOMEWIDGET_H