+Qt::DropActions PLModel::supportedDropActions() const
+{
+ return Qt::CopyAction;
+}
+
+Qt::ItemFlags PLModel::flags(const QModelIndex &index) const
+{
+ Qt::ItemFlags defaultFlags = QAbstractItemModel::flags(index);
+ if( index.isValid() )
+ return Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | defaultFlags;
+ else
+ return Qt::ItemIsDropEnabled | defaultFlags;
+}
+
+QStringList PLModel::mimeTypes() const
+{
+ QStringList types;
+ types << "vlc/playlist-item-id";
+ return types;
+}
+
+QMimeData *PLModel::mimeData(const QModelIndexList &indexes) const
+{
+ QMimeData *mimeData = new QMimeData();
+ QByteArray encodedData;
+ QDataStream stream(&encodedData, QIODevice::WriteOnly);
+
+ foreach (QModelIndex index, indexes) {
+ if (index.isValid() && index.column() == 0 )
+ stream << itemId(index);
+ }
+ mimeData->setData("vlc/playlist-item-id", encodedData);
+ return mimeData;
+}
+
+bool PLModel::dropMimeData(const QMimeData *data, Qt::DropAction action,
+ int row, int column, const QModelIndex &target)
+{
+ if ( data->hasFormat("vlc/playlist-item-id") )
+ {
+ if (action == Qt::IgnoreAction)
+ return true;
+
+ PLItem *targetItem;
+ if( target.isValid() )
+ targetItem = static_cast<PLItem*>( target.internalPointer() );
+ else
+ targetItem = rootItem;
+
+ QByteArray encodedData = data->data("vlc/playlist-item-id");
+ QDataStream stream(&encodedData, QIODevice::ReadOnly);
+
+ PLItem *newParentItem;
+ while (!stream.atEnd())
+ {
+ int i;
+ int srcId;
+ stream >> srcId;
+
+ PL_LOCK;
+ playlist_item_t *p_target =
+ playlist_ItemGetById( p_playlist, targetItem->i_id,
+ VLC_TRUE );
+ playlist_item_t *p_src = playlist_ItemGetById( p_playlist, srcId,
+ VLC_TRUE );
+
+ if( !p_target || !p_src )
+ {
+ PL_UNLOCK;
+ return false;
+ }
+ if( p_target->i_children == -1 ) /* A leaf */
+ {
+ PLItem *parentItem = targetItem->parent();
+ assert( parentItem );
+ playlist_item_t *p_parent =
+ playlist_ItemGetById( p_playlist, parentItem->i_id,
+ VLC_TRUE );
+ if( !p_parent )
+ {
+ PL_UNLOCK;
+ return false;
+ }
+ for( i = 0 ; i< p_parent->i_children ; i++ )
+ if( p_parent->pp_children[i] == p_target ) break;
+ playlist_TreeMove( p_playlist, p_src, p_parent, i );
+ newParentItem = parentItem;
+ }
+ else
+ {
+ /* \todo: if we drop on a top-level node, use copy instead ? */
+ playlist_TreeMove( p_playlist, p_src, p_target, 0 );
+ i = 0;
+ newParentItem = targetItem;
+ }
+ /* Remove from source */
+ PLItem *srcItem = FindById( rootItem, p_src->i_id );
+ // We dropped on the source selector. Ask the dialog to forward
+ // to the main view
+ if( !srcItem )
+ {
+ emit shouldRemove( p_src->i_id );
+ }
+ else
+ srcItem->remove( srcItem );
+
+ /* Display at new destination */
+ PLItem *newItem = new PLItem( p_src, newParentItem, this );
+ newParentItem->insertChild( newItem, i, true );
+ UpdateTreeItem( p_src, newItem, true );
+ if( p_src->i_children != -1 )
+ UpdateNodeChildren( newItem );
+ PL_UNLOCK;
+ }
+ }
+ return true;
+}
+
+void PLModel::removeItem( int i_id )
+{
+ PLItem *item = FindById( rootItem,i_id );
+ if( item ) item->remove( item );
+}
+