mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-08-07 06:36:55 +02:00
Merge remote branch 'origin/master' into dynamic
This commit is contained in:
@@ -124,8 +124,9 @@ AudioControls::AudioControls( QWidget* parent )
|
|||||||
connect( ui->repeatButton, SIGNAL( clicked() ), SLOT( onRepeatClicked() ) );
|
connect( ui->repeatButton, SIGNAL( clicked() ), SLOT( onRepeatClicked() ) );
|
||||||
connect( ui->shuffleButton, SIGNAL( clicked() ), SLOT( onShuffleClicked() ) );
|
connect( ui->shuffleButton, SIGNAL( clicked() ), SLOT( onShuffleClicked() ) );
|
||||||
|
|
||||||
connect( ui->artistTrackLabel, SIGNAL( clicked() ), SLOT( onTrackClicked() ) );
|
connect( ui->artistTrackLabel, SIGNAL( clickedArtist() ), SLOT( onArtistClicked() ) );
|
||||||
connect( ui->albumLabel, SIGNAL( clicked() ), SLOT( onAlbumClicked() ) );
|
connect( ui->artistTrackLabel, SIGNAL( clickedTrack() ), SLOT( onTrackClicked() ) );
|
||||||
|
connect( ui->albumLabel, SIGNAL( clickedAlbum() ), SLOT( onAlbumClicked() ) );
|
||||||
|
|
||||||
// <From AudioEngine>
|
// <From AudioEngine>
|
||||||
connect( AudioEngine::instance(), SIGNAL( loading( Tomahawk::result_ptr ) ), SLOT( onPlaybackLoading( Tomahawk::result_ptr ) ) );
|
connect( AudioEngine::instance(), SIGNAL( loading( Tomahawk::result_ptr ) ), SLOT( onPlaybackLoading( Tomahawk::result_ptr ) ) );
|
||||||
@@ -413,9 +414,9 @@ AudioControls::onShuffleClicked()
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
AudioControls::onTrackClicked()
|
AudioControls::onArtistClicked()
|
||||||
{
|
{
|
||||||
PlaylistManager::instance()->showCurrentTrack();
|
PlaylistManager::instance()->show( m_currentTrack->artist() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -424,3 +425,10 @@ AudioControls::onAlbumClicked()
|
|||||||
{
|
{
|
||||||
PlaylistManager::instance()->show( m_currentTrack->album() );
|
PlaylistManager::instance()->show( m_currentTrack->album() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
AudioControls::onTrackClicked()
|
||||||
|
{
|
||||||
|
PlaylistManager::instance()->showCurrentTrack();
|
||||||
|
}
|
||||||
|
@@ -38,8 +38,10 @@ private slots:
|
|||||||
|
|
||||||
void onRepeatClicked();
|
void onRepeatClicked();
|
||||||
void onShuffleClicked();
|
void onShuffleClicked();
|
||||||
void onTrackClicked();
|
|
||||||
|
void onArtistClicked();
|
||||||
void onAlbumClicked();
|
void onAlbumClicked();
|
||||||
|
void onTrackClicked();
|
||||||
|
|
||||||
void onCoverArtDownloaded();
|
void onCoverArtDownloaded();
|
||||||
|
|
||||||
|
@@ -1,5 +1,7 @@
|
|||||||
#include "database.h"
|
#include "database.h"
|
||||||
|
|
||||||
|
#define WORKER_THREADS 5
|
||||||
|
|
||||||
Database* Database::s_instance = 0;
|
Database* Database::s_instance = 0;
|
||||||
|
|
||||||
|
|
||||||
@@ -13,12 +15,18 @@ Database::instance()
|
|||||||
Database::Database( const QString& dbname, QObject* parent )
|
Database::Database( const QString& dbname, QObject* parent )
|
||||||
: QObject( parent )
|
: QObject( parent )
|
||||||
, m_impl( new DatabaseImpl( dbname, this ) )
|
, m_impl( new DatabaseImpl( dbname, this ) )
|
||||||
, m_workerRO( new DatabaseWorker( m_impl, this, false ) )
|
|
||||||
, m_workerRW( new DatabaseWorker( m_impl, this, true ) )
|
, m_workerRW( new DatabaseWorker( m_impl, this, true ) )
|
||||||
{
|
{
|
||||||
s_instance = this;
|
s_instance = this;
|
||||||
|
|
||||||
m_workerRO->start();
|
for ( int i = 0; i < WORKER_THREADS; i++ )
|
||||||
|
{
|
||||||
|
DatabaseWorker* worker = new DatabaseWorker( m_impl, this, false );
|
||||||
|
worker->start();
|
||||||
|
|
||||||
|
m_workersRO << worker;
|
||||||
|
}
|
||||||
|
|
||||||
m_workerRW->start();
|
m_workerRW->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27,8 +35,8 @@ Database::~Database()
|
|||||||
{
|
{
|
||||||
qDebug() << Q_FUNC_INFO;
|
qDebug() << Q_FUNC_INFO;
|
||||||
|
|
||||||
|
qDeleteAll( m_workersRO );
|
||||||
delete m_workerRW;
|
delete m_workerRW;
|
||||||
delete m_workerRO;
|
|
||||||
delete m_impl;
|
delete m_impl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,12 +54,31 @@ Database::enqueue( QSharedPointer<DatabaseCommand> lc )
|
|||||||
if( lc->doesMutates() )
|
if( lc->doesMutates() )
|
||||||
{
|
{
|
||||||
//qDebug() << Q_FUNC_INFO << "RW" << lc->commandname();
|
//qDebug() << Q_FUNC_INFO << "RW" << lc->commandname();
|
||||||
emit newJobRO( lc );
|
m_workerRW->enqueue( lc );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//qDebug() << Q_FUNC_INFO << "RO" << lc->commandname();
|
// qDebug() << Q_FUNC_INFO << "RO" << lc->commandname();
|
||||||
emit newJobRW( lc );
|
|
||||||
|
int busyThreads = 0;
|
||||||
|
DatabaseWorker* happyThread = 0;
|
||||||
|
for ( int i = 0; i < m_workersRO.count(); i++ )
|
||||||
|
{
|
||||||
|
DatabaseWorker* worker = m_workersRO.at( i );
|
||||||
|
|
||||||
|
if ( !worker->busy() )
|
||||||
|
{
|
||||||
|
happyThread = worker;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
busyThreads++;
|
||||||
|
|
||||||
|
if ( !happyThread || worker->outstandingJobs() < happyThread->outstandingJobs() )
|
||||||
|
happyThread = worker;
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << "Enqueueing command to thread:" << happyThread << busyThreads << lc->commandname();
|
||||||
|
happyThread->enqueue( lc );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -45,7 +45,8 @@ public slots:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
DatabaseImpl* m_impl;
|
DatabaseImpl* m_impl;
|
||||||
DatabaseWorker *m_workerRO, *m_workerRW;
|
DatabaseWorker* m_workerRW;
|
||||||
|
QList<DatabaseWorker*> m_workersRO;
|
||||||
bool m_indexReady;
|
bool m_indexReady;
|
||||||
|
|
||||||
static Database* s_instance;
|
static Database* s_instance;
|
||||||
|
@@ -15,18 +15,6 @@ DatabaseWorker::DatabaseWorker( DatabaseImpl* lib, Database* db, bool mutates )
|
|||||||
, m_outstanding( 0 )
|
, m_outstanding( 0 )
|
||||||
{
|
{
|
||||||
moveToThread( this );
|
moveToThread( this );
|
||||||
if( mutates )
|
|
||||||
{
|
|
||||||
connect( db, SIGNAL( newJobRW(QSharedPointer<DatabaseCommand>) ),
|
|
||||||
SLOT( doWork(QSharedPointer<DatabaseCommand>) ),
|
|
||||||
Qt::QueuedConnection );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
connect( db, SIGNAL( newJobRO(QSharedPointer<DatabaseCommand>) ),
|
|
||||||
SLOT( doWork(QSharedPointer<DatabaseCommand>) ),
|
|
||||||
Qt::QueuedConnection );
|
|
||||||
}
|
|
||||||
|
|
||||||
qDebug() << "CTOR DatabaseWorker" << this->thread();
|
qDebug() << "CTOR DatabaseWorker" << this->thread();
|
||||||
}
|
}
|
||||||
@@ -50,7 +38,19 @@ DatabaseWorker::run()
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
DatabaseWorker::doWork( QSharedPointer<DatabaseCommand> cmd )
|
DatabaseWorker::enqueue( const QSharedPointer<DatabaseCommand>& cmd )
|
||||||
|
{
|
||||||
|
QMutexLocker lock( &m_mut );
|
||||||
|
m_commands << cmd;
|
||||||
|
m_outstanding++;
|
||||||
|
|
||||||
|
if ( m_outstanding == 1 )
|
||||||
|
QTimer::singleShot( 0, this, SLOT( doWork() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
DatabaseWorker::doWork()
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Run the dbcmd. Only inside a transaction if the cmd does mutates.
|
Run the dbcmd. Only inside a transaction if the cmd does mutates.
|
||||||
@@ -59,8 +59,16 @@ DatabaseWorker::doWork( QSharedPointer<DatabaseCommand> cmd )
|
|||||||
log to the database oplog for replication to peers.
|
log to the database oplog for replication to peers.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
QTime timer;
|
QTime timer;
|
||||||
timer.start();
|
timer.start();
|
||||||
|
|
||||||
|
QSharedPointer<DatabaseCommand> cmd;
|
||||||
|
{
|
||||||
|
QMutexLocker lock( &m_mut );
|
||||||
|
cmd = m_commands.takeFirst();
|
||||||
|
}
|
||||||
|
|
||||||
if( cmd->doesMutates() )
|
if( cmd->doesMutates() )
|
||||||
{
|
{
|
||||||
bool transok = m_dbimpl->database().transaction();
|
bool transok = m_dbimpl->database().transaction();
|
||||||
@@ -154,6 +162,14 @@ DatabaseWorker::doWork( QSharedPointer<DatabaseCommand> cmd )
|
|||||||
}
|
}
|
||||||
|
|
||||||
cmd->emitFinished();
|
cmd->emitFinished();
|
||||||
|
|
||||||
|
{
|
||||||
|
QMutexLocker lock( &m_mut );
|
||||||
|
m_outstanding--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( m_outstanding > 0 )
|
||||||
|
doWork();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -24,13 +24,17 @@ Q_OBJECT
|
|||||||
public:
|
public:
|
||||||
DatabaseWorker( DatabaseImpl*, Database*, bool mutates );
|
DatabaseWorker( DatabaseImpl*, Database*, bool mutates );
|
||||||
~DatabaseWorker();
|
~DatabaseWorker();
|
||||||
//void enqueue( QSharedPointer<DatabaseCommand> );
|
|
||||||
|
void enqueue( const QSharedPointer<DatabaseCommand>& );
|
||||||
|
|
||||||
|
bool busy() const { return m_outstanding > 0; }
|
||||||
|
unsigned int outstandingJobs() const { return m_outstanding; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void run();
|
void run();
|
||||||
|
|
||||||
public slots:
|
private slots:
|
||||||
void doWork( QSharedPointer<DatabaseCommand> );
|
void doWork();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void logOp( DatabaseCommandLoggable* command );
|
void logOp( DatabaseCommandLoggable* command );
|
||||||
@@ -38,8 +42,10 @@ private:
|
|||||||
QMutex m_mut;
|
QMutex m_mut;
|
||||||
DatabaseImpl* m_dbimpl;
|
DatabaseImpl* m_dbimpl;
|
||||||
QList< QSharedPointer<DatabaseCommand> > m_commands;
|
QList< QSharedPointer<DatabaseCommand> > m_commands;
|
||||||
|
|
||||||
bool m_abort;
|
bool m_abort;
|
||||||
int m_outstanding;
|
int m_outstanding;
|
||||||
|
|
||||||
QJson::Serializer m_serializer;
|
QJson::Serializer m_serializer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -57,6 +57,7 @@ QueryLabel::~QueryLabel()
|
|||||||
void
|
void
|
||||||
QueryLabel::init()
|
QueryLabel::init()
|
||||||
{
|
{
|
||||||
|
m_hoverType = None;
|
||||||
setContentsMargins( 0, 0, 0, 0 );
|
setContentsMargins( 0, 0, 0, 0 );
|
||||||
setMouseTracking( true );
|
setMouseTracking( true );
|
||||||
|
|
||||||
@@ -251,6 +252,7 @@ void
|
|||||||
QueryLabel::updateLabel()
|
QueryLabel::updateLabel()
|
||||||
{
|
{
|
||||||
m_hoverArea = QRect();
|
m_hoverArea = QRect();
|
||||||
|
m_hoverType = None;
|
||||||
|
|
||||||
updateGeometry();
|
updateGeometry();
|
||||||
update();
|
update();
|
||||||
@@ -302,6 +304,7 @@ QueryLabel::paintEvent( QPaintEvent* event )
|
|||||||
{
|
{
|
||||||
m_hoverArea.setLeft( 0 );
|
m_hoverArea.setLeft( 0 );
|
||||||
m_hoverArea.setRight( fontMetrics().width( elidedText ) + contentsMargins().left() * 2 );
|
m_hoverArea.setRight( fontMetrics().width( elidedText ) + contentsMargins().left() * 2 );
|
||||||
|
m_hoverType = Track;
|
||||||
}
|
}
|
||||||
|
|
||||||
p.setPen( palette().mid().color() );
|
p.setPen( palette().mid().color() );
|
||||||
@@ -311,8 +314,16 @@ QueryLabel::paintEvent( QPaintEvent* event )
|
|||||||
|
|
||||||
if ( elidedText != s || ( m_result.isNull() && m_query.isNull() ) )
|
if ( elidedText != s || ( m_result.isNull() && m_query.isNull() ) )
|
||||||
{
|
{
|
||||||
p.setBrush( palette().window() );
|
if ( m_hoverArea.width() )
|
||||||
p.setPen( palette().color( foregroundRole() ) );
|
{
|
||||||
|
p.setPen( palette().highlightedText().color() );
|
||||||
|
p.setBrush( palette().highlight() );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p.setBrush( palette().window() );
|
||||||
|
p.setPen( palette().color( foregroundRole() ) );
|
||||||
|
}
|
||||||
p.drawText( r, align, elidedText );
|
p.drawText( r, align, elidedText );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -328,7 +339,7 @@ QueryLabel::paintEvent( QPaintEvent* event )
|
|||||||
p.setBrush( palette().window() );
|
p.setBrush( palette().window() );
|
||||||
p.setPen( palette().color( foregroundRole() ) );
|
p.setPen( palette().color( foregroundRole() ) );
|
||||||
|
|
||||||
if ( m_hoverArea.width() && m_hoverArea.left() + contentsMargins().left() == r.left() )
|
if ( m_hoverType == Artist )
|
||||||
{
|
{
|
||||||
p.setPen( palette().highlightedText().color() );
|
p.setPen( palette().highlightedText().color() );
|
||||||
p.setBrush( palette().highlight() );
|
p.setBrush( palette().highlight() );
|
||||||
@@ -347,7 +358,7 @@ QueryLabel::paintEvent( QPaintEvent* event )
|
|||||||
p.drawText( r, align, DASH );
|
p.drawText( r, align, DASH );
|
||||||
r.adjust( dashX, 0, 0, 0 );
|
r.adjust( dashX, 0, 0, 0 );
|
||||||
}
|
}
|
||||||
if ( m_hoverArea.width() && m_hoverArea.left() + contentsMargins().left() == r.left() )
|
if ( m_hoverType == Album )
|
||||||
{
|
{
|
||||||
p.setPen( palette().highlightedText().color() );
|
p.setPen( palette().highlightedText().color() );
|
||||||
p.setBrush( palette().highlight() );
|
p.setBrush( palette().highlight() );
|
||||||
@@ -366,7 +377,7 @@ QueryLabel::paintEvent( QPaintEvent* event )
|
|||||||
p.drawText( r, align, DASH );
|
p.drawText( r, align, DASH );
|
||||||
r.adjust( dashX, 0, 0, 0 );
|
r.adjust( dashX, 0, 0, 0 );
|
||||||
}
|
}
|
||||||
if ( m_hoverArea.width() && m_hoverArea.left() + contentsMargins().left() == r.left() )
|
if ( m_hoverType == Track )
|
||||||
{
|
{
|
||||||
p.setPen( palette().highlightedText().color() );
|
p.setPen( palette().highlightedText().color() );
|
||||||
p.setBrush( palette().highlight() );
|
p.setBrush( palette().highlight() );
|
||||||
@@ -413,7 +424,23 @@ QueryLabel::mouseReleaseEvent( QMouseEvent* event )
|
|||||||
|
|
||||||
m_dragPos = QPoint();
|
m_dragPos = QPoint();
|
||||||
if ( time.elapsed() < qApp->doubleClickInterval() )
|
if ( time.elapsed() < qApp->doubleClickInterval() )
|
||||||
emit clicked();
|
{
|
||||||
|
switch( m_hoverType )
|
||||||
|
{
|
||||||
|
case Artist:
|
||||||
|
emit clickedArtist();
|
||||||
|
break;
|
||||||
|
case Album:
|
||||||
|
emit clickedAlbum();
|
||||||
|
break;
|
||||||
|
case Track:
|
||||||
|
emit clickedTrack();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
emit clicked();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -434,6 +461,7 @@ QueryLabel::mouseMoveEvent( QMouseEvent* event )
|
|||||||
if ( m_query.isNull() && m_result.isNull() )
|
if ( m_query.isNull() && m_result.isNull() )
|
||||||
{
|
{
|
||||||
m_hoverArea = QRect();
|
m_hoverArea = QRect();
|
||||||
|
m_hoverType = None;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -460,19 +488,23 @@ QueryLabel::mouseMoveEvent( QMouseEvent* event )
|
|||||||
}
|
}
|
||||||
|
|
||||||
QRect hoverArea;
|
QRect hoverArea;
|
||||||
|
m_hoverType = None;
|
||||||
if ( m_type & Artist && x < artistX )
|
if ( m_type & Artist && x < artistX )
|
||||||
{
|
{
|
||||||
|
m_hoverType = Artist;
|
||||||
hoverArea.setLeft( 0 );
|
hoverArea.setLeft( 0 );
|
||||||
hoverArea.setRight( artistX + contentsMargins().left() );
|
hoverArea.setRight( artistX + contentsMargins().left() );
|
||||||
}
|
}
|
||||||
else if ( m_type & Album && x < albumX && x > artistX )
|
else if ( m_type & Album && x < albumX && x > artistX )
|
||||||
{
|
{
|
||||||
|
m_hoverType = Album;
|
||||||
int spacing = ( m_type & Artist ) ? dashX : 0;
|
int spacing = ( m_type & Artist ) ? dashX : 0;
|
||||||
hoverArea.setLeft( artistX + spacing );
|
hoverArea.setLeft( artistX + spacing );
|
||||||
hoverArea.setRight( albumX + spacing + contentsMargins().left() );
|
hoverArea.setRight( albumX + spacing + contentsMargins().left() );
|
||||||
}
|
}
|
||||||
else if ( m_type & Track && x < trackX && x > albumX )
|
else if ( m_type & Track && x < trackX && x > albumX )
|
||||||
{
|
{
|
||||||
|
m_hoverType = Track;
|
||||||
int spacing = ( m_type & Album ) ? dashX : 0;
|
int spacing = ( m_type & Album ) ? dashX : 0;
|
||||||
hoverArea.setLeft( albumX + spacing );
|
hoverArea.setLeft( albumX + spacing );
|
||||||
hoverArea.setRight( trackX + contentsMargins().left() );
|
hoverArea.setRight( trackX + contentsMargins().left() );
|
||||||
@@ -495,6 +527,7 @@ void
|
|||||||
QueryLabel::leaveEvent( QEvent* event )
|
QueryLabel::leaveEvent( QEvent* event )
|
||||||
{
|
{
|
||||||
m_hoverArea = QRect();
|
m_hoverArea = QRect();
|
||||||
|
m_hoverType = None;
|
||||||
repaint();
|
repaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -16,6 +16,7 @@ Q_OBJECT
|
|||||||
public:
|
public:
|
||||||
enum DisplayType
|
enum DisplayType
|
||||||
{
|
{
|
||||||
|
None = 0,
|
||||||
Artist = 1,
|
Artist = 1,
|
||||||
Album = 2,
|
Album = 2,
|
||||||
Track = 4,
|
Track = 4,
|
||||||
@@ -61,6 +62,9 @@ public slots:
|
|||||||
|
|
||||||
signals:
|
signals:
|
||||||
void clicked();
|
void clicked();
|
||||||
|
void clickedArtist();
|
||||||
|
void clickedAlbum();
|
||||||
|
void clickedTrack();
|
||||||
|
|
||||||
void textChanged( const QString& text );
|
void textChanged( const QString& text );
|
||||||
void resultChanged( const Tomahawk::result_ptr& result );
|
void resultChanged( const Tomahawk::result_ptr& result );
|
||||||
@@ -89,6 +93,7 @@ private:
|
|||||||
Qt::Alignment align;
|
Qt::Alignment align;
|
||||||
Qt::TextElideMode mode;
|
Qt::TextElideMode mode;
|
||||||
|
|
||||||
|
DisplayType m_hoverType;
|
||||||
QRect m_hoverArea;
|
QRect m_hoverArea;
|
||||||
QPoint m_dragPos;
|
QPoint m_dragPos;
|
||||||
QMargins m_textMargins;
|
QMargins m_textMargins;
|
||||||
|
Reference in New Issue
Block a user