Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
QgsProviderSublayerTask: make it possible to restrict it to a particu…
…lar provider

Avoids the 'ERROR: Status 2: File  pagingEnabled='false'
preferCoordinatesForWfsT11='false' restrictToRequestBBOX='1'
srsname='EPSG:25832' typename='dvg:nw_dvg1_bld'
url='https://www.wfs.nrw.de/geobasis/wfs_nw_dvg' version='auto' could
not be found' type of message in the scenario described by
#51144 (comment)
  • Loading branch information
rouault committed Jan 3, 2023
1 parent 494e636 commit 8866b0c
Show file tree
Hide file tree
Showing 8 changed files with 45 additions and 9 deletions.
Expand Up @@ -398,7 +398,7 @@ The optional ``feedback`` argument can be used to provide cancellation support f

virtual QString suggestGroupNameForUri( const QString &uri ) const;
%Docstring
Returns a name that can be used as a group name for sublayers got from
Returns a name that can be used as a group name for sublayers retrieved from
the specified ``uri``.

The default implementation returns an empty string.
Expand Down
Expand Up @@ -39,6 +39,14 @@ possible, regardless of how expensive this may be.
%Docstring
Constructor for QgsProviderSublayerTask, which retrieves sublayer details for the
specified ``uri``.
%End

QgsProviderSublayerTask( const QString &uri, const QString &providerKey, bool includeSystemTables = false );
%Docstring
Constructor for QgsProviderSublayerTask, which retrieves sublayer details for the
specified ``uri``, restricted to a particular provider.

.. versionadded:: 3.30
%End

~QgsProviderSublayerTask();
Expand Down
8 changes: 4 additions & 4 deletions src/app/layers/qgsapplayerhandling.cpp
Expand Up @@ -324,7 +324,7 @@ QList< QgsMapLayer * > QgsAppLayerHandling::addOgrVectorLayers( const QStringLis
case SublayerHandling::AskUser:
{
// prompt user for sublayers
QgsProviderSublayersDialog dlg( uri, path, sublayers, {QgsMapLayerType::VectorLayer}, QgisApp::instance() );
QgsProviderSublayersDialog dlg( uri, QString(), path, sublayers, {QgsMapLayerType::VectorLayer}, QgisApp::instance() );

if ( dlg.exec() )
sublayers = dlg.selectedLayers();
Expand Down Expand Up @@ -534,7 +534,7 @@ bool QgsAppLayerHandling::askUserForZipItemLayers( const QString &path, const QL
case SublayerHandling::AskUser:
{
// prompt user for sublayers
QgsProviderSublayersDialog dlg( path, path, sublayers, acceptableTypes, QgisApp::instance() );
QgsProviderSublayersDialog dlg( path, QString(), path, sublayers, acceptableTypes, QgisApp::instance() );

if ( dlg.exec() )
sublayers = dlg.selectedLayers();
Expand Down Expand Up @@ -936,7 +936,7 @@ QList< QgsMapLayer * > QgsAppLayerHandling::openLayer( const QString &fileName,
case SublayerHandling::AskUser:
{
// prompt user for sublayers
QgsProviderSublayersDialog dlg( fileName, fileName, sublayers, {}, QgisApp::instance() );
QgsProviderSublayersDialog dlg( fileName, QString(), fileName, sublayers, {}, QgisApp::instance() );
dlg.setNonLayerItems( nonLayerItems );

if ( dlg.exec() )
Expand Down Expand Up @@ -1373,7 +1373,7 @@ T *QgsAppLayerHandling::addLayerPrivate( QgsMapLayerType type, const QString &ur
{
case SublayerHandling::AskUser:
{
QgsProviderSublayersDialog dlg( updatedUri, path, sublayers, {type}, QgisApp::instance() );
QgsProviderSublayersDialog dlg( updatedUri, providerKey, path, sublayers, {type}, QgisApp::instance() );
QString groupName = providerMetadata->suggestGroupNameForUri( uri );
if ( !groupName.isEmpty() )
dlg.setGroupName( groupName );
Expand Down
2 changes: 1 addition & 1 deletion src/core/providers/qgsprovidermetadata.h
Expand Up @@ -458,7 +458,7 @@ class CORE_EXPORT QgsProviderMetadata : public QObject
virtual QList< QgsProviderSublayerDetails > querySublayers( const QString &uri, Qgis::SublayerQueryFlags flags = Qgis::SublayerQueryFlags(), QgsFeedback *feedback = nullptr ) const;

/**
* Returns a name that can be used as a group name for sublayers got from
* Returns a name that can be used as a group name for sublayers retrieved from
* the specified \a uri.
*
* The default implementation returns an empty string.
Expand Down
19 changes: 18 additions & 1 deletion src/core/providers/qgsprovidersublayertask.cpp
Expand Up @@ -17,6 +17,7 @@

#include "qgsprovidersublayertask.h"
#include "qgsfeedback.h"
#include "qgsprovidermetadata.h"
#include "qgsproviderregistry.h"
#include "qgsprovidersublayerdetails.h"
#include "qgsreadwritelocker.h"
Expand All @@ -28,6 +29,14 @@ QgsProviderSublayerTask::QgsProviderSublayerTask( const QString &uri, bool inclu
{
}

QgsProviderSublayerTask::QgsProviderSublayerTask( const QString &uri, const QString &providerKey, bool includeSystemTables )
: QgsTask( tr( "Retrieving layers" ), QgsTask::CanCancel | QgsTask::CancelWithoutPrompt | QgsTask::Silent )
, mUri( uri )
, mProviderKey( providerKey )
, mIncludeSystemTables( includeSystemTables )
{
}

QList<QgsProviderSublayerDetails> QgsProviderSublayerTask::results() const
{
const QgsReadWriteLocker locker( mLock, QgsReadWriteLocker::Read );
Expand All @@ -44,7 +53,15 @@ bool QgsProviderSublayerTask::run()
if ( mIncludeSystemTables )
flags |= Qgis::SublayerQueryFlag::IncludeSystemTables;

const QList<QgsProviderSublayerDetails> res = QgsProviderRegistry::instance()->querySublayers( mUri, flags, mFeedback.get() );
QList<QgsProviderSublayerDetails> res;
if ( mProviderKey.isEmpty() )
res = QgsProviderRegistry::instance()->querySublayers( mUri, flags, mFeedback.get() );
else
{
QgsProviderMetadata *provider = QgsProviderRegistry::instance()->providerMetadata( mProviderKey );
if ( provider )
res = provider->querySublayers( mUri, flags, mFeedback.get() );
}

const QgsReadWriteLocker locker( mLock, QgsReadWriteLocker::Write );
mResults = res;
Expand Down
10 changes: 10 additions & 0 deletions src/core/providers/qgsprovidersublayertask.h
Expand Up @@ -55,6 +55,14 @@ class CORE_EXPORT QgsProviderSublayerTask : public QgsTask
*/
QgsProviderSublayerTask( const QString &uri, bool includeSystemTables = false );

/**
* Constructor for QgsProviderSublayerTask, which retrieves sublayer details for the
* specified \a uri, restricted to a particular provider.
*
* \since QGIS 3.30
*/
QgsProviderSublayerTask( const QString &uri, const QString &providerKey, bool includeSystemTables = false );

~QgsProviderSublayerTask() override;

/**
Expand All @@ -72,6 +80,8 @@ class CORE_EXPORT QgsProviderSublayerTask : public QgsTask

QString mUri;

QString mProviderKey;

bool mIncludeSystemTables = false;

std::unique_ptr< QgsFeedback > mFeedback;
Expand Down
4 changes: 2 additions & 2 deletions src/gui/qgsprovidersublayersdialog.cpp
Expand Up @@ -111,7 +111,7 @@ void QgsProviderSublayerDialogModel::setGeometryTypesResolved( bool resolved )
emit dataChanged( index( 0, 0 ), index( rowCount( QModelIndex() ), columnCount() ) );
}

QgsProviderSublayersDialog::QgsProviderSublayersDialog( const QString &uri, const QString &filePathIn, const QList<QgsProviderSublayerDetails> initialDetails, const QList<QgsMapLayerType> &acceptableTypes, QWidget *parent, Qt::WindowFlags fl )
QgsProviderSublayersDialog::QgsProviderSublayersDialog( const QString &uri, const QString &providerKey, const QString &filePathIn, const QList<QgsProviderSublayerDetails> initialDetails, const QList<QgsMapLayerType> &acceptableTypes, QWidget *parent, Qt::WindowFlags fl )
: QDialog( parent, fl )
{
setupUi( this );
Expand Down Expand Up @@ -177,7 +177,7 @@ QgsProviderSublayersDialog::QgsProviderSublayersDialog( const QString &uri, cons
if ( QgsProviderUtils::sublayerDetailsAreIncomplete( initialDetails ) )
{
// initial details are incomplete, so fire up a task in the background to fully populate the model...
mTask = new QgsProviderSublayerTask( uri, true );
mTask = new QgsProviderSublayerTask( uri, providerKey, true );
connect( mTask.data(), &QgsProviderSublayerTask::taskCompleted, this, [ = ]
{
QList< QgsProviderSublayerDetails > res = mTask->results();
Expand Down
1 change: 1 addition & 0 deletions src/gui/qgsprovidersublayersdialog.h
Expand Up @@ -78,6 +78,7 @@ class GUI_EXPORT QgsProviderSublayersDialog : public QDialog, private Ui::QgsPro
* Constructor.
*/
QgsProviderSublayersDialog( const QString &uri,
const QString &providerKey,
const QString &filePath,
const QList< QgsProviderSublayerDetails> initialDetails = QList< QgsProviderSublayerDetails>(),
const QList< QgsMapLayerType > &acceptableTypes = QList< QgsMapLayerType >(),
Expand Down

0 comments on commit 8866b0c

Please sign in to comment.