Skip to content
Permalink
Browse files

Add API for providers to test whether a particular URI should be

blocklisted and hidden from the QGIS interface, e.g. it is an internal
detail only (or sidecar file) and shouldn't be shown in things like the
browser panel

And adds blocklists for .aux.xml, .shp.xml and .tif.xml files for
the ogr/gdal providers
  • Loading branch information
nyalldawson committed Nov 5, 2020
1 parent 4c9338b commit 04dc5f5e56023ebc03cd1cc2b446e5a9b15d7933
@@ -194,6 +194,26 @@ priority for the same URI.

The default implementation returns 0 for all URIs.

.. versionadded:: 3.18
%End

virtual bool uriIsBlocklisted( const QString &uri ) const;
%Docstring
Returns ``True`` if the specified ``uri`` is known by this provider to be something which should
be blocklisted from the QGIS interface, e.g. an internal detail only.

Specifically, this method can be utilised by the browser panel to hide noisy internal details
by returning ``True`` for URIs which are known to be sidecar files only, such as ".aux.xml" files
or ".shp.xml" files, or the "ept-build.json" files which sit alongside Entwine "ept.json" point
cloud sources.

The default method returns ``False`` for all URIs.

.. warning::

Returning ``True`` from an implementation of this method indicates that ALL providers should
ignore the specified ``uri``, not just the provider associated with this metadata!

.. versionadded:: 3.18
%End

@@ -316,6 +316,21 @@ handle the URI.

.. seealso:: :py:func:`preferredProvidersForUri`

.. versionadded:: 3.18
%End

bool uriIsBlocklisted( const QString &uri ) const;
%Docstring
Returns ``True`` if the specified ``uri`` is known by any registered provider to be something which should
be blocklisted from the QGIS interface, e.g. an internal detail only.

Specifically, this method can be utilised by the browser panel to hide noisy internal details
for URIs which are known to be sidecar files only, such as ".aux.xml" files or ".shp.xml" files,
or the "ept-build.json" files which sit alongside Entwine "ept.json" point cloud sources.

This method tests whether any of the registered providers return ``True`` for the their
:py:func:`QgsProviderMetadata.uriIsBlocklisted()` implementation for the specified URI.

.. versionadded:: 3.18
%End

@@ -2357,6 +2357,24 @@ QString QgsGdalProviderMetadata::encodeUri( const QVariantMap &parts ) const
return path + ( !layerName.isEmpty() ? QStringLiteral( "|%1" ).arg( layerName ) : QString() );
}

bool QgsGdalProviderMetadata::uriIsBlocklisted( const QString &uri ) const
{
const QVariantMap parts = decodeUri( uri );
if ( !parts.contains( QStringLiteral( "path" ) ) )
return false;

QFileInfo fi( parts.value( QStringLiteral( "path" ) ).toString() );
const QString suffix = fi.completeSuffix();

// internal details only
if ( suffix.compare( QLatin1String( "aux.xml" ), Qt::CaseInsensitive ) == 0 )
return true;
if ( suffix.compare( QLatin1String( "tif.xml" ), Qt::CaseInsensitive ) == 0 )
return true;

return false;
}


