31#include "providers/gdal/qgsgdalprovider.h"
32#include "providers/ogr/qgsogrprovidermetadata.h"
33#include "providers/ogr/qgsogrprovider.h"
34#include "providers/meshmemory/qgsmeshmemorydataprovider.h"
37#include "providers/ept/qgseptprovider.h"
41#include "providers/copc/qgscopcprovider.h"
47#ifdef HAVE_STATIC_PROVIDERS
48#include "qgswmsprovider.h"
49#include "qgswcsprovider.h"
50#include "qgsdelimitedtextprovider.h"
51#include "qgsafsprovider.h"
52#include "qgsamsprovider.h"
54#include "qgsspatialiteprovider.h"
55#include "qgswfsprovider.h"
56#include "qgswfsprovidermetadata.h"
57#include "qgsoapifprovider.h"
58#include "qgsvirtuallayerprovider.h"
61#include "qgspostgresprovider.h"
68#include <QRegularExpression>
77 const QMutexLocker locker( &sMutex );
97 const QString &providerKey )
100 const QgsProviderRegistry::Providers::const_iterator i =
101 metaData.find( providerKey );
103 if ( i != metaData.end() )
109 for (
auto it = metaData.begin(); it != metaData.end(); ++it )
111 if ( providerKey.compare( it->first, Qt::CaseInsensitive ) == 0 )
118QgsProviderRegistry::QgsProviderRegistry(
const QString &pluginPath )
126 char **argv = qApp->argv();
127 QString appDir = argv[0];
128 int bin = appDir.findRev(
"/bin", -1,
false );
129 QString baseDir = appDir.left( bin );
130 QString mLibraryDirectory = baseDir +
"/lib";
134 mLibraryDirectory.setPath( pluginPath );
142 bool matchesUri(
const QString &uri )
const override
144 const QFileInfo fi( uri );
145 if ( fi.suffix().compare( QLatin1String(
"las" ), Qt::CaseInsensitive ) == 0 || fi.suffix().compare( QLatin1String(
"laz" ), Qt::CaseInsensitive ) == 0 )
154 QObject::tr(
"LAS and LAZ files cannot be opened by this QGIS install." ),
155 QList<Qgis::LayerType>() << Qgis::LayerType::PointCloud );
158 res.
detailedWarning = QObject::tr(
"The installer used to install this version of QGIS does "
159 "not include the PDAL library required for opening LAS and LAZ point clouds. Please "
160 "obtain one of the alternative installers from https://qgis.org which has point "
161 "cloud support enabled." );
163 res.
detailedWarning = QObject::tr(
"This QGIS build does not include the PDAL library dependency required for opening LAS or LAZ point clouds." );
170void QgsProviderRegistry::init()
175 mProviders[ QgsMemoryProvider::providerKey() ] =
new QgsMemoryProviderMetadata();
179 mProviders[ QgsMeshMemoryDataProvider::providerKey() ] =
new QgsMeshMemoryProviderMetadata();
183 mProviders[ QgsGdalProvider::providerKey() ] =
new QgsGdalProviderMetadata();
187 mProviders[ QgsOgrProvider::providerKey() ] =
new QgsOgrProviderMetadata();
192 mProviders[ vt->
key() ] = vt;
198 mProviders[ pc->
key() ] = pc;
205 mProviders[ pc->
key() ] = pc;
210#ifdef HAVE_STATIC_PROVIDERS
211 mProviders[ QgsWmsProvider::providerKey() ] =
new QgsWmsProviderMetadata();
212 mProviders[ QgsWcsProvider::providerKey() ] =
new QgsWcsProviderMetadata();
213 mProviders[ QgsDelimitedTextProvider::providerKey() ] =
new QgsDelimitedTextProviderMetadata();
214 mProviders[ QgsAfsProvider::providerKey() ] =
new QgsAfsProviderMetadata();
215 mProviders[ QgsAmsProvider::providerKey() ] =
new QgsAmsProviderMetadata();
216#ifdef HAVE_SPATIALITE
217 mProviders[ QgsSpatiaLiteProvider::providerKey() ] =
new QgsSpatiaLiteProviderMetadata();
218 mProviders[ QgsWFSProvider::providerKey() ] =
new QgsWfsProviderMetadata();
219 mProviders[ QgsOapifProvider::providerKey() ] =
new QgsOapifProviderMetadata();
220 mProviders[ QgsVirtualLayerProvider::providerKey() ] =
new QgsVirtualLayerProviderMetadata();
222#ifdef HAVE_POSTGRESQL
223 mProviders[ QgsPostgresProvider::providerKey() ] =
new QgsPostgresProviderMetadata();
228#ifdef HAVE_STATIC_PROVIDERS
229 QgsDebugMsg( QStringLiteral(
"Forced only static providers" ) );
233 mLibraryDirectory.setSorting( QDir::Name | QDir::IgnoreCase );
234 mLibraryDirectory.setFilter( QDir::Files | QDir::NoSymLinks );
236#if defined(Q_OS_WIN) || defined(__CYGWIN__)
237 mLibraryDirectory.setNameFilters( QStringList(
"*.dll" ) );
238#elif defined(ANDROID)
239 mLibraryDirectory.setNameFilters( QStringList(
"*provider_*.so" ) );
241 mLibraryDirectory.setNameFilters( QStringList( QStringLiteral(
"*.so" ) ) );
244 QgsDebugMsgLevel( QStringLiteral(
"Checking %1 for provider plugins" ).arg( mLibraryDirectory.path() ), 2 );
246 if ( mLibraryDirectory.count() == 0 )
248 QgsDebugMsg( QStringLiteral(
"No dynamic QGIS data provider plugins found in:\n%1\n" ).arg( mLibraryDirectory.path() ) );
252 const QString filePattern = getenv(
"QGIS_PROVIDER_FILE" );
253 QRegularExpression fileRegexp;
254 if ( !filePattern.isEmpty() )
256 fileRegexp.setPattern( filePattern );
259 typedef std::vector<QgsProviderMetadata *> *multiple_factory_function();
261 const auto constEntryInfoList = mLibraryDirectory.entryInfoList();
262 for (
const QFileInfo &fi : constEntryInfoList )
264 if ( !filePattern.isEmpty() )
266 if ( fi.fileName().indexOf( fileRegexp ) == -1 )
268 QgsDebugMsg(
"provider " + fi.fileName() +
" skipped because doesn't match pattern " + filePattern );
274 if ( fi.fileName().contains( QStringLiteral(
"authmethod" ), Qt::CaseSensitivity::CaseInsensitive ) )
280 QLibrary myLib( fi.filePath() );
283 QgsDebugMsg( QStringLiteral(
"Checking %1: ...invalid (lib not loadable): %2" ).arg( myLib.fileName(), myLib.errorString() ) );
287 bool libraryLoaded {
false };
288 QFunctionPointer func = myLib.resolve( QStringLiteral(
"providerMetadataFactory" ).toLatin1().data() );
295 if ( findMetadata_( mProviders, meta->
key() ) )
297 QgsDebugMsg( QStringLiteral(
"Checking %1: ...invalid (key %2 already registered)" ).arg( myLib.fileName() ).arg( meta->
key() ) );
302 mProviders[meta->
key()] = meta;
303 libraryLoaded =
true;
308 QFunctionPointer multi_func = myLib.resolve( QStringLiteral(
"multipleProviderMetadataFactory" ).toLatin1().data() );
309 multiple_factory_function *multi_function =
reinterpret_cast< multiple_factory_function *
>(
cast_to_fptr( multi_func ) );
310 if ( multi_function )
312 std::vector<QgsProviderMetadata *> *metadatas = multi_function();
313 for (
const auto meta : *metadatas )
315 if ( findMetadata_( mProviders, meta->
key() ) )
317 QgsDebugMsg( QStringLiteral(
"Checking %1: ...invalid (key %2 already registered)" ).arg( myLib.fileName() ).arg( meta->
key() ) );
322 mProviders[meta->
key()] = meta;
323 libraryLoaded =
true;
329 if ( ! libraryLoaded )
331 QgsDebugMsgLevel( QStringLiteral(
"Checking %1: ...invalid (no providerMetadataFactory method)" ).arg( myLib.fileName() ), 2 );
336 QgsDebugMsg( QStringLiteral(
"Loaded %1 providers (%2) " ).arg( mProviders.size() ).arg(
providerList().join(
';' ) ) );
338 QStringList pointCloudWildcards;
339 QStringList pointCloudFilters;
342 for ( Providers::const_iterator it = mProviders.begin(); it != mProviders.end(); ++it )
344 const QString &key = it->first;
372 QgsDebugMsgLevel( QStringLiteral(
"Checking %1: ...loaded OK (%2 file mesh filters)" ).arg( key ).arg( mMeshFileFilters.split(
";;" ).count() ), 2 );
380 QgsDebugMsgLevel( QStringLiteral(
"Checking %1: ...loaded OK (%2 file dataset filters)" ).arg( key ).arg( mMeshDatasetFileFilters.split(
";;" ).count() ), 2 );
389#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
390 const QStringList filters =
filePointCloudFilters.split( QStringLiteral(
";;" ), QString::SkipEmptyParts );
392 const QStringList filters =
filePointCloudFilters.split( QStringLiteral(
";;" ), Qt::SkipEmptyParts );
394 for (
const QString &filter : filters )
396 pointCloudFilters.append( filter );
405 if ( !pointCloudFilters.empty() )
407 pointCloudFilters.insert( 0, QObject::tr(
"All Supported Files" ) + QStringLiteral(
" (%1)" ).arg( pointCloudWildcards.join(
' ' ) ) );
408 pointCloudFilters.insert( 1, QObject::tr(
"All Files" ) + QStringLiteral(
" (*.*)" ) );
409 mPointCloudFileFilters = pointCloudFilters.join( QLatin1String(
";;" ) );
413 mDatabaseDrivers = QgsOgrProviderUtils::databaseDrivers();
416 mDirectoryDrivers = QgsOgrProviderUtils::directoryDrivers();
419 mProtocolDrivers = QgsOgrProviderUtils::protocolDrivers();
426void QgsProviderRegistry::clean()
429 if ( QgsProject::sProject )
432 Providers::const_iterator it = mProviders.begin();
434 while ( it != mProviders.end() )
437 it->second->cleanupProvider();
444bool QgsProviderRegistry::exists()
446 return static_cast< bool >( sInstance );
451 qDeleteAll( mUnusableUriHandlers );
454 if ( sInstance ==
this )
474 Providers::const_iterator it = mProviders.begin();
476 if ( mProviders.empty() )
477 return QObject::tr(
"No data provider plugins are available. No vector layers can be loaded" );
482 list += QLatin1String(
"<ol>" );
484 while ( it != mProviders.end() )
487 list += QLatin1String(
"<li>" );
489 list += it->second->description();
492 list += QLatin1String(
"<br></li>" );
500 list += QLatin1String(
"</ol>" );
507 mLibraryDirectory = path;
514 return mLibraryDirectory;
527 QgsDataProvider::ReadFlags flags )
544 const QList< QgsDataItemProvider * > itemProviders =
dataItemProviders( providerKey );
549 ret = ret | itemProvider->capabilities();
560 return QVariantMap();
595 bool overwrite, QMap<int, int> &oldToNewAttrIdxMap,
596 QString &errorMessage,
597 const QMap<QString, QVariant> *options )
601 return meta->
createEmptyLayer( uri, fields, wkbType, srs, overwrite, oldToNewAttrIdxMap, errorMessage, options );
604 errorMessage = QObject::tr(
"Unable to load %1 provider" ).arg( providerKey );
605 return Qgis::VectorExportResult::ErrorInvalidProvider;
612 const QStringList &createOptions )
627 return QList<QPair<QString, QString> >();
636 return QList<QgsDataItemProvider *>();
639int QgsProviderRegistry::listStyles(
const QString &providerKey,
const QString &uri, QStringList &ids, QStringList &names, QStringList &descriptions, QString &errCause )
645 res = meta->
listStyles( uri, ids, names, descriptions, errCause );
649 errCause = QObject::tr(
"Unable to load %1 provider" ).arg( providerKey );
660 return meta->
styleExists( uri, styleId, errorCause );
664 errorCause = QObject::tr(
"Unable to load %1 provider" ).arg( providerKey );
679 errCause = QObject::tr(
"Unable to load %1 provider" ).arg( providerKey );
686 const bool ret(
false );
693 errCause = QObject::tr(
"Unable to load %1 provider" ).arg( providerKey );
699 const QString &sldStyle,
const QString &styleName,
const QString &styleDescription,
700 const QString &uiFileContent,
bool useAsDefault, QString &errCause )
705 ret = meta->
saveStyle( uri, qmlStyle, sldStyle, styleName, styleDescription,
706 uiFileContent, useAsDefault, errCause );
709 errCause = QObject::tr(
"Unable to load %1 provider" ).arg( providerKey );
722 errCause = QObject::tr(
"Unable to load %1 provider" ).arg( providerKey );
735 errCause = QObject::tr(
"Unable to load %1 provider" ).arg( providerKey );
742 errorMessage.clear();
755 return meta->
createDb( dbPath, errCause );
758 errCause = QStringLiteral(
"Resolving createDb(...) failed" );
775 Q_UNUSED( providerKey );
778 Q_UNUSED( widgetMode );
779 QgsDebugMsg(
"deprecated call - use QgsGui::sourceSelectProviderRegistry()->createDataSourceWidget() instead" );
784 QString
const &functionName )
const
787 const QString lib =
library( providerKey );
792 QLibrary myLib( lib );
794 QgsDebugMsg(
"Library name is " + myLib.fileName() );
798 return myLib.resolve( functionName.toLatin1().data() );
802 QgsDebugMsg(
"Cannot load library: " + myLib.errorString() );
810 const QString lib =
library( providerKey );
815 std::unique_ptr< QLibrary > myLib(
new QLibrary( lib ) );
817 QgsDebugMsg(
"Library name is " + myLib->fileName() );
820 return myLib.release();
822 QgsDebugMsg(
"Cannot load library: " + myLib->errorString() );
829 QgsDebugMsg(
"deprecated - use QgsGui::providerGuiRegistry() instead." );
848 QgsDebugMsgLevel( QStringLiteral(
"Trying to register a null metadata provider!" ), 2 );
855 return mVectorFileFilters;
860 return mRasterFileFilters;
865 return mMeshFileFilters;
870 return mMeshDatasetFileFilters;
875 return mPointCloudFileFilters;
880 return mDatabaseDrivers;
885 return mDirectoryDrivers;
890 return mProtocolDrivers;
896 for ( Providers::const_iterator it = mProviders.begin(); it != mProviders.end(); ++it )
898 lst.append( it->first );
905 return findMetadata_( mProviders, providerKey );
911 for ( Providers::const_iterator it = mProviders.begin(); it != mProviders.end(); ++it )
913 if ( it->second->supportedLayerTypes().contains( type ) )
914 lst.insert( it->first );
921 QList< QgsProviderRegistry::ProviderCandidateDetails > res;
923 for (
auto it = mProviders.begin(); it != mProviders.end(); ++it )
928 const int thisProviderPriority = it->second->priorityForUri( uri );
929 if ( thisProviderPriority == 0 )
932 if ( thisProviderPriority > maxPriority )
935 maxPriority = thisProviderPriority;
937 if ( thisProviderPriority == maxPriority )
947 mUnusableUriHandlers << handler;
955 if ( handler->matchesUri( uri ) )
957 details = handler->details( uri );
967 if ( providers.empty() )
972 if ( provider.metadata()->key() == providerKey )
980 for (
auto it = mProviders.begin(); it != mProviders.end(); ++it )
982 if ( it->second->uriIsBlocklisted( uri ) )
994 QList<QgsProviderSublayerDetails> res;
995 for (
auto it = mProviders.begin(); it != mProviders.end(); ++it )
1001 res.append( it->second->querySublayers( uri, flags, feedback ) );
VectorExportResult
Vector layer export result codes.
DataType
Raster data types.
LayerType
Types of layers that can be added to a map.
WkbType
The WKB type describes the number of dimensions a geometry has.
This class represents a coordinate reference system (CRS).
This is the interface for those who want to add custom data items to the browser tree.
Abstract base class for spatial data provider implementations.
Base class for feedback objects to be used for cancellation of something running in a worker thread.
bool isCanceled() const SIP_HOLDGIL
Tells whether the operation has been canceled already.
Container of fields for a vector layer.
static QString wildcardsFromFilter(const QString &filter)
Given a filter string like "GeoTIFF Files (*.tiff *.tif)", extracts the wildcard portion of this filt...
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
Custom exception class which is raised when an operation is not supported.
static QgsProject * instance()
Returns the QgsProject singleton instance.
void removeAllMapLayers()
Removes all registered layers.
Contains information pertaining to a candidate provider.
Contains information about unusable URIs which aren't handled by any registered providers.
QString detailedWarning
Contains a longer, user-friendly, translated message advising why the URI is not usable.
An interface used to handle unusable URIs which aren't handled by any registered providers,...
virtual UnusableUriDetails details(const QString &uri) const =0
Returns the details for advising the user why the uri is not usable.
virtual bool matchesUri(const QString &uri) const =0
Returns true if the handle is an unusable URI handler for the specified uri.
A registry / canonical manager of data providers.
QString absoluteToRelativeUri(const QString &providerKey, const QString &uri, const QgsReadWriteContext &context) const
Converts absolute path(s) to relative path(s) in the given provider-specific URI.
QgsDataProvider * createProvider(const QString &providerKey, const QString &dataSource, const QgsDataProvider::ProviderOptions &options=QgsDataProvider::ProviderOptions(), QgsDataProvider::ReadFlags flags=QgsDataProvider::ReadFlags())
Creates a new instance of a provider.
std::map< QString, QgsProviderMetadata * > Providers
Type for data provider metadata associative container.
bool styleExists(const QString &providerKey, const QString &uri, const QString &styleId, QString &errorCause)
Returns true if a layer style with the specified styleId exists in the provider defined by providerKe...
QString loadStyle(const QString &providerKey, const QString &uri, QString &errCause)
Loads a layer style defined by uri.
QString getStyleById(const QString &providerKey, const QString &uri, const QString &styleId, QString &errCause)
Gets a layer style defined by styleId.
QVariantMap decodeUri(const QString &providerKey, const QString &uri)
Breaks a provider data source URI into its component paths (e.g.
void setLibraryDirectory(const QDir &path)
Sets library directory where to search for plugins.
QgsTransaction * createTransaction(const QString &providerKey, const QString &connString)
Returns new instance of transaction.
QList< QgsProviderSublayerDetails > querySublayers(const QString &uri, Qgis::SublayerQueryFlags flags=Qgis::SublayerQueryFlags(), QgsFeedback *feedback=nullptr) const
Queries the specified uri and returns a list of any valid sublayers found in the dataset which can be...
Q_DECL_DEPRECATED void registerGuis(QWidget *widget)
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance.
WidgetMode
Different ways a source select dialog can be used.
QString protocolDrivers() const
Returns a string containing the available protocol drivers.
QList< QgsProviderRegistry::ProviderCandidateDetails > preferredProvidersForUri(const QString &uri) const
Returns the details for the preferred provider(s) for opening the specified uri.
Q_DECL_DEPRECATED QString library(const QString &providerKey) const
Returns path for the library of the provider.
QString databaseDrivers() const
Returns a string containing the available database drivers.
QString encodeUri(const QString &providerKey, const QVariantMap &parts)
Reassembles a provider data source URI from its component paths (e.g.
QList< QgsDataItemProvider * > dataItemProviders(const QString &providerKey) const
Returns list of data item providers of the provider.
QgsRasterDataProvider * createRasterDataProvider(const QString &providerKey, const QString &uri, const QString &format, int nBands, Qgis::DataType type, int width, int height, double *geoTransform, const QgsCoordinateReferenceSystem &crs, const QStringList &createOptions=QStringList())
Creates new instance of raster data provider.
QList< QPair< QString, QString > > pyramidResamplingMethods(const QString &providerKey)
Returns list of raster pyramid resampling methods.
bool uriIsBlocklisted(const QString &uri) const
Returns true if the specified uri is known by any registered provider to be something which should be...
Q_DECL_DEPRECATED QLibrary * createProviderLibrary(const QString &providerKey) const
Returns a new QLibrary for the specified providerKey.
Qgis::VectorExportResult createEmptyLayer(const QString &providerKey, const QString &uri, const QgsFields &fields, Qgis::WkbType wkbType, const QgsCoordinateReferenceSystem &srs, bool overwrite, QMap< int, int > &oldToNewAttrIdxMap, QString &errorMessage, const QMap< QString, QVariant > *options)
Creates new empty vector layer.
bool handleUnusableUri(const QString &uri, UnusableUriDetails &details) const
Returns true if the specified uri can potentially be handled by QGIS, if additional dependencies or b...
QString fileVectorFilters() const
Returns a file filter string for supported vector files.
QString fileRasterFilters() const
Returns a file filter string for supported raster files.
QString fileMeshFilters() const
Returns a file filter string for supported mesh files.
QString pluginList(bool asHtml=false) const
Returns list of provider plugins found.
Q_DECL_DEPRECATED int providerCapabilities(const QString &providerKey) const
Returns the provider capabilities.
bool shouldDeferUriForOtherProviders(const QString &uri, const QString &providerKey) const
Returns true if the provider with matching providerKey should defer handling of the specified uri to ...
bool deleteStyleById(const QString &providerKey, const QString &uri, const QString &styleId, QString &errCause)
Deletes a layer style defined by styleId.
QStringList providerList() const
Returns list of available providers by their keys.
QString fileMeshDatasetFilters() const
Returns a file filter string for supported mesh dataset files.
QString loadStoredStyle(const QString &providerKey, const QString &uri, QString &styleName, QString &errCause)
Loads a layer style from the provider storage, reporting its name.
QDir libraryDirectory() const
Returns the library directory where plugins are found.
QString relativeToAbsoluteUri(const QString &providerKey, const QString &uri, const QgsReadWriteContext &context) const
Converts relative path(s) to absolute path(s) in the given provider-specific URI.
QgsProviderMetadata * providerMetadata(const QString &providerKey) const
Returns metadata of the provider or nullptr if not found.
int listStyles(const QString &providerKey, const QString &uri, QStringList &ids, QStringList &names, QStringList &descriptions, QString &errCause)
Lists stored layer styles in the provider defined by providerKey and uri.
bool createDb(const QString &providerKey, const QString &dbPath, QString &errCause)
Creates database by the provider on the path.
bool saveStyle(const QString &providerKey, const QString &uri, const QString &qmlStyle, const QString &sldStyle, const QString &styleName, const QString &styleDescription, const QString &uiFileContent, bool useAsDefault, QString &errCause)
Saves a layer style to provider.
QSet< QString > providersForLayerType(Qgis::LayerType type) const
Returns a list of the provider keys for available providers which handle the specified layer type.
bool registerProvider(QgsProviderMetadata *providerMetadata)
register a new vector data provider from its providerMetadata
Q_DECL_DEPRECATED QFunctionPointer function(const QString &providerKey, const QString &functionName) const
Gets pointer to provider function.
QString directoryDrivers() const
Returns a string containing the available directory drivers.
bool saveLayerMetadata(const QString &providerKey, const QString &uri, const QgsLayerMetadata &metadata, QString &errorMessage) SIP_THROW(QgsNotSupportedException)
Saves metadata to the layer corresponding to the specified uri.
bool registerUnusableUriHandler(UnusableUriHandlerInterface *handler)
Registers an unusable URI handler, used to handle unusable URIs which aren't handled by any registere...
Q_DECL_DEPRECATED QWidget * createSelectionWidget(const QString &providerKey, QWidget *parent=nullptr, Qt::WindowFlags fl=Qt::WindowFlags(), QgsProviderRegistry::WidgetMode widgetMode=QgsProviderRegistry::WidgetMode::None)
Returns a new widget for selecting layers from a provider.
QString filePointCloudFilters() const
Returns a file filter string for supported point clouds.
Base class for raster data providers.
The class is used as a container of context for various read/write operations on other objects.
Scoped object for logging of the runtime for a single operation or group of operations.
This class allows including a set of layers in a database-side transaction, provided the layer data p...
#define Q_NOWARN_DEPRECATED_POP
#define Q_NOWARN_DEPRECATED_PUSH
#define QgsDebugMsgLevel(str, level)
void cleanupProviderFunction_t()
const QgsCoordinateReferenceSystem & crs
Setting options for creating vector data providers.