diff --git a/python/PyQt6/gui/auto_generated/qgsbrowsertreeview.sip.in b/python/PyQt6/gui/auto_generated/qgsbrowsertreeview.sip.in
index b66a85c92856..b1066e07390d 100644
--- a/python/PyQt6/gui/auto_generated/qgsbrowsertreeview.sip.in
+++ b/python/PyQt6/gui/auto_generated/qgsbrowsertreeview.sip.in
@@ -66,12 +66,14 @@ Returns ``True`` if the item was found and could be selected.
.. versionadded:: 3.28
%End
- void expandPath( const QString &path );
+ void expandPath( const QString &path, bool selectPath = false );
%Docstring
Expands out a file ``path`` in the view.
The ``path`` must correspond to a valid directory existing on the file system.
+Since QGIS 3.38 the ``selectPath`` argument can be used to automatically select the path too.
+
.. versionadded:: 3.28
%End
diff --git a/python/PyQt6/gui/auto_generated/qgsdatasourceselectdialog.sip.in b/python/PyQt6/gui/auto_generated/qgsdatasourceselectdialog.sip.in
index 9784db0fb3be..5e68643d3188 100644
--- a/python/PyQt6/gui/auto_generated/qgsdatasourceselectdialog.sip.in
+++ b/python/PyQt6/gui/auto_generated/qgsdatasourceselectdialog.sip.in
@@ -65,12 +65,14 @@ Sets a description label
.. versionadded:: 3.8
%End
- void expandPath( const QString &path );
+ void expandPath( const QString &path, bool selectPath = false );
%Docstring
Expands out a file ``path`` in the view.
The ``path`` must correspond to a valid directory existing on the file system.
+Since QGIS 3.38 the ``selectPath`` argument can be used to automatically select the path too.
+
.. versionadded:: 3.28
%End
@@ -101,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 );
@@ -176,12 +183,14 @@ Sets a description label
.. versionadded:: 3.8
%End
- void expandPath( const QString &path );
+ void expandPath( const QString &path, bool selectPath = false );
%Docstring
Expands out a file ``path`` in the view.
The ``path`` must correspond to a valid directory existing on the file system.
+Since QGIS 3.38 the ``selectPath`` argument can be used to automatically select the path too.
+
.. versionadded:: 3.28
%End
diff --git a/python/gui/auto_generated/qgsbrowsertreeview.sip.in b/python/gui/auto_generated/qgsbrowsertreeview.sip.in
index b66a85c92856..b1066e07390d 100644
--- a/python/gui/auto_generated/qgsbrowsertreeview.sip.in
+++ b/python/gui/auto_generated/qgsbrowsertreeview.sip.in
@@ -66,12 +66,14 @@ Returns ``True`` if the item was found and could be selected.
.. versionadded:: 3.28
%End
- void expandPath( const QString &path );
+ void expandPath( const QString &path, bool selectPath = false );
%Docstring
Expands out a file ``path`` in the view.
The ``path`` must correspond to a valid directory existing on the file system.
+Since QGIS 3.38 the ``selectPath`` argument can be used to automatically select the path too.
+
.. versionadded:: 3.28
%End
diff --git a/python/gui/auto_generated/qgsdatasourceselectdialog.sip.in b/python/gui/auto_generated/qgsdatasourceselectdialog.sip.in
index 9784db0fb3be..5e68643d3188 100644
--- a/python/gui/auto_generated/qgsdatasourceselectdialog.sip.in
+++ b/python/gui/auto_generated/qgsdatasourceselectdialog.sip.in
@@ -65,12 +65,14 @@ Sets a description label
.. versionadded:: 3.8
%End
- void expandPath( const QString &path );
+ void expandPath( const QString &path, bool selectPath = false );
%Docstring
Expands out a file ``path`` in the view.
The ``path`` must correspond to a valid directory existing on the file system.
+Since QGIS 3.38 the ``selectPath`` argument can be used to automatically select the path too.
+
.. versionadded:: 3.28
%End
@@ -101,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 );
@@ -176,12 +183,14 @@ Sets a description label
.. versionadded:: 3.8
%End
- void expandPath( const QString &path );
+ void expandPath( const QString &path, bool selectPath = false );
%Docstring
Expands out a file ``path`` in the view.
The ``path`` must correspond to a valid directory existing on the file system.
+Since QGIS 3.38 the ``selectPath`` argument can be used to automatically select the path too.
+
.. versionadded:: 3.28
%End
diff --git a/src/app/qgisapp.cpp b/src/app/qgisapp.cpp
index 450dbaea75ce..c6856c998c8d 100644
--- a/src/app/qgisapp.cpp
+++ b/src/app/qgisapp.cpp
@@ -7753,7 +7753,9 @@ void QgisApp::changeDataSource( QgsMapLayer *layer )
{
const QString path = sourceParts.value( QStringLiteral( "path" ) ).toString();
const QString closestPath = QFile::exists( path ) ? path : QgsFileUtils::findClosestExistingPath( path );
- dlg.expandPath( closestPath );
+
+ const QFileInfo pathInfo( closestPath );
+ dlg.expandPath( pathInfo.isDir() ? closestPath : pathInfo.dir().path(), true );
if ( source.contains( path ) )
{
source.replace( path, QStringLiteral( "%2" ).arg( QUrl::fromLocalFile( closestPath ).toString(),
diff --git a/src/gui/qgsbrowsertreeview.cpp b/src/gui/qgsbrowsertreeview.cpp
index 6ce4a05b989d..4377084e8e0f 100644
--- a/src/gui/qgsbrowsertreeview.cpp
+++ b/src/gui/qgsbrowsertreeview.cpp
@@ -177,7 +177,7 @@ bool QgsBrowserTreeView::hasExpandedDescendant( const QModelIndex &index ) const
return false;
}
-void QgsBrowserTreeView::expandPath( const QString &str )
+void QgsBrowserTreeView::expandPath( const QString &str, bool selectPath )
{
const QStringList pathParts = QgsFileUtils::splitPathToComponents( str );
if ( pathParts.isEmpty() )
@@ -289,6 +289,7 @@ void QgsBrowserTreeView::expandPath( const QString &str )
currentDir = QDir( thisPath );
}
+ QgsDirectoryItem *lastItem = nullptr;
for ( QgsDirectoryItem *i : std::as_const( pathItems ) )
{
QModelIndex index = mBrowserModel->findItem( i );
@@ -297,7 +298,11 @@ void QgsBrowserTreeView::expandPath( const QString &str )
index = proxyModel->mapFromSource( index );
}
expand( index );
+ lastItem = i;
}
+
+ if ( selectPath && lastItem )
+ setSelectedItem( lastItem );
}
bool QgsBrowserTreeView::setSelectedItem( QgsDataItem *item )
diff --git a/src/gui/qgsbrowsertreeview.h b/src/gui/qgsbrowsertreeview.h
index 121b8f6003ab..d91a8c08e3b9 100644
--- a/src/gui/qgsbrowsertreeview.h
+++ b/src/gui/qgsbrowsertreeview.h
@@ -82,9 +82,11 @@ class GUI_EXPORT QgsBrowserTreeView : public QTreeView
*
* The \a path must correspond to a valid directory existing on the file system.
*
+ * Since QGIS 3.38 the \a selectPath argument can be used to automatically select the path too.
+ *
* \since QGIS 3.28
*/
- void expandPath( const QString &path );
+ void expandPath( const QString &path, bool selectPath = false );
protected:
diff --git a/src/gui/qgsdatasourceselectdialog.cpp b/src/gui/qgsdatasourceselectdialog.cpp
index fc76099de596..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 );
@@ -194,9 +249,9 @@ void QgsDataSourceSelectWidget::setDescription( const QString &description )
}
}
-void QgsDataSourceSelectWidget::expandPath( const QString &path )
+void QgsDataSourceSelectWidget::expandPath( const QString &path, bool selectPath )
{
- mBrowserTreeView->expandPath( path );
+ mBrowserTreeView->expandPath( path, selectPath );
}
void QgsDataSourceSelectWidget::setFilter()
@@ -205,7 +260,6 @@ void QgsDataSourceSelectWidget::setFilter()
mBrowserProxyModel.setFilterString( filter );
}
-
void QgsDataSourceSelectWidget::refreshModel( const QModelIndex &index )
{
@@ -255,7 +309,6 @@ void QgsDataSourceSelectWidget::setValid( bool valid )
}
-
void QgsDataSourceSelectWidget::setFilterSyntax( QAction *action )
{
if ( !action )
@@ -354,9 +407,9 @@ void QgsDataSourceSelectDialog::setDescription( const QString &description )
mWidget->setDescription( description );
}
-void QgsDataSourceSelectDialog::expandPath( const QString &path )
+void QgsDataSourceSelectDialog::expandPath( const QString &path, bool selectPath )
{
- mWidget->expandPath( path );
+ mWidget->expandPath( path, selectPath );
}
QgsMimeDataUtils::Uri QgsDataSourceSelectDialog::uri() const
diff --git a/src/gui/qgsdatasourceselectdialog.h b/src/gui/qgsdatasourceselectdialog.h
index d9668835d1c3..8a2796b50591 100644
--- a/src/gui/qgsdatasourceselectdialog.h
+++ b/src/gui/qgsdatasourceselectdialog.h
@@ -82,9 +82,11 @@ class GUI_EXPORT QgsDataSourceSelectWidget: public QgsPanelWidget, private Ui::Q
*
* The \a path must correspond to a valid directory existing on the file system.
*
+ * Since QGIS 3.38 the \a selectPath argument can be used to automatically select the path too.
+ *
* \since QGIS 3.28
*/
- void expandPath( const QString &path );
+ void expandPath( const QString &path, bool selectPath = false );
/**
* Returns the (possibly invalid) uri of the selected data source
@@ -102,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:
/**
@@ -135,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;
@@ -195,9 +203,11 @@ class GUI_EXPORT QgsDataSourceSelectDialog: public QDialog
*
* The \a path must correspond to a valid directory existing on the file system.
*
+ * Since QGIS 3.38 the \a selectPath argument can be used to automatically select the path too.
+ *
* \since QGIS 3.28
*/
- void expandPath( const QString &path );
+ void expandPath( const QString &path, bool selectPath = false );
/**
* Returns the (possibly invalid) uri of the selected data source