1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-03-21 00:09:47 +01:00

* PlayableModel is now capable of dealing with trees.

This commit is contained in:
Christian Muehlhaeuser 2012-05-31 21:22:18 +02:00
parent 623850a281
commit 751f029564
2 changed files with 273 additions and 57 deletions

View File

@ -42,9 +42,16 @@ PlayableModel::PlayableModel( QObject* parent )
, m_rootItem( new PlayableItem( 0, this ) )
, m_readOnly( true )
, m_style( Detailed )
, m_loading( false )
{
connect( AudioEngine::instance(), SIGNAL( started( Tomahawk::result_ptr ) ), SLOT( onPlaybackStarted( Tomahawk::result_ptr ) ), Qt::DirectConnection );
connect( AudioEngine::instance(), SIGNAL( stopped() ), SLOT( onPlaybackStopped() ), Qt::DirectConnection );
m_header << tr( "Artist" ) << tr( "Title" ) << tr( "Composer" ) << tr( "Album" ) << tr( "Track" ) << tr( "Duration" )
<< tr( "Bitrate" ) << tr( "Age" ) << tr( "Year" ) << tr( "Size" ) << tr( "Origin" ) << tr( "Score" ) << tr( "Name" );
m_headerStyle[ Detailed ] << Artist << Track << Composer << Album << AlbumPos << Duration << Bitrate << Age << Year << Filesize << Origin << Score;
m_headerStyle[ Collection ] << Name << Composer << Duration << Bitrate << Age << Year << Filesize << Origin;
}
@ -95,6 +102,10 @@ PlayableModel::columnCount( const QModelIndex& parent ) const
return 1;
break;
case Collection:
return 8;
break;
case Detailed:
default:
return 12;
@ -103,6 +114,20 @@ PlayableModel::columnCount( const QModelIndex& parent ) const
}
bool
PlayableModel::hasChildren( const QModelIndex& parent ) const
{
PlayableItem* parentItem = itemFromIndex( parent );
if ( !parentItem )
return false;
if ( parentItem == m_rootItem )
return true;
return ( !parentItem->artist().isNull() || !parentItem->album().isNull() );
}
QModelIndex
PlayableModel::parent( const QModelIndex& child ) const
{
@ -124,42 +149,50 @@ PlayableModel::parent( const QModelIndex& child ) const
QVariant
PlayableModel::data( const QModelIndex& index, int role ) const
PlayableModel::artistData( const artist_ptr& artist, int role ) const
{
PlayableItem* entry = itemFromIndex( index );
if ( !entry )
return QVariant();
if ( role == Qt::DecorationRole )
{
return QVariant();
}
if ( role == Qt::SizeHintRole )
{
return QSize( 0, 18 );
}
if ( role == Qt::TextAlignmentRole )
{
return QVariant( columnAlignment( index.column() ) );
}
if ( role == StyleRole )
{
return m_style;
}
return QSize( 0, 44 );
if ( role != Qt::DisplayRole ) // && role != Qt::ToolTipRole )
return QVariant();
const query_ptr& query = entry->query()->displayQuery();
switch( index.column() )
return artist->name();
}
QVariant
PlayableModel::albumData( const album_ptr& album, int role ) const
{
if ( role == Qt::SizeHintRole )
return QSize( 0, 32 );
if ( role != Qt::DisplayRole ) // && role != Qt::ToolTipRole )
return QVariant();
return album->name();
}
QVariant
PlayableModel::queryData( const query_ptr& query, int column, int role ) const
{
if ( role == Qt::SizeHintRole )
return QSize( 0, 18 );
if ( role != Qt::DisplayRole ) // && role != Qt::ToolTipRole )
return QVariant();
if ( !m_headerStyle.contains( m_style ) )
return query->track();
switch( m_headerStyle[ m_style ].at( column ) )
{
case Artist:
return query->artist();
break;
case Name:
case Track:
return query->track();
break;
@ -191,7 +224,7 @@ PlayableModel::data( const QModelIndex& index, int role ) const
}
if ( query->numResults() )
{
switch( index.column() )
switch( m_headerStyle[ m_style ].at( column ) )
{
case Bitrate:
if ( query->results().first()->bitrate() > 0 )
@ -225,16 +258,58 @@ PlayableModel::data( const QModelIndex& index, int role ) const
}
QVariant
PlayableModel::data( const QModelIndex& index, int role ) const
{
PlayableItem* entry = itemFromIndex( index );
if ( !entry )
return QVariant();
if ( role == Qt::DecorationRole )
{
return QVariant();
}
if ( role == Qt::TextAlignmentRole )
{
return QVariant( columnAlignment( index.column() ) );
}
if ( role == StyleRole )
{
return m_style;
}
if ( !entry->query().isNull() )
{
return queryData( entry->query()->displayQuery(), index.column(), role );
}
else if ( !entry->artist().isNull() )
{
return artistData( entry->artist(), role );
}
else if ( !entry->album().isNull() )
{
return albumData( entry->album(), role );
}
return QVariant();
}
QVariant
PlayableModel::headerData( int section, Qt::Orientation orientation, int role ) const
{
Q_UNUSED( orientation );
QStringList headers;
headers << tr( "Artist" ) << tr( "Title" ) << tr( "Composer" ) << tr( "Album" ) << tr( "Track" ) << tr( "Duration" ) << tr( "Bitrate" ) << tr( "Age" ) << tr( "Year" ) << tr( "Size" ) << tr( "Origin" ) << tr( "Score" );
if ( role == Qt::DisplayRole && section >= 0 )
{
return headers.at( section );
if ( m_headerStyle.contains( m_style ) )
{
return m_header.at( m_headerStyle[ m_style ].at( section ) );
}
else
return tr( "Name" );
}
if ( role == Qt::TextAlignmentRole )
@ -315,7 +390,7 @@ QStringList
PlayableModel::mimeTypes() const
{
QStringList types;
types << "application/tomahawk.query.list";
types << "application/tomahawk.mixed";
return types;
}
@ -325,26 +400,134 @@ PlayableModel::mimeData( const QModelIndexList &indexes ) const
{
qDebug() << Q_FUNC_INFO;
QByteArray queryData;
QDataStream queryStream( &queryData, QIODevice::WriteOnly );
QByteArray resultData;
QDataStream resultStream( &resultData, QIODevice::WriteOnly );
foreach ( const QModelIndex& i, indexes )
// lets try with artist only
bool fail = false;
foreach ( const QModelIndex& i, indexes)
{
if ( i.column() > 0 )
if ( i.column() > 0 || indexes.contains( i.parent() ) )
continue;
QModelIndex idx = index( i.row(), 0, i.parent() );
PlayableItem* item = itemFromIndex( idx );
if ( item )
PlayableItem* item = itemFromIndex( i );
if ( !item )
continue;
if ( !item->artist().isNull() )
{
const artist_ptr& artist = item->artist();
resultStream << artist->name();
}
else
{
fail = true;
break;
}
}
if ( !fail )
{
QMimeData* mimeData = new QMimeData();
mimeData->setData( "application/tomahawk.metadata.artist", resultData );
return mimeData;
}
// lets try with album only
fail = false;
resultData.clear();
foreach ( const QModelIndex& i, indexes )
{
if ( i.column() > 0 || indexes.contains( i.parent() ) )
continue;
PlayableItem* item = itemFromIndex( i );
if ( !item )
continue;
if ( !item->album().isNull() )
{
const album_ptr& album = item->album();
resultStream << album->artist()->name();
resultStream << album->name();
}
else
{
fail = true;
break;
}
}
if ( !fail )
{
QMimeData* mimeData = new QMimeData();
mimeData->setData( "application/tomahawk.metadata.album", resultData );
return mimeData;
}
// lets try with tracks only
fail = false;
resultData.clear();
foreach ( const QModelIndex& i, indexes )
{
if ( i.column() > 0 || indexes.contains( i.parent() ) )
continue;
PlayableItem* item = itemFromIndex( i );
if ( !item )
continue;
if ( !item->result().isNull() )
{
const result_ptr& result = item->result();
resultStream << qlonglong( &result );
}
else
{
fail = true;
break;
}
}
if ( !fail )
{
QMimeData* mimeData = new QMimeData();
mimeData->setData( "application/tomahawk.result.list", resultData );
return mimeData;
}
// Ok... we have to use mixed
resultData.clear();
foreach ( const QModelIndex& i, indexes )
{
if ( i.column() > 0 || indexes.contains( i.parent() ) )
continue;
PlayableItem* item = itemFromIndex( i );
if ( !item )
continue;
if ( !item->artist().isNull() )
{
const artist_ptr& artist = item->artist();
resultStream << QString( "application/tomahawk.metadata.artist" ) << artist->name();
}
else if ( !item->album().isNull() )
{
const album_ptr& album = item->album();
resultStream << QString( "application/tomahawk.metadata.album" ) << album->artist()->name() << album->name();
}
else if ( !item->result().isNull() )
{
const result_ptr& result = item->result();
resultStream << QString( "application/tomahawk.result.list" ) << qlonglong( &result );
}
else if ( !item->result().isNull() )
{
const query_ptr& query = item->query();
queryStream << qlonglong( &query );
resultStream << QString( "application/tomahawk.query.list" ) << qlonglong( &query );
}
}
QMimeData* mimeData = new QMimeData();
mimeData->setData( "application/tomahawk.query.list", queryData );
mimeData->setData( "application/tomahawk.mixed", resultData );
return mimeData;
}
@ -354,7 +537,7 @@ PlayableModel::clear()
{
if ( rowCount( QModelIndex() ) )
{
emit loadingFinished();
finishLoading();
emit beginResetModel();
delete m_rootItem;
@ -508,20 +691,6 @@ PlayableModel::remove( const QList<QPersistentModelIndex>& indexes )
}
PlayableItem*
PlayableModel::itemFromIndex( const QModelIndex& index ) const
{
if ( index.isValid() )
{
return static_cast<PlayableItem*>( index.internalPointer() );
}
else
{
return m_rootItem;
}
}
void
PlayableModel::onPlaybackStarted( const Tomahawk::result_ptr& result )
{
@ -591,3 +760,33 @@ PlayableModel::onDataChanged()
if ( p && p->index.isValid() )
emit dataChanged( p->index, p->index.sibling( p->index.row(), columnCount() - 1 ) );
}
void
PlayableModel::startLoading()
{
m_loading = true;
emit loadingStarted();
}
void
PlayableModel::finishLoading()
{
m_loading = false;
emit loadingFinished();
}
PlayableItem*
PlayableModel::itemFromIndex( const QModelIndex& index ) const
{
if ( index.isValid() )
{
return static_cast<PlayableItem*>( index.internalPointer() );
}
else
{
return m_rootItem;
}
}

View File

@ -22,6 +22,7 @@
#define PLAYABLEMODEL_H
#include <QAbstractItemModel>
#include <QPixmap>
#include "PlaylistInterface.h"
#include "Typedefs.h"
@ -38,7 +39,7 @@ Q_OBJECT
public:
enum PlayableItemStyle
{ Detailed = 0, Short = 1, ShortWithAvatars = 2, Large = 3 };
{ Detailed = 0, Short = 1, ShortWithAvatars = 2, Large = 3, Collection = 4 };
enum PlayableModelRole
{ StyleRole = Qt::UserRole + 1 };
@ -55,7 +56,8 @@ public:
Year = 8,
Filesize = 9,
Origin = 10,
Score = 11
Score = 11,
Name = 12
};
explicit PlayableModel( QObject* parent = 0 );
@ -69,19 +71,27 @@ public:
virtual bool isReadOnly() const { return m_readOnly; }
virtual void setReadOnly( bool b ) { m_readOnly = b; }
virtual bool isLoading() const { return m_loading; }
virtual QString title() const { return m_title; }
virtual void setTitle( const QString& title ) { m_title = title; }
virtual QString description() const { return m_description; }
virtual void setDescription( const QString& description ) { m_description = description; }
virtual QPixmap icon() const { return m_icon; }
virtual void setIcon( const QPixmap& pixmap ) { m_icon = pixmap; }
virtual int trackCount() const { return rowCount( QModelIndex() ); }
virtual int rowCount( const QModelIndex& parent ) const;
virtual int columnCount( const QModelIndex& parent = QModelIndex() ) const;
virtual bool hasChildren( 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 QVariant artistData( const Tomahawk::artist_ptr& artist, int role = Qt::DisplayRole ) const;
virtual QVariant albumData( const Tomahawk::album_ptr& album, int role = Qt::DisplayRole ) const;
virtual QVariant queryData( const Tomahawk::query_ptr&, int column, int role = Qt::DisplayRole ) const;
virtual QMimeData* mimeData( const QModelIndexList& indexes ) const;
virtual QStringList mimeTypes() const;
@ -134,6 +144,8 @@ public slots:
protected:
PlayableItem* rootItem() const { return m_rootItem; }
void startLoading();
void finishLoading();
private slots:
void onDataChanged();
@ -152,8 +164,13 @@ private:
QString m_title;
QString m_description;
QPixmap m_icon;
QHash< PlayableItemStyle, QList<Columns> > m_headerStyle;
QStringList m_header;
PlayableItemStyle m_style;
bool m_loading;
};
#endif // PLAYABLEMODEL_H