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;