1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-08-13 09:34:53 +02:00

Merge remote-tracking branch 'origin/master' into accounts

Conflicts:
	src/libtomahawk/tomahawksettings.cpp
	src/tomahawkapp.cpp
This commit is contained in:
Leo Franchi
2012-02-24 10:59:47 -06:00
46 changed files with 389 additions and 170 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -100,8 +100,6 @@ AudioControls::AudioControls( QWidget* parent )
m_sliderTimeLine.setCurveShape( QTimeLine::LinearCurve );
ui->seekSlider->setTimeLine( &m_sliderTimeLine );
m_defaultCover = QPixmap( RESPATH "images/no-album-no-case.png" ).scaled( ui->coverImage->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation );
connect( &m_phononTickCheckTimer, SIGNAL( timeout() ), SLOT( phononTickCheckTimeout() ) );
connect( &m_sliderTimeLine, SIGNAL( frameChanged( int ) ), ui->seekSlider, SLOT( setValue( int ) ) );
@@ -264,14 +262,14 @@ AudioControls::onAlbumCoverUpdated()
void
AudioControls::setAlbumCover()
{
if ( !m_currentTrack->album()->cover().isNull() )
if ( !m_currentTrack->album()->cover( ui->coverImage->size() ).isNull() )
{
QPixmap cover;
cover.loadFromData( m_currentTrack->album()->cover() );
ui->coverImage->setPixmap( cover.scaled( ui->coverImage->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation ) );
cover = m_currentTrack->album()->cover( ui->coverImage->size() );
ui->coverImage->setPixmap( cover );
}
else
ui->coverImage->setPixmap( m_defaultCover );
ui->coverImage->setPixmap( TomahawkUtils::defaultPixmap( TomahawkUtils::DefaultAlbumCover, TomahawkUtils::ScaledCover, ui->coverImage->size() ) );
}
@@ -279,10 +277,16 @@ void
AudioControls::onSocialActionsLoaded()
{
Query* query = qobject_cast< Query* >( sender() );
if ( !query || query != m_currentTrack->toQuery().data() )
if ( !query )
return;
setSocialActions();
query_ptr currentQuery = m_currentTrack->toQuery();
if ( query->artist() == currentQuery->artist() &&
query->track() == currentQuery->track() &&
query->album() == currentQuery->album() )
{
setSocialActions();
}
}

View File

@@ -91,8 +91,6 @@ private:
Ui::AudioControls *ui;
QPixmap m_defaultCover;
Tomahawk::result_ptr m_currentTrack;
Tomahawk::PlaylistInterface::RepeatMode m_repeatMode;
bool m_shuffled;

View File

@@ -32,6 +32,7 @@ using namespace Tomahawk;
Album::~Album()
{
delete m_cover;
}
@@ -71,6 +72,7 @@ Album::Album( unsigned int id, const QString& name, const Tomahawk::artist_ptr&
, m_id( id )
, m_name( name )
, m_artist( artist )
, m_cover( 0 )
, m_infoLoaded( false )
{
connect( Tomahawk::InfoSystem::InfoSystem::instance(),
@@ -97,11 +99,14 @@ Album::artist() const
}
QByteArray
Album::cover() const
#ifndef ENABLE_HEADLESS
QPixmap
Album::cover( const QSize& size, bool forceLoad ) const
{
if ( !m_infoLoaded )
{
if ( !forceLoad )
return QPixmap();
m_uuid = uuid();
Tomahawk::InfoSystem::InfoStringHash trackInfo;
@@ -117,8 +122,31 @@ Album::cover() const
Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( requestData );
}
return m_cover;
if ( !m_cover && !m_coverBuffer.isEmpty() )
{
m_cover = new QPixmap();
m_cover->loadFromData( m_coverBuffer );
}
if ( m_cover && !m_cover->isNull() && !size.isEmpty() )
{
if ( m_coverCache.contains( size.width() ) )
{
return m_coverCache.value( size.width() );
}
QPixmap scaledCover;
scaledCover = m_cover->scaled( size, Qt::KeepAspectRatio, Qt::SmoothTransformation );
m_coverCache.insert( size.width(), scaledCover );
return scaledCover;
}
if ( m_cover )
return *m_cover;
else
return QPixmap();
}
#endif
void
@@ -137,7 +165,7 @@ Album::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVaria
const QByteArray ba = returnedData["imgbytes"].toByteArray();
if ( ba.length() )
{
m_cover = ba;
m_coverBuffer = ba;
}
}

View File

@@ -19,8 +19,13 @@
#ifndef TOMAHAWKALBUM_H
#define TOMAHAWKALBUM_H
#include "config.h"
#include <QtCore/QObject>
#include <QtCore/QSharedPointer>
#ifndef ENABLE_HEADLESS
#include <QtGui/QPixmap>
#endif
#include "typedefs.h"
#include "playlistinterface.h"
@@ -44,7 +49,9 @@ public:
unsigned int id() const { return m_id; }
QString name() const { return m_name; }
artist_ptr artist() const;
QByteArray cover() const;
#ifndef ENABLE_HEADLESS
QPixmap cover( const QSize& size, bool forceLoad = true ) const;
#endif
bool infoLoaded() const { return m_infoLoaded; }
Tomahawk::playlistinterface_ptr playlistInterface();
@@ -64,10 +71,13 @@ private:
unsigned int m_id;
QString m_name;
artist_ptr m_artist;
QByteArray m_cover;
QByteArray m_coverBuffer;
mutable QPixmap* m_cover;
bool m_infoLoaded;
mutable QString m_uuid;
mutable QHash< int, QPixmap > m_coverCache;
Tomahawk::playlistinterface_ptr m_playlistInterface;
};

View File

@@ -31,6 +31,7 @@ using namespace Tomahawk;
Artist::~Artist()
{
delete m_cover;
}
@@ -69,6 +70,7 @@ Artist::Artist( unsigned int id, const QString& name )
: QObject()
, m_id( id )
, m_name( name )
, m_cover( 0 )
, m_infoLoaded( false )
{
m_sortname = DatabaseImpl::sortname( name, true );
@@ -89,11 +91,14 @@ Artist::onTracksAdded( const QList<Tomahawk::query_ptr>& tracks )
}
QByteArray
Artist::cover() const
#ifndef ENABLE_HEADLESS
QPixmap
Artist::cover( const QSize& size, bool forceLoad ) const
{
if ( !m_infoLoaded )
{
if ( !forceLoad )
return QPixmap();
m_uuid = uuid();
Tomahawk::InfoSystem::InfoStringHash trackInfo;
@@ -108,8 +113,31 @@ Artist::cover() const
Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( requestData );
}
return m_cover;
if ( !m_cover && !m_coverBuffer.isEmpty() )
{
m_cover = new QPixmap();
m_cover->loadFromData( m_coverBuffer );
}
if ( m_cover && !m_cover->isNull() && !size.isEmpty() )
{
if ( m_coverCache.contains( size.width() ) )
{
return m_coverCache.value( size.width() );
}
QPixmap scaledCover;
scaledCover = m_cover->scaled( size, Qt::KeepAspectRatio, Qt::SmoothTransformation );
m_coverCache.insert( size.width(), scaledCover );
return scaledCover;
}
if ( m_cover )
return *m_cover;
else
return QPixmap();
}
#endif
void
@@ -128,7 +156,7 @@ Artist::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVari
const QByteArray ba = returnedData["imgbytes"].toByteArray();
if ( ba.length() )
{
m_cover = ba;
m_coverBuffer = ba;
}
}

