1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-08-21 21:25:52 +02:00

* Added activity label to sources in the sidebar (currently only shows Idle / currently playing track).

* DatabaseCommand_LogPlayback now contains an action-enum, which indicates if the track has just started / finished playback.
This commit is contained in:
Christian Muehlhaeuser
2011-01-06 09:03:18 +01:00
parent ce30f01ec9
commit 8d50ef1b88
18 changed files with 158 additions and 28 deletions

View File

@@ -97,6 +97,7 @@ AudioEngine::stop()
m_audio->stopPlayback(); m_audio->stopPlayback();
setCurrentTrack( Tomahawk::result_ptr() );
emit stopped(); emit stopped();
} }
@@ -157,16 +158,7 @@ AudioEngine::loadTrack( const Tomahawk::result_ptr& result )
err = true; err = true;
else else
{ {
m_lastTrack = m_currentTrack; setCurrentTrack( result );
if ( !m_lastTrack.isNull() )
{
DatabaseCommand_LogPlayback* cmd = new DatabaseCommand_LogPlayback( m_lastTrack, m_timeElapsed );
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>(cmd) );
emit finished( m_lastTrack );
}
m_currentTrack = result;
io = Servent::instance()->getIODeviceForUrl( m_currentTrack ); io = Servent::instance()->getIODeviceForUrl( m_currentTrack );
if ( !io || io.isNull() ) if ( !io || io.isNull() )
@@ -311,10 +303,14 @@ AudioEngine::setStreamData( long sampleRate, int channels )
if ( sampleRate < 44100 ) if ( sampleRate < 44100 )
sampleRate = 44100; sampleRate = 44100;
m_audio->initAudio( sampleRate, channels ); m_audio->initAudio( sampleRate, channels );
if ( m_audio->startPlayback() ) if ( m_audio->startPlayback() )
{ {
emit started( m_currentTrack ); emit started( m_currentTrack );
DatabaseCommand_LogPlayback* cmd = new DatabaseCommand_LogPlayback( m_currentTrack, DatabaseCommand_LogPlayback::Started );
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>(cmd) );
} }
else else
{ {
@@ -352,6 +348,22 @@ AudioEngine::clearBuffers()
} }
void
AudioEngine::setCurrentTrack( const Tomahawk::result_ptr& result )
{
m_lastTrack = m_currentTrack;
if ( !m_lastTrack.isNull() )
{
DatabaseCommand_LogPlayback* cmd = new DatabaseCommand_LogPlayback( m_lastTrack, DatabaseCommand_LogPlayback::Finished, m_timeElapsed );
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>(cmd) );
emit finished( m_lastTrack );
}
m_currentTrack = result;
}
void void
AudioEngine::run() AudioEngine::run()
{ {

View File

@@ -80,6 +80,8 @@ private slots:
void engineLoop(); void engineLoop();
void loop(); void loop();
void setCurrentTrack( const Tomahawk::result_ptr& result );
private: private:
void run(); void run();
void clearBuffers(); void clearBuffers();

View File

@@ -29,6 +29,8 @@ SourceInfoWidget::SourceInfoWidget( const Tomahawk::source_ptr& source, QWidget*
ui->historyView->setModel( m_historyModel ); ui->historyView->setModel( m_historyModel );
m_historyModel->loadHistory( source ); m_historyModel->loadHistory( source );
connect( source.data(), SIGNAL( playbackFinished( Tomahawk::query_ptr ) ), SLOT( onPlaybackFinished( Tomahawk::query_ptr ) ) );
ui->recentCollectionView->setColumnHidden( TrackModel::Bitrate, true ); ui->recentCollectionView->setColumnHidden( TrackModel::Bitrate, true );
ui->recentCollectionView->setColumnHidden( TrackModel::Origin, true ); ui->recentCollectionView->setColumnHidden( TrackModel::Origin, true );
ui->recentCollectionView->setColumnHidden( TrackModel::Filesize, true ); ui->recentCollectionView->setColumnHidden( TrackModel::Filesize, true );
@@ -49,6 +51,13 @@ SourceInfoWidget::~SourceInfoWidget()
} }
void
SourceInfoWidget::onPlaybackFinished( const Tomahawk::query_ptr& query )
{
m_historyModel->insertTrack( 0, query );
}
void void
SourceInfoWidget::changeEvent( QEvent* e ) SourceInfoWidget::changeEvent( QEvent* e )
{ {

View File

@@ -27,6 +27,9 @@ public:
protected: protected:
void changeEvent( QEvent* e ); void changeEvent( QEvent* e );
private slots:
void onPlaybackFinished( const Tomahawk::query_ptr& query );
private: private:
Ui::SourceInfoWidget *ui; Ui::SourceInfoWidget *ui;

View File

@@ -38,16 +38,16 @@ DatabaseCommand_AddFiles::postCommitHook()
// collection browser will update/fade in etc. // collection browser will update/fade in etc.
Collection* coll = source()->collection().data(); Collection* coll = source()->collection().data();
connect( this, SIGNAL( notify( const QList<QVariant>&, Tomahawk::collection_ptr ) ), connect( this, SIGNAL( notify( QList<QVariant>, Tomahawk::collection_ptr ) ),
coll, SIGNAL( setTracks( const QList<QVariant>&, Tomahawk::collection_ptr ) ), coll, SIGNAL( setTracks( QList<QVariant>, Tomahawk::collection_ptr ) ),
Qt::QueuedConnection ); Qt::QueuedConnection );
// do it like this so it gets called in the right thread: // do it like this so it gets called in the right thread:
emit notify( m_files, source()->collection() ); emit notify( m_files, source()->collection() );
// also re-calc the collection stats, to updates the "X tracks" in the sidebar etc: // also re-calc the collection stats, to updates the "X tracks" in the sidebar etc:
DatabaseCommand_CollectionStats* cmd = new DatabaseCommand_CollectionStats( source() ); DatabaseCommand_CollectionStats* cmd = new DatabaseCommand_CollectionStats( source() );
connect( cmd, SIGNAL( done( const QVariantMap& ) ), connect( cmd, SIGNAL( done( QVariantMap ) ),
source().data(), SLOT( setStats( const QVariantMap& ) ), Qt::QueuedConnection ); source().data(), SLOT( setStats( QVariantMap ) ), Qt::QueuedConnection );
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>( cmd ) ); Database::instance()->enqueue( QSharedPointer<DatabaseCommand>( cmd ) );
if( source()->isLocal() ) if( source()->isLocal() )

View File

@@ -5,6 +5,7 @@
#include "collection.h" #include "collection.h"
#include "database/database.h" #include "database/database.h"
#include "databaseimpl.h" #include "databaseimpl.h"
#include "pipeline.h"
#include "network/servent.h" #include "network/servent.h"
using namespace Tomahawk; using namespace Tomahawk;
@@ -16,6 +17,28 @@ DatabaseCommand_LogPlayback::postCommitHook()
{ {
qDebug() << Q_FUNC_INFO; qDebug() << Q_FUNC_INFO;
connect( this, SIGNAL( trackPlaying( Tomahawk::query_ptr ) ),
source().data(), SIGNAL( playbackStarted( Tomahawk::query_ptr ) ), Qt::QueuedConnection );
connect( this, SIGNAL( trackPlayed( Tomahawk::query_ptr ) ),
source().data(), SIGNAL( playbackFinished( Tomahawk::query_ptr ) ), Qt::QueuedConnection );
QVariantMap m;
m.insert( "track", m_track );
m.insert( "artist", m_artist );
m.insert( "qid", uuid() );
Tomahawk::query_ptr q( new Tomahawk::Query( m ) );
Tomahawk::Pipeline::instance()->add( q );
if ( m_action == Finished )
{
emit trackPlayed( q );
}
else if ( m_action == Started )
{
emit trackPlaying( q );
}
if( source()->isLocal() ) if( source()->isLocal() )
Servent::instance()->triggerDBSync(); Servent::instance()->triggerDBSync();
} }
@@ -27,6 +50,9 @@ DatabaseCommand_LogPlayback::exec( DatabaseImpl* dbi )
qDebug() << Q_FUNC_INFO; qDebug() << Q_FUNC_INFO;
Q_ASSERT( !source().isNull() ); Q_ASSERT( !source().isNull() );
if ( m_action != Finished )
return;
TomahawkSqlQuery query = dbi->newquery(); TomahawkSqlQuery query = dbi->newquery();
query.prepare( "INSERT INTO playback_log(source,track,playtime,secs_played) " query.prepare( "INSERT INTO playback_log(source,track,playtime,secs_played) "
"VALUES (?, ?, ?, ?)" ); "VALUES (?, ?, ?, ?)" );

View File

@@ -17,14 +17,21 @@ Q_PROPERTY( QString artist READ artist WRITE setArtist )
Q_PROPERTY( QString track READ track WRITE setTrack ) Q_PROPERTY( QString track READ track WRITE setTrack )
Q_PROPERTY( unsigned int playtime READ playtime WRITE setPlaytime ) Q_PROPERTY( unsigned int playtime READ playtime WRITE setPlaytime )
Q_PROPERTY( unsigned int secsPlayed READ secsPlayed WRITE setSecsPlayed ) Q_PROPERTY( unsigned int secsPlayed READ secsPlayed WRITE setSecsPlayed )
Q_PROPERTY( int action READ action WRITE setAction )
public: public:
enum Action
{
Started = 1,
Finished = 2
};
explicit DatabaseCommand_LogPlayback( QObject* parent = 0 ) explicit DatabaseCommand_LogPlayback( QObject* parent = 0 )
: DatabaseCommandLoggable( parent ) : DatabaseCommandLoggable( parent )
{} {}
explicit DatabaseCommand_LogPlayback( const Tomahawk::result_ptr& result, unsigned int secsPlayed, QObject* parent = 0 ) explicit DatabaseCommand_LogPlayback( const Tomahawk::result_ptr& result, Action action, unsigned int secsPlayed = 0, QObject* parent = 0 )
: DatabaseCommandLoggable( parent ), m_result( result ), m_secsPlayed( secsPlayed ) : DatabaseCommandLoggable( parent ), m_result( result ), m_secsPlayed( secsPlayed ), m_action( action )
{ {
m_playtime = QDateTime::currentDateTimeUtc().toTime_t(); m_playtime = QDateTime::currentDateTimeUtc().toTime_t();
setSource( SourceList::instance()->getLocal() ); setSource( SourceList::instance()->getLocal() );
@@ -51,6 +58,13 @@ public:
unsigned int secsPlayed() const { return m_secsPlayed; } unsigned int secsPlayed() const { return m_secsPlayed; }
void setSecsPlayed( unsigned int i ) { m_secsPlayed = i; } void setSecsPlayed( unsigned int i ) { m_secsPlayed = i; }
int action() const { return m_action; }
void setAction( int a ) { m_action = (Action)a; }
signals:
void trackPlaying( const Tomahawk::query_ptr& query );
void trackPlayed( const Tomahawk::query_ptr& query );
private: private:
Tomahawk::result_ptr m_result; Tomahawk::result_ptr m_result;
@@ -58,6 +72,7 @@ private:
QString m_track; QString m_track;
unsigned int m_playtime; unsigned int m_playtime;
unsigned int m_secsPlayed; unsigned int m_secsPlayed;
Action m_action;
}; };
#endif // DATABASECOMMAND_LOGPLAYBACK_H #endif // DATABASECOMMAND_LOGPLAYBACK_H

View File

@@ -20,7 +20,8 @@ DatabaseCommand_PlaybackHistory::exec( DatabaseImpl* dbi )
QString sql = QString( QString sql = QString(
"SELECT track, playtime, secs_played " "SELECT track, playtime, secs_played "
"FROM playback_log " "FROM playback_log "
"%1" ).arg( whereToken ); "%1 "
"ORDER BY playtime DESC").arg( whereToken );
query.prepare( sql ); query.prepare( sql );
query.exec(); query.exec();

View File

@@ -23,6 +23,7 @@ public:
float score() const; float score() const;
RID id() const; RID id() const;
collection_ptr collection() const { return m_collection; } collection_ptr collection() const { return m_collection; }
Tomahawk::artist_ptr artist() const { return m_artist; } Tomahawk::artist_ptr artist() const { return m_artist; }

View File

@@ -29,7 +29,7 @@ public:
bool isLocal() const { return m_isLocal; } bool isLocal() const { return m_isLocal; }
bool isOnline() const { return m_online; } bool isOnline() const { return m_online; }
const QString& userName() const { return m_username; } QString userName() const { return m_username; }
QString friendlyName() const; QString friendlyName() const;
void setFriendlyName( const QString& fname ) { m_friendlyname = fname; } void setFriendlyName( const QString& fname ) { m_friendlyname = fname; }
@@ -53,6 +53,9 @@ signals:
void stats( const QVariantMap& ); void stats( const QVariantMap& );
void usernameChanged( const QString& ); void usernameChanged( const QString& );
void playbackStarted( const Tomahawk::query_ptr& query );
void playbackFinished( const Tomahawk::query_ptr& query );
// this signal is emitted from DBSyncConnection: // this signal is emitted from DBSyncConnection:
void loadingStateChanged( DBSyncConnection::State newstate, DBSyncConnection::State oldstate, const QString& info ); void loadingStateChanged( DBSyncConnection::State newstate, DBSyncConnection::State oldstate, const QString& info );

View File

@@ -154,27 +154,50 @@ PlaylistModel::appendTrack( const Tomahawk::query_ptr& query )
} }
void
PlaylistModel::insertTrack( unsigned int row, const Tomahawk::query_ptr& query )
{
if ( query.isNull() )
return;
QList< Tomahawk::query_ptr > ql;
ql << query;
onTracksInserted( row, ql );
}
void void
PlaylistModel::onTracksAdded( const QList<Tomahawk::query_ptr>& tracks, const Tomahawk::collection_ptr& collection ) PlaylistModel::onTracksAdded( const QList<Tomahawk::query_ptr>& tracks, const Tomahawk::collection_ptr& collection )
{
onTracksInserted( rowCount( QModelIndex() ), tracks, collection );
}
void
PlaylistModel::onTracksInserted( unsigned int row, const QList<Tomahawk::query_ptr>& tracks, const Tomahawk::collection_ptr& collection )
{ {
if ( !tracks.count() ) if ( !tracks.count() )
return; return;
int c = rowCount( QModelIndex() ); int c = row;
QPair< int, int > crows; QPair< int, int > crows;
crows.first = c; crows.first = c;
crows.second = c + tracks.count() - 1; crows.second = c + tracks.count() - 1;
emit beginInsertRows( QModelIndex(), crows.first, crows.second ); emit beginInsertRows( QModelIndex(), crows.first, crows.second );
int i = 0;
PlItem* plitem; PlItem* plitem;
foreach( const query_ptr& query, tracks ) foreach( const query_ptr& query, tracks )
{ {
plentry_ptr entry = plentry_ptr( new PlaylistEntry() ); plentry_ptr entry = plentry_ptr( new PlaylistEntry() );
entry->setQuery( query ); entry->setQuery( query );
plitem = new PlItem( entry, m_rootItem ); plitem = new PlItem( entry, m_rootItem, row + i );
plitem->index = createIndex( m_rootItem->children.count() - 1, 0, plitem ); plitem->index = createIndex( row + i, 0, plitem );
i++;
connect( plitem, SIGNAL( dataChanged() ), SLOT( onDataChanged() ) ); connect( plitem, SIGNAL( dataChanged() ), SLOT( onDataChanged() ) );
} }

View File

@@ -35,6 +35,7 @@ public:
void loadHistory( const Tomahawk::source_ptr& source, unsigned int amount = 100 ); void loadHistory( const Tomahawk::source_ptr& source, unsigned int amount = 100 );
void appendTrack( const Tomahawk::query_ptr& query ); void appendTrack( const Tomahawk::query_ptr& query );
void insertTrack( unsigned int row, const Tomahawk::query_ptr& query );
virtual void removeIndex( const QModelIndex& index, bool moreToCome = false ); virtual void removeIndex( const QModelIndex& index, bool moreToCome = false );
@@ -54,6 +55,7 @@ private slots:
void onPlaylistChanged( bool waitForUpdate = true ); void onPlaylistChanged( bool waitForUpdate = true );
void onTracksAdded( const QList<Tomahawk::query_ptr>& tracks, const Tomahawk::collection_ptr& collection = Tomahawk::collection_ptr() ); void onTracksAdded( const QList<Tomahawk::query_ptr>& tracks, const Tomahawk::collection_ptr& collection = Tomahawk::collection_ptr() );
void onTracksInserted( unsigned int row, const QList<Tomahawk::query_ptr>& tracks, const Tomahawk::collection_ptr& collection = Tomahawk::collection_ptr() );
private: private:
QList<Tomahawk::plentry_ptr> playlistEntries() const; QList<Tomahawk::plentry_ptr> playlistEntries() const;

View File

@@ -39,6 +39,8 @@ SourceTreeItemWidget::SourceTreeItemWidget( const source_ptr& source, QWidget* p
connect( source.data(), SIGNAL( stats( QVariantMap ) ), SLOT( gotStats( QVariantMap ) ) ); connect( source.data(), SIGNAL( stats( QVariantMap ) ), SLOT( gotStats( QVariantMap ) ) );
connect( source.data(), SIGNAL( playbackStarted( Tomahawk::query_ptr ) ), SLOT( onPlaybackStarted( Tomahawk::query_ptr ) ) );
ui->avatarImage->setPixmap( QPixmap( RESPATH "images/user-avatar.png" ) ); ui->avatarImage->setPixmap( QPixmap( RESPATH "images/user-avatar.png" ) );
displayname = source->friendlyName(); displayname = source->friendlyName();
@@ -52,7 +54,9 @@ SourceTreeItemWidget::SourceTreeItemWidget( const source_ptr& source, QWidget* p
} }
ui->nameLabel->setText( displayname ); ui->nameLabel->setText( displayname );
ui->activityLabel->setText( tr( "Idle" ) );
ui->infoLabel->setForegroundRole( QPalette::Dark ); ui->infoLabel->setForegroundRole( QPalette::Dark );
ui->activityLabel->setForegroundRole( QPalette::Dark );
connect( ui->onOffButton, SIGNAL( clicked() ), SIGNAL( clicked() ) ); connect( ui->onOffButton, SIGNAL( clicked() ), SIGNAL( clicked() ) );
connect( ui->infoButton, SIGNAL( clicked() ), SLOT( onInfoButtonClicked() ) ); connect( ui->infoButton, SIGNAL( clicked() ), SLOT( onInfoButtonClicked() ) );
@@ -124,6 +128,13 @@ SourceTreeItemWidget::onLoadingStateChanged( DBSyncConnection::State newstate, D
} }
void
SourceTreeItemWidget::onPlaybackStarted( const Tomahawk::query_ptr& query )
{
ui->activityLabel->setText( tr( "Playing: %1 by %2" ).arg( query->track() ).arg( query->artist() ) );
}
void void
SourceTreeItemWidget::onOnline() SourceTreeItemWidget::onOnline()
{ {

View File

@@ -32,6 +32,8 @@ private slots:
void gotStats( const QVariantMap& stats ); void gotStats( const QVariantMap& stats );
void onLoadingStateChanged( DBSyncConnection::State newstate, DBSyncConnection::State oldstate, const QString& info ); void onLoadingStateChanged( DBSyncConnection::State newstate, DBSyncConnection::State oldstate, const QString& info );
void onPlaybackStarted( const Tomahawk::query_ptr& query );
void onInfoButtonClicked(); void onInfoButtonClicked();
private: private:

View File

@@ -7,7 +7,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>359</width> <width>359</width>
<height>44</height> <height>58</height>
</rect> </rect>
</property> </property>
<property name="sizePolicy"> <property name="sizePolicy">
@@ -19,13 +19,13 @@
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>0</width> <width>0</width>
<height>44</height> <height>58</height>
</size> </size>
</property> </property>
<property name="maximumSize"> <property name="maximumSize">
<size> <size>
<width>16777215</width> <width>16777215</width>
<height>44</height> <height>58</height>
</size> </size>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@@ -103,14 +103,11 @@
<property name="topMargin"> <property name="topMargin">
<number>4</number> <number>4</number>
</property> </property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin"> <property name="bottomMargin">
<number>4</number> <number>4</number>
</property> </property>
<item> <item>
<widget class="QLabel" name="nameLabel"> <widget class="ElidedLabel" name="nameLabel">
<property name="font"> <property name="font">
<font> <font>
<weight>75</weight> <weight>75</weight>
@@ -129,6 +126,13 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="ElidedLabel" name="activityLabel">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout> </layout>
</item> </item>
<item> <item>
@@ -192,6 +196,11 @@
<extends>QPushButton</extends> <extends>QPushButton</extends>
<header>imagebutton.h</header> <header>imagebutton.h</header>
</customwidget> </customwidget>
<customwidget>
<class>ElidedLabel</class>
<extends>QLabel</extends>
<header>elidedlabel.h</header>
</customwidget>
</customwidgets> </customwidgets>
<resources/> <resources/>
<connections/> <connections/>

View File

@@ -265,6 +265,7 @@ TomahawkApp::registerMetaTypes()
// Extra definition for namespaced-versions of signals/slots required // Extra definition for namespaced-versions of signals/slots required
qRegisterMetaType< Tomahawk::collection_ptr >("Tomahawk::collection_ptr"); qRegisterMetaType< Tomahawk::collection_ptr >("Tomahawk::collection_ptr");
qRegisterMetaType< Tomahawk::result_ptr >("Tomahawk::result_ptr"); qRegisterMetaType< Tomahawk::result_ptr >("Tomahawk::result_ptr");
qRegisterMetaType< Tomahawk::query_ptr >("Tomahawk::query_ptr");
qRegisterMetaType< Tomahawk::source_ptr >("Tomahawk::source_ptr"); qRegisterMetaType< Tomahawk::source_ptr >("Tomahawk::source_ptr");
qRegisterMetaType< QList<Tomahawk::playlist_ptr> >("QList<Tomahawk::playlist_ptr>"); qRegisterMetaType< QList<Tomahawk::playlist_ptr> >("QList<Tomahawk::playlist_ptr>");
qRegisterMetaType< QList<Tomahawk::plentry_ptr> >("QList<Tomahawk::plentry_ptr>"); qRegisterMetaType< QList<Tomahawk::plentry_ptr> >("QList<Tomahawk::plentry_ptr>");

View File

@@ -61,6 +61,15 @@ WelcomeWidget::onSourceAdded( const Tomahawk::source_ptr& source )
{ {
connect( source->collection().data(), SIGNAL( playlistsAdded( QList<Tomahawk::playlist_ptr> ) ), SLOT( updatePlaylists() ) ); connect( source->collection().data(), SIGNAL( playlistsAdded( QList<Tomahawk::playlist_ptr> ) ), SLOT( updatePlaylists() ) );
connect( source->collection().data(), SIGNAL( playlistsDeleted( QList<Tomahawk::playlist_ptr> ) ), SLOT( updatePlaylists() ) ); connect( source->collection().data(), SIGNAL( playlistsDeleted( QList<Tomahawk::playlist_ptr> ) ), SLOT( updatePlaylists() ) );
connect( source.data(), SIGNAL( playbackFinished( Tomahawk::query_ptr ) ), SLOT( onPlaybackFinished( Tomahawk::query_ptr ) ) );
}
void
WelcomeWidget::onPlaybackFinished( const Tomahawk::query_ptr& query )
{
m_tracksModel->insertTrack( 0, query );
} }

View File

@@ -77,6 +77,7 @@ public slots:
private slots: private slots:
void onSourceAdded( const Tomahawk::source_ptr& source ); void onSourceAdded( const Tomahawk::source_ptr& source );
void onPlaylistActivated( QListWidgetItem* item ); void onPlaylistActivated( QListWidgetItem* item );
void onPlaybackFinished( const Tomahawk::query_ptr& query );
private: private:
Ui::WelcomeWidget *ui; Ui::WelcomeWidget *ui;