Support drag and drop to move files

This commit is contained in:
reionwong 2021-11-04 01:35:09 +08:00
parent 2d733384f0
commit cad758b31f
4 changed files with 135 additions and 15 deletions

View file

@ -46,6 +46,7 @@
#include <QApplication> #include <QApplication>
#include <QDesktopWidget> #include <QDesktopWidget>
#include <QMimeDatabase> #include <QMimeDatabase>
#include <QMimeData>
#include <QClipboard> #include <QClipboard>
#include <QPainter> #include <QPainter>
#include <QDrag> #include <QDrag>
@ -1008,6 +1009,57 @@ void FolderModel::dragSelected(int x, int y)
QMetaObject::invokeMethod(this, "dragSelectedInternal", Qt::QueuedConnection, Q_ARG(int, x), Q_ARG(int, y)); QMetaObject::invokeMethod(this, "dragSelectedInternal", Qt::QueuedConnection, Q_ARG(int, x), Q_ARG(int, y));
} }
void FolderModel::drop(QQuickItem *target, QObject *dropEvent, int row)
{
QMimeData *mimeData = qobject_cast<QMimeData *>(dropEvent->property("mimeData").value<QObject *>());
if (!mimeData) {
return;
}
QModelIndex idx;
KFileItem item;
if (row > -1 && row < rowCount()) {
idx = index(row, 0);
item = itemForIndex(idx);
}
QUrl dropTargetUrl;
// So we get to run mostLocalUrl() over the current URL.
if (item.isNull()) {
item = rootItem();
}
if (item.isNull()) {
dropTargetUrl = m_dirModel->dirLister()->url();
} else {
dropTargetUrl = item.mostLocalUrl();
}
if (idx.isValid() && !(flags(idx) & Qt::ItemIsDropEnabled)) {
return;
}
// 处理url
QList<QUrl> sourceUrls;
for (const QUrl &url : mimeData->urls()) {
QFileInfo info(url.toLocalFile());
QUrl newUrl = QUrl::fromLocalFile(info.dir().path());
// 相同的目录下不加入
if (newUrl != dropTargetUrl) {
sourceUrls.append(url);
}
}
if (!sourceUrls.isEmpty()) {
KIO::Job *job = KIO::move(sourceUrls, dropTargetUrl, KIO::HideProgressInfo);
job->start();
}
}
void FolderModel::setWallpaperSelected() void FolderModel::setWallpaperSelected()
{ {
if (!m_selectionModel) if (!m_selectionModel)

View file

@ -197,6 +197,7 @@ public:
Q_INVOKABLE void addItemDragImage(int row, int x, int y, int width, int height, const QVariant &image); Q_INVOKABLE void addItemDragImage(int row, int x, int y, int width, int height, const QVariant &image);
Q_INVOKABLE void clearDragImages(); Q_INVOKABLE void clearDragImages();
Q_INVOKABLE void dragSelected(int x, int y); Q_INVOKABLE void dragSelected(int x, int y);
Q_INVOKABLE void drop(QQuickItem *target, QObject *dropEvent, int row);
Q_INVOKABLE void setWallpaperSelected(); Q_INVOKABLE void setWallpaperSelected();

View file

@ -21,6 +21,7 @@ import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12 import QtQuick.Layouts 1.12
import Cutefish.FileManager 1.0 import Cutefish.FileManager 1.0
import Cutefish.DragDrop 1.0 as DragDrop
import FishUI 1.0 as FishUI import FishUI 1.0 as FishUI
GridView { GridView {
@ -147,6 +148,38 @@ GridView {
cPress = null cPress = null
} }
function drop(target, event, pos) {
var dropPos = mapToItem(control.contentItem, pos.x, pos.y)
var dropIndex = control.indexAt(dropPos.x, dropPos.y)
var dragPos = mapToItem(control.contentItem, control.dragX, control.dragY)
var dragIndex = control.indexAt(dragPos.x, dragPos.y)
if (control.dragX === -1 || dragIndex !== dropIndex) {
dirModel.drop(control, event, dropItemAt(dropPos))
}
}
function dropItemAt(pos) {
var item = control.itemAt(pos.x, pos.y)
if (item) {
if (item.blank) {
return -1
}
var hOffset = Math.abs(Math.min(control.contentX, control.originX))
var hPos = mapToItem(item, pos.x + hOffset, pos.y)
if ((hPos.x < 0 || hPos.y < 0 || hPos.x > item.width || hPos.y > item.height)) {
return -1
} else {
return positioner.map(item.index)
}
}
return -1
}
highlightMoveDuration: 0 highlightMoveDuration: 0
keyNavigationEnabled : true keyNavigationEnabled : true
keyNavigationWraps : true keyNavigationWraps : true
@ -205,7 +238,7 @@ GridView {
var newIndex = positioner.nearestItem(currentIndex, var newIndex = positioner.nearestItem(currentIndex,
effectiveNavDirection(control.flow, control.effectiveLayoutDirection, Qt.LeftArrow)) effectiveNavDirection(control.flow, control.effectiveLayoutDirection, Qt.LeftArrow))
if (newIndex !== -1) { if (newIndex !== -1) {
currentIndex = newIndex; currentIndex = newIndex
updateSelection(event.modifiers) updateSelection(event.modifiers)
} }
} }
@ -215,7 +248,7 @@ GridView {
var newIndex = positioner.nearestItem(currentIndex, var newIndex = positioner.nearestItem(currentIndex,
effectiveNavDirection(control.flow, control.effectiveLayoutDirection, Qt.RightArrow)) effectiveNavDirection(control.flow, control.effectiveLayoutDirection, Qt.RightArrow))
if (newIndex !== -1) { if (newIndex !== -1) {
currentIndex = newIndex; currentIndex = newIndex
updateSelection(event.modifiers) updateSelection(event.modifiers)
} }
} }
@ -276,22 +309,14 @@ GridView {
folderModel: dirModel folderModel: dirModel
perStripe: Math.floor(((control.flow == GridView.FlowLeftToRight) perStripe: Math.floor(((control.flow == GridView.FlowLeftToRight)
? control.width : control.height) / ((control.flow == GridView.FlowLeftToRight) ? control.width : control.height) / ((control.flow == GridView.FlowLeftToRight)
? control.cellWidth : control.cellHeight)); ? control.cellWidth : control.cellHeight))
} }
DropArea { DragDrop.DropArea {
id: _dropArea
anchors.fill: parent anchors.fill: parent
onDropped: { onDrop: {
var dropPos = mapToItem(control.contentItem, drop.x, drop.y) control.drop(control, event, mapToItem(control, event.x, event.y))
var dropIndex = control.indexAt(drop.x, drop.y)
var dragPos = mapToItem(control.contentItem, control.dragX, control.dragY)
var dragIndex = control.indexAt(dragPos.x, dragPos.y)
if (control.dragX == -1 || dragIndex !== dropIndex) {
}
} }
} }
@ -429,7 +454,7 @@ GridView {
clearPressState() clearPressState()
} else { } else {
if (control.editor && control.editor.targetItem) if (control.editor && control.editor.targetItem)
return; return
dirModel.pinSelection() dirModel.pinSelection()
control.rubberBand = rubberBandObject.createObject(control.contentItem, {x: cPress.x, y: cPress.y}) control.rubberBand = rubberBandObject.createObject(control.contentItem, {x: cPress.x, y: cPress.y})

View file

@ -21,6 +21,7 @@ import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12 import QtQuick.Layouts 1.12
import FishUI 1.0 as FishUI import FishUI 1.0 as FishUI
import Cutefish.FileManager 1.0 import Cutefish.FileManager 1.0
import Cutefish.DragDrop 1.0 as DragDrop
ListView { ListView {
id: control id: control
@ -91,6 +92,39 @@ ListView {
cPress = null cPress = null
} }
function drop(target, event, pos) {
var dropPos = mapToItem(control.contentItem, pos.x, pos.y)
var dropIndex = control.indexAt(dropPos.x, dropPos.y)
var dragPos = mapToItem(control.contentItem, control.dragX, control.dragY)
var dragIndex = control.indexAt(dragPos.x, dragPos.y)
if (control.dragX === -1 || dragIndex !== dropIndex) {
dirModel.drop(control, event, dropItemAt(dropPos))
}
}
function dropItemAt(pos) {
var item = control.itemAt(pos.x, pos.y)
if (item) {
if (item.blank) {
return -1
}
var hOffset = Math.abs(Math.min(control.contentX, control.originX))
var hPos = mapToItem(item, pos.x + hOffset, pos.y)
if ((hPos.x < 0 || hPos.y < 0 || hPos.x > item.width || hPos.y > item.height)) {
return -1
} else {
return item.index
}
}
return -1
}
highlightMoveDuration: 0 highlightMoveDuration: 0
Keys.enabled: true Keys.enabled: true
Keys.onPressed: { Keys.onPressed: {
@ -174,6 +208,14 @@ ListView {
cPress = mapToItem(control.contentItem, pressX, pressY) cPress = mapToItem(control.contentItem, pressX, pressY)
} }
DragDrop.DropArea {
anchors.fill: parent
onDrop: {
control.drop(control, event, mapToItem(control, event.x, event.y))
}
}
MouseArea { MouseArea {
id: _mouseArea id: _mouseArea
anchors.fill: parent anchors.fill: parent