From c9a3b697ef9827f262726c43fe8a51477edc03f9 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Fri, 16 Mar 2012 17:50:26 +0100 Subject: [PATCH 01/29] * Easier substring extraction. --- src/libtomahawk/database/databaseimpl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libtomahawk/database/databaseimpl.cpp b/src/libtomahawk/database/databaseimpl.cpp index 54e3e993f..8eb193441 100644 --- a/src/libtomahawk/database/databaseimpl.cpp +++ b/src/libtomahawk/database/databaseimpl.cpp @@ -482,7 +482,7 @@ DatabaseImpl::sortname( const QString& str, bool replaceArticle ) if ( replaceArticle && s.startsWith( "the " ) ) { - s = s.right( s.length() - 4 ); + s = s.mid( 4 ); } return s; From ce44b175440dd62fb8901a4e3ef7f43bebc45577 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Fri, 16 Mar 2012 17:50:39 +0100 Subject: [PATCH 02/29] * Updated ChangeLog. --- ChangeLog | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ChangeLog b/ChangeLog index d7433e89b..cb01d412d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,5 @@ +Version 0.4.1: + Version 0.4.0: * Added visual notification for database indexing job. * Fixed icons not appearing in resolvers list. From 28f62d850d6335e10a7d0e30ac94a84c6673cd56 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Fri, 16 Mar 2012 20:14:11 +0100 Subject: [PATCH 03/29] * Attempt to unbreak headless. --- src/libtomahawk/album.h | 2 ++ src/libtomahawk/artist.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/libtomahawk/album.h b/src/libtomahawk/album.h index 1e886c47c..df0b805be 100644 --- a/src/libtomahawk/album.h +++ b/src/libtomahawk/album.h @@ -73,7 +73,9 @@ private: QString m_name; artist_ptr m_artist; QByteArray m_coverBuffer; +#ifndef ENABLE_HEADLESS mutable QPixmap* m_cover; +#endif bool m_infoLoaded; mutable QString m_uuid; diff --git a/src/libtomahawk/artist.h b/src/libtomahawk/artist.h index a9f9a5b7c..b99917026 100644 --- a/src/libtomahawk/artist.h +++ b/src/libtomahawk/artist.h @@ -72,7 +72,9 @@ private: QString m_name; QString m_sortname; QByteArray m_coverBuffer; +#ifndef ENABLE_HEADLESS mutable QPixmap* m_cover; +#endif bool m_infoLoaded; mutable QString m_uuid; From 967c767f0b278e088d5a1c811a145b24af3748fa Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Fri, 16 Mar 2012 20:16:03 +0100 Subject: [PATCH 04/29] * More headless fixes. --- src/libtomahawk/album.cpp | 2 ++ src/libtomahawk/artist.cpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/libtomahawk/album.cpp b/src/libtomahawk/album.cpp index 16dfc5ca4..21bf0a609 100644 --- a/src/libtomahawk/album.cpp +++ b/src/libtomahawk/album.cpp @@ -31,7 +31,9 @@ using namespace Tomahawk; Album::~Album() { +#ifndef ENABLE_HEADLESS delete m_cover; +#endif } diff --git a/src/libtomahawk/artist.cpp b/src/libtomahawk/artist.cpp index 0171ffa23..1daee97e5 100644 --- a/src/libtomahawk/artist.cpp +++ b/src/libtomahawk/artist.cpp @@ -31,7 +31,9 @@ using namespace Tomahawk; Artist::~Artist() { +#ifndef ENABLE_HEADLESS delete m_cover; +#endif } From 4d91fab887392413b27c537f7c1c3100b347c397 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Fri, 16 Mar 2012 20:23:27 +0100 Subject: [PATCH 05/29] * Headless fix. --- src/libtomahawk/album.cpp | 2 ++ src/libtomahawk/artist.cpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/libtomahawk/album.cpp b/src/libtomahawk/album.cpp index 21bf0a609..b1489ddc8 100644 --- a/src/libtomahawk/album.cpp +++ b/src/libtomahawk/album.cpp @@ -76,7 +76,9 @@ Album::Album( unsigned int id, const QString& name, const Tomahawk::artist_ptr& , m_id( id ) , m_name( name ) , m_artist( artist ) +#ifndef ENABLE_HEADLESS , m_cover( 0 ) +#endif , m_infoLoaded( false ) { connect( Tomahawk::InfoSystem::InfoSystem::instance(), diff --git a/src/libtomahawk/artist.cpp b/src/libtomahawk/artist.cpp index 1daee97e5..20cb4f116 100644 --- a/src/libtomahawk/artist.cpp +++ b/src/libtomahawk/artist.cpp @@ -75,7 +75,9 @@ Artist::Artist( unsigned int id, const QString& name ) : QObject() , m_id( id ) , m_name( name ) +#ifndef ENABLE_HEADLESS , m_cover( 0 ) +#endif , m_infoLoaded( false ) { m_sortname = DatabaseImpl::sortname( name, true ); From 0e2da32f0c3c92267f97fe75aa89a77fc26c0953 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Fri, 16 Mar 2012 20:26:30 +0100 Subject: [PATCH 06/29] * Headless. Now. --- src/libtomahawk/album.cpp | 2 +- src/libtomahawk/album.h | 6 +++--- src/libtomahawk/artist.cpp | 2 +- src/libtomahawk/artist.h | 6 +++--- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/libtomahawk/album.cpp b/src/libtomahawk/album.cpp index b1489ddc8..417880d5e 100644 --- a/src/libtomahawk/album.cpp +++ b/src/libtomahawk/album.cpp @@ -76,10 +76,10 @@ Album::Album( unsigned int id, const QString& name, const Tomahawk::artist_ptr& , m_id( id ) , m_name( name ) , m_artist( artist ) + , m_infoLoaded( false ) #ifndef ENABLE_HEADLESS , m_cover( 0 ) #endif - , m_infoLoaded( false ) { connect( Tomahawk::InfoSystem::InfoSystem::instance(), SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ), diff --git a/src/libtomahawk/album.h b/src/libtomahawk/album.h index df0b805be..9ecacf900 100644 --- a/src/libtomahawk/album.h +++ b/src/libtomahawk/album.h @@ -73,13 +73,13 @@ private: QString m_name; artist_ptr m_artist; QByteArray m_coverBuffer; -#ifndef ENABLE_HEADLESS - mutable QPixmap* m_cover; -#endif bool m_infoLoaded; mutable QString m_uuid; +#ifndef ENABLE_HEADLESS + mutable QPixmap* m_cover; mutable QHash< int, QPixmap > m_coverCache; +#endif Tomahawk::playlistinterface_ptr m_playlistInterface; }; diff --git a/src/libtomahawk/artist.cpp b/src/libtomahawk/artist.cpp index 20cb4f116..e90ca835a 100644 --- a/src/libtomahawk/artist.cpp +++ b/src/libtomahawk/artist.cpp @@ -75,10 +75,10 @@ Artist::Artist( unsigned int id, const QString& name ) : QObject() , m_id( id ) , m_name( name ) + , m_infoLoaded( false ) #ifndef ENABLE_HEADLESS , m_cover( 0 ) #endif - , m_infoLoaded( false ) { m_sortname = DatabaseImpl::sortname( name, true ); diff --git a/src/libtomahawk/artist.h b/src/libtomahawk/artist.h index b99917026..0c656bfa6 100644 --- a/src/libtomahawk/artist.h +++ b/src/libtomahawk/artist.h @@ -72,13 +72,13 @@ private: QString m_name; QString m_sortname; QByteArray m_coverBuffer; -#ifndef ENABLE_HEADLESS - mutable QPixmap* m_cover; -#endif bool m_infoLoaded; mutable QString m_uuid; +#ifndef ENABLE_HEADLESS + mutable QPixmap* m_cover; mutable QHash< int, QPixmap > m_coverCache; +#endif Tomahawk::playlistinterface_ptr m_playlistInterface; }; From 8b99d234e86b7374c74a3c6f24f7c22d9f66407a Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Fri, 16 Mar 2012 22:12:17 +0100 Subject: [PATCH 07/29] * DRY: Added RecentlyPlayedModel. --- src/libtomahawk/CMakeLists.txt | 1 + .../playlist/RecentlyPlayedModel.cpp | 140 ++++++++++++++++++ .../playlist/RecentlyPlayedModel.h | 55 +++++++ src/libtomahawk/playlist/playlistmodel.cpp | 20 --- src/libtomahawk/playlist/playlistmodel.h | 4 +- .../widgets/infowidgets/sourceinfowidget.cpp | 13 +- .../widgets/infowidgets/sourceinfowidget.h | 5 +- src/libtomahawk/widgets/welcomewidget.cpp | 78 ++-------- src/libtomahawk/widgets/welcomewidget.h | 10 +- 9 files changed, 213 insertions(+), 113 deletions(-) create mode 100644 src/libtomahawk/playlist/RecentlyPlayedModel.cpp create mode 100644 src/libtomahawk/playlist/RecentlyPlayedModel.h diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index 52d714ad2..b9d636d73 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -77,6 +77,7 @@ set( libGuiSources playlist/artistview.cpp playlist/customplaylistview.cpp playlist/ViewHeader.cpp + playlist/RecentlyPlayedModel.cpp playlist/dynamic/DynamicPlaylist.cpp playlist/dynamic/DynamicView.cpp diff --git a/src/libtomahawk/playlist/RecentlyPlayedModel.cpp b/src/libtomahawk/playlist/RecentlyPlayedModel.cpp new file mode 100644 index 000000000..db41f2766 --- /dev/null +++ b/src/libtomahawk/playlist/RecentlyPlayedModel.cpp @@ -0,0 +1,140 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2012, Christian Muehlhaeuser + * + * 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 "RecentlyPlayedModel.h" + +#include +#include + +#include "source.h" +#include "sourcelist.h" +#include "database/database.h" +#include "database/databasecommand_playbackhistory.h" +#include "utils/tomahawkutils.h" +#include "utils/logger.h" + +#define HISTORY_TRACK_ITEMS 25 + +using namespace Tomahawk; + + +RecentlyPlayedModel::RecentlyPlayedModel( const source_ptr& source, QObject* parent ) + : PlaylistModel( parent ) + , m_source( source ) + , m_limit( HISTORY_TRACK_ITEMS ) +{ + if ( source.isNull() ) + { + connect( SourceList::instance(), SIGNAL( ready() ), SLOT( onSourcesReady() ) ); + connect( SourceList::instance(), SIGNAL( sourceAdded( Tomahawk::source_ptr ) ), SLOT( onSourceAdded( Tomahawk::source_ptr ) ) ); + } + else + { + onSourceAdded( source ); + loadHistory(); + } +} + + +RecentlyPlayedModel::~RecentlyPlayedModel() +{ +} + + +void +RecentlyPlayedModel::loadHistory() +{ + if ( rowCount( QModelIndex() ) ) + { + clear(); + } + + DatabaseCommand_PlaybackHistory* cmd = new DatabaseCommand_PlaybackHistory( m_source ); + cmd->setLimit( m_limit ); + + connect( cmd, SIGNAL( tracks( QList ) ), + SLOT( append( QList ) ), Qt::QueuedConnection ); + + Database::instance()->enqueue( QSharedPointer( cmd ) ); +} + + +void +RecentlyPlayedModel::onSourcesReady() +{ + Q_ASSERT( m_source.isNull() ); + + loadHistory(); + + foreach ( const source_ptr& source, SourceList::instance()->sources() ) + onSourceAdded( source ); +} + + +void +RecentlyPlayedModel::onSourceAdded( const Tomahawk::source_ptr& source ) +{ + connect( source.data(), SIGNAL( playbackFinished( Tomahawk::query_ptr ) ), SLOT( onPlaybackFinished( Tomahawk::query_ptr ) ), Qt::UniqueConnection ); +} + + +void +RecentlyPlayedModel::onPlaybackFinished( const Tomahawk::query_ptr& query ) +{ + int count = trackCount(); + unsigned int playtime = query->playedBy().second; + + if ( count ) + { + TrackModelItem* oldestItem = itemFromIndex( index( count - 1, 0, QModelIndex() ) ); + if ( oldestItem->query()->playedBy().second >= playtime ) + return; + + TrackModelItem* youngestItem = itemFromIndex( index( 0, 0, QModelIndex() ) ); + if ( youngestItem->query()->playedBy().second <= playtime ) + insert( query, 0 ); + else + { + for ( int i = 0; i < count - 1; i++ ) + { + TrackModelItem* item1 = itemFromIndex( index( i, 0, QModelIndex() ) ); + TrackModelItem* item2 = itemFromIndex( index( i + 1, 0, QModelIndex() ) ); + + if ( item1->query()->playedBy().second >= playtime && item2->query()->playedBy().second <= playtime ) + { + insert( query, i + 1 ); + break; + } + } + } + } + else + insert( query, 0 ); + + if ( trackCount() > (int)m_limit ) + remove( m_limit ); + + ensureResolved(); +} + + +bool +RecentlyPlayedModel::isTemporary() const +{ + return true; +} diff --git a/src/libtomahawk/playlist/RecentlyPlayedModel.h b/src/libtomahawk/playlist/RecentlyPlayedModel.h new file mode 100644 index 000000000..748535905 --- /dev/null +++ b/src/libtomahawk/playlist/RecentlyPlayedModel.h @@ -0,0 +1,55 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Christian Muehlhaeuser + * + * 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 RECENTLYPLAYEDMODEL_H +#define RECENTLYPLAYEDMODEL_H + +#include +#include + +#include "typedefs.h" +#include "playlistmodel.h" + +#include "dllmacro.h" + +class DLLEXPORT RecentlyPlayedModel : public PlaylistModel +{ +Q_OBJECT + +public: + explicit RecentlyPlayedModel( const Tomahawk::source_ptr& source, QObject* parent = 0 ); + ~RecentlyPlayedModel(); + + unsigned int limit() const { return m_limit; } + void setLimit( unsigned int limit ) { m_limit = limit; } + + bool isTemporary() const; + +private slots: + void onSourcesReady(); + void onSourceAdded( const Tomahawk::source_ptr& source ); + + void onPlaybackFinished( const Tomahawk::query_ptr& query ); + void loadHistory(); + +private: + Tomahawk::source_ptr m_source; + unsigned int m_limit; +}; + +#endif // RECENTLYPLAYEDMODEL_H diff --git a/src/libtomahawk/playlist/playlistmodel.cpp b/src/libtomahawk/playlist/playlistmodel.cpp index 4cd5a2b59..6d5d28392 100644 --- a/src/libtomahawk/playlist/playlistmodel.cpp +++ b/src/libtomahawk/playlist/playlistmodel.cpp @@ -86,26 +86,6 @@ PlaylistModel::loadPlaylist( const Tomahawk::playlist_ptr& playlist, bool loadEn } -void -PlaylistModel::loadHistory( const Tomahawk::source_ptr& source, unsigned int amount ) -{ - if ( rowCount( QModelIndex() ) ) - { - clear(); - } - - m_playlist.clear(); - - DatabaseCommand_PlaybackHistory* cmd = new DatabaseCommand_PlaybackHistory( source ); - cmd->setLimit( amount ); - - connect( cmd, SIGNAL( tracks( QList ) ), - SLOT( append( QList ) ), Qt::QueuedConnection ); - - Database::instance()->enqueue( QSharedPointer( cmd ) ); -} - - void PlaylistModel::clear() { diff --git a/src/libtomahawk/playlist/playlistmodel.h b/src/libtomahawk/playlist/playlistmodel.h index 95d4dddaf..f5586e043 100644 --- a/src/libtomahawk/playlist/playlistmodel.h +++ b/src/libtomahawk/playlist/playlistmodel.h @@ -47,14 +47,12 @@ public: explicit PlaylistModel( QObject* parent = 0 ); ~PlaylistModel(); - virtual QMimeData* mimeData ( const QModelIndexList& indexes ) const; + virtual QMimeData* mimeData( const QModelIndexList& indexes ) const; virtual bool dropMimeData( const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent ); Tomahawk::playlist_ptr playlist() const { return m_playlist; } virtual void loadPlaylist( const Tomahawk::playlist_ptr& playlist, bool loadEntries = true ); - void loadHistory( const Tomahawk::source_ptr& source, unsigned int amount = 50 ); - bool isTemporary() const; public slots: diff --git a/src/libtomahawk/widgets/infowidgets/sourceinfowidget.cpp b/src/libtomahawk/widgets/infowidgets/sourceinfowidget.cpp index 6f133872e..9a67ce08d 100644 --- a/src/libtomahawk/widgets/infowidgets/sourceinfowidget.cpp +++ b/src/libtomahawk/widgets/infowidgets/sourceinfowidget.cpp @@ -24,7 +24,7 @@ #include "playlist/albummodel.h" #include "playlist/collectionflatmodel.h" -#include "playlist/playlistmodel.h" +#include "playlist/RecentlyPlayedModel.h" #include "database/database.h" #include "database/databasecommand_alltracks.h" @@ -66,10 +66,9 @@ SourceInfoWidget::SourceInfoWidget( const Tomahawk::source_ptr& source, QWidget* ui->recentCollectionView->setTrackModel( m_recentCollectionModel ); ui->recentCollectionView->sortByColumn( TrackModel::Age, Qt::DescendingOrder ); - m_historyModel = new PlaylistModel( ui->historyView ); + m_historyModel = new RecentlyPlayedModel( source, ui->historyView ); m_historyModel->setStyle( TrackModel::Short ); ui->historyView->setPlaylistModel( m_historyModel ); - m_historyModel->loadHistory( source, 25 ); m_recentAlbumModel = new AlbumModel( ui->recentAlbumView ); ui->recentAlbumView->setAlbumModel( m_recentAlbumModel ); @@ -78,7 +77,6 @@ SourceInfoWidget::SourceInfoWidget( const Tomahawk::source_ptr& source, QWidget* onCollectionChanged(); connect( source->collection().data(), SIGNAL( changed() ), SLOT( onCollectionChanged() ) ); - connect( source.data(), SIGNAL( playbackFinished( Tomahawk::query_ptr ) ), SLOT( onPlaybackFinished( Tomahawk::query_ptr ) ) ); m_title = tr( "New Additions" ); if ( source->isLocal() ) @@ -138,13 +136,6 @@ SourceInfoWidget::onLoadedTrackHistory( const QList& querie } -void -SourceInfoWidget::onPlaybackFinished( const Tomahawk::query_ptr& query ) -{ - m_historyModel->insert( query, 0 ); -} - - void SourceInfoWidget::changeEvent( QEvent* e ) { diff --git a/src/libtomahawk/widgets/infowidgets/sourceinfowidget.h b/src/libtomahawk/widgets/infowidgets/sourceinfowidget.h index eb1817aba..1c5f67da9 100644 --- a/src/libtomahawk/widgets/infowidgets/sourceinfowidget.h +++ b/src/libtomahawk/widgets/infowidgets/sourceinfowidget.h @@ -28,7 +28,7 @@ class AlbumModel; class CollectionFlatModel; -class PlaylistModel; +class RecentlyPlayedModel; namespace Ui { @@ -62,14 +62,13 @@ private slots: void loadRecentAdditions(); void onCollectionChanged(); - void onPlaybackFinished( const Tomahawk::query_ptr& query ); void onLoadedTrackHistory( const QList& queries ); private: Ui::SourceInfoWidget *ui; CollectionFlatModel* m_recentCollectionModel; - PlaylistModel* m_historyModel; + RecentlyPlayedModel* m_historyModel; AlbumModel* m_recentAlbumModel; Tomahawk::source_ptr m_source; diff --git a/src/libtomahawk/widgets/welcomewidget.cpp b/src/libtomahawk/widgets/welcomewidget.cpp index 145771d1c..3235a2371 100644 --- a/src/libtomahawk/widgets/welcomewidget.cpp +++ b/src/libtomahawk/widgets/welcomewidget.cpp @@ -29,16 +29,14 @@ #include "audio/audioengine.h" #include "playlist/albummodel.h" -#include "playlist/playlistmodel.h" +#include "playlist/RecentlyPlayedModel.h" #include "widgets/overlaywidget.h" #include "utils/tomahawkutils.h" #include "utils/logger.h" #include "dynamic/GeneratorInterface.h" #include "RecentlyPlayedPlaylistsModel.h" -#define HISTORY_TRACK_ITEMS 25 #define HISTORY_PLAYLIST_ITEMS 10 -#define HISTORY_RESOLVING_TIMEOUT 2500 using namespace Tomahawk; @@ -72,7 +70,7 @@ WelcomeWidget::WelcomeWidget( QWidget* parent ) ui->playlistWidget->setVerticalScrollMode( QAbstractItemView::ScrollPerPixel ); updatePlaylists(); - m_tracksModel = new PlaylistModel( ui->tracksView ); + m_tracksModel = new RecentlyPlayedModel( source_ptr(), ui->tracksView ); m_tracksModel->setStyle( TrackModel::ShortWithAvatars ); ui->tracksView->overlay()->setEnabled( false ); ui->tracksView->setPlaylistModel( m_tracksModel ); @@ -81,9 +79,6 @@ WelcomeWidget::WelcomeWidget( QWidget* parent ) ui->additionsView->setAlbumModel( m_recentAlbumsModel ); ui->additionsView->proxyModel()->sort( -1 ); - m_timer = new QTimer( this ); - connect( m_timer, SIGNAL( timeout() ), SLOT( checkQueries() ) ); - 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 ) ) ); @@ -129,13 +124,18 @@ WelcomeWidget::isBeingPlayed() const void WelcomeWidget::onSourcesReady() { - m_tracksModel->loadHistory( Tomahawk::source_ptr(), HISTORY_TRACK_ITEMS ); - foreach ( const source_ptr& source, SourceList::instance()->sources() ) onSourceAdded( source ); } +void +WelcomeWidget::onSourceAdded( const Tomahawk::source_ptr& source ) +{ + connect( source->collection().data(), SIGNAL( changed() ), SLOT( updateRecentAdditions() ), Qt::UniqueConnection ); +} + + void WelcomeWidget::updateRecentAdditions() { @@ -157,66 +157,6 @@ WelcomeWidget::updatePlaylists() } -void -WelcomeWidget::onSourceAdded( const Tomahawk::source_ptr& source ) -{ - connect( source->collection().data(), SIGNAL( changed() ), SLOT( updateRecentAdditions() ), Qt::UniqueConnection ); - connect( source.data(), SIGNAL( playbackFinished( Tomahawk::query_ptr ) ), SLOT( onPlaybackFinished( Tomahawk::query_ptr ) ), Qt::UniqueConnection ); -} - - -void -WelcomeWidget::checkQueries() -{ - if ( m_timer->isActive() ) - m_timer->stop(); - - m_tracksModel->ensureResolved(); -} - - -void -WelcomeWidget::onPlaybackFinished( const Tomahawk::query_ptr& query ) -{ - int count = m_tracksModel->trackCount(); - unsigned int playtime = query->playedBy().second; - - if ( count ) - { - TrackModelItem* oldestItem = m_tracksModel->itemFromIndex( m_tracksModel->index( count - 1, 0, QModelIndex() ) ); - if ( oldestItem->query()->playedBy().second >= playtime ) - return; - - TrackModelItem* youngestItem = m_tracksModel->itemFromIndex( m_tracksModel->index( 0, 0, QModelIndex() ) ); - if ( youngestItem->query()->playedBy().second <= playtime ) - m_tracksModel->insert( query, 0 ); - else - { - for ( int i = 0; i < count - 1; i++ ) - { - TrackModelItem* item1 = m_tracksModel->itemFromIndex( m_tracksModel->index( i, 0, QModelIndex() ) ); - TrackModelItem* item2 = m_tracksModel->itemFromIndex( m_tracksModel->index( i + 1, 0, QModelIndex() ) ); - - if ( item1->query()->playedBy().second >= playtime && item2->query()->playedBy().second <= playtime ) - { - m_tracksModel->insert( query, i + 1 ); - break; - } - } - } - } - else - m_tracksModel->insert( query, 0 ); - - if ( m_tracksModel->trackCount() > HISTORY_TRACK_ITEMS ) - m_tracksModel->remove( HISTORY_TRACK_ITEMS ); - - if ( m_timer->isActive() ) - m_timer->stop(); - m_timer->start( HISTORY_RESOLVING_TIMEOUT ); -} - - void WelcomeWidget::onPlaylistActivated( const QModelIndex& item ) { diff --git a/src/libtomahawk/widgets/welcomewidget.h b/src/libtomahawk/widgets/welcomewidget.h index dc4e9250c..6b5c7a929 100644 --- a/src/libtomahawk/widgets/welcomewidget.h +++ b/src/libtomahawk/widgets/welcomewidget.h @@ -34,7 +34,7 @@ #include "dllmacro.h" class AlbumModel; -class PlaylistModel; +class RecentlyPlayedModel; class OverlayWidget; namespace Ui @@ -106,21 +106,17 @@ public slots: void updateRecentAdditions(); void loadData(); + private slots: void onSourcesReady(); void onSourceAdded( const Tomahawk::source_ptr& source ); void onPlaylistActivated( const QModelIndex& ); - void onPlaybackFinished( const Tomahawk::query_ptr& query ); - - void checkQueries(); private: Ui::WelcomeWidget *ui; - PlaylistModel* m_tracksModel; + RecentlyPlayedModel* m_tracksModel; AlbumModel* m_recentAlbumsModel; - - QTimer* m_timer; }; #endif // WELCOMEWIDGET_H From 8495c6397ad08dd002d183b133c9c3685d3e9f00 Mon Sep 17 00:00:00 2001 From: Jason Herskowitz Date: Fri, 16 Mar 2012 17:43:06 -0400 Subject: [PATCH 08/29] Change text from GChat to Google Talk in account dialog --- src/accounts/xmpp/googlewrapper/googlewrapper.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/accounts/xmpp/googlewrapper/googlewrapper.h b/src/accounts/xmpp/googlewrapper/googlewrapper.h index 833cf3be2..24e677f7f 100644 --- a/src/accounts/xmpp/googlewrapper/googlewrapper.h +++ b/src/accounts/xmpp/googlewrapper/googlewrapper.h @@ -38,7 +38,7 @@ public: virtual QString prettyName() const { return "Google"; } virtual QString factoryId() const { return "googleaccount"; } - QString description() const { return tr( "Connect to GChat to find your friends" ); } + QString description() const { return tr( "Connect to Google Talk to find your friends" ); } virtual QPixmap icon() const; virtual Account* createAccount( const QString& pluginId ); }; From d2b719b61c869db1dfa60d6f2baac294fda72ee5 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Fri, 16 Mar 2012 22:48:31 +0100 Subject: [PATCH 09/29] * DRY: Added RecentlyAddedModel. --- src/libtomahawk/CMakeLists.txt | 1 + .../playlist/RecentlyAddedModel.cpp | 102 ++++++++++++++++++ src/libtomahawk/playlist/RecentlyAddedModel.h | 54 ++++++++++ .../playlist/collectionflatmodel.cpp | 10 -- .../playlist/collectionflatmodel.h | 2 - src/libtomahawk/playlist/playlistmodel.cpp | 9 -- src/libtomahawk/playlist/playlistmodel.h | 1 - src/libtomahawk/playlist/trackmodel.cpp | 9 ++ src/libtomahawk/playlist/trackmodel.h | 2 + .../widgets/infowidgets/sourceinfowidget.cpp | 33 +----- .../widgets/infowidgets/sourceinfowidget.h | 5 +- src/libtomahawk/widgets/welcomewidget.cpp | 1 - 12 files changed, 174 insertions(+), 55 deletions(-) create mode 100644 src/libtomahawk/playlist/RecentlyAddedModel.cpp create mode 100644 src/libtomahawk/playlist/RecentlyAddedModel.h diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index b9d636d73..6727aa2da 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -77,6 +77,7 @@ set( libGuiSources playlist/artistview.cpp playlist/customplaylistview.cpp playlist/ViewHeader.cpp + playlist/RecentlyAddedModel.cpp playlist/RecentlyPlayedModel.cpp playlist/dynamic/DynamicPlaylist.cpp diff --git a/src/libtomahawk/playlist/RecentlyAddedModel.cpp b/src/libtomahawk/playlist/RecentlyAddedModel.cpp new file mode 100644 index 000000000..e5adacc67 --- /dev/null +++ b/src/libtomahawk/playlist/RecentlyAddedModel.cpp @@ -0,0 +1,102 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2012, Christian Muehlhaeuser + * + * 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 "RecentlyAddedModel.h" + +#include +#include + +#include "source.h" +#include "sourcelist.h" +#include "database/database.h" +#include "database/databasecommand_alltracks.h" +#include "utils/tomahawkutils.h" +#include "utils/logger.h" + +#define LATEST_TRACK_ITEMS 250 + +using namespace Tomahawk; + + +RecentlyAddedModel::RecentlyAddedModel( const source_ptr& source, QObject* parent ) + : TrackModel( parent ) + , m_source( source ) + , m_limit( LATEST_TRACK_ITEMS ) +{ + if ( source.isNull() ) + { + connect( SourceList::instance(), SIGNAL( ready() ), SLOT( onSourcesReady() ) ); + connect( SourceList::instance(), SIGNAL( sourceAdded( Tomahawk::source_ptr ) ), SLOT( onSourceAdded( Tomahawk::source_ptr ) ) ); + } + else + { + onSourceAdded( source ); + loadHistory(); + } +} + + +RecentlyAddedModel::~RecentlyAddedModel() +{ +} + + +void +RecentlyAddedModel::loadHistory() +{ + if ( rowCount( QModelIndex() ) ) + { + clear(); + } + + DatabaseCommand_AllTracks* cmd = new DatabaseCommand_AllTracks( m_source->collection() ); + cmd->setLimit( m_limit ); + cmd->setSortOrder( DatabaseCommand_AllTracks::ModificationTime ); + cmd->setSortDescending( true ); + + connect( cmd, SIGNAL( tracks( QList, QVariant ) ), + SLOT( append( QList ) ), Qt::QueuedConnection ); + + Database::instance()->enqueue( QSharedPointer( cmd ) ); +} + + +void +RecentlyAddedModel::onSourcesReady() +{ + Q_ASSERT( m_source.isNull() ); + + loadHistory(); + + foreach ( const source_ptr& source, SourceList::instance()->sources() ) + onSourceAdded( source ); +} + + +void +RecentlyAddedModel::onSourceAdded( const Tomahawk::source_ptr& source ) +{ + connect( source->collection().data(), SIGNAL( changed() ), SLOT( loadHistory() ) ); +} + + +bool +RecentlyAddedModel::isTemporary() const +{ + return true; +} diff --git a/src/libtomahawk/playlist/RecentlyAddedModel.h b/src/libtomahawk/playlist/RecentlyAddedModel.h new file mode 100644 index 000000000..53d113f43 --- /dev/null +++ b/src/libtomahawk/playlist/RecentlyAddedModel.h @@ -0,0 +1,54 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Christian Muehlhaeuser + * + * 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 RECENTLYADDEDMODEL_H +#define RECENTLYADDEDMODEL_H + +#include +#include + +#include "typedefs.h" +#include "trackmodel.h" + +#include "dllmacro.h" + +class DLLEXPORT RecentlyAddedModel : public TrackModel +{ +Q_OBJECT + +public: + explicit RecentlyAddedModel( const Tomahawk::source_ptr& source, QObject* parent = 0 ); + ~RecentlyAddedModel(); + + unsigned int limit() const { return m_limit; } + void setLimit( unsigned int limit ) { m_limit = limit; } + + bool isTemporary() const; + +private slots: + void onSourcesReady(); + void onSourceAdded( const Tomahawk::source_ptr& source ); + + void loadHistory(); + +private: + Tomahawk::source_ptr m_source; + unsigned int m_limit; +}; + +#endif // RECENTLYADDEDMODEL_H diff --git a/src/libtomahawk/playlist/collectionflatmodel.cpp b/src/libtomahawk/playlist/collectionflatmodel.cpp index 7d94ba023..7265cb27b 100644 --- a/src/libtomahawk/playlist/collectionflatmodel.cpp +++ b/src/libtomahawk/playlist/collectionflatmodel.cpp @@ -138,13 +138,3 @@ CollectionFlatModel::onTracksRemoved( const QList& tracks ) } } } - - -void -CollectionFlatModel::onDataChanged() -{ - TrackModelItem* p = (TrackModelItem*)sender(); - - if ( p ) - emit dataChanged( p->index, p->index.sibling( p->index.row(), columnCount( QModelIndex() ) - 1 ) ); -} diff --git a/src/libtomahawk/playlist/collectionflatmodel.h b/src/libtomahawk/playlist/collectionflatmodel.h index 0d2784b44..b5982974f 100644 --- a/src/libtomahawk/playlist/collectionflatmodel.h +++ b/src/libtomahawk/playlist/collectionflatmodel.h @@ -58,8 +58,6 @@ signals: void trackCountChanged( unsigned int tracks ); private slots: - void onDataChanged(); - void onTracksAdded( const QList& tracks ); void onTracksRemoved( const QList& tracks ); diff --git a/src/libtomahawk/playlist/playlistmodel.cpp b/src/libtomahawk/playlist/playlistmodel.cpp index 6d5d28392..080af747e 100644 --- a/src/libtomahawk/playlist/playlistmodel.cpp +++ b/src/libtomahawk/playlist/playlistmodel.cpp @@ -257,15 +257,6 @@ PlaylistModel::trackResolved( bool ) } -void -PlaylistModel::onDataChanged() -{ - TrackModelItem* p = (TrackModelItem*)sender(); - if ( p && p->index.isValid() ) - emit dataChanged( p->index, p->index.sibling( p->index.row(), columnCount() - 1 ) ); -} - - void PlaylistModel::onRevisionLoaded( Tomahawk::PlaylistRevision revision ) { diff --git a/src/libtomahawk/playlist/playlistmodel.h b/src/libtomahawk/playlist/playlistmodel.h index f5586e043..01c3ff3b3 100644 --- a/src/libtomahawk/playlist/playlistmodel.h +++ b/src/libtomahawk/playlist/playlistmodel.h @@ -84,7 +84,6 @@ protected: void removeFromWaitList( const QString& revisionguid ) { m_waitForRevision.removeAll( revisionguid ); } private slots: - void onDataChanged(); void onRevisionLoaded( Tomahawk::PlaylistRevision revision ); void parsedDroppedTracks( QList ); void trackResolved( bool ); diff --git a/src/libtomahawk/playlist/trackmodel.cpp b/src/libtomahawk/playlist/trackmodel.cpp index e31885612..9633398c0 100644 --- a/src/libtomahawk/playlist/trackmodel.cpp +++ b/src/libtomahawk/playlist/trackmodel.cpp @@ -584,3 +584,12 @@ TrackModel::columnAlignment( int column ) const return Qt::AlignLeft; } } + + +void +TrackModel::onDataChanged() +{ + TrackModelItem* p = (TrackModelItem*)sender(); + if ( p && p->index.isValid() ) + emit dataChanged( p->index, p->index.sibling( p->index.row(), columnCount() - 1 ) ); +} diff --git a/src/libtomahawk/playlist/trackmodel.h b/src/libtomahawk/playlist/trackmodel.h index a368c508b..206fe7573 100644 --- a/src/libtomahawk/playlist/trackmodel.h +++ b/src/libtomahawk/playlist/trackmodel.h @@ -134,6 +134,8 @@ protected: TrackModelItem* rootItem() const { return m_rootItem; } private slots: + void onDataChanged(); + void onPlaybackStarted( const Tomahawk::result_ptr& result ); void onPlaybackStopped(); diff --git a/src/libtomahawk/widgets/infowidgets/sourceinfowidget.cpp b/src/libtomahawk/widgets/infowidgets/sourceinfowidget.cpp index 9a67ce08d..4514bdd85 100644 --- a/src/libtomahawk/widgets/infowidgets/sourceinfowidget.cpp +++ b/src/libtomahawk/widgets/infowidgets/sourceinfowidget.cpp @@ -24,10 +24,10 @@ #include "playlist/albummodel.h" #include "playlist/collectionflatmodel.h" +#include "playlist/RecentlyAddedModel.h" #include "playlist/RecentlyPlayedModel.h" #include "database/database.h" -#include "database/databasecommand_alltracks.h" #include "database/databasecommand_allalbums.h" #include "utils/tomahawkutils.h" @@ -61,9 +61,9 @@ SourceInfoWidget::SourceInfoWidget( const Tomahawk::source_ptr& source, QWidget* ui->historyView->overlay()->setEnabled( false ); - m_recentCollectionModel = new CollectionFlatModel( ui->recentCollectionView ); - m_recentCollectionModel->setStyle( TrackModel::Short ); - ui->recentCollectionView->setTrackModel( m_recentCollectionModel ); + m_recentTracksModel = new RecentlyAddedModel( source, ui->recentCollectionView ); + m_recentTracksModel->setStyle( TrackModel::Short ); + ui->recentCollectionView->setTrackModel( m_recentTracksModel ); ui->recentCollectionView->sortByColumn( TrackModel::Age, Qt::DescendingOrder ); m_historyModel = new RecentlyPlayedModel( source, ui->historyView ); @@ -75,7 +75,6 @@ SourceInfoWidget::SourceInfoWidget( const Tomahawk::source_ptr& source, QWidget* ui->recentAlbumView->proxyModel()->sort( -1 ); onCollectionChanged(); - connect( source->collection().data(), SIGNAL( changed() ), SLOT( onCollectionChanged() ) ); m_title = tr( "New Additions" ); @@ -101,7 +100,6 @@ SourceInfoWidget::~SourceInfoWidget() void SourceInfoWidget::onCollectionChanged() { - loadTracks(); loadRecentAdditions(); } @@ -113,29 +111,6 @@ SourceInfoWidget::loadRecentAdditions() } -void -SourceInfoWidget::loadTracks() -{ - DatabaseCommand_AllTracks* cmd = new DatabaseCommand_AllTracks( m_source->collection() ); - cmd->setLimit( 250 ); - cmd->setSortOrder( DatabaseCommand_AllTracks::ModificationTime ); - cmd->setSortDescending( true ); - - connect( cmd, SIGNAL( tracks( QList, QVariant ) ), - SLOT( onLoadedTrackHistory( QList ) ), Qt::QueuedConnection ); - - Database::instance()->enqueue( QSharedPointer( cmd ) ); -} - - -void -SourceInfoWidget::onLoadedTrackHistory( const QList& queries ) -{ - m_recentCollectionModel->clear(); - m_recentCollectionModel->append( queries ); -} - - void SourceInfoWidget::changeEvent( QEvent* e ) { diff --git a/src/libtomahawk/widgets/infowidgets/sourceinfowidget.h b/src/libtomahawk/widgets/infowidgets/sourceinfowidget.h index 1c5f67da9..73b8fa9eb 100644 --- a/src/libtomahawk/widgets/infowidgets/sourceinfowidget.h +++ b/src/libtomahawk/widgets/infowidgets/sourceinfowidget.h @@ -28,6 +28,7 @@ class AlbumModel; class CollectionFlatModel; +class RecentlyAddedModel; class RecentlyPlayedModel; namespace Ui @@ -58,16 +59,14 @@ protected: void changeEvent( QEvent* e ); private slots: - void loadTracks(); void loadRecentAdditions(); void onCollectionChanged(); - void onLoadedTrackHistory( const QList& queries ); private: Ui::SourceInfoWidget *ui; - CollectionFlatModel* m_recentCollectionModel; + RecentlyAddedModel* m_recentTracksModel; RecentlyPlayedModel* m_historyModel; AlbumModel* m_recentAlbumModel; diff --git a/src/libtomahawk/widgets/welcomewidget.cpp b/src/libtomahawk/widgets/welcomewidget.cpp index 3235a2371..928524d86 100644 --- a/src/libtomahawk/widgets/welcomewidget.cpp +++ b/src/libtomahawk/widgets/welcomewidget.cpp @@ -95,7 +95,6 @@ WelcomeWidget::~WelcomeWidget() void WelcomeWidget::loadData() { - m_recentAlbumsModel->addFilteredCollection( collection_ptr(), 20, DatabaseCommand_AllAlbums::ModificationTime, true ); } From 29c49b12b7c9cee5d26c0060427659d58a7d2aa4 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Fri, 16 Mar 2012 23:23:58 +0100 Subject: [PATCH 10/29] * This is explicitly WIP: Added Latest Additions & Recently Played nodes. --- src/sourcetree/items/sourceitem.cpp | 88 +++++++++++++++++++++++++---- src/sourcetree/items/sourceitem.h | 10 ++++ 2 files changed, 88 insertions(+), 10 deletions(-) diff --git a/src/sourcetree/items/sourceitem.cpp b/src/sourcetree/items/sourceitem.cpp index 82a977f7c..ee2301ec2 100644 --- a/src/sourcetree/items/sourceitem.cpp +++ b/src/sourcetree/items/sourceitem.cpp @@ -27,6 +27,10 @@ #include "utils/logger.h" #include "widgets/SocialPlaylistWidget.h" #include "playlist/customplaylistview.h" +#include "playlist/collectionview.h" +#include "playlist/playlistview.h" +#include "playlist/RecentlyAddedModel.h" +#include "playlist/RecentlyPlayedModel.h" #include "source.h" #include "sourcelist.h" @@ -40,12 +44,14 @@ SourceItem::SourceItem( SourcesModel* mdl, SourceTreeItem* parent, const Tomahaw , m_playlists( 0 ) , m_stations( 0 ) , m_latchedOn( false ) - , m_sourceInfoItem( 0 ) + , m_sourceInfoItem( 0 ) , m_coolPlaylistsItem( 0 ) , m_collectionPage( 0 ) , m_sourceInfoPage( 0 ) , m_coolPlaylistsPage( 0 ) , m_lovedTracksPage( 0 ) + , m_latestAdditionsPage( 0 ) + , m_recentPlaysPage( 0 ) , m_whatsHotPage( 0 ) { if ( m_source.isNull() ) @@ -54,20 +60,31 @@ SourceItem::SourceItem( SourcesModel* mdl, SourceTreeItem* parent, const Tomahaw return; } - m_lovedTracksItem = new GenericPageItem( model(), this, tr( "Loved Tracks" ), QIcon( RESPATH "images/loved_playlist.png" ), - boost::bind( &SourceItem::lovedTracksClicked, this ), - boost::bind( &SourceItem::getLovedTracksPage, this ) ); - m_lovedTracksItem->setSortValue( -250 ); - m_collectionItem = new GenericPageItem( model(), this, tr( "Collection" ), QIcon( RESPATH "images/drop-song.png" ), //FIXME different icon boost::bind( &SourceItem::collectionClicked, this ), boost::bind( &SourceItem::getCollectionPage, this ) ); - m_collectionItem->setSortValue( -350 ); - m_sourceInfoItem = new GenericPageItem( model(), this, tr( "New Additions" ), QIcon( RESPATH "images/new-additions.png" ), +/* m_sourceInfoItem = new GenericPageItem( model(), this, tr( "New Additions" ), QIcon( RESPATH "images/new-additions.png" ), boost::bind( &SourceItem::sourceInfoClicked, this ), - boost::bind( &SourceItem::getSourceInfoPage, this ) ); - m_sourceInfoItem->setSortValue( -300 ); + boost::bind( &SourceItem::getSourceInfoPage, this ) );*/ + + m_latestAdditionsItem = new GenericPageItem( model(), this, tr( "Latest Additions" ), QIcon( RESPATH "images/new-additions.png" ), + boost::bind( &SourceItem::latestAdditionsClicked, this ), + boost::bind( &SourceItem::getLatestAdditionsPage, this ) ); + + m_recentPlaysItem = new GenericPageItem( model(), this, tr( "Recently Played" ), QIcon( RESPATH "images/new-additions.png" ), + boost::bind( &SourceItem::recentPlaysClicked, this ), + boost::bind( &SourceItem::getRecentPlaysPage, this ) ); + + m_lovedTracksItem = new GenericPageItem( model(), this, tr( "Loved Tracks" ), QIcon( RESPATH "images/loved_playlist.png" ), + boost::bind( &SourceItem::lovedTracksClicked, this ), + boost::bind( &SourceItem::getLovedTracksPage, this ) ); + + m_collectionItem->setSortValue( -350 ); +// m_sourceInfoItem->setSortValue( -300 ); + m_latestAdditionsItem->setSortValue( -250 ); + m_recentPlaysItem->setSortValue( -200 ); + m_lovedTracksItem->setSortValue( -150 ); // create category items if there are playlists to show, or stations to show QList< playlist_ptr > playlists = source->collection()->playlists(); @@ -498,3 +515,54 @@ SourceItem::getLovedTracksPage() const { return m_lovedTracksPage; } + + +ViewPage* +SourceItem::latestAdditionsClicked() +{ + if ( !m_latestAdditionsPage ) + { + CollectionView* cv = new CollectionView( ViewManager::instance()->widget() ); + RecentlyAddedModel* raModel = new RecentlyAddedModel( m_source, cv ); + + cv->setTrackModel( raModel ); + cv->sortByColumn( TrackModel::Age, Qt::DescendingOrder ); + + m_latestAdditionsPage = cv; + } + + ViewManager::instance()->show( m_latestAdditionsPage ); + return m_latestAdditionsPage; +} + + +ViewPage* +SourceItem::getLatestAdditionsPage() const +{ + return m_latestAdditionsPage; +} + + +ViewPage* +SourceItem::recentPlaysClicked() +{ + if ( !m_recentPlaysPage ) + { + PlaylistView* pv = new PlaylistView( ViewManager::instance()->widget() ); + RecentlyPlayedModel* raModel = new RecentlyPlayedModel( m_source, pv ); + + pv->setPlaylistModel( raModel ); + + m_recentPlaysPage = pv; + } + + ViewManager::instance()->show( m_recentPlaysPage ); + return m_recentPlaysPage; +} + + +ViewPage* +SourceItem::getRecentPlaysPage() const +{ + return m_recentPlaysPage; +} diff --git a/src/sourcetree/items/sourceitem.h b/src/sourcetree/items/sourceitem.h index 4aa84443d..cc9c82a2d 100644 --- a/src/sourcetree/items/sourceitem.h +++ b/src/sourcetree/items/sourceitem.h @@ -80,6 +80,12 @@ private slots: Tomahawk::ViewPage* lovedTracksClicked(); Tomahawk::ViewPage* getLovedTracksPage() const; + Tomahawk::ViewPage* latestAdditionsClicked(); + Tomahawk::ViewPage* getLatestAdditionsPage() const; + + Tomahawk::ViewPage* recentPlaysClicked(); + Tomahawk::ViewPage* getRecentPlaysPage() const; + private: void playlistsAddedInternal( SourceTreeItem* parent, const QList< Tomahawk::dynplaylist_ptr >& playlists ); template< typename T > @@ -97,11 +103,15 @@ private: GenericPageItem* m_sourceInfoItem; GenericPageItem* m_coolPlaylistsItem; GenericPageItem* m_lovedTracksItem; + GenericPageItem* m_latestAdditionsItem; + GenericPageItem* m_recentPlaysItem; Tomahawk::ViewPage* m_collectionPage; Tomahawk::ViewPage* m_sourceInfoPage; Tomahawk::ViewPage* m_coolPlaylistsPage; Tomahawk::ViewPage* m_lovedTracksPage; + Tomahawk::ViewPage* m_latestAdditionsPage; + Tomahawk::ViewPage* m_recentPlaysPage; Tomahawk::ViewPage* m_whatsHotPage; }; From d86124203c8459dba5640927def285663f647aa7 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Sat, 17 Mar 2012 01:32:15 +0100 Subject: [PATCH 11/29] * Don't crash in onCoverUpdated if there's no current track. --- src/audiocontrols.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/audiocontrols.cpp b/src/audiocontrols.cpp index 95c079e0c..c81895aa3 100644 --- a/src/audiocontrols.cpp +++ b/src/audiocontrols.cpp @@ -252,7 +252,7 @@ void AudioControls::onCoverUpdated() { Query* query = qobject_cast< Query* >( sender() ); - if ( !query || query != m_currentTrack->toQuery().data() ) + if ( !query || !m_currentTrack || query != m_currentTrack->toQuery().data() ) return; setCover(); From d5aed7b6df11634ea6d86691feea94e8a3462a36 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Sat, 17 Mar 2012 01:33:03 +0100 Subject: [PATCH 12/29] * Fetch square covers from Last.fm. --- src/accounts/lastfm/lastfmplugin.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/accounts/lastfm/lastfmplugin.cpp b/src/accounts/lastfm/lastfmplugin.cpp index 992cf7a36..2af69cf41 100644 --- a/src/accounts/lastfm/lastfmplugin.cpp +++ b/src/accounts/lastfm/lastfmplugin.cpp @@ -456,7 +456,7 @@ LastFmPlugin::notInCacheSlot( QHash criteria, Tomahawk::InfoSy imgurl.addEncodedQueryItem( "artist", QUrl::toPercentEncoding( artistName, "", "+" ) ); imgurl.addEncodedQueryItem( "album", QUrl::toPercentEncoding( albumName, "", "+" ) ); imgurl.addQueryItem( "autocorrect", QString::number( 1 ) ); - imgurl.addQueryItem( "size", "large" ); + imgurl.addQueryItem( "size", "largesquare" ); imgurl.addQueryItem( "api_key", "7a90f6672a04b809ee309af169f34b8b" ); QNetworkRequest req( imgurl ); @@ -475,7 +475,7 @@ LastFmPlugin::notInCacheSlot( QHash criteria, Tomahawk::InfoSy imgurl.addQueryItem( "method", "artist.imageredirect" ); imgurl.addEncodedQueryItem( "artist", QUrl::toPercentEncoding( artistName, "", "+" ) ); imgurl.addQueryItem( "autocorrect", QString::number( 1 ) ); - imgurl.addQueryItem( "size", "large" ); + imgurl.addQueryItem( "size", "largesquare" ); imgurl.addQueryItem( "api_key", "7a90f6672a04b809ee309af169f34b8b" ); QNetworkRequest req( imgurl ); From b70114a22557be39d998b017fd82c4553a40bdfb Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Sat, 17 Mar 2012 05:42:25 +0100 Subject: [PATCH 13/29] * Fixed race condition during resolving. --- .../database/databasecommand_resolve.cpp | 40 ++++++++++--------- src/libtomahawk/result.cpp | 18 ++++++++- src/libtomahawk/result.h | 6 ++- 3 files changed, 44 insertions(+), 20 deletions(-) diff --git a/src/libtomahawk/database/databasecommand_resolve.cpp b/src/libtomahawk/database/databasecommand_resolve.cpp index 38149e83d..4f13539a5 100644 --- a/src/libtomahawk/database/databasecommand_resolve.cpp +++ b/src/libtomahawk/database/databasecommand_resolve.cpp @@ -55,9 +55,6 @@ DatabaseCommand_Resolve::exec( DatabaseImpl* lib ) qDebug() << "Using result-hint to speed up resolving:" << m_query->resultHint(); Tomahawk::result_ptr result = lib->resultFromHint( m_query ); - /* qDebug() << "Result null:" << result.isNull(); - * qDebug() << "Collection null:" << result->collection().isNull(); - * qDebug() << "Source null:" << result->collection()->source().isNull();*/ if ( !result.isNull() && !result->collection().isNull() && result->collection()->source()->isOnline() ) { QList res; @@ -137,7 +134,7 @@ DatabaseCommand_Resolve::resolve( DatabaseImpl* lib ) else { s = SourceList::instance()->get( files_query.value( 16 ).toUInt() ); - if( s.isNull() ) + if ( s.isNull() ) { qDebug() << "Could not find source" << files_query.value( 16 ).toUInt(); continue; @@ -147,12 +144,15 @@ DatabaseCommand_Resolve::resolve( DatabaseImpl* lib ) } Tomahawk::result_ptr result = Tomahawk::Result::get( url ); - Tomahawk::artist_ptr artist = - Tomahawk::Artist::get( files_query.value( 18 ).toUInt(), files_query.value( 12 ).toString() ); - Tomahawk::album_ptr album = - Tomahawk::Album::get( files_query.value( 19 ).toUInt(), files_query.value( 13 ).toString(), artist ); - Tomahawk::artist_ptr composer = - Tomahawk::Artist::get( files_query.value( 20 ).toUInt(), files_query.value( 15 ).toString() ); + if ( result->isValid() ) + { + qDebug() << "Result already cached:" << result->toString(); + continue; + } + + Tomahawk::artist_ptr artist = Tomahawk::Artist::get( files_query.value( 18 ).toUInt(), files_query.value( 12 ).toString() ); + Tomahawk::album_ptr album = Tomahawk::Album::get( files_query.value( 19 ).toUInt(), files_query.value( 13 ).toString(), artist ); + Tomahawk::artist_ptr composer = Tomahawk::Artist::get( files_query.value( 20 ).toUInt(), files_query.value( 15 ).toString() ); result->setModificationTime( files_query.value( 1 ).toUInt() ); result->setSize( files_query.value( 2 ).toUInt() ); @@ -181,6 +181,7 @@ DatabaseCommand_Resolve::resolve( DatabaseImpl* lib ) result->setAttributes( attr ); result->setCollection( s->collection() ); + res << result; } @@ -270,7 +271,7 @@ DatabaseCommand_Resolve::fullTextResolve( DatabaseImpl* lib ) else { s = SourceList::instance()->get( files_query.value( 16 ).toUInt() ); - if( s.isNull() ) + if ( s.isNull() ) { qDebug() << "Could not find source" << files_query.value( 16 ).toUInt(); continue; @@ -280,12 +281,15 @@ DatabaseCommand_Resolve::fullTextResolve( DatabaseImpl* lib ) } Tomahawk::result_ptr result = Tomahawk::Result::get( url ); - Tomahawk::artist_ptr artist = - Tomahawk::Artist::get( files_query.value( 18 ).toUInt(), files_query.value( 12 ).toString() ); - Tomahawk::album_ptr album = - Tomahawk::Album::get( files_query.value( 19 ).toUInt(), files_query.value( 13 ).toString(), artist ); - Tomahawk::artist_ptr composer = - Tomahawk::Artist::get( files_query.value( 20 ).toUInt(), files_query.value( 15 ).toString() ); + if ( result->isValid() ) + { + qDebug() << "Result already cached:" << result->toString(); + continue; + } + + Tomahawk::artist_ptr artist = Tomahawk::Artist::get( files_query.value( 18 ).toUInt(), files_query.value( 12 ).toString() ); + Tomahawk::album_ptr album = Tomahawk::Album::get( files_query.value( 19 ).toUInt(), files_query.value( 13 ).toString(), artist ); + Tomahawk::artist_ptr composer = Tomahawk::Artist::get( files_query.value( 20 ).toUInt(), files_query.value( 15 ).toString() ); result->setModificationTime( files_query.value( 1 ).toUInt() ); result->setSize( files_query.value( 2 ).toUInt() ); @@ -322,8 +326,8 @@ DatabaseCommand_Resolve::fullTextResolve( DatabaseImpl* lib ) } result->setAttributes( attr ); - result->setCollection( s->collection() ); + res << result; } diff --git a/src/libtomahawk/result.cpp b/src/libtomahawk/result.cpp index 43dad0afd..8b3a66d61 100644 --- a/src/libtomahawk/result.cpp +++ b/src/libtomahawk/result.cpp @@ -43,7 +43,7 @@ Result::get( const QString& url ) return s_results.value( url ); } - result_ptr r = result_ptr( new Result( url ), &QObject::deleteLater ); + result_ptr r = result_ptr( new Result( url ), &Result::deleteLater ); s_results.insert( url, r ); return r; @@ -68,12 +68,28 @@ Result::Result( const QString& url ) Result::~Result() +{ +} + + +void +Result::deleteLater() { QMutexLocker lock( &s_mutex ); + if ( s_results.contains( m_url ) ) { s_results.remove( m_url ); } + + QObject::deleteLater(); +} + + +bool +Result::isValid() const +{ + return !m_rid.isEmpty(); } diff --git a/src/libtomahawk/result.h b/src/libtomahawk/result.h index 2d743e4dd..95bafcd74 100644 --- a/src/libtomahawk/result.h +++ b/src/libtomahawk/result.h @@ -58,6 +58,7 @@ public: static Tomahawk::result_ptr get( const QString& url ); virtual ~Result(); + bool isValid() const; QVariant toVariant() const; QString toString() const; Tomahawk::query_ptr toQuery(); @@ -108,6 +109,9 @@ public: unsigned int trackId() const { return m_trackId; } unsigned int fileId() const { return m_fileId; } +public slots: + void deleteLater(); + signals: // emitted when the collection this result comes from is going offline/online: void statusChanged(); @@ -115,7 +119,7 @@ signals: private slots: void onOffline(); void onOnline(); - + private: // private constructor explicit Result( const QString& url ); From bd098e3ff267dbe636192464683314679e1f225d Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Sat, 17 Mar 2012 05:49:43 +0100 Subject: [PATCH 14/29] * Fixed cached resolving. --- src/libtomahawk/database/databasecommand_resolve.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libtomahawk/database/databasecommand_resolve.cpp b/src/libtomahawk/database/databasecommand_resolve.cpp index 4f13539a5..354208105 100644 --- a/src/libtomahawk/database/databasecommand_resolve.cpp +++ b/src/libtomahawk/database/databasecommand_resolve.cpp @@ -147,6 +147,7 @@ DatabaseCommand_Resolve::resolve( DatabaseImpl* lib ) if ( result->isValid() ) { qDebug() << "Result already cached:" << result->toString(); + res << result; continue; } @@ -284,6 +285,7 @@ DatabaseCommand_Resolve::fullTextResolve( DatabaseImpl* lib ) if ( result->isValid() ) { qDebug() << "Result already cached:" << result->toString(); + res << result; continue; } From 3e11945c028125c23909fbca37df3b3dce5842af Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Sat, 17 Mar 2012 06:55:49 +0100 Subject: [PATCH 15/29] * Added PlaylistLargeItemDelegate. Loved, latest & recent tracks use it. --- src/libtomahawk/CMakeLists.txt | 1 + .../databasecommand_loadsocialactions.cpp | 7 +- .../playlist/PlaylistLargeItemDelegate.cpp | 228 ++++++++++++++++++ .../playlist/PlaylistLargeItemDelegate.h | 55 +++++ .../playlist/customplaylistview.cpp | 1 + src/libtomahawk/playlist/trackmodel.cpp | 19 +- src/libtomahawk/playlist/trackmodel.h | 4 +- src/libtomahawk/playlist/trackmodelitem.cpp | 2 + src/libtomahawk/playlist/trackview.cpp | 25 +- src/libtomahawk/query.cpp | 65 ++++- src/libtomahawk/query.h | 3 +- src/libtomahawk/result.h | 2 +- src/libtomahawk/viewmanager.cpp | 8 +- src/sourcetree/items/sourceitem.cpp | 67 ++--- 14 files changed, 435 insertions(+), 52 deletions(-) create mode 100644 src/libtomahawk/playlist/PlaylistLargeItemDelegate.cpp create mode 100644 src/libtomahawk/playlist/PlaylistLargeItemDelegate.h diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index 6727aa2da..35df525d8 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -79,6 +79,7 @@ set( libGuiSources playlist/ViewHeader.cpp playlist/RecentlyAddedModel.cpp playlist/RecentlyPlayedModel.cpp + playlist/PlaylistLargeItemDelegate.cpp playlist/dynamic/DynamicPlaylist.cpp playlist/dynamic/DynamicView.cpp diff --git a/src/libtomahawk/database/databasecommand_loadsocialactions.cpp b/src/libtomahawk/database/databasecommand_loadsocialactions.cpp index efb5a9d50..bd2474752 100644 --- a/src/libtomahawk/database/databasecommand_loadsocialactions.cpp +++ b/src/libtomahawk/database/databasecommand_loadsocialactions.cpp @@ -65,9 +65,10 @@ DatabaseCommand_LoadSocialActions::exec( DatabaseImpl* dbi ) action.action = query.value( 0 ); // action action.value = query.value( 1 ); // comment action.timestamp = query.value( 2 ); // timestamp - action.source = query.value( 3 ); // source - - allSocialActions.append( action ); + action.source = SourceList::instance()->get( query.value( 3 ).toInt() ); // source + + if ( !action.source.isNull() ) + allSocialActions.append( action ); } m_query->setAllSocialActions( allSocialActions ); diff --git a/src/libtomahawk/playlist/PlaylistLargeItemDelegate.cpp b/src/libtomahawk/playlist/PlaylistLargeItemDelegate.cpp new file mode 100644 index 000000000..b94c17ac2 --- /dev/null +++ b/src/libtomahawk/playlist/PlaylistLargeItemDelegate.cpp @@ -0,0 +1,228 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Christian Muehlhaeuser + * + * 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 "PlaylistLargeItemDelegate.h" + +#include +#include + +#include "query.h" +#include "result.h" +#include "artist.h" +#include "source.h" +#include "sourcelist.h" + +#include "trackmodel.h" +#include "trackmodelitem.h" +#include "trackproxymodel.h" +#include "trackview.h" +#include "trackheader.h" + +#include "utils/tomahawkutilsgui.h" +#include "utils/logger.h" + +using namespace Tomahawk; + + +PlaylistLargeItemDelegate::PlaylistLargeItemDelegate( TrackView* parent, TrackProxyModel* proxy ) + : QStyledItemDelegate( (QObject*)parent ) + , m_view( parent ) + , m_model( proxy ) +{ + m_topOption = QTextOption( Qt::AlignTop ); + m_topOption.setWrapMode( QTextOption::NoWrap ); + + m_centerRightOption = QTextOption( Qt::AlignVCenter | Qt::AlignRight ); + m_centerRightOption.setWrapMode( QTextOption::NoWrap ); + + m_bottomOption = QTextOption( Qt::AlignBottom ); + m_bottomOption.setWrapMode( QTextOption::NoWrap ); +} + + +QSize +PlaylistLargeItemDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const +{ + QSize size = QStyledItemDelegate::sizeHint( option, index ); + + if ( index.isValid() ) + { + int rowHeight = option.fontMetrics.height() + 8; + size.setHeight( rowHeight * 3 ); + } + + return size; +} + + +QWidget* +PlaylistLargeItemDelegate::createEditor( QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const +{ + Q_UNUSED( parent ); + Q_UNUSED( option ); + Q_UNUSED( index ); + return 0; +} + + +void +PlaylistLargeItemDelegate::prepareStyleOption( QStyleOptionViewItemV4* option, const QModelIndex& index, TrackModelItem* item ) const +{ + initStyleOption( option, index ); + + if ( item->isPlaying() ) + { + option->palette.setColor( QPalette::Highlight, option->palette.color( QPalette::Mid ) ); + option->state |= QStyle::State_Selected; + } + + if ( option->state & QStyle::State_Selected ) + { + option->palette.setColor( QPalette::Text, option->palette.color( QPalette::HighlightedText ) ); + } + else + { + float opacity = 0.0; + if ( item->query()->results().count() ) + opacity = item->query()->results().first()->score(); + + opacity = qMax( (float)0.3, opacity ); + QColor textColor = TomahawkUtils::alphaBlend( option->palette.color( QPalette::Text ), option->palette.color( QPalette::BrightText ), opacity ); + + option->palette.setColor( QPalette::Text, textColor ); + } +} + + +void +PlaylistLargeItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const +{ + TrackModelItem* item = m_model->itemFromIndex( m_model->mapToSource( index ) ); + Q_ASSERT( item ); + + QStyleOptionViewItemV4 opt = option; + prepareStyleOption( &opt, index, item ); + opt.text.clear(); + + qApp->style()->drawControl( QStyle::CE_ItemViewItem, &opt, painter ); + + if ( m_view->header()->visualIndex( index.column() ) > 0 ) + return; + + QPixmap pixmap, avatar; + QString artist, track, upperText, lowerText; + source_ptr source = item->query()->playedBy().first; + unsigned int duration = 0; + + if ( item->query()->results().count() ) + { + artist = item->query()->results().first()->artist()->name(); + track = item->query()->results().first()->track(); + duration = item->query()->results().first()->duration(); + } + else + { + artist = item->query()->artist(); + track = item->query()->track(); + } + + lowerText = item->query()->socialActionDescription( "Love" ); + + if ( source.isNull() ) + { + } + else + { + upperText = QString( "%1 - %2" ).arg( artist ).arg( track ); + QString playtime = TomahawkUtils::ageToString( QDateTime::fromTime_t( item->query()->playedBy().second ), true ); + + if ( source == SourceList::instance()->getLocal() ) + lowerText = QString( tr( "played %1 by you" ) ).arg( playtime ); + else + lowerText = QString( tr( "played %1 by %2" ) ).arg( playtime ).arg( source->friendlyName() ); + } + + painter->save(); + { + QRect r = opt.rect.adjusted( 3, 6, 0, -6 ); + + // Paint Now Playing Speaker Icon + if ( item->isPlaying() ) + { + QPixmap nowPlayingIcon = TomahawkUtils::defaultPixmap( TomahawkUtils::NowPlayingSpeaker ); + QRect npr = r.adjusted( 3, r.height() / 2 - nowPlayingIcon.height() / 2, 18 - r.width(), -r.height() / 2 + nowPlayingIcon.height() / 2 ); + nowPlayingIcon = TomahawkUtils::defaultPixmap( TomahawkUtils::NowPlayingSpeaker, TomahawkUtils::Original, npr.size() ); + painter->drawPixmap( npr, nowPlayingIcon ); + r.adjust( 22, 0, 0, 0 ); + } + + painter->setPen( opt.palette.text().color() ); + + QSize avatarSize( 32, 32 ); + QRect pixmapRect = r.adjusted( 6, 0, -option.rect.width() + option.rect.height() - 6 + r.left(), 0 ); + QRect avatarRect = r.adjusted( option.rect.width() - r.left() - 12 - avatarSize.width(), ( option.rect.height() - avatarSize.height() ) / 2 - 5, 0, 0 ); + avatarRect.setSize( avatarSize ); + + if ( source ) + avatar = source->avatar( Source::FancyStyle, avatarRect.size() ); + + pixmap = item->query()->cover( pixmapRect.size(), false ); + if ( !pixmap ) + { + pixmap = TomahawkUtils::defaultPixmap( TomahawkUtils::DefaultTrackImage, TomahawkUtils::ScaledCover, pixmapRect.size() ); + } + + painter->drawPixmap( pixmapRect, pixmap ); + + if ( !avatar.isNull() ) + painter->drawPixmap( avatarRect, avatar ); + + QFont boldFont = opt.font; + boldFont.setPixelSize( 15 ); + boldFont.setWeight( 99 ); + + QFont smallBoldFont = opt.font; + smallBoldFont.setPixelSize( 12 ); + smallBoldFont.setBold( true ); + smallBoldFont.setWeight( 80 ); + + r.adjust( pixmapRect.width() + 12, 1, -28 - avatar.width(), 0 ); + QRect leftRect = r.adjusted( 0, 0, -r.width() / 2 - 4, 0 ); + QRect rightRect = r.adjusted( r.width() / 2 + 4, 0, 0, 0 ); + + painter->setFont( boldFont ); + QString text = painter->fontMetrics().elidedText( artist, Qt::ElideRight, leftRect.width() ); + painter->drawText( leftRect, text, m_topOption ); + + painter->setFont( smallBoldFont ); + text = painter->fontMetrics().elidedText( track, Qt::ElideRight, leftRect.width() ); + painter->drawText( leftRect.adjusted( 0, 19, 0, 0 ), text, m_topOption ); + + painter->setFont( opt.font ); + text = painter->fontMetrics().elidedText( lowerText, Qt::ElideRight, leftRect.width() ); + painter->drawText( leftRect, text, m_bottomOption ); + + if ( duration > 0 ) + { + painter->setFont( smallBoldFont ); + text = painter->fontMetrics().elidedText( TomahawkUtils::timeToString( duration ), Qt::ElideRight, rightRect.width() ); + painter->drawText( rightRect, text, m_centerRightOption ); + } + } + painter->restore(); +} diff --git a/src/libtomahawk/playlist/PlaylistLargeItemDelegate.h b/src/libtomahawk/playlist/PlaylistLargeItemDelegate.h new file mode 100644 index 000000000..6bdae39aa --- /dev/null +++ b/src/libtomahawk/playlist/PlaylistLargeItemDelegate.h @@ -0,0 +1,55 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Christian Muehlhaeuser + * + * 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 PLAYLISTLARGEITEMDELEGATE_H +#define PLAYLISTLARGEITEMDELEGATE_H + +#include +#include + +#include "dllmacro.h" + +class TrackModel; +class TrackModelItem; +class TrackProxyModel; +class TrackView; + +class DLLEXPORT PlaylistLargeItemDelegate : public QStyledItemDelegate +{ +Q_OBJECT + +public: + PlaylistLargeItemDelegate( TrackView* parent = 0, TrackProxyModel* proxy = 0 ); + +protected: + void paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const; + QSize sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const; + QWidget* createEditor( QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const; + +private: + void prepareStyleOption( QStyleOptionViewItemV4* option, const QModelIndex& index, TrackModelItem* item ) const; + + QTextOption m_topOption; + QTextOption m_centerRightOption; + QTextOption m_bottomOption; + + TrackView* m_view; + TrackProxyModel* m_model; +}; + +#endif // PLAYLISTLARGEITEMDELEGATE_H diff --git a/src/libtomahawk/playlist/customplaylistview.cpp b/src/libtomahawk/playlist/customplaylistview.cpp index b3b2c2ba5..8c6341447 100644 --- a/src/libtomahawk/playlist/customplaylistview.cpp +++ b/src/libtomahawk/playlist/customplaylistview.cpp @@ -37,6 +37,7 @@ CustomPlaylistView::CustomPlaylistView( CustomPlaylistView::PlaylistType type, c setFrameShape( QFrame::NoFrame ); setAttribute( Qt::WA_MacShowFocusRect, 0 ); + m_model->setStyle( TrackModel::Large ); setPlaylistModel( m_model ); generateTracks(); diff --git a/src/libtomahawk/playlist/trackmodel.cpp b/src/libtomahawk/playlist/trackmodel.cpp index 9633398c0..1d7f6ffcc 100644 --- a/src/libtomahawk/playlist/trackmodel.cpp +++ b/src/libtomahawk/playlist/trackmodel.cpp @@ -88,6 +88,7 @@ TrackModel::columnCount( const QModelIndex& parent ) const { case Short: case ShortWithAvatars: + case Large: return 1; break; @@ -259,14 +260,24 @@ TrackModel::headerData( int section, Qt::Orientation orientation, int role ) con void -TrackModel::getCover( const QModelIndex& index ) +TrackModel::updateDetailedInfo( const QModelIndex& index ) { - if ( style() != TrackModel::Short ) + if ( style() != TrackModel::Short && style() != TrackModel::Large ) + return; + + TrackModelItem* item = itemFromIndex( index ); + if ( item->query().isNull() ) return; - TrackModelItem* item = itemFromIndex( index ); - if ( !item->query().isNull() ) + if ( style() == TrackModel::Short || style() == TrackModel::Large ) + { item->query()->cover( QSize( 0, 0 ) ); + } + + if ( style() == TrackModel::Large ) + { + item->query()->loadSocialActions(); + } } diff --git a/src/libtomahawk/playlist/trackmodel.h b/src/libtomahawk/playlist/trackmodel.h index 206fe7573..6d76e6aaf 100644 --- a/src/libtomahawk/playlist/trackmodel.h +++ b/src/libtomahawk/playlist/trackmodel.h @@ -36,7 +36,7 @@ Q_OBJECT public: enum TrackItemStyle - { Detailed = 0, Short = 1, ShortWithAvatars = 2 }; + { Detailed = 0, Short = 1, ShortWithAvatars = 2, Large = 3 }; enum TrackModelRole { StyleRole = Qt::UserRole + 1 }; @@ -98,7 +98,7 @@ public: /// Returns a flat list of all tracks in this model QList< Tomahawk::query_ptr > queries() const; - void getCover( const QModelIndex& index ); + void updateDetailedInfo( const QModelIndex& index ); signals: void repeatModeChanged( Tomahawk::PlaylistInterface::RepeatMode mode ); diff --git a/src/libtomahawk/playlist/trackmodelitem.cpp b/src/libtomahawk/playlist/trackmodelitem.cpp index b6e1ce452..18f0c5126 100644 --- a/src/libtomahawk/playlist/trackmodelitem.cpp +++ b/src/libtomahawk/playlist/trackmodelitem.cpp @@ -1,3 +1,4 @@ + /* === This file is part of Tomahawk Player - === * * Copyright 2010-2011, Christian Muehlhaeuser @@ -115,4 +116,5 @@ TrackModelItem::setupItem( const Tomahawk::query_ptr& query, TrackModelItem* par connect( query.data(), SIGNAL( resultsRemoved( Tomahawk::result_ptr ) ), SIGNAL( dataChanged() ) ); connect( query.data(), SIGNAL( resultsChanged() ), SIGNAL( dataChanged() ) ); connect( query.data(), SIGNAL( updated() ), SIGNAL( dataChanged() ) ); + connect( query.data(), SIGNAL( socialActionsLoaded() ), SIGNAL( dataChanged() ) ); } diff --git a/src/libtomahawk/playlist/trackview.cpp b/src/libtomahawk/playlist/trackview.cpp index e87f04931..913183044 100644 --- a/src/libtomahawk/playlist/trackview.cpp +++ b/src/libtomahawk/playlist/trackview.cpp @@ -147,15 +147,18 @@ TrackView::setTrackModel( TrackModel* model ) setAcceptDrops( true ); - if ( model->style() == TrackModel::Short || model->style() == TrackModel::ShortWithAvatars ) + switch( model->style() ) { - setHeaderHidden( true ); - setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff ); - } - else - { - setHeaderHidden( false ); - setHorizontalScrollBarPolicy( Qt::ScrollBarAsNeeded ); + case TrackModel::Short: + case TrackModel::ShortWithAvatars: + case TrackModel::Large: + setHeaderHidden( true ); + setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff ); + break; + + default: + setHeaderHidden( false ); + setHorizontalScrollBarPolicy( Qt::ScrollBarAsNeeded ); } } @@ -163,7 +166,7 @@ TrackView::setTrackModel( TrackModel* model ) void TrackView::onViewChanged() { - if ( m_model->style() != TrackModel::Short ) // eventual FIXME? + if ( m_model->style() != TrackModel::Short && m_model->style() != TrackModel::Large ) // eventual FIXME? return; if ( m_timer.isActive() ) @@ -196,7 +199,7 @@ TrackView::onScrollTimeout() for ( int i = left.row(); i <= max; i++ ) { - m_model->getCover( m_proxyModel->mapToSource( m_proxyModel->index( i, 0 ) ) ); + m_model->updateDetailedInfo( m_proxyModel->mapToSource( m_proxyModel->index( i, 0 ) ) ); } } @@ -519,7 +522,7 @@ TrackView::updateHoverIndex( const QPoint& pos ) repaint(); } - if ( !m_model || m_model->style() == TrackModel::Short || m_model->style() == TrackModel::ShortWithAvatars ) + if ( !m_model || m_model->style() != TrackModel::Detailed ) return; if ( idx.column() == TrackModel::Artist || idx.column() == TrackModel::Album ) diff --git a/src/libtomahawk/query.cpp b/src/libtomahawk/query.cpp index 7b94e4167..e59248057 100644 --- a/src/libtomahawk/query.cpp +++ b/src/libtomahawk/query.cpp @@ -521,7 +521,7 @@ Query::setAllSocialActions( const QList< SocialAction >& socialActions ) QList< SocialAction > -Query::allSocialActions() +Query::allSocialActions() const { return m_allSocialActions; } @@ -537,7 +537,7 @@ Query::parseSocialActions() { Tomahawk::SocialAction socialAction; socialAction = it.next(); - if ( socialAction.timestamp.toUInt() > highestTimestamp && socialAction.source.toInt() == SourceList::instance()->getLocal()->id() ) + if ( socialAction.timestamp.toUInt() > highestTimestamp && socialAction.source->id() == SourceList::instance()->getLocal()->id() ) { m_currentSocialActions[ socialAction.action.toString() ] = socialAction.value.toBool(); } @@ -584,6 +584,67 @@ Query::setLoved( bool loved ) } +QString +Query::socialActionDescription( const QString& action ) const +{ + QString desc; + QList< Tomahawk::SocialAction > socialActions = allSocialActions(); + + QStringList actionSources; + int loveTotal = 0; + foreach ( const Tomahawk::SocialAction& sa, socialActions ) + { + if ( sa.action == action ) + { + if ( actionSources.contains( sa.source->friendlyName() ) ) + continue; + actionSources << sa.source->friendlyName(); + loveTotal++; + } + } + + actionSources.clear(); + int loveCounter = 0; + foreach ( const Tomahawk::SocialAction& sa, socialActions ) + { + if ( sa.action == action ) + { + if ( actionSources.contains( sa.source->friendlyName() ) ) + continue; + actionSources << sa.source->friendlyName(); + + if ( ++loveCounter > 3 ) + continue; + else if ( loveCounter > 1 ) + { + if ( loveCounter == loveTotal ) + desc += tr( " and " ); + else + desc += ", "; + } + + if ( sa.source->isLocal() ) + { + if ( loveCounter == 1 ) + desc += tr( "You" ); + else + desc += tr( "you" ); + } + else + desc += sa.source->friendlyName(); + } + } + if ( loveCounter > 0 ) + { + if ( loveCounter > 3 ) + desc += " " + tr( "and %1 others" ).arg( loveCounter - 3 ); + desc += " " + tr( "loved this track" ); //FIXME: more action descs required + } + + return desc; +} + + #ifndef ENABLE_HEADLESS QPixmap Query::cover( const QSize& size, bool forceLoad ) const diff --git a/src/libtomahawk/query.h b/src/libtomahawk/query.h index 8f4b64194..8629dcfec 100644 --- a/src/libtomahawk/query.h +++ b/src/libtomahawk/query.h @@ -114,8 +114,9 @@ public: bool loved(); void loadSocialActions(); - QList< Tomahawk::SocialAction > allSocialActions(); + QList< Tomahawk::SocialAction > allSocialActions() const; void setAllSocialActions( const QList< Tomahawk::SocialAction >& socialActions ); + QString socialActionDescription( const QString& action ) const; QWeakPointer< Tomahawk::Query > weakRef() { return m_ownRef; } void setWeakRef( QWeakPointer< Tomahawk::Query > weakRef ) { m_ownRef = weakRef; } diff --git a/src/libtomahawk/result.h b/src/libtomahawk/result.h index 95bafcd74..6dd4c76c4 100644 --- a/src/libtomahawk/result.h +++ b/src/libtomahawk/result.h @@ -41,7 +41,7 @@ struct SocialAction QVariant action; QVariant value; QVariant timestamp; - QVariant source; + Tomahawk::source_ptr source; }; diff --git a/src/libtomahawk/viewmanager.cpp b/src/libtomahawk/viewmanager.cpp index ef8008773..10b8e968e 100644 --- a/src/libtomahawk/viewmanager.cpp +++ b/src/libtomahawk/viewmanager.cpp @@ -41,6 +41,7 @@ #include "tomahawksettings.h" #include "customplaylistview.h" +#include "PlaylistLargeItemDelegate.h" #include "dynamic/widgets/DynamicWidget.h" #include "widgets/welcomewidget.h" @@ -437,7 +438,12 @@ Tomahawk::ViewPage* ViewManager::showTopLovedPage() { if ( !m_topLovedWidget ) - m_topLovedWidget = new CustomPlaylistView( CustomPlaylistView::TopLovedTracks, source_ptr(), m_widget ); + { + CustomPlaylistView* view = new CustomPlaylistView( CustomPlaylistView::TopLovedTracks, source_ptr(), m_widget ); + view->setItemDelegate( new PlaylistLargeItemDelegate( view, view->proxyModel() ) ); + + m_topLovedWidget = view; + } return show( m_topLovedWidget ); } diff --git a/src/sourcetree/items/sourceitem.cpp b/src/sourcetree/items/sourceitem.cpp index ee2301ec2..d6a9a37f1 100644 --- a/src/sourcetree/items/sourceitem.cpp +++ b/src/sourcetree/items/sourceitem.cpp @@ -31,6 +31,7 @@ #include "playlist/playlistview.h" #include "playlist/RecentlyAddedModel.h" #include "playlist/RecentlyPlayedModel.h" +#include "playlist/PlaylistLargeItemDelegate.h" #include "source.h" #include "sourcelist.h" @@ -103,7 +104,7 @@ SourceItem::SourceItem( SourcesModel* mdl, SourceTreeItem* parent, const Tomahaw onStationsAdded( stations ); } - if( ViewManager::instance()->pageForCollection( source->collection() ) ) + if ( ViewManager::instance()->pageForCollection( source->collection() ) ) model()->linkSourceItemToPage( this, ViewManager::instance()->pageForCollection( source->collection() ) ); m_defaultAvatar = TomahawkUtils::createAvatarFrame( QPixmap( RESPATH "images/user-avatar.png" ) ); @@ -301,7 +302,7 @@ SourceItem::playlistDeletedInternal( SourceTreeItem* parent, const T& p ) for( int i = 0; i < curCount; i++ ) { PlaylistItem* pl = qobject_cast< PlaylistItem* >( parent->children().at( i ) ); - if( pl && pl->playlist() == p ) + if ( pl && pl->playlist() == p ) { parent->beginRowsRemoved( i, i ); parent->removeChild( pl ); @@ -312,20 +313,20 @@ SourceItem::playlistDeletedInternal( SourceTreeItem* parent, const T& p ) } } - if( ( parent == m_playlists || parent == m_stations ) && + if ( ( parent == m_playlists || parent == m_stations ) && parent->children().isEmpty() && parent->parent() ) // Don't leave an empty Playlist or Station category { int idx = parent->parent()->children().indexOf( parent ); - if( idx < 0 ) + if ( idx < 0 ) return; parent->parent()->beginRowsRemoved( idx, idx ); parent->parent()->removeChild( parent ); parent->parent()->endRowsRemoved(); - if( parent == m_playlists ) + if ( parent == m_playlists ) m_playlists = 0; - else if( parent == m_stations ) + else if ( parent == m_stations ) m_stations = 0; delete parent; } @@ -335,12 +336,10 @@ SourceItem::playlistDeletedInternal( SourceTreeItem* parent, const T& p ) void SourceItem::onPlaylistsAdded( const QList< playlist_ptr >& playlists ) { -// qDebug() << Q_FUNC_INFO << m_source->friendlyName() << playlists.count(); - - if( playlists.isEmpty() ) + if ( playlists.isEmpty() ) return; - if( !m_playlists ) + if ( !m_playlists ) { // add the category too int cur = children().count(); @@ -354,19 +353,18 @@ SourceItem::onPlaylistsAdded( const QList< playlist_ptr >& playlists ) int from = m_playlists->children().count() - addOffset; m_playlists->beginRowsAdded( from, from + playlists.count() - 1 ); - foreach( const playlist_ptr& p, playlists ) + foreach ( const playlist_ptr& p, playlists ) { PlaylistItem* plItem = new PlaylistItem( model(), m_playlists, p, m_playlists->children().count() - addOffset ); -// qDebug() << "Playlist added:" << p->title() << p->creator() << p->info(); p->loadRevision(); items << plItem; - if( m_source->isLocal() ) + if ( m_source->isLocal() ) connect( p.data(), SIGNAL( aboutToBeDeleted( Tomahawk::playlist_ptr ) ), - SLOT( onPlaylistDeleted( Tomahawk::playlist_ptr ) ), Qt::QueuedConnection ); + SLOT( onPlaylistDeleted( Tomahawk::playlist_ptr ) ), Qt::QueuedConnection ); else connect( p.data(), SIGNAL( deleted( Tomahawk::playlist_ptr ) ), - SLOT( onPlaylistDeleted( Tomahawk::playlist_ptr ) ), Qt::QueuedConnection ); + SLOT( onPlaylistDeleted( Tomahawk::playlist_ptr ) ), Qt::QueuedConnection ); } m_playlists->endRowsAdded(); @@ -374,7 +372,7 @@ SourceItem::onPlaylistsAdded( const QList< playlist_ptr >& playlists ) void -SourceItem::onPlaylistDeleted( const playlist_ptr& playlist ) +SourceItem::onPlaylistDeleted( const playlist_ptr& playlist ) { playlistDeletedInternal( m_playlists, playlist ); } @@ -383,10 +381,10 @@ SourceItem::onPlaylistDeleted( const playlist_ptr& playlist ) void SourceItem::onAutoPlaylistsAdded( const QList< dynplaylist_ptr >& playlists ) { - if( playlists.isEmpty() ) + if ( playlists.isEmpty() ) return; - if( !m_playlists ) + if ( !m_playlists ) { // add the category too int cur = children().count(); @@ -402,8 +400,8 @@ SourceItem::onAutoPlaylistsAdded( const QList< dynplaylist_ptr >& playlists ) void SourceItem::onAutoPlaylistDeleted( const dynplaylist_ptr& playlist ) { - if( !m_playlists ) - qDebug() << "NO playlist category item for a deleting playlist.."; + if ( !m_playlists ) + qDebug() << "NO playlist category item for a deleting playlist..."; playlistDeletedInternal( m_playlists, playlist ); } @@ -412,10 +410,10 @@ SourceItem::onAutoPlaylistDeleted( const dynplaylist_ptr& playlist ) void SourceItem::onStationsAdded( const QList< dynplaylist_ptr >& stations ) { - if( stations.isEmpty() ) + if ( stations.isEmpty() ) return; - if( !m_stations ) + if ( !m_stations ) { // add the category too int cur = children().count(); @@ -445,7 +443,7 @@ SourceItem::requestExpanding() ViewPage* SourceItem::sourceInfoClicked() { - if( m_source.isNull() ) + if ( m_source.isNull() ) return 0; m_sourceInfoPage = ViewManager::instance()->show( m_source ); @@ -463,7 +461,7 @@ SourceItem::getSourceInfoPage() const ViewPage* SourceItem::collectionClicked() { - if( m_source.isNull() ) + if ( m_source.isNull() ) return 0; m_collectionPage = ViewManager::instance()->show( m_source->collection() ); @@ -503,7 +501,12 @@ ViewPage* SourceItem::lovedTracksClicked() { if ( !m_lovedTracksPage ) - m_lovedTracksPage = new CustomPlaylistView( m_source.isNull() ? CustomPlaylistView::TopLovedTracks : CustomPlaylistView::SourceLovedTracks, m_source, ViewManager::instance()->widget() ); + { + CustomPlaylistView* view = new CustomPlaylistView( m_source.isNull() ? CustomPlaylistView::TopLovedTracks : CustomPlaylistView::SourceLovedTracks, m_source, ViewManager::instance()->widget() ); + view->setItemDelegate( new PlaylistLargeItemDelegate( view, view->proxyModel() ) ); + + m_lovedTracksPage = view; + } ViewManager::instance()->show( m_lovedTracksPage ); return m_lovedTracksPage; @@ -523,8 +526,13 @@ SourceItem::latestAdditionsClicked() if ( !m_latestAdditionsPage ) { CollectionView* cv = new CollectionView( ViewManager::instance()->widget() ); - RecentlyAddedModel* raModel = new RecentlyAddedModel( m_source, cv ); + cv->setFrameShape( QFrame::NoFrame ); + cv->setAttribute( Qt::WA_MacShowFocusRect, 0 ); + RecentlyAddedModel* raModel = new RecentlyAddedModel( m_source, cv ); + raModel->setStyle( TrackModel::Large ); + + cv->setItemDelegate( new PlaylistLargeItemDelegate( cv, cv->proxyModel() ) ); cv->setTrackModel( raModel ); cv->sortByColumn( TrackModel::Age, Qt::DescendingOrder ); @@ -549,8 +557,13 @@ SourceItem::recentPlaysClicked() if ( !m_recentPlaysPage ) { PlaylistView* pv = new PlaylistView( ViewManager::instance()->widget() ); - RecentlyPlayedModel* raModel = new RecentlyPlayedModel( m_source, pv ); + pv->setFrameShape( QFrame::NoFrame ); + pv->setAttribute( Qt::WA_MacShowFocusRect, 0 ); + RecentlyPlayedModel* raModel = new RecentlyPlayedModel( m_source, pv ); + raModel->setStyle( TrackModel::Large ); + + pv->setItemDelegate( new PlaylistLargeItemDelegate( pv, pv->proxyModel() ) ); pv->setPlaylistModel( raModel ); m_recentPlaysPage = pv; From 6f0d29dde9abbe58ee619226883f0330e2f7445b Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Sat, 17 Mar 2012 08:08:28 +0100 Subject: [PATCH 16/29] * Bold font decoration for usernames in the delegate. --- .../playlist/PlaylistLargeItemDelegate.cpp | 49 ++++++++++++++++--- .../playlist/PlaylistLargeItemDelegate.h | 2 + src/libtomahawk/query.cpp | 14 ++++-- src/libtomahawk/query.h | 5 +- 4 files changed, 57 insertions(+), 13 deletions(-) diff --git a/src/libtomahawk/playlist/PlaylistLargeItemDelegate.cpp b/src/libtomahawk/playlist/PlaylistLargeItemDelegate.cpp index b94c17ac2..f1c036456 100644 --- a/src/libtomahawk/playlist/PlaylistLargeItemDelegate.cpp +++ b/src/libtomahawk/playlist/PlaylistLargeItemDelegate.cpp @@ -20,6 +20,7 @@ #include #include +#include #include "query.h" #include "result.h" @@ -109,6 +110,29 @@ PlaylistLargeItemDelegate::prepareStyleOption( QStyleOptionViewItemV4* option, c } +void +PlaylistLargeItemDelegate::drawRichText( QPainter* painter, const QRect& rect, int flags, QTextDocument& text ) const +{ + text.setPageSize( QSize( rect.width(), QWIDGETSIZE_MAX ) ); + QAbstractTextDocumentLayout* layout = text.documentLayout(); + + const int height = qRound( layout->documentSize().height() ); + int y = rect.y(); + if ( flags & Qt::AlignBottom ) + y += ( rect.height() - height ); + else if ( flags & Qt::AlignVCenter ) + y += ( rect.height() - height ) / 2; + + QAbstractTextDocumentLayout::PaintContext context; + context.palette.setColor( QPalette::Text, painter->pen().color() ); + + painter->save(); + painter->translate( rect.x(), y ); + layout->draw( painter, context ); + painter->restore(); +} + + void PlaylistLargeItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const { @@ -141,8 +165,8 @@ PlaylistLargeItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& track = item->query()->track(); } - lowerText = item->query()->socialActionDescription( "Love" ); - + lowerText = item->query()->socialActionDescription( "Love", Query::Detailed ); + if ( source.isNull() ) { } @@ -201,9 +225,12 @@ PlaylistLargeItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& smallBoldFont.setBold( true ); smallBoldFont.setWeight( 80 ); + QFont smallFont = opt.font; + smallFont.setPixelSize( 10 ); + r.adjust( pixmapRect.width() + 12, 1, -28 - avatar.width(), 0 ); - QRect leftRect = r.adjusted( 0, 0, -r.width() / 2 - 4, 0 ); - QRect rightRect = r.adjusted( r.width() / 2 + 4, 0, 0, 0 ); + QRect leftRect = r.adjusted( 0, 0, -48, 0 ); + QRect rightRect = r.adjusted( r.width() - 40, 0, 0, 0 ); painter->setFont( boldFont ); QString text = painter->fontMetrics().elidedText( artist, Qt::ElideRight, leftRect.width() ); @@ -213,9 +240,17 @@ PlaylistLargeItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& text = painter->fontMetrics().elidedText( track, Qt::ElideRight, leftRect.width() ); painter->drawText( leftRect.adjusted( 0, 19, 0, 0 ), text, m_topOption ); - painter->setFont( opt.font ); - text = painter->fontMetrics().elidedText( lowerText, Qt::ElideRight, leftRect.width() ); - painter->drawText( leftRect, text, m_bottomOption ); + painter->setFont( smallFont ); + QTextDocument textDoc; + textDoc.setHtml( lowerText ); + textDoc.setDocumentMargin( 0 ); + textDoc.setDefaultFont( painter->font() ); + textDoc.setDefaultTextOption( m_bottomOption ); + + if ( textDoc.idealWidth() > leftRect.width() ) + textDoc.setHtml( item->query()->socialActionDescription( "Love", Query::Short ) ); + + drawRichText( painter, leftRect, Qt::AlignBottom, textDoc ); if ( duration > 0 ) { diff --git a/src/libtomahawk/playlist/PlaylistLargeItemDelegate.h b/src/libtomahawk/playlist/PlaylistLargeItemDelegate.h index 6bdae39aa..56ea64a57 100644 --- a/src/libtomahawk/playlist/PlaylistLargeItemDelegate.h +++ b/src/libtomahawk/playlist/PlaylistLargeItemDelegate.h @@ -20,6 +20,7 @@ #define PLAYLISTLARGEITEMDELEGATE_H #include +#include #include #include "dllmacro.h" @@ -43,6 +44,7 @@ protected: private: void prepareStyleOption( QStyleOptionViewItemV4* option, const QModelIndex& index, TrackModelItem* item ) const; + void drawRichText( QPainter* painter, const QRect& rect, int flags, QTextDocument& text ) const; QTextOption m_topOption; QTextOption m_centerRightOption; diff --git a/src/libtomahawk/query.cpp b/src/libtomahawk/query.cpp index e59248057..dd47eec9a 100644 --- a/src/libtomahawk/query.cpp +++ b/src/libtomahawk/query.cpp @@ -585,7 +585,7 @@ Query::setLoved( bool loved ) QString -Query::socialActionDescription( const QString& action ) const +Query::socialActionDescription( const QString& action, DescriptionMode mode ) const { QString desc; QList< Tomahawk::SocialAction > socialActions = allSocialActions(); @@ -626,18 +626,22 @@ Query::socialActionDescription( const QString& action ) const if ( sa.source->isLocal() ) { if ( loveCounter == 1 ) - desc += tr( "You" ); + desc += "" + tr( "You" ) + ""; else - desc += tr( "you" ); + desc += "" + tr( "you" ) + ""; } else - desc += sa.source->friendlyName(); + desc += "" + sa.source->friendlyName() + ""; } } if ( loveCounter > 0 ) { if ( loveCounter > 3 ) - desc += " " + tr( "and %1 others" ).arg( loveCounter - 3 ); + desc += " " + tr( "and %1%2 others%3" ).arg( "" ).arg( loveCounter - 3 ).arg( "" ); + + if ( mode == Short ) + desc = "" + tr( "%1 people" ).arg( loveCounter ) + ""; + desc += " " + tr( "loved this track" ); //FIXME: more action descs required } diff --git a/src/libtomahawk/query.h b/src/libtomahawk/query.h index 8629dcfec..f4e2c1b74 100644 --- a/src/libtomahawk/query.h +++ b/src/libtomahawk/query.h @@ -48,6 +48,9 @@ friend class ::DatabaseCommand_LoadPlaylistEntries; friend class Pipeline; public: + enum DescriptionMode + { Detailed = 0, Short = 1 }; + static query_ptr get( const QString& artist, const QString& track, const QString& album, const QID& qid = QString(), bool autoResolve = true ); static query_ptr get( const QString& query, const QID& qid ); @@ -116,7 +119,7 @@ public: void loadSocialActions(); QList< Tomahawk::SocialAction > allSocialActions() const; void setAllSocialActions( const QList< Tomahawk::SocialAction >& socialActions ); - QString socialActionDescription( const QString& action ) const; + QString socialActionDescription( const QString& action, DescriptionMode mode ) const; QWeakPointer< Tomahawk::Query > weakRef() { return m_ownRef; } void setWeakRef( QWeakPointer< Tomahawk::Query > weakRef ) { m_ownRef = weakRef; } From 6e34b3f620f41e2e253b3b8cd9dc6f36305ddfe5 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Sat, 17 Mar 2012 08:54:02 +0100 Subject: [PATCH 17/29] * Fixed size for the search widget. --- src/libtomahawk/thirdparty/Qocoa/qsearchfield.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/libtomahawk/thirdparty/Qocoa/qsearchfield.cpp b/src/libtomahawk/thirdparty/Qocoa/qsearchfield.cpp index a1da7af8c..ffd45acef 100644 --- a/src/libtomahawk/thirdparty/Qocoa/qsearchfield.cpp +++ b/src/libtomahawk/thirdparty/Qocoa/qsearchfield.cpp @@ -52,14 +52,13 @@ QSearchField::QSearchField(QWidget *parent) : QWidget(parent) setContentsMargins(0, 0, 0, 0); lineEdit->setStyleSheet( "QLineEdit { border: 1px solid gray; border-radius: 6px; }" ); + lineEdit->setMinimumHeight(27); + setFixedHeight(27); #ifdef Q_WS_MAC lineEdit->setContentsMargins(0, 0, 0, 0); - lineEdit->setMinimumHeight(27); - setFixedHeight(27); #else lineEdit->setContentsMargins(2, 2, 2, 2); - lineEdit->setMinimumHeight(27); #endif } From afe6ed8463482b246db861f2e88841966a0d6231 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Sat, 17 Mar 2012 09:40:04 +0100 Subject: [PATCH 18/29] * Added a Chart delegate. --- src/libtomahawk/CMakeLists.txt | 1 + .../playlist/PlaylistChartItemDelegate.cpp | 236 ++++++++++++++++++ .../playlist/PlaylistChartItemDelegate.h | 56 +++++ src/libtomahawk/widgets/whatshotwidget.cpp | 5 +- 4 files changed, 297 insertions(+), 1 deletion(-) create mode 100644 src/libtomahawk/playlist/PlaylistChartItemDelegate.cpp create mode 100644 src/libtomahawk/playlist/PlaylistChartItemDelegate.h diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index 35df525d8..5e845fa2a 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -80,6 +80,7 @@ set( libGuiSources playlist/RecentlyAddedModel.cpp playlist/RecentlyPlayedModel.cpp playlist/PlaylistLargeItemDelegate.cpp + playlist/PlaylistChartItemDelegate.cpp playlist/dynamic/DynamicPlaylist.cpp playlist/dynamic/DynamicView.cpp diff --git a/src/libtomahawk/playlist/PlaylistChartItemDelegate.cpp b/src/libtomahawk/playlist/PlaylistChartItemDelegate.cpp new file mode 100644 index 000000000..00cd60093 --- /dev/null +++ b/src/libtomahawk/playlist/PlaylistChartItemDelegate.cpp @@ -0,0 +1,236 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Christian Muehlhaeuser + * + * 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 "PlaylistChartItemDelegate.h" + +#include +#include + +#include "query.h" +#include "result.h" +#include "artist.h" +#include "source.h" +#include "sourcelist.h" + +#include "trackmodel.h" +#include "trackmodelitem.h" +#include "trackproxymodel.h" +#include "trackview.h" +#include "trackheader.h" + +#include "utils/tomahawkutilsgui.h" +#include "utils/logger.h" + +using namespace Tomahawk; + + +PlaylistChartItemDelegate::PlaylistChartItemDelegate( TrackView* parent, TrackProxyModel* proxy ) + : QStyledItemDelegate( (QObject*)parent ) + , m_view( parent ) + , m_model( proxy ) +{ + m_topOption = QTextOption( Qt::AlignTop ); + m_topOption.setWrapMode( QTextOption::NoWrap ); + + m_centerOption = QTextOption( Qt::AlignCenter ); + m_centerOption.setWrapMode( QTextOption::NoWrap ); + + m_centerRightOption = QTextOption( Qt::AlignVCenter | Qt::AlignRight ); + m_centerRightOption.setWrapMode( QTextOption::NoWrap ); + + m_bottomOption = QTextOption( Qt::AlignBottom ); + m_bottomOption.setWrapMode( QTextOption::NoWrap ); +} + + +QSize +PlaylistChartItemDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const +{ + QSize size = QStyledItemDelegate::sizeHint( option, index ); + + int stretch = 0; + switch ( index.row() ) + { + case 0: + stretch = 6; + break; + case 1: + case 2: + stretch = 5; + break; + + default: + if ( index.row() < 10 ) + stretch = 3; + else + stretch = 2; + } + + if ( index.isValid() ) + { + int rowHeight = option.fontMetrics.height() + 8; + size.setHeight( rowHeight * stretch ); + } + + return size; +} + + +QWidget* +PlaylistChartItemDelegate::createEditor( QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const +{ + Q_UNUSED( parent ); + Q_UNUSED( option ); + Q_UNUSED( index ); + return 0; +} + + +void +PlaylistChartItemDelegate::prepareStyleOption( QStyleOptionViewItemV4* option, const QModelIndex& index, TrackModelItem* item ) const +{ + initStyleOption( option, index ); + + if ( item->isPlaying() ) + { + option->palette.setColor( QPalette::Highlight, option->palette.color( QPalette::Mid ) ); + option->state |= QStyle::State_Selected; + } + + if ( option->state & QStyle::State_Selected ) + { + option->palette.setColor( QPalette::Text, option->palette.color( QPalette::HighlightedText ) ); + } + else + { + float opacity = 0.0; + if ( item->query()->results().count() ) + opacity = item->query()->results().first()->score(); + + opacity = qMax( (float)0.3, opacity ); + QColor textColor = TomahawkUtils::alphaBlend( option->palette.color( QPalette::Text ), option->palette.color( QPalette::BrightText ), opacity ); + + option->palette.setColor( QPalette::Text, textColor ); + } +} + + +void +PlaylistChartItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const +{ + TrackModelItem* item = m_model->itemFromIndex( m_model->mapToSource( index ) ); + Q_ASSERT( item ); + + QStyleOptionViewItemV4 opt = option; + prepareStyleOption( &opt, index, item ); + opt.text.clear(); + + qApp->style()->drawControl( QStyle::CE_ItemViewItem, &opt, painter ); + + if ( m_view->header()->visualIndex( index.column() ) > 0 ) + return; + + QPixmap pixmap, avatar; + QString artist, track, upperText, lowerText; + unsigned int duration = 0; + + if ( item->query()->results().count() ) + { + artist = item->query()->results().first()->artist()->name(); + track = item->query()->results().first()->track(); + duration = item->query()->results().first()->duration(); + } + else + { + artist = item->query()->artist(); + track = item->query()->track(); + } + + painter->save(); + { + QRect r = opt.rect.adjusted( 3, 6, 0, -6 ); + + // Paint Now Playing Speaker Icon + if ( item->isPlaying() ) + { + QPixmap nowPlayingIcon = TomahawkUtils::defaultPixmap( TomahawkUtils::NowPlayingSpeaker ); + QRect npr = r.adjusted( 3, r.height() / 2 - nowPlayingIcon.height() / 2, 18 - r.width(), -r.height() / 2 + nowPlayingIcon.height() / 2 ); + nowPlayingIcon = TomahawkUtils::defaultPixmap( TomahawkUtils::NowPlayingSpeaker, TomahawkUtils::Original, npr.size() ); + painter->drawPixmap( npr, nowPlayingIcon ); + r.adjust( 22, 0, 0, 0 ); + } + + painter->setPen( opt.palette.text().color() ); + + QFont figureFont = opt.font; + figureFont.setPixelSize( 18 ); + figureFont.setWeight( 99 ); + + QFont boldFont = opt.font; + boldFont.setPixelSize( 15 ); + boldFont.setWeight( 99 ); + + QFont smallBoldFont = opt.font; + smallBoldFont.setPixelSize( 12 ); + smallBoldFont.setWeight( 80 ); + + if ( index.row() == 0 ) + figureFont.setPixelSize( 36 ); + else if ( index.row() == 1 ) + figureFont.setPixelSize( 30 ); + else if ( index.row() == 2 ) + figureFont.setPixelSize( 24 ); + else if ( index.row() >= 10 ) + { + boldFont.setPixelSize( 12 ); + smallBoldFont.setPixelSize( 11 ); + } + + QRect figureRect = r.adjusted( 0, 0, -option.rect.width() + 60 - 6 + r.left(), 0 ); + painter->setFont( figureFont ); + painter->drawText( figureRect, QString::number( index.row() + 1 ), m_centerOption ); + + QRect pixmapRect = r.adjusted( figureRect.width() + 6, 0, -option.rect.width() + figureRect.width() + option.rect.height() - 6 + r.left(), 0 ); + pixmap = item->query()->cover( pixmapRect.size(), false ); + if ( !pixmap ) + { + pixmap = TomahawkUtils::defaultPixmap( TomahawkUtils::DefaultTrackImage, TomahawkUtils::ScaledCover, pixmapRect.size() ); + } + painter->drawPixmap( pixmapRect, pixmap ); + + r.adjust( pixmapRect.width() + figureRect.width() + 18, 1, -28, 0 ); + QRect leftRect = r.adjusted( 0, 0, -48, 0 ); + QRect rightRect = r.adjusted( r.width() - 40, 0, 0, 0 ); + + painter->setFont( boldFont ); + QString text = painter->fontMetrics().elidedText( artist, Qt::ElideRight, leftRect.width() ); + painter->drawText( leftRect, text, m_topOption ); + + painter->setFont( smallBoldFont ); + text = painter->fontMetrics().elidedText( track, Qt::ElideRight, leftRect.width() ); + painter->drawText( index.row() >= 10 ? leftRect : leftRect.adjusted( 0, 19, 0, 0 ), text, index.row() >= 10 ? m_bottomOption : m_topOption ); + + if ( duration > 0 ) + { + painter->setFont( smallBoldFont ); + text = painter->fontMetrics().elidedText( TomahawkUtils::timeToString( duration ), Qt::ElideRight, rightRect.width() ); + painter->drawText( rightRect, text, m_centerRightOption ); + } + } + painter->restore(); +} diff --git a/src/libtomahawk/playlist/PlaylistChartItemDelegate.h b/src/libtomahawk/playlist/PlaylistChartItemDelegate.h new file mode 100644 index 000000000..1819be8a0 --- /dev/null +++ b/src/libtomahawk/playlist/PlaylistChartItemDelegate.h @@ -0,0 +1,56 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Christian Muehlhaeuser + * + * 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 PLAYLISTCHARTITEMDELEGATE_H +#define PLAYLISTCHARTITEMDELEGATE_H + +#include +#include + +#include "dllmacro.h" + +class TrackModel; +class TrackModelItem; +class TrackProxyModel; +class TrackView; + +class DLLEXPORT PlaylistChartItemDelegate : public QStyledItemDelegate +{ +Q_OBJECT + +public: + PlaylistChartItemDelegate( TrackView* parent = 0, TrackProxyModel* proxy = 0 ); + +protected: + void paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const; + QSize sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const; + QWidget* createEditor( QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const; + +private: + void prepareStyleOption( QStyleOptionViewItemV4* option, const QModelIndex& index, TrackModelItem* item ) const; + + QTextOption m_topOption; + QTextOption m_centerOption; + QTextOption m_centerRightOption; + QTextOption m_bottomOption; + + TrackView* m_view; + TrackProxyModel* m_model; +}; + +#endif // PLAYLISTCHARTITEMDELEGATE_H diff --git a/src/libtomahawk/widgets/whatshotwidget.cpp b/src/libtomahawk/widgets/whatshotwidget.cpp index c4c9ecfb4..b116aaea0 100644 --- a/src/libtomahawk/widgets/whatshotwidget.cpp +++ b/src/libtomahawk/widgets/whatshotwidget.cpp @@ -35,6 +35,7 @@ #include "dynamic/GeneratorInterface.h" #include "playlist/playlistmodel.h" #include "playlist/treeproxymodel.h" +#include "playlist/PlaylistChartItemDelegate.h" #include "widgets/overlaywidget.h" #include "utils/tomahawkutils.h" #include "utils/logger.h" @@ -81,6 +82,8 @@ WhatsHotWidget::WhatsHotWidget( QWidget* parent ) ui->tracksViewLeft->overlay()->setEnabled( false ); ui->tracksViewLeft->setHeaderHidden( true ); ui->tracksViewLeft->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff ); + ui->tracksViewLeft->setItemDelegate( new PlaylistChartItemDelegate( ui->tracksViewLeft, ui->tracksViewLeft->proxyModel() ) ); + ui->tracksViewLeft->setUniformRowHeights( false ); TreeProxyModel* artistsProxy = new TreeProxyModel( ui->artistsViewLeft ); artistsProxy->setFilterCaseSensitivity( Qt::CaseInsensitive ); @@ -289,7 +292,7 @@ WhatsHotWidget::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestDat connect( loader, SIGNAL( tracks( Tomahawk::ChartDataLoader*, QList< Tomahawk::query_ptr > ) ), this, SLOT( chartTracksLoaded( Tomahawk::ChartDataLoader*, QList< Tomahawk::query_ptr > ) ) ); PlaylistModel* trackModel = new PlaylistModel( ui->tracksViewLeft ); - trackModel->setStyle( TrackModel::Short ); + trackModel->setStyle( TrackModel::Large ); m_trackModels[ chartId ] = trackModel; From 48d2ac71fa8133f66dce85379f56aa95f4aea8b5 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Sat, 17 Mar 2012 09:46:35 +0100 Subject: [PATCH 19/29] * Use bigger fonts for top chart items. --- .../playlist/PlaylistChartItemDelegate.cpp | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/libtomahawk/playlist/PlaylistChartItemDelegate.cpp b/src/libtomahawk/playlist/PlaylistChartItemDelegate.cpp index 00cd60093..8fecc813c 100644 --- a/src/libtomahawk/playlist/PlaylistChartItemDelegate.cpp +++ b/src/libtomahawk/playlist/PlaylistChartItemDelegate.cpp @@ -188,13 +188,29 @@ PlaylistChartItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& QFont smallBoldFont = opt.font; smallBoldFont.setPixelSize( 12 ); smallBoldFont.setWeight( 80 ); - + + QFont durationFont = opt.font; + durationFont.setPixelSize( 12 ); + durationFont.setWeight( 80 ); + if ( index.row() == 0 ) + { figureFont.setPixelSize( 36 ); + boldFont.setPixelSize( 26 ); + smallBoldFont.setPixelSize( 22 ); + } else if ( index.row() == 1 ) + { figureFont.setPixelSize( 30 ); + boldFont.setPixelSize( 22 ); + smallBoldFont.setPixelSize( 18 ); + } else if ( index.row() == 2 ) + { figureFont.setPixelSize( 24 ); + boldFont.setPixelSize( 18 ); + smallBoldFont.setPixelSize( 14 ); + } else if ( index.row() >= 10 ) { boldFont.setPixelSize( 12 ); @@ -223,11 +239,11 @@ PlaylistChartItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& painter->setFont( smallBoldFont ); text = painter->fontMetrics().elidedText( track, Qt::ElideRight, leftRect.width() ); - painter->drawText( index.row() >= 10 ? leftRect : leftRect.adjusted( 0, 19, 0, 0 ), text, index.row() >= 10 ? m_bottomOption : m_topOption ); + painter->drawText( index.row() >= 10 ? leftRect : leftRect.adjusted( 0, painter->fontMetrics().height() + 6, 0, 0 ), text, index.row() >= 10 ? m_bottomOption : m_topOption ); if ( duration > 0 ) { - painter->setFont( smallBoldFont ); + painter->setFont( durationFont ); text = painter->fontMetrics().elidedText( TomahawkUtils::timeToString( duration ), Qt::ElideRight, rightRect.width() ); painter->drawText( rightRect, text, m_centerRightOption ); } From 6d068e33ce8a53e6a0475598e80ccc628b45bb15 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Sat, 17 Mar 2012 10:04:59 +0100 Subject: [PATCH 20/29] * Use different color for chart position. --- src/libtomahawk/playlist/PlaylistChartItemDelegate.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libtomahawk/playlist/PlaylistChartItemDelegate.cpp b/src/libtomahawk/playlist/PlaylistChartItemDelegate.cpp index 8fecc813c..a715fbb5e 100644 --- a/src/libtomahawk/playlist/PlaylistChartItemDelegate.cpp +++ b/src/libtomahawk/playlist/PlaylistChartItemDelegate.cpp @@ -175,8 +175,6 @@ PlaylistChartItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& r.adjust( 22, 0, 0, 0 ); } - painter->setPen( opt.palette.text().color() ); - QFont figureFont = opt.font; figureFont.setPixelSize( 18 ); figureFont.setWeight( 99 ); @@ -219,7 +217,9 @@ PlaylistChartItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& QRect figureRect = r.adjusted( 0, 0, -option.rect.width() + 60 - 6 + r.left(), 0 ); painter->setFont( figureFont ); + painter->setPen( option.palette.text().color().lighter( 450 ) ); painter->drawText( figureRect, QString::number( index.row() + 1 ), m_centerOption ); + painter->setPen( opt.palette.text().color() ); QRect pixmapRect = r.adjusted( figureRect.width() + 6, 0, -option.rect.width() + figureRect.width() + option.rect.height() - 6 + r.left(), 0 ); pixmap = item->query()->cover( pixmapRect.size(), false ); From 15194438ee7d40852aa8715c29d66702888a4ec0 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Sat, 17 Mar 2012 10:35:29 +0100 Subject: [PATCH 21/29] * Slightly decrease size of third chart item. --- src/libtomahawk/playlist/PlaylistChartItemDelegate.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libtomahawk/playlist/PlaylistChartItemDelegate.cpp b/src/libtomahawk/playlist/PlaylistChartItemDelegate.cpp index a715fbb5e..3449230f1 100644 --- a/src/libtomahawk/playlist/PlaylistChartItemDelegate.cpp +++ b/src/libtomahawk/playlist/PlaylistChartItemDelegate.cpp @@ -70,9 +70,11 @@ PlaylistChartItemDelegate::sizeHint( const QStyleOptionViewItem& option, const Q stretch = 6; break; case 1: - case 2: stretch = 5; break; + case 2: + stretch = 4; + break; default: if ( index.row() < 10 ) From 57e55d0b8830f3c681712d9d746ab08afe957715 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Sat, 17 Mar 2012 11:23:40 +0100 Subject: [PATCH 22/29] * other vs others. --- lang/tomahawk_en.ts | 1985 +++++++++++++++++++++---------------- src/libtomahawk/query.cpp | 2 +- 2 files changed, 1137 insertions(+), 850 deletions(-) diff --git a/lang/tomahawk_en.ts b/lang/tomahawk_en.ts index 061841a3e..e339dfadd 100644 --- a/lang/tomahawk_en.ts +++ b/lang/tomahawk_en.ts @@ -1,6 +1,42 @@ + + AccountFactoryWrapper + + + Dialog + + + + + Description goes here + + + + + Add Account + + + + + AccountFactoryWrapperDelegate + + + Online + + + + + Connecting... + + + + + Offline + + + ActionCollection @@ -14,54 +50,59 @@ - - + + &Follow in real-time + + + + + &Listen Privately - - + + &Listen Publicly - + &Load Playlist - + &Rename Playlist - + &Copy Playlist Link - + &Play - + &Stop - + &Previous Track - + &Next Track - + &Quit @@ -78,31 +119,31 @@ Other Albums by Artist - - - - Click to show Super Collection Tracks - - - + Click to show Official Tracks - - - Click to show Super Collection Albums + + + Click to show SuperCollection Tracks - + + + Click to show SuperCollection Albums + + + + Click to show Official Albums - + Other Albums by %1 @@ -110,18 +151,18 @@ AlbumModel - + Album - - + + All albums from %1 - + All albums @@ -129,12 +170,12 @@ AlbumView - + After you have scanned your music collection you will find your latest album additions right here. - + This collection doesn't have any recent albums. @@ -162,13 +203,13 @@ - - - Click to show Super Collection Albums + + + Click to show SuperCollection Albums - + Click to show Official Albums @@ -176,17 +217,17 @@ ArtistView - + After you have scanned your music collection you will find your tracks right here. - + This collection is currently empty. - + Sorry, your filter '%1' did not match any results. @@ -239,27 +280,27 @@ - + Time Left - + Shuffle - + Repeat - + Low - + High @@ -267,41 +308,41 @@ AudioEngine - + Tomahawk is stopped. - + Tomahawk is playing "%1" by %2%3. - - on album %1 + + on album %1 CategoryAddItem - - + + New Playlist - - - - + + + + New Station - - - + + + %1 Station @@ -309,12 +350,12 @@ CategoryItem - + Playlists - + Stations @@ -340,43 +381,10 @@ - - CollectionItem - - - Top Loved Tracks - - - - - Loved Tracks - - - - - Dashboard - - - - - Charts - - - - - New Additions - - - - - Super Collection - - - CollectionView - + This collection is empty. @@ -452,6 +460,14 @@ + + DelegateConfigWrapper + + + Delete Account + + + DiagnosticsDialog @@ -471,60 +487,10 @@ - GetNewStuffDelegate + DropJob - - Installed - - - - - - Installing - - - - - - Failed - - - - - Uninstalling - - - - - Install - - - - - Upgrading - - - - - Uninstall - - - - - Upgrade - - - - - %1 downloads - - - - - GetNewStuffDialog - - - Download New Resolvers + + No tracks found for given %1 @@ -537,30 +503,10 @@ - GoogleWrapper + IndexingJobItem - - Configure this Google Account - - - - - Google Address - - - - - Enter your Google login to connect with your friends using Tomahawk! - - - - - Add Friend - - - - - Enter Google Address: + + Indexing database @@ -582,152 +528,6 @@ - - JabberConfig - - - Jabber Configuration - - - - - Configure this Jabber account - - - - - Enter your Jabber login to connect with your friends using Tomahawk! - - - - - Login Information - - - - - Jabber ID: - - - - - e.g. user@example.com - - - - - Password: - - - - - An account with this name already exists! - - - - - Advanced Jabber Settings - - - - - Server: - - - - - Port: - - - - - JabberPlugin - - - User Interaction - - - - - Host is unknown - - - - - Item not found - - - - - Authorization Error - - - - - Remote Stream Error - - - - - Remote Connection failed - - - - - Internal Server Error - - - - - System shutdown - - - - - Conflict - - - - - Unknown - - - - - Add Friend - - - - - Enter Jabber 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 - - - - - Do you want to grant <b>%1</b> access to your Collection? - - - JobStatusView @@ -746,6 +546,34 @@ + + LastFmConfig + + + Form + + + + + Scrobble tracks to Last.fm + + + + + Username: + + + + + Password: + + + + + Test Login + + + LastfmContext @@ -847,12 +675,25 @@ PlaylistItemDelegate - + played %1 by you - + + played %1 by %2 + + + + + PlaylistLargeItemDelegate + + + played %1 by you + + + + played %1 by %2 @@ -870,12 +711,12 @@ - + All tracks by %1 on album %2 - + All tracks by %1 @@ -921,7 +762,7 @@ PlaylistView - + This playlist is currently empty. Add some tracks to it and enjoy the music! @@ -975,16 +816,17 @@ - No Proxy Hosts: + No Proxy Hosts: +(Overrides system proxy) - + localhost *.example.com (space separated) - + Use proxy for DNS lookups? @@ -992,7 +834,7 @@ QObject - + %n year(s) ago %n year ago @@ -1000,7 +842,7 @@ - + %n year(s) %n year @@ -1008,7 +850,7 @@ - + %n month(s) ago %n month ago @@ -1016,7 +858,7 @@ - + %n month(s) %n month @@ -1024,7 +866,7 @@ - + %n week(s) ago %n week ago @@ -1032,7 +874,7 @@ - + %n week(s) %n week @@ -1040,7 +882,7 @@ - + %n day(s) ago %n day ago @@ -1048,7 +890,7 @@ - + %n day(s) %n day @@ -1056,7 +898,7 @@ - + %n hour(s) ago %n hour ago @@ -1064,7 +906,7 @@ - + %n hour(s) %n hour @@ -1072,20 +914,35 @@ - + %1 minutes ago - + %1 minutes - + just now + + + Friend Finders + + + + + Music Finders + + + + + Status Updaters + + QuaZipFilePrivate @@ -1104,10 +961,6 @@ - Open Queue - - - Show Queue @@ -1150,12 +1003,12 @@ SearchWidget - + Search: %1 - + Results for '%1' @@ -1163,118 +1016,41 @@ SettingsDialog - - Accounts - - - - + Collection - - Last.fm - - - - - Resolvers - - - - + Advanced - - - Failed + + All - - Success + + Services - - Could not contact server + + Install resolver from file - - Load script resolver file - - - - - Delete Account - - - - + Information - + Changing this setting requires a restart of Tomahawk! - - SipConfigDelegate - - - Online - - - - - Connecting... - - - - - Offline - - - - - SipHandler - - - Legal Warning - - - - - By pressing I Agree below, you agree that your use of Tomahawk will be in accordance with any applicable laws, including copyright and intellectual property laws, in effect in your country of residence, and indemnify the Tomahawk developers and project from liability should you choose to break those laws. - -For more information, please see http://gettomahawk.com/legal - - - - - I Do Not Agree - - - - - I Agree - - - - - SipModel - - - Add New Account... - - - SocialPlaylistWidget @@ -1321,20 +1097,32 @@ For more information, please see http://gettomahawk.com/legal - + Offline - + All available tracks - + Online + + + + Show + + + + + + Hide + + SourceInfoWidget @@ -1354,45 +1142,73 @@ For more information, please see http://gettomahawk.com/legal - + New Additions - + My recent activity - + Recent activity from %1 + + SourceItem + + + Collection + + + + + Latest Additions + + + + + Recently Played + + + + + Loved Tracks + + + + + SuperCollection + + + SourceTreeView - + &Copy Link - + &Delete %1 - + &Export Playlist - + Save XSPF - + Playlists (*.xspf) @@ -1400,25 +1216,113 @@ For more information, please see http://gettomahawk.com/legal SourcesModel - + + Group + + + + Collection - + Playlist - + Automatic Playlist - + Station + + + Browse + + + + + Search History + + + + + My Music + + + + + SuperCollection + + + + + Top Loved Tracks + + + + + Dashboard + + + + + Charts + + + + + Friends + + + + + SpotifyConfig + + + Form + + + + + Configure your Spotify credentials + + + + + Username: + + + + + placeholderUsername + + + + + Password: + + + + + placeholderPw + + + + + High Quality Streaming + + + + + This product uses SPOTIFY(R) CORE but is not endorsed, certified or otherwise approved in any way by Spotify. Spotify is the registered trade mark of the Spotify Group. + + StackedSettingsDialog @@ -1428,33 +1332,17 @@ For more information, please see http://gettomahawk.com/legal - - Accounts - - - - - Connect to your friends with Google Chat, Twitter, and more. - - - - - - ... - - - - + 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 @@ -1462,144 +1350,390 @@ For more information, please see http://gettomahawk.com/legal - + Upload collection list to The Echo Nest to enable user radio - + Watch for changes - + Time between scans, in seconds: - - Now Playing Information + + Internet Services - - Applications to update with currently playing track: + + Install from file... - - Adium + + Filter by capability: - - Scrobble tracks to Last.fm - - - - - Username: - - - - - Password: - - - - - Test Login - - - - - Script Resolvers - - - - - Script resolvers search for a given track to make it playable. - - - - - Get more resolvers... - - - - + Advanced Network Settings - + If you're having difficulty connecting to peers, try setting this to your external IP address/host name and a port number (default 50210). Make sure to forward that port to this machine! - + Static Host Name: - + Static Port: - + Always use static host name/port? (Overrides UPnP discovery/port forwarding) - + Proxy Settings... - + Send reports after Tomahawk crashed - + Playdar HTTP API - + Use UPnP to establish port forward + + Tomahawk::Accounts::AccountDelegate + + + Add Account + + + + + Remove Account + + + + + %1 downloads + + + + + Online + + + + + Connecting... + + + + + Offline + + + + + Tomahawk::Accounts::GoogleWrapper + + + Configure this Google Account + + + + + Google Address + + + + + 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 + + + + + Tomahawk::Accounts::GoogleWrapperSip + + + Add Friend + + + + + Enter Google Address: + + + + + Tomahawk::Accounts::LastFmAccountFactory + + + Scrobble your tracks to last.fm, and find freely downloadable tracks to play + + + + + Tomahawk::Accounts::LastFmConfig + + + + Failed + + + + + Success + + + + + Could not contact server + + + + + Tomahawk::Accounts::SpotifyAccountFactory + + + Play music from and sync your playlists with Spotify + + + + + 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 - - Copy Track &Link + + + &Love - + + &Copy Track Link + + + + + Show &Album page + + + + + Show &Artist page + + + + + Un-&Love + + + + &Delete Items - + &Delete Item @@ -1607,32 +1741,32 @@ For more information, please see http://gettomahawk.com/legal Tomahawk::CustomPlaylistView - + Top Loved Tracks - + Your loved tracks - + %1's loved tracks - + The most loved tracks from all your friends - + All of your loved tracks - + All of %1's loved tracks @@ -1661,15 +1795,15 @@ For more information, please see http://gettomahawk.com/legal Tomahawk::DynamicModel - - + + Could not find a playable track. Please change the filters or try again. - + Failed to generate preview with the desired filters @@ -1705,269 +1839,279 @@ Please change the filters or try again. + + 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 - - - - - - - + + + + + + + More - + 0 BPM - + 500 BPM - + 0 secs - + 3600 secs - + -100 dB - + 100 dB - + Major - + Minor - + C - + C Sharp - + D - + E Flat - + E - + F - + F Sharp - + G - + A Flat - + A - + B Flat - + B - + Ascending - + Descending - + Tempo - + Duration - + Loudness - + Artist Familiarity - + Artist Hotttnesss - + Song Hotttnesss - + Latitude - + Longitude - + Mode - + Key - + Energy - + 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 %n minute long @@ -1975,37 +2119,37 @@ Please change the filters or try again. - + 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 @@ -2108,25 +2252,33 @@ Please change the filters or try again. + + Tomahawk::GroovesharkParser + + + Error fetching Grooveshark information from the network! + + + Tomahawk::InfoSystem::ChartsPlugin - + Top Overall - + Artists - + Albums - + Tracks @@ -2134,31 +2286,39 @@ Please change the filters or try again. Tomahawk::InfoSystem::LastFmPlugin - + Top Tracks - + Loved Tracks - + Hyped Tracks - + Top Artists - + Hyped Artists + + Tomahawk::ItunesParser + + + Error fetching iTunes information from the network! + + + Tomahawk::JSPFLoader @@ -2195,50 +2355,122 @@ Please change the filters or try again. - - + + &Listen Along + + Tomahawk::Query + + + and + + + + + You + + + + + you + + + + + and + + + + + %n other(s) + + %n other + %n others + + + + and %1%n other(s)%2 + + and %1%n other%2 + and %1%n others%2 + + + + + %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 - + Fetching - + Parsing - + Saving (%1%) + + Tomahawk::SpotifyParser + + + Error fetching Spotify information from the network! + + + TomahawkApp - + My Collection @@ -2246,12 +2478,12 @@ Please change the filters or try again. TomahawkOAuthTwitter - + Twitter PIN - + After authenticating on Twitter's web site, enter the displayed PIN number here: @@ -2261,27 +2493,27 @@ enter the displayed PIN number here: TomahawkTrayIcon - + Hide Tomahawk Window - + Show Tomahawk Window - + Currently not playing. - + Play - + Pause @@ -2425,7 +2657,7 @@ enter the displayed PIN number here: - + Play @@ -2445,134 +2677,128 @@ enter the displayed PIN number here: - + 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. - - - Playback Error + + 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. 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. - - - - + Create New Station - + Name: - + New Station - + New Playlist - + Pause - + Go &offline - + Go &online - + Authentication Error - + %1 by %2 track, artist name - + %1 - %2 current track, some window title - + About Tomahawk - - <h2><b>Tomahawk %1<br/>(%2)</h2>Copyright 2010, 2011<br/>Christian Muehlhaeuser &lt;muesli@tomahawk-player.org&gt;<br/><br/>Thanks to: Leo Franchi, Jeff Mitchell, Dominik Schmidt, Jason Herskowitz, Alejandro Wainzinger, Hugo Lindstr&ouml;m, Michael Zanetti, Harald Sitter and Steve Robertson + + <h2><b>Tomahawk %1<br/>(%2)</h2>Copyright 2010 - 2012<br/>Christian Muehlhaeuser &lt;muesli@tomahawk-player.org&gt;<br/><br/>Thanks to: Leo Franchi, Jeff Mitchell, Dominik Schmidt, Jason Herskowitz, Alejandro Wainzinger, Hugo Lindstr&ouml;m, Michael Zanetti, Harald Sitter and Steve Robertson @@ -2650,65 +2876,70 @@ enter the displayed PIN number here: TrackModel - + Artist - + Title - + Album - + Track - + Duration - + Bitrate - + Age - + Year - + Size - + Origin - + Score + + + Composer + + TrackView - + Sorry, your filter '%1' did not match any results. @@ -2729,7 +2960,7 @@ enter the displayed PIN number here: TreeItemDelegate - + Unknown @@ -2737,54 +2968,59 @@ enter the displayed PIN number here: TreeModel - + Name - + Duration - + Bitrate - + Age - + Year - + Size - + Origin - + + Composer + + + + All Artists - - + + My Collection - - + + Collection of %1 @@ -2792,34 +3028,32 @@ enter the displayed PIN number here: 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. @@ -2829,158 +3063,50 @@ You can re-send a sync message at any time simply by sending another tweet using - + 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 - - - - - Tweet! - - - - - - - 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 - - - - - Send Message! - - - - - 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! - - - - - TwitterPlugin - - - Twitter - - ViewManager - - All available tracks + + SuperCollection - + + Combined libraries of all your online friends + + + + All available albums @@ -3003,7 +3129,7 @@ You may wish to try re-authenticating. - + No recently created playlists in your network. @@ -3016,7 +3142,7 @@ You may wish to try re-authenticating. WhatsHotWidget - + Charts @@ -3070,7 +3196,22 @@ Lyrics for "%1" by %2: 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 @@ -3078,101 +3219,247 @@ Lyrics for "%1" by %2: 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: + + + + + XmppSipPlugin + + + User Interaction + + + + + Host is unknown + + + + + Item not found + + + + + Authorization Error + + + + + Remote Stream Error + + + + + Remote Connection failed + + + + + Internal Server Error + + + + + System shutdown + + + + + Conflict + + + + + Unknown + + + + + 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 + + + + + Do you want to grant <b>%1</b> access to your Collection? + + + ZeroconfConfig - + Form - + Local Network configuration - + This plugin will automatically find other users running Tomahawk on your local network - + Connect automatically when Tomahawk starts diff --git a/src/libtomahawk/query.cpp b/src/libtomahawk/query.cpp index dd47eec9a..60f5a1ea6 100644 --- a/src/libtomahawk/query.cpp +++ b/src/libtomahawk/query.cpp @@ -637,7 +637,7 @@ Query::socialActionDescription( const QString& action, DescriptionMode mode ) co if ( loveCounter > 0 ) { if ( loveCounter > 3 ) - desc += " " + tr( "and %1%2 others%3" ).arg( "" ).arg( loveCounter - 3 ).arg( "" ); + desc += " " + tr( "and" ) + " " + tr( "%n other(s)", "", loveCounter - 3 ) + ""; if ( mode == Short ) desc = "" + tr( "%1 people" ).arg( loveCounter ) + ""; From ebbedb2b991f1f02b862b91af14ad6eaa9574c70 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Sat, 17 Mar 2012 12:10:09 +0100 Subject: [PATCH 23/29] * Prevent race condition. --- .../database/databasecommand_resolve.cpp | 6 ++++-- src/libtomahawk/result.cpp | 15 ++++++++------- src/libtomahawk/result.h | 2 +- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/libtomahawk/database/databasecommand_resolve.cpp b/src/libtomahawk/database/databasecommand_resolve.cpp index 354208105..9d0e4199c 100644 --- a/src/libtomahawk/database/databasecommand_resolve.cpp +++ b/src/libtomahawk/database/databasecommand_resolve.cpp @@ -143,8 +143,9 @@ DatabaseCommand_Resolve::resolve( DatabaseImpl* lib ) url = QString( "servent://%1\t%2" ).arg( s->userName() ).arg( url ); } + bool cached = Tomahawk::Result::isCached( url ); Tomahawk::result_ptr result = Tomahawk::Result::get( url ); - if ( result->isValid() ) + if ( cached ) { qDebug() << "Result already cached:" << result->toString(); res << result; @@ -281,8 +282,9 @@ DatabaseCommand_Resolve::fullTextResolve( DatabaseImpl* lib ) url = QString( "servent://%1\t%2" ).arg( s->userName() ).arg( url ); } + bool cached = Tomahawk::Result::isCached( url ); Tomahawk::result_ptr result = Tomahawk::Result::get( url ); - if ( result->isValid() ) + if ( cached ) { qDebug() << "Result already cached:" << result->toString(); res << result; diff --git a/src/libtomahawk/result.cpp b/src/libtomahawk/result.cpp index 8b3a66d61..8f2f267a5 100644 --- a/src/libtomahawk/result.cpp +++ b/src/libtomahawk/result.cpp @@ -50,6 +50,14 @@ Result::get( const QString& url ) } +bool +Result::isCached( const QString& url ) +{ + QMutexLocker lock( &s_mutex ); + return ( s_results.contains( url ) ); +} + + Result::Result( const QString& url ) : QObject() , m_url( url ) @@ -86,13 +94,6 @@ Result::deleteLater() } -bool -Result::isValid() const -{ - return !m_rid.isEmpty(); -} - - artist_ptr Result::artist() const { diff --git a/src/libtomahawk/result.h b/src/libtomahawk/result.h index 6dd4c76c4..c2b566269 100644 --- a/src/libtomahawk/result.h +++ b/src/libtomahawk/result.h @@ -56,9 +56,9 @@ friend class ::DatabaseCommand_LoadFile; public: static Tomahawk::result_ptr get( const QString& url ); + static bool isCached( const QString& url ); virtual ~Result(); - bool isValid() const; QVariant toVariant() const; QString toString() const; Tomahawk::query_ptr toQuery(); From a2bfd73d555ac1a8e8b6107bba4cee89a0ca701f Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Sat, 17 Mar 2012 17:09:57 +0100 Subject: [PATCH 24/29] * Fixed crash situation in AudioControls. --- src/audiocontrols.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/audiocontrols.cpp b/src/audiocontrols.cpp index c81895aa3..070686cdd 100644 --- a/src/audiocontrols.cpp +++ b/src/audiocontrols.cpp @@ -277,7 +277,7 @@ void AudioControls::onSocialActionsLoaded() { Query* query = qobject_cast< Query* >( sender() ); - if ( !query || query != m_currentTrack->toQuery().data() ) + if ( !query || !m_currentTrack || query != m_currentTrack->toQuery().data() ) return; setSocialActions(); From 2e3132732a381059071fe2faacb242c61bd0d8f8 Mon Sep 17 00:00:00 2001 From: Jason Herskowitz Date: Sun, 18 Mar 2012 09:40:16 -0400 Subject: [PATCH 25/29] Add grayscale icon to be used for OS X systray --- data/icons/tomahawk-icon-128x128-grayscale.png | Bin 0 -> 69076 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 data/icons/tomahawk-icon-128x128-grayscale.png diff --git a/data/icons/tomahawk-icon-128x128-grayscale.png b/data/icons/tomahawk-icon-128x128-grayscale.png new file mode 100644 index 0000000000000000000000000000000000000000..550781596b809f729dc32b47c6aa05611d60ba71 GIT binary patch literal 69076 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�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 PM4ukVcVE(V_!a*TdI*lF literal 0 HcmV?d00001 From 8d59a335025790efa055b32398d262d32b89c87d Mon Sep 17 00:00:00 2001 From: Jason Herskowitz Date: Sun, 18 Mar 2012 09:54:25 -0400 Subject: [PATCH 26/29] Make systray icon actually use the grayscale version --- resources.qrc | 1 + src/tomahawktrayicon.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/resources.qrc b/resources.qrc index ad8118fc5..d9085f22b 100644 --- a/resources.qrc +++ b/resources.qrc @@ -137,5 +137,6 @@ data/images/lastfm-icon.png data/sql/dbmigrate-27_to_28.sql data/images/process-stop.png + data/icons/tomahawk-icon-128x128-grayscale.png diff --git a/src/tomahawktrayicon.cpp b/src/tomahawktrayicon.cpp index b8d927ec2..2ef75067c 100644 --- a/src/tomahawktrayicon.cpp +++ b/src/tomahawktrayicon.cpp @@ -35,7 +35,7 @@ TomahawkTrayIcon::TomahawkTrayIcon( QObject* parent ) , m_currentAnimationFrame( 0 ) , m_showWindowAction( 0 ) { - QIcon icon( RESPATH "icons/tomahawk-icon-128x128.png" ); + QIcon icon( RESPATH "icons/tomahawk-icon-128x128-grayscale.png" ); setIcon( icon ); refreshToolTip(); From ba82c142efe60a885298ea0ba5ea9a8c920e2193 Mon Sep 17 00:00:00 2001 From: Jason Herskowitz Date: Sun, 18 Mar 2012 10:26:13 -0400 Subject: [PATCH 27/29] Copy edit Url to URL --- src/LoadXSPFDialog.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/LoadXSPFDialog.ui b/src/LoadXSPFDialog.ui index 90350a425..7057d87fe 100644 --- a/src/LoadXSPFDialog.ui +++ b/src/LoadXSPFDialog.ui @@ -19,7 +19,7 @@ - Playlist Url + Playlist URL From 195953f4f8452f51a48abece856e44e44f26888a Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Sun, 18 Mar 2012 13:25:37 -0400 Subject: [PATCH 28/29] Update spotify description --- src/accounts/spotify/SpotifyAccount.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/accounts/spotify/SpotifyAccount.h b/src/accounts/spotify/SpotifyAccount.h index 0bbb5f9b5..f83021177 100644 --- a/src/accounts/spotify/SpotifyAccount.h +++ b/src/accounts/spotify/SpotifyAccount.h @@ -41,7 +41,7 @@ public: SpotifyAccountFactory() {} virtual Account* createAccount( const QString& accountId = QString() ); - virtual QString description() const { return tr( "Play music from and sync your playlists with Spotify" ); } + virtual QString description() const { return tr( "Play music from and sync your playlists with Spotify Premium" ); } virtual QString factoryId() const { return "spotifyaccount"; } virtual QString prettyName() const { return "Spotify"; } From 42b277924085ecd884d8bd6d4109ef9ea4a0f4d0 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Sun, 18 Mar 2012 13:26:33 -0400 Subject: [PATCH 29/29] Fix atticaid sync issue that would lose value --- src/libtomahawk/accounts/AccountModel.cpp | 1 + src/libtomahawk/accounts/AccountModelNode.h | 21 ++++++++++++++++---- src/libtomahawk/accounts/ResolverAccount.cpp | 3 +++ 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/libtomahawk/accounts/AccountModel.cpp b/src/libtomahawk/accounts/AccountModel.cpp index 53b04d961..450ecf506 100644 --- a/src/libtomahawk/accounts/AccountModel.cpp +++ b/src/libtomahawk/accounts/AccountModel.cpp @@ -30,6 +30,7 @@ using namespace Tomahawk; using namespace Accounts; #define ACCOUNTMODEL_DEBUG 0 + AccountModel::AccountModel( QObject* parent ) : QAbstractListModel( parent ) { diff --git a/src/libtomahawk/accounts/AccountModelNode.h b/src/libtomahawk/accounts/AccountModelNode.h index 28a3a5625..857d57402 100644 --- a/src/libtomahawk/accounts/AccountModelNode.h +++ b/src/libtomahawk/accounts/AccountModelNode.h @@ -26,6 +26,8 @@ #include +#define ACCOUNTMODELNODE_DEBUG 0 + namespace Tomahawk { namespace Accounts { @@ -87,7 +89,9 @@ struct AccountModelNode { { if ( AccountManager::instance()->factoryForAccount( acct ) == fac ) { -// qDebug() << "Found account for factory:" << acct->accountFriendlyName(); +#if ACCOUNTMODELNODE_DEBUG + qDebug() << "Found account for factory:" << acct->accountFriendlyName(); +#endif accounts.append( acct ); } } @@ -98,15 +102,24 @@ struct AccountModelNode { init(); atticaContent = cnt; -// qDebug() << "Creating attica model node for resolver:" << cnt.id(); - +#if ACCOUNTMODELNODE_DEBUG + qDebug() << "Creating attica model node for resolver:" << cnt.id(); +#endif foreach ( Account* acct, AccountManager::instance()->accounts( Accounts::ResolverType ) ) { +#if ACCOUNTMODELNODE_DEBUG + qDebug() << "Checking account:" << acct->accountFriendlyName() << qobject_cast< AtticaResolverAccount* >( acct ); +#endif if ( AtticaResolverAccount* resolver = qobject_cast< AtticaResolverAccount* >( acct ) ) { +#if ACCOUNTMODELNODE_DEBUG + qDebug() << "With attica id:" << resolver->atticaId(); +#endif if ( resolver->atticaId() == atticaContent.id() ) { -// qDebug() << "found atticaaccount :" << resolver->accountFriendlyName(); +#if ACCOUNTMODELNODE_DEBUG + qDebug() << "found atticaaccount :" << resolver->accountFriendlyName(); +#endif atticaAccount = resolver; break; } diff --git a/src/libtomahawk/accounts/ResolverAccount.cpp b/src/libtomahawk/accounts/ResolverAccount.cpp index 801477fd2..885530bc7 100644 --- a/src/libtomahawk/accounts/ResolverAccount.cpp +++ b/src/libtomahawk/accounts/ResolverAccount.cpp @@ -102,6 +102,8 @@ ResolverAccount::ResolverAccount( const QString& accountId, const QString& path setAccountFriendlyName( m_resolver.data()->name() ); setTypes( AccountType( ResolverType ) ); + + sync(); } @@ -225,6 +227,7 @@ AtticaResolverAccount::AtticaResolverAccount( const QString& accountId, const QS TomahawkSettings::instance()->setValue( QString( "accounts/%1/atticaresolver" ).arg( accountId ), true ); loadIcon(); + sync(); }