diff --git a/src/filewidgets/kdiroperator.h b/src/filewidgets/kdiroperator.h --- a/src/filewidgets/kdiroperator.h +++ b/src/filewidgets/kdiroperator.h @@ -550,7 +550,7 @@ void setupMenu(int whichActions); /** - * Reimplemented - allow dropping of files if @p b is true + * Reimplemented - allow dropping of files if @p b is true, defaults to true since 5.58 * @param b true if the widget should allow dropping of files */ virtual void setAcceptDrops(bool b); diff --git a/src/filewidgets/kdiroperator.cpp b/src/filewidgets/kdiroperator.cpp --- a/src/filewidgets/kdiroperator.cpp +++ b/src/filewidgets/kdiroperator.cpp @@ -28,6 +28,7 @@ #include "kfilemetapreview_p.h" #include "kpreviewwidgetbase.h" #include "knewfilemenu.h" +#include #include "../pathhelpers_p.h" #include @@ -414,6 +415,7 @@ d->updateSorting(QDir::Name | QDir::DirsFirst); setFocusPolicy(Qt::WheelFocus); + setAcceptDrops(true); } KDirOperator::~KDirOperator() @@ -1379,6 +1381,56 @@ } } break; + case QEvent::DragEnter: { + // Accepts drops of one file or folder only + QDragEnterEvent *evt = static_cast(event); + const QList urls = KUrlMimeData::urlsFromMimeData(evt->mimeData()); + event->setAccepted(urls.size() == 1 && evt->mimeData()->hasFormat(QStringLiteral("text/uri-list"))); + } + break; + case QEvent::Drop: { + QDropEvent *evt = static_cast(event); + if (evt->dropAction() == Qt::CopyAction || evt->dropAction() == Qt::MoveAction) { + + const QList urls = KUrlMimeData::urlsFromMimeData(evt->mimeData()); + + if (urls.size() != 1) { + // only one file/folder can be dropped at the moment + evt->ignore(); + } else { + const QUrl url = urls.constFirst(); + + // stat the url to get details + KIO::StatJob *job = KIO::stat(url, KIO::HideProgressInfo); + job->exec(); + + KIO::UDSEntry entry = job->statResult(); + + if (entry.isDir()) { + setUrl(url, false); + } else { + // if the current url is not known + if (d->dirLister->findByUrl(url).isNull()) { + setUrl(url.adjusted(QUrl::RemoveFilename), false); + + // Will set the current item once loading has finished + QMetaObject::Connection connection; + auto urlSetterClosure = [this, url, connection](){ + this->setCurrentItem(url); + QObject::disconnect(connection); + }; + connection = connect(this, &KDirOperator::finishedLoading, this, urlSetterClosure); + } else { + this->setCurrentItem(url); + } + } + evt->accept(); + } + } else { + evt->ignore(); + } + } + break; default: break; } @@ -1461,12 +1513,17 @@ return itemView; } -void KDirOperator::setAcceptDrops(bool b) +void KDirOperator::setAcceptDrops(bool acceptsDrops) { - // TODO: - //if (d->fileView) - // d->fileView->widget()->setAcceptDrops(b); - QWidget::setAcceptDrops(b); + QWidget::setAcceptDrops(acceptsDrops); + if (view()) { + view()->setAcceptDrops(acceptsDrops); + if (acceptsDrops) { + view()->installEventFilter(this); + } else { + view()->removeEventFilter(this); + } + } } void KDirOperator::setDropOptions(int options) @@ -1503,6 +1560,11 @@ QAbstractItemView *newView = createView(this, viewKind); setView(newView); + if (this->acceptDrops()) { + newView->setAcceptDrops(true); + newView->installEventFilter(this); + } + d->_k_togglePreview(preview); } diff --git a/tests/kfilewidgettest_gui.cpp b/tests/kfilewidgettest_gui.cpp --- a/tests/kfilewidgettest_gui.cpp +++ b/tests/kfilewidgettest_gui.cpp @@ -31,6 +31,7 @@ fileWidget->setAttribute(Qt::WA_DeleteOnClose); fileWidget->show(); + QObject::connect(fileWidget, &KFileWidget::destroyed, &app, &QApplication::quit); + return app.exec(); } -