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 <QDesktopWidget>
#include <QMimeDatabase>
#include <QMimeData>
#include <QClipboard>
#include <QPainter>
#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));
}
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()
{
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 clearDragImages();
Q_INVOKABLE void dragSelected(int x, int y);
Q_INVOKABLE void drop(QQuickItem *target, QObject *dropEvent, int row);
Q_INVOKABLE void setWallpaperSelected();

View file

@ -21,6 +21,7 @@ import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
import Cutefish.FileManager 1.0
import Cutefish.DragDrop 1.0 as DragDrop
import FishUI 1.0 as FishUI
GridView {
@ -147,6 +148,38 @@ GridView {
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
keyNavigationEnabled : true
keyNavigationWraps : true
@ -205,7 +238,7 @@ GridView {
var newIndex = positioner.nearestItem(currentIndex,
effectiveNavDirection(control.flow, control.effectiveLayoutDirection, Qt.LeftArrow))
if (newIndex !== -1) {
currentIndex = newIndex;
currentIndex = newIndex
updateSelection(event.modifiers)
}
}
@ -215,7 +248,7 @@ GridView {
var newIndex = positioner.nearestItem(currentIndex,
effectiveNavDirection(control.flow, control.effectiveLayoutDirection, Qt.RightArrow))
if (newIndex !== -1) {
currentIndex = newIndex;
currentIndex = newIndex
updateSelection(event.modifiers)
}
}
@ -276,22 +309,14 @@ GridView {
folderModel: dirModel
perStripe: Math.floor(((control.flow == GridView.FlowLeftToRight)
? control.width : control.height) / ((control.flow == GridView.FlowLeftToRight)
? control.cellWidth : control.cellHeight));
? control.cellWidth : control.cellHeight))
}
DropArea {
id: _dropArea
DragDrop.DropArea {
anchors.fill: parent
onDropped: {
var dropPos = mapToItem(control.contentItem, drop.x, drop.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) {
}
onDrop: {
control.drop(control, event, mapToItem(control, event.x, event.y))
}
}
@ -429,7 +454,7 @@ GridView {
clearPressState()
} else {
if (control.editor && control.editor.targetItem)
return;
return
dirModel.pinSelection()
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 FishUI 1.0 as FishUI
import Cutefish.FileManager 1.0
import Cutefish.DragDrop 1.0 as DragDrop
ListView {
id: control
@ -91,6 +92,39 @@ ListView {
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
Keys.enabled: true
Keys.onPressed: {
@ -174,6 +208,14 @@ ListView {
cPress = mapToItem(control.contentItem, pressX, pressY)
}
DragDrop.DropArea {
anchors.fill: parent
onDrop: {
control.drop(control, event, mapToItem(control, event.x, event.y))
}
}
MouseArea {
id: _mouseArea
anchors.fill: parent