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); @@ -922,6 +922,8 @@ class Private; Private *const d; + void onDropEvent(QDropEvent *evt); + Q_PRIVATE_SLOT(d, void _k_slotDetailedView()) Q_PRIVATE_SLOT(d, void _k_slotSimpleView()) Q_PRIVATE_SLOT(d, void _k_slotTreeView()) 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,13 +1381,59 @@ } } break; + case QEvent::DragEnter: { + // Accepts drops of one file or folder only + QDragEnterEvent *evt = static_cast(event); + const QList urls = KUrlMimeData::urlsFromMimeData(evt->mimeData()); + // only one file/folder can be dropped + event->setAccepted(urls.size() == 1); + } + break; + case QEvent::Drop: { + QDropEvent *evt = static_cast(event); + onDropEvent(evt); + } + break; default: break; } return QWidget::eventFilter(watched, event); } +void KDirOperator::onDropEvent(QDropEvent* evt){ + + const QList urls = KUrlMimeData::urlsFromMimeData(evt->mimeData(), KUrlMimeData::DecodeOptions::PreferLocalUrls); + + 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](){ + setCurrentItem(url); + QObject::disconnect(connection); + }; + connection = connect(this, &KDirOperator::finishedLoading, this, urlSetterClosure); + } else { + setCurrentItem(url); + } + } + evt->accept(); +} + bool KDirOperator::Private::checkPreviewInternal() const { const QStringList supported = KIO::PreviewJob::supportedMimeTypes(); @@ -1461,12 +1509,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 +1556,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(); } - diff --git a/tests/kfilewidgettest_saving_gui.cpp b/tests/kfilewidgettest_saving_gui.cpp --- a/tests/kfilewidgettest_saving_gui.cpp +++ b/tests/kfilewidgettest_saving_gui.cpp @@ -38,7 +38,7 @@ app.connect(fileWidget->cancelButton(), &QPushButton::clicked, fileWidget, [&app, fileWidget]() { qDebug() << "canceled"; fileWidget->slotCancel(); - app.exit(); + app.quit(); }); app.connect(fileWidget, &KFileWidget::accepted, fileWidget, [&app, fileWidget]() { @@ -48,7 +48,8 @@ qDebug() << fileWidget->selectedUrl(); qDebug() << fileWidget->selectedFiles(); qDebug() << fileWidget->selectedUrls(); - app.exit(); + qDebug() << fileWidget->selectedUrls(); + app.quit(); }); fileWidget->show();