diff --git a/src/libtomahawk/playlist/PlayableModel.cpp b/src/libtomahawk/playlist/PlayableModel.cpp
index 5a6206399..e3a6c66db 100644
--- a/src/libtomahawk/playlist/PlayableModel.cpp
+++ b/src/libtomahawk/playlist/PlayableModel.cpp
@@ -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;
+    }
+}
diff --git a/src/libtomahawk/playlist/PlayableModel.h b/src/libtomahawk/playlist/PlayableModel.h
index 7ee0f763c..28db6a001 100644
--- a/src/libtomahawk/playlist/PlayableModel.h
+++ b/src/libtomahawk/playlist/PlayableModel.h
@@ -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