View File

@@ -19,8 +19,13 @@
#ifndef TOMAHAWKARTIST_H
#define TOMAHAWKARTIST_H
#include "config.h"
#include <QtCore/QObject>
#include <QtCore/QSharedPointer>
#ifndef ENABLE_HEADLESS
#include <QtGui/QPixmap>
#endif
#include "typedefs.h"
#include "dllmacro.h"
@@ -43,7 +48,9 @@ public:
unsigned int id() const { return m_id; }
QString name() const { return m_name; }
QString sortname() const { return m_sortname; }
QByteArray cover() const;
#ifndef ENABLE_HEADLESS
QPixmap cover( const QSize& size, bool forceLoad = true ) const;
#endif
bool infoLoaded() const { return m_infoLoaded; }
Tomahawk::playlistinterface_ptr playlistInterface();
@@ -63,10 +70,13 @@ private:
unsigned int m_id;
QString m_name;
QString m_sortname;
QByteArray m_cover;
QByteArray m_coverBuffer;
mutable QPixmap* m_cover;
bool m_infoLoaded;
mutable QString m_uuid;
mutable QHash< int, QPixmap > m_coverCache;
Tomahawk::playlistinterface_ptr m_playlistInterface;
};

View File

@@ -18,6 +18,8 @@
#include "audioengine.h"
#include "config.h"
#include <QtCore/QUrl>
#include <QtNetwork/QNetworkReply>
@@ -328,13 +330,15 @@ AudioEngine::sendWaitingNotificationSlot() const
void
AudioEngine::sendNowPlayingNotification()
{
#ifndef ENABLE_HEADLESS
if ( m_currentTrack->album().isNull() || m_currentTrack->album()->infoLoaded() )
onNowPlayingInfoReady();
else
{
connect( m_currentTrack->album().data(), SIGNAL( updated() ), SLOT( onNowPlayingInfoReady() ), Qt::UniqueConnection );
m_currentTrack->album()->cover();
m_currentTrack->album()->cover( QSize( 0, 0 ) );
}
#endif
}
@@ -357,9 +361,11 @@ AudioEngine::onNowPlayingInfoReady()
if ( !m_currentTrack->album().isNull() )
{
#ifndef ENABLE_HEADLESS
QImage cover;
cover.loadFromData( m_currentTrack->album()->cover() );
cover = m_currentTrack->album()->cover( QSize( 0, 0 ) ).toImage();
playInfo["image"] = QVariant( cover );
#endif
}
Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo(

View File

@@ -88,6 +88,7 @@ ContextMenu::setQueries( const QList<Tomahawk::query_ptr>& queries )
m_sigmap->setMapping( m_loveAction, ActionLove );
connect( queries.first().data(), SIGNAL( socialActionsLoaded() ), SLOT( onSocialActionsLoaded() ) );
m_queries.first()->loadSocialActions();
onSocialActionsLoaded();
}

View File

