36 #include "providers/gdal/qgsgdalprovider.h"
37 #include "providers/ogr/qgsogrprovider.h"
38 #include "providers/meshmemory/qgsmeshmemorydataprovider.h"
41 #include "providers/ept/qgseptprovider.h"
47 #ifdef HAVE_STATIC_PROVIDERS
48 #include "qgswmsprovider.h"
49 #include "qgspostgresprovider.h"
59 QMutexLocker locker( &sMutex );
79 const QString &providerKey )
82 QgsProviderRegistry::Providers::const_iterator i =
83 metaData.find( providerKey );
85 if ( i != metaData.end() )
91 for (
auto it = metaData.begin(); it != metaData.end(); ++it )
93 if ( providerKey.compare( it->first, Qt::CaseInsensitive ) == 0 )
100 QgsProviderRegistry::QgsProviderRegistry(
const QString &pluginPath )
108 char **argv = qApp->argv();
109 QString appDir = argv[0];
110 int bin = appDir.findRev(
"/bin", -1,
false );
111 QString baseDir = appDir.left( bin );
112 QString mLibraryDirectory = baseDir +
"/lib";
116 mLibraryDirectory.setPath( pluginPath );
124 bool matchesUri(
const QString &uri )
const override
126 const QFileInfo fi( uri );
127 if ( fi.suffix().compare( QLatin1String(
"las" ), Qt::CaseInsensitive ) == 0 || fi.suffix().compare( QLatin1String(
"laz" ), Qt::CaseInsensitive ) == 0 )
136 QObject::tr(
"LAS and LAZ files cannot be opened by this QGIS install." ),
140 res.
detailedWarning = QObject::tr(
"The installer used to install this version of QGIS does "
141 "not include the PDAL library required for opening LAS and LAZ point clouds. Please "
142 "obtain one of the alternative installers from https://qgis.org which has point "
143 "cloud support enabled." );
145 res.
detailedWarning = QObject::tr(
"This QGIS build does not include the PDAL library dependency required for opening LAS or LAZ point clouds." );
152 void QgsProviderRegistry::init()
158 mProviders[ QgsMemoryProvider::providerKey() ] =
new QgsProviderMetadata( QgsMemoryProvider::providerKey(), QgsMemoryProvider::providerDescription(), &QgsMemoryProvider::createProvider );
162 mProviders[ QgsMeshMemoryDataProvider::providerKey() ] =
new QgsProviderMetadata( QgsMeshMemoryDataProvider::providerKey(), QgsMeshMemoryDataProvider::providerDescription(), &QgsMeshMemoryDataProvider::createProvider );
167 mProviders[ QgsGdalProvider::providerKey() ] =
new QgsGdalProviderMetadata();
171 mProviders[ QgsOgrProvider::providerKey() ] =
new QgsOgrProviderMetadata();
176 mProviders[ vt->
key() ] = vt;
182 mProviders[ pc->
key() ] = pc;
188 #ifdef HAVE_STATIC_PROVIDERS
189 mProviders[ QgsWmsProvider::providerKey() ] =
new QgsWmsProviderMetadata();
190 mProviders[ QgsPostgresProvider::providerKey() ] =
new QgsPostgresProviderMetadata();
194 #ifdef HAVE_STATIC_PROVIDERS
195 QgsDebugMsg( QStringLiteral(
"Forced only static providers" ) );
199 mLibraryDirectory.setSorting( QDir::Name | QDir::IgnoreCase );
200 mLibraryDirectory.setFilter( QDir::Files | QDir::NoSymLinks );
202 #if defined(Q_OS_WIN) || defined(__CYGWIN__)
203 mLibraryDirectory.setNameFilters( QStringList(
"*.dll" ) );
204 #elif defined(ANDROID)
205 mLibraryDirectory.setNameFilters( QStringList(
"*provider*.so" ) );
207 mLibraryDirectory.setNameFilters( QStringList( QStringLiteral(
"*.so" ) ) );
210 QgsDebugMsgLevel( QStringLiteral(
"Checking %1 for provider plugins" ).arg( mLibraryDirectory.path() ), 2 );
212 if ( mLibraryDirectory.count() == 0 )
214 QgsDebugMsg( QStringLiteral(
"No dynamic QGIS data provider plugins found in:\n%1\n" ).arg( mLibraryDirectory.path() ) );
218 QString filePattern = getenv(
"QGIS_PROVIDER_FILE" );
220 if ( !filePattern.isEmpty() )
222 fileRegexp.setPattern( filePattern );
225 typedef std::vector<QgsProviderMetadata *> *multiple_factory_function();
227 const auto constEntryInfoList = mLibraryDirectory.entryInfoList();
228 for (
const QFileInfo &fi : constEntryInfoList )
230 if ( !fileRegexp.isEmpty() )
232 if ( fileRegexp.indexIn( fi.fileName() ) == -1 )
234 QgsDebugMsg(
"provider " + fi.fileName() +
" skipped because doesn't match pattern " + filePattern );
240 if ( fi.fileName().contains( QStringLiteral(
"authmethod" ), Qt::CaseSensitivity::CaseInsensitive ) )
246 QLibrary myLib( fi.filePath() );
249 QgsDebugMsg( QStringLiteral(
"Checking %1: ...invalid (lib not loadable): %2" ).arg( myLib.fileName(), myLib.errorString() ) );
253 bool libraryLoaded {
false };
254 QFunctionPointer func = myLib.resolve( QStringLiteral(
"providerMetadataFactory" ).toLatin1().data() );
255 factory_function *
function =
reinterpret_cast< factory_function *
>(
cast_to_fptr( func ) );
261 if ( findMetadata_( mProviders, meta->
key() ) )
263 QgsDebugMsg( QStringLiteral(
"Checking %1: ...invalid (key %2 already registered)" ).arg( myLib.fileName() ).arg( meta->
key() ) );
268 mProviders[meta->
key()] = meta;
269 libraryLoaded =
true;
274 QFunctionPointer multi_func = myLib.resolve( QStringLiteral(
"multipleProviderMetadataFactory" ).toLatin1().data() );
275 multiple_factory_function *multi_function =
reinterpret_cast< multiple_factory_function *
>(
cast_to_fptr( multi_func ) );
276 if ( multi_function )
278 std::vector<QgsProviderMetadata *> *metadatas = multi_function();
279 for (
const auto meta : *metadatas )
281 if ( findMetadata_( mProviders, meta->
key() ) )
283 QgsDebugMsg( QStringLiteral(
"Checking %1: ...invalid (key %2 already registered)" ).arg( myLib.fileName() ).arg( meta->
key() ) );
288 mProviders[meta->
key()] = meta;
289 libraryLoaded =
true;
295 if ( ! libraryLoaded )
297 QgsDebugMsgLevel( QStringLiteral(
"Checking %1: ...invalid (no providerMetadataFactory method)" ).arg( myLib.fileName() ), 2 );
302 QgsDebugMsg( QStringLiteral(
"Loaded %1 providers (%2) " ).arg( mProviders.size() ).arg(
providerList().join(
';' ) ) );
304 QStringList pointCloudWildcards;
305 QStringList pointCloudFilters;
308 for ( Providers::const_iterator it = mProviders.begin(); it != mProviders.end(); ++it )
310 const QString &key = it->first;
338 QgsDebugMsgLevel( QStringLiteral(
"Checking %1: ...loaded OK (%2 file mesh filters)" ).arg( key ).arg( mMeshFileFilters.split(
";;" ).count() ), 2 );
346 QgsDebugMsgLevel( QStringLiteral(
"Checking %1: ...loaded OK (%2 file dataset filters)" ).arg( key ).arg( mMeshDatasetFileFilters.split(
";;" ).count() ), 2 );
355 #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
356 const QStringList filters =
filePointCloudFilters.split( QStringLiteral(
";;" ), QString::SkipEmptyParts );
358 const QStringList filters =
filePointCloudFilters.split( QStringLiteral(
";;" ), Qt::SkipEmptyParts );
360 for (
const QString &filter : filters )
362 pointCloudFilters.append( filter );
371 if ( !pointCloudFilters.empty() )
373 pointCloudFilters.insert( 0, QObject::tr(
"All Supported Files" ) + QStringLiteral(
" (%1)" ).arg( pointCloudWildcards.join(
' ' ) ) );
374 pointCloudFilters.insert( 1, QObject::tr(
"All Files" ) + QStringLiteral(
" (*.*)" ) );
375 mPointCloudFileFilters = pointCloudFilters.join( QLatin1String(
";;" ) );
379 mDatabaseDrivers = QgsOgrProviderUtils::databaseDrivers();
382 mDirectoryDrivers = QgsOgrProviderUtils::directoryDrivers();
385 mProtocolDrivers = QgsOgrProviderUtils::protocolDrivers();
392 void QgsProviderRegistry::clean()
395 if ( QgsProject::sProject )
398 Providers::const_iterator it = mProviders.begin();
400 while ( it != mProviders.end() )
403 it->second->cleanupProvider();
410 bool QgsProviderRegistry::exists()
412 return static_cast< bool >( sInstance );
417 qDeleteAll( mUnusableUriHandlers );
420 if ( sInstance ==
this )
440 Providers::const_iterator it = mProviders.begin();
442 if ( mProviders.empty() )
443 return QObject::tr(
"No data provider plugins are available. No vector layers can be loaded" );
448 list += QLatin1String(
"<ol>" );
450 while ( it != mProviders.end() )
453 list += QLatin1String(
"<li>" );
455 list += it->second->description();
458 list += QLatin1String(
"<br></li>" );
466 list += QLatin1String(
"</ol>" );
473 mLibraryDirectory = path;
480 return mLibraryDirectory;
493 QgsDataProvider::ReadFlags flags )
510 const QList< QgsDataItemProvider * > itemProviders =
dataItemProviders( providerKey );
515 ret = ret | itemProvider->capabilities();
526 return QVariantMap();
543 bool overwrite, QMap<int, int> &oldToNewAttrIdxMap,
544 QString &errorMessage,
545 const QMap<QString, QVariant> *options )
549 return meta->
createEmptyLayer( uri, fields, wkbType, srs, overwrite, oldToNewAttrIdxMap, errorMessage, options );
552 errorMessage = QObject::tr(
"Unable to load %1 provider" ).arg( providerKey );
553 return Qgis::VectorExportResult::ErrorInvalidProvider;
560 const QStringList &createOptions )
575 return QList<QPair<QString, QString> >();
584 return QList<QgsDataItemProvider *>();
587 int QgsProviderRegistry::listStyles(
const QString &providerKey,
const QString &uri, QStringList &ids, QStringList &names, QStringList &descriptions, QString &errCause )
593 res = meta->
listStyles( uri, ids, names, descriptions, errCause );
597 errCause = QObject::tr(
"Unable to load %1 provider" ).arg( providerKey );
612 errCause = QObject::tr(
"Unable to load %1 provider" ).arg( providerKey );
626 errCause = QObject::tr(
"Unable to load %1 provider" ).arg( providerKey );
632 const QString &sldStyle,
const QString &styleName,
const QString &styleDescription,
633 const QString &uiFileContent,
bool useAsDefault, QString &errCause )
638 ret = meta->
saveStyle( uri, qmlStyle, sldStyle, styleName, styleDescription,
639 uiFileContent, useAsDefault, errCause );
642 errCause = QObject::tr(
"Unable to load %1 provider" ).arg( providerKey );
655 errCause = QObject::tr(
"Unable to load %1 provider" ).arg( providerKey );
662 errorMessage.clear();
675 return meta->
createDb( dbPath, errCause );
678 errCause = QStringLiteral(
"Resolving createDb(...) failed" );
695 Q_UNUSED( providerKey );
698 Q_UNUSED( widgetMode );
699 QgsDebugMsg(
"deprecated call - use QgsGui::sourceSelectProviderRegistry()->createDataSourceWidget() instead" );
704 QString
const &functionName )
707 QString lib =
library( providerKey );
712 QLibrary myLib( lib );
714 QgsDebugMsg(
"Library name is " + myLib.fileName() );
718 return myLib.resolve( functionName.toLatin1().data() );
722 QgsDebugMsg(
"Cannot load library: " + myLib.errorString() );
730 QString lib =
library( providerKey );
735 std::unique_ptr< QLibrary > myLib(
new QLibrary( lib ) );
737 QgsDebugMsg(
"Library name is " + myLib->fileName() );
740 return myLib.release();
742 QgsDebugMsg(
"Cannot load library: " + myLib->errorString() );
749 QgsDebugMsg(
"deprecated - use QgsGui::providerGuiRegistry() instead." );
768 QgsDebugMsgLevel( QStringLiteral(
"Trying to register a null metadata provider!" ), 2 );
775 return mVectorFileFilters;
780 return mRasterFileFilters;
785 return mMeshFileFilters;
790 return mMeshDatasetFileFilters;
795 return mPointCloudFileFilters;
800 return mDatabaseDrivers;
805 return mDirectoryDrivers;
810 return mProtocolDrivers;
816 for ( Providers::const_iterator it = mProviders.begin(); it != mProviders.end(); ++it )
818 lst.append( it->first );
825 return findMetadata_( mProviders, providerKey );
830 QList< QgsProviderRegistry::ProviderCandidateDetails > res;
832 for (
auto it = mProviders.begin(); it != mProviders.end(); ++it )
837 const int thisProviderPriority = it->second->priorityForUri( uri );
838 if ( thisProviderPriority == 0 )
841 if ( thisProviderPriority > maxPriority )
844 maxPriority = thisProviderPriority;
846 if ( thisProviderPriority == maxPriority )
856 mUnusableUriHandlers << handler;
864 if ( handler->matchesUri( uri ) )
866 details = handler->details( uri );
876 if ( providers.empty() )
881 if ( provider.metadata()->key() == providerKey )
889 for (
auto it = mProviders.begin(); it != mProviders.end(); ++it )
891 if ( it->second->uriIsBlocklisted( uri ) )
VectorExportResult
Vector layer export result codes.
DataType
Raster data types.
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.
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.
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 deleteStyleById(const QString &providerKey, const QString &uri, QString styleId, QString &errCause)
Deletes a layer style defined by styleId.
QString loadStyle(const QString &providerKey, const QString &uri, QString &errCause)
Loads a layer style defined by uri.
Q_DECL_DEPRECATED QFunctionPointer function(const QString &providerKey, const QString &functionName)
Gets pointer to provider function.
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.
Qgis::VectorExportResult createEmptyLayer(const QString &providerKey, const QString &uri, const QgsFields &fields, QgsWkbTypes::Type wkbType, const QgsCoordinateReferenceSystem &srs, bool overwrite, QMap< int, int > &oldToNewAttrIdxMap, QString &errorMessage, const QMap< QString, QVariant > *options)
Creates new empty vector layer.
QgsTransaction * createTransaction(const QString &providerKey, const QString &connString)
Returns new instance of transaction.
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.
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 ...
QStringList providerList() const
Returns list of available providers by their keys.
QString getStyleById(const QString &providerKey, const QString &uri, QString styleId, QString &errCause)
Gets a layer style defined by styleId.
QString fileMeshDatasetFilters() const
Returns a file filter string for supported mesh dataset files.
QDir libraryDirectory() const
Returns the library directory where plugins are found.
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.
bool registerProvider(QgsProviderMetadata *providerMetadata)
register a new vector data provider from its providerMetadata
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.
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...
Type
The WKB type describes the number of dimensions a geometry has.
@ PointCloudLayer
Added in 3.18.
#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.