From d95897df572504f3a2092a6306b5b66a9e952390 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Thu, 9 May 2024 09:01:53 +1000 Subject: [PATCH] Allow dropping paths onto data source select dialog to expand browser paths Makes it a bit easier to fix data sources for files in deep paths --- .../qgsdatasourceselectdialog.sip.in | 5 ++ .../qgsdatasourceselectdialog.sip.in | 5 ++ src/gui/qgsdatasourceselectdialog.cpp | 55 +++++++++++++++++++ src/gui/qgsdatasourceselectdialog.h | 6 ++ 4 files changed, 71 insertions(+) diff --git a/python/PyQt6/gui/auto_generated/qgsdatasourceselectdialog.sip.in b/python/PyQt6/gui/auto_generated/qgsdatasourceselectdialog.sip.in index bb10bdfa3b08..5e68643d3188 100644 --- a/python/PyQt6/gui/auto_generated/qgsdatasourceselectdialog.sip.in +++ b/python/PyQt6/gui/auto_generated/qgsdatasourceselectdialog.sip.in @@ -103,6 +103,11 @@ Apply filter to the model Scroll to last selected index and expand it's children %End + virtual void dragEnterEvent( QDragEnterEvent *event ); + + virtual void dropEvent( QDropEvent *event ); + + signals: void validationChanged( bool isValid ); diff --git a/python/gui/auto_generated/qgsdatasourceselectdialog.sip.in b/python/gui/auto_generated/qgsdatasourceselectdialog.sip.in index bb10bdfa3b08..5e68643d3188 100644 --- a/python/gui/auto_generated/qgsdatasourceselectdialog.sip.in +++ b/python/gui/auto_generated/qgsdatasourceselectdialog.sip.in @@ -103,6 +103,11 @@ Apply filter to the model Scroll to last selected index and expand it's children %End + virtual void dragEnterEvent( QDragEnterEvent *event ); + + virtual void dropEvent( QDropEvent *event ); + + signals: void validationChanged( bool isValid ); diff --git a/src/gui/qgsdatasourceselectdialog.cpp b/src/gui/qgsdatasourceselectdialog.cpp index af21480a89f8..b98b57639caa 100644 --- a/src/gui/qgsdatasourceselectdialog.cpp +++ b/src/gui/qgsdatasourceselectdialog.cpp @@ -31,6 +31,7 @@ #include #include #include +#include QgsDataSourceSelectWidget::QgsDataSourceSelectWidget( QgsBrowserGuiModel *browserModel, @@ -116,6 +117,8 @@ QgsDataSourceSelectWidget::QgsDataSourceSelectWidget( { mActionShowFilter->trigger(); } + + setAcceptDrops( true ); } QgsDataSourceSelectWidget::~QgsDataSourceSelectWidget() = default; @@ -145,6 +148,58 @@ void QgsDataSourceSelectWidget::showEvent( QShowEvent *e ) } } +QString QgsDataSourceSelectWidget::acceptableFilePath( QDropEvent *event ) const +{ + if ( event->mimeData()->hasUrls() ) + { + const QList< QUrl > urls = event->mimeData()->urls(); + for ( const QUrl &url : urls ) + { + const QString local = url.toLocalFile(); + if ( local.isEmpty() ) + continue; + + if ( QFile::exists( local ) ) + { + return local; + } + } + } + return QString(); +} + +void QgsDataSourceSelectWidget::dragEnterEvent( QDragEnterEvent *event ) +{ + const QString filePath = acceptableFilePath( event ); + if ( !filePath.isEmpty() ) + { + event->acceptProposedAction(); + } + else + { + event->ignore(); + } +} + +void QgsDataSourceSelectWidget::dropEvent( QDropEvent *event ) +{ + const QString filePath = acceptableFilePath( event ); + if ( !filePath.isEmpty() ) + { + event->acceptProposedAction(); + + const QFileInfo fi( filePath ); + if ( fi.isDir() ) + { + expandPath( filePath, true ); + } + else + { + expandPath( fi.dir().path(), true ); + } + } +} + void QgsDataSourceSelectWidget::showFilterWidget( bool visible ) { QgsSettings().setValue( QStringLiteral( "datasourceSelectFilterVisible" ), visible, QgsSettings::Section::Gui ); diff --git a/src/gui/qgsdatasourceselectdialog.h b/src/gui/qgsdatasourceselectdialog.h index 95861cab06fc..8a2796b50591 100644 --- a/src/gui/qgsdatasourceselectdialog.h +++ b/src/gui/qgsdatasourceselectdialog.h @@ -104,6 +104,9 @@ class GUI_EXPORT QgsDataSourceSelectWidget: public QgsPanelWidget, private Ui::Q //! Scroll to last selected index and expand it's children void showEvent( QShowEvent *e ) override; + void dragEnterEvent( QDragEnterEvent *event ) override; + void dropEvent( QDropEvent *event ) override; + signals: /** @@ -137,6 +140,9 @@ class GUI_EXPORT QgsDataSourceSelectWidget: public QgsPanelWidget, private Ui::Q void setValid( bool valid ); + //! Returns file name if object meets drop criteria. + QString acceptableFilePath( QDropEvent *event ) const; + QgsBrowserProxyModel mBrowserProxyModel; QgsBrowserGuiModel *mBrowserModel = nullptr; QgsMimeDataUtils::Uri mUri;