From 6626c7f877bbea80a897e8fde2e00b9e70b498a7 Mon Sep 17 00:00:00 2001 From: Patrick von Reth Date: Tue, 17 Jul 2012 14:13:08 +0200 Subject: [PATCH 01/79] update windows love button if the track is loved inside of tomahawk --- src/TomahawkWindow.cpp | 57 ++++++++++++++++++++++-------------------- src/TomahawkWindow.h | 1 + 2 files changed, 31 insertions(+), 27 deletions(-) diff --git a/src/TomahawkWindow.cpp b/src/TomahawkWindow.cpp index 5cc182325..e92735567 100644 --- a/src/TomahawkWindow.cpp +++ b/src/TomahawkWindow.cpp @@ -600,20 +600,7 @@ TomahawkWindow::winEvent( MSG* msg, long* result ) if ( !AudioEngine::instance()->currentTrack().isNull() ) { AudioEngine::instance()->currentTrack()->toQuery()->setLoved( !AudioEngine::instance()->currentTrack()->toQuery()->loved() ); - if ( 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_taskbarList->ThumbBarUpdateButtons( winId(), ARRAYSIZE( m_thumbButtons ), m_thumbButtons ); + updateWindowsLoveButton(); } break; } @@ -639,23 +626,15 @@ TomahawkWindow::audioStateChanged( AudioState newState, AudioState oldState ) { case AudioEngine::Playing: { + if ( !AudioEngine::instance()->currentTrack().isNull() ) + { + connect(AudioEngine::instance()->currentTrack()->toQuery().data(),SIGNAL(socialActionsLoaded()),this,SLOT(updateWindowsLoveButton())); + } 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; + updateWindowsLoveButton(); - 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; } break; @@ -669,6 +648,10 @@ TomahawkWindow::audioStateChanged( AudioState newState, AudioState oldState ) case AudioEngine::Stopped: { + if ( !AudioEngine::instance()->currentTrack().isNull() ) + { + disconnect(AudioEngine::instance()->currentTrack()->toQuery().data(),SIGNAL(socialActionsLoaded()),this,SLOT(updateWindowsLoveButton())); + } 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; @@ -685,6 +668,26 @@ TomahawkWindow::audioStateChanged( AudioState newState, AudioState oldState ) m_taskbarList->ThumbBarUpdateButtons( winId(), ARRAYSIZE( m_thumbButtons ), m_thumbButtons ); } + +void +TomahawkWindow::updateWindowsLoveButton() +{ + 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; + m_taskbarList->ThumbBarUpdateButtons( winId(), ARRAYSIZE( m_thumbButtons ), m_thumbButtons ); +} + #endif diff --git a/src/TomahawkWindow.h b/src/TomahawkWindow.h index c0220039b..542722ebe 100644 --- a/src/TomahawkWindow.h +++ b/src/TomahawkWindow.h @@ -144,6 +144,7 @@ private slots: #ifdef Q_OS_WIN void audioStateChanged( AudioState newState, AudioState oldState ); + void updateWindowsLoveButton(); #endif private: From 349509d0b030d1590691ab72433a51e9e6319ae6 Mon Sep 17 00:00:00 2001 From: Patrick von Reth Date: Tue, 17 Jul 2012 18:36:08 +0200 Subject: [PATCH 02/79] fixed connect/disconnect logic --- src/TomahawkWindow.cpp | 19 ++++++++++++++----- src/TomahawkWindow.h | 1 + 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/TomahawkWindow.cpp b/src/TomahawkWindow.cpp index e92735567..8ad2ee3a9 100644 --- a/src/TomahawkWindow.cpp +++ b/src/TomahawkWindow.cpp @@ -104,7 +104,7 @@ TomahawkWindow::TomahawkWindow( QWidget* parent ) 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))); + connect( AudioEngine::instance(), SIGNAL( stateChanged( AudioState, AudioState) ), SLOT( audioStateChanged( AudioState, AudioState) ) ); #endif ui->setupUi( this ); @@ -412,6 +412,7 @@ TomahawkWindow::setupSignals() connect( AudioEngine::instance(), SIGNAL( error( AudioEngine::AudioErrorCode ) ), SLOT( onAudioEngineError( AudioEngine::AudioErrorCode ) ) ); connect( AudioEngine::instance(), SIGNAL( loading( const Tomahawk::result_ptr& ) ), SLOT( onPlaybackLoading( const Tomahawk::result_ptr& ) ) ); connect( AudioEngine::instance(), SIGNAL( started( Tomahawk::result_ptr ) ), SLOT( audioStarted() ) ); + connect( AudioEngine::instance(), SIGNAL( finished(Tomahawk::result_ptr) ), SLOT( audioFinished() ) ); connect( AudioEngine::instance(), SIGNAL( resumed()), SLOT( audioStarted() ) ); connect( AudioEngine::instance(), SIGNAL( paused() ), SLOT( audioPaused() ) ); connect( AudioEngine::instance(), SIGNAL( stopped() ), SLOT( audioStopped() ) ); @@ -626,10 +627,6 @@ TomahawkWindow::audioStateChanged( AudioState newState, AudioState oldState ) { case AudioEngine::Playing: { - if ( !AudioEngine::instance()->currentTrack().isNull() ) - { - connect(AudioEngine::instance()->currentTrack()->toQuery().data(),SIGNAL(socialActionsLoaded()),this,SLOT(updateWindowsLoveButton())); - } 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; @@ -1037,6 +1034,18 @@ TomahawkWindow::audioStarted() ui->actionPlay->setText( tr( "Pause" ) ); ActionCollection::instance()->getAction( "stop" )->setEnabled( true ); + +#ifdef Q_OS_WIN + connect( AudioEngine::instance()->currentTrack()->toQuery().data(), SIGNAL( socialActionsLoaded() ), SLOT( updateWindowsLoveButton() ) ); +#endif +} + +void +TomahawkWindow::audioFinished() +{ +#ifdef Q_OS_WIN + disconnect( AudioEngine::instance()->currentTrack()->toQuery().data(), SIGNAL( socialActionsLoaded() ), SLOT( updateWindowsLoveButton() ) ); +#endif } diff --git a/src/TomahawkWindow.h b/src/TomahawkWindow.h index 542722ebe..7ee64cc5d 100644 --- a/src/TomahawkWindow.h +++ b/src/TomahawkWindow.h @@ -121,6 +121,7 @@ private slots: void onPlaybackLoading( const Tomahawk::result_ptr& result ); void audioStarted(); + void audioFinished(); void audioPaused(); void audioStopped(); From 90e532395b3fb03d063983a70c164f380ee9bc2a Mon Sep 17 00:00:00 2001 From: Patrick von Reth Date: Tue, 17 Jul 2012 18:42:07 +0200 Subject: [PATCH 03/79] compile fix --- src/TomahawkWindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/TomahawkWindow.cpp b/src/TomahawkWindow.cpp index 8ad2ee3a9..09e6fe70d 100644 --- a/src/TomahawkWindow.cpp +++ b/src/TomahawkWindow.cpp @@ -1044,7 +1044,7 @@ void TomahawkWindow::audioFinished() { #ifdef Q_OS_WIN - disconnect( AudioEngine::instance()->currentTrack()->toQuery().data(), SIGNAL( socialActionsLoaded() ), SLOT( updateWindowsLoveButton() ) ); + disconnect( AudioEngine::instance()->currentTrack()->toQuery().data(), SIGNAL( socialActionsLoaded() ), this, SLOT( updateWindowsLoveButton() ) ); #endif } From 813e657ee4e42bf542ca13591d49bc4ff51e87ec Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Sat, 21 Jul 2012 18:19:03 -0400 Subject: [PATCH 04/79] Show currently playing icon and support jumping for grid views --- src/libtomahawk/playlist/GridItemDelegate.cpp | 6 ++ src/libtomahawk/playlist/GridItemDelegate.h | 3 + src/libtomahawk/playlist/GridView.cpp | 59 ++++++++++++++ src/libtomahawk/playlist/GridView.h | 15 +++- src/libtomahawk/widgets/WelcomeWidget.cpp | 64 ++++++++++++++- src/libtomahawk/widgets/WelcomeWidget.h | 4 + src/libtomahawk/widgets/WhatsHotWidget.cpp | 10 ++- src/libtomahawk/widgets/WhatsHotWidget_p.h | 3 +- .../widgets/infowidgets/AlbumInfoWidget.cpp | 15 +++- .../widgets/infowidgets/AlbumInfoWidget.h | 7 +- .../widgets/infowidgets/AlbumInfoWidget_p.h | 78 +++++++++++++++++++ .../widgets/infowidgets/ArtistInfoWidget.cpp | 14 +++- .../widgets/infowidgets/ArtistInfoWidget.h | 4 +- .../widgets/infowidgets/ArtistInfoWidget_p.h | 10 ++- 14 files changed, 276 insertions(+), 16 deletions(-) create mode 100644 src/libtomahawk/widgets/infowidgets/AlbumInfoWidget_p.h diff --git a/src/libtomahawk/playlist/GridItemDelegate.cpp b/src/libtomahawk/playlist/GridItemDelegate.cpp index 6110608bc..a79104a96 100644 --- a/src/libtomahawk/playlist/GridItemDelegate.cpp +++ b/src/libtomahawk/playlist/GridItemDelegate.cpp @@ -459,6 +459,8 @@ GridItemDelegate::onPlaybackFinished() foreach ( ImageButton* button, m_pauseButton ) button->deleteLater(); m_pauseButton.clear(); + + emit stoppedPlaying( QModelIndex() ); } @@ -501,6 +503,8 @@ GridItemDelegate::onPlaylistChanged( const QPersistentModelIndex& index ) m_spinner[ index ]->deleteLater(); m_spinner.remove( index ); } + + emit stoppedPlaying( index ); } } } @@ -532,6 +536,8 @@ GridItemDelegate::onPlaybackStarted( const QPersistentModelIndex& index ) connect( button, SIGNAL( clicked( bool ) ), AudioEngine::instance(), SLOT( playPause() ) ); m_pauseButton[ index ] = button; + + emit startedPlaying( index ); } diff --git a/src/libtomahawk/playlist/GridItemDelegate.h b/src/libtomahawk/playlist/GridItemDelegate.h index b05b171a3..a14414715 100644 --- a/src/libtomahawk/playlist/GridItemDelegate.h +++ b/src/libtomahawk/playlist/GridItemDelegate.h @@ -58,6 +58,9 @@ protected: signals: void updateIndex( const QModelIndex& idx ); + void startedPlaying( const QPersistentModelIndex& ); + void stoppedPlaying( const QPersistentModelIndex& ); + private slots: void modelChanged(); void doUpdateIndex( const QPersistentModelIndex& idx ); diff --git a/src/libtomahawk/playlist/GridView.cpp b/src/libtomahawk/playlist/GridView.cpp index 0b0197f2c..bccd83657 100644 --- a/src/libtomahawk/playlist/GridView.cpp +++ b/src/libtomahawk/playlist/GridView.cpp @@ -34,6 +34,7 @@ #include "GridItemDelegate.h" #include "AlbumModel.h" #include "PlayableModel.h" +#include "PlayableProxyModelPlaylistInterface.h" #include "ContextMenu.h" #include "ViewManager.h" #include "utils/Logger.h" @@ -44,6 +45,32 @@ using namespace Tomahawk; +class GridPlaylistInterface : public PlayableProxyModelPlaylistInterface { + Q_OBJECT +public: + explicit GridPlaylistInterface( PlayableProxyModel* proxy, GridView* view ) : PlayableProxyModelPlaylistInterface( proxy ), m_view( view ) {} + + virtual bool hasChildInterface( playlistinterface_ptr playlistInterface ) + { + if ( m_view.isNull() || !m_view.data()->m_playing.isValid() ) + { + return false; + } + + PlayableItem* item = m_view.data()->model()->itemFromIndex( m_view.data()->proxyModel()->mapToSource( m_view.data()->m_playing ) ); + if ( item ) + { + if ( !item->album().isNull() ) + return item->album()->playlistInterface( Tomahawk::Mixed ) == playlistInterface; + else if ( !item->artist().isNull() ) + return item->artist()->playlistInterface( Tomahawk::Mixed ) == playlistInterface; + } + + return false; + } +private: + QWeakPointer m_view; +}; GridView::GridView( QWidget* parent ) : QListView( parent ) @@ -77,6 +104,8 @@ GridView::GridView( QWidget* parent ) setAutoResize( false ); setProxyModel( new PlayableProxyModel( this ) ); + m_playlistInterface = playlistinterface_ptr( new GridPlaylistInterface( m_proxyModel, this ) ); + connect( this, SIGNAL( doubleClicked( QModelIndex ) ), SLOT( onItemActivated( QModelIndex ) ) ); connect( this, SIGNAL( customContextMenuRequested( QPoint ) ), SLOT( onCustomContextMenu( QPoint ) ) ); @@ -103,6 +132,8 @@ GridView::setProxyModel( PlayableProxyModel* model ) m_delegate = new GridItemDelegate( this, m_proxyModel ); connect( m_delegate, SIGNAL( updateIndex( QModelIndex ) ), this, SLOT( update( QModelIndex ) ) ); + connect( m_delegate, SIGNAL( startedPlaying( QPersistentModelIndex ) ), this, SLOT( onDelegatePlaying( QPersistentModelIndex ) ) ); + connect( m_delegate, SIGNAL( stoppedPlaying( QPersistentModelIndex ) ), this, SLOT( onDelegateStopped( QPersistentModelIndex ) ) ); setItemDelegate( m_delegate ); QListView::setModel( m_proxyModel ); @@ -238,6 +269,21 @@ GridView::verifySize() } +void +GridView::onDelegatePlaying( const QPersistentModelIndex& index ) +{ + m_playing = index; +} + + +void +GridView::onDelegateStopped( const QPersistentModelIndex& index ) +{ + if ( m_playing == index ) + m_playing = QPersistentModelIndex(); +} + + void GridView::layoutItems() { @@ -356,3 +402,16 @@ GridView::setFilter( const QString& filter ) m_proxyModel->setFilter( filter ); return true; } + +bool +GridView::jumpToCurrentTrack() +{ + if ( !m_playing.isValid() ) + return false; + + scrollTo( m_playing, QListView::PositionAtCenter ); + + return true; +} + +#include "GridView.moc" diff --git a/src/libtomahawk/playlist/GridView.h b/src/libtomahawk/playlist/GridView.h index 7003f0573..56bce3332 100644 --- a/src/libtomahawk/playlist/GridView.h +++ b/src/libtomahawk/playlist/GridView.h @@ -37,6 +37,7 @@ namespace Tomahawk class AnimatedSpinner; class GridItemDelegate; class PlayableModel; +class GridPlaylistInterface; class DLLEXPORT GridView : public QListView, public Tomahawk::ViewPage { @@ -64,13 +65,15 @@ public: void setEmptyTip( const QString& tip ); virtual QWidget* widget() { return this; } - virtual Tomahawk::playlistinterface_ptr playlistInterface() const { return proxyModel()->playlistInterface(); } + virtual Tomahawk::playlistinterface_ptr playlistInterface() const { return m_playlistInterface; } virtual QString title() const { return m_model->title(); } virtual QString description() const { return m_model->description(); } virtual bool setFilter( const QString& filter ); - virtual bool jumpToCurrentTrack() { return false; } + virtual bool jumpToCurrentTrack(); + + virtual bool isBeingPlayed() const { return m_playing.isValid(); } public slots: void onItemActivated( const QModelIndex& index ); @@ -94,6 +97,9 @@ private slots: void onFilterChanged( const QString& filter ); void onCustomContextMenu( const QPoint& pos ); + void onDelegatePlaying( const QPersistentModelIndex& idx ); + void onDelegateStopped( const QPersistentModelIndex& idx ); + void layoutItems(); void verifySize(); @@ -103,8 +109,11 @@ private: GridItemDelegate* m_delegate; AnimatedSpinner* m_loadingSpinner; OverlayWidget* m_overlay; + Tomahawk::playlistinterface_ptr m_playlistInterface; QModelIndex m_contextMenuIndex; + QPersistentModelIndex m_playing; + Tomahawk::ContextMenu* m_contextMenu; QString m_emptyTip; @@ -113,6 +122,8 @@ private: bool m_autoResize; QRect m_paintRect; + + friend ::GridPlaylistInterface; }; #endif // GRIDVIEW_H diff --git a/src/libtomahawk/widgets/WelcomeWidget.cpp b/src/libtomahawk/widgets/WelcomeWidget.cpp index 7456233d2..37f80611e 100644 --- a/src/libtomahawk/widgets/WelcomeWidget.cpp +++ b/src/libtomahawk/widgets/WelcomeWidget.cpp @@ -43,6 +43,54 @@ using namespace Tomahawk; +class WelcomeWidgetInterface : public Tomahawk::PlaylistInterface +{ + Q_OBJECT +public: + explicit WelcomeWidgetInterface( WelcomeWidget* w ) + : PlaylistInterface() + , m_w( w ) + { + connect( m_w->ui->tracksView->proxyModel()->playlistInterface().data(), SIGNAL( repeatModeChanged( Tomahawk::PlaylistModes::RepeatMode ) ), + SIGNAL( repeatModeChanged( Tomahawk::PlaylistModes::RepeatMode ) ) ); + + connect( m_w->ui->tracksView->proxyModel()->playlistInterface().data(), SIGNAL( shuffleModeChanged( bool ) ), + SIGNAL( shuffleModeChanged( bool ) ) ); + } + virtual ~WelcomeWidgetInterface() {} + + + virtual Tomahawk::PlaylistModes::RepeatMode repeatMode() const { return m_w->ui->tracksView->proxyModel()->playlistInterface()->repeatMode(); } + virtual bool shuffled() const { return m_w->ui->tracksView->proxyModel()->playlistInterface()->shuffled(); } + + virtual Tomahawk::result_ptr currentItem() const { return m_w->ui->tracksView->proxyModel()->playlistInterface()->currentItem(); } + virtual Tomahawk::result_ptr siblingItem( int itemsAway ) { return m_w->ui->tracksView->proxyModel()->playlistInterface()->siblingItem( itemsAway ); } + virtual int trackCount() const { return m_w->ui->tracksView->proxyModel()->playlistInterface()->trackCount(); } + virtual QList< Tomahawk::query_ptr > tracks() { return m_w->ui->tracksView->proxyModel()->playlistInterface()->tracks(); } + + virtual bool hasChildInterface( Tomahawk::playlistinterface_ptr other ) + { + return m_w->ui->tracksView->proxyModel()->playlistInterface() == other || + m_w->ui->tracksView->proxyModel()->playlistInterface()->hasChildInterface( other ) || + m_w->ui->additionsView->playlistInterface()->hasChildInterface( other ); + } + + virtual void setRepeatMode( Tomahawk::PlaylistModes::RepeatMode mode ) + { + m_w->ui->tracksView->proxyModel()->playlistInterface()->setRepeatMode( mode ); + } + + virtual void setShuffled( bool enabled ) + { + m_w->ui->tracksView->proxyModel()->playlistInterface()->setShuffled( enabled ); + } + +private: + WelcomeWidget* m_w; + +}; + + WelcomeWidget::WelcomeWidget( QWidget* parent ) : QWidget( parent ) , ui( new Ui::WelcomeWidget ) @@ -78,6 +126,8 @@ WelcomeWidget::WelcomeWidget( QWidget* parent ) ui->additionsView->setPlayableModel( m_recentAlbumsModel ); ui->additionsView->proxyModel()->sort( -1 ); + m_playlistInterface = playlistinterface_ptr( new WelcomeWidgetInterface( this ) ); + connect( SourceList::instance(), SIGNAL( ready() ), SLOT( onSourcesReady() ) ); connect( SourceList::instance(), SIGNAL( sourceAdded( Tomahawk::source_ptr ) ), SLOT( onSourceAdded( Tomahawk::source_ptr ) ) ); connect( ui->playlistWidget, SIGNAL( activated( QModelIndex ) ), SLOT( onPlaylistActivated( QModelIndex ) ) ); @@ -101,20 +151,29 @@ WelcomeWidget::loadData() Tomahawk::playlistinterface_ptr WelcomeWidget::playlistInterface() const { - return ui->tracksView->playlistInterface(); + return m_playlistInterface; } bool WelcomeWidget::jumpToCurrentTrack() { - return ui->tracksView->jumpToCurrentTrack(); + if ( ui->tracksView->jumpToCurrentTrack() ) + return true; + + if ( ui->additionsView->jumpToCurrentTrack() ) + return true; + + return false; } bool WelcomeWidget::isBeingPlayed() const { + if ( ui->additionsView->isBeingPlayed() ) + return true; + return AudioEngine::instance()->currentTrackPlaylist() == ui->tracksView->playlistInterface(); } @@ -320,3 +379,4 @@ PlaylistWidget::setModel( QAbstractItemModel* model ) emit modelChanged(); } +#include "WelcomeWidget.moc" diff --git a/src/libtomahawk/widgets/WelcomeWidget.h b/src/libtomahawk/widgets/WelcomeWidget.h index 5233f1594..e941f055f 100644 --- a/src/libtomahawk/widgets/WelcomeWidget.h +++ b/src/libtomahawk/widgets/WelcomeWidget.h @@ -37,6 +37,7 @@ class AlbumModel; class RecentlyPlayedModel; class OverlayWidget; +class WelcomeWidgetInterface; namespace Ui { @@ -125,6 +126,9 @@ private: RecentlyPlayedModel* m_tracksModel; AlbumModel* m_recentAlbumsModel; + Tomahawk::playlistinterface_ptr m_playlistInterface; + + friend class ::WelcomeWidgetInterface; }; #endif // WELCOMEWIDGET_H diff --git a/src/libtomahawk/widgets/WhatsHotWidget.cpp b/src/libtomahawk/widgets/WhatsHotWidget.cpp index 8dba1e009..b064c46f1 100644 --- a/src/libtomahawk/widgets/WhatsHotWidget.cpp +++ b/src/libtomahawk/widgets/WhatsHotWidget.cpp @@ -130,6 +130,9 @@ WhatsHotWidget::isBeingPlayed() const if ( AudioEngine::instance()->currentTrackPlaylist() == ui->tracksViewLeft->playlistInterface() ) return true; + if ( ui->albumsView->isBeingPlayed() ) + return true; + return false; } @@ -137,10 +140,13 @@ WhatsHotWidget::isBeingPlayed() const bool WhatsHotWidget::jumpToCurrentTrack() { - if ( ui->artistsViewLeft->jumpToCurrentTrack() ) + if ( ui->artistsViewLeft->model() && ui->artistsViewLeft->jumpToCurrentTrack() ) return true; - if ( ui->tracksViewLeft->jumpToCurrentTrack() ) + if ( ui->tracksViewLeft->model() && ui->tracksViewLeft->jumpToCurrentTrack() ) + return true; + + if ( ui->albumsView->model() && ui->albumsView->jumpToCurrentTrack() ) return true; return false; diff --git a/src/libtomahawk/widgets/WhatsHotWidget_p.h b/src/libtomahawk/widgets/WhatsHotWidget_p.h index e75d4aa62..8be446db3 100644 --- a/src/libtomahawk/widgets/WhatsHotWidget_p.h +++ b/src/libtomahawk/widgets/WhatsHotWidget_p.h @@ -65,7 +65,8 @@ public: virtual bool hasChildInterface( Tomahawk::playlistinterface_ptr other ) { return m_w->ui->tracksViewLeft->playlistInterface() == other || - m_w->ui->artistsViewLeft->playlistInterface() == other; + m_w->ui->artistsViewLeft->playlistInterface() == other || + m_w->ui->albumsView->playlistInterface()->hasChildInterface( other ); } diff --git a/src/libtomahawk/widgets/infowidgets/AlbumInfoWidget.cpp b/src/libtomahawk/widgets/infowidgets/AlbumInfoWidget.cpp index 442a25977..bacbc1902 100644 --- a/src/libtomahawk/widgets/infowidgets/AlbumInfoWidget.cpp +++ b/src/libtomahawk/widgets/infowidgets/AlbumInfoWidget.cpp @@ -20,6 +20,7 @@ #include "AlbumInfoWidget.h" #include "ui_AlbumInfoWidget.h" +#include "AlbumInfoWidget_p.h" #include "audio/AudioEngine.h" #include "ViewManager.h" @@ -61,6 +62,7 @@ AlbumInfoWidget::AlbumInfoWidget( const Tomahawk::album_ptr& album, QWidget* par m_pixmap = TomahawkUtils::defaultPixmap( TomahawkUtils::DefaultAlbumCover, TomahawkUtils::ScaledCover, QSize( 48, 48 ) ); + m_playlistInterface = playlistinterface_ptr( new MetaAlbumInfoInterface( this ) ); load( album ); } @@ -74,7 +76,7 @@ AlbumInfoWidget::~AlbumInfoWidget() Tomahawk::playlistinterface_ptr AlbumInfoWidget::playlistInterface() const { - return ui->tracksView->playlistInterface(); + return m_playlistInterface; } @@ -84,6 +86,10 @@ AlbumInfoWidget::isBeingPlayed() const //tDebug() << Q_FUNC_INFO << "audioengine playlistInterface = " << AudioEngine::instance()->currentTrackPlaylist()->id(); //tDebug() << Q_FUNC_INFO << "albumsView playlistInterface = " << ui->albumsView->playlistInterface()->id(); //tDebug() << Q_FUNC_INFO << "tracksView playlistInterface = " << ui->tracksView->playlistInterface()->id(); + + if ( ui->albumsView->isBeingPlayed() ) + return true; + if ( ui->albumsView->playlistInterface() == AudioEngine::instance()->currentTrackPlaylist() ) return true; @@ -94,6 +100,13 @@ AlbumInfoWidget::isBeingPlayed() const } +bool +AlbumInfoWidget::jumpToCurrentTrack() +{ + return ui->albumsView->jumpToCurrentTrack(); +} + + artist_ptr AlbumInfoWidget::descriptionArtist() const { if ( !m_album.isNull() && !m_album->artist().isNull() ) diff --git a/src/libtomahawk/widgets/infowidgets/AlbumInfoWidget.h b/src/libtomahawk/widgets/infowidgets/AlbumInfoWidget.h index 0c7c7248b..c4f756e51 100644 --- a/src/libtomahawk/widgets/infowidgets/AlbumInfoWidget.h +++ b/src/libtomahawk/widgets/infowidgets/AlbumInfoWidget.h @@ -41,6 +41,7 @@ class PlayableModel; class TreeModel; +class MetaAlbumInfoInterface; namespace Ui { @@ -70,7 +71,7 @@ public: virtual bool isTemporaryPage() const { return true; } virtual bool isBeingPlayed() const; - virtual bool jumpToCurrentTrack() { return false; } + virtual bool jumpToCurrentTrack(); public slots: /** \brief Loads information for a given album. @@ -104,10 +105,14 @@ private: PlayableModel* m_albumsModel; TreeModel* m_tracksModel; + Tomahawk::playlistinterface_ptr m_playlistInterface; + QString m_title; QString m_description; QString m_longDescription; QPixmap m_pixmap; + + friend class MetaAlbumInfoInterface; }; #endif // ALBUMINFOWIDGET_H diff --git a/src/libtomahawk/widgets/infowidgets/AlbumInfoWidget_p.h b/src/libtomahawk/widgets/infowidgets/AlbumInfoWidget_p.h new file mode 100644 index 000000000..b39fe65eb --- /dev/null +++ b/src/libtomahawk/widgets/infowidgets/AlbumInfoWidget_p.h @@ -0,0 +1,78 @@ +/* === 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 ALBUMINFOWIDGET_P_H +#define ALBUMINFOWIDGET_P_H + +#include "AlbumInfoWidget.h" +#include "ui_AlbumInfoWidget.h" +#include "PlaylistInterface.h" +#include "TreeProxyModel.h" +#include "Result.h" +#include "Typedefs.h" + +#include + +class MetaAlbumInfoInterface : public Tomahawk::PlaylistInterface +{ + Q_OBJECT +public: + explicit MetaAlbumInfoInterface( AlbumInfoWidget* w ) + : PlaylistInterface() + , m_w( w ) + { + connect( m_w->ui->tracksView->proxyModel()->playlistInterface().data(), SIGNAL( repeatModeChanged( Tomahawk::PlaylistModes::RepeatMode ) ), + SIGNAL( repeatModeChanged( Tomahawk::PlaylistModes::RepeatMode ) ) ); + + connect( m_w->ui->tracksView->proxyModel()->playlistInterface().data(), SIGNAL( shuffleModeChanged( bool ) ), + SIGNAL( shuffleModeChanged( bool ) ) ); + } + virtual ~MetaAlbumInfoInterface() {} + + + virtual Tomahawk::PlaylistModes::RepeatMode repeatMode() const { return m_w->ui->tracksView->proxyModel()->playlistInterface()->repeatMode(); } + virtual bool shuffled() const { return m_w->ui->tracksView->proxyModel()->playlistInterface()->shuffled(); } + + virtual Tomahawk::result_ptr currentItem() const { return m_w->ui->tracksView->proxyModel()->playlistInterface()->currentItem(); } + virtual Tomahawk::result_ptr siblingItem( int itemsAway ) { return m_w->ui->tracksView->proxyModel()->playlistInterface()->siblingItem( itemsAway ); } + virtual int trackCount() const { return m_w->ui->tracksView->proxyModel()->playlistInterface()->trackCount(); } + virtual QList< Tomahawk::query_ptr > tracks() { return m_w->ui->tracksView->proxyModel()->playlistInterface()->tracks(); } + + virtual bool hasChildInterface( Tomahawk::playlistinterface_ptr other ) + { + return m_w->ui->tracksView->proxyModel()->playlistInterface() == other || + m_w->ui->tracksView->proxyModel()->playlistInterface()->hasChildInterface( other ) || + m_w->ui->albumsView->playlistInterface()->hasChildInterface( other ); + } + + virtual void setRepeatMode( Tomahawk::PlaylistModes::RepeatMode mode ) + { + m_w->ui->tracksView->proxyModel()->playlistInterface()->setRepeatMode( mode ); + } + + virtual void setShuffled( bool enabled ) + { + m_w->ui->tracksView->proxyModel()->playlistInterface()->setShuffled( enabled ); + } + +private: + AlbumInfoWidget* m_w; + +}; + +#endif diff --git a/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget.cpp b/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget.cpp index 9227dbe13..b533d16a6 100644 --- a/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget.cpp +++ b/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget.cpp @@ -57,7 +57,7 @@ ArtistInfoWidget::ArtistInfoWidget( const Tomahawk::artist_ptr& artist, QWidget* widget->setPalette( pal ); widget->setAutoFillBackground( true ); - m_plInterface = Tomahawk::playlistinterface_ptr( new MetaPlaylistInterface( this ) ); + m_plInterface = Tomahawk::playlistinterface_ptr( new MetaArtistInfoInterface( this ) ); /* TomahawkUtils::unmarginLayout( ui->layoutWidget->layout() ); TomahawkUtils::unmarginLayout( ui->layoutWidget1->layout() ); @@ -173,6 +173,12 @@ ArtistInfoWidget::playlistInterface() const bool ArtistInfoWidget::isBeingPlayed() const { + if ( ui->albums->isBeingPlayed() ) + return true; + + if ( ui->relatedArtists->isBeingPlayed() ) + return true; + if ( ui->albums->playlistInterface() == AudioEngine::instance()->currentTrackPlaylist() ) return true; @@ -198,6 +204,12 @@ ArtistInfoWidget::jumpToCurrentTrack() if ( ui->topHits->jumpToCurrentTrack() ) return true; + if ( ui->albums->jumpToCurrentTrack() ) + return true; + + if ( ui->relatedArtists->jumpToCurrentTrack() ) + return true; + return false; } diff --git a/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget.h b/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget.h index c913ec859..a3b91f2a8 100644 --- a/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget.h +++ b/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget.h @@ -46,7 +46,7 @@ namespace Ui class ArtistInfoWidget; } -class MetaPlaylistInterface; +class MetaArtistInfoInterface; class DLLEXPORT ArtistInfoWidget : public QWidget, public Tomahawk::ViewPage { @@ -113,7 +113,7 @@ private: QString m_longDescription; QPixmap m_pixmap; - friend class MetaPlaylistInterface; + friend class ::MetaArtistInfoInterface; }; #endif // ARTISTINFOWIDGET_H diff --git a/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget_p.h b/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget_p.h index 10f6776b4..f923a5374 100644 --- a/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget_p.h +++ b/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget_p.h @@ -29,11 +29,11 @@ #include -class MetaPlaylistInterface : public Tomahawk::PlaylistInterface +class MetaArtistInfoInterface : public Tomahawk::PlaylistInterface { Q_OBJECT public: - explicit MetaPlaylistInterface( ArtistInfoWidget* w ) + explicit MetaArtistInfoInterface( ArtistInfoWidget* w ) : PlaylistInterface() , m_w( w ) { @@ -51,7 +51,7 @@ public: connect( m_w->ui->topHits->proxyModel()->playlistInterface().data(), SIGNAL( shuffleModeChanged( bool ) ), SLOT( anyShuffleChanged( bool ) ) ); } - virtual ~MetaPlaylistInterface() {} + virtual ~MetaArtistInfoInterface() {} // Any one is fine, we keep them all synched @@ -70,7 +70,9 @@ public: { return ( m_w->ui->albums->playlistInterface() == other ) || ( m_w->ui->relatedArtists->playlistInterface() == other ) || - ( m_w->ui->topHits->playlistInterface() == other ); + ( m_w->ui->topHits->playlistInterface() == other ) || + ( m_w->ui->albums->playlistInterface()->hasChildInterface( other ) ) || + ( m_w->ui->relatedArtists->playlistInterface()->hasChildInterface( other ) ); } public slots: From 7d5986e61fb6759f44b195283488aab1d0dca047 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Sat, 21 Jul 2012 21:07:13 -0400 Subject: [PATCH 05/79] Add friend type declaration --- src/libtomahawk/playlist/GridView.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libtomahawk/playlist/GridView.h b/src/libtomahawk/playlist/GridView.h index 56bce3332..13e8fa10b 100644 --- a/src/libtomahawk/playlist/GridView.h +++ b/src/libtomahawk/playlist/GridView.h @@ -123,7 +123,7 @@ private: QRect m_paintRect; - friend ::GridPlaylistInterface; + friend class ::GridPlaylistInterface; }; #endif // GRIDVIEW_H From 76a8e2b2b24f802a982b6223c89aef8d80d5549f Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Sun, 22 Jul 2012 10:58:25 -0400 Subject: [PATCH 06/79] Pointer guards --- .../widgets/infowidgets/AlbumInfoWidget.cpp | 8 ++++---- .../widgets/infowidgets/ArtistInfoWidget.cpp | 20 +++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/libtomahawk/widgets/infowidgets/AlbumInfoWidget.cpp b/src/libtomahawk/widgets/infowidgets/AlbumInfoWidget.cpp index bacbc1902..e5a61c1c8 100644 --- a/src/libtomahawk/widgets/infowidgets/AlbumInfoWidget.cpp +++ b/src/libtomahawk/widgets/infowidgets/AlbumInfoWidget.cpp @@ -87,13 +87,13 @@ AlbumInfoWidget::isBeingPlayed() const //tDebug() << Q_FUNC_INFO << "albumsView playlistInterface = " << ui->albumsView->playlistInterface()->id(); //tDebug() << Q_FUNC_INFO << "tracksView playlistInterface = " << ui->tracksView->playlistInterface()->id(); - if ( ui->albumsView->isBeingPlayed() ) + if ( ui->albumsView && ui->albumsView->isBeingPlayed() ) return true; - if ( ui->albumsView->playlistInterface() == AudioEngine::instance()->currentTrackPlaylist() ) + if ( ui->albumsView && ui->albumsView->playlistInterface() == AudioEngine::instance()->currentTrackPlaylist() ) return true; - if ( ui->tracksView->playlistInterface() == AudioEngine::instance()->currentTrackPlaylist() ) + if ( ui->tracksView && ui->tracksView->playlistInterface() == AudioEngine::instance()->currentTrackPlaylist() ) return true; return false; @@ -103,7 +103,7 @@ AlbumInfoWidget::isBeingPlayed() const bool AlbumInfoWidget::jumpToCurrentTrack() { - return ui->albumsView->jumpToCurrentTrack(); + return ui->albumsView && ui->albumsView->jumpToCurrentTrack(); } diff --git a/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget.cpp b/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget.cpp index b533d16a6..086d6ed3d 100644 --- a/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget.cpp +++ b/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget.cpp @@ -173,19 +173,19 @@ ArtistInfoWidget::playlistInterface() const bool ArtistInfoWidget::isBeingPlayed() const { - if ( ui->albums->isBeingPlayed() ) + if ( ui->albums && ui->albums->isBeingPlayed() ) return true; - if ( ui->relatedArtists->isBeingPlayed() ) + if ( ui->relatedArtists && ui->relatedArtists->isBeingPlayed() ) return true; - if ( ui->albums->playlistInterface() == AudioEngine::instance()->currentTrackPlaylist() ) + if ( ui->albums && ui->albums->playlistInterface() == AudioEngine::instance()->currentTrackPlaylist() ) return true; - if ( ui->relatedArtists->playlistInterface() == AudioEngine::instance()->currentTrackPlaylist() ) + if ( ui->relatedArtists && ui->relatedArtists->playlistInterface() == AudioEngine::instance()->currentTrackPlaylist() ) return true; - if ( ui->topHits->playlistInterface() == AudioEngine::instance()->currentTrackPlaylist() ) + if ( ui->topHits && ui->topHits->playlistInterface() == AudioEngine::instance()->currentTrackPlaylist() ) return true; return false; @@ -195,19 +195,19 @@ ArtistInfoWidget::isBeingPlayed() const bool ArtistInfoWidget::jumpToCurrentTrack() { - if ( ui->albums->jumpToCurrentTrack() ) + if ( ui->albums && ui->albums->jumpToCurrentTrack() ) return true; - if ( ui->relatedArtists->jumpToCurrentTrack() ) + if ( ui->relatedArtists && ui->relatedArtists->jumpToCurrentTrack() ) return true; - if ( ui->topHits->jumpToCurrentTrack() ) + if ( ui->topHits && ui->topHits->jumpToCurrentTrack() ) return true; - if ( ui->albums->jumpToCurrentTrack() ) + if ( ui->albums && ui->albums->jumpToCurrentTrack() ) return true; - if ( ui->relatedArtists->jumpToCurrentTrack() ) + if ( ui->relatedArtists && ui->relatedArtists->jumpToCurrentTrack() ) return true; return false; From 7690eddff33d12c2b61a1b2c2d49eaf9c09311e1 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Sun, 22 Jul 2012 14:09:41 -0400 Subject: [PATCH 07/79] New source tree popup widget for playlist delete confirmation --- src/libtomahawk/CMakeLists.txt | 1 + src/libtomahawk/Playlist.cpp | 2 +- src/libtomahawk/utils/Closure.cpp | 3 +- .../widgets/SourceTreePopupDialog.cpp | 162 ++++++++++++++++++ .../widgets/SourceTreePopupDialog.h | 69 ++++++++ src/sourcetree/SourceTreeView.cpp | 39 ++++- src/sourcetree/SourceTreeView.h | 6 +- 7 files changed, 270 insertions(+), 12 deletions(-) create mode 100644 src/libtomahawk/widgets/SourceTreePopupDialog.cpp create mode 100644 src/libtomahawk/widgets/SourceTreePopupDialog.h diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index 0a325c166..723730dc8 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -139,6 +139,7 @@ set( libGuiSources widgets/ToggleButton.cpp widgets/FadingPixmap.cpp widgets/SocialPlaylistWidget.cpp + widgets/SourceTreePopupDialog.cpp widgets/infowidgets/SourceInfoWidget.cpp widgets/infowidgets/ArtistInfoWidget.cpp widgets/infowidgets/AlbumInfoWidget.cpp diff --git a/src/libtomahawk/Playlist.cpp b/src/libtomahawk/Playlist.cpp index 1762b7b26..b7f9cc837 100644 --- a/src/libtomahawk/Playlist.cpp +++ b/src/libtomahawk/Playlist.cpp @@ -508,7 +508,7 @@ Playlist::setNewRevision( const QString& rev, tDebug() << "m_entries" << m_entries; tLog() << "Playlist error for playlist with guid" << guid() << "from source" << author()->friendlyName(); - Q_ASSERT( false ); // XXX +// Q_ASSERT( false ); // XXX } } diff --git a/src/libtomahawk/utils/Closure.cpp b/src/libtomahawk/utils/Closure.cpp index 2b2a608bb..8fec43b97 100644 --- a/src/libtomahawk/utils/Closure.cpp +++ b/src/libtomahawk/utils/Closure.cpp @@ -1,5 +1,6 @@ /* This file is part of Clementine. Copyright 2011, David Sansome + Copyright 2012, Leo Franchi Clementine is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -29,7 +30,7 @@ Closure::Closure(QObject* sender, const ClosureArgumentWrapper* val3) : QObject(receiver), callback_(NULL), - autoDelete_( true ), + autoDelete_(true), val0_(val0), val1_(val1), val2_(val2), diff --git a/src/libtomahawk/widgets/SourceTreePopupDialog.cpp b/src/libtomahawk/widgets/SourceTreePopupDialog.cpp new file mode 100644 index 000000000..cabdc73a7 --- /dev/null +++ b/src/libtomahawk/widgets/SourceTreePopupDialog.cpp @@ -0,0 +1,162 @@ +/* === 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 "SourceTreePopupDialog.h" + +#include "sourcetree/SourceTreeView.h" + +#include +#include +#include +#include +#include +#include +#include + +SourceTreePopupDialog::SourceTreePopupDialog( SourceTreeView* parent ) + : QWidget( 0 ) + , m_result( false ) + , m_label( 0 ) + , m_buttons( 0 ) +{ + setWindowFlags( Qt::FramelessWindowHint ); + setWindowFlags( Qt::Popup ); + + setAutoFillBackground( false ); + setAttribute( Qt::WA_TranslucentBackground, true ); + + setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ); + + m_label = new QLabel( this ); + m_buttons = new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this ); + m_buttons->button( QDialogButtonBox::Ok )->setIcon( QIcon() ); + m_buttons->button( QDialogButtonBox::Cancel )->setIcon( QIcon() ); + + connect( m_buttons, SIGNAL( accepted() ), this, SLOT( onAccepted() ) ); + connect( m_buttons, SIGNAL( rejected() ), this, SLOT( onRejected() ) ); + + setLayout( new QVBoxLayout ); + + layout()->addWidget( m_label ); + layout()->addWidget( m_buttons ); +/* + m_buttons->button( QDialogButtonBox::Ok )->setStyleSheet( + "QPushButton { \ + background-color: #F15C5E; \ + border-style: solid; \ + border-width: 1px; \ + border-radius: 10px; \ + border-color: #B64547; \ + padding: 2px; \ + } \ + QPushButton:pressed { \ + border-style: solid; \ + border-width: 1px; \ + border-radius: 10px; \ + border-color: #B64547; \ + background-color: #D35052; \ + border-style: flat; \ + }" );*/ +} + + +void +SourceTreePopupDialog::setMainText( const QString& text ) +{ + m_label->setText( text ); +} + + +void +SourceTreePopupDialog::setOkButtonText( const QString& text ) +{ + if ( m_buttons && m_buttons->button( QDialogButtonBox::Ok ) ) + m_buttons->button( QDialogButtonBox::Ok )->setText( text ); +} + + +void +SourceTreePopupDialog::paintEvent( QPaintEvent* event ) +{ + // Constants for painting + const int leftTriangleWidth = 20; + const int cornerRounding = 8; + const int leftEdgeOffset = offset() - 6; + const QRect brect = rect().adjusted( 2, 3, -2, -3 ); + + QPainterPath outline; + // Left triangle top branch + outline.moveTo( brect.left(), brect.height() / 2 ); + outline.lineTo( leftEdgeOffset, brect.height() / 2 - leftTriangleWidth / 2 ); + + // main outline + outline.lineTo( leftEdgeOffset, cornerRounding ); + outline.quadTo( QPoint( leftEdgeOffset, brect.top() ), QPoint( leftEdgeOffset + cornerRounding, brect.top() ) ); + outline.lineTo( brect.width() - cornerRounding, brect.top() ); + outline.quadTo( QPoint( brect.width(), brect.top() ), QPoint( brect.width(), cornerRounding ) ); + outline.lineTo( brect.width(), brect.height() - cornerRounding ); + outline.quadTo( brect.bottomRight(), QPoint( brect.right() - cornerRounding, brect.height() ) ); + outline.lineTo( leftEdgeOffset + cornerRounding, brect.height() ); + outline.quadTo( QPoint( leftEdgeOffset, brect.height() ), QPoint( leftEdgeOffset, brect.height() - cornerRounding ) ); + + // Left triangle bottom branch + outline.lineTo( leftEdgeOffset, brect.height() / 2 + leftTriangleWidth / 2 ); + outline.lineTo( brect.left(), brect.height() / 2 ); + + QPainter p( this ); + p.setRenderHint( QPainter::Antialiasing ); + + QPen pen( QColor( "#3F4247" ) ); + pen.setWidth( 2 ); + p.setPen( pen ); + p.drawPath( outline ); + + p.fillPath( outline, QColor( "#D6E3F1" ) ); +} + + +void +SourceTreePopupDialog::focusOutEvent( QFocusEvent* ) +{ + hide(); +} + + +void +SourceTreePopupDialog::showEvent( QShowEvent* ) +{ + m_result = false; +} + + +void +SourceTreePopupDialog::onAccepted() +{ + hide(); + m_result = true; + emit result( m_result ); +} + + +void +SourceTreePopupDialog::onRejected() +{ + hide(); + m_result = false; + emit result( m_result ); +} diff --git a/src/libtomahawk/widgets/SourceTreePopupDialog.h b/src/libtomahawk/widgets/SourceTreePopupDialog.h new file mode 100644 index 000000000..f181dfe2a --- /dev/null +++ b/src/libtomahawk/widgets/SourceTreePopupDialog.h @@ -0,0 +1,69 @@ +/* === 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 SOURCETREE_POPUP_DIALOG +#define SOURCETREE_POPUP_DIALOG + +#include "DllMacro.h" + +#include + +class QShowEvent; +class QLabel; +class QDialogButtonBox; +class QPushButton; +class QFocusEvent; +class SourceTreeView; + +/** + * Place me at offset() to the left of the right edge of the sourcetree. + */ +class DLLEXPORT SourceTreePopupDialog : public QWidget +{ + Q_OBJECT +public: + explicit SourceTreePopupDialog( SourceTreeView* parent ); + + int offset() const { return 14; } + + void setMainText( const QString& text ); + void setOkButtonText( const QString& text ); + + bool resultValue() const { return m_result; } + +signals: + void result( bool accepted ); + +protected: + virtual void paintEvent( QPaintEvent* ); + virtual void focusOutEvent( QFocusEvent* ); + virtual void showEvent( QShowEvent* ); + +private slots: + void onAccepted(); + void onRejected(); + +private: + QString m_text; + bool m_result; + + QLabel* m_label; + QDialogButtonBox* m_buttons; +}; + +#endif diff --git a/src/sourcetree/SourceTreeView.cpp b/src/sourcetree/SourceTreeView.cpp index 55a97a338..577b0649c 100644 --- a/src/sourcetree/SourceTreeView.cpp +++ b/src/sourcetree/SourceTreeView.cpp @@ -51,6 +51,8 @@ #include "LatchManager.h" #include "utils/TomahawkUtilsGui.h" #include "utils/Logger.h" +#include +#include "widgets/SourceTreePopupDialog.h" using namespace Tomahawk; @@ -362,29 +364,48 @@ SourceTreeView::deletePlaylist( const QModelIndex& idxIn ) Q_ASSERT( false ); } - QMessageBox askDelete( QMessageBox::Question, tr( "Delete %1?", "playlist/station/..." ).arg( typeDesc ), - tr( "Would you like to delete the %1 \"%2\"?", "e.g. Would you like to delete the playlist named Foobar?" ) - .arg( typeDesc ).arg( idx.data().toString() ), - QMessageBox::Yes | QMessageBox::No, this ); + if ( m_popupDialog.isNull() ) + { + m_popupDialog = QWeakPointer< SourceTreePopupDialog >( new SourceTreePopupDialog( this ) ); + connect( m_popupDialog.data(), SIGNAL( result( bool ) ), this, SLOT( onDeletePlaylistResult( bool ) ) ); + } -#ifdef Q_OS_MAC - askDelete.setWindowModality( Qt::WindowModal ); -#endif + m_popupDialog.data()->setMainText( tr( "Would you like to delete the %1 \"%2\"?", "e.g. Would you like to delete the playlist named Foobar?" ) + .arg( typeDesc ).arg( idx.data().toString() ) ); + m_popupDialog.data()->setOkButtonText( tr( "Delete" ) ); + m_popupDialog.data()->setProperty( "idx", QVariant::fromValue< QModelIndex >( idx ) ); - int r = askDelete.exec(); - if ( r != QMessageBox::Yes ) + const QPoint rightCenter = viewport()->mapToGlobal( visualRect( idx ).topRight() + QPoint( 0, visualRect( idx ).height() / 2 ) ); + m_popupDialog.data()->move( rightCenter.x() - m_popupDialog.data()->offset(), rightCenter.y() - m_popupDialog.data()->sizeHint().height() / 2. ); + m_popupDialog.data()->show(); +} + + +void +SourceTreeView::onDeletePlaylistResult( bool result ) +{ + Q_ASSERT( !m_popupDialog.isNull() ); + + const QModelIndex idx = m_popupDialog.data()->property( "idx" ).value< QModelIndex >(); + Q_ASSERT( idx.isValid() ); + + if ( !result ) return; + SourcesModel::RowType type = ( SourcesModel::RowType )model()->data( idx, SourcesModel::SourceTreeItemTypeRole ).toInt(); + if ( type == SourcesModel::StaticPlaylist ) { PlaylistItem* item = itemFromIndex< PlaylistItem >( idx ); playlist_ptr playlist = item->playlist(); + qDebug() << "Doing delete of playlist:" << playlist->title(); Playlist::remove( playlist ); } else if ( type == SourcesModel::AutomaticPlaylist || type == SourcesModel::Station ) { DynamicPlaylistItem* item = itemFromIndex< DynamicPlaylistItem >( idx ); dynplaylist_ptr playlist = item->dynPlaylist(); + qDebug() << "Doing delete of playlist:" << playlist->title(); DynamicPlaylist::remove( playlist ); } } diff --git a/src/sourcetree/SourceTreeView.h b/src/sourcetree/SourceTreeView.h index 775ecb62b..9959b01c3 100644 --- a/src/sourcetree/SourceTreeView.h +++ b/src/sourcetree/SourceTreeView.h @@ -26,6 +26,7 @@ #include #include +class SourceTreePopupDialog; class CollectionModel; class PlaylistModel; class SourcesModel; @@ -84,6 +85,8 @@ private slots: void onCustomContextMenu( const QPoint& pos ); void onSelectionChanged(); + void onDeletePlaylistResult( bool result ); + protected: void drawRow( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const; @@ -106,6 +109,7 @@ private: QModelIndex m_contextMenuIndex; SourceDelegate* m_delegate; Tomahawk::LatchManager* m_latchManager; + QWeakPointer m_popupDialog; QMenu m_playlistMenu; QMenu m_roPlaylistMenu; @@ -115,7 +119,7 @@ private: bool m_dragging; QRect m_dropRect; QPersistentModelIndex m_dropIndex; - + QPersistentModelIndex m_selectedIndex; }; From e46a5f307fd43b8b16906bf23c0b82e7afd1a086 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hugo=20Lindstr=C3=B6m?= Date: Sun, 22 Jul 2012 20:45:00 +0200 Subject: [PATCH 08/79] Set resulthint from resolver lookups --- src/libtomahawk/utils/SpotifyParser.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libtomahawk/utils/SpotifyParser.cpp b/src/libtomahawk/utils/SpotifyParser.cpp index d312934c2..3f7bbb577 100644 --- a/src/libtomahawk/utils/SpotifyParser.cpp +++ b/src/libtomahawk/utils/SpotifyParser.cpp @@ -337,6 +337,9 @@ SpotifyParser::playlistListingResult( const QString& msgType, const QVariantMap& if ( q.isNull() ) continue; + if( !trackMap.value( "id" ).toString().isEmpty() ) + q->setResultHint( trackMap.value( "id" ).toString() ); + m_tracks << q; } From 6790a10615d05a96e6c309988f8c2f9e688f7fb8 Mon Sep 17 00:00:00 2001 From: Tomahawk CI Date: Sun, 22 Jul 2012 22:16:56 +0000 Subject: [PATCH 09/79] 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 | 46 +++++++++++++++++++++--------------------- 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, 93 insertions(+), 93 deletions(-) diff --git a/lang/tomahawk_ar.ts b/lang/tomahawk_ar.ts index 8d022ae17..ec00d1022 100644 --- a/lang/tomahawk_ar.ts +++ b/lang/tomahawk_ar.ts @@ -146,17 +146,17 @@ connect and stream from you? ألبومات أخرى للفنان - + Sorry, we could not find any other albums for this artist! نعتذر, لم نستطيع إيجاد ألبومات أخرى لهذا الفنان! - + Sorry, we could not find any tracks for this album! نعتذر، لم نستطيع إيجاد أغاني أخرى لهذا الألبوم! - + Other Albums by %1 ألبومات أخرى ل%1 @@ -3711,12 +3711,12 @@ You can re-send a sync message at any time simply by sending another tweet using الأغاني التي إستمعت إليها مؤخرا - + No recently created playlists in your network. لا قوائم أغاني جديدة أنشئت مؤخرا على شبكتك. - + Welcome to Tomahawk مرحبا بكم في توماهوك diff --git a/lang/tomahawk_bg.ts b/lang/tomahawk_bg.ts index 69c7fb575..8d74916d2 100644 --- a/lang/tomahawk_bg.ts +++ b/lang/tomahawk_bg.ts @@ -145,17 +145,17 @@ connect and stream from you? Други албуми на този артист - + Sorry, we could not find any other albums for this artist! Съжалявам, но не откривам нито един албум от този артист! - + Sorry, we could not find any tracks for this album! Съжалявам, но не откривам нито една песен за този артист! - + Other Albums by %1 Други албуми от %1 @@ -3723,12 +3723,12 @@ You can re-send a sync message at any time simply by sending another tweet using Наскоро изпълнени - + No recently created playlists in your network. Не откривам наскоро създадени списъци в твоята мрежа - + Welcome to Tomahawk Здравей! diff --git a/lang/tomahawk_ca.ts b/lang/tomahawk_ca.ts index 955a02cd4..5cbd98bf0 100644 --- a/lang/tomahawk_ca.ts +++ b/lang/tomahawk_ca.ts @@ -145,17 +145,17 @@ connect and stream from you? Altres Àlbums de l'Artista - + Sorry, we could not find any other albums for this artist! - + Sorry, we could not find any tracks for this album! - + Other Albums by %1 Altres Àlbums de %1 @@ -3710,12 +3710,12 @@ Podeu reenviar un missatge de sincronisme en qualsevol moment simplement enviant Cançons Escoltades Recentment - + No recently created playlists in your network. No hi ha cançons escoltades recentment a la xarxa. - + Welcome to Tomahawk Us donem la benvinguda a Tomahawk diff --git a/lang/tomahawk_de.ts b/lang/tomahawk_de.ts index cc0a37f69..4ecc74216 100644 --- a/lang/tomahawk_de.ts +++ b/lang/tomahawk_de.ts @@ -146,17 +146,17 @@ erlauben sich mit dir zu verbinden? Andere Alben des Künstlers - + Sorry, we could not find any other albums for this artist! Sorry, wir konnten keine anderen Alben für diesen Künstler finden! - + Sorry, we could not find any tracks for this album! Sorry, wir konnten keine anderen Lieder für dieses Album finden! - + Other Albums by %1 Andere Alben von %1 @@ -3701,12 +3701,12 @@ You can re-send a sync message at any time simply by sending another tweet using Kürzlich gehörte Lieder - + No recently created playlists in your network. Es gibt keine kürzlich erstellten Playlisten in deinem Netzwerk. - + Welcome to Tomahawk Willkommen bei Tomahawk diff --git a/lang/tomahawk_en.ts b/lang/tomahawk_en.ts index 893995482..8b30b28ea 100644 --- a/lang/tomahawk_en.ts +++ b/lang/tomahawk_en.ts @@ -146,17 +146,17 @@ connect and stream from you? Other Albums by Artist - + Sorry, we could not find any other albums for this artist! Sorry, we could not find any other albums for this artist! - + Sorry, we could not find any tracks for this album! Sorry, we could not find any tracks for this album! - + Other Albums by %1 Other Albums by %1 @@ -3711,12 +3711,12 @@ You can re-send a sync message at any time simply by sending another tweet using Recently Played Tracks - + No recently created playlists in your network. No recently created playlists in your network. - + Welcome to Tomahawk Welcome to Tomahawk diff --git a/lang/tomahawk_es.ts b/lang/tomahawk_es.ts index 5137dfcd0..5795d583b 100644 --- a/lang/tomahawk_es.ts +++ b/lang/tomahawk_es.ts @@ -145,17 +145,17 @@ connect and stream from you? Otros álbumes por el artista - + Sorry, we could not find any other albums for this artist! - + Sorry, we could not find any tracks for this album! - + Other Albums by %1 Otros álbumes por %1 @@ -3709,12 +3709,12 @@ Puede reenviar el mensaje de sincronización en cualquier momento simplemente en Pistas reproducidas recientemente - + No recently created playlists in your network. No hay listas de reproducción recientemente creadas en su red. - + Welcome to Tomahawk Bienvenido a Tomahawk diff --git a/lang/tomahawk_fr.ts b/lang/tomahawk_fr.ts index 62e675a3c..190c16323 100644 --- a/lang/tomahawk_fr.ts +++ b/lang/tomahawk_fr.ts @@ -146,17 +146,17 @@ de se connecter et streamer de vous? Tous les albums par cet artiste - + Sorry, we could not find any other albums for this artist! Désolé, aucun autre album n'a pu être trouvé pour cet artiste ! - + Sorry, we could not find any tracks for this album! Désolé, on a pas pu trouver aucune pistes pour cet album! - + Other Albums by %1 Autres albums de %1 @@ -3711,12 +3711,12 @@ Vous pouvez envoyer un message de synchronisation quand vous le souhaitez en env Joués récemment - + No recently created playlists in your network. Pas de liste de lecture créée récemment sur votre réseau. - + Welcome to Tomahawk Bienvenue dans Tomahawk diff --git a/lang/tomahawk_ja.ts b/lang/tomahawk_ja.ts index 19c1685c7..55a4173d6 100644 --- a/lang/tomahawk_ja.ts +++ b/lang/tomahawk_ja.ts @@ -5,12 +5,12 @@ Allow %1 to connect and stream from you? - + %1からの接続、又はストリーミングを許可しますか? Allow Streaming - + ストリーミングを許可 @@ -23,7 +23,7 @@ connect and stream from you? Tomahawk needs you to decide whether %1 is allowed to connect. - + %1からの接続を許可することが必要です。 @@ -145,17 +145,17 @@ connect and stream from you? 他のアルバム - + Sorry, we could not find any other albums for this artist! このアーティストのアルバムは他に見つかりませんでした。 - + Sorry, we could not find any tracks for this album! このアルバムの曲は見つかりませんでした。 - + Other Albums by %1 %1の他のアルバム @@ -451,7 +451,7 @@ connect and stream from you? About - + 情報 @@ -1690,12 +1690,12 @@ connect and stream from you? Local Music Information - + ローカルミュージック情報 Path to scan for music files: - + 音楽ファイルの検索パス: @@ -1708,42 +1708,42 @@ connect and stream from you? Upload collection list to The Echo Nest to enable user radio - + The Echo Nestにコレクションのリストをアップロードして、ユーザーラジオを有効にする Watch for changes - + 変更を監視 Time between scans, in seconds: - + スキャン作業の時間間隔(秒数): Advanced Settings - + 詳細設定 Remote Peer Connection Method - + リモートピアとの接続方法 None (outgoing connections only) - + 無 (出接続のみ) Use UPnP to establish port forward (recommended) - + UPnPを使用して、ポートのフォワーディングを設ける (推奨) Use static external IP address/host name and port - + グローバル静的IP、又はホスト名とポートを使用する @@ -1753,22 +1753,22 @@ connect and stream from you? SOCKS Proxy - + SOCKSのプロクシ Use SOCKS Proxy - + SOCKSのプロクシを使用する Clear All Access Control Entries - + 全てのアクセス制御のエントリーを削除する Internet Services - + インターネットサービス @@ -3701,12 +3701,12 @@ Twitterを使っている友達にTomahawkを接続したいなら、ツイー 最近再生したトラック - + No recently created playlists in your network. ネットワークに最近作成したプレイリストはありません。 - + Welcome to Tomahawk Tomahawkへようこそ diff --git a/lang/tomahawk_pl.ts b/lang/tomahawk_pl.ts index 4b7d2cfd6..f29ab9498 100644 --- a/lang/tomahawk_pl.ts +++ b/lang/tomahawk_pl.ts @@ -145,17 +145,17 @@ connect and stream from you? Inne albumy artysty - + Sorry, we could not find any other albums for this artist! - + Sorry, we could not find any tracks for this album! - + Other Albums by %1 Inne albumy %1 @@ -3705,12 +3705,12 @@ Zawsze możesz ponownie wysłać wiadomość synchronizacyjną - po prostu wyśl Ostatnio Odtworzone Utwory - + No recently created playlists in your network. Brak ostatnio utworzonych list w twojej sieci. - + Welcome to Tomahawk Witaj w Tomahawk diff --git a/lang/tomahawk_pt_BR.ts b/lang/tomahawk_pt_BR.ts index d33e59fa4..9328a2347 100644 --- a/lang/tomahawk_pt_BR.ts +++ b/lang/tomahawk_pt_BR.ts @@ -146,17 +146,17 @@ se conecte e faça o stream de você? Outros álbuns do artista - + Sorry, we could not find any other albums for this artist! Desculpe, mas não conseguimos encontrar outro álbum para este artista! - + Sorry, we could not find any tracks for this album! Desculpe, mas não conseguimos encontrar outras faixas para este álbum! - + Other Albums by %1 Outros álbuns de %1 @@ -3711,12 +3711,12 @@ Você pode enviar uma outra mensagem de sincronia a qualquer momento simplesment Faixas reproduzidas recentemente - + No recently created playlists in your network. Nenhuma lista de reprodução criada recentemente na sua rede. - + Welcome to Tomahawk Bem-vindo ao Tomahawk diff --git a/lang/tomahawk_ru.ts b/lang/tomahawk_ru.ts index 7d42754ce..f13c31fbd 100644 --- a/lang/tomahawk_ru.ts +++ b/lang/tomahawk_ru.ts @@ -145,17 +145,17 @@ connect and stream from you? Другие альбомы артиста - + Sorry, we could not find any other albums for this artist! - + Sorry, we could not find any tracks for this album! - + Other Albums by %1 Другие альбомы %1 @@ -3703,12 +3703,12 @@ You can re-send a sync message at any time simply by sending another tweet using Последние Воспроизводимые Песни - + No recently created playlists in your network. Нет списков, созданных в последнее время в вашей сети. - + Welcome to Tomahawk Добро пожаловать в Tomahawk diff --git a/lang/tomahawk_sv.ts b/lang/tomahawk_sv.ts index 7babac319..4f4c35ac8 100644 --- a/lang/tomahawk_sv.ts +++ b/lang/tomahawk_sv.ts @@ -145,17 +145,17 @@ connect and stream from you? Andra album av artisten - + Sorry, we could not find any other albums for this artist! - + Sorry, we could not find any tracks for this album! - + Other Albums by %1 Andra album av %1 @@ -3694,12 +3694,12 @@ You can re-send a sync message at any time simply by sending another tweet using Senaste spelade spår - + No recently created playlists in your network. Inga skapade spellistor i ditt nätverk på sistone. - + Welcome to Tomahawk Välkommen till Tomahawk diff --git a/lang/tomahawk_tr.ts b/lang/tomahawk_tr.ts index e167967a9..350c31e87 100644 --- a/lang/tomahawk_tr.ts +++ b/lang/tomahawk_tr.ts @@ -145,17 +145,17 @@ connect and stream from you? Sanatçının Diğer Albümleri - + Sorry, we could not find any other albums for this artist! - + Sorry, we could not find any tracks for this album! - + Other Albums by %1 Diğer %1 Albümleri @@ -3693,12 +3693,12 @@ You can re-send a sync message at any time simply by sending another tweet using - + No recently created playlists in your network. - + Welcome to Tomahawk diff --git a/lang/tomahawk_zh_CN.ts b/lang/tomahawk_zh_CN.ts index 010057964..da9cd841b 100644 --- a/lang/tomahawk_zh_CN.ts +++ b/lang/tomahawk_zh_CN.ts @@ -145,17 +145,17 @@ connect and stream from you? 艺人的其他专辑 - + Sorry, we could not find any other albums for this artist! - + Sorry, we could not find any tracks for this album! - + Other Albums by %1 %1 的其他专辑 @@ -3693,12 +3693,12 @@ You can re-send a sync message at any time simply by sending another tweet using 最近播放曲目 - + No recently created playlists in your network. - + Welcome to Tomahawk diff --git a/lang/tomahawk_zh_TW.ts b/lang/tomahawk_zh_TW.ts index 3f38ca231..bd29dee6a 100644 --- a/lang/tomahawk_zh_TW.ts +++ b/lang/tomahawk_zh_TW.ts @@ -145,17 +145,17 @@ connect and stream from you? 列出演出者的其他專輯 - + Sorry, we could not find any other albums for this artist! - + Sorry, we could not find any tracks for this album! - + Other Albums by %1 列出所有其他專輯,依 %1 @@ -3693,12 +3693,12 @@ You can re-send a sync message at any time simply by sending another tweet using 最近播放的曲目 - + No recently created playlists in your network. 沒有最近建立的播放清單在您的網路。 - + Welcome to Tomahawk 歡迎到 Tomahawk From 544112847343f393f977b029273b3244705c201b Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Mon, 23 Jul 2012 17:15:47 -0400 Subject: [PATCH 10/79] Add workaround for Qt bug for Qt::Popup on OS X/Cocoa --- src/libtomahawk/CMakeLists.txt | 3 +- .../widgets/SourceTreePopupDialog.cpp | 11 ++++++ .../widgets/SourceTreePopupDialog_mac.h | 29 +++++++++++++++ .../widgets/SourceTreePopupDialog_mac.mm | 35 +++++++++++++++++++ 4 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 src/libtomahawk/widgets/SourceTreePopupDialog_mac.h create mode 100644 src/libtomahawk/widgets/SourceTreePopupDialog_mac.mm diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index 723730dc8..f5577de71 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -391,7 +391,8 @@ IF( APPLE ) SET( libSources ${libSources} utils/TomahawkUtils_Mac.mm mac/FileHelpers.mm - thirdparty/Qocoa/qsearchfield_mac.mm ) + thirdparty/Qocoa/qsearchfield_mac.mm + widgets/SourceTreePopupDialog_mac.mm ) SET_SOURCE_FILES_PROPERTIES(utils/TomahawkUtils_Mac.mm PROPERTIES COMPILE_FLAGS "-fvisibility=default") diff --git a/src/libtomahawk/widgets/SourceTreePopupDialog.cpp b/src/libtomahawk/widgets/SourceTreePopupDialog.cpp index cabdc73a7..062171a72 100644 --- a/src/libtomahawk/widgets/SourceTreePopupDialog.cpp +++ b/src/libtomahawk/widgets/SourceTreePopupDialog.cpp @@ -28,6 +28,10 @@ #include #include +#ifdef QT_MAC_USE_COCOA +#include "SourceTreePopupDialog_mac.h" +#endif + SourceTreePopupDialog::SourceTreePopupDialog( SourceTreeView* parent ) : QWidget( 0 ) , m_result( false ) @@ -127,6 +131,13 @@ SourceTreePopupDialog::paintEvent( QPaintEvent* event ) p.drawPath( outline ); p.fillPath( outline, QColor( "#D6E3F1" ) ); + +#ifdef QT_MAC_USE_COCOA + // Work around bug in Qt/Mac Cocoa where opening subsequent popups + // would incorrectly calculate the background due to it not being + // invalidated. + SourceTreePopupHelper::clearBackground( this ); +#endif } diff --git a/src/libtomahawk/widgets/SourceTreePopupDialog_mac.h b/src/libtomahawk/widgets/SourceTreePopupDialog_mac.h new file mode 100644 index 000000000..86649cbb5 --- /dev/null +++ b/src/libtomahawk/widgets/SourceTreePopupDialog_mac.h @@ -0,0 +1,29 @@ +/* === 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 SOURCETREE_POPUP_DIALOG_MAC_H +#define SOURCETREE_POPUP_DIALOG_MAC_H + +class QWidget; + +namespace SourceTreePopupHelper { + +void clearBackground( QWidget* widget ); + +} +#endif diff --git a/src/libtomahawk/widgets/SourceTreePopupDialog_mac.mm b/src/libtomahawk/widgets/SourceTreePopupDialog_mac.mm new file mode 100644 index 000000000..8ae495eaf --- /dev/null +++ b/src/libtomahawk/widgets/SourceTreePopupDialog_mac.mm @@ -0,0 +1,35 @@ +/* === 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 "SourceTreePopupDialog_mac.h" + +#include + +#import +#import +#import + +void +SourceTreePopupHelper::clearBackground( QWidget* widget ) +{ + Q_ASSERT( widget ); + // Workaround from QTBUG-15368 + NSView* view = reinterpret_cast< NSView* >( widget->winId() ); + NSWindow* cocoaWindow = [view window]; + [cocoaWindow invalidateShadow]; +} From c2285dba8401db3098d5a301336363d27370d7ba Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Mon, 23 Jul 2012 17:46:00 -0400 Subject: [PATCH 11/79] Show creator of playlist in infobar if it exists --- src/libtomahawk/playlist/PlaylistModel.cpp | 2 +- src/libtomahawk/utils/SpotifyParser.cpp | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/libtomahawk/playlist/PlaylistModel.cpp b/src/libtomahawk/playlist/PlaylistModel.cpp index b324b2f42..f5724aaa4 100644 --- a/src/libtomahawk/playlist/PlaylistModel.cpp +++ b/src/libtomahawk/playlist/PlaylistModel.cpp @@ -80,7 +80,7 @@ PlaylistModel::loadPlaylist( const Tomahawk::playlist_ptr& playlist, bool loadEn setReadOnly( !m_playlist->author()->isLocal() ); setTitle( playlist->title() ); setDescription( tr( "A playlist by %1, created %2" ) - .arg( playlist->author()->isLocal() ? tr( "you" ) : playlist->author()->friendlyName() ) + .arg( playlist->creator().isEmpty() ? ( playlist->author()->isLocal() ? tr( "you" ) : playlist->author()->friendlyName() ) : playlist->creator() ) .arg( TomahawkUtils::ageToString( QDateTime::fromTime_t( playlist->createdOn() ), true ) ) ); m_isTemporary = false; diff --git a/src/libtomahawk/utils/SpotifyParser.cpp b/src/libtomahawk/utils/SpotifyParser.cpp index d312934c2..e937f8716 100644 --- a/src/libtomahawk/utils/SpotifyParser.cpp +++ b/src/libtomahawk/utils/SpotifyParser.cpp @@ -105,7 +105,7 @@ SpotifyParser::lookupSpotifyBrowse( const QString& linkRaw ) m_browseUri.replace( "/", ":" ); m_browseUri = "spotify:" + m_browseUri; } - + if ( m_browseUri.contains( "playlist" ) && Tomahawk::Accounts::SpotifyAccount::instance() != 0 && Tomahawk::Accounts::SpotifyAccount::instance()->loggedIn() ) @@ -303,7 +303,7 @@ SpotifyParser::spotifyTrackLookupFinished() if ( !q.isNull() ) { q->setResultHint( t.value( "trackuri" ).toString() ); - + m_tracks << q; } } @@ -333,10 +333,10 @@ SpotifyParser::playlistListingResult( const QString& msgType, const QVariantMap& { QVariantMap trackMap = blob.toMap(); const query_ptr q = Query::get( trackMap.value( "artist" ).toString(), trackMap.value( "track" ).toString(), trackMap.value( "album" ).toString(), uuid(), false ); - + if ( q.isNull() ) continue; - + m_tracks << q; } @@ -355,7 +355,6 @@ SpotifyParser::checkBrowseFinished() if ( m_createNewPlaylist && !m_tracks.isEmpty() ) { - m_playlist = Playlist::create( SourceList::instance()->getLocal(), uuid(), m_title, From f4b1c5ba9feb0342c16b5b1dfd972fc1045a446b Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Mon, 23 Jul 2012 17:59:47 -0400 Subject: [PATCH 12/79] Only show original creator if it's not the same as the user herself --- src/libtomahawk/utils/SpotifyParser.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/libtomahawk/utils/SpotifyParser.cpp b/src/libtomahawk/utils/SpotifyParser.cpp index e937f8716..19e000171 100644 --- a/src/libtomahawk/utils/SpotifyParser.cpp +++ b/src/libtomahawk/utils/SpotifyParser.cpp @@ -355,11 +355,19 @@ SpotifyParser::checkBrowseFinished() if ( m_createNewPlaylist && !m_tracks.isEmpty() ) { + QString spotifyUsername; + + if ( Accounts::SpotifyAccount::instance() && Accounts::SpotifyAccount::instance()->loggedIn() ) + { + QVariantHash creds = Accounts::SpotifyAccount::instance()->credentials(); + spotifyUsername = creds.value( "username" ).toString(); + } + m_playlist = Playlist::create( SourceList::instance()->getLocal(), uuid(), m_title, m_info, - m_creator, + spotifyUsername == m_creator ? QString() : m_creator, false, m_tracks ); @@ -370,10 +378,9 @@ SpotifyParser::checkBrowseFinished() SpotifyPlaylistUpdater* updater = new SpotifyPlaylistUpdater( Accounts::SpotifyAccount::instance(), m_playlist->currentrevision(), m_browseUri, m_playlist ); - QVariantHash creds = Accounts::SpotifyAccount::instance()->credentials(); // If the user isnt dropping a playlist the he owns, its subscribeable - if ( !m_browseUri.contains( creds.value( "username" ).toString() ) ) + if ( !m_browseUri.contains( spotifyUsername ) ) updater->setCanSubscribe( true ); // Just register the infos From d97274be78955a7acd39a86df4a55a8dc3157c7f Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Tue, 24 Jul 2012 12:06:09 +0200 Subject: [PATCH 13/79] xmpp: check for error presences in AvatarManager --- src/accounts/xmpp/sip/AvatarManager.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/accounts/xmpp/sip/AvatarManager.cpp b/src/accounts/xmpp/sip/AvatarManager.cpp index 9ff1d26bf..68abbf819 100644 --- a/src/accounts/xmpp/sip/AvatarManager.cpp +++ b/src/accounts/xmpp/sip/AvatarManager.cpp @@ -73,6 +73,11 @@ AvatarManager::fetchVCard( const QString& jid ) void AvatarManager::onNewPresence( const Jreen::Presence& presence ) { + if ( presence.error() ) + { + return; + } + Jreen::VCardUpdate::Ptr update = presence.payload(); if ( update ) { From deca5bc70d0065302a077ce41e916de1923fce2e Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Tue, 24 Jul 2012 12:28:10 +0200 Subject: [PATCH 14/79] Rename FindLibEchonest to FindEchonest, make it version aware and overall more state of the art :P --- CMakeLists.txt | 4 +-- CMakeModules/FindEchonest.cmake | 36 ++++++++++++++++++++++ CMakeModules/FindLibEchonest.cmake | 42 -------------------------- src/CMakeLists.txt | 5 ++- src/infoplugins/generic/CMakeLists.txt | 2 +- src/libtomahawk/CMakeLists.txt | 5 ++- 6 files changed, 43 insertions(+), 51 deletions(-) create mode 100644 CMakeModules/FindEchonest.cmake delete mode 100644 CMakeModules/FindLibEchonest.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 3f3bdf8c1..c1331dd12 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -104,8 +104,8 @@ if(PHONON_FOUND) message(STATUS "Phonon found; ensure that phonon-vlc is at least 0.4") endif() -macro_optional_find_package(LibEchonest 2.0.0) -macro_log_feature(LIBECHONEST_FOUND "Echonest" "Qt library for communicating with The Echo Nest" "http://projects.kde.org/libechonest" TRUE "" "libechonest 2.0.0 is needed for dynamic playlists and the infosystem") +macro_optional_find_package(Echonest 2.0.0) +macro_log_feature(ECHONEST_FOUND "Echonest" "Qt library for communicating with The Echo Nest" "http://projects.kde.org/libechonest" TRUE "" "libechonest 2.0.0 is needed for dynamic playlists and the infosystem") macro_optional_find_package(CLucene 0.9.23) macro_log_feature(CLucene_FOUND "CLucene" "The open-source, C++ search engine" "http://clucene.sf.net" TRUE "" "CLucene is used for indexing the collection") diff --git a/CMakeModules/FindEchonest.cmake b/CMakeModules/FindEchonest.cmake new file mode 100644 index 000000000..768d0eb4c --- /dev/null +++ b/CMakeModules/FindEchonest.cmake @@ -0,0 +1,36 @@ +# - Find libechonest +# Find the libechonest includes and the libechonest libraries +# This module defines +# ECHONEST_INCLUDE_DIR, root echonest include dir. Include echonest includes with echonest/foo.h +# ECHONEST_LIBRARIES, the path to libechonest +# ECHONEST_FOUND, whether libechonest was found + +FIND_PACKAGE(PkgConfig QUIET) +PKG_CHECK_MODULES(PC_ECHONEST QUIET libechonest) + +FIND_PATH(ECHONEST_INCLUDE_DIR NAMES echonest/Track.h + HINTS + ${PC_ECHONEST_INCLUDEDIR} + ${PC_ECHONEST_INCLUDE_DIRS} + ${CMAKE_INSTALL_INCLUDEDIR} + ${KDE4_INCLUDE_DIR} +) + +FIND_LIBRARY(ECHONEST_LIBRARIES NAMES echonest + HINTS + ${PC_ECHONEST_LIBDIR} + ${PC_ECHONEST_LIBRARY_DIRS} + ${CMAKE_INSTALL_LIBDIR} + ${KDE4_LIB_DIR} +) + +IF(ECHONEST_LIBRARIES AND ECHONEST_INCLUDE_DIR AND NOT PC_ECHONEST_VERSION) + MESSAGE(WARNING "You don't have pkg-config and so the libechonest version check does not work!") +ENDIF() + +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Echonest + REQUIRED_VARS ECHONEST_LIBRARIES ECHONEST_INCLUDE_DIR + VERSION_VAR PC_ECHONEST_VERSION) + +MARK_AS_ADVANCED(ECHONEST_INCLUDE_DIR ECHONEST_LIBRARIES) diff --git a/CMakeModules/FindLibEchonest.cmake b/CMakeModules/FindLibEchonest.cmake deleted file mode 100644 index 9c78462f4..000000000 --- a/CMakeModules/FindLibEchonest.cmake +++ /dev/null @@ -1,42 +0,0 @@ -# - Find libechonest -# Find the libechonest includes and the libechonest libraries -# This module defines -# LIBECHONEST_INCLUDE_DIR, root echonest include dir. Include echonest includes with echonest/foo.h -# LIBECHONEST_LIBRARY, the path to libechonest -# LIBECHONEST_FOUND, whether libechonest was found - - -find_path(LIBECHONEST_INCLUDE_DIR NAMES echonest_export.h - HINTS - ~/usr/include - /opt/local/include - /usr/include - /usr/local/include - /opt/kde4/include - ${KDE4_INCLUDE_DIR} - PATH_SUFFIXES echonest -) - -find_library( LIBECHONEST_LIBRARY NAMES echonest - PATHS - ~/usr/lib - /opt/local/lib - /usr/lib - /usr/lib64 - /usr/local/lib - /opt/kde4/lib - ${KDE4_LIB_DIR} -) - - -if(LIBECHONEST_INCLUDE_DIR AND LIBECHONEST_LIBRARY) - set(LIBECHONEST_FOUND TRUE) - message(STATUS "Found libechonest: ${LIBECHONEST_INCLUDE_DIR}, ${LIBECHONEST_LIBRARY}") -else(LIBECHONEST_INCLUDE_DIR AND LIBECHONEST_LIBRARY) - set(LIBECHONEST_FOUND FALSE) - if (LIBECHONEST_FIND_REQUIRED) - message(FATAL_ERROR "Could NOT find required package libechonest") - endif(LIBECHONEST_FIND_REQUIRED) -endif(LIBECHONEST_INCLUDE_DIR AND LIBECHONEST_LIBRARY) - -mark_as_advanced(LIBECHONEST_INCLUDE_DIR LIBECHONEST_LIBRARY) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 863aa797f..c7894f210 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -113,8 +113,7 @@ INCLUDE_DIRECTORIES( ${PHONON_INCLUDES} ${QJSON_INCLUDE_DIR} ${LIBATTICA_INCLUDE_DIR} - ${LIBECHONEST_INCLUDE_DIR} - ${LIBECHONEST_INCLUDE_DIR}/.. + ${ECHONEST_INCLUDE_DIR} ${LIBLASTFM_INCLUDE_DIRS} ${LIBLASTFM_INCLUDE_DIRS}/.. ) @@ -200,7 +199,7 @@ TARGET_LINK_LIBRARIES( tomahawk ${OS_SPECIFIC_LINK_LIBRARIES} ${QT_LIBRARIES} ${MAC_EXTRA_LIBS} - ${LIBECHONEST_LIBRARY} + ${ECHONEST_LIBRARIES} ${QXTWEB_LIBRARIES} ${QJSON_LIBRARIES} ${TAGLIB_LIBRARIES} diff --git a/src/infoplugins/generic/CMakeLists.txt b/src/infoplugins/generic/CMakeLists.txt index c077e1e77..60e981687 100644 --- a/src/infoplugins/generic/CMakeLists.txt +++ b/src/infoplugins/generic/CMakeLists.txt @@ -1,4 +1,4 @@ -include_directories(${LIBECHONEST_INCLUDE_DIR}) +include_directories(${ECHONEST_INCLUDE_DIR}) list(APPEND simple_plugins Echonest diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index 0a325c166..8145a821b 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -332,8 +332,7 @@ include_directories( . ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/. ${CMAKE_CURRENT_SOURCE_DIR} ${QT_INCLUDE_DIR} ${QJSON_INCLUDE_DIR} - ${LIBECHONEST_INCLUDE_DIR} - ${LIBECHONEST_INCLUDE_DIR}/.. + ${ECHONEST_INCLUDE_DIR} ${LIBLASTFM_INCLUDE_DIRS} ${LIBLASTFM_INCLUDE_DIRS}/.. ${CLUCENE_INCLUDE_DIRS} @@ -445,7 +444,7 @@ TARGET_LINK_LIBRARIES( tomahawklib ${PHONON_LIBS} ${TAGLIB_LIBRARIES} ${CLUCENE_LIBRARIES} - ${LIBECHONEST_LIBRARY} + ${ECHONEST_LIBRARIES} ${QT_QTSQL_LIBRARY} ${QT_QTUITOOLS_LIBRARY} ${QT_QTGUI_LIBRARY} From 51adf23cb9709962af910af7d9d5151a3281a8b3 Mon Sep 17 00:00:00 2001 From: Alejandro Wainzinger Date: Tue, 24 Jul 2012 22:17:42 +0900 Subject: [PATCH 15/79] Add context for translator on transfer status strings. --- src/libtomahawk/jobview/TransferStatusItem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libtomahawk/jobview/TransferStatusItem.cpp b/src/libtomahawk/jobview/TransferStatusItem.cpp index ae5794013..ec696a974 100644 --- a/src/libtomahawk/jobview/TransferStatusItem.cpp +++ b/src/libtomahawk/jobview/TransferStatusItem.cpp @@ -55,7 +55,7 @@ TransferStatusItem::mainText() const return QString( "%1" ).arg( QString( "%1 - %2" ).arg( m_stream.data()->track()->artist()->name() ).arg( m_stream.data()->track()->track() ) ); else if ( !m_stream.data()->source().isNull() && !m_stream.data()->track().isNull() ) return QString( "%1 %2 %3" ).arg( QString( "%1 - %2" ).arg( m_stream.data()->track()->artist()->name() ).arg( m_stream.data()->track()->track() ) ) - .arg( m_stream.data()->type() == StreamConnection::RECEIVING ? tr( "from" ) : tr( "to" ) ) + .arg( m_stream.data()->type() == StreamConnection::RECEIVING ? tr( "from", "streaming artist - track from friend" ) : tr( "to", "streaming artist - track to friend" ) ) .arg( m_stream.data()->source()->friendlyName() ); else return QString(); From 4a0f91d052740f11bed8e41041d3004624280094 Mon Sep 17 00:00:00 2001 From: Tomahawk CI Date: Tue, 24 Jul 2012 22:17:05 +0000 Subject: [PATCH 16/79] Automatic merge of Transifex translations --- lang/tomahawk_ar.ts | 6 +- lang/tomahawk_bg.ts | 6 +- lang/tomahawk_ca.ts | 6 +- lang/tomahawk_de.ts | 6 +- lang/tomahawk_en.ts | 2 + lang/tomahawk_es.ts | 6 +- lang/tomahawk_fr.ts | 6 +- lang/tomahawk_ja.ts | 6 +- lang/tomahawk_pl.ts | 6 +- lang/tomahawk_pt_BR.ts | 6 +- lang/tomahawk_ru.ts | 177 +++++++++++++++++++++-------------------- lang/tomahawk_sv.ts | 6 +- lang/tomahawk_tr.ts | 2 + lang/tomahawk_zh_CN.ts | 2 + lang/tomahawk_zh_TW.ts | 2 + 15 files changed, 138 insertions(+), 107 deletions(-) diff --git a/lang/tomahawk_ar.ts b/lang/tomahawk_ar.ts index ec00d1022..2e375a71f 100644 --- a/lang/tomahawk_ar.ts +++ b/lang/tomahawk_ar.ts @@ -3538,12 +3538,14 @@ enter the displayed PIN number here: from - من + streaming artist - track from friend + to - إلى + streaming artist - track to friend + diff --git a/lang/tomahawk_bg.ts b/lang/tomahawk_bg.ts index 8d74916d2..fc5ad004a 100644 --- a/lang/tomahawk_bg.ts +++ b/lang/tomahawk_bg.ts @@ -3548,12 +3548,14 @@ enter the displayed PIN number here: from - от + streaming artist - track from friend + to - до + streaming artist - track to friend + diff --git a/lang/tomahawk_ca.ts b/lang/tomahawk_ca.ts index 5cbd98bf0..94180e068 100644 --- a/lang/tomahawk_ca.ts +++ b/lang/tomahawk_ca.ts @@ -3537,12 +3537,14 @@ introduïu el PIN aquí: from - de + streaming artist - track from friend + to - a + streaming artist - track to friend + diff --git a/lang/tomahawk_de.ts b/lang/tomahawk_de.ts index 4ecc74216..435ab6792 100644 --- a/lang/tomahawk_de.ts +++ b/lang/tomahawk_de.ts @@ -3533,12 +3533,14 @@ Tomahawk auf Twitter's Website authentifiziert hast: from - von + streaming artist - track from friend + to - an + streaming artist - track to friend + diff --git a/lang/tomahawk_en.ts b/lang/tomahawk_en.ts index 8b30b28ea..c2886d466 100644 --- a/lang/tomahawk_en.ts +++ b/lang/tomahawk_en.ts @@ -3538,11 +3538,13 @@ enter the displayed PIN number here: from + streaming artist - track from friend from to + streaming artist - track to friend to diff --git a/lang/tomahawk_es.ts b/lang/tomahawk_es.ts index 5795d583b..e40f6115d 100644 --- a/lang/tomahawk_es.ts +++ b/lang/tomahawk_es.ts @@ -3536,12 +3536,14 @@ introduzca su número PIN aquí: from - de + streaming artist - track from friend + to - para + streaming artist - track to friend + diff --git a/lang/tomahawk_fr.ts b/lang/tomahawk_fr.ts index 190c16323..7fe9345ac 100644 --- a/lang/tomahawk_fr.ts +++ b/lang/tomahawk_fr.ts @@ -3538,12 +3538,14 @@ saisissez le numéro PIN ici : from - de + streaming artist - track from friend + to - à + streaming artist - track to friend + diff --git a/lang/tomahawk_ja.ts b/lang/tomahawk_ja.ts index 55a4173d6..3148af2a2 100644 --- a/lang/tomahawk_ja.ts +++ b/lang/tomahawk_ja.ts @@ -3528,12 +3528,14 @@ Meta+Ctrl+Z from - から + streaming artist - track from friend + to - まで + streaming artist - track to friend + diff --git a/lang/tomahawk_pl.ts b/lang/tomahawk_pl.ts index f29ab9498..ff27e0820 100644 --- a/lang/tomahawk_pl.ts +++ b/lang/tomahawk_pl.ts @@ -3532,12 +3532,14 @@ wprowadź pokazany numer PIN tutaj: from - od + streaming artist - track from friend + to - do + streaming artist - track to friend + diff --git a/lang/tomahawk_pt_BR.ts b/lang/tomahawk_pt_BR.ts index 9328a2347..2442bf381 100644 --- a/lang/tomahawk_pt_BR.ts +++ b/lang/tomahawk_pt_BR.ts @@ -3538,12 +3538,14 @@ colocar o número PIN mostrado aqui: from - de + streaming artist - track from friend + to - para + streaming artist - track to friend + diff --git a/lang/tomahawk_ru.ts b/lang/tomahawk_ru.ts index f13c31fbd..94409ce08 100644 --- a/lang/tomahawk_ru.ts +++ b/lang/tomahawk_ru.ts @@ -5,17 +5,18 @@ Allow %1 to connect and stream from you? - + Разрешить %1 ⏎ +подключиться и слушать ваш поток? Allow Streaming - + Разрешить Поток Deny Access - + Запретить доступ @@ -305,17 +306,17 @@ connect and stream from you? Sorry, Tomahawk couldn't find the track '%1' by %2 - + К сожалению, Tomahawk не мог найти песню '%1' %2 Sorry, Tomahawk couldn't find the artist '%1' - + К сожалению, Tomahawk не мог найти исполнителя '%1' Sorry, Tomahawk couldn't find the album '%1' by %2 - + К сожалению, Tomahawk не мог найти альбом '%1' %2 @@ -486,7 +487,7 @@ connect and stream from you? Filter... - + Фильтр... @@ -626,32 +627,32 @@ connect and stream from you? Top Loved Tracks - + Топ Любимых Песен Sorry, we could not find any loved tracks! - + К сожалению, мы не смогли найти никаких любимых песен! The most loved tracks from all your friends - + Любимые песни ваших друзей All of your loved tracks - + Все ваши любимые песни All of %1's loved tracks - + Все из %1 любимые песни Loved Tracks - + Любимые Песни @@ -659,107 +660,107 @@ connect and stream from you? Form - + Форма Tags - + Теги Title: - + Название: Title... - + Название... Artist: - + Исполнитель: Artist... - + Исполнитель...Алб Album: - + Альбом: Album... - + Альбом... Disc Number: - + Номер диска: Duration: - + Продолжительность: 00.00 - + 00.00 Year: - + Год: Bitrate: - + Битрей: File - + Файл File Name: - + Имя файла: File Name... - + Имя файла... File Size... - + Размер Файла... File size... - + Размер файла... File Size: - + Размер Файла: Back - + Назад Forward - + Вперед @@ -882,7 +883,7 @@ connect and stream from you? Caption - + Заголовок @@ -1737,7 +1738,7 @@ connect and stream from you? Use UPnP to establish port forward (recommended) - + Использование UPnP для проброса портов (рекомендуется) @@ -1991,7 +1992,7 @@ connect and stream from you? Create local copy - + Создать локальную копию @@ -2029,7 +2030,7 @@ connect and stream from you? Logged in as %1 - + Вошли как %1 @@ -2048,7 +2049,7 @@ connect and stream from you? Play music from and sync your playlists with Spotify Premium - + Слушать музыку и синхронизировать плейлисты с Spotify Премиум @@ -2193,7 +2194,7 @@ You may wish to try re-authenticating. Log on to your Jabber/XMPP account to connect to your friends - + Войдите в ваш Jabber/XMPP аккаунт чтобы соединится с вашими друзьями. @@ -2221,12 +2222,12 @@ You may wish to try re-authenticating. Continue Playback after this &Track - + Продолжить воспроизведение после этого &Песни Stop Playback after this &Track - + Остановить воспроизведение после этого &Песни @@ -2242,12 +2243,12 @@ You may wish to try re-authenticating. Copy Album &Link - + Копировать &Ссылку Альбома Copy Artist &Link - + Копировать &Ссылку Исполнителя @@ -2395,7 +2396,7 @@ Try tweaking the filters for a new set of songs to play. is - + is @@ -2433,7 +2434,7 @@ Try tweaking the filters for a new set of songs to play. More - + Более @@ -2473,122 +2474,122 @@ Try tweaking the filters for a new set of songs to play. Minor - + Minor C - + C C Sharp - + C Sharp D - + D E Flat - + E Flat E - + E F - + F F Sharp - + F Sharp G - + G A Flat - + A Flat A - + A B Flat - + B Flat B - + B Ascending - + Ascending Descending - + Descending Tempo - + Tempo Duration - + Продолжительность Loudness - + Loudness Artist Familiarity - + Artist Familiarity Artist Hotttnesss - + Artist Hotttnesss Song Hotttnesss - + Song Hotttnesss Latitude - + Latitude Longitude - + Longitude Mode - + Mode @@ -2603,12 +2604,12 @@ Try tweaking the filters for a new set of songs to play. Danceability - + Danceability only by ~%1 - + только ~ %1 @@ -2618,7 +2619,7 @@ Try tweaking the filters for a new set of songs to play. with genre ~%1 - + с жанром ~%1 @@ -2644,7 +2645,7 @@ Try tweaking the filters for a new set of songs to play. about %1 BPM - + около %1 BPM @@ -2659,7 +2660,7 @@ Try tweaking the filters for a new set of songs to play. at around %1%2 %3 - + около %1%2 %3 @@ -2669,22 +2670,22 @@ Try tweaking the filters for a new set of songs to play. in a %1 key - + в %1 ключ sorted in %1 %2 order - + отсортированы в %1 %2 порядке with a %1 mood - + настроение %1 in a %1 style - + в стиле %1 @@ -2737,12 +2738,12 @@ Try tweaking the filters for a new set of songs to play. Loudness - + Loudness Danceability - + Danceability @@ -2752,17 +2753,17 @@ Try tweaking the filters for a new set of songs to play. Song Hotttnesss - + Song Hotttnesss Artist Hotttnesss - + Artist Hotttnesss Artist Familiarity - + Artist Familiarity @@ -3408,7 +3409,7 @@ enter the displayed PIN number here: %1 by %2 track, artist name - + %1 %2 @@ -3531,11 +3532,13 @@ enter the displayed PIN number here: from + streaming artist - track from friend из to + streaming artist - track to friend к @@ -3682,7 +3685,7 @@ You can re-send a sync message at any time simply by sending another tweet using Sorry, we could not find any recent plays! - + К сожалению, мы не смогли найти никаких воспроизвидений песен! @@ -3778,7 +3781,7 @@ Lyrics for "%1" by %2: Failed to parse contents of XSPF playlist - + Невозможно разобрать содержимое XSPF плейлиста diff --git a/lang/tomahawk_sv.ts b/lang/tomahawk_sv.ts index 4f4c35ac8..65d2736a4 100644 --- a/lang/tomahawk_sv.ts +++ b/lang/tomahawk_sv.ts @@ -3526,12 +3526,14 @@ enter the displayed PIN number here: from - från + streaming artist - track from friend + to - till + streaming artist - track to friend + diff --git a/lang/tomahawk_tr.ts b/lang/tomahawk_tr.ts index 350c31e87..a798887ea 100644 --- a/lang/tomahawk_tr.ts +++ b/lang/tomahawk_tr.ts @@ -3525,11 +3525,13 @@ enter the displayed PIN number here: from + streaming artist - track from friend to + streaming artist - track to friend diff --git a/lang/tomahawk_zh_CN.ts b/lang/tomahawk_zh_CN.ts index da9cd841b..9dfae0c46 100644 --- a/lang/tomahawk_zh_CN.ts +++ b/lang/tomahawk_zh_CN.ts @@ -3525,11 +3525,13 @@ enter the displayed PIN number here: from + streaming artist - track from friend to + streaming artist - track to friend diff --git a/lang/tomahawk_zh_TW.ts b/lang/tomahawk_zh_TW.ts index bd29dee6a..48d5f2005 100644 --- a/lang/tomahawk_zh_TW.ts +++ b/lang/tomahawk_zh_TW.ts @@ -3525,11 +3525,13 @@ enter the displayed PIN number here: from + streaming artist - track from friend to + streaming artist - track to friend From c8bda2ccbe090679bef1cf2f6989d9395ccd0f34 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Tue, 24 Jul 2012 21:12:34 -0400 Subject: [PATCH 17/79] differentiate between synced and subscribed updaters, and show icon --- data/images/playlist-subscribed.png | Bin 0 -> 1452 bytes resources.qrc | 1 + .../playlist/PlaylistUpdaterInterface.h | 9 +++++++- src/libtomahawk/playlist/XspfUpdater.h | 2 ++ src/sourcetree/SourceDelegate.cpp | 20 ++++++++++++++++-- src/sourcetree/items/PlaylistItems.cpp | 16 +++++++++++++- src/sourcetree/items/PlaylistItems.h | 9 ++++++-- 7 files changed, 51 insertions(+), 6 deletions(-) create mode 100755 data/images/playlist-subscribed.png diff --git a/data/images/playlist-subscribed.png b/data/images/playlist-subscribed.png new file mode 100755 index 0000000000000000000000000000000000000000..09234c0702000fbc6e40d28d8e9b526ccc9f1a27 GIT binary patch literal 1452 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`Gjk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+m{T%CB1$5BeXNr6bM+EIYV;~{3xK*A7;Nk-3KEmEQ%e+* zQqwc@Y?a>c-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxKsVXI%s|1+P|wiV z#N6CmN5ROz&_Lh7NZ-&%*U;R`*vQJjKmiJrfVLH-q*(>IxIyg#@@$ndN=gc>^!3Zj z%k|2Q_413-^$jg8EkR}&8R-I5=oVMzl_XZ^<`pZ$OmImpPA){ffi_eM3D1{oGuTzrd=COM+4n&cLd=IHa;5RX-@T zIKQ+g85kdF$}r8qu)}W=NFmTQR{lkqz(`5Vami0E%}vcK@pQ3O0?O#6WTsdd8@d`g z8yGvAnj4$A8Wy<*8<{#gnV37n%)qAC$kD>k)xgZr*bJo8)xgoo*~rn@ z$;HUR(#g`?!V#v|Gq1QLF)uk4W^X3YUZ`G6yn3yii&7Iy@{2<9^K)P+ARr^ZB)>Q# zzd*q`*i<1rGcP5-yciTY5Wl*l7G;*DrnnX5=PH0h*D4c>?M|*{E*1ucrY=zXE!_-E zTr5mX44q9(Tpf+gm7sc4$O$ohpkwqwNdqaVz=VM555$Bgd>{v&byD+y`K1V$G4fx( zdcwfKc+boN@o2 zkGHt{6Gb`ZPOi!B{l!QRJn(`SpAE**y1SoN(U2r$Kq^-jlQB zT#`C${s})gr=C@A-F#yCM-`==JAQ=Cj4+z1t5y+h?dn%_c6R3378&7P2MpKEcJMkF z5MAuncXxJ>3}b7o?2P-5AGvjixBrl=&`S0U5{zJwJR-Iue&Z!8X%@Cy#-2qR9%<~B z?OLuN@0INNL*v!vzHPfMPjA*cs&X@U+UBGOJid8JG)p$3i1V?0b3xwGx-*8wx>tJE=0C4(TYd0UWPAJKDQhO3 zDq0ht>Hpbd>5`Zn4(p;zUhPIZ4T~4ZNXM3MI&E9M@vio=gIx_5(k7O6sb%d~lV21P zZK(U*BW~7)EVY#hm*1QYx@=v4pLx!G`J%qrr*2IAbML2bT2gxB@};?(9@}Z3`Rm)J z&T6ys@KbZwM+}e7@SQ$ZFKQ~s>8E4p`DphQJCEAlRduWq3_iL?#29TVSwQ8dr>mdK II;Vst0H_NDjQ{`u literal 0 HcmV?d00001 diff --git a/resources.qrc b/resources.qrc index ca9e2d340..b853e65a3 100644 --- a/resources.qrc +++ b/resources.qrc @@ -148,5 +148,6 @@ data/images/jump-link.png data/images/scrollbar-vertical-handle.png data/images/scrollbar-horizontal-handle.png + data/images/playlist-subscribed.png diff --git a/src/libtomahawk/playlist/PlaylistUpdaterInterface.h b/src/libtomahawk/playlist/PlaylistUpdaterInterface.h index 0776451bd..79c582d89 100644 --- a/src/libtomahawk/playlist/PlaylistUpdaterInterface.h +++ b/src/libtomahawk/playlist/PlaylistUpdaterInterface.h @@ -35,6 +35,12 @@ namespace Tomahawk /** * PlaylistUpdaters are attached to playlists. They usually manipulate the playlist in some way * due to external input (spotify syncing) or timers (xspf updating) + * + * Updaters have 2 modes of operation: syncing and subscribing. Syncing implies two-way sync, that is, this + * playlist is reproduced on some other service (e.g. spotify or rdio). + * + * Subscribing implies the playlist is being updated periodically with changes from some source, and the user + * is working with a copy: e.g. an xspf updater or a spotify subscribed playlist. */ class PlaylistUpdaterFactory; @@ -71,7 +77,8 @@ public: static void registerUpdaterFactory( PlaylistUpdaterFactory* f ); - virtual bool sync() const { return true; } + virtual bool sync() const { return false; } + virtual bool subscribed() const { return false; } signals: void changed(); diff --git a/src/libtomahawk/playlist/XspfUpdater.h b/src/libtomahawk/playlist/XspfUpdater.h index cbe875119..c83efd18b 100644 --- a/src/libtomahawk/playlist/XspfUpdater.h +++ b/src/libtomahawk/playlist/XspfUpdater.h @@ -48,6 +48,8 @@ public: void setInterval( int intervalMsecs ) ; int intervalMsecs() const { return m_timer->interval(); } + bool subscribed() const { return true; } + public slots: void updateNow(); void setAutoUpdate( bool autoUpdate ); diff --git a/src/sourcetree/SourceDelegate.cpp b/src/sourcetree/SourceDelegate.cpp index 5a0571a0b..0548b2870 100644 --- a/src/sourcetree/SourceDelegate.cpp +++ b/src/sourcetree/SourceDelegate.cpp @@ -1,7 +1,7 @@ /* === This file is part of Tomahawk Player - === * * Copyright 2010-2011, Christian Muehlhaeuser - * Copyright 2011, Leo Franchi + * Copyright 2011-2012, Leo Franchi * Copyright 2011, Michael Zanetti * Copyright 2010-2012, Jeff Mitchell * @@ -143,7 +143,7 @@ SourceDelegate::paintDecorations( QPainter* painter, const QStyleOptionViewItem& iconW = ah->originalSize().height() - 4; } } - + QRect iconRect = QRect( 4, option.rect.y() + 2, iconW, iconW ); QPixmap speaker = option.state & QStyle::State_Selected ? m_nowPlayingSpeaker : m_nowPlayingSpeakerDark; speaker = speaker.scaledToHeight( iconW, Qt::SmoothTransformation ); @@ -549,6 +549,22 @@ SourceDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, co else QStyledItemDelegate::paint( painter, o, index ); } + else if ( type == SourcesModel::StaticPlaylist ) + { + QStyledItemDelegate::paint( painter, o, index ); + + PlaylistItem* plItem = qobject_cast< PlaylistItem* >( item ); + if ( plItem->subscribed() && !plItem->subscribedIcon().isNull() ) + { + const int padding = 2; + const int imgWidth = o.rect.height() - 2*padding; + + const QPixmap icon = plItem->subscribedIcon().scaled( imgWidth, imgWidth, Qt::KeepAspectRatio, Qt::SmoothTransformation ); + + const QRect subRect( o.rect.right() - padding - imgWidth, o.rect.top() + padding, imgWidth, imgWidth ); + painter->drawPixmap( subRect, icon ); + } + } else QStyledItemDelegate::paint( painter, o, index ); } diff --git a/src/sourcetree/items/PlaylistItems.cpp b/src/sourcetree/items/PlaylistItems.cpp index 8fb322915..5925bdcda 100644 --- a/src/sourcetree/items/PlaylistItems.cpp +++ b/src/sourcetree/items/PlaylistItems.cpp @@ -1,6 +1,6 @@ /* * - * Copyright 2010-2011, Leo Franchi + * Copyright 2010-2012, Leo Franchi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -280,6 +280,7 @@ PlaylistItem::onUpdated() if ( !newOverlay && !m_overlaidIcon.isNull() ) m_overlaidIcon = QIcon(); + emit updated(); } @@ -292,6 +293,19 @@ PlaylistItem::createOverlay() if ( m_playlist->updaters().isEmpty() ) return false; + m_showSubscribed = false; + foreach ( PlaylistUpdaterInterface* updater, m_playlist->updaters() ) + { + if ( updater->subscribed() ) + { + m_showSubscribed = true; + break; + } + } + + if ( m_showSubscribed && m_subscribedIcon.isNull() ) + m_subscribedIcon = QPixmap( RESPATH "images/playlist-subscribed.png" ); + QList< QPixmap > icons; foreach ( PlaylistUpdaterInterface* updater, m_playlist->updaters() ) { diff --git a/src/sourcetree/items/PlaylistItems.h b/src/sourcetree/items/PlaylistItems.h index 31198e778..f5d1b34c3 100644 --- a/src/sourcetree/items/PlaylistItems.h +++ b/src/sourcetree/items/PlaylistItems.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2011, Leo Franchi + * Copyright 2010-2012, Leo Franchi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -42,6 +42,10 @@ public: virtual SourceTreeItem* activateCurrent(); + bool subscribed() const { return m_showSubscribed; } + QPixmap subscribedIcon() const { return m_subscribedIcon; } + QList< QAction* > subscribedActions() const; + public slots: virtual void activate(); virtual void doubleClicked(); @@ -58,9 +62,10 @@ private slots: private: bool createOverlay(); - bool m_loaded; + bool m_loaded, m_showSubscribed; Tomahawk::playlist_ptr m_playlist; QIcon m_icon, m_overlaidIcon; + QPixmap m_subscribedIcon; QList m_overlaidUpdaters; }; Q_DECLARE_OPERATORS_FOR_FLAGS(PlaylistItem::DropTypes) From 1ba3f91cbafe1e48bb1199dc0a81912170c18b0f Mon Sep 17 00:00:00 2001 From: Jason Herskowitz Date: Tue, 24 Jul 2012 21:27:10 -0400 Subject: [PATCH 18/79] Add toggleable subscribe icons for subscribable playlists --- data/images/artistpage-background-tile.png | Bin 0 -> 46113 bytes data/images/subscribe-off.png | Bin 0 -> 3433 bytes data/images/subscribe-on.png | Bin 0 -> 3401 bytes resource.qrc | 0 thirdparty/jreen | 1 + 5 files changed, 1 insertion(+) create mode 100644 data/images/artistpage-background-tile.png create mode 100644 data/images/subscribe-off.png create mode 100644 data/images/subscribe-on.png create mode 100644 resource.qrc create mode 160000 thirdparty/jreen diff --git a/data/images/artistpage-background-tile.png b/data/images/artistpage-background-tile.png new file mode 100644 index 0000000000000000000000000000000000000000..e3e6358236d9a7f3719e4b0a4059ca87fe05ff8a GIT binary patch literal 46113 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 JPDHLkV1h3_cMbpm literal 0 HcmV?d00001 diff --git a/data/images/subscribe-off.png b/data/images/subscribe-off.png new file mode 100644 index 0000000000000000000000000000000000000000..99565fd800afd4fd5788c734d7d6a92bbe3a09d2 GIT binary patch literal 3433 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 LNkvXXu0mjf^pk~8 literal 0 HcmV?d00001 diff --git a/data/images/subscribe-on.png b/data/images/subscribe-on.png new file mode 100644 index 0000000000000000000000000000000000000000..81da59c8da8b26922c2a7efe4658823b7c65e7dd GIT binary patch literal 3401 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 literal 0 HcmV?d00001 diff --git a/resource.qrc b/resource.qrc new file mode 100644 index 000000000..e69de29bb diff --git a/thirdparty/jreen b/thirdparty/jreen new file mode 160000 index 000000000..2957d0ff0 --- /dev/null +++ b/thirdparty/jreen @@ -0,0 +1 @@ +Subproject commit 2957d0ff03d9561af8afc4bd3a45947392868875 From b642ca136b1ad8262be43e0df076b554d490f429 Mon Sep 17 00:00:00 2001 From: Jason Herskowitz Date: Tue, 24 Jul 2012 22:13:07 -0400 Subject: [PATCH 19/79] More subtle subscripton-on.png icon --- data/images/subscribe-on.png | Bin 3401 -> 3622 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/data/images/subscribe-on.png b/data/images/subscribe-on.png index 81da59c8da8b26922c2a7efe4658823b7c65e7dd..d02b6355f0978908232bf60133f0d3c70b25e1fe 100644 GIT binary patch delta 956 zcmV;t14I1D8m1huc?y630RI60puMM)00009a7bBm000XU000XU0RWnu7ytkO2XskI zMF-pm83GI_tet^r000AINkla zd!l;1eh}DE2%z8&i(1X)@Dk^ux49g>h$Y7INgmIC#S+tDJ5@J(8|kiQYDV>X{Rl8z zBxveEp6E>Yz1Ame_Rm_-TFympF&nmcvnSY?U)0?&#Le&+5$#eT6$}T0?OLzJgx%08 zaz%{h*LZ)k^@ZPQAM%axBqyr}0odLC(u4lj9aZsipVp#!z5X%KUmQc^Hn+n%O+@3G zik_k7E7bC!`56UrMBY11GeOeX9{FjhpHY8bV_)+l-fw(JAB&u-d;q}C_DODQ z9W&ZS9C71?=-8|7a5p4S2{mJ?J^+!lPgq$*0|+YCyKJ zeY~8M3$~w@WE*lt)bcAdG@x5rZ!op|Dt#<+J#5v07yPiNnAb)YG(sR3a3PN49hKs` zOr`MK^{`b&RNY`fBivGrh?XL^OB3z|2w9eqB*`U7`wK@QaFr$% zT3xjyRcX>k0|_EJ>f=7a?e6!|{y2`WWLef#v|N&DnvMg<%7HIe)`|_Y)b3*B_Qr91 zqFm0Qv`oSDIPj3|ZzbJh`4sdB$35VLq`@>2jQ?4b%YFfAny#1hDzLMhCP{zWJ_npm el4N#e4ZwfKHL>FF4HzE)0000~%d1XN7{-6k(lJo(QpZG6h!Aou%7A1biXr6> zSbK(nV&HNx-1{$ZNpYf#l!-`=OSyG&$=s0)7#z9o$6&9$zx988XHE9nYrX4vpY^Qg zT}x!m6)1N7O~4*tvtc2C%ooF$;GPPe0n{agqKBat$Uultm#jiu1=h)JM4q*YMZ6Fk zR^)A6g4B@F0K*f&h3?;2O@wTaaQZ4?BRHYRrFKoI%Z}yg94u>pp#vu4?9{pFic<+g zE!Ym52kj!mXTg6su--5)+eXW7IWO`31ak1LmaR!vNf*JN2$jX3qT%EOp6TMc$>fThcaP zX;PVe7_^3Z_2~@rs3IThDh0NeWL>;k`JojR(m;zw1~uXR507- zHsVJ|%2TecAHXeORtq*5Fy#rTOBPA&1U4FmQ}BeFYPlZ@J^{D{Wlz9=wxS&*jEwQy P00000NkvXXu0mjfW#~ Date: Tue, 24 Jul 2012 22:14:08 -0400 Subject: [PATCH 20/79] Toggle subscription on/off via icon --- data/images/artistpage-background-tile.png | Bin 46113 -> 0 bytes resource.qrc | 0 resources.qrc | 3 +- .../accounts/spotify/SpotifyPlaylistUpdater.h | 4 +- .../playlist/PlaylistUpdaterInterface.h | 4 ++ src/libtomahawk/playlist/XspfUpdater.cpp | 9 ++++ src/libtomahawk/playlist/XspfUpdater.h | 4 +- src/sourcetree/SourceDelegate.cpp | 23 +++++++++- src/sourcetree/items/PlaylistItems.cpp | 42 +++++++++++++++--- src/sourcetree/items/PlaylistItems.h | 10 +++-- 10 files changed, 82 insertions(+), 17 deletions(-) delete mode 100644 data/images/artistpage-background-tile.png delete mode 100644 resource.qrc diff --git a/data/images/artistpage-background-tile.png b/data/images/artistpage-background-tile.png deleted file mode 100644 index e3e6358236d9a7f3719e4b0a4059ca87fe05ff8a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 46113 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 JPDHLkV1h3_cMbpm diff --git a/resource.qrc b/resource.qrc deleted file mode 100644 index e69de29bb..000000000 diff --git a/resources.qrc b/resources.qrc index b853e65a3..31c2acd60 100644 --- a/resources.qrc +++ b/resources.qrc @@ -148,6 +148,7 @@ data/images/jump-link.png data/images/scrollbar-vertical-handle.png data/images/scrollbar-horizontal-handle.png - data/images/playlist-subscribed.png + data/images/subscribe-on.png + data/images/subscribe-off.png diff --git a/src/libtomahawk/accounts/spotify/SpotifyPlaylistUpdater.h b/src/libtomahawk/accounts/spotify/SpotifyPlaylistUpdater.h index b5de8e4b9..3345a8c4b 100644 --- a/src/libtomahawk/accounts/spotify/SpotifyPlaylistUpdater.h +++ b/src/libtomahawk/accounts/spotify/SpotifyPlaylistUpdater.h @@ -2,7 +2,7 @@ * * Copyright 2010-2012, Leo Franchi * Copyright 2012, Hugo Lindström - * + * * 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 @@ -74,7 +74,7 @@ public slots: void tomahawkPlaylistRenamed( const QString&, const QString& ); void aboutToDelete(); - + private slots: // SpotifyResolver message handlers, all take msgtype, msg as argument void onTracksInsertedReturn( const QString& msgType, const QVariantMap& msg, const QVariant& extraData ); diff --git a/src/libtomahawk/playlist/PlaylistUpdaterInterface.h b/src/libtomahawk/playlist/PlaylistUpdaterInterface.h index 79c582d89..a58feb0f1 100644 --- a/src/libtomahawk/playlist/PlaylistUpdaterInterface.h +++ b/src/libtomahawk/playlist/PlaylistUpdaterInterface.h @@ -78,7 +78,11 @@ public: static void registerUpdaterFactory( PlaylistUpdaterFactory* f ); virtual bool sync() const { return false; } + virtual void setSync( bool ) {} + + virtual bool canSubscribe() const { return false; } virtual bool subscribed() const { return false; } + virtual void setSubscribed( bool ) {} signals: void changed(); diff --git a/src/libtomahawk/playlist/XspfUpdater.cpp b/src/libtomahawk/playlist/XspfUpdater.cpp index 879184ba2..585707c9c 100644 --- a/src/libtomahawk/playlist/XspfUpdater.cpp +++ b/src/libtomahawk/playlist/XspfUpdater.cpp @@ -144,6 +144,8 @@ XspfUpdater::setAutoUpdate( bool autoUpdate ) // Update immediately as well if ( m_autoUpdate ) QTimer::singleShot( 0, this, SLOT( updateNow() ) ); + + emit changed(); } void @@ -158,3 +160,10 @@ XspfUpdater::setInterval( int intervalMsecs ) m_timer->setInterval( intervalMsecs ); } + + +void +XspfUpdater::setSubscribed( bool subscribed ) +{ + setAutoUpdate( subscribed ); +} diff --git a/src/libtomahawk/playlist/XspfUpdater.h b/src/libtomahawk/playlist/XspfUpdater.h index c83efd18b..6cff1d875 100644 --- a/src/libtomahawk/playlist/XspfUpdater.h +++ b/src/libtomahawk/playlist/XspfUpdater.h @@ -48,7 +48,9 @@ public: void setInterval( int intervalMsecs ) ; int intervalMsecs() const { return m_timer->interval(); } - bool subscribed() const { return true; } + bool canSubscribe() const { return true; } + bool subscribed() const { return m_autoUpdate; } + void setSubscribed( bool subscribed ); public slots: void updateNow(); diff --git a/src/sourcetree/SourceDelegate.cpp b/src/sourcetree/SourceDelegate.cpp index 0548b2870..233fb15c2 100644 --- a/src/sourcetree/SourceDelegate.cpp +++ b/src/sourcetree/SourceDelegate.cpp @@ -554,7 +554,7 @@ SourceDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, co QStyledItemDelegate::paint( painter, o, index ); PlaylistItem* plItem = qobject_cast< PlaylistItem* >( item ); - if ( plItem->subscribed() && !plItem->subscribedIcon().isNull() ) + if ( plItem->canSubscribe() && !plItem->subscribedIcon().isNull() ) { const int padding = 2; const int imgWidth = o.rect.height() - 2*padding; @@ -655,10 +655,29 @@ SourceDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, const QSt } } } + else if ( event->type() == QEvent::MouseButtonRelease && type == SourcesModel::StaticPlaylist ) + { + PlaylistItem* plItem = qobject_cast< PlaylistItem* >( index.data( SourcesModel::SourceTreeItemRole ).value< SourceTreeItem* >() ); + Q_ASSERT( plItem ); + + QMouseEvent* mev = static_cast< QMouseEvent* >( event ); + if ( plItem->canSubscribe() && !plItem->subscribedIcon().isNull() ) + { + const int padding = 2; + const int imgWidth = option.rect.height() - 2*padding; + const QRect subRect( option.rect.right() - padding - imgWidth, option.rect.top() + padding, imgWidth, imgWidth ); + + if ( subRect.contains( mev->pos() ) ) + { + // Toggle playlist subscription + plItem->setSubscribed( !plItem->subscribed() ); + } + } + } } // We emit our own clicked() signal instead of relying on QTreeView's, because that is fired whether or not a delegate accepts - // a mouse press event. Since we want to swallow click events when they are on headphones other action items, here wemake sure we only + // a mouse press event. Since we want to swallow click events when they are on headphones other action items, here we make sure we only // emit if we really want to if ( event->type() == QEvent::MouseButtonRelease ) { diff --git a/src/sourcetree/items/PlaylistItems.cpp b/src/sourcetree/items/PlaylistItems.cpp index 5925bdcda..c36313796 100644 --- a/src/sourcetree/items/PlaylistItems.cpp +++ b/src/sourcetree/items/PlaylistItems.cpp @@ -40,6 +40,8 @@ using namespace Tomahawk; PlaylistItem::PlaylistItem( SourcesModel* mdl, SourceTreeItem* parent, const playlist_ptr& pl, int index ) : SourceTreeItem( mdl, parent, SourcesModel::StaticPlaylist, index ) , m_loaded( false ) + , m_canSubscribe( false ) + , m_showSubscribed( false ) , m_playlist( pl ) { connect( pl.data(), SIGNAL( revisionLoaded( Tomahawk::PlaylistRevision ) ), @@ -293,18 +295,22 @@ PlaylistItem::createOverlay() if ( m_playlist->updaters().isEmpty() ) return false; - m_showSubscribed = false; + m_showSubscribed = false; + m_canSubscribe = false; foreach ( PlaylistUpdaterInterface* updater, m_playlist->updaters() ) { - if ( updater->subscribed() ) + if ( updater->canSubscribe() ) { - m_showSubscribed = true; + m_canSubscribe = true; + m_showSubscribed = updater->subscribed(); break; } } - if ( m_showSubscribed && m_subscribedIcon.isNull() ) - m_subscribedIcon = QPixmap( RESPATH "images/playlist-subscribed.png" ); + if ( m_canSubscribe && m_showSubscribed && m_subscribedOnIcon.isNull() ) + m_subscribedOnIcon = QPixmap( RESPATH "images/subscribe-on.png" ); + else if ( m_canSubscribe && !m_showSubscribed && m_subscribedOffIcon.isNull() ) + m_subscribedOffIcon = QPixmap( RESPATH "images/subscribe-off.png" ); QList< QPixmap > icons; foreach ( PlaylistUpdaterInterface* updater, m_playlist->updaters() ) @@ -313,6 +319,9 @@ PlaylistItem::createOverlay() icons << updater->typeIcon(); } + m_overlaidIcon = QIcon(); + m_overlaidUpdaters = m_playlist->updaters(); + if ( icons.isEmpty() ) return false; @@ -321,8 +330,6 @@ PlaylistItem::createOverlay() if ( icons.size() > 2 ) icons = icons.mid( 0, 2 ); - m_overlaidIcon = QIcon(); - m_overlaidUpdaters = m_playlist->updaters(); QPixmap base = m_icon.pixmap( 48, 48 ); QPainter p( &base ); @@ -384,6 +391,27 @@ PlaylistItem::activateCurrent() } +void +PlaylistItem::setSubscribed( bool subscribed ) +{ + Q_ASSERT( !m_overlaidUpdaters.isEmpty() ); + if ( m_overlaidUpdaters.isEmpty() ) + { + qWarning() << "NO playlist updater but got a toggle subscribed action on the playlist item!?"; + return; + } + else if ( m_overlaidUpdaters.size() > 1 ) + { + qWarning() << "Got TWO subscribed updaters at the same time? Toggling both... wtf"; + } + + foreach( PlaylistUpdaterInterface* updater, m_overlaidUpdaters ) + { + updater->setSubscribed( subscribed ); + } +} + + DynamicPlaylistItem::DynamicPlaylistItem( SourcesModel* mdl, SourceTreeItem* parent, const dynplaylist_ptr& pl, int index ) : PlaylistItem( mdl, parent, pl.staticCast< Playlist >(), index ) , m_dynplaylist( pl ) diff --git a/src/sourcetree/items/PlaylistItems.h b/src/sourcetree/items/PlaylistItems.h index f5d1b34c3..e1bc3ea6e 100644 --- a/src/sourcetree/items/PlaylistItems.h +++ b/src/sourcetree/items/PlaylistItems.h @@ -42,9 +42,11 @@ public: virtual SourceTreeItem* activateCurrent(); + // subscription management + bool canSubscribe() const { return m_canSubscribe; } bool subscribed() const { return m_showSubscribed; } - QPixmap subscribedIcon() const { return m_subscribedIcon; } - QList< QAction* > subscribedActions() const; + QPixmap subscribedIcon() const { return m_showSubscribed ? m_subscribedOnIcon : m_subscribedOffIcon; } + void setSubscribed( bool subscribed ); public slots: virtual void activate(); @@ -62,10 +64,10 @@ private slots: private: bool createOverlay(); - bool m_loaded, m_showSubscribed; + bool m_loaded, m_canSubscribe, m_showSubscribed; Tomahawk::playlist_ptr m_playlist; QIcon m_icon, m_overlaidIcon; - QPixmap m_subscribedIcon; + QPixmap m_subscribedOnIcon, m_subscribedOffIcon; QList m_overlaidUpdaters; }; Q_DECLARE_OPERATORS_FOR_FLAGS(PlaylistItem::DropTypes) From 3d1b7ac4cf90da27e55bf1933c7b994b48b0ba11 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Tue, 24 Jul 2012 22:37:08 -0400 Subject: [PATCH 21/79] Differentiate between setting subscribed and changing status --- .../accounts/spotify/SpotifyAccount.cpp | 8 ++++---- .../accounts/spotify/SpotifyPlaylistUpdater.cpp | 15 +++++++++++++-- .../accounts/spotify/SpotifyPlaylistUpdater.h | 3 +++ 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/libtomahawk/accounts/spotify/SpotifyAccount.cpp b/src/libtomahawk/accounts/spotify/SpotifyAccount.cpp index f330678ea..a5d643dbf 100644 --- a/src/libtomahawk/accounts/spotify/SpotifyAccount.cpp +++ b/src/libtomahawk/accounts/spotify/SpotifyAccount.cpp @@ -679,7 +679,7 @@ SpotifyAccount::setSubscribedForPlaylist( const playlist_ptr& playlist, bool sub sendMessage( msg, this ); updater->setSync( subscribed ); - updater->setSubscribed( subscribed ); + updater->setSubscribedStatus( subscribed ); } @@ -733,7 +733,7 @@ SpotifyAccount::resolverMessage( const QString &msgType, const QVariantMap &msg QObject* receiver = m_qidToSlotMap[ qid ].first; QString slot = m_qidToSlotMap[ qid ].second; m_qidToSlotMap.remove( qid ); - + QVariant extraData; if ( m_qidToExtraData.contains( qid ) ) extraData = m_qidToExtraData.take( qid ); @@ -1214,7 +1214,7 @@ SpotifyAccount::sendMessage( const QVariantMap &m, QObject* obj, const QString& } m_qidToExtraData[ qid ] = extraData; - + m_spotifyResolver.data()->sendMessage( msg ); return qid; @@ -1312,7 +1312,7 @@ SpotifyAccount::setSyncForPlaylist( const QString& spotifyPlaylistId, bool sync if ( info ) info->sync = sync; - + if ( !m_configWidget.isNull() ) m_configWidget.data()->setPlaylists( m_allSpotifyPlaylists.values() ); diff --git a/src/libtomahawk/accounts/spotify/SpotifyPlaylistUpdater.cpp b/src/libtomahawk/accounts/spotify/SpotifyPlaylistUpdater.cpp index e2c4ab252..d0474cabe 100644 --- a/src/libtomahawk/accounts/spotify/SpotifyPlaylistUpdater.cpp +++ b/src/libtomahawk/accounts/spotify/SpotifyPlaylistUpdater.cpp @@ -65,7 +65,7 @@ SpotifyUpdaterFactory::create( const Tomahawk::playlist_ptr& pl, const QVariantH SpotifyPlaylistUpdater* updater = new SpotifyPlaylistUpdater( m_account.data(), latestRev, spotifyId, pl ); updater->setSync( sync ); updater->setCanSubscribe( canSubscribe ); - updater->setSubscribed( isSubscribed ); + updater->setSubscribedStatus( isSubscribed ); m_account.data()->registerUpdaterForPlaylist( spotifyId, updater ); return updater; @@ -242,8 +242,9 @@ SpotifyPlaylistUpdater::sync() const return m_sync; } + void -SpotifyPlaylistUpdater::setSubscribed( bool subscribed ) +SpotifyPlaylistUpdater::setSubscribedStatus( bool subscribed ) { if ( m_subscribed == subscribed ) return; @@ -255,6 +256,16 @@ SpotifyPlaylistUpdater::setSubscribed( bool subscribed ) } +void +SpotifyPlaylistUpdater::setSubscribed( bool subscribed ) +{ + if ( !m_spotify.isNull() ) + m_spotify.data()->setSubscribedForPlaylist( playlist(), subscribed ); + + // Spotify account will in turn call setSUbscribedStatus +} + + bool SpotifyPlaylistUpdater::subscribed() const { diff --git a/src/libtomahawk/accounts/spotify/SpotifyPlaylistUpdater.h b/src/libtomahawk/accounts/spotify/SpotifyPlaylistUpdater.h index 3345a8c4b..10ceef393 100644 --- a/src/libtomahawk/accounts/spotify/SpotifyPlaylistUpdater.h +++ b/src/libtomahawk/accounts/spotify/SpotifyPlaylistUpdater.h @@ -55,7 +55,10 @@ public: bool sync() const; void setSync( bool sync ); bool subscribed() const; + // actually change the subscribed value in spotify void setSubscribed( bool subscribed ); + // Just set the subscribed flag + void setSubscribedStatus( bool subscribed ); bool canSubscribe() const; void setCanSubscribe( bool canSub ); QString spotifyId() const { return m_spotifyId; } From ebe7063ec828e940a7fc47808e4c91fc32dfe246 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Wed, 25 Jul 2012 14:41:45 +0200 Subject: [PATCH 22/79] * Updated ChangeLog. --- ChangeLog | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/ChangeLog b/ChangeLog index d3df8fd69..7b2f72577 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,18 @@ 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.5: + * Fixed bug where the wrong avatar could be shown for a user. + * Fixed shortcuts not working in the global search field on OS X. + * Fixed The Echo Nest stations. + * Code-signed executable on OS X for GateKeeper. + * Fixed logging in to Spotify when pressing return in the config dialog. + * Fixed queue not auto-collapsing when playing the last track. + * Fixed bug where album listings would fail to show up. + * Improved stability. + * Fixed bug where it was not possible to drop a mixture of resolved + and unresolved tracks onto a playlist. + Version 0.5.4: * Improved stability. * Added support for Spotify album lookups. From 92ae8ea352bfeaf9b579e3d3b321bc2cd73d47ed Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Wed, 25 Jul 2012 09:41:21 -0400 Subject: [PATCH 23/79] Port new changelog entry to master --- ChangeLog | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ChangeLog b/ChangeLog index 7b2f72577..85e9fd93a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,8 @@ Version 0.6.0: removing the tendency to jump away from the mouse. Version 0.5.5: + * Changed the Spotify config dialog to indicate when the user + is logged in. * Fixed bug where the wrong avatar could be shown for a user. * Fixed shortcuts not working in the global search field on OS X. * Fixed The Echo Nest stations. From 8efa33e2493bee7c802845a3a19e78fcacbe53ae Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Wed, 25 Jul 2012 22:38:36 +0200 Subject: [PATCH 24/79] * Reverted broken commit. --- data/images/artistpage-background-tile.png | Bin 46113 -> 0 bytes data/images/subscribe-off.png | Bin 3433 -> 0 bytes data/images/subscribe-on.png | Bin 3622 -> 0 bytes resource.qrc | 0 thirdparty/jreen | 1 - 5 files changed, 1 deletion(-) delete mode 100644 data/images/artistpage-background-tile.png delete mode 100644 data/images/subscribe-off.png delete mode 100644 data/images/subscribe-on.png delete mode 100644 resource.qrc delete mode 160000 thirdparty/jreen diff --git a/data/images/artistpage-background-tile.png b/data/images/artistpage-background-tile.png deleted file mode 100644 index e3e6358236d9a7f3719e4b0a4059ca87fe05ff8a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 46113 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 JPDHLkV1h3_cMbpm diff --git a/data/images/subscribe-off.png b/data/images/subscribe-off.png deleted file mode 100644 index 99565fd800afd4fd5788c734d7d6a92bbe3a09d2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3433 zcmV-v4VLnWP)EX>4Tx0C?J+Q+HUC_ZB|i_hk=OLfG)Jmu!ImA|tE_$Pihg5Rw34gb)%y#f69p zRumNxoJdu~g4GI0orvO~D7a@qiilc^Ra`jkAKa(4eR}Wh?fcjJyyu+f{LXpL4}cL8 zCXwc%Y5+M>g*-agACFH+#L2yY0u@N$1RxOR%fe>`#Q*^C19^CUbg)1C0k3ZW0swH; zE+i7i;s1lWP$pLZAdvvzA`<5d0gzGv$SzdK6adH=0I*ZDWC{S3003-xd_p1ssto|_ z^hrJi0NAOM+!p}Yq8zCR0F40vnJ7mj0zkU}U{!%qECRs70HCZuA}$2Lt^t5qwlYTo zfV~9(c8*w(4?ti5fSE!p%m5%b0suoE6U_r4Oaq`W(!b!TUvP!ENC5!A%azTSOVTqG zxRuZvck=My;vwR~Y_URN7by^C3FIQ2mzyIKNaq7g&I|wm8u`(|{y0C7=jP<$=4R(? z@ASo@{%i1WB0eGU-~POe0t5gMPS5Y!U*+Z218~Oyuywy{sapWrRsd+<`CT*H37}dE z(0cicc{uz)9-g64$UGe!3JVMEC1RnyFyo6p|1;rl;ER6t{6HT5+j{T-ahgDxt-zy$ z{c&M#cCJ#6=gR~_F>d$gBmT#QfBlXr(c(0*Tr3re@mPttP$EsodAU-NL?OwQ;u7h9 zGVvdl{RxwI4FIf$Pry#L2er#=z<%xl0*ek<(slqqe)BDi8VivC5N9+pdG`PSlfU_o zKq~;2Moa!tiTSO!5zH77Xo1hL_iEAz&sE_ z2IPPo3ZWR5K^auQI@koYumc*P5t`u;w81er4d>tzT!HIw7Y1M$p28Tsh6w~g$Osc* zAv%Z=Vvg7%&IlKojszlMNHmgwq#)^t6j36@$a16tsX}UzT}UJHEpik&ja)$bklV;0 zGK&0)yhkyVfwEBp)B<%txu_o+ipHRG(R4HqU4WLNYtb6C9zB4zqNmYI=yh}eeTt4_ zfYC7yW{lZkT#ScBV2M~7CdU?I?5=ix(HVZgM=}{CnA%mPqZa^68Xe5gFH?u96Et<2 zCC!@_L(8Nsqt(!wX=iEoXfNq>x(VHb9z~bXm(pwK2kGbOgYq4YG!XMxcgB zqf}$J#u<$v7REAV@mNCEa#jQDENhreVq3EL>`ZnA`x|yIdrVV9bE;;nW|3x{=5fsd z4#u(I@HyF>O3oq94bFQl11&!-vDRv>X03j$H`;pIzS?5#a_tuF>)P*iaGgM%ES>c_ zZ94aL3A#4AQM!e?+jYlFJ5+DSzi0S9#6BJCZ5(XZOGfi zTj0IRdtf>~J!SgN=>tB-J_4V5pNGDtz9Qc}z9W9tewls;{GR(e`pf-~_`l(K@)q$< z1z-We0p$U`ff|9c18V~x1epY-2Q>wa1-k|>3_cY?3<(WcA99m#z!&lx`C~KOXDpi0 z70L*m6G6C?@k ziR8rC#65}Qa{}jVnlqf_npBo_W3J`gqPZ95>CVfZcRX1&S&)1jiOPpx423?lIEROmG(H@JAFg?XogQlb;dIZPf{y+kr|S? zBlAsGMAqJ{&)IR=Ejg5&l$@hd4QZCNE7vf$D7Q~$D=U)?Nn}(WA6du22pZOfRS_cv~1-c(_QtNLti0-)8>m`6CO07JR*suu!$(^sg%jf zZm#rNxnmV!m1I@#YM0epR(~oNm0zrItf;Q|utvD%;#W>z)qM4NZQ9!2O1H}G>qzUQ z>u#*~S--DJy=p<#(1!30tsC);y-IHSJr>wyfLop*ExT zdYyk=%U1oZtGB+{Cfe4&-FJKQ4uc&PJKpb5^_C@dOYIJXG+^@gCvI%WcHjN%gI&kHifN$EH?V5MBa9S!3!a?Q1 zC*P)gd*e{(q0YnH!_D8Bf4B7r>qvPk(mKC&tSzH$pgp0z@92!9ogH2sN4~fJe(y2k zV|B+hk5`_cohUu=`Q(C=R&z?UQbnZ;IU-!xL z-sg{9@Vs#JBKKn3CAUkhJ+3`ResKNaNUvLO>t*-L?N>ambo5Q@JJIjcfBI^`)pOVQ z*DhV3dA;w(>>IakCfyvkCA#(acJ}QTcM9%I++BK)c(44v+WqPW`VZ=VwEnSWz-{38 zV8CF{!&wjS4he^z{*?dIhvCvk%tzHDMk9@nogW_?4H~`jWX_Y}r?RIL&&qyQ|9R_k ztLNYS;`>X_Sp3-V3;B!Bzpi#4Uv(1#^~LPRtPr6i?Np`d{mX&?nURB*J-Fx_dL&g*4k_DwaZW#;RRL!In-+n+Tx06zk2l6C_R3~72S zgKc$;q~{{y($u1y?NQs|i=~tU5%D1KC~#8J&8E&{%5DmP4**naJp_C_i+o+ud$zBZ zQod?g+ylH1ymT9r01m0vdImV=u79QgxCxw$h_@T@Y2X!Lqbc6RNIEkC`)1C`_D2yR z+xvkP;H_HgH<@{NM7#=oXnT^>oo`y$H`(4cs&5W&$;?G5WhEjG051Yh0;?^>W5CZX z_?XSMNz%rw9tM^q{ZVVZQES~55f_0aU`J-YQ%d<;(wi;#h~H3Vu1VTC;}oziX{+sp zq}>tmb!J`wUY4`~?f`xR{sa~cyEaL>G_zllE|*faN5owXu-txlt<~yaMEq|1DzF%^ zpHIL!hN=$EcJ^O^$7-!xBI4WjdT;x_G8l>N<$hDH*?yus*81v8+xJU)yk+o(q+e_= zNm>V1ZSMgdXZ zu^hv8^Ngh95%GPk_1|XhLozdu0Oy7w(FejfVKiJ(Bpr^3^L;o^JxWu$4BTh?f}~r6 z>&%S11)P_3Zztn_2IYVL0y1;Eq!)mv`)!i6ZhIB@w3PD090TwV_LXz-r@D7P00000 LNkvXXu0mjf^pk~8 diff --git a/data/images/subscribe-on.png b/data/images/subscribe-on.png deleted file mode 100644 index d02b6355f0978908232bf60133f0d3c70b25e1fe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3622 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 diff --git a/resource.qrc b/resource.qrc deleted file mode 100644 index e69de29bb..000000000 diff --git a/thirdparty/jreen b/thirdparty/jreen deleted file mode 160000 index 2957d0ff0..000000000 --- a/thirdparty/jreen +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 2957d0ff03d9561af8afc4bd3a45947392868875 From 6861eb3000a94bdf79a56cee50208e2a6078c2be Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Wed, 25 Jul 2012 22:39:02 +0200 Subject: [PATCH 25/79] * Readded images. --- data/images/artistpage-background-tile.png | Bin 0 -> 46113 bytes data/images/subscribe-off.png | Bin 0 -> 3433 bytes data/images/subscribe-on.png | Bin 0 -> 3622 bytes 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 data/images/artistpage-background-tile.png create mode 100644 data/images/subscribe-off.png create mode 100644 data/images/subscribe-on.png diff --git a/data/images/artistpage-background-tile.png b/data/images/artistpage-background-tile.png new file mode 100644 index 0000000000000000000000000000000000000000..e3e6358236d9a7f3719e4b0a4059ca87fe05ff8a GIT binary patch literal 46113 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 JPDHLkV1h3_cMbpm literal 0 HcmV?d00001 diff --git a/data/images/subscribe-off.png b/data/images/subscribe-off.png new file mode 100644 index 0000000000000000000000000000000000000000..99565fd800afd4fd5788c734d7d6a92bbe3a09d2 GIT binary patch literal 3433 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 LNkvXXu0mjf^pk~8 literal 0 HcmV?d00001 diff --git a/data/images/subscribe-on.png b/data/images/subscribe-on.png new file mode 100644 index 0000000000000000000000000000000000000000..d02b6355f0978908232bf60133f0d3c70b25e1fe GIT binary patch literal 3622 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 literal 0 HcmV?d00001 From 810c933e93d1823f624ce3fc47f4d195d04c4fb1 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Wed, 25 Jul 2012 17:43:48 -0400 Subject: [PATCH 26/79] Include fix --- src/sourcetree/SourceTreeView.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sourcetree/SourceTreeView.cpp b/src/sourcetree/SourceTreeView.cpp index 577b0649c..cabb5cebe 100644 --- a/src/sourcetree/SourceTreeView.cpp +++ b/src/sourcetree/SourceTreeView.cpp @@ -51,7 +51,7 @@ #include "LatchManager.h" #include "utils/TomahawkUtilsGui.h" #include "utils/Logger.h" -#include +#include "utils/Closure.h" #include "widgets/SourceTreePopupDialog.h" using namespace Tomahawk; From e62afc6ed704c2e28e2883ed55255410eac19518 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Wed, 25 Jul 2012 17:58:31 -0400 Subject: [PATCH 27/79] Add debug --- src/sourcetree/SourceTreeView.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sourcetree/SourceTreeView.cpp b/src/sourcetree/SourceTreeView.cpp index cabb5cebe..742b89a17 100644 --- a/src/sourcetree/SourceTreeView.cpp +++ b/src/sourcetree/SourceTreeView.cpp @@ -375,6 +375,7 @@ SourceTreeView::deletePlaylist( const QModelIndex& idxIn ) m_popupDialog.data()->setOkButtonText( tr( "Delete" ) ); m_popupDialog.data()->setProperty( "idx", QVariant::fromValue< QModelIndex >( idx ) ); + qDebug() << "POPUP HAS HEIGHT:" << m_popupDialog.data()->sizeHint().height(); const QPoint rightCenter = viewport()->mapToGlobal( visualRect( idx ).topRight() + QPoint( 0, visualRect( idx ).height() / 2 ) ); m_popupDialog.data()->move( rightCenter.x() - m_popupDialog.data()->offset(), rightCenter.y() - m_popupDialog.data()->sizeHint().height() / 2. ); m_popupDialog.data()->show(); From 55fec99ce3b2d0c9d28f75df9baa996f996d5602 Mon Sep 17 00:00:00 2001 From: Tomahawk CI Date: Wed, 25 Jul 2012 22:17:42 +0000 Subject: [PATCH 28/79] Automatic merge of Transifex translations --- lang/tomahawk_ar.ts | 24 +++++------ lang/tomahawk_bg.ts | 24 +++++------ lang/tomahawk_ca.ts | 24 +++++------ lang/tomahawk_de.ts | 24 +++++------ lang/tomahawk_en.ts | 24 +++++------ lang/tomahawk_es.ts | 24 +++++------ lang/tomahawk_fr.ts | 24 +++++------ lang/tomahawk_ja.ts | 24 +++++------ lang/tomahawk_pl.ts | 24 +++++------ lang/tomahawk_pt_BR.ts | 24 +++++------ lang/tomahawk_ru.ts | 96 +++++++++++++++++++++--------------------- lang/tomahawk_sv.ts | 24 +++++------ lang/tomahawk_tr.ts | 24 +++++------ lang/tomahawk_zh_CN.ts | 24 +++++------ lang/tomahawk_zh_TW.ts | 24 +++++------ 15 files changed, 216 insertions(+), 216 deletions(-) diff --git a/lang/tomahawk_ar.ts b/lang/tomahawk_ar.ts index 2e375a71f..2f8df4164 100644 --- a/lang/tomahawk_ar.ts +++ b/lang/tomahawk_ar.ts @@ -3259,7 +3259,7 @@ enter the displayed PIN number here: - + Play إستمع @@ -3392,59 +3392,59 @@ enter the displayed PIN number here: تعليق - + 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 fc5ad004a..5500136e0 100644 --- a/lang/tomahawk_bg.ts +++ b/lang/tomahawk_bg.ts @@ -3266,7 +3266,7 @@ enter the displayed PIN number here: - + Play Изпълни @@ -3402,59 +3402,59 @@ enter the displayed PIN number here: Пауза - + 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 94180e068..05de21f0d 100644 --- a/lang/tomahawk_ca.ts +++ b/lang/tomahawk_ca.ts @@ -3258,7 +3258,7 @@ introduïu el PIN aquí: - + Play Reprodueix @@ -3391,59 +3391,59 @@ introduïu el PIN aquí: 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 435ab6792..e9ec8e41d 100644 --- a/lang/tomahawk_de.ts +++ b/lang/tomahawk_de.ts @@ -3254,7 +3254,7 @@ Tomahawk auf Twitter's Website authentifiziert hast: - + Play Abspielen @@ -3387,59 +3387,59 @@ Tomahawk auf Twitter's Website authentifiziert hast: 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 c2886d466..3457068fc 100644 --- a/lang/tomahawk_en.ts +++ b/lang/tomahawk_en.ts @@ -3259,7 +3259,7 @@ enter the displayed PIN number here: - + Play Play @@ -3392,59 +3392,59 @@ enter the displayed PIN number here: 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 e40f6115d..d06be4a8e 100644 --- a/lang/tomahawk_es.ts +++ b/lang/tomahawk_es.ts @@ -3257,7 +3257,7 @@ introduzca su número PIN aquí: - + Play Reproducir @@ -3390,59 +3390,59 @@ introduzca su número PIN aquí: 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 7fe9345ac..af971e93c 100644 --- a/lang/tomahawk_fr.ts +++ b/lang/tomahawk_fr.ts @@ -3259,7 +3259,7 @@ saisissez le numéro PIN ici : - + Play Lecture @@ -3392,59 +3392,59 @@ saisissez le numéro PIN ici : 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 3148af2a2..edfa8d158 100644 --- a/lang/tomahawk_ja.ts +++ b/lang/tomahawk_ja.ts @@ -3249,7 +3249,7 @@ Meta+Ctrl+Z - + Play 再生 @@ -3382,59 +3382,59 @@ Meta+Ctrl+Z 一時停止 - + 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 ff27e0820..e80843f1f 100644 --- a/lang/tomahawk_pl.ts +++ b/lang/tomahawk_pl.ts @@ -3253,7 +3253,7 @@ wprowadź pokazany numer PIN tutaj: - + Play Odtwarzaj @@ -3386,59 +3386,59 @@ wprowadź pokazany numer PIN tutaj: 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 2442bf381..fe9bede88 100644 --- a/lang/tomahawk_pt_BR.ts +++ b/lang/tomahawk_pt_BR.ts @@ -3259,7 +3259,7 @@ colocar o número PIN mostrado aqui: - + Play Reporduzir @@ -3392,59 +3392,59 @@ colocar o número PIN mostrado aqui: 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 94409ce08..ded4a11aa 100644 --- a/lang/tomahawk_ru.ts +++ b/lang/tomahawk_ru.ts @@ -148,12 +148,12 @@ connect and stream from you? Sorry, we could not find any other albums for this artist! - + К сожалению, мы не смогли найти другие альбомы этого исполнителя! Sorry, we could not find any tracks for this album! - + К сожалению, мы не смогли найти никаких треков для этого альбома! @@ -205,22 +205,22 @@ connect and stream from you? Cover - + Обложка Sorry, we could not find any albums for this artist! - + К сожалению, мы не смогли найти никаких альбомов этого исполнителя! Sorry, we could not find any related artists! - + К сожалению, мы не смогли найти никаких исполнители! Sorry, we could not find any top hits for this artist! - + К сожалению, мы не смогли найти никаких хитов этого исполнителя! @@ -549,7 +549,7 @@ connect and stream from you? Import Playback History - + Импортировать Историю Воспроизведений @@ -844,7 +844,7 @@ connect and stream from you? Age - + Возраст @@ -859,7 +859,7 @@ connect and stream from you? Origin - + Расположение @@ -878,7 +878,7 @@ connect and stream from you? InfoBar - + InfoBar @@ -895,7 +895,7 @@ connect and stream from you? RadioButton - + RadioButton @@ -1240,7 +1240,7 @@ connect and stream from you? Some changed settings will not take effect until Tomahawk is restarted - + Некоторые измененные настройки не вступят в силу до перезапуска Tomahawk @@ -1321,12 +1321,12 @@ connect and stream from you? Listening to "%1" by %2. %3 - + Прослушивание "%1" %2. %3 Listening to "%1" by %2 on "%3". %4 - + Прослушивание "%1" by %2 on "%3". %4 @@ -1443,12 +1443,12 @@ connect and stream from you? Latest additions to %1's collection - + Новые поступления в коллекции %1 Sorry, we could not find any recent additions! - + К сожалению, мы не смогли найти никаких последних добавлений! @@ -1463,12 +1463,12 @@ connect and stream from you? %1's recently played tracks - + %1 последние проиграные треки Sorry, we could not find any recent plays! - + К сожалению, мы не смогли найти никаких воспроизвидений треков! @@ -1528,7 +1528,7 @@ connect and stream from you? Would you like to delete the %1 <b>"%2"</b>? e.g. Would you like to delete the playlist named Foobar? - + Вы хотите удалить %1 <b>"%2"</b>? @@ -1639,7 +1639,7 @@ connect and stream from you? Right click on any Tomahawk playlist to sync it to Spotify. - + Щелкните правой кнопкой мыши по любому плейлисту Tomahawk для синхронизации его с Spotify. @@ -1654,7 +1654,7 @@ connect and stream from you? Delete Tomahawk playlist when removing synchronization - + Удалить плейлист Tomahawk, при удалении синхронизации. @@ -1743,7 +1743,7 @@ connect and stream from you? Use static external IP address/host name and port - + Использовать статический IP-адрес / имя хоста и порт @@ -1839,7 +1839,7 @@ connect and stream from you? Remove - + Удалить @@ -1937,7 +1937,7 @@ connect and stream from you? Test Login - + Проверить Вход @@ -1958,7 +1958,7 @@ connect and stream from you? Playback History Imported - + История воспроизведений импортирована. @@ -2999,7 +2999,7 @@ Try tweaking the filters for a new set of songs to play. Syncing - + Синхронизация @@ -3019,7 +3019,7 @@ Try tweaking the filters for a new set of songs to play. Offline - + Не в сети @@ -3253,7 +3253,7 @@ enter the displayed PIN number here: - + Play Играть @@ -3290,7 +3290,7 @@ enter the displayed PIN number here: Go forward one page - + Перейдите на следующую страницу @@ -3386,59 +3386,59 @@ enter the displayed PIN number here: Пауза - + 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 Авторское право 2010 - 2012 - + Thanks to: Благодарность - + About Tomahawk О Tomahawk @@ -3491,7 +3491,7 @@ enter the displayed PIN number here: Sorry, but we could not find similar tracks for this song! - + Извините, но мы не смогли найти похожие треки на эту песню! @@ -3506,7 +3506,7 @@ enter the displayed PIN number here: You first listened to it on %1. - + Первое прослушивание этой песни %1. @@ -3516,7 +3516,7 @@ enter the displayed PIN number here: You've never listened to %1 before. - + Вы никогда не слушали %1 до этого. @@ -3575,7 +3575,7 @@ enter the displayed PIN number here: Sorry, your filter '%1' did not match any results. - + К сожалению, '%1' фильтр не найдено ни одного результата. @@ -3655,7 +3655,7 @@ You can re-send a sync message at any time simply by sending another tweet using After you have scanned your music collection you will find your tracks right here. - + После сканирования вашей музыкальной коллекции вы найдете треки прямо здесь. @@ -3675,12 +3675,12 @@ You can re-send a sync message at any time simply by sending another tweet using Recently Played Tracks - + Последние Воспроизводимые Песни Recently played tracks from all your friends - + Последние воспроизводимые песни все ваших друзей @@ -4006,7 +4006,7 @@ Lyrics for "%1" by %2: Do you want to add <b>%1</b> to your friend list? - + Вы хотите добавить <b>%1</b> в списке ваших друзей? diff --git a/lang/tomahawk_sv.ts b/lang/tomahawk_sv.ts index 65d2736a4..353b59b35 100644 --- a/lang/tomahawk_sv.ts +++ b/lang/tomahawk_sv.ts @@ -3247,7 +3247,7 @@ enter the displayed PIN number here: - + Play Spela upp @@ -3380,59 +3380,59 @@ enter the displayed PIN number here: 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 a798887ea..afa004bc8 100644 --- a/lang/tomahawk_tr.ts +++ b/lang/tomahawk_tr.ts @@ -3246,7 +3246,7 @@ enter the displayed PIN number here: - + Play @@ -3379,59 +3379,59 @@ enter the displayed PIN number here: - + 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 9dfae0c46..b0051ca20 100644 --- a/lang/tomahawk_zh_CN.ts +++ b/lang/tomahawk_zh_CN.ts @@ -3246,7 +3246,7 @@ enter the displayed PIN number here: - + Play @@ -3379,59 +3379,59 @@ enter the displayed PIN number here: - + 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 48d5f2005..36feb381b 100644 --- a/lang/tomahawk_zh_TW.ts +++ b/lang/tomahawk_zh_TW.ts @@ -3246,7 +3246,7 @@ enter the displayed PIN number here: - + Play 播放 @@ -3379,59 +3379,59 @@ enter the displayed PIN number here: 暫停 - + 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 c45eec065d53684d014d09ed2c6e54003ba123a6 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Thu, 26 Jul 2012 01:30:21 +0200 Subject: [PATCH 29/79] * Fixed accessing invalid query in DbCmd_PlaybackHistory. --- src/libtomahawk/database/DatabaseCommand_PlaybackHistory.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libtomahawk/database/DatabaseCommand_PlaybackHistory.cpp b/src/libtomahawk/database/DatabaseCommand_PlaybackHistory.cpp index a2093dd25..67aea6dc4 100644 --- a/src/libtomahawk/database/DatabaseCommand_PlaybackHistory.cpp +++ b/src/libtomahawk/database/DatabaseCommand_PlaybackHistory.cpp @@ -49,7 +49,7 @@ DatabaseCommand_PlaybackHistory::exec( DatabaseImpl* dbi ) query.prepare( sql ); query.exec(); - while( query.next() ) + while ( query.next() ) { TomahawkSqlQuery query_track = dbi->newquery(); @@ -66,6 +66,8 @@ DatabaseCommand_PlaybackHistory::exec( DatabaseImpl* dbi ) if ( query_track.next() ) { Tomahawk::query_ptr q = Tomahawk::Query::get( query_track.value( 1 ).toString(), query_track.value( 0 ).toString(), QString() ); + if ( q.isNull() ) + continue; if ( query.value( 3 ).toUInt() == 0 ) { From 111de470237ec925a4afb80c44ed73c071703a11 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Thu, 26 Jul 2012 17:27:55 -0400 Subject: [PATCH 30/79] Fix vertical positioning --- src/libtomahawk/widgets/SourceTreePopupDialog.cpp | 11 +++++++---- src/libtomahawk/widgets/SourceTreePopupDialog.h | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/libtomahawk/widgets/SourceTreePopupDialog.cpp b/src/libtomahawk/widgets/SourceTreePopupDialog.cpp index 062171a72..7427d1559 100644 --- a/src/libtomahawk/widgets/SourceTreePopupDialog.cpp +++ b/src/libtomahawk/widgets/SourceTreePopupDialog.cpp @@ -58,6 +58,7 @@ SourceTreePopupDialog::SourceTreePopupDialog( SourceTreeView* parent ) layout()->addWidget( m_label ); layout()->addWidget( m_buttons ); + /* m_buttons->button( QDialogButtonBox::Ok )->setStyleSheet( "QPushButton { \ @@ -105,8 +106,8 @@ SourceTreePopupDialog::paintEvent( QPaintEvent* event ) QPainterPath outline; // Left triangle top branch - outline.moveTo( brect.left(), brect.height() / 2 ); - outline.lineTo( leftEdgeOffset, brect.height() / 2 - leftTriangleWidth / 2 ); + outline.moveTo( brect.left(), brect.top() + brect.height() / 2 ); + outline.lineTo( leftEdgeOffset, brect.top() + brect.height() / 2 - leftTriangleWidth / 2 ); // main outline outline.lineTo( leftEdgeOffset, cornerRounding ); @@ -119,10 +120,11 @@ SourceTreePopupDialog::paintEvent( QPaintEvent* event ) outline.quadTo( QPoint( leftEdgeOffset, brect.height() ), QPoint( leftEdgeOffset, brect.height() - cornerRounding ) ); // Left triangle bottom branch - outline.lineTo( leftEdgeOffset, brect.height() / 2 + leftTriangleWidth / 2 ); - outline.lineTo( brect.left(), brect.height() / 2 ); + outline.lineTo( leftEdgeOffset, brect.top() + brect.height() / 2 + leftTriangleWidth / 2 ); + outline.lineTo( brect.left(), brect.top() + brect.height() / 2 ); QPainter p( this ); + p.setRenderHint( QPainter::Antialiasing ); QPen pen( QColor( "#3F4247" ) ); @@ -130,6 +132,7 @@ SourceTreePopupDialog::paintEvent( QPaintEvent* event ) p.setPen( pen ); p.drawPath( outline ); + p.setOpacity( 0.93 ); p.fillPath( outline, QColor( "#D6E3F1" ) ); #ifdef QT_MAC_USE_COCOA diff --git a/src/libtomahawk/widgets/SourceTreePopupDialog.h b/src/libtomahawk/widgets/SourceTreePopupDialog.h index f181dfe2a..ac03139b6 100644 --- a/src/libtomahawk/widgets/SourceTreePopupDialog.h +++ b/src/libtomahawk/widgets/SourceTreePopupDialog.h @@ -39,7 +39,7 @@ class DLLEXPORT SourceTreePopupDialog : public QWidget public: explicit SourceTreePopupDialog( SourceTreeView* parent ); - int offset() const { return 14; } + int offset() const { return 16; } void setMainText( const QString& text ); void setOkButtonText( const QString& text ); From 70aa98753b3fccd2a4c57fe3cf062118754ced98 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Thu, 26 Jul 2012 22:05:09 -0400 Subject: [PATCH 31/79] Give each playlist a weak pointer to its own shared pointer --- src/libtomahawk/Playlist.cpp | 8 +++++ src/libtomahawk/Playlist.h | 3 ++ .../database/DatabaseCollection.cpp | 4 +++ .../DatabaseCommand_LoadAllPlaylists.cpp | 1 + ...DatabaseCommand_LoadAllSortedPlaylists.cpp | 33 +------------------ .../DatabaseCommand_LoadDynamicPlaylist.cpp | 4 ++- .../playlist/dynamic/DynamicPlaylist.cpp | 1 + 7 files changed, 21 insertions(+), 33 deletions(-) diff --git a/src/libtomahawk/Playlist.cpp b/src/libtomahawk/Playlist.cpp index b7f9cc837..feb2a3840 100644 --- a/src/libtomahawk/Playlist.cpp +++ b/src/libtomahawk/Playlist.cpp @@ -189,6 +189,7 @@ Playlist::create( const source_ptr& author, } playlist_ptr playlist( new Playlist( author, guid, title, info, creator, shared, entries ), &QObject::deleteLater ); + playlist->setWeakSelf( playlist.toWeakRef() ); // save to DB in the background // Watch for the created() signal if you need to be sure it's written. @@ -710,6 +711,13 @@ Playlist::checkRevisionQueue() } +void +Playlist::setWeakSelf( QWeakPointer< Playlist > self ) +{ + m_weakSelf = self; +} + + Tomahawk::playlistinterface_ptr Playlist::playlistInterface() { diff --git a/src/libtomahawk/Playlist.h b/src/libtomahawk/Playlist.h index c3ac6c45b..2e8953431 100644 --- a/src/libtomahawk/Playlist.h +++ b/src/libtomahawk/Playlist.h @@ -35,6 +35,7 @@ #include "DllMacro.h" +class SourceTreePopupDialog; class DatabaseCommand_LoadAllPlaylists; class DatabaseCommand_LoadAllSortedPlaylists; class DatabaseCommand_SetPlaylistRevision; @@ -249,6 +250,7 @@ public slots: void resolve(); + void setWeakSelf( QWeakPointer< Playlist > self ); protected: // called from loadAllPlaylists DB cmd: explicit Playlist( const source_ptr& src, @@ -289,6 +291,7 @@ private: void setBusy( bool b ); void checkRevisionQueue(); + QWeakPointer< Playlist > m_weakSelf; source_ptr m_source; QString m_currentrevision; QString m_guid, m_title, m_info, m_creator; diff --git a/src/libtomahawk/database/DatabaseCollection.cpp b/src/libtomahawk/database/DatabaseCollection.cpp index 2dca1980d..9744b428e 100644 --- a/src/libtomahawk/database/DatabaseCollection.cpp +++ b/src/libtomahawk/database/DatabaseCollection.cpp @@ -144,6 +144,8 @@ DatabaseCollection::autoPlaylistCreated( const source_ptr& source, const QVarian data[7].toBool(), //shared data[8].toInt(), //lastmod data[9].toString() ), &QObject::deleteLater ); //GUID + p->setWeakSelf( p.toWeakRef() ); + addAutoPlaylist( p ); } @@ -162,6 +164,8 @@ DatabaseCollection::stationCreated( const source_ptr& source, const QVariantList data[7].toBool(), //shared data[8].toInt(), //lastmod data[9].toString() ), &QObject::deleteLater ); //GUID + p->setWeakSelf( p.toWeakRef() ); + addStation( p ); } diff --git a/src/libtomahawk/database/DatabaseCommand_LoadAllPlaylists.cpp b/src/libtomahawk/database/DatabaseCommand_LoadAllPlaylists.cpp index 43179d10d..ede7245b7 100644 --- a/src/libtomahawk/database/DatabaseCommand_LoadAllPlaylists.cpp +++ b/src/libtomahawk/database/DatabaseCommand_LoadAllPlaylists.cpp @@ -72,6 +72,7 @@ DatabaseCommand_LoadAllPlaylists::exec( DatabaseImpl* dbi ) query.value(4).toInt(), //lastmod query.value(0).toString() //GUID ), &QObject::deleteLater ); + p->setWeakSelf( p.toWeakRef() ); plists.append( p ); } diff --git a/src/libtomahawk/database/DatabaseCommand_LoadAllSortedPlaylists.cpp b/src/libtomahawk/database/DatabaseCommand_LoadAllSortedPlaylists.cpp index 8e0c33c50..95bd87136 100644 --- a/src/libtomahawk/database/DatabaseCommand_LoadAllSortedPlaylists.cpp +++ b/src/libtomahawk/database/DatabaseCommand_LoadAllSortedPlaylists.cpp @@ -70,38 +70,7 @@ DatabaseCommand_LoadAllSortedPlaylists::exec( DatabaseImpl* dbi ) while ( query.next() ) { plists << QPair< int, QString >( query.value(9).toInt(), query.value(0).toString() ); -// playlist_ptr p; -// bool dynamic = query.value(8).toBool(); -// source_ptr s = SourceList::instance()->get( query.value(9).toInt() ); -// -// if ( dynamic ) -// { -// p = dynplaylist_ptr( new DynamicPlaylist( s, -// query.value(6).toString(), //current rev -// query.value(1).toString(), //title -// query.value(2).toString(), //info -// query.value(3).toString(), //creator -// query.value(7).toInt(), //createdOn -// query.value(10).toString(), //type -// (GeneratorMode)query.value(11).toInt(), // mode -// query.value(5).toBool(), //shared -// query.value(4).toInt(), //lastmod -// query.value(0).toString() //GUID -// ) ); -// } else -// { -// p = playlist_ptr( new Playlist( s, //src -// query.value(6).toString(), //current rev -// query.value(1).toString(), //title -// query.value(2).toString(), //info -// query.value(3).toString(), //creator -// query.value(7).toInt(), //createdOn -// query.value(5).toBool(), //shared -// query.value(4).toInt(), //lastmod -// query.value(0).toString() //GUID -// ) ); -// } -// plists.append( p ); + } emit done( plists ); diff --git a/src/libtomahawk/database/DatabaseCommand_LoadDynamicPlaylist.cpp b/src/libtomahawk/database/DatabaseCommand_LoadDynamicPlaylist.cpp index f0444ae01..70df163aa 100644 --- a/src/libtomahawk/database/DatabaseCommand_LoadDynamicPlaylist.cpp +++ b/src/libtomahawk/database/DatabaseCommand_LoadDynamicPlaylist.cpp @@ -60,6 +60,8 @@ Tomahawk::DatabaseCommand_LoadDynamicPlaylist::exec( DatabaseImpl* dbi ) query.value(5).toInt(), //lastmod query.value(0).toString() ) ); //GUID + p->setWeakSelf( p.toWeakRef() ); +/* tLog() << "Loaded individual dynamic playlist:" << query.value(7).toString() //current rev << query.value(1).toString() //title << query.value(2).toString() //info @@ -69,7 +71,7 @@ Tomahawk::DatabaseCommand_LoadDynamicPlaylist::exec( DatabaseImpl* dbi ) << static_cast(query.value(9).toInt()) // dynamic mode << query.value(6).toBool() //shared << query.value(5).toInt() //lastmod - << query.value(0).toString(); //GUID + << query.value(0).toString(); //GUID */ emit dynamicPlaylistLoaded( p ); } diff --git a/src/libtomahawk/playlist/dynamic/DynamicPlaylist.cpp b/src/libtomahawk/playlist/dynamic/DynamicPlaylist.cpp index 85ceda9f4..4cea498c1 100644 --- a/src/libtomahawk/playlist/dynamic/DynamicPlaylist.cpp +++ b/src/libtomahawk/playlist/dynamic/DynamicPlaylist.cpp @@ -155,6 +155,7 @@ DynamicPlaylist::create( const Tomahawk::source_ptr& author, ) { dynplaylist_ptr dynplaylist = Tomahawk::dynplaylist_ptr( new DynamicPlaylist( author, guid, title, info, creator, type, mode, shared, autoLoad ), &QObject::deleteLater ); + dynplaylist->setWeakSelf( dynplaylist.toWeakRef() ); DatabaseCommand_CreateDynamicPlaylist* cmd = new DatabaseCommand_CreateDynamicPlaylist( author, dynplaylist, autoLoad ); connect( cmd, SIGNAL(finished()), dynplaylist.data(), SIGNAL(created()) ); From 9d6b5e60fc57de530e4c0cf2d1d7ebcf29ab6632 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Thu, 26 Jul 2012 22:05:28 -0400 Subject: [PATCH 32/79] Allow Closures to be created when running in a different thread from the receiver --- src/libtomahawk/utils/Closure.cpp | 11 +++++++++-- src/libtomahawk/utils/Closure.h | 1 + 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/libtomahawk/utils/Closure.cpp b/src/libtomahawk/utils/Closure.cpp index 8fec43b97..daa1003b2 100644 --- a/src/libtomahawk/utils/Closure.cpp +++ b/src/libtomahawk/utils/Closure.cpp @@ -17,9 +17,15 @@ */ #include "Closure.h" +#include namespace _detail { +static bool on_this_thread(QObject* obj) +{ + return QCoreApplication::instance()->thread() == obj->thread(); +} + Closure::Closure(QObject* sender, const char* signal, QObject* receiver, @@ -28,9 +34,10 @@ Closure::Closure(QObject* sender, const ClosureArgumentWrapper* val1, const ClosureArgumentWrapper* val2, const ClosureArgumentWrapper* val3) - : QObject(receiver), + : QObject(on_this_thread(receiver) ? receiver : 0), callback_(NULL), autoDelete_(true), + outOfThreadReceiver_(on_this_thread(receiver) ? 0 : receiver ), val0_(val0), val1_(val1), val2_(val2), @@ -78,7 +85,7 @@ void Closure::Invoked() { callback_(); } else { slot_.invoke( - parent(), + parent() ? parent() : outOfThreadReceiver_, val0_ ? val0_->arg() : QGenericArgument(), val1_ ? val1_->arg() : QGenericArgument(), val2_ ? val2_->arg() : QGenericArgument(), diff --git a/src/libtomahawk/utils/Closure.h b/src/libtomahawk/utils/Closure.h index 591712358..de47502bc 100644 --- a/src/libtomahawk/utils/Closure.h +++ b/src/libtomahawk/utils/Closure.h @@ -89,6 +89,7 @@ class DLLEXPORT Closure : public QObject, boost::noncopyable { QMetaMethod slot_; std::tr1::function callback_; bool autoDelete_; + QObject* outOfThreadReceiver_; boost::scoped_ptr val0_; boost::scoped_ptr val1_; From 36c86211332eb8ca620bb762891f72d02d741352 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Thu, 26 Jul 2012 22:05:44 -0400 Subject: [PATCH 33/79] Allow playlist updaters to put custom questions in playlist delete dialogs --- src/libtomahawk/Playlist.cpp | 80 +++++++++++++++++++ src/libtomahawk/Playlist.h | 13 +++ src/libtomahawk/Typedefs.h | 3 + .../spotify/SpotifyPlaylistUpdater.cpp | 51 ++++++------ .../accounts/spotify/SpotifyPlaylistUpdater.h | 8 +- .../playlist/PlaylistUpdaterInterface.h | 6 ++ .../widgets/SourceTreePopupDialog.cpp | 52 +++++++++++- .../widgets/SourceTreePopupDialog.h | 20 ++++- src/sourcetree/SourceTreeView.cpp | 34 +++++--- 9 files changed, 222 insertions(+), 45 deletions(-) diff --git a/src/libtomahawk/Playlist.cpp b/src/libtomahawk/Playlist.cpp index feb2a3840..a90834132 100644 --- a/src/libtomahawk/Playlist.cpp +++ b/src/libtomahawk/Playlist.cpp @@ -37,7 +37,9 @@ #include "PlaylistPlaylistInterface.h" #include "utils/Logger.h" +#include "utils/Closure.h" #include "PlaylistUpdaterInterface.h" +#include "widgets/SourceTreePopupDialog.h" using namespace Tomahawk; @@ -311,6 +313,84 @@ Playlist::removeUpdater( PlaylistUpdaterInterface* updater ) } +bool +Playlist::hasCustomDeleter() const +{ + foreach ( PlaylistUpdaterInterface* updater, m_updaters ) + { + if ( !updater->deleteQuestions().isEmpty() ) + return true; + } + + return false; +} + + +void +Playlist::customDelete( const QPoint& leftCenter ) +{ + if ( !hasCustomDeleter() ) + return; + + Tomahawk::PlaylistDeleteQuestions questions; + foreach ( PlaylistUpdaterInterface* updater, m_updaters ) + { + if ( updater->deleteQuestions().isEmpty() ) + continue; + + questions.append( updater->deleteQuestions() ); + } + + Q_ASSERT( !questions.isEmpty() ); + SourceTreePopupDialog* dialog = new SourceTreePopupDialog; + NewClosure( dialog, SIGNAL( result( bool ) ), this, SLOT( onDeleteResult( SourceTreePopupDialog* ) ), dialog ); + + dialog->setMainText( tr( "Would you like to delete the playlist \"%2\"?", "e.g. Would you like to delete the playlist named Foobar?" ) + .arg( title() ) ); + dialog->setOkButtonText( tr( "Delete" ) ); + dialog->setExtraQuestions( questions ); + + dialog->move( leftCenter.x() - dialog->offset(), leftCenter.y() - dialog->sizeHint().height() / 2. ); + dialog->show(); +} + + +void +Playlist::onDeleteResult( SourceTreePopupDialog* dialog ) +{ + dialog->deleteLater(); + + const bool ret = dialog->resultValue(); + + if ( !ret ) + return; + + playlist_ptr p = m_weakSelf.toStrongRef(); + if ( p.isNull() ) + { + qWarning() << "Got null m_weakSelf weak ref in Playlsit::onDeleteResult!!"; + Q_ASSERT( false ); + return; + } + + const QMap< int, bool > questionResults = dialog->questionResults(); + foreach ( PlaylistUpdaterInterface* updater, m_updaters ) + { + updater->setQuestionResults( questionResults ); + } + + dynplaylist_ptr dynpl = p.dynamicCast< DynamicPlaylist >(); + if ( !dynpl.isNull() ) + { + DynamicPlaylist::remove( dynpl ); + } + else + { + remove( p ); + } +} + + void Playlist::loadRevision( const QString& rev ) { diff --git a/src/libtomahawk/Playlist.h b/src/libtomahawk/Playlist.h index 2e8953431..697b0114d 100644 --- a/src/libtomahawk/Playlist.h +++ b/src/libtomahawk/Playlist.h @@ -195,6 +195,18 @@ public: void removeUpdater( PlaylistUpdaterInterface* updater ); QList updaters() const { return m_updaters; } + /** + * Some updaters might have custom deleters in order to perform more actions that require + * user prompting on delete. + */ + bool hasCustomDeleter() const; + /** + * If this playlist has a custom deleter, let it do the deleting itself. + * + * If it needs user prompting, use the \param customDeleter as the right-most center point. + */ + void customDelete( const QPoint& rightCenter ); + Tomahawk::playlistinterface_ptr playlistInterface(); signals: @@ -284,6 +296,7 @@ private slots: void onResultsFound( const QList& results ); void onResolvingFinished(); + void onDeleteResult( SourceTreePopupDialog* ); private: Playlist(); void init(); diff --git a/src/libtomahawk/Typedefs.h b/src/libtomahawk/Typedefs.h index 730799e9a..aad92ff9d 100644 --- a/src/libtomahawk/Typedefs.h +++ b/src/libtomahawk/Typedefs.h @@ -98,6 +98,9 @@ namespace Tomahawk typedef QMultiHash< QString, SerializedUpdater > SerializedUpdaters; typedef QList< SerializedUpdater > SerializedUpdaterList; + // Yes/no questions with an associated enum value + typedef QPair< QString, int > PlaylistDeleteQuestion; + typedef QList< PlaylistDeleteQuestion > PlaylistDeleteQuestions; namespace InfoSystem { diff --git a/src/libtomahawk/accounts/spotify/SpotifyPlaylistUpdater.cpp b/src/libtomahawk/accounts/spotify/SpotifyPlaylistUpdater.cpp index d0474cabe..28c3cf748 100644 --- a/src/libtomahawk/accounts/spotify/SpotifyPlaylistUpdater.cpp +++ b/src/libtomahawk/accounts/spotify/SpotifyPlaylistUpdater.cpp @@ -131,44 +131,28 @@ SpotifyPlaylistUpdater::remove( bool askToDeletePlaylist ) void -SpotifyPlaylistUpdater::aboutToDelete() +SpotifyPlaylistUpdater::unsyncOrDelete( bool toDelete ) { if ( QThread::currentThread() != QApplication::instance()->thread() ) - QMetaObject::invokeMethod( const_cast(this), "aboutToDelete", Qt::BlockingQueuedConnection ); + QMetaObject::invokeMethod( const_cast(this), "unsyncOrDelete", Qt::BlockingQueuedConnection, Q_ARG( bool, toDelete ) ); else { if ( m_subscribed ) { m_spotify.data()->setSubscribedForPlaylist( playlist(), false ); } - else if ( m_sync ) + else if ( m_sync && toDelete ) { - checkDeleteDialog(); + // User wants to delete it! + QVariantMap msg; + msg[ "_msgtype" ] = "deletePlaylist"; + msg[ "playlistid" ] = m_spotifyId; + m_spotify.data()->sendMessage( msg ); } } } -void -SpotifyPlaylistUpdater::checkDeleteDialog() const -{ - // Ask if we should delete the playlist on the spotify side as well - QMessageBox askDelete( QMessageBox::Question, tr( "Delete in Spotify?" ), tr( "Would you like to delete the corresponding Spotify playlist as well?" ), QMessageBox::Yes | QMessageBox::No, 0 ); - int ret = askDelete.exec(); - if ( ret == QMessageBox::Yes ) - { - if ( m_spotify.isNull() ) - return; - - // User wants to delete it! - QVariantMap msg; - msg[ "_msgtype" ] = "deletePlaylist"; - msg[ "playlistid" ] = m_spotifyId; - m_spotify.data()->sendMessage( msg ); - } -} - - void SpotifyPlaylistUpdater::playlistRevisionLoaded() { @@ -293,6 +277,25 @@ SpotifyPlaylistUpdater::canSubscribe() const } +PlaylistDeleteQuestions +SpotifyPlaylistUpdater::deleteQuestions() const +{ + // 1234 is our magic key + if ( m_sync && !m_subscribed ) + return Tomahawk::PlaylistDeleteQuestions() << qMakePair( tr( "Delete associated Spotify playlist?" ), 1234 ); + else + return Tomahawk::PlaylistDeleteQuestions(); +} + + +void +SpotifyPlaylistUpdater::setQuestionResults( const QMap< int, bool > results ) +{ + const bool toDelete = results.value( 1234, false ); + unsyncOrDelete( toDelete ); +} + + void SpotifyPlaylistUpdater::spotifyTracksAdded( const QVariantList& tracks, const QString& startPosId, const QString& newRev, const QString& oldRev ) { diff --git a/src/libtomahawk/accounts/spotify/SpotifyPlaylistUpdater.h b/src/libtomahawk/accounts/spotify/SpotifyPlaylistUpdater.h index 10ceef393..d72c17248 100644 --- a/src/libtomahawk/accounts/spotify/SpotifyPlaylistUpdater.h +++ b/src/libtomahawk/accounts/spotify/SpotifyPlaylistUpdater.h @@ -23,6 +23,7 @@ #include "playlist/PlaylistUpdaterInterface.h" #include "utils/Closure.h" #include "DllMacro.h" +#include "Typedefs.h" #include #include @@ -63,6 +64,9 @@ public: void setCanSubscribe( bool canSub ); QString spotifyId() const { return m_spotifyId; } + virtual Tomahawk::PlaylistDeleteQuestions deleteQuestions() const; + virtual void setQuestionResults( const QMap< int, bool > results ); + void remove( bool askToDeletePlaylist = true ); public slots: /// Spotify callbacks when we are directly instructed from the resolver @@ -76,15 +80,13 @@ public slots: void tomahawkTracksMoved( const QList& ,int ); void tomahawkPlaylistRenamed( const QString&, const QString& ); - void aboutToDelete(); - private slots: // SpotifyResolver message handlers, all take msgtype, msg as argument void onTracksInsertedReturn( const QString& msgType, const QVariantMap& msg, const QVariant& extraData ); void onTracksRemovedReturn( const QString& msgType, const QVariantMap& msg, const QVariant& extraData ); void onTracksMovedReturn( const QString& msgType, const QVariantMap& msg, const QVariant& extraData ); - void checkDeleteDialog() const; + void unsyncOrDelete( bool toDelete ); void playlistRevisionLoaded(); private: diff --git a/src/libtomahawk/playlist/PlaylistUpdaterInterface.h b/src/libtomahawk/playlist/PlaylistUpdaterInterface.h index a58feb0f1..61885dd6d 100644 --- a/src/libtomahawk/playlist/PlaylistUpdaterInterface.h +++ b/src/libtomahawk/playlist/PlaylistUpdaterInterface.h @@ -25,6 +25,7 @@ #include #include +#include #ifndef ENABLE_HEADLESS #include @@ -84,6 +85,11 @@ public: virtual bool subscribed() const { return false; } virtual void setSubscribed( bool ) {} + // The int data value associated with each question must be unique across *all* playlist updaters, + // as setQuestionResults is called with all questions from all updaters. + virtual PlaylistDeleteQuestions deleteQuestions() const { return PlaylistDeleteQuestions(); } + virtual void setQuestionResults( const QMap< int, bool > results ) {} + signals: void changed(); diff --git a/src/libtomahawk/widgets/SourceTreePopupDialog.cpp b/src/libtomahawk/widgets/SourceTreePopupDialog.cpp index 7427d1559..d6943a357 100644 --- a/src/libtomahawk/widgets/SourceTreePopupDialog.cpp +++ b/src/libtomahawk/widgets/SourceTreePopupDialog.cpp @@ -18,22 +18,25 @@ #include "SourceTreePopupDialog.h" -#include "sourcetree/SourceTreeView.h" - #include #include #include #include +#include #include #include +#include #include #ifdef QT_MAC_USE_COCOA #include "SourceTreePopupDialog_mac.h" #endif -SourceTreePopupDialog::SourceTreePopupDialog( SourceTreeView* parent ) +using namespace Tomahawk; + +SourceTreePopupDialog::SourceTreePopupDialog() : QWidget( 0 ) + , m_layout( 0 ) , m_result( false ) , m_label( 0 ) , m_buttons( 0 ) @@ -54,10 +57,12 @@ SourceTreePopupDialog::SourceTreePopupDialog( SourceTreeView* parent ) connect( m_buttons, SIGNAL( accepted() ), this, SLOT( onAccepted() ) ); connect( m_buttons, SIGNAL( rejected() ), this, SLOT( onRejected() ) ); - setLayout( new QVBoxLayout ); + m_layout = new QVBoxLayout; + setLayout( m_layout ); layout()->addWidget( m_label ); layout()->addWidget( m_buttons ); + setContentsMargins( contentsMargins().left() + 2, contentsMargins().top(), contentsMargins().right(), contentsMargins().bottom() ); /* m_buttons->button( QDialogButtonBox::Ok )->setStyleSheet( @@ -95,6 +100,30 @@ SourceTreePopupDialog::setOkButtonText( const QString& text ) } +void +SourceTreePopupDialog::setExtraQuestions( const Tomahawk::PlaylistDeleteQuestions& questions ) +{ + m_questions = questions; + + int idx = m_layout->indexOf( m_label ) + 1; + foreach ( const Tomahawk::PlaylistDeleteQuestion& question, m_questions ) + { + QCheckBox* cb = new QCheckBox( question.first, this ); + cb->setLayoutDirection( Qt::RightToLeft ); + cb->setProperty( "data", question.second ); + + QHBoxLayout* h = new QHBoxLayout; + h->addStretch( 1 ); + h->addWidget( cb ); +// m_layout->insertLayout( h, cb, 0 ); + m_layout->insertLayout( idx, h, 0 ); + + m_questionCheckboxes << cb; + idx++; + } +} + + void SourceTreePopupDialog::paintEvent( QPaintEvent* event ) { @@ -163,6 +192,7 @@ SourceTreePopupDialog::onAccepted() { hide(); m_result = true; + calculateResults(); emit result( m_result ); } @@ -172,5 +202,19 @@ SourceTreePopupDialog::onRejected() { hide(); m_result = false; + calculateResults(); emit result( m_result ); } + + +void +SourceTreePopupDialog::calculateResults() +{ + foreach ( const QCheckBox* b, m_questionCheckboxes ) + { + if ( b->property( "data" ).toInt() != 0 ) + { + m_questionResults[ b->property( "data" ).toInt() ] = ( b->checkState() == Qt::Checked ); + } + } +} diff --git a/src/libtomahawk/widgets/SourceTreePopupDialog.h b/src/libtomahawk/widgets/SourceTreePopupDialog.h index ac03139b6..a7d3e3e9b 100644 --- a/src/libtomahawk/widgets/SourceTreePopupDialog.h +++ b/src/libtomahawk/widgets/SourceTreePopupDialog.h @@ -20,15 +20,18 @@ #define SOURCETREE_POPUP_DIALOG #include "DllMacro.h" +#include "Typedefs.h" #include +#include +class QVBoxLayout; class QShowEvent; class QLabel; class QDialogButtonBox; class QPushButton; class QFocusEvent; -class SourceTreeView; +class QCheckBox; /** * Place me at offset() to the left of the right edge of the sourcetree. @@ -37,14 +40,16 @@ class DLLEXPORT SourceTreePopupDialog : public QWidget { Q_OBJECT public: - explicit SourceTreePopupDialog( SourceTreeView* parent ); + explicit SourceTreePopupDialog(); int offset() const { return 16; } void setMainText( const QString& text ); void setOkButtonText( const QString& text ); + void setExtraQuestions( const Tomahawk::PlaylistDeleteQuestions& questions ); bool resultValue() const { return m_result; } + QMap< int, bool > questionResults() const { return m_questionResults; } signals: void result( bool accepted ); @@ -59,11 +64,22 @@ private slots: void onRejected(); private: + void calculateResults(); + + QVBoxLayout* m_layout; + QList< QCheckBox* > m_questionCheckboxes; + QString m_text; bool m_result; + Tomahawk::PlaylistDeleteQuestions m_questions; + QMap< int, bool > m_questionResults; QLabel* m_label; QDialogButtonBox* m_buttons; }; + +Q_DECLARE_METATYPE( SourceTreePopupDialog* ) #endif + +class QCheckBox; diff --git a/src/sourcetree/SourceTreeView.cpp b/src/sourcetree/SourceTreeView.cpp index 742b89a17..6ae602c05 100644 --- a/src/sourcetree/SourceTreeView.cpp +++ b/src/sourcetree/SourceTreeView.cpp @@ -364,21 +364,31 @@ SourceTreeView::deletePlaylist( const QModelIndex& idxIn ) Q_ASSERT( false ); } - if ( m_popupDialog.isNull() ) + PlaylistItem* item = itemFromIndex< PlaylistItem >( idx ); + playlist_ptr playlist = item->playlist(); + + const QPoint rightCenter = viewport()->mapToGlobal( visualRect( idx ).topRight() + QPoint( 0, visualRect( idx ).height() / 2 ) ); + if ( playlist->hasCustomDeleter() ) { - m_popupDialog = QWeakPointer< SourceTreePopupDialog >( new SourceTreePopupDialog( this ) ); - connect( m_popupDialog.data(), SIGNAL( result( bool ) ), this, SLOT( onDeletePlaylistResult( bool ) ) ); + playlist->customDelete( rightCenter ); + } + else + { + if ( m_popupDialog.isNull() ) + { + m_popupDialog = QWeakPointer< SourceTreePopupDialog >( new SourceTreePopupDialog() ); + connect( m_popupDialog.data(), SIGNAL( result( bool ) ), this, SLOT( onDeletePlaylistResult( bool ) ) ); + } + + m_popupDialog.data()->setMainText( tr( "Would you like to delete the %1 \"%2\"?", "e.g. Would you like to delete the playlist named Foobar?" ) + .arg( typeDesc ).arg( idx.data().toString() ) ); + m_popupDialog.data()->setOkButtonText( tr( "Delete" ) ); + m_popupDialog.data()->setProperty( "idx", QVariant::fromValue< QModelIndex >( idx ) ); + + m_popupDialog.data()->move( rightCenter.x() - m_popupDialog.data()->offset(), rightCenter.y() - m_popupDialog.data()->sizeHint().height() / 2. ); + m_popupDialog.data()->show(); } - m_popupDialog.data()->setMainText( tr( "Would you like to delete the %1 \"%2\"?", "e.g. Would you like to delete the playlist named Foobar?" ) - .arg( typeDesc ).arg( idx.data().toString() ) ); - m_popupDialog.data()->setOkButtonText( tr( "Delete" ) ); - m_popupDialog.data()->setProperty( "idx", QVariant::fromValue< QModelIndex >( idx ) ); - - qDebug() << "POPUP HAS HEIGHT:" << m_popupDialog.data()->sizeHint().height(); - const QPoint rightCenter = viewport()->mapToGlobal( visualRect( idx ).topRight() + QPoint( 0, visualRect( idx ).height() / 2 ) ); - m_popupDialog.data()->move( rightCenter.x() - m_popupDialog.data()->offset(), rightCenter.y() - m_popupDialog.data()->sizeHint().height() / 2. ); - m_popupDialog.data()->show(); } From 3fbd58fcc9424ed18e9718b5a1ea1abb30d9b885 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Thu, 26 Jul 2012 22:41:50 -0400 Subject: [PATCH 34/79] Call playlist results if an updater has a custom deleter regardless --- src/libtomahawk/Playlist.cpp | 3 +-- src/libtomahawk/accounts/spotify/SpotifyPlaylistUpdater.h | 1 + src/libtomahawk/playlist/PlaylistUpdaterInterface.h | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libtomahawk/Playlist.cpp b/src/libtomahawk/Playlist.cpp index a90834132..3e21c36b5 100644 --- a/src/libtomahawk/Playlist.cpp +++ b/src/libtomahawk/Playlist.cpp @@ -318,7 +318,7 @@ Playlist::hasCustomDeleter() const { foreach ( PlaylistUpdaterInterface* updater, m_updaters ) { - if ( !updater->deleteQuestions().isEmpty() ) + if ( updater->hasCustomDeleter() ) return true; } @@ -341,7 +341,6 @@ Playlist::customDelete( const QPoint& leftCenter ) questions.append( updater->deleteQuestions() ); } - Q_ASSERT( !questions.isEmpty() ); SourceTreePopupDialog* dialog = new SourceTreePopupDialog; NewClosure( dialog, SIGNAL( result( bool ) ), this, SLOT( onDeleteResult( SourceTreePopupDialog* ) ), dialog ); diff --git a/src/libtomahawk/accounts/spotify/SpotifyPlaylistUpdater.h b/src/libtomahawk/accounts/spotify/SpotifyPlaylistUpdater.h index d72c17248..133ab1274 100644 --- a/src/libtomahawk/accounts/spotify/SpotifyPlaylistUpdater.h +++ b/src/libtomahawk/accounts/spotify/SpotifyPlaylistUpdater.h @@ -64,6 +64,7 @@ public: void setCanSubscribe( bool canSub ); QString spotifyId() const { return m_spotifyId; } + virtual bool hasCustomDeleter() const { return true; } virtual Tomahawk::PlaylistDeleteQuestions deleteQuestions() const; virtual void setQuestionResults( const QMap< int, bool > results ); diff --git a/src/libtomahawk/playlist/PlaylistUpdaterInterface.h b/src/libtomahawk/playlist/PlaylistUpdaterInterface.h index 61885dd6d..92e46e235 100644 --- a/src/libtomahawk/playlist/PlaylistUpdaterInterface.h +++ b/src/libtomahawk/playlist/PlaylistUpdaterInterface.h @@ -87,6 +87,7 @@ public: // The int data value associated with each question must be unique across *all* playlist updaters, // as setQuestionResults is called with all questions from all updaters. + virtual bool hasCustomDeleter() const { return false; } virtual PlaylistDeleteQuestions deleteQuestions() const { return PlaylistDeleteQuestions(); } virtual void setQuestionResults( const QMap< int, bool > results ) {} From b35e6ce61d6150aea1e84b6d2661ac2fab479e5d Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Fri, 27 Jul 2012 14:59:22 -0400 Subject: [PATCH 35/79] TWK-998: Stable sort in job view proxy, by creation date --- src/libtomahawk/jobview/JobStatusItem.cpp | 2 ++ src/libtomahawk/jobview/JobStatusItem.h | 4 ++++ src/libtomahawk/jobview/JobStatusModel.cpp | 23 +++++++++++++++------- src/libtomahawk/jobview/JobStatusModel.h | 4 +++- 4 files changed, 25 insertions(+), 8 deletions(-) diff --git a/src/libtomahawk/jobview/JobStatusItem.cpp b/src/libtomahawk/jobview/JobStatusItem.cpp index 9db2726a2..8c2dd2b1d 100644 --- a/src/libtomahawk/jobview/JobStatusItem.cpp +++ b/src/libtomahawk/jobview/JobStatusItem.cpp @@ -18,10 +18,12 @@ #include "JobStatusItem.h" +#include JobStatusItem::JobStatusItem() : QObject() + , m_createdOn( QDateTime::currentMSecsSinceEpoch() ) { } diff --git a/src/libtomahawk/jobview/JobStatusItem.h b/src/libtomahawk/jobview/JobStatusItem.h index e2d8ca606..dc85d8ae4 100644 --- a/src/libtomahawk/jobview/JobStatusItem.h +++ b/src/libtomahawk/jobview/JobStatusItem.h @@ -65,12 +65,16 @@ public: virtual void createDelegate( QObject* parent ); virtual QStyledItemDelegate* customDelegate() const; + qint64 age() const { return m_createdOn; } signals: /// Ask for an update void statusChanged(); /// Job is finished, will be deleted by the model void finished(); + +private: + qint64 m_createdOn; }; Q_DECLARE_METATYPE( JobStatusItem* ); diff --git a/src/libtomahawk/jobview/JobStatusModel.cpp b/src/libtomahawk/jobview/JobStatusModel.cpp index 1744a5d4b..8a364e926 100644 --- a/src/libtomahawk/jobview/JobStatusModel.cpp +++ b/src/libtomahawk/jobview/JobStatusModel.cpp @@ -82,14 +82,14 @@ JobStatusSortModel::refreshDelegatesSlot() bool JobStatusSortModel::lessThan( const QModelIndex& left, const QModelIndex& right ) const { - QVariant leftVar = left.data( JobStatusModel::JobDataRole ); - JobStatusItem* leftItem = leftVar.value< JobStatusItem* >(); - QVariant rightVar = right.data( JobStatusModel::JobDataRole ); - JobStatusItem* rightItem = rightVar.value< JobStatusItem* >(); - if ( !leftItem || !rightItem ) - return false; + const int leftSort = left.data( JobStatusModel::SortRole ).toInt(); + const int rightSort = right.data( JobStatusModel::SortRole ).toInt(); - return leftItem->weight() < rightItem->weight(); + if ( leftSort == rightSort ) + return left.data( JobStatusModel::AgeRole ).toUInt() > right.data( JobStatusModel::AgeRole ).toUInt(); + + + return leftSort < rightSort; } @@ -204,6 +204,15 @@ JobStatusModel::data( const QModelIndex& index, int role ) const case JobDataRole: return QVariant::fromValue< JobStatusItem* >( item ); + + case SortRole: + return item->weight(); + + case AgeRole: + return item->age(); + + default: + return QVariant(); } return QVariant(); diff --git a/src/libtomahawk/jobview/JobStatusModel.h b/src/libtomahawk/jobview/JobStatusModel.h index dc4d80ca5..358a581c7 100644 --- a/src/libtomahawk/jobview/JobStatusModel.h +++ b/src/libtomahawk/jobview/JobStatusModel.h @@ -37,7 +37,9 @@ public: // DisplayRole is main col RightColumnRole = Qt::UserRole + 1, AllowMultiLineRole = Qt::UserRole + 2, - JobDataRole = Qt::UserRole + 3 + JobDataRole = Qt::UserRole + 3, + SortRole = Qt::UserRole + 4, + AgeRole = Qt::UserRole + 5 }; explicit JobStatusModel( QObject* parent = 0 ); From 6c7206c14769756f60a8a0e0312dec9bdd454fe4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hugo=20Lindstr=C3=B6m?= Date: Fri, 27 Jul 2012 22:42:51 +0200 Subject: [PATCH 36/79] Add extra types --- .../generic/newreleases/NewReleasesPlugin.cpp | 119 +++++++++++++----- 1 file changed, 85 insertions(+), 34 deletions(-) diff --git a/src/infoplugins/generic/newreleases/NewReleasesPlugin.cpp b/src/infoplugins/generic/newreleases/NewReleasesPlugin.cpp index b5b2ae1a2..9f0bf12f5 100644 --- a/src/infoplugins/generic/newreleases/NewReleasesPlugin.cpp +++ b/src/infoplugins/generic/newreleases/NewReleasesPlugin.cpp @@ -42,7 +42,7 @@ NewReleasesPlugin::NewReleasesPlugin() : InfoPlugin() , m_nrFetchJobs ( 0 ) { - m_nrVersion = "0"; + m_nrVersion = "0.1"; m_supportedGetTypes << InfoNewReleaseCapabilities << InfoNewRelease; } @@ -54,8 +54,10 @@ NewReleasesPlugin::~NewReleasesPlugin() void NewReleasesPlugin::init() { + QVariantList source_qvarlist = TomahawkUtils::Cache::instance()->getData( "NewReleasesPlugin", "nr_sources" ).toList(); - foreach( const QVariant & source, source_qvarlist ) { + foreach( const QVariant & source, source_qvarlist ) + { m_nrSources.append( source.toString() ); tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "fetched source from cache" << source.toString(); @@ -79,21 +81,28 @@ void NewReleasesPlugin::getInfo ( InfoRequestData requestData ) InfoStringHash hash = requestData.input.value< Tomahawk::InfoSystem::InfoStringHash >(); bool foundSource = false; - switch ( requestData.type ) { + switch ( requestData.type ) + { case InfoNewRelease: /// We need something to check if the request is actually ment to go to this plugin - if ( !hash.contains ( "nr_source" ) ) { + if ( !hash.contains ( "nr_source" ) ) + { tDebug ( LOGVERBOSE ) << Q_FUNC_INFO << "Hash did not contain required param!"; dataError ( requestData ); break; - } else { - foreach ( QString resource, m_nrSources ) { - if ( resource == hash["nr_source"] ) { + } + else + { + foreach ( QString resource, m_nrSources ) + { + if ( resource == hash["nr_source"] ) + { foundSource = true; } } - if ( !foundSource ) { + if ( !foundSource ) + { dataError ( requestData ); break; } @@ -112,7 +121,8 @@ void NewReleasesPlugin::getInfo ( InfoRequestData requestData ) void NewReleasesPlugin::fetchNRFromCache ( InfoRequestData requestData ) { - if ( !requestData.input.canConvert< Tomahawk::InfoSystem::InfoStringHash >() ) { + if ( !requestData.input.canConvert< Tomahawk::InfoSystem::InfoStringHash >() ) + { dataError ( requestData ); return; } @@ -121,7 +131,8 @@ void NewReleasesPlugin::fetchNRFromCache ( InfoRequestData requestData ) Tomahawk::InfoSystem::InfoStringHash criteria; /// Each request needs to contain both a id and source - if ( !hash.contains ( "nr_id" ) && !hash.contains ( "nr_source" ) ) { + if ( !hash.contains ( "nr_id" ) && !hash.contains ( "nr_source" ) ) + { tDebug ( LOGVERBOSE ) << Q_FUNC_INFO << "Hash did not contain required params!"; dataError ( requestData ); return; @@ -136,7 +147,8 @@ void NewReleasesPlugin::fetchNRFromCache ( InfoRequestData requestData ) void NewReleasesPlugin::fetchNRCapabilitiesFromCache ( InfoRequestData requestData ) { - if ( !requestData.input.canConvert< Tomahawk::InfoSystem::InfoStringHash >() ) { + if ( !requestData.input.canConvert< Tomahawk::InfoSystem::InfoStringHash >() ) + { tDebug ( LOGVERBOSE ) << Q_FUNC_INFO << "Could not convert requestData to InfoStringHash!"; dataError ( requestData ); return; @@ -150,15 +162,18 @@ void NewReleasesPlugin::fetchNRCapabilitiesFromCache ( InfoRequestData requestDa void NewReleasesPlugin::notInCacheSlot ( InfoStringHash criteria, InfoRequestData requestData ) { - switch ( requestData.type ) { - case InfoNewRelease: { + switch ( requestData.type ) + { + case InfoNewRelease: + { tDebug ( LOGVERBOSE ) << Q_FUNC_INFO << "InfoNewRelease not in cache! Fetching..."; fetchNR ( requestData, criteria["nr_source"], criteria["nr_id"] ); return; } - case InfoNewReleaseCapabilities: { + case InfoNewReleaseCapabilities: + { tDebug ( LOGVERBOSE ) << Q_FUNC_INFO << "InfoChartCapabilities not in cache! Fetching..."; fetchNRSourcesList( false ); m_cachedRequests.append ( requestData ); @@ -166,7 +181,8 @@ void NewReleasesPlugin::notInCacheSlot ( InfoStringHash criteria, InfoRequestDat return; } - default: { + default: + { tLog() << Q_FUNC_INFO << "Couldn't figure out what to do with this type of request after cache miss"; emit info ( requestData, QVariant() ); return; @@ -191,19 +207,22 @@ void NewReleasesPlugin::nrSourcesList() tDebug ( LOGVERBOSE ) << "Got newreleases sources list"; QNetworkReply* reply = qobject_cast ( sender() ); - if ( reply->error() == QNetworkReply::NoError ) { + if ( reply->error() == QNetworkReply::NoError ) + { QJson::Parser p; bool ok; const QVariantMap res = p.parse ( reply, &ok ).toMap(); const QVariantList sources = res.value ( "sources" ).toList(); - if ( !ok ) { + if ( !ok ) + { tLog() << "Failed to parse sources" << p.errorString() << "On line" << p.errorLine(); return; } m_nrSources.clear(); - foreach ( const QVariant &source, sources ) { + foreach ( const QVariant &source, sources ) + { m_nrSources << source.toString(); } TomahawkUtils::Cache::instance()->putData( "NewReleasesPlugin", 172800000 /* 2 days */, "nr_sources", m_nrSources ); @@ -214,9 +233,11 @@ void NewReleasesPlugin::nrSourcesList() void NewReleasesPlugin::fetchAllNRSources() { - if ( !m_nrSources.isEmpty() && m_allNRsMap.isEmpty() ) { + if ( !m_nrSources.isEmpty() && m_allNRsMap.isEmpty() ) + { tDebug ( LOGVERBOSE ) << Q_FUNC_INFO << "InfoNewRelease fetching source data"; - foreach ( QString source, m_nrSources ) { + foreach ( QString source, m_nrSources ) + { QUrl url = QUrl ( QString ( CHART_URL "newreleases/%1" ).arg ( source ) ); QNetworkReply* reply = TomahawkUtils::nam()->get ( QNetworkRequest ( url ) ); reply->setProperty ( "nr_source", source ); @@ -246,12 +267,14 @@ void NewReleasesPlugin::nrList() tDebug ( LOGVERBOSE ) << "Got newreleases list result"; QNetworkReply* reply = qobject_cast ( sender() ); - if ( reply->error() == QNetworkReply::NoError ) { + if ( reply->error() == QNetworkReply::NoError ) + { QJson::Parser p; bool ok; const QVariantMap res = p.parse ( reply, &ok ).toMap(); - if ( !ok ) { + if ( !ok ) + { tLog() << "Failed to parse resources" << p.errorString() << "On line" << p.errorLine(); return; @@ -267,31 +290,53 @@ void NewReleasesPlugin::nrList() // Building: // [Source] - New Release QList< InfoStringHash > albumNRs; - - foreach ( const QVariant &nrObj, res.values() ) { - if ( !nrObj.toMap().isEmpty() ) { + QHash< QString, QVariantMap > extraType; + foreach ( const QVariant &nrObj, res.values() ) + { + if ( !nrObj.toMap().isEmpty() ) + { const QVariantMap nrMap = nrObj.toMap(); const QString type = nrMap.value ( "type" ).toString(); + const QString extra = nrMap.value( "extra" ).toString(); InfoStringHash nr; nr["id"] = nrMap.value ( "id" ).toString(); nr["label"] = nrMap.value ( "name" ).toString(); nr["date"] = nrMap.value ( "date" ).toString(); - if ( type == "Album" ) { + if ( type == "Album" ) + { nr[ "type" ] = "album"; - albumNRs.append ( nr ); - } else { + + if( !extra.isEmpty() ) + { + qDebug() << "FOUND EXTRA!! " << extra; + QList< Tomahawk::InfoSystem::InfoStringHash > extraTypeData = extraType[ extra ][ type ].value< QList< Tomahawk::InfoSystem::InfoStringHash > >(); + extraTypeData.append( nr ); + extraType[ extra ][ type ] = QVariant::fromValue< QList< Tomahawk::InfoSystem::InfoStringHash > >( extraTypeData ); + } + else + albumNRs.append ( nr ); + } + else + { tLog() << "Unknown newrelease type " << type; continue; } } + + foreach( const QString& c, extraType.keys() ) + { + newreleases[ c ] = extraType[ c ]; + tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "extraType has types:" << c; + } } if ( !albumNRs.isEmpty() ) newreleases.insert ( tr ( "Albums" ), QVariant::fromValue< QList< Tomahawk::InfoSystem::InfoStringHash > > ( albumNRs ) ); + /// @note For displaying purposes, upper the first letter /// @note Remeber to lower it when fetching this! nrName = source; @@ -306,8 +351,10 @@ void NewReleasesPlugin::nrList() } m_nrFetchJobs--; - if ( !m_cachedRequests.isEmpty() && m_nrFetchJobs == 0 ) { - foreach ( InfoRequestData request, m_cachedRequests ) { + if ( !m_cachedRequests.isEmpty() && m_nrFetchJobs == 0 ) + { + foreach ( InfoRequestData request, m_cachedRequests ) + { emit info ( request, m_allNRsMap ); // update cache Tomahawk::InfoSystem::InfoStringHash criteria; @@ -325,12 +372,14 @@ void NewReleasesPlugin::nrReturned() QNetworkReply* reply = qobject_cast ( sender() ); QVariantMap returnedData; - if ( reply->error() == QNetworkReply::NoError ) { + if ( reply->error() == QNetworkReply::NoError ) + { QJson::Parser p; bool ok; QVariantMap res = p.parse ( reply, &ok ).toMap(); - if ( !ok ) { + if ( !ok ) + { tLog() << "Failed to parse json from chart lookup:" << p.errorString() << "On line" << p.errorLine(); return; } @@ -339,9 +388,11 @@ void NewReleasesPlugin::nrReturned() QVariantList albumList = res.value ( "list" ).toList(); QList< Tomahawk::InfoSystem::InfoStringHash > newreleases; - foreach( const QVariant & albumObj, albumList ) { + foreach( const QVariant & albumObj, albumList ) + { QVariantMap albumMap = albumObj.toMap(); - if(!albumMap.isEmpty()) { + if( !albumMap.isEmpty() ) + { const QString album = albumMap.value("album").toString(); const QString artist = albumMap.value("artist").toString(); const QString date = albumMap.value("date").toString(); From 111f56908177f15bb949db34f923fc028d7dd26e Mon Sep 17 00:00:00 2001 From: Tomahawk CI Date: Fri, 27 Jul 2012 22:16:58 +0000 Subject: [PATCH 37/79] Automatic merge of Transifex translations --- lang/tomahawk_ar.ts | 62 ++++++++++++++++++++++++------------------ lang/tomahawk_bg.ts | 62 ++++++++++++++++++++++++------------------ lang/tomahawk_ca.ts | 62 ++++++++++++++++++++++++------------------ lang/tomahawk_de.ts | 62 ++++++++++++++++++++++++------------------ lang/tomahawk_en.ts | 62 ++++++++++++++++++++++++------------------ lang/tomahawk_es.ts | 62 ++++++++++++++++++++++++------------------ lang/tomahawk_fr.ts | 62 ++++++++++++++++++++++++------------------ lang/tomahawk_ja.ts | 62 ++++++++++++++++++++++++------------------ lang/tomahawk_pl.ts | 60 ++++++++++++++++++++++------------------ lang/tomahawk_pt_BR.ts | 62 ++++++++++++++++++++++++------------------ lang/tomahawk_ru.ts | 60 ++++++++++++++++++++++------------------ lang/tomahawk_sv.ts | 60 ++++++++++++++++++++++------------------ lang/tomahawk_tr.ts | 60 ++++++++++++++++++++++------------------ lang/tomahawk_zh_CN.ts | 60 ++++++++++++++++++++++------------------ lang/tomahawk_zh_TW.ts | 60 ++++++++++++++++++++++------------------ 15 files changed, 519 insertions(+), 399 deletions(-) diff --git a/lang/tomahawk_ar.ts b/lang/tomahawk_ar.ts index 2f8df4164..3bf6b38b0 100644 --- a/lang/tomahawk_ar.ts +++ b/lang/tomahawk_ar.ts @@ -1475,69 +1475,68 @@ connect and stream from you? SourceTreeView - + &Copy Link &نسخ الرابط - + &Delete %1 &أحذف %1 - + Add to my Playlists أضف إلى لوائحي للأغاني - + Add to my Automatic Playlists أضف إلى لوائحي الأوتوماتيكية للأغاني - + Add to my Stations أضف إلى إذاعاتي - + &Export Playlist &تصدير قائمة الأغاني - + playlist قائمة الأغاني - + automatic playlist قائمة أغاني أوتوماتيكية - + station إذاعة - - Delete %1? - playlist/station/... - أحذف %1؟ - - - + Would you like to delete the %1 <b>"%2"</b>? e.g. Would you like to delete the playlist named Foobar? هل ترغب في حذف %1 <b>"%2"</b>؟ - + + Delete + + + + Save XSPF حفظ XSPF - + Playlists (*.xspf) قوائم أغاني (*.xspf) @@ -1671,14 +1670,9 @@ connect and stream from you? SpotifyPlaylistUpdater - - Delete in Spotify? - أحذف في سبوتيفي (Spotify)؟ - - - - Would you like to delete the corresponding Spotify playlist as well? - هل ترغب في حذف قائمة التشغيل المطابقة على سبوتيفي (Spotify)؟ + + Delete associated Spotify playlist? + @@ -2866,7 +2860,7 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::InfoSystem::NewReleasesPlugin - + Albums ألبومات @@ -2929,6 +2923,20 @@ Try tweaking the filters for a new set of songs to play. &استمع مع + + Tomahawk::Playlist + + + Would you like to delete the playlist <b>"%2"</b>? + e.g. Would you like to delete the playlist named Foobar? + + + + + Delete + + + Tomahawk::Query diff --git a/lang/tomahawk_bg.ts b/lang/tomahawk_bg.ts index 5500136e0..772ad2174 100644 --- a/lang/tomahawk_bg.ts +++ b/lang/tomahawk_bg.ts @@ -1476,69 +1476,68 @@ Tomahaw създаде доклад относно това и изпращай SourceTreeView - + &Copy Link &Копирай адресът - + &Delete %1 &Изтрий %1 - + Add to my Playlists Добави към моите списъци - + Add to my Automatic Playlists Добави към моите автоматично-генерирани списъци - + Add to my Stations Добави към станциите ми - + &Export Playlist &Изнеси списък - + playlist списък - + automatic playlist автоматично-генериран списък - + station станция - - Delete %1? - playlist/station/... - Изтрий %1? - - - + Would you like to delete the %1 <b>"%2"</b>? e.g. Would you like to delete the playlist named Foobar? Наистина ли желаеш да изтриеш %1 <b>''%2" </b> - + + Delete + + + + Save XSPF Запази XSPF - + Playlists (*.xspf) Списъци (*.xspf) @@ -1673,14 +1672,9 @@ Tomahaw създаде доклад относно това и изпращай SpotifyPlaylistUpdater - - Delete in Spotify? - Изтривам и в Spotify? - - - - Would you like to delete the corresponding Spotify playlist as well? - Желаеш ли да изтриеш и съответните Spotify списъци? + + Delete associated Spotify playlist? + @@ -2873,7 +2867,7 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::InfoSystem::NewReleasesPlugin - + Albums Албуми @@ -2936,6 +2930,20 @@ Try tweaking the filters for a new set of songs to play. &Слушай заедно + + Tomahawk::Playlist + + + Would you like to delete the playlist <b>"%2"</b>? + e.g. Would you like to delete the playlist named Foobar? + + + + + Delete + + + Tomahawk::Query diff --git a/lang/tomahawk_ca.ts b/lang/tomahawk_ca.ts index 05de21f0d..0bd5a1f9f 100644 --- a/lang/tomahawk_ca.ts +++ b/lang/tomahawk_ca.ts @@ -1473,69 +1473,68 @@ connect and stream from you? SourceTreeView - + &Copy Link &Copia l'Enllaç - + &Delete %1 &Esborra %1 - + Add to my Playlists Afegeix a les meves Llistes - + Add to my Automatic Playlists Afegeix a les meves Llistes Automàtiques - + Add to my Stations Afegeix a les meves Emissores - + &Export Playlist E&xporta la Llista de Reproducció - + playlist llista - + automatic playlist llista automàtica - + station emissora - - Delete %1? - playlist/station/... - Voleu esborrar %1? - - - + Would you like to delete the %1 <b>"%2"</b>? e.g. Would you like to delete the playlist named Foobar? Voleu esborrar %1 <b>"%2"</b>? - + + Delete + + + + Save XSPF Desa com XSPF - + Playlists (*.xspf) Llistes de reproducció (*.xspf) @@ -1669,14 +1668,9 @@ connect and stream from you? SpotifyPlaylistUpdater - - Delete in Spotify? - Voleu esborrar-ho de Spotify? - - - - Would you like to delete the corresponding Spotify playlist as well? - Voleu esborrar les llistes de Spotify, també? + + Delete associated Spotify playlist? + @@ -2865,7 +2859,7 @@ Intenteu ajustar els filtres per reproduir noves cançons. Tomahawk::InfoSystem::NewReleasesPlugin - + Albums Àlbums @@ -2928,6 +2922,20 @@ Intenteu ajustar els filtres per reproduir noves cançons. &Escolta a la vegada + + Tomahawk::Playlist + + + Would you like to delete the playlist <b>"%2"</b>? + e.g. Would you like to delete the playlist named Foobar? + + + + + Delete + + + Tomahawk::Query diff --git a/lang/tomahawk_de.ts b/lang/tomahawk_de.ts index e9ec8e41d..868b9f558 100644 --- a/lang/tomahawk_de.ts +++ b/lang/tomahawk_de.ts @@ -1474,69 +1474,68 @@ erlauben sich mit dir zu verbinden? SourceTreeView - + &Copy Link &Kopiere Link - + &Delete %1 &Lösche %1 - + Add to my Playlists Zu meinen Playlisten hinzufügen - + Add to my Automatic Playlists Zu meinen Automatischen Playlisten hinzufügen - + Add to my Stations Zu meinen Stationen hinzufügen - + &Export Playlist Playlist &exportieren - + playlist Playlist - + automatic playlist Automatische Playlist - + station Station - - Delete %1? - playlist/station/... - %1 löschen? - - - + Would you like to delete the %1 <b>"%2"</b>? e.g. Would you like to delete the playlist named Foobar? Möchtest du die %1 <b>"%2"</b> löschen? - + + Delete + + + + Save XSPF XSPF speichern - + Playlists (*.xspf) Playlisten (*.xspf) @@ -1670,14 +1669,9 @@ erlauben sich mit dir zu verbinden? SpotifyPlaylistUpdater - - Delete in Spotify? - Auf Spotify löschen - - - - Would you like to delete the corresponding Spotify playlist as well? - Möchtest du die entsprechende Spotify Playlist auch löschen? + + Delete associated Spotify playlist? + @@ -2861,7 +2855,7 @@ Versuch die Filter anzupassen für neue Lieder. Tomahawk::InfoSystem::NewReleasesPlugin - + Albums Alben @@ -2924,6 +2918,20 @@ Versuch die Filter anzupassen für neue Lieder. &Mithören + + Tomahawk::Playlist + + + Would you like to delete the playlist <b>"%2"</b>? + e.g. Would you like to delete the playlist named Foobar? + + + + + Delete + + + Tomahawk::Query diff --git a/lang/tomahawk_en.ts b/lang/tomahawk_en.ts index 3457068fc..a2de16985 100644 --- a/lang/tomahawk_en.ts +++ b/lang/tomahawk_en.ts @@ -1474,69 +1474,68 @@ connect and stream from you? SourceTreeView - + &Copy Link &Copy Link - + &Delete %1 &Delete %1 - + Add to my Playlists Add to my Playlists - + Add to my Automatic Playlists Add to my Automatic Playlists - + Add to my Stations Add to my Stations - + &Export Playlist &Export Playlist - + playlist playlist - + automatic playlist automatic playlist - + station station - - Delete %1? - playlist/station/... - Delete %1? - - - + Would you like to delete the %1 <b>"%2"</b>? e.g. Would you like to delete the playlist named Foobar? Would you like to delete the %1 <b>"%2"</b>? - + + Delete + Delete + + + Save XSPF Save XSPF - + Playlists (*.xspf) Playlists (*.xspf) @@ -1670,14 +1669,9 @@ connect and stream from you? SpotifyPlaylistUpdater - - Delete in Spotify? - Delete in Spotify? - - - - Would you like to delete the corresponding Spotify playlist as well? - Would you like to delete the corresponding Spotify playlist as well? + + Delete associated Spotify playlist? + Delete associated Spotify playlist? @@ -2866,7 +2860,7 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::InfoSystem::NewReleasesPlugin - + Albums Albums @@ -2929,6 +2923,20 @@ Try tweaking the filters for a new set of songs to play. &Listen Along + + Tomahawk::Playlist + + + Would you like to delete the playlist <b>"%2"</b>? + e.g. Would you like to delete the playlist named Foobar? + Would you like to delete the playlist <b>"%2"</b>? + + + + Delete + Delete + + Tomahawk::Query diff --git a/lang/tomahawk_es.ts b/lang/tomahawk_es.ts index d06be4a8e..260fbe71c 100644 --- a/lang/tomahawk_es.ts +++ b/lang/tomahawk_es.ts @@ -1472,69 +1472,68 @@ connect and stream from you? SourceTreeView - + &Copy Link &Copiar enlace - + &Delete %1 &Eliminar %1 - + Add to my Playlists - + Add to my Automatic Playlists - + Add to my Stations - + &Export Playlist &Exportar lista de reproducción - + playlist - + automatic playlist - + station - - Delete %1? - playlist/station/... - - - - + Would you like to delete the %1 <b>"%2"</b>? e.g. Would you like to delete the playlist named Foobar? - + + Delete + + + + Save XSPF Guardar XSPF - + Playlists (*.xspf) Listas de reproducción (*.xspf) @@ -1668,14 +1667,9 @@ connect and stream from you? SpotifyPlaylistUpdater - - Delete in Spotify? - ¿Borrar en Spotify? - - - - Would you like to delete the corresponding Spotify playlist as well? - Quieres eliminar la lista de Spotify correspondiente, también? + + Delete associated Spotify playlist? + @@ -2864,7 +2858,7 @@ Intente ajustar los filtros para reproducir nuevas canciones. Tomahawk::InfoSystem::NewReleasesPlugin - + Albums Álbumes @@ -2927,6 +2921,20 @@ Intente ajustar los filtros para reproducir nuevas canciones. &Escuchar juntos + + Tomahawk::Playlist + + + Would you like to delete the playlist <b>"%2"</b>? + e.g. Would you like to delete the playlist named Foobar? + + + + + Delete + + + Tomahawk::Query diff --git a/lang/tomahawk_fr.ts b/lang/tomahawk_fr.ts index af971e93c..a15482b9b 100644 --- a/lang/tomahawk_fr.ts +++ b/lang/tomahawk_fr.ts @@ -1474,69 +1474,68 @@ de se connecter et streamer de vous? SourceTreeView - + &Copy Link &Copier le lien - + &Delete %1 &Supprimer %1 - + Add to my Playlists Ajoute a mes listes de lecture - + Add to my Automatic Playlists Ajoute a mes listes de lecture automatique - + Add to my Stations Ajouter à mes stations - + &Export Playlist &Exporter la liste de lecture - + playlist liste de lecture - + automatic playlist liste de lecture automatique - + station station - - Delete %1? - playlist/station/... - Supprimer %1? - - - + Would you like to delete the %1 <b>"%2"</b>? e.g. Would you like to delete the playlist named Foobar? Voulez-vous supprimer la %1 <b>"%2"</b>? - + + Delete + + + + Save XSPF Enregistrer XSPF - + Playlists (*.xspf) Listes de lecture (*.xspf) @@ -1670,14 +1669,9 @@ de se connecter et streamer de vous? SpotifyPlaylistUpdater - - Delete in Spotify? - Supprimer dans Spotify ? - - - - Would you like to delete the corresponding Spotify playlist as well? - Voulez-vous aussi supprimer la liste de lecture correspondante dans Spotify ? + + Delete associated Spotify playlist? + @@ -2866,7 +2860,7 @@ Essayez de changer les filtres pour avoir de nouveaux morceaux à jouer. Tomahawk::InfoSystem::NewReleasesPlugin - + Albums Albums @@ -2929,6 +2923,20 @@ Essayez de changer les filtres pour avoir de nouveaux morceaux à jouer.&Ecouter avec + + Tomahawk::Playlist + + + Would you like to delete the playlist <b>"%2"</b>? + e.g. Would you like to delete the playlist named Foobar? + + + + + Delete + + + Tomahawk::Query diff --git a/lang/tomahawk_ja.ts b/lang/tomahawk_ja.ts index edfa8d158..ba4772ec2 100644 --- a/lang/tomahawk_ja.ts +++ b/lang/tomahawk_ja.ts @@ -1474,69 +1474,68 @@ connect and stream from you? SourceTreeView - + &Copy Link リンクをコピー - + &Delete %1 %1を削除 - + Add to my Playlists プレイリストに追加する - + Add to my Automatic Playlists 自動プレイリストに追加する - + Add to my Stations ステーションに追加する - + &Export Playlist プレイリストを書き出し - + playlist プレイリスト - + automatic playlist 自動プレイリスト - + station ステーション - - Delete %1? - playlist/station/... - %1を削除しますか? - - - + Would you like to delete the %1 <b>"%2"</b>? e.g. Would you like to delete the playlist named Foobar? <b>"%2"</b>と言う%1を削除しますか? - + + Delete + + + + Save XSPF XSPFを保存する - + Playlists (*.xspf) プレイリスト (*.xspf) @@ -1670,14 +1669,9 @@ connect and stream from you? SpotifyPlaylistUpdater - - Delete in Spotify? - Spotifyにも削除しますか? - - - - Would you like to delete the corresponding Spotify playlist as well? - 同期のSpotifyのプレイリストも削除してもよろしいですか? + + Delete associated Spotify playlist? + @@ -2856,7 +2850,7 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::InfoSystem::NewReleasesPlugin - + Albums アルバム @@ -2919,6 +2913,20 @@ Try tweaking the filters for a new set of songs to play. + + Tomahawk::Playlist + + + Would you like to delete the playlist <b>"%2"</b>? + e.g. Would you like to delete the playlist named Foobar? + + + + + Delete + + + Tomahawk::Query diff --git a/lang/tomahawk_pl.ts b/lang/tomahawk_pl.ts index e80843f1f..acbf13124 100644 --- a/lang/tomahawk_pl.ts +++ b/lang/tomahawk_pl.ts @@ -1472,69 +1472,68 @@ connect and stream from you? SourceTreeView - + &Copy Link &Kopiuj Link - + &Delete %1 &Usuń %1 - + Add to my Playlists - + Add to my Automatic Playlists - + Add to my Stations - + &Export Playlist &Eksportuj Listę - + playlist - + automatic playlist - + station - - Delete %1? - playlist/station/... - - - - + Would you like to delete the %1 <b>"%2"</b>? e.g. Would you like to delete the playlist named Foobar? - + + Delete + + + + Save XSPF Zapisz XSPF - + Playlists (*.xspf) Listy (*.xspf) @@ -1668,13 +1667,8 @@ connect and stream from you? SpotifyPlaylistUpdater - - Delete in Spotify? - - - - - Would you like to delete the corresponding Spotify playlist as well? + + Delete associated Spotify playlist? @@ -2860,7 +2854,7 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::InfoSystem::NewReleasesPlugin - + Albums Albumy @@ -2923,6 +2917,20 @@ Try tweaking the filters for a new set of songs to play. &Słuchaj razem + + Tomahawk::Playlist + + + Would you like to delete the playlist <b>"%2"</b>? + e.g. Would you like to delete the playlist named Foobar? + + + + + Delete + + + Tomahawk::Query diff --git a/lang/tomahawk_pt_BR.ts b/lang/tomahawk_pt_BR.ts index fe9bede88..3e356d862 100644 --- a/lang/tomahawk_pt_BR.ts +++ b/lang/tomahawk_pt_BR.ts @@ -1474,69 +1474,68 @@ se conecte e faça o stream de você? SourceTreeView - + &Copy Link &Copiar link - + &Delete %1 &Excluir %1 - + Add to my Playlists Adicionar às minhas Playlists - + Add to my Automatic Playlists Adicionar às minhas Playlists Automáticas - + Add to my Stations Adicionar às minhas Estações - + &Export Playlist &Exportar Playlist - + playlist playlist - + automatic playlist playlist automática - + station estação - - Delete %1? - playlist/station/... - Deletar %1? - - - + Would you like to delete the %1 <b>"%2"</b>? e.g. Would you like to delete the playlist named Foobar? Gostaria de deletar a %1 <b>"%2"</b>? - + + Delete + + + + Save XSPF Salvar XSPF - + Playlists (*.xspf) Playlists (*.xspf) @@ -1670,14 +1669,9 @@ se conecte e faça o stream de você? SpotifyPlaylistUpdater - - Delete in Spotify? - Deletar no Spotify? - - - - Would you like to delete the corresponding Spotify playlist as well? - Você também gostaria de deletar a playlist correspondente no Spotify? + + Delete associated Spotify playlist? + @@ -2866,7 +2860,7 @@ Tente ajustar os filtros para ouvir um novo conjunto de músicas. Tomahawk::InfoSystem::NewReleasesPlugin - + Albums Álbuns @@ -2929,6 +2923,20 @@ Tente ajustar os filtros para ouvir um novo conjunto de músicas. &Ouvir Junto + + Tomahawk::Playlist + + + Would you like to delete the playlist <b>"%2"</b>? + e.g. Would you like to delete the playlist named Foobar? + + + + + Delete + + + Tomahawk::Query diff --git a/lang/tomahawk_ru.ts b/lang/tomahawk_ru.ts index ded4a11aa..18919260e 100644 --- a/lang/tomahawk_ru.ts +++ b/lang/tomahawk_ru.ts @@ -1474,69 +1474,68 @@ connect and stream from you? SourceTreeView - + &Copy Link &Скопировать Cсылку - + &Delete %1 &Удалить %1 - + Add to my Playlists Добавить к моим Плейлистам - + Add to my Automatic Playlists Добавить к моим Автоматическим Плейлистам - + Add to my Stations Добавить к моим Станциям - + &Export Playlist &Экспорт Плейлиста - + playlist плейлист - + automatic playlist автоматический плейлист - + station станция - - Delete %1? - playlist/station/... - Удалить %1? - - - + Would you like to delete the %1 <b>"%2"</b>? e.g. Would you like to delete the playlist named Foobar? Вы хотите удалить %1 <b>"%2"</b>? - + + Delete + + + + Save XSPF Сохранить XSPF - + Playlists (*.xspf) Плейлисты (*.xspf) @@ -1670,13 +1669,8 @@ connect and stream from you? SpotifyPlaylistUpdater - - Delete in Spotify? - Удалить в Spotify? - - - - Would you like to delete the corresponding Spotify playlist as well? + + Delete associated Spotify playlist? @@ -2861,7 +2855,7 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::InfoSystem::NewReleasesPlugin - + Albums Альбом @@ -2924,6 +2918,20 @@ Try tweaking the filters for a new set of songs to play. &Слушать Его + + Tomahawk::Playlist + + + Would you like to delete the playlist <b>"%2"</b>? + e.g. Would you like to delete the playlist named Foobar? + + + + + Delete + + + Tomahawk::Query diff --git a/lang/tomahawk_sv.ts b/lang/tomahawk_sv.ts index 353b59b35..0b343e9b3 100644 --- a/lang/tomahawk_sv.ts +++ b/lang/tomahawk_sv.ts @@ -1473,69 +1473,68 @@ connect and stream from you? SourceTreeView - + &Copy Link &Kopiera länk - + &Delete %1 &Ta bort %1 - + Add to my Playlists - + Add to my Automatic Playlists - + Add to my Stations - + &Export Playlist &Exportera spellista - + playlist - + automatic playlist - + station - - Delete %1? - playlist/station/... - - - - + Would you like to delete the %1 <b>"%2"</b>? e.g. Would you like to delete the playlist named Foobar? - + + Delete + + + + Save XSPF Spara XSPF - + Playlists (*.xspf) Spellistor (*.xspf) @@ -1669,13 +1668,8 @@ connect and stream from you? SpotifyPlaylistUpdater - - Delete in Spotify? - - - - - Would you like to delete the corresponding Spotify playlist as well? + + Delete associated Spotify playlist? @@ -2855,7 +2849,7 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::InfoSystem::NewReleasesPlugin - + Albums @@ -2918,6 +2912,20 @@ Try tweaking the filters for a new set of songs to play. + + Tomahawk::Playlist + + + Would you like to delete the playlist <b>"%2"</b>? + e.g. Would you like to delete the playlist named Foobar? + + + + + Delete + + + Tomahawk::Query diff --git a/lang/tomahawk_tr.ts b/lang/tomahawk_tr.ts index afa004bc8..ea45836df 100644 --- a/lang/tomahawk_tr.ts +++ b/lang/tomahawk_tr.ts @@ -1472,69 +1472,68 @@ connect and stream from you? SourceTreeView - + &Copy Link - + &Delete %1 - + Add to my Playlists - + Add to my Automatic Playlists - + Add to my Stations - + &Export Playlist - + playlist - + automatic playlist - + station - - Delete %1? - playlist/station/... - - - - + Would you like to delete the %1 <b>"%2"</b>? e.g. Would you like to delete the playlist named Foobar? - + + Delete + + + + Save XSPF - + Playlists (*.xspf) @@ -1668,13 +1667,8 @@ connect and stream from you? SpotifyPlaylistUpdater - - Delete in Spotify? - - - - - Would you like to delete the corresponding Spotify playlist as well? + + Delete associated Spotify playlist? @@ -2854,7 +2848,7 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::InfoSystem::NewReleasesPlugin - + Albums @@ -2917,6 +2911,20 @@ Try tweaking the filters for a new set of songs to play. + + Tomahawk::Playlist + + + Would you like to delete the playlist <b>"%2"</b>? + e.g. Would you like to delete the playlist named Foobar? + + + + + Delete + + + Tomahawk::Query diff --git a/lang/tomahawk_zh_CN.ts b/lang/tomahawk_zh_CN.ts index b0051ca20..a6cd7e81a 100644 --- a/lang/tomahawk_zh_CN.ts +++ b/lang/tomahawk_zh_CN.ts @@ -1472,69 +1472,68 @@ connect and stream from you? SourceTreeView - + &Copy Link - + &Delete %1 - + Add to my Playlists - + Add to my Automatic Playlists - + Add to my Stations - + &Export Playlist - + playlist - + automatic playlist - + station - - Delete %1? - playlist/station/... - - - - + Would you like to delete the %1 <b>"%2"</b>? e.g. Would you like to delete the playlist named Foobar? - + + Delete + + + + Save XSPF - + Playlists (*.xspf) @@ -1668,13 +1667,8 @@ connect and stream from you? SpotifyPlaylistUpdater - - Delete in Spotify? - - - - - Would you like to delete the corresponding Spotify playlist as well? + + Delete associated Spotify playlist? @@ -2854,7 +2848,7 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::InfoSystem::NewReleasesPlugin - + Albums @@ -2917,6 +2911,20 @@ Try tweaking the filters for a new set of songs to play. + + Tomahawk::Playlist + + + Would you like to delete the playlist <b>"%2"</b>? + e.g. Would you like to delete the playlist named Foobar? + + + + + Delete + + + Tomahawk::Query diff --git a/lang/tomahawk_zh_TW.ts b/lang/tomahawk_zh_TW.ts index 36feb381b..9b2dabb5c 100644 --- a/lang/tomahawk_zh_TW.ts +++ b/lang/tomahawk_zh_TW.ts @@ -1472,69 +1472,68 @@ connect and stream from you? SourceTreeView - + &Copy Link 複製鏈接 - + &Delete %1 - + Add to my Playlists - + Add to my Automatic Playlists - + Add to my Stations - + &Export Playlist 匯出播放清單 - + playlist - + automatic playlist - + station - - Delete %1? - playlist/station/... - - - - + Would you like to delete the %1 <b>"%2"</b>? e.g. Would you like to delete the playlist named Foobar? - + + Delete + + + + Save XSPF 儲存 XSPF - + Playlists (*.xspf) 播放清單(*.xspf) @@ -1668,13 +1667,8 @@ connect and stream from you? SpotifyPlaylistUpdater - - Delete in Spotify? - - - - - Would you like to delete the corresponding Spotify playlist as well? + + Delete associated Spotify playlist? @@ -2854,7 +2848,7 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::InfoSystem::NewReleasesPlugin - + Albums 專輯 @@ -2917,6 +2911,20 @@ Try tweaking the filters for a new set of songs to play. + + Tomahawk::Playlist + + + Would you like to delete the playlist <b>"%2"</b>? + e.g. Would you like to delete the playlist named Foobar? + + + + + Delete + + + Tomahawk::Query From d2ed4aeaf8129092e90cd24ebf3b0fd0a95e6335 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Fri, 27 Jul 2012 18:53:37 -0400 Subject: [PATCH 38/79] TWK-1009: Save spotify id from dragging in playlists to tracks --- src/libtomahawk/Playlist.cpp | 5 +---- src/libtomahawk/utils/SpotifyParser.cpp | 9 +++++++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/libtomahawk/Playlist.cpp b/src/libtomahawk/Playlist.cpp index 3e21c36b5..8966f8484 100644 --- a/src/libtomahawk/Playlist.cpp +++ b/src/libtomahawk/Playlist.cpp @@ -181,10 +181,7 @@ Playlist::create( const source_ptr& author, p->setGuid( uuid() ); p->setDuration( query->duration() ); p->setLastmodified( 0 ); - QString annotation = ""; - if ( !query->property( "annotation" ).toString().isEmpty() ) - annotation = query->property( "annotation" ).toString(); - p->setAnnotation( annotation ); + p->setAnnotation( query->property( "annotation" ).toString() ); p->setQuery( query ); entries << p; diff --git a/src/libtomahawk/utils/SpotifyParser.cpp b/src/libtomahawk/utils/SpotifyParser.cpp index ce2ecc682..48de033d6 100644 --- a/src/libtomahawk/utils/SpotifyParser.cpp +++ b/src/libtomahawk/utils/SpotifyParser.cpp @@ -237,6 +237,7 @@ SpotifyParser::spotifyBrowseFinished() tLog() << "Setting resulthint to " << trackResult.value( "trackuri" ); q->setResultHint( trackResult.value( "trackuri" ).toString() ); + q->setProperty( "annotation", trackResult.value( "trackuri" ).toString() ); m_tracks << q; } @@ -337,8 +338,12 @@ SpotifyParser::playlistListingResult( const QString& msgType, const QVariantMap& if ( q.isNull() ) continue; - if( !trackMap.value( "id" ).toString().isEmpty() ) - q->setResultHint( trackMap.value( "id" ).toString() ); + const QString id = trackMap.value( "id" ).toString(); + if( !id.isEmpty() ) + { + q->setResultHint( id ); + q->setProperty( "annotation", id ); + } m_tracks << q; } From d32307ca0f3ebded257b4db99a9c8fca5578c527 Mon Sep 17 00:00:00 2001 From: Tomahawk CI Date: Sat, 28 Jul 2012 22:16:57 +0000 Subject: [PATCH 39/79] Automatic merge of Transifex translations --- lang/tomahawk_ar.ts | 6 +- lang/tomahawk_bg.ts | 6 +- lang/tomahawk_ca.ts | 6 +- lang/tomahawk_de.ts | 6 +- lang/tomahawk_en.ts | 6 +- lang/tomahawk_es.ts | 6 +- lang/tomahawk_fr.ts | 6 +- lang/tomahawk_ja.ts | 6 +- lang/tomahawk_lt.ts | 4076 ++++++++++++++++++++++++++++++++++++++++ lang/tomahawk_pl.ts | 6 +- lang/tomahawk_pt_BR.ts | 6 +- lang/tomahawk_ru.ts | 6 +- lang/tomahawk_sv.ts | 6 +- lang/tomahawk_tr.ts | 6 +- lang/tomahawk_zh_CN.ts | 6 +- lang/tomahawk_zh_TW.ts | 6 +- 16 files changed, 4121 insertions(+), 45 deletions(-) create mode 100644 lang/tomahawk_lt.ts diff --git a/lang/tomahawk_ar.ts b/lang/tomahawk_ar.ts index 3bf6b38b0..5d6cf5f7b 100644 --- a/lang/tomahawk_ar.ts +++ b/lang/tomahawk_ar.ts @@ -2926,13 +2926,13 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::Playlist - + Would you like to delete the playlist <b>"%2"</b>? e.g. Would you like to delete the playlist named Foobar? - + Delete @@ -3038,7 +3038,7 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::SpotifyParser - + Error fetching Spotify information from the network! مشكلة في جلب معلومات "Spotify" من الشبكة! diff --git a/lang/tomahawk_bg.ts b/lang/tomahawk_bg.ts index 772ad2174..4ea9d5474 100644 --- a/lang/tomahawk_bg.ts +++ b/lang/tomahawk_bg.ts @@ -2933,13 +2933,13 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::Playlist - + Would you like to delete the playlist <b>"%2"</b>? e.g. Would you like to delete the playlist named Foobar? - + Delete @@ -3045,7 +3045,7 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::SpotifyParser - + Error fetching Spotify information from the network! Грешка при извличане на информация от Spotify diff --git a/lang/tomahawk_ca.ts b/lang/tomahawk_ca.ts index 0bd5a1f9f..0bc9cb7a3 100644 --- a/lang/tomahawk_ca.ts +++ b/lang/tomahawk_ca.ts @@ -2925,13 +2925,13 @@ Intenteu ajustar els filtres per reproduir noves cançons. Tomahawk::Playlist - + Would you like to delete the playlist <b>"%2"</b>? e.g. Would you like to delete the playlist named Foobar? - + Delete @@ -3037,7 +3037,7 @@ Intenteu ajustar els filtres per reproduir noves cançons. Tomahawk::SpotifyParser - + Error fetching Spotify information from the network! Error en cercar la informació de Spotify a través de la xarxa! diff --git a/lang/tomahawk_de.ts b/lang/tomahawk_de.ts index 868b9f558..74b595131 100644 --- a/lang/tomahawk_de.ts +++ b/lang/tomahawk_de.ts @@ -2921,13 +2921,13 @@ Versuch die Filter anzupassen für neue Lieder. Tomahawk::Playlist - + Would you like to delete the playlist <b>"%2"</b>? e.g. Would you like to delete the playlist named Foobar? - + Delete @@ -3033,7 +3033,7 @@ Versuch die Filter anzupassen für neue Lieder. Tomahawk::SpotifyParser - + Error fetching Spotify information from the network! Konnte Spotify-Daten nicht laden! diff --git a/lang/tomahawk_en.ts b/lang/tomahawk_en.ts index a2de16985..8686aeb57 100644 --- a/lang/tomahawk_en.ts +++ b/lang/tomahawk_en.ts @@ -2926,13 +2926,13 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::Playlist - + Would you like to delete the playlist <b>"%2"</b>? e.g. Would you like to delete the playlist named Foobar? Would you like to delete the playlist <b>"%2"</b>? - + Delete Delete @@ -3038,7 +3038,7 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::SpotifyParser - + Error fetching Spotify information from the network! Error fetching Spotify information from the network! diff --git a/lang/tomahawk_es.ts b/lang/tomahawk_es.ts index 260fbe71c..a3f14ea62 100644 --- a/lang/tomahawk_es.ts +++ b/lang/tomahawk_es.ts @@ -2924,13 +2924,13 @@ Intente ajustar los filtros para reproducir nuevas canciones. Tomahawk::Playlist - + Would you like to delete the playlist <b>"%2"</b>? e.g. Would you like to delete the playlist named Foobar? - + Delete @@ -3036,7 +3036,7 @@ Intente ajustar los filtros para reproducir nuevas canciones. Tomahawk::SpotifyParser - + Error fetching Spotify information from the network! Error al buscar la información de Spotify en la red! diff --git a/lang/tomahawk_fr.ts b/lang/tomahawk_fr.ts index a15482b9b..52f32c29d 100644 --- a/lang/tomahawk_fr.ts +++ b/lang/tomahawk_fr.ts @@ -2926,13 +2926,13 @@ Essayez de changer les filtres pour avoir de nouveaux morceaux à jouer. Tomahawk::Playlist - + Would you like to delete the playlist <b>"%2"</b>? e.g. Would you like to delete the playlist named Foobar? - + Delete @@ -3038,7 +3038,7 @@ Essayez de changer les filtres pour avoir de nouveaux morceaux à jouer. Tomahawk::SpotifyParser - + Error fetching Spotify information from the network! Échec du chargement des informations Spotify depuis le réseau! diff --git a/lang/tomahawk_ja.ts b/lang/tomahawk_ja.ts index ba4772ec2..0bb52b517 100644 --- a/lang/tomahawk_ja.ts +++ b/lang/tomahawk_ja.ts @@ -2916,13 +2916,13 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::Playlist - + Would you like to delete the playlist <b>"%2"</b>? e.g. Would you like to delete the playlist named Foobar? - + Delete @@ -3028,7 +3028,7 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::SpotifyParser - + Error fetching Spotify information from the network! diff --git a/lang/tomahawk_lt.ts b/lang/tomahawk_lt.ts new file mode 100644 index 000000000..e085422de --- /dev/null +++ b/lang/tomahawk_lt.ts @@ -0,0 +1,4076 @@ + + + ACLJobDelegate + + + Allow %1 to +connect and stream from you? + + + + + Allow Streaming + + + + + Deny Access + + + + + ACLJobItem + + + Tomahawk needs you to decide whether %1 is allowed to connect. + + + + + AccountFactoryWrapper + + + Dialog + + + + + Description goes here + + + + + Add Account + Pridėti paskyrą + + + + AccountFactoryWrapperDelegate + + + Online + Prisijungęs + + + + Connecting... + Jungiamasi... + + + + Offline + Atsijungęs + + + + ActionCollection + + + &Listen Along + K&lausytis kartu + + + + Stop &Listening Along + + + + + &Follow in real-time + + + + + + &Listen Privately + K&lausytis privačiai + + + + + &Listen Publicly + K&lausytis viešai + + + + &Load Playlist + Įke&lti grojaraštį + + + + &Rename Playlist + Per&vadinti grojaraštį + + + + &Copy Playlist Link + + + + + &Play + &Groti + + + + &Stop + &Sustabdyti + + + + &Previous Track + Ankstesnis takelis + + + + &Next Track + Kitas takelis + + + + &Quit + &Baigti darbą + + + + AlbumInfoWidget + + + Form + + + + + Other Albums by Artist + Kiti atlikėjo albumai + + + + Sorry, we could not find any other albums for this artist! + + + + + Sorry, we could not find any tracks for this album! + + + + + Other Albums by %1 + Kiti %1 albumai + + + + AlbumModel + + + + All albums from %1 + Visi %1 albumai + + + + All albums + Visi albumai + + + + ArtistInfoWidget + + + Form + + + + + Top Hits + + + + + Related Artists + + + + + Artist + + + + + Albums + Albumai + + + + Cover + + + + + Sorry, we could not find any albums for this artist! + + + + + Sorry, we could not find any related artists! + + + + + Sorry, we could not find any top hits for this artist! + + + + + AudioControls + + + Prev + Ankstesnis + + + + Play + Groti + + + + Pause + Pristabdyti + + + + Next + Kitas + + + + Artist + Atlikėjas + + + + Album + Albumas + + + + Owner + Savininkas + + + + social + + + + + love + + + + + Time + + + + + Time Left + + + + + Shuffle + Maišyti + + + + Repeat + Kartoti + + + + Low + + + + + High + + + + + AudioEngine + + + Sorry, Tomahawk couldn't find the track '%1' by %2 + + + + + Sorry, Tomahawk couldn't find the artist '%1' + + + + + Sorry, Tomahawk couldn't find the album '%1' by %2 + + + + + CategoryAddItem + + + Create new Playlist + + + + + Create new Station + + + + + + New Station + Nauja stotis + + + + + %1 Station + + + + + CategoryItem + + + Playlists + Grojaraščiai + + + + Stations + Stotys + + + + ClearButton + + + Clear + Valyti + + + + ContextWidget + + + InfoBar + + + + + + Show Footnotes + + + + + Hide Footnotes + + + + + CrashReporter + + + Tomahawk Crash Reporter + + + + + <html><head/><body><p><span style=" font-weight:600;">Sorry!</span> Tomahawk crashed. Please tell us about it! Tomahawk has created an error report for you that can help improve the stability in the future. You can now send this report directly to the Tomahawk developers.</p></body></html> + + + + + Send this report + + + + + Don't send + + + + + Abort + + + + + You can disable sending crash reports in the configuration dialog. + + + + + Uploaded %L1 of %L2 KB. + + + + + + Close + Užverti + + + + Sent! <b>Many thanks</b>. + Išsiųsta! <b>Labai ačiū</b>. + + + + Failed to send crash info. + + + + + DatabaseCommand_AllAlbums + + + Unknown + + + + + DelegateConfigWrapper + + + About + Apie + + + + Delete Account + Pašalinti paskyrą + + + + About this Account + Apie šią paskyrą + + + + DiagnosticsDialog + + + Tomahawk Diagnostics + + + + + &Copy to Clipboard + + + + + Open &Log-file + + + + + FlexibleHeader + + + Filter... + + + + + GlobalSearchWidget + + + Form + + + + + IndexingJobItem + + + Indexing database + + + + + InfoBar + + + InfoBar + + + + + Filter... + + + + + LastFmConfig + + + Form + + + + + Scrobble tracks to Last.fm + + + + + Username: + Vartotojo vardas: + + + + Password: + Slaptažodis: + + + + Test Login + Išbandyti prisijungimą + + + + Import Playback History + + + + + LastfmContext + + + Last.fm + Last.fm + + + + LatchedStatusItem + + + %1 is listening along with you! + + + + + LoadXSPF + + + Load XSPF + Įkelti XSPF + + + + Playlist URL + Grojaraščio URL + + + + Enter URL... + Įveskite URL... + + + + ... + ... + + + + Automatically update + Atnaujinti automatiškai + + + + LoadXSPFDialog + + + Load XSPF File + Įkelti XSPF failą + + + + XSPF Files (*.xspf) + XSPF failai (*.xspf) + + + + LocalCollection + + + Bookmarks + + + + + Saved tracks + Išsaugoti takeliai + + + + LovedTracksItem + + + Top Loved Tracks + + + + + Sorry, we could not find any loved tracks! + + + + + The most loved tracks from all your friends + + + + + All of your loved tracks + + + + + All of %1's loved tracks + + + + + Loved Tracks + + + + + MetadataEditor + + + Form + + + + + Tags + + + + + Title: + + + + + Title... + + + + + Artist: + Atlikėjas: + + + + Artist... + + + + + Album: + Albumas: + + + + Album... + + + + + Disc Number: + + + + + Duration: + + + + + 00.00 + + + + + Year: + Metai: + + + + Bitrate: + + + + + File + Failas + + + + File Name: + Failo vardas: + + + + File Name... + + + + + File Size... + + + + + File size... + + + + + File Size: + + + + + Back + Atgal + + + + Forward + Pirmyn + + + + - Properties + + + + + NewPlaylistWidget + + + Enter a title for the new playlist: + Įveskite naujojo grojaraščio pavadinimą: + + + + Tomahawk offers a variety of ways to help you create playlists and find music you enjoy! + + + + + Just enter a genre or tag name and Tomahawk will suggest a few songs to get you started with your new playlist: + + + + + &Create Playlist + Su&kurti grojaraštį + + + + Create a new playlist + Sukurti naują grojaraštį + + + + NewReleasesWidget + + + New Releases + + + + + PlayableModel + + + Artist + + + + + Title + + + + + Composer + + + + + Album + + + + + Track + + + + + Duration + + + + + Bitrate + + + + + Age + + + + + Year + + + + + Size + + + + + Origin + + + + + Score + + + + + + Name + + + + + PlaylistHeader + + + InfoBar + + + + + Caption + + + + + Description + + + + + + + RadioButton + + + + + PlaylistItemDelegate + + + played %1 by you + + + + + played %1 by %2 + + + + + PlaylistLargeItemDelegate + + + played %1 by you + + + + + played %1 by %2 + + + + + added %1 + + + + + PlaylistModel + + + A playlist by %1, created %2 + + + + + you + + + + + All tracks by %1 on album %2 + Visi %1 takeliai iš albumo %2 + + + + All tracks by %1 + Visi %1 takeliai + + + + PlaylistTypeSelectorDlg + + + New Playlist + Naujas grojaraštis + + + + Just a regular old playlist... Give it a name, drag in some tracks, and go! + + + + + Don't know exactly what you want? Give Tomahawk a few pointers and let it build a playlist for you! + + + + + Name: + Vardas: + + + + New Playlist... + Naujas grojaraštis... + + + + Create Manual Playlist + + + + + Create Automatic Playlist + + + + + PlaylistView + + + This playlist is currently empty. + + + + + This playlist is currently empty. Add some tracks to it and enjoy the music! + + + + + ProxyDialog + + + Proxy Settings + + + + + Hostname of proxy server + + + + + Host + Serveris + + + + Port + Prievadas + + + + Proxy login + Proxy prisijungimas + + + + User + Vartotojas + + + + Password + Slaptažodis + + + + Proxy password + Proxy slaptažodis + + + + No Proxy Hosts: +(Overrides system proxy) + + + + + localhost *.example.com (space separated) + + + + + Use proxy for DNS lookups? + + + + + QObject + + + %n year(s) ago + + + + + %n year(s) + + + + + %n month(s) ago + + + + + %n month(s) + + + + + %n week(s) ago + + + + + %n week(s) + + + + + %n day(s) ago + + + + + %n day(s) + + + + + %n hour(s) ago + + + + + %n hour(s) + + + + + %1 minutes ago + + + + + %1 minutes + + + + + just now + ką tik + + + + Friend Finders + + + + + Music Finders + + + + + Status Updaters + + + + + QuaZipFilePrivate + + + ZIP/UNZIP API error %1 + + + + + QueueView + + + InfoBar + + + + + + Open Queue + + + + + Open Queue - %n item(s) + + + + + Close Queue + + + + + RelatedArtistsContext + + + Related Artists + + + + + ResolverConfigDelegate + + + Not found: %1 + Nerasta: %1 + + + + Failed to load: %1 + Nepavyko įkelti: %1 + + + + SearchLineEdit + + + Search + + + + + SearchWidget + + + Search: %1 + + + + + Results for '%1' + + + + + SettingsDialog + + + Collection + Kolekcija + + + + Advanced + Išplėstinės + + + + All + Visi + + + + Some changed settings will not take effect until Tomahawk is restarted + + + + + Services + Paslaugos + + + + Install resolver from file + + + + + Delete all Access Control entries? + + + + + Do you really want to delete all Access Control entries? You will be asked for a decision again for each peer that you connect to. + + + + + Information + + + + + SocialPlaylistWidget + + + Popular New Albums From Your Friends + + + + + Most Played Playlists + + + + + Most Played Tracks You Don't Have + + + + + SocialWidget + + + Form + + + + + Facebook + + + + + Twitter + + + + + Cover + + + + + TextLabel + + + + + Tweet + + + + + Listening to "%1" by %2. %3 + + + + + Listening to "%1" by %2 on "%3". %4 + + + + + %1 characters left + + + + + SourceDelegate + + + Track + Takelis + + + + Album + Albumas + + + + Artist + Atlikėjas + + + + Local + + + + + Top 10 + Top 10 + + + + All available tracks + Visi prieinami takeliai + + + + + Show + Rodyti + + + + + Hide + Slėpti + + + + SourceInfoWidget + + + Recent Albums + + + + + Latest Additions + Naujai pridėta + + + + Recently Played Tracks + Neseniai klausyti takeliai + + + + New Additions + + + + + My recent activity + Paskiausia mano veikla + + + + Recent activity from %1 + + + + + SourceItem + + + Collection + Kolekcija + + + + + Latest Additions + + + + + Recently Played + Neseniai grota + + + + SuperCollection + Super Kolekcija + + + + Latest additions to your collection + + + + + Latest additions to %1's collection + + + + + Sorry, we could not find any recent additions! + + + + + Recently Played Tracks + + + + + Your recently played tracks + + + + + %1's recently played tracks + + + + + Sorry, we could not find any recent plays! + + + + + SourceTreeView + + + &Copy Link + &Kopijuoti nuorodą + + + + &Delete %1 + + + + + Add to my Playlists + + + + + Add to my Automatic Playlists + + + + + Add to my Stations + + + + + &Export Playlist + + + + + playlist + + + + + automatic playlist + + + + + station + + + + + Would you like to delete the %1 <b>"%2"</b>? + e.g. Would you like to delete the playlist named Foobar? + + + + + Delete + + + + + Save XSPF + Išsaugoti XSPF + + + + Playlists (*.xspf) + Grojaraščiai (*.xspf) + + + + SourcesModel + + + Group + + + + + Collection + Kolekcija + + + + Playlist + Grojaraštis + + + + Automatic Playlist + + + + + Station + Stotis + + + + Browse + Naršyti + + + + Search History + Paieškos istorija + + + + My Music + Mano muzika + + + + SuperCollection + Super Kolekcija + + + + Dashboard + + + + + Recently Played + Neseniai klausyta + + + + Charts + + + + + New Releases + + + + + Friends + Draugai + + + + SpotifyConfig + + + Form + + + + + Configure your Spotify account + + + + + Username or Facebook Email + + + + + Log In + Prisijungti + + + + Right click on any Tomahawk playlist to sync it to Spotify. + + + + + High Quality Streams + + + + + Spotify playlists to keep in sync: + + + + + Delete Tomahawk playlist when removing synchronization + + + + + Username: + Vartotojo vardas: + + + + Password: + Slaptažodis: + + + + SpotifyPlaylistUpdater + + + Delete associated Spotify playlist? + + + + + StackedSettingsDialog + + + Tomahawk Settings + Tomahawk nuostatos + + + + Local Music Information + Vietinės muzikos informacija + + + + Path to scan for music files: + + + + + The Echo Nest supports keeping track of your catalog metadata + and using it to craft personalized radios. Enabling this option + will allow you (and all your friends) to create automatic playlists + and stations based on your personal taste profile. + + + + + Upload collection list to The Echo Nest to enable user radio + + + + + Watch for changes + Sekti pokyčius + + + + Time between scans, in seconds: + + + + + Advanced Settings + + + + + Remote Peer Connection Method + + + + + None (outgoing connections only) + + + + + Use UPnP to establish port forward (recommended) + + + + + Use static external IP address/host name and port + + + + + Set this to your external IP address or host name. Make sure to forward the port to this host! + + + + + SOCKS Proxy + + + + + Use SOCKS Proxy + + + + + Clear All Access Control Entries + + + + + Internet Services + + + + + Install from file... + + + + + Filter by capability: + + + + + Static Host Name: + + + + + Static Port: + + + + + Proxy Settings... + + + + + Other Settings + + + + + Send reports after Tomahawk crashed + + + + + Allow web browsers to interact with Tomahawk (recommended) + + + + + TemporaryPageItem + + + Copy Artist Link + + + + + Copy Album Link + + + + + Copy Track Link + + + + + Tomahawk::Accounts::AccountDelegate + + + Add Account + Pridėti paskyrą + + + + Remove + + + + + %1 downloads + + + + + Online + Prisijungęs + + + + Connecting... + Jungiamasi... + + + + Offline + Atsijungęs + + + + Tomahawk::Accounts::AccountModel + + + Manual Install Required + + + + + Unfortunately, automatic installation of this resolver is not available or disabled for your platform.<br /><br />Please use "Install from file" above, by fetching it from your distribution or compiling it yourself. Further instructions can be found here:<br /><br />http://www.tomahawk-player.org/resolvers/%1 + + + + + Tomahawk::Accounts::GoogleWrapper + + + Configure this Google Account + + + + + Google Address + Google adresas + + + + Enter your Google login to connect with your friends using Tomahawk! + + + + + username@gmail.com + + + + + Tomahawk::Accounts::GoogleWrapperFactory + + + Connect to Google Talk to find your friends + Prisijungti prie Google Talk tam, kad rasti draugų + + + + Tomahawk::Accounts::GoogleWrapperSip + + + Add Friend + Pridėti draugą + + + + Enter Google Address: + + + + + Tomahawk::Accounts::LastFmAccountFactory + + + Scrobble your tracks to last.fm, and find freely downloadable tracks to play + + + + + Tomahawk::Accounts::LastFmConfig + + + Testing... + + + + + Test Login + + + + + Importing %1 + e.g. Importing 2012/01/01 + + + + + Importing History... + + + + + History Incomplete. Resume + + + + + Playback History Imported + + + + + + Failed + Nepavyko + + + + Success + + + + + Could not contact server + + + + + Tomahawk::Accounts::SpotifyAccount + + + Sync with Spotify + + + + + Re-enable syncing with Spotify + + + + + Create local copy + + + + + Subscribe to playlist changes + + + + + Re-enable playlist subscription + + + + + Stop subscribing to changes + + + + + Stop syncing with Spotify + + + + + Tomahawk::Accounts::SpotifyAccountConfig + + + Logging in... + Prisijungiama... + + + + Failed: %1 + Nepavyko: %1 + + + + Logged in as %1 + + + + + Log Out + Atsijungti + + + + + Log In + + + + + Tomahawk::Accounts::SpotifyAccountFactory + + + Play music from and sync your playlists with Spotify Premium + + + + + Tomahawk::Accounts::TwitterAccountFactory + + + Connect to your Twitter followers. + + + + + Tomahawk::Accounts::TwitterConfigWidget + + + + + Tweet! + + + + + + Status: No saved credentials + + + + + + + Authenticate + + + + + + Status: Credentials saved for %1 + + + + + + De-authenticate + + + + + + + + + + + Tweetin' Error + + + + + The credentials could not be verified. +You may wish to try re-authenticating. + + + + + Status: Error validating credentials + + + + + Global Tweet + + + + + Direct Message + + + + + Send Message! + + + + + @Mention + + + + + Send Mention! + + + + + You must enter a user name for this type of tweet. + + + + + Your saved credentials could not be loaded. +You may wish to try re-authenticating. + + + + + Your saved credentials could not be verified. +You may wish to try re-authenticating. + + + + + + There was an error posting your status -- sorry! + + + + + + Tweeted! + + + + + Your tweet has been posted! + + + + + There was an error posting your direct message -- sorry! + + + + + Your message has been posted! + + + + + Tomahawk::Accounts::XmppAccountFactory + + + Log on to your Jabber/XMPP account to connect to your friends + + + + + Tomahawk::Accounts::ZeroconfFactory + + + Automatically connect to Tomahawks on the local network + + + + + Tomahawk::ContextMenu + + + &Play + + + + + + + Add to &Queue + + + + + Continue Playback after this &Track + + + + + Stop Playback after this &Track + + + + + + &Love + + + + + &Copy Track Link + + + + + Copy Album &Link + + + + + Copy Artist &Link + + + + + Un-&Love + + + + + &Delete Items + + + + + &Show Track Page + + + + + Properties... + + + + + &Delete Item + + + + + &Show Album Page + + + + + &Show Artist Page + + + + + Tomahawk::DropJobNotifier + + + playlist + + + + + artist + + + + + track + + + + + album + + + + + Fetching %1 from database + + + + + Parsing %1 %2 + + + + + Tomahawk::DynamicControlList + + + Click to collapse + + + + + Tomahawk::DynamicModel + + + + Could not find a playable track. + +Please change the filters or try again. + + + + + Failed to generate preview with the desired filters + + + + + Tomahawk::DynamicSetupWidget + + + Type: + + + + + Generate + + + + + Tomahawk::DynamicView + + + Add some filters above to seed this station! + + + + + Press Generate to get started! + + + + + Add some filters above, and press Generate to get started! + + + + + Tomahawk::DynamicWidget + + + Station ran out of tracks! + +Try tweaking the filters for a new set of songs to play. + + + + + Tomahawk::EchonestControl + + + + + + + + is + + + + + from user + + + + + + No users with Echo Nest Catalogs enabled. Try enabling option in Collection settings + + + + + similar to + + + + + + + + + + + Less + Mažiau + + + + + + + + + + More + Daugiau + + + + 0 BPM + + + + + 500 BPM + + + + + 0 secs + + + + + 3600 secs + + + + + -100 dB + -100 dB + + + + 100 dB + -100 dB + + + + Major + Mažorinis + + + + Minor + Minorinis + + + + C + + + + + C Sharp + + + + + D + + + + + E Flat + + + + + E + + + + + F + + + + + F Sharp + + + + + G + + + + + A Flat + + + + + A + + + + + B Flat + + + + + B + + + + + Ascending + + + + + Descending + + + + + Tempo + Tempas + + + + Duration + Trukmė + + + + Loudness + Garsumas + + + + Artist Familiarity + + + + + Artist Hotttnesss + + + + + Song Hotttnesss + + + + + Latitude + + + + + Longitude + + + + + Mode + + + + + Key + + + + + Energy + Energija + + + + Danceability + + + + + only by ~%1 + + + + + similar to ~%1 + + + + + with genre ~%1 + + + + + + from no one + + + + + My Collection + + + + + from %1 radio + + + + + with %1 %2 + + + + + about %1 BPM + + + + + about %n minute(s) long + + + + + about %1 dB + + + + + at around %1%2 %3 + + + + + in %1 + + + + + in a %1 key + + + + + sorted in %1 %2 order + + + + + with a %1 mood + + + + + in a %1 style + + + + + Tomahawk::EchonestSteerer + + + Steer this station: + + + + + Much less + + + + + Less + + + + + A bit less + + + + + Keep at current + + + + + A bit more + + + + + More + + + + + Much more + + + + + Tempo + + + + + Loudness + + + + + Danceability + + + + + Energy + + + + + Song Hotttnesss + + + + + Artist Hotttnesss + + + + + Artist Familiarity + + + + + By Description + + + + + Enter a description + + + + + Apply steering command + + + + + Reset all steering commands + + + + + Tomahawk::GroovesharkParser + + + Error fetching Grooveshark information from the network! + + + + + Tomahawk::InfoSystem::ChartsPlugin + + + Top Overall + + + + + Artists + + + + + Albums + + + + + Tracks + + + + + Tomahawk::InfoSystem::FdoNotifyPlugin + + + Tomahawk is playing "%1" by %2%3. + + + + + on "%1" + + + + + Tomahawk::InfoSystem::LastFmInfoPlugin + + + Top Tracks + + + + + Loved Tracks + + + + + Hyped Tracks + + + + + Top Artists + + + + + Hyped Artists + + + + + Tomahawk::InfoSystem::NewReleasesPlugin + + + Albums + + + + + Tomahawk::InfoSystem::TwitterInfoPlugin + + + Listening to "%1" by %2 and loving it! %3 + + + + + Tomahawk::ItunesParser + + + Error fetching iTunes information from the network! + + + + + Tomahawk::JSPFLoader + + + New Playlist + + + + + Failed to save tracks + + + + + Some tracks in the playlist do not contain an artist and a title. They will be ignored. + + + + + XSPF Error + + + + + This is not a valid XSPF playlist. + + + + + Tomahawk::LatchManager + + + &Catch Up + + + + + + &Listen Along + + + + + Tomahawk::Playlist + + + Would you like to delete the playlist <b>"%2"</b>? + e.g. Would you like to delete the playlist named Foobar? + + + + + Delete + + + + + Tomahawk::Query + + + and + + + + + You + + + + + you + + + + + and + + + + + %n other(s) + + + + + %1 people + + + + + loved this track + + + + + Tomahawk::RdioParser + + + Error fetching Rdio information from the network! + + + + + Tomahawk::ShortenedLinkParser + + + Network error parsing shortened link! + + + + + Tomahawk::Source + + + + Scanning (%L1 tracks) + + + + + Scanning + + + + + Checking + + + + + Syncing + + + + + Importing + + + + + Saving (%1%) + + + + + Online + Prisijungęs + + + + Offline + Atsijungęs + + + + Tomahawk::SpotifyParser + + + Error fetching Spotify information from the network! + + + + + Tomahawk::XspfUpdater + + + Automatically update from XSPF + + + + + TomahawkApp + + + My Collection + + + + + TomahawkOAuthTwitter + + + Twitter PIN + + + + + After authenticating on Twitter's web site, +enter the displayed PIN number here: + + + + + TomahawkTrayIcon + + + &Stop Playback after current Track + + + + + + Hide Tomahawk Window + + + + + Show Tomahawk Window + + + + + Currently not playing. + + + + + Play + + + + + Pause + + + + + &Love + + + + + Un-&Love + + + + + &Continue Playback after current Track + + + + + TomahawkWindow + + + Tomahawk + + + + + &Settings + + + + + &Controls + + + + + &Network + + + + + &Window + + + + + &Help + + + + + &Quit + + + + + Ctrl+Q + + + + + Go &Online + + + + + Add &Friend... + + + + + U&pdate Collection + + + + + Update Collection + + + + + &Configure Tomahawk... + + + + + Load &XSPF... + + + + + Create &New Playlist... + + + + + About &Tomahawk... + + + + + Create New &Automatic Playlist + + + + + Create New &Station + + + + + Show Offline Sources + + + + + Hide Offline Sources + + + + + Minimize + + + + + Ctrl+M + + + + + Zoom + + + + + Meta+Ctrl+Z + + + + + &Legal Info... + + + + + Diagnostics... + + + + + Fully &Rescan Collection + + + + + Fully Rescan Collection + + + + + + Play + Groti + + + + Space + + + + + Previous + + + + + Next + + + + + 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 klaida + + + + This is not a valid XSPF playlist. + + + + + Failed to save tracks + Nepavyko išsaugoti takelių + + + + 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 + Pristabdyti + + + + 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> + <h2><b>Tomahawk %1</h2> + + + + Copyright 2010 - 2012 + + + + + Thanks to: + + + + + About Tomahawk + Apie Tomahawk + + + + TopTracksContext + + + Top Hits + + + + + TrackInfoWidget + + + Form + + + + + Cover + + + + + Track + Takelis + + + + Artist + Atlikėjas + + + + Album + Albumas + + + + Statistics + + + + + Similar Tracks + + + + + Sorry, but we could not find similar tracks for this song! + + + + + You've listened to this track %n time(s). + + + + + You've never listened to this track before. + + + + + You first listened to it on %1. + + + + + You've listened to %1 %n time(s). + + + + + You've never listened to %1 before. + + + + + TrackView + + + Sorry, your filter '%1' did not match any results. + + + + + TransferStatusItem + + + from + streaming artist - track from friend + + + + + to + streaming artist - track to friend + + + + + TreeItemDelegate + + + Unknown + + + + + TreeModel + + + All Artists + Visi atlikėjai + + + + + My Collection + Mano kolekcija + + + + + Collection of %1 + + + + + TreeView + + + Sorry, your filter '%1' did not match any results. + + + + + TwitterConfigWidget + + + Configure this Twitter account + + + + + The Twitter plugin allows you to discover and play music from your Twitter friends running Tomahawk and post messages to your account. + + + + + Status: No saved credentials + + + + + Authenticate with Twitter + + + + + Twitter Connections + + + + + +If you only want to post tweets, you're done. + +If you want to connect Tomahawk to your friends using Twitter, select the type of tweet and press the button below to send a sync message. You must both be following each other as Direct Messages are used. Then be (very) patient -- it can take several minutes! + +You can re-send a sync message at any time simply by sending another tweet using the button. + + + + + Select the kind of tweet you would like, then press the button to post it: + + + + + Global Tweet + + + + + @Mention + + + + + Direct Message + + + + + e.g. @tomahawk + + + + + Send Message + + + + + ViewManager + + + After you have scanned your music collection you will find your tracks right here. + + + + + This collection is empty. + Ši kolekcija yra tuščia. + + + + SuperCollection + + + + + Combined libraries of all your online friends + + + + + Recently Played Tracks + + + + + Recently played tracks from all your friends + + + + + Sorry, we could not find any recent plays! + + + + + WelcomeWidget + + + Recent Additions + + + + + Newest Stations & Playlists + + + + + Recently Played Tracks + + + + + No recently created playlists in your network. + + + + + Welcome to Tomahawk + + + + + WhatsHotWidget + + + Charts + + + + + WikipediaContext + + + Wikipedia + Vikipedija + + + + XMPPBot + + + +Terms for %1: + + + + + + No terms found, sorry. + + + + + +Hotttness for %1: %2 + + + + + + +Familiarity for %1: %2 + + + + + + +Lyrics for "%1" by %2: + +%3 + + + + + + XSPFLoader + + + Failed to parse contents of XSPF playlist + + + + + Some playlist entries were found without artist and track name, they will be omitted + + + + + Failed to fetch the desired playlist from the network, or the desired file does not exist + + + + + New Playlist + + + + + XmlConsole + + + Xml stream console + + + + + + Filter + + + + + Save log + + + + + Disabled + + + + + By JID + + + + + By namespace uri + + + + + By all attributes + + + + + Visible stanzas + + + + + Information query + + + + + Message + + + + + Presence + + + + + Custom + + + + + Close + + + + + Save XMPP log to file + + + + + OpenDocument Format (*.odf);;HTML file (*.html);;Plain text (*.txt) + + + + + XmppConfigWidget + + + Xmpp Configuration + + + + + Configure this Xmpp account + + + + + Enter your Xmpp login to connect with your friends using Tomahawk! + + + + + Login Information + + + + + Xmpp ID: + + + + + e.g. user@example.com + + + + + Password: + + + + + An account with this name already exists! + + + + + Advanced Xmpp Settings + + + + + Server: + + + + + Port: + + + + + Lots of servers don't support this (e.g. GTalk, jabber.org) + + + + + Publish currently playing track + + + + + Enforce secure connection + + + + + XmppSipPlugin + + + User Interaction + + + + + Host is unknown + + + + + Item not found + + + + + Authorization Error + + + + + Remote Stream Error + + + + + Remote Connection failed + + + + + Internal Server Error + + + + + System shutdown + + + + + Conflict + + + + + Unknown + + + + + Do you want to add <b>%1</b> to your friend list? + + + + + No Compression Support + + + + + No Encryption Support + + + + + No Authorization Support + + + + + No Supported Feature + + + + + Add Friend + + + + + Enter Xmpp ID: + + + + + Add Friend... + + + + + XML Console... + + + + + I'm sorry -- I'm just an automatic presence used by Tomahawk Player (http://gettomahawk.com). If you are getting this message, the person you are trying to reach is probably not signed on, so please try again later! + + + + + Authorize User + + + + + ZeroconfConfig + + + Form + + + + + Local Network configuration + + + + + This plugin will automatically find other users running Tomahawk on your local network + + + + + Connect automatically when Tomahawk starts + + + + \ No newline at end of file diff --git a/lang/tomahawk_pl.ts b/lang/tomahawk_pl.ts index acbf13124..8b6943723 100644 --- a/lang/tomahawk_pl.ts +++ b/lang/tomahawk_pl.ts @@ -2920,13 +2920,13 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::Playlist - + Would you like to delete the playlist <b>"%2"</b>? e.g. Would you like to delete the playlist named Foobar? - + Delete @@ -3032,7 +3032,7 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::SpotifyParser - + Error fetching Spotify information from the network! diff --git a/lang/tomahawk_pt_BR.ts b/lang/tomahawk_pt_BR.ts index 3e356d862..ff07bc43d 100644 --- a/lang/tomahawk_pt_BR.ts +++ b/lang/tomahawk_pt_BR.ts @@ -2926,13 +2926,13 @@ Tente ajustar os filtros para ouvir um novo conjunto de músicas. Tomahawk::Playlist - + Would you like to delete the playlist <b>"%2"</b>? e.g. Would you like to delete the playlist named Foobar? - + Delete @@ -3038,7 +3038,7 @@ Tente ajustar os filtros para ouvir um novo conjunto de músicas. Tomahawk::SpotifyParser - + Error fetching Spotify information from the network! Erro ao obter informações do Spotify pela rede! diff --git a/lang/tomahawk_ru.ts b/lang/tomahawk_ru.ts index 18919260e..62fe0a1c4 100644 --- a/lang/tomahawk_ru.ts +++ b/lang/tomahawk_ru.ts @@ -2921,13 +2921,13 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::Playlist - + Would you like to delete the playlist <b>"%2"</b>? e.g. Would you like to delete the playlist named Foobar? - + Delete @@ -3033,7 +3033,7 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::SpotifyParser - + Error fetching Spotify information from the network! Возникла ошибка при получении информации из Spotify! diff --git a/lang/tomahawk_sv.ts b/lang/tomahawk_sv.ts index 0b343e9b3..ade068ffe 100644 --- a/lang/tomahawk_sv.ts +++ b/lang/tomahawk_sv.ts @@ -2915,13 +2915,13 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::Playlist - + Would you like to delete the playlist <b>"%2"</b>? e.g. Would you like to delete the playlist named Foobar? - + Delete @@ -3027,7 +3027,7 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::SpotifyParser - + Error fetching Spotify information from the network! diff --git a/lang/tomahawk_tr.ts b/lang/tomahawk_tr.ts index ea45836df..fe6c382d7 100644 --- a/lang/tomahawk_tr.ts +++ b/lang/tomahawk_tr.ts @@ -2914,13 +2914,13 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::Playlist - + Would you like to delete the playlist <b>"%2"</b>? e.g. Would you like to delete the playlist named Foobar? - + Delete @@ -3026,7 +3026,7 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::SpotifyParser - + Error fetching Spotify information from the network! diff --git a/lang/tomahawk_zh_CN.ts b/lang/tomahawk_zh_CN.ts index a6cd7e81a..1e777f7be 100644 --- a/lang/tomahawk_zh_CN.ts +++ b/lang/tomahawk_zh_CN.ts @@ -2914,13 +2914,13 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::Playlist - + Would you like to delete the playlist <b>"%2"</b>? e.g. Would you like to delete the playlist named Foobar? - + Delete @@ -3026,7 +3026,7 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::SpotifyParser - + Error fetching Spotify information from the network! diff --git a/lang/tomahawk_zh_TW.ts b/lang/tomahawk_zh_TW.ts index 9b2dabb5c..b615088dd 100644 --- a/lang/tomahawk_zh_TW.ts +++ b/lang/tomahawk_zh_TW.ts @@ -2914,13 +2914,13 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::Playlist - + Would you like to delete the playlist <b>"%2"</b>? e.g. Would you like to delete the playlist named Foobar? - + Delete @@ -3026,7 +3026,7 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::SpotifyParser - + Error fetching Spotify information from the network! From 643b2374a66148601e78b9baeb6babe2a78d1212 Mon Sep 17 00:00:00 2001 From: Tomahawk CI Date: Mon, 30 Jul 2012 00:16:59 +0200 Subject: [PATCH 40/79] Automatic merge of Transifex translations --- lang/tomahawk_ja.ts | 95 ++++----- lang/tomahawk_lt.ts | 484 ++++++++++++++++++++++---------------------- 2 files changed, 291 insertions(+), 288 deletions(-) diff --git a/lang/tomahawk_ja.ts b/lang/tomahawk_ja.ts index 0bb52b517..aeb6af093 100644 --- a/lang/tomahawk_ja.ts +++ b/lang/tomahawk_ja.ts @@ -1527,7 +1527,7 @@ connect and stream from you? Delete - + 削除 @@ -1671,7 +1671,7 @@ connect and stream from you? Delete associated Spotify playlist? - + 関連付けられたSpotifyのプレイリストも削除しますか? @@ -1697,7 +1697,10 @@ connect and stream from you? and using it to craft personalized radios. Enabling this option will allow you (and all your friends) to create automatic playlists and stations based on your personal taste profile. - + The Echo Nestはカタログのメタデータを整理して、 +個人的なラジオを作成する機能があります。 +このオプションを有効にすると、あなたと友達の音楽の好みに +基づいた自動プレイリストやステーションを作れます。 @@ -1767,42 +1770,42 @@ connect and stream from you? Install from file... - + ファイルからインストール... Filter by capability: - + 機能別に分類: Static Host Name: - + 静的ホスト名: Static Port: - + 静的ポート: Proxy Settings... - + プロクシ設定 Other Settings - + 他の設定 Send reports after Tomahawk crashed - + Tomahawkがクラッシュしたら、レポートを送信 Allow web browsers to interact with Tomahawk (recommended) - + ウェブブラウザーとの対話を許可する(お勧め) @@ -1810,17 +1813,17 @@ connect and stream from you? Copy Artist Link - + アーティストリンクをコピー Copy Album Link - + アルバムリンクをコピー Copy Track Link - + トラックリンクをコピー @@ -1833,12 +1836,12 @@ connect and stream from you? Remove - + 削除 %1 downloads - + %1ダウンロード @@ -1848,7 +1851,7 @@ connect and stream from you? Connecting... - + 接続中... @@ -1861,12 +1864,12 @@ connect and stream from you? Manual Install Required - + 手動インストールが要求 Unfortunately, automatic installation of this resolver is not available or disabled for your platform.<br /><br />Please use "Install from file" above, by fetching it from your distribution or compiling it yourself. Further instructions can be found here:<br /><br />http://www.tomahawk-player.org/resolvers/%1 - + 残念ながら、このプラットフォームでは、リゾルバの自動インストールは設けてないか、無効にされました。<br /><br />以上の「ファイルからインストール」を使用して、又はディストリビューションから取得するか、自分でコンパイルして下さい。詳しくはこちらを参照:<br /><br />http://www.tomahawk-player.org/resolvers/%1 @@ -1874,22 +1877,22 @@ connect and stream from you? Configure this Google Account - + Googleのアカウントを設定 Google Address - + Googleのアドレス Enter your Google login to connect with your friends using Tomahawk! - + Googleのログイン情報を入力して、Tomahawkで友達に接続しましょう! username@gmail.com - + username@gmail.com @@ -1897,7 +1900,7 @@ connect and stream from you? Connect to Google Talk to find your friends - + Google Talkに接続して、友達を探す @@ -1905,12 +1908,12 @@ connect and stream from you? Add Friend - + 友達を追加 Enter Google Address: - + Googleのアドレスを入力: @@ -1918,7 +1921,7 @@ connect and stream from you? Scrobble your tracks to last.fm, and find freely downloadable tracks to play - + Last.fmにトラックをscrobbleして、無料ダウンロードのトラックを探して再生する @@ -1926,49 +1929,49 @@ connect and stream from you? Testing... - + 試験用接続... Test Login - + ログインを試用 Importing %1 e.g. Importing 2012/01/01 - + %1をインポート Importing History... - + 履歴をインポート中... History Incomplete. Resume - + 不完全履歴。回復 Playback History Imported - + 再生履歴インポート完了 Failed - + 失敗しました Success - + 完成 Could not contact server - + サーバーに接続できませんでした @@ -1976,37 +1979,37 @@ connect and stream from you? Sync with Spotify - + Spotifyと同期する Re-enable syncing with Spotify - + Spotifyとの同期を再び有効にする Create local copy - + ローカルのコピーを作成 Subscribe to playlist changes - + プレイリストの変更フィードに登録する Re-enable playlist subscription - + 再びプレイリストのフィードに登録する Stop subscribing to changes - + 変更フィードの登録を解除 Stop syncing with Spotify - + Spotifyとの同期を解除 @@ -2019,17 +2022,17 @@ connect and stream from you? Failed: %1 - + 失敗しました: %1 Logged in as %1 - + %1としてログイン済み Log Out - + ログアウト diff --git a/lang/tomahawk_lt.ts b/lang/tomahawk_lt.ts index e085422de..7fc507f3a 100644 --- a/lang/tomahawk_lt.ts +++ b/lang/tomahawk_lt.ts @@ -10,12 +10,12 @@ connect and stream from you? Allow Streaming - + Leisti transliavimą Deny Access - + Drausti priėjimą @@ -36,7 +36,7 @@ connect and stream from you? Description goes here - + Apibūdinimo vieta čia @@ -72,12 +72,12 @@ connect and stream from you? Stop &Listening Along - + Stabdyti k&lausymąsi kartu &Follow in real-time - + Se&kti realiu laiku @@ -104,7 +104,7 @@ connect and stream from you? &Copy Playlist Link - + &Kopijuoti grojaraščio nuorodą @@ -189,12 +189,12 @@ connect and stream from you? Related Artists - + Susiję atlikėjai Artist - + Atlikėjas @@ -204,7 +204,7 @@ connect and stream from you? Cover - + Viršelis @@ -323,12 +323,12 @@ connect and stream from you? Create new Playlist - + Sukurti naują grojaraštį Create new Station - + Sukurti naują stotį @@ -375,12 +375,12 @@ connect and stream from you? Show Footnotes - + Rodyti išnašas Hide Footnotes - + Slėpti išnašas @@ -388,7 +388,7 @@ connect and stream from you? Tomahawk Crash Reporter - + Tomahawk strigties pranešyklė @@ -398,22 +398,22 @@ connect and stream from you? Send this report - + Siųsti šią ataskaitą Don't send - + Nesiųsti Abort - + Nutraukti You can disable sending crash reports in the configuration dialog. - + Galite išjungti strigčių ataskaitų siuntimą konfigūracijos dialogo lange. @@ -434,7 +434,7 @@ connect and stream from you? Failed to send crash info. - + Nepavyko nusiųsti strigties informacijos. @@ -468,17 +468,17 @@ connect and stream from you? Tomahawk Diagnostics - + Tomahawk diagnostika &Copy to Clipboard - + &Kopijuoti į iškarpinę Open &Log-file - + Atverti žurna&lą @@ -515,7 +515,7 @@ connect and stream from you? Filter... - + Filtruoti... @@ -548,7 +548,7 @@ connect and stream from you? Import Playback History - + Įkelti klausymosi istoriją @@ -564,7 +564,7 @@ connect and stream from you? %1 is listening along with you! - + %1 klausosi kartu su Jumis! @@ -626,12 +626,12 @@ connect and stream from you? Top Loved Tracks - + Populiariausios mylimos dainos Sorry, we could not find any loved tracks! - + Deja, neradome jokių mylimų dainų! @@ -641,17 +641,17 @@ connect and stream from you? All of your loved tracks - + Visos Jūsų mylimos dainos All of %1's loved tracks - + Visos %1 mylimos dainos Loved Tracks - + Mylimos dainos @@ -669,12 +669,12 @@ connect and stream from you? Title: - + Pavadinimas: Title... - + Pavadinimas... @@ -684,7 +684,7 @@ connect and stream from you? Artist... - + Atlikėjas... @@ -694,22 +694,22 @@ connect and stream from you? Album... - + Albumas... Disc Number: - + Disko numeris: Duration: - + Trukmė: 00.00 - + 00.00 @@ -719,7 +719,7 @@ connect and stream from you? Bitrate: - + Bitų dažnis: @@ -734,22 +734,22 @@ connect and stream from you? File Name... - + Failo vardas... File Size... - + Failo dydis... File size... - + Failo dydis... File Size: - + Failo dydis: @@ -764,7 +764,7 @@ connect and stream from you? - Properties - + - Savybės @@ -808,68 +808,68 @@ connect and stream from you? Artist - + Atlikėjas Title - + Pavadinimas Composer - + Kompozitorius Album - + Albumas Track - + Takelio numeris Duration - + Trukmė Bitrate - + Bitų dažnis Age - + Amžius Year - + Metai Size - + Dydis Origin - + Šaltinis Score - + Įvertis Name - + Vardas @@ -887,7 +887,7 @@ connect and stream from you? Description - + Apibūdinimas @@ -981,12 +981,12 @@ connect and stream from you? Create Manual Playlist - + Sukurti rankinį grojaraštį Create Automatic Playlist - + Sukurti automatinį grojaraštį @@ -994,12 +994,12 @@ connect and stream from you? This playlist is currently empty. - + Šis grojaraštis kol kas tuščias. This playlist is currently empty. Add some tracks to it and enjoy the music! - + Šis grojaraštis kol kas tuščias. Pridėkite takelių ir mėgaukitės muzika! @@ -1007,12 +1007,12 @@ connect and stream from you? Proxy Settings - + Proxy nuostatos Hostname of proxy server - + Proxy serverio vardas @@ -1066,52 +1066,52 @@ connect and stream from you? %n year(s) ago - + prieš %n metusprieš %n metusprieš %n metų %n year(s) - + %n metai%n metai%n metų %n month(s) ago - + prieš %n mėnesįprieš %n mėnesiusprieš %n mėnesių %n month(s) - + %n mėnuo%n mėnesiai%n mėnesių %n week(s) ago - + prieš %n savaitęprieš %n savaitesprieš %n savaičių %n week(s) - + %n savaitė%n savaitės%n savaičių %n day(s) ago - + prieš %n dienąprieš %n dienasprieš %n dienų %n day(s) - + %n diena%n dienos%n dienų %n hour(s) ago - + prieš %n valandąprieš %n valandasprieš %n valandų %n hour(s) - + %n valanda%n valandos%n valandų @@ -1131,12 +1131,12 @@ connect and stream from you? Friend Finders - + Draugų ieškyklės Music Finders - + Muzikos ieškyklės @@ -1149,7 +1149,7 @@ connect and stream from you? ZIP/UNZIP API error %1 - + ZIP/UNZIP API klaida %1 @@ -1163,17 +1163,17 @@ connect and stream from you? Open Queue - + Atverti eilę Open Queue - %n item(s) - + Atverti eilę - %n elementasAtverti eilę - %n elementaiAtverti eilę - %n elementų Close Queue - + Užverti eilę @@ -1263,7 +1263,7 @@ connect and stream from you? Information - + Informacija @@ -1276,7 +1276,7 @@ connect and stream from you? Most Played Playlists - + Dažniausiai grojami grojaraščiai @@ -1294,12 +1294,12 @@ connect and stream from you? Facebook - + Facebook Twitter - + Twitter @@ -1397,7 +1397,7 @@ connect and stream from you? New Additions - + Naujai pridėta @@ -1451,17 +1451,17 @@ connect and stream from you? Recently Played Tracks - + Neseniai groti takeliai Your recently played tracks - + Jūsų neseniai groti takeliai %1's recently played tracks - + %1 neseniai groti takeliai @@ -1479,22 +1479,22 @@ connect and stream from you? &Delete %1 - + Paša&linti %1 Add to my Playlists - + Pridėti prie mano grojaraščių Add to my Automatic Playlists - + Pridėti prie mano automatinių grojaraščių Add to my Stations - + Pridėti prie mano stočių @@ -1504,17 +1504,17 @@ connect and stream from you? playlist - + grojaraštis automatic playlist - + automatinis grojaraštis station - + stotis @@ -1525,7 +1525,7 @@ connect and stream from you? Delete - + Pašalinti @@ -1558,7 +1558,7 @@ connect and stream from you? Automatic Playlist - + Automatinis grojaraštis @@ -1588,7 +1588,7 @@ connect and stream from you? Dashboard - + Skydelis @@ -1669,7 +1669,7 @@ connect and stream from you? Delete associated Spotify playlist? - + Pašalinti susietą Spotify grojaraštį? @@ -1760,12 +1760,12 @@ connect and stream from you? Internet Services - + Internetinės paslaugos Install from file... - + Įdiegti iš failo... @@ -1775,17 +1775,17 @@ connect and stream from you? Static Host Name: - + Statinis serverio vardas: Static Port: - + Statinis prievadas: Proxy Settings... - + Proxy nuostatos... @@ -1795,7 +1795,7 @@ connect and stream from you? Send reports after Tomahawk crashed - + Siųsti ataskaitas apie Tomahawk strigtis @@ -1808,17 +1808,17 @@ connect and stream from you? Copy Artist Link - + Kopijuoti atlikėjo nuorodą Copy Album Link - + Kopijuoti albumo nuorodą Copy Track Link - + Kopijuoti takelio nuorodą @@ -1859,7 +1859,7 @@ connect and stream from you? Manual Install Required - + Reikalingas rankinis įdiegimas @@ -1872,7 +1872,7 @@ connect and stream from you? Configure this Google Account - + Konfigūruoti šią Google paskyrą @@ -1908,7 +1908,7 @@ connect and stream from you? Enter Google Address: - + Įveskite Google adresą: @@ -1924,7 +1924,7 @@ connect and stream from you? Testing... - + Bandoma... @@ -1935,22 +1935,22 @@ connect and stream from you? Importing %1 e.g. Importing 2012/01/01 - + Įkeliama %1 Importing History... - + Įkeliama istorija... History Incomplete. Resume - + Istorija nepilna. Tęskite Playback History Imported - + Klausymosi istorija įkelta @@ -1974,7 +1974,7 @@ connect and stream from you? Sync with Spotify - + Sinchronizuoti su Spotify @@ -1984,7 +1984,7 @@ connect and stream from you? Create local copy - + Sukurti vietinę kopiją @@ -2022,7 +2022,7 @@ connect and stream from you? Logged in as %1 - + Prisijungta kaip %1 @@ -2065,14 +2065,14 @@ connect and stream from you? Status: No saved credentials - + Būsena: Nėra išsaugotų prisijungimo duomenų Authenticate - + Nustatyti tapatybę @@ -2116,12 +2116,12 @@ You may wish to try re-authenticating. Direct Message - + Tiesioginė žinutė Send Message! - + Siųsti žinutę! @@ -2199,14 +2199,14 @@ You may wish to try re-authenticating. &Play - + &Groti Add to &Queue - + Pridėti į &eilę @@ -2216,7 +2216,7 @@ You may wish to try re-authenticating. Stop Playback after this &Track - + Sustabdyti grojimą po šio &takelio @@ -2227,17 +2227,17 @@ You may wish to try re-authenticating. &Copy Track Link - + &Kopijuoti takelio nuorodą Copy Album &Link - + Kopijuoti albumo &nuorodą Copy Artist &Link - + Kopijuoti atlikėjo &nuorodą @@ -2252,12 +2252,12 @@ You may wish to try re-authenticating. &Show Track Page - + &Rodyti takelio puslapį Properties... - + Savybės... @@ -2267,12 +2267,12 @@ You may wish to try re-authenticating. &Show Album Page - + &Rodyti albumo puslapį &Show Artist Page - + &Rodyti atlikėjo puslapį @@ -2280,22 +2280,22 @@ You may wish to try re-authenticating. playlist - + grojaraštis artist - + atlikėjas track - + takelis album - + albumas @@ -2313,7 +2313,7 @@ You may wish to try re-authenticating. Click to collapse - + Spustelėkite, kad suskleisti @@ -2337,12 +2337,12 @@ Please change the filters or try again. Type: - + Tipas: Generate - + Kurti @@ -2355,7 +2355,7 @@ Please change the filters or try again. Press Generate to get started! - + Spauskite "Kurti", kad pradėti! @@ -2383,7 +2383,7 @@ Try tweaking the filters for a new set of songs to play. is - + yra @@ -2399,7 +2399,7 @@ Try tweaking the filters for a new set of songs to play. similar to - + panašus į @@ -2426,12 +2426,12 @@ Try tweaking the filters for a new set of songs to play. 0 BPM - + 0 taktų per minutę 500 BPM - + 500 taktų per minutę @@ -2526,12 +2526,12 @@ Try tweaking the filters for a new set of songs to play. Ascending - + Didėjančiai Descending - + Mažėjančiai @@ -2566,12 +2566,12 @@ Try tweaking the filters for a new set of songs to play. Latitude - + Platuma Longitude - + Ilguma @@ -2617,7 +2617,7 @@ Try tweaking the filters for a new set of songs to play. My Collection - + Mano kolekcija @@ -2642,7 +2642,7 @@ Try tweaking the filters for a new set of songs to play. about %1 dB - + apie %1 dB @@ -2685,17 +2685,17 @@ Try tweaking the filters for a new set of songs to play. Much less - + Žymiai mažiau Less - + Mažiau A bit less - + Šiek tiek mažiau @@ -2705,27 +2705,27 @@ Try tweaking the filters for a new set of songs to play. A bit more - + Šiek tiek daugiau More - + Daugiau Much more - + Žymiai daugiau Tempo - + Tempas Loudness - + Garsumas @@ -2755,12 +2755,12 @@ Try tweaking the filters for a new set of songs to play. By Description - + Pagal apibūdinimą Enter a description - + Įveskite apibūdinimą @@ -2791,17 +2791,17 @@ Try tweaking the filters for a new set of songs to play. Artists - + Atlikėjai Albums - + Albumai Tracks - + Takeliai @@ -2809,12 +2809,12 @@ Try tweaking the filters for a new set of songs to play. Tomahawk is playing "%1" by %2%3. - + Tomahawk groja "%1" atliekamą %2%3. on "%1" - + iš albumo "%1" @@ -2850,7 +2850,7 @@ Try tweaking the filters for a new set of songs to play. Albums - + Albumai @@ -2874,12 +2874,12 @@ Try tweaking the filters for a new set of songs to play. New Playlist - + Naujas grojaraštis Failed to save tracks - + Nepavyko išsaugoti dainų @@ -2889,7 +2889,7 @@ Try tweaking the filters for a new set of songs to play. XSPF Error - + XSPF klaida @@ -2902,13 +2902,13 @@ Try tweaking the filters for a new set of songs to play. &Catch Up - + &Pasivyti &Listen Along - + K&lausytis kartu @@ -2917,12 +2917,12 @@ Try tweaking the filters for a new set of songs to play. Would you like to delete the playlist <b>"%2"</b>? e.g. Would you like to delete the playlist named Foobar? - + Ar norite pašalinti grojaraštį <b>"%2"</b>? Delete - + Pašalinti @@ -2985,32 +2985,32 @@ Try tweaking the filters for a new set of songs to play. Scanning (%L1 tracks) - + Peržvelgiama (%L1 takeliai) Scanning - + Peržvelgiama Checking - + Tikrinama Syncing - + Sinchronizuojama Importing - + Įkeliama Saving (%1%) - + Išsaugoma (%1%) @@ -3044,7 +3044,7 @@ Try tweaking the filters for a new set of songs to play. My Collection - + Mano kolekcija @@ -3052,7 +3052,7 @@ Try tweaking the filters for a new set of songs to play. Twitter PIN - + Twitter PIN @@ -3072,12 +3072,12 @@ enter the displayed PIN number here: Hide Tomahawk Window - + Slėpti Tomahawk langą Show Tomahawk Window - + Rodyti Tomahawk langą @@ -3087,22 +3087,22 @@ enter the displayed PIN number here: Play - + Groti Pause - + Pristabdyti &Love - + &Myliu Un-&Love - + &Nemyliu @@ -3115,92 +3115,92 @@ enter the displayed PIN number here: Tomahawk - + Tomahawk &Settings - + &Nuostatos &Controls - + &Valdymas &Network - + Ti&nklas &Window - + &Langas &Help - + Ž&inynas &Quit - + &Baigti darbą Ctrl+Q - + Ctrl+Q Go &Online - + Prisi&jungti Add &Friend... - + Pridėti &draugą... U&pdate Collection - + At&naujinti kolekciją Update Collection - + Atnaujinti kolekciją &Configure Tomahawk... - + &Konfigūruoti Tomahawk... Load &XSPF... - + Įkelti &XSPF... Create &New Playlist... - + Sukurti naują &grojaraštį About &Tomahawk... - + Apie &Tomahawk... Create New &Automatic Playlist - + Sukurti naują &automatinį grojaraštį Create New &Station - + Sukurti naują &stotį @@ -3215,12 +3215,12 @@ enter the displayed PIN number here: Minimize - + Sumažinti Ctrl+M - + Ctrl+M @@ -3235,22 +3235,22 @@ enter the displayed PIN number here: &Legal Info... - + &Teisinė informacija... Diagnostics... - + Diagnostika... Fully &Rescan Collection - + Pilnai pe&ržvelgti kolekciją Fully Rescan Collection - + Pilnai peržvelgti kolekciją @@ -3266,32 +3266,32 @@ enter the displayed PIN number here: Previous - + Ankstesnis Next - + Kitas Back - + Atgal Go back one page - + Grįžti vienu puslapiu atgal Forward - + Pirmyn Go forward one page - + Eiti vienu puslapiu pirmyn @@ -3302,7 +3302,7 @@ enter the displayed PIN number here: Check For Updates... - + Tikrinti, ar yra atnaujinimų... @@ -3359,27 +3359,27 @@ enter the displayed PIN number here: Station - + Stotis Create New Station - + Sukurti naują stotį Name: - + Pavadinimas: Playlist - + Grojaraštis Automatic Playlist - + Automatinis grojaraštis @@ -3389,12 +3389,12 @@ enter the displayed PIN number here: Go &offline - + &Atsijungti Go &online - + &Prisijungti @@ -3431,12 +3431,12 @@ enter the displayed PIN number here: Copyright 2010 - 2012 - + Autorinės teisės 2010 - 2012 Thanks to: - + Dėkojame: @@ -3462,7 +3462,7 @@ enter the displayed PIN number here: Cover - + Viršelis @@ -3482,12 +3482,12 @@ enter the displayed PIN number here: Statistics - + Statistika Similar Tracks - + Panašūs takeliai @@ -3497,7 +3497,7 @@ enter the displayed PIN number here: You've listened to this track %n time(s). - + Jūs klausėtės šio takelio %n kartą.Jūs klausėtės šio takelio %n kartus.Jūs klausėtės šio takelio %n kartų. @@ -3512,12 +3512,12 @@ enter the displayed PIN number here: You've listened to %1 %n time(s). - + Jūs klausėtės %1 %n kartą.Jūs klausėtės %1 %n kartus.Jūs klausėtės %1 %n kartų. You've never listened to %1 before. - + Jūs niekada anksčiau nesiklausėte %1. @@ -3672,12 +3672,12 @@ You can re-send a sync message at any time simply by sending another tweet using Recently Played Tracks - + Neseniai groti takeliai Recently played tracks from all your friends - + Visų Jūsų draugų neseniai groti takeliai @@ -3787,7 +3787,7 @@ Lyrics for "%1" by %2: New Playlist - + Naujas grojaraštis @@ -3904,7 +3904,7 @@ Lyrics for "%1" by %2: Password: - + Slaptažodis: @@ -3919,12 +3919,12 @@ Lyrics for "%1" by %2: Server: - + Serveris: Port: - + Prievadas: @@ -3997,7 +3997,7 @@ Lyrics for "%1" by %2: Do you want to add <b>%1</b> to your friend list? - + Ar norite pridėti <b>%1</b> prie savo draugų sąrašo? @@ -4022,7 +4022,7 @@ Lyrics for "%1" by %2: Add Friend - + Pridėti draugą @@ -4032,7 +4032,7 @@ Lyrics for "%1" by %2: Add Friend... - + Pridėti draugą... From cfbccb85cf365dd855fa912186dd9d64e5871009 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Sun, 29 Jul 2012 15:08:43 -0400 Subject: [PATCH 41/79] TWK-1017: Show now-playing icon next to playlist in flat view mode --- src/libtomahawk/ViewManager.cpp | 1 + src/libtomahawk/playlist/FlexibleView.cpp | 37 ++++++++++++++++++++++- src/libtomahawk/playlist/FlexibleView.h | 5 +++ src/sourcetree/items/PlaylistItems.cpp | 9 ++++-- 4 files changed, 49 insertions(+), 3 deletions(-) diff --git a/src/libtomahawk/ViewManager.cpp b/src/libtomahawk/ViewManager.cpp index 7ec8e0f5d..bae8e9b5e 100644 --- a/src/libtomahawk/ViewManager.cpp +++ b/src/libtomahawk/ViewManager.cpp @@ -2,6 +2,7 @@ * * Copyright 2010-2011, Christian Muehlhaeuser * Copyright 2010-2011, Jeff Mitchell + * Copyright 2010-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 diff --git a/src/libtomahawk/playlist/FlexibleView.cpp b/src/libtomahawk/playlist/FlexibleView.cpp index 3a6d7534d..187b3e34c 100644 --- a/src/libtomahawk/playlist/FlexibleView.cpp +++ b/src/libtomahawk/playlist/FlexibleView.cpp @@ -27,12 +27,39 @@ #include "playlist/TrackView.h" #include "playlist/GridView.h" #include "playlist/PlaylistLargeItemDelegate.h" +#include "PlayableProxyModelPlaylistInterface.h" #include "utils/TomahawkUtilsGui.h" #include "utils/Logger.h" using namespace Tomahawk; +class FlexibleViewInterface : public PlayableProxyModelPlaylistInterface { + Q_OBJECT +public: + explicit FlexibleViewInterface( PlayableProxyModel* proxy, FlexibleView* view ) : PlayableProxyModelPlaylistInterface( proxy ), m_view( view ) {} + + virtual bool hasChildInterface( playlistinterface_ptr playlistInterface ) + { + if ( m_view.isNull() ) + return false; + + if ( m_view.data()->detailedView() && m_view.data()->detailedView()->proxyModel()->playlistInterface() == playlistInterface ) + return true; + + if ( m_view.data()->gridView() && m_view.data()->gridView()->playlistInterface()->hasChildInterface( playlistInterface ) ) + return true; + + if ( m_view.data()->trackView() && m_view.data()->trackView()->proxyModel()->playlistInterface() == playlistInterface ) + return true; + + return false; + } + +private: + QWeakPointer m_view; +}; + FlexibleView::FlexibleView( QWidget* parent ) : QWidget( parent ) , m_header( new FlexibleHeader( this ) ) @@ -43,6 +70,8 @@ FlexibleView::FlexibleView( QWidget* parent ) { qRegisterMetaType< FlexibleViewMode >( "FlexibleViewMode" ); + m_playlistInterface = playlistinterface_ptr( new FlexibleViewInterface( m_trackView->proxyModel(), this ) ); + PlaylistLargeItemDelegate* del = new PlaylistLargeItemDelegate( PlaylistLargeItemDelegate::LovedTracks, m_trackView, m_trackView->proxyModel() ); connect( del, SIGNAL( updateIndex( QModelIndex ) ), m_trackView, SLOT( update( QModelIndex ) ) ); m_trackView->setItemDelegate( del ); @@ -79,8 +108,12 @@ FlexibleView::setTrackView( TrackView* view ) delete m_trackView; } + if ( view && m_trackView != view ) + m_playlistInterface = playlistinterface_ptr( new FlexibleViewInterface( view->proxyModel(), this ) ); + m_trackView = view; m_stack->addWidget( view ); + } @@ -169,7 +202,7 @@ FlexibleView::setCurrentMode( FlexibleViewMode mode ) Tomahawk::playlistinterface_ptr FlexibleView::playlistInterface() const { - return m_trackView->playlistInterface(); + return m_playlistInterface; } @@ -232,3 +265,5 @@ FlexibleView::setPixmap( const QPixmap& pixmap ) m_pixmap = pixmap; m_header->setPixmap( pixmap ); } + +#include "FlexibleView.moc" diff --git a/src/libtomahawk/playlist/FlexibleView.h b/src/libtomahawk/playlist/FlexibleView.h index 3b502643a..a78104116 100644 --- a/src/libtomahawk/playlist/FlexibleView.h +++ b/src/libtomahawk/playlist/FlexibleView.h @@ -29,6 +29,7 @@ class GridView; class TrackView; class PlayableModel; class FlexibleHeader; +class FlexibleViewInterface; class DLLEXPORT FlexibleView : public QWidget, public Tomahawk::ViewPage { @@ -80,10 +81,14 @@ private: TrackView* m_detailedView; GridView* m_gridView; + Tomahawk::playlistinterface_ptr m_playlistInterface; + PlayableModel* m_model; QStackedWidget* m_stack; FlexibleViewMode m_mode; + + friend class ::FlexibleViewInterface; }; Q_DECLARE_METATYPE( FlexibleView::FlexibleViewMode ); diff --git a/src/sourcetree/items/PlaylistItems.cpp b/src/sourcetree/items/PlaylistItems.cpp index c36313796..3630b1f0d 100644 --- a/src/sourcetree/items/PlaylistItems.cpp +++ b/src/sourcetree/items/PlaylistItems.cpp @@ -108,8 +108,13 @@ PlaylistItem::IDValue() const bool PlaylistItem::isBeingPlayed() const { - if ( ViewManager::instance()->pageForPlaylist( m_playlist ) ) - return AudioEngine::instance()->currentTrackPlaylist() == ViewManager::instance()->pageForPlaylist( m_playlist )->playlistInterface(); + if ( ViewPage* page = ViewManager::instance()->pageForPlaylist( m_playlist ) ) + { + if ( AudioEngine::instance()->currentTrackPlaylist() == page->playlistInterface() ) + return true; + if ( page->playlistInterface()->hasChildInterface( AudioEngine::instance()->currentTrackPlaylist() ) ) + return true; + } return false; } From ea11f7c7be51edaa1cf44168f4f61aae5b3e5f6b Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Sun, 29 Jul 2012 17:53:55 -0400 Subject: [PATCH 42/79] Show currently-playing speaker for GenericPageItems with children interfaces --- src/sourcetree/items/GenericPageItems.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/sourcetree/items/GenericPageItems.cpp b/src/sourcetree/items/GenericPageItems.cpp index 3ce127d40..97a790ad3 100644 --- a/src/sourcetree/items/GenericPageItems.cpp +++ b/src/sourcetree/items/GenericPageItems.cpp @@ -86,7 +86,16 @@ bool GenericPageItem::isBeingPlayed() const { if ( m_get() ) - return m_get()->isBeingPlayed(); + { + if ( m_get()->isBeingPlayed() ) + return true; + + if ( !m_get()->playlistInterface().isNull() && m_get()->playlistInterface() == AudioEngine::instance()->currentTrackPlaylist() ) + return true; + + if ( !m_get()->playlistInterface().isNull() && m_get()->playlistInterface()->hasChildInterface( AudioEngine::instance()->currentTrackPlaylist() ) ) + return true; + } return false; } From e28d61935e897db7b640681764daa684b1004ef4 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Sun, 29 Jul 2012 17:55:28 -0400 Subject: [PATCH 43/79] Show playing icon when playing grid-view playlists --- src/libtomahawk/CMakeLists.txt | 1 + src/libtomahawk/audio/AudioEngine.cpp | 7 ++- .../database/DatabaseCommand_Resolve.cpp | 2 +- src/libtomahawk/playlist/GridView.cpp | 3 + .../playlist/SingleTrackPlaylistInterface.h | 59 +++++++++++++++++++ 5 files changed, 70 insertions(+), 2 deletions(-) create mode 100644 src/libtomahawk/playlist/SingleTrackPlaylistInterface.h diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index d98f14c19..c148deb59 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -74,6 +74,7 @@ set( libGuiSources playlist/PlaylistLargeItemDelegate.cpp playlist/PlaylistChartItemDelegate.cpp playlist/PlayableItem.cpp + playlist/SingleTrackPlaylistInterface.h playlist/dynamic/DynamicPlaylist.cpp playlist/dynamic/DynamicView.cpp diff --git a/src/libtomahawk/audio/AudioEngine.cpp b/src/libtomahawk/audio/AudioEngine.cpp index e8f07c45c..dde5ed1ad 100644 --- a/src/libtomahawk/audio/AudioEngine.cpp +++ b/src/libtomahawk/audio/AudioEngine.cpp @@ -42,6 +42,7 @@ #include "jobview/ErrorStatusMessage.h" #include "utils/Logger.h" +#include "SingleTrackPlaylistInterface.h" using namespace Tomahawk; @@ -582,7 +583,11 @@ AudioEngine::playItem( Tomahawk::playlistinterface_ptr playlist, const Tomahawk: m_playlist.data()->reset(); setPlaylist( playlist ); - m_currentTrackPlaylist = playlist; + + if ( playlist.isNull() ) + m_currentTrackPlaylist = playlistinterface_ptr( new SingleTrackPlaylistInterface( result->toQuery() ) ); + else + m_currentTrackPlaylist = playlist; if ( !result.isNull() ) { diff --git a/src/libtomahawk/database/DatabaseCommand_Resolve.cpp b/src/libtomahawk/database/DatabaseCommand_Resolve.cpp index f9f631f70..bcb708429 100644 --- a/src/libtomahawk/database/DatabaseCommand_Resolve.cpp +++ b/src/libtomahawk/database/DatabaseCommand_Resolve.cpp @@ -219,7 +219,7 @@ DatabaseCommand_Resolve::fullTextResolve( DatabaseImpl* lib ) emit albums( m_query->id(), albumList ); } - + if ( trackPairs.length() == 0 ) { qDebug() << "No candidates found in first pass, aborting resolve" << m_query->fullTextQuery(); diff --git a/src/libtomahawk/playlist/GridView.cpp b/src/libtomahawk/playlist/GridView.cpp index bccd83657..c1d85aa14 100644 --- a/src/libtomahawk/playlist/GridView.cpp +++ b/src/libtomahawk/playlist/GridView.cpp @@ -35,6 +35,7 @@ #include "AlbumModel.h" #include "PlayableModel.h" #include "PlayableProxyModelPlaylistInterface.h" +#include "SingleTrackPlaylistInterface.h" #include "ContextMenu.h" #include "ViewManager.h" #include "utils/Logger.h" @@ -64,6 +65,8 @@ public: return item->album()->playlistInterface( Tomahawk::Mixed ) == playlistInterface; else if ( !item->artist().isNull() ) return item->artist()->playlistInterface( Tomahawk::Mixed ) == playlistInterface; + else if ( !item->query().isNull() && !playlistInterface.dynamicCast< SingleTrackPlaylistInterface >().isNull() ) + return item->query() == playlistInterface.dynamicCast< SingleTrackPlaylistInterface >()->track(); } return false; diff --git a/src/libtomahawk/playlist/SingleTrackPlaylistInterface.h b/src/libtomahawk/playlist/SingleTrackPlaylistInterface.h new file mode 100644 index 000000000..5438debdf --- /dev/null +++ b/src/libtomahawk/playlist/SingleTrackPlaylistInterface.h @@ -0,0 +1,59 @@ +/* === 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 SINGLE_TRACK_PLAYLIST_INTERFACE +#define SINGLE_TRACK_PLAYLIST_INTERFACE + +#include "PlaylistInterface.h" +#include "DllMacro.h" +#include "Query.h" +#include "Typedefs.h" +#include "Result.h" + +namespace Tomahawk +{ + +class DLLEXPORT SingleTrackPlaylistInterface : public PlaylistInterface +{ + Q_OBJECT +public: + explicit SingleTrackPlaylistInterface( const query_ptr& query ) + : PlaylistInterface() + , m_track( query ) + { + } + + query_ptr track() const { return m_track; } + void setQuery( const query_ptr& track ) { m_track = track; } + + virtual result_ptr currentItem() const { return result_ptr(); } + virtual PlaylistModes::RepeatMode repeatMode() const { return PlaylistModes::NoRepeat; } + virtual void setRepeatMode( PlaylistModes::RepeatMode ) {} + virtual void setShuffled( bool ) {} + virtual bool shuffled() const { return false; } + virtual result_ptr siblingItem( int itemsAway ) { return result_ptr(); } + virtual int trackCount() const { return 1; } + virtual QList< query_ptr > tracks() { return QList< query_ptr >(); } + +private: + query_ptr m_track; +}; + +} + +#endif From bfb10e385f7b99b74fdf7463b4ce0d512101c79f Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Sun, 29 Jul 2012 17:55:47 -0400 Subject: [PATCH 44/79] Hide warning --- src/libtomahawk/playlist/PlaylistUpdaterInterface.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libtomahawk/playlist/PlaylistUpdaterInterface.h b/src/libtomahawk/playlist/PlaylistUpdaterInterface.h index 92e46e235..1d569e1a2 100644 --- a/src/libtomahawk/playlist/PlaylistUpdaterInterface.h +++ b/src/libtomahawk/playlist/PlaylistUpdaterInterface.h @@ -89,7 +89,7 @@ public: // as setQuestionResults is called with all questions from all updaters. virtual bool hasCustomDeleter() const { return false; } virtual PlaylistDeleteQuestions deleteQuestions() const { return PlaylistDeleteQuestions(); } - virtual void setQuestionResults( const QMap< int, bool > results ) {} + virtual void setQuestionResults( const QMap< int, bool > ) {} signals: void changed(); From 8e7c9d81302be148669d0654f8ce01e33055e68a Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Sun, 29 Jul 2012 22:44:57 -0400 Subject: [PATCH 45/79] Use the query that was used to play the track in AudioEngine --- src/libtomahawk/audio/AudioEngine.cpp | 8 ++++---- src/libtomahawk/audio/AudioEngine.h | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libtomahawk/audio/AudioEngine.cpp b/src/libtomahawk/audio/AudioEngine.cpp index dde5ed1ad..137a58a61 100644 --- a/src/libtomahawk/audio/AudioEngine.cpp +++ b/src/libtomahawk/audio/AudioEngine.cpp @@ -575,7 +575,7 @@ AudioEngine::loadNextTrack() void -AudioEngine::playItem( Tomahawk::playlistinterface_ptr playlist, const Tomahawk::result_ptr& result ) +AudioEngine::playItem( Tomahawk::playlistinterface_ptr playlist, const Tomahawk::result_ptr& result, const Tomahawk::query_ptr& fromQuery ) { tDebug( LOGEXTRA ) << Q_FUNC_INFO << ( result.isNull() ? QString() : result->url() ); @@ -584,8 +584,8 @@ AudioEngine::playItem( Tomahawk::playlistinterface_ptr playlist, const Tomahawk: setPlaylist( playlist ); - if ( playlist.isNull() ) - m_currentTrackPlaylist = playlistinterface_ptr( new SingleTrackPlaylistInterface( result->toQuery() ) ); + if ( playlist.isNull() && !fromQuery.isNull() ) + m_currentTrackPlaylist = playlistinterface_ptr( new SingleTrackPlaylistInterface( fromQuery ) ); else m_currentTrackPlaylist = playlist; @@ -611,7 +611,7 @@ AudioEngine::playItem( Tomahawk::playlistinterface_ptr playlist, const Tomahawk: { if ( query->numResults() && query->results().first()->isOnline() ) { - playItem( playlist, query->results().first() ); + playItem( playlist, query->results().first(), query ); return; } diff --git a/src/libtomahawk/audio/AudioEngine.h b/src/libtomahawk/audio/AudioEngine.h index e5183ea40..df5d5f5f8 100644 --- a/src/libtomahawk/audio/AudioEngine.h +++ b/src/libtomahawk/audio/AudioEngine.h @@ -86,11 +86,11 @@ public slots: void seek( qint64 ms ); void seek( int ms ); // for compatibility with seekbar in audiocontrols void setVolume( int percentage ); - void lowerVolume(); + void lowerVolume(); void raiseVolume(); void mute(); - void playItem( Tomahawk::playlistinterface_ptr playlist, const Tomahawk::result_ptr& result ); + void playItem( Tomahawk::playlistinterface_ptr playlist, const Tomahawk::result_ptr& result, const Tomahawk::query_ptr& fromQuery = Tomahawk::query_ptr() ); void playItem( Tomahawk::playlistinterface_ptr playlist, const Tomahawk::query_ptr& query ); void playItem( const Tomahawk::artist_ptr& artist ); void playItem( const Tomahawk::album_ptr& album ); From 527b4906c9db88396b928a2711c93e73d2637a90 Mon Sep 17 00:00:00 2001 From: Tomahawk CI Date: Tue, 31 Jul 2012 00:18:08 +0200 Subject: [PATCH 46/79] Automatic merge of Transifex translations --- lang/tomahawk_ar.ts | 20 +-- lang/tomahawk_bg.ts | 20 +-- lang/tomahawk_ca.ts | 20 +-- lang/tomahawk_de.ts | 20 +-- lang/tomahawk_en.ts | 20 +-- lang/tomahawk_es.ts | 20 +-- lang/tomahawk_fr.ts | 20 +-- lang/tomahawk_ja.ts | 20 +-- lang/tomahawk_lt.ts | 294 ++++++++++++++++++++--------------------- lang/tomahawk_pl.ts | 20 +-- lang/tomahawk_pt_BR.ts | 20 +-- lang/tomahawk_ru.ts | 20 +-- lang/tomahawk_sv.ts | 20 +-- lang/tomahawk_tr.ts | 20 +-- lang/tomahawk_zh_CN.ts | 20 +-- lang/tomahawk_zh_TW.ts | 20 +-- 16 files changed, 297 insertions(+), 297 deletions(-) diff --git a/lang/tomahawk_ar.ts b/lang/tomahawk_ar.ts index 5d6cf5f7b..4dcfe636e 100644 --- a/lang/tomahawk_ar.ts +++ b/lang/tomahawk_ar.ts @@ -304,17 +304,17 @@ connect and stream from you? AudioEngine - + Sorry, Tomahawk couldn't find the track '%1' by %2 نعتذر، لم نستطيع إيجاد الأغنية '%1' ل%2 - + Sorry, Tomahawk couldn't find the artist '%1' نعتذر، لم نستطيع إيجاد الفنان '%1' - + Sorry, Tomahawk couldn't find the album '%1' by %2 نعتذر، لم نستطيع إيجاد الألبوم '%1' ل%2 @@ -3668,37 +3668,37 @@ You can re-send a sync message at any time simply by sending another tweet using ViewManager - + After you have scanned your music collection you will find your tracks right here. بعد إجراء مسح مجموعة أغانيك الخاصة ستجد أغانيك هنا. - + This collection is empty. هذه المجموعة فارغة. - + SuperCollection سوبر كولكشن - + Combined libraries of all your online friends مكتبات مجمعة لكل اصحابك المتصلين - + Recently Played Tracks الأغاني التي إستمعت إليها مؤخرا - + Recently played tracks from all your friends جميع الأغاني التي استمع إليها أصدقائك مؤخرا - + Sorry, we could not find any recent plays! diff --git a/lang/tomahawk_bg.ts b/lang/tomahawk_bg.ts index 4ea9d5474..a31de7729 100644 --- a/lang/tomahawk_bg.ts +++ b/lang/tomahawk_bg.ts @@ -303,17 +303,17 @@ connect and stream from you? AudioEngine - + Sorry, Tomahawk couldn't find the track '%1' by %2 - + Sorry, Tomahawk couldn't find the artist '%1' - + Sorry, Tomahawk couldn't find the album '%1' by %2 @@ -3679,38 +3679,38 @@ You can re-send a sync message at any time simply by sending another tweet using ViewManager - + After you have scanned your music collection you will find your tracks right here. След като бъде сканирана колекцията ти, ще откриеш твоите песни точно тук. - + This collection is empty. Празна колекция. - + SuperCollection Супер колекция /Сборен излед от локалните и наличните в колекциите на приятелите ти/ - + Combined libraries of all your online friends Обща колекция с всичките ми приятели на линия - + Recently Played Tracks Наскоро изпълени песни - + Recently played tracks from all your friends Наскоро изпълнени песни от всичките ти приятели - + Sorry, we could not find any recent plays! diff --git a/lang/tomahawk_ca.ts b/lang/tomahawk_ca.ts index 0bc9cb7a3..d982ec637 100644 --- a/lang/tomahawk_ca.ts +++ b/lang/tomahawk_ca.ts @@ -303,17 +303,17 @@ connect and stream from you? AudioEngine - + Sorry, Tomahawk couldn't find the track '%1' by %2 - + Sorry, Tomahawk couldn't find the artist '%1' - + Sorry, Tomahawk couldn't find the album '%1' by %2 @@ -3667,37 +3667,37 @@ Podeu reenviar un missatge de sincronisme en qualsevol moment simplement enviant ViewManager - + After you have scanned your music collection you will find your tracks right here. - + This collection is empty. - + SuperCollection SuperCol·lecció - + Combined libraries of all your online friends Biblioteques combinades de tots els amis en línia - + Recently Played Tracks Cançons Escoltades Recentment - + Recently played tracks from all your friends Cançons escoltades recentment pels amics - + Sorry, we could not find any recent plays! diff --git a/lang/tomahawk_de.ts b/lang/tomahawk_de.ts index 74b595131..b6a80f863 100644 --- a/lang/tomahawk_de.ts +++ b/lang/tomahawk_de.ts @@ -304,17 +304,17 @@ erlauben sich mit dir zu verbinden? AudioEngine - + Sorry, Tomahawk couldn't find the track '%1' by %2 Sorry, Tomahawk konnte '%1' von %2 nicht finden - + Sorry, Tomahawk couldn't find the artist '%1' Sorry, Tomahawk konnte den Künstler '%1' nicht finden - + Sorry, Tomahawk couldn't find the album '%1' by %2 Sorry, Tomahawk konnte das Album '%1' von %2 nicht finden @@ -3658,37 +3658,37 @@ You can re-send a sync message at any time simply by sending another tweet using ViewManager - + After you have scanned your music collection you will find your tracks right here. Nachdem du deine Musik Sammlung gescannt hast, findest du all deine Lieder genau hier. - + This collection is empty. Diese Sammlung ist leer. - + SuperCollection SuperCollection - + Combined libraries of all your online friends Kombinierte Sammlung all deiner Freunde - + Recently Played Tracks Zuletzt gehörte Lieder - + Recently played tracks from all your friends Zuletzt gehörte Lieder all deiner Freunde - + Sorry, we could not find any recent plays! diff --git a/lang/tomahawk_en.ts b/lang/tomahawk_en.ts index 8686aeb57..de44ed72f 100644 --- a/lang/tomahawk_en.ts +++ b/lang/tomahawk_en.ts @@ -304,17 +304,17 @@ connect and stream from you? AudioEngine - + Sorry, Tomahawk couldn't find the track '%1' by %2 Sorry, Tomahawk couldn't find the track '%1' by %2 - + Sorry, Tomahawk couldn't find the artist '%1' Sorry, Tomahawk couldn't find the artist '%1' - + Sorry, Tomahawk couldn't find the album '%1' by %2 Sorry, Tomahawk couldn't find the album '%1' by %2 @@ -3668,37 +3668,37 @@ You can re-send a sync message at any time simply by sending another tweet using ViewManager - + After you have scanned your music collection you will find your tracks right here. After you have scanned your music collection you will find your tracks right here. - + This collection is empty. This collection is empty. - + SuperCollection SuperCollection - + Combined libraries of all your online friends Combined libraries of all your online friends - + Recently Played Tracks Recently Played Tracks - + Recently played tracks from all your friends Recently played tracks from all your friends - + Sorry, we could not find any recent plays! Sorry, we could not find any recent plays! diff --git a/lang/tomahawk_es.ts b/lang/tomahawk_es.ts index a3f14ea62..dcb69638e 100644 --- a/lang/tomahawk_es.ts +++ b/lang/tomahawk_es.ts @@ -303,17 +303,17 @@ connect and stream from you? AudioEngine - + Sorry, Tomahawk couldn't find the track '%1' by %2 - + Sorry, Tomahawk couldn't find the artist '%1' - + Sorry, Tomahawk couldn't find the album '%1' by %2 @@ -3666,37 +3666,37 @@ Puede reenviar el mensaje de sincronización en cualquier momento simplemente en ViewManager - + After you have scanned your music collection you will find your tracks right here. - + This collection is empty. - + SuperCollection SuperColección - + Combined libraries of all your online friends Bibliotecas combinadas de todos tus amigos conectados - + Recently Played Tracks Temas Escuchados Recientemente - + Recently played tracks from all your friends Temas escuchados recientemente por mis amigos - + Sorry, we could not find any recent plays! diff --git a/lang/tomahawk_fr.ts b/lang/tomahawk_fr.ts index 52f32c29d..55c217173 100644 --- a/lang/tomahawk_fr.ts +++ b/lang/tomahawk_fr.ts @@ -304,17 +304,17 @@ de se connecter et streamer de vous? AudioEngine - + Sorry, Tomahawk couldn't find the track '%1' by %2 Désolé, on a pas pu trouver la piste '%1' pour %2 - + Sorry, Tomahawk couldn't find the artist '%1' Désolé, on a pas pu trouver l'artiste '%1' - + Sorry, Tomahawk couldn't find the album '%1' by %2 Désolé, on a pas pu trouver l'album '%1' pour %2 @@ -3668,37 +3668,37 @@ Vous pouvez envoyer un message de synchronisation quand vous le souhaitez en env ViewManager - + After you have scanned your music collection you will find your tracks right here. Après avoir scanné votre collection musicale, vous trouverez tous vos titres ici. - + This collection is empty. La collection est vide. - + SuperCollection SuperCollection - + Combined libraries of all your online friends Collections regroupant toutes celles de vos amis en ligne - + Recently Played Tracks Derniers titres joués - + Recently played tracks from all your friends Derniers titres joués par vos amis - + Sorry, we could not find any recent plays! diff --git a/lang/tomahawk_ja.ts b/lang/tomahawk_ja.ts index aeb6af093..376774542 100644 --- a/lang/tomahawk_ja.ts +++ b/lang/tomahawk_ja.ts @@ -303,17 +303,17 @@ connect and stream from you? AudioEngine - + Sorry, Tomahawk couldn't find the track '%1' by %2 Tomahawkは%2の%1を見つかりませんでした。 - + Sorry, Tomahawk couldn't find the artist '%1' Tomahawkは'%1'と言うアーティストを見つかりませんでした。 - + Sorry, Tomahawk couldn't find the album '%1' by %2 Tomahawkは%2の%1を見つかりませんでした。 @@ -3661,37 +3661,37 @@ Twitterを使っている友達にTomahawkを接続したいなら、ツイー ViewManager - + After you have scanned your music collection you will find your tracks right here. コレクションのスキャンが完了したら、トラックはここに表示されます。 - + This collection is empty. このコレクションには何も入っていません。 - + SuperCollection スーパーコレクション - + Combined libraries of all your online friends オンラインの友達全員のライブラリ - + Recently Played Tracks 最近再生したトラック - + Recently played tracks from all your friends 友達の最近再生したトラック - + Sorry, we could not find any recent plays! diff --git a/lang/tomahawk_lt.ts b/lang/tomahawk_lt.ts index 7fc507f3a..b3dafcb85 100644 --- a/lang/tomahawk_lt.ts +++ b/lang/tomahawk_lt.ts @@ -137,7 +137,7 @@ connect and stream from you? Form - + Forma @@ -147,12 +147,12 @@ connect and stream from you? Sorry, we could not find any other albums for this artist! - + Atsiprašome, neradome jokių kitų šio atlikėjo albumų! Sorry, we could not find any tracks for this album! - + Atsiprašome, neradome jokių takelių iš šio albumo! @@ -179,7 +179,7 @@ connect and stream from you? Form - + Forma @@ -209,12 +209,12 @@ connect and stream from you? Sorry, we could not find any albums for this artist! - + Atsiprašome, neradome jokių šio atlikėjo albumų! Sorry, we could not find any related artists! - + Atsiprašome, neradome jokių susijusių atlikėjų! @@ -303,19 +303,19 @@ connect and stream from you? AudioEngine - + Sorry, Tomahawk couldn't find the track '%1' by %2 - + Atsiprašome, Tomahawk nepavyko rasti takelio '%1', atliekamo %2 - + Sorry, Tomahawk couldn't find the artist '%1' - + Atsiprašome, Tomahawk nepavyko rasti atlikėjo '%1' - + Sorry, Tomahawk couldn't find the album '%1' by %2 - + Atsiprašome, Tomahawk nepavyko rasti %2 atliekamo albumo '%1' @@ -486,7 +486,7 @@ connect and stream from you? Filter... - + Filtruoti... @@ -494,7 +494,7 @@ connect and stream from you? Form - + Forma @@ -523,12 +523,12 @@ connect and stream from you? Form - + Forma Scrobble tracks to Last.fm - + Pranešti grojamus takelius Last.fm @@ -613,7 +613,7 @@ connect and stream from you? Bookmarks - + Žymelės @@ -636,7 +636,7 @@ connect and stream from you? The most loved tracks from all your friends - + Visų Jūsų draugų labiausiai mylimos dainos @@ -659,12 +659,12 @@ connect and stream from you? Form - + Forma Tags - + Žymės @@ -800,7 +800,7 @@ connect and stream from you? New Releases - + Nauji leidimai @@ -882,7 +882,7 @@ connect and stream from you? Caption - + Pavadinimas @@ -894,7 +894,7 @@ connect and stream from you? RadioButton - + Akutė @@ -961,12 +961,12 @@ connect and stream from you? Just a regular old playlist... Give it a name, drag in some tracks, and go! - + Tiesiog senas geras grojaraštis... Suteikite jam vardą, įtempkite keletą dainų ir pirmyn! Don't know exactly what you want? Give Tomahawk a few pointers and let it build a playlist for you! - + Nežinote, ko tiksliai norite? Suteikite Tomahawk keletą nuorodų ir leiskite jam sukurti Jums grojaraštį! @@ -1181,7 +1181,7 @@ connect and stream from you? Related Artists - + Susiję atlikėjai @@ -1281,7 +1281,7 @@ connect and stream from you? Most Played Tracks You Don't Have - + Dažniausiai groti takeliai, kurių Jūs neturite @@ -1289,7 +1289,7 @@ connect and stream from you? Form - + Forma @@ -1304,12 +1304,12 @@ connect and stream from you? Cover - + Viršelis TextLabel - + Teksto etiketė @@ -1319,17 +1319,17 @@ connect and stream from you? Listening to "%1" by %2. %3 - + Klausosi "%1", atliekamą %2. %3 Listening to "%1" by %2 on "%3". %4 - + Klausosi "%1", atliekamą %2 iš albumo "%3". %4 %1 characters left - + Liko simbolių: %1 @@ -1421,7 +1421,7 @@ connect and stream from you? Latest Additions - + Neseniai pridėta @@ -1436,17 +1436,17 @@ connect and stream from you? Latest additions to your collection - + Neseniai pridėta prie Jūsų kolekcijos Latest additions to %1's collection - + Neseniai pridėta prie %1 kolekcijos Sorry, we could not find any recent additions! - + Atsiprašome, neradome nieko, kas pridėta neseniai! @@ -1466,7 +1466,7 @@ connect and stream from you? Sorry, we could not find any recent plays! - + Atsiprašome, neradome jokių neseniai grotų takelių! @@ -1520,7 +1520,7 @@ connect and stream from you? Would you like to delete the %1 <b>"%2"</b>? e.g. Would you like to delete the playlist named Foobar? - + Ar norite pašalinti %1 <b>"%2"</b>? @@ -1603,7 +1603,7 @@ connect and stream from you? New Releases - + Nauji leidimai @@ -1616,17 +1616,17 @@ connect and stream from you? Form - + Forma Configure your Spotify account - + Konfigūruoti Jūsų Spotify paskyrą Username or Facebook Email - + Vartotojo vardas arba Facebook elektroninis paštas @@ -1636,22 +1636,22 @@ connect and stream from you? Right click on any Tomahawk playlist to sync it to Spotify. - + Dešiniu pelės klavišu spustelėkite ant bet kurio Tomahawk grojaraščio, jei norite sinchronizuoti jį su Spotify. High Quality Streams - + Aukštos kokybės srautai Spotify playlists to keep in sync: - + Sinchronizuojami Spotify grojaraščiai: Delete Tomahawk playlist when removing synchronization - + Ištrinti Tomahawk grojaraštį kai panaikinamas sinchronizavimas @@ -1715,7 +1715,7 @@ connect and stream from you? Advanced Settings - + Išplėstinės nuostatos @@ -1745,12 +1745,12 @@ connect and stream from you? SOCKS Proxy - + SOCKS Proxy Use SOCKS Proxy - + Naudoti SOCKS Proxy @@ -1770,7 +1770,7 @@ connect and stream from you? Filter by capability: - + Filtruoti pagal gebėjimą: @@ -1790,7 +1790,7 @@ connect and stream from you? Other Settings - + Kitos nuostatos @@ -1800,7 +1800,7 @@ connect and stream from you? Allow web browsers to interact with Tomahawk (recommended) - + Leisti žiniatinklio naršyklėms sąveikauti su Tomahawk (rekomenduojama) @@ -1831,12 +1831,12 @@ connect and stream from you? Remove - + Pašalinti %1 downloads - + %1 atsisiuntimų @@ -1929,7 +1929,7 @@ connect and stream from you? Test Login - + Išbandyti prisijungimą @@ -1979,7 +1979,7 @@ connect and stream from you? Re-enable syncing with Spotify - + Iš naujo įjungti sinchronizavimą su Spotify @@ -1989,22 +1989,22 @@ connect and stream from you? Subscribe to playlist changes - + Sekti grojaraščio pokyčius Re-enable playlist subscription - + Sekti grojarašio atnaujinimus iš naujo Stop subscribing to changes - + Nebesekti grojaraščio pokyčių Stop syncing with Spotify - + Stabdyti sinchronizavimą su Spotify @@ -2033,7 +2033,7 @@ connect and stream from you? Log In - + Prisijungti @@ -2106,7 +2106,7 @@ You may wish to try re-authenticating. Status: Error validating credentials - + Būsena: Klaida tikrinant prisijungimo duomenis @@ -2154,7 +2154,7 @@ You may wish to try re-authenticating. There was an error posting your status -- sorry! - + Įvyko klaida siunčiant Jūsų būseną -- atsiprašome! @@ -2175,7 +2175,7 @@ You may wish to try re-authenticating. Your message has been posted! - + Jūsų žinutė sėkmingai išsiųsta! @@ -2211,7 +2211,7 @@ You may wish to try re-authenticating. Continue Playback after this &Track - + Tęsti grojimą po šio &takelio @@ -2222,7 +2222,7 @@ You may wish to try re-authenticating. &Love - + My&liu @@ -2242,12 +2242,12 @@ You may wish to try re-authenticating. Un-&Love - + Nemy&liu &Delete Items - + Iš&trinti elementus @@ -2262,7 +2262,7 @@ You may wish to try re-authenticating. &Delete Item - + Iš&trinti elementą @@ -2300,12 +2300,12 @@ You may wish to try re-authenticating. Fetching %1 from database - + Gaunama %1 iš duomenų bazės Parsing %1 %2 - + Nagrinėjama %1 %2 @@ -2436,12 +2436,12 @@ Try tweaking the filters for a new set of songs to play. 0 secs - + 0 sekundžių 3600 secs - + 3600 sekundžių @@ -2637,7 +2637,7 @@ Try tweaking the filters for a new set of songs to play. about %n minute(s) long - + apytikriai %n minutės ilgioapytikriai %n minučių ilgioapytikriai %n minučių ilgio @@ -2735,7 +2735,7 @@ Try tweaking the filters for a new set of songs to play. Energy - + Energija @@ -2822,12 +2822,12 @@ Try tweaking the filters for a new set of songs to play. Top Tracks - + Populiariausi takeliai Loved Tracks - + Mylimi takeliai @@ -2837,7 +2837,7 @@ Try tweaking the filters for a new set of songs to play. Top Artists - + Populiariausi atlikėjai @@ -3036,7 +3036,7 @@ Try tweaking the filters for a new set of songs to play. Automatically update from XSPF - + Automatiškai atnaujinti iš XSPF @@ -3066,7 +3066,7 @@ enter the displayed PIN number here: &Stop Playback after current Track - + Sta&bdyti grojimą po dabartinio takelio @@ -3082,7 +3082,7 @@ enter the displayed PIN number here: Currently not playing. - + Šiuo metu negrojama. @@ -3107,7 +3107,7 @@ enter the displayed PIN number here: &Continue Playback after current Track - + &Tęsti grojimą po dabartinio takelio @@ -3261,7 +3261,7 @@ enter the displayed PIN number here: Space - + Tarpas @@ -3296,7 +3296,7 @@ enter the displayed PIN number here: Global Search... - + Globali paieška... @@ -3421,7 +3421,7 @@ enter the displayed PIN number here: <h2><b>Tomahawk %1<br/>(%2)</h2> - + <h2><b>Tomahawk %1<br/>(%2)</h2> @@ -3457,7 +3457,7 @@ enter the displayed PIN number here: Form - + Forma @@ -3492,7 +3492,7 @@ enter the displayed PIN number here: Sorry, but we could not find similar tracks for this song! - + Atsiprašome, neradome jokių į šią dainą panašių takelių! @@ -3502,12 +3502,12 @@ enter the displayed PIN number here: You've never listened to this track before. - + Jūs niekad anksčiau nesiklausėte šio takelio. You first listened to it on %1. - + Pirmąkart klausėtės jo %1. @@ -3576,7 +3576,7 @@ enter the displayed PIN number here: Sorry, your filter '%1' did not match any results. - + Atsiprašome, Jūsų užklausa '%1' neatitiko jokių rezultatų. @@ -3584,7 +3584,7 @@ enter the displayed PIN number here: Configure this Twitter account - + Konfigūruoti šią Twitter paskyrą @@ -3594,7 +3594,7 @@ enter the displayed PIN number here: Status: No saved credentials - + Būsena: Nėra išsaugotų prisijungimo duomenų @@ -3634,12 +3634,12 @@ You can re-send a sync message at any time simply by sending another tweet using Direct Message - + Tiesioginė žinutė e.g. @tomahawk - + pvz. @tomahawk @@ -3650,37 +3650,37 @@ You can re-send a sync message at any time simply by sending another tweet using ViewManager - + After you have scanned your music collection you will find your tracks right here. - + Peržvelgus Jūsų muzikos kolekciją, savo takelius galėsite rasti čia akimirksniu. - + This collection is empty. Ši kolekcija yra tuščia. - - - SuperCollection - - - Combined libraries of all your online friends - + SuperCollection + Super kolekcija - + + Combined libraries of all your online friends + Jungtinė visų Jūsų prisijungusių draugų kolekcija + + + Recently Played Tracks Neseniai groti takeliai - + Recently played tracks from all your friends Visų Jūsų draugų neseniai groti takeliai - + Sorry, we could not find any recent plays! @@ -3690,22 +3690,22 @@ You can re-send a sync message at any time simply by sending another tweet using Recent Additions - + Neseniai pridėta Newest Stations & Playlists - + Naujausios stotys ir grojaraščiai Recently Played Tracks - + Neseniai groti takeliai No recently created playlists in your network. - + Jūsų tinkle nėra neseniai sukurtų grojaraščių. @@ -3795,7 +3795,7 @@ Lyrics for "%1" by %2: Xml stream console - + Xml srauto pultas @@ -3806,27 +3806,27 @@ Lyrics for "%1" by %2: Save log - + Išsaugoti žurnalą Disabled - + Išjungta By JID - + Pagal JID By namespace uri - + Pagal vardų erdvės uri By all attributes - + Pagal visus požymius @@ -3856,17 +3856,17 @@ Lyrics for "%1" by %2: Close - + Užverti Save XMPP log to file - + Išsaugoti XMPP žurnalą į failą OpenDocument Format (*.odf);;HTML file (*.html);;Plain text (*.txt) - + OpenDocument formatas (*.odf);;HTML failas (*.html);;Paprastas tekstas (*.txt) @@ -3874,32 +3874,32 @@ Lyrics for "%1" by %2: Xmpp Configuration - + Xmpp konfigūracija Configure this Xmpp account - + Konfigūruoti šią Xmpp paskyrą Enter your Xmpp login to connect with your friends using Tomahawk! - + Įveskite savo Xmpp prisijungimo duomenis, jei norite prisijungti prie savo draugų, besinaudojančių Tomahawk! Login Information - + Prisijungimo informacija Xmpp ID: - + Xmpp ID: e.g. user@example.com - + pvz. user@example.com @@ -3909,12 +3909,12 @@ Lyrics for "%1" by %2: An account with this name already exists! - + Paskyra šiuo vardu jau yra! Advanced Xmpp Settings - + Išplėstinės Xmpp nuostatos @@ -3929,17 +3929,17 @@ Lyrics for "%1" by %2: Lots of servers don't support this (e.g. GTalk, jabber.org) - + Daugybė serverių to nepalaiko (pvz. GTalk, jabber.org) Publish currently playing track - + Viešinti šiuo metu grojamą takelį Enforce secure connection - + Priverstinai naudoti saugų prisijungimą @@ -3947,37 +3947,37 @@ Lyrics for "%1" by %2: User Interaction - + Vartotojo sąveika Host is unknown - + Serveris nežinomas Item not found - + Elementas nerastas Authorization Error - + Tapatybės patvirtinimo klaida Remote Stream Error - + Nuotolinio srauto klaida Remote Connection failed - + Nuotolinis prisijungimas nepavyko Internal Server Error - + Vidinė serverio klaida @@ -3987,7 +3987,7 @@ Lyrics for "%1" by %2: Conflict - + Konfliktas @@ -4002,12 +4002,12 @@ Lyrics for "%1" by %2: No Compression Support - + Nėra glaudinimo palaikymo No Encryption Support - + Nėra užšifravimo palaikymo @@ -4027,7 +4027,7 @@ Lyrics for "%1" by %2: Enter Xmpp ID: - + Įveskite Xmpp ID: @@ -4037,7 +4037,7 @@ Lyrics for "%1" by %2: XML Console... - + XML pultas... @@ -4055,12 +4055,12 @@ Lyrics for "%1" by %2: Form - + Forma Local Network configuration - + Vietinio tinklo konfigūracija @@ -4070,7 +4070,7 @@ Lyrics for "%1" by %2: Connect automatically when Tomahawk starts - + Prisijungti automatiškai kai Tomahawk paleidžiamas \ No newline at end of file diff --git a/lang/tomahawk_pl.ts b/lang/tomahawk_pl.ts index 8b6943723..bfba9303e 100644 --- a/lang/tomahawk_pl.ts +++ b/lang/tomahawk_pl.ts @@ -303,17 +303,17 @@ connect and stream from you? AudioEngine - + Sorry, Tomahawk couldn't find the track '%1' by %2 - + Sorry, Tomahawk couldn't find the artist '%1' - + Sorry, Tomahawk couldn't find the album '%1' by %2 @@ -3662,37 +3662,37 @@ Zawsze możesz ponownie wysłać wiadomość synchronizacyjną - po prostu wyśl ViewManager - + After you have scanned your music collection you will find your tracks right here. - + This collection is empty. - + SuperCollection SuperKolekcja - + Combined libraries of all your online friends Połączone biblioteki wszystkich twoich znajomych online - + Recently Played Tracks - + Recently played tracks from all your friends - + Sorry, we could not find any recent plays! diff --git a/lang/tomahawk_pt_BR.ts b/lang/tomahawk_pt_BR.ts index ff07bc43d..b70be8031 100644 --- a/lang/tomahawk_pt_BR.ts +++ b/lang/tomahawk_pt_BR.ts @@ -304,17 +304,17 @@ se conecte e faça o stream de você? AudioEngine - + Sorry, Tomahawk couldn't find the track '%1' by %2 Desculpe, o Tomahawk não encontrou a faixa '%1' de %2 - + Sorry, Tomahawk couldn't find the artist '%1' Desculpe, o Tomahawk não encontrou o artista '%1' - + Sorry, Tomahawk couldn't find the album '%1' by %2 Desculpe, o Tomahawk não encontrou o álbum '%1' de %2 @@ -3668,37 +3668,37 @@ Você pode enviar uma outra mensagem de sincronia a qualquer momento simplesment ViewManager - + After you have scanned your music collection you will find your tracks right here. Depois de escanear sua biblioteca de músicas as faixas irão aparecer aqui. - + This collection is empty. Esta coleção esta vazia. - + SuperCollection SuperColeção - + Combined libraries of all your online friends Bibliotecas combinadas de todos os seus amigos online - + Recently Played Tracks Faixas Reproduzidas Recentemente - + Recently played tracks from all your friends Faixas reproduzidas recentemente por todos os seus amigos - + Sorry, we could not find any recent plays! diff --git a/lang/tomahawk_ru.ts b/lang/tomahawk_ru.ts index 62fe0a1c4..de87cd21e 100644 --- a/lang/tomahawk_ru.ts +++ b/lang/tomahawk_ru.ts @@ -304,17 +304,17 @@ connect and stream from you? AudioEngine - + Sorry, Tomahawk couldn't find the track '%1' by %2 К сожалению, Tomahawk не мог найти песню '%1' %2 - + Sorry, Tomahawk couldn't find the artist '%1' К сожалению, Tomahawk не мог найти исполнителя '%1' - + Sorry, Tomahawk couldn't find the album '%1' by %2 К сожалению, Tomahawk не мог найти альбом '%1' %2 @@ -3661,37 +3661,37 @@ You can re-send a sync message at any time simply by sending another tweet using ViewManager - + After you have scanned your music collection you will find your tracks right here. После сканирования вашей музыкальной коллекции вы найдете треки прямо здесь. - + This collection is empty. Коллекция пуста - + SuperCollection Общая коллекция - + Combined libraries of all your online friends Комбинированные библиотек всех ваших друзей онлайн - + Recently Played Tracks Последние Воспроизводимые Песни - + Recently played tracks from all your friends Последние воспроизводимые песни все ваших друзей - + Sorry, we could not find any recent plays! К сожалению, мы не смогли найти никаких воспроизвидений песен! diff --git a/lang/tomahawk_sv.ts b/lang/tomahawk_sv.ts index ade068ffe..3600e5f68 100644 --- a/lang/tomahawk_sv.ts +++ b/lang/tomahawk_sv.ts @@ -303,17 +303,17 @@ connect and stream from you? AudioEngine - + Sorry, Tomahawk couldn't find the track '%1' by %2 - + Sorry, Tomahawk couldn't find the artist '%1' - + Sorry, Tomahawk couldn't find the album '%1' by %2 @@ -3651,37 +3651,37 @@ You can re-send a sync message at any time simply by sending another tweet using ViewManager - + After you have scanned your music collection you will find your tracks right here. - + This collection is empty. - + SuperCollection - + Combined libraries of all your online friends - + Recently Played Tracks - + Recently played tracks from all your friends - + Sorry, we could not find any recent plays! diff --git a/lang/tomahawk_tr.ts b/lang/tomahawk_tr.ts index fe6c382d7..99ee00d17 100644 --- a/lang/tomahawk_tr.ts +++ b/lang/tomahawk_tr.ts @@ -303,17 +303,17 @@ connect and stream from you? AudioEngine - + Sorry, Tomahawk couldn't find the track '%1' by %2 - + Sorry, Tomahawk couldn't find the artist '%1' - + Sorry, Tomahawk couldn't find the album '%1' by %2 @@ -3650,37 +3650,37 @@ You can re-send a sync message at any time simply by sending another tweet using ViewManager - + After you have scanned your music collection you will find your tracks right here. - + This collection is empty. - + SuperCollection - + Combined libraries of all your online friends - + Recently Played Tracks - + Recently played tracks from all your friends - + Sorry, we could not find any recent plays! diff --git a/lang/tomahawk_zh_CN.ts b/lang/tomahawk_zh_CN.ts index 1e777f7be..23391e90e 100644 --- a/lang/tomahawk_zh_CN.ts +++ b/lang/tomahawk_zh_CN.ts @@ -303,17 +303,17 @@ connect and stream from you? AudioEngine - + Sorry, Tomahawk couldn't find the track '%1' by %2 - + Sorry, Tomahawk couldn't find the artist '%1' - + Sorry, Tomahawk couldn't find the album '%1' by %2 @@ -3650,37 +3650,37 @@ You can re-send a sync message at any time simply by sending another tweet using ViewManager - + After you have scanned your music collection you will find your tracks right here. - + This collection is empty. - + SuperCollection - + Combined libraries of all your online friends - + Recently Played Tracks 最近播放曲目 - + Recently played tracks from all your friends 所有朋友最近播放的曲目 - + Sorry, we could not find any recent plays! diff --git a/lang/tomahawk_zh_TW.ts b/lang/tomahawk_zh_TW.ts index b615088dd..5310aa494 100644 --- a/lang/tomahawk_zh_TW.ts +++ b/lang/tomahawk_zh_TW.ts @@ -303,17 +303,17 @@ connect and stream from you? AudioEngine - + Sorry, Tomahawk couldn't find the track '%1' by %2 - + Sorry, Tomahawk couldn't find the artist '%1' - + Sorry, Tomahawk couldn't find the album '%1' by %2 @@ -3650,37 +3650,37 @@ You can re-send a sync message at any time simply by sending another tweet using ViewManager - + After you have scanned your music collection you will find your tracks right here. - + This collection is empty. - + SuperCollection 超級收藏 - + Combined libraries of all your online friends 聯合您所有線上朋友的音樂庫 - + Recently Played Tracks - + Recently played tracks from all your friends - + Sorry, we could not find any recent plays! From adde983572e0af618d3aee601b2f06b2f891adee Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Mon, 30 Jul 2012 19:51:17 -0400 Subject: [PATCH 47/79] When double-clicking on a track in grid view, go to the track page --- src/libtomahawk/playlist/GridView.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libtomahawk/playlist/GridView.cpp b/src/libtomahawk/playlist/GridView.cpp index c1d85aa14..6714bd97f 100644 --- a/src/libtomahawk/playlist/GridView.cpp +++ b/src/libtomahawk/playlist/GridView.cpp @@ -213,7 +213,7 @@ GridView::onItemActivated( const QModelIndex& index ) else if ( !item->artist().isNull() ) ViewManager::instance()->show( item->artist() ); else if ( !item->query().isNull() ) - AudioEngine::instance()->playItem( playlistinterface_ptr(), item->query() ); + ViewManager::instance()->show( item->query() ); } } From 2c3e7492a5df183e14dbea7ac4a7059dcbf83328 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Mon, 30 Jul 2012 19:51:47 -0400 Subject: [PATCH 48/79] Jump to and scroll to playing track in grid view on track page --- src/libtomahawk/playlist/GridView.cpp | 11 ++++++ src/libtomahawk/playlist/GridView.h | 1 + .../widgets/infowidgets/TrackInfoWidget.cpp | 39 +++++++++++++------ .../widgets/infowidgets/TrackInfoWidget.h | 4 +- 4 files changed, 43 insertions(+), 12 deletions(-) diff --git a/src/libtomahawk/playlist/GridView.cpp b/src/libtomahawk/playlist/GridView.cpp index 6714bd97f..4c5e635ca 100644 --- a/src/libtomahawk/playlist/GridView.cpp +++ b/src/libtomahawk/playlist/GridView.cpp @@ -417,4 +417,15 @@ GridView::jumpToCurrentTrack() return true; } + +QRect +GridView::currentTrackRect() const +{ + if ( !m_playing.isValid() ) + return QRect(); + + return visualRect( m_playing ); +} + + #include "GridView.moc" diff --git a/src/libtomahawk/playlist/GridView.h b/src/libtomahawk/playlist/GridView.h index 13e8fa10b..a5b006d2b 100644 --- a/src/libtomahawk/playlist/GridView.h +++ b/src/libtomahawk/playlist/GridView.h @@ -72,6 +72,7 @@ public: virtual bool setFilter( const QString& filter ); virtual bool jumpToCurrentTrack(); + QRect currentTrackRect() const; virtual bool isBeingPlayed() const { return m_playing.isValid(); } diff --git a/src/libtomahawk/widgets/infowidgets/TrackInfoWidget.cpp b/src/libtomahawk/widgets/infowidgets/TrackInfoWidget.cpp index 98d20957f..c8c4f4a45 100644 --- a/src/libtomahawk/widgets/infowidgets/TrackInfoWidget.cpp +++ b/src/libtomahawk/widgets/infowidgets/TrackInfoWidget.cpp @@ -38,6 +38,7 @@ using namespace Tomahawk; TrackInfoWidget::TrackInfoWidget( const Tomahawk::query_ptr& query, QWidget* parent ) : QWidget( parent ) , ui( new Ui::TrackInfoWidget ) + , m_scrollArea( 0 ) { QWidget* widget = new QWidget; ui->setupUi( widget ); @@ -98,17 +99,17 @@ TrackInfoWidget::TrackInfoWidget( const Tomahawk::query_ptr& query, QWidget* par m_pixmap = TomahawkUtils::defaultPixmap( TomahawkUtils::DefaultAlbumCover, TomahawkUtils::ScaledCover, QSize( 48, 48 ) ); ui->cover->setPixmap( TomahawkUtils::defaultPixmap( TomahawkUtils::DefaultTrackImage, TomahawkUtils::ScaledCover, QSize( ui->cover->sizeHint() ) ) ); - QScrollArea* area = new QScrollArea(); - area->setWidgetResizable( true ); - area->setWidget( widget ); - area->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOn ); + m_scrollArea = new QScrollArea(); + m_scrollArea->setWidgetResizable( true ); + m_scrollArea->setWidget( widget ); + m_scrollArea->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOn ); - area->setStyleSheet( "QScrollArea { background-color: #454e59 }" ); - area->setFrameShape( QFrame::NoFrame ); - area->setAttribute( Qt::WA_MacShowFocusRect, 0 ); + m_scrollArea->setStyleSheet( "QScrollArea { background-color: #454e59 }" ); + m_scrollArea->setFrameShape( QFrame::NoFrame ); + m_scrollArea->setAttribute( Qt::WA_MacShowFocusRect, 0 ); QVBoxLayout* layout = new QVBoxLayout(); - layout->addWidget( area ); + layout->addWidget( m_scrollArea ); setLayout( layout ); TomahawkUtils::unmarginLayout( layout ); @@ -141,12 +142,28 @@ TrackInfoWidget::playlistInterface() const bool TrackInfoWidget::isBeingPlayed() const { - //tDebug() << Q_FUNC_INFO << "audioengine playlistInterface = " << AudioEngine::instance()->currentTrackPlaylist()->id(); - //tDebug() << Q_FUNC_INFO << "albumsView playlistInterface = " << ui->albumsView->playlistInterface()->id(); - //tDebug() << Q_FUNC_INFO << "tracksView playlistInterface = " << ui->tracksView->playlistInterface()->id(); if ( ui->similarTracksView->playlistInterface() == AudioEngine::instance()->currentTrackPlaylist() ) return true; + if ( ui->similarTracksView->playlistInterface()->hasChildInterface( AudioEngine::instance()->currentTrackPlaylist() ) ) + return true; + + return false; +} + + +bool +TrackInfoWidget::jumpToCurrentTrack() +{ + if ( ui->similarTracksView->jumpToCurrentTrack() && !ui->similarTracksView->currentTrackRect().isEmpty() ) + { + // We embed the view in a scrollarea, so we have to manually ensure we make it visible + const QRect itemRect = ui->similarTracksView->currentTrackRect(); + m_scrollArea->ensureVisible( itemRect.right(), itemRect.bottom(), 50, 50 ); + + return true; + } + return false; } diff --git a/src/libtomahawk/widgets/infowidgets/TrackInfoWidget.h b/src/libtomahawk/widgets/infowidgets/TrackInfoWidget.h index 48766be37..1e26ebfae 100644 --- a/src/libtomahawk/widgets/infowidgets/TrackInfoWidget.h +++ b/src/libtomahawk/widgets/infowidgets/TrackInfoWidget.h @@ -40,6 +40,7 @@ #include "Typedefs.h" class PlayableModel; +class QScrollArea; namespace Ui { @@ -68,7 +69,7 @@ public: virtual bool isTemporaryPage() const { return true; } virtual bool showInfoBar() const { return false; } - virtual bool jumpToCurrentTrack() { return false; } + virtual bool jumpToCurrentTrack(); public slots: void load( const Tomahawk::query_ptr& query ); @@ -88,6 +89,7 @@ private slots: private: Ui::TrackInfoWidget *ui; + QScrollArea* m_scrollArea; Tomahawk::query_ptr m_query; Tomahawk::artist_ptr m_artist; From a70f14e7ab206c74e538cbc6482daee7aee74c08 Mon Sep 17 00:00:00 2001 From: Tomahawk CI Date: Wed, 1 Aug 2012 00:17:58 +0200 Subject: [PATCH 49/79] Automatic merge of Transifex translations --- lang/tomahawk_ar.ts | 12 ++++++------ lang/tomahawk_bg.ts | 12 ++++++------ lang/tomahawk_ca.ts | 12 ++++++------ lang/tomahawk_de.ts | 12 ++++++------ lang/tomahawk_en.ts | 12 ++++++------ lang/tomahawk_es.ts | 12 ++++++------ lang/tomahawk_fr.ts | 12 ++++++------ lang/tomahawk_ja.ts | 12 ++++++------ lang/tomahawk_lt.ts | 12 ++++++------ lang/tomahawk_pl.ts | 12 ++++++------ lang/tomahawk_pt_BR.ts | 12 ++++++------ lang/tomahawk_ru.ts | 12 ++++++------ lang/tomahawk_sv.ts | 12 ++++++------ lang/tomahawk_tr.ts | 12 ++++++------ lang/tomahawk_zh_CN.ts | 12 ++++++------ lang/tomahawk_zh_TW.ts | 12 ++++++------ 16 files changed, 96 insertions(+), 96 deletions(-) diff --git a/lang/tomahawk_ar.ts b/lang/tomahawk_ar.ts index 4dcfe636e..87bef4c6d 100644 --- a/lang/tomahawk_ar.ts +++ b/lang/tomahawk_ar.ts @@ -3503,32 +3503,32 @@ enter the displayed PIN number here: أغاني قريبة - + Sorry, but we could not find similar tracks for this song! نعتذر، لم نستطيع إيجاد أغاني قريبة من هذه الأغنية! - + You've listened to this track %n time(s). لقد استمعت إلى هذه الأغنية %n مرة.لقد استمعت إلى هذه الأغنية مرة %n.لقد استمعت إلى هذه الأغنية مرتين %n.لقد استمعت إلى هذه الأغنية %n مرات.لقد استمعت إلى هذه الأغنية %n مرات.لقد استمعت إلى هذه الأغنية %n مرات. - + You've never listened to this track before. لم تستمع لهذه الأغنية من قبل. - + You first listened to it on %1. استمعت إليها أولاً في %1. - + You've listened to %1 %n time(s). لقد استمعت إلى %1 %n مرة.لقد استمعت إلى %1 مرة %n.لقد استمعت إلى %1 مرتين %n.لقد استمعت إلى %1 %n مرات.لقد استمعت إلى %1 %n مرات.لقد استمعت إلى %1 %n مرات. - + You've never listened to %1 before. لم تستمع إلى %1 من قبل. diff --git a/lang/tomahawk_bg.ts b/lang/tomahawk_bg.ts index a31de7729..d1623802e 100644 --- a/lang/tomahawk_bg.ts +++ b/lang/tomahawk_bg.ts @@ -3513,32 +3513,32 @@ enter the displayed PIN number here: Подобни песни - + Sorry, but we could not find similar tracks for this song! Съжалявам, но не откривам нито една подобна на тази песен! - + You've listened to this track %n time(s). Ти си слушал тази песен %n път(и)Ти си слушал тази песен %n път(и) - + You've never listened to this track before. Никога не си слушал тази песен преди - + You first listened to it on %1. Първоначално си я слушал на %1 - + You've listened to %1 %n time(s). Слушал си %1 път(и)Слушал си %1 %n път(и) - + You've never listened to %1 before. Никога не си слушал %1 преди diff --git a/lang/tomahawk_ca.ts b/lang/tomahawk_ca.ts index d982ec637..8a00c725b 100644 --- a/lang/tomahawk_ca.ts +++ b/lang/tomahawk_ca.ts @@ -3502,32 +3502,32 @@ introduïu el PIN aquí: Cançons Semblants - + Sorry, but we could not find similar tracks for this song! - + You've listened to this track %n time(s). Heu escoltat aquesta cançó %n cop.Heu escoltat aquesta cançó %n cops. - + You've never listened to this track before. No heu escoltat mai aquesta cançó abans. - + You first listened to it on %1. Vau escoltar aquesta cançó per primer cop el %1. - + You've listened to %1 %n time(s). Heu escoltat %1 %n cop.Heu escoltat %1 %n cops. - + You've never listened to %1 before. No heu escoltat mai %1 abans. diff --git a/lang/tomahawk_de.ts b/lang/tomahawk_de.ts index b6a80f863..aba234270 100644 --- a/lang/tomahawk_de.ts +++ b/lang/tomahawk_de.ts @@ -3498,32 +3498,32 @@ Tomahawk auf Twitter's Website authentifiziert hast: Ähnliche Lieder - + Sorry, but we could not find similar tracks for this song! Sorry, wir konnten keine ähnlichen Lieder finden! - + You've listened to this track %n time(s). Du hast dieses Lied einmal gehört.Du hast dieses Lied %n mal gehört. - + You've never listened to this track before. Du hast dieses Lied noch nie angehört. - + You first listened to it on %1. Du hast dieses Lied zum ersten mal am %1 gehört. - + You've listened to %1 %n time(s). Du hast %1 einmal angehört.Du hast %1 %n mal angehört. - + You've never listened to %1 before. Du hast %1 vorher noch nie gehört. diff --git a/lang/tomahawk_en.ts b/lang/tomahawk_en.ts index de44ed72f..286b5f63a 100644 --- a/lang/tomahawk_en.ts +++ b/lang/tomahawk_en.ts @@ -3503,32 +3503,32 @@ enter the displayed PIN number here: Similar Tracks - + Sorry, but we could not find similar tracks for this song! Sorry, but we could not find similar tracks for this song! - + You've listened to this track %n time(s). You've listened to this track %n time.You've listened to this track %n times. - + You've never listened to this track before. You've never listened to this track before. - + You first listened to it on %1. You first listened to it on %1. - + You've listened to %1 %n time(s). You've listened to %1 %n time.You've listened to %1 %n times. - + You've never listened to %1 before. You've never listened to %1 before. diff --git a/lang/tomahawk_es.ts b/lang/tomahawk_es.ts index dcb69638e..f218c78ab 100644 --- a/lang/tomahawk_es.ts +++ b/lang/tomahawk_es.ts @@ -3501,32 +3501,32 @@ introduzca su número PIN aquí: Temas Similares - + Sorry, but we could not find similar tracks for this song! - + You've listened to this track %n time(s). Ha escuchado esta canción %n vez.Ha escuchado esta canción %n veces. - + You've never listened to this track before. Nunca ha escuchado este tema antes. - + You first listened to it on %1. Escuchó este tema pro primera vez en %1. - + You've listened to %1 %n time(s). Ha escuchado %1 %n vez.Ha escuchado %1 %n veces. - + You've never listened to %1 before. Nunca ha escuchado %1 antes. diff --git a/lang/tomahawk_fr.ts b/lang/tomahawk_fr.ts index 55c217173..a4c40e996 100644 --- a/lang/tomahawk_fr.ts +++ b/lang/tomahawk_fr.ts @@ -3503,32 +3503,32 @@ saisissez le numéro PIN ici : Piste similaire - + Sorry, but we could not find similar tracks for this song! Désolé, on a pas pu trouver aucune pistes pour cette chanson! - + You've listened to this track %n time(s). Vous avez écouté cette piste %n fois.Vous avez écouté cette piste %n fois. - + You've never listened to this track before. Vous n'avez encore jamais écouté cette piste. - + You first listened to it on %1. Vous l'avez écouté pour la première fois le %1. - + You've listened to %1 %n time(s). Vous avez écouté %1 %n fois.Vous avez écouté %1 %n fois. - + You've never listened to %1 before. Vous n'avez encore jamais écouté %1. diff --git a/lang/tomahawk_ja.ts b/lang/tomahawk_ja.ts index 376774542..91ee2d615 100644 --- a/lang/tomahawk_ja.ts +++ b/lang/tomahawk_ja.ts @@ -3496,32 +3496,32 @@ Meta+Ctrl+Z 似ているトラック - + Sorry, but we could not find similar tracks for this song! この曲に似ているトラックが見つかりませんでした。 - + You've listened to this track %n time(s). このトラックは%n回聴いています。 - + You've never listened to this track before. このトラックを一度も聴いていません。 - + You first listened to it on %1. 初めてこの曲を聴いたのは、%1です。 - + You've listened to %1 %n time(s). %1を%n回聴いています。 - + You've never listened to %1 before. %1を一度も聴いていません。 diff --git a/lang/tomahawk_lt.ts b/lang/tomahawk_lt.ts index b3dafcb85..ed385a489 100644 --- a/lang/tomahawk_lt.ts +++ b/lang/tomahawk_lt.ts @@ -3490,32 +3490,32 @@ enter the displayed PIN number here: Panašūs takeliai - + Sorry, but we could not find similar tracks for this song! Atsiprašome, neradome jokių į šią dainą panašių takelių! - + You've listened to this track %n time(s). Jūs klausėtės šio takelio %n kartą.Jūs klausėtės šio takelio %n kartus.Jūs klausėtės šio takelio %n kartų. - + You've never listened to this track before. Jūs niekad anksčiau nesiklausėte šio takelio. - + You first listened to it on %1. Pirmąkart klausėtės jo %1. - + You've listened to %1 %n time(s). Jūs klausėtės %1 %n kartą.Jūs klausėtės %1 %n kartus.Jūs klausėtės %1 %n kartų. - + You've never listened to %1 before. Jūs niekada anksčiau nesiklausėte %1. diff --git a/lang/tomahawk_pl.ts b/lang/tomahawk_pl.ts index bfba9303e..60284577d 100644 --- a/lang/tomahawk_pl.ts +++ b/lang/tomahawk_pl.ts @@ -3497,32 +3497,32 @@ wprowadź pokazany numer PIN tutaj: - + Sorry, but we could not find similar tracks for this song! - + You've listened to this track %n time(s). - + You've never listened to this track before. - + You first listened to it on %1. - + You've listened to %1 %n time(s). - + You've never listened to %1 before. diff --git a/lang/tomahawk_pt_BR.ts b/lang/tomahawk_pt_BR.ts index b70be8031..93ed8315a 100644 --- a/lang/tomahawk_pt_BR.ts +++ b/lang/tomahawk_pt_BR.ts @@ -3503,32 +3503,32 @@ colocar o número PIN mostrado aqui: Faixas Similares - + Sorry, but we could not find similar tracks for this song! Desculpe, mas não conseguimos encontrar faixas similares para esta música! - + You've listened to this track %n time(s). Você ouviu esta faixa %n vez.Você ouviu esta faixa %n vezes. - + You've never listened to this track before. Você nunca ouviu esta faixa antes. - + You first listened to it on %1. Você ouviu pela primeira vez em %1. - + You've listened to %1 %n time(s). Você ouviu %1 %n vez.Você ouviu %1 %n vezes. - + You've never listened to %1 before. Você nunca ouviu %1 antes. diff --git a/lang/tomahawk_ru.ts b/lang/tomahawk_ru.ts index de87cd21e..a616be0ef 100644 --- a/lang/tomahawk_ru.ts +++ b/lang/tomahawk_ru.ts @@ -3497,32 +3497,32 @@ enter the displayed PIN number here: Похожие Песни - + Sorry, but we could not find similar tracks for this song! Извините, но мы не смогли найти похожие треки на эту песню! - + You've listened to this track %n time(s). - + You've never listened to this track before. Вы никогда не слушали этот трек раньше. - + You first listened to it on %1. Первое прослушивание этой песни %1. - + You've listened to %1 %n time(s). - + You've never listened to %1 before. Вы никогда не слушали %1 до этого. diff --git a/lang/tomahawk_sv.ts b/lang/tomahawk_sv.ts index 3600e5f68..979264ac2 100644 --- a/lang/tomahawk_sv.ts +++ b/lang/tomahawk_sv.ts @@ -3491,32 +3491,32 @@ enter the displayed PIN number here: - + Sorry, but we could not find similar tracks for this song! - + You've listened to this track %n time(s). - + You've never listened to this track before. - + You first listened to it on %1. - + You've listened to %1 %n time(s). - + You've never listened to %1 before. diff --git a/lang/tomahawk_tr.ts b/lang/tomahawk_tr.ts index 99ee00d17..afb0133c1 100644 --- a/lang/tomahawk_tr.ts +++ b/lang/tomahawk_tr.ts @@ -3490,32 +3490,32 @@ enter the displayed PIN number here: - + Sorry, but we could not find similar tracks for this song! - + You've listened to this track %n time(s). - + You've never listened to this track before. - + You first listened to it on %1. - + You've listened to %1 %n time(s). - + You've never listened to %1 before. diff --git a/lang/tomahawk_zh_CN.ts b/lang/tomahawk_zh_CN.ts index 23391e90e..4857d6754 100644 --- a/lang/tomahawk_zh_CN.ts +++ b/lang/tomahawk_zh_CN.ts @@ -3490,32 +3490,32 @@ enter the displayed PIN number here: - + Sorry, but we could not find similar tracks for this song! - + You've listened to this track %n time(s). - + You've never listened to this track before. - + You first listened to it on %1. - + You've listened to %1 %n time(s). - + You've never listened to %1 before. diff --git a/lang/tomahawk_zh_TW.ts b/lang/tomahawk_zh_TW.ts index 5310aa494..b1e903722 100644 --- a/lang/tomahawk_zh_TW.ts +++ b/lang/tomahawk_zh_TW.ts @@ -3490,32 +3490,32 @@ enter the displayed PIN number here: - + Sorry, but we could not find similar tracks for this song! - + You've listened to this track %n time(s). - + You've never listened to this track before. - + You first listened to it on %1. - + You've listened to %1 %n time(s). - + You've never listened to %1 before. From 26509493a2b5763cedb9c7ae99a6fdba311b2e76 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Mon, 30 Jul 2012 20:53:18 -0400 Subject: [PATCH 50/79] Initial last.fm loved track syncing --- src/libtomahawk/Query.cpp | 15 +- src/libtomahawk/Query.h | 2 +- .../accounts/lastfm/LastFmAccount.h | 1 + .../accounts/lastfm/LastFmConfig.cpp | 164 +++++++++++++++++- .../accounts/lastfm/LastFmConfig.h | 23 ++- .../accounts/lastfm/LastFmConfig.ui | 9 +- .../DatabaseCommand_LoadSocialActions.cpp | 100 +++++++---- .../DatabaseCommand_LoadSocialActions.h | 24 ++- 8 files changed, 284 insertions(+), 54 deletions(-) diff --git a/src/libtomahawk/Query.cpp b/src/libtomahawk/Query.cpp index 24b219d7d..444bace2e 100644 --- a/src/libtomahawk/Query.cpp +++ b/src/libtomahawk/Query.cpp @@ -459,14 +459,19 @@ Query::checkResults() bool -Query::equals( const Tomahawk::query_ptr& other ) const +Query::equals( const Tomahawk::query_ptr& other, bool ignoreCase ) const { if ( other.isNull() ) return false; - return ( artist() == other->artist() && - album() == other->album() && - track() == other->track() ); + if ( ignoreCase ) + return ( artist().toLower() == other->artist().toLower() && + album().toLower() == other->album().toLower() && + track().toLower() == other->track().toLower() ); + else + return ( artist() == other->artist() && + album() == other->album() && + track() == other->track() ); } @@ -502,7 +507,7 @@ Query::howSimilar( const Tomahawk::result_ptr& r ) 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(); diff --git a/src/libtomahawk/Query.h b/src/libtomahawk/Query.h index 62ee4e6ac..be8f3d613 100644 --- a/src/libtomahawk/Query.h +++ b/src/libtomahawk/Query.h @@ -122,7 +122,7 @@ public: void setAlbumPos( unsigned int albumpos ) { m_albumpos = albumpos; } void setDiscNumber( unsigned int discnumber ) { m_discnumber = discnumber; } - bool equals( const Tomahawk::query_ptr& other ) const; + bool equals( const Tomahawk::query_ptr& other, bool ignoreCase = false ) const; QVariant toVariant() const; QString toString() const; diff --git a/src/libtomahawk/accounts/lastfm/LastFmAccount.h b/src/libtomahawk/accounts/lastfm/LastFmAccount.h index f1b7ffc0c..ef4bbea3b 100644 --- a/src/libtomahawk/accounts/lastfm/LastFmAccount.h +++ b/src/libtomahawk/accounts/lastfm/LastFmAccount.h @@ -26,6 +26,7 @@ #include #include +#include namespace Tomahawk { class ExternalResolverGui; diff --git a/src/libtomahawk/accounts/lastfm/LastFmConfig.cpp b/src/libtomahawk/accounts/lastfm/LastFmConfig.cpp index aceea6bff..f6151d2c4 100644 --- a/src/libtomahawk/accounts/lastfm/LastFmConfig.cpp +++ b/src/libtomahawk/accounts/lastfm/LastFmConfig.cpp @@ -1,6 +1,6 @@ /* === This file is part of Tomahawk Player - === * - * Copyright 2010-2011, Leo Franchi + * Copyright 2010-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 @@ -22,11 +22,16 @@ #include "LastFmAccount.h" #include "database/Database.h" #include "database/DatabaseCommand_LogPlayback.h" +#include +#include #include "utils/TomahawkUtils.h" #include "utils/Logger.h" -#include "lastfm/ws.h" -#include "lastfm/User.h" -#include "lastfm/XmlQuery.h" +#include "utils/Closure.h" + +#include +#include +#include +#include using namespace Tomahawk::Accounts; @@ -36,6 +41,8 @@ LastFmConfig::LastFmConfig( LastFmAccount* account ) , m_account( account ) , m_page( 1 ) , m_lastTimeStamp( 0 ) + , m_totalLovedPages( -1 ) + , m_doneFetchingLoved( false ) { m_ui = new Ui_LastFmConfig; m_ui->setupUi( this ); @@ -48,6 +55,7 @@ LastFmConfig::LastFmConfig( LastFmAccount* account ) connect( m_ui->testLogin, SIGNAL( clicked( bool ) ), SLOT( testLogin() ) ); connect( m_ui->importHistory, SIGNAL( clicked( bool ) ), SLOT( loadHistory() ) ); + connect( m_ui->syncLovedTracks, SIGNAL( clicked( bool ) ), SLOT( syncLovedTracks() ) ); connect( m_ui->username, SIGNAL( textChanged( QString ) ), SLOT( enableButton() ) ); connect( m_ui->password, SIGNAL( textChanged( QString ) ), SLOT( enableButton() ) ); @@ -141,7 +149,7 @@ LastFmConfig::onHistoryLoaded() foreach ( lastfm::XmlQuery e, lfm.children( "track" ) ) { // tDebug() << "Found:" << e.children( "artist" ).first()["name"].text() << e["name"].text() << e["date"].attribute( "uts" ).toUInt(); - Tomahawk::query_ptr query = Query::get( e.children( "artist" ).first()["name"].text(), e["name"].text(), QString(), QString(), false ); + Tomahawk::query_ptr query = Tomahawk::Query::get( e.children( "artist" ).first()["name"].text(), e["name"].text(), QString(), QString(), false ); if ( query.isNull() ) continue; @@ -237,3 +245,149 @@ LastFmConfig::onLastFmFinished() } } } + + +void +LastFmConfig::syncLovedTracks( uint page ) +{ + QNetworkReply* reply = lastfm::User( username() ).getLovedTracks( 200, page ); + + m_ui->progressBar->show(); + + NewClosure( reply, SIGNAL( finished() ), this, SLOT( onLovedFinished( QNetworkReply* ) ), reply ); + + DatabaseCommand_LoadSocialActions* cmd = new DatabaseCommand_LoadSocialActions( "Love", SourceList::instance()->getLocal() ); + connect( cmd, SIGNAL( done( DatabaseCommand_LoadSocialActions::TrackActions ) ), this, SLOT( localLovedLoaded( DatabaseCommand_LoadSocialActions::TrackActions ) ) ); + + Database::instance()->enqueue( QSharedPointer< DatabaseCommand >( cmd ) ); + +} + + +void +LastFmConfig::onLovedFinished( QNetworkReply* reply ) +{ + Q_ASSERT( reply ); + + try + { + lastfm::XmlQuery lfm; + lfm.parse( reply->readAll() ); + + if ( !lfm.children( "lovedtracks" ).isEmpty() ) + { + lastfm::XmlQuery loved = lfm.children( "lovedtracks" ).first(); + + const int thisPage = loved.attribute( "page" ).toInt(); + + if ( m_totalLovedPages < 0 ) + { + m_totalLovedPages = loved.attribute( "totalPages" ).toInt(); + m_ui->progressBar->setMaximum( m_totalLovedPages ); + } + + m_ui->progressBar->setValue( thisPage ); + foreach ( lastfm::XmlQuery e, loved.children( "track" ) ) + { +// tDebug() << "Found:" << e.children( "artist" ).first()["name"].text() << e["name"].text() << e["date"].attribute( "uts" ).toUInt(); + Tomahawk::query_ptr query = Tomahawk::Query::get( e.children( "artist" ).first()["name"].text(), e["name"].text(), QString(), QString(), false ); + if ( query.isNull() ) + continue; + + m_lastfmLoved.insert( query ); + } + + + if ( thisPage == m_totalLovedPages ) + { + m_doneFetchingLoved = true; + + if ( !m_localLoved.isEmpty() ) + syncLoved(); + + return; + } + else + { + syncLovedTracks( thisPage + 1 ); + } + } + } + catch( lastfm::ws::ParseError e ) + { + tDebug() << "XmlQuery error:" << e.message(); + } +} + + +bool trackEquality( const Tomahawk::query_ptr& first, const Tomahawk::query_ptr& second ) +{ + return first->equals( second, true ); +} + + +void +LastFmConfig::localLovedLoaded( DatabaseCommand_LoadSocialActions::TrackActions tracks ) +{ + m_localLoved = tracks; + + if ( m_doneFetchingLoved ) + syncLoved(); +} + + +void +LastFmConfig::syncLoved() +{ + QSet< Tomahawk::query_ptr > localToLove, lastFmToLove, lastFmToUnlove; + + const QSet< Tomahawk::query_ptr > myLoved = m_localLoved.keys().toSet(); + + foreach ( const Tomahawk::query_ptr& lastfmLoved, m_lastfmLoved ) + { + QSet< Tomahawk::query_ptr >::const_iterator iter = std::find_if( myLoved.begin(), myLoved.end(), boost::bind( &trackEquality, _1, boost::ref( lastfmLoved ) ) ); + if ( iter == myLoved.constEnd() ) + { +// qDebug() << "Found last.fm loved track that we didn't have loved locally:" << lastfmLoved->track() << lastfmLoved->artist(); + localToLove << lastfmLoved; + } + } + + foreach ( const Tomahawk::query_ptr& localLoved, myLoved ) + { + QSet< Tomahawk::query_ptr >::const_iterator iter = std::find_if( m_lastfmLoved.begin(), m_lastfmLoved.end(), boost::bind( &trackEquality, _1, boost::ref( localLoved ) ) ); + + // If we unloved it locally, but it's still loved on last.fm, unlove it + if ( m_localLoved[ localLoved ].value.toString() == "false" && iter != m_lastfmLoved.constEnd() ) + lastFmToUnlove << localLoved; + + // If we loved it locally but not loved on last.fm, love it + if ( m_localLoved[ localLoved ].value.toString() == "true" && iter == m_lastfmLoved.constEnd() ) + lastFmToLove << localLoved; + } + + foreach ( const Tomahawk::query_ptr& track, localToLove ) + { + // Don't use the infosystem as we don't want to tweet a few hundred times :) + DatabaseCommand_SocialAction* cmd = new DatabaseCommand_SocialAction( track, QString( "Love" ), QString( "true" ) ); + Database::instance()->enqueue( QSharedPointer(cmd) ); + } + + lastFmToLove.unite( lastFmToUnlove ); + + foreach ( const Tomahawk::query_ptr& track, lastFmToLove ) + { + lastfm::MutableTrack lfmTrack; + lfmTrack.stamp(); + + lfmTrack.setTitle( track->track() ); + lfmTrack.setArtist( track->artist() ); + lfmTrack.setSource( lastfm::Track::Player ); + + if ( lastFmToUnlove.contains( track ) ) + lfmTrack.unlove(); + else + lfmTrack.love(); + } +} + diff --git a/src/libtomahawk/accounts/lastfm/LastFmConfig.h b/src/libtomahawk/accounts/lastfm/LastFmConfig.h index c7c53f2b9..704eb58ad 100644 --- a/src/libtomahawk/accounts/lastfm/LastFmConfig.h +++ b/src/libtomahawk/accounts/lastfm/LastFmConfig.h @@ -1,6 +1,6 @@ /* === This file is part of Tomahawk Player - === * - * Copyright 2010-2011, Leo Franchi + * Copyright 2010-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 @@ -19,7 +19,12 @@ #ifndef LASTFMCONFIG_H #define LASTFMCONFIG_H +#include "Query.h" +#include "database/DatabaseCommand_LoadSocialActions.h" + #include +#include +#include class Ui_LastFmConfig; @@ -45,19 +50,31 @@ public slots: private slots: void enableButton(); - + void loadHistory(); void onHistoryLoaded(); + void syncLovedTracks() { syncLovedTracks( 1 ); } + void syncLovedTracks( uint page ); + void onLovedFinished( QNetworkReply* reply ); + void localLovedLoaded( DatabaseCommand_LoadSocialActions::TrackActions ); + signals: void sizeHintChanged(); private: + void syncLoved(); + LastFmAccount* m_account; Ui_LastFmConfig* m_ui; - + unsigned int m_page; unsigned int m_lastTimeStamp; + + int m_totalLovedPages; + bool m_doneFetchingLoved; + QSet< Tomahawk::query_ptr > m_lastfmLoved; + DatabaseCommand_LoadSocialActions::TrackActions m_localLoved; }; } diff --git a/src/libtomahawk/accounts/lastfm/LastFmConfig.ui b/src/libtomahawk/accounts/lastfm/LastFmConfig.ui index 1a75ae970..20a07ced7 100644 --- a/src/libtomahawk/accounts/lastfm/LastFmConfig.ui +++ b/src/libtomahawk/accounts/lastfm/LastFmConfig.ui @@ -23,7 +23,7 @@ - :/data/images/lastfm-icon.png + :/data/images/lastfm-icon.png Qt::AlignCenter @@ -84,6 +84,13 @@ + + + + Synchronize Loved Tracks + + + diff --git a/src/libtomahawk/database/DatabaseCommand_LoadSocialActions.cpp b/src/libtomahawk/database/DatabaseCommand_LoadSocialActions.cpp index 49e6b7e25..cc53e781f 100644 --- a/src/libtomahawk/database/DatabaseCommand_LoadSocialActions.cpp +++ b/src/libtomahawk/database/DatabaseCommand_LoadSocialActions.cpp @@ -37,40 +37,74 @@ DatabaseCommand_LoadSocialActions::exec( DatabaseImpl* dbi ) TomahawkSqlQuery query = dbi->newquery(); - QVariant srcid = source()->isLocal() ? QVariant( QVariant::Int ) : source()->id(); - - int artid = dbi->artistId( m_artist, false ); - if( artid < 1 ) - return; - - int trkid = dbi->trackId( artid, m_track, false ); - if( trkid < 1 ) - return; - - QString whereToken; - whereToken = QString( "WHERE id IS %1" ).arg( trkid ); - - QString sql = QString( - "SELECT k, v, timestamp, source " - "FROM social_attributes %1 " - "ORDER BY timestamp ASC" ).arg( whereToken ); - - query.prepare( sql ); - query.exec(); - - QList< Tomahawk::SocialAction > allSocialActions; - while ( query.next() ) + if ( m_actionOnly.isNull() ) { - Tomahawk::SocialAction action; - action.action = query.value( 0 ); // action - action.value = query.value( 1 ); // comment - action.timestamp = query.value( 2 ); // timestamp - action.source = SourceList::instance()->get( query.value( 3 ).toInt() ); // source - - if ( !action.source.isNull() ) - allSocialActions.append( action ); - } + // Load for just specified track + int artid = dbi->artistId( m_artist, false ); + if( artid < 1 ) + return; - m_query->setAllSocialActions( allSocialActions ); + int trkid = dbi->trackId( artid, m_track, false ); + if( trkid < 1 ) + return; + + QString whereToken; + whereToken = QString( "WHERE id IS %1" ).arg( trkid ); + + QString sql = QString( + "SELECT k, v, timestamp, source " + "FROM social_attributes %1 " + "ORDER BY timestamp ASC" ).arg( whereToken ); + + query.prepare( sql ); + query.exec(); + + QList< Tomahawk::SocialAction > allSocialActions; + while ( query.next() ) + { + Tomahawk::SocialAction action; + action.action = query.value( 0 ); // action + action.value = query.value( 1 ); // comment + action.timestamp = query.value( 2 ); // timestamp + action.source = SourceList::instance()->get( query.value( 3 ).toInt() ); // source + + if ( !action.source.isNull() ) + allSocialActions.append( action ); + } + + m_query->setAllSocialActions( allSocialActions ); + } + else + { + // Load all tracks with this social action + const QString srcStr = source()->isLocal() ? "IS NULL" : QString( "=%1" ).arg( source()->id() ); + + query.prepare( QString( "SELECT id, v, timestamp FROM social_attributes WHERE source %1 AND k = ? " ).arg( srcStr ) ); + query.addBindValue( m_actionOnly ); + + query.exec(); + + DatabaseCommand_LoadSocialActions::TrackActions trackActions; + while ( query.next() ) + { + const QVariantMap track = dbi->track( query.value( 0 ).toInt() ); + if ( track.value( "artist" ).toString().isEmpty() || track.value( "name" ).toString().isEmpty() ) + continue; + + const QVariantMap artist = dbi->artist( track.value( "artist" ).toInt() ); + + const query_ptr trackQuery = Query::get( artist.value( "name" ).toString(), track.value( "name" ).toString(), QString(), QString(), false ); + + Tomahawk::SocialAction action; + action.action = m_actionOnly; // action + action.value = query.value( 1 ); // comment + action.timestamp = query.value( 2 ); // timestamp + action.source = source(); // source + + trackActions[ trackQuery ] = action; + } + + emit done( trackActions ); + } } diff --git a/src/libtomahawk/database/DatabaseCommand_LoadSocialActions.h b/src/libtomahawk/database/DatabaseCommand_LoadSocialActions.h index 8656823b3..2eca2c3a8 100644 --- a/src/libtomahawk/database/DatabaseCommand_LoadSocialActions.h +++ b/src/libtomahawk/database/DatabaseCommand_LoadSocialActions.h @@ -1,6 +1,7 @@ /* === This file is part of Tomahawk Player - === * * Copyright 2011, Christopher Reichert + * 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 @@ -45,6 +46,7 @@ class DLLEXPORT DatabaseCommand_LoadSocialActions : public DatabaseCommand Q_OBJECT public: + typedef QMap TrackActions; /** * \brief Default constructor for DatabaseCommand_LoadSocialActions. * @@ -69,6 +71,16 @@ public: setTrack( query->track() ); } + /** + * Load all tracks with a specific social action + */ + explicit DatabaseCommand_LoadSocialActions( const QString& action, const Tomahawk::source_ptr& source, QObject* parent = 0 ) + : DatabaseCommand( parent ), m_actionOnly( action ) + { + setSource( source ); + qRegisterMetaType( "DatabaseCommand_LoadSocialAction::TrackActions" ); + } + /** * \brief Returns the name of this database command. * \return QString containing the database command name 'loadsocialaction'. @@ -115,20 +127,20 @@ public: void setTrack( const QString& s ) { m_track = s; } signals: - /** - * \brief Emitted when the database command has finished the Query successfully - * - * \param QList of all social actions - * \see QList + * All loaded social actions for each track found, for queries that generate all tracks + * with matching actions. */ - void done( QList< Tomahawk::SocialAction >& allSocialActions ); + void done( DatabaseCommand_LoadSocialActions::TrackActions actionsForTracks ); private: Tomahawk::query_ptr m_query; QString m_artist; QString m_track; + QString m_actionOnly; }; +Q_DECLARE_METATYPE( DatabaseCommand_LoadSocialActions::TrackActions ) + #endif // DATABASECOMMAND_LOADSOCIALACTIONS_H From 0c4db907b326fc4ebfed58e3f00479a055d6ed72 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Tue, 31 Jul 2012 17:48:41 -0400 Subject: [PATCH 51/79] UI tweaks for synchronizing last.fm loved tracks --- src/libtomahawk/accounts/lastfm/LastFmConfig.cpp | 13 +++++++++++-- src/libtomahawk/accounts/lastfm/LastFmConfig.h | 2 +- .../database/DatabaseCommand_LoadSocialActions.h | 1 + 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/libtomahawk/accounts/lastfm/LastFmConfig.cpp b/src/libtomahawk/accounts/lastfm/LastFmConfig.cpp index f6151d2c4..efc2ea1f5 100644 --- a/src/libtomahawk/accounts/lastfm/LastFmConfig.cpp +++ b/src/libtomahawk/accounts/lastfm/LastFmConfig.cpp @@ -43,6 +43,7 @@ LastFmConfig::LastFmConfig( LastFmAccount* account ) , m_lastTimeStamp( 0 ) , m_totalLovedPages( -1 ) , m_doneFetchingLoved( false ) + , m_doneFetchingLocal( false ) { m_ui = new Ui_LastFmConfig; m_ui->setupUi( this ); @@ -252,6 +253,8 @@ LastFmConfig::syncLovedTracks( uint page ) { QNetworkReply* reply = lastfm::User( username() ).getLovedTracks( 200, page ); + m_ui->syncLovedTracks->setEnabled( false ); + m_ui->syncLovedTracks->setText( tr( "Synchronizing..." ) ); m_ui->progressBar->show(); NewClosure( reply, SIGNAL( finished() ), this, SLOT( onLovedFinished( QNetworkReply* ) ), reply ); @@ -283,7 +286,7 @@ LastFmConfig::onLovedFinished( QNetworkReply* reply ) if ( m_totalLovedPages < 0 ) { m_totalLovedPages = loved.attribute( "totalPages" ).toInt(); - m_ui->progressBar->setMaximum( m_totalLovedPages ); + m_ui->progressBar->setMaximum( m_totalLovedPages + 2 ); } m_ui->progressBar->setValue( thisPage ); @@ -302,7 +305,7 @@ LastFmConfig::onLovedFinished( QNetworkReply* reply ) { m_doneFetchingLoved = true; - if ( !m_localLoved.isEmpty() ) + if ( m_doneFetchingLocal ) syncLoved(); return; @@ -330,6 +333,7 @@ void LastFmConfig::localLovedLoaded( DatabaseCommand_LoadSocialActions::TrackActions tracks ) { m_localLoved = tracks; + m_doneFetchingLocal = true; if ( m_doneFetchingLoved ) syncLoved(); @@ -343,6 +347,8 @@ LastFmConfig::syncLoved() const QSet< Tomahawk::query_ptr > myLoved = m_localLoved.keys().toSet(); + m_ui->progressBar->setValue( m_ui->progressBar->value() + 1 ); + foreach ( const Tomahawk::query_ptr& lastfmLoved, m_lastfmLoved ) { QSet< Tomahawk::query_ptr >::const_iterator iter = std::find_if( myLoved.begin(), myLoved.end(), boost::bind( &trackEquality, _1, boost::ref( lastfmLoved ) ) ); @@ -389,5 +395,8 @@ LastFmConfig::syncLoved() else lfmTrack.love(); } + + m_ui->progressBar->setValue( m_ui->progressBar->value() + 1 ); + m_ui->syncLovedTracks->setText( tr( "Synchronization Finished" ) ); } diff --git a/src/libtomahawk/accounts/lastfm/LastFmConfig.h b/src/libtomahawk/accounts/lastfm/LastFmConfig.h index 704eb58ad..b443b85a5 100644 --- a/src/libtomahawk/accounts/lastfm/LastFmConfig.h +++ b/src/libtomahawk/accounts/lastfm/LastFmConfig.h @@ -72,7 +72,7 @@ private: unsigned int m_lastTimeStamp; int m_totalLovedPages; - bool m_doneFetchingLoved; + bool m_doneFetchingLoved, m_doneFetchingLocal; QSet< Tomahawk::query_ptr > m_lastfmLoved; DatabaseCommand_LoadSocialActions::TrackActions m_localLoved; }; diff --git a/src/libtomahawk/database/DatabaseCommand_LoadSocialActions.h b/src/libtomahawk/database/DatabaseCommand_LoadSocialActions.h index 2eca2c3a8..fdc987bd5 100644 --- a/src/libtomahawk/database/DatabaseCommand_LoadSocialActions.h +++ b/src/libtomahawk/database/DatabaseCommand_LoadSocialActions.h @@ -126,6 +126,7 @@ public: */ void setTrack( const QString& s ) { m_track = s; } + virtual bool doesMutates() const { return false; } signals: /** * All loaded social actions for each track found, for queries that generate all tracks From ddfef98e207fe2d47a66d4aa6c287e595f70f66a Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Tue, 31 Jul 2012 18:11:14 -0400 Subject: [PATCH 52/79] Speed up the loved tracks model --- src/libtomahawk/playlist/LovedTracksModel.cpp | 25 ++++++++++++++++++- src/libtomahawk/playlist/LovedTracksModel.h | 1 + src/libtomahawk/playlist/PlaylistModel.h | 3 +-- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/libtomahawk/playlist/LovedTracksModel.cpp b/src/libtomahawk/playlist/LovedTracksModel.cpp index b0552d76e..6af5da878 100644 --- a/src/libtomahawk/playlist/LovedTracksModel.cpp +++ b/src/libtomahawk/playlist/LovedTracksModel.cpp @@ -74,7 +74,7 @@ LovedTracksModel::loadTracks() } DatabaseCommand_GenericSelect* cmd = new DatabaseCommand_GenericSelect( sql, DatabaseCommand_GenericSelect::Track, -1, 0 ); - connect( cmd, SIGNAL( tracks( QList ) ), this, SLOT( appendQueries( QList ) ) ); + connect( cmd, SIGNAL( tracks( QList ) ), this, SLOT( tracksLoaded( QList ) ) ); Database::instance()->enqueue( QSharedPointer( cmd ) ); } @@ -131,3 +131,26 @@ LovedTracksModel::isTemporary() const { return true; } + + +void +LovedTracksModel::tracksLoaded( QList< query_ptr > newLoved ) +{ + finishLoading(); + + QList< query_ptr > tracks; + + foreach ( const plentry_ptr ple, playlistEntries() ) + tracks << ple->query(); + + bool changed = false; + QList< query_ptr > mergedTracks = TomahawkUtils::mergePlaylistChanges( tracks, newLoved, changed ); + + if ( changed ) + { + QList el = playlist()->entriesFromQueries( mergedTracks, true ); + + clear(); + appendEntries( el ); + } +} diff --git a/src/libtomahawk/playlist/LovedTracksModel.h b/src/libtomahawk/playlist/LovedTracksModel.h index 6b3b40d1d..9491ef905 100644 --- a/src/libtomahawk/playlist/LovedTracksModel.h +++ b/src/libtomahawk/playlist/LovedTracksModel.h @@ -50,6 +50,7 @@ private slots: void onTrackLoved(); void loadTracks(); + void tracksLoaded( QList ); private: Tomahawk::source_ptr m_source; unsigned int m_limit; diff --git a/src/libtomahawk/playlist/PlaylistModel.h b/src/libtomahawk/playlist/PlaylistModel.h index 88ac0ec90..3963c2faa 100644 --- a/src/libtomahawk/playlist/PlaylistModel.h +++ b/src/libtomahawk/playlist/PlaylistModel.h @@ -77,6 +77,7 @@ protected: bool waitForRevision( const QString& revisionguid ) const { return m_waitForRevision.contains( revisionguid ); } void removeFromWaitList( const QString& revisionguid ) { m_waitForRevision.removeAll( revisionguid ); } + QList playlistEntries() const; private slots: void onRevisionLoaded( Tomahawk::PlaylistRevision revision ); void parsedDroppedTracks( QList ); @@ -86,8 +87,6 @@ private: void beginPlaylistChanges(); void endPlaylistChanges(); - QList playlistEntries() const; - Tomahawk::playlist_ptr m_playlist; bool m_isTemporary; bool m_changesOngoing; From a463c02273f3ce99c49e09bc8e54cde5b7cc6196 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Tue, 31 Jul 2012 21:33:04 -0400 Subject: [PATCH 53/79] Debounce updates to loved tracks model --- src/libtomahawk/playlist/LovedTracksModel.cpp | 13 ++++++++----- src/libtomahawk/playlist/LovedTracksModel.h | 1 + 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/libtomahawk/playlist/LovedTracksModel.cpp b/src/libtomahawk/playlist/LovedTracksModel.cpp index 6af5da878..0ad14a0e0 100644 --- a/src/libtomahawk/playlist/LovedTracksModel.cpp +++ b/src/libtomahawk/playlist/LovedTracksModel.cpp @@ -29,6 +29,8 @@ #include "utils/TomahawkUtils.h" #include "utils/Logger.h" +#include + #define LOVED_TRACK_ITEMS 25 using namespace Tomahawk; @@ -36,8 +38,13 @@ using namespace Tomahawk; LovedTracksModel::LovedTracksModel( QObject* parent ) : PlaylistModel( parent ) + , m_smoothingTimer( new QTimer ) , m_limit( LOVED_TRACK_ITEMS ) { + m_smoothingTimer->setInterval( 150 ); + m_smoothingTimer->setSingleShot( false ); + + connect( m_smoothingTimer, SIGNAL( timeout() ), this, SLOT( loadTracks() ) ); } @@ -49,10 +56,6 @@ LovedTracksModel::~LovedTracksModel() void LovedTracksModel::loadTracks() { - if ( rowCount( QModelIndex() ) ) - { - clear(); - } startLoading(); QString sql; @@ -122,7 +125,7 @@ LovedTracksModel::onSourceAdded( const Tomahawk::source_ptr& source ) void LovedTracksModel::onTrackLoved() { - loadTracks(); + m_smoothingTimer->start(); } diff --git a/src/libtomahawk/playlist/LovedTracksModel.h b/src/libtomahawk/playlist/LovedTracksModel.h index 9491ef905..43210b6a7 100644 --- a/src/libtomahawk/playlist/LovedTracksModel.h +++ b/src/libtomahawk/playlist/LovedTracksModel.h @@ -53,6 +53,7 @@ private slots: void tracksLoaded( QList ); private: Tomahawk::source_ptr m_source; + QTimer* m_smoothingTimer; unsigned int m_limit; }; From eecceb134afb86e160947432f7c281775cf3f2ac Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Tue, 31 Jul 2012 21:33:17 -0400 Subject: [PATCH 54/79] Show UI if fetching from last.fm failed --- src/libtomahawk/accounts/lastfm/LastFmConfig.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/libtomahawk/accounts/lastfm/LastFmConfig.cpp b/src/libtomahawk/accounts/lastfm/LastFmConfig.cpp index efc2ea1f5..9ae5f6729 100644 --- a/src/libtomahawk/accounts/lastfm/LastFmConfig.cpp +++ b/src/libtomahawk/accounts/lastfm/LastFmConfig.cpp @@ -315,9 +315,16 @@ LastFmConfig::onLovedFinished( QNetworkReply* reply ) syncLovedTracks( thisPage + 1 ); } } + else + { + m_ui->syncLovedTracks->setText( "Failed" ); + m_ui->progressBar->hide(); + } } catch( lastfm::ws::ParseError e ) { + m_ui->syncLovedTracks->setText( "Failed" ); + m_ui->progressBar->hide(); tDebug() << "XmlQuery error:" << e.message(); } } From 18c50a3f02e9966c74ba363f26fcd1b0c1441848 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Tue, 31 Jul 2012 22:21:15 -0400 Subject: [PATCH 55/79] Emit sizeHintChanged() when showing progressbar --- src/libtomahawk/accounts/lastfm/LastFmConfig.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libtomahawk/accounts/lastfm/LastFmConfig.cpp b/src/libtomahawk/accounts/lastfm/LastFmConfig.cpp index 9ae5f6729..14131c21d 100644 --- a/src/libtomahawk/accounts/lastfm/LastFmConfig.cpp +++ b/src/libtomahawk/accounts/lastfm/LastFmConfig.cpp @@ -256,6 +256,7 @@ LastFmConfig::syncLovedTracks( uint page ) m_ui->syncLovedTracks->setEnabled( false ); m_ui->syncLovedTracks->setText( tr( "Synchronizing..." ) ); m_ui->progressBar->show(); + emit sizeHintChanged(); NewClosure( reply, SIGNAL( finished() ), this, SLOT( onLovedFinished( QNetworkReply* ) ), reply ); @@ -319,12 +320,14 @@ LastFmConfig::onLovedFinished( QNetworkReply* reply ) { m_ui->syncLovedTracks->setText( "Failed" ); m_ui->progressBar->hide(); + emit sizeHintChanged(); } } catch( lastfm::ws::ParseError e ) { m_ui->syncLovedTracks->setText( "Failed" ); m_ui->progressBar->hide(); + emit sizeHintChanged(); tDebug() << "XmlQuery error:" << e.message(); } } From 03121f95ff2d238822e5b6c24a9b50545cc75d95 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Tue, 31 Jul 2012 22:21:31 -0400 Subject: [PATCH 56/79] Fix oversight in debounce: Singleshot timer --- src/libtomahawk/playlist/LovedTracksModel.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libtomahawk/playlist/LovedTracksModel.cpp b/src/libtomahawk/playlist/LovedTracksModel.cpp index 0ad14a0e0..63d6f5a01 100644 --- a/src/libtomahawk/playlist/LovedTracksModel.cpp +++ b/src/libtomahawk/playlist/LovedTracksModel.cpp @@ -41,8 +41,8 @@ LovedTracksModel::LovedTracksModel( QObject* parent ) , m_smoothingTimer( new QTimer ) , m_limit( LOVED_TRACK_ITEMS ) { - m_smoothingTimer->setInterval( 150 ); - m_smoothingTimer->setSingleShot( false ); + m_smoothingTimer->setInterval( 300 ); + m_smoothingTimer->setSingleShot( true ); connect( m_smoothingTimer, SIGNAL( timeout() ), this, SLOT( loadTracks() ) ); } From ea3f982415c402bcf7d69c6c62a1fb38e123d5cf Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Tue, 31 Jul 2012 22:21:44 -0400 Subject: [PATCH 57/79] Don't re-start already running animation --- src/libtomahawk/utils/AnimatedSpinner.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libtomahawk/utils/AnimatedSpinner.cpp b/src/libtomahawk/utils/AnimatedSpinner.cpp index 2d66e7273..cf22a3ad6 100644 --- a/src/libtomahawk/utils/AnimatedSpinner.cpp +++ b/src/libtomahawk/utils/AnimatedSpinner.cpp @@ -165,7 +165,7 @@ AnimatedSpinner::drawFrame( QPainter* p, const QRect& rect ) void AnimatedSpinner::fadeIn() { - if ( parentWidget() && isVisible() ) + if ( parentWidget() && isVisible() || m_animation->state() == QTimeLine::Running ) return; m_animation->start(); From c7cbb47742dd87daa4b16ff2c9878d956ed6c452 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Tue, 31 Jul 2012 22:57:18 -0400 Subject: [PATCH 58/79] Re-enable button when fixing login --- src/libtomahawk/accounts/lastfm/LastFmConfig.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libtomahawk/accounts/lastfm/LastFmConfig.cpp b/src/libtomahawk/accounts/lastfm/LastFmConfig.cpp index 14131c21d..6a8c98b63 100644 --- a/src/libtomahawk/accounts/lastfm/LastFmConfig.cpp +++ b/src/libtomahawk/accounts/lastfm/LastFmConfig.cpp @@ -226,6 +226,7 @@ LastFmConfig::onLastFmFinished() { m_ui->testLogin->setText( tr( "Success" ) ); m_ui->testLogin->setEnabled( false ); + m_ui->syncLovedTracks->setEnabled( true ); } } else From 003b9594826a9458add5f73b8b10e0d8ae3eb7e7 Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Wed, 1 Aug 2012 12:52:26 +0200 Subject: [PATCH 59/79] Ensure that we do not draw branching primitives under QtCurve. --- src/sourcetree/SourceTreeView.cpp | 7 +++++++ src/sourcetree/SourceTreeView.h | 1 + 2 files changed, 8 insertions(+) diff --git a/src/sourcetree/SourceTreeView.cpp b/src/sourcetree/SourceTreeView.cpp index 6ae602c05..c439b6316 100644 --- a/src/sourcetree/SourceTreeView.cpp +++ b/src/sourcetree/SourceTreeView.cpp @@ -838,6 +838,13 @@ SourceTreeView::drawRow( QPainter* painter, const QStyleOptionViewItem& option, QTreeView::drawRow( painter, option, index ); } +void +SourceTreeView::drawBranches( QPainter *painter, const QRect &rect, const QModelIndex &index ) const +{ + if( !QString( qApp->style()->metaObject()->className() ).toLower().contains( "qtcurve" ) ) + QTreeView::drawBranches( painter, rect, index ); +} + template< typename T > T* SourceTreeView::itemFromIndex( const QModelIndex& index ) const diff --git a/src/sourcetree/SourceTreeView.h b/src/sourcetree/SourceTreeView.h index 9959b01c3..83d330ee9 100644 --- a/src/sourcetree/SourceTreeView.h +++ b/src/sourcetree/SourceTreeView.h @@ -89,6 +89,7 @@ private slots: protected: void drawRow( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const; + void drawBranches( QPainter *painter, const QRect &rect, const QModelIndex &index ) const; virtual void paintEvent( QPaintEvent* event ); From 9eaec0106bf7ee50140119fa4441c6b04f40aa0b Mon Sep 17 00:00:00 2001 From: Tomahawk CI Date: Thu, 2 Aug 2012 00:17:36 +0200 Subject: [PATCH 60/79] Automatic merge of Transifex translations --- lang/tomahawk_ar.ts | 51 +++++++++++++++++++++++++++--------------- lang/tomahawk_bg.ts | 51 +++++++++++++++++++++++++++--------------- lang/tomahawk_ca.ts | 51 +++++++++++++++++++++++++++--------------- lang/tomahawk_de.ts | 51 +++++++++++++++++++++++++++--------------- lang/tomahawk_en.ts | 51 +++++++++++++++++++++++++++--------------- lang/tomahawk_es.ts | 51 +++++++++++++++++++++++++++--------------- lang/tomahawk_fr.ts | 51 +++++++++++++++++++++++++++--------------- lang/tomahawk_ja.ts | 51 +++++++++++++++++++++++++++--------------- lang/tomahawk_lt.ts | 51 +++++++++++++++++++++++++++--------------- lang/tomahawk_pl.ts | 51 +++++++++++++++++++++++++++--------------- lang/tomahawk_pt_BR.ts | 51 +++++++++++++++++++++++++++--------------- lang/tomahawk_ru.ts | 51 +++++++++++++++++++++++++++--------------- lang/tomahawk_sv.ts | 51 +++++++++++++++++++++++++++--------------- lang/tomahawk_tr.ts | 51 +++++++++++++++++++++++++++--------------- lang/tomahawk_zh_CN.ts | 51 +++++++++++++++++++++++++++--------------- lang/tomahawk_zh_TW.ts | 51 +++++++++++++++++++++++++++--------------- 16 files changed, 528 insertions(+), 288 deletions(-) diff --git a/lang/tomahawk_ar.ts b/lang/tomahawk_ar.ts index 87bef4c6d..7c9b8e4c5 100644 --- a/lang/tomahawk_ar.ts +++ b/lang/tomahawk_ar.ts @@ -551,6 +551,11 @@ connect and stream from you? Import Playback History استيراد تاريخ إعادة الإستماع + + + Synchronize Loved Tracks + + LastfmContext @@ -1919,7 +1924,7 @@ connect and stream from you? Tomahawk::Accounts::LastFmAccountFactory - + Scrobble your tracks to last.fm, and find freely downloadable tracks to play إبعث أغانيك الخاصة إلى last .fm و جد أغاني جديدة مجانا للاستماع إليها @@ -1927,52 +1932,62 @@ connect and stream from you? Tomahawk::Accounts::LastFmConfig - + Testing... اختبار... - + Test Login اختبار الدخول - + Importing %1 e.g. Importing 2012/01/01 استيراد %1 - + Importing History... نقل التاريخ... - + History Incomplete. Resume تاريخ ناقص. استأنف - + Playback History Imported تم استيراد تاريخ إعادة الإستماع - - + + Failed فشلت - + Success نجاح - + Could not contact server لم أستطيع الإتصال بالخادم + + + Synchronizing... + + + + + Synchronization Finished + + Tomahawk::Accounts::SpotifyAccount @@ -2940,37 +2955,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 d1623802e..a46af60f9 100644 --- a/lang/tomahawk_bg.ts +++ b/lang/tomahawk_bg.ts @@ -553,6 +553,11 @@ Tomahaw създаде доклад относно това и изпращай Import Playback History Импортирай история на просвирените песни + + + Synchronize Loved Tracks + + LastfmContext @@ -1925,7 +1930,7 @@ Tomahaw създаде доклад относно това и изпращай Tomahawk::Accounts::LastFmAccountFactory - + Scrobble your tracks to last.fm, and find freely downloadable tracks to play Качи информация за изпълнените песни в Last.fm и открий свободно разпространявани. @@ -1933,52 +1938,62 @@ Tomahaw създаде доклад относно това и изпращай Tomahawk::Accounts::LastFmConfig - + Testing... Тествам... - + Test Login Тествай връзката - + Importing %1 e.g. Importing 2012/01/01 Импортирам %1 - + Importing History... Импортирам... - + History Incomplete. Resume Непълна информация. Продължи. - + Playback History Imported Историята на просвирените песни е импортирана - - + + Failed Неуспешно - + Success Ура! - + Could not contact server Не мога да се свържа със сървъра + + + Synchronizing... + + + + + Synchronization Finished + + Tomahawk::Accounts::SpotifyAccount @@ -2947,37 +2962,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 8a00c725b..66aff7ff4 100644 --- a/lang/tomahawk_ca.ts +++ b/lang/tomahawk_ca.ts @@ -550,6 +550,11 @@ connect and stream from you? Import Playback History Importa l'historial de reproducció + + + Synchronize Loved Tracks + + LastfmContext @@ -1918,7 +1923,7 @@ i emissores de ràdio basades en el vostre gust musical. Tomahawk::Accounts::LastFmAccountFactory - + Scrobble your tracks to last.fm, and find freely downloadable tracks to play Fes scrobbling de les cançons a last.fm, i cerca cançons descarregables gratuïtament per escoltar-les @@ -1926,52 +1931,62 @@ i emissores de ràdio basades en el vostre gust musical. Tomahawk::Accounts::LastFmConfig - + Testing... S'està comprovant... - + Test Login Comprova l'inici de sessió - + Importing %1 e.g. Importing 2012/01/01 S'està important %1 - + Importing History... S'està important l'historial... - + History Incomplete. Resume Historial incomplet... Reprèn - + Playback History Imported S'ha importat l'historial de reproducció - - + + Failed Error - + Success Èxit - + Could not contact server No s'ha pogut contactar amb el servidor + + + Synchronizing... + + + + + Synchronization Finished + + Tomahawk::Accounts::SpotifyAccount @@ -2939,37 +2954,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 aba234270..3eddb5dfc 100644 --- a/lang/tomahawk_de.ts +++ b/lang/tomahawk_de.ts @@ -551,6 +551,11 @@ erlauben sich mit dir zu verbinden? Import Playback History Lieder-Historie importieren + + + Synchronize Loved Tracks + + LastfmContext @@ -1916,7 +1921,7 @@ erlauben sich mit dir zu verbinden? Tomahawk::Accounts::LastFmAccountFactory - + Scrobble your tracks to last.fm, and find freely downloadable tracks to play Gehörte Stücke zu last.fm scrobbeln und frei-verfügbare Stücke anhören @@ -1924,52 +1929,62 @@ erlauben sich mit dir zu verbinden? Tomahawk::Accounts::LastFmConfig - + Testing... Teste... - + Test Login Login testen - + Importing %1 e.g. Importing 2012/01/01 Importiere %1 - + Importing History... Importiere Historie... - + History Incomplete. Resume Historie unvollständig. Fortfahren - + Playback History Imported Lieder-Historie importiert - - + + Failed Fehlgeschlagen - + Success Erfolgreich - + Could not contact server Konnte den Server nicht erreichen! + + + Synchronizing... + + + + + Synchronization Finished + + Tomahawk::Accounts::SpotifyAccount @@ -2935,37 +2950,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 286b5f63a..14289ce83 100644 --- a/lang/tomahawk_en.ts +++ b/lang/tomahawk_en.ts @@ -551,6 +551,11 @@ connect and stream from you? Import Playback History Import Playback History + + + Synchronize Loved Tracks + Synchronize Loved Tracks + LastfmContext @@ -1919,7 +1924,7 @@ connect and stream from you? Tomahawk::Accounts::LastFmAccountFactory - + Scrobble your tracks to last.fm, and find freely downloadable tracks to play Scrobble your tracks to last.fm, and find freely downloadable tracks to play @@ -1927,52 +1932,62 @@ connect and stream from you? Tomahawk::Accounts::LastFmConfig - + Testing... Testing... - + Test Login Test Login - + Importing %1 e.g. Importing 2012/01/01 Importing %1 - + Importing History... Importing History... - + History Incomplete. Resume History Incomplete. Resume - + Playback History Imported Playback History Imported - - + + Failed Failed - + Success Success - + Could not contact server Could not contact server + + + Synchronizing... + Synchronizing... + + + + Synchronization Finished + Synchronization Finished + Tomahawk::Accounts::SpotifyAccount @@ -2940,37 +2955,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 f218c78ab..0d5d66f99 100644 --- a/lang/tomahawk_es.ts +++ b/lang/tomahawk_es.ts @@ -550,6 +550,11 @@ connect and stream from you? Import Playback History + + + Synchronize Loved Tracks + + LastfmContext @@ -1917,7 +1922,7 @@ y estaciones basadas en sus gustos personales. Tomahawk::Accounts::LastFmAccountFactory - + Scrobble your tracks to last.fm, and find freely downloadable tracks to play Hacer Scrobble de mis temas a last.fm y encontrar canciones gratuitas para reproducirlas @@ -1925,52 +1930,62 @@ y estaciones basadas en sus gustos personales. Tomahawk::Accounts::LastFmConfig - + Testing... - + Test Login Comprobar Inicio de Sesión - + Importing %1 e.g. Importing 2012/01/01 - + Importing History... - + History Incomplete. Resume - + Playback History Imported - - + + Failed Fallo - + Success Éxito - + Could not contact server No se pudo contactar el servidor + + + Synchronizing... + + + + + Synchronization Finished + + Tomahawk::Accounts::SpotifyAccount @@ -2938,37 +2953,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 a4c40e996..3bba6dfc7 100644 --- a/lang/tomahawk_fr.ts +++ b/lang/tomahawk_fr.ts @@ -551,6 +551,11 @@ de se connecter et streamer de vous? Import Playback History Importer l'historique + + + Synchronize Loved Tracks + + LastfmContext @@ -1919,7 +1924,7 @@ et des stations basées sur vos goûts. Tomahawk::Accounts::LastFmAccountFactory - + Scrobble your tracks to last.fm, and find freely downloadable tracks to play Scrobbler vos écoutes sur Last.fm et trouver des morceaux téléchargeables gratuitement @@ -1927,52 +1932,62 @@ et des stations basées sur vos goûts. Tomahawk::Accounts::LastFmConfig - + Testing... Test... - + Test Login Test de connexion - + Importing %1 e.g. Importing 2012/01/01 Importation %1 - + Importing History... Import de l'historique... - + History Incomplete. Resume Historique incomplet. Reprendre - + Playback History Imported Historique de lecture importé - - + + Failed Échec - + Success Succès - + Could not contact server Impossible de contacter le serveur + + + Synchronizing... + + + + + Synchronization Finished + + Tomahawk::Accounts::SpotifyAccount @@ -2940,37 +2955,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 91ee2d615..2c468da23 100644 --- a/lang/tomahawk_ja.ts +++ b/lang/tomahawk_ja.ts @@ -551,6 +551,11 @@ connect and stream from you? Import Playback History 再生履歴をインポートする + + + Synchronize Loved Tracks + + LastfmContext @@ -1919,7 +1924,7 @@ connect and stream from you? Tomahawk::Accounts::LastFmAccountFactory - + Scrobble your tracks to last.fm, and find freely downloadable tracks to play Last.fmにトラックをscrobbleして、無料ダウンロードのトラックを探して再生する @@ -1927,52 +1932,62 @@ connect and stream from you? Tomahawk::Accounts::LastFmConfig - + Testing... 試験用接続... - + Test Login ログインを試用 - + Importing %1 e.g. Importing 2012/01/01 %1をインポート - + Importing History... 履歴をインポート中... - + History Incomplete. Resume 不完全履歴。回復 - + Playback History Imported 再生履歴インポート完了 - - + + Failed 失敗しました - + Success 完成 - + Could not contact server サーバーに接続できませんでした + + + Synchronizing... + + + + + Synchronization Finished + + Tomahawk::Accounts::SpotifyAccount @@ -2933,37 +2948,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_lt.ts b/lang/tomahawk_lt.ts index ed385a489..3b78fed99 100644 --- a/lang/tomahawk_lt.ts +++ b/lang/tomahawk_lt.ts @@ -550,6 +550,11 @@ connect and stream from you? Import Playback History Įkelti klausymosi istoriją + + + Synchronize Loved Tracks + + LastfmContext @@ -1914,7 +1919,7 @@ connect and stream from you? Tomahawk::Accounts::LastFmAccountFactory - + Scrobble your tracks to last.fm, and find freely downloadable tracks to play @@ -1922,52 +1927,62 @@ connect and stream from you? Tomahawk::Accounts::LastFmConfig - + Testing... Bandoma... - + Test Login Išbandyti prisijungimą - + Importing %1 e.g. Importing 2012/01/01 Įkeliama %1 - + Importing History... Įkeliama istorija... - + History Incomplete. Resume Istorija nepilna. Tęskite - + Playback History Imported Klausymosi istorija įkelta - - + + Failed Nepavyko - + Success - + Could not contact server + + + Synchronizing... + + + + + Synchronization Finished + + Tomahawk::Accounts::SpotifyAccount @@ -2928,37 +2943,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 60284577d..3a27fc3ec 100644 --- a/lang/tomahawk_pl.ts +++ b/lang/tomahawk_pl.ts @@ -550,6 +550,11 @@ connect and stream from you? Import Playback History + + + Synchronize Loved Tracks + + LastfmContext @@ -1918,7 +1923,7 @@ indywidualnego profilu gustu. Tomahawk::Accounts::LastFmAccountFactory - + Scrobble your tracks to last.fm, and find freely downloadable tracks to play @@ -1926,52 +1931,62 @@ indywidualnego profilu gustu. Tomahawk::Accounts::LastFmConfig - + Testing... - + Test Login - + Importing %1 e.g. Importing 2012/01/01 - + Importing History... - + History Incomplete. Resume - + Playback History Imported - - + + Failed - + Success - + Could not contact server + + + Synchronizing... + + + + + Synchronization Finished + + Tomahawk::Accounts::SpotifyAccount @@ -2934,37 +2949,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 93ed8315a..36deebde4 100644 --- a/lang/tomahawk_pt_BR.ts +++ b/lang/tomahawk_pt_BR.ts @@ -551,6 +551,11 @@ se conecte e faça o stream de você? Import Playback History Importar Histórico de Reprodução + + + Synchronize Loved Tracks + + LastfmContext @@ -1919,7 +1924,7 @@ automáticas baseadas no seu gosto pessoal. Tomahawk::Accounts::LastFmAccountFactory - + Scrobble your tracks to last.fm, and find freely downloadable tracks to play Faça o scrobble para o last.fm e encontre faixas gratuitas para reproduzir @@ -1927,52 +1932,62 @@ automáticas baseadas no seu gosto pessoal. Tomahawk::Accounts::LastFmConfig - + Testing... Testando... - + Test Login Testar Login - + Importing %1 e.g. Importing 2012/01/01 Importando %1 - + Importing History... Importando Histórico... - + History Incomplete. Resume Histórico Incompleto. Retomar - + Playback History Imported Reproduzir Histórico Importado - - + + Failed Falhou - + Success Sucesso - + Could not contact server Não foi possível contatar o servidor + + + Synchronizing... + + + + + Synchronization Finished + + Tomahawk::Accounts::SpotifyAccount @@ -2940,37 +2955,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 a616be0ef..f75cd2dbb 100644 --- a/lang/tomahawk_ru.ts +++ b/lang/tomahawk_ru.ts @@ -551,6 +551,11 @@ connect and stream from you? Import Playback History Импортировать Историю Воспроизведений + + + Synchronize Loved Tracks + + LastfmContext @@ -1916,7 +1921,7 @@ connect and stream from you? Tomahawk::Accounts::LastFmAccountFactory - + Scrobble your tracks to last.fm, and find freely downloadable tracks to play @@ -1924,52 +1929,62 @@ connect and stream from you? Tomahawk::Accounts::LastFmConfig - + Testing... Тестирую... - + Test Login Проверить Вход - + Importing %1 e.g. Importing 2012/01/01 Импортирование %1 - + Importing History... Импортирование истории... - + History Incomplete. Resume - + Playback History Imported История воспроизведений импортирована. - - + + Failed Неудача - + Success Успех - + Could not contact server Не удается связаться с сервером + + + Synchronizing... + + + + + Synchronization Finished + + Tomahawk::Accounts::SpotifyAccount @@ -2935,37 +2950,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 979264ac2..04a01ab55 100644 --- a/lang/tomahawk_sv.ts +++ b/lang/tomahawk_sv.ts @@ -550,6 +550,11 @@ connect and stream from you? Import Playback History + + + Synchronize Loved Tracks + + LastfmContext @@ -1915,7 +1920,7 @@ connect and stream from you? Tomahawk::Accounts::LastFmAccountFactory - + Scrobble your tracks to last.fm, and find freely downloadable tracks to play @@ -1923,52 +1928,62 @@ connect and stream from you? Tomahawk::Accounts::LastFmConfig - + Testing... - + Test Login - + Importing %1 e.g. Importing 2012/01/01 - + Importing History... - + History Incomplete. Resume - + Playback History Imported - - + + Failed Misslyckades - + Success - + Could not contact server + + + Synchronizing... + + + + + Synchronization Finished + + Tomahawk::Accounts::SpotifyAccount @@ -2929,37 +2944,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 afb0133c1..e7db53448 100644 --- a/lang/tomahawk_tr.ts +++ b/lang/tomahawk_tr.ts @@ -550,6 +550,11 @@ connect and stream from you? Import Playback History + + + Synchronize Loved Tracks + + LastfmContext @@ -1914,7 +1919,7 @@ connect and stream from you? Tomahawk::Accounts::LastFmAccountFactory - + Scrobble your tracks to last.fm, and find freely downloadable tracks to play @@ -1922,52 +1927,62 @@ connect and stream from you? Tomahawk::Accounts::LastFmConfig - + Testing... - + Test Login - + Importing %1 e.g. Importing 2012/01/01 - + Importing History... - + History Incomplete. Resume - + Playback History Imported - - + + Failed - + Success - + Could not contact server + + + Synchronizing... + + + + + Synchronization Finished + + Tomahawk::Accounts::SpotifyAccount @@ -2928,37 +2943,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 4857d6754..dfc30b483 100644 --- a/lang/tomahawk_zh_CN.ts +++ b/lang/tomahawk_zh_CN.ts @@ -550,6 +550,11 @@ connect and stream from you? Import Playback History + + + Synchronize Loved Tracks + + LastfmContext @@ -1914,7 +1919,7 @@ connect and stream from you? Tomahawk::Accounts::LastFmAccountFactory - + Scrobble your tracks to last.fm, and find freely downloadable tracks to play @@ -1922,52 +1927,62 @@ connect and stream from you? Tomahawk::Accounts::LastFmConfig - + Testing... - + Test Login - + Importing %1 e.g. Importing 2012/01/01 - + Importing History... - + History Incomplete. Resume - + Playback History Imported - - + + Failed - + Success - + Could not contact server + + + Synchronizing... + + + + + Synchronization Finished + + Tomahawk::Accounts::SpotifyAccount @@ -2928,37 +2943,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 b1e903722..1c496449d 100644 --- a/lang/tomahawk_zh_TW.ts +++ b/lang/tomahawk_zh_TW.ts @@ -550,6 +550,11 @@ connect and stream from you? Import Playback History + + + Synchronize Loved Tracks + + LastfmContext @@ -1914,7 +1919,7 @@ connect and stream from you? Tomahawk::Accounts::LastFmAccountFactory - + Scrobble your tracks to last.fm, and find freely downloadable tracks to play @@ -1922,52 +1927,62 @@ connect and stream from you? Tomahawk::Accounts::LastFmConfig - + Testing... - + Test Login - + Importing %1 e.g. Importing 2012/01/01 - + Importing History... - + History Incomplete. Resume - + Playback History Imported - - + + Failed 失敗 - + Success 成功 - + Could not contact server 無法聯繫服務器 + + + Synchronizing... + + + + + Synchronization Finished + + Tomahawk::Accounts::SpotifyAccount @@ -2928,37 +2943,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 2b4e1c7d92929fec807265b8a62ce14e3321c9a4 Mon Sep 17 00:00:00 2001 From: Jason Herskowitz Date: Wed, 1 Aug 2012 20:43:46 -0400 Subject: [PATCH 61/79] New subscribe icon --- data/images/subscribe-on.png | Bin 3622 -> 3673 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/data/images/subscribe-on.png b/data/images/subscribe-on.png index d02b6355f0978908232bf60133f0d3c70b25e1fe..0661f7eed6a8d35d347bebd7ce68ae9edb9d2156 100644 GIT binary patch delta 3627 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

B?e*iQkmyoD7Oep{W002ovPDHLkV1lU)?alxI delta 3576 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 yegSEku9x&Gu(O;dNq^fu2b@llWOii@z< Date: Wed, 1 Aug 2012 20:55:04 -0400 Subject: [PATCH 62/79] Tweak subscribe icon --- data/images/subscribe-on.png | Bin 3673 -> 3441 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/data/images/subscribe-on.png b/data/images/subscribe-on.png index 0661f7eed6a8d35d347bebd7ce68ae9edb9d2156..37f78f7cd8337de4e16a5678c2fb2a1e06b75b72 100644 GIT binary patch delta 727 zcmV;|0x1329Pt{krwV^DJ46Q?C;$KgtVu*cR5(vv)z9lyRTKsA&${((5cI=}Kp`TU zL{gGbsZh{Bkp@zr!vz0`x)*{P^uv1{_8*uLq$o5BnnWR43S}Z@G|z|zHBc(+?FRR} z_kFe>JkHyDt-aS-=brmwEova+YW=LTUp!akK_TVW;#~MFlk0GVN|WM z92NhFN>;h$_nc#@-kVT^IaPxfs(jG^s{E3;tn93~Z*3b@rLj;VnpDqcbhc}y6DtVB zry1?d2Wi4T;QZ*_iYEGY+4 zz2n7URMt0OwYshx&E#FE-ZAl-vS=Doo0~u06}wk9&ynKejDkH?&K2)e@B78z&P-mf z@=?*XgDP!vVRx6RlGw*PW|*^0mYR*uc(=zN_9DydpM=+rpo? zscf`{mpgH`P^%%5INwdSWpqcCo64!V;*BeI|xmaw}e4r9vb~rg>Z}H;#auNOz zkJeyIMn8YF^e(9RK0~Ugaw<^0OL#&%u}1p3%Dsul%W-mR5BN_d) z7#e5!l3WZ9DJPS8DkQVwYU?V=(v(^5!HiBgMp6Ua=v3mK;*7Y_Xe)I#{k?(H z;_i%2*RWaHgqoW!{{j}hZQ(`nOtH0ruho28KJO+!!&2EY{sYFhA28nyphy4!002ov JPDHLkV1gcRZLI(R delta 961 zcmV;y13vum8rdAMrwV^72uu2aBa zP#9sEjtvQoWh6~MKzfLv0uzdQh@$=gBdA`2!k$BViA5I2F=?6t;Jtqz12zHc&1@Nfq|3lz zGuxl0>5(dqBuQ!tR3DldX_^wp@fu*Kr2BhO|8K{E7n3A88OJe_NRp%^tj&AB75EUq z%mA#qs^bhm(qi1!BuTc_j`QBD-EQN(e-C&cjJ%L#g$NyL1gK<{RWv>FiulPWimcsk zAN1arA>R9qW_Ev265RrZ2MSw#Yr!v9oGzp#U&}$$l?77eFsnHMcqB=ZLt*9YtX7-N z;ECJ2+P--n5;%WVeEM6H?GsI1ofG{H!whO3TVVYRSmEM0ej0eaA{0mk;N~FD#OlF9 zkB;PeZDohEiR0L%kSIiDZ26vMhNN4fC_3(*7?vk-r>GNAIH~A!$hf3{jaR3xrM0i);qQR^)uOW!Cn+Fk^==hK%p& zhk4lX_?&;;;mz8)Fk4WNnGLxpir$hGRfII1aeCV6-5*=}`gDVb2D@xnm9ueKS0DV) zk^&eX$!T@r%QK<+LX%ZkN%H|PxhR7GnZe4zoU=E?y3Ysn>lvrV?#c<;M>WN)&M*> zlrxvBhn4hw0PL!q-c5gKMuFkLM=)_YU}{>nYI$LO{RKz=cF+g+-Bwt;TmG<_VP?Ap z;Ju#!)>7(}tPl?m=S;WJ$!pFe*f88>X%h}iIxSyfwr*L@i7SqCNkAANU?NG9Q31qp zd=Gzcsw}eXgxRhL1btztw3$pQ3 Date: Wed, 1 Aug 2012 21:52:19 +0200 Subject: [PATCH 63/79] Replace the list widget in the settings dialog with a horizontal thingy. --- src/CMakeLists.txt | 1 - src/SettingsDialog.cpp | 104 +++++++++++++++++++-------------- src/SettingsDialog.h | 8 ++- src/SettingsListDelegate.cpp | 74 ----------------------- src/SettingsListDelegate.h | 39 ------------- src/StackedSettingsDialog.ui | 110 +++++++++++------------------------ 6 files changed, 100 insertions(+), 236 deletions(-) delete mode 100644 src/SettingsListDelegate.cpp delete mode 100644 src/SettingsListDelegate.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c7894f210..26a4b8342 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -70,7 +70,6 @@ SET( tomahawkSourcesGui ${tomahawkSourcesGui} AudioControls.cpp SettingsDialog.cpp DiagnosticsDialog.cpp - SettingsListDelegate.cpp TomahawkWindow.cpp LoadXSPFDialog.cpp SocialWidget.cpp diff --git a/src/SettingsDialog.cpp b/src/SettingsDialog.cpp index 213373ea0..7e9c07293 100644 --- a/src/SettingsDialog.cpp +++ b/src/SettingsDialog.cpp @@ -3,6 +3,7 @@ * Copyright 2010-2011, Christian Muehlhaeuser * Copyright 2010-2011, Leo Franchi * Copyright 2010-2012, Jeff Mitchell + * Copyright 2012, Teo Mrnjavac * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -28,6 +29,7 @@ #include #include #include +#include #include "AtticaManager.h" #include "AclRegistry.h" @@ -39,7 +41,6 @@ #include "ExternalResolverGui.h" #include "utils/TomahawkUtilsGui.h" #include "utils/GuiHelpers.h" -#include "SettingsListDelegate.h" #include "accounts/AccountDelegate.h" #include "database/Database.h" #include "network/Servent.h" @@ -72,11 +73,18 @@ SettingsDialog::SettingsDialog( QWidget *parent ) TomahawkSettings* s = TomahawkSettings::instance(); TomahawkUtils::unmarginLayout( layout() ); - ui->stackedWidget->setContentsMargins( 4, 4, 4, 0 ); +#ifdef Q_WS_X11 + ui->stackedWidget->setContentsMargins( 4, 4, 4, 4 ); +#else + ui->stackedWidget->setContentsMargins( 4, 4, 4, 0 ); +#endif ui->checkBoxReporter->setChecked( s->crashReporterEnabled() ); ui->checkBoxHttp->setChecked( s->httpEnabled() ); + m_toolBar = new QToolBar( tr( "Tomahawk Settings" ), this ); + ui->horizontalLayout->insertWidget( 0, m_toolBar ); + m_toolBar->setToolButtonStyle( Qt::ToolButtonTextUnderIcon ); //Network settings TomahawkSettings::ExternalAddressMode mode = TomahawkSettings::instance()->externalAddressMode(); @@ -102,8 +110,6 @@ SettingsDialog::SettingsDialog( QWidget *parent ) createIcons(); #ifdef Q_WS_X11 - ui->listWidget->setFrameShape( QFrame::StyledPanel ); - ui->listWidget->setFrameShadow( QFrame::Sunken ); setContentsMargins( 4, 4, 4, 4 ); #else setContentsMargins( 0, 4, 4, 4 ); @@ -210,9 +216,6 @@ SettingsDialog::SettingsDialog( QWidget *parent ) connect( ui->upnpRadioButton, SIGNAL( toggled(bool) ), SLOT( toggleRemoteMode() ) ); connect( ui->enableProxyCheckBox, SIGNAL( toggled(bool) ), SLOT( toggleProxyEnabled() ) ); connect( this, SIGNAL( rejected() ), SLOT( onRejected() ) ); - - ui->listWidget->setCurrentRow( 0 ); - ui->listWidget->setItemDelegate(new SettingsListDelegate()); } @@ -280,56 +283,67 @@ SettingsDialog::serventReady() void SettingsDialog::createIcons() { - /// Not fun but QListWidget sucks. Do our max-width calculation manually - /// so the icons arre lined up. - // Resolvers is the longest string... in english. fml. - ensurePolished(); - int maxlen = 0; - QFontMetrics fm( font() ); - QListWidgetItem *accountsButton = new QListWidgetItem( ui->listWidget ); - accountsButton->setIcon( QIcon( RESPATH "images/account-settings.png" ) ); - accountsButton->setText( tr( "Services" ) ); - accountsButton->setTextAlignment( Qt::AlignHCenter ); - accountsButton->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled ); - maxlen = fm.width( accountsButton->text() ); + m_settingsGroup = new QActionGroup( m_toolBar ); - QListWidgetItem *musicButton = new QListWidgetItem( ui->listWidget ); - musicButton->setIcon( QIcon( RESPATH "images/music-settings.png" ) ); - musicButton->setText( tr( "Collection" ) ); - musicButton->setTextAlignment( Qt::AlignHCenter ); - musicButton->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled ); - maxlen = qMax( fm.width( musicButton->text() ), maxlen ); + QWidget *leftSpacer = new QWidget( m_toolBar ); + leftSpacer->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred ); + m_toolBar->addWidget( leftSpacer ); - QListWidgetItem *advancedButton = new QListWidgetItem( ui->listWidget ); - advancedButton->setIcon( QIcon( RESPATH "images/advanced-settings.png" ) ); - advancedButton->setText( tr( "Advanced" ) ); - advancedButton->setTextAlignment( Qt::AlignHCenter ); - advancedButton->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled ); - maxlen = qMax( fm.width( advancedButton->text() ), maxlen ); + QAction *accountsAction = new QAction( QIcon( RESPATH "images/account-settings.png" ), + tr( "Services" ), + m_toolBar ); + accountsAction->setCheckable( true ); + accountsAction->setToolTip( tr( "Services
" + "Configure the accounts and services used by Tomahawk " + "to search and retrieve music, find your friends and " + "update your status." ) ); + m_settingsGroup->addAction( accountsAction ); - maxlen += 15; // padding - accountsButton->setSizeHint( QSize( maxlen, 60 ) ); - musicButton->setSizeHint( QSize( maxlen, 60 ) ); - advancedButton->setSizeHint( QSize( maxlen, 60 ) ); + QAction *musicAction = new QAction( QIcon( RESPATH "images/music-settings.png" ), + tr( "Collection" ), + m_toolBar ); + musicAction->setCheckable( true ); + musicAction->setToolTip( tr( "Collection
" + "Manage how Tomahawk finds music on your computer." ) ); + m_settingsGroup->addAction( musicAction ); -#ifndef Q_WS_MAC - // doesn't listen to sizehint... - ui->listWidget->setFixedWidth( maxlen + 8 ); -#endif - connect( ui->listWidget, SIGNAL( currentItemChanged( QListWidgetItem*, QListWidgetItem* ) ), SLOT( changePage( QListWidgetItem*, QListWidgetItem* ) ) ); + QAction *advancedAction = new QAction( QIcon( RESPATH "images/advanced-settings.png" ), + tr( "Advanced" ), + m_toolBar ); + advancedAction->setCheckable( true ); + advancedAction->setToolTip( tr( "Advanced
" + "Configure Tomahawk's advanced settings, including " + "network connectivity settings, browser interaction " + "and more." ) ); + m_settingsGroup->addAction( advancedAction ); + + m_settingsGroup->setExclusive( true ); + + m_toolBar->addActions( m_settingsGroup->actions() ); + + QWidget *rightSpacer = new QWidget( m_toolBar ); + rightSpacer->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred ); + m_toolBar->addWidget( rightSpacer ); + + connect( m_settingsGroup, SIGNAL( triggered( QAction * ) ), + this, SLOT( changePage( QAction * ) ) ); + + accountsAction->setChecked( true ); + changePage( accountsAction ); } void -SettingsDialog::changePage( QListWidgetItem* current, QListWidgetItem* previous ) +SettingsDialog::changePage( QAction *action ) { - if ( !current ) - current = previous; - - ui->stackedWidget->setCurrentIndex( ui->listWidget->row(current) ); + int index = m_settingsGroup->actions().indexOf( action ); + if( ui->stackedWidget->currentIndex() != index ) + { + ui->stackedWidget->setCurrentIndex( index ); + } } diff --git a/src/SettingsDialog.h b/src/SettingsDialog.h index 487f6e4ae..88cb934a0 100644 --- a/src/SettingsDialog.h +++ b/src/SettingsDialog.h @@ -3,6 +3,7 @@ * Copyright 2010-2011, Christian Muehlhaeuser * Copyright 2010-2011, Leo Franchi * Copyright 2010-2012, Jeff Mitchell + * Copyright 2012, Teo Mrnjavac * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,6 +24,8 @@ #include #include +#include +#include #include "config.h" @@ -94,7 +97,7 @@ private slots: void updateScanOptionsView(); - void changePage( QListWidgetItem*, QListWidgetItem* ); + void changePage( QAction *action ); void serventReady(); void aclEntryClearButtonClicked(); @@ -106,6 +109,9 @@ private: Ui_StackedSettingsDialog* ui; + QToolBar *m_toolBar; + QActionGroup *m_settingsGroup; + ProxyDialog m_proxySettings; bool m_rejected; bool m_restartRequired; diff --git a/src/SettingsListDelegate.cpp b/src/SettingsListDelegate.cpp deleted file mode 100644 index 3756c5314..000000000 --- a/src/SettingsListDelegate.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/* === This file is part of Tomahawk Player - === - * - * Copyright 2011, Michael Zanetti - * Copyright 2011, 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 "SettingsListDelegate.h" -#include "utils/Logger.h" - -#include -#include -#include - -SettingsListDelegate::SettingsListDelegate(QObject *parent) : - QStyledItemDelegate(parent) -{ -} - - -void SettingsListDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const -{ - painter->save(); - - QStyleOptionViewItemV4 opt = option; - initStyleOption( &opt, QModelIndex() ); - qApp->style()->drawControl( QStyle::CE_ItemViewItem, &opt, painter ); - -#if defined(Q_WS_MAC) || defined(Q_WS_WIN) - // On mac draw our own selection rect as we don't get one from osx (around the whole icon or around just text) - if ( opt.state & QStyle::State_Selected ) - { - painter->setRenderHint( QPainter::Antialiasing ); - - QPainterPath p; - p.addRoundedRect( opt.rect.adjusted( 2, 1, -1, -1 ), 5, 5 ); - - QColor fill( 214, 214, 214 ); - QColor border( 107, 107, 107 ); - painter->setPen( border ); - painter->drawPath( p ); - painter->fillPath( p, fill ); - } -#else - if ( ( option.state & QStyle::State_Selected ) == QStyle::State_Selected ) - { - painter->setPen( option.palette.color( QPalette::HighlightedText ) ); - } -#endif - - int horizontalOffset = ( option.rect.width() - option.decorationSize.width() ) /2; - QRect iconRect = option.rect.adjusted( horizontalOffset, 6, -horizontalOffset, -option.rect.height() + 6 + option.decorationSize.height() ); - QPixmap avatar = index.data( Qt::DecorationRole ).value().pixmap( iconRect.size() ); - painter->drawPixmap( iconRect, avatar ); - - QRect textRect = option.rect.adjusted( 6, iconRect.height() + 8, -6, 0 ); - QString text = painter->fontMetrics().elidedText( index.data( Qt::DisplayRole ).toString(), Qt::ElideRight, textRect.width() ); - QTextOption to( Qt::AlignHCenter ); - painter->drawText( textRect, text, to ); - - painter->restore(); -} diff --git a/src/SettingsListDelegate.h b/src/SettingsListDelegate.h deleted file mode 100644 index 730de7858..000000000 --- a/src/SettingsListDelegate.h +++ /dev/null @@ -1,39 +0,0 @@ -/* === This file is part of Tomahawk Player - === - * - * Copyright 2011, Michael Zanetti - * Copyright 2011, 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 SETTINGSLISTDELEGATE_H -#define SETTINGSLISTDELEGATE_H - -#include - -class SettingsListDelegate : public QStyledItemDelegate -{ - Q_OBJECT -public: - explicit SettingsListDelegate(QObject *parent = 0); - - virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; - -signals: - -public slots: - -}; - -#endif // SETTINGSLISTDELEGATE_H diff --git a/src/StackedSettingsDialog.ui b/src/StackedSettingsDialog.ui index 08dcdf48b..e260416d4 100644 --- a/src/StackedSettingsDialog.ui +++ b/src/StackedSettingsDialog.ui @@ -18,74 +18,11 @@ 0 - - - - - - - Qt::NoFocus - - - QFrame::StyledPanel - - - QFrame::Sunken - - - Qt::ScrollBarAlwaysOff - - - Qt::ScrollBarAlwaysOff - - - true - - - - 32 - 32 - - - - QListView::Static - - - QListView::Adjust - - - QListView::Batched - - - 1 - - - QListView::IconMode - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 1 - 4 - - - - - - + - 2 + 0 @@ -93,9 +30,12 @@ 0 - - - Internet Services + + + QFrame::NoFrame + + + QFrame::Plain @@ -153,11 +93,17 @@ 0 - - - Local Music Information + + + QFrame::NoFrame + + + QFrame::Plain + + 2 + @@ -234,17 +180,23 @@ 0 - + 0 0 - - Advanced Settings + + QFrame::NoFrame + + + QFrame::Plain + + -1 + 2 @@ -342,10 +294,13 @@ Qt::Vertical + + QSizePolicy::Fixed + 20 - 40 + 10 @@ -378,10 +333,13 @@ Qt::Vertical + + QSizePolicy::Fixed + 20 - 40 + 10 From 67611d10d12f417eff9c2708fbbfe505ee06d045 Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Wed, 1 Aug 2012 22:13:52 +0200 Subject: [PATCH 64/79] Added a styled separator line in the Settings Dialog. --- src/SettingsDialog.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/SettingsDialog.cpp b/src/SettingsDialog.cpp index 7e9c07293..024e8a603 100644 --- a/src/SettingsDialog.cpp +++ b/src/SettingsDialog.cpp @@ -82,6 +82,11 @@ SettingsDialog::SettingsDialog( QWidget *parent ) ui->checkBoxReporter->setChecked( s->crashReporterEnabled() ); ui->checkBoxHttp->setChecked( s->httpEnabled() ); + QFrame *sepLine = new QFrame( this ); + sepLine->setFrameShape( QFrame::HLine ); + sepLine->setFrameShadow( QFrame::Sunken ); + ui->horizontalLayout->insertWidget( 0, sepLine ); + m_toolBar = new QToolBar( tr( "Tomahawk Settings" ), this ); ui->horizontalLayout->insertWidget( 0, m_toolBar ); m_toolBar->setToolButtonStyle( Qt::ToolButtonTextUnderIcon ); From 2236b0ffb38e9538f08cb4b3e268e29bbac4b449 Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Wed, 1 Aug 2012 22:14:58 +0200 Subject: [PATCH 65/79] Moved the settings categories to the left. --- src/SettingsDialog.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/SettingsDialog.cpp b/src/SettingsDialog.cpp index 024e8a603..b1aa8b7a2 100644 --- a/src/SettingsDialog.cpp +++ b/src/SettingsDialog.cpp @@ -292,10 +292,6 @@ SettingsDialog::createIcons() m_settingsGroup = new QActionGroup( m_toolBar ); - QWidget *leftSpacer = new QWidget( m_toolBar ); - leftSpacer->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred ); - m_toolBar->addWidget( leftSpacer ); - QAction *accountsAction = new QAction( QIcon( RESPATH "images/account-settings.png" ), tr( "Services" ), m_toolBar ); @@ -329,10 +325,6 @@ SettingsDialog::createIcons() m_toolBar->addActions( m_settingsGroup->actions() ); - QWidget *rightSpacer = new QWidget( m_toolBar ); - rightSpacer->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred ); - m_toolBar->addWidget( rightSpacer ); - connect( m_settingsGroup, SIGNAL( triggered( QAction * ) ), this, SLOT( changePage( QAction * ) ) ); From 7e47d0efcc4dab2413bddea105663a0a0f65e458 Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Thu, 2 Aug 2012 12:24:28 +0200 Subject: [PATCH 66/79] Reenabled ProxyStyle under QtCurve, and fixed QSlider appearance. --- src/TomahawkWindow.cpp | 6 +----- src/libtomahawk/utils/ProxyStyle.cpp | 16 ++++++++++++++++ src/libtomahawk/utils/ProxyStyle.h | 1 + 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/TomahawkWindow.cpp b/src/TomahawkWindow.cpp index 09e6fe70d..7949baa62 100644 --- a/src/TomahawkWindow.cpp +++ b/src/TomahawkWindow.cpp @@ -202,11 +202,7 @@ TomahawkWindow::saveSettings() void TomahawkWindow::applyPlatformTweaks() { - // HACK QtCurve causes an infinite loop on startup. This is because setStyle calls setPalette, which calls ensureBaseStyle, - // which loads QtCurve. QtCurve calls setPalette, which creates an infinite loop. The UI will look like CRAP with QtCurve, but - // the user is asking for it explicitly... so he's gonna be stuck with an ugly UI. - if ( !QString( qApp->style()->metaObject()->className() ).toLower().contains( "qtcurve" ) ) - qApp->setStyle( new ProxyStyle() ); + qApp->setStyle( new ProxyStyle() ); #ifdef Q_OS_MAC setUnifiedTitleAndToolBarOnMac( true ); diff --git a/src/libtomahawk/utils/ProxyStyle.cpp b/src/libtomahawk/utils/ProxyStyle.cpp index cb7cd45e1..4a33e506f 100644 --- a/src/libtomahawk/utils/ProxyStyle.cpp +++ b/src/libtomahawk/utils/ProxyStyle.cpp @@ -1,6 +1,7 @@ /* === This file is part of Tomahawk Player - === * * Copyright 2010-2011, Christian Muehlhaeuser + * Copyright 2012, Teo Mrnjavac * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -82,3 +83,18 @@ ProxyStyle::drawControl( ControlElement ce, const QStyleOption* opt, QPainter* p else QProxyStyle::drawControl( ce, opt, p, w ); } + +QSize +ProxyStyle::sizeFromContents( QStyle::ContentsType type, const QStyleOption *option, const QSize &size, const QWidget *widget ) const +{ + if( type == CT_Splitter ) + { + const QSplitter* splitter = qobject_cast< const QSplitter* >( widget ); + if( splitter->orientation() == Qt::Horizontal ) + return QSize( 1, size.height() ); + else + return QSize( size.width(), 1 ); + } + else + return QProxyStyle::sizeFromContents( type, option, size, widget ); +} diff --git a/src/libtomahawk/utils/ProxyStyle.h b/src/libtomahawk/utils/ProxyStyle.h index 0a8d636ca..aa1dec625 100644 --- a/src/libtomahawk/utils/ProxyStyle.h +++ b/src/libtomahawk/utils/ProxyStyle.h @@ -31,6 +31,7 @@ public: virtual void drawPrimitive( PrimitiveElement pe, const QStyleOption *opt, QPainter *p, const QWidget *w = 0 ) const; virtual void drawControl( ControlElement ce, const QStyleOption *opt, QPainter *p, const QWidget *w = 0 ) const; + virtual QSize sizeFromContents( ContentsType type, const QStyleOption *option, const QSize &size, const QWidget *widget ) const; }; #endif // PROXYSTYLE_H From eabefe438d59977c0ba87b1c071cb17698c8f66a Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Wed, 1 Aug 2012 14:35:28 -0400 Subject: [PATCH 67/79] Fix ambiguous if() statement --- src/libtomahawk/utils/AnimatedSpinner.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libtomahawk/utils/AnimatedSpinner.cpp b/src/libtomahawk/utils/AnimatedSpinner.cpp index cf22a3ad6..9c9f7c878 100644 --- a/src/libtomahawk/utils/AnimatedSpinner.cpp +++ b/src/libtomahawk/utils/AnimatedSpinner.cpp @@ -165,7 +165,7 @@ AnimatedSpinner::drawFrame( QPainter* p, const QRect& rect ) void AnimatedSpinner::fadeIn() { - if ( parentWidget() && isVisible() || m_animation->state() == QTimeLine::Running ) + if ( ( parentWidget() && isVisible() ) || m_animation->state() == QTimeLine::Running ) return; m_animation->start(); From 99d75636a91acc2ad79b871a04d39fde2553589f Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Thu, 2 Aug 2012 09:26:06 -0400 Subject: [PATCH 68/79] Ignore preview-only URLs for now, until we properly handle them --- src/libtomahawk/resolvers/QtScriptResolver.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libtomahawk/resolvers/QtScriptResolver.cpp b/src/libtomahawk/resolvers/QtScriptResolver.cpp index e58a7b090..6b1d1ec5e 100644 --- a/src/libtomahawk/resolvers/QtScriptResolver.cpp +++ b/src/libtomahawk/resolvers/QtScriptResolver.cpp @@ -411,6 +411,11 @@ QtScriptResolver::parseResultVariantList( const QVariantList& reslist ) if ( m.value( "artist" ).toString().trimmed().isEmpty() || m.value( "track" ).toString().trimmed().isEmpty() ) continue; + // TODO we need to handle preview urls separately. they should never trump a real url, and we need to display + // the purchaseUrl for the user to upgrade to a full stream. + if ( m.value( "preview" ).toBool() == true ) + continue; + Tomahawk::result_ptr rp = Tomahawk::Result::get( m.value( "url" ).toString() ); Tomahawk::artist_ptr ap = Tomahawk::Artist::get( m.value( "artist" ).toString(), false ); rp->setArtist( ap ); From a19198b206e0123868d75c0641043b1db7032b7c Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Thu, 2 Aug 2012 19:01:30 +0200 Subject: [PATCH 69/79] Removed the annoying thin grey line from the Queue splitter widget. Also made the ContextWidget header cursor a PointingHand because consistency is good. --- src/libtomahawk/context/ContextWidget.cpp | 1 + src/libtomahawk/utils/ProxyStyle.cpp | 7 ++++++- src/libtomahawk/widgets/AnimatedSplitter.cpp | 9 ++++----- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/libtomahawk/context/ContextWidget.cpp b/src/libtomahawk/context/ContextWidget.cpp index bbf0e8334..618d1a0fb 100644 --- a/src/libtomahawk/context/ContextWidget.cpp +++ b/src/libtomahawk/context/ContextWidget.cpp @@ -84,6 +84,7 @@ ContextWidget::ContextWidget( QWidget* parent ) QPalette whitePal = ui->toggleButton->palette(); whitePal.setColor( QPalette::Foreground, Qt::white ); ui->toggleButton->setPalette( whitePal ); + ui->toggleButton->setCursor( Qt::PointingHandCursor ); QFont boldFont = ui->toggleButton->font(); boldFont.setPixelSize( 12 ); diff --git a/src/libtomahawk/utils/ProxyStyle.cpp b/src/libtomahawk/utils/ProxyStyle.cpp index 4a33e506f..fe57817c8 100644 --- a/src/libtomahawk/utils/ProxyStyle.cpp +++ b/src/libtomahawk/utils/ProxyStyle.cpp @@ -77,7 +77,12 @@ ProxyStyle::drawControl( ControlElement ce, const QStyleOption* opt, QPainter* p if ( !splitter->sizes().contains( 0 ) ) { p->setPen( QColor( 0x8c, 0x8c, 0x8c ) ); - p->drawLine( opt->rect.topLeft(), opt->rect.bottomRight() ); + // We must special-case this because of the AnimatedSplitterHandle which has a + // SizeHint of 0,0. + if( splitter->orientation() == Qt::Vertical ) + p->drawLine( opt->rect.topLeft(), opt->rect.topRight() ); + else + p->drawLine( opt->rect.topLeft(), opt->rect.bottomRight() ); } } else diff --git a/src/libtomahawk/widgets/AnimatedSplitter.cpp b/src/libtomahawk/widgets/AnimatedSplitter.cpp index 539433136..95992e19a 100644 --- a/src/libtomahawk/widgets/AnimatedSplitter.cpp +++ b/src/libtomahawk/widgets/AnimatedSplitter.cpp @@ -298,9 +298,8 @@ AnimatedSplitterHandle::sizeHint() const m_lastCount = splitter()->count(); } - // sizeHint is 0,0 if widget below handle has size 0 or is hidden - if ( splitter()->widget( m_indexInSplitter )->height() == 0 ) - return QSize( 0, 0 ); - else - return QSize( 1, 1 ); + // Since we are in an AnimatedSplitter, we always return 0,0 for SizeHint, simply + // because we know there's going to be a handle in the bottom widget to move the + // splitter. + return QSize( 0, 0 ); } From 9d03d77068e7e58eebebdc87f4c08f393807a300 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Thu, 2 Aug 2012 21:24:38 +0200 Subject: [PATCH 70/79] * Style fix. --- src/libtomahawk/network/ControlConnection.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libtomahawk/network/ControlConnection.cpp b/src/libtomahawk/network/ControlConnection.cpp index 59704fc4b..a3f069c8e 100644 --- a/src/libtomahawk/network/ControlConnection.cpp +++ b/src/libtomahawk/network/ControlConnection.cpp @@ -96,12 +96,14 @@ ControlConnection::~ControlConnection() m_dbsyncconn->deleteLater(); } + source_ptr ControlConnection::source() const { return m_source; } + Connection* ControlConnection::clone() { From 6fadeab1ddc3171b7ff9bf880deead43ce3609e2 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Thu, 2 Aug 2012 21:49:08 +0200 Subject: [PATCH 71/79] Revert "Moved the settings categories to the left." This reverts commit 2236b0ffb38e9538f08cb4b3e268e29bbac4b449. --- src/SettingsDialog.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/SettingsDialog.cpp b/src/SettingsDialog.cpp index b1aa8b7a2..024e8a603 100644 --- a/src/SettingsDialog.cpp +++ b/src/SettingsDialog.cpp @@ -292,6 +292,10 @@ SettingsDialog::createIcons() m_settingsGroup = new QActionGroup( m_toolBar ); + QWidget *leftSpacer = new QWidget( m_toolBar ); + leftSpacer->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred ); + m_toolBar->addWidget( leftSpacer ); + QAction *accountsAction = new QAction( QIcon( RESPATH "images/account-settings.png" ), tr( "Services" ), m_toolBar ); @@ -325,6 +329,10 @@ SettingsDialog::createIcons() m_toolBar->addActions( m_settingsGroup->actions() ); + QWidget *rightSpacer = new QWidget( m_toolBar ); + rightSpacer->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred ); + m_toolBar->addWidget( rightSpacer ); + connect( m_settingsGroup, SIGNAL( triggered( QAction * ) ), this, SLOT( changePage( QAction * ) ) ); From 95c48aa7223cc05b009570be6917e36bdb54ab5a Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Thu, 2 Aug 2012 17:33:13 -0400 Subject: [PATCH 72/79] Massively improve/simplify the seek slider logic. Fails (kinda) when you seek after pausing, but this is a Phonon bug that needs an update, no real way to work around it --- src/AudioControls.cpp | 131 +++++++++++++++++++++++++----------------- src/AudioControls.h | 3 +- 2 files changed, 78 insertions(+), 56 deletions(-) diff --git a/src/AudioControls.cpp b/src/AudioControls.cpp index e4b57075b..e081ddea6 100644 --- a/src/AudioControls.cpp +++ b/src/AudioControls.cpp @@ -37,6 +37,8 @@ #include "ViewManager.h" #include "Source.h" +const static int ALLOWED_MAX_DIVERSION = 300; + using namespace Tomahawk; @@ -205,22 +207,20 @@ AudioControls::onPlaybackStarted( const Tomahawk::result_ptr& result ) ui->seekSlider->setValue( 0 ); ui->seekSlider->setEnabled( AudioEngine::instance()->canSeek() ); - m_phononTickCheckTimer.stop(); - m_sliderTimeLine.stop(); m_sliderTimeLine.setDuration( duration ); m_sliderTimeLine.setFrameRange( 0, duration ); m_sliderTimeLine.setCurveShape( QTimeLine::LinearCurve ); m_sliderTimeLine.setCurrentTime( 0 ); - m_seekMsecs = -1; + m_seeked = false; ui->seekSlider->setVisible( true ); int updateRate = (double)1000 / ( (double)ui->seekSlider->contentsRect().width() / (double)( duration / 1000 ) ); m_sliderTimeLine.setUpdateInterval( qBound( 40, updateRate, 500 ) ); - m_noTimeChange = false; m_lastSliderCheck = 0; + m_phononTickCheckTimer.start( 500 ); } @@ -326,18 +326,15 @@ AudioControls::onPlaybackResumed() { tDebug( LOGEXTRA ) << Q_FUNC_INFO; ui->stackedLayout->setCurrentWidget( ui->pauseButton ); - m_sliderTimeLine.resume(); } void AudioControls::onPlaybackSeeked( qint64 msec ) { - tDebug( LOGEXTRA ) << Q_FUNC_INFO << " setting current timer to " << msec; - m_sliderTimeLine.setPaused( true ); - m_sliderTimeLine.setCurrentTime( msec ); - m_lastSliderCheck = msec; - m_seekMsecs = msec; + tDebug( LOGEXTRA ) << Q_FUNC_INFO; + m_seeked = true; + onPlaybackTimer( msec ); } @@ -356,7 +353,8 @@ AudioControls::onPlaybackStopped() ui->seekSlider->setVisible( false ); m_sliderTimeLine.stop(); m_sliderTimeLine.setCurrentTime( 0 ); - + m_phononTickCheckTimer.stop(); + ui->stackedLayout->setCurrentWidget( ui->playPauseButton ); ui->loveButton->setEnabled( false ); ui->loveButton->setVisible( false ); @@ -368,65 +366,90 @@ AudioControls::onPlaybackStopped() void AudioControls::onPlaybackTimer( qint64 msElapsed ) { + //tDebug() << Q_FUNC_INFO; + + m_phononTickCheckTimer.stop(); + + if ( m_currentTrack.isNull() ) + { + m_sliderTimeLine.stop(); + return; + } + const int seconds = msElapsed / 1000; - if ( seconds != m_lastTextSecondShown && !m_currentTrack.isNull() ) + if ( seconds != m_lastTextSecondShown ) { ui->timeLabel->setText( TomahawkUtils::timeToString( seconds ) ); ui->timeLeftLabel->setText( "-" + TomahawkUtils::timeToString( m_currentTrack->duration() - seconds ) ); m_lastTextSecondShown = seconds; } - //tDebug( LOGEXTRA ) << Q_FUNC_INFO << "msElapsed =" << msElapsed << "and timer current time =" << m_sliderTimeLine.currentTime() << "and m_seekMsecs =" << m_seekMsecs; - if ( msElapsed > 0 && msElapsed != m_lastSliderCheck && m_seekMsecs == -1 && msElapsed - 500 < m_lastSliderCheck ) + m_phononTickCheckTimer.start( 500 ); + + if ( msElapsed == 0 ) return; - m_lastSliderCheck = msElapsed; - - if ( m_currentTrack.isNull() ) - { - m_sliderTimeLine.stop(); - return; - } - - ui->seekSlider->blockSignals( true ); - - if ( sender() != &m_phononTickCheckTimer ) - m_phononTickCheckTimer.start( 1000 ); int currentTime = m_sliderTimeLine.currentTime(); - if ( m_noTimeChange ) + //tDebug( LOGEXTRA ) << Q_FUNC_INFO << "msElapsed =" << msElapsed << "and timer current time =" << m_sliderTimeLine.currentTime(); + + // First condition checks for the common case where + // 1) the track has been started + // 2) we haven't seeked, + // 3) the timeline is pretty close to the actual time elapsed, within ALLOWED_MAX_DIVERSIONmsec, so no adustment needed, and + // 4) The audio engine is actually currently running + if ( msElapsed > 0 + && !m_seeked + && qAbs( msElapsed - currentTime ) <= ALLOWED_MAX_DIVERSION + && AudioEngine::instance()->state() == AudioEngine::Playing ) { - if ( currentTime != msElapsed ) + if ( m_sliderTimeLine.state() != QTimeLine::Running ) + m_sliderTimeLine.resume(); + m_lastSliderCheck = msElapsed; + return; + } + else + { + //tDebug() << Q_FUNC_INFO << "Fallthrough"; + // If we're in here we're offset, so we need to do some munging around + ui->seekSlider->blockSignals( true ); + + // First handle seeks + if ( m_seeked ) { + //tDebug() << Q_FUNC_INFO << "Seeked"; m_sliderTimeLine.setPaused( true ); - m_noTimeChange = false; m_sliderTimeLine.setCurrentTime( msElapsed ); - m_seekMsecs = -1; - m_sliderTimeLine.resume(); + m_seeked = false; + if ( AudioEngine::instance()->state() == AudioEngine::Playing ) + m_sliderTimeLine.resume(); } + // Next handle falling behind by too much, or getting ahead by too much (greater than allowed amount, which would have been sorted above) + // However, a Phonon bug means that after a seek we'll actually have AudioEngine's state be Playing, when it ain't, so have to detect that + else if ( AudioEngine::instance()->state() == AudioEngine::Playing ) + { + //tDebug() << Q_FUNC_INFO << "AudioEngine playing"; + m_sliderTimeLine.setPaused( true ); + m_sliderTimeLine.setCurrentTime( msElapsed ); + if ( msElapsed != m_lastSliderCheck ) + m_sliderTimeLine.resume(); + } + // Finally, the case where the audioengine isn't playing; if the timeline is still running, pause it and catch up + else if ( AudioEngine::instance()->state() != AudioEngine::Playing ) + { + //tDebug() << Q_FUNC_INFO << "AudioEngine not playing"; + if ( msElapsed != currentTime || m_sliderTimeLine.state() == QTimeLine::Running) + { + m_sliderTimeLine.setPaused( true ); + m_sliderTimeLine.setCurrentTime( msElapsed ); + } + } + else + { + tDebug() << Q_FUNC_INFO << "What to do? How could we even get here?"; + } + m_lastSliderCheck = msElapsed; + ui->seekSlider->blockSignals( false ); } - else if ( currentTime >= msElapsed || m_seekMsecs != -1 ) - { - m_sliderTimeLine.setPaused( true ); - - m_noTimeChange = false; - if ( currentTime == msElapsed ) - m_noTimeChange = true; - - m_sliderTimeLine.setCurrentTime( msElapsed ); - m_seekMsecs = -1; - if ( AudioEngine::instance()->state() != AudioEngine::Paused && sender() != &m_phononTickCheckTimer ) - m_sliderTimeLine.resume(); - } - else if ( m_sliderTimeLine.duration() > msElapsed && m_sliderTimeLine.state() == QTimeLine::NotRunning && AudioEngine::instance()->state() == AudioEngine::Playing ) - { - m_sliderTimeLine.start(); - } - else if ( m_sliderTimeLine.state() == QTimeLine::Paused && AudioEngine::instance()->state() != AudioEngine::Paused ) - { - m_sliderTimeLine.resume(); - } - - ui->seekSlider->blockSignals( false ); } diff --git a/src/AudioControls.h b/src/AudioControls.h index aad7af1b9..3e5b0e7c5 100644 --- a/src/AudioControls.h +++ b/src/AudioControls.h @@ -101,9 +101,8 @@ private: QTimer m_phononTickCheckTimer; QTimeLine m_sliderTimeLine; - qint64 m_seekMsecs; + bool m_seeked; qint64 m_lastSliderCheck; - bool m_noTimeChange; qint64 m_lastTextSecondShown; QWidget* m_parent; From 87fc3563a17bee8023bd726d7925e41fe536579a Mon Sep 17 00:00:00 2001 From: Tomahawk CI Date: Fri, 3 Aug 2012 00:17:14 +0200 Subject: [PATCH 73/79] Automatic merge of Transifex translations --- lang/tomahawk_ar.ts | 173 +++++++++++++++++++++-------------------- lang/tomahawk_bg.ts | 173 +++++++++++++++++++++-------------------- lang/tomahawk_ca.ts | 173 +++++++++++++++++++++-------------------- lang/tomahawk_de.ts | 173 +++++++++++++++++++++-------------------- lang/tomahawk_en.ts | 173 +++++++++++++++++++++-------------------- lang/tomahawk_es.ts | 173 +++++++++++++++++++++-------------------- lang/tomahawk_fr.ts | 173 +++++++++++++++++++++-------------------- lang/tomahawk_ja.ts | 173 +++++++++++++++++++++-------------------- lang/tomahawk_lt.ts | 173 +++++++++++++++++++++-------------------- lang/tomahawk_pl.ts | 173 +++++++++++++++++++++-------------------- lang/tomahawk_pt_BR.ts | 173 +++++++++++++++++++++-------------------- lang/tomahawk_ru.ts | 173 +++++++++++++++++++++-------------------- lang/tomahawk_sv.ts | 173 +++++++++++++++++++++-------------------- lang/tomahawk_tr.ts | 173 +++++++++++++++++++++-------------------- lang/tomahawk_zh_CN.ts | 173 +++++++++++++++++++++-------------------- lang/tomahawk_zh_TW.ts | 173 +++++++++++++++++++++-------------------- 16 files changed, 1424 insertions(+), 1344 deletions(-) diff --git a/lang/tomahawk_ar.ts b/lang/tomahawk_ar.ts index 7c9b8e4c5..3de9024d6 100644 --- a/lang/tomahawk_ar.ts +++ b/lang/tomahawk_ar.ts @@ -374,12 +374,12 @@ connect and stream from you? - + Show Footnotes أظهر الحاشية - + Hide Footnotes إخفي الحاشية @@ -1229,47 +1229,67 @@ connect and stream from you? SettingsDialog - + Collection مجموعة - + Advanced متقدمة - + All الكل - + + Tomahawk Settings + + + + Some changed settings will not take effect until Tomahawk is restarted بعض الإعدادات التي تم تغييرها لن تصبح نافذة المفعول حتى يتم إعادة تشغيل توماهوك - + Services خدمات - + + <b>Services</b><br>Configure the accounts and services used by Tomahawk to search and retrieve music, find your friends and update your status. + + + + + <b>Collection</b><br>Manage how Tomahawk finds music on your computer. + + + + + <b>Advanced</b><br>Configure Tomahawk's advanced settings, including network connectivity settings, browser interaction and more. + + + + Install resolver from file تثبيت محلل من ملف - + Delete all Access Control entries? حذف كافة بيانات التحكم بالوصول؟ - + Do you really want to delete all Access Control entries? You will be asked for a decision again for each peer that you connect to. هل فعلا تريد حذف جميع بيانات التحكم بالوصول؟ سوف يطلب منك اتخاذ القرار مجددا لكل ند على اتصال به. - + Information معلومات @@ -1688,17 +1708,12 @@ connect and stream from you? إعدادات توماهوك - - Local Music Information - معلومات الأغاني المحلية - - - + Path to scan for music files: ماسار لتفحص ملفات الموسيقى: - + The Echo Nest supports keeping track of your catalog metadata and using it to craft personalized radios. Enabling this option will allow you (and all your friends) to create automatic playlists @@ -1708,107 +1723,97 @@ connect and stream from you? إنشاء قوائم أغاني أوتوماتيكيا و إذاعات حسب ذوقك الشخصي. - + Upload collection list to The Echo Nest to enable user radio تحميل قائمة المجموعة إلى "The Echo" لتمكين راديو المستخدم - + Watch for changes إنتبه للتغييرات - + Time between scans, in seconds: الوقت بين المسوحات، بالثواني: - - Advanced Settings - إعدادات متقدمة - - - + Remote Peer Connection Method طريقة الاتصال بالند البعيد - + None (outgoing connections only) لا شيء (الاتصالات الصادرة فقط) - + Use UPnP to establish port forward (recommended) استخدم عمل UPnP لإنشاء بوابة إعادة التوجيه (موصى به) - + Use static external IP address/host name and port استخدم عنوان/مضيف ايب (IP) و بوابة ثابتين - + Set this to your external IP address or host name. Make sure to forward the port to this host! عين هذا إلى عنوان الايب الخارجي (External IP) الخاص بك أو اسم المضيف. تأكد من إحالة البوابة إلى هذا المضيف! - + SOCKS Proxy سوكس الوكيل - + Use SOCKS Proxy استخدم سوكس الوكيل - + Clear All Access Control Entries حذف كافة بيانات التحكم بالوصول - - Internet Services - خدمات الانترنت - - - + Install from file... تثبيت من ملف... - + Filter by capability: ترشيح حسب القدرة: - + Static Host Name: اسم مضيف ثابت: - + Static Port: بوابة ثابتة: - + Proxy Settings... إعدادات الوسيط... - + Other Settings إعدادات أخرى - + Send reports after Tomahawk crashed أرسل تقارير بعد فشل توماهوك - + Allow web browsers to interact with Tomahawk (recommended) السماح لمحرك البحث بالتفاعل مع توماهوك (موصى به) @@ -3282,7 +3287,7 @@ enter the displayed PIN number here: - + Play إستمع @@ -3302,172 +3307,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 a46af60f9..e8e0fe9c4 100644 --- a/lang/tomahawk_bg.ts +++ b/lang/tomahawk_bg.ts @@ -373,12 +373,12 @@ connect and stream from you? - + Show Footnotes Покажи подробности - + Hide Footnotes Скрий подробности @@ -1229,47 +1229,67 @@ Tomahaw създаде доклад относно това и изпращай SettingsDialog - + Collection Колекция - + Advanced Разширени - + All Всички - + + Tomahawk Settings + + + + Some changed settings will not take effect until Tomahawk is restarted Някои промени няма да имат ефект, докато програмата не бъде рестартирана. - + Services Услуги - + + <b>Services</b><br>Configure the accounts and services used by Tomahawk to search and retrieve music, find your friends and update your status. + + + + + <b>Collection</b><br>Manage how Tomahawk finds music on your computer. + + + + + <b>Advanced</b><br>Configure Tomahawk's advanced settings, including network connectivity settings, browser interaction and more. + + + + Install resolver from file Инсталирай услиги за търсене от файл - + Delete all Access Control entries? - + Do you really want to delete all Access Control entries? You will be asked for a decision again for each peer that you connect to. - + Information Информация @@ -1690,17 +1710,12 @@ Tomahaw създаде доклад относно това и изпращай Настройки на Tomahawk - - Local Music Information - Информация за локалната музика - - - + Path to scan for music files: Път за сканиране за музика: - + The Echo Nest supports keeping track of your catalog metadata and using it to craft personalized radios. Enabling this option will allow you (and all your friends) to create automatic playlists @@ -1711,107 +1726,97 @@ Tomahaw създаде доклад относно това и изпращай базирани на вашият персонален вкус. - + Upload collection list to The Echo Nest to enable user radio Качи списък на колекцията ти в The Echo Nest за да се създаде потребителско радио - + Watch for changes Наблюдавай за промени - + Time between scans, in seconds: Време между две сканирания, в секунди - - Advanced Settings - Разширени настройки - - - + Remote Peer Connection Method Начин за свързване - + None (outgoing connections only) Без. (само изходящи връзки) - + Use UPnP to establish port forward (recommended) Ползвай UPnP (препоръчително) - + Use static external IP address/host name and port Ползвай статичен IP адрес/име и порт - + Set this to your external IP address or host name. Make sure to forward the port to this host! Настрой тук, своят външен IP адрес или име. Моля увери се, че си настроил прехвърляне на избраният порт, към адресът ти от локалната мрежа. - + SOCKS Proxy SOCKS Proxy - + Use SOCKS Proxy Ползвай SOCKS Proxy - + Clear All Access Control Entries - - Internet Services - Интернет услуги - - - + Install from file... Инсталирай от файл... - + Filter by capability: Филтрирай по възможности: - + Static Host Name: Статичен адрес: - + Static Port: Статичен порт: - + Proxy Settings... Настройка на Proxy: - + Other Settings Други настройки - + Send reports after Tomahawk crashed Изпрати сервизна информация след забиване. - + Allow web browsers to interact with Tomahawk (recommended) Позволи на браузърите да работят съвместно с Tomahawk (препоръчително) @@ -3289,7 +3294,7 @@ enter the displayed PIN number here: - + Play Изпълни @@ -3309,175 +3314,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 66aff7ff4..2514f535d 100644 --- a/lang/tomahawk_ca.ts +++ b/lang/tomahawk_ca.ts @@ -373,12 +373,12 @@ connect and stream from you? - + Show Footnotes Mostra les Notes al peu - + Hide Footnotes Amaga les Notes al peu @@ -1227,47 +1227,67 @@ connect and stream from you? SettingsDialog - + Collection Col·lecció - + Advanced Avançat - + All Tot - + + Tomahawk Settings + + + + Some changed settings will not take effect until Tomahawk is restarted Alguns paràmetres no tindran efecte fins que no reinicieu Tomahawk - + Services Serveis - + + <b>Services</b><br>Configure the accounts and services used by Tomahawk to search and retrieve music, find your friends and update your status. + + + + + <b>Collection</b><br>Manage how Tomahawk finds music on your computer. + + + + + <b>Advanced</b><br>Configure Tomahawk's advanced settings, including network connectivity settings, browser interaction and more. + + + + Install resolver from file Instal·la un Resolver des d'un fitxer - + Delete all Access Control entries? - + Do you really want to delete all Access Control entries? You will be asked for a decision again for each peer that you connect to. - + Information Informació @@ -1686,17 +1706,12 @@ connect and stream from you? Paràmetres de Tomahawk - - Local Music Information - Informació de la Música Local - - - + Path to scan for music files: Camí als fitxers de música: - + The Echo Nest supports keeping track of your catalog metadata and using it to craft personalized radios. Enabling this option will allow you (and all your friends) to create automatic playlists @@ -1707,107 +1722,97 @@ aquesta opció podreu crear llistes de reproducció automàtiques i emissores de ràdio basades en el vostre gust musical. - + Upload collection list to The Echo Nest to enable user radio Carrega la llista de la col·lecció a The Echo Nest per activar la radio d'usuari - + Watch for changes Monitoritza els canvis - + Time between scans, in seconds: Temps entre escanejos, en segons: - - Advanced Settings - Paràmetres Avançats - - - + Remote Peer Connection Method Mètode de connexió remota entre iguals - + None (outgoing connections only) Cap (només connexions cap a l'exterior) - + Use UPnP to establish port forward (recommended) Utiliza UPnP per establir el redireccionament de ports (recomanat) - + Use static external IP address/host name and port Utilitza l'adreça IP estàtica externa/nom de l'ordinador i el port - + Set this to your external IP address or host name. Make sure to forward the port to this host! Ajusteu aquest paràmetre amb la vostra adreça IP o el nom de l'ordinador. Assegure-vos que redireccioneu el port a aquest ordinador! - + SOCKS Proxy Proxys SOCKS - + Use SOCKS Proxy Utilitza un proxy SOCKS - + Clear All Access Control Entries - - Internet Services - Serveis d'Internet - - - + Install from file... Instal·la des d'un fitxer... - + Filter by capability: Filtra per capacitats: - + Static Host Name: Nom de l'ordinador estàtic: - + Static Port: Port estàtic: - + Proxy Settings... Paràmetres del proxy... - + Other Settings Altres Paràmetres - + Send reports after Tomahawk crashed Envia informació de les fallades de Tomahawk - + Allow web browsers to interact with Tomahawk (recommended) Permet que els navegadors web interactuin amb Tomahawk (recomanat) @@ -3281,7 +3286,7 @@ introduïu el PIN aquí: - + Play Reprodueix @@ -3301,172 +3306,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 3eddb5dfc..a1eb2dad4 100644 --- a/lang/tomahawk_de.ts +++ b/lang/tomahawk_de.ts @@ -374,12 +374,12 @@ erlauben sich mit dir zu verbinden? - + Show Footnotes Footnotes einblenden - + Hide Footnotes Footnotes ausblenden @@ -1228,47 +1228,67 @@ erlauben sich mit dir zu verbinden? SettingsDialog - + Collection Sammlung - + Advanced Erweitert - + All Alle - + + Tomahawk Settings + + + + Some changed settings will not take effect until Tomahawk is restarted Einige geänderte Einstellungen haben keinen Effekt bis zum nächsten Neustart - + Services Dienste - + + <b>Services</b><br>Configure the accounts and services used by Tomahawk to search and retrieve music, find your friends and update your status. + + + + + <b>Collection</b><br>Manage how Tomahawk finds music on your computer. + + + + + <b>Advanced</b><br>Configure Tomahawk's advanced settings, including network connectivity settings, browser interaction and more. + + + + Install resolver from file Installiere Resolver Datei - + Delete all Access Control entries? Alle erteilten Zugriffsrechte löschen? - + Do you really want to delete all Access Control entries? You will be asked for a decision again for each peer that you connect to. Willst du wirklich alle Zugriffseinstellungen zurücksetzen? Du wirst für alle Verbindungen erneut nach Zugriffseinstellungen gefragt werden. - + Information Information @@ -1687,17 +1707,12 @@ erlauben sich mit dir zu verbinden? Tomahawk Einstellungen - - Local Music Information - Information über lokale Musik - - - + Path to scan for music files: Pfad zu den Musikdateien: - + The Echo Nest supports keeping track of your catalog metadata and using it to craft personalized radios. Enabling this option will allow you (and all your friends) to create automatic playlists @@ -1705,107 +1720,97 @@ erlauben sich mit dir zu verbinden? - + Upload collection list to The Echo Nest to enable user radio Liste der aktuellen Sammlung an Echo Nest übermitteln, um User Radio zu aktivieren - + Watch for changes Automatisch aktualisieren - + Time between scans, in seconds: Zeitinterval (in Sekunden) zwischen zwei Scans: - - Advanced Settings - Erweiterte Einstellungen - - - + Remote Peer Connection Method Verbindung zu anderen Tomahawks - + None (outgoing connections only) Keine (nur ausgehende Verbindungen möglich) - + Use UPnP to establish port forward (recommended) UPnP für Port-Weiterleitung verwenden (empfohlen) - + Use static external IP address/host name and port Statische externe IP Adresse / Hostnamen und Port verwenden - + Set this to your external IP address or host name. Make sure to forward the port to this host! Stelle hier deine externe IP Adresse oder Hostnamen ein. Du musst den Port selbst an diesen Rechner weiterleiten! - + SOCKS Proxy SOCKS Proxy - + Use SOCKS Proxy SOCKS Proxy verwenden - + Clear All Access Control Entries Alle erteilten Zugriffsrechte löschen - - Internet Services - Internet Dienste - - - + Install from file... Installiere Datei... - + Filter by capability: Nach Fähigkeiten filtern: - + Static Host Name: Statischer Rechnername: - + Static Port: Statischer Port: - + Proxy Settings... Proxy-Einstellungen… - + Other Settings Andere Einstellungen - + Send reports after Tomahawk crashed Übermittlung von Fehlerberichten nach Tomahawk Absturz - + Allow web browsers to interact with Tomahawk (recommended) Erlaube Web Browser mit Tomahawk zu interagieren (empfohlen) @@ -3277,7 +3282,7 @@ Tomahawk auf Twitter's Website authentifiziert hast: - + Play Abspielen @@ -3297,172 +3302,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 14289ce83..614d5c974 100644 --- a/lang/tomahawk_en.ts +++ b/lang/tomahawk_en.ts @@ -374,12 +374,12 @@ connect and stream from you? - + Show Footnotes Show Footnotes - + Hide Footnotes Hide Footnotes @@ -1228,47 +1228,67 @@ connect and stream from you? SettingsDialog - + Collection Collection - + Advanced Advanced - + All All - + + Tomahawk Settings + Tomahawk Settings + + + Some changed settings will not take effect until Tomahawk is restarted Some changed settings will not take effect until Tomahawk is restarted - + Services Services - + + <b>Services</b><br>Configure the accounts and services used by Tomahawk to search and retrieve music, find your friends and update your status. + <b>Services</b><br>Configure the accounts and services used by Tomahawk to search and retrieve music, find your friends and update your status. + + + + <b>Collection</b><br>Manage how Tomahawk finds music on your computer. + <b>Collection</b><br>Manage how Tomahawk finds music on your computer. + + + + <b>Advanced</b><br>Configure Tomahawk's advanced settings, including network connectivity settings, browser interaction and more. + <b>Advanced</b><br>Configure Tomahawk's advanced settings, including network connectivity settings, browser interaction and more. + + + Install resolver from file Install resolver from file - + Delete all Access Control entries? Delete all Access Control entries? - + Do you really want to delete all Access Control entries? You will be asked for a decision again for each peer that you connect to. Do you really want to delete all Access Control entries? You will be asked for a decision again for each peer that you connect to. - + Information Information @@ -1687,17 +1707,12 @@ connect and stream from you? Tomahawk Settings - - Local Music Information - Local Music Information - - - + Path to scan for music files: Path to scan for music files: - + The Echo Nest supports keeping track of your catalog metadata and using it to craft personalized radios. Enabling this option will allow you (and all your friends) to create automatic playlists @@ -1708,107 +1723,97 @@ connect and stream from you? and stations based on your personal taste profile. - + Upload collection list to The Echo Nest to enable user radio Upload collection list to The Echo Nest to enable user radio - + Watch for changes Watch for changes - + Time between scans, in seconds: Time between scans, in seconds: - - Advanced Settings - Advanced Settings - - - + Remote Peer Connection Method Remote Peer Connection Method - + None (outgoing connections only) None (outgoing connections only) - + Use UPnP to establish port forward (recommended) Use UPnP to establish port forward (recommended) - + Use static external IP address/host name and port Use static external IP address/host name and port - + Set this to your external IP address or host name. Make sure to forward the port to this host! Set this to your external IP address or host name. Make sure to forward the port to this host! - + SOCKS Proxy SOCKS Proxy - + Use SOCKS Proxy Use SOCKS Proxy - + Clear All Access Control Entries Clear All Access Control Entries - - Internet Services - Internet Services - - - + Install from file... Install from file... - + Filter by capability: Filter by capability: - + Static Host Name: Static Host Name: - + Static Port: Static Port: - + Proxy Settings... Proxy Settings... - + Other Settings Other Settings - + Send reports after Tomahawk crashed Send reports after Tomahawk crashed - + Allow web browsers to interact with Tomahawk (recommended) Allow web browsers to interact with Tomahawk (recommended) @@ -3282,7 +3287,7 @@ enter the displayed PIN number here: - + Play Play @@ -3302,172 +3307,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 0d5d66f99..fd9497c64 100644 --- a/lang/tomahawk_es.ts +++ b/lang/tomahawk_es.ts @@ -373,12 +373,12 @@ connect and stream from you? - + Show Footnotes Mostrar información de contexto - + Hide Footnotes Ocultar información de contexto @@ -1226,47 +1226,67 @@ connect and stream from you? SettingsDialog - + Collection Colección - + Advanced Avanzado - + All Todo - + + Tomahawk Settings + + + + Some changed settings will not take effect until Tomahawk is restarted Algunos cambios no tomarán efecto hasta reiniciar Tomahawk - + Services Servicios - + + <b>Services</b><br>Configure the accounts and services used by Tomahawk to search and retrieve music, find your friends and update your status. + + + + + <b>Collection</b><br>Manage how Tomahawk finds music on your computer. + + + + + <b>Advanced</b><br>Configure Tomahawk's advanced settings, including network connectivity settings, browser interaction and more. + + + + Install resolver from file Instalar un Resolver desde un fichero - + Delete all Access Control entries? - + Do you really want to delete all Access Control entries? You will be asked for a decision again for each peer that you connect to. - + Information Información @@ -1685,17 +1705,12 @@ connect and stream from you? Preferencias de Tomahawk - - Local Music Information - Información de música local - - - + Path to scan for music files: Ruta para escanear archivos de música: - + The Echo Nest supports keeping track of your catalog metadata and using it to craft personalized radios. Enabling this option will allow you (and all your friends) to create automatic playlists @@ -1706,107 +1721,97 @@ usted podrá (y sus amigos) crear listas de reproducción automáticas y estaciones basadas en sus gustos personales. - + Upload collection list to The Echo Nest to enable user radio Subir la lista de colección a Echo Nest para activar la radio del usuario - + Watch for changes Vigilar los cambios en las carpetas - + Time between scans, in seconds: Tiempo entre escaneo, en segundos: - - Advanced Settings - Ajustes avanzados - - - + Remote Peer Connection Method Método de conexión remota - + None (outgoing connections only) Ninguna (sólo conexiones salientes) - + Use UPnP to establish port forward (recommended) Usar UPnP para establecer la redirección de puertos (recomendado) - + Use static external IP address/host name and port Usar IP estática externa/nombre de host y puero - + Set this to your external IP address or host name. Make sure to forward the port to this host! Ajustar a la dirección IP externa o nombre de la máquina. Hay que redirigir los puertos a esta máquina! - + SOCKS Proxy Proxy SOCKS - + Use SOCKS Proxy Utilizar el Proxy SOCKS - + Clear All Access Control Entries - - Internet Services - Servicios de Internet - - - + Install from file... Instalar desde un fichero... - + Filter by capability: Filtrar por capacidad: - + Static Host Name: Nombre estático del host: - + Static Port: Puerto estático: - + Proxy Settings... Configuración del proxy... - + Other Settings Otros Ajustes - + Send reports after Tomahawk crashed Mandar reportes después de que Tomahawk falle - + Allow web browsers to interact with Tomahawk (recommended) Permitir a los navegadores web interactuar con Tomahawk (recomendado) @@ -3280,7 +3285,7 @@ introduzca su número PIN aquí: - + Play Reproducir @@ -3300,172 +3305,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 3bba6dfc7..cdef43390 100644 --- a/lang/tomahawk_fr.ts +++ b/lang/tomahawk_fr.ts @@ -374,12 +374,12 @@ de se connecter et streamer de vous? - + Show Footnotes Afficher les notes - + Hide Footnotes Masquer les notes @@ -1228,47 +1228,67 @@ de se connecter et streamer de vous? SettingsDialog - + Collection Collection - + Advanced Avancés - + All Tous - + + Tomahawk Settings + + + + Some changed settings will not take effect until Tomahawk is restarted Certaines modifications ne prendront effet qu'au prochain démarrage de Tomahawk - + Services Services - + + <b>Services</b><br>Configure the accounts and services used by Tomahawk to search and retrieve music, find your friends and update your status. + + + + + <b>Collection</b><br>Manage how Tomahawk finds music on your computer. + + + + + <b>Advanced</b><br>Configure Tomahawk's advanced settings, including network connectivity settings, browser interaction and more. + + + + Install resolver from file Installer un script de résolution depuis un fichier - + Delete all Access Control entries? Supprimer toutes les entrées de Contrôle d'accès? - + Do you really want to delete all Access Control entries? You will be asked for a decision again for each peer that you connect to. Voulez-vous vraiment supprimer toutes les entrées de contrôle d'accès ? On vous demandera de nouveau votre autorisation pour toutes les nouvelles connexions. - + Information Information @@ -1687,17 +1707,12 @@ de se connecter et streamer de vous? Paramètres de Tomahawk - - Local Music Information - Fichiers de musique locaux - - - + Path to scan for music files: Chemin à scanner pour des fichiers musicaux : - + The Echo Nest supports keeping track of your catalog metadata and using it to craft personalized radios. Enabling this option will allow you (and all your friends) to create automatic playlists @@ -1708,107 +1723,97 @@ vous (et vos amis) pourrez créer des listes de lecture automatiquement et des stations basées sur vos goûts. - + Upload collection list to The Echo Nest to enable user radio Envoyer la collection à The Echo Nest pour activer la radio utilisateur - + Watch for changes Surveiller les changements - + Time between scans, in seconds: Période de scan, en secondes : - - Advanced Settings - Paramètres avancés - - - + Remote Peer Connection Method Méthode de connexion distante à un pair - + None (outgoing connections only) Aucune (Connexions sortantes uniquement) - + Use UPnP to establish port forward (recommended) Utiliser UPnP pour la redirection des ports (recommandé) - + Use static external IP address/host name and port Utiliser une adresse IP externe statique/nom d'hôte et un port - + Set this to your external IP address or host name. Make sure to forward the port to this host! Indiquez votre adresse IP externe ou nom d'hôte. Vérifiez que le port est bien redirigé vers cet hôte ! - + SOCKS Proxy Proxy SOCKS - + Use SOCKS Proxy Utiliser un proxy SOCKS - + Clear All Access Control Entries Supprimer toutes les entrées de Contrôle d'accès - - Internet Services - Services Internet - - - + Install from file... Installer depuis un fichier... - + Filter by capability: Filtrer par fonctionnalité : - + Static Host Name: Nom d'hôte statique : - + Static Port: Port statique : - + Proxy Settings... Paramètres du proxy... - + Other Settings Autres paramètres - + Send reports after Tomahawk crashed Envoyer un rapport après un crash de Tomahawk - + Allow web browsers to interact with Tomahawk (recommended) Permettre aux navigateurs web d’interagir avec Tomahawk (recommandé) @@ -3282,7 +3287,7 @@ saisissez le numéro PIN ici : - + Play Lecture @@ -3302,172 +3307,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 2c468da23..dd9e9ca69 100644 --- a/lang/tomahawk_ja.ts +++ b/lang/tomahawk_ja.ts @@ -373,12 +373,12 @@ connect and stream from you? - + Show Footnotes 脚注を表示 - + Hide Footnotes 脚注を隠す @@ -1228,47 +1228,67 @@ connect and stream from you? SettingsDialog - + Collection コレクション - + Advanced 詳細 - + All すべて - + + Tomahawk Settings + + + + Some changed settings will not take effect until Tomahawk is restarted Tomahawkを再起動すると設定変更が反映されます - + Services サービス - + + <b>Services</b><br>Configure the accounts and services used by Tomahawk to search and retrieve music, find your friends and update your status. + + + + + <b>Collection</b><br>Manage how Tomahawk finds music on your computer. + + + + + <b>Advanced</b><br>Configure Tomahawk's advanced settings, including network connectivity settings, browser interaction and more. + + + + Install resolver from file ファイルからリゾルバをインストールする - + Delete all Access Control entries? 全てのアクセス制御のエントリーを削除しますか? - + Do you really want to delete all Access Control entries? You will be asked for a decision again for each peer that you connect to. 本当に全てのアクセス制御のエントリーを削除しますか?ピア接続に対して、改めて同意を求めます。 - + Information 情報 @@ -1687,17 +1707,12 @@ connect and stream from you? 設定 - - Local Music Information - ローカルミュージック情報 - - - + Path to scan for music files: 音楽ファイルの検索パス: - + The Echo Nest supports keeping track of your catalog metadata and using it to craft personalized radios. Enabling this option will allow you (and all your friends) to create automatic playlists @@ -1708,107 +1723,97 @@ connect and stream from you? 基づいた自動プレイリストやステーションを作れます。 - + Upload collection list to The Echo Nest to enable user radio The Echo Nestにコレクションのリストをアップロードして、ユーザーラジオを有効にする - + Watch for changes 変更を監視 - + Time between scans, in seconds: スキャン作業の時間間隔(秒数): - - Advanced Settings - 詳細設定 - - - + Remote Peer Connection Method リモートピアとの接続方法 - + None (outgoing connections only) 無 (出接続のみ) - + Use UPnP to establish port forward (recommended) UPnPを使用して、ポートのフォワーディングを設ける (推奨) - + Use static external IP address/host name and port グローバル静的IP、又はホスト名とポートを使用する - + Set this to your external IP address or host name. Make sure to forward the port to this host! フォーム - + SOCKS Proxy SOCKSのプロクシ - + Use SOCKS Proxy SOCKSのプロクシを使用する - + Clear All Access Control Entries 全てのアクセス制御のエントリーを削除する - - Internet Services - インターネットサービス - - - + Install from file... ファイルからインストール... - + Filter by capability: 機能別に分類: - + Static Host Name: 静的ホスト名: - + Static Port: 静的ポート: - + Proxy Settings... プロクシ設定 - + Other Settings 他の設定 - + Send reports after Tomahawk crashed Tomahawkがクラッシュしたら、レポートを送信 - + Allow web browsers to interact with Tomahawk (recommended) ウェブブラウザーとの対話を許可する(お勧め) @@ -3275,7 +3280,7 @@ Meta+Ctrl+Z - + Play 再生 @@ -3295,172 +3300,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_lt.ts b/lang/tomahawk_lt.ts index 3b78fed99..7ec770c21 100644 --- a/lang/tomahawk_lt.ts +++ b/lang/tomahawk_lt.ts @@ -373,12 +373,12 @@ connect and stream from you? - + Show Footnotes Rodyti išnašas - + Hide Footnotes Slėpti išnašas @@ -1226,47 +1226,67 @@ connect and stream from you? SettingsDialog - + Collection Kolekcija - + Advanced Išplėstinės - + All Visi - + + Tomahawk Settings + + + + Some changed settings will not take effect until Tomahawk is restarted - + Services Paslaugos - + + <b>Services</b><br>Configure the accounts and services used by Tomahawk to search and retrieve music, find your friends and update your status. + + + + + <b>Collection</b><br>Manage how Tomahawk finds music on your computer. + + + + + <b>Advanced</b><br>Configure Tomahawk's advanced settings, including network connectivity settings, browser interaction and more. + + + + Install resolver from file - + Delete all Access Control entries? - + Do you really want to delete all Access Control entries? You will be asked for a decision again for each peer that you connect to. - + Information Informacija @@ -1685,17 +1705,12 @@ connect and stream from you? Tomahawk nuostatos - - Local Music Information - Vietinės muzikos informacija - - - + Path to scan for music files: - + The Echo Nest supports keeping track of your catalog metadata and using it to craft personalized radios. Enabling this option will allow you (and all your friends) to create automatic playlists @@ -1703,107 +1718,97 @@ connect and stream from you? - + Upload collection list to The Echo Nest to enable user radio - + Watch for changes Sekti pokyčius - + Time between scans, in seconds: - - Advanced Settings - Išplėstinės nuostatos - - - + Remote Peer Connection Method - + None (outgoing connections only) - + Use UPnP to establish port forward (recommended) - + Use static external IP address/host name and port - + Set this to your external IP address or host name. Make sure to forward the port to this host! - + SOCKS Proxy SOCKS Proxy - + Use SOCKS Proxy Naudoti SOCKS Proxy - + Clear All Access Control Entries - - Internet Services - Internetinės paslaugos - - - + Install from file... Įdiegti iš failo... - + Filter by capability: Filtruoti pagal gebėjimą: - + Static Host Name: Statinis serverio vardas: - + Static Port: Statinis prievadas: - + Proxy Settings... Proxy nuostatos... - + Other Settings Kitos nuostatos - + Send reports after Tomahawk crashed Siųsti ataskaitas apie Tomahawk strigtis - + Allow web browsers to interact with Tomahawk (recommended) Leisti žiniatinklio naršyklėms sąveikauti su Tomahawk (rekomenduojama) @@ -3269,7 +3274,7 @@ enter the displayed PIN number here: - + Play Groti @@ -3289,172 +3294,172 @@ enter the displayed PIN number here: Kitas - + Back Atgal - + Go back one page Grįžti vienu puslapiu atgal - + Forward Pirmyn - + Go forward one page Eiti vienu puslapiu pirmyn - + Global Search... Globali paieška... - - + + Check For Updates... Tikrinti, ar yra atnaujinimų... - - - + + + Connect To Peer - + Enter peer address: - + Enter peer port: - + Enter peer key: - + XSPF Error XSPF klaida - + This is not a valid XSPF playlist. - + Failed to save tracks Nepavyko išsaugoti takelių - + 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 Stotis - + Create New Station Sukurti naują stotį - + Name: Pavadinimas: - + Playlist Grojaraštis - + Automatic Playlist Automatinis grojaraštis - + Pause Pristabdyti - + Go &offline &Atsijungti - + Go &online &Prisijungti - + 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 Autorinės teisės 2010 - 2012 - + Thanks to: Dėkojame: - + About Tomahawk Apie Tomahawk diff --git a/lang/tomahawk_pl.ts b/lang/tomahawk_pl.ts index 3a27fc3ec..b551391b3 100644 --- a/lang/tomahawk_pl.ts +++ b/lang/tomahawk_pl.ts @@ -373,12 +373,12 @@ connect and stream from you? - + Show Footnotes Pokaż przypisy - + Hide Footnotes Schowaj przypisy @@ -1226,47 +1226,67 @@ connect and stream from you? SettingsDialog - + Collection Kolekcje - + Advanced Zaawansowane - + All Wszystkie - + + Tomahawk Settings + + + + Some changed settings will not take effect until Tomahawk is restarted - + Services Usługi - + + <b>Services</b><br>Configure the accounts and services used by Tomahawk to search and retrieve music, find your friends and update your status. + + + + + <b>Collection</b><br>Manage how Tomahawk finds music on your computer. + + + + + <b>Advanced</b><br>Configure Tomahawk's advanced settings, including network connectivity settings, browser interaction and more. + + + + Install resolver from file - + Delete all Access Control entries? - + Do you really want to delete all Access Control entries? You will be asked for a decision again for each peer that you connect to. - + Information Informacja @@ -1685,17 +1705,12 @@ connect and stream from you? Ustawienia Tomahawk - - Local Music Information - Informacje o Lokalnej Muzyce - - - + Path to scan for music files: Ścieżka poszukiwania plików muzycznych: - + The Echo Nest supports keeping track of your catalog metadata and using it to craft personalized radios. Enabling this option will allow you (and all your friends) to create automatic playlists @@ -1707,107 +1722,97 @@ tworzenie automatycznych list i stacji na podstawie twojego indywidualnego profilu gustu. - + Upload collection list to The Echo Nest to enable user radio Wyślij informacje o kolekcji do The Echo Nest, aby włączyć radio użytkownika - + Watch for changes Obserwuj zmiany - + Time between scans, in seconds: Czas pomiędzy skanami, w sekundach: - - Advanced Settings - - - - + Remote Peer Connection Method - + None (outgoing connections only) - + Use UPnP to establish port forward (recommended) - + Use static external IP address/host name and port - + Set this to your external IP address or host name. Make sure to forward the port to this host! - + SOCKS Proxy - + Use SOCKS Proxy - + Clear All Access Control Entries - - Internet Services - Usługi internetowe - - - + Install from file... Zainstaluj z pliku... - + Filter by capability: - + Static Host Name: Nazwa statycznego hosta: - + Static Port: Statyczny Port: - + Proxy Settings... Ustawienia Proxy... - + Other Settings - + Send reports after Tomahawk crashed Wysyłaj zgłoszenia po awarii Tomahawka - + Allow web browsers to interact with Tomahawk (recommended) @@ -3276,7 +3281,7 @@ wprowadź pokazany numer PIN tutaj: - + Play Odtwarzaj @@ -3296,172 +3301,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 36deebde4..313c85204 100644 --- a/lang/tomahawk_pt_BR.ts +++ b/lang/tomahawk_pt_BR.ts @@ -374,12 +374,12 @@ se conecte e faça o stream de você? - + Show Footnotes Mostrar Notas de Rodapé - + Hide Footnotes Ocultar Notas de Rodapé @@ -1228,47 +1228,67 @@ se conecte e faça o stream de você? SettingsDialog - + Collection Coleção - + Advanced Avançado - + All Todos - + + Tomahawk Settings + + + + Some changed settings will not take effect until Tomahawk is restarted Algumas configurações não terão efeito até que o Tomahawk seja reiniciado - + Services Serviços - + + <b>Services</b><br>Configure the accounts and services used by Tomahawk to search and retrieve music, find your friends and update your status. + + + + + <b>Collection</b><br>Manage how Tomahawk finds music on your computer. + + + + + <b>Advanced</b><br>Configure Tomahawk's advanced settings, including network connectivity settings, browser interaction and more. + + + + Install resolver from file Instalar resolvedor via arquivo - + Delete all Access Control entries? Excluir todas as entradas de controle de acesso? - + Do you really want to delete all Access Control entries? You will be asked for a decision again for each peer that you connect to. Você realmente quer apagar todas as entradas de controle de acesso? Você será solicitado a tomar uma decisão para cada ponto a que você se conectar. - + Information Informação @@ -1687,17 +1707,12 @@ se conecte e faça o stream de você? Configurações do Tomahawk - - Local Music Information - Informação de Músicas Locais - - - + Path to scan for music files: Caminho para os arquivos de música: - + The Echo Nest supports keeping track of your catalog metadata and using it to craft personalized radios. Enabling this option will allow you (and all your friends) to create automatic playlists @@ -1708,107 +1723,97 @@ irá permitir a você (e seus amigos) criar playlists e estações automáticas baseadas no seu gosto pessoal. - + Upload collection list to The Echo Nest to enable user radio Carregar coleção ao Echo Nest para habilitar a rádio do usuário - + Watch for changes Acompanhar alterações - + Time between scans, in seconds: Tempo entre escaneamentos, em segundos: - - Advanced Settings - Configurações Avançadas - - - + Remote Peer Connection Method Método de Conexão Remota por Peer - + None (outgoing connections only) Nenhum (somente conexões de saída) - + Use UPnP to establish port forward (recommended) Use UPnP para estabelecer o encaminhamento de porta (recomendado) - + Use static external IP address/host name and port Use endereço IP, nome de servidor e porta estáticos externos. - + Set this to your external IP address or host name. Make sure to forward the port to this host! Defina esta opção para o seu endereço de IP externo ou servidor. Certifique-se de encaminhar a porta para este servidor! - + SOCKS Proxy Proxy SOCKS - + Use SOCKS Proxy Utilizar Proxy SOCKS - + Clear All Access Control Entries Limpar todas as entradas de controle de acesso - - Internet Services - Serviços de Internet - - - + Install from file... Instalar via arquivo... - + Filter by capability: Filtrar por capacidade: - + Static Host Name: Nome do Servidor Estático: - + Static Port: Porta Estática: - + Proxy Settings... Configurações de Proxy... - + Other Settings Outras configurações - + Send reports after Tomahawk crashed Enviar informações caso o Tomahawk trave - + Allow web browsers to interact with Tomahawk (recommended) Permitir que navegadores web interajam com o Tomahawk (recomendado) @@ -3282,7 +3287,7 @@ colocar o número PIN mostrado aqui: - + Play Reporduzir @@ -3302,172 +3307,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 f75cd2dbb..26e921da8 100644 --- a/lang/tomahawk_ru.ts +++ b/lang/tomahawk_ru.ts @@ -374,12 +374,12 @@ connect and stream from you? - + Show Footnotes Показать Информацию об Исполнителе - + Hide Footnotes Спрятать Информацию об Исполнителе @@ -1228,47 +1228,67 @@ connect and stream from you? SettingsDialog - + Collection Коллекция - + Advanced Дополнительны - + All Все - + + Tomahawk Settings + + + + Some changed settings will not take effect until Tomahawk is restarted Некоторые измененные настройки не вступят в силу до перезапуска Tomahawk - + Services Сервисы - + + <b>Services</b><br>Configure the accounts and services used by Tomahawk to search and retrieve music, find your friends and update your status. + + + + + <b>Collection</b><br>Manage how Tomahawk finds music on your computer. + + + + + <b>Advanced</b><br>Configure Tomahawk's advanced settings, including network connectivity settings, browser interaction and more. + + + + Install resolver from file Установить resolver из файла - + Delete all Access Control entries? Удаление всех записей контроля доступа? - + Do you really want to delete all Access Control entries? You will be asked for a decision again for each peer that you connect to. - + Information Инофрмация @@ -1687,17 +1707,12 @@ connect and stream from you? Настройки - - Local Music Information - Информация о локальной коллекции - - - + Path to scan for music files: Путь по которому сканировать музыку: - + The Echo Nest supports keeping track of your catalog metadata and using it to craft personalized radios. Enabling this option will allow you (and all your friends) to create automatic playlists @@ -1705,107 +1720,97 @@ connect and stream from you? - + Upload collection list to The Echo Nest to enable user radio Заргузить список на The Echo Nest, чтобы включить пользовательское радио - + Watch for changes Следить за изменением коллекции - + Time between scans, in seconds: Время между сканированием, в секундах: - - Advanced Settings - Дополнительные Настройки - - - + Remote Peer Connection Method - + None (outgoing connections only) - + Use UPnP to establish port forward (recommended) Использование UPnP для проброса портов (рекомендуется) - + Use static external IP address/host name and port Использовать статический IP-адрес / имя хоста и порт - + Set this to your external IP address or host name. Make sure to forward the port to this host! - + SOCKS Proxy SOCKS Прокси - + Use SOCKS Proxy Использовать SOCKS Прокси - + Clear All Access Control Entries - - Internet Services - Сервисы интернета - - - + Install from file... Установить из файла - + Filter by capability: Фильтр по возможности: - + Static Host Name: Статическое имя хоста: - + Static Port: Статический порт: - + Proxy Settings... Настройки прокси... - + Other Settings Другие Настройки - + Send reports after Tomahawk crashed Отправить отчет после падения Tomahawk - + Allow web browsers to interact with Tomahawk (recommended) @@ -3276,7 +3281,7 @@ enter the displayed PIN number here: - + Play Играть @@ -3296,172 +3301,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 - + %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 04a01ab55..80681eff9 100644 --- a/lang/tomahawk_sv.ts +++ b/lang/tomahawk_sv.ts @@ -373,12 +373,12 @@ connect and stream from you? - + Show Footnotes Visa fotnot - + Hide Footnotes Dölj fotnot @@ -1227,47 +1227,67 @@ connect and stream from you? SettingsDialog - + Collection Samling - + Advanced Avancerat - + All Alla - + + Tomahawk Settings + + + + Some changed settings will not take effect until Tomahawk is restarted - + Services Tjänster - + + <b>Services</b><br>Configure the accounts and services used by Tomahawk to search and retrieve music, find your friends and update your status. + + + + + <b>Collection</b><br>Manage how Tomahawk finds music on your computer. + + + + + <b>Advanced</b><br>Configure Tomahawk's advanced settings, including network connectivity settings, browser interaction and more. + + + + Install resolver from file Installera resolver från fil - + Delete all Access Control entries? - + Do you really want to delete all Access Control entries? You will be asked for a decision again for each peer that you connect to. - + Information Information @@ -1686,17 +1706,12 @@ connect and stream from you? Inställningar för Tomahawk - - Local Music Information - - - - + Path to scan for music files: Sökväg att leta efter musik i - + The Echo Nest supports keeping track of your catalog metadata and using it to craft personalized radios. Enabling this option will allow you (and all your friends) to create automatic playlists @@ -1704,107 +1719,97 @@ connect and stream from you? - + Upload collection list to The Echo Nest to enable user radio - + Watch for changes Bevaka förändringar - + Time between scans, in seconds: Intervall mellan letande, i sekunder - - Advanced Settings - - - - + Remote Peer Connection Method - + None (outgoing connections only) - + Use UPnP to establish port forward (recommended) - + Use static external IP address/host name and port - + Set this to your external IP address or host name. Make sure to forward the port to this host! - + SOCKS Proxy - + Use SOCKS Proxy - + Clear All Access Control Entries - - Internet Services - Internet-tjänster - - - + Install from file... Installera från fil… - + Filter by capability: Filtrera efter funktion: - + Static Host Name: - + Static Port: Statisk port: - + Proxy Settings... Proxyinställningar... - + Other Settings - + Send reports after Tomahawk crashed Skicka en felrapport om Tomahawk kraschar - + Allow web browsers to interact with Tomahawk (recommended) @@ -3270,7 +3275,7 @@ enter the displayed PIN number here: - + Play Spela upp @@ -3290,172 +3295,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 e7db53448..eab967dcc 100644 --- a/lang/tomahawk_tr.ts +++ b/lang/tomahawk_tr.ts @@ -373,12 +373,12 @@ connect and stream from you? - + Show Footnotes Dipnotları Göster - + Hide Footnotes Dipnotları Gizle @@ -1226,47 +1226,67 @@ connect and stream from you? SettingsDialog - + Collection - + Advanced - + All - + + Tomahawk Settings + + + + Some changed settings will not take effect until Tomahawk is restarted - + Services - + + <b>Services</b><br>Configure the accounts and services used by Tomahawk to search and retrieve music, find your friends and update your status. + + + + + <b>Collection</b><br>Manage how Tomahawk finds music on your computer. + + + + + <b>Advanced</b><br>Configure Tomahawk's advanced settings, including network connectivity settings, browser interaction and more. + + + + Install resolver from file - + Delete all Access Control entries? - + Do you really want to delete all Access Control entries? You will be asked for a decision again for each peer that you connect to. - + Information @@ -1685,17 +1705,12 @@ connect and stream from you? - - Local Music Information - - - - + Path to scan for music files: - + The Echo Nest supports keeping track of your catalog metadata and using it to craft personalized radios. Enabling this option will allow you (and all your friends) to create automatic playlists @@ -1703,107 +1718,97 @@ connect and stream from you? - + Upload collection list to The Echo Nest to enable user radio - + Watch for changes - + Time between scans, in seconds: - - Advanced Settings - - - - + Remote Peer Connection Method - + None (outgoing connections only) - + Use UPnP to establish port forward (recommended) - + Use static external IP address/host name and port - + Set this to your external IP address or host name. Make sure to forward the port to this host! - + SOCKS Proxy - + Use SOCKS Proxy - + Clear All Access Control Entries - - Internet Services - - - - + Install from file... - + Filter by capability: - + Static Host Name: - + Static Port: - + Proxy Settings... - + Other Settings - + Send reports after Tomahawk crashed - + Allow web browsers to interact with Tomahawk (recommended) @@ -3269,7 +3274,7 @@ enter the displayed PIN number here: - + Play @@ -3289,172 +3294,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 dfc30b483..5804711f1 100644 --- a/lang/tomahawk_zh_CN.ts +++ b/lang/tomahawk_zh_CN.ts @@ -373,12 +373,12 @@ connect and stream from you? - + Show Footnotes 显示脚注 - + Hide Footnotes 隐藏脚注 @@ -1226,47 +1226,67 @@ connect and stream from you? SettingsDialog - + Collection - + Advanced - + All - + + Tomahawk Settings + + + + Some changed settings will not take effect until Tomahawk is restarted - + Services - + + <b>Services</b><br>Configure the accounts and services used by Tomahawk to search and retrieve music, find your friends and update your status. + + + + + <b>Collection</b><br>Manage how Tomahawk finds music on your computer. + + + + + <b>Advanced</b><br>Configure Tomahawk's advanced settings, including network connectivity settings, browser interaction and more. + + + + Install resolver from file - + Delete all Access Control entries? - + Do you really want to delete all Access Control entries? You will be asked for a decision again for each peer that you connect to. - + Information @@ -1685,17 +1705,12 @@ connect and stream from you? - - Local Music Information - - - - + Path to scan for music files: - + The Echo Nest supports keeping track of your catalog metadata and using it to craft personalized radios. Enabling this option will allow you (and all your friends) to create automatic playlists @@ -1703,107 +1718,97 @@ connect and stream from you? - + Upload collection list to The Echo Nest to enable user radio - + Watch for changes - + Time between scans, in seconds: - - Advanced Settings - - - - + Remote Peer Connection Method - + None (outgoing connections only) - + Use UPnP to establish port forward (recommended) - + Use static external IP address/host name and port - + Set this to your external IP address or host name. Make sure to forward the port to this host! - + SOCKS Proxy - + Use SOCKS Proxy - + Clear All Access Control Entries - - Internet Services - - - - + Install from file... - + Filter by capability: - + Static Host Name: - + Static Port: - + Proxy Settings... - + Other Settings - + Send reports after Tomahawk crashed - + Allow web browsers to interact with Tomahawk (recommended) 允许浏览器与 Tomahawk 之间的交互 (推荐) @@ -3269,7 +3274,7 @@ enter the displayed PIN number here: - + Play @@ -3289,172 +3294,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 1c496449d..dc1c4c22b 100644 --- a/lang/tomahawk_zh_TW.ts +++ b/lang/tomahawk_zh_TW.ts @@ -373,12 +373,12 @@ connect and stream from you? - + Show Footnotes 顯示註腳 - + Hide Footnotes 隱藏註腳 @@ -1226,47 +1226,67 @@ connect and stream from you? SettingsDialog - + Collection 收藏 - + Advanced 進階 - + All 所有 - + + Tomahawk Settings + + + + Some changed settings will not take effect until Tomahawk is restarted - + Services 服務 - + + <b>Services</b><br>Configure the accounts and services used by Tomahawk to search and retrieve music, find your friends and update your status. + + + + + <b>Collection</b><br>Manage how Tomahawk finds music on your computer. + + + + + <b>Advanced</b><br>Configure Tomahawk's advanced settings, including network connectivity settings, browser interaction and more. + + + + Install resolver from file 從檔案安裝解析器 - + Delete all Access Control entries? - + Do you really want to delete all Access Control entries? You will be asked for a decision again for each peer that you connect to. - + Information 資訊 @@ -1685,17 +1705,12 @@ connect and stream from you? Tomahawk 設定 - - Local Music Information - 本地音樂資訊 - - - + Path to scan for music files: 掃描音樂檔的路徑: - + The Echo Nest supports keeping track of your catalog metadata and using it to craft personalized radios. Enabling this option will allow you (and all your friends) to create automatic playlists @@ -1703,107 +1718,97 @@ connect and stream from you? - + Upload collection list to The Echo Nest to enable user radio - + Watch for changes 觀看變化 - + Time between scans, in seconds: - - Advanced Settings - - - - + Remote Peer Connection Method - + None (outgoing connections only) - + Use UPnP to establish port forward (recommended) - + Use static external IP address/host name and port - + Set this to your external IP address or host name. Make sure to forward the port to this host! - + SOCKS Proxy - + Use SOCKS Proxy - + Clear All Access Control Entries - - Internet Services - 上網服務 - - - + Install from file... 從安裝檔案... - + Filter by capability: 按能力篩選: - + Static Host Name: 靜態主機名稱: - + Static Port: 靜態通訊埠: - + Proxy Settings... 代理服務器設定... - + Other Settings - + Send reports after Tomahawk crashed - + Allow web browsers to interact with Tomahawk (recommended) 允許 Web 瀏覽器與 Tomahawk 互動 (推薦) @@ -3269,7 +3274,7 @@ enter the displayed PIN number here: - + Play 播放 @@ -3289,172 +3294,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 70cb7bd92b9a2002f072e2c1df43846e6028fffb Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Fri, 3 Aug 2012 01:28:03 +0200 Subject: [PATCH 74/79] QCA is not optional anymore for a long time --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c1331dd12..3ce8f10fa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -122,7 +122,7 @@ 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) -macro_log_feature(QCA2_FOUND "QCA2" "Provides encryption and signing functions required for Grooveshark resolver" "http://delta.affinix.com/qca/" FALSE "" "") +macro_log_feature(QCA2_FOUND "QCA2" "Provides encryption and signing functions required for Grooveshark resolver" "http://delta.affinix.com/qca/" TRUE "" "") macro_optional_find_package(LibAttica 0.4.0) macro_log_feature(LIBATTICA_FOUND "libattica" "Provides support for automatic fetching and managing of resolvers from the tomahawk website" "https://projects.kde.org/projects/kdesupport/attica" TRUE "" "") From 8b42e88a8dc73439a70075fe2e60d817f76573a1 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Fri, 3 Aug 2012 07:20:02 +0200 Subject: [PATCH 75/79] * Fixes for compiling new settings dialog on OSX. --- src/SettingsDialog.cpp | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/SettingsDialog.cpp b/src/SettingsDialog.cpp index 024e8a603..d516a8dee 100644 --- a/src/SettingsDialog.cpp +++ b/src/SettingsDialog.cpp @@ -120,22 +120,11 @@ SettingsDialog::SettingsDialog( QWidget *parent ) setContentsMargins( 0, 4, 4, 4 ); #endif -#ifdef Q_WS_MAC - ui->listWidget->setFixedWidth( 83 ); -#endif - #ifdef Q_WS_MAC // Avoid resize handles on sheets on osx m_proxySettings.setSizeGripEnabled( true ); QSizeGrip* p = m_proxySettings.findChild< QSizeGrip* >(); p->setFixedSize( 0, 0 ); - - ui->groupBoxNetworkAdvanced->layout()->removeItem( ui->verticalSpacer ); - ui->groupBoxNetworkAdvanced->layout()->removeItem( ui->verticalSpacer_2 ); - ui->groupBoxNetworkAdvanced->layout()->removeItem( ui->verticalSpacer_4 ); - delete ui->verticalSpacer; - delete ui->verticalSpacer_2; - delete ui->verticalSpacer_4; #endif // Accounts From 0dd2cb5f1559c480a7bbfa9984f765c74da623e0 Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Fri, 3 Aug 2012 15:46:57 +0200 Subject: [PATCH 76/79] Don't let the Settings dialog be shrunk too much. --- src/SettingsDialog.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/SettingsDialog.cpp b/src/SettingsDialog.cpp index d516a8dee..9e449a387 100644 --- a/src/SettingsDialog.cpp +++ b/src/SettingsDialog.cpp @@ -193,6 +193,7 @@ SettingsDialog::SettingsDialog( QWidget *parent ) { ui->dirTree->checkPath( dir, Qt::Checked ); } + ui->advancedPage->setMinimumSize( ui->advancedPage->sizeHint() ); // NOW PLAYING // #ifdef Q_WS_MAC From afba38f9ff0f9da5df916d43d4d46593af19c2d6 Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Fri, 3 Aug 2012 16:03:15 +0200 Subject: [PATCH 77/79] Fixed alignment in Settings dialog, advanced page. --- src/SettingsDialog.cpp | 6 ++++++ src/StackedSettingsDialog.ui | 31 ++++++++++++++++++++++++++++--- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/SettingsDialog.cpp b/src/SettingsDialog.cpp index 9e449a387..7c5a8f964 100644 --- a/src/SettingsDialog.cpp +++ b/src/SettingsDialog.cpp @@ -195,6 +195,12 @@ SettingsDialog::SettingsDialog( QWidget *parent ) } ui->advancedPage->setMinimumSize( ui->advancedPage->sizeHint() ); + int buttonsWidth = qMax( ui->proxyButton->sizeHint().width(), + ui->aclEntryClearButton->sizeHint().width() ); + ui->proxyButton->setFixedWidth( buttonsWidth ); + ui->aclEntryClearButton->setFixedWidth( buttonsWidth ); + + // NOW PLAYING // #ifdef Q_WS_MAC // ui->checkBoxEnableAdium->setChecked( s->nowPlayingEnabled() ); diff --git a/src/StackedSettingsDialog.ui b/src/StackedSettingsDialog.ui index e260416d4..70d0c49fc 100644 --- a/src/StackedSettingsDialog.ui +++ b/src/StackedSettingsDialog.ui @@ -22,7 +22,7 @@ - 0 + 2 @@ -318,8 +318,30 @@ + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 40 + 20 + + + + + + + 0 + 0 + + Proxy Settings... @@ -353,7 +375,7 @@ - Qt::RightToLeft + Qt::LeftToRight Allow web browsers to interact with Tomahawk (recommended) @@ -366,7 +388,7 @@ - Qt::RightToLeft + Qt::LeftToRight Send reports after Tomahawk crashed @@ -383,6 +405,9 @@ Qt::Horizontal + + QSizePolicy::Expanding + 40 From 5d54f20becd654db39beac661ef295789e6584a0 Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Fri, 3 Aug 2012 16:08:54 +0200 Subject: [PATCH 78/79] Back to page 0. --- src/StackedSettingsDialog.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/StackedSettingsDialog.ui b/src/StackedSettingsDialog.ui index 70d0c49fc..af3cfe49d 100644 --- a/src/StackedSettingsDialog.ui +++ b/src/StackedSettingsDialog.ui @@ -22,7 +22,7 @@ - 2 + 0 From 3b083a25350550b853c5465ed38a307b829c5f12 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Fri, 3 Aug 2012 11:41:00 -0400 Subject: [PATCH 79/79] Handle case where attica load is super slow --- src/libtomahawk/accounts/AccountModel.cpp | 15 +++++++++++++-- src/libtomahawk/accounts/AccountModel.h | 2 ++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/libtomahawk/accounts/AccountModel.cpp b/src/libtomahawk/accounts/AccountModel.cpp index 41a1963c1..01b2687f6 100644 --- a/src/libtomahawk/accounts/AccountModel.cpp +++ b/src/libtomahawk/accounts/AccountModel.cpp @@ -38,8 +38,9 @@ using namespace Accounts; AccountModel::AccountModel( QObject* parent ) : QAbstractListModel( parent ) + , m_waitingForAtticaLoaded( true ) { - connect( AtticaManager::instance(), SIGNAL( resolversLoaded( Attica::Content::List ) ), this, SLOT( loadData() ) ); + connect( AtticaManager::instance(), SIGNAL( resolversLoaded( Attica::Content::List ) ), this, SLOT( atticaLoaded() ) ); connect( AtticaManager::instance(), SIGNAL( startedInstalling( QString ) ), this, SLOT( onStartedInstalling( QString ) ) ); connect( AtticaManager::instance(), SIGNAL( resolverInstalled( QString ) ), this, SLOT( onFinishedInstalling( QString ) ) ); connect( AtticaManager::instance(), SIGNAL( resolverInstallationFailed( QString ) ), this, SLOT( resolverInstallFailed( QString ) ) ); @@ -51,6 +52,15 @@ AccountModel::AccountModel( QObject* parent ) loadData(); } + +void +AccountModel::atticaLoaded() +{ + m_waitingForAtticaLoaded = false; + loadData(); +} + + void AccountModel::loadData() { @@ -644,7 +654,8 @@ AccountModel::accountAdded( Account* account ) if ( ResolverAccount* resolver = qobject_cast< ResolverAccount* >( account ) ) { qDebug() << "Plain old manual resolver added, appending at end"; - Q_ASSERT( qobject_cast< AtticaResolverAccount* >( account ) == 0 ); // should NOT get attica accounts here, should be caught above + if ( !m_waitingForAtticaLoaded ) + Q_ASSERT( qobject_cast< AtticaResolverAccount* >( account ) == 0 ); // should NOT get attica accounts here, should be caught above const int count = m_accounts.size(); beginInsertRows( QModelIndex(), count, count ); m_accounts << new AccountModelNode( resolver ); diff --git a/src/libtomahawk/accounts/AccountModel.h b/src/libtomahawk/accounts/AccountModel.h index 13de779f1..09be15187 100644 --- a/src/libtomahawk/accounts/AccountModel.h +++ b/src/libtomahawk/accounts/AccountModel.h @@ -100,6 +100,7 @@ signals: void errorInstalling( const QPersistentModelIndex& idx ); private slots: + void atticaLoaded(); void loadData(); void accountAdded( Tomahawk::Accounts::Account* ); @@ -112,6 +113,7 @@ private slots: private: QModelIndex indexForAtticaId( const QString& resolverId ) const; + bool m_waitingForAtticaLoaded; QList< AccountModelNode* > m_accounts; QSet< QString > m_waitingForAtticaInstall; };