1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-01-17 22:38:33 +01:00

* Added Album class with convenience methods.

* Cleaned up PlaylistInterface. Now basic classes (like the new Album or Artist class) can easily be accessed by the AudioEngine as a proper playlist.
* Added SourceInfoWidget, a summary page for sources.
* Added AlbumView / -Model / -Item.
* WIP: PlaylistManager.
* Many other cleanups / improvements I don't even remember anymore ;-)
This commit is contained in:
Christian Muehlhaeuser 2010-11-21 10:05:11 +01:00
parent ab2d21a692
commit 3f2cce0f69
63 changed files with 1854 additions and 275 deletions

2
README
View File

@ -42,7 +42,7 @@ libEchonest 0.1
$ sudo make install
Now compile Tomahawk
-------------------
--------------------
$ sudo ldconfig -v | grep -Ei 'qjson|gloox|echonest'
$ mkdir build && cd build
$ cmake ..

BIN
data/images/source-info.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -4,30 +4,61 @@
#include <QObject>
#include <QSharedPointer>
#include "artist.h"
#include "tomahawk/typedefs.h"
#include "tomahawk/artist.h"
#include "tomahawk/collection.h"
#include "tomahawk/playlistinterface.h"
namespace Tomahawk
{
class Album;
typedef QSharedPointer<Album> album_ptr;
class Album : public QObject
class Album : public QObject, public PlaylistInterface
{
Q_OBJECT
public:
Album( artist_ptr artist, const QString& name )
: m_name( name )
, m_artist( artist )
{}
static album_ptr get( unsigned int id, const QString& name, const Tomahawk::artist_ptr& artist, const Tomahawk::collection_ptr& collection );
const QString& name() const { return m_name; }
const artist_ptr artist() const { return m_artist; }
Album( unsigned int id, const QString& name, const Tomahawk::artist_ptr& artist, const Tomahawk::collection_ptr& collection );
unsigned int id() const { return m_id; }
QString name() const { return m_name; }
artist_ptr artist() const { return m_artist; }
Tomahawk::collection_ptr collection() const { return m_collection; }
QList<Tomahawk::query_ptr> tracks();
virtual int trackCount() const { return m_queries.count(); }
virtual Tomahawk::result_ptr previousItem() { return siblingItem( -1 ); }
virtual Tomahawk::result_ptr nextItem() { return siblingItem( 1 ); }
virtual Tomahawk::result_ptr siblingItem( int itemsAway );
virtual PlaylistInterface::RepeatMode repeatMode() const { return PlaylistInterface::NoRepeat; }
virtual bool shuffled() const { return false; }
virtual void setRepeatMode( PlaylistInterface::RepeatMode ) {}
virtual void setShuffled( bool ) {}
signals:
void repeatModeChanged( PlaylistInterface::RepeatMode mode );
void shuffleModeChanged( bool enabled );
void tracksAdded( const QList<Tomahawk::query_ptr>& tracks, const Tomahawk::collection_ptr& );
void trackCountChanged( unsigned int tracks );
private slots:
void onTracksAdded( const QList<Tomahawk::query_ptr>& tracks, const Tomahawk::collection_ptr& collection );
private:
unsigned int m_id;
QString m_name;
artist_ptr m_artist;
QList<Tomahawk::query_ptr> m_queries;
Tomahawk::collection_ptr m_collection;
unsigned int m_currentTrack;
};
}; // ns

View File

