From 0e36f77dd41e6f804ab96ba719d62f7144c8d13b Mon Sep 17 00:00:00 2001 From: Patrick von Reth Date: Sat, 7 Jul 2012 19:07:56 +0300 Subject: [PATCH 01/28] improved support for thumbnail buttons --- src/TomahawkWindow.cpp | 154 ++++++++++++++++++++++++++++++----------- src/TomahawkWindow.h | 17 +++++ 2 files changed, 130 insertions(+), 41 deletions(-) diff --git a/src/TomahawkWindow.cpp b/src/TomahawkWindow.cpp index 925fb68c9..eb5d2a9e3 100644 --- a/src/TomahawkWindow.cpp +++ b/src/TomahawkWindow.cpp @@ -73,7 +73,6 @@ #ifdef Q_OS_WIN #include - #include #ifndef THBN_CLICKED #define THBN_CLICKED 0x1800 #endif @@ -89,6 +88,7 @@ TomahawkWindow::TomahawkWindow( QWidget* parent ) : QMainWindow( parent ) #ifdef Q_OS_WIN , m_buttonCreatedID( RegisterWindowMessage( L"TaskbarButtonCreated" ) ) + , m_taskbarList(0) #endif , ui( new Ui::TomahawkWindow ) , m_searchWidget( 0 ) @@ -103,6 +103,9 @@ TomahawkWindow::TomahawkWindow( QWidget* parent ) connect( vm, SIGNAL( hideQueueRequested() ), SLOT( hideQueue() ) ); connect( APP, SIGNAL( tomahawkLoaded() ), vm, SLOT( setTomahawkLoaded() ) ); // Pass loaded signal into libtomahawk so components in there can connect to ViewManager +#ifdef Q_OS_WIN + connect(AudioEngine::instance(),SIGNAL(stateChanged(AudioState,AudioState)),this,SLOT(audioStateChanged(AudioState,AudioState))); +#endif ui->setupUi( this ); ui->menuApp->insertAction( ui->actionCreatePlaylist, ActionCollection::instance()->getAction( "togglePrivacy" ) ); @@ -337,7 +340,6 @@ TomahawkWindow::setupWindowsButtons() HRESULT hr = S_OK; QPixmap play( RESPATH "images/play-rest.png" ); - QPixmap pause( RESPATH "images/pause-rest.png" ); QPixmap back( RESPATH "images/back-rest.png" ); QPixmap love( RESPATH "images/not-loved.png" ); @@ -345,43 +347,50 @@ TomahawkWindow::setupWindowsButtons() transform.rotate( 180 ); QPixmap next( back.transformed( transform ) ); - THUMBBUTTON thumbButtons[5]; + THUMBBUTTONMASK dwMask = THUMBBUTTONMASK( THB_ICON | THB_TOOLTIP | THB_FLAGS ); + m_thumbButtons[0].dwMask = dwMask; + m_thumbButtons[0].iId = PREVIOUS; + m_thumbButtons[0].hIcon = back.toWinHICON(); + m_thumbButtons[0].dwFlags = THBF_ENABLED; + m_thumbButtons[0].szTip[ tr( "Back" ).toWCharArray( m_thumbButtons[0].szTip ) ] = 0; - THUMBBUTTONMASK dwMask = THUMBBUTTONMASK( THB_ICON | THB_TOOLTIP ); - thumbButtons[0].dwMask = dwMask; - thumbButtons[0].iId = 1; - thumbButtons[0].hIcon = back.toWinHICON(); - thumbButtons[0].szTip[ tr( "Back" ).toWCharArray( thumbButtons[0].szTip ) ] = 0; + m_thumbButtons[1].dwMask = dwMask; + m_thumbButtons[1].iId = PLAY_PAUSE; + m_thumbButtons[1].hIcon = play.toWinHICON(); + m_thumbButtons[1].dwFlags = THBF_ENABLED; + m_thumbButtons[1].szTip[ tr( "Play" ).toWCharArray( m_thumbButtons[1].szTip ) ] = 0; - thumbButtons[1].dwMask = dwMask; - thumbButtons[1].iId = 2; - thumbButtons[1].hIcon = pause.toWinHICON(); - thumbButtons[1].szTip[ tr( "Pause" ).toWCharArray( thumbButtons[1].szTip ) ] = 0; - thumbButtons[2].dwMask = dwMask; - thumbButtons[2].iId = 3; - thumbButtons[2].hIcon = play.toWinHICON(); - thumbButtons[2].szTip[ tr( "Play" ).toWCharArray( thumbButtons[2].szTip ) ] = 0; + m_thumbButtons[2].dwMask = dwMask; + m_thumbButtons[2].iId = NEXT; + m_thumbButtons[2].hIcon = next.toWinHICON(); + m_thumbButtons[2].dwFlags = THBF_ENABLED; + m_thumbButtons[2].szTip[ tr( "Next" ).toWCharArray( m_thumbButtons[2].szTip ) ] = 0; - thumbButtons[3].dwMask = dwMask; - thumbButtons[3].iId = 4; - thumbButtons[3].hIcon = next.toWinHICON(); - thumbButtons[3].szTip[ tr( "Next" ).toWCharArray( thumbButtons[3].szTip ) ] = 0; + m_thumbButtons[3].dwMask = dwMask; + m_thumbButtons[3].iId = -1; + m_thumbButtons[3].hIcon = 0; + m_thumbButtons[3].dwFlags = THBF_NOBACKGROUND | THBF_DISABLED; + m_thumbButtons[3].szTip[0] = 0; - thumbButtons[4].dwMask = dwMask; - thumbButtons[4].iId = 5; - thumbButtons[4].hIcon = love.toWinHICON(); - thumbButtons[4].szTip[ tr( "Love" ).toWCharArray( thumbButtons[4].szTip ) ] = 0; + m_thumbButtons[4].dwMask = dwMask; + m_thumbButtons[4].iId = LOVE; + m_thumbButtons[4].hIcon = love.toWinHICON(); + m_thumbButtons[4].dwFlags = THBF_DISABLED; + m_thumbButtons[4].szTip[ tr( "Love" ).toWCharArray( m_thumbButtons[4].szTip ) ] = 0; - ITaskbarList3 *taskbarList; - if ( S_OK == CoCreateInstance( CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, IID_ITaskbarList3, (void **)&taskbarList ) ) + if ( S_OK == CoCreateInstance( CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, IID_ITaskbarList3, (void **)&m_taskbarList ) ) { - taskbarList->HrInit(); + hr = m_taskbarList->HrInit(); if ( SUCCEEDED( hr ) ) { - hr = taskbarList->ThumbBarAddButtons( winId(), ARRAYSIZE( thumbButtons ), thumbButtons ); + hr = m_taskbarList->ThumbBarAddButtons( winId(), ARRAYSIZE( m_thumbButtons ), m_thumbButtons ); + } + else + { + m_taskbarList->Release(); + m_taskbarList = 0; } - taskbarList->Release(); } return SUCCEEDED( hr ); @@ -571,29 +580,39 @@ TomahawkWindow::winEvent( MSG* msg, long* result ) case WM_COMMAND: if ( HIWORD( msg->wParam ) == THBN_CLICKED ) { - switch( LOWORD( msg->wParam ) ) + switch( TB_STATES(LOWORD( msg->wParam )) ) { - case 1: + case PREVIOUS: tLog() << TB_PRESSED << "Previous"; AudioEngine::instance()->previous(); break; - case 2: - tLog() << TB_PRESSED << "Pause"; - AudioEngine::instance()->pause(); + case PLAY_PAUSE: + tLog() << TB_PRESSED << "Play/Pause"; + AudioEngine::instance()->playPause(); break; - case 3: - tLog() << TB_PRESSED << "Play"; - AudioEngine::instance()->play(); - break; - case 4: + case NEXT: tLog() << TB_PRESSED << "Next"; AudioEngine::instance()->next(); break; - case 5: + case LOVE: tLog() << TB_PRESSED << "Love"; if ( !AudioEngine::instance()->currentTrack().isNull() ) { - AudioEngine::instance()->currentTrack()->toQuery()->setLoved( true ); + AudioEngine::instance()->currentTrack()->toQuery()->setLoved( !AudioEngine::instance()->currentTrack()->toQuery()->loved() ); + if ( AudioEngine::instance()->currentTrack()->toQuery()->loved()) + { + QPixmap loved( RESPATH "images/loved.png" ); + m_thumbButtons[4].hIcon = loved.toWinHICON(); + m_thumbButtons[4].szTip[ tr( "Unlove" ).toWCharArray( m_thumbButtons[4].szTip ) ] = 0; + + } + else + { + QPixmap not_loved( RESPATH "images/not-loved.png" ); + m_thumbButtons[4].hIcon = not_loved.toWinHICON(); + m_thumbButtons[4].szTip[ tr( "Love" ).toWCharArray( m_thumbButtons[4].szTip ) ] = 0; + } + m_taskbarList->ThumbBarUpdateButtons( winId(), ARRAYSIZE( m_thumbButtons ), m_thumbButtons ); } break; } @@ -607,9 +626,62 @@ TomahawkWindow::winEvent( MSG* msg, long* result ) return false; } + +void TomahawkWindow::audioStateChanged( AudioState newState, AudioState oldState ) +{ + if(m_taskbarList == 0) + return; + switch(newState){ + case AudioEngine::Playing: + { + QPixmap pause( RESPATH "images/pause-rest.png" ); + m_thumbButtons[1].hIcon = pause.toWinHICON(); + m_thumbButtons[1].szTip[ tr( "Pause" ).toWCharArray( m_thumbButtons[1].szTip ) ] = 0; + + if ( !AudioEngine::instance()->currentTrack().isNull() && AudioEngine::instance()->currentTrack()->toQuery()->loved()) + { + QPixmap loved( RESPATH "images/loved.png" ); + m_thumbButtons[4].hIcon = loved.toWinHICON(); + m_thumbButtons[4].szTip[ tr( "Unlove" ).toWCharArray( m_thumbButtons[4].szTip ) ] = 0; + + } + else + { + QPixmap not_loved( RESPATH "images/not-loved.png" ); + m_thumbButtons[4].hIcon = not_loved.toWinHICON(); + m_thumbButtons[4].szTip[ tr( "Love" ).toWCharArray( m_thumbButtons[4].szTip ) ] = 0; + } + m_thumbButtons[4].dwFlags = THBF_ENABLED; + } + break; + case AudioEngine::Paused: + { + QPixmap play( RESPATH "images/play-rest.png" ); + m_thumbButtons[1].hIcon = play.toWinHICON(); + m_thumbButtons[1].szTip[ tr( "Play" ).toWCharArray( m_thumbButtons[1].szTip ) ] = 0; + } + break; + case AudioEngine::Stopped: + { + QPixmap play( RESPATH "images/play-rest.png" ); + m_thumbButtons[1].hIcon = play.toWinHICON(); + m_thumbButtons[1].szTip[ tr( "Play" ).toWCharArray( m_thumbButtons[1].szTip ) ] = 0; + + QPixmap not_loved( RESPATH "images/not-loved.png" ); + m_thumbButtons[4].hIcon = not_loved.toWinHICON(); + m_thumbButtons[4].dwFlags = THBF_DISABLED; + } + break; + default: + return; + } + m_taskbarList->ThumbBarUpdateButtons( winId(), ARRAYSIZE( m_thumbButtons ), m_thumbButtons ); +} + #endif + void TomahawkWindow::onHistoryBackAvailable( bool avail ) { diff --git a/src/TomahawkWindow.h b/src/TomahawkWindow.h index 715b652f0..71925bb76 100644 --- a/src/TomahawkWindow.h +++ b/src/TomahawkWindow.h @@ -31,6 +31,10 @@ #include "audio/AudioEngine.h" #include "utils/XspfLoader.h" +#ifdef Q_OS_WIN +#include +#endif + namespace Tomahawk { namespace Accounts @@ -138,6 +142,10 @@ private slots: void crashNow(); +#ifdef Q_OS_WIN + void audioStateChanged( AudioState newState, AudioState oldState ); +#endif + private: void loadSettings(); void saveSettings(); @@ -151,6 +159,15 @@ private: #ifdef Q_OS_WIN bool setupWindowsButtons(); const unsigned int m_buttonCreatedID; + ITaskbarList3 *m_taskbarList; + THUMBBUTTON m_thumbButtons[5]; + enum TB_STATES{ + PREVIOUS, + PLAY_PAUSE, + NEXT, + LOVE + }; + #endif Ui::TomahawkWindow* ui; From 375ae62f6428825f933ac962678ebdb18b6f0984 Mon Sep 17 00:00:00 2001 From: Patrick von Reth Date: Sun, 8 Jul 2012 16:53:19 +0200 Subject: [PATCH 02/28] make code more readable --- src/TomahawkWindow.cpp | 82 +++++++++++++++++++++--------------------- src/TomahawkWindow.h | 8 +---- 2 files changed, 42 insertions(+), 48 deletions(-) diff --git a/src/TomahawkWindow.cpp b/src/TomahawkWindow.cpp index eb5d2a9e3..796f4964b 100644 --- a/src/TomahawkWindow.cpp +++ b/src/TomahawkWindow.cpp @@ -348,24 +348,24 @@ TomahawkWindow::setupWindowsButtons() QPixmap next( back.transformed( transform ) ); THUMBBUTTONMASK dwMask = THUMBBUTTONMASK( THB_ICON | THB_TOOLTIP | THB_FLAGS ); - m_thumbButtons[0].dwMask = dwMask; - m_thumbButtons[0].iId = PREVIOUS; - m_thumbButtons[0].hIcon = back.toWinHICON(); - m_thumbButtons[0].dwFlags = THBF_ENABLED; - m_thumbButtons[0].szTip[ tr( "Back" ).toWCharArray( m_thumbButtons[0].szTip ) ] = 0; + m_thumbButtons[TP_PREVIOUS].dwMask = dwMask; + m_thumbButtons[TP_PREVIOUS].iId = TP_PREVIOUS; + m_thumbButtons[TP_PREVIOUS].hIcon = back.toWinHICON(); + m_thumbButtons[TP_PREVIOUS].dwFlags = THBF_ENABLED; + m_thumbButtons[TP_PREVIOUS].szTip[ tr( "Back" ).toWCharArray( m_thumbButtons[TP_PREVIOUS].szTip ) ] = 0; - m_thumbButtons[1].dwMask = dwMask; - m_thumbButtons[1].iId = PLAY_PAUSE; - m_thumbButtons[1].hIcon = play.toWinHICON(); - m_thumbButtons[1].dwFlags = THBF_ENABLED; - m_thumbButtons[1].szTip[ tr( "Play" ).toWCharArray( m_thumbButtons[1].szTip ) ] = 0; + m_thumbButtons[TP_PLAY_PAUSE].dwMask = dwMask; + m_thumbButtons[TP_PLAY_PAUSE].iId = TP_PLAY_PAUSE; + m_thumbButtons[TP_PLAY_PAUSE].hIcon = play.toWinHICON(); + m_thumbButtons[TP_PLAY_PAUSE].dwFlags = THBF_ENABLED; + m_thumbButtons[TP_PLAY_PAUSE].szTip[ tr( "Play" ).toWCharArray( m_thumbButtons[TP_PLAY_PAUSE].szTip ) ] = 0; - m_thumbButtons[2].dwMask = dwMask; - m_thumbButtons[2].iId = NEXT; - m_thumbButtons[2].hIcon = next.toWinHICON(); - m_thumbButtons[2].dwFlags = THBF_ENABLED; - m_thumbButtons[2].szTip[ tr( "Next" ).toWCharArray( m_thumbButtons[2].szTip ) ] = 0; + m_thumbButtons[TP_NEXT].dwMask = dwMask; + m_thumbButtons[TP_NEXT].iId = TP_NEXT; + m_thumbButtons[TP_NEXT].hIcon = next.toWinHICON(); + m_thumbButtons[TP_NEXT].dwFlags = THBF_ENABLED; + m_thumbButtons[TP_NEXT].szTip[ tr( "Next" ).toWCharArray( m_thumbButtons[TP_NEXT].szTip ) ] = 0; m_thumbButtons[3].dwMask = dwMask; m_thumbButtons[3].iId = -1; @@ -373,11 +373,11 @@ TomahawkWindow::setupWindowsButtons() m_thumbButtons[3].dwFlags = THBF_NOBACKGROUND | THBF_DISABLED; m_thumbButtons[3].szTip[0] = 0; - m_thumbButtons[4].dwMask = dwMask; - m_thumbButtons[4].iId = LOVE; - m_thumbButtons[4].hIcon = love.toWinHICON(); - m_thumbButtons[4].dwFlags = THBF_DISABLED; - m_thumbButtons[4].szTip[ tr( "Love" ).toWCharArray( m_thumbButtons[4].szTip ) ] = 0; + m_thumbButtons[TP_LOVE].dwMask = dwMask; + m_thumbButtons[TP_LOVE].iId = TP_LOVE; + m_thumbButtons[TP_LOVE].hIcon = love.toWinHICON(); + m_thumbButtons[TP_LOVE].dwFlags = THBF_DISABLED; + m_thumbButtons[TP_LOVE].szTip[ tr( "Love" ).toWCharArray( m_thumbButtons[TP_LOVE].szTip ) ] = 0; if ( S_OK == CoCreateInstance( CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, IID_ITaskbarList3, (void **)&m_taskbarList ) ) { @@ -582,19 +582,19 @@ TomahawkWindow::winEvent( MSG* msg, long* result ) { switch( TB_STATES(LOWORD( msg->wParam )) ) { - case PREVIOUS: + case TP_PREVIOUS: tLog() << TB_PRESSED << "Previous"; AudioEngine::instance()->previous(); break; - case PLAY_PAUSE: + case TP_PLAY_PAUSE: tLog() << TB_PRESSED << "Play/Pause"; AudioEngine::instance()->playPause(); break; - case NEXT: + case TP_NEXT: tLog() << TB_PRESSED << "Next"; AudioEngine::instance()->next(); break; - case LOVE: + case TP_LOVE: tLog() << TB_PRESSED << "Love"; if ( !AudioEngine::instance()->currentTrack().isNull() ) { @@ -602,15 +602,15 @@ TomahawkWindow::winEvent( MSG* msg, long* result ) if ( AudioEngine::instance()->currentTrack()->toQuery()->loved()) { QPixmap loved( RESPATH "images/loved.png" ); - m_thumbButtons[4].hIcon = loved.toWinHICON(); - m_thumbButtons[4].szTip[ tr( "Unlove" ).toWCharArray( m_thumbButtons[4].szTip ) ] = 0; + m_thumbButtons[TP_LOVE].hIcon = loved.toWinHICON(); + m_thumbButtons[TP_LOVE].szTip[ tr( "Unlove" ).toWCharArray( m_thumbButtons[TP_LOVE].szTip ) ] = 0; } else { QPixmap not_loved( RESPATH "images/not-loved.png" ); - m_thumbButtons[4].hIcon = not_loved.toWinHICON(); - m_thumbButtons[4].szTip[ tr( "Love" ).toWCharArray( m_thumbButtons[4].szTip ) ] = 0; + m_thumbButtons[TP_LOVE].hIcon = not_loved.toWinHICON(); + m_thumbButtons[TP_LOVE].szTip[ tr( "Love" ).toWCharArray( m_thumbButtons[TP_LOVE].szTip ) ] = 0; } m_taskbarList->ThumbBarUpdateButtons( winId(), ARRAYSIZE( m_thumbButtons ), m_thumbButtons ); } @@ -635,41 +635,41 @@ void TomahawkWindow::audioStateChanged( AudioState newState, AudioState oldState case AudioEngine::Playing: { QPixmap pause( RESPATH "images/pause-rest.png" ); - m_thumbButtons[1].hIcon = pause.toWinHICON(); - m_thumbButtons[1].szTip[ tr( "Pause" ).toWCharArray( m_thumbButtons[1].szTip ) ] = 0; + m_thumbButtons[TP_PLAY_PAUSE].hIcon = pause.toWinHICON(); + m_thumbButtons[TP_PLAY_PAUSE].szTip[ tr( "Pause" ).toWCharArray( m_thumbButtons[TP_PLAY_PAUSE].szTip ) ] = 0; if ( !AudioEngine::instance()->currentTrack().isNull() && AudioEngine::instance()->currentTrack()->toQuery()->loved()) { QPixmap loved( RESPATH "images/loved.png" ); - m_thumbButtons[4].hIcon = loved.toWinHICON(); - m_thumbButtons[4].szTip[ tr( "Unlove" ).toWCharArray( m_thumbButtons[4].szTip ) ] = 0; + m_thumbButtons[TP_LOVE].hIcon = loved.toWinHICON(); + m_thumbButtons[TP_LOVE].szTip[ tr( "Unlove" ).toWCharArray( m_thumbButtons[TP_LOVE].szTip ) ] = 0; } else { QPixmap not_loved( RESPATH "images/not-loved.png" ); - m_thumbButtons[4].hIcon = not_loved.toWinHICON(); - m_thumbButtons[4].szTip[ tr( "Love" ).toWCharArray( m_thumbButtons[4].szTip ) ] = 0; + m_thumbButtons[TP_LOVE].hIcon = not_loved.toWinHICON(); + m_thumbButtons[TP_LOVE].szTip[ tr( "Love" ).toWCharArray( m_thumbButtons[TP_LOVE].szTip ) ] = 0; } - m_thumbButtons[4].dwFlags = THBF_ENABLED; + m_thumbButtons[TP_LOVE].dwFlags = THBF_ENABLED; } break; case AudioEngine::Paused: { QPixmap play( RESPATH "images/play-rest.png" ); - m_thumbButtons[1].hIcon = play.toWinHICON(); - m_thumbButtons[1].szTip[ tr( "Play" ).toWCharArray( m_thumbButtons[1].szTip ) ] = 0; + m_thumbButtons[TP_PLAY_PAUSE].hIcon = play.toWinHICON(); + m_thumbButtons[TP_PLAY_PAUSE].szTip[ tr( "Play" ).toWCharArray( m_thumbButtons[TP_PLAY_PAUSE].szTip ) ] = 0; } break; case AudioEngine::Stopped: { QPixmap play( RESPATH "images/play-rest.png" ); - m_thumbButtons[1].hIcon = play.toWinHICON(); - m_thumbButtons[1].szTip[ tr( "Play" ).toWCharArray( m_thumbButtons[1].szTip ) ] = 0; + m_thumbButtons[TP_PLAY_PAUSE].hIcon = play.toWinHICON(); + m_thumbButtons[TP_PLAY_PAUSE].szTip[ tr( "Play" ).toWCharArray( m_thumbButtons[TP_PLAY_PAUSE].szTip ) ] = 0; QPixmap not_loved( RESPATH "images/not-loved.png" ); - m_thumbButtons[4].hIcon = not_loved.toWinHICON(); - m_thumbButtons[4].dwFlags = THBF_DISABLED; + m_thumbButtons[TP_LOVE].hIcon = not_loved.toWinHICON(); + m_thumbButtons[TP_LOVE].dwFlags = THBF_DISABLED; } break; default: diff --git a/src/TomahawkWindow.h b/src/TomahawkWindow.h index 71925bb76..0e9b318f5 100644 --- a/src/TomahawkWindow.h +++ b/src/TomahawkWindow.h @@ -161,13 +161,7 @@ private: const unsigned int m_buttonCreatedID; ITaskbarList3 *m_taskbarList; THUMBBUTTON m_thumbButtons[5]; - enum TB_STATES{ - PREVIOUS, - PLAY_PAUSE, - NEXT, - LOVE - }; - + enum TB_STATES{ TP_PREVIOUS = 0,TP_PLAY_PAUSE = 1,TP_NEXT = 2,TP_LOVE = 4 }; #endif Ui::TomahawkWindow* ui; From c7002a136438654009c658c38760d207ef404474 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Mon, 9 Jul 2012 18:48:25 -0400 Subject: [PATCH 03/28] Properly threadify databaseworker, untested as of yet --- src/libtomahawk/database/Database.cpp | 41 +++++++++++++------ src/libtomahawk/database/Database.h | 5 ++- src/libtomahawk/database/DatabaseWorker.cpp | 44 ++++++++++++++------- src/libtomahawk/database/DatabaseWorker.h | 26 +++++++++--- 4 files changed, 83 insertions(+), 33 deletions(-) diff --git a/src/libtomahawk/database/Database.cpp b/src/libtomahawk/database/Database.cpp index dff1e06fa..1e735df48 100644 --- a/src/libtomahawk/database/Database.cpp +++ b/src/libtomahawk/database/Database.cpp @@ -42,7 +42,7 @@ Database::Database( const QString& dbname, QObject* parent ) : QObject( parent ) , m_ready( false ) , m_impl( new DatabaseImpl( dbname ) ) - , m_workerRW( new DatabaseWorker( this, true ) ) + , m_workerRW( new DatabaseWorkerThread( this, true ) ) { s_instance = this; @@ -65,8 +65,23 @@ Database::~Database() { qDebug() << Q_FUNC_INFO; - qDeleteAll( m_workers ); + m_workerRW->quit(); + foreach ( DatabaseWorkerThread *thread, m_workers ) + { + if ( thread->worker() ) + thread->quit(); + } + + m_workerRW->wait( 60000 ); delete m_workerRW; + m_workerRW = 0; + foreach ( DatabaseWorkerThread *thread, m_workers ) + { + thread->wait( 60000 ); + delete thread; + } + m_workers.clear(); + qDeleteAll( m_implHash.values() ); delete m_impl; } @@ -84,7 +99,8 @@ Database::enqueue( const QList< QSharedPointer >& lc ) { Q_ASSERT( m_ready ); qDebug() << "Enqueueing" << lc.count() << "commands to rw thread"; - m_workerRW->enqueue( lc ); + if ( m_workerRW->worker() ) + m_workerRW->worker().data()->enqueue( lc ); } @@ -95,7 +111,8 @@ Database::enqueue( const QSharedPointer& lc ) if ( lc->doesMutates() ) { qDebug() << "Enqueueing command to rw thread:" << lc->commandname(); - m_workerRW->enqueue( lc ); + if ( m_workerRW->worker() ) + m_workerRW->worker().data()->enqueue( lc ); } else { @@ -103,7 +120,7 @@ Database::enqueue( const QSharedPointer& lc ) // create new thread if < WORKER_THREADS if ( m_workers.count() < m_maxConcurrentThreads ) { - DatabaseWorker* worker = new DatabaseWorker( this, false ); + DatabaseWorkerThread* worker = new DatabaseWorkerThread( this, false ); worker->start(); m_workers << worker; @@ -111,24 +128,24 @@ Database::enqueue( const QSharedPointer& lc ) // find thread for commandname with lowest amount of outstanding jobs and enqueue job int busyThreads = 0; - DatabaseWorker* happyThread = 0; + QWeakPointer< DatabaseWorker > happyWorker; for ( int i = 0; i < m_workers.count(); i++ ) { - DatabaseWorker* worker = m_workers.at( i ); + DatabaseWorkerThread* workerThread = m_workers.at( i ); - if ( !worker->busy() ) + if ( workerThread->worker() && !workerThread->worker().data()->busy() ) { - happyThread = worker; + happyWorker = workerThread->worker(); break; } busyThreads++; - if ( !happyThread || worker->outstandingJobs() < happyThread->outstandingJobs() ) - happyThread = worker; + if ( !happyWorker || ( workerThread->worker() && workerThread->worker().data()->outstandingJobs() < happyWorker.data()->outstandingJobs() ) ) + happyWorker = workerThread->worker(); } // qDebug() << "Enqueueing command to thread:" << happyThread << busyThreads << lc->commandname(); - happyThread->enqueue( lc ); + happyWorker.data()->enqueue( lc ); } } diff --git a/src/libtomahawk/database/Database.h b/src/libtomahawk/database/Database.h index 98b81441f..ae44ae9c2 100644 --- a/src/libtomahawk/database/Database.h +++ b/src/libtomahawk/database/Database.h @@ -30,6 +30,7 @@ #include "DllMacro.h" class DatabaseImpl; +class DatabaseWorkerThread; class DatabaseWorker; /* @@ -75,8 +76,8 @@ private: bool m_ready; DatabaseImpl* m_impl; - DatabaseWorker* m_workerRW; - QList m_workers; + DatabaseWorkerThread* m_workerRW; + QList< DatabaseWorkerThread* > m_workers; int m_maxConcurrentThreads; QHash< QThread*, DatabaseImpl* > m_implHash; diff --git a/src/libtomahawk/database/DatabaseWorker.cpp b/src/libtomahawk/database/DatabaseWorker.cpp index 9711c62dd..ebad6cc1f 100644 --- a/src/libtomahawk/database/DatabaseWorker.cpp +++ b/src/libtomahawk/database/DatabaseWorker.cpp @@ -34,17 +34,42 @@ //#define DEBUG_TIMING TRUE #endif -DatabaseWorker::DatabaseWorker( Database* db, bool mutates ) + +DatabaseWorkerThread::DatabaseWorkerThread( Database* db, bool mutates ) : QThread() , m_db( db ) + , m_mutates( mutates ) +{ + Q_UNUSED( db ); + Q_UNUSED( mutates ); +} + + +void +DatabaseWorkerThread::run() +{ + m_worker = QWeakPointer< DatabaseWorker >( new DatabaseWorker( m_db, m_mutates ) ); + exec(); + tDebug() << Q_FUNC_INFO << "DatabaseWorker finishing..."; + if ( m_worker ) + delete m_worker.data(); +} + + +DatabaseWorkerThread::~DatabaseWorkerThread() +{ +} + + + +DatabaseWorker::DatabaseWorker( Database* db, bool mutates ) + : QObject() + , m_db( db ) , m_outstanding( 0 ) { Q_UNUSED( db ); Q_UNUSED( mutates ); - - moveToThread( this ); - - qDebug() << "CTOR DatabaseWorker" << this->thread(); + tDebug() << Q_FUNC_INFO << "New db connection with name:" << Database::instance()->impl()->database().connectionName() << "on thread" << this->thread(); } @@ -65,15 +90,6 @@ DatabaseWorker::~DatabaseWorker() } -void -DatabaseWorker::run() -{ - tDebug() << "New db connection with name:" << Database::instance()->impl()->database().connectionName(); - exec(); - qDebug() << Q_FUNC_INFO << "DatabaseWorker finishing..."; -} - - void DatabaseWorker::enqueue( const QList< QSharedPointer >& cmds ) { diff --git a/src/libtomahawk/database/DatabaseWorker.h b/src/libtomahawk/database/DatabaseWorker.h index 90c7d5d12..3c60500c1 100644 --- a/src/libtomahawk/database/DatabaseWorker.h +++ b/src/libtomahawk/database/DatabaseWorker.h @@ -34,12 +34,12 @@ class Database; class DatabaseCommandLoggable; -class DatabaseWorker : public QThread +class DatabaseWorker : public QObject { Q_OBJECT public: - DatabaseWorker( Database*, bool mutates ); + DatabaseWorker( Database* db, bool mutates ); ~DatabaseWorker(); bool busy() const { return m_outstanding > 0; } @@ -49,9 +49,6 @@ public slots: void enqueue( const QSharedPointer& ); void enqueue( const QList< QSharedPointer >& ); -protected: - void run(); - private slots: void doWork(); @@ -66,4 +63,23 @@ private: QJson::Serializer m_serializer; }; +class DatabaseWorkerThread : public QThread +{ +Q_OBJECT + +public: + DatabaseWorkerThread( Database* db, bool mutates ); + ~DatabaseWorkerThread(); + + QWeakPointer< DatabaseWorker > worker() { return m_worker; } + +protected: + void run(); + +private: + QWeakPointer< DatabaseWorker > m_worker; + Database* m_db; + bool m_mutates; +}; + #endif // DATABASEWORKER_H From f7ffead6c2d40b02cd1d69c9046d0ba2a2886fc4 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Tue, 10 Jul 2012 07:02:17 -0400 Subject: [PATCH 04/28] More work --- src/libtomahawk/database/Database.cpp | 23 +++++++++++++-------- src/libtomahawk/database/Database.h | 2 +- src/libtomahawk/database/DatabaseWorker.cpp | 17 ++++++++------- src/libtomahawk/database/DatabaseWorker.h | 2 +- 4 files changed, 26 insertions(+), 18 deletions(-) diff --git a/src/libtomahawk/database/Database.cpp b/src/libtomahawk/database/Database.cpp index 1e735df48..5405a26b8 100644 --- a/src/libtomahawk/database/Database.cpp +++ b/src/libtomahawk/database/Database.cpp @@ -66,7 +66,7 @@ Database::~Database() qDebug() << Q_FUNC_INFO; m_workerRW->quit(); - foreach ( DatabaseWorkerThread *thread, m_workers ) + foreach ( DatabaseWorkerThread *thread, m_workerThreads ) { if ( thread->worker() ) thread->quit(); @@ -75,12 +75,12 @@ Database::~Database() m_workerRW->wait( 60000 ); delete m_workerRW; m_workerRW = 0; - foreach ( DatabaseWorkerThread *thread, m_workers ) + foreach ( DatabaseWorkerThread *thread, m_workerThreads ) { thread->wait( 60000 ); delete thread; } - m_workers.clear(); + m_workerThreads.clear(); qDeleteAll( m_implHash.values() ); delete m_impl; @@ -118,21 +118,24 @@ Database::enqueue( const QSharedPointer& lc ) { // find existing amount of worker threads for commandname // create new thread if < WORKER_THREADS - if ( m_workers.count() < m_maxConcurrentThreads ) + if ( m_workerThreads.count() < m_maxConcurrentThreads ) { - DatabaseWorkerThread* worker = new DatabaseWorkerThread( this, false ); - worker->start(); + DatabaseWorkerThread* workerThread = new DatabaseWorkerThread( this, false ); + tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "P1" << ( workerThread->worker() ? "true" : "false" ); + workerThread->start(); + tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "P2" << ( workerThread->worker() ? "true" : "false" ); - m_workers << worker; + m_workerThreads << workerThread; } // find thread for commandname with lowest amount of outstanding jobs and enqueue job int busyThreads = 0; QWeakPointer< DatabaseWorker > happyWorker; - for ( int i = 0; i < m_workers.count(); i++ ) + for ( int i = 0; i < m_workerThreads.count(); i++ ) { - DatabaseWorkerThread* workerThread = m_workers.at( i ); + DatabaseWorkerThread* workerThread = m_workerThreads.at( i ); + tDebug( LOGVERBOSE ) << Q_FUNC_INFO << i << ( workerThread->worker() ? "true" : "false" ); if ( workerThread->worker() && !workerThread->worker().data()->busy() ) { happyWorker = workerThread->worker(); @@ -145,6 +148,8 @@ Database::enqueue( const QSharedPointer& lc ) } // qDebug() << "Enqueueing command to thread:" << happyThread << busyThreads << lc->commandname(); + tDebug( LOGVERBOSE ) << Q_FUNC_INFO << m_workerThreads.count() << m_maxConcurrentThreads; + Q_ASSERT( happyWorker ); happyWorker.data()->enqueue( lc ); } } diff --git a/src/libtomahawk/database/Database.h b/src/libtomahawk/database/Database.h index ae44ae9c2..6eaf78578 100644 --- a/src/libtomahawk/database/Database.h +++ b/src/libtomahawk/database/Database.h @@ -77,7 +77,7 @@ private: DatabaseImpl* m_impl; DatabaseWorkerThread* m_workerRW; - QList< DatabaseWorkerThread* > m_workers; + QList< DatabaseWorkerThread* > m_workerThreads; int m_maxConcurrentThreads; QHash< QThread*, DatabaseImpl* > m_implHash; diff --git a/src/libtomahawk/database/DatabaseWorker.cpp b/src/libtomahawk/database/DatabaseWorker.cpp index ebad6cc1f..e9577eac8 100644 --- a/src/libtomahawk/database/DatabaseWorker.cpp +++ b/src/libtomahawk/database/DatabaseWorker.cpp @@ -40,17 +40,17 @@ DatabaseWorkerThread::DatabaseWorkerThread( Database* db, bool mutates ) , m_db( db ) , m_mutates( mutates ) { - Q_UNUSED( db ); - Q_UNUSED( mutates ); } void DatabaseWorkerThread::run() { + tDebug() << Q_FUNC_INFO << "DatabaseWorkerThread starting..."; m_worker = QWeakPointer< DatabaseWorker >( new DatabaseWorker( m_db, m_mutates ) ); + tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "P5" << ( m_worker ? "true" : "false" ); exec(); - tDebug() << Q_FUNC_INFO << "DatabaseWorker finishing..."; + tDebug() << Q_FUNC_INFO << "DatabaseWorkerThread finishing..."; if ( m_worker ) delete m_worker.data(); } @@ -61,13 +61,19 @@ DatabaseWorkerThread::~DatabaseWorkerThread() } +QWeakPointer< DatabaseWorker > +DatabaseWorkerThread::worker() const +{ + tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "P4" << ( m_worker ? "true" : "false" ); + return m_worker; +} + DatabaseWorker::DatabaseWorker( Database* db, bool mutates ) : QObject() , m_db( db ) , m_outstanding( 0 ) { - Q_UNUSED( db ); Q_UNUSED( mutates ); tDebug() << Q_FUNC_INFO << "New db connection with name:" << Database::instance()->impl()->database().connectionName() << "on thread" << this->thread(); } @@ -84,9 +90,6 @@ DatabaseWorker::~DatabaseWorker() tDebug() << "Outstanding db command to finish:" << cmd->guid() << cmd->commandname(); } } - - thread()->quit(); - wait(); } diff --git a/src/libtomahawk/database/DatabaseWorker.h b/src/libtomahawk/database/DatabaseWorker.h index 3c60500c1..cccfddf58 100644 --- a/src/libtomahawk/database/DatabaseWorker.h +++ b/src/libtomahawk/database/DatabaseWorker.h @@ -71,7 +71,7 @@ public: DatabaseWorkerThread( Database* db, bool mutates ); ~DatabaseWorkerThread(); - QWeakPointer< DatabaseWorker > worker() { return m_worker; } + QWeakPointer< DatabaseWorker > worker() const; protected: void run(); From c7e4fc777f563a5a10dc13b01237ce45b0153efb Mon Sep 17 00:00:00 2001 From: Tomahawk CI Date: Tue, 10 Jul 2012 22:19:56 +0000 Subject: [PATCH 05/28] Automatic merge of Transifex translations --- lang/tomahawk_ar.ts | 10 +++++----- lang/tomahawk_bg.ts | 10 +++++----- lang/tomahawk_ca.ts | 10 +++++----- lang/tomahawk_de.ts | 10 +++++----- lang/tomahawk_en.ts | 10 +++++----- lang/tomahawk_es.ts | 10 +++++----- lang/tomahawk_fr.ts | 10 +++++----- lang/tomahawk_ja.ts | 10 +++++----- lang/tomahawk_pl.ts | 10 +++++----- lang/tomahawk_pt_BR.ts | 10 +++++----- lang/tomahawk_ru.ts | 10 +++++----- lang/tomahawk_sv.ts | 10 +++++----- lang/tomahawk_tr.ts | 10 +++++----- lang/tomahawk_zh_CN.ts | 10 +++++----- lang/tomahawk_zh_TW.ts | 10 +++++----- 15 files changed, 75 insertions(+), 75 deletions(-) diff --git a/lang/tomahawk_ar.ts b/lang/tomahawk_ar.ts index eac0feeed..3478231bf 100644 --- a/lang/tomahawk_ar.ts +++ b/lang/tomahawk_ar.ts @@ -1953,23 +1953,23 @@ connect and stream from you? جاري تسجيل الدخول... - + Failed: %1 فشل: %1 - + Logged in as %1 - + Log Out - - + + Log In تسجيل الدخول diff --git a/lang/tomahawk_bg.ts b/lang/tomahawk_bg.ts index a27878c4c..e1aa89d77 100644 --- a/lang/tomahawk_bg.ts +++ b/lang/tomahawk_bg.ts @@ -1959,23 +1959,23 @@ Tomahaw създаде доклад относно това и изпращай Влизам... - + Failed: %1 Неуспех: %1 - + Logged in as %1 - + Log Out - - + + Log In Влез diff --git a/lang/tomahawk_ca.ts b/lang/tomahawk_ca.ts index 7160ad885..1cc995668 100644 --- a/lang/tomahawk_ca.ts +++ b/lang/tomahawk_ca.ts @@ -1952,23 +1952,23 @@ i emissores de ràdio basades en el vostre gust musical. Iniciant sessió... - + Failed: %1 Error: %1 - + Logged in as %1 - + Log Out - - + + Log In Incia Sessió diff --git a/lang/tomahawk_de.ts b/lang/tomahawk_de.ts index 1b2237e8f..681d54669 100644 --- a/lang/tomahawk_de.ts +++ b/lang/tomahawk_de.ts @@ -1950,23 +1950,23 @@ erlauben sich mit dir zu verbinden? Anmelden... - + Failed: %1 Fehler: %1 - + Logged in as %1 - + Log Out - - + + Log In Anmelden diff --git a/lang/tomahawk_en.ts b/lang/tomahawk_en.ts index 10a6df695..b75364586 100644 --- a/lang/tomahawk_en.ts +++ b/lang/tomahawk_en.ts @@ -1953,23 +1953,23 @@ connect and stream from you? Logging in... - + Failed: %1 Failed: %1 - + Logged in as %1 Logged in as %1 - + Log Out Log Out - - + + Log In Log In diff --git a/lang/tomahawk_es.ts b/lang/tomahawk_es.ts index f7a42bc44..33aa1bf79 100644 --- a/lang/tomahawk_es.ts +++ b/lang/tomahawk_es.ts @@ -1951,23 +1951,23 @@ y estaciones basadas en sus gustos personales. Inciando sesión... - + Failed: %1 Fallo: %1 - + Logged in as %1 - + Log Out - - + + Log In Iniciar Sesión diff --git a/lang/tomahawk_fr.ts b/lang/tomahawk_fr.ts index 342404a62..c9426a2ef 100644 --- a/lang/tomahawk_fr.ts +++ b/lang/tomahawk_fr.ts @@ -1953,23 +1953,23 @@ et des stations basées sur vos goûts. Connexion... - + Failed: %1 Echec : %1 - + Logged in as %1 - + Log Out - - + + Log In Connexion diff --git a/lang/tomahawk_ja.ts b/lang/tomahawk_ja.ts index 0691b4a4e..c1a3e62be 100644 --- a/lang/tomahawk_ja.ts +++ b/lang/tomahawk_ja.ts @@ -1950,23 +1950,23 @@ connect and stream from you? ログイン中... - + Failed: %1 - + Logged in as %1 - + Log Out - - + + Log In ログイン diff --git a/lang/tomahawk_pl.ts b/lang/tomahawk_pl.ts index 105e7571f..ffe7d6422 100644 --- a/lang/tomahawk_pl.ts +++ b/lang/tomahawk_pl.ts @@ -1952,23 +1952,23 @@ indywidualnego profilu gustu. - + Failed: %1 - + Logged in as %1 - + Log Out - - + + Log In diff --git a/lang/tomahawk_pt_BR.ts b/lang/tomahawk_pt_BR.ts index 6c267e2e7..d127f49ac 100644 --- a/lang/tomahawk_pt_BR.ts +++ b/lang/tomahawk_pt_BR.ts @@ -1953,23 +1953,23 @@ automáticas baseadas no seu gosto pessoal. Logando... - + Failed: %1 Falha: %1 - + Logged in as %1 - + Log Out - - + + Log In Log In diff --git a/lang/tomahawk_ru.ts b/lang/tomahawk_ru.ts index d69fe6cf9..cc4062c14 100644 --- a/lang/tomahawk_ru.ts +++ b/lang/tomahawk_ru.ts @@ -1949,23 +1949,23 @@ connect and stream from you? Вхожу... - + Failed: %1 Ошибка: %1 - + Logged in as %1 - + Log Out - - + + Log In Войти diff --git a/lang/tomahawk_sv.ts b/lang/tomahawk_sv.ts index 34cc8d559..71f494c06 100644 --- a/lang/tomahawk_sv.ts +++ b/lang/tomahawk_sv.ts @@ -1949,23 +1949,23 @@ connect and stream from you? - + Failed: %1 - + Logged in as %1 - + Log Out - - + + Log In diff --git a/lang/tomahawk_tr.ts b/lang/tomahawk_tr.ts index 207f69445..c59d988f2 100644 --- a/lang/tomahawk_tr.ts +++ b/lang/tomahawk_tr.ts @@ -1948,23 +1948,23 @@ connect and stream from you? - + Failed: %1 - + Logged in as %1 - + Log Out - - + + Log In diff --git a/lang/tomahawk_zh_CN.ts b/lang/tomahawk_zh_CN.ts index 0a6958e41..9fc116298 100644 --- a/lang/tomahawk_zh_CN.ts +++ b/lang/tomahawk_zh_CN.ts @@ -1948,23 +1948,23 @@ connect and stream from you? - + Failed: %1 - + Logged in as %1 - + Log Out - - + + Log In diff --git a/lang/tomahawk_zh_TW.ts b/lang/tomahawk_zh_TW.ts index b840551b7..7e02e1844 100644 --- a/lang/tomahawk_zh_TW.ts +++ b/lang/tomahawk_zh_TW.ts @@ -1948,23 +1948,23 @@ connect and stream from you? 登錄中... - + Failed: %1 失敗:%1 - + Logged in as %1 - + Log Out - - + + Log In 登錄 From 97ff1100d149b23aed3b9f282f222bfacd58d128 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Tue, 10 Jul 2012 18:23:32 -0400 Subject: [PATCH 06/28] Fix stupid error, and hence fix this branch up --- src/libtomahawk/database/Database.cpp | 73 +++++++++++---------- src/libtomahawk/database/Database.h | 4 +- src/libtomahawk/database/DatabaseWorker.cpp | 2 - 3 files changed, 40 insertions(+), 39 deletions(-) diff --git a/src/libtomahawk/database/Database.cpp b/src/libtomahawk/database/Database.cpp index 5405a26b8..d4aee987c 100644 --- a/src/libtomahawk/database/Database.cpp +++ b/src/libtomahawk/database/Database.cpp @@ -57,7 +57,16 @@ Database::Database( const QString& dbname, QObject* parent ) connect( m_impl, SIGNAL( indexReady() ), SIGNAL( ready() ) ); connect( m_impl, SIGNAL( indexReady() ), SLOT( setIsReadyTrue() ) ); - m_workerRW->start(); + Q_ASSERT( m_workerRW ); + m_workerRW.data()->start(); + + while ( m_workerThreads.count() < m_maxConcurrentThreads ) + { + QWeakPointer< DatabaseWorkerThread > workerThread( new DatabaseWorkerThread( this, false ) ); + Q_ASSERT( workerThread ); + workerThread.data()->start(); + m_workerThreads << workerThread; + } } @@ -65,20 +74,26 @@ Database::~Database() { qDebug() << Q_FUNC_INFO; - m_workerRW->quit(); - foreach ( DatabaseWorkerThread *thread, m_workerThreads ) + if ( m_workerRW ) + m_workerRW.data()->quit(); + foreach ( QWeakPointer< DatabaseWorkerThread > workerThread, m_workerThreads ) { - if ( thread->worker() ) - thread->quit(); + if ( workerThread && workerThread.data()->worker() ) + workerThread.data()->quit(); } - m_workerRW->wait( 60000 ); - delete m_workerRW; - m_workerRW = 0; - foreach ( DatabaseWorkerThread *thread, m_workerThreads ) + if ( m_workerRW ) { - thread->wait( 60000 ); - delete thread; + m_workerRW.data()->wait( 60000 ); + delete m_workerRW.data(); + } + foreach ( QWeakPointer< DatabaseWorkerThread > workerThread, m_workerThreads ) + { + if ( workerThread ) + { + workerThread.data()->wait( 60000 ); + delete workerThread.data(); + } } m_workerThreads.clear(); @@ -99,8 +114,8 @@ Database::enqueue( const QList< QSharedPointer >& lc ) { Q_ASSERT( m_ready ); qDebug() << "Enqueueing" << lc.count() << "commands to rw thread"; - if ( m_workerRW->worker() ) - m_workerRW->worker().data()->enqueue( lc ); + if ( m_workerRW && m_workerRW.data()->worker() ) + m_workerRW.data()->worker().data()->enqueue( lc ); } @@ -111,44 +126,32 @@ Database::enqueue( const QSharedPointer& lc ) if ( lc->doesMutates() ) { qDebug() << "Enqueueing command to rw thread:" << lc->commandname(); - if ( m_workerRW->worker() ) - m_workerRW->worker().data()->enqueue( lc ); + if ( m_workerRW && m_workerRW.data()->worker() ) + m_workerRW.data()->worker().data()->enqueue( lc ); } else { - // find existing amount of worker threads for commandname - // create new thread if < WORKER_THREADS - if ( m_workerThreads.count() < m_maxConcurrentThreads ) - { - DatabaseWorkerThread* workerThread = new DatabaseWorkerThread( this, false ); - tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "P1" << ( workerThread->worker() ? "true" : "false" ); - workerThread->start(); - tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "P2" << ( workerThread->worker() ? "true" : "false" ); - - m_workerThreads << workerThread; - } - // find thread for commandname with lowest amount of outstanding jobs and enqueue job int busyThreads = 0; + QWeakPointer< DatabaseWorkerThread > workerThread; QWeakPointer< DatabaseWorker > happyWorker; for ( int i = 0; i < m_workerThreads.count(); i++ ) { - DatabaseWorkerThread* workerThread = m_workerThreads.at( i ); - - tDebug( LOGVERBOSE ) << Q_FUNC_INFO << i << ( workerThread->worker() ? "true" : "false" ); - if ( workerThread->worker() && !workerThread->worker().data()->busy() ) + workerThread = m_workerThreads.at( i ); + + if ( workerThread && workerThread.data()->worker() && !workerThread.data()->worker().data()->busy() ) { - happyWorker = workerThread->worker(); + happyWorker = workerThread.data()->worker(); break; } busyThreads++; - if ( !happyWorker || ( workerThread->worker() && workerThread->worker().data()->outstandingJobs() < happyWorker.data()->outstandingJobs() ) ) - happyWorker = workerThread->worker(); + if ( ( !happyWorker && workerThread && workerThread.data()->worker() ) || + ( workerThread && workerThread.data()->worker() && workerThread.data()->worker().data()->outstandingJobs() < happyWorker.data()->outstandingJobs() ) ) + happyWorker = workerThread.data()->worker(); } // qDebug() << "Enqueueing command to thread:" << happyThread << busyThreads << lc->commandname(); - tDebug( LOGVERBOSE ) << Q_FUNC_INFO << m_workerThreads.count() << m_maxConcurrentThreads; Q_ASSERT( happyWorker ); happyWorker.data()->enqueue( lc ); } diff --git a/src/libtomahawk/database/Database.h b/src/libtomahawk/database/Database.h index 6eaf78578..7d5c118d7 100644 --- a/src/libtomahawk/database/Database.h +++ b/src/libtomahawk/database/Database.h @@ -76,8 +76,8 @@ private: bool m_ready; DatabaseImpl* m_impl; - DatabaseWorkerThread* m_workerRW; - QList< DatabaseWorkerThread* > m_workerThreads; + QWeakPointer< DatabaseWorkerThread > m_workerRW; + QList< QWeakPointer< DatabaseWorkerThread > > m_workerThreads; int m_maxConcurrentThreads; QHash< QThread*, DatabaseImpl* > m_implHash; diff --git a/src/libtomahawk/database/DatabaseWorker.cpp b/src/libtomahawk/database/DatabaseWorker.cpp index e9577eac8..48fee65b9 100644 --- a/src/libtomahawk/database/DatabaseWorker.cpp +++ b/src/libtomahawk/database/DatabaseWorker.cpp @@ -48,7 +48,6 @@ DatabaseWorkerThread::run() { tDebug() << Q_FUNC_INFO << "DatabaseWorkerThread starting..."; m_worker = QWeakPointer< DatabaseWorker >( new DatabaseWorker( m_db, m_mutates ) ); - tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "P5" << ( m_worker ? "true" : "false" ); exec(); tDebug() << Q_FUNC_INFO << "DatabaseWorkerThread finishing..."; if ( m_worker ) @@ -64,7 +63,6 @@ DatabaseWorkerThread::~DatabaseWorkerThread() QWeakPointer< DatabaseWorker > DatabaseWorkerThread::worker() const { - tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "P4" << ( m_worker ? "true" : "false" ); return m_worker; } From 8dcf7d0db280af1bf1cda1d04eda6aa0d029b599 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Tue, 10 Jul 2012 19:23:12 -0400 Subject: [PATCH 07/28] Potentially solve the 4-is-not-JSON bug --- src/DiagnosticsDialog.cpp | 2 +- src/accounts/xmpp/sip/XmppSip.cpp | 6 ++---- src/libtomahawk/sip/SipHandler.cpp | 9 +++++---- src/libtomahawk/sip/SipInfo.cpp | 18 ++++++++---------- src/libtomahawk/sip/SipInfo.h | 4 ++-- 5 files changed, 18 insertions(+), 21 deletions(-) diff --git a/src/DiagnosticsDialog.cpp b/src/DiagnosticsDialog.cpp index 17a084632..1ed6e2255 100644 --- a/src/DiagnosticsDialog.cpp +++ b/src/DiagnosticsDialog.cpp @@ -241,7 +241,7 @@ DiagnosticsDialog::updateAccountLabel( Tomahawk::Accounts::Account* account ) accountInfo.append( QString(" %1: %2:%3 %4" /*" (%5)"*/ "\n") .arg( peerId ) - .arg( sipInfo.host().hostName() ) + .arg( sipInfo.host() ) .arg( sipInfo.port() ) .arg( versionString ) // .arg( connected ? "connected" : "not connected") diff --git a/src/accounts/xmpp/sip/XmppSip.cpp b/src/accounts/xmpp/sip/XmppSip.cpp index b0614549e..bf6bc488a 100644 --- a/src/accounts/xmpp/sip/XmppSip.cpp +++ b/src/accounts/xmpp/sip/XmppSip.cpp @@ -435,7 +435,7 @@ XmppSipPlugin::sendMsg( const QString& to, const SipInfo& info ) TomahawkXmppMessage *sipMessage; if ( info.isVisible() ) { - sipMessage = new TomahawkXmppMessage( info.host().hostName(), info.port(), info.uniqname(), info.key() ); + sipMessage = new TomahawkXmppMessage( info.host(), info.port(), info.uniqname(), info.key() ); } else sipMessage = new TomahawkXmppMessage(); @@ -892,9 +892,7 @@ XmppSipPlugin::onNewIq( const Jreen::IQ& iq ) info.setVisible( sipMessage->visible() ); if ( sipMessage->visible() ) { - QHostInfo hi; - hi.setHostName( sipMessage->ip() ); - info.setHost( hi ); + info.setHost( sipMessage->ip() ); info.setPort( sipMessage->port() ); info.setUniqname( sipMessage->uniqname() ); info.setKey( sipMessage->key() ); diff --git a/src/libtomahawk/sip/SipHandler.cpp b/src/libtomahawk/sip/SipHandler.cpp index cfc698e96..fbc26255e 100644 --- a/src/libtomahawk/sip/SipHandler.cpp +++ b/src/libtomahawk/sip/SipHandler.cpp @@ -137,7 +137,7 @@ SipHandler::onPeerOnline( const QString& peerId ) Servent::instance()->registerOffer( key, conn ); info.setVisible( true ); - info.setHost( QHostInfo::fromName( Servent::instance()->externalAddress() ) ); + info.setHost( Servent::instance()->externalAddress() ); info.setPort( Servent::instance()->externalPort() ); info.setKey( key ); info.setUniqname( nodeid ); @@ -180,10 +180,11 @@ SipHandler::onSipInfo( const QString& peerId, const SipInfo& info ) if ( info.isVisible() ) { if( !Servent::instance()->visibleExternally() || - Servent::instance()->externalAddress() <= info.host().hostName() ) + Servent::instance()->externalAddress() < info.host() || + ( Servent::instance()->externalAddress() == info.host() && Servent::instance()->externalPort() < info.port() ) ) { - tDebug() << "Initiate connection to" << peerId << Servent::instance()->externalAddress() << info.host().hostName() << ( Servent::instance()->externalAddress() <= info.host().hostName() ); - Servent::instance()->connectToPeer( info.host().hostName(), + tDebug() << "Initiate connection to" << peerId << "at" << info.host(); + Servent::instance()->connectToPeer( info.host(), info.port(), info.key(), peerId, diff --git a/src/libtomahawk/sip/SipInfo.cpp b/src/libtomahawk/sip/SipInfo.cpp index b877fdc3e..b0a39001a 100644 --- a/src/libtomahawk/sip/SipInfo.cpp +++ b/src/libtomahawk/sip/SipInfo.cpp @@ -44,7 +44,7 @@ public: ~SipInfoPrivate() { } QVariant visible; - QHostInfo host; + QString host; int port; QString uniqname; QString key; @@ -81,7 +81,7 @@ void SipInfo::clear() { d->visible.clear(); - d->host = QHostInfo(); + d->host = QString(); d->port = -1; d->uniqname = QString(); d->key = QString(); @@ -96,9 +96,9 @@ SipInfo::isValid() const { if( // visible and all data available - ( d->visible.toBool() && !d->host.hostName().isNull() && ( d->port > 0 ) && !d->uniqname.isNull() && !d->key.isNull() ) + ( d->visible.toBool() && !d->host.isEmpty() && ( d->port > 0 ) && !d->uniqname.isNull() && !d->key.isNull() ) // invisible and no data available - || ( !d->visible.toBool() && d->host.hostName().isNull() && ( d->port < 0 ) && d->uniqname.isNull() && d->key.isNull() ) + || ( !d->visible.toBool() && d->host.isEmpty() && ( d->port < 0 ) && d->uniqname.isNull() && d->key.isNull() ) ) return true; } @@ -124,13 +124,13 @@ SipInfo::isVisible() const void -SipInfo::setHost( const QHostInfo& host ) +SipInfo::setHost( const QString& host ) { d->host = host; } -const QHostInfo +const QString SipInfo::host() const { Q_ASSERT( isValid() ); @@ -195,7 +195,7 @@ SipInfo::toJson() const m["visible"] = isVisible(); if( isVisible() ) { - m["ip"] = host().hostName(); + m["ip"] = host(); m["port"] = port(); m["key"] = key(); m["uniqname"] = uniqname(); @@ -227,9 +227,7 @@ SipInfo::fromJson( QString json ) info.setVisible( m["visible"].toBool() ); if( m["visible"].toBool() ) { - QHostInfo hostInfo; - hostInfo.setHostName( m["host"].toString() ); - info.setHost( hostInfo ); + info.setHost( m["host"].toString() ); info.setPort( m["port"].toInt() ); info.setUniqname( m["uniqname"].toString() ); info.setKey( m["key"].toString() ); diff --git a/src/libtomahawk/sip/SipInfo.h b/src/libtomahawk/sip/SipInfo.h index d354aab70..4b5ea2b48 100644 --- a/src/libtomahawk/sip/SipInfo.h +++ b/src/libtomahawk/sip/SipInfo.h @@ -43,8 +43,8 @@ public: void setVisible( bool visible ); bool isVisible() const; - void setHost( const QHostInfo& host ); - const QHostInfo host() const; + void setHost( const QString& host ); + const QString host() const; void setPort( int port ); int port() const; From e9314775aa0a667f1f22036b32f3120cfce4b228 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Tue, 10 Jul 2012 21:09:07 -0400 Subject: [PATCH 08/28] Better PortFwdThread handling...separate out the thread controller from the actual threaded worker --- src/libtomahawk/network/PortFwdThread.cpp | 69 ++++++++++++++++------- src/libtomahawk/network/PortFwdThread.h | 41 +++++++++++--- src/libtomahawk/network/Servent.cpp | 16 ++++-- src/libtomahawk/network/Servent.h | 2 +- 4 files changed, 94 insertions(+), 34 deletions(-) diff --git a/src/libtomahawk/network/PortFwdThread.cpp b/src/libtomahawk/network/PortFwdThread.cpp index 0da9a7b8e..b6b4d84a6 100644 --- a/src/libtomahawk/network/PortFwdThread.cpp +++ b/src/libtomahawk/network/PortFwdThread.cpp @@ -29,29 +29,69 @@ #include - PortFwdThread::PortFwdThread( unsigned int port ) : QThread() - , m_externalPort( 0 ) , m_port( port ) { - moveToThread( this ); - start(); } PortFwdThread::~PortFwdThread() { - qDebug() << Q_FUNC_INFO << "waiting for event loop to finish..."; - quit(); - wait( 6000 ); +} + + +void +PortFwdThread::run() +{ + m_worker = QWeakPointer< PortFwdWorker >( new PortFwdWorker( m_port ) ); + Q_ASSERT( m_worker ); + connect( m_worker.data(), SIGNAL( externalAddressDetected( QHostAddress, unsigned int ) ), this, SIGNAL( externalAddressDetected( QHostAddress, unsigned int ) ) ); + QTimer::singleShot( 0, m_worker.data(), SLOT( work() ) ); + exec(); + + if ( m_worker.data()->externalPort() ) + { + qDebug() << "Unregistering port fwd"; + m_worker.data()->unregister(); + } + + if ( m_worker ) + delete m_worker.data(); +} + + +QWeakPointer< PortFwdWorker > +PortFwdThread::worker() const +{ + return m_worker; +} + + +PortFwdWorker::PortFwdWorker( unsigned int port ) + : QObject() + , m_externalPort( 0 ) + , m_port( port ) +{ +} + + +PortFwdWorker::~PortFwdWorker() +{ delete m_portfwd; } void -PortFwdThread::work() +PortFwdWorker::unregister() +{ + m_portfwd->remove( m_externalPort ); +} + + +void +PortFwdWorker::work() { qsrand( QTime( 0, 0, 0 ).secsTo( QTime::currentTime() ) ); m_portfwd = new Portfwd(); @@ -103,16 +143,3 @@ PortFwdThread::work() emit externalAddressDetected( m_externalAddress, m_externalPort ); } - -void -PortFwdThread::run() -{ - QTimer::singleShot( 0, this, SLOT( work() ) ); - exec(); - - if ( m_externalPort ) - { - qDebug() << "Unregistering port fwd"; - m_portfwd->remove( m_externalPort ); - } -} diff --git a/src/libtomahawk/network/PortFwdThread.h b/src/libtomahawk/network/PortFwdThread.h index 85eb98023..093065ff7 100644 --- a/src/libtomahawk/network/PortFwdThread.h +++ b/src/libtomahawk/network/PortFwdThread.h @@ -22,9 +22,35 @@ #include #include #include +#include class Portfwd; +class PortFwdWorker : public QObject +{ +Q_OBJECT + +public: + explicit PortFwdWorker( unsigned int port ); + ~PortFwdWorker(); + + unsigned int externalPort() const { return m_externalPort; } + + void unregister(); + +signals: + void externalAddressDetected( QHostAddress ha, unsigned int port ); + +public slots: + void work(); + +private: + Portfwd* m_portfwd; + QHostAddress m_externalAddress; + unsigned int m_externalPort, m_port; +}; + + class PortFwdThread : public QThread { Q_OBJECT @@ -33,18 +59,17 @@ public: explicit PortFwdThread( unsigned int port ); ~PortFwdThread(); + QWeakPointer< PortFwdWorker > worker() const; + signals: void externalAddressDetected( QHostAddress ha, unsigned int port ); - -private slots: - void work(); - -private: + +protected: void run(); - Portfwd* m_portfwd; - QHostAddress m_externalAddress; - unsigned int m_externalPort, m_port; +private: + QWeakPointer< PortFwdWorker > m_worker; + unsigned int m_port; }; #endif // PORTFWDTHREAD_H diff --git a/src/libtomahawk/network/Servent.cpp b/src/libtomahawk/network/Servent.cpp index 1180a01e0..b25c842e7 100644 --- a/src/libtomahawk/network/Servent.cpp +++ b/src/libtomahawk/network/Servent.cpp @@ -60,7 +60,6 @@ Servent::Servent( QObject* parent ) , m_port( 0 ) , m_externalPort( 0 ) , m_ready( false ) - , m_portfwd( 0 ) { s_instance = this; @@ -89,7 +88,13 @@ Servent::Servent( QObject* parent ) Servent::~Servent() { - delete m_portfwd; + + if ( m_portfwd ) + { + m_portfwd.data()->quit(); + m_portfwd.data()->wait( 60000 ); + delete m_portfwd.data(); + } } @@ -144,9 +149,11 @@ Servent::startListening( QHostAddress ha, bool upnp, int port ) } // TODO check if we have a public/internet IP on this machine directly tLog() << "External address mode set to upnp..."; - m_portfwd = new PortFwdThread( m_port ); - connect( m_portfwd, SIGNAL( externalAddressDetected( QHostAddress, unsigned int ) ), + m_portfwd = QWeakPointer< PortFwdThread >( new PortFwdThread( m_port ) ); + Q_ASSERT( m_portfwd ); + connect( m_portfwd.data(), SIGNAL( externalAddressDetected( QHostAddress, unsigned int ) ), SLOT( setExternalAddress( QHostAddress, unsigned int ) ) ); + m_portfwd.data()->start(); break; } @@ -226,6 +233,7 @@ Servent::setExternalAddress( QHostAddress ha, unsigned int port ) return; } + tLog() << "UPnP setup successful"; m_ready = true; emit ready(); } diff --git a/src/libtomahawk/network/Servent.h b/src/libtomahawk/network/Servent.h index 5f1dfa8a2..8fa679a6d 100644 --- a/src/libtomahawk/network/Servent.h +++ b/src/libtomahawk/network/Servent.h @@ -174,7 +174,7 @@ private: QMap< QString,boost::function< QSharedPointer< QIODevice >(Tomahawk::result_ptr) > > m_iofactories; - PortFwdThread* m_portfwd; + QWeakPointer< PortFwdThread > m_portfwd; static Servent* s_instance; }; From d2a5092862ad53800b5655f0a4786e8fc6cc94b0 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Tue, 10 Jul 2012 23:27:14 -0400 Subject: [PATCH 09/28] Increased pointer safety (oops 19336) --- src/libtomahawk/DropJob.cpp | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/libtomahawk/DropJob.cpp b/src/libtomahawk/DropJob.cpp index 5f1cea4bd..ee8b5f791 100644 --- a/src/libtomahawk/DropJob.cpp +++ b/src/libtomahawk/DropJob.cpp @@ -699,8 +699,21 @@ DropJob::removeDuplicates() foreach ( const Tomahawk::query_ptr& item, m_resultList ) { bool contains = false; + Q_ASSERT( !item.isNull() ); + if ( item.isNull() ) + { + m_resultList.removeOne( item ); + continue; + } + foreach( const Tomahawk::query_ptr &tmpItem, list ) { + if ( tmpItem.isNull() ) + { + list.removeOne( tmpItem ); + continue; + } + if ( item->album() == tmpItem->album() && item->artist() == tmpItem->artist() && item->track() == tmpItem->track() ) @@ -726,10 +739,18 @@ DropJob::removeRemoteSources() QList< Tomahawk::query_ptr > list; foreach ( const Tomahawk::query_ptr& item, m_resultList ) { + Q_ASSERT( !item.isNull() ); + if ( item.isNull() ) + { + m_resultList.removeOne( item ); + continue; + } + bool hasLocalSource = false; foreach ( const Tomahawk::result_ptr& result, item->results() ) { - if ( !result->collection()->source().isNull() && result->collection()->source()->isLocal() ) + if ( !result->collection().isNull() && !result->collection()->source().isNull() && + !result->collection()->source().isNull() && result->collection()->source()->isLocal() ) hasLocalSource = true; } if ( hasLocalSource ) From c3474833b93c2465ced744d4e51d1beece5fca97 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Tue, 10 Jul 2012 23:31:58 -0400 Subject: [PATCH 10/28] Increased pointer safety (oops 19400) --- src/libtomahawk/Pipeline.cpp | 7 +++++++ src/libtomahawk/Query.cpp | 5 +++++ 2 files changed, 12 insertions(+) diff --git a/src/libtomahawk/Pipeline.cpp b/src/libtomahawk/Pipeline.cpp index 6e12e5734..c378c2ef0 100644 --- a/src/libtomahawk/Pipeline.cpp +++ b/src/libtomahawk/Pipeline.cpp @@ -272,9 +272,16 @@ Pipeline::reportResults( QID qid, const QList< result_ptr >& results ) } const query_ptr& q = m_qids.value( qid ); + Q_ASSERT( !q.isNull() ); + if ( q.isNull() ) + return; + QList< result_ptr > cleanResults; foreach ( const result_ptr& r, results ) { + if ( r.isNull() ) + continue; + float score = q->howSimilar( r ); r->setScore( score ); if ( !q->isFullTextQuery() && score < MINSCORE ) diff --git a/src/libtomahawk/Query.cpp b/src/libtomahawk/Query.cpp index a8c7f7d7e..24b219d7d 100644 --- a/src/libtomahawk/Query.cpp +++ b/src/libtomahawk/Query.cpp @@ -498,6 +498,11 @@ Query::toString() const float Query::howSimilar( const Tomahawk::result_ptr& r ) { + Q_ASSERT( !r->artist().isNull() ); + Q_ASSERT( !r->album().isNull() ); + if ( r->artist().isNull() || r->album().isNull() ) + return 0.0; + // result values const QString rArtistname = r->artist()->sortname(); const QString rAlbumname = r->album()->sortname(); From 26e5c302d8b6c14529c5b09272d8ac13c56b6c59 Mon Sep 17 00:00:00 2001 From: Tomahawk CI Date: Wed, 11 Jul 2012 22:17:45 +0000 Subject: [PATCH 11/28] Automatic merge of Transifex translations --- lang/tomahawk_ar.ts | 14 +++++++------- lang/tomahawk_bg.ts | 14 +++++++------- lang/tomahawk_ca.ts | 14 +++++++------- lang/tomahawk_de.ts | 14 +++++++------- lang/tomahawk_en.ts | 14 +++++++------- lang/tomahawk_es.ts | 14 +++++++------- lang/tomahawk_fr.ts | 14 +++++++------- lang/tomahawk_ja.ts | 14 +++++++------- lang/tomahawk_pl.ts | 14 +++++++------- lang/tomahawk_pt_BR.ts | 14 +++++++------- lang/tomahawk_ru.ts | 14 +++++++------- lang/tomahawk_sv.ts | 14 +++++++------- lang/tomahawk_tr.ts | 14 +++++++------- lang/tomahawk_zh_CN.ts | 14 +++++++------- lang/tomahawk_zh_TW.ts | 14 +++++++------- 15 files changed, 105 insertions(+), 105 deletions(-) diff --git a/lang/tomahawk_ar.ts b/lang/tomahawk_ar.ts index 3478231bf..c92fa3677 100644 --- a/lang/tomahawk_ar.ts +++ b/lang/tomahawk_ar.ts @@ -2892,37 +2892,37 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::Query - + and و - + You أنت - + you أنت - + and و - + %n other(s) %n أخرين%n أخر%n أخرين%n أخرين%n أخرين%n أخرين - + %1 people %1 أشخاص - + loved this track أحببت هذه الأغنية diff --git a/lang/tomahawk_bg.ts b/lang/tomahawk_bg.ts index e1aa89d77..68c491a1f 100644 --- a/lang/tomahawk_bg.ts +++ b/lang/tomahawk_bg.ts @@ -2899,37 +2899,37 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::Query - + and и - + You Ти - + you ти - + and и - + %n other(s) %n друг%n други - + %1 people %1 хора - + loved this track хареса тази песен diff --git a/lang/tomahawk_ca.ts b/lang/tomahawk_ca.ts index 1cc995668..06d38cfbf 100644 --- a/lang/tomahawk_ca.ts +++ b/lang/tomahawk_ca.ts @@ -2891,37 +2891,37 @@ Intenteu ajustar els filtres per reproduir noves cançons. Tomahawk::Query - + and i - + You Jo - + you jo - + and i - + %n other(s) %n més%n més - + %1 people %1 persones - + loved this track els ha encantat aquesta cançó diff --git a/lang/tomahawk_de.ts b/lang/tomahawk_de.ts index 681d54669..cfe87b43a 100644 --- a/lang/tomahawk_de.ts +++ b/lang/tomahawk_de.ts @@ -2887,37 +2887,37 @@ Versuch die Filter anzupassen für neue Lieder. Tomahawk::Query - + and und - + You Du - + you du - + and und - + %n other(s) %n anderer%n andere - + %1 people %1 Leute - + loved this track liebte dieses Lied diff --git a/lang/tomahawk_en.ts b/lang/tomahawk_en.ts index b75364586..7362f034a 100644 --- a/lang/tomahawk_en.ts +++ b/lang/tomahawk_en.ts @@ -2892,37 +2892,37 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::Query - + and and - + You You - + you you - + and and - + %n other(s) %n other%n others - + %1 people %1 people - + loved this track loved this track diff --git a/lang/tomahawk_es.ts b/lang/tomahawk_es.ts index 33aa1bf79..d65d653c2 100644 --- a/lang/tomahawk_es.ts +++ b/lang/tomahawk_es.ts @@ -2890,37 +2890,37 @@ Intente ajustar los filtros para reproducir nuevas canciones. Tomahawk::Query - + and y - + You usted - + you usted - + and y - + %n other(s) %n más%n más - + %1 people %1 personas - + loved this track han añadido este tema a Favoritos diff --git a/lang/tomahawk_fr.ts b/lang/tomahawk_fr.ts index c9426a2ef..b7647c919 100644 --- a/lang/tomahawk_fr.ts +++ b/lang/tomahawk_fr.ts @@ -2892,37 +2892,37 @@ Essayez de changer les filtres pour avoir de nouveaux morceaux à jouer. Tomahawk::Query - + and et - + You Vous - + you vous - + and et - + %n other(s) %n autre%n autres - + %1 people %1 personnes - + loved this track a enregistré cette piste dans ses favoris diff --git a/lang/tomahawk_ja.ts b/lang/tomahawk_ja.ts index c1a3e62be..cfaa5e0c5 100644 --- a/lang/tomahawk_ja.ts +++ b/lang/tomahawk_ja.ts @@ -2882,37 +2882,37 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::Query - + and - + You - + you - + and - + %n other(s) - + %1 people - + loved this track diff --git a/lang/tomahawk_pl.ts b/lang/tomahawk_pl.ts index ffe7d6422..762469948 100644 --- a/lang/tomahawk_pl.ts +++ b/lang/tomahawk_pl.ts @@ -2886,37 +2886,37 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::Query - + and i - + You Ty - + you ty - + and i - + %n other(s) %n inny%n inne%n innych - + %1 people - + loved this track diff --git a/lang/tomahawk_pt_BR.ts b/lang/tomahawk_pt_BR.ts index d127f49ac..b392c4e7b 100644 --- a/lang/tomahawk_pt_BR.ts +++ b/lang/tomahawk_pt_BR.ts @@ -2892,37 +2892,37 @@ Tente ajustar os filtros para ouvir um novo conjunto de músicas. Tomahawk::Query - + and e - + You Você - + you você - + and e - + %n other(s) %n outro%n outros - + %1 people %1 pessoas - + loved this track favoritou essa faixa diff --git a/lang/tomahawk_ru.ts b/lang/tomahawk_ru.ts index cc4062c14..474b94e9c 100644 --- a/lang/tomahawk_ru.ts +++ b/lang/tomahawk_ru.ts @@ -2886,37 +2886,37 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::Query - + and и - + You Ты - + you ты - + and и - + %n other(s) - + %1 people %1 человек - + loved this track любимый diff --git a/lang/tomahawk_sv.ts b/lang/tomahawk_sv.ts index 71f494c06..92bd18710 100644 --- a/lang/tomahawk_sv.ts +++ b/lang/tomahawk_sv.ts @@ -2881,37 +2881,37 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::Query - + and - + You - + you - + and - + %n other(s) - + %1 people - + loved this track diff --git a/lang/tomahawk_tr.ts b/lang/tomahawk_tr.ts index c59d988f2..4e3b3caa8 100644 --- a/lang/tomahawk_tr.ts +++ b/lang/tomahawk_tr.ts @@ -2880,37 +2880,37 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::Query - + and - + You - + you - + and - + %n other(s) - + %1 people - + loved this track diff --git a/lang/tomahawk_zh_CN.ts b/lang/tomahawk_zh_CN.ts index 9fc116298..313542a94 100644 --- a/lang/tomahawk_zh_CN.ts +++ b/lang/tomahawk_zh_CN.ts @@ -2880,37 +2880,37 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::Query - + and - + You - + you - + and - + %n other(s) - + %1 people - + loved this track diff --git a/lang/tomahawk_zh_TW.ts b/lang/tomahawk_zh_TW.ts index 7e02e1844..c2ad37438 100644 --- a/lang/tomahawk_zh_TW.ts +++ b/lang/tomahawk_zh_TW.ts @@ -2880,37 +2880,37 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::Query - + and - + You - + you - + and - + %n other(s) - + %1 people - + loved this track From 09d89c3663b59fb570ab2e3d45aa057b64082fe1 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Thu, 12 Jul 2012 07:22:20 +0200 Subject: [PATCH 12/28] * Use a RAMDirectory if we can't open the regular lucene index file. --- src/libtomahawk/database/FuzzyIndex.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/libtomahawk/database/FuzzyIndex.cpp b/src/libtomahawk/database/FuzzyIndex.cpp index 64db5b690..176e55ccc 100644 --- a/src/libtomahawk/database/FuzzyIndex.cpp +++ b/src/libtomahawk/database/FuzzyIndex.cpp @@ -49,15 +49,24 @@ FuzzyIndex::FuzzyIndex( QObject* parent, bool wipe ) QByteArray path = m_lucenePath.toUtf8(); const char* cPath = path.constData(); + bool failed = false; tDebug() << "Opening Lucene directory:" << path; try { - m_luceneDir = FSDirectory::getDirectory( cPath ); m_analyzer = _CLNEW SimpleAnalyzer(); + m_luceneDir = FSDirectory::getDirectory( cPath ); } catch ( CLuceneError& error ) { tDebug() << "Caught CLucene error:" << error.what(); + failed = true; + } + + if ( failed ) + { + tDebug() << "Initializing RAM directory instead."; + + m_luceneDir = _CLNEW RAMDirectory(); wipe = true; } From 5f907258eb4efb80cd49ec57616490352dd43b81 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Thu, 12 Jul 2012 07:22:56 +0200 Subject: [PATCH 13/28] * Style updates and smaller fixes. --- src/libtomahawk/filemetadata/MetadataEditor.cpp | 3 ++- src/libtomahawk/filemetadata/MetadataEditor.h | 14 +++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/libtomahawk/filemetadata/MetadataEditor.cpp b/src/libtomahawk/filemetadata/MetadataEditor.cpp index 7137003ac..b881604e6 100644 --- a/src/libtomahawk/filemetadata/MetadataEditor.cpp +++ b/src/libtomahawk/filemetadata/MetadataEditor.cpp @@ -34,7 +34,8 @@ #include "filemetadata/taghandlers/tag.h" #include "utils/TomahawkUtils.h" -MetadataEditor::MetadataEditor( Tomahawk::result_ptr result, QWidget *parent ) + +MetadataEditor::MetadataEditor( const Tomahawk::result_ptr& result, QWidget* parent ) : QDialog( parent ) , ui( new Ui::MetadataEditor ) , m_result( result ) diff --git a/src/libtomahawk/filemetadata/MetadataEditor.h b/src/libtomahawk/filemetadata/MetadataEditor.h index d66de1db1..ccd743b92 100644 --- a/src/libtomahawk/filemetadata/MetadataEditor.h +++ b/src/libtomahawk/filemetadata/MetadataEditor.h @@ -35,16 +35,16 @@ class MetadataEditor : public QDialog Q_OBJECT public: - MetadataEditor( Tomahawk::result_ptr result, QWidget* parent = 0 ); + MetadataEditor( const Tomahawk::result_ptr& result, QWidget* parent = 0 ); ~MetadataEditor() {}; protected: - QString title() { return ui->titleLineEdit->text(); } - QString artist() { return ui->artistLineEdit->text(); } - QString album() { return ui->albumLineEdit->text(); } - int discnumber() { return ui->discNumberSpinBox->value(); } - int year() { return ui->yearSpinBox->value(); } - int bitrate() { return ui->bitrateSpinBox->value(); } + QString title() const { return ui->titleLineEdit->text(); } + QString artist() const { return ui->artistLineEdit->text(); } + QString album() const { return ui->albumLineEdit->text(); } + int discnumber() const { return ui->discNumberSpinBox->value(); } + int year() const { return ui->yearSpinBox->value(); } + int bitrate() const { return ui->bitrateSpinBox->value(); } private slots: void writeMetadata(); From 81b9af0dc932e4dbc89d26642cdf516e090f7e5f Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Thu, 12 Jul 2012 08:34:37 +0200 Subject: [PATCH 14/28] * Expose logfile's path in Logger. --- src/libtomahawk/utils/Logger.cpp | 22 ++++++++++++++-------- src/libtomahawk/utils/Logger.h | 5 +++-- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/libtomahawk/utils/Logger.cpp b/src/libtomahawk/utils/Logger.cpp index d9d85ab5c..def5f8409 100644 --- a/src/libtomahawk/utils/Logger.cpp +++ b/src/libtomahawk/utils/Logger.cpp @@ -30,7 +30,6 @@ #include "utils/TomahawkUtils.h" -#define LOGFILE TomahawkUtils::appLogDir().filePath( "Tomahawk.log" ).toLocal8Bit() #define LOGFILE_SIZE 1024 * 256 #define RELEASE_LEVEL_THRESHOLD 0 @@ -98,7 +97,7 @@ log( const char *msg, unsigned int debugLevel, bool toDisk = true ) void -TomahawkLogHandler( QtMsgType type, const char *msg ) +TomahawkLogHandler( QtMsgType type, const char* msg ) { static QMutex s_mutex; @@ -124,30 +123,37 @@ TomahawkLogHandler( QtMsgType type, const char *msg ) } +QString +logFile() +{ + return TomahawkUtils::appLogDir().filePath( "Tomahawk.log" ); +} + + void setupLogfile() { - if ( QFileInfo( LOGFILE ).size() > LOGFILE_SIZE ) + if ( QFileInfo( logFile().toLocal8Bit() ).size() > LOGFILE_SIZE ) { QByteArray lc; { - QFile f( LOGFILE ); + QFile f( logFile().toLocal8Bit() ); f.open( QIODevice::ReadOnly | QIODevice::Text ); lc = f.readAll(); f.close(); } - QFile::remove( LOGFILE ); + QFile::remove( logFile().toLocal8Bit() ); { - QFile f( LOGFILE ); + QFile f( logFile().toLocal8Bit() ); f.open( QIODevice::WriteOnly | QIODevice::Text ); - f.write( lc.right( LOGFILE_SIZE - (LOGFILE_SIZE / 4) ) ); + f.write( lc.right( LOGFILE_SIZE - ( LOGFILE_SIZE / 4 ) ) ); f.close(); } } - logfile.open( LOGFILE, ios::app ); + logfile.open( logFile().toLocal8Bit(), ios::app ); qInstallMsgHandler( TomahawkLogHandler ); } diff --git a/src/libtomahawk/utils/Logger.h b/src/libtomahawk/utils/Logger.h index 6c1f69fdb..f3e0a1ea6 100644 --- a/src/libtomahawk/utils/Logger.h +++ b/src/libtomahawk/utils/Logger.h @@ -51,7 +51,7 @@ namespace Logger { } }; - + class DLLEXPORT TSqlLog : public TLog { public: @@ -60,8 +60,9 @@ namespace Logger } }; - DLLEXPORT void TomahawkLogHandler( QtMsgType type, const char *msg ); + DLLEXPORT void TomahawkLogHandler( QtMsgType type, const char* msg ); DLLEXPORT void setupLogfile(); + DLLEXPORT QString logFile(); } #define tLog Logger::TLog From f3d3f19ef8959afae6f4a85136581ac315d696a6 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Thu, 12 Jul 2012 08:35:29 +0200 Subject: [PATCH 15/28] * Provide convenience openUrl( url ) method in TomahawkUtilsGui, since QDesktopServices fail to work on Windows. --- src/libtomahawk/utils/TomahawkUtilsGui.cpp | 17 +++++++++++++++-- src/libtomahawk/utils/TomahawkUtilsGui.h | 2 ++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/libtomahawk/utils/TomahawkUtilsGui.cpp b/src/libtomahawk/utils/TomahawkUtilsGui.cpp index 4dfef653b..e867cc4c1 100644 --- a/src/libtomahawk/utils/TomahawkUtilsGui.cpp +++ b/src/libtomahawk/utils/TomahawkUtilsGui.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #ifdef Q_WS_X11 #include @@ -43,6 +44,7 @@ #ifdef Q_WS_WIN #include #include + #include #endif @@ -134,7 +136,7 @@ drawShadowText( QPainter* painter, const QRect& rect, const QString& text, const painter->save(); painter->drawText( rect, text, textOption ); - + /* QFont font = painter->font(); font.setPixelSize( font.pixelSize() + 2 ); painter->setFont( font ); @@ -182,7 +184,7 @@ drawBackgroundAndNumbers( QPainter* painter, const QString& text, const QRect& f painter->setPen( origpen ); painter->setPen( Qt::white ); painter->drawText( figRect.adjusted( -5, 0, 6, 0 ), text, QTextOption( Qt::AlignCenter ) ); - + painter->restore(); } @@ -293,6 +295,17 @@ bringToFront() #endif +void +openUrl( const QUrl& url ) +{ +#ifdef Q_OS_WIN + ShellExecuteW( 0, 0, (TCHAR*)url.toString().utf16(), 0, 0, SW_SHOWNORMAL ); +#else + QDesktopServices::openUrl( url ); +#endif +} + + QPixmap createAvatarFrame( const QPixmap &avatar ) { diff --git a/src/libtomahawk/utils/TomahawkUtilsGui.h b/src/libtomahawk/utils/TomahawkUtilsGui.h index 6e8f7d8bf..71e764074 100644 --- a/src/libtomahawk/utils/TomahawkUtilsGui.h +++ b/src/libtomahawk/utils/TomahawkUtilsGui.h @@ -45,6 +45,8 @@ namespace TomahawkUtils /// Platform-specific bringing tomahawk mainwindow to front, b/c qt's activate() and such don't seem to work well enough for us DLLEXPORT void bringToFront(); + DLLEXPORT void openUrl( const QUrl& url ); + DLLEXPORT QPixmap createAvatarFrame( const QPixmap &avatar ); DLLEXPORT QColor alphaBlend( const QColor& colorFrom, const QColor& colorTo, float opacity ); From a9dff282e3aa2022ded3595dc85e49466c6a4e33 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Thu, 12 Jul 2012 08:40:17 +0200 Subject: [PATCH 16/28] * Cleaned up DiagnosticsDialog. --- src/DiagnosticsDialog.cpp | 253 +++++++++++++------------------------- src/DiagnosticsDialog.h | 14 +-- src/DiagnosticsDialog.ui | 25 ++-- 3 files changed, 102 insertions(+), 190 deletions(-) diff --git a/src/DiagnosticsDialog.cpp b/src/DiagnosticsDialog.cpp index 1ed6e2255..7d33c5ded 100644 --- a/src/DiagnosticsDialog.cpp +++ b/src/DiagnosticsDialog.cpp @@ -22,10 +22,6 @@ #include "config.h" -#include "accounts/AccountManager.h" -#include "network/Servent.h" -#include "SourceList.h" - #include #include #include @@ -34,8 +30,13 @@ #include #include -#include "utils/Logger.h" +#include "accounts/AccountManager.h" +#include "network/Servent.h" +#include "SourceList.h" + #include "sip/SipHandler.h" +#include "utils/TomahawkUtilsGui.h" +#include "utils/Logger.h" DiagnosticsDialog::DiagnosticsDialog( QWidget *parent ) @@ -44,10 +45,9 @@ DiagnosticsDialog::DiagnosticsDialog( QWidget *parent ) { ui->setupUi( this ); - connect( ui->clipboardButton, SIGNAL( clicked() ), this, SLOT( copyToClipboard() ) ); - connect( ui->buttonBox, SIGNAL( rejected() ), this, SLOT( reject() ) ); - - ui->scrollAreaWidgetContents->setLayout( new QVBoxLayout() ); + connect( ui->clipboardButton, SIGNAL( clicked() ), SLOT( copyToClipboard() ) ); + connect( ui->logfileButton, SIGNAL( clicked() ), SLOT( openLogfile() ) ); + connect( ui->buttonBox, SIGNAL( rejected() ), SLOT( reject() ) ); updateLogView(); } @@ -58,16 +58,10 @@ DiagnosticsDialog::updateLogView() { QString log; - log.append( - QString("TOMAHAWK DIAGNOSTICS LOG -%1 \n\n") - .arg( QDateTime::currentDateTime().toString() ) - ); - - // network + log.append( QString( "TOMAHAWK DIAGNOSTICS LOG -%1 \n\n" ).arg( QDateTime::currentDateTime().toString() ) ); log.append( "TOMAHAWK-VERSION: " TOMAHAWK_VERSION "\n\n" ); - - // network log.append( "NETWORK:\n General:\n" ); + if ( Servent::instance()->visibleExternally() ) { log.append( @@ -86,9 +80,7 @@ DiagnosticsDialog::updateLogView() log.append( " visible: false" ); } - ui->scrollAreaWidgetContents->layout()->addWidget( new QLabel( log, this ) ); - // Peers / Accounts, TODO - ui->scrollAreaWidgetContents->layout()->addWidget( new QLabel( "ACCOUNTS:\n", this ) ); + log.append( "ACCOUNTS:\n" ); const QList< Tomahawk::source_ptr > sources = SourceList::instance()->sources( true ); const QList< Tomahawk::Accounts::Account* > accounts = Tomahawk::Accounts::AccountManager::instance()->accounts( Tomahawk::Accounts::SipType ); @@ -98,167 +90,98 @@ DiagnosticsDialog::updateLogView() if ( !account || !account->sipPlugin() ) continue; - connect( account, SIGNAL( connectionStateChanged( Tomahawk::Accounts::Account::ConnectionState ) ), - SLOT( onAccountConnectionStateChanged( Tomahawk::Accounts::Account::ConnectionState ) ) ); - connect( account, SIGNAL( error( int, QString ) ), - SLOT( onAccountError( int, QString ) ) ); + connect( account, SIGNAL( connectionStateChanged( Tomahawk::Accounts::Account::ConnectionState ) ), SLOT( updateLogView() ), Qt::UniqueConnection ); + connect( account, SIGNAL( error( int, QString ) ), SLOT( updateLogView() ), Qt::UniqueConnection ); + connect( account->sipPlugin(), SIGNAL( peerOnline( QString ) ), SLOT( updateLogView() ), Qt::UniqueConnection ); + connect( account->sipPlugin(), SIGNAL( peerOffline( QString ) ), SLOT( updateLogView() ), Qt::UniqueConnection ); + connect( account->sipPlugin(), SIGNAL( sipInfoReceived( QString, SipInfo ) ), SLOT( updateLogView() ), Qt::UniqueConnection ); + connect( account->sipPlugin(), SIGNAL( softwareVersionReceived( QString, QString ) ), SLOT( updateLogView() ), Qt::UniqueConnection ); - connect( account->sipPlugin(), SIGNAL( peerOnline( QString ) ), SLOT( onPeerOnline( QString ) ) ); - connect( account->sipPlugin(), SIGNAL( peerOffline( QString ) ), SLOT( onPeerOffline( QString ) ) ); - connect( account->sipPlugin(), SIGNAL( sipInfoReceived( QString, SipInfo ) ), SLOT( onSipInfoReceived( QString, SipInfo ) ) ); - connect( account->sipPlugin(), SIGNAL( softwareVersionReceived( QString, QString ) ), SLOT( onSoftwareVersionReceived( QString, QString ) ) ); - - QLabel* accountInfoLabel = new QLabel( this ); - ui->scrollAreaWidgetContents->layout()->addWidget( accountInfoLabel ); - m_accountDescriptionStore.insert( account, accountInfoLabel ); - - updateAccountLabel( account ); + log.append( accountLog( account ) + "\n" ); } - ui->scrollAreaWidgetContents->layout()->addItem( new QSpacerItem( 1, 1, QSizePolicy::Fixed, QSizePolicy::Expanding ) ); + ui->text->setText( log ); } void DiagnosticsDialog::copyToClipboard() { - QString log; - foreach ( QLabel* label, m_accountDescriptionStore.values() ) + QApplication::clipboard()->setText( ui->text->toPlainText() ); +} + + +void +DiagnosticsDialog::openLogfile() +{ + TomahawkUtils::openUrl( Logger::logFile() ); +} + + +QString +DiagnosticsDialog::accountLog( Tomahawk::Accounts::Account* account ) +{ + QString accountInfo; + QString stateString; + switch( account->connectionState() ) { - log += label->text() + "\n\n"; + case Tomahawk::Accounts::Account::Connecting: + stateString = "Connecting"; + break; + case Tomahawk::Accounts::Account::Connected: + stateString = "Connected"; + break; + + case Tomahawk::Accounts::Account::Disconnected: + stateString = "Disconnected"; + break; + case Tomahawk::Accounts::Account::Disconnecting: + stateString = "Disconnecting"; } + accountInfo.append( + QString( " %2 (%1): %3 (%4)\n" ) + .arg( account->accountServiceName() ) + .arg( account->sipPlugin()->friendlyName() ) + .arg( account->accountFriendlyName()) + .arg( stateString ) + ); - QApplication::clipboard()->setText( log ); -} - - -void -DiagnosticsDialog::onAccountConnectionStateChanged( Tomahawk::Accounts::Account::ConnectionState /* state */ ) -{ - Tomahawk::Accounts::Account* account = qobject_cast< Tomahawk::Accounts::Account* >( sender() ); - Q_ASSERT( account ); - - updateAccountLabel( account ); -} - - -void -DiagnosticsDialog::onAccountError( int /* errorId */ , QString /* errorString */ ) -{ - Tomahawk::Accounts::Account* account = qobject_cast< Tomahawk::Accounts::Account* >( sender() ); - Q_ASSERT( account ); -} - - -void -DiagnosticsDialog::onPeerOnline( const QString& ) -{ - Tomahawk::Accounts::Account* account = qobject_cast< SipPlugin* >( sender() )->account(); - Q_ASSERT( account ); - - updateAccountLabel( account ); -} - - -void -DiagnosticsDialog::onPeerOffline( const QString& ) -{ - Tomahawk::Accounts::Account* account = qobject_cast< SipPlugin* >( sender() )->account(); - Q_ASSERT( account ); - - updateAccountLabel( account ); -} - - -void -DiagnosticsDialog::onSipInfoReceived( const QString& /* peerId */ , const SipInfo& /* info */ ) -{ - Tomahawk::Accounts::Account* account = qobject_cast< SipPlugin* >( sender() )->account(); - Q_ASSERT( account ); - - updateAccountLabel( account ); -} - - -void -DiagnosticsDialog::onSoftwareVersionReceived( const QString& /* peerId */ , const QString& /* versionString */ ) -{ - Tomahawk::Accounts::Account* account = qobject_cast< SipPlugin* >( sender() )->account(); - Q_ASSERT( account ); - - updateAccountLabel( account ); -} - - -void -DiagnosticsDialog::updateAccountLabel( Tomahawk::Accounts::Account* account ) -{ - QLabel* accountInfoLabel = m_accountDescriptionStore.value( account ); - - if ( accountInfoLabel ) + foreach( const QString& peerId, account->sipPlugin()->peersOnline() ) { - QString accountInfo; - QString stateString; - switch( account->connectionState() ) + QString versionString = SipHandler::instance()->versionString( peerId ); + SipInfo sipInfo = SipHandler::instance()->sipInfo( peerId ); + if ( !sipInfo.isValid() ) { - case Tomahawk::Accounts::Account::Connecting: - stateString = "Connecting"; - break; - case Tomahawk::Accounts::Account::Connected: - stateString = "Connected"; - break; - - case Tomahawk::Accounts::Account::Disconnected: - stateString = "Disconnected"; - break; - case Tomahawk::Accounts::Account::Disconnecting: - stateString = "Disconnecting"; + accountInfo.append( + QString(" %1: %2 %3" /*"(%4)"*/ "\n") + .arg( peerId ) + .arg( "sipinfo invalid" ) + .arg( versionString ) + // .arg( connected ? "connected" : "not connected") + ); } - accountInfo.append( - QString( " %2 (%1): %3 (%4)\n" ) - .arg( account->accountServiceName() ) - .arg( account->sipPlugin()->friendlyName() ) - .arg( account->accountFriendlyName()) - .arg( stateString ) - ); - - foreach( const QString& peerId, account->sipPlugin()->peersOnline() ) + else if ( sipInfo.isVisible() ) { - QString versionString = SipHandler::instance()->versionString( peerId ); - SipInfo sipInfo = SipHandler::instance()->sipInfo( peerId ); - if ( !sipInfo.isValid() ) - { - accountInfo.append( - QString(" %1: %2 %3" /*"(%4)"*/ "\n") - .arg( peerId ) - .arg( "sipinfo invalid" ) - .arg( versionString ) - // .arg( connected ? "connected" : "not connected") - ); - } - else if ( sipInfo.isVisible() ) - { - accountInfo.append( - QString(" %1: %2:%3 %4" /*" (%5)"*/ "\n") - .arg( peerId ) - .arg( sipInfo.host() ) - .arg( sipInfo.port() ) - .arg( versionString ) - // .arg( connected ? "connected" : "not connected") - ); - } - else - { - accountInfo.append( - QString(" %1: visible: false %2" /*" (%3)"*/ "\n") - .arg( peerId ) - .arg( versionString ) - // .arg( connected ? "connected" : "not connected") - ); - } + accountInfo.append( + QString(" %1: %2:%3 %4" /*" (%5)"*/ "\n") + .arg( peerId ) + .arg( sipInfo.host() ) + .arg( sipInfo.port() ) + .arg( versionString ) + // .arg( connected ? "connected" : "not connected") + ); + } + else + { + accountInfo.append( + QString(" %1: visible: false %2" /*" (%3)"*/ "\n") + .arg( peerId ) + .arg( versionString ) + // .arg( connected ? "connected" : "not connected") + ); } - accountInfo.append( "\n" ); - - accountInfoLabel->setText( accountInfo ); } + accountInfo.append( "\n" ); + + return accountInfo; } \ No newline at end of file diff --git a/src/DiagnosticsDialog.h b/src/DiagnosticsDialog.h index 99da5aae9..4fa29dd6e 100644 --- a/src/DiagnosticsDialog.h +++ b/src/DiagnosticsDialog.h @@ -45,19 +45,11 @@ public: private slots: void updateLogView(); void copyToClipboard(); - - void onAccountConnectionStateChanged( Tomahawk::Accounts::Account::ConnectionState state ); - void onAccountError( int errorId, QString errorString ); - void onPeerOnline( const QString& ); - void onPeerOffline( const QString& ); - void onSipInfoReceived( const QString& peerId, const SipInfo& info ); - void onSoftwareVersionReceived( const QString& peerId, const QString& versionString ); + void openLogfile(); + + QString accountLog( Tomahawk::Accounts::Account* ); - void updateAccountLabel( Tomahawk::Accounts::Account* ); private: - - QMap< Tomahawk::Accounts::Account*, QLabel* > m_accountDescriptionStore; - Ui::DiagnosticsDialog* ui; }; diff --git a/src/DiagnosticsDialog.ui b/src/DiagnosticsDialog.ui index d304b65f6..c3e249d67 100644 --- a/src/DiagnosticsDialog.ui +++ b/src/DiagnosticsDialog.ui @@ -26,20 +26,10 @@ - - - true + + + QTextEdit::NoWrap - - - - 0 - 0 - 708 - 386 - - - @@ -49,7 +39,14 @@ - Copy to Clipboard + &Copy to Clipboard + + + + + + + Open &Log-file From daf895c53d06d5117af286f43cccfd06a68520fb Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Thu, 12 Jul 2012 09:14:33 +0200 Subject: [PATCH 17/28] * Try to fix compiling on mingw. --- src/libtomahawk/utils/TomahawkUtilsGui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libtomahawk/utils/TomahawkUtilsGui.cpp b/src/libtomahawk/utils/TomahawkUtilsGui.cpp index e867cc4c1..669041e22 100644 --- a/src/libtomahawk/utils/TomahawkUtilsGui.cpp +++ b/src/libtomahawk/utils/TomahawkUtilsGui.cpp @@ -299,7 +299,7 @@ void openUrl( const QUrl& url ) { #ifdef Q_OS_WIN - ShellExecuteW( 0, 0, (TCHAR*)url.toString().utf16(), 0, 0, SW_SHOWNORMAL ); + ShellExecuteW( 0, 0, (LPCWSTR*)url.toString().utf16(), 0, 0, SW_SHOWNORMAL ); #else QDesktopServices::openUrl( url ); #endif From 3f50bace71ae656cc7344b6d82777e49f2156460 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Thu, 12 Jul 2012 09:47:09 +0200 Subject: [PATCH 18/28] * Really fix compiling on Windows. --- src/libtomahawk/utils/TomahawkUtilsGui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libtomahawk/utils/TomahawkUtilsGui.cpp b/src/libtomahawk/utils/TomahawkUtilsGui.cpp index 669041e22..4b981f9ec 100644 --- a/src/libtomahawk/utils/TomahawkUtilsGui.cpp +++ b/src/libtomahawk/utils/TomahawkUtilsGui.cpp @@ -299,7 +299,7 @@ void openUrl( const QUrl& url ) { #ifdef Q_OS_WIN - ShellExecuteW( 0, 0, (LPCWSTR*)url.toString().utf16(), 0, 0, SW_SHOWNORMAL ); + ShellExecuteW( 0, 0, (LPCWSTR)url.toString().utf16(), 0, 0, SW_SHOWNORMAL ); #else QDesktopServices::openUrl( url ); #endif From c09dcc74e3b302317468ade45b927967199dcd65 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Thu, 12 Jul 2012 10:00:21 +0200 Subject: [PATCH 19/28] * Updated ChangeLog. --- ChangeLog | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index 5cae48c3b..678c7aed1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,11 @@ Version 0.6.0: * Access Control queries now stay on the bottom of the job view, removing the tendency to jump away from the mouse. +Version 0.5.4: + * Improved stability. + * Fixed not always updating the database index after scanning. + * Fixed connection issue between Tomahawk peers. + Version 0.5.3: * Fixed broken artist names when importing Last.fm playback history. * Fixed crash when filtering collections. From f239473f0c8b1b03fbb34ccd7f691605ec0b61c5 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Thu, 12 Jul 2012 11:22:25 +0200 Subject: [PATCH 20/28] * Style fixes. --- src/TomahawkWindow.cpp | 80 ++++++++++++++++++++++-------------------- src/TomahawkWindow.h | 2 +- 2 files changed, 43 insertions(+), 39 deletions(-) diff --git a/src/TomahawkWindow.cpp b/src/TomahawkWindow.cpp index f6c34cacc..5cc182325 100644 --- a/src/TomahawkWindow.cpp +++ b/src/TomahawkWindow.cpp @@ -362,7 +362,6 @@ TomahawkWindow::setupWindowsButtons() m_thumbButtons[TP_PLAY_PAUSE].dwFlags = THBF_ENABLED; m_thumbButtons[TP_PLAY_PAUSE].szTip[ tr( "Play" ).toWCharArray( m_thumbButtons[TP_PLAY_PAUSE].szTip ) ] = 0; - m_thumbButtons[TP_NEXT].dwMask = dwMask; m_thumbButtons[TP_NEXT].iId = TP_NEXT; m_thumbButtons[TP_NEXT].hIcon = next.toWinHICON(); @@ -629,61 +628,66 @@ TomahawkWindow::winEvent( MSG* msg, long* result ) return false; } -void TomahawkWindow::audioStateChanged( AudioState newState, AudioState oldState ) + +void +TomahawkWindow::audioStateChanged( AudioState newState, AudioState oldState ) { - if(m_taskbarList == 0) + if ( m_taskbarList == 0 ) return; - switch(newState){ - case AudioEngine::Playing: + + switch ( newState ) { - QPixmap pause( RESPATH "images/pause-rest.png" ); - m_thumbButtons[TP_PLAY_PAUSE].hIcon = pause.toWinHICON(); - m_thumbButtons[TP_PLAY_PAUSE].szTip[ tr( "Pause" ).toWCharArray( m_thumbButtons[TP_PLAY_PAUSE].szTip ) ] = 0; - - if ( !AudioEngine::instance()->currentTrack().isNull() && AudioEngine::instance()->currentTrack()->toQuery()->loved()) + case AudioEngine::Playing: { - QPixmap loved( RESPATH "images/loved.png" ); - m_thumbButtons[TP_LOVE].hIcon = loved.toWinHICON(); - m_thumbButtons[TP_LOVE].szTip[ tr( "Unlove" ).toWCharArray( m_thumbButtons[TP_LOVE].szTip ) ] = 0; + QPixmap pause( RESPATH "images/pause-rest.png" ); + m_thumbButtons[TP_PLAY_PAUSE].hIcon = pause.toWinHICON(); + m_thumbButtons[TP_PLAY_PAUSE].szTip[ tr( "Pause" ).toWCharArray( m_thumbButtons[TP_PLAY_PAUSE].szTip ) ] = 0; + if ( !AudioEngine::instance()->currentTrack().isNull() && AudioEngine::instance()->currentTrack()->toQuery()->loved() ) + { + QPixmap loved( RESPATH "images/loved.png" ); + m_thumbButtons[TP_LOVE].hIcon = loved.toWinHICON(); + m_thumbButtons[TP_LOVE].szTip[ tr( "Unlove" ).toWCharArray( m_thumbButtons[TP_LOVE].szTip ) ] = 0; + } + else + { + QPixmap not_loved( RESPATH "images/not-loved.png" ); + m_thumbButtons[TP_LOVE].hIcon = not_loved.toWinHICON(); + m_thumbButtons[TP_LOVE].szTip[ tr( "Love" ).toWCharArray( m_thumbButtons[TP_LOVE].szTip ) ] = 0; + } + m_thumbButtons[TP_LOVE].dwFlags = THBF_ENABLED; } - else + break; + + case AudioEngine::Paused: { + QPixmap play( RESPATH "images/play-rest.png" ); + m_thumbButtons[TP_PLAY_PAUSE].hIcon = play.toWinHICON(); + m_thumbButtons[TP_PLAY_PAUSE].szTip[ tr( "Play" ).toWCharArray( m_thumbButtons[TP_PLAY_PAUSE].szTip ) ] = 0; + } + break; + + case AudioEngine::Stopped: + { + QPixmap play( RESPATH "images/play-rest.png" ); + m_thumbButtons[TP_PLAY_PAUSE].hIcon = play.toWinHICON(); + m_thumbButtons[TP_PLAY_PAUSE].szTip[ tr( "Play" ).toWCharArray( m_thumbButtons[TP_PLAY_PAUSE].szTip ) ] = 0; + QPixmap not_loved( RESPATH "images/not-loved.png" ); m_thumbButtons[TP_LOVE].hIcon = not_loved.toWinHICON(); - m_thumbButtons[TP_LOVE].szTip[ tr( "Love" ).toWCharArray( m_thumbButtons[TP_LOVE].szTip ) ] = 0; + m_thumbButtons[TP_LOVE].dwFlags = THBF_DISABLED; } - m_thumbButtons[TP_LOVE].dwFlags = THBF_ENABLED; - } break; - case AudioEngine::Paused: - { - QPixmap play( RESPATH "images/play-rest.png" ); - m_thumbButtons[TP_PLAY_PAUSE].hIcon = play.toWinHICON(); - m_thumbButtons[TP_PLAY_PAUSE].szTip[ tr( "Play" ).toWCharArray( m_thumbButtons[TP_PLAY_PAUSE].szTip ) ] = 0; - } - break; - case AudioEngine::Stopped: - { - QPixmap play( RESPATH "images/play-rest.png" ); - m_thumbButtons[TP_PLAY_PAUSE].hIcon = play.toWinHICON(); - m_thumbButtons[TP_PLAY_PAUSE].szTip[ tr( "Play" ).toWCharArray( m_thumbButtons[TP_PLAY_PAUSE].szTip ) ] = 0; - QPixmap not_loved( RESPATH "images/not-loved.png" ); - m_thumbButtons[TP_LOVE].hIcon = not_loved.toWinHICON(); - m_thumbButtons[TP_LOVE].dwFlags = THBF_DISABLED; - } - break; - default: - return; + default: + return; } + m_taskbarList->ThumbBarUpdateButtons( winId(), ARRAYSIZE( m_thumbButtons ), m_thumbButtons ); } - #endif - void TomahawkWindow::onHistoryBackAvailable( bool avail ) { diff --git a/src/TomahawkWindow.h b/src/TomahawkWindow.h index 07f900a23..c0220039b 100644 --- a/src/TomahawkWindow.h +++ b/src/TomahawkWindow.h @@ -32,7 +32,7 @@ #include "utils/XspfLoader.h" #ifdef Q_OS_WIN -#include + #include #endif namespace Tomahawk From 6901a9f47e2f3552af7eaec9e4be3ae08dec1db3 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Thu, 12 Jul 2012 11:50:21 -0400 Subject: [PATCH 21/28] Pointer safety --- src/libtomahawk/database/DatabaseCommand_LogPlayback.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libtomahawk/database/DatabaseCommand_LogPlayback.cpp b/src/libtomahawk/database/DatabaseCommand_LogPlayback.cpp index 37e089940..a9839b47e 100644 --- a/src/libtomahawk/database/DatabaseCommand_LogPlayback.cpp +++ b/src/libtomahawk/database/DatabaseCommand_LogPlayback.cpp @@ -54,6 +54,10 @@ DatabaseCommand_LogPlayback::postCommitHook() // do not auto resolve this track m_query = Tomahawk::Query::get( m_artist, m_track, QString() ); } + + if ( m_query.isNull() ) + return; + m_query->setPlayedBy( source(), m_playtime ); if ( m_action == Finished ) From 3d3c381dd7c816230f54247df237bafe291ce6d5 Mon Sep 17 00:00:00 2001 From: Tomahawk CI Date: Thu, 12 Jul 2012 22:17:52 +0000 Subject: [PATCH 22/28] Automatic merge of Transifex translations --- lang/tomahawk_ar.ts | 87 ++++++++++++++++++++++------------------- lang/tomahawk_bg.ts | 87 ++++++++++++++++++++++------------------- lang/tomahawk_ca.ts | 87 ++++++++++++++++++++++------------------- lang/tomahawk_de.ts | 89 ++++++++++++++++++++++-------------------- lang/tomahawk_en.ts | 87 ++++++++++++++++++++++------------------- lang/tomahawk_es.ts | 87 ++++++++++++++++++++++------------------- lang/tomahawk_fr.ts | 87 ++++++++++++++++++++++------------------- lang/tomahawk_ja.ts | 87 ++++++++++++++++++++++------------------- lang/tomahawk_pl.ts | 87 ++++++++++++++++++++++------------------- lang/tomahawk_pt_BR.ts | 87 ++++++++++++++++++++++------------------- lang/tomahawk_ru.ts | 87 ++++++++++++++++++++++------------------- lang/tomahawk_sv.ts | 87 ++++++++++++++++++++++------------------- lang/tomahawk_tr.ts | 87 ++++++++++++++++++++++------------------- lang/tomahawk_zh_CN.ts | 87 ++++++++++++++++++++++------------------- lang/tomahawk_zh_TW.ts | 87 ++++++++++++++++++++++------------------- 15 files changed, 691 insertions(+), 616 deletions(-) diff --git a/lang/tomahawk_ar.ts b/lang/tomahawk_ar.ts index c92fa3677..41f6e1ebd 100644 --- a/lang/tomahawk_ar.ts +++ b/lang/tomahawk_ar.ts @@ -472,9 +472,14 @@ connect and stream from you? تشخيص توماهوك - - Copy to Clipboard - نسخ إلى الحافظة + + &Copy to Clipboard + + + + + Open &Log-file + @@ -730,7 +735,7 @@ connect and stream from you? تقدم - + - Properties - خصائص @@ -3219,7 +3224,7 @@ enter the displayed PIN number here: - + Play إستمع @@ -3239,172 +3244,172 @@ enter the displayed PIN number here: التالي - + Back إلى الوراء - + Go back one page العودة صفحة واحدة إلى الوراء - + Forward تقدم - + Go forward one page تقدم صفحة واحدة - + Global Search... بحث شامل... - - + + Check For Updates... التحقق من التحديثات... - - - + + + Connect To Peer ربط بالند - + Enter peer address: أدخل عنوان الند: - + Enter peer port: أدخل بوابة الند: - + Enter peer key: أدخل مفتاح الند: - + XSPF Error خطأ XSPF - + This is not a valid XSPF playlist. قائمة الأغاني XSPF هذه ليست صالحة. - + Failed to save tracks فشل في حفظ الأغاني - + Some tracks in the playlist do not contain an artist and a title. They will be ignored. بعض الأغاني في قائمة الأغاني لا تحتوي على إسم الفنان أو إسم الأغنية. هذه الأغاني سوف تتجاهل. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. Make sure you have a suitable Phonon backend and required plugins installed. عذرا، هناك مشكلة في الوصول إلى جهاز الصوت أو الأغنية المطلوب، سوف يتم تخطي الأغنية الحالية. تأكد أن لديك خلفية فونون المناسبة والإضافات المطلوبة مثبتة. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. عذرا، هناك مشكلة في الوصول إلى جهاز الصوت أو الأغنية المطلوب، سوف يتم تخطي الأغنية الحالية. - + Station إذاعة - + Create New Station إنشاء قائمة أغاني جديدة - + Name: الاسم: - + Playlist قائمة الأغاني - + Automatic Playlist قائمة أغاني أوتوماتيكية - + Pause تعليق - + Go &offline أصبح &غير متصل - + Go &online اصبح &متصل - + Authentication Error خطأ في المصادقة - + Error connecting to SIP: Authentication failed! خطأ في الاتصال بسيب (SIP): فشلت المصادقة! - + %1 by %2 track, artist name %1 من قبل %2 - + %1 - %2 current track, some window title %1 - %2 - + <h2><b>Tomahawk %1<br/>(%2)</h2> <h2><b>Tomahawk %1<br/>(%2)</h2> - + <h2><b>Tomahawk %1</h2> <h2><b>Tomahawk %1</h2> - + Copyright 2010 - 2012 حقوق الطبع والنشر ٢٠١٠ - ٢٠١٢ - + Thanks to: شكر لكل من: - + About Tomahawk عن توماهوك diff --git a/lang/tomahawk_bg.ts b/lang/tomahawk_bg.ts index 68c491a1f..0ae5c430d 100644 --- a/lang/tomahawk_bg.ts +++ b/lang/tomahawk_bg.ts @@ -474,9 +474,14 @@ Tomahaw създаде доклад относно това и изпращай Диагностична информация относно Tomahawk - - Copy to Clipboard - Копирай в буферът + + &Copy to Clipboard + + + + + Open &Log-file + @@ -732,7 +737,7 @@ Tomahaw създаде доклад относно това и изпращай - + - Properties @@ -3226,7 +3231,7 @@ enter the displayed PIN number here: - + Play Изпълни @@ -3246,175 +3251,175 @@ enter the displayed PIN number here: Следваща - + Back - + Go back one page Една страница назад - + Forward Напред - + Go forward one page Една страница напред - + Global Search... Глобално търсене... - - + + Check For Updates... Провери за обновления... - - - + + + Connect To Peer Свържи се с друг потребител - + Enter peer address: Въведи адресът на отдалеченият потребител: - + Enter peer port: Въведи порт: - + Enter peer key: Въведи ключът за удостоверяване: - + XSPF Error XSPF Грешка - + This is not a valid XSPF playlist. Това не е валиден XSPF списък - + Failed to save tracks Не мога да запазя списъкът с песни - + Some tracks in the playlist do not contain an artist and a title. They will be ignored. Някои от песните в този списък нямат артист и заглавие. Те ще бъдат игнорирани. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. Make sure you have a suitable Phonon backend and required plugins installed. Съжалявам. Има проблем с достъпа до твоето аудио-устройство или до избраната песен - тя ще бъде прескочена. Моля, увери се, че са инсталирани подходящ Phonon и приставки. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. Съжалявам. Има проблем с достъпа до твоето аудио устройство или избраната песен. Тя ще бъде пропусната. - + Station Станция - + Create New Station Създай нова станция - + Name: Име: - + Playlist Списък - + Automatic Playlist Автоматично-генериран списък - + Pause Пауза - + Go &offline Излез &извън линия - + Go &online Свържи &се - + Authentication Error Грешка при удостоверяване - + Error connecting to SIP: Authentication failed! Грешка при свързване: Неуспешно удостоверяване! - + %1 by %2 track, artist name %1 от %2 - + %1 - %2 current track, some window title %1 - %2 - + <h2><b>Tomahawk %1<br/>(%2)</h2> <h2><b>Tomahawk %1<br/>(%2)</h2> - + <h2><b>Tomahawk %1</h2> <h2><b>Tomahawk %1</h2> - + Copyright 2010 - 2012 Всички права - запазени. 2010 - 2012 - + Thanks to: Благодарности на: - + About Tomahawk Относно Tomahawk diff --git a/lang/tomahawk_ca.ts b/lang/tomahawk_ca.ts index 06d38cfbf..578d03edc 100644 --- a/lang/tomahawk_ca.ts +++ b/lang/tomahawk_ca.ts @@ -471,9 +471,14 @@ connect and stream from you? Diagnòstics de Tomahawk - - Copy to Clipboard - Copia al Porta-retalls + + &Copy to Clipboard + + + + + Open &Log-file + @@ -729,7 +734,7 @@ connect and stream from you? - + - Properties @@ -3218,7 +3223,7 @@ introduïu el PIN aquí: - + Play Reprodueix @@ -3238,172 +3243,172 @@ introduïu el PIN aquí: Següent - + Back Enrere - + Go back one page Retrocedeix una pàgina - + Forward Endavant - + Go forward one page Avança una pàgina - + Global Search... Cerca Global... - - + + Check For Updates... Comprova les actualitzacions... - - - + + + Connect To Peer Connexió Remota - + Enter peer address: Introduïu l'adreça remota: - + Enter peer port: Introduïu el port remot: - + Enter peer key: Introduïu la clau remota: - + XSPF Error Error XSPF - + This is not a valid XSPF playlist. No és una llista XSPF vàlida. - + Failed to save tracks Error en desar les cançons - + Some tracks in the playlist do not contain an artist and a title. They will be ignored. Algunes cançons de la llista no contenen ni artista ni titol i s'han ignorat. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. Make sure you have a suitable Phonon backend and required plugins installed. Hi ha un problema per accedir al dispositiu de so o a la cançó. La cançó actual s'ha saltat. Assegureu-vos que teniu un back.end de Phonon adequant i els plugins necessaris instal·lats. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. Hi ha un problema per accedir al dispositiu de so o a la cançó, la cançó actual s'ha saltat. - + Station Emissora - + Create New Station Crea una Nova Emissora - + Name: Nom: - + Playlist Llista - + Automatic Playlist Llista Automàtica - + Pause Pausa - + Go &offline &Desconnecta't - + Go &online &Connecta't - + Authentication Error Error d'autentificació - + Error connecting to SIP: Authentication failed! S'ha produït un error connectant-se a SIP: Ha fallat autentificant! - + %1 by %2 track, artist name %1 de %2 - + %1 - %2 current track, some window title %1 - %2 - + <h2><b>Tomahawk %1<br/>(%2)</h2> <h2><b>Tomahawk %1<br/>(%2)</h2> - + <h2><b>Tomahawk %1</h2> <h2><b>Tomahawk %1</h2> - + Copyright 2010 - 2012 Copyright 2010 - 2012 - + Thanks to: Gràcies a: - + About Tomahawk Quant a Tomahawk diff --git a/lang/tomahawk_de.ts b/lang/tomahawk_de.ts index cfe87b43a..5bbf3920d 100644 --- a/lang/tomahawk_de.ts +++ b/lang/tomahawk_de.ts @@ -472,9 +472,14 @@ erlauben sich mit dir zu verbinden? Tomahawk Diagnose Tool - - Copy to Clipboard - In die Zwischenablage kopieren + + &Copy to Clipboard + + + + + Open &Log-file + @@ -730,7 +735,7 @@ erlauben sich mit dir zu verbinden? Vorwärts - + - Properties - Eigenschaften @@ -786,7 +791,7 @@ erlauben sich mit dir zu verbinden? Composer - Komponent + Komponist @@ -3214,7 +3219,7 @@ Tomahawk auf Twitter's Website authentifiziert hast: - + Play Abspielen @@ -3234,172 +3239,172 @@ Tomahawk auf Twitter's Website authentifiziert hast: Weiter - + Back Zurück - + Go back one page Gehe eine Seite zurück - + Forward Vorwärts - + Go forward one page Gehe eine Seite vorwärts - + Global Search... Globale Suche... - - + + Check For Updates... Nach Updates suchen... - - - + + + Connect To Peer Mit anderem Tomahawk verbinden - + Enter peer address: Gib die Adresse der Gegenstelle ein: - + Enter peer port: Gib den Port der Gegenstelle ein: - + Enter peer key: Gib den Schlüssel der Gegenstelle ein: - + XSPF Error XSPF-Fehler - + This is not a valid XSPF playlist. Dies ist keine gültige XSPF-Playlist. - + Failed to save tracks Konnte Stücke nicht abspeichern - + Some tracks in the playlist do not contain an artist and a title. They will be ignored. Einige Stücke in der Playlist enthalten weder Künstler noch Titel. Diese werden ignoriert. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. Make sure you have a suitable Phonon backend and required plugins installed. Es tut uns leid, Tomahawk kann auf dein Audio-Gerät oder das gewünschte Stück nicht zugreifen und überspringt es deshalb. Vergewisser dich, dass ein geignetes Phonon-Backend mitsamt benötigten Plugins installiert ist. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. Es tut uns leid, Tomahawk kann auf dein Audio-Gerät oder das gewünschte Stück nicht zugreifen und überspringt es deshalb. - + Station Station - + Create New Station Neue Station erstellen - + Name: Name: - + Playlist Playlist - + Automatic Playlist Automatische Playlist - + Pause Pause - + Go &offline Verbindung &trennen - + Go &online &Verbindung herstellen - + Authentication Error Authentifizierungsfehler - + Error connecting to SIP: Authentication failed! Verbindungsfehler mit SIP: Authentifizierung fehlgeschlagen! - + %1 by %2 track, artist name %1 von %2 - + %1 - %2 current track, some window title %1 - %2 - + <h2><b>Tomahawk %1<br/>(%2)</h2> <h2><b>Tomahawk %1<br/>(%2)</h2> - + <h2><b>Tomahawk %1</h2> <h2><b>Tomahawk %1</h2> - + Copyright 2010 - 2012 Copright 2010 - 2012 - + Thanks to: Danke an: - + About Tomahawk Über Tomahawk diff --git a/lang/tomahawk_en.ts b/lang/tomahawk_en.ts index 7362f034a..52dafea70 100644 --- a/lang/tomahawk_en.ts +++ b/lang/tomahawk_en.ts @@ -472,9 +472,14 @@ connect and stream from you? Tomahawk Diagnostics - - Copy to Clipboard - Copy to Clipboard + + &Copy to Clipboard + &Copy to Clipboard + + + + Open &Log-file + Open &Log-file @@ -730,7 +735,7 @@ connect and stream from you? Forward - + - Properties - Properties @@ -3219,7 +3224,7 @@ enter the displayed PIN number here: - + Play Play @@ -3239,172 +3244,172 @@ enter the displayed PIN number here: Next - + Back Back - + Go back one page Go back one page - + Forward Forward - + Go forward one page Go forward one page - + Global Search... Global Search... - - + + Check For Updates... Check For Updates... - - - + + + Connect To Peer Connect To Peer - + Enter peer address: Enter peer address: - + Enter peer port: Enter peer port: - + Enter peer key: Enter peer key: - + XSPF Error XSPF Error - + This is not a valid XSPF playlist. This is not a valid XSPF playlist. - + Failed to save tracks Failed to save tracks - + Some tracks in the playlist do not contain an artist and a title. They will be ignored. Some tracks in the playlist do not contain an artist and a title. They will be ignored. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. Make sure you have a suitable Phonon backend and required plugins installed. Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. Make sure you have a suitable Phonon backend and required plugins installed. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. - + Station Station - + Create New Station Create New Station - + Name: Name: - + Playlist Playlist - + Automatic Playlist Automatic Playlist - + Pause Pause - + Go &offline Go &offline - + Go &online Go &online - + Authentication Error Authentication Error - + Error connecting to SIP: Authentication failed! Error connecting to SIP: Authentication failed! - + %1 by %2 track, artist name %1 by %2 - + %1 - %2 current track, some window title %1 - %2 - + <h2><b>Tomahawk %1<br/>(%2)</h2> <h2><b>Tomahawk %1<br/>(%2)</h2> - + <h2><b>Tomahawk %1</h2> <h2><b>Tomahawk %1</h2> - + Copyright 2010 - 2012 Copyright 2010 - 2012 - + Thanks to: Thanks to: - + About Tomahawk About Tomahawk diff --git a/lang/tomahawk_es.ts b/lang/tomahawk_es.ts index d65d653c2..ad5dbfa8a 100644 --- a/lang/tomahawk_es.ts +++ b/lang/tomahawk_es.ts @@ -471,9 +471,14 @@ connect and stream from you? Diagnósticos de Tomahawk - - Copy to Clipboard - Copiar al portapapeles + + &Copy to Clipboard + + + + + Open &Log-file + @@ -729,7 +734,7 @@ connect and stream from you? - + - Properties @@ -3217,7 +3222,7 @@ introduzca su número PIN aquí: - + Play Reproducir @@ -3237,172 +3242,172 @@ introduzca su número PIN aquí: Siguiente - + Back - + Go back one page - + Forward - + Go forward one page - + Global Search... Búsqueda global... - - + + Check For Updates... Buscar actualizaciones... - - - + + + Connect To Peer Conectar a un par - + Enter peer address: Introducir dirección del par: - + Enter peer port: Introducir puerto del par: - + Enter peer key: Introducir contraseña del par: - + XSPF Error Error XSPF - + This is not a valid XSPF playlist. Esta no es una lista de reproducción XSPF válida. - + Failed to save tracks Fallo al guardar pistas - + Some tracks in the playlist do not contain an artist and a title. They will be ignored. Algunas pistas en la lista de reproducción no contienen artista ni título. Serán ignoradas. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. Make sure you have a suitable Phonon backend and required plugins installed. Se ha producido un error al acceder al dispostivo de audio o al tema deseado y se va saltar. Asegúrese de que ha instalado un backend de Phonon adecuado y los plugins necesarios. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. Se ha producido un error al acceder al dispostivo de audio o al tema deseado y se va saltar. - + Station - + Create New Station Crear nueva estación - + Name: Nombre: - + Playlist - + Automatic Playlist - + Pause Pausar - + Go &offline &Desconectarse - + Go &online &Conectarse - + Authentication Error Error de autenticación - + Error connecting to SIP: Authentication failed! - + %1 by %2 track, artist name %1 por %2 - + %1 - %2 current track, some window title %1 - %2 - + <h2><b>Tomahawk %1<br/>(%2)</h2> <h2><b>Tomahawk %1<br/>(%2)</h2> - + <h2><b>Tomahawk %1</h2> <h2><b>Tomahawk %1</h2> - + Copyright 2010 - 2012 - + Thanks to: - + About Tomahawk Acerca de Tomahawk diff --git a/lang/tomahawk_fr.ts b/lang/tomahawk_fr.ts index b7647c919..b02fa3971 100644 --- a/lang/tomahawk_fr.ts +++ b/lang/tomahawk_fr.ts @@ -472,9 +472,14 @@ de se connecter et streamer de vous? Diagnostics de Tomahawk - - Copy to Clipboard - Copier dans le presse papier + + &Copy to Clipboard + + + + + Open &Log-file + @@ -730,7 +735,7 @@ de se connecter et streamer de vous? Avancer - + - Properties - Propriétés @@ -3219,7 +3224,7 @@ saisissez le numéro PIN ici : - + Play Lecture @@ -3239,172 +3244,172 @@ saisissez le numéro PIN ici : Suivant - + Back Retour - + Go back one page Reculer d'une page - + Forward Avancer - + Go forward one page Avancer d'une page - + Global Search... Recherche Globale... - - + + Check For Updates... Rechercher une mise à jour... - - - + + + Connect To Peer Connexion à un pair - + Enter peer address: Adresse du pair : - + Enter peer port: Port du pair : - + Enter peer key: Clé du pair : - + XSPF Error Erreur XSPF - + This is not a valid XSPF playlist. Ceci n'est pas une liste de lecture XSPF valide. - + Failed to save tracks Échec de la sauvegarde des pistes - + Some tracks in the playlist do not contain an artist and a title. They will be ignored. Certaines pistes dans la liste de lecture ne contiennent pas d'artiste ou de titre. Elles seront ignorées. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. Make sure you have a suitable Phonon backend and required plugins installed. Désolé, il y a un problème d'accès à votre matériel audio ou la piste en cours va être sautée. Vérifiez que vous avez un backend Phonon et les plugins requis installés. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. Désolé, il y a un problème d'accès à votre matériel audio ou la piste en cours va être sauter. - + Station Station - + Create New Station Créer une nouvelle station - + Name: Nom : - + Playlist Liste de lecture - + Automatic Playlist Liste de lecture automatique - + Pause Pause - + Go &offline Se &déconnecter - + Go &online Se c&onnecter - + Authentication Error Erreur d'authentification - + Error connecting to SIP: Authentication failed! Erreur de connexion SIP : échec de l'authentification ! - + %1 by %2 track, artist name %1 par %2 - + %1 - %2 current track, some window title %1 - %2 - + <h2><b>Tomahawk %1<br/>(%2)</h2> <h2><b>Tomahawk %1<br/>(%2)</h2> - + <h2><b>Tomahawk %1</h2> <h2><b>Tomahawk %1</h2> - + Copyright 2010 - 2012 Droit d'auteur 2010 - 2012 - + Thanks to: Merci a: - + About Tomahawk A propos de Tomahawk diff --git a/lang/tomahawk_ja.ts b/lang/tomahawk_ja.ts index cfaa5e0c5..664ad2fbf 100644 --- a/lang/tomahawk_ja.ts +++ b/lang/tomahawk_ja.ts @@ -472,9 +472,14 @@ connect and stream from you? Tomahawkの診断 - - Copy to Clipboard - クリップボードにコピーする + + &Copy to Clipboard + + + + + Open &Log-file + @@ -730,7 +735,7 @@ connect and stream from you? - + - Properties @@ -3209,7 +3214,7 @@ Meta+Ctrl+Z - + Play 再生 @@ -3229,172 +3234,172 @@ Meta+Ctrl+Z 次へ - + Back プレイリスト - + Go back one page - + Forward - + Go forward one page - + Global Search... - - + + Check For Updates... - - - + + + Connect To Peer - + Enter peer address: - + Enter peer port: - + Enter peer key: - + XSPF Error - + This is not a valid XSPF playlist. - + Failed to save tracks - + Some tracks in the playlist do not contain an artist and a title. They will be ignored. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. Make sure you have a suitable Phonon backend and required plugins installed. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. - + Station ステーション - + Create New Station 新規ステーションを作成 - + Name: 名前: - + Playlist プレイリスト - + Automatic Playlist - + Pause 一時停止 - + Go &offline - + Go &online - + Authentication Error - + Error connecting to SIP: Authentication failed! - + %1 by %2 track, artist name %1 by %2 - + %1 - %2 current track, some window title %1 - %2 - + <h2><b>Tomahawk %1<br/>(%2)</h2> <h2><b>Tomahawk %1<br/>(%2)</h2> - + <h2><b>Tomahawk %1</h2> <h2><b>Tomahawk %1</h2> - + Copyright 2010 - 2012 Copyright 2010 - 2012 - + Thanks to: Thanks to: - + About Tomahawk Tomahawkについて diff --git a/lang/tomahawk_pl.ts b/lang/tomahawk_pl.ts index 762469948..638f26874 100644 --- a/lang/tomahawk_pl.ts +++ b/lang/tomahawk_pl.ts @@ -471,9 +471,14 @@ connect and stream from you? Diagnostyka Tomahawk - - Copy to Clipboard - Skopiuj do schowka + + &Copy to Clipboard + + + + + Open &Log-file + @@ -729,7 +734,7 @@ connect and stream from you? - + - Properties @@ -3213,7 +3218,7 @@ wprowadź pokazany numer PIN tutaj: - + Play Odtwarzaj @@ -3233,172 +3238,172 @@ wprowadź pokazany numer PIN tutaj: Następny - + Back - + Go back one page - + Forward - + Go forward one page - + Global Search... Globalne Wyszukiwanie... - - + + Check For Updates... Sprawdź uaktualnienia... - - - + + + Connect To Peer - + Enter peer address: - + Enter peer port: - + Enter peer key: - + XSPF Error Błąd XSPF - + This is not a valid XSPF playlist. To nie jest poprawna lista XSPF. - + Failed to save tracks Nie udało się zapisać utworów - + Some tracks in the playlist do not contain an artist and a title. They will be ignored. Niektóre utwory na liście nie zawierają artysty i tytułu. Zostaną one zignorowane. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. Make sure you have a suitable Phonon backend and required plugins installed. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. - + Station - + Create New Station Utwórz Nową Stację - + Name: Nazwa: - + Playlist - + Automatic Playlist - + Pause Pauza - + Go &offline Przejdź do trybu &offline - + Go &online Przejdź do trybu &online - + Authentication Error Błąd uwierzytelniania - + Error connecting to SIP: Authentication failed! - + %1 by %2 track, artist name %1 wykonawcy %2 - + %1 - %2 current track, some window title %1 - %2 - + <h2><b>Tomahawk %1<br/>(%2)</h2> - + <h2><b>Tomahawk %1</h2> - + Copyright 2010 - 2012 - + Thanks to: - + About Tomahawk diff --git a/lang/tomahawk_pt_BR.ts b/lang/tomahawk_pt_BR.ts index b392c4e7b..58ae843f8 100644 --- a/lang/tomahawk_pt_BR.ts +++ b/lang/tomahawk_pt_BR.ts @@ -472,9 +472,14 @@ se conecte e faça o stream de você? Diagnósticos do Tomahawk - - Copy to Clipboard - Copiar + + &Copy to Clipboard + + + + + Open &Log-file + @@ -730,7 +735,7 @@ se conecte e faça o stream de você? Avançar - + - Properties - Propriedades @@ -3219,7 +3224,7 @@ colocar o número PIN mostrado aqui: - + Play Reporduzir @@ -3239,172 +3244,172 @@ colocar o número PIN mostrado aqui: Próximo - + Back Voltar - + Go back one page Voltar uma página - + Forward Avançar - + Go forward one page Avançar uma página - + Global Search... Busca global... - - + + Check For Updates... Buscar atualizações... - - - + + + Connect To Peer Conectar-se ao par - + Enter peer address: Coloque o endereço do par: - + Enter peer port: Coloque a porta do par: - + Enter peer key: Coloque a chave do par: - + XSPF Error Erro de XSPF - + This is not a valid XSPF playlist. Esta não é uma lista de reprodução XSPF válida. - + Failed to save tracks Falha ao salvar faixas - + Some tracks in the playlist do not contain an artist and a title. They will be ignored. Algumas faixas da lista de reprodução não contem artista e título. Estas serão ignoradas. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. Make sure you have a suitable Phonon backend and required plugins installed. Desculpe, há um problema ao acessar sua placa de áudio ou a faixa desejada, a faixa atual será ignorada. Certifique-se de ter um backend do Phonon adequado e os plugins necessários instalados. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. Desculpe, há um problema ao acessar sua placa de áudio ou a faixa desejada, a faixa atual será ignorada. - + Station Estação - + Create New Station Criar uma nova estação - + Name: Nome: - + Playlist Playlist - + Automatic Playlist Playlist Automática - + Pause PIN do Twitter - + Go &offline Desc&onectar - + Go &online C&onectar - + Authentication Error Erro de autenticação - + Error connecting to SIP: Authentication failed! Erro ao conectar ao SIP: Falha de autenticação! - + %1 by %2 track, artist name %1 de %2 - + %1 - %2 current track, some window title %1 - %2 - + <h2><b>Tomahawk %1<br/>(%2)</h2> <h2><b>Tomahawk %1<br/>(%2)</h2> - + <h2><b>Tomahawk %1</h2> <h2><b>Tomahawk %1</h2> - + Copyright 2010 - 2012 Copyright 2010 - 2012 - + Thanks to: Agradecimentos: - + About Tomahawk Sobre o Tomahawk diff --git a/lang/tomahawk_ru.ts b/lang/tomahawk_ru.ts index 474b94e9c..c8e9962d1 100644 --- a/lang/tomahawk_ru.ts +++ b/lang/tomahawk_ru.ts @@ -471,9 +471,14 @@ connect and stream from you? Диагностика - - Copy to Clipboard - Сохранить в буфер обмена + + &Copy to Clipboard + + + + + Open &Log-file + @@ -729,7 +734,7 @@ connect and stream from you? - + - Properties @@ -3212,7 +3217,7 @@ enter the displayed PIN number here: - + Play Играть @@ -3232,172 +3237,172 @@ enter the displayed PIN number here: Следующая - + Back Назад - + Go back one page Перейти на предыдущую страницу - + Forward Вперед - + Go forward one page - + Global Search... Глобальный поиск - - + + Check For Updates... Проверить обновления... - - - + + + Connect To Peer Связаться с Peer - + Enter peer address: Введите адрес узла: - + Enter peer port: Введите адрес порта: - + Enter peer key: Введите адрес ключа: - + XSPF Error Ошибка XSPF - + This is not a valid XSPF playlist. Это не является допустимым XSPF плейлистом. - + Failed to save tracks Не удалось сохранить песни - + Some tracks in the playlist do not contain an artist and a title. They will be ignored. Некоторые треки в плейлисте не содержат исполнителя и название. Они будут проигнорированы. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. Make sure you have a suitable Phonon backend and required plugins installed. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. - + Station Станция - + Create New Station Создать новую станцию - + Name: Имя: - + Playlist Плейлист - + Automatic Playlist Автоматический Плейлист - + Pause Пауза - + Go &offline Отключиться - + Go &online Подлючиться - + Authentication Error Ошибка авторизации - + Error connecting to SIP: Authentication failed! Ошибка соединения с SIP: Ошибка авторизации! - + %1 by %2 track, artist name - + %1 - %2 current track, some window title %1 - %2 - + <h2><b>Tomahawk %1<br/>(%2)</h2> <h2><b>Tomahawk %1<br/>(%2)</h2> - + <h2><b>Tomahawk %1</h2> <h2><b>Tomahawk %1</h2> - + Copyright 2010 - 2012 Авторское право 2010 - 2012 - + Thanks to: Благодарность - + About Tomahawk О Tomahawk diff --git a/lang/tomahawk_sv.ts b/lang/tomahawk_sv.ts index 92bd18710..f73257155 100644 --- a/lang/tomahawk_sv.ts +++ b/lang/tomahawk_sv.ts @@ -471,9 +471,14 @@ connect and stream from you? Diagnostik för Tomahawk - - Copy to Clipboard - Kopiera till urklipp + + &Copy to Clipboard + + + + + Open &Log-file + @@ -729,7 +734,7 @@ connect and stream from you? - + - Properties @@ -3207,7 +3212,7 @@ enter the displayed PIN number here: - + Play Spela upp @@ -3227,172 +3232,172 @@ enter the displayed PIN number here: Nästa - + Back - + Go back one page - + Forward - + Go forward one page - + Global Search... Global sökning... - - + + Check For Updates... Leta efter uppdateringar... - - - + + + Connect To Peer Anslut till klient - + Enter peer address: Ange klientadress: - + Enter peer port: Ange klientport: - + Enter peer key: Ange klientnyckel: - + XSPF Error XSPF-fel - + This is not a valid XSPF playlist. Detta är inte en giltig XSPF-spellista. - + Failed to save tracks Misslyckades med att spara spår - + Some tracks in the playlist do not contain an artist and a title. They will be ignored. Några spår i spellistan innehåller inte någon artist och titel. De kommer att ignoreras. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. Make sure you have a suitable Phonon backend and required plugins installed. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. - + Station - + Create New Station Skapa ny station - + Name: Namn: - + Playlist - + Automatic Playlist - + Pause Paus - + Go &offline Koppla &från - + Go &online A&nslut - + Authentication Error Autentiseringsfel - + Error connecting to SIP: Authentication failed! - + %1 by %2 track, artist name %1 av %2 - + %1 - %2 current track, some window title %1 - %2 - + <h2><b>Tomahawk %1<br/>(%2)</h2> - + <h2><b>Tomahawk %1</h2> - + Copyright 2010 - 2012 - + Thanks to: - + About Tomahawk diff --git a/lang/tomahawk_tr.ts b/lang/tomahawk_tr.ts index 4e3b3caa8..7149903f6 100644 --- a/lang/tomahawk_tr.ts +++ b/lang/tomahawk_tr.ts @@ -471,9 +471,14 @@ connect and stream from you? Tomahawk Tanılama - - Copy to Clipboard - Pano'ya Kopyala + + &Copy to Clipboard + + + + + Open &Log-file + @@ -729,7 +734,7 @@ connect and stream from you? - + - Properties @@ -3206,7 +3211,7 @@ enter the displayed PIN number here: - + Play @@ -3226,172 +3231,172 @@ enter the displayed PIN number here: - + Back - + Go back one page - + Forward - + Go forward one page - + Global Search... - - + + Check For Updates... - - - + + + Connect To Peer - + Enter peer address: - + Enter peer port: - + Enter peer key: - + XSPF Error - + This is not a valid XSPF playlist. - + Failed to save tracks - + Some tracks in the playlist do not contain an artist and a title. They will be ignored. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. Make sure you have a suitable Phonon backend and required plugins installed. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. - + Station - + Create New Station - + Name: - + Playlist - + Automatic Playlist - + Pause - + Go &offline - + Go &online - + Authentication Error - + Error connecting to SIP: Authentication failed! - + %1 by %2 track, artist name - + %1 - %2 current track, some window title - + <h2><b>Tomahawk %1<br/>(%2)</h2> - + <h2><b>Tomahawk %1</h2> - + Copyright 2010 - 2012 - + Thanks to: - + About Tomahawk diff --git a/lang/tomahawk_zh_CN.ts b/lang/tomahawk_zh_CN.ts index 313542a94..4daaeaeab 100644 --- a/lang/tomahawk_zh_CN.ts +++ b/lang/tomahawk_zh_CN.ts @@ -471,9 +471,14 @@ connect and stream from you? Tomahawk 诊断信息 - - Copy to Clipboard - 复制到剪贴板 + + &Copy to Clipboard + + + + + Open &Log-file + @@ -729,7 +734,7 @@ connect and stream from you? - + - Properties @@ -3206,7 +3211,7 @@ enter the displayed PIN number here: - + Play @@ -3226,172 +3231,172 @@ enter the displayed PIN number here: - + Back - + Go back one page - + Forward - + Go forward one page - + Global Search... - - + + Check For Updates... - - - + + + Connect To Peer - + Enter peer address: - + Enter peer port: - + Enter peer key: - + XSPF Error - + This is not a valid XSPF playlist. - + Failed to save tracks - + Some tracks in the playlist do not contain an artist and a title. They will be ignored. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. Make sure you have a suitable Phonon backend and required plugins installed. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. - + Station - + Create New Station - + Name: - + Playlist - + Automatic Playlist - + Pause - + Go &offline - + Go &online - + Authentication Error - + Error connecting to SIP: Authentication failed! - + %1 by %2 track, artist name - + %1 - %2 current track, some window title - + <h2><b>Tomahawk %1<br/>(%2)</h2> - + <h2><b>Tomahawk %1</h2> - + Copyright 2010 - 2012 - + Thanks to: - + About Tomahawk diff --git a/lang/tomahawk_zh_TW.ts b/lang/tomahawk_zh_TW.ts index c2ad37438..cb8ce803d 100644 --- a/lang/tomahawk_zh_TW.ts +++ b/lang/tomahawk_zh_TW.ts @@ -471,9 +471,14 @@ connect and stream from you? Tomahawk 診斷 - - Copy to Clipboard - 複製到剪貼簿 + + &Copy to Clipboard + + + + + Open &Log-file + @@ -729,7 +734,7 @@ connect and stream from you? - + - Properties @@ -3206,7 +3211,7 @@ enter the displayed PIN number here: - + Play 播放 @@ -3226,172 +3231,172 @@ enter the displayed PIN number here: 下一首 - + Back - + Go back one page - + Forward - + Go forward one page - + Global Search... 全域搜尋... - - + + Check For Updates... 檢查更新... - - - + + + Connect To Peer 連接點對點 - + Enter peer address: 輸入對等地址: - + Enter peer port: 輸入對等連接埠: - + Enter peer key: 輸入對等密鑰: - + XSPF Error XSPF 錯誤 - + This is not a valid XSPF playlist. - + Failed to save tracks 無法儲存曲目 - + Some tracks in the playlist do not contain an artist and a title. They will be ignored. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. Make sure you have a suitable Phonon backend and required plugins installed. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. - + Station - + Create New Station - + Name: 名稱: - + Playlist - + Automatic Playlist - + Pause 暫停 - + Go &offline 離線 - + Go &online 上網 - + Authentication Error 驗證錯誤 - + Error connecting to SIP: Authentication failed! - + %1 by %2 track, artist name - + %1 - %2 current track, some window title - + <h2><b>Tomahawk %1<br/>(%2)</h2> <h2><b>Tomahawk %1<br/>(%2)</h2> - + <h2><b>Tomahawk %1</h2> <h2><b>Tomahawk %1</h2> - + Copyright 2010 - 2012 - + Thanks to: - + About Tomahawk From ad3f981c9fef0c7a3eec53d3d0b521e135b74d91 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Fri, 13 Jul 2012 09:52:08 +0200 Subject: [PATCH 23/28] * Fixed Windows shutdown. --- src/TomahawkApp.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/TomahawkApp.cpp b/src/TomahawkApp.cpp index 1f14126bf..cf8f1e795 100644 --- a/src/TomahawkApp.cpp +++ b/src/TomahawkApp.cpp @@ -380,11 +380,10 @@ TomahawkApp::~TomahawkApp() delete m_audioEngine.data(); delete Tomahawk::Accounts::AccountManager::instance(); - delete TomahawkUtils::Cache::instance(); #ifndef ENABLE_HEADLESS - delete m_mainwindow; delete AtticaManager::instance(); + delete m_mainwindow; #endif if ( !m_database.isNull() ) @@ -395,6 +394,8 @@ TomahawkApp::~TomahawkApp() if ( !m_infoSystem.isNull() ) delete m_infoSystem.data(); + delete TomahawkUtils::Cache::instance(); + tLog() << "Finished shutdown."; } From f39722c2f85cc7b64701430d1dfafbadf30d5e5b Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Fri, 13 Jul 2012 11:03:21 +0200 Subject: [PATCH 24/28] * Updated ChangeLog. --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index 678c7aed1..d3df8fd69 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,6 +4,7 @@ Version 0.6.0: Version 0.5.4: * Improved stability. + * Added support for Spotify album lookups. * Fixed not always updating the database index after scanning. * Fixed connection issue between Tomahawk peers. From a8fffe6fdc09a629a372b034036b848ce55d21ef Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Fri, 13 Jul 2012 11:30:22 -0400 Subject: [PATCH 25/28] Experimental: Re-implement asynchronous artist/album ID. No more boost::thread usage, using QFutureInterface instead. Now we keep the same model as before but use the undocumented API of QFutureInterface --- CMakeLists.txt | 2 +- src/TomahawkApp.cpp | 21 +++ src/TomahawkApp.h | 5 +- src/libtomahawk/Album.cpp | 102 ++++++++++- src/libtomahawk/Album.h | 19 +- src/libtomahawk/Artist.cpp | 97 +++++++++-- src/libtomahawk/Artist.h | 24 ++- src/libtomahawk/CMakeLists.txt | 1 + src/libtomahawk/GlobalActionManager.h | 3 + src/libtomahawk/database/Database.cpp | 7 + src/libtomahawk/database/Database.h | 2 + src/libtomahawk/database/DatabaseImpl.cpp | 1 - src/libtomahawk/database/IdThreadWorker.cpp | 181 ++++++++++++++++++++ src/libtomahawk/database/IdThreadWorker.h | 54 ++++++ 14 files changed, 490 insertions(+), 29 deletions(-) create mode 100644 src/libtomahawk/database/IdThreadWorker.cpp create mode 100644 src/libtomahawk/database/IdThreadWorker.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 2b3f4cd32..aededc36e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -118,7 +118,7 @@ macro_log_feature(TAGLIB_FOUND "TagLib" "Audio Meta-Data Library" "http://develo include( CheckTagLibFileName ) check_taglib_filename( COMPLEX_TAGLIB_FILENAME ) -macro_optional_find_package(Boost) +macro_optional_find_package( Boost ) macro_log_feature(Boost_FOUND "Boost" "Provides free peer-reviewed portable C++ source libraries" "http://www.boost.org" TRUE "" "") #FIXME: give useful explaination macro_optional_find_package(QCA2) diff --git a/src/TomahawkApp.cpp b/src/TomahawkApp.cpp index cf8f1e795..fe93c8717 100644 --- a/src/TomahawkApp.cpp +++ b/src/TomahawkApp.cpp @@ -719,6 +719,27 @@ TomahawkApp::loadUrl( const QString& url ) } +bool +TomahawkApp::notify( QObject *receiver, QEvent *e ) +{ + try + { + return TOMAHAWK_APPLICATION::notify( receiver, e ); + } + catch ( const std::exception& e ) + { + qWarning( "TomahawkApp::notify caught a std exception in a Qt event handler: " ); + qFatal( e.what() ); + } + catch ( ... ) + { + qFatal( "TomahawkApp::notify caught a non-std-exception from a Qt event handler. Aborting." ); + } + + return false; +} + + void TomahawkApp::instanceStarted( KDSingleApplicationGuard::Instance instance ) { diff --git a/src/TomahawkApp.h b/src/TomahawkApp.h index ae8a7c127..74cfffc11 100644 --- a/src/TomahawkApp.h +++ b/src/TomahawkApp.h @@ -98,7 +98,10 @@ public: virtual bool loadUrl( const QString& url ); bool isTomahawkLoaded() const { return m_loaded; } - + + // reimplemented from QApplication/QCoreApplication + virtual bool notify( QObject* receiver, QEvent* e ); + signals: void tomahawkLoaded(); diff --git a/src/libtomahawk/Album.cpp b/src/libtomahawk/Album.cpp index bf88e86ab..1c7456248 100644 --- a/src/libtomahawk/Album.cpp +++ b/src/libtomahawk/Album.cpp @@ -23,13 +23,22 @@ #include "AlbumPlaylistInterface.h" #include "database/Database.h" #include "database/DatabaseImpl.h" +#include "database/IdThreadWorker.h" #include "Query.h" #include "Source.h" #include "utils/Logger.h" +#include + using namespace Tomahawk; +QHash< QString, album_ptr > Album::s_albumsByName = QHash< QString, album_ptr >(); +QHash< unsigned int, album_ptr > Album::s_albumsById = QHash< unsigned int, album_ptr >(); + +static QMutex s_nameCacheMutex; +static QMutex s_idCacheMutex; +static QReadWriteLock s_idMutex; Album::~Album() { @@ -40,6 +49,12 @@ Album::~Album() #endif } +inline QString +albumCacheKey( const Tomahawk::artist_ptr& artist, const QString& albumName ) +{ + return QString( "%1\t\t%2" ).arg( artist->name() ).arg( albumName ); +} + album_ptr Album::get( const Tomahawk::artist_ptr& artist, const QString& name, bool autoCreate ) @@ -47,11 +62,22 @@ Album::get( const Tomahawk::artist_ptr& artist, const QString& name, bool autoCr if ( !Database::instance() || !Database::instance()->impl() ) return album_ptr(); - int albid = Database::instance()->impl()->albumId( artist->id(), name, autoCreate ); - if ( albid < 1 && autoCreate ) - return album_ptr(); + QMutexLocker l( &s_nameCacheMutex ); - return Album::get( albid, name, artist ); + const QString key = albumCacheKey( artist, name ); + if ( s_albumsByName.contains( key ) ) + { + return s_albumsByName[ key ]; + } + + qDebug() << "LOOKING UP ALBUM:" << artist->name() << name; + album_ptr album = album_ptr( new Album( name, artist ) ); + album->setWeakRef( album.toWeakRef() ); + album->loadId( autoCreate ); + + s_albumsByName[ key ] = album; + + return album; } @@ -61,17 +87,17 @@ Album::get( unsigned int id, const QString& name, const Tomahawk::artist_ptr& ar static QHash< unsigned int, album_ptr > s_albums; static QMutex s_mutex; - QMutexLocker lock( &s_mutex ); - if ( s_albums.contains( id ) ) + QMutexLocker lock( &s_idCacheMutex ); + if ( s_albumsById.contains( id ) ) { - return s_albums.value( id ); + return s_albumsById.value( id ); } album_ptr a = album_ptr( new Album( id, name, artist ), &QObject::deleteLater ); a->setWeakRef( a.toWeakRef() ); if ( id > 0 ) - s_albums.insert( id, a ); + s_albumsById.insert( id, a ); return a; } @@ -79,6 +105,7 @@ Album::get( unsigned int id, const QString& name, const Tomahawk::artist_ptr& ar Album::Album( unsigned int id, const QString& name, const Tomahawk::artist_ptr& artist ) : QObject() + , m_waitingForId( false ) , m_id( id ) , m_name( name ) , m_artist( artist ) @@ -92,6 +119,20 @@ Album::Album( unsigned int id, const QString& name, const Tomahawk::artist_ptr& } +Album::Album( const QString& name, const Tomahawk::artist_ptr& artist ) + : QObject() + , m_waitingForId( true ) + , m_name( name ) + , m_artist( artist ) + , m_coverLoaded( false ) + , m_coverLoading( false ) +#ifndef ENABLE_HEADLESS + , m_cover( 0 ) +#endif +{ + m_sortname = DatabaseImpl::sortname( name ); +} + void Album::onTracksLoaded( Tomahawk::ModelMode mode, const Tomahawk::collection_ptr& collection ) { @@ -106,6 +147,49 @@ Album::artist() const } +void +Album::loadId( bool autoCreate ) +{ + Q_ASSERT( m_waitingForId ); + IdThreadWorker::getAlbumId( m_ownRef.toStrongRef(), autoCreate ); +} + + +void +Album::setIdFuture( QFuture future ) +{ + m_idFuture = future; +} + + +unsigned int +Album::id() const +{ + s_idMutex.lockForRead(); + const bool waiting = m_waitingForId; + unsigned int finalId = m_id; + s_idMutex.unlock(); + + if ( waiting ) + { + qDebug() << Q_FUNC_INFO << "ALBUM WAITING FOR MUTEX:" << m_name; + finalId = m_idFuture.result(); + + qDebug() << Q_FUNC_INFO << "ALBUM GOT ID::" << m_name << finalId; + s_idMutex.lockForWrite(); + m_id = finalId; + m_waitingForId = false; + + if ( m_id > 0 ) + s_albumsById[ m_id ] = m_ownRef.toStrongRef(); + s_idMutex.unlock(); + + } + + return finalId; +} + + #ifndef ENABLE_HEADLESS QPixmap Album::cover( const QSize& size, bool forceLoad ) const @@ -243,4 +327,4 @@ Album::infoid() const m_uuid = uuid(); return m_uuid; -} \ No newline at end of file +} diff --git a/src/libtomahawk/Album.h b/src/libtomahawk/Album.h index 89c6ad09f..41ea9c5d6 100644 --- a/src/libtomahawk/Album.h +++ b/src/libtomahawk/Album.h @@ -27,6 +27,7 @@ #ifndef ENABLE_HEADLESS #include #endif +#include #include "Typedefs.h" #include "PlaylistInterface.h" @@ -34,6 +35,8 @@ #include "Collection.h" #include "infosystem/InfoSystem.h" +class IdThreadWorker; + namespace Tomahawk { @@ -45,10 +48,11 @@ public: static album_ptr get( const Tomahawk::artist_ptr& artist, const QString& name, bool autoCreate = false ); static album_ptr get( unsigned int id, const QString& name, const Tomahawk::artist_ptr& artist ); - explicit Album( unsigned int id, const QString& name, const Tomahawk::artist_ptr& artist ); + Album( unsigned int id, const QString& name, const Tomahawk::artist_ptr& artist ); + Album( const QString& name, const Tomahawk::artist_ptr& artist ); virtual ~Album(); - unsigned int id() const { return m_id; } + unsigned int id() const; QString name() const { return m_name; } QString sortname() const { return m_sortname; } @@ -64,6 +68,7 @@ public: QWeakPointer< Tomahawk::Album > weakRef() { return m_ownRef; } void setWeakRef( QWeakPointer< Tomahawk::Album > weakRef ) { m_ownRef = weakRef; } + void loadId( bool autoCreate ); signals: void tracksAdded( const QList& tracks, Tomahawk::ModelMode mode, const Tomahawk::collection_ptr& collection ); void updated(); @@ -78,8 +83,11 @@ private slots: private: Q_DISABLE_COPY( Album ) QString infoid() const; + void setIdFuture( QFuture future ); - unsigned int m_id; + mutable bool m_waitingForId; + mutable QFuture m_idFuture; + mutable unsigned int m_id; QString m_name; QString m_sortname; @@ -98,6 +106,11 @@ private: QHash< Tomahawk::ModelMode, QHash< Tomahawk::collection_ptr, Tomahawk::playlistinterface_ptr > > m_playlistInterface; QWeakPointer< Tomahawk::Album > m_ownRef; + + static QHash< QString, album_ptr > s_albumsByName; + static QHash< unsigned int, album_ptr > s_albumsById; + + friend class ::IdThreadWorker; }; } // ns diff --git a/src/libtomahawk/Artist.cpp b/src/libtomahawk/Artist.cpp index 4b255c70b..d3c0d5751 100644 --- a/src/libtomahawk/Artist.cpp +++ b/src/libtomahawk/Artist.cpp @@ -25,12 +25,21 @@ #include "database/DatabaseImpl.h" #include "database/DatabaseCommand_AllAlbums.h" #include "database/DatabaseCommand_TrackStats.h" +#include "database/IdThreadWorker.h" #include "Source.h" #include "utils/Logger.h" +#include + using namespace Tomahawk; +QHash< QString, artist_ptr > Artist::s_artistsByName = QHash< QString, artist_ptr >(); +QHash< unsigned int, artist_ptr > Artist::s_artistsById = QHash< unsigned int, artist_ptr >(); + +static QMutex s_nameCacheMutex; +static QMutex s_idCacheMutex; +static QReadWriteLock s_idMutex; Artist::~Artist() { @@ -45,34 +54,40 @@ Artist::~Artist() artist_ptr Artist::get( const QString& name, bool autoCreate ) { + if ( name.isEmpty() ) + return artist_ptr(); + + QMutexLocker lock( &s_nameCacheMutex ); + if ( s_artistsByName.contains( name ) ) + return s_artistsByName.value( name ); + if ( !Database::instance() || !Database::instance()->impl() ) return artist_ptr(); - int artid = Database::instance()->impl()->artistId( name, autoCreate ); - if ( artid < 1 && autoCreate ) - return artist_ptr(); + artist_ptr artist = artist_ptr( new Artist( name ), &QObject::deleteLater ); + artist->setWeakRef( artist.toWeakRef() ); + artist->loadId( autoCreate ); - return Artist::get( artid, name ); + s_artistsByName[ name ] = artist; + + return artist; } artist_ptr Artist::get( unsigned int id, const QString& name ) { - static QHash< unsigned int, artist_ptr > s_artists; - static QMutex s_mutex; - - QMutexLocker lock( &s_mutex ); - if ( s_artists.contains( id ) ) + QMutexLocker lock( &s_idCacheMutex ); + if ( s_artistsById.contains( id ) ) { - return s_artists.value( id ); + return s_artistsById.value( id ); } artist_ptr a = artist_ptr( new Artist( id, name ), &QObject::deleteLater ); a->setWeakRef( a.toWeakRef() ); if ( id > 0 ) - s_artists.insert( id, a ); + s_artistsById.insert( id, a ); return a; } @@ -80,6 +95,7 @@ Artist::get( unsigned int id, const QString& name ) Artist::Artist( unsigned int id, const QString& name ) : QObject() + , m_waitingForFuture( false ) , m_id( id ) , m_name( name ) , m_coverLoaded( false ) @@ -95,6 +111,24 @@ Artist::Artist( unsigned int id, const QString& name ) } +Artist::Artist( const QString& name ) + : QObject() + , m_waitingForFuture( true ) + , m_id( 0 ) + , m_name( name ) + , m_coverLoaded( false ) + , m_coverLoading( false ) + , m_simArtistsLoaded( false ) + , m_biographyLoaded( false ) + , m_infoJobs( 0 ) +#ifndef ENABLE_HEADLESS + , m_cover( 0 ) +#endif +{ + m_sortname = DatabaseImpl::sortname( name, true ); +} + + void Artist::onTracksLoaded( Tomahawk::ModelMode mode, const Tomahawk::collection_ptr& collection ) { @@ -192,6 +226,47 @@ Artist::similarArtists() const } +void +Artist::loadId( bool autoCreate ) +{ + Q_ASSERT( m_waitingForFuture ); + + IdThreadWorker::getArtistId( m_ownRef.toStrongRef(), autoCreate ); +} + + +void +Artist::setIdFuture( QFuture future ) +{ + m_idFuture = future; +} + + +unsigned int +Artist::id() const +{ + s_idMutex.lockForRead(); + const bool waiting = m_waitingForFuture; + unsigned int finalid = m_id; + s_idMutex.unlock(); + + if ( waiting ) + { + finalid = m_idFuture.result(); + + s_idMutex.lockForWrite(); + m_id = finalid; + m_waitingForFuture = false; + + if ( m_id > 0 ) + s_artistsById[ m_id ] = m_ownRef.toStrongRef(); + s_idMutex.unlock(); + } + + return m_id; +} + + QString Artist::biography() const { diff --git a/src/libtomahawk/Artist.h b/src/libtomahawk/Artist.h index 3eef077a1..3031be5f3 100644 --- a/src/libtomahawk/Artist.h +++ b/src/libtomahawk/Artist.h @@ -27,10 +27,16 @@ #include #endif +#include +#include + #include "Typedefs.h" #include "DllMacro.h" #include "Query.h" + +class IdThreadWorker; + namespace Tomahawk { @@ -42,10 +48,11 @@ public: static artist_ptr get( const QString& name, bool autoCreate = false ); static artist_ptr get( unsigned int id, const QString& name ); - explicit Artist( unsigned int id, const QString& name ); + Artist( unsigned int id, const QString& name ); + explicit Artist( const QString& name ); virtual ~Artist(); - unsigned int id() const { return m_id; } + unsigned int id() const; QString name() const { return m_name; } QString sortname() const { return m_sortname; } @@ -72,6 +79,7 @@ public: QWeakPointer< Tomahawk::Artist > weakRef() { return m_ownRef; } void setWeakRef( QWeakPointer< Tomahawk::Artist > weakRef ) { m_ownRef = weakRef; } + void loadId( bool autoCreate ); signals: void tracksAdded( const QList& tracks, Tomahawk::ModelMode mode, const Tomahawk::collection_ptr& collection ); void albumsAdded( const QList& albums, Tomahawk::ModelMode mode ); @@ -93,7 +101,12 @@ private: Artist(); QString infoid() const; - unsigned int m_id; + void setIdFuture( QFuture idFuture ); + + mutable bool m_waitingForFuture; + mutable QFuture m_idFuture; + mutable unsigned int m_id; + QString m_name; QString m_sortname; @@ -123,6 +136,11 @@ private: QHash< Tomahawk::ModelMode, QHash< Tomahawk::collection_ptr, Tomahawk::playlistinterface_ptr > > m_playlistInterface; QWeakPointer< Tomahawk::Artist > m_ownRef; + + static QHash< QString, artist_ptr > s_artistsByName; + static QHash< unsigned int, artist_ptr > s_artistsById; + + friend class ::IdThreadWorker; }; } // ns diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index 71481e3a7..a8118437e 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -257,6 +257,7 @@ set( libSources database/DatabaseCommand_SetTrackAttributes.cpp database/Database.cpp database/TomahawkSqlQuery.cpp + database/IdThreadWorker.cpp infosystem/InfoSystem.cpp infosystem/InfoSystemCache.cpp diff --git a/src/libtomahawk/GlobalActionManager.h b/src/libtomahawk/GlobalActionManager.h index 0b26ac954..c04290d15 100644 --- a/src/libtomahawk/GlobalActionManager.h +++ b/src/libtomahawk/GlobalActionManager.h @@ -60,7 +60,10 @@ public slots: /// Takes a spotify link and performs the default open action on it bool openRdioLink( const QString& link ); + /// Creates a link from the requested data and copies it to the clipboard void copyToClipboard( const Tomahawk::query_ptr& query ); + + QString copyPlaylistToClipboard( const Tomahawk::dynplaylist_ptr& playlist ); void savePlaylistToFile( const Tomahawk::playlist_ptr& playlist, const QString& filename ); diff --git a/src/libtomahawk/database/Database.cpp b/src/libtomahawk/database/Database.cpp index d4aee987c..70deab543 100644 --- a/src/libtomahawk/database/Database.cpp +++ b/src/libtomahawk/database/Database.cpp @@ -22,6 +22,7 @@ #include "DatabaseCommand.h" #include "DatabaseImpl.h" #include "DatabaseWorker.h" +#include "IdThreadWorker.h" #include "utils/Logger.h" #include "Source.h" @@ -43,6 +44,7 @@ Database::Database( const QString& dbname, QObject* parent ) , m_ready( false ) , m_impl( new DatabaseImpl( dbname ) ) , m_workerRW( new DatabaseWorkerThread( this, true ) ) + , m_idWorker( new IdThreadWorker( this ) ) { s_instance = this; @@ -67,6 +69,7 @@ Database::Database( const QString& dbname, QObject* parent ) workerThread.data()->start(); m_workerThreads << workerThread; } + m_idWorker->start(); } @@ -74,6 +77,9 @@ Database::~Database() { qDebug() << Q_FUNC_INFO; + m_idWorker->stop(); + delete m_idWorker; + if ( m_workerRW ) m_workerRW.data()->quit(); foreach ( QWeakPointer< DatabaseWorkerThread > workerThread, m_workerThreads ) @@ -99,6 +105,7 @@ Database::~Database() qDeleteAll( m_implHash.values() ); delete m_impl; + } diff --git a/src/libtomahawk/database/Database.h b/src/libtomahawk/database/Database.h index 7d5c118d7..f499e8b98 100644 --- a/src/libtomahawk/database/Database.h +++ b/src/libtomahawk/database/Database.h @@ -32,6 +32,7 @@ class DatabaseImpl; class DatabaseWorkerThread; class DatabaseWorker; +class IdThreadWorker; /* This class is really a firewall/pimpl - the public functions of LibraryImpl @@ -78,6 +79,7 @@ private: DatabaseImpl* m_impl; QWeakPointer< DatabaseWorkerThread > m_workerRW; QList< QWeakPointer< DatabaseWorkerThread > > m_workerThreads; + IdThreadWorker* m_idWorker; int m_maxConcurrentThreads; QHash< QThread*, DatabaseImpl* > m_implHash; diff --git a/src/libtomahawk/database/DatabaseImpl.cpp b/src/libtomahawk/database/DatabaseImpl.cpp index 051df69a5..7b9b8fc3a 100644 --- a/src/libtomahawk/database/DatabaseImpl.cpp +++ b/src/libtomahawk/database/DatabaseImpl.cpp @@ -42,7 +42,6 @@ #define CURRENT_SCHEMA_VERSION 28 - DatabaseImpl::DatabaseImpl( const QString& dbname ) { QTime t; diff --git a/src/libtomahawk/database/IdThreadWorker.cpp b/src/libtomahawk/database/IdThreadWorker.cpp new file mode 100644 index 000000000..b623a539e --- /dev/null +++ b/src/libtomahawk/database/IdThreadWorker.cpp @@ -0,0 +1,181 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2012 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 "IdThreadWorker.h" + +#include "Artist.h" +#include "Album.h" +#include "Database.h" +#include "DatabaseImpl.h" +#include "Source.h" + +#define ID_THREAD_DEBUG 1 + +#include + +using namespace Tomahawk; + +namespace { + enum QueryType { + ArtistType, + AlbumType + }; +} + + +static QWaitCondition s_waitCond; +static QMutex s_mutex; + +struct QueueItem +{ + QFutureInterface promise; + artist_ptr artist; + album_ptr album; + QueryType type; + bool create; +}; + +// TODO Q_GLOBAL_STATIC +QQueue< QueueItem* > IdThreadWorker::s_workQueue = QQueue< QueueItem* >(); + +IdThreadWorker::IdThreadWorker( Database* db ) + : QThread() + , m_db( db ) + , m_stop( false ) +{ +} + + +IdThreadWorker::~IdThreadWorker() +{ + wait(); +} + + +void +IdThreadWorker::stop() +{ + { + QMutexLocker l( &s_mutex ); + m_stop = true; + } + + s_waitCond.wakeOne(); +} + + +QueueItem* +internalGet( const artist_ptr& artist, const album_ptr& album, bool autoCreate, QueryType type ) +{ + QueueItem* item = new QueueItem; + item->artist = artist; + item->album = album; + item->type = type; + item->create = autoCreate; + + return item; +} + + +void +IdThreadWorker::getArtistId( const artist_ptr& artist, bool autoCreate ) +{ + QueueItem* item = internalGet( artist, album_ptr(), autoCreate, ArtistType ); + artist->setIdFuture( item->promise.future() ); + +#if ID_THREAD_DEBUG + qDebug() << "QUEUEING ARTIST:" << artist->name(); +#endif + + s_mutex.lock(); + s_workQueue.enqueue( item ); + s_mutex.unlock(); + s_waitCond.wakeOne(); +#if ID_THREAD_DEBUG + qDebug() << "DONE WOKE UP THREAD:" << artist->name(); +#endif +} + + +void +IdThreadWorker::getAlbumId( const album_ptr& album, bool autoCreate ) +{ + QueueItem* item = internalGet( artist_ptr(), album, autoCreate, AlbumType ); + album->setIdFuture( item->promise.future() ); + +#if ID_THREAD_DEBUG + qDebug() << "QUEUEING ALUBM:" << album->artist()->name() << album->name(); +#endif + s_mutex.lock(); + s_workQueue.enqueue( item ); + s_mutex.unlock(); + s_waitCond.wakeOne(); +#if ID_THREAD_DEBUG + qDebug() << "DONE WOKE UP THREAD:" << album->artist()->name() << album->name(); +#endif +} + + +void +IdThreadWorker::run() +{ + m_impl = Database::instance()->impl(); + + while ( !m_stop ) + { + s_mutex.lock(); +#if ID_THREAD_DEBUG + qDebug() << "IdWorkerThread waiting on condition..."; +#endif + s_waitCond.wait( &s_mutex ); +#if ID_THREAD_DEBUG + qDebug() << "IdWorkerThread WOKEN UP"; +#endif + + while ( !s_workQueue.isEmpty() ) + { + QueueItem* item = s_workQueue.dequeue(); + s_mutex.unlock(); + +#if ID_THREAD_DEBUG + qDebug() << "WITH CONTENTS:" << (item->type == ArtistType ? item->artist->name() : item->album->artist()->name() + " _ " + item->album->name()); +#endif + if ( item->type == ArtistType ) + { + unsigned int id = m_impl->artistId( item->artist->name(), item->create ); + item->promise.reportFinished( &id ); + + item->artist->id(); + delete item; + } + else if ( item->type == AlbumType ) + { + unsigned int artistId = m_impl->artistId( item->album->artist()->name(), item->create ); + unsigned int albumId = m_impl->albumId( artistId, item->album->name(), item->create ); + item->promise.reportFinished( &albumId ); + + item->album->id(); + delete item; + } + + s_mutex.lock(); + } + + s_mutex.unlock(); + } +} diff --git a/src/libtomahawk/database/IdThreadWorker.h b/src/libtomahawk/database/IdThreadWorker.h new file mode 100644 index 000000000..90ce53a6e --- /dev/null +++ b/src/libtomahawk/database/IdThreadWorker.h @@ -0,0 +1,54 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2012 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 IDTHREADWORKER_H +#define IDTHREADWORKER_H + +#include "DllMacro.h" +#include "Typedefs.h" + +#include +#include +#include +#include + +class QueueItem; +class Database; +class DatabaseImpl; + +class DLLEXPORT IdThreadWorker : public QThread +{ + Q_OBJECT +public: + explicit IdThreadWorker( Database* db ); + virtual ~IdThreadWorker(); + + void run(); + void stop(); + + static void getArtistId( const Tomahawk::artist_ptr& artist, bool autoCreate = false ); + static void getAlbumId( const Tomahawk::album_ptr& album, bool autoCreate = false ); + +private: + Database* m_db; + DatabaseImpl* m_impl; + bool m_stop; + + static QQueue< QueueItem* > s_workQueue; +}; + +#endif // IDTHREADWORKER_H From c064d27fb8d4c89d1b54e54a003a5260ca50ef00 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Fri, 13 Jul 2012 11:38:23 -0400 Subject: [PATCH 26/28] Less debug --- src/libtomahawk/Album.cpp | 4 +--- src/libtomahawk/database/IdThreadWorker.cpp | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/libtomahawk/Album.cpp b/src/libtomahawk/Album.cpp index 1c7456248..4b3ebcf0d 100644 --- a/src/libtomahawk/Album.cpp +++ b/src/libtomahawk/Album.cpp @@ -70,7 +70,7 @@ Album::get( const Tomahawk::artist_ptr& artist, const QString& name, bool autoCr return s_albumsByName[ key ]; } - qDebug() << "LOOKING UP ALBUM:" << artist->name() << name; +// qDebug() << "LOOKING UP ALBUM:" << artist->name() << name; album_ptr album = album_ptr( new Album( name, artist ) ); album->setWeakRef( album.toWeakRef() ); album->loadId( autoCreate ); @@ -172,10 +172,8 @@ Album::id() const if ( waiting ) { - qDebug() << Q_FUNC_INFO << "ALBUM WAITING FOR MUTEX:" << m_name; finalId = m_idFuture.result(); - qDebug() << Q_FUNC_INFO << "ALBUM GOT ID::" << m_name << finalId; s_idMutex.lockForWrite(); m_id = finalId; m_waitingForId = false; diff --git a/src/libtomahawk/database/IdThreadWorker.cpp b/src/libtomahawk/database/IdThreadWorker.cpp index b623a539e..b673da236 100644 --- a/src/libtomahawk/database/IdThreadWorker.cpp +++ b/src/libtomahawk/database/IdThreadWorker.cpp @@ -24,7 +24,7 @@ #include "DatabaseImpl.h" #include "Source.h" -#define ID_THREAD_DEBUG 1 +#define ID_THREAD_DEBUG 0 #include From abf552e3a154d2babdb6519357d120e01f7ad533 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Fri, 13 Jul 2012 11:51:48 -0400 Subject: [PATCH 27/28] Try including qfutureinterface via QtCore/ to see if it helps the OS X slave --- src/libtomahawk/Artist.h | 1 - src/libtomahawk/database/IdThreadWorker.cpp | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libtomahawk/Artist.h b/src/libtomahawk/Artist.h index 3031be5f3..af0dba4c0 100644 --- a/src/libtomahawk/Artist.h +++ b/src/libtomahawk/Artist.h @@ -27,7 +27,6 @@ #include #endif -#include #include #include "Typedefs.h" diff --git a/src/libtomahawk/database/IdThreadWorker.cpp b/src/libtomahawk/database/IdThreadWorker.cpp index b673da236..a8ff77e14 100644 --- a/src/libtomahawk/database/IdThreadWorker.cpp +++ b/src/libtomahawk/database/IdThreadWorker.cpp @@ -26,7 +26,7 @@ #define ID_THREAD_DEBUG 0 -#include +#include using namespace Tomahawk; From 6ee2e0fe14126258dd22a490d07bb6a3c4020500 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Fri, 13 Jul 2012 13:07:32 -0400 Subject: [PATCH 28/28] TWK-968: Fix PlayableModel/DropJob for mixed mimetype --- src/libtomahawk/DropJob.cpp | 8 +++++++- src/libtomahawk/playlist/PlayableModel.cpp | 9 +++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/libtomahawk/DropJob.cpp b/src/libtomahawk/DropJob.cpp index ee8b5f791..a7dce734d 100644 --- a/src/libtomahawk/DropJob.cpp +++ b/src/libtomahawk/DropJob.cpp @@ -425,12 +425,18 @@ DropJob::tracksFromMixedData( const QMimeData *data ) QDataStream singleStream( &singleData, QIODevice::WriteOnly ); QMimeData singleMimeData; - if ( mimeType == "application/tomahawk.query.list" || mimeType == "application/tomahawk.result.list" ) + if ( mimeType == "application/tomahawk.query.list" ) { qlonglong query; stream >> query; singleStream << query; } + else if ( mimeType == "application/tomahawk.result.list" ) + { + qlonglong result; + stream >> result; + singleStream << result; + } else if ( mimeType == "application/tomahawk.metadata.album" ) { QString artist; diff --git a/src/libtomahawk/playlist/PlayableModel.cpp b/src/libtomahawk/playlist/PlayableModel.cpp index 0af16f581..ebb1c8283 100644 --- a/src/libtomahawk/playlist/PlayableModel.cpp +++ b/src/libtomahawk/playlist/PlayableModel.cpp @@ -451,6 +451,7 @@ PlayableModel::mimeData( const QModelIndexList &indexes ) const // Ok... we have to use mixed resultData.clear(); + QDataStream mixedStream( &resultData, QIODevice::WriteOnly ); foreach ( const QModelIndex& i, indexes ) { if ( i.column() > 0 || indexes.contains( i.parent() ) ) @@ -463,22 +464,22 @@ PlayableModel::mimeData( const QModelIndexList &indexes ) const if ( !item->artist().isNull() ) { const artist_ptr& artist = item->artist(); - resultStream << QString( "application/tomahawk.metadata.artist" ) << artist->name(); + mixedStream << QString( "application/tomahawk.metadata.artist" ) << artist->name(); } else if ( !item->album().isNull() ) { const album_ptr& album = item->album(); - resultStream << QString( "application/tomahawk.metadata.album" ) << album->artist()->name() << album->name(); + mixedStream << QString( "application/tomahawk.metadata.album" ) << album->artist()->name() << album->name(); } else if ( !item->result().isNull() ) { const result_ptr& result = item->result(); - resultStream << QString( "application/tomahawk.result.list" ) << qlonglong( &result ); + mixedStream << QString( "application/tomahawk.result.list" ) << qlonglong( &result ); } else if ( !item->query().isNull() ) { const query_ptr& query = item->query(); - resultStream << QString( "application/tomahawk.query.list" ) << qlonglong( &query ); + mixedStream << QString( "application/tomahawk.query.list" ) << qlonglong( &query ); } }