@@ -169,7 +169,6 @@ DatabaseCommand_AllAlbums::execForCollection( DatabaseImpl* dbi )
void
DatabaseCommand_AllAlbums::exec( DatabaseImpl* dbi )
{
return;
if ( !m_artist.isNull() )
{
execForArtist( dbi );

View File

@@ -20,6 +20,7 @@
#include "artist.h"
#include "album.h"
#include "pipeline.h"
#include "sourcelist.h"
#include "utils/logger.h"
@@ -30,10 +31,14 @@ DatabaseCommand_Resolve::DatabaseCommand_Resolve( const query_ptr& query )
: DatabaseCommand()
, m_query( query )
{
Q_ASSERT( Pipeline::instance()->isRunning() );
}
DatabaseCommand_Resolve::~DatabaseCommand_Resolve()
{}
{
}
void
DatabaseCommand_Resolve::exec( DatabaseImpl* lib )

View File

@@ -43,7 +43,6 @@ SpotifyPlugin::SpotifyPlugin()
: InfoPlugin()
, m_chartsFetchJobs( 0 )
{
m_supportedGetTypes << InfoChart << InfoChartCapabilities;
}
@@ -71,7 +70,6 @@ SpotifyPlugin::getInfo( Tomahawk::InfoSystem::InfoRequestData requestData )
InfoStringHash hash = requestData.input.value< Tomahawk::InfoSystem::InfoStringHash >();
switch ( requestData.type )
{
case InfoChart:
@@ -87,6 +85,7 @@ SpotifyPlugin::getInfo( Tomahawk::InfoSystem::InfoRequestData requestData )
case InfoChartCapabilities:
fetchChartCapabilities( requestData );
break;
default:
dataError( requestData );
}
@@ -110,7 +109,6 @@ SpotifyPlugin::fetchChart( Tomahawk::InfoSystem::InfoRequestData requestData )
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "Hash did not contain required params!";
dataError( requestData );
return;
}
/// Set the criterias for current chart
criteria["chart_id"] = hash["chart_id"];
@@ -118,6 +116,8 @@ SpotifyPlugin::fetchChart( Tomahawk::InfoSystem::InfoRequestData requestData )
emit getCachedInfo( criteria, 86400000 /* Expire chart cache in 1 day */, requestData );
}
void
SpotifyPlugin::fetchChartCapabilities( Tomahawk::InfoSystem::InfoRequestData requestData )
{
@@ -132,12 +132,12 @@ SpotifyPlugin::fetchChartCapabilities( Tomahawk::InfoSystem::InfoRequestData req
emit getCachedInfo( criteria, 604800000, requestData );
}
void
SpotifyPlugin::notInCacheSlot( Tomahawk::InfoSystem::InfoStringHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData )
{
switch ( requestData.type )
{
case InfoChart:
{
/// Fetch the chart, we need source and id
@@ -149,8 +149,6 @@ SpotifyPlugin::notInCacheSlot( Tomahawk::InfoSystem::InfoStringHash criteria, To
reply->setProperty( "requestData", QVariant::fromValue< Tomahawk::InfoSystem::InfoRequestData >( requestData ) );
connect( reply, SIGNAL( finished() ), SLOT( chartReturned() ) );
return;
}
case InfoChartCapabilities:
{
@@ -212,9 +210,8 @@ SpotifyPlugin::chartTypes()
}
QVariantMap charts;
foreach(QVariant geos, chartObj.value("Charts").toList().takeLast().toMap().value("geo").toList() )
foreach( QVariant geos, chartObj.value( "Charts" ).toList().takeLast().toMap().value( "geo" ).toList() )
{
const QString geo = geos.toMap().value( "name" ).toString();
const QString geoId = geos.toMap().value( "id" ).toString();
QString country;
@@ -225,7 +222,6 @@ SpotifyPlugin::chartTypes()
country = geo;
else
{
QLocale l( QString( "en_%1" ).arg( geo ) );
country = Tomahawk::CountryUtils::fullCountryFromCode( geo );
@@ -240,7 +236,7 @@ SpotifyPlugin::chartTypes()
}
QList< InfoStringHash > chart_types;
foreach(QVariant types, chartObj.value("Charts").toList().takeFirst().toMap().value("types").toList() )
foreach( QVariant types, chartObj.value( "Charts" ).toList().takeFirst().toMap().value( "types" ).toList() )
{
QString type = types.toMap().value( "id" ).toString();
QString label = types.toMap().value( "name" ).toString();
@@ -251,18 +247,15 @@ SpotifyPlugin::chartTypes()
c[ "type" ] = type;
chart_types.append( c );
}
charts.insert( country.toUtf8(), QVariant::fromValue<QList< InfoStringHash > >( chart_types ) );
}
QVariantMap defaultMap;
defaultMap[ "spotify" ] = QStringList() << "United States" << "Top Albums";
m_allChartsMap[ "defaults" ] = defaultMap;
m_allChartsMap.insert( "Spotify", QVariant::fromValue<QVariantMap>( charts ) );
}
else
{
@@ -281,13 +274,12 @@ SpotifyPlugin::chartTypes()
}
m_cachedRequests.clear();
}
}
void
SpotifyPlugin::chartReturned()
{
/// Chart request returned something! Woho
QNetworkReply* reply = qobject_cast<QNetworkReply*>( sender() );
QString url = reply->url().toString();
@@ -318,14 +310,13 @@ SpotifyPlugin::chartReturned()
else
setChartType( None );
foreach(QVariant result, res.value("toplist").toMap().value("result").toList() )
foreach( QVariant result, res.value( "toplist" ).toMap().value( "result" ).toList() )
{
QString title, artist;
QVariantMap chartMap = result.toMap();
if ( !chartMap.isEmpty() )
{
title = chartMap.value( "title" ).toString();
artist = chartMap.value( "artist" ).toString();
@@ -341,7 +332,6 @@ SpotifyPlugin::chartReturned()
if( chartType() == Album )
{
InfoStringHash pair;
pair["artist"] = artist;
pair["album"] = title;
@@ -351,10 +341,8 @@ SpotifyPlugin::chartReturned()
if( chartType() == Artist )
{
top_artists << chartMap.value( "name" ).toString();
qDebug() << "SpotifyChart type is artist";
}
}
}
@@ -393,5 +381,4 @@ SpotifyPlugin::chartReturned()
}
else
qDebug() << "Network error in fetching chart:" << reply->url().toString();
}

View File

@@ -61,6 +61,7 @@ Pipeline::Pipeline( QObject* parent )
Pipeline::~Pipeline()
{
tDebug() << Q_FUNC_INFO;
m_running = false;
// stop script resolvers
@@ -418,10 +419,11 @@ Pipeline::shunt( const query_ptr& q )
r->resolve( q );
emit resolving( q );
m_qidsTimeout.insert( q->id(), true );
if ( r->timeout() > 0 )
{
m_qidsTimeout.insert( q->id(), true );
new FuncTimeout( r->timeout(), boost::bind( &Pipeline::timeoutShunt, this, q ), this );
}
}
else
{

View File

@@ -48,6 +48,8 @@ public:
explicit Pipeline( QObject* parent = 0 );
virtual ~Pipeline();
bool isRunning() const { return m_running; }
unsigned int pendingQueryCount() const { return m_queries_pending.count(); }
unsigned int activeQueryCount() const { return m_qidsState.count(); }

View File

@@ -40,7 +40,6 @@ AlbumItemDelegate::AlbumItemDelegate( QAbstractItemView* parent, AlbumProxyModel
, m_view( parent )
, m_model( proxy )
{
m_defaultCover = QPixmap( RESPATH "images/no-album-art-placeholder.png" );
}
@@ -89,21 +88,19 @@ AlbumItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option,
painter->drawLine( shadowRect.bottomLeft() + QPoint( 0, 4 ), shadowRect.bottomRight() + QPoint( 0, 4 ) );
}
QRect r = option.rect.adjusted( 6, 5, -6, -41 );
QPixmap cover;
if ( !item->album().isNull() )
{
cover.loadFromData( item->album()->cover() );
cover = item->album()->cover( r.size() );
if ( cover.isNull() )
cover = TomahawkUtils::defaultPixmap( TomahawkUtils::DefaultAlbumCover, TomahawkUtils::CoverInCase, r.size() );
}
else if ( !item->artist().isNull() )
{
cover.loadFromData( item->artist()->cover() );
cover = item->artist()->cover( r.size() );
}
if ( cover.isNull() )
cover = m_defaultCover;
QRect r = option.rect.adjusted( 6, 5, -6, -41 );
if ( option.state & QStyle::State_Selected )
{
#if defined(Q_WS_MAC) || defined(Q_WS_WIN)
@@ -123,17 +120,7 @@ AlbumItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option,
#endif
}
QPixmap scover;
if ( m_cache.contains( cover.cacheKey() ) )
{
scover = m_cache.value( cover.cacheKey() );
}
else
{
scover = cover.scaled( r.size(), Qt::KeepAspectRatio, Qt::SmoothTransformation );
m_cache.insert( cover.cacheKey(), scover );
}
painter->drawPixmap( r, scover );
painter->drawPixmap( r, cover );
painter->setPen( opt.palette.color( QPalette::Text ) );
QTextOption to;

View File

@@ -49,12 +49,10 @@ private:
QAbstractItemView* m_view;
AlbumProxyModel* m_model;
mutable QHash< qint64, QPixmap > m_cache;
mutable QHash< QPersistentModelIndex, QRect > m_artistNameRects;
QPersistentModelIndex m_hoveringOver;
QPixmap m_shadowPixmap;
QPixmap m_defaultCover;
};
#endif // ALBUMITEMDELEGATE_H

View File

@@ -80,6 +80,11 @@ ArtistView::ArtistView( QWidget* parent )
setFont( f );
#endif
m_timer.setInterval( SCROLL_TIMEOUT );
connect( verticalScrollBar(), SIGNAL( rangeChanged( int, int ) ), SLOT( onViewChanged() ) );
connect( verticalScrollBar(), SIGNAL( valueChanged( int ) ), SLOT( onViewChanged() ) );
connect( &m_timer, SIGNAL( timeout() ), SLOT( onScrollTimeout() ) );
connect( this, SIGNAL( doubleClicked( QModelIndex ) ), SLOT( onItemActivated( QModelIndex ) ) );
connect( this, SIGNAL( customContextMenuRequested( const QPoint& ) ), SLOT( onCustomContextMenu( const QPoint& ) ) );
connect( m_contextMenu, SIGNAL( triggered( int ) ), SLOT( onMenuTriggered( int ) ) );
@@ -129,6 +134,7 @@ ArtistView::setTreeModel( TreeModel* model )
connect( m_model, SIGNAL( itemCountChanged( unsigned int ) ), SLOT( onItemCountChanged( unsigned int ) ) );
connect( m_proxyModel, SIGNAL( filterChanged( QString ) ), SLOT( onFilterChanged( QString ) ) );
connect( m_proxyModel, SIGNAL( rowsInserted( QModelIndex, int, int ) ), SLOT( onViewChanged() ) );
guid(); // this will set the guid on the header
@@ -145,6 +151,43 @@ ArtistView::setTreeModel( TreeModel* model )
}
void
ArtistView::onViewChanged()
{
if ( m_timer.isActive() )
m_timer.stop();
m_timer.start();
}
void
ArtistView::onScrollTimeout()
{
if ( m_timer.isActive() )
m_timer.stop();
QModelIndex left = indexAt( viewport()->rect().topLeft() );
while ( left.isValid() && left.parent().isValid() )
left = left.parent();
QModelIndex right = indexAt( viewport()->rect().bottomLeft() );
while ( right.isValid() && right.parent().isValid() )
right = right.parent();
int max = m_proxyModel->playlistInterface()->trackCount();
if ( right.isValid() )
max = right.row() + 1;
if ( !max )
return;
for ( int i = left.row(); i < max; i++ )
{
m_model->getCover( m_proxyModel->mapToSource( m_proxyModel->index( i, 0 ) ) );
}
}
void
ArtistView::currentChanged( const QModelIndex& current, const QModelIndex& previous )
{

View File

@@ -95,6 +95,8 @@ private slots:
void onItemCountChanged( unsigned int items );
void onFilterChanged( const QString& filter );
void onFilteringStarted();
void onViewChanged();
void onScrollTimeout();
void onCustomContextMenu( const QPoint& pos );
void onMenuTriggered( int action );
@@ -113,6 +115,7 @@ private:
Tomahawk::ContextMenu* m_contextMenu;
bool m_showModes;
QTimer m_timer;
mutable QString m_guid;
};

