From 1f124dec53a01a3916a3ae628e7b7c7c02bc5fd8 Mon Sep 17 00:00:00 2001 From: "Uwe L. Korn" Date: Tue, 16 Jul 2013 11:33:52 +0200 Subject: [PATCH] Add "Hot Playlists" to NetworkActivity --- .../NetworkActivityWidget.cpp | 67 +++++++-- .../NetworkActivityWidget.h | 17 ++- .../NetworkActivityWidget.ui | 6 +- .../NetworkActivityWidget_p.h | 2 + .../NetworkActivityWorker.cpp | 129 ++++++++++++++++-- .../NetworkActivityWorker.h | 12 +- .../NetworkActivityWorker_p.h | 13 ++ src/libtomahawk/CMakeLists.txt | 46 ++++--- .../DatabaseCommand_CalculatePlaytime.cpp | 107 +++++++++++++++ .../DatabaseCommand_CalculatePlaytime.h | 55 ++++++++ .../DatabaseCommand_CalculatePlaytime_p.h | 50 +++++++ src/libtomahawk/widgets/PlaylistsModel.cpp | 121 ++++++++++++++++ src/libtomahawk/widgets/PlaylistsModel.h | 54 ++++++++ src/libtomahawk/widgets/PlaylistsModel_p.h | 47 +++++++ 14 files changed, 671 insertions(+), 55 deletions(-) create mode 100644 src/libtomahawk/database/DatabaseCommand_CalculatePlaytime.cpp create mode 100644 src/libtomahawk/database/DatabaseCommand_CalculatePlaytime.h create mode 100644 src/libtomahawk/database/DatabaseCommand_CalculatePlaytime_p.h create mode 100644 src/libtomahawk/widgets/PlaylistsModel.cpp create mode 100644 src/libtomahawk/widgets/PlaylistsModel.h create mode 100644 src/libtomahawk/widgets/PlaylistsModel_p.h diff --git a/src/libtomahawk-widgets/NetworkActivityWidget.cpp b/src/libtomahawk-widgets/NetworkActivityWidget.cpp index 6bd063f62..e2a6a266b 100644 --- a/src/libtomahawk-widgets/NetworkActivityWidget.cpp +++ b/src/libtomahawk-widgets/NetworkActivityWidget.cpp @@ -30,7 +30,9 @@ #include "utils/TomahawkStyle.h" #include "utils/TomahawkUtilsGui.h" #include "widgets/OverlayWidget.h" +#include "widgets/PlaylistsModel.h" #include "Pipeline.h" +#include "PlaylistDelegate.h" #include #include @@ -111,8 +113,6 @@ NetworkActivityWidget::NetworkActivityWidget( QWidget* parent ) // Trending Tracks { d->trendingTracksModel = new PlaylistModel( d->ui->trendingTracksView ); - // TODO: - // m_tracksModel = new RecentlyPlayedModel( ui->tracksView, HISTORY_TRACK_ITEMS ); d->ui->trendingTracksView->proxyModel()->setStyle( PlayableProxyModel::Short ); d->ui->trendingTracksView->overlay()->setEnabled( false ); d->ui->trendingTracksView->setPlaylistModel( d->trendingTracksModel ); @@ -146,7 +146,7 @@ NetworkActivityWidget::NetworkActivityWidget( QWidget* parent ) // Hot Playlists { - TomahawkStyle::stylePageFrame( d->ui->hotPlaylistsFrame ); + TomahawkStyle::stylePageFrame( d->ui->playlistsFrame ); QFont f = d->ui->hotPlaylistsLabel->font(); f.setFamily( "Pathway Gothic One" ); @@ -158,6 +158,31 @@ NetworkActivityWidget::NetworkActivityWidget( QWidget* parent ) d->ui->hotPlaylistsLabel->setPalette( p ); } + { + d->ui->playlistView->setFrameShape( QFrame::NoFrame ); + d->ui->playlistView->setAttribute( Qt::WA_MacShowFocusRect, 0 ); + d->ui->playlistView->setItemDelegate( new PlaylistDelegate() ); + d->ui->playlistView->overlay()->resize( 380, 86 ); + d->ui->playlistView->setVerticalScrollMode( QAbstractItemView::ScrollPerPixel ); + + QPalette p = d->ui->playlistView->palette(); + p.setColor( QPalette::Text, TomahawkStyle::HEADER_TEXT ); + p.setColor( QPalette::BrightText, TomahawkStyle::HEADER_TEXT ); + p.setColor( QPalette::Foreground, TomahawkStyle::HEADER_TEXT ); + p.setColor( QPalette::Highlight, TomahawkStyle::HEADER_TEXT ); + p.setColor( QPalette::HighlightedText, TomahawkStyle::HEADER_BACKGROUND ); + + d->ui->playlistView->setPalette( p ); + d->ui->playlistView->setMinimumHeight( 400 ); + d->ui->playlistView->setStyleSheet( "QListView { background-color: transparent; }" ); + TomahawkStyle::styleScrollBar( d->ui->playlistView->verticalScrollBar() ); + TomahawkStyle::stylePageFrame( d->ui->playlistsFrame ); + + // updatePlaylists(); + // connect( ui->playlistWidget, SIGNAL( activated( QModelIndex ) ), SLOT( onPlaylistActivated( QModelIndex ) ) ); + // connect( model, SIGNAL( emptinessChanged( bool ) ), this, SLOT( updatePlaylists() ) ); + } + { QScrollArea* area = new QScrollArea(); area->setWidgetResizable( true ); @@ -171,18 +196,27 @@ NetworkActivityWidget::NetworkActivityWidget( QWidget* parent ) } // Load data in separate thread - d->worker = new NetworkActivityWorker(); - d->worker->moveToThread( d->worker ); + d->workerThread = new QThread(); + d->workerThread->start(); + d->worker = new NetworkActivityWorker( ); + d->worker->moveToThread( d->workerThread ); connect( d->worker, SIGNAL( trendingTracks( QList ) ), - SLOT( trendingTracks( QList ) ), Qt::QueuedConnection); - connect( d->worker, SIGNAL( finished() ), d->worker, SLOT( deleteLater() ) ); - d->worker->start(); + SLOT( trendingTracks( QList ) ), + Qt::QueuedConnection); + connect( d->worker, SIGNAL( hotPlaylists(QList) ), + SLOT(hotPlaylists(QList)), + Qt::QueuedConnection); + connect( d->worker, SIGNAL( finished() ), + d->workerThread, SLOT( quit() ), + Qt::QueuedConnection ); + // connect( d->workerThread, SIGNAL( finished() ), d->workerThread, SLOT( deleteLater() ), Qt::QueuedConnection ); + // connect( d->workerThread, SIGNAL( destroyed() ), d->worker, SLOT( deleteLater() ), Qt::QueuedConnection ); + QMetaObject::invokeMethod( d->worker, "run", Qt::QueuedConnection ); } NetworkActivityWidget::~NetworkActivityWidget() { - delete d_ptr; } @@ -279,6 +313,13 @@ NetworkActivityWidget::overallCharts( const QList& tracks ) } } +void +NetworkActivityWidget::hotPlaylists( const QList& playlists ) +{ + Q_D( NetworkActivityWidget ); + d->ui->playlistView->setModel( new PlaylistsModel( playlists, this ) ); +} + void NetworkActivityWidget::trendingTracks( const QList& tracks ) @@ -326,7 +367,7 @@ NetworkActivityWidget::fetchYearCharts() QDateTime to = QDateTime::currentDateTime(); QDateTime yearAgo = to.addYears( -1 ); DatabaseCommand_NetworkCharts* yearCharts = new DatabaseCommand_NetworkCharts( yearAgo, to ); - yearCharts->setLimit( NETWORKCHARTS_NUM_TRACKS ); + yearCharts->setLimit( numberOfNetworkChartEntries ); connect( yearCharts, SIGNAL( done( QList ) ), SLOT( yearlyCharts( QList ) ) ); Database::instance()->enqueue( Tomahawk::dbcmd_ptr( yearCharts ) ); } @@ -336,7 +377,7 @@ void NetworkActivityWidget::fetchOverallCharts() { DatabaseCommand_NetworkCharts* overallCharts = new DatabaseCommand_NetworkCharts(); - overallCharts->setLimit( NETWORKCHARTS_NUM_TRACKS ); + overallCharts->setLimit( numberOfNetworkChartEntries ); connect( overallCharts, SIGNAL( done( QList ) ), SLOT( overallCharts( QList ) ) ); Database::instance()->enqueue( Tomahawk::dbcmd_ptr( overallCharts ) ); } @@ -348,7 +389,7 @@ NetworkActivityWidget::fetchWeekCharts() QDateTime to = QDateTime::currentDateTime(); QDateTime weekAgo = to.addDays( -7 ); DatabaseCommand_NetworkCharts* weekCharts = new DatabaseCommand_NetworkCharts( weekAgo, to ); - weekCharts->setLimit( NETWORKCHARTS_NUM_TRACKS ); + weekCharts->setLimit( numberOfNetworkChartEntries ); connect( weekCharts, SIGNAL( done( QList ) ), SLOT( weeklyCharts( QList ) ) ); Database::instance()->enqueue( Tomahawk::dbcmd_ptr( weekCharts ) ); } @@ -360,7 +401,7 @@ NetworkActivityWidget::fetchMonthCharts() QDateTime to = QDateTime::currentDateTime(); QDateTime monthAgo = to.addMonths( -1 ); DatabaseCommand_NetworkCharts* monthCharts = new DatabaseCommand_NetworkCharts( monthAgo, to ); - monthCharts->setLimit( NETWORKCHARTS_NUM_TRACKS ); + monthCharts->setLimit( numberOfNetworkChartEntries ); connect( monthCharts, SIGNAL( done( QList ) ), SLOT( monthlyCharts( QList ) ) ); Database::instance()->enqueue( Tomahawk::dbcmd_ptr( monthCharts ) ); } diff --git a/src/libtomahawk-widgets/NetworkActivityWidget.h b/src/libtomahawk-widgets/NetworkActivityWidget.h index fa590c3f6..350e53867 100644 --- a/src/libtomahawk-widgets/NetworkActivityWidget.h +++ b/src/libtomahawk-widgets/NetworkActivityWidget.h @@ -19,9 +19,6 @@ #ifndef NETWORKACTIVITYWIDGET_H #define NETWORKACTIVITYWIDGET_H -#define NETWORKCHARTS_NUM_TRACKS 20 -#define TRENDING_TRACKS_NUM 3 - #include "ViewPage.h" #include "WidgetsDllMacro.h" @@ -61,7 +58,13 @@ public: virtual bool isBeingPlayed() const; virtual bool jumpToCurrentTrack(); -signals: + + static const uint numberOfHotPlaylists = 3; + static const uint numberOfTrendingTracks = 3; + static const uint numberOfNetworkChartEntries = 20; + +protected: + QScopedPointer d_ptr; private slots: void weeklyCharts( const QList& ); @@ -69,6 +72,7 @@ private slots: void yearlyCharts( const QList& ); void overallCharts( const QList& ); + void hotPlaylists( const QList& playlists ); void trendingTracks( const QList< Tomahawk::track_ptr >& tracks ); void leftCrumbIndexChanged( const QModelIndex& ); @@ -85,11 +89,10 @@ private: void showOverallCharts(); Q_DECLARE_PRIVATE( NetworkActivityWidget ) - NetworkActivityWidgetPrivate* d_ptr; }; -}; // Widgets +} // Widgets -}; // Tomahawk +} // Tomahawk #endif // NETWORKACTIVITYWIDGET_H diff --git a/src/libtomahawk-widgets/NetworkActivityWidget.ui b/src/libtomahawk-widgets/NetworkActivityWidget.ui index 031080488..986186550 100644 --- a/src/libtomahawk-widgets/NetworkActivityWidget.ui +++ b/src/libtomahawk-widgets/NetworkActivityWidget.ui @@ -7,7 +7,7 @@ 0 0 875 - 520 + 526 @@ -26,7 +26,7 @@ - + @@ -60,7 +60,7 @@ - + QFrame::StyledPanel diff --git a/src/libtomahawk-widgets/NetworkActivityWidget_p.h b/src/libtomahawk-widgets/NetworkActivityWidget_p.h index 01262efd0..6ecbac576 100644 --- a/src/libtomahawk-widgets/NetworkActivityWidget_p.h +++ b/src/libtomahawk-widgets/NetworkActivityWidget_p.h @@ -31,6 +31,7 @@ public: : q_ptr ( q ) , ui( new Ui::NetworkActivityWidget ) , sortedProxy( 0 ) + , workerThread( 0 ) { } @@ -52,6 +53,7 @@ private: Tomahawk::Widgets::NetworkActivityWidget::ViewType activeView; Tomahawk::NetworkActivityWorker* worker; + QThread* workerThread; }; #endif // NETWORKACTIVITYWIDGET_P_H diff --git a/src/libtomahawk-widgets/NetworkActivityWorker.cpp b/src/libtomahawk-widgets/NetworkActivityWorker.cpp index c00e96208..c03b6694b 100644 --- a/src/libtomahawk-widgets/NetworkActivityWorker.cpp +++ b/src/libtomahawk-widgets/NetworkActivityWorker.cpp @@ -19,15 +19,19 @@ #include "NetworkActivityWorker_p.h" #include "database/Database.h" +#include "database/DatabaseCommand_CalculatePlaytime.h" +#include "database/DatabaseCommand_LoadAllPlaylists.h" +#include "database/DatabaseCommand_LoadAllSources.h" #include "database/DatabaseCommand_TrendingTracks.h" #include "database/DatabaseImpl.h" -#include "utils/Logger.h" #include "NetworkActivityWidget.h" +#include + namespace Tomahawk { NetworkActivityWorker::NetworkActivityWorker( QObject* parent ) - : QThread( parent ) + : QObject( parent ) , d_ptr( new NetworkActivityWorkerPrivate( this ) ) { } @@ -41,19 +45,85 @@ NetworkActivityWorker::~NetworkActivityWorker() void NetworkActivityWorker::run() { - tLog() << Q_FUNC_INFO; { // Load trending tracks qRegisterMetaType< QList< QPair< double,Tomahawk::track_ptr > > >("QList< QPair< double,Tomahawk::track_ptr > >"); DatabaseCommand_TrendingTracks* dbcmd = new DatabaseCommand_TrendingTracks(); - dbcmd->setLimit( TRENDING_TRACKS_NUM ); + dbcmd->setLimit( Tomahawk::Widgets::NetworkActivityWidget::numberOfTrendingTracks ); connect( dbcmd, SIGNAL( done( QList< QPair< double,Tomahawk::track_ptr > >) ), - SLOT( trendingTracksReceived( QList< QPair< double,Tomahawk::track_ptr > > ) ), Qt::QueuedConnection ); + SLOT( trendingTracksReceived( QList< QPair< double,Tomahawk::track_ptr > > ) ), + Qt::QueuedConnection ); Database::instance()->enqueue( dbcmd_ptr( dbcmd ) ); } + { + DatabaseCommand_LoadAllSources* dbcmd = new DatabaseCommand_LoadAllSources(); + connect( dbcmd, SIGNAL( done( QList ) ), + SLOT( allSourcesReceived( QList ) ), + Qt::QueuedConnection); + Database::instance()->enqueue( dbcmd_ptr( dbcmd ) ); + } +} - // Start the event loop - exec(); + +void +NetworkActivityWorker::allPlaylistsReceived( const QList& playlists ) +{ + Q_D( NetworkActivityWorker ); + d->sourcesToLoad--; + d->playlists.append( playlists ); + + if ( d->sourcesToLoad == 0 ) + { + // Load all playlist entries + foreach( playlist_ptr playlist, d->playlists ) + { + if ( !playlist->loaded() ) + { + d->playlistsRevisionToLoad++; + connect( playlist.data(), SIGNAL( revisionLoaded( Tomahawk::PlaylistRevision ) ), + SLOT( revisionLoaded( Tomahawk::PlaylistRevision ) ), + Qt::QueuedConnection ); + playlist->loadRevision(); + } + } + checkRevisionLoadedDone(); + } +} + + +void +NetworkActivityWorker::allSourcesReceived( const QList& sources ) +{ + Q_D( NetworkActivityWorker ); + d->sourcesToLoad = sources.count(); + + foreach ( const source_ptr& source, sources) + { + DatabaseCommand_LoadAllPlaylists* dbcmd = new DatabaseCommand_LoadAllPlaylists( source ); + connect( dbcmd, SIGNAL( done( QList ) ), + SLOT( allPlaylistsReceived ( QList ) ), + Qt::QueuedConnection ); + Database::instance()->enqueue( dbcmd_ptr( dbcmd ) ); + } +} + + +void +NetworkActivityWorker::playtime( uint playtime ) +{ + Q_D( NetworkActivityWorker ); + d->playlistCount.insert( playtime, d->playlistStack.pop() ); + calculateNextPlaylist(); +} + + +void +NetworkActivityWorker::revisionLoaded(PlaylistRevision revision) +{ + Q_UNUSED( revision ); + Q_D( NetworkActivityWorker ); + d->playlistsRevisionToLoad--; + checkRevisionLoadedDone(); } @@ -75,13 +145,54 @@ NetworkActivityWorker::trendingTracksReceived( const QListplaylistStack.isEmpty() ) + { + DatabaseCommand_CalculatePlaytime* dbcmd = new DatabaseCommand_CalculatePlaytime( d->playlistStack.top(), QDateTime::currentDateTime().addDays( -7 ), QDateTime::currentDateTime() ); + connect( dbcmd, SIGNAL( done( uint ) ), SLOT( playtime( uint ) ), Qt::QueuedConnection ); + Database::instance()->enqueue( dbcmd_ptr( dbcmd ) ); + } + else + { + d->playlistCount.remove( 0 ); + QList playlists; + QMapIterator iter (d->playlistCount); + iter.toBack(); + while (iter.hasPrevious() && (uint)playlists.size() < Widgets::NetworkActivityWidget::numberOfHotPlaylists ) + { + iter.previous(); + playlists << iter.value(); + } + emit hotPlaylists( playlists ); + d->hotPlaylistsDone = true; + checkDone(); + } +} + +void +NetworkActivityWorker::checkRevisionLoadedDone() +{ + Q_D( NetworkActivityWorker ); + if ( d->playlistsRevisionToLoad == 0 ) + { + foreach (playlist_ptr playlist, d->playlists) { + d->playlistStack.push( playlist ); + } + calculateNextPlaylist(); + } +} + void NetworkActivityWorker::checkDone() { Q_D( NetworkActivityWorker ); - if ( d->trendingTracksDone ) + if ( d->trendingTracksDone && d->hotPlaylistsDone ) { - quit(); + emit finished(); } } diff --git a/src/libtomahawk-widgets/NetworkActivityWorker.h b/src/libtomahawk-widgets/NetworkActivityWorker.h index 0f2470ff4..ccac40ebe 100644 --- a/src/libtomahawk-widgets/NetworkActivityWorker.h +++ b/src/libtomahawk-widgets/NetworkActivityWorker.h @@ -20,6 +20,7 @@ #ifndef TOMAHAWK_NETWORKACTIVITYWORKER_H #define TOMAHAWK_NETWORKACTIVITYWORKER_H +#include "Playlist.h" #include "Typedefs.h" #include @@ -28,27 +29,36 @@ namespace Tomahawk { class NetworkActivityWorkerPrivate; -class NetworkActivityWorker : public QThread +class NetworkActivityWorker : public QObject { Q_OBJECT public: explicit NetworkActivityWorker( QObject *parent = 0 ); virtual ~NetworkActivityWorker(); +public slots: void run(); signals: void trendingTracks( const QList& tracks ); + void hotPlaylists( const QList& playlists ); + void finished(); protected: QScopedPointer d_ptr; private slots: + void allPlaylistsReceived( const QList& playlists ); + void allSourcesReceived( const QList< Tomahawk::source_ptr >& sources ); + void playtime( uint playtime ); + void revisionLoaded( Tomahawk::PlaylistRevision revision ); void trendingTracksReceived( const QList< QPair< double,Tomahawk::track_ptr > >& tracks ); private: Q_DECLARE_PRIVATE( NetworkActivityWorker ) + void calculateNextPlaylist(); + void checkRevisionLoadedDone(); void checkDone(); }; diff --git a/src/libtomahawk-widgets/NetworkActivityWorker_p.h b/src/libtomahawk-widgets/NetworkActivityWorker_p.h index d33505fa5..c38958161 100644 --- a/src/libtomahawk-widgets/NetworkActivityWorker_p.h +++ b/src/libtomahawk-widgets/NetworkActivityWorker_p.h @@ -22,6 +22,8 @@ #include "NetworkActivityWorker.h" +#include + namespace Tomahawk { @@ -31,6 +33,9 @@ public: NetworkActivityWorkerPrivate( NetworkActivityWorker* q ) : q_ptr( q ) , trendingTracksDone( false ) + , hotPlaylistsDone( false ) + , playlistsRevisionToLoad( 0 ) + , trackStatsToLoad( 0 ) { } @@ -38,6 +43,14 @@ public: Q_DECLARE_PUBLIC( NetworkActivityWorker ) private: bool trendingTracksDone; + + bool hotPlaylistsDone; + QList playlists; + uint playlistsRevisionToLoad; + uint sourcesToLoad; + uint trackStatsToLoad; + QStack playlistStack; + QMultiMap playlistCount; }; } // Tomahawk diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index 4d70fe1b1..139f759b6 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -128,36 +128,37 @@ set( libGuiSources utils/NetworkAccessManager.cpp widgets/AnimatedCounterLabel.cpp + widgets/AnimatedSplitter.cpp widgets/BasicHeader.cpp - widgets/FilterHeader.cpp - widgets/ScriptCollectionHeader.cpp widgets/Breadcrumb.cpp widgets/BreadcrumbButton.cpp - widgets/CheckDirTree.cpp - widgets/QueryLabel.cpp - widgets/ImageButton.cpp - widgets/StatsGauge.cpp - widgets/AnimatedSplitter.cpp - widgets/ElidedLabel.cpp - widgets/NewPlaylistWidget.cpp - widgets/SearchWidget.cpp - widgets/SeekSlider.cpp - widgets/PlaylistTypeSelectorDialog.cpp - widgets/HistoryWidget.cpp - widgets/WhatsHotWidget.cpp - widgets/NewReleasesWidget.cpp widgets/ChartDataLoader.cpp - widgets/RecentlyPlayedPlaylistsModel.cpp - widgets/RecentPlaylistsModel.cpp - widgets/OverlayButton.cpp - widgets/OverlayWidget.cpp + widgets/CheckDirTree.cpp + widgets/ComboBox.cpp + widgets/ElidedLabel.cpp + widgets/FadingPixmap.cpp + widgets/FilterHeader.cpp widgets/HeaderLabel.cpp widgets/HeaderWidget.cpp - widgets/ComboBox.cpp - widgets/ToggleButton.cpp - widgets/FadingPixmap.cpp + widgets/HistoryWidget.cpp + widgets/ImageButton.cpp + widgets/NewPlaylistWidget.cpp + widgets/NewReleasesWidget.cpp + widgets/OverlayButton.cpp + widgets/OverlayWidget.cpp widgets/PlayableCover.cpp + widgets/PlaylistsModel.cpp + widgets/PlaylistTypeSelectorDialog.cpp + widgets/QueryLabel.cpp + widgets/RecentPlaylistsModel.cpp + widgets/RecentlyPlayedPlaylistsModel.cpp + widgets/ScriptCollectionHeader.cpp + widgets/SearchWidget.cpp + widgets/SeekSlider.cpp widgets/SourceTreePopupDialog.cpp + widgets/StatsGauge.cpp + widgets/ToggleButton.cpp + widgets/WhatsHotWidget.cpp widgets/infowidgets/SourceInfoWidget.cpp widgets/infowidgets/ArtistInfoWidget.cpp widgets/infowidgets/AlbumInfoWidget.cpp @@ -245,6 +246,7 @@ list(APPEND libSources database/DatabaseCommand_AllArtists.cpp database/DatabaseCommand_AllTracks.cpp database/DatabaseCommand_ArtistStats.cpp + database/DatabaseCommand_CalculatePlaytime.cpp database/DatabaseCommand_ClientAuthValid.cpp database/DatabaseCommand_CollectionAttributes.cpp database/DatabaseCommand_CollectionStats.cpp diff --git a/src/libtomahawk/database/DatabaseCommand_CalculatePlaytime.cpp b/src/libtomahawk/database/DatabaseCommand_CalculatePlaytime.cpp new file mode 100644 index 000000000..74380abba --- /dev/null +++ b/src/libtomahawk/database/DatabaseCommand_CalculatePlaytime.cpp @@ -0,0 +1,107 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2013, Uwe L. Korn + * + * 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 "DatabaseCommand_CalculatePlaytime_p.h" + +#include "database/DatabaseImpl.h" +#include "Source.h" +#include "Track.h" + +namespace Tomahawk { + +DatabaseCommand_CalculatePlaytime::DatabaseCommand_CalculatePlaytime( const playlist_ptr& playlist, QDateTime from, QDateTime to, QObject* parent ) + : DatabaseCommand( parent, new DatabaseCommand_CalculatePlaytimePrivate( this , from, to ) ) +{ + Q_D( DatabaseCommand_CalculatePlaytime ); + foreach( plentry_ptr entry, playlist->entries() ) + { + d->tracks.append( entry->query()->track() ); + } +} + +DatabaseCommand_CalculatePlaytime::DatabaseCommand_CalculatePlaytime( const track_ptr& track, QDateTime from, QDateTime to, QObject* parent ) + : DatabaseCommand( parent, new DatabaseCommand_CalculatePlaytimePrivate( this , from, to ) ) +{ + Q_D( DatabaseCommand_CalculatePlaytime ); + d->tracks.append( track ); +} + + +DatabaseCommand_CalculatePlaytime::DatabaseCommand_CalculatePlaytime( const QList& tracks, QDateTime from, QDateTime to, QObject* parent ) + : DatabaseCommand( parent, new DatabaseCommand_CalculatePlaytimePrivate( this , from, to ) ) +{ + Q_D( DatabaseCommand_CalculatePlaytime ); + d->tracks = tracks; +} + + +DatabaseCommand_CalculatePlaytime::DatabaseCommand_CalculatePlaytime( const query_ptr& query, QDateTime from, QDateTime to, QObject* parent) + : DatabaseCommand( parent, new DatabaseCommand_CalculatePlaytimePrivate( this , from, to ) ) +{ + Q_D( DatabaseCommand_CalculatePlaytime ); + d->tracks.append( query->track() ); +} + + +DatabaseCommand_CalculatePlaytime::DatabaseCommand_CalculatePlaytime( const QList& queries, QDateTime from, QDateTime to, QObject* parent) + : DatabaseCommand( parent, new DatabaseCommand_CalculatePlaytimePrivate( this , from, to ) ) +{ + Q_D( DatabaseCommand_CalculatePlaytime ); + foreach ( query_ptr query, queries ) + { + d->tracks.append( query->track() ); + } +} + + +DatabaseCommand_CalculatePlaytime::~DatabaseCommand_CalculatePlaytime() +{ +} + +void +DatabaseCommand_CalculatePlaytime::exec( DatabaseImpl *dbi ) +{ + Q_D( DatabaseCommand_CalculatePlaytime ); + + // Get all trackIds + QStringList trackIds; + foreach ( track_ptr track, d->tracks ) + { + trackIds.append( QString::number( track->trackId() ) ); + } + + QString sql = QString( + " SELECT SUM(secs_played) " + " FROM playback_log " + " WHERE track in ( %1 ) AND playtime >= %2 AND playtime <= %3 " + ).arg( trackIds.join(", ") ).arg( d->from.toTime_t() ).arg( d->to.toTime_t() ); + + TomahawkSqlQuery query = dbi->newquery(); + query.prepare( sql ); + query.exec(); + + uint playtime; + while ( query.next() ) + { + playtime = query.value( 0 ).toUInt(); + } + emit done( playtime ); +} + + +} // namespace Tomahawk diff --git a/src/libtomahawk/database/DatabaseCommand_CalculatePlaytime.h b/src/libtomahawk/database/DatabaseCommand_CalculatePlaytime.h new file mode 100644 index 000000000..45b900d9d --- /dev/null +++ b/src/libtomahawk/database/DatabaseCommand_CalculatePlaytime.h @@ -0,0 +1,55 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2013, Uwe L. Korn + * + * 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 . + */ + +#pragma once +#ifndef TOMAHAWK_DATABASECOMMAND_CALCULATEPLAYTIME_H +#define TOMAHAWK_DATABASECOMMAND_CALCULATEPLAYTIME_H + +#include "database/DatabaseCommand.h" + +namespace Tomahawk { + +class DatabaseCommand_CalculatePlaytimePrivate; + +class DLLEXPORT DatabaseCommand_CalculatePlaytime : public Tomahawk::DatabaseCommand +{ + Q_OBJECT +public: + explicit DatabaseCommand_CalculatePlaytime( const playlist_ptr& playlist, QDateTime from, QDateTime to, QObject* parent = 0 ); + explicit DatabaseCommand_CalculatePlaytime( const track_ptr& track, QDateTime from, QDateTime to, QObject* parent = 0 ); + explicit DatabaseCommand_CalculatePlaytime( const QList& tracks, QDateTime from, QDateTime to, QObject* parent = 0 ); + explicit DatabaseCommand_CalculatePlaytime( const query_ptr& query, QDateTime from, QDateTime to, QObject* parent = 0 ); + explicit DatabaseCommand_CalculatePlaytime( const QList& queries, QDateTime from, QDateTime to, QObject* parent = 0 ); + virtual ~DatabaseCommand_CalculatePlaytime(); + + virtual void exec( DatabaseImpl* dbi ); + + virtual bool doesMutates() const { return false; } + virtual QString commandname() const { return "calculateplaytime"; } + + +signals: + void done( uint playtime ); + +private: + Q_DECLARE_PRIVATE( DatabaseCommand_CalculatePlaytime ) +}; + +} // namespace Tomahawk + +#endif // TOMAHAWK_DATABASECOMMAND_CALCULATEPLAYTIME_H diff --git a/src/libtomahawk/database/DatabaseCommand_CalculatePlaytime_p.h b/src/libtomahawk/database/DatabaseCommand_CalculatePlaytime_p.h new file mode 100644 index 000000000..f438741eb --- /dev/null +++ b/src/libtomahawk/database/DatabaseCommand_CalculatePlaytime_p.h @@ -0,0 +1,50 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2013, Uwe L. Korn + * + * 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 . + */ + +#pragma once +#ifndef DATABASECOMMAND_CALCULATEPLAYTIME_P_H +#define DATABASECOMMAND_CALCULATEPLAYTIME_P_H + +#include "database/DatabaseCommand_p.h" +#include "database/DatabaseCommand_CalculatePlaytime.h" + +#include + +namespace Tomahawk +{ + +class DatabaseCommand_CalculatePlaytimePrivate : public DatabaseCommandPrivate +{ + DatabaseCommand_CalculatePlaytimePrivate( DatabaseCommand_CalculatePlaytime* q, QDateTime _from, QDateTime _to ) + : DatabaseCommandPrivate( q ) + , from( _from ) + , to( _to ) + { + } + + Q_DECLARE_PUBLIC( DatabaseCommand_CalculatePlaytime ) + +private: + QDateTime from; + QDateTime to; + QList tracks; +}; + +} + +#endif // DATABASECOMMAND_CALCULATEPLAYTIME_P_H diff --git a/src/libtomahawk/widgets/PlaylistsModel.cpp b/src/libtomahawk/widgets/PlaylistsModel.cpp new file mode 100644 index 000000000..553999db1 --- /dev/null +++ b/src/libtomahawk/widgets/PlaylistsModel.cpp @@ -0,0 +1,121 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2013, Uwe L. Korn + * + * 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 "PlaylistsModel_p.h" + +#include "widgets/RecentlyPlayedPlaylistsModel.h" +#include "Track.h" + +namespace Tomahawk { + + +PlaylistsModel::PlaylistsModel( const QList& playlists, QObject* parent ) + : QAbstractListModel(parent) + , d_ptr( new PlaylistsModelPrivate( this, playlists ) ) +{ + updateArtists(); +} + + +PlaylistsModel::~PlaylistsModel() +{ +} + + +QVariant +PlaylistsModel::data( const QModelIndex& index, int role ) const +{ + Q_D( const PlaylistsModel ); + + if ( !index.isValid() || !hasIndex( index.row(), index.column(), index.parent() ) ) + return QVariant(); + + playlist_ptr pl = d->playlists.value( index.row() ); + switch( role ) + { + case Qt::DisplayRole: + return pl->title(); + case RecentlyPlayedPlaylistsModel::PlaylistRole: + return QVariant::fromValue< Tomahawk::playlist_ptr >( pl ); + case RecentlyPlayedPlaylistsModel::ArtistRole: + { + return d->artists[pl]; + } + case RecentlyPlayedPlaylistsModel::PlaylistTypeRole: + { + if ( !pl.dynamicCast< Tomahawk::DynamicPlaylist >().isNull() ) + { + dynplaylist_ptr dynp = pl.dynamicCast< Tomahawk::DynamicPlaylist >(); + if ( dynp->mode() == Static ) + return RecentlyPlayedPlaylistsModel::AutoPlaylist; + else if ( dynp->mode() == OnDemand ) + return RecentlyPlayedPlaylistsModel::Station; + } + else + { + return RecentlyPlayedPlaylistsModel::StaticPlaylist; + } + } + case RecentlyPlayedPlaylistsModel::DynamicPlaylistRole: + { + dynplaylist_ptr dynp = pl.dynamicCast< Tomahawk::DynamicPlaylist >(); + return QVariant::fromValue< Tomahawk::dynplaylist_ptr >( dynp ); + } + case RecentlyPlayedPlaylistsModel::TrackCountRole: + { + if ( !pl.dynamicCast< Tomahawk::DynamicPlaylist >().isNull() && pl.dynamicCast< Tomahawk::DynamicPlaylist >()->mode() == OnDemand ) + return QString( QChar( 0x221E ) ); + else + return pl->entries().count(); + } + default: + return QVariant(); + } +} + + +int +PlaylistsModel::rowCount( const QModelIndex& ) const +{ + Q_D( const PlaylistsModel ); + return d->playlists.count(); +} + + +void +PlaylistsModel::updateArtists() +{ + Q_D( PlaylistsModel ); + d->artists.clear(); + + foreach ( playlist_ptr playlist, d->playlists ) + { + QStringList artists; + + foreach ( const Tomahawk::plentry_ptr& entry, playlist->entries() ) + { + if ( !artists.contains( entry->query()->track()->artist() ) ) + artists << entry->query()->track()->artist(); + } + + d->artists[ playlist ] = artists.join( ", " ); + } +} + + +} // namespace Tomahawk diff --git a/src/libtomahawk/widgets/PlaylistsModel.h b/src/libtomahawk/widgets/PlaylistsModel.h new file mode 100644 index 000000000..45c83c33e --- /dev/null +++ b/src/libtomahawk/widgets/PlaylistsModel.h @@ -0,0 +1,54 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2013, Uwe L. Korn + * + * 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 . + */ + +#pragma once +#ifndef TOMAHAWK_PLAYLISTSMODEL_H +#define TOMAHAWK_PLAYLISTSMODEL_H + +#include "DllMacro.h" +#include "Typedefs.h" + +#include + +namespace Tomahawk { + +class PlaylistsModelPrivate; + +class DLLEXPORT PlaylistsModel : public QAbstractListModel +{ + Q_OBJECT +public: + explicit PlaylistsModel( const QList& playlists, QObject* parent = 0 ); + virtual ~PlaylistsModel(); + + virtual QVariant data( const QModelIndex& index, int role = Qt::DisplayRole ) const; + virtual int rowCount( const QModelIndex& parent = QModelIndex() ) const; + +protected: + QScopedPointer d_ptr; + + void updateArtists(); + +private: + Q_DECLARE_PRIVATE( PlaylistsModel ) + +}; + +} // namespace Tomahawk + +#endif // TOMAHAWK_PLAYLISTSMODEL_H diff --git a/src/libtomahawk/widgets/PlaylistsModel_p.h b/src/libtomahawk/widgets/PlaylistsModel_p.h new file mode 100644 index 000000000..9bf6bb5bb --- /dev/null +++ b/src/libtomahawk/widgets/PlaylistsModel_p.h @@ -0,0 +1,47 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2013, Uwe L. Korn + * + * 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 . + */ + +#pragma once +#ifndef PLAYLISTSMODEL_P_H +#define PLAYLISTSMODEL_P_H + +#include "PlaylistsModel.h" + +namespace Tomahawk +{ + +class PlaylistsModelPrivate +{ +public: + PlaylistsModelPrivate( PlaylistsModel* q, const QList& _playlists ) + : q_ptr( q ) + , playlists( _playlists ) + { + } + virtual ~PlaylistsModelPrivate() {} + + PlaylistsModel* q_ptr; + Q_DECLARE_PUBLIC( PlaylistsModel ) +private: + QList playlists; + QMap artists; +}; + +} + +#endif // PLAYLISTSMODEL_P_H