summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBart Cerneels <bart.cerneels@kde.org>2011-06-07 07:43:02 (GMT)
committerBart Cerneels <bart.cerneels@kde.org>2011-06-08 14:36:22 (GMT)
commitfffc1ea983281e6cb1f6ce2129f046e598fe01c4 (patch)
tree06caf8ccde3174cc56340dcbbb14645ad66c3fa6
parent044fd7a86650e2f6fc09aeee45dc71d7ec690237 (diff)
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@kde.org
-rw-r--r--src/browsers/CollectionTreeItemModel.cpp64
-rw-r--r--src/browsers/CollectionTreeItemModel.h5
-rw-r--r--src/browsers/CollectionTreeView.cpp2
-rw-r--r--src/core/collections/CollectionLocation.cpp2
4 files changed, 70 insertions, 3 deletions
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 );