View File

@@ -42,7 +42,7 @@ CustomPlaylistView::CustomPlaylistView( CustomPlaylistView::PlaylistType type, c
if ( m_type == SourceLovedTracks )
connect( m_source.data(), SIGNAL( socialAttributesChanged( QString ) ), this, SLOT( socialAttributesChanged( QString ) ) );
else if ( m_type == AllLovedTracks )
else if ( m_type == TopLovedTracks )
{
connect( SourceList::instance()->getLocal().data(), SIGNAL( socialAttributesChanged( QString ) ), this, SLOT( socialAttributesChanged( QString ) ) );
foreach ( const source_ptr& s, SourceList::instance()->sources( true ) )
@@ -86,12 +86,12 @@ CustomPlaylistView::generateTracks()
"GROUP BY track.id "
"ORDER BY counter DESC, social_attributes.timestamp DESC " ).arg( m_source->isLocal() ? "IS NULL" : QString( "= %1" ).arg( m_source->id() ) );
break;
case AllLovedTracks:
case TopLovedTracks:
sql = QString( "SELECT track.name, artist.name, source, COUNT(*) as counter "
"FROM social_attributes, track, artist "
"WHERE social_attributes.id = track.id AND artist.id = track.artist AND social_attributes.k = 'Love' AND social_attributes.v = 'true'"
"WHERE social_attributes.id = track.id AND artist.id = track.artist AND social_attributes.k = 'Love' AND social_attributes.v = 'true' "
"GROUP BY track.id "
"ORDER BY counter DESC, social_attributes.timestamp DESC " );
"ORDER BY counter DESC, social_attributes.timestamp DESC LIMIT 0, 50" );
break;
}

View File

@@ -33,7 +33,7 @@ class DLLEXPORT CustomPlaylistView : public PlaylistView
public:
enum PlaylistType {
SourceLovedTracks,
AllLovedTracks
TopLovedTracks
};
explicit CustomPlaylistView( PlaylistType type, const source_ptr& s, QWidget* parent = 0 );

View File

@@ -155,32 +155,18 @@ TreeItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option,
QPixmap cover;
if ( !item->album().isNull() )
{
cover.loadFromData( item->album()->cover() );
cover = item->album()->cover( r.size(), false );
if ( cover.isNull() )
cover = TomahawkUtils::defaultPixmap( TomahawkUtils::DefaultAlbumCover, TomahawkUtils::ScaledCover, r.size() );
}
else if ( !item->artist().isNull() )
{
cover.loadFromData( item->artist()->cover() );
cover = item->artist()->cover( r.size(), false );
if ( cover.isNull() )
cover = TomahawkUtils::defaultPixmap( TomahawkUtils::DefaultArtistImage, TomahawkUtils::ScaledCover, r.size() );
}
QPixmap scover;
if ( cover.isNull() )
{
if ( !item->artist().isNull() )
cover = m_defaultArtistImage;
else
cover = m_defaultAlbumCover;
}
if ( m_cache.contains( cover.cacheKey() ) )
{
scover = m_cache.value( cover.cacheKey() );
}
else
{
scover = cover.scaled( r.size(), Qt::KeepAspectRatio, Qt::SmoothTransformation );
m_cache.insert( cover.cacheKey(), scover );
}
painter->drawPixmap( r, scover );
painter->drawPixmap( r, cover );
QTextOption to;
to.setAlignment( Qt::AlignVCenter );

View File

@@ -43,8 +43,6 @@ private:
ArtistView* m_view;
TreeProxyModel* m_model;
mutable QHash< qint64, QPixmap > m_cache;
QPixmap m_nowPlayingIcon;
QPixmap m_defaultAlbumCover;
QPixmap m_defaultArtistImage;

View File

@@ -87,6 +87,18 @@ TreeModel::collection() const
}
void
TreeModel::getCover( const QModelIndex& index )
{
TreeModelItem* item = itemFromIndex( index );
if ( !item->artist().isNull() && !item->artist()->infoLoaded() )
item->artist()->cover( QSize( 0, 0 ) );
else if ( !item->album().isNull() && !item->album()->infoLoaded() )
item->album()->cover( QSize( 0, 0 ) );
}
void
TreeModel::setCurrentItem( const QModelIndex& index )
{
@@ -783,6 +795,8 @@ TreeModel::onAlbumsAdded( const QList<Tomahawk::album_ptr>& albums, const QModel
albumitem = new TreeModelItem( album, parentItem );
albumitem->index = createIndex( parentItem->children.count() - 1, 0, albumitem );
connect( albumitem, SIGNAL( dataChanged() ), SLOT( onDataChanged() ) );
getCover( albumitem->index );
}
emit endInsertRows();

View File

@@ -98,6 +98,8 @@ public:
void addAlbums( const Tomahawk::artist_ptr& artist, const QModelIndex& parent, bool autoRefetch = false );
void addTracks( const Tomahawk::album_ptr& album, const QModelIndex& parent, bool autoRefetch = false );
void getCover( const QModelIndex& index );
ColumnStyle columnStyle() const { return m_columnStyle; }
void setColumnStyle( ColumnStyle style );

View File

@@ -489,7 +489,7 @@ Query::loadSocialActions()
query_ptr q = m_ownRef.toStrongRef();
DatabaseCommand_LoadSocialActions* cmd = new DatabaseCommand_LoadSocialActions( q );
connect( cmd, SIGNAL( finished() ), SLOT( onSocialActionsLoaded() ));
connect( cmd, SIGNAL( finished() ), SLOT( onSocialActionsLoaded() ) );
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>(cmd) );
}

