33 #include "providers/gdal/qgsgdalprovider.h"
34 #include "providers/ogr/qgsogrprovidermetadata.h"
35 #include "providers/ogr/qgsogrprovider.h"
36 #include "providers/meshmemory/qgsmeshmemorydataprovider.h"
39 #include "providers/ept/qgseptprovider.h"
45 #ifdef HAVE_STATIC_PROVIDERS
46 #include "qgswmsprovider.h"
47 #include "qgswcsprovider.h"
48 #include "qgsdelimitedtextprovider.h"
49 #include "qgsafsprovider.h"
50 #include "qgsamsprovider.h"
51 #ifdef HAVE_SPATIALITE
52 #include "qgsspatialiteprovider.h"
53 #include "qgswfsprovider.h"
54 #include "qgsoapifprovider.h"
55 #include "qgsvirtuallayerprovider.h"
57 #ifdef HAVE_POSTGRESQL
58 #include "qgspostgresprovider.h"
65 #include <QRegularExpression>
74 const QMutexLocker locker( &sMutex );
94 const QString &providerKey )
97 const QgsProviderRegistry::Providers::const_iterator i =
98 metaData.find( providerKey );
100 if ( i != metaData.end() )
106 for (
auto it = metaData.begin(); it != metaData.end(); ++it )
108 if ( providerKey.compare( it->first, Qt::CaseInsensitive ) == 0 )
115 QgsProviderRegistry::QgsProviderRegistry(
const QString &pluginPath )
123 char **argv = qApp->argv();
124 QString appDir = argv[0];
125 int bin = appDir.findRev(
"/bin", -1,
false );
126 QString baseDir = appDir.left( bin );
127 QString mLibraryDirectory = baseDir +
"/lib";
131 mLibraryDirectory.setPath( pluginPath );
139 bool matchesUri(
const QString &uri )
const override
141 const QFileInfo fi( uri );
142 if ( fi.suffix().compare( QLatin1String(
"las" ), Qt::CaseInsensitive ) == 0 || fi.suffix().compare( QLatin1String(
"laz" ), Qt::CaseInsensitive ) == 0 )
151 QObject::tr(
"LAS and LAZ files cannot be opened by this QGIS install." ),
155 res.
detailedWarning = QObject::tr(
"The installer used to install this version of QGIS does "
156 "not include the PDAL library required for opening LAS and LAZ point clouds. Please "
157 "obtain one of the alternative installers from https://qgis.org which has point "
158 "cloud support enabled." );
160 res.
detailedWarning = QObject::tr(
"This QGIS build does not include the PDAL library dependency required for opening LAS or LAZ point clouds." );
167 void QgsProviderRegistry::init()
173 mProviders[ QgsMemoryProvider::providerKey() ] =
new QgsProviderMetadata( QgsMemoryProvider::providerKey(), QgsMemoryProvider::providerDescription(), &QgsMemoryProvider::createProvider );
177 mProviders[ QgsMeshMemoryDataProvider::providerKey() ] =
new QgsProviderMetadata( QgsMeshMemoryDataProvider::providerKey(), QgsMeshMemoryDataProvider::providerDescription(), &QgsMeshMemoryDataProvider::createProvider );
182 mProviders[ QgsGdalProvider::providerKey() ] =
new QgsGdalProviderMetadata();
186 mProviders[ QgsOgrProvider::providerKey() ] =
new QgsOgrProviderMetadata();
191 mProviders[ vt->
key() ] = vt;
197 mProviders[ pc->
key() ] = pc;
203 #ifdef HAVE_STATIC_PROVIDERS
204 mProviders[ QgsWmsProvider::providerKey() ] =
new QgsWmsProviderMetadata();
205 mProviders[ QgsWcsProvider::providerKey() ] =
new QgsWcsProviderMetadata();
206 mProviders[ QgsDelimitedTextProvider::providerKey() ] =
new QgsDelimitedTextProviderMetadata();
207 mProviders[ QgsAfsProvider::providerKey() ] =
new QgsAfsProviderMetadata();
208 mProviders[ QgsAmsProvider::providerKey() ] =
new QgsAmsProviderMetadata();
209 #ifdef HAVE_SPATIALITE
210 mProviders[ QgsSpatiaLiteProvider::providerKey() ] =
new QgsSpatiaLiteProviderMetadata();
211 mProviders[ QgsWFSProvider::providerKey() ] =
new QgsWfsProviderMetadata();
212 mProviders[ QgsOapifProvider::providerKey() ] =
new QgsOapifProviderMetadata();
213 mProviders[ QgsVirtualLayerProvider::providerKey() ] =
new QgsVirtualLayerProviderMetadata();
215 #ifdef HAVE_POSTGRESQL
216 mProviders[ QgsPostgresProvider::providerKey() ] =
new QgsPostgresProviderMetadata();
221 #ifdef HAVE_STATIC_PROVIDERS
222 QgsDebugMsg( QStringLiteral(
"Forced only static providers" ) );
226 mLibraryDirectory.setSorting( QDir::Name | QDir::IgnoreCase );
227 mLibraryDirectory.setFilter( QDir::Files | QDir::NoSymLinks );
229 #if defined(Q_OS_WIN) || defined(__CYGWIN__)
230 mLibraryDirectory.setNameFilters( QStringList(
"*.dll" ) );
231 #elif defined(ANDROID)
232 mLibraryDirectory.setNameFilters( QStringList(
"*provider_*.so" ) );
234 mLibraryDirectory.setNameFilters( QStringList( QStringLiteral(
"*.so" ) ) );
237 QgsDebugMsgLevel( QStringLiteral(
"Checking %1 for provider plugins" ).arg( mLibraryDirectory.path() ), 2 );
239 if ( mLibraryDirectory.count() == 0 )
241 QgsDebugMsg( QStringLiteral(
"No dynamic QGIS data provider plugins found in:\n%1\n" ).arg( mLibraryDirectory.path() ) );
245 const QString filePattern = getenv(
"QGIS_PROVIDER_FILE" );
246 QRegularExpression fileRegexp;
247 if ( !filePattern.isEmpty() )
249 fileRegexp.setPattern( filePattern );
252 typedef std::vector<QgsProviderMetadata *> *multiple_factory_function();
254 const auto constEntryInfoList = mLibraryDirectory.entryInfoList();
255 for (
const QFileInfo &fi : constEntryInfoList )
257 if ( !filePattern.isEmpty() )
259 if ( fi.fileName().indexOf( fileRegexp ) == -1 )
261 QgsDebugMsg(
"provider " + fi.fileName() +
" skipped because doesn't match pattern " + filePattern );
267 if ( fi.fileName().contains( QStringLiteral(
"authmethod" ), Qt::CaseSensitivity::CaseInsensitive ) )
273 QLibrary myLib( fi.filePath() );
276 QgsDebugMsg( QStringLiteral(
"Checking %1: ...invalid (lib not loadable): %2" ).arg( myLib.fileName(), myLib.errorString() ) );
280 bool libraryLoaded {
false };
281 QFunctionPointer func = myLib.resolve( QStringLiteral(
"providerMetadataFactory" ).toLatin1().data() );
282 factory_function *
function =
reinterpret_cast< factory_function *
>(
cast_to_fptr( func ) );
288 if ( findMetadata_( mProviders, meta->
key() ) )
290 QgsDebugMsg( QStringLiteral(
"Checking %1: ...invalid (key %2 already registered)" ).arg( myLib.fileName() ).arg( meta->
key() ) );
295 mProviders[meta->
key()] = meta;
296 libraryLoaded =
true;
301 QFunctionPointer multi_func = myLib.resolve( QStringLiteral(
"multipleProviderMetadataFactory" ).toLatin1().data() );
302 multiple_factory_function *multi_function =
reinterpret_cast< multiple_factory_function *
>(
cast_to_fptr( multi_func ) );
303 if ( multi_function )
305 std::vector<QgsProviderMetadata *> *metadatas = multi_function();
306 for (
const auto meta : *metadatas )
308 if ( findMetadata_( mProviders, meta->
key() ) )
310 QgsDebugMsg( QStringLiteral(
"Checking %1: ...invalid (key %2 already registered)" ).arg( myLib.fileName() ).arg( meta->
key() ) );
315 mProviders[meta->
key()] = meta;
316 libraryLoaded =
true;
322 if ( ! libraryLoaded )
324 QgsDebugMsgLevel( QStringLiteral(
"Checking %1: ...invalid (no providerMetadataFactory method)" ).arg( myLib.fileName() ), 2 );
329 QgsDebugMsg( QStringLiteral(
"Loaded %1 providers (%2) " ).arg( mProviders.size() ).arg(
providerList().join(
';' ) ) );
331 QStringList pointCloudWildcards;
332 QStringList pointCloudFilters;
335 for ( Providers::const_iterator it = mProviders.begin(); it != mProviders.end(); ++it )
337 const QString &key = it->first;
365 QgsDebugMsgLevel( QStringLiteral(
"Checking %1: ...loaded OK (%2 file mesh filters)" ).arg( key ).arg( mMeshFileFilters.split(
";;" ).count() ), 2 );
373 QgsDebugMsgLevel( QStringLiteral(
"Checking %1: ...loaded OK (%2 file dataset filters)" ).arg( key ).arg( mMeshDatasetFileFilters.split(
";;" ).count() ), 2 );
382 #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
383 const QStringList filters =
filePointCloudFilters.split( QStringLiteral(
";;" ), QString::SkipEmptyParts );
385 const QStringList filters =
filePointCloudFilters.split( QStringLiteral(
";;" ), Qt::SkipEmptyParts );
387 for (
const QString &filter : filters )
389 pointCloudFilters.append( filter );
398 if ( !pointCloudFilters.empty() )
400 pointCloudFilters.insert( 0, QObject::tr(
"All Supported Files" ) + QStringLiteral(
" (%1)" ).arg( pointCloudWildcards.join(
' ' ) ) );
401 pointCloudFilters.insert( 1, QObject::tr(
"All Files" ) + QStringLiteral(
" (*.*)" ) );
402 mPointCloudFileFilters = pointCloudFilters.join( QLatin1String(
";;" ) );
406 mDatabaseDrivers = QgsOgrProviderUtils::databaseDrivers();
409 mDirectoryDrivers = QgsOgrProviderUtils::directoryDrivers();
412 mProtocolDrivers = QgsOgrProviderUtils::protocolDrivers();
419 void QgsProviderRegistry::clean()
422 if ( QgsProject::sProject )
425 Providers::const_iterator it = mProviders.begin();
427 while ( it != mProviders.end() )
430 it->second->cleanupProvider();
437 bool QgsProviderRegistry::exists()
439 return static_cast< bool >( sInstance );
444 qDeleteAll( mUnusableUriHandlers );
447 if ( sInstance ==
this )
467 Providers::const_iterator it = mProviders.begin();
469 if ( mProviders.empty() )
470 return QObject::tr(
"No data provider plugins are available. No vector layers can be loaded" );
475 list += QLatin1String(
"<ol>" );
477 while ( it != mProviders.end() )
480 list += QLatin1String(
"<li>" );
482 list += it->second->description();
485 list += QLatin1String(
"<br></li>" );
493 list += QLatin1String(
"</ol>" );
500 mLibraryDirectory = path;
507 return mLibraryDirectory;
520 QgsDataProvider::ReadFlags flags )
537 const QList< QgsDataItemProvider * > itemProviders =
dataItemProviders( providerKey );
542 ret = ret | itemProvider->capabilities();
553 return QVariantMap();
570 bool overwrite, QMap<int, int> &oldToNewAttrIdxMap,
571 QString &errorMessage,
572 const QMap<QString, QVariant> *options )
576 return meta->
createEmptyLayer( uri, fields, wkbType, srs, overwrite, oldToNewAttrIdxMap, errorMessage, options );
579 errorMessage = QObject::tr(
"Unable to load %1 provider" ).arg( providerKey );
580 return Qgis::VectorExportResult::ErrorInvalidProvider;
587 const QStringList &createOptions )
602 return QList<QPair<QString, QString> >();
611 return QList<QgsDataItemProvider *>();
614 int QgsProviderRegistry::listStyles(
const QString &providerKey,
const QString &uri, QStringList &ids, QStringList &names, QStringList &descriptions, QString &errCause )
620 res = meta->
listStyles( uri, ids, names, descriptions, errCause );
624 errCause = QObject::tr(
"Unable to load %1 provider" ).arg( providerKey );
639 errCause = QObject::tr(
"Unable to load %1 provider" ).arg( providerKey );
646 const bool ret(
false );
653 errCause = QObject::tr(
"Unable to load %1 provider" ).arg( providerKey );
659 const QString &sldStyle,
const QString &styleName,
const QString &styleDescription,
660 const QString &uiFileContent,
bool useAsDefault, QString &errCause )
665 ret = meta->
saveStyle( uri, qmlStyle, sldStyle, styleName, styleDescription,
666 uiFileContent, useAsDefault, errCause );
669 errCause = QObject::tr(
"Unable to load %1 provider" ).arg( providerKey );
682 errCause = QObject::tr(
"Unable to load %1 provider" ).arg( providerKey );
689 errorMessage.clear();
702 return meta->
createDb( dbPath, errCause );
705 errCause = QStringLiteral(
"Resolving createDb(...) failed" );
722 Q_UNUSED( providerKey );
725 Q_UNUSED( widgetMode );
726 QgsDebugMsg(
"deprecated call - use QgsGui::sourceSelectProviderRegistry()->createDataSourceWidget() instead" );
731 QString
const &functionName )
734 const QString lib =
library( providerKey );
739 QLibrary myLib( lib );
741 QgsDebugMsg(
"Library name is " + myLib.fileName() );
745 return myLib.resolve( functionName.toLatin1().data() );
749 QgsDebugMsg(
"Cannot load library: " + myLib.errorString() );
757 const QString lib =
library( providerKey );
762 std::unique_ptr< QLibrary > myLib(
new QLibrary( lib ) );
764 QgsDebugMsg(
"Library name is " + myLib->fileName() );
767 return myLib.release();
769 QgsDebugMsg(
"Cannot load library: " + myLib->errorString() );
776 QgsDebugMsg(
"deprecated - use QgsGui::providerGuiRegistry() instead." );
795 QgsDebugMsgLevel( QStringLiteral(
"Trying to register a null metadata provider!" ), 2 );
802 return mVectorFileFilters;
807 return mRasterFileFilters;
812 return mMeshFileFilters;
817 return mMeshDatasetFileFilters;
822 return mPointCloudFileFilters;
827 return mDatabaseDrivers;
832 return mDirectoryDrivers;
837 return mProtocolDrivers;
843 for ( Providers::const_iterator it = mProviders.begin(); it != mProviders.end(); ++it )
845 lst.append( it->first );
852 return findMetadata_( mProviders, providerKey );
857 QList< QgsProviderRegistry::ProviderCandidateDetails > res;
859 for (
auto it = mProviders.begin(); it != mProviders.end(); ++it )
864 const int thisProviderPriority = it->second->priorityForUri( uri );
865 if ( thisProviderPriority == 0 )
868 if ( thisProviderPriority > maxPriority )
871 maxPriority = thisProviderPriority;
873 if ( thisProviderPriority == maxPriority )
883 mUnusableUriHandlers << handler;
891 if ( handler->matchesUri( uri ) )
893 details = handler->details( uri );
903 if ( providers.empty() )
908 if ( provider.metadata()->key() == providerKey )
916 for (
auto it = mProviders.begin(); it != mProviders.end(); ++it )
918 if ( it->second->uriIsBlocklisted( uri ) )
930 QList<QgsProviderSublayerDetails> res;
931 for (
auto it = mProviders.begin(); it != mProviders.end(); ++it )
937 res.append( it->second->querySublayers( uri, flags, feedback ) );
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.
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.
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.
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.
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.