@ -7,9 +7,6 @@
namespace Tomahawk
{
class Artist;
typedef QSharedPointer<Artist> artist_ptr;
class Artist : public QObject
{
Q_OBJECT
@ -19,7 +16,7 @@ public:
: m_name( name )
{};
const QString& name() const { return m_name; }
QString name() const { return m_name; }
private:
QString m_name;

View File

@ -21,11 +21,6 @@
namespace Tomahawk
{
/*
Call load(), then wait for the finishedLoading() signal,
then call tracks() to get all tracks.
*/
class Collection : public QObject
{
Q_OBJECT
@ -62,7 +57,7 @@ public slots:
virtual void removeTracks( const QList<QVariant> &olditems ) = 0;
void setPlaylists( const QList<Tomahawk::playlist_ptr>& plists );
void setTracks( const QList<QVariant>& tracks, Tomahawk::collection_ptr collection );
void setTracks( const QList<Tomahawk::query_ptr>& tracks, Tomahawk::collection_ptr collection );
protected:
QString m_name;

View File

@ -49,7 +49,7 @@ public:
void setLastmodified( unsigned int i ) { m_lastmodified = i; }
source_ptr lastsource() const { return m_lastsource; }
void setLastsource( source_ptr s ) { m_lastsource = s ; }
void setLastsource( source_ptr s ) { m_lastsource = s; }
private:
QString m_guid;

View File

@ -3,43 +3,25 @@
#include <QModelIndex>
#include "plitem.h"
#include "tomahawk/collection.h"
#include "tomahawk/source.h"
#include "tomahawk/typedefs.h"
class PlaylistInterface
{
public:
enum RepeatMode { NoRepeat, RepeatOne, RepeatAll };
PlaylistInterface()
{
m_rootItem = 0;
}
PlaylistInterface() {}
virtual ~PlaylistInterface() {}
virtual void setCurrentItem( const QModelIndex& ) = 0;
virtual int trackCount() const = 0;
virtual PlItem* previousItem() = 0;
virtual PlItem* nextItem() = 0;
virtual PlItem* siblingItem( int itemsAway ) = 0;
virtual Tomahawk::result_ptr previousItem() = 0;
virtual Tomahawk::result_ptr nextItem() = 0;
virtual Tomahawk::result_ptr siblingItem( int itemsAway ) = 0;
virtual PlaylistInterface::RepeatMode repeatMode() const = 0;
virtual bool shuffled() const = 0;
PlItem* itemFromIndex( const QModelIndex& index ) const
{
if ( index.isValid() )
return static_cast<PlItem*>( index.internalPointer() );
else
{
return m_rootItem;
}
}
public slots:
virtual void setRepeatMode( RepeatMode mode ) = 0;
virtual void setShuffled( bool enabled ) = 0;
@ -48,10 +30,6 @@ signals:
virtual void repeatModeChanged( PlaylistInterface::RepeatMode mode ) = 0;
virtual void shuffleModeChanged( bool enabled ) = 0;
virtual void trackCountChanged( unsigned int tracks ) = 0;
public:
PlItem* m_rootItem;
bool m_flat;
};
#endif // PLAYLISTINTERFACE_H

View File

@ -3,8 +3,10 @@
#include <QObject>
#include "collection.h"
#include "tomahawk/typedefs.h"
#include "collection.h"
#include "artist.h"
#include "album.h"
namespace Tomahawk
{
@ -21,11 +23,11 @@ public:
RID id() const;
collection_ptr collection() const { return m_collection; }
QString artist() const { return m_artist; }
QString album() const { return m_album; }
QString track() const { return m_track; }
QString url() const { return m_url; }
QString mimetype() const { return m_mimetype; }
Tomahawk::artist_ptr artist() const { return m_artist; }
Tomahawk::album_ptr album() const { return m_album; }
QString track() const { return m_track; }
QString url() const { return m_url; }
QString mimetype() const { return m_mimetype; }
unsigned int duration() const { return m_duration; }
unsigned int bitrate() const { return m_bitrate; }
@ -33,11 +35,10 @@ public:
unsigned int albumpos() const { return m_albumpos; }
unsigned int modificationTime() const { return m_modtime; }
unsigned int dbid() const { return m_id; }
// for debug output:
QString toString() const
{
return QString( "Result(%1 %2\t%3 - %4 %5" ).arg( id() ).arg( score() ).arg( artist() ).arg( track() ).arg( url() );
}
QString toString() const;
signals:
// emitted when the collection this result comes from is going offline:
@ -48,8 +49,8 @@ private:
mutable RID m_rid;
collection_ptr m_collection;
QString m_artist;
QString m_album;
Tomahawk::artist_ptr m_artist;
Tomahawk::album_ptr m_album;
QString m_track;
QString m_url;
QString m_mimetype;
@ -59,6 +60,8 @@ private:
unsigned int m_size;
unsigned int m_albumpos;
unsigned int m_modtime;
unsigned int m_id;
};
}; //ns

View File

@ -4,20 +4,18 @@
#include <QObject>
#include <QSharedPointer>
#include "artist.h"
#include "tomahawk/artist.h"
#include "tomahawk/typedefs.h"
namespace Tomahawk
{
class Track;
typedef QSharedPointer<Track> track_ptr;
class Track : public QObject
{
Q_OBJECT
public:
Track( artist_ptr artist, const QString& name )
Track( Tomahawk::artist_ptr artist, const QString& name )
: m_name( name )
, m_artist( artist )
{}

View File

@ -6,6 +6,8 @@
namespace Tomahawk
{
class Artist;
class Album;
class Collection;
class Playlist;
class PlaylistEntry;
@ -19,6 +21,8 @@ namespace Tomahawk
typedef QSharedPointer<Query> query_ptr;
typedef QSharedPointer<Result> result_ptr;
typedef QSharedPointer<Source> source_ptr;
typedef QSharedPointer<Artist> artist_ptr;
typedef QSharedPointer<Album> album_ptr;
// let's keep these typesafe, they are different kinds of GUID:
typedef QString QID; //query id

View File

@ -33,6 +33,7 @@
<file>./data/images/shuffle-on-rest.png</file>
<file>./data/images/skip-pressed.png</file>
<file>./data/images/skip-rest.png</file>
<file>./data/images/source-info.png</file>
<file>./data/images/source-off-pressed.png</file>
<file>./data/images/source-off-rest.png</file>
<file>./data/images/source-on-pressed.png</file>

View File

@ -27,6 +27,7 @@ SET( TOMAHAWK_INC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../include/" )
#ENDFOREACH( moddir )
SET( tomahawkSources ${tomahawkSources}
album.cpp
pipeline.cpp
playlist.cpp
pluginapi.cpp
@ -67,6 +68,7 @@ SET( tomahawkSources ${tomahawkSources}
database/databasecommand.cpp
database/databasecommandloggable.cpp
database/databasecommand_resolve.cpp
database/databasecommand_allalbums.cpp
database/databasecommand_alltracks.cpp
database/databasecommand_addfiles.cpp
database/databasecommand_dirmtimes.cpp
@ -117,6 +119,10 @@ SET( tomahawkSourcesGui ${tomahawkSourcesGui}
playlist/trackmodel.cpp
playlist/trackproxymodel.cpp
playlist/trackview.cpp
playlist/albumitem.cpp
playlist/albummodel.cpp
playlist/albumproxymodel.cpp
playlist/albumview.cpp
sourcetree/sourcesmodel.cpp
sourcetree/sourcetreeitem.cpp
@ -129,6 +135,8 @@ SET( tomahawkSourcesGui ${tomahawkSourcesGui}
topbar/lineedit.cpp
topbar/searchbutton.cpp
infowidgets/sourceinfowidget.cpp
tomahawkwindow.cpp
audiocontrols.cpp
settingsdialog.cpp
@ -169,6 +177,7 @@ SET( tomahawkHeaders ${tomahawkHeaders}
database/databasecommand.h
database/databasecommandloggable.h
database/databasecommand_resolve.h
database/databasecommand_allalbums.h
database/databasecommand_alltracks.h
database/databasecommand_addfiles.h
database/databasecommand_dirmtimes.h
@ -235,6 +244,10 @@ SET( tomahawkHeadersGui ${tomahawkHeadersGui}
playlist/trackmodel.h
playlist/trackproxymodel.h
playlist/trackview.h
playlist/albumitem.h
playlist/albummodel.h
playlist/albumproxymodel.h
playlist/albumview.h
sourcetree/sourcesmodel.h
sourcetree/sourcetreeitem.h
@ -248,6 +261,8 @@ SET( tomahawkHeadersGui ${tomahawkHeadersGui}
topbar/lineedit_p.h
topbar/searchbutton.h
infowidgets/sourceinfowidget.h
tomahawkwindow.h
audiocontrols.h
settingsdialog.h
@ -261,6 +276,7 @@ SET( tomahawkUI ${tomahawkUI}
audiocontrols.ui
sourcetree/sourcetreeitemwidget.ui
topbar/topbar.ui
infowidgets/sourceinfowidget.ui
)
INCLUDE_DIRECTORIES(

83
src/album.cpp Normal file
View File

@ -0,0 +1,83 @@
#include "tomahawk/album.h"
#include <QDebug>
#include "tomahawk/collection.h"
#include "tomahawk/tomahawkapp.h"
#include "database/database.h"
#include "database/databasecommand_alltracks.h"
using namespace Tomahawk;
album_ptr
Album::get( unsigned int id, const QString& name, const Tomahawk::artist_ptr& artist, const Tomahawk::collection_ptr& collection )
{
static QHash< unsigned int, album_ptr > s_albums;
if ( s_albums.contains( id ) )
{
return s_albums.value( id );
}
album_ptr a = album_ptr( new Album( id, name, artist, collection ) );
s_albums.insert( id, a );
return a;
}
Album::Album( unsigned int id, const QString& name, const Tomahawk::artist_ptr& artist, const Tomahawk::collection_ptr& collection )
: m_id( id )
, m_name( name )
, m_artist( artist )
, m_collection( collection )
, m_currentTrack( 0 )
{
}
void
Album::onTracksAdded( const QList<Tomahawk::query_ptr>& tracks, const Tomahawk::collection_ptr& collection )
{
qDebug() << Q_FUNC_INFO;
m_queries << tracks;
emit tracksAdded( tracks, collection );
}
Tomahawk::result_ptr
Album::siblingItem( int itemsAway )
{
int p = m_currentTrack;
p += itemsAway;
if ( p < 0 )
return Tomahawk::result_ptr();
if ( p >= m_queries.count() )
return Tomahawk::result_ptr();
m_currentTrack = p;
return m_queries.at( p )->results().first();
}
QList<Tomahawk::query_ptr>
Album::tracks()
{
if ( m_queries.isEmpty() )
{
DatabaseCommand_AllTracks* cmd = new DatabaseCommand_AllTracks( m_collection );
cmd->setAlbum( this );
cmd->setSortOrder( DatabaseCommand_AllTracks::AlbumPosition );
connect( cmd, SIGNAL( tracks( QList<Tomahawk::query_ptr>, Tomahawk::collection_ptr ) ),
SLOT( onTracksAdded( QList<Tomahawk::query_ptr>, Tomahawk::collection_ptr ) ) );
APP->database()->enqueue( QSharedPointer<DatabaseCommand>( cmd ) );
}
return m_queries;
}

View File

@ -200,7 +200,6 @@ AudioEngine::loadTrack( const Tomahawk::result_ptr& result )
m_transcode->clearBuffers();
m_input = io;
m_audio->clearBuffers();
if ( m_audio->isPaused() )
m_audio->resume();
}
@ -235,9 +234,9 @@ AudioEngine::loadPreviousTrack()
return;
}
PlItem* pl = m_playlist->previousItem();
if ( pl )
loadTrack( pl->query()->results().at( 0 ) );
Tomahawk::result_ptr result = m_playlist->previousItem();
if ( !result.isNull() )
loadTrack( result );
else
stop();
}
@ -254,9 +253,9 @@ AudioEngine::loadNextTrack()
return;
}
PlItem* pl = m_playlist->nextItem();
if ( pl )
loadTrack( pl->query()->results().at( 0 ) );
Tomahawk::result_ptr result = m_playlist->nextItem();
if ( !result.isNull() )
loadTrack( result );
else
stop();
}

View File

@ -4,6 +4,7 @@
#include <QNetworkReply>
#include "tomahawk/tomahawkapp.h"
#include "tomahawk/album.h"
#include "utils/tomahawkutils.h"
#include "audioengine.h"
@ -25,7 +26,7 @@ AudioControls::AudioControls( QWidget* parent )
ui->trackLabelLayout->setSpacing( 3 );
QFont font( ui->artistTrackLabel->font() );
font.setPixelSize( 12 );
// font.setPixelSize( 12 );
ui->artistTrackLabel->setFont( font );
ui->artistTrackLabel->setElideMode( Qt::ElideMiddle );
@ -122,6 +123,7 @@ AudioControls::AudioControls( QWidget* parent )
connect( ui->shuffleButton, SIGNAL( clicked() ), SLOT( onShuffleClicked() ) );
connect( ui->artistTrackLabel, SIGNAL( clicked() ), SLOT( onTrackClicked() ) );
connect( ui->albumLabel, SIGNAL( clicked() ), SLOT( onAlbumClicked() ) );
// <From AudioEngine>
connect( (QObject*)TomahawkApp::instance()->audioEngine(), SIGNAL( loading( const Tomahawk::result_ptr& ) ), SLOT( onPlaybackLoading( const Tomahawk::result_ptr& ) ) );
@ -212,7 +214,7 @@ AudioControls::onPlaybackStarted( const Tomahawk::result_ptr& result )
onPlaybackLoading( result );
QString imgurl = "http://ws.audioscrobbler.com/2.0/?method=album.imageredirect&artist=%1&album=%2&size=medium&api_key=7a90f6672a04b809ee309af169f34b8b";
QNetworkRequest req( imgurl.arg( result->artist() ).arg( result->album() ) );
QNetworkRequest req( imgurl.arg( result->artist()->name() ).arg( result->album()->name() ) );
QNetworkReply* reply = APP->nam()->get( req );
connect( reply, SIGNAL( finished() ), SLOT( onCoverArtDownloaded() ) );
}
@ -225,8 +227,8 @@ AudioControls::onPlaybackLoading( const Tomahawk::result_ptr& result )
m_currentTrack = result;
ui->artistTrackLabel->setText( QString( "%1 - %2" ).arg( result->artist() ).arg( result->track() ) );
ui->albumLabel->setText( result->album() );
ui->artistTrackLabel->setText( QString( "%1 - %2" ).arg( result->artist()->name() ).arg( result->track() ) );
ui->albumLabel->setText( result->album()->name() );
ui->ownerLabel->setText( result->collection()->source()->friendlyName() );
ui->coverImage->setPixmap( m_defaultCover );
@ -411,5 +413,12 @@ AudioControls::onShuffleClicked()
void
AudioControls::onTrackClicked()
{
APP->playlistManager()->showCurrentTrack();
APP->playlistManager()->showCurrentTrack();
}
void
AudioControls::onAlbumClicked()
{
APP->playlistManager()->show( m_currentTrack->album() );
}

View File

@ -39,6 +39,7 @@ private slots:
void onRepeatClicked();
void onShuffleClicked();
void onTrackClicked();
void onAlbumClicked();
void onCoverArtDownloaded();

View File

@ -216,7 +216,10 @@
</widget>
</item>
<item>
<widget class="QLabel" name="albumLabel">
<widget class="ElidedLabel" name="albumLabel">
<property name="cursor">
<cursorShape>PointingHandCursor</cursorShape>
</property>
<property name="text">
<string>Album</string>
</property>

View File

@ -85,26 +85,10 @@ Collection::setPlaylists( const QList<Tomahawk::playlist_ptr>& plists )
void
Collection::setTracks( const QList<QVariant>& tracks, Tomahawk::collection_ptr collection )
Collection::setTracks( const QList<Tomahawk::query_ptr>& tracks, Tomahawk::collection_ptr collection )
{
qDebug() << Q_FUNC_INFO << tracks.count() << collection->name();
QList<query_ptr> qs;
foreach( const QVariant& v, tracks )
{
query_ptr query = query_ptr( new Query( v ) );
QVariantMap t = query->toVariant().toMap();
t["score"] = 1.0;
QList<result_ptr> results;
result_ptr result = result_ptr( new Result( t, collection ) );
results << result;
query->addResults( results );
qs << query;
}
m_tracks << qs;
emit tracksAdded( qs, collection );
m_tracks << tracks;
emit tracksAdded( tracks, collection );
}

View File

@ -19,14 +19,12 @@ void
DatabaseCollection::loadPlaylists()
{
qDebug() << Q_FUNC_INFO;
// load our playlists
DatabaseCommand_LoadAllPlaylists* cmd = new DatabaseCommand_LoadAllPlaylists( source() );
connect( cmd, SIGNAL( done( const QList<Tomahawk::playlist_ptr>& ) ),
SLOT( setPlaylists( const QList<Tomahawk::playlist_ptr>& ) ) );
TomahawkApp::instance()->database()->enqueue(
QSharedPointer<DatabaseCommand>( cmd )
);
TomahawkApp::instance()->database()->enqueue( QSharedPointer<DatabaseCommand>( cmd ) );
}
@ -35,14 +33,13 @@ DatabaseCollection::loadTracks()
{
qDebug() << Q_FUNC_INFO << source()->userName();
DatabaseCommand_AllTracks* cmd = new DatabaseCommand_AllTracks( source()->collection() );
connect( cmd, SIGNAL( tracks( QList<QVariant>, Tomahawk::collection_ptr ) ),
SLOT( setTracks( QList<QVariant>, Tomahawk::collection_ptr ) ) );
connect( cmd, SIGNAL( tracks( QList<Tomahawk::query_ptr>, Tomahawk::collection_ptr ) ),
SLOT( setTracks( QList<Tomahawk::query_ptr>, Tomahawk::collection_ptr ) ) );
/* connect( cmd, SIGNAL( done( Tomahawk::collection_ptr ) ),
SIGNAL( tracksFinished( Tomahawk::collection_ptr ) ) );*/
TomahawkApp::instance()->database()->enqueue(
QSharedPointer<DatabaseCommand>( cmd )
);
TomahawkApp::instance()->database()->enqueue( QSharedPointer<DatabaseCommand>( cmd ) );
}
@ -51,9 +48,8 @@ DatabaseCollection::addTracks( const QList<QVariant> &newitems )
{
qDebug() << Q_FUNC_INFO << newitems.length();
DatabaseCommand_AddFiles* cmd = new DatabaseCommand_AddFiles( newitems, source() );
TomahawkApp::instance()->database()->enqueue(
QSharedPointer<DatabaseCommand>( cmd )
);
TomahawkApp::instance()->database()->enqueue( QSharedPointer<DatabaseCommand>( cmd ) );
}

View File

@ -39,7 +39,7 @@ DatabaseCommand::_exec( DatabaseImpl* lib )
m_state = RUNNING;
emit running();
exec( lib );
m_state=FINISHED;
m_state = FINISHED;
//qDebug() << "FINISHED" << thread();
}

View File

@ -0,0 +1,53 @@
#include "databasecommand_allalbums.h"
#include <QSqlQuery>
#include "databaseimpl.h"
void
DatabaseCommand_AllAlbums::exec( DatabaseImpl* dbi )
{
Q_ASSERT( !m_collection->source().isNull() );
TomahawkSqlQuery query = dbi->newquery();
QList<Tomahawk::album_ptr> al;
QString m_orderToken;
switch ( m_sortOrder )
{
case 0:
break;
case ModificationTime:
m_orderToken = "file.mtime";
}
QString sql = QString(
"SELECT DISTINCT album.id, album.name, album.artist, artist.name "
"FROM album, file, file_join "
"LEFT OUTER JOIN artist "
"ON album.artist = artist.id "
"WHERE file.id = file_join.file "
"AND file_join.album = album.id "
"AND file.source %1 "
"%2 %3 %4"
).arg( m_collection->source()->isLocal() ? "IS NULL" : QString( "= %1" ).arg( m_collection->source()->id() ) )
.arg( m_sortOrder > 0 ? QString( "ORDER BY %1" ).arg( m_orderToken ) : QString() )
.arg( m_sortDescending ? "DESC" : QString() )
.arg( m_amount > 0 ? QString( "LIMIT 0, %1" ).arg( m_amount ) : QString() );
query.prepare( sql );
query.exec();
while( query.next() )
{
Tomahawk::artist_ptr artist = Tomahawk::artist_ptr( new Tomahawk::Artist( query.value( 3 ).toString() ) );
Tomahawk::album_ptr album = Tomahawk::Album::get( query.value( 0 ).toUInt(), query.value( 1 ).toString(), artist, m_collection );
al << album;
}
if ( al.count() )
emit albums( al, m_collection );
emit done( m_collection );
}

View File

@ -0,0 +1,49 @@
#ifndef DATABASECOMMAND_ALLALBUMS_H
#define DATABASECOMMAND_ALLALBUMS_H
#include <QObject>
#include <QVariantMap>
#include "databasecommand.h"
#include "tomahawk/album.h"
#include "tomahawk/collection.h"
#include "tomahawk/typedefs.h"
class DatabaseCommand_AllAlbums : public DatabaseCommand
{
Q_OBJECT
public:
enum SortOrder {
None = 0,
ModificationTime = 1
};
explicit DatabaseCommand_AllAlbums( const Tomahawk::collection_ptr& collection, QObject* parent = 0 )
: DatabaseCommand( parent )
, m_collection( collection )
, m_amount( 0 )
, m_sortOrder( DatabaseCommand_AllAlbums::None )
, m_sortDescending( false )
{}
virtual void exec( DatabaseImpl* );
virtual bool doesMutates() const { return false; }
virtual QString commandname() const { return "allalbums"; }
void setLimit( unsigned int amount ) { m_amount = amount; }
void setSortOrder( DatabaseCommand_AllAlbums::SortOrder order ) { m_sortOrder = order; }
void setSortDescending( bool descending ) { m_sortDescending = descending; }
signals:
void albums( const QList<Tomahawk::album_ptr>&, const Tomahawk::collection_ptr& );
void done( const Tomahawk::collection_ptr& );
private:
Tomahawk::collection_ptr m_collection;
unsigned int m_amount;
DatabaseCommand_AllAlbums::SortOrder m_sortOrder;
bool m_sortDescending;
};
#endif // DATABASECOMMAND_ALLALBUMS_H

View File

@ -4,17 +4,32 @@
#include "databaseimpl.h"
void
DatabaseCommand_AllTracks::exec( DatabaseImpl* dbi )
{
Q_ASSERT( !m_collection->source().isNull() );
TomahawkSqlQuery query = dbi->newquery();
QList<QVariant> tl;
QList<Tomahawk::query_ptr> ql;
QString m_orderToken;
switch ( m_sortOrder )
{
case 0:
break;
case ModificationTime:
m_orderToken = "file.mtime";
break;
case AlbumPosition:
m_orderToken = "file_join.albumpos";
break;
}
QString sql = QString(
"SELECT file.id, artist.name, album.name, track.name, file.size, "
"file.duration, file.bitrate, file.url, file.source, file.mtime, file.mimetype, file_join.albumpos "
"file.duration, file.bitrate, file.url, file.source, file.mtime, file.mimetype, file_join.albumpos, artist.id, album.id "
"FROM file, artist, track, file_join "
"LEFT OUTER JOIN album "
"ON file_join.album = album.id "
@ -22,13 +37,16 @@ DatabaseCommand_AllTracks::exec( DatabaseImpl* dbi )
"AND file_join.artist = artist.id "
"AND file_join.track = track.id "
"AND file.source %1 "
).arg( m_collection->source()->isLocal() ? "IS NULL" : QString( "= %1" ).arg( m_collection->source()->id() ) );
"%2 "
"%3 %4 %5"
).arg( m_collection->source()->isLocal() ? "IS NULL" : QString( "= %1" ).arg( m_collection->source()->id() ) )
.arg( !m_album ? QString() : QString( "AND album.id = %1" ).arg( m_album->id() ) )
.arg( m_sortOrder > 0 ? QString( "ORDER BY %1" ).arg( m_orderToken ) : QString() )
.arg( m_sortDescending ? "DESC" : QString() )
.arg( m_amount > 0 ? QString( "LIMIT 0, %1" ).arg( m_amount ) : QString() );
query.prepare( sql );
if( !query.exec() )
{
qDebug() << "ERROR:" << dbi->database().lastError().databaseText() << dbi->database().lastError().driverText();
}
query.exec();
int i = 0;
while( query.next() )
@ -43,26 +61,37 @@ DatabaseCommand_AllTracks::exec( DatabaseImpl* dbi )
t["id"] = QString( "%1" ).arg( query.value( 0 ).toInt() );
t["artist"] = query.value( 1 ).toString();
t["album"] = query.value( 2 ).toString();
t["track"] = query.value( 3 ).toString();
t["size"] = query.value( 4 ).toInt();
t["artistid"] = query.value( 12 ).toUInt();
t["album"] = query.value( 2 ).toString();
t["albumid"] = query.value( 13 ).toUInt();
t["track"] = query.value( 3 ).toString();
t["size"] = query.value( 4 ).toInt();
t["duration"] = query.value( 5 ).toInt();
t["bitrate"] = query.value( 6 ).toInt();
t["bitrate"] = query.value( 6 ).toInt();
t["mtime"] = query.value( 9 ).toInt();
t["mimetype"] = query.value( 10 ).toString();
t["albumpos"] = query.value( 11 ).toUInt();
tl.append( t );
Tomahawk::query_ptr query = Tomahawk::query_ptr( new Tomahawk::Query( t ) );
t["score"] = 1.0;
QList<Tomahawk::result_ptr> results;
Tomahawk::result_ptr result = Tomahawk::result_ptr( new Tomahawk::Result( t, m_collection ) );
results << result;
query->addResults( results );
ql << query;
if ( ++i % 1000 == 0 )
{
emit tracks( tl, m_collection );
tl.clear();
emit tracks( ql, m_collection );
ql.clear();
}
}
qDebug() << Q_FUNC_INFO << tl.length();
qDebug() << Q_FUNC_INFO << ql.length();
if ( tl.count() )
emit tracks( tl, m_collection );
if ( ql.count() )
emit tracks( ql, m_collection );
emit done( m_collection );
}

View File

@ -5,6 +5,7 @@
#include <QVariantMap>
#include "databasecommand.h"
#include "tomahawk/album.h"
#include "tomahawk/collection.h"
#include "tomahawk/typedefs.h"
@ -12,8 +13,19 @@ class DatabaseCommand_AllTracks : public DatabaseCommand
{
Q_OBJECT
public:
enum SortOrder {
None = 0,
ModificationTime = 1,
AlbumPosition = 2
};
explicit DatabaseCommand_AllTracks( const Tomahawk::collection_ptr& collection, QObject* parent = 0 )
: DatabaseCommand( parent ), m_collection( collection )
: DatabaseCommand( parent )
, m_collection( collection )
, m_album( 0 )
, m_amount( 0 )
, m_sortOrder( DatabaseCommand_AllTracks::None )
, m_sortDescending( false )
{}
virtual void exec( DatabaseImpl* );
@ -21,12 +33,21 @@ public:
virtual bool doesMutates() const { return false; }
virtual QString commandname() const { return "alltracks"; }
void setAlbum( Tomahawk::Album* album ) { m_album = album; }
void setLimit( unsigned int amount ) { m_amount = amount; }
void setSortOrder( DatabaseCommand_AllTracks::SortOrder order ) { m_sortOrder = order; }
void setSortDescending( bool descending ) { m_sortDescending = descending; }
signals:
void tracks( const QList<QVariant>&, const Tomahawk::collection_ptr& );
void tracks( const QList<Tomahawk::query_ptr>&, const Tomahawk::collection_ptr& );
void done( const Tomahawk::collection_ptr& );
private:
Tomahawk::collection_ptr m_collection;
Tomahawk::Album* m_album;
unsigned int m_amount;
DatabaseCommand_AllTracks::SortOrder m_sortOrder;
bool m_sortDescending;
};
#endif // DATABASECOMMAND_ALLTRACKS_H

View File

@ -1,6 +1,7 @@
#include "databasecommand_resolve.h"
#include "tomahawk/tomahawkapp.h"
#include "tomahawk/album.h"
#define MINSCORE 0.5
@ -61,7 +62,9 @@ DatabaseCommand_Resolve::exec( DatabaseImpl* lib )
"album.name as albname, "
"track.name as trkname, "
"file.source, "
"file_join.albumpos "
"file_join.albumpos, "
"artist.id as artid, "
"album.id as albid "
"FROM file, file_join, artist, track "
"LEFT JOIN album ON album.id = file_join.album "
"WHERE "
@ -98,7 +101,9 @@ DatabaseCommand_Resolve::exec( DatabaseImpl* lib )
m["duration"] = files_query.value(5).toInt();
m["bitrate"] = files_query.value(6).toInt();
m["artist"] = files_query.value(10).toString();
m["artistid"] = files_query.value(15).toUInt();
m["album"] = files_query.value(11).toString();
m["albumid"] = files_query.value(16).toUInt();
m["track"] = files_query.value(12).toString();
m["srcid"] = files_query.value(13).toInt();
m["albumpos"] = files_query.value(14).toUInt();

View File

@ -68,9 +68,9 @@ void EchoNestPlugin::getArtistBiography(const QString &caller, const QVariant& d
if( !isValidArtistData( caller, data, customData ) )
return;
Artist artist( data.toString() );
Echonest::Artist artist( data.toString() );
QNetworkReply *reply = artist.fetchBiographies();
reply->setProperty("artist", QVariant::fromValue<Artist>(artist));
reply->setProperty("artist", QVariant::fromValue<Echonest::Artist>(artist));
reply->setProperty( "data", data );
m_replyMap[reply] = customData;
m_callerMap[reply] = caller;
@ -83,9 +83,9 @@ void EchoNestPlugin::getArtistFamiliarity(const QString &caller, const QVariant&
return;
qDebug() << "Fetching artist familiarity!" << data;
Artist artist( data.toString() );
Echonest::Artist artist( data.toString() );
QNetworkReply* reply = artist.fetchFamiliarity();
reply->setProperty( "artist", QVariant::fromValue<Artist>(artist));
reply->setProperty( "artist", QVariant::fromValue<Echonest::Artist>(artist));
reply->setProperty( "data", data );
m_replyMap[reply] = customData;
m_callerMap[reply] = caller;
@ -97,9 +97,9 @@ void EchoNestPlugin::getArtistHotttnesss(const QString &caller, const QVariant&
if( !isValidArtistData( caller, data, customData ) )
return;
Artist artist( data.toString() );
Echonest::Artist artist( data.toString() );
QNetworkReply* reply = artist.fetchHotttnesss();
reply->setProperty( "artist", QVariant::fromValue<Artist>(artist));
reply->setProperty( "artist", QVariant::fromValue<Echonest::Artist>(artist));
reply->setProperty( "data", data );
m_replyMap[reply] = customData;
m_callerMap[reply] = caller;
@ -111,9 +111,9 @@ void EchoNestPlugin::getArtistTerms(const QString &caller, const QVariant& data,
if( !isValidArtistData( caller, data, customData ) )
return;
Artist artist( data.toString() );
Echonest::Artist artist( data.toString() );
QNetworkReply* reply = artist.fetchTerms( Echonest::Artist::Weight );
reply->setProperty( "artist", QVariant::fromValue<Artist>(artist));
reply->setProperty( "artist", QVariant::fromValue<Echonest::Artist>(artist));
reply->setProperty( "data", data );
m_replyMap[reply] = customData;
m_callerMap[reply] = caller;
@ -122,7 +122,7 @@ void EchoNestPlugin::getArtistTerms(const QString &caller, const QVariant& data,
void EchoNestPlugin::getMiscTopTerms(const QString &caller, const QVariant& data, InfoCustomDataHash& customData)
{
QNetworkReply* reply = Artist::topTerms( 20 );
QNetworkReply* reply = Echonest::Artist::topTerms( 20 );
m_replyMap[reply] = customData;
m_callerMap[reply] = caller;
connect( reply,SIGNAL(finished()), SLOT( getMiscTopSlot()));
@ -132,7 +132,7 @@ void EchoNestPlugin::getMiscTopTerms(const QString &caller, const QVariant& data
void EchoNestPlugin::getArtistBiographySlot()
{
QNetworkReply* reply = qobject_cast<QNetworkReply*>( sender() );
Artist artist = artistFromReply( reply );
Echonest::Artist artist = artistFromReply( reply );
BiographyList biographies = artist.biographies();
InfoGenericMap biographyMap;
Q_FOREACH(const Biography& biography, biographies)
@ -155,7 +155,7 @@ void EchoNestPlugin::getArtistBiographySlot()
void EchoNestPlugin::getArtistFamiliaritySlot()
{
QNetworkReply* reply = qobject_cast<QNetworkReply*>( sender() );
Artist artist = artistFromReply( reply );
Echonest::Artist artist = artistFromReply( reply );
qreal familiarity = artist.familiarity();
emit info( m_callerMap[reply], Tomahawk::InfoSystem::InfoArtistFamiliarity, reply->property( "data" ), familiarity, m_replyMap[reply] );
emit finished( m_callerMap[reply], Tomahawk::InfoSystem::InfoArtistFamiliarity);
@ -167,7 +167,7 @@ void EchoNestPlugin::getArtistFamiliaritySlot()
void EchoNestPlugin::getArtistHotttnesssSlot()
{
QNetworkReply* reply = qobject_cast<QNetworkReply*>( sender() );
Artist artist = artistFromReply( reply );
Echonest::Artist artist = artistFromReply( reply );
qreal hotttnesss = artist.hotttnesss();
emit info( m_callerMap[reply], Tomahawk::InfoSystem::InfoArtistHotttness, reply->property( "data" ), hotttnesss, m_replyMap[reply] );
emit finished( m_callerMap[reply], Tomahawk::InfoSystem::InfoArtistHotttness);
@ -179,7 +179,7 @@ void EchoNestPlugin::getArtistHotttnesssSlot()
void EchoNestPlugin::getArtistTermsSlot()
{
QNetworkReply* reply = qobject_cast<QNetworkReply*>( sender() );
Artist artist = artistFromReply( reply );
Echonest::Artist artist = artistFromReply( reply );
TermList terms = artist.terms();
InfoGenericMap termsMap;
Q_FOREACH( const Echonest::Term& term, terms ) {
@ -198,7 +198,7 @@ void EchoNestPlugin::getArtistTermsSlot()
void EchoNestPlugin::getMiscTopSlot()
{
QNetworkReply* reply = qobject_cast<QNetworkReply*>( sender() );
TermList terms = Artist::parseTopTerms( reply );
TermList terms = Echonest::Artist::parseTopTerms( reply );
InfoGenericMap termsMap;
Q_FOREACH( const Echonest::Term& term, terms ) {
QMap< QString, QString > termMap;
@ -250,7 +250,7 @@ bool EchoNestPlugin::isValidTrackData(const QString &caller, const QVariant& dat
Artist EchoNestPlugin::artistFromReply(QNetworkReply* reply)
{
Artist artist = reply->property("artist").value<Artist>();
Echonest::Artist artist = reply->property("artist").value<Echonest::Artist>();
try {
artist.parseProfile(reply);
} catch( const Echonest::ParseError& e ) {

View File

@ -0,0 +1,55 @@
#include "sourceinfowidget.h"
#include "ui_sourceinfowidget.h"
#include "tomahawk/tomahawkapp.h"
#include "utils/tomahawkutils.h"
#include "playlist/playlistmanager.h"
#include "playlist/albummodel.h"
#include "playlist/collectionflatmodel.h"
#include "database/databasecommand_alltracks.h"
#include "database/databasecommand_allalbums.h"
SourceInfoWidget::SourceInfoWidget( const Tomahawk::source_ptr& source, QWidget* parent )
: QWidget( parent )
, ui( new Ui::SourceInfoWidget )
{
ui->setupUi( this );
ui->sourceLabel->setText( source->friendlyName() );
m_recentCollectionModel = new CollectionFlatModel( ui->recentCollectionView );
ui->recentCollectionView->setModel( m_recentCollectionModel );
m_recentCollectionModel->addFilteredCollection( source->collection(), 250, DatabaseCommand_AllTracks::ModificationTime );
// ui->recentCollectionView->setColumnHidden( TrackModel::Bitrate, true );
// ui->recentCollectionView->setColumnHidden( TrackModel::Origin, true );
m_recentAlbumModel = new AlbumModel( ui->recentAlbumView );
ui->recentAlbumView->setModel( m_recentAlbumModel );
m_recentAlbumModel->addFilteredCollection( source->collection(), 20, DatabaseCommand_AllAlbums::ModificationTime );
}
SourceInfoWidget::~SourceInfoWidget()
{
delete ui;
}
void
SourceInfoWidget::changeEvent( QEvent* e )
{
QWidget::changeEvent( e );
switch ( e->type() )
{
case QEvent::LanguageChange:
ui->retranslateUi( this );
break;
default:
break;
}
}

View File

@ -0,0 +1,36 @@
#ifndef SOURCEINFOWIDGET_H
#define SOURCEINFOWIDGET_H
#include <QWidget>
#include "tomahawk/album.h"
#include "tomahawk/result.h"
#include "tomahawk/playlistinterface.h"
class AlbumModel;
class CollectionFlatModel;
namespace Ui
{
class SourceInfoWidget;
}
class SourceInfoWidget : public QWidget
{
Q_OBJECT
public:
SourceInfoWidget( const Tomahawk::source_ptr& source, QWidget* parent = 0 );
~SourceInfoWidget();
protected:
void changeEvent( QEvent* e );
private:
Ui::SourceInfoWidget *ui;
CollectionFlatModel* m_recentCollectionModel;
AlbumModel* m_recentAlbumModel;
};
#endif // SOURCEINFOWIDGET_H

View File

@ -0,0 +1,115 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SourceInfoWidget</class>
<widget class="QWidget" name="SourceInfoWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>985</width>
<height>460</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>9</pointsize>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3" stretch="0,0,0">
<item>
<widget class="QLabel" name="sourceLabel">
<property name="font">
<font>
<pointsize>22</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Source Name</string>
</property>
<property name="scaledContents">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label_2">
<property name="font">
<font>
<pointsize>13</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Recent Albums</string>
</property>
</widget>
</item>
<item>
<widget class="AlbumView" name="recentAlbumView">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>210</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>210</height>
</size>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="label">
<property name="font">
<font>
<pointsize>13</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Latest Additions to their Collection</string>
</property>
</widget>
</item>
<item>
<widget class="CollectionView" name="recentCollectionView"/>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>CollectionView</class>
<extends>QTreeView</extends>
<header>collectionview.h</header>
</customwidget>
<customwidget>
<class>AlbumView</class>
<extends>QListView</extends>
<header>albumview.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,60 @@
#include "albumitem.h"
#include "utils/tomahawkutils.h"
#include <QDebug>
using namespace Tomahawk;
AlbumItem::~AlbumItem()
{
// Don't use qDeleteAll here! The children will remove themselves
// from the list when they get deleted and the qDeleteAll iterator
// will fail badly!
for ( int i = children.count() - 1; i >= 0; i-- )
delete children.at( i );
if ( parent && index.isValid() )
{
parent->children.removeAt( index.row() );
}
}
AlbumItem::AlbumItem( AlbumItem* parent, QAbstractItemModel* model )
{
this->parent = parent;
this->model = model;
childCount = 0;
toberemoved = false;
if ( parent )
{
parent->children.append( this );
}
}
AlbumItem::AlbumItem( const Tomahawk::album_ptr& album, AlbumItem* parent, int row )
: QObject( parent )
, m_album( album )
{
this->parent = parent;
if ( parent )
{
if ( row < 0 )
{
parent->children.append( this );
row = parent->children.count() - 1;
}
else
{
parent->children.insert( row, this );
}
this->model = parent->model;
}
toberemoved = false;
}

39
src/playlist/albumitem.h Normal file
View File

@ -0,0 +1,39 @@
#ifndef ALBUMITEM_H
#define ALBUMITEM_H
#include <QAbstractItemModel>
#include <QHash>
#include <QPersistentModelIndex>
#include <QPixmap>
#include "tomahawk/album.h"
class AlbumItem : public QObject
{
Q_OBJECT
public:
~AlbumItem();
explicit AlbumItem( AlbumItem* parent = 0, QAbstractItemModel* model = 0 );
explicit AlbumItem( const Tomahawk::album_ptr& album, AlbumItem* parent = 0, int row = -1 );
const Tomahawk::album_ptr& album() const { return m_album; };
AlbumItem* parent;
QList<AlbumItem*> children;
QHash<QString, AlbumItem*> hash;
int childCount;
QPersistentModelIndex index;
QAbstractItemModel* model;
QPixmap cover;
bool toberemoved;
signals:
void dataChanged();
private:
Tomahawk::album_ptr m_album;
};
#endif // ALBUMITEM_H

306
src/playlist/albummodel.cpp Normal file
View File

@ -0,0 +1,306 @@
#include "albummodel.h"
#include <QDebug>
#include <QListView>
#include <QMimeData>
#include <QNetworkReply>
#include "tomahawk/tomahawkapp.h"
#include "database.h"
#define LASTFM_DEFAULT_COVER "http://cdn.last.fm/flatness/catalogue/noimage"
using namespace Tomahawk;
AlbumModel::AlbumModel( QObject* parent )
: QAbstractItemModel( parent )
, m_rootItem( new AlbumItem( 0, this ) )
{
qDebug() << Q_FUNC_INFO;
m_defaultCover = QPixmap( RESPATH "images/no-album-art-placeholder.png" )
.scaled( QSize( 64, 64 ), Qt::IgnoreAspectRatio, Qt::SmoothTransformation );
}
AlbumModel::~AlbumModel()
{
delete m_rootItem;
}
QModelIndex
AlbumModel::index( int row, int column, const QModelIndex& parent ) const
{
if ( !m_rootItem || row < 0 || column < 0 )
return QModelIndex();
AlbumItem* parentItem = itemFromIndex( parent );
AlbumItem* childItem = parentItem->children.value( row );
if ( !childItem )
return QModelIndex();
return createIndex( row, column, childItem );
}
int
AlbumModel::rowCount( const QModelIndex& parent ) const
{
if ( parent.column() > 0 )
return 0;
AlbumItem* parentItem = itemFromIndex( parent );
if ( !parentItem )
return 0;
return parentItem->children.count();
}
int
AlbumModel::columnCount( const QModelIndex& parent ) const
{
return 1;
}
QModelIndex
AlbumModel::parent( const QModelIndex& child ) const
{
AlbumItem* entry = itemFromIndex( child );
if ( !entry )
return QModelIndex();
AlbumItem* parentEntry = entry->parent;
if ( !parentEntry )
return QModelIndex();
AlbumItem* grandparentEntry = parentEntry->parent;
if ( !grandparentEntry )
return QModelIndex();
int row = grandparentEntry->children.indexOf( parentEntry );
return createIndex( row, 0, parentEntry );
}
QVariant
AlbumModel::data( const QModelIndex& index, int role ) const
{
AlbumItem* entry = itemFromIndex( index );
if ( !entry )
return QVariant();
if ( role == Qt::DecorationRole )
{
return entry->cover;
}
if ( role == Qt::SizeHintRole )
{
return QSize( 90, 90 );
}
if ( role != Qt::DisplayRole ) // && role != Qt::ToolTipRole )
return QVariant();
const album_ptr& album = entry->album();
switch( index.column() )
{
case 0:
return album->name();
break;
}
return QVariant();
}
QVariant
AlbumModel::headerData( int section, Qt::Orientation orientation, int role ) const
{
QStringList headers;
headers << tr( "Album" );
if ( orientation == Qt::Horizontal && role == Qt::DisplayRole && section >= 0 )
{
return headers.at( section );
}
return QVariant();
}
Qt::ItemFlags
AlbumModel::flags( const QModelIndex& index ) const
{
Qt::ItemFlags defaultFlags = QAbstractItemModel::flags( index );
if ( index.isValid() && index.column() == 0 )
return Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | defaultFlags;
else
return defaultFlags;
}
QStringList
AlbumModel::mimeTypes() const
{
QStringList types;
types << "application/tomahawk.query.list";
return types;
}
QMimeData*
AlbumModel::mimeData( const QModelIndexList &indexes ) const
{
qDebug() << Q_FUNC_INFO;
QByteArray queryData;
QDataStream queryStream( &queryData, QIODevice::WriteOnly );
foreach ( const QModelIndex& i, indexes )
{
if ( i.column() > 0 )
continue;
QModelIndex idx = index( i.row(), 0, i.parent() );
AlbumItem* item = itemFromIndex( idx );
if ( item )
{
const album_ptr& album = item->album();
queryStream << qlonglong( &album );
}
}
QMimeData* mimeData = new QMimeData();
mimeData->setData( "application/tomahawk.query.list", queryData );
return mimeData;
}
void
AlbumModel::removeIndex( const QModelIndex& index )
{
qDebug() << Q_FUNC_INFO;
if ( index.column() > 0 )
return;
AlbumItem* item = itemFromIndex( index );
if ( item )
{
emit beginRemoveRows( index.parent(), index.row(), index.row() );
delete item;
emit endRemoveRows();
}
}
void
AlbumModel::removeIndexes( const QList<QModelIndex>& indexes )
{
foreach( const QModelIndex& idx, indexes )
{
removeIndex( idx );
}
}
void
AlbumModel::addFilteredCollection( const collection_ptr& collection, unsigned int amount, DatabaseCommand_AllAlbums::SortOrder order )
{
qDebug() << Q_FUNC_INFO << collection->name()
<< collection->source()->id()
<< collection->source()->userName()
<< amount << order;
DatabaseCommand_AllAlbums* cmd = new DatabaseCommand_AllAlbums( collection );
cmd->setLimit( amount );
cmd->setSortOrder( order );
cmd->setSortDescending( true );
connect( cmd, SIGNAL( albums( QList<Tomahawk::album_ptr>, Tomahawk::collection_ptr ) ),
SLOT( onAlbumsAdded( QList<Tomahawk::album_ptr>, Tomahawk::collection_ptr ) ) );
TomahawkApp::instance()->database()->enqueue( QSharedPointer<DatabaseCommand>( cmd ) );
}
void
AlbumModel::onAlbumsAdded( const QList<Tomahawk::album_ptr>& albums, const Tomahawk::collection_ptr& collection )
{
if ( !albums.count() )
return;
int c = rowCount( QModelIndex() );
QPair< int, int > crows;
crows.first = c;
crows.second = c + albums.count() - 1;
emit beginInsertRows( QModelIndex(), crows.first, crows.second );
AlbumItem* albumitem;
foreach( const album_ptr& album, albums )
{
albumitem = new AlbumItem( album, m_rootItem );
albumitem->cover = m_defaultCover;
albumitem->index = createIndex( m_rootItem->children.count() - 1, 0, albumitem );
QString imgurl = "http://ws.audioscrobbler.com/2.0/?method=album.imageredirect&artist=%1&album=%2&size=medium&api_key=7a90f6672a04b809ee309af169f34b8b";
QNetworkRequest req( imgurl.arg( album->artist()->name() ).arg( album->name() ) );
req.setAttribute( QNetworkRequest::User, (qlonglong)albumitem );
QNetworkReply* reply = APP->nam()->get( req );
connect( reply, SIGNAL( finished() ), SLOT( onCoverArtDownloaded() ) );
// connect( albumitem, SIGNAL( dataChanged() ), SLOT( onDataChanged() ) );
}
emit endInsertRows();
qDebug() << rowCount( QModelIndex() );
}
void
AlbumModel::onCoverArtDownloaded()
{
QNetworkReply* reply = qobject_cast<QNetworkReply*>( sender() );
qDebug() << "attr:" << reply->request().attribute( QNetworkRequest::User );
QUrl redir = reply->attribute( QNetworkRequest::RedirectionTargetAttribute ).toUrl();
if ( redir.isEmpty() )
{
const QByteArray ba = reply->readAll();
if ( ba.length() )
{
QPixmap pm;
pm.loadFromData( ba );
qlonglong pptr = reply->request().attribute( QNetworkRequest::User ).toLongLong();
AlbumItem* ai = reinterpret_cast<AlbumItem*>(pptr);
if ( pm.isNull() || reply->url().toString().startsWith( LASTFM_DEFAULT_COVER ) )
{
ai->cover = m_defaultCover;
}
else
{
ai->cover = pm.scaled( QSize( 64, 64 ), Qt::IgnoreAspectRatio, Qt::SmoothTransformation );
}
}
}
else
{
// Follow HTTP redirect
QNetworkRequest req( redir );
req.setAttribute( QNetworkRequest::User, reply->request().attribute( QNetworkRequest::User ) );
QNetworkReply* reply = APP->nam()->get( req );
connect( reply, SIGNAL( finished() ), SLOT( onCoverArtDownloaded() ) );
}
reply->deleteLater();
}

86
src/playlist/albummodel.h Normal file
View File

@ -0,0 +1,86 @@
#ifndef ALBUMMODEL_H
#define ALBUMMODEL_H
#include <QAbstractItemModel>
#include <QPixmap>
#include "tomahawk/album.h"
#include "tomahawk/collection.h"
#include "tomahawk/playlistinterface.h"
#include "database/databasecommand_allalbums.h"
#include "albumitem.h"
class QMetaData;
class AlbumModel : public QAbstractItemModel, public PlaylistInterface
{
Q_OBJECT
public:
explicit AlbumModel( QObject* parent = 0 );
virtual ~AlbumModel();
virtual QModelIndex index( int row, int column, const QModelIndex& parent ) const;
virtual QModelIndex parent( const QModelIndex& child ) const;
virtual bool isReadOnly() const { return true; }
virtual int trackCount() const { return rowCount( QModelIndex() ); }
virtual int albumCount() const { return rowCount( QModelIndex() ); }
virtual int rowCount( const QModelIndex& parent ) const;
virtual int columnCount( const QModelIndex& parent ) const;
virtual QVariant data( const QModelIndex& index, int role = Qt::DisplayRole ) const;
virtual QVariant headerData( int section, Qt::Orientation orientation, int role ) const;
virtual void removeIndex( const QModelIndex& index );
virtual void removeIndexes( const QList<QModelIndex>& indexes );
virtual Tomahawk::result_ptr previousItem() { return Tomahawk::result_ptr(); }
virtual Tomahawk::result_ptr nextItem() { return Tomahawk::result_ptr(); }
virtual Tomahawk::result_ptr siblingItem( int direction ) { return Tomahawk::result_ptr(); }
virtual PlaylistInterface::RepeatMode repeatMode() const { return PlaylistInterface::NoRepeat; }
virtual bool shuffled() const { return false; }
virtual QMimeData* mimeData( const QModelIndexList& indexes ) const;
virtual QStringList mimeTypes() const;
virtual Qt::ItemFlags flags( const QModelIndex& index ) const;
void addFilteredCollection( const Tomahawk::collection_ptr& collection, unsigned int amount, DatabaseCommand_AllAlbums::SortOrder order );
AlbumItem* itemFromIndex( const QModelIndex& index ) const
{
if ( index.isValid() )
return static_cast<AlbumItem*>( index.internalPointer() );
else
{
return m_rootItem;
}
}
public slots:
virtual void setRepeatMode( PlaylistInterface::RepeatMode mode ) {}
virtual void setShuffled( bool shuffled ) {}
signals:
void repeatModeChanged( PlaylistInterface::RepeatMode mode );
void shuffleModeChanged( bool enabled );
void trackCountChanged( unsigned int tracks );
protected:
private slots:
void onAlbumsAdded( const QList<Tomahawk::album_ptr>& albums, const Tomahawk::collection_ptr& collection );
void onCoverArtDownloaded();
private:
QPersistentModelIndex m_currentIndex;
AlbumItem* m_rootItem;
QPixmap m_defaultCover;
};
#endif // ALBUMMODEL_H

View File

@ -0,0 +1,116 @@
#include "albumproxymodel.h"
#include <QDebug>
#include <QListView>
#include "tomahawk/query.h"
#include "collectionmodel.h"
AlbumProxyModel::AlbumProxyModel( QObject* parent )
: QSortFilterProxyModel( parent )
, m_model( 0 )
{
qsrand( QTime( 0, 0, 0 ).secsTo( QTime::currentTime() ) );
setFilterCaseSensitivity( Qt::CaseInsensitive );
setSortCaseSensitivity( Qt::CaseInsensitive );
setDynamicSortFilter( true );
setSourceModel( 0 );
}
void
AlbumProxyModel::setSourceModel( AlbumModel* sourceModel )
{
m_model = sourceModel;
QSortFilterProxyModel::setSourceModel( sourceModel );
}
void
AlbumProxyModel::setFilterRegExp( const QString& pattern )
{
qDebug() << Q_FUNC_INFO;
QSortFilterProxyModel::setFilterRegExp( pattern );
emit filterChanged( pattern );
}
bool
AlbumProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex& sourceParent ) const
{
if ( filterRegExp().isEmpty() )
return true;
AlbumItem* pi = sourceModel()->itemFromIndex( sourceModel()->index( sourceRow, 0, sourceParent ) );
if ( !pi )
return false;
const Tomahawk::album_ptr& q = pi->album();
QStringList sl = filterRegExp().pattern().split( " ", QString::SkipEmptyParts );
bool found = true;
foreach( const QString& s, sl )
{
if ( !q->name().contains( s, Qt::CaseInsensitive ) )
{
found = false;
}
}
return found;
}
void
AlbumProxyModel::removeIndex( const QModelIndex& index )
{
qDebug() << Q_FUNC_INFO;
if ( !sourceModel() )
return;
if ( index.column() > 0 )
return;
sourceModel()->removeIndex( mapToSource( index ) );
}
void
AlbumProxyModel::removeIndexes( const QList<QModelIndex>& indexes )
{
if ( !sourceModel() )
return;
foreach( const QModelIndex& idx, indexes )
{
removeIndex( idx );
}
}
Tomahawk::result_ptr
AlbumProxyModel::previousItem()
{
return siblingItem( -1 );
}
Tomahawk::result_ptr
AlbumProxyModel::nextItem()
{
return siblingItem( 1 );
}
Tomahawk::result_ptr
AlbumProxyModel::siblingItem( int itemsAway )
{
qDebug() << Q_FUNC_INFO;
return Tomahawk::result_ptr();
}

View File

@ -0,0 +1,55 @@
#ifndef ALBUMPROXYMODEL_H
#define ALBUMPROXYMODEL_H
#include <QSortFilterProxyModel>
#include "tomahawk/playlistinterface.h"
#include "playlist/albummodel.h"
class AlbumProxyModel : public QSortFilterProxyModel, public PlaylistInterface
{
Q_OBJECT
public:
explicit AlbumProxyModel( QObject* parent = 0 );
virtual AlbumModel* sourceModel() const { return m_model; }
virtual void setSourceModel( AlbumModel* sourceModel );
virtual int trackCount() const { return rowCount( QModelIndex() ); }
virtual int albumCount() const { return rowCount( QModelIndex() ); }
virtual void removeIndex( const QModelIndex& index );
virtual void removeIndexes( const QList<QModelIndex>& indexes );
virtual Tomahawk::result_ptr previousItem();
virtual Tomahawk::result_ptr nextItem();
virtual Tomahawk::result_ptr siblingItem( int direction );
void setFilterRegExp( const QString& pattern );
virtual PlaylistInterface::RepeatMode repeatMode() const { return m_repeatMode; }
virtual bool shuffled() const { return m_shuffled; }
signals:
void repeatModeChanged( PlaylistInterface::RepeatMode mode );
void shuffleModeChanged( bool enabled );
void trackCountChanged( unsigned int tracks );
void filterChanged( const QString& filter );
public slots:
virtual void setRepeatMode( RepeatMode mode ) { m_repeatMode = mode; emit repeatModeChanged( mode ); }
virtual void setShuffled( bool enabled ) { m_shuffled = enabled; emit shuffleModeChanged( enabled ); }
protected:
bool filterAcceptsRow( int sourceRow, const QModelIndex& sourceParent ) const;
private:
AlbumModel* m_model;
RepeatMode m_repeatMode;
bool m_shuffled;
};
#endif // ALBUMPROXYMODEL_H

135
src/playlist/albumview.cpp Normal file
View File

@ -0,0 +1,135 @@
#include "albumview.h"
#include <QDebug>
#include <QHeaderView>
#include <QKeyEvent>
#include <QPainter>
#include <QScrollBar>
#include "tomahawk/tomahawkapp.h"
#include "audioengine.h"
#include "tomahawksettings.h"
#include "albummodel.h"
#include "albumproxymodel.h"
#include "playlistmanager.h"
using namespace Tomahawk;
AlbumView::AlbumView( QWidget* parent )
: QListView( parent )
, m_model( 0 )
, m_proxyModel( 0 )
// , m_delegate( 0 )
{
setDragEnabled( true );
setDropIndicatorShown( false );
setDragDropOverwriteMode( false );
setUniformItemSizes( true );
setSpacing( 8 );
setResizeMode( Adjust );
setViewMode( IconMode );
setIconSize( QSize( 64, 64 ) );
setProxyModel( new AlbumProxyModel( this ) );
connect( this, SIGNAL( doubleClicked( QModelIndex ) ), SLOT( onItemActivated( QModelIndex ) ) );
}
AlbumView::~AlbumView()
{
qDebug() << Q_FUNC_INFO;
}
void
AlbumView::setProxyModel( AlbumProxyModel* model )
{
m_proxyModel = model;
// m_delegate = new PlaylistItemDelegate( this, m_proxyModel );
// setItemDelegate( m_delegate );
QListView::setModel( m_proxyModel );
}
void
AlbumView::setModel( AlbumModel* model )
{
m_model = model;
if ( m_proxyModel )
m_proxyModel->setSourceModel( model );
connect( m_proxyModel, SIGNAL( filterChanged( QString ) ), SLOT( onFilterChanged( QString ) ) );
setAcceptDrops( false );
}
void
AlbumView::onItemActivated( const QModelIndex& index )
{
AlbumItem* item = m_model->itemFromIndex( m_proxyModel->mapToSource( index ) );
if ( item )
{
// qDebug() << "Result activated:" << item->album()->tracks().first()->toString() << item->album()->tracks().first()->results().first()->url();
// APP->audioEngine()->playItem( item->album().data(), item->album()->tracks().first()->results().first() );
APP->playlistManager()->show( item->album() );
}
}
void
AlbumView::dragEnterEvent( QDragEnterEvent* event )
{
qDebug() << Q_FUNC_INFO;
QListView::dragEnterEvent( event );
}
void
AlbumView::dragMoveEvent( QDragMoveEvent* event )
{
QListView::dragMoveEvent( event );
}
void
AlbumView::dropEvent( QDropEvent* event )
{
QListView::dropEvent( event );
}
void
AlbumView::paintEvent( QPaintEvent* event )
{
QListView::paintEvent( event );
}
void
AlbumView::onFilterChanged( const QString& )
{
if ( selectedIndexes().count() )
scrollTo( selectedIndexes().at( 0 ), QAbstractItemView::PositionAtCenter );
}
void
AlbumView::startDrag( Qt::DropActions supportedActions )
{
}
// Inspired from dolphin's draganddrophelper.cpp
QPixmap
AlbumView::createDragPixmap( int itemCount ) const
{
return QPixmap();
}

48
src/playlist/albumview.h Normal file
View File

@ -0,0 +1,48 @@
#ifndef ALBUMVIEW_H
#define ALBUMVIEW_H
#include <QListView>
#include <QSortFilterProxyModel>
class AlbumModel;
class AlbumProxyModel;
class AlbumView : public QListView
{
Q_OBJECT
public:
explicit AlbumView( QWidget* parent = 0 );
~AlbumView();
void setProxyModel( AlbumProxyModel* model );
AlbumModel* model() { return m_model; }
AlbumProxyModel* proxyModel() { return (AlbumProxyModel*)m_proxyModel; }
// PlaylistItemDelegate* delegate() { return m_delegate; }
void setModel( AlbumModel* model );
public slots:
void onItemActivated( const QModelIndex& index );
protected:
virtual void startDrag( Qt::DropActions supportedActions );
virtual void dragEnterEvent( QDragEnterEvent* event );
virtual void dragMoveEvent( QDragMoveEvent* event );
virtual void dropEvent( QDropEvent* event );
void paintEvent( QPaintEvent* event );
private slots:
void onFilterChanged( const QString& filter );
private:
QPixmap createDragPixmap( int itemCount ) const;
AlbumModel* m_model;
AlbumProxyModel* m_proxyModel;
// PlaylistItemDelegate* m_delegate;
};
#endif // ALBUMVIEW_H

View File

@ -4,6 +4,8 @@
#include <QMimeData>
#include <QTreeView>
#include "database.h"
using namespace Tomahawk;
@ -11,7 +13,6 @@ CollectionFlatModel::CollectionFlatModel( QObject* parent )
: TrackModel( parent )
{
qDebug() << Q_FUNC_INFO;
m_rootItem = new PlItem( 0, this );
connect( &APP->sourcelist(), SIGNAL( sourceRemoved( Tomahawk::source_ptr ) ), SLOT( onSourceOffline( Tomahawk::source_ptr ) ) );
}
@ -61,6 +62,28 @@ CollectionFlatModel::addCollection( const collection_ptr& collection )
}
void
CollectionFlatModel::addFilteredCollection( const collection_ptr& collection, unsigned int amount, DatabaseCommand_AllTracks::SortOrder order )
{
qDebug() << Q_FUNC_INFO << collection->name()
<< collection->source()->id()
<< collection->source()->userName()
<< amount << order;
emit loadingStarts();
DatabaseCommand_AllTracks* cmd = new DatabaseCommand_AllTracks( collection );
cmd->setLimit( amount );
cmd->setSortOrder( order );
cmd->setSortDescending( true );
connect( cmd, SIGNAL( tracks( QList<Tomahawk::query_ptr>, Tomahawk::collection_ptr ) ),
SLOT( onTracksAdded( QList<Tomahawk::query_ptr>, Tomahawk::collection_ptr ) ) );
TomahawkApp::instance()->database()->enqueue( QSharedPointer<DatabaseCommand>( cmd ) );
}
void
CollectionFlatModel::removeCollection( const collection_ptr& collection )
{

View File

@ -14,6 +14,8 @@
#include "tomahawk/playlist.h"
#include "tomahawk/playlistinterface.h"
#include "databasecommand_alltracks.h"
class QMetaData;
class CollectionFlatModel : public TrackModel
@ -32,6 +34,8 @@ public:
void addCollection( const Tomahawk::collection_ptr& collection );
void removeCollection( const Tomahawk::collection_ptr& collection );
void addFilteredCollection( const Tomahawk::collection_ptr& collection, unsigned int amount, DatabaseCommand_AllTracks::SortOrder order );
signals:
void repeatModeChanged( PlaylistInterface::RepeatMode mode );
void shuffleModeChanged( bool enabled );

View File

@ -9,6 +9,7 @@ using namespace Tomahawk;
CollectionModel::CollectionModel( QObject* parent )
: QAbstractItemModel( parent )
, m_rootItem( 0 )
{
qDebug() << Q_FUNC_INFO;
@ -262,3 +263,15 @@ CollectionModel::onSourceOffline( Tomahawk::source_ptr src )
removeCollection( src->collection() );
}
}
PlItem*
CollectionModel::itemFromIndex( const QModelIndex& index ) const
{
if ( index.isValid() )
return static_cast<PlItem*>( index.internalPointer() );
else
{
return m_rootItem;
}
}

View File

@ -37,11 +37,9 @@ public:
void addCollection( const Tomahawk::collection_ptr& collection );
void removeCollection( const Tomahawk::collection_ptr& collection );
// PlItem* itemFromIndex( const QModelIndex& index ) const;
virtual PlItem* previousItem() { return 0; }
virtual PlItem* nextItem() { return 0; }
virtual PlItem* siblingItem( int direction ) { return 0; }
virtual Tomahawk::result_ptr previousItem() { return Tomahawk::result_ptr(); }
virtual Tomahawk::result_ptr nextItem() { return Tomahawk::result_ptr(); }
virtual Tomahawk::result_ptr siblingItem( int direction ) { return Tomahawk::result_ptr(); }
virtual void setCurrentItem( const QModelIndex& index ) {}
@ -51,6 +49,8 @@ public:
virtual void setRepeatMode( PlaylistInterface::RepeatMode mode ) {}
virtual void setShuffled( bool shuffled ) {}
PlItem* itemFromIndex( const QModelIndex& index ) const;
signals:
void repeatModeChanged( PlaylistInterface::RepeatMode mode );
void shuffleModeChanged( bool enabled );
@ -66,6 +66,7 @@ private slots:
void onSourceOffline( Tomahawk::source_ptr src );
private:
PlItem* m_rootItem;
QMap< Tomahawk::collection_ptr, PlItem* > m_collectionIndex;
};

View File

@ -3,6 +3,7 @@
#include <QDebug>
#include <QTreeView>
#include "tomahawk/album.h"
#include "tomahawk/query.h"
#include "collectionmodel.h"
@ -41,26 +42,34 @@ CollectionProxyModel::lessThan( const QModelIndex& left, const QModelIndex& righ
unsigned int albumpos1 = 0, albumpos2 = 0;
unsigned int bitrate1 = 0, bitrate2 = 0;
unsigned int mtime1 = 0, mtime2 = 0;
unsigned int id1 = 0, id2 = 0;
if ( q1->numResults() )
{
const Tomahawk::result_ptr& r = q1->results().at( 0 );
artist1 = r->artist();
album1 = r->album();
artist1 = r->artist()->name();
album1 = r->album()->name();
track1 = r->track();
albumpos1 = r->albumpos();
bitrate1 = r->bitrate();
mtime1 = r->modificationTime();
id1 = r->dbid();
}
if ( q2->numResults() )
{
const Tomahawk::result_ptr& r = q2->results().at( 0 );
artist2 = r->artist();
album2 = r->album();
artist2 = r->artist()->name();
album2 = r->album()->name();
track2 = r->track();
albumpos2 = r->albumpos();
bitrate2 = r->bitrate();
mtime2 = r->modificationTime();
id2 = r->dbid();
}
if ( album1 == "Gern Geschehen" )
{
qDebug() << artist1 << artist2 << album1 << album2 << id1 << id2;
}
if ( left.column() == 0 ) // sort by artist
@ -71,7 +80,7 @@ CollectionProxyModel::lessThan( const QModelIndex& left, const QModelIndex& righ
{
if ( albumpos1 == albumpos2 )
{
return QString::localeAwareCompare( track1, track2 ) < 0;
return id1 < id2;
}
return albumpos1 < albumpos2;

View File

@ -9,6 +9,8 @@
#include "trackproxymodel.h"
#include "trackmodel.h"
#include "infowidgets/sourceinfowidget.h"
#define FILTER_TIMEOUT 280
PlaylistManager::PlaylistManager( QObject* parent )
@ -44,34 +46,32 @@ PlaylistManager::show( const Tomahawk::playlist_ptr& playlist )
{
unlinkPlaylist();
if ( !m_views.contains( playlist ) )
if ( !m_playlistViews.contains( playlist ) )
{
QList<PlaylistView*> views;
{
PlaylistView* view = new PlaylistView();
PlaylistModel* model = new PlaylistModel();
view->setModel( model );
views << view;
PlaylistView* view = new PlaylistView();
PlaylistModel* model = new PlaylistModel();
view->setModel( model );
m_currentProxyModel = view->proxyModel();
m_currentModel = view->model();
m_currentProxyModel = view->proxyModel();
m_currentModel = view->model();
model->loadPlaylist( playlist );
playlist->resolve();
}
model->loadPlaylist( playlist );
playlist->resolve();
m_views.insert( playlist, views );
m_widget->addWidget( views.first() );
m_widget->setCurrentWidget( views.first() );
m_currentView = views.first();
m_playlistViews.insert( playlist, view );
m_views.insert( (PlaylistInterface*)m_currentProxyModel, view );
m_widget->addWidget( view );
m_widget->setCurrentWidget( view );
m_currentView = view;
}
else
{
QList<PlaylistView*> views = m_views.value( playlist );
m_widget->setCurrentWidget( views.first() );
m_currentProxyModel = views.first()->proxyModel();
m_currentModel = views.first()->model();
m_currentView = views.first();
PlaylistView* view = m_playlistViews.value( playlist );
m_widget->setCurrentWidget( view );
m_currentProxyModel = view->proxyModel();
m_currentModel = view->model();
m_currentView = view;
}
m_superCollectionVisible = false;
@ -82,6 +82,47 @@ PlaylistManager::show( const Tomahawk::playlist_ptr& playlist )
}
bool
PlaylistManager::show( const Tomahawk::album_ptr& album )
{
qDebug() << Q_FUNC_INFO << &album << album.data();
unlinkPlaylist();
if ( !m_albumViews.contains( album ) )
{
PlaylistView* view = new PlaylistView();
PlaylistModel* model = new PlaylistModel();
view->setModel( model );
m_currentProxyModel = view->proxyModel();
m_currentModel = view->model();
model->loadAlbum( album );
m_albumViews.insert( album, view );
m_views.insert( (PlaylistInterface*)m_currentProxyModel, view );
m_widget->addWidget( view );
m_widget->setCurrentWidget( view );
m_currentView = view;
}
else
{
PlaylistView* view = m_albumViews.value( album );
m_widget->setCurrentWidget( view );
m_currentProxyModel = view->proxyModel();
m_currentModel = view->model();
m_currentView = view;
}
m_superCollectionVisible = false;
linkPlaylist();
emit numSourcesChanged( 1 );
return true;
}
bool
PlaylistManager::show( const Tomahawk::collection_ptr& collection )
{
@ -89,32 +130,29 @@ PlaylistManager::show( const Tomahawk::collection_ptr& collection )
if ( !m_collectionViews.contains( collection ) )
{
QList<CollectionView*> views;
{
CollectionView* view = new CollectionView();
CollectionFlatModel* model = new CollectionFlatModel();
view->setModel( model );
views << view;
CollectionView* view = new CollectionView();
CollectionFlatModel* model = new CollectionFlatModel();
view->setModel( model );
m_currentProxyModel = view->proxyModel();
m_currentModel = view->model();
m_currentProxyModel = view->proxyModel();
m_currentModel = view->model();
model->addCollection( collection );
// collection->loadAllTracks();
}
model->addCollection( collection );
m_collectionViews.insert( collection, views );
m_widget->addWidget( views.first() );
m_widget->setCurrentWidget( views.first() );
m_currentView = views.first();
m_collectionViews.insert( collection, view );
m_views.insert( (PlaylistInterface*)m_currentProxyModel, view );
m_widget->addWidget( view );
m_widget->setCurrentWidget( view );
m_currentView = view;
}
else
{
QList<CollectionView*> views = m_collectionViews.value( collection );
m_widget->setCurrentWidget( views.first() );
m_currentProxyModel = views.first()->proxyModel();
m_currentModel = views.first()->model();
m_currentView = views.first();
CollectionView* view = m_collectionViews.value( collection );
m_widget->setCurrentWidget( view );
m_currentProxyModel = view->proxyModel();
m_currentModel = view->model();
m_currentView = view;
}
m_superCollectionVisible = false;
@ -125,6 +163,35 @@ PlaylistManager::show( const Tomahawk::collection_ptr& collection )
}
bool
PlaylistManager::show( const Tomahawk::source_ptr& source )
{
unlinkPlaylist();
m_currentProxyModel = 0;
m_currentModel = 0;
m_currentView = 0;
if ( !m_sourceViews.contains( source ) )
{
SourceInfoWidget* swidget = new SourceInfoWidget( source );
m_currentInfoWidget = swidget;
m_widget->addWidget( m_currentInfoWidget );
m_sourceViews.insert( source, swidget );
}
else
{
m_currentInfoWidget = m_sourceViews.value( source );
}
m_widget->setCurrentWidget( m_currentInfoWidget );
m_superCollectionVisible = false;
emit numSourcesChanged( 1 );
return true;
}
bool
PlaylistManager::showSuperCollection()
{
@ -134,7 +201,6 @@ PlaylistManager::showSuperCollection()
{
m_superCollections.append( source->collection() );
m_superCollectionFlatModel->addCollection( source->collection() );
// source->collection()->loadAllTracks();
}
}
@ -142,6 +208,7 @@ PlaylistManager::showSuperCollection()
m_currentProxyModel = m_superCollectionView->proxyModel();
m_currentModel = m_superCollectionView->model();
m_currentView = m_superCollectionView;
m_views.insert( (PlaylistInterface*)m_currentProxyModel, m_superCollectionView );
m_superCollectionVisible = true;
linkPlaylist();
@ -269,28 +336,15 @@ PlaylistManager::setShuffled( bool enabled )
void
PlaylistManager::showCurrentTrack()
{
bool found = false;
PlaylistInterface* playlist = APP->audioEngine()->currentPlaylist();
foreach ( const QList<PlaylistView*>& pv, m_views.values() )
if ( m_views.contains( playlist ) )
{
if ( APP->audioEngine()->currentPlaylist() == pv.first()->proxyModel() )
{
Tomahawk::playlist_ptr pptr = m_views.key( pv );
show( pptr );
found = true;
}
}
m_currentView = m_views.value( playlist );
m_currentProxyModel = m_currentView->proxyModel();
m_currentModel = m_currentView->model();
if ( !found )
{
foreach ( const QList<CollectionView*>& pv, m_collectionViews.values() )
{
if ( APP->audioEngine()->currentPlaylist() == pv.first()->proxyModel() )
{
Tomahawk::collection_ptr cptr = m_collectionViews.key( pv );
show( cptr );
}
}
m_widget->setCurrentWidget( m_currentView );
}
if ( m_currentView && m_currentProxyModel )

View File

@ -15,6 +15,7 @@ class PlaylistView;
class TrackProxyModel;
class TrackModel;
class TrackView;
class SourceInfoWidget;
class PlaylistManager : public QObject
{
@ -28,10 +29,12 @@ public:
bool isSuperCollectionVisible() const { return true; }
QList<PlaylistView*> views( const Tomahawk::playlist_ptr& playlist ) { return m_views.value( playlist ); }
// QList<PlaylistView*> views( const Tomahawk::playlist_ptr& playlist ) { return m_views.value( playlist ); }
bool show( const Tomahawk::playlist_ptr& playlist );
bool show( const Tomahawk::album_ptr& album );
bool show( const Tomahawk::collection_ptr& collection );
bool show( const Tomahawk::source_ptr& source );
bool showSuperCollection();
void showCurrentTrack();
@ -69,13 +72,18 @@ private:
QList< Tomahawk::collection_ptr > m_superCollections;
QHash< Tomahawk::collection_ptr, QList<CollectionView*> > m_collectionViews;
QHash< Tomahawk::playlist_ptr, QList<PlaylistView*> > m_views;
QHash< PlaylistInterface*, TrackView* > m_views;
QHash< Tomahawk::collection_ptr, CollectionView* > m_collectionViews;
QHash< Tomahawk::playlist_ptr, PlaylistView* > m_playlistViews;
QHash< Tomahawk::album_ptr, PlaylistView* > m_albumViews;
QHash< Tomahawk::source_ptr, SourceInfoWidget* > m_sourceViews;
TrackProxyModel* m_currentProxyModel;
TrackModel* m_currentModel;
TrackView* m_currentView;
QWidget* m_currentInfoWidget;
int m_currentMode;
bool m_superCollectionVisible;

View File

@ -4,6 +4,8 @@
#include <QMimeData>
#include <QTreeView>
#include "tomahawk/album.h"
using namespace Tomahawk;
@ -12,7 +14,6 @@ PlaylistModel::PlaylistModel( QObject* parent )
, m_waitForUpdate( false )
{
qDebug() << Q_FUNC_INFO;
m_rootItem = new PlItem( 0, this );
}
@ -85,6 +86,61 @@ PlaylistModel::loadPlaylist( const Tomahawk::playlist_ptr& playlist )
}
void
PlaylistModel::loadAlbum( const Tomahawk::album_ptr& album )
{
if ( album.isNull() )
return;
if ( rowCount( QModelIndex() ) )
{
emit beginRemoveRows( QModelIndex(), 0, rowCount( QModelIndex() ) - 1 );
delete m_rootItem;
emit endRemoveRows();
m_rootItem = new PlItem( 0, this );
}
m_playlist.clear();
setReadOnly( false );
connect( album.data(), SIGNAL( tracksAdded( QList<Tomahawk::query_ptr>, Tomahawk::collection_ptr ) ),
SLOT( onTracksAdded( QList<Tomahawk::query_ptr>, Tomahawk::collection_ptr ) ) );
onTracksAdded( album->tracks(), album->collection() );
}
void
PlaylistModel::onTracksAdded( const QList<Tomahawk::query_ptr>& tracks, const Tomahawk::collection_ptr& collection )
{
if ( !tracks.count() )
return;
int c = rowCount( QModelIndex() );
QPair< int, int > crows;
crows.first = c;
crows.second = c + tracks.count() - 1;
emit beginInsertRows( QModelIndex(), crows.first, crows.second );
PlItem* plitem;
foreach( const query_ptr& query, tracks )
{
plentry_ptr entry = plentry_ptr( new PlaylistEntry() );
entry->setQuery( query );
plitem = new PlItem( entry, m_rootItem );
plitem->index = createIndex( m_rootItem->children.count() - 1, 0, plitem );
connect( plitem, SIGNAL( dataChanged() ), SLOT( onDataChanged() ) );
}
emit endInsertRows();
emit trackCountChanged( rowCount( QModelIndex() ) );
qDebug() << rowCount( QModelIndex() );
}
void
PlaylistModel::onDataChanged()
{
@ -179,7 +235,13 @@ PlaylistModel::onPlaylistChanged()
{
qDebug() << Q_FUNC_INFO;
if ( m_playlist.isNull() )
return;
QList<plentry_ptr> l = playlistEntries();
if ( !l.count() )
return;
foreach( const plentry_ptr& ple, l )
{
qDebug() << "updateinternal:" << ple->query()->toString();

View File

@ -31,6 +31,7 @@ public:
virtual bool dropMimeData( const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent );
void loadPlaylist( const Tomahawk::playlist_ptr& playlist );
void loadAlbum( const Tomahawk::album_ptr& album );
virtual void removeIndex( const QModelIndex& index );
@ -49,6 +50,8 @@ private slots:
void onRevisionLoaded( Tomahawk::PlaylistRevision revision );
void onPlaylistChanged();
void onTracksAdded( const QList<Tomahawk::query_ptr>& tracks, const Tomahawk::collection_ptr& collection );
private:
QList<Tomahawk::plentry_ptr> playlistEntries() const;

View File

@ -24,6 +24,15 @@ PlaylistView::~PlaylistView()
}
void
PlaylistView::setModel( TrackModel* model )
{
TrackView::setModel( model );
// setColumnHidden( 5, true ); // Hide age column per default
}
void
PlaylistView::setupMenus()
{

View File

@ -14,6 +14,8 @@ public:
explicit PlaylistView( QWidget* parent = 0 );
~PlaylistView();
void setModel( TrackModel* model );
protected:
virtual void keyPressEvent( QKeyEvent* event );

View File

@ -6,7 +6,8 @@
#include <QAbstractItemModel>
#include "tomahawk/query.h"
#include "tomahawk/result.h"
#include "tomahawk/typedefs.h"
class PlItem : public QObject
{

View File

@ -5,12 +5,14 @@
#include <QTreeView>
#include "tomahawk/tomahawkapp.h"
#include "tomahawk/album.h"
using namespace Tomahawk;
TrackModel::TrackModel( QObject* parent )
: QAbstractItemModel( parent )
, m_rootItem( new PlItem( 0, this ) )
, m_readOnly( true )
{
qDebug() << Q_FUNC_INFO;
@ -140,7 +142,7 @@ TrackModel::data( const QModelIndex& index, int role ) const
switch( index.column() )
{
case 0:
return query->results().first()->artist();
return query->results().first()->artist()->name();
break;
case 1:
@ -148,7 +150,7 @@ TrackModel::data( const QModelIndex& index, int role ) const
break;
case 2:
return query->results().first()->album();
return query->results().first()->album()->name();
break;
case 3:
@ -293,3 +295,15 @@ TrackModel::removeIndexes( const QList<QModelIndex>& indexes )
removeIndex( idx );
}
}
PlItem*
TrackModel::itemFromIndex( const QModelIndex& index ) const
{
if ( index.isValid() )
return static_cast<PlItem*>( index.internalPointer() );
else
{
return m_rootItem;
}
}

View File

@ -4,6 +4,7 @@
#include <QAbstractItemModel>
#include "tomahawk/playlistinterface.h"
#include "playlist/plitem.h"
class QMetaData;
@ -12,6 +13,16 @@ class TrackModel : public QAbstractItemModel, public PlaylistInterface
Q_OBJECT
public:
enum Columns {
Artist = 0,
Track = 1,
Album = 2,
Duration = 3,
Bitrate = 4,
Age = 5,
Origin = 6
};
explicit TrackModel( QObject* parent = 0 );
virtual ~TrackModel();
@ -31,9 +42,9 @@ public:
virtual void removeIndex( const QModelIndex& index );
virtual void removeIndexes( const QList<QModelIndex>& indexes );
virtual PlItem* previousItem() { return 0; }
virtual PlItem* nextItem() { return 0; }
virtual PlItem* siblingItem( int direction ) { return 0; }
virtual Tomahawk::result_ptr previousItem() { return Tomahawk::result_ptr(); }
virtual Tomahawk::result_ptr nextItem() { return Tomahawk::result_ptr(); }
virtual Tomahawk::result_ptr siblingItem( int direction ) { return Tomahawk::result_ptr(); }
virtual QMimeData* mimeData( const QModelIndexList& indexes ) const;
virtual QStringList mimeTypes() const;
@ -45,7 +56,14 @@ public:
virtual PlaylistInterface::RepeatMode repeatMode() const { return PlaylistInterface::NoRepeat; }
virtual bool shuffled() const { return false; }
PlItem* itemFromIndex( const QModelIndex& index ) const;
PlItem* m_rootItem;
signals:
void repeatModeChanged( PlaylistInterface::RepeatMode mode );
void shuffleModeChanged( bool enabled );
void trackCountChanged( unsigned int tracks );
public slots:

View File

@ -3,6 +3,7 @@
#include <QDebug>
#include <QTreeView>
#include "tomahawk/album.h"
#include "tomahawk/query.h"
#include "collectionmodel.h"
@ -43,27 +44,26 @@ TrackProxyModel::setFilterRegExp( const QString& pattern )
}
PlItem*
Tomahawk::result_ptr
TrackProxyModel::previousItem()
{
return siblingItem( -1 );
}
PlItem*
Tomahawk::result_ptr
TrackProxyModel::nextItem()
{
return siblingItem( 1 );
}
PlItem*
Tomahawk::result_ptr
TrackProxyModel::siblingItem( int itemsAway )
{
qDebug() << Q_FUNC_INFO;
QModelIndex idx = index( 0, 0 );
if( rowCount() )
{
if ( m_shuffled )
@ -114,7 +114,7 @@ TrackProxyModel::siblingItem( int itemsAway )
{
qDebug() << "Next PlaylistItem found:" << item->query()->toString() << item->query()->results().at( 0 )->url();
setCurrentItem( idx );
return item;
return item->query()->results().at( 0 );
}
idx = index( idx.row() + ( itemsAway > 0 ? 1 : -1 ), 0 );
@ -122,7 +122,7 @@ TrackProxyModel::siblingItem( int itemsAway )
while ( idx.isValid() );
setCurrentItem( QModelIndex() );
return 0;
return Tomahawk::result_ptr();
}
@ -148,8 +148,8 @@ TrackProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex& sourceParen
{
if ( !r.isNull() )
{
if ( !r->artist().contains( s, Qt::CaseInsensitive ) &&
!r->album() .contains( s, Qt::CaseInsensitive ) &&
if ( !r->artist()->name().contains( s, Qt::CaseInsensitive ) &&
!r->album()->name().contains( s, Qt::CaseInsensitive ) &&
!r->track() .contains( s, Qt::CaseInsensitive ) )
{
found = false;

View File

@ -24,15 +24,17 @@ public:
virtual void removeIndex( const QModelIndex& index );
virtual void removeIndexes( const QList<QModelIndex>& indexes );
virtual PlItem* previousItem();
virtual PlItem* nextItem();
virtual PlItem* siblingItem( int itemsAway );
virtual Tomahawk::result_ptr previousItem();
virtual Tomahawk::result_ptr nextItem();
virtual Tomahawk::result_ptr siblingItem( int itemsAway );
void setFilterRegExp( const QString& pattern );
virtual PlaylistInterface::RepeatMode repeatMode() const { return m_repeatMode; }
virtual bool shuffled() const { return m_shuffled; }
PlItem* itemFromIndex( const QModelIndex& index ) const { return sourceModel()->itemFromIndex( index ); }
signals:
void repeatModeChanged( PlaylistInterface::RepeatMode mode );
void shuffleModeChanged( bool enabled );

View File

@ -125,7 +125,7 @@ TrackView::onSectionResized( int logicalIndex, int oldSize, int newSize )
void
TrackView::onItemActivated( const QModelIndex& index )
{
PlItem* item = ((PlaylistInterface*)m_model)->itemFromIndex( m_proxyModel->mapToSource( index ) );
PlItem* item = m_model->itemFromIndex( m_proxyModel->mapToSource( index ) );
if ( item && item->query()->numResults() )
{
qDebug() << "Result activated:" << item->query()->toString() << item->query()->results().first()->url();

View File

@ -1,5 +1,7 @@
#include "tomahawk/result.h"
#include "tomahawk/album.h"
using namespace Tomahawk;
@ -9,8 +11,8 @@ Result::Result( const QVariant& v, const collection_ptr& collection )
{
QVariantMap m = m_v.toMap();
m_artist = m.value( "artist" ).toString();
m_album = m.value( "album" ).toString();
m_artist = artist_ptr( new Artist( m.value( "artist" ).toString() ) );
m_album = Album::get( m.value( "albumid" ).toUInt(), m.value( "album" ).toString(), m_artist, collection );
m_track = m.value( "track" ).toString();
m_url = m.value( "url" ).toString();
m_mimetype = m.value( "mimetype" ).toString();
@ -21,6 +23,8 @@ Result::Result( const QVariant& v, const collection_ptr& collection )
m_albumpos = m.value( "albumpos" ).toUInt();
m_modtime = m.value( "mtime" ).toUInt();
m_id = m.value( "id" ).toUInt();
if ( !m_collection.isNull() )
connect( m_collection->source().data(), SIGNAL( offline() ), SIGNAL( becomingUnavailable() ), Qt::QueuedConnection );
}
@ -42,3 +46,10 @@ Result::id() const
}
return m_rid;
};
QString
Result::toString() const
{
return QString( "Result(%1 %2\t%3 - %4 %5" ).arg( id() ).arg( score() ).arg( artist()->name() ).arg( track() ).arg( url() );
}

View File

@ -5,6 +5,7 @@
#include <QCryptographicHash>
#include <tomahawk/tomahawkapp.h>
#include "tomahawk/album.h"
#include "tomahawk/typedefs.h"
#include "audio/audioengine.h"
#include "tomahawksettings.h"
@ -81,8 +82,8 @@ Scrobbler::trackStarted( const Tomahawk::result_ptr& track )
m_track.stamp();
m_track.setTitle( track->track() );
m_track.setArtist( track->artist() );
m_track.setAlbum( track->album() );
m_track.setArtist( track->artist()->name() );
m_track.setAlbum( track->album()->name() );
m_track.setDuration( track->duration() );
m_track.setSource( lastfm::Track::Player );

View File

@ -3,9 +3,11 @@
#include "ui_sourcetreeitemwidget.h"
#include "tomahawk/tomahawkapp.h"
#include "tomahawk/album.h"
#include "database.h"
#include "databasecommand_collectionstats.h"
#include "dbsyncconnection.h"
#include "playlistmanager.h"
using namespace Tomahawk;
@ -27,6 +29,8 @@ SourceTreeItemWidget::SourceTreeItemWidget( const source_ptr& source, QWidget* p
displayname = tr( "Super Collection" );
ui->infoLabel->setText( tr( "All available tracks" ) );
ui->onOffButton->hide();
}
else
{
@ -42,12 +46,16 @@ SourceTreeItemWidget::SourceTreeItemWidget( const source_ptr& source, QWidget* p
displayname = source->userName();
ui->infoLabel->setText( "???" );
ui->onOffButton->hide();
ui->infoButton->setPixmap( RESPATH "images/source-info.png" );
}
ui->nameLabel->setText( displayname );
ui->infoLabel->setForegroundRole( QPalette::Dark );
connect( ui->onOffButton, SIGNAL( clicked() ), SIGNAL( clicked() ) );
connect( ui->infoButton, SIGNAL( clicked() ), SLOT( onInfoButtonClicked() ) );
onOffline();
}
@ -119,6 +127,8 @@ SourceTreeItemWidget::onLoadingStateChanged( DBSyncConnection::State newstate, D
void
SourceTreeItemWidget::onOnline()
{
return;
if ( !m_source.isNull() )
ui->onOffButton->setPixmap( RESPATH "images/source-on-rest.png" );
}
@ -127,6 +137,15 @@ SourceTreeItemWidget::onOnline()
void
SourceTreeItemWidget::onOffline()
{
return;
if ( !m_source.isNull() )
ui->onOffButton->setPixmap( RESPATH "images/source-off-rest.png" );
}
void
SourceTreeItemWidget::onInfoButtonClicked()
{
APP->playlistManager()->show( m_source );
}

View File

@ -32,6 +32,8 @@ private slots:
void gotStats( const QVariantMap& stats );
void onLoadingStateChanged( DBSyncConnection::State newstate, DBSyncConnection::State oldstate, const QString& info );
void onInfoButtonClicked();
private:
Tomahawk::source_ptr m_source;

View File

@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>298</width>
<width>359</width>
<height>44</height>
</rect>
</property>
@ -32,15 +32,6 @@
<string>Form</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="topMargin">
<number>1</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>1</number>
</property>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
@ -156,6 +147,34 @@
</property>
</widget>
</item>
<item>
<widget class="ImageButton" name="infoButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>56</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>56</width>
<height>16777215</height>
</size>
</property>
<property name="cursor">
<cursorShape>PointingHandCursor</cursorShape>
</property>
<property name="text">
<string>Info</string>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>

View File

@ -133,16 +133,9 @@ SourceTreeView::onItemActivated( const QModelIndex& index )
else
{
qDebug() << "SourceTreeItem toggled:" << item->source()->userName();
APP->playlistManager()->show( item->source()->collection() );
/*if ( APP->playlistManager()->superCollections().contains( item->source()->collection() ) )
{
emit onOnline( index );
}
else
{
emit onOffline( index );
}*/
APP->playlistManager()->show( item->source()->collection() );
// APP->playlistManager()->show( item->source() );
}
}
}

View File

@ -6,6 +6,8 @@
#include <QTime>
#include <QNetworkReply>
#include "tomahawk/artist.h"
#include "tomahawk/album.h"
#include "tomahawk/collection.h"
#include "tomahawk/infosystem.h"
#include "database/database.h"
@ -282,6 +284,8 @@ TomahawkApp::registerMetaTypes()
qRegisterMetaType< QList<Tomahawk::plentry_ptr> >("QList<Tomahawk::plentry_ptr>");
qRegisterMetaType< QList<Tomahawk::query_ptr> >("QList<Tomahawk::query_ptr>");
qRegisterMetaType< QList<Tomahawk::result_ptr> >("QList<Tomahawk::result_ptr>");
qRegisterMetaType< QList<Tomahawk::artist_ptr> >("QList<Tomahawk::artist_ptr>");
qRegisterMetaType< QList<Tomahawk::album_ptr> >("QList<Tomahawk::album_ptr>");
qRegisterMetaType< QMap< QString, Tomahawk::plentry_ptr > >("QMap< QString, Tomahawk::plentry_ptr >");
qRegisterMetaType< Tomahawk::PlaylistRevision >("Tomahawk::PlaylistRevision");
qRegisterMetaType< Tomahawk::QID >("Tomahawk::QID");

View File

@ -301,7 +301,7 @@ TomahawkWindow::setWindowTitle( const QString& title )
QMainWindow::setWindowTitle( title );
else
{
QString s = m_currentTrack->track() + " " + tr( "by" ) + " " + m_currentTrack->artist();
QString s = m_currentTrack->track() + " " + tr( "by" ) + " " + m_currentTrack->artist()->name();
QMainWindow::setWindowTitle( s + " - " + title );
}
}
@ -310,5 +310,5 @@ TomahawkWindow::setWindowTitle( const QString& title )
void
TomahawkWindow::showAboutTomahawk()
{
QMessageBox::about( this, "About Tomahawk", "Copyright 2010 Christian Muehlhaeuser <muesli@gmail.com>\nThanks to: Leo Franchi, Dominik Schmidt and Steve Robertson" );
QMessageBox::about( this, "About Tomahawk", "Copyright 2010 Christian Muehlhaeuser <muesli@gmail.com>\n\nThanks to: Leo Franchi, Jeff Mitchell, Dominik Schmidt and Steve Robertson" );
}

View File

@ -2,6 +2,7 @@
#include "tomahawk/tomahawkapp.h"
#include "tomahawk/infosystem.h"
#include "tomahawk/album.h"
#include "tomahawk/typedefs.h"
#include <tomahawksettings.h>
#include <audio/audioengine.h>
@ -72,9 +73,9 @@ void XMPPBot::newTrackSlot(const Tomahawk::result_ptr &track)
if (!track)
return;
QString status = QString("%1 - %2 (%3)")
.arg(track->artist())
.arg(track->artist()->name())
.arg(track->track())
.arg(track->album());
.arg(track->album()->name());
m_client.data()->setPresence(Presence::Available, 1, status.toStdString());
}
@ -180,7 +181,7 @@ void XMPPBot::handleMessage(const Message& msg, MessageSession* session)
qDebug() << "jid from:" << QString::fromStdString(msg.from().full()) << ", jid to:" << QString::fromStdString(msg.to().full());
qDebug() << "Operating on tokens:" << tokens;
if (m_currTrack.isNull() || m_currTrack->artist().isEmpty() || m_currTrack->track().isEmpty())
if (m_currTrack.isNull() || m_currTrack->artist()->name().isEmpty() || m_currTrack->track().isEmpty())
{
qDebug() << "XMPPBot can't figure out track";
QString m_currReturnMessage("\n\nSorry, I can't figure out what track is playing.\n\n");
@ -193,18 +194,18 @@ void XMPPBot::handleMessage(const Message& msg, MessageSession* session)
Q_FOREACH(QString token, tokens)
{
if (token == "biography")
infoMap[InfoArtistBiography] = m_currTrack.data()->artist();
infoMap[InfoArtistBiography] = m_currTrack.data()->artist()->name();
if (token == "terms")
infoMap[InfoArtistTerms] = m_currTrack.data()->artist();
infoMap[InfoArtistTerms] = m_currTrack.data()->artist()->name();
if (token == "hotttness")
infoMap[InfoArtistHotttness] = m_currTrack.data()->artist();
infoMap[InfoArtistHotttness] = m_currTrack.data()->artist()->name();
if (token == "familiarity")
infoMap[InfoArtistFamiliarity] = m_currTrack.data()->artist();
infoMap[InfoArtistFamiliarity] = m_currTrack.data()->artist()->name();
if (token == "lyrics")
{
MusixMatchHash myhash;
myhash["trackName"] = m_currTrack.data()->track();
myhash["artistName"] = m_currTrack.data()->artist();
myhash["artistName"] = m_currTrack.data()->artist()->name();
infoMap[InfoTrackLyrics] = QVariant::fromValue<Tomahawk::InfoSystem::MusixMatchHash>(myhash);
}
}