View File

@@ -46,19 +46,24 @@ TomahawkSettings::TomahawkSettings( QObject* parent )
{
s_instance = this;
if( !contains( "configversion") )
#ifdef Q_OS_LINUX
QFile file( fileName() );
file.setPermissions( file.permissions() & ~(QFile::ReadGroup | QFile::WriteGroup | QFile::ExeGroup | QFile::ReadOther | QFile::WriteOther | QFile::ExeOther ) );
#endif
if ( !contains( "configversion" ) )
{
setValue( "configversion", TOMAHAWK_SETTINGS_VERSION );
doInitialSetup();
}
else if( value( "configversion" ).toUInt() != TOMAHAWK_SETTINGS_VERSION )
else if ( value( "configversion" ).toUInt() != TOMAHAWK_SETTINGS_VERSION )
{
qDebug() << "Config version outdated, old:" << value( "configversion" ).toUInt()
<< "new:" << TOMAHAWK_SETTINGS_VERSION
<< "Doing upgrade, if any...";
int current = value( "configversion" ).toUInt();
while( current < TOMAHAWK_SETTINGS_VERSION )
while ( current < TOMAHAWK_SETTINGS_VERSION )
{
doUpgrade( current, current + 1 );
@@ -67,7 +72,6 @@ TomahawkSettings::TomahawkSettings( QObject* parent )
// insert upgrade code here as required
setValue( "configversion", TOMAHAWK_SETTINGS_VERSION );
}
}
@@ -100,22 +104,23 @@ TomahawkSettings::doUpgrade( int oldVersion, int newVersion )
{
Q_UNUSED( newVersion );
if( oldVersion == 1 )
if ( oldVersion == 1 )
{
qDebug() << "Migrating config from verson 1 to 2: script resolver config name";
if( contains( "script/resolvers" ) ) {
setValue( "script/loadedresolvers", value( "script/resolvers" ) );
remove( "script/resolvers" );
}
} else if( oldVersion == 2 )
}
else if ( oldVersion == 2 )
{
qDebug() << "Migrating config from version 2 to 3: Converting jabber and twitter accounts to new SIP Factory approach";
// migrate old accounts to new system. only jabber and twitter, and max one each. create a new plugin for each if needed
// not pretty as we hardcode a plugin id and assume that we know how the config layout is, but hey, this is migration after all
if( contains( "jabber/username" ) && contains( "jabber/password" ) )
if ( contains( "jabber/username" ) && contains( "jabber/password" ) )
{
QString sipName = "sipjabber";
if( value( "jabber/username" ).toString().contains( "@gmail" ) )
if ( value( "jabber/username" ).toString().contains( "@gmail" ) )
sipName = "sipgoogle";
setValue( QString( "%1_legacy/username" ).arg( sipName ), value( "jabber/username" ) );
@@ -132,7 +137,7 @@ TomahawkSettings::doUpgrade( int oldVersion, int newVersion )
remove( "jabber/server" );
remove( "jabber/port" );
}
if( contains( "twitter/ScreenName" ) && contains( "twitter/OAuthToken" ) )
if ( contains( "twitter/ScreenName" ) && contains( "twitter/OAuthToken" ) )
{
setValue( "siptwitter_legacy/ScreenName", value( "twitter/ScreenName" ) );
setValue( "siptwitter_legacy/OAuthToken", value( "twitter/OAuthToken" ) );
@@ -153,7 +158,8 @@ TomahawkSettings::doUpgrade( int oldVersion, int newVersion )
}
// create a zeroconf plugin too
addSipPlugin( "sipzeroconf_legacy" );
} else if ( oldVersion == 3 )
}
else if ( oldVersion == 3 )
{
if ( contains( "script/atticaresolverstates" ) )
{
@@ -192,7 +198,8 @@ TomahawkSettings::doUpgrade( int oldVersion, int newVersion )
tDebug() << "UPGRADING AND DELETING:" << resolverDir.absolutePath();
TomahawkUtils::removeDirectory( resolverDir.absolutePath() );
}
} else if ( oldVersion == 4 )
}
else if ( oldVersion == 4 )
{
// 0.3.0 contained a bug which prevent indexing local files. Force a reindex.
QTimer::singleShot( 0, this, SLOT( updateIndex() ) );
@@ -1021,6 +1028,7 @@ TomahawkSettings::setNowPlayingEnabled( bool enable )
setValue( "adium/enablenowplaying", enable );
}
TomahawkSettings::PrivateListeningMode
TomahawkSettings::privateListeningMode() const
{

View File

@@ -42,6 +42,18 @@ namespace TomahawkUtils
MediaTypeTrack
};
enum ImageType
{
DefaultAlbumCover,
DefaultArtistImage
};
enum ImageMode
{
NoDefaultCover,
CoverInCase,
ScaledCover
};
class DLLEXPORT NetworkProxyFactory : public QNetworkProxyFactory
{
public:

View File

@@ -36,6 +36,8 @@
#include <windowsx.h>
#endif
#include "logger.h"
namespace TomahawkUtils
{
static int s_headerHeight = 0;
@@ -83,15 +85,15 @@ createDragPixmap( MediaType type, int itemCount )
QPixmap pixmap;
switch ( type )
{
case MediaTypeArtist:
pixmap = QPixmap( ":/data/images/artist-icon.png" ).scaledToWidth( size, Qt::SmoothTransformation );
break;
case MediaTypeAlbum:
pixmap = QPixmap( ":/data/images/album-icon.png" ).scaledToWidth( size, Qt::SmoothTransformation );
break;
case MediaTypeTrack:
pixmap = QPixmap( QString( ":/data/images/track-icon-%2x%2.png" ).arg( size ) );
break;
case MediaTypeArtist:
pixmap = QPixmap( ":/data/images/artist-icon.png" ).scaledToWidth( size, Qt::SmoothTransformation );
break;
case MediaTypeAlbum:
pixmap = QPixmap( ":/data/images/album-icon.png" ).scaledToWidth( size, Qt::SmoothTransformation );
break;
case MediaTypeTrack:
pixmap = QPixmap( QString( ":/data/images/track-icon-%2x%2.png" ).arg( size ) );
break;
}
int x = 0;
@@ -303,4 +305,59 @@ alphaBlend( const QColor& colorFrom, const QColor& colorTo, float opacity )
return QColor( r, g, b );
}
QPixmap
defaultPixmap( ImageType type, ImageMode mode, const QSize& size )
{
QPixmap pixmap;
QHash< int, QPixmap > subsubcache;
QHash< int, QHash< int, QPixmap > > subcache;
static QHash< int, QHash< int, QHash< int, QPixmap > > > cache;
if ( cache.contains( type ) )
{
subcache = cache.value( type );
if ( subcache.contains( mode ) )
{
subsubcache = subcache.value( mode );
if ( subsubcache.contains( size.width() ) )
return subsubcache.value( size.width() );
}
}
switch ( type )
{
case DefaultAlbumCover:
if ( mode == CoverInCase )
pixmap = QPixmap( RESPATH "images/no-album-art-placeholder.png" );
else
pixmap = QPixmap( RESPATH "images/no-album-no-case.png" );
break;
case DefaultArtistImage:
pixmap = QPixmap( RESPATH "images/no-artist-image-placeholder.png" );
break;
default:
break;
}
if ( pixmap.isNull() )
{
Q_ASSERT( false );
return QPixmap();
}
if ( !size.isNull() )
pixmap = pixmap.scaled( size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation );
subsubcache.insert( size.width(), pixmap );
subcache.insert( mode, subsubcache );
cache.insert( type, subcache );
return pixmap;
}
} // ns

