41 typedef void fileMeshFilters_t( QString &fileMeshFiltersString, QString &fileMeshDatasetFiltersString );
59 QMutexLocker locker( &sMutex );
70 QgsProviderRegistry::QgsProviderRegistry(
const QString &pluginPath )
78 char **argv = qApp->argv();
79 QString appDir = argv[0];
80 int bin = appDir.findRev(
"/bin", -1,
false );
81 QString baseDir = appDir.left( bin );
82 QString mLibraryDirectory = baseDir +
"/lib";
84 mLibraryDirectory = pluginPath;
89 void QgsProviderRegistry::init()
92 mProviders[ QgsMemoryProvider::providerKey() ] =
new QgsProviderMetadata( QgsMemoryProvider::providerKey(), QgsMemoryProvider::providerDescription(), &QgsMemoryProvider::createProvider );
93 mProviders[ QgsMeshMemoryDataProvider::providerKey() ] =
new QgsProviderMetadata( QgsMeshMemoryDataProvider::providerKey(), QgsMeshMemoryDataProvider::providerDescription(), &QgsMeshMemoryDataProvider::createProvider );
95 mLibraryDirectory.setSorting( QDir::Name | QDir::IgnoreCase );
96 mLibraryDirectory.setFilter( QDir::Files | QDir::NoSymLinks );
98 #if defined(Q_OS_WIN) || defined(__CYGWIN__) 99 mLibraryDirectory.setNameFilters( QStringList(
"*.dll" ) );
100 #elif defined(ANDROID) 101 mLibraryDirectory.setNameFilters( QStringList(
"*provider.so" ) );
103 mLibraryDirectory.setNameFilters( QStringList( QStringLiteral(
"*.so" ) ) );
106 QgsDebugMsg( QStringLiteral(
"Checking %1 for provider plugins" ).arg( mLibraryDirectory.path() ) );
108 if ( mLibraryDirectory.count() == 0 )
110 QString msg = QObject::tr(
"No QGIS data provider plugins found in:\n%1\n" ).arg( mLibraryDirectory.path() );
111 msg += QObject::tr(
"No vector layers can be loaded. Check your QGIS installation" );
114 output->
setTitle( QObject::tr(
"No Data Providers" ) );
121 QString filePattern = getenv(
"QGIS_PROVIDER_FILE" );
123 if ( !filePattern.isEmpty() )
125 fileRegexp.setPattern( filePattern );
128 const auto constEntryInfoList = mLibraryDirectory.entryInfoList();
129 for (
const QFileInfo &fi : constEntryInfoList )
131 if ( !fileRegexp.isEmpty() )
133 if ( fileRegexp.indexIn( fi.fileName() ) == -1 )
135 QgsDebugMsg(
"provider " + fi.fileName() +
" skipped because doesn't match pattern " + filePattern );
140 QLibrary myLib( fi.filePath() );
143 QgsDebugMsg( QStringLiteral(
"Checking %1: ...invalid (lib not loadable): %2" ).arg( myLib.fileName(), myLib.errorString() ) );
152 QgsDebugMsg( QStringLiteral(
"Checking %1: ...invalid (has type method)" ).arg( myLib.fileName() ) );
160 QgsDebugMsg( QStringLiteral(
"Checking %1: ...invalid (no isProvider method)" ).arg( myLib.fileName() ) );
167 QgsDebugMsg( QStringLiteral(
"Checking %1: ...invalid (not a provider)" ).arg( myLib.fileName() ) );
175 QgsDebugMsg( QStringLiteral(
"Checking %1: ...invalid (no description method)" ).arg( myLib.fileName() ) );
182 QgsDebugMsg( QStringLiteral(
"Checking %1: ...invalid (no providerKey method)" ).arg( myLib.fileName() ) );
191 if ( pDatabaseDrivers )
193 mDatabaseDrivers = pDatabaseDrivers();
198 if ( pDirectoryDrivers )
200 mDirectoryDrivers = pDirectoryDrivers();
205 if ( pProtocolDrivers )
207 mProtocolDrivers = pProtocolDrivers();
212 if ( pFileVectorFilters )
216 if ( !fileVectorFilters.isEmpty() )
217 mVectorFileFilters += fileVectorFilters;
219 QgsDebugMsg( QStringLiteral(
"Checking %1: ...loaded OK (%2 file filters)" ).arg( myLib.fileName() ).arg( fileVectorFilters.split(
";;" ).count() ) );
229 pBuild( fileRasterFilters );
231 QgsDebugMsg(
"raster filters: " + fileRasterFilters );
232 if ( !fileRasterFilters.isEmpty() )
233 mRasterFileFilters += fileRasterFilters;
235 QgsDebugMsg( QStringLiteral(
"Checking %1: ...loaded OK (%2 file filters)" ).arg( myLib.fileName() ).arg( fileRasterFilters.split(
";;" ).count() ) );
240 if ( pFileMeshFilters )
245 pFileMeshFilters( fileMeshFilters, fileMeshDatasetFilters );
247 if ( !fileMeshFilters.isEmpty() )
248 mMeshFileFilters += fileMeshFilters;
249 if ( !fileMeshDatasetFilters.isEmpty() )
250 mMeshDatasetFileFilters += fileMeshDatasetFilters;
252 QgsDebugMsg( QStringLiteral(
"Checking %1: ...loaded OK (%2 file mesh filters, %3 file dataset filters)" ).arg( myLib.fileName() ).arg( mMeshFileFilters.split(
";;" ).count() ).arg( mMeshDatasetFileFilters.split(
";;" ).count() ) );
266 void QgsProviderRegistry::clean()
269 if ( QgsProject::sProject )
272 Providers::const_iterator it = mProviders.begin();
274 while ( it != mProviders.end() )
277 QString lib = it->second->library();
278 if ( !lib.isEmpty() )
280 QLibrary myLib( lib );
281 if ( myLib.isLoaded() )
294 bool QgsProviderRegistry::exists()
296 return static_cast< bool >( sInstance );
302 if ( sInstance ==
this )
317 QString
const &providerKey )
319 QgsProviderRegistry::Providers::const_iterator i =
320 metaData.find( providerKey );
322 if ( i != metaData.end() )
347 Providers::const_iterator it = mProviders.begin();
349 if ( mProviders.empty() )
350 return QObject::tr(
"No data provider plugins are available. No vector layers can be loaded" );
355 list += QLatin1String(
"<ol>" );
357 while ( it != mProviders.end() )
360 list += QLatin1String(
"<li>" );
362 list += it->second->description();
365 list += QLatin1String(
"<br></li>" );
373 list += QLatin1String(
"</ol>" );
380 mLibraryDirectory = path;
387 return mLibraryDirectory;
421 QString lib =
library( providerKey );
423 #ifdef TESTPROVIDERLIB 424 const char *cLib = lib.toUtf8();
428 void *handle = dlopen( cOgrLib, RTLD_LAZY | RTLD_GLOBAL );
435 QgsDebugMsg( QStringLiteral(
"dlopen succeeded" ) );
441 QLibrary myLib( lib );
443 QgsDebugMsg(
"Library name is " + myLib.fileName() );
453 QgsDebugMsg( QStringLiteral(
"Failed to load %1: no classFactory method" ).arg( lib ) );
465 QgsDebugMsg( QStringLiteral(
"Instantiated the data provider plugin: %1" ).arg( dataProvider->
name() ) );
474 return QVariantMap();
480 return QVariantMap();
494 if ( !dataCapabilities )
499 return dataCapabilities();
511 if ( !selectFactory )
514 return selectFactory( parent, fl, widgetMode );
518 QString
const &functionName )
520 QString lib =
library( providerKey );
524 QLibrary myLib(
library( providerKey ) );
526 QgsDebugMsg(
"Library name is " + myLib.fileName() );
530 return myLib.resolve( functionName.toLatin1().data() );
534 QgsDebugMsg(
"Cannot load library: " + myLib.errorString() );
541 QString lib =
library( providerKey );
545 std::unique_ptr< QLibrary > myLib(
new QLibrary( lib ) );
547 QgsDebugMsg(
"Library name is " + myLib->fileName() );
550 return myLib.release();
552 QgsDebugMsg(
"Cannot load library: " + myLib->errorString() );
559 typedef void registerGui_function( QWidget * parent );
562 for (
const QString &provider : constProviderList )
564 registerGui_function *registerGui =
reinterpret_cast< registerGui_function *
>(
cast_to_fptr(
function( provider,
"registerGui" ) ) );
569 registerGui( parent );
575 if ( providerMetadata )
577 if ( mProviders.find( providerMetadata->
key() ) == mProviders.end() )
584 QgsDebugMsgLevel( QStringLiteral(
"Cannot register provider metadata: a provider with the same key (%1) was already registered!" ).arg( providerMetadata->
key() ), 2 );
589 QgsDebugMsgLevel( QStringLiteral(
"Trying to register a null metadata provider!" ), 2 );
596 return mVectorFileFilters;
601 return mRasterFileFilters;
606 return mMeshFileFilters;
611 return mMeshDatasetFileFilters;
616 return mDatabaseDrivers;
621 return mDirectoryDrivers;
626 return mProtocolDrivers;
632 for ( Providers::const_iterator it = mProviders.begin(); it != mProviders.end(); ++it )
634 lst.append( it->first );
641 return findMetadata_( mProviders, providerKey );
bool registerProvider(QgsProviderMetadata *providerMetadata)
register a new vector data provider from its providerMetadata
WidgetMode
Different ways a source select dialog can be used (embedded is for the data source manager dialog) ...
QString databaseDrivers_t()
void cleanupProviderFunction_t()
virtual void setTitle(const QString &title)=0
Sets title for the messages.
QVariantMap decodeUri_t(const QString &uri)
static void warning(const QString &msg)
Goes to qWarning.
virtual QString protocolDrivers() const
Returns a string containing the available protocol drivers.
QString library(const QString &providerKey) const
Returns path for the library of the provider.
void registerGuis(QWidget *widget)
void fileMeshFilters_t(QString &fileMeshFiltersString, QString &fileMeshDatasetFiltersString)
virtual QString databaseDrivers() const
Returns a string containing the available database drivers.
QString directoryDrivers_t()
static QgsMessageOutput * createMessageOutput()
function that returns new class derived from QgsMessageOutput (don't forget to delete it then if show...
QgsDataProvider * classFactoryFunction_t(const QString *, const QgsDataProvider::ProviderOptions &options)
QVariantMap decodeUri(const QString &providerKey, const QString &uri)
Breaks a provider data source URI into its component paths (e.g.
Abstract base class for spatial data provider implementations.
virtual ~QgsProviderRegistry()
virtual QString name() const =0
Returns a provider name.
virtual QString fileVectorFilters() const
Returns vector file filter string.
QgsDataProvider * createProvider(const QString &providerKey, const QString &dataSource, const QgsDataProvider::ProviderOptions &options=QgsDataProvider::ProviderOptions())
Creates a new instance of a provider.
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.
void initProviderFunction_t()
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance.
#define QgsDebugMsgLevel(str, level)
QLibrary * createProviderLibrary(const QString &providerKey) const
Returns a new QLibrary for the specified providerKey.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
virtual void setMessage(const QString &message, MessageType msgType)=0
Sets message, it won't be displayed until.
void setLibraryDirectory(const QDir &path)
Sets library directory where to search for plugins.
const QgsProviderMetadata * providerMetadata(const QString &providerKey) const
Returns metadata of the provider or nullptr if not found.
QString pluginList(bool asHtml=false) const
Returns list of provider plugins found.
void removeAllMapLayers()
Removes all registered layers.
virtual QString fileMeshDatasetFilters() const
Returns mesh's dataset file filter string.
QString fileVectorFilters_t()
A registry / canonical manager of data providers.
int providerCapabilities(const QString &providerKey) const
Returns the provider capabilities.
virtual void showMessage(bool blocking=true)=0
display the message to the user and deletes itself
Setting options for creating vector data providers.
virtual QString fileMeshFilters() const
Returns mesh file filter string.
virtual QString directoryDrivers() const
Returns a string containing the available directory drivers.
std::map< QString, QgsProviderMetadata * > Providers
Type for data provider metadata associative container.
static QgsProject * instance()
Returns the QgsProject singleton instance.
QWidget * selectFactoryFunction_t(QWidget *parent, Qt::WindowFlags fl, QgsProviderRegistry::WidgetMode widgetMode)
QFunctionPointer function(const QString &providerKey, const QString &functionName)
Gets pointer to provider function.
virtual QString fileRasterFilters() const
Returns raster file filter string.
void buildsupportedrasterfilefilter_t(QString &fileFiltersString)
QString protocolDrivers_t()
QStringList providerList() const
Returns list of available providers by their keys.
Interface for showing messages from QGIS in GUI independent way.
QDir libraryDirectory() const
Returns the library directory where plugins are found.