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"
43 #include "providers/copc/qgscopcprovider.h"
49 #ifdef HAVE_STATIC_PROVIDERS
50 #include "qgswmsprovider.h"
51 #include "qgswcsprovider.h"
52 #include "qgsdelimitedtextprovider.h"
53 #include "qgsafsprovider.h"
54 #include "qgsamsprovider.h"
55 #ifdef HAVE_SPATIALITE
56 #include "qgsspatialiteprovider.h"
57 #include "qgswfsprovider.h"
58 #include "qgsoapifprovider.h"
59 #include "qgsvirtuallayerprovider.h"
61 #ifdef HAVE_POSTGRESQL
62 #include "qgspostgresprovider.h"
69 #include <QRegularExpression>
78 const QMutexLocker locker( &sMutex );
98 const QString &providerKey )
101 const QgsProviderRegistry::Providers::const_iterator i =
102 metaData.find( providerKey );
104 if ( i != metaData.end() )
110 for (
auto it = metaData.begin(); it != metaData.end(); ++it )
112 if ( providerKey.compare( it->first, Qt::CaseInsensitive ) == 0 )
119 QgsProviderRegistry::QgsProviderRegistry(
const QString &pluginPath )
127 char **argv = qApp->argv();
128 QString appDir = argv[0];
129 int bin = appDir.findRev(
"/bin", -1,
false );
130 QString baseDir = appDir.left( bin );
131 QString mLibraryDirectory = baseDir +
"/lib";
135 mLibraryDirectory.setPath( pluginPath );
143 bool matchesUri(
const QString &uri )
const override
145 const QFileInfo fi( uri );
146 if ( fi.suffix().compare( QLatin1String(
"las" ), Qt::CaseInsensitive ) == 0 || fi.suffix().compare( QLatin1String(
"laz" ), Qt::CaseInsensitive ) == 0 )
155 QObject::tr(
"LAS and LAZ files cannot be opened by this QGIS install." ),
159 res.
detailedWarning = QObject::tr(
"The installer used to install this version of QGIS does "
160 "not include the PDAL library required for opening LAS and LAZ point clouds. Please "
161 "obtain one of the alternative installers from https://qgis.org which has point "
162 "cloud support enabled." );
164 res.
detailedWarning = QObject::tr(
"This QGIS build does not include the PDAL library dependency required for opening LAS or LAZ point clouds." );
171 void QgsProviderRegistry::init()
176 mProviders[ QgsMemoryProvider::providerKey() ] =
new QgsMemoryProviderMetadata();
180 mProviders[ QgsMeshMemoryDataProvider::providerKey() ] =
new QgsMeshMemoryProviderMetadata();
184 mProviders[ QgsGdalProvider::providerKey() ] =
new QgsGdalProviderMetadata();
188 mProviders[ QgsOgrProvider::providerKey() ] =
new QgsOgrProviderMetadata();
193 mProviders[ vt->
key() ] = vt;
199 mProviders[ pc->
key() ] = pc;
206 mProviders[ pc->
key() ] = pc;
211 #ifdef HAVE_STATIC_PROVIDERS
212 mProviders[ QgsWmsProvider::providerKey() ] =
new QgsWmsProviderMetadata();
213 mProviders[ QgsWcsProvider::providerKey() ] =
new QgsWcsProviderMetadata();
214 mProviders[ QgsDelimitedTextProvider::providerKey() ] =
new QgsDelimitedTextProviderMetadata();
215 mProviders[ QgsAfsProvider::providerKey() ] =
new QgsAfsProviderMetadata();
216 mProviders[ QgsAmsProvider::providerKey() ] =
new QgsAmsProviderMetadata();
217 #ifdef HAVE_SPATIALITE
218 mProviders[ QgsSpatiaLiteProvider::providerKey() ] =
new QgsSpatiaLiteProviderMetadata();
219 mProviders[ QgsWFSProvider::providerKey() ] =
new QgsWfsProviderMetadata();
220 mProviders[ QgsOapifProvider::providerKey() ] =
new QgsOapifProviderMetadata();
221 mProviders[ QgsVirtualLayerProvider::providerKey() ] =
new QgsVirtualLayerProviderMetadata();
223 #ifdef HAVE_POSTGRESQL
224 mProviders[ QgsPostgresProvider::providerKey() ] =
new QgsPostgresProviderMetadata();
229 #ifdef HAVE_STATIC_PROVIDERS
230 QgsDebugMsg( QStringLiteral(
"Forced only static providers" ) );
234 mLibraryDirectory.setSorting( QDir::Name | QDir::IgnoreCase );
235 mLibraryDirectory.setFilter( QDir::Files | QDir::NoSymLinks );
237 #if defined(Q_OS_WIN) || defined(__CYGWIN__)
238 mLibraryDirectory.setNameFilters( QStringList(
"*.dll" ) );
239 #elif defined(ANDROID)
240 mLibraryDirectory.setNameFilters( QStringList(
"*provider_*.so" ) );
242 mLibraryDirectory.setNameFilters( QStringList( QStringLiteral(
"*.so" ) ) );
245 QgsDebugMsgLevel( QStringLiteral(
"Checking %1 for provider plugins" ).arg( mLibraryDirectory.path() ), 2 );
247 if ( mLibraryDirectory.count() == 0 )
249 QgsDebugMsg( QStringLiteral(
"No dynamic QGIS data provider plugins found in:\n%1\n" ).arg( mLibraryDirectory.path() ) );
253 const QString filePattern = getenv(
"QGIS_PROVIDER_FILE" );
254 QRegularExpression fileRegexp;
255 if ( !filePattern.isEmpty() )
257 fileRegexp.setPattern( filePattern );
260 typedef std::vector<QgsProviderMetadata *> *multiple_factory_function();
262 const auto constEntryInfoList = mLibraryDirectory.entryInfoList();
263 for (
const QFileInfo &fi : constEntryInfoList )
265 if ( !filePattern.isEmpty() )
267 if ( fi.fileName().indexOf( fileRegexp ) == -1 )
269 QgsDebugMsg(
"provider " + fi.fileName() +
" skipped because doesn't match pattern " + filePattern );
275 if ( fi.fileName().contains( QStringLiteral(
"authmethod" ), Qt::CaseSensitivity::CaseInsensitive ) )
281 QLibrary myLib( fi.filePath() );
284 QgsDebugMsg( QStringLiteral(
"Checking %1: ...invalid (lib not loadable): %2" ).arg( myLib.fileName(), myLib.errorString() ) );
288 bool libraryLoaded {
false };
289 QFunctionPointer func = myLib.resolve( QStringLiteral(
"providerMetadataFactory" ).toLatin1().data() );
290 factory_function *
function =
reinterpret_cast< factory_function *
>(
cast_to_fptr( func ) );
296 if ( findMetadata_( mProviders, meta->
key() ) )
298 QgsDebugMsg( QStringLiteral(
"Checking %1: ...invalid (key %2 already registered)" ).arg( myLib.fileName() ).arg( meta->
key() ) );
303 mProviders[meta->
key()] = meta;
304 libraryLoaded =
true;
309 QFunctionPointer multi_func = myLib.resolve( QStringLiteral(
"multipleProviderMetadataFactory" ).toLatin1().data() );
310 multiple_factory_function *multi_function =
reinterpret_cast< multiple_factory_function *
>(
cast_to_fptr( multi_func ) );
311 if ( multi_function )
313 std::vector<QgsProviderMetadata *> *metadatas = multi_function();
314 for (
const auto meta : *metadatas )
316 if ( findMetadata_( mProviders, meta->
key() ) )
318 QgsDebugMsg( QStringLiteral(
"Checking %1: ...invalid (key %2 already registered)" ).arg( myLib.fileName() ).arg( meta->
key() ) );
323 mProviders[meta->
key()] = meta;
324 libraryLoaded =
true;
330 if ( ! libraryLoaded )
332 QgsDebugMsgLevel( QStringLiteral(
"Checking %1: ...invalid (no providerMetadataFactory method)" ).arg( myLib.fileName() ), 2 );
337 QgsDebugMsg( QStringLiteral(
"Loaded %1 providers (%2) " ).arg( mProviders.size() ).arg(
providerList().join(
';' ) ) );
339 QStringList pointCloudWildcards;
340 QStringList pointCloudFilters;
343 for ( Providers::const_iterator it = mProviders.begin(); it != mProviders.end(); ++it )
345 const QString &key = it->first;
373 QgsDebugMsgLevel( QStringLiteral(
"Checking %1: ...loaded OK (%2 file mesh filters)" ).arg( key ).arg( mMeshFileFilters.split(
";;" ).count() ), 2 );
381 QgsDebugMsgLevel( QStringLiteral(
"Checking %1: ...loaded OK (%2 file dataset filters)" ).arg( key ).arg( mMeshDatasetFileFilters.split(
";;" ).count() ), 2 );
390 #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
391 const QStringList filters =
filePointCloudFilters.split( QStringLiteral(
";;" ), QString::SkipEmptyParts );
393 const QStringList filters =
filePointCloudFilters.split( QStringLiteral(
";;" ), Qt::SkipEmptyParts );
395 for (
const QString &filter : filters )
397 pointCloudFilters.append( filter );
406 if ( !pointCloudFilters.empty() )
408 pointCloudFilters.insert( 0, QObject::tr(
"All Supported Files" ) + QStringLiteral(
" (%1)" ).arg( pointCloudWildcards.join(
' ' ) ) );
409 pointCloudFilters.insert( 1, QObject::tr(
"All Files" ) + QStringLiteral(
" (*.*)" ) );
410 mPointCloudFileFilters = pointCloudFilters.join( QLatin1String(
";;" ) );
414 mDatabaseDrivers = QgsOgrProviderUtils::databaseDrivers();
417 mDirectoryDrivers = QgsOgrProviderUtils::directoryDrivers();
420 mProtocolDrivers = QgsOgrProviderUtils::protocolDrivers();
427 void QgsProviderRegistry::clean()
430 if ( QgsProject::sProject )
433 Providers::const_iterator it = mProviders.begin();
435 while ( it != mProviders.end() )
438 it->second->cleanupProvider();
445 bool QgsProviderRegistry::exists()
447 return static_cast< bool >( sInstance );
452 qDeleteAll( mUnusableUriHandlers );
455 if ( sInstance ==
this )
475 Providers::const_iterator it = mProviders.begin();
477 if ( mProviders.empty() )
478 return QObject::tr(
"No data provider plugins are available. No vector layers can be loaded" );
483 list += QLatin1String(
"<ol>" );
485 while ( it != mProviders.end() )
488 list += QLatin1String(
"<li>" );
490 list += it->second->description();
493 list += QLatin1String(
"<br></li>" );
501 list += QLatin1String(
"</ol>" );
508 mLibraryDirectory = path;
515 return mLibraryDirectory;
528 QgsDataProvider::ReadFlags flags )
545 const QList< QgsDataItemProvider * > itemProviders =
dataItemProviders( providerKey );
550 ret = ret | itemProvider->capabilities();
561 return QVariantMap();
578 bool overwrite, QMap<int, int> &oldToNewAttrIdxMap,
579 QString &errorMessage,
580 const QMap<QString, QVariant> *options )
584 return meta->
createEmptyLayer( uri, fields, wkbType, srs, overwrite, oldToNewAttrIdxMap, errorMessage, options );
587 errorMessage = QObject::tr(
"Unable to load %1 provider" ).arg( providerKey );
588 return Qgis::VectorExportResult::ErrorInvalidProvider;
595 const QStringList &createOptions )
610 return QList<QPair<QString, QString> >();
619 return QList<QgsDataItemProvider *>();
622 int QgsProviderRegistry::listStyles(
const QString &providerKey,
const QString &uri, QStringList &ids, QStringList &names, QStringList &descriptions, QString &errCause )
628 res = meta->
listStyles( uri, ids, names, descriptions, errCause );
632 errCause = QObject::tr(
"Unable to load %1 provider" ).arg( providerKey );
643 return meta->
styleExists( uri, styleId, errorCause );
647 errorCause = QObject::tr(
"Unable to load %1 provider" ).arg( providerKey );
662 errCause = QObject::tr(
"Unable to load %1 provider" ).arg( providerKey );
669 const bool ret(
false );
676 errCause = QObject::tr(
"Unable to load %1 provider" ).arg( providerKey );
682 const QString &sldStyle,
const QString &styleName,
const QString &styleDescription,
683 const QString &uiFileContent,
bool useAsDefault, QString &errCause )
688 ret = meta->
saveStyle( uri, qmlStyle, sldStyle, styleName, styleDescription,
689 uiFileContent, useAsDefault, errCause );
692 errCause = QObject::tr(
"Unable to load %1 provider" ).arg( providerKey );
705 errCause = QObject::tr(
"Unable to load %1 provider" ).arg( providerKey );
712 errorMessage.clear();
725 return meta->
createDb( dbPath, errCause );
728 errCause = QStringLiteral(
"Resolving createDb(...) failed" );
745 Q_UNUSED( providerKey );
748 Q_UNUSED( widgetMode );
749 QgsDebugMsg(
"deprecated call - use QgsGui::sourceSelectProviderRegistry()->createDataSourceWidget() instead" );
754 QString
const &functionName )
const
757 const QString lib =
library( providerKey );
762 QLibrary myLib( lib );
764 QgsDebugMsg(
"Library name is " + myLib.fileName() );
768 return myLib.resolve( functionName.toLatin1().data() );
772 QgsDebugMsg(
"Cannot load library: " + myLib.errorString() );
780 const QString lib =
library( providerKey );
785 std::unique_ptr< QLibrary > myLib(
new QLibrary( lib ) );
787 QgsDebugMsg(
"Library name is " + myLib->fileName() );
790 return myLib.release();
792 QgsDebugMsg(
"Cannot load library: " + myLib->errorString() );
799 QgsDebugMsg(
"deprecated - use QgsGui::providerGuiRegistry() instead." );
818 QgsDebugMsgLevel( QStringLiteral(
"Trying to register a null metadata provider!" ), 2 );
825 return mVectorFileFilters;
830 return mRasterFileFilters;
835 return mMeshFileFilters;
840 return mMeshDatasetFileFilters;
845 return mPointCloudFileFilters;
850 return mDatabaseDrivers;
855 return mDirectoryDrivers;
860 return mProtocolDrivers;
866 for ( Providers::const_iterator it = mProviders.begin(); it != mProviders.end(); ++it )
868 lst.append( it->first );
875 return findMetadata_( mProviders, providerKey );
881 for ( Providers::const_iterator it = mProviders.begin(); it != mProviders.end(); ++it )
883 if ( it->second->supportedLayerTypes().contains( type ) )
884 lst.insert( it->first );
891 QList< QgsProviderRegistry::ProviderCandidateDetails > res;
893 for (
auto it = mProviders.begin(); it != mProviders.end(); ++it )
898 const int thisProviderPriority = it->second->priorityForUri( uri );
899 if ( thisProviderPriority == 0 )
902 if ( thisProviderPriority > maxPriority )
905 maxPriority = thisProviderPriority;
907 if ( thisProviderPriority == maxPriority )
917 mUnusableUriHandlers << handler;
925 if ( handler->matchesUri( uri ) )
927 details = handler->details( uri );
937 if ( providers.empty() )
942 if ( provider.metadata()->key() == providerKey )
950 for (
auto it = mProviders.begin(); it != mProviders.end(); ++it )
952 if ( it->second->uriIsBlocklisted( uri ) )
964 QList<QgsProviderSublayerDetails> res;
965 for (
auto it = mProviders.begin(); it != mProviders.end(); ++it )
971 res.append( it->second->querySublayers( uri, flags, feedback ) );