View File

@@ -19,6 +19,8 @@
#ifndef TOMAHAWKUTILSGUI_H
#define TOMAHAWKUTILSGUI_H
#include <QSize>
#include "tomahawkutils.h"
#include "dllmacro.h"
@@ -46,6 +48,8 @@ namespace TomahawkUtils
DLLEXPORT int headerHeight();
DLLEXPORT void setHeaderHeight( int height );
DLLEXPORT QPixmap defaultPixmap( ImageType type, ImageMode mode, const QSize& size = QSize( 0, 0 ) );
}
#endif // TOMAHAWKUTILSGUI_H

View File

@@ -432,7 +432,7 @@ Tomahawk::ViewPage*
ViewManager::showTopLovedPage()
{
if ( !m_topLovedWidget )
m_topLovedWidget = new CustomPlaylistView( CustomPlaylistView::AllLovedTracks, source_ptr(), m_widget );
m_topLovedWidget = new CustomPlaylistView( CustomPlaylistView::TopLovedTracks, source_ptr(), m_widget );
return show( m_topLovedWidget );
}

View File

@@ -133,6 +133,7 @@ signals:
void hideQueueRequested();
void tomahawkLoaded();
public slots:
Tomahawk::ViewPage* showSuperCollection();
Tomahawk::ViewPage* showWelcomePage();

View File