QgsGdalProvider *QgsGdalProviderMetadata::createProvider( const QString &uri, const QgsDataProvider::ProviderOptions &options, QgsDataProvider::ReadFlags flags )
{
@@ -367,6 +367,7 @@ class QgsGdalProviderMetadata final: public QgsProviderMetadata
QgsGdalProviderMetadata();
QVariantMap decodeUri( const QString &uri ) const override;
QString encodeUri( const QVariantMap &parts ) const override;
bool uriIsBlocklisted( const QString &uri ) const override;
QgsGdalProvider *createProvider( const QString &uri, const QgsDataProvider::ProviderOptions &options, QgsDataProvider::ReadFlags flags = QgsDataProvider::ReadFlags() ) override;
QgsGdalProvider *createRasterDataProvider(
const QString &uri,
@@ -7167,6 +7167,21 @@ QString QgsOgrProviderMetadata::filters( FilterType type )
return QString();
}

bool QgsOgrProviderMetadata::uriIsBlocklisted( const QString &uri ) const
{
const QVariantMap parts = decodeUri( uri );
if ( !parts.contains( QStringLiteral( "path" ) ) )
return false;

QFileInfo fi( parts.value( QStringLiteral( "path" ) ).toString() );
const QString suffix = fi.completeSuffix();

// internal details only
if ( suffix.compare( QLatin1String( "shp.xml" ), Qt::CaseInsensitive ) == 0 )
return true;

return false;
}

QMap<QString, QgsAbstractProviderConnection *> QgsOgrProviderMetadata::connections( bool cached )
{
@@ -754,6 +754,7 @@ class QgsOgrProviderMetadata final: public QgsProviderMetadata
QVariantMap decodeUri( const QString &uri ) const override;
QString encodeUri( const QVariantMap &parts ) const override;
QString filters( FilterType type ) override;
bool uriIsBlocklisted( const QString &uri ) const override;
QgsVectorLayerExporter::ExportError createEmptyLayer(
const QString &uri,
const QgsFields &fields,
@@ -86,6 +86,11 @@ int QgsProviderMetadata::priorityForUri( const QString & ) const
return 0;
}

bool QgsProviderMetadata::uriIsBlocklisted( const QString & ) const
{
return false;
}

QgsDataProvider *QgsProviderMetadata::createProvider( const QString &uri,
const QgsDataProvider::ProviderOptions &options,
QgsDataProvider::ReadFlags flags )
@@ -252,6 +252,24 @@ class CORE_EXPORT QgsProviderMetadata : public QObject
*/
virtual int priorityForUri( const QString &uri ) const;

/**
* Returns TRUE if the specified \a uri is known by this provider to be something which should
* be blocklisted from the QGIS interface, e.g. an internal detail only.
*
* Specifically, this method can be utilised by the browser panel to hide noisy internal details
* by returning TRUE for URIs which are known to be sidecar files only, such as ".aux.xml" files
* or ".shp.xml" files, or the "ept-build.json" files which sit alongside Entwine "ept.json" point
* cloud sources.
*
* The default method returns FALSE for all URIs.
*
* \warning Returning TRUE from an implementation of this method indicates that ALL providers should
* ignore the specified \a uri, not just the provider associated with this metadata!
*
* \since QGIS 3.18
*/
virtual bool uriIsBlocklisted( const QString &uri ) const;

/**
* Class factory to return a pointer to a newly created QgsDataProvider object
*
@@ -772,3 +772,13 @@ bool QgsProviderRegistry::shouldDeferUriForOtherProviders( const QString &uri, c

return !providers.contains( QgsProviderRegistry::instance()->providerMetadata( providerKey ) );
}

bool QgsProviderRegistry::uriIsBlocklisted( const QString &uri ) const
{
for ( auto it = mProviders.begin(); it != mProviders.end(); ++it )
{
if ( it->second->uriIsBlocklisted( uri ) )
return true;
}
return false;
}
@@ -318,6 +318,21 @@ class CORE_EXPORT QgsProviderRegistry
*/
bool shouldDeferUriForOtherProviders( const QString &uri, const QString &providerKey ) const;

/**
* Returns TRUE if the specified \a uri is known by any registered provider to be something which should
* be blocklisted from the QGIS interface, e.g. an internal detail only.
*
* Specifically, this method can be utilised by the browser panel to hide noisy internal details
* for URIs which are known to be sidecar files only, such as ".aux.xml" files or ".shp.xml" files,
* or the "ept-build.json" files which sit alongside Entwine "ept.json" point cloud sources.
*
* This method tests whether any of the registered providers return TRUE for the their
* QgsProviderMetadata::uriIsBlocklisted() implementation for the specified URI.
*
* \since QGIS 3.18
*/
bool uriIsBlocklisted( const QString &uri ) const;

/**
* Returns a file filter string for supported vector files.
*
@@ -66,6 +66,15 @@ def testShouldDeferUriForOtherProviders(self):
self.assertFalse(QgsProviderRegistry.instance().shouldDeferUriForOtherProviders('/home/nyall/ept.json', 'ept'))
self.assertFalse(QgsProviderRegistry.instance().shouldDeferUriForOtherProviders('/home/nyall/my.json', 'ogr'))

def testUriIsBlocklisted(self):
self.assertFalse(QgsProviderRegistry.instance().uriIsBlocklisted('/home/nyall/me.tif'))
self.assertFalse(QgsProviderRegistry.instance().uriIsBlocklisted('/home/nyall/me.shp'))

# internal details only -- we should be hiding these uris!
self.assertTrue(QgsProviderRegistry.instance().uriIsBlocklisted('/home/nyall/me.shp.xml'))
self.assertTrue(QgsProviderRegistry.instance().uriIsBlocklisted('/home/nyall/me.aux.xml'))
self.assertTrue(QgsProviderRegistry.instance().uriIsBlocklisted('/home/nyall/me.tif.xml'))


if __name__ == '__main__':
unittest.main()

0 comments on commit 04dc5f5

Please sign in to comment.
You can’t perform that action at this time.