From 89fffcc37fcd8078f66f93c8f4f32b737cfbb6fe Mon Sep 17 00:00:00 2001 From: David Sansome Date: Sun, 11 Jul 2010 18:04:35 +0000 Subject: [PATCH] Support internal drag and drop in the queue --- src/playlist/queue.cpp | 69 ++++++++++++++++++++++++++++++++++++ src/playlist/queue.h | 7 ++++ src/playlist/queuemanager.ui | 12 +++++++ 3 files changed, 88 insertions(+) diff --git a/src/playlist/queue.cpp b/src/playlist/queue.cpp index 529c5ef53..3adcfa34b 100644 --- a/src/playlist/queue.cpp +++ b/src/playlist/queue.cpp @@ -16,6 +16,12 @@ #include "queue.h" +#include +#include +#include + +const char* Queue::kRowsMimetype = "application/x-clementine-queue-rows"; + Queue::Queue(QObject* parent) : QAbstractProxyModel(parent) { @@ -34,6 +40,9 @@ QModelIndex Queue::mapFromSource(const QModelIndex& source_index) const { } QModelIndex Queue::mapToSource(const QModelIndex& proxy_index) const { + if (!proxy_index.isValid()) + return QModelIndex(); + return source_indexes_[proxy_index.row()]; } @@ -208,3 +217,63 @@ void Queue::MoveUp(int row) { void Queue::MoveDown(int row) { Move(QList() << row, row + 2); } + +QStringList Queue::mimeTypes() const { + return QStringList() << kRowsMimetype; +} + +Qt::DropActions Queue::supportedDropActions() const { + return Qt::MoveAction | Qt::CopyAction | Qt::LinkAction; +} + +QMimeData* Queue::mimeData(const QModelIndexList& indexes) const { + QMimeData* data = new QMimeData; + + QList rows; + foreach (const QModelIndex& index, indexes) { + if (index.column() != Column_CombinedArtistTitle) + continue; + + rows << index.row(); + } + + QBuffer buf; + buf.open(QIODevice::WriteOnly); + QDataStream stream(&buf); + stream << rows; + buf.close(); + + data->setData(kRowsMimetype, buf.data()); + + return data; +} + +bool Queue::dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int, const QModelIndex&) { + if (action == Qt::IgnoreAction) + return false; + + if (data->hasFormat(kRowsMimetype)) { + // Dragged from the queue + + QList proxy_rows; + QDataStream stream(data->data(kRowsMimetype)); + stream >> proxy_rows; + qStableSort(proxy_rows); // Make sure we take them in order + + Move(proxy_rows, row); + } + + return true; +} + +Qt::ItemFlags Queue::flags(const QModelIndex &index) const { + Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable; + + if (index.isValid()) + flags |= Qt::ItemIsDragEnabled; + else + flags |= Qt::ItemIsDropEnabled; + + return flags; + +} diff --git a/src/playlist/queue.h b/src/playlist/queue.h index bc97aa6c5..3e7ae7ceb 100644 --- a/src/playlist/queue.h +++ b/src/playlist/queue.h @@ -33,6 +33,8 @@ public: ColumnCount }; + static const char* kRowsMimetype; + // Query the queue bool is_empty() const; int PositionOf(const QModelIndex& source_index) const; @@ -56,6 +58,11 @@ public: int rowCount(const QModelIndex &parent = QModelIndex()) const; int columnCount(const QModelIndex &parent = QModelIndex()) const; QVariant data(const QModelIndex& proxy_index, int role) const; + QStringList mimeTypes() const; + Qt::DropActions supportedDropActions() const; + QMimeData* mimeData(const QModelIndexList& indexes) const; + bool dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent); + Qt::ItemFlags flags(const QModelIndex &index) const; private slots: void SourceDataChanged(const QModelIndex& top_left, const QModelIndex& bottom_right); diff --git a/src/playlist/queuemanager.ui b/src/playlist/queuemanager.ui index 78e10fb1f..a017bb4bc 100644 --- a/src/playlist/queuemanager.ui +++ b/src/playlist/queuemanager.ui @@ -22,6 +22,18 @@ + + true + + + true + + + QAbstractItemView::DragDrop + + + Qt::MoveAction + true