@@ -61,7 +61,7 @@ AlbumInfoWidget::AlbumInfoWidget( const Tomahawk::album_ptr& album, ModelMode st
ui->tracksView->setTreeModel( m_tracksModel );
ui->tracksView->setRootIsDecorated( false );
m_pixmap = QPixmap( RESPATH "images/no-album-art-placeholder.png" ).scaledToWidth( 48, Qt::SmoothTransformation );
m_pixmap = TomahawkUtils::defaultPixmap( TomahawkUtils::DefaultAlbumCover, TomahawkUtils::ScaledCover, QSize( 48, 48 ) );
m_button = new OverlayButton( ui->tracksView );
m_button->setCheckable( true );
@@ -243,10 +243,10 @@ AlbumInfoWidget::loadAlbums( bool autoRefetch )
void
AlbumInfoWidget::onAlbumCoverUpdated()
{
if ( m_album->cover().isNull() )
if ( m_album->cover( QSize( 0, 0 ) ).isNull() )
return;
m_pixmap.loadFromData( m_album->cover() );
m_pixmap = m_album->cover( QSize( 0, 0 ) );
emit pixmapChanged( m_pixmap );
}

View File

@@ -77,7 +77,7 @@ ArtistInfoWidget::ArtistInfoWidget( const Tomahawk::artist_ptr& artist, QWidget*
ui->topHits->setTrackModel( m_topHitsModel );
ui->topHits->setSortingEnabled( false );
m_pixmap = QPixmap( RESPATH "images/no-album-no-case.png" ).scaledToWidth( 48, Qt::SmoothTransformation );
m_pixmap = TomahawkUtils::defaultPixmap( TomahawkUtils::DefaultArtistImage, TomahawkUtils::ScaledCover, QSize( 48, 48 ) );
m_button = new OverlayButton( ui->albums );
m_button->setText( tr( "Click to show Super Collection Albums" ) );
@@ -289,10 +289,10 @@ ArtistInfoWidget::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestD
void
ArtistInfoWidget::onArtistImageUpdated()
{
if ( m_artist->cover().isNull() )
if ( m_artist->cover( QSize( 0, 0 ) ).isNull() )
return;
m_pixmap.loadFromData( m_artist->cover() );
m_pixmap = m_artist->cover( QSize( 0, 0 ) );
emit pixmapChanged( m_pixmap );
}

View File

@@ -28,9 +28,8 @@ using namespace Tomahawk;
GroupItem::GroupItem( SourcesModel* model, SourceTreeItem* parent, const QString& text, int peerSortValue )
: SourceTreeItem( model, parent, SourcesModel::Group )
: SourceTreeItem( model, parent, SourcesModel::Group, peerSortValue )
, m_text( text )
, m_peerSortValue( peerSortValue )
{
// expand by default
QTimer::singleShot( 0, this, SLOT( requestExpanding() ) );

View File

@@ -36,7 +36,6 @@ public:
virtual QString text() const;
virtual bool willAcceptDrag( const QMimeData* data ) const { Q_UNUSED( data ); return false; }
virtual QIcon icon() const { return QIcon(); }
virtual int peerSortValue() const { return m_peerSortValue; }
virtual bool isBeingPlayed() const { return false; }
public slots:
@@ -50,7 +49,6 @@ private slots:
private:
QString m_text;
int m_peerSortValue;
};
#endif

View File

@@ -486,7 +486,7 @@ ViewPage*
SourceItem::lovedTracksClicked()
{
if ( !m_lovedTracksPage )
m_lovedTracksPage = new CustomPlaylistView( m_source.isNull() ? CustomPlaylistView::AllLovedTracks : CustomPlaylistView::SourceLovedTracks, m_source, ViewManager::instance()->widget() );
m_lovedTracksPage = new CustomPlaylistView( m_source.isNull() ? CustomPlaylistView::TopLovedTracks : CustomPlaylistView::SourceLovedTracks, m_source, ViewManager::instance()->widget() );
ViewManager::instance()->show( m_lovedTracksPage );
return m_lovedTracksPage;

View File

@@ -23,11 +23,12 @@
using namespace Tomahawk;
SourceTreeItem::SourceTreeItem( SourcesModel* model, SourceTreeItem* parent, SourcesModel::RowType thisType, int index )
SourceTreeItem::SourceTreeItem( SourcesModel* model, SourceTreeItem* parent, SourcesModel::RowType thisType, int peerSortValue, int index )
: QObject()
, m_type( thisType )
, m_parent( parent )
, m_model( model )
, m_peerSortValue( peerSortValue )
{
connect( this, SIGNAL( beginChildRowsAdded( int, int ) ), m_model, SLOT( onItemRowsAddedBegin( int, int ) ) );
connect( this, SIGNAL( beginChildRowsRemoved( int, int ) ), m_model, SLOT( onItemRowsRemovedBegin( int, int ) ) );

View File

@@ -43,7 +43,7 @@ public:
Q_DECLARE_FLAGS( DropTypes, DropType )
SourceTreeItem() : m_type( SourcesModel::Invalid ), m_parent( 0 ), m_model( 0 ) {}
SourceTreeItem( SourcesModel* model, SourceTreeItem* parent, SourcesModel::RowType thisType, int index = -1 ); // if index is -1, append at end of parent's child list
SourceTreeItem( SourcesModel* model, SourceTreeItem* parent, SourcesModel::RowType thisType, int peerSortValue = 0, int index = -1 ); // if index is -1, append at end of parent's child list
virtual ~SourceTreeItem();
// generic info used by the tree model
@@ -63,7 +63,7 @@ public:
virtual bool willAcceptDrag( const QMimeData* ) const { return false; }
virtual bool dropMimeData( const QMimeData*, Qt::DropAction ) { return false; }
virtual bool setData( const QVariant&, bool ) { return false; }
virtual int peerSortValue() const { return 0; } // How to sort relative to peers in the tree.
virtual int peerSortValue() const { return m_peerSortValue; } // How to sort relative to peers in the tree.
virtual int IDValue() const { return 0; }
virtual DropTypes supportedDropTypes( const QMimeData* mimeData ) const { Q_UNUSED( mimeData ); return DropTypesNone; }
virtual void setDropType( DropType type ) { m_dropType = type; }
@@ -101,6 +101,7 @@ private:
SourceTreeItem* m_parent;
QList< SourceTreeItem* > m_children;
SourcesModel* m_model;
int m_peerSortValue;
DropType m_dropType;
};

View File

@@ -82,7 +82,7 @@ SourceDelegate::~SourceDelegate()
QSize
SourceDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const
{
SourceTreeItem *item = index.data( SourcesModel::SourceTreeItemRole ).value< SourceTreeItem* >();
SourceTreeItem* item = index.data( SourcesModel::SourceTreeItemRole ).value< SourceTreeItem* >();
SourcesModel::RowType type = static_cast< SourcesModel::RowType >( index.data( SourcesModel::SourceTreeItemTypeRole ).toInt() );
if ( type == SourcesModel::Collection )
@@ -93,6 +93,10 @@ SourceDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex&
{
return QSize( option.rect.width(), 6 );
}
else if ( type == SourcesModel::Group && index.row() > 0 )
{
return QSize( option.rect.width(), 24 );
}
else if ( m_expandedMap.contains( index ) )
{
if ( !m_expandedMap.value( index )->initialized() )
@@ -128,7 +132,7 @@ SourceDelegate::paintDecorations( QPainter* painter, const QStyleOptionViewItem&
if ( playable && playing && item->isBeingPlayed() )
{
const int iconW = option.rect.height() - 4;
QRect iconRect = QRect( option.rect.x() - iconW - 4, option.rect.y() + 2, iconW, iconW );
QRect iconRect = QRect( 4, option.rect.y() + 2, iconW, iconW );
QPixmap speaker = option.state & QStyle::State_Selected ? m_nowPlayingSpeaker : m_nowPlayingSpeakerDark;
speaker = speaker.scaledToHeight( iconW, Qt::SmoothTransformation );
painter->drawPixmap( iconRect, speaker );
@@ -238,9 +242,11 @@ SourceDelegate::paintCollection( QPainter* painter, const QStyleOptionViewItem&
}
}
text = painter->fontMetrics().elidedText( desc, Qt::ElideRight, textRect.width() );
textRect.adjust( 0, 0, 0, 2 );
text = painter->fontMetrics().elidedText( desc, Qt::ElideRight, textRect.width() - 4 );
QTextOption to( Qt::AlignVCenter );
painter->drawText( textRect.adjusted( 0, 0, 0, 2 ), text, to );
to.setWrapMode( QTextOption::NoWrap );
painter->drawText( textRect, text, to );
if ( status )
{
@@ -305,7 +311,7 @@ SourceDelegate::paintGroup( QPainter* painter, const QStyleOptionViewItem& optio
font.setBold( true );
painter->setFont( font );
QTextOption to( Qt::AlignVCenter );
QTextOption to( Qt::AlignBottom );
painter->setPen( option.palette.color( QPalette::Base ) );
painter->setBrush( option.palette.color( QPalette::Base ) );
@@ -325,7 +331,7 @@ SourceDelegate::paintGroup( QPainter* painter, const QStyleOptionViewItem& optio
font.setPixelSize( font.pixelSize() - 1 );
painter->setFont( font );
QTextOption to( Qt::AlignVCenter | Qt::AlignRight );
QTextOption to( Qt::AlignBottom | Qt::AlignRight );
// draw close icon
painter->setPen( Qt::white );
@@ -400,8 +406,6 @@ SourceDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, co
if ( type != SourcesModel::Group && type != SourcesModel::Category && type != SourcesModel::Divider )
QApplication::style()->drawControl( QStyle::CE_ItemViewItem, &o3, painter );
paintDecorations( painter, o3, index );
if ( type == SourcesModel::Collection )
{
paintCollection( painter, o, index );
@@ -532,6 +536,8 @@ SourceDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, co
}
}
paintDecorations( painter, o3, index );
painter->restore();
}

View File

@@ -39,6 +39,7 @@
#include "globalactionmanager.h"
#include "dropjob.h"
#include "items/playlistitems.h"
#include "playlist/artistview.h"
#include "playlist/playlistview.h"
#include "playlist/dynamic/widgets/DynamicWidget.h"
@@ -53,8 +54,6 @@ SourcesModel::SourcesModel( QObject* parent )
m_rootItem = new SourceTreeItem( this, 0, Invalid );
appendGroups();
appendItem( source_ptr() );
onSourcesAdded( SourceList::instance()->sources() );
connect( SourceList::instance(), SIGNAL( sourceAdded( Tomahawk::source_ptr ) ), SLOT( onSourceAdded( Tomahawk::source_ptr ) ) );
@@ -265,28 +264,34 @@ SourcesModel::appendGroups()
{
beginInsertRows( QModelIndex(), rowCount(), rowCount() + 2 );
new SourceTreeItem( this, m_rootItem, SourcesModel::Divider, 0 );
new HistoryItem( this, m_rootItem, tr( "History" ), 5 );
GroupItem* browse = new GroupItem( this, m_rootItem, tr( "Browse" ), 10 );
GroupItem* browse = new GroupItem( this, m_rootItem, tr( "Browse" ), 0 );
new HistoryItem( this, m_rootItem, tr( "Search History" ), 1 );
// new SourceTreeItem( this, m_rootItem, SourcesModel::Divider, 2 );
m_myMusicGroup = new GroupItem( this, m_rootItem, tr( "My Music" ), 3 );
// super collection
GenericPageItem* sc = new GenericPageItem( this, browse, tr( "SuperCollection" ), QIcon( RESPATH "images/supercollection.png" ),
boost::bind( &ViewManager::showSuperCollection, ViewManager::instance() ),
boost::bind( &ViewManager::superCollectionView, ViewManager::instance() ) );
sc->setSortValue( 1 );
// browse section
GenericPageItem* loved = new GenericPageItem( this, browse, tr( "Top Loved Tracks" ), QIcon( RESPATH "images/loved_playlist.png" ),
boost::bind( &ViewManager::showTopLovedPage, ViewManager::instance() ),
boost::bind( &ViewManager::topLovedWidget, ViewManager::instance() ) );
loved->setSortValue( -250 );
loved->setSortValue( 2 );
// add misc children of root node
GenericPageItem* recent = new GenericPageItem( this, browse, tr( "Dashboard" ), QIcon( RESPATH "images/dashboard.png" ),
boost::bind( &ViewManager::showWelcomePage, ViewManager::instance() ),
boost::bind( &ViewManager::welcomeWidget, ViewManager::instance() ) );
recent->setSortValue( -300 );
recent->setSortValue( 0 );
GenericPageItem* hot = new GenericPageItem( this, browse, tr( "Charts" ), QIcon( RESPATH "images/charts.png" ),
boost::bind( &ViewManager::showWhatsHotPage, ViewManager::instance() ),
boost::bind( &ViewManager::whatsHotWidget, ViewManager::instance() ) );
hot->setSortValue( -300 );
hot->setSortValue( 3 );
m_collectionsGroup = new GroupItem( this, m_rootItem, tr( "Friends" ), 15 );
m_collectionsGroup = new GroupItem( this, m_rootItem, tr( "Friends" ), 4 );
endInsertRows();
}
@@ -298,7 +303,7 @@ SourcesModel::appendItem( const Tomahawk::source_ptr& source )
SourceTreeItem* parent;
if ( !source.isNull() && source->isLocal() )
{
parent = m_rootItem;
parent = m_myMusicGroup;
}
else
{

View File

@@ -139,6 +139,7 @@ private:
SourceTreeItem* m_rootItem;
GroupItem* m_collectionsGroup;
GroupItem* m_myMusicGroup;
QList< Tomahawk::source_ptr > m_sourcesWithViewPage;
QHash< Tomahawk::source_ptr, SourceTreeItem* > m_sourcesWithViewPageItems;

View File

@@ -66,7 +66,7 @@ SourcesProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex& sourcePar
if ( item && item->type() != SourcesModel::Divider && item->parent()->parent() == 0 && !item->children().count() )
return false;
if ( !m_filtered )
return true;

View File

@@ -256,14 +256,14 @@ SourceTreeView::selectRequest( const QPersistentModelIndex& idx )
void
SourceTreeView::expandRequest( const QPersistentModelIndex &idx )
SourceTreeView::expandRequest( const QPersistentModelIndex& idx )
{
expand( idx );
}
void
SourceTreeView::toggleExpandRequest( const QPersistentModelIndex &idx )
SourceTreeView::toggleExpandRequest( const QPersistentModelIndex& idx )
{
if ( isExpanded( idx ) )
collapse( idx );

View File

@@ -61,7 +61,6 @@
#include "utils/logger.h"
#include "utils/tomahawkutilsgui.h"
#include <lastfm/ws.h>
#include "config.h"
#ifndef ENABLE_HEADLESS
@@ -170,7 +169,7 @@ TomahawkApp::init()
m_scanManager = QWeakPointer<ScanManager>( new ScanManager( this ) );
// init pipeline and resolver factories
new Pipeline( this );
new Pipeline();
#ifndef ENABLE_HEADLESS
Pipeline::instance()->addExternalResolverFactory( boost::bind( &QtScriptResolver::factory, _1 ) );
@@ -300,6 +299,8 @@ TomahawkApp::~TomahawkApp()
{
tLog() << "Shutting down Tomahawk...";
Pipeline::instance()->stop();
if ( !m_servent.isNull() )
delete m_servent.data();
if ( !m_scanManager.isNull() )
@@ -311,22 +312,18 @@ TomahawkApp::~TomahawkApp()
if ( !m_infoSystem.isNull() )
delete m_infoSystem.data();
//FIXME: delete GeneratorFactory::registerFactory( "echonest", new EchonestFactory ); ?
delete Tomahawk::Accounts::AccountManager::instance();
Pipeline::instance()->stop();
#ifndef ENABLE_HEADLESS
delete m_mainwindow;
delete AtticaManager::instance();
#endif
delete Pipeline::instance();
if ( !m_database.isNull() )
delete m_database.data();
delete Pipeline::instance();
tLog() << "Finished shutdown.";
}
@@ -352,6 +349,13 @@ TomahawkApp::printHelp()
echo( " --testdb Use a test database instead of real collection\n" );
echo( " --noupnp Disable UPnP\n" );
echo( " --nosip Disable SIP\n" );
echo( "\nPlayback Controls:\n" );
echo( " --playpause Toggle playing/paused state\n" );
echo( " --play Start/resume playback\n" );
echo( " --pause Pause playback\n" );
echo( " --stop Stop playback\n" );
echo( " --next Advances to the next track (if available)\n" );
echo( " --prev Returns to the previous track (if available)\n" );
echo( "\nurl is a tomahawk:// command or alternatively a url that Tomahawk can recognize.\n" );
echo( "For more documentation, see http://wiki.tomahawk-player.org/mediawiki/index.php/Tomahawk://_Links\n" );
}
@@ -465,7 +469,6 @@ TomahawkApp::initHTTP()
tLog() << "Starting HTTPd on" << m_session.listenInterface().toString() << m_session.port();
m_session.start();
}
@@ -512,6 +515,7 @@ TomahawkApp::initServent()
}
}
// Called after Servent emits ready()
void
TomahawkApp::initSIP()
@@ -540,10 +544,7 @@ TomahawkApp::spotifyApiCheckFinished()
QNetworkReply* reply = qobject_cast< QNetworkReply* >( sender() );
Q_ASSERT( reply );
if ( reply->error() )
DropJob::setCanParseSpotifyPlaylists( false );
else
DropJob::setCanParseSpotifyPlaylists( true );
DropJob::setCanParseSpotifyPlaylists( !reply->error() );
#endif
}
@@ -603,5 +604,19 @@ TomahawkApp::instanceStarted( KDSingleApplicationGuard::Instance instance )
return;
QString arg1 = instance.arguments[ 1 ];
loadUrl( arg1 );
if ( loadUrl( arg1 ) )
return;
if ( instance.arguments.contains( "--next" ) )
AudioEngine::instance()->next();
else if ( instance.arguments.contains( "--prev" ) )
AudioEngine::instance()->previous();
else if ( instance.arguments.contains( "--playpause" ) )
AudioEngine::instance()->playPause();
else if ( instance.arguments.contains( "--play" ) )
AudioEngine::instance()->play();
else if ( instance.arguments.contains( "--pause" ) )
AudioEngine::instance()->pause();
else if ( instance.arguments.contains( "--stop" ) )
AudioEngine::instance()->stop();
}