[amarok] src: Enable drag and drop tracks to any collection.

Bart Cerneels bart.cerneels at kde.org
Wed Jun 8 16:36:44 CEST 2011


Git commit fffc1ea983281e6cb1f6ce2129f046e598fe01c4 by Bart Cerneels.
Committed on 07/06/2011 at 09:43.
Pushed by shanachie into branch 'master'.

Enable drag and drop tracks to any collection.

Works inside the collection browser and from The Playlist.
Tested to/from USB, iPod and MySQL-collections.

funds += €250 http://mail.kde.org/pipermail/amarok-devel/2011-May/009047.html ?

BUG:223400
CCMAIL:amarok-devel at kde.org

M  +64   -0    src/browsers/CollectionTreeItemModel.cpp     
M  +4    -1    src/browsers/CollectionTreeItemModel.h     
M  +1    -1    src/browsers/CollectionTreeView.cpp     
M  +1    -1    src/core/collections/CollectionLocation.cpp     

http://commits.kde.org/amarok/fffc1ea983281e6cb1f6ce2129f046e598fe01c4

diff --git a/src/browsers/CollectionTreeItemModel.cpp b/src/browsers/CollectionTreeItemModel.cpp
index 80d965a..538884f 100644
--- a/src/browsers/CollectionTreeItemModel.cpp
+++ b/src/browsers/CollectionTreeItemModel.cpp
@@ -21,16 +21,20 @@
 #include "CollectionTreeItemModel.h"
 
 #include <amarokconfig.h>
+#include "AmarokMimeData.h"
 #include "CollectionTreeItem.h"
 #include "core/support/Debug.h"
 #include "core/support/Amarok.h"
 #include "core/collections/Collection.h"
+#include "core/collections/CollectionLocation.h"
+#include "core/meta/Meta.h"
 #include "core-impl/collections/support/CollectionManager.h"
 #include "core/collections/QueryMaker.h"
 
 #include <KLocale>
 
 #include <QTimer>
+#include <QMap>
 
 CollectionTreeItemModel::CollectionTreeItemModel( const QList<int> &levelType )
     : CollectionTreeItemModelBase()
@@ -89,6 +93,17 @@ CollectionTreeItemModel::setLevels( const QList<int> &levelType )
         QTimer::singleShot( 0, this, SLOT( requestCollectionsExpansion() ) );
 }
 
+Qt::ItemFlags
+CollectionTreeItemModel::flags( const QModelIndex &idx ) const
+{
+    Qt::ItemFlags flags = CollectionTreeItemModelBase::flags( idx );
+    //TODO: check for CollectionLocation::isWritable().
+    if( !idx.parent().isValid() )
+        return flags | Qt::ItemIsDropEnabled;
+    else
+        return flags;
+}
+
 QVariant
 CollectionTreeItemModel::data(const QModelIndex &index, int role) const
 {
@@ -101,6 +116,55 @@ CollectionTreeItemModel::data(const QModelIndex &index, int role) const
 }
 
 bool
+CollectionTreeItemModel::dropMimeData( const QMimeData *data, Qt::DropAction action, int row,
+                                  int column, const QModelIndex &parent )
+{
+    if( !parent.isValid() && row == -1 && column == -1 )
+        return true; //only droppable on root (collection header) items.
+
+    CollectionTreeItem *item = static_cast<CollectionTreeItem*>( parent.internalPointer() );
+    Q_ASSERT(item->type() == CollectionTreeItem::Collection);
+
+    Collections::CollectionLocation *targetLocation = item->parentCollection()->location();
+    Q_ASSERT(targetLocation);
+
+    //TODO: accept external drops.
+    const AmarokMimeData *mimeData = qobject_cast<const AmarokMimeData *>( data );
+    Q_ASSERT(mimeData);
+
+    //TODO: optimize for copy from same provider.
+    Meta::TrackList tracks = mimeData->tracks();
+    QMap<const Collections::Collection *, Meta::TrackPtr> collectionTrackMap;
+
+    foreach( Meta::TrackPtr track, tracks )
+    {
+        const Collections::Collection *sourceCollection = track->collection();
+        collectionTrackMap.insertMulti( sourceCollection, track );
+    }
+
+    foreach( const Collections::Collection *sourceCollection, collectionTrackMap.uniqueKeys() )
+    {
+        Collections::CollectionLocation *sourceLocation = sourceCollection->location();
+        Q_ASSERT(sourceLocation);
+        if( sourceLocation == targetLocation )
+            return true; //continue;
+        if( action == Qt::CopyAction )
+        {
+            sourceLocation->prepareCopy( collectionTrackMap.values( sourceCollection ),
+                                        targetLocation );
+        }
+        else if( action == Qt::MoveAction )
+        {
+            sourceLocation->prepareMove( collectionTrackMap.values( sourceCollection ),
+                                        targetLocation );
+        }
+    }
+
+    return true;
+}
+
+
+bool
 CollectionTreeItemModel::canFetchMore( const QModelIndex &parent ) const
 {
     if ( !parent.isValid() )
diff --git a/src/browsers/CollectionTreeItemModel.h b/src/browsers/CollectionTreeItemModel.h
index 533c510..759e3b8 100644
--- a/src/browsers/CollectionTreeItemModel.h
+++ b/src/browsers/CollectionTreeItemModel.h
@@ -37,7 +37,10 @@ class CollectionTreeItemModel: public CollectionTreeItemModelBase
         CollectionTreeItemModel( const QList<int> &levelType );
         ~CollectionTreeItemModel();
 
-        virtual QVariant data(const QModelIndex &index, int role) const;
+        virtual Qt::ItemFlags flags( const QModelIndex &index ) const;
+        virtual QVariant data( const QModelIndex &index, int role ) const;
+        virtual bool dropMimeData( const QMimeData *data, Qt::DropAction action, int row,
+                                  int column, const QModelIndex &parent );
         virtual bool canFetchMore( const QModelIndex &parent ) const;
         virtual void fetchMore( const QModelIndex &parent );
         virtual void setLevels( const QList<int> &levelType );
diff --git a/src/browsers/CollectionTreeView.cpp b/src/browsers/CollectionTreeView.cpp
index 15b2316..24a42aa 100644
--- a/src/browsers/CollectionTreeView.cpp
+++ b/src/browsers/CollectionTreeView.cpp
@@ -85,7 +85,7 @@ CollectionTreeView::CollectionTreeView( QWidget *parent)
     setHorizontalScrollMode( QAbstractItemView::ScrollPerPixel ); // Scrolling per item is really not smooth and looks terrible
 #endif
 
-    setDragDropMode( QAbstractItemView::DragOnly ); // implement drop when time allows
+    setDragDropMode( QAbstractItemView::DragDrop ); // implement drop when time allows
 
     if( KGlobalSettings::graphicEffectsLevel() != KGlobalSettings::NoEffects )
         setAnimated( true );
diff --git a/src/core/collections/CollectionLocation.cpp b/src/core/collections/CollectionLocation.cpp
index 4fb4fa5..d36cf7a 100644
--- a/src/core/collections/CollectionLocation.cpp
+++ b/src/core/collections/CollectionLocation.cpp
@@ -96,7 +96,7 @@ void
 CollectionLocation::prepareCopy( Meta::TrackPtr track, CollectionLocation *destination,
                                  const Transcoding::Configuration &configuration )
 {
-    debug() << "prepare copy 1 track from"<<collection()->collectionId()<<"to"<<destination->collection()->collectionId();
+    Q_ASSERT(destination);
     Meta::TrackList list;
     list.append( track );
     prepareCopy( list, destination, configuration );


More information about the Amarok-devel mailing list