QGIS API Documentation  3.4.15-Madeira (e83d02e274)
qgsproviderregistry.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsproviderregistry.cpp - Singleton class for
3  registering data providers.
4  -------------------
5  begin : Sat Jan 10 2004
6  copyright : (C) 2004 by Gary E.Sherman
7  email : sherman at mrcc.com
8  ***************************************************************************/
9 
10 /***************************************************************************
11  * *
12  * This program is free software; you can redistribute it and/or modify *
13  * it under the terms of the GNU General Public License as published by *
14  * the Free Software Foundation; either version 2 of the License, or *
15  * (at your option) any later version. *
16  * *
17  ***************************************************************************/
18 
19 #include "qgsproviderregistry.h"
20 
21 #include <QString>
22 #include <QDir>
23 #include <QLibrary>
24 
25 #include "qgis.h"
26 #include "qgsdataprovider.h"
27 #include "qgslogger.h"
28 #include "qgsmessageoutput.h"
29 #include "qgsmessagelog.h"
30 #include "qgsprovidermetadata.h"
31 #include "qgsvectorlayer.h"
32 #include "qgsproject.h"
35 
36 // typedefs for provider plugin functions of interest
37 typedef QString providerkey_t();
38 typedef QString description_t();
39 typedef bool isprovider_t();
40 typedef QString fileVectorFilters_t();
41 typedef void buildsupportedrasterfilefilter_t( QString &fileFiltersString );
42 typedef QString databaseDrivers_t();
43 typedef QString directoryDrivers_t();
44 typedef QString protocolDrivers_t();
45 typedef void initProviderFunction_t();
46 typedef QVariantMap decodeUri_t( const QString &uri );
47 
48 //typedef int dataCapabilities_t();
49 //typedef QgsDataItem * dataItem_t(QString);
50 
51 static QgsProviderRegistry *sInstance = nullptr;
52 
54 {
55  if ( !sInstance )
56  {
57  static QMutex sMutex;
58  QMutexLocker locker( &sMutex );
59  if ( !sInstance )
60  {
61  sInstance = new QgsProviderRegistry( pluginPath );
62  }
63  }
64  return sInstance;
65 } // QgsProviderRegistry::instance
66 
67 
68 
69 QgsProviderRegistry::QgsProviderRegistry( const QString &pluginPath )
70 {
71  // At startup, examine the libs in the qgis/lib dir and store those that
72  // are a provider shared lib
73  // check all libs in the current plugin directory and get name and descriptions
74  //TODO figure out how to register and identify data source plugin for a specific
75  //TODO layer type
76 #if 0
77  char **argv = qApp->argv();
78  QString appDir = argv[0];
79  int bin = appDir.findRev( "/bin", -1, false );
80  QString baseDir = appDir.left( bin );
81  QString mLibraryDirectory = baseDir + "/lib";
82 #endif
83  mLibraryDirectory = pluginPath;
84  init();
85 }
86 
87 
88 void QgsProviderRegistry::init()
89 {
90  // add standard providers
91  mProviders[ QgsMemoryProvider::providerKey() ] = new QgsProviderMetadata( QgsMemoryProvider::providerKey(), QgsMemoryProvider::providerDescription(), &QgsMemoryProvider::createProvider );
92  mProviders[ QgsMeshMemoryDataProvider::providerKey() ] = new QgsProviderMetadata( QgsMeshMemoryDataProvider::providerKey(), QgsMeshMemoryDataProvider::providerDescription(), &QgsMeshMemoryDataProvider::createProvider );
93 
94  mLibraryDirectory.setSorting( QDir::Name | QDir::IgnoreCase );
95  mLibraryDirectory.setFilter( QDir::Files | QDir::NoSymLinks );
96 
97 #if defined(Q_OS_WIN) || defined(__CYGWIN__)
98  mLibraryDirectory.setNameFilters( QStringList( "*.dll" ) );
99 #elif defined(ANDROID)
100  mLibraryDirectory.setNameFilters( QStringList( "*provider.so" ) );
101 #else
102  mLibraryDirectory.setNameFilters( QStringList( QStringLiteral( "*.so" ) ) );
103 #endif
104 
105  QgsDebugMsg( QStringLiteral( "Checking %1 for provider plugins" ).arg( mLibraryDirectory.path() ) );
106 
107  if ( mLibraryDirectory.count() == 0 )
108  {
109  QString msg = QObject::tr( "No QGIS data provider plugins found in:\n%1\n" ).arg( mLibraryDirectory.path() );
110  msg += QObject::tr( "No vector layers can be loaded. Check your QGIS installation" );
111 
113  output->setTitle( QObject::tr( "No Data Providers" ) );
115  output->showMessage();
116  return;
117  }
118 
119  // provider file regex pattern, only files matching the pattern are loaded if the variable is defined
120  QString filePattern = getenv( "QGIS_PROVIDER_FILE" );
121  QRegExp fileRegexp;
122  if ( !filePattern.isEmpty() )
123  {
124  fileRegexp.setPattern( filePattern );
125  }
126 
127  Q_FOREACH ( const QFileInfo &fi, mLibraryDirectory.entryInfoList() )
128  {
129  if ( !fileRegexp.isEmpty() )
130  {
131  if ( fileRegexp.indexIn( fi.fileName() ) == -1 )
132  {
133  QgsDebugMsg( "provider " + fi.fileName() + " skipped because doesn't match pattern " + filePattern );
134  continue;
135  }
136  }
137 
138  QLibrary myLib( fi.filePath() );
139  if ( !myLib.load() )
140  {
141  QgsDebugMsg( QStringLiteral( "Checking %1: ...invalid (lib not loadable): %2" ).arg( myLib.fileName(), myLib.errorString() ) );
142  continue;
143  }
144 
145  //MH: Added a further test to detect non-provider plugins linked to provider plugins.
146  //Only pure provider plugins have 'type' not defined
147  isprovider_t *hasType = reinterpret_cast< isprovider_t * >( cast_to_fptr( myLib.resolve( "type" ) ) );
148  if ( hasType )
149  {
150  QgsDebugMsg( QStringLiteral( "Checking %1: ...invalid (has type method)" ).arg( myLib.fileName() ) );
151  continue;
152  }
153 
154  // get the description and the key for the provider plugin
155  isprovider_t *isProvider = reinterpret_cast< isprovider_t * >( cast_to_fptr( myLib.resolve( "isProvider" ) ) );
156  if ( !isProvider )
157  {
158  QgsDebugMsg( QStringLiteral( "Checking %1: ...invalid (no isProvider method)" ).arg( myLib.fileName() ) );
159  continue;
160  }
161 
162  // check to see if this is a provider plugin
163  if ( !isProvider() )
164  {
165  QgsDebugMsg( QStringLiteral( "Checking %1: ...invalid (not a provider)" ).arg( myLib.fileName() ) );
166  continue;
167  }
168 
169  // looks like a provider. get the key and description
170  description_t *pDesc = reinterpret_cast< description_t * >( cast_to_fptr( myLib.resolve( "description" ) ) );
171  if ( !pDesc )
172  {
173  QgsDebugMsg( QStringLiteral( "Checking %1: ...invalid (no description method)" ).arg( myLib.fileName() ) );
174  continue;
175  }
176 
177  providerkey_t *pKey = reinterpret_cast< providerkey_t * >( cast_to_fptr( myLib.resolve( "providerKey" ) ) );
178  if ( !pKey )
179  {
180  QgsDebugMsg( QStringLiteral( "Checking %1: ...invalid (no providerKey method)" ).arg( myLib.fileName() ) );
181  continue;
182  }
183 
184  // add this provider to the provider map
185  mProviders[pKey()] = new QgsProviderMetadata( pKey(), pDesc(), myLib.fileName() );
186 
187  // load database drivers
188  databaseDrivers_t *pDatabaseDrivers = reinterpret_cast< databaseDrivers_t * >( cast_to_fptr( myLib.resolve( "databaseDrivers" ) ) );
189  if ( pDatabaseDrivers )
190  {
191  mDatabaseDrivers = pDatabaseDrivers();
192  }
193 
194  // load directory drivers
195  directoryDrivers_t *pDirectoryDrivers = reinterpret_cast< directoryDrivers_t * >( cast_to_fptr( myLib.resolve( "directoryDrivers" ) ) );
196  if ( pDirectoryDrivers )
197  {
198  mDirectoryDrivers = pDirectoryDrivers();
199  }
200 
201  // load protocol drivers
202  protocolDrivers_t *pProtocolDrivers = reinterpret_cast< protocolDrivers_t * >( cast_to_fptr( myLib.resolve( "protocolDrivers" ) ) );
203  if ( pProtocolDrivers )
204  {
205  mProtocolDrivers = pProtocolDrivers();
206  }
207 
208  // now get vector file filters, if any
209  fileVectorFilters_t *pFileVectorFilters = reinterpret_cast< fileVectorFilters_t * >( cast_to_fptr( myLib.resolve( "fileVectorFilters" ) ) );
210  if ( pFileVectorFilters )
211  {
212  QString fileVectorFilters = pFileVectorFilters();
213 
214  if ( !fileVectorFilters.isEmpty() )
215  mVectorFileFilters += fileVectorFilters;
216 
217  QgsDebugMsg( QStringLiteral( "Checking %1: ...loaded OK (%2 file filters)" ).arg( myLib.fileName() ).arg( fileVectorFilters.split( ";;" ).count() ) );
218  }
219 
220  // now get raster file filters, if any
221  // this replaces deprecated QgsRasterLayer::buildSupportedRasterFileFilter
223  reinterpret_cast< buildsupportedrasterfilefilter_t * >( cast_to_fptr( myLib.resolve( "buildSupportedRasterFileFilter" ) ) );
224  if ( pBuild )
225  {
226  QString fileRasterFilters;
227  pBuild( fileRasterFilters );
228 
229  QgsDebugMsg( "raster filters: " + fileRasterFilters );
230  if ( !fileRasterFilters.isEmpty() )
231  mRasterFileFilters += fileRasterFilters;
232 
233  QgsDebugMsg( QStringLiteral( "Checking %1: ...loaded OK (%2 file filters)" ).arg( myLib.fileName() ).arg( fileRasterFilters.split( ";;" ).count() ) );
234  }
235 
236  // call initProvider() if such function is available - allows provider to register its services to QGIS
237  initProviderFunction_t *initFunc = reinterpret_cast< initProviderFunction_t * >( cast_to_fptr( myLib.resolve( "initProvider" ) ) );
238  if ( initFunc )
239  initFunc();
240  }
241 } // QgsProviderRegistry ctor
242 
243 
244 // typedef for the unload dataprovider function
246 
247 void QgsProviderRegistry::clean()
248 {
249  // avoid recreating a new project just to clean it
250  if ( QgsProject::sProject )
252 
253  Providers::const_iterator it = mProviders.begin();
254 
255  while ( it != mProviders.end() )
256  {
257  QgsDebugMsgLevel( QStringLiteral( "cleanup:%1" ).arg( it->first ), 5 );
258  QString lib = it->second->library();
259  if ( !lib.isEmpty() )
260  {
261  QLibrary myLib( lib );
262  if ( myLib.isLoaded() )
263  {
264  cleanupProviderFunction_t *cleanupFunc = reinterpret_cast< cleanupProviderFunction_t * >( cast_to_fptr( myLib.resolve( "cleanupProvider" ) ) );
265  if ( cleanupFunc )
266  cleanupFunc();
267  }
268  }
269  delete it->second;
270  ++it;
271  }
272  mProviders.clear();
273 }
274 
276 {
277  clean();
278  if ( sInstance == this )
279  sInstance = nullptr;
280 }
281 
282 
291 static
292 QgsProviderMetadata *findMetadata_( QgsProviderRegistry::Providers const &metaData,
293  QString const &providerKey )
294 {
295  QgsProviderRegistry::Providers::const_iterator i =
296  metaData.find( providerKey );
297 
298  if ( i != metaData.end() )
299  {
300  return i->second;
301  }
302 
303  return nullptr;
304 } // findMetadata_
305 
306 
307 
308 QString QgsProviderRegistry::library( QString const &providerKey ) const
309 {
310  QgsProviderMetadata *md = findMetadata_( mProviders, providerKey );
311 
312  if ( md )
313  {
314  return md->library();
315  }
316 
317  return QString();
318 }
319 
320 
321 QString QgsProviderRegistry::pluginList( bool asHTML ) const
322 {
323  Providers::const_iterator it = mProviders.begin();
324 
325  if ( mProviders.empty() )
326  return QObject::tr( "No data provider plugins are available. No vector layers can be loaded" );
327 
328  QString list;
329 
330  if ( asHTML )
331  list += QLatin1String( "<ol>" );
332 
333  while ( it != mProviders.end() )
334  {
335  if ( asHTML )
336  list += QLatin1String( "<li>" );
337 
338  list += it->second->description();
339 
340  if ( asHTML )
341  list += QLatin1String( "<br></li>" );
342  else
343  list += '\n';
344 
345  ++it;
346  }
347 
348  if ( asHTML )
349  list += QLatin1String( "</ol>" );
350 
351  return list;
352 }
353 
355 {
356  mLibraryDirectory = path;
357  clean();
358  init();
359 }
360 
362 {
363  return mLibraryDirectory;
364 }
365 
366 
367 
368 // typedef for the QgsDataProvider class factory
369 typedef QgsDataProvider *classFactoryFunction_t( const QString *, const QgsDataProvider::ProviderOptions &options );
370 
371 
372 /* Copied from QgsVectorLayer::setDataProvider
373  * TODO: Make it work in the generic environment
374  *
375  * TODO: Is this class really the best place to put a data provider loader?
376  * It seems more sensible to provide the code in one place rather than
377  * in qgsrasterlayer, qgsvectorlayer, serversourceselect, etc.
378  */
379 QgsDataProvider *QgsProviderRegistry::createProvider( QString const &providerKey, QString const &dataSource, const QgsDataProvider::ProviderOptions &options )
380 {
381  // XXX should I check for and possibly delete any pre-existing providers?
382  // XXX How often will that scenario occur?
383 
384  const QgsProviderMetadata *metadata = providerMetadata( providerKey );
385  if ( !metadata )
386  {
387  QgsMessageLog::logMessage( QObject::tr( "Invalid data provider %1" ).arg( providerKey ) );
388  return nullptr;
389  }
390 
391  if ( metadata->createFunction() )
392  {
393  return metadata->createFunction()( dataSource, options );
394  }
395 
396  // load the plugin
397  QString lib = library( providerKey );
398 
399 #ifdef TESTPROVIDERLIB
400  const char *cLib = lib.toUtf8();
401 
402  // test code to help debug provider loading problems
403  // void *handle = dlopen(cLib, RTLD_LAZY);
404  void *handle = dlopen( cOgrLib, RTLD_LAZY | RTLD_GLOBAL );
405  if ( !handle )
406  {
407  QgsLogger::warning( "Error in dlopen" );
408  }
409  else
410  {
411  QgsDebugMsg( QStringLiteral( "dlopen succeeded" ) );
412  dlclose( handle );
413  }
414 
415 #endif
416  // load the data provider
417  QLibrary myLib( lib );
418 
419  QgsDebugMsg( "Library name is " + myLib.fileName() );
420  if ( !myLib.load() )
421  {
422  QgsMessageLog::logMessage( QObject::tr( "Failed to load %1: %2" ).arg( lib, myLib.errorString() ) );
423  return nullptr;
424  }
425 
426  classFactoryFunction_t *classFactory = reinterpret_cast< classFactoryFunction_t * >( cast_to_fptr( myLib.resolve( "classFactory" ) ) );
427  if ( !classFactory )
428  {
429  QgsDebugMsg( QStringLiteral( "Failed to load %1: no classFactory method" ).arg( lib ) );
430  return nullptr;
431  }
432 
433  QgsDataProvider *dataProvider = classFactory( &dataSource, options );
434  if ( !dataProvider )
435  {
436  QgsMessageLog::logMessage( QObject::tr( "Unable to instantiate the data provider plugin %1" ).arg( lib ) );
437  myLib.unload();
438  return nullptr;
439  }
440 
441  QgsDebugMsg( QStringLiteral( "Instantiated the data provider plugin: %1" ).arg( dataProvider->name() ) );
442  return dataProvider;
443 } // QgsProviderRegistry::setDataProvider
444 
445 QVariantMap QgsProviderRegistry::decodeUri( const QString &providerKey, const QString &uri )
446 {
447  std::unique_ptr< QLibrary > library( createProviderLibrary( providerKey ) );
448  if ( !library )
449  {
450  return QVariantMap();
451  }
452 
453  decodeUri_t *decodeUri = reinterpret_cast< decodeUri_t *>( cast_to_fptr( library->resolve( "decodeUri" ) ) );
454  if ( !decodeUri )
455  {
456  return QVariantMap();
457  }
458  return decodeUri( uri );
459 }
460 
461 int QgsProviderRegistry::providerCapabilities( const QString &providerKey ) const
462 {
463  std::unique_ptr< QLibrary > library( createProviderLibrary( providerKey ) );
464  if ( !library )
465  {
467  }
468 
469  dataCapabilities_t *dataCapabilities = reinterpret_cast< dataCapabilities_t *>( cast_to_fptr( library->resolve( "dataCapabilities" ) ) );
470  if ( !dataCapabilities )
471  {
473  }
474 
475  return dataCapabilities();
476 }
477 
478 // This should be QWidget, not QDialog
479 typedef QWidget *selectFactoryFunction_t( QWidget *parent, Qt::WindowFlags fl, QgsProviderRegistry::WidgetMode widgetMode );
480 
481 QWidget *QgsProviderRegistry::createSelectionWidget( const QString &providerKey,
482  QWidget *parent, Qt::WindowFlags fl, QgsProviderRegistry::WidgetMode widgetMode )
483 {
484  selectFactoryFunction_t *selectFactory =
485  reinterpret_cast< selectFactoryFunction_t * >( cast_to_fptr( function( providerKey, "selectWidget" ) ) );
486 
487  if ( !selectFactory )
488  return nullptr;
489 
490  return selectFactory( parent, fl, widgetMode );
491 }
492 
493 QFunctionPointer QgsProviderRegistry::function( QString const &providerKey,
494  QString const &functionName )
495 {
496  QString lib = library( providerKey );
497  if ( lib.isEmpty() )
498  return nullptr;
499 
500  QLibrary myLib( library( providerKey ) );
501 
502  QgsDebugMsg( "Library name is " + myLib.fileName() );
503 
504  if ( myLib.load() )
505  {
506  return myLib.resolve( functionName.toLatin1().data() );
507  }
508  else
509  {
510  QgsDebugMsg( "Cannot load library: " + myLib.errorString() );
511  return nullptr;
512  }
513 }
514 
515 QLibrary *QgsProviderRegistry::createProviderLibrary( QString const &providerKey ) const
516 {
517  QString lib = library( providerKey );
518  if ( lib.isEmpty() )
519  return nullptr;
520 
521  std::unique_ptr< QLibrary > myLib( new QLibrary( lib ) );
522 
523  QgsDebugMsg( "Library name is " + myLib->fileName() );
524 
525  if ( myLib->load() )
526  return myLib.release();
527 
528  QgsDebugMsg( "Cannot load library: " + myLib->errorString() );
529 
530  return nullptr;
531 }
532 
533 void QgsProviderRegistry::registerGuis( QWidget *parent )
534 {
535  typedef void registerGui_function( QWidget * parent );
536 
537  Q_FOREACH ( const QString &provider, providerList() )
538  {
539  registerGui_function *registerGui = reinterpret_cast< registerGui_function * >( cast_to_fptr( function( provider, "registerGui" ) ) );
540 
541  if ( !registerGui )
542  continue;
543 
544  registerGui( parent );
545  }
546 }
547 
549 {
550  if ( providerMetadata )
551  {
552  if ( mProviders.find( providerMetadata->key() ) == mProviders.end() )
553  {
554  mProviders[ providerMetadata->key() ] = providerMetadata;
555  return true;
556  }
557  else
558  {
559  QgsDebugMsgLevel( QStringLiteral( "Cannot register provider metadata: a provider with the same key (%1) was already registered!" ).arg( providerMetadata->key() ), 2 );
560  }
561  }
562  else
563  {
564  QgsDebugMsgLevel( QStringLiteral( "Trying to register a null metadata provider!" ), 2 );
565  }
566  return false;
567 }
568 
570 {
571  return mVectorFileFilters;
572 }
573 
575 {
576  return mRasterFileFilters;
577 }
578 
580 {
581  return mDatabaseDrivers;
582 }
583 
585 {
586  return mDirectoryDrivers;
587 }
588 
590 {
591  return mProtocolDrivers;
592 }
593 
595 {
596  QStringList lst;
597  for ( Providers::const_iterator it = mProviders.begin(); it != mProviders.end(); ++it )
598  {
599  lst.append( it->first );
600  }
601  return lst;
602 }
603 
604 const QgsProviderMetadata *QgsProviderRegistry::providerMetadata( const QString &providerKey ) const
605 {
606  return findMetadata_( mProviders, providerKey );
607 }
bool registerProvider(QgsProviderMetadata *providerMetadata)
register a new vector data provider from its providerMetadata
QDir libraryDirectory() const
Returns the library directory where plugins are found.
WidgetMode
Different ways a source select dialog can be used (embedded is for the data source manager dialog) ...
QString databaseDrivers_t()
virtual QString databaseDrivers() const
Returns a string containing the available database drivers.
void cleanupProviderFunction_t()
CreateDataProviderFunction createFunction() const
Returns a pointer to the direct provider creation function, if supported by the provider.
virtual void setTitle(const QString &title)=0
Sets title for the messages.
QVariantMap decodeUri_t(const QString &uri)
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
QString library(const QString &providerKey) const
Returns path for the library of the provider.
static void warning(const QString &msg)
Goes to qWarning.
Definition: qgslogger.cpp:121
const QgsProviderMetadata * providerMetadata(const QString &providerKey) const
Returns metadata of the provider or NULL if not found.
QString key() const
This returns the unique key associated with the provider.
void registerGuis(QWidget *widget)
QString directoryDrivers_t()
static QgsMessageOutput * createMessageOutput()
function that returns new class derived from QgsMessageOutput (don&#39;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)
Returns the components (e.g.
Abstract base class for spatial data provider implementations.
virtual QString name() const =0
Returns a provider name.
QString description_t()
QgsDataProvider * createProvider(const QString &providerKey, const QString &dataSource, const QgsDataProvider::ProviderOptions &options=QgsDataProvider::ProviderOptions())
Creates a new instance of a provider.
QStringList providerList() const
Returns list of available providers by their keys.
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.
bool isprovider_t()
void initProviderFunction_t()
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance.
QString library() const
This returns the library file name.
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39
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 QString protocolDrivers() const
Returns a string containing the available protocol drivers.
int providerCapabilities(const QString &providerKey) const
Returns the provider capabilities.
virtual void setMessage(const QString &message, MessageType msgType)=0
Sets message, it won&#39;t be displayed until.
void setLibraryDirectory(const QDir &path)
Sets library directory where to search for plugins.
void removeAllMapLayers()
Removes all registered layers.
QLibrary * createProviderLibrary(const QString &providerKey) const
Returns a new QLibrary for the specified providerKey.
#define cast_to_fptr(f)
Definition: qgis.h:171
virtual QString directoryDrivers() const
Returns a string containing the available directory drivers.
virtual QString fileRasterFilters() const
Returns raster file filter string.
QString fileVectorFilters_t()
QString pluginList(bool asHtml=false) const
Returns list of provider plugins found.
A registry / canonical manager of data providers.
virtual void showMessage(bool blocking=true)=0
display the message to the user and deletes itself
virtual QString fileVectorFilters() const
Returns vector file filter string.
Setting options for creating vector data providers.
QString providerkey_t()
Holds data provider key, description, and associated shared library file or function pointer informat...
std::map< QString, QgsProviderMetadata * > Providers
Open the given vector data source.
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:411
QWidget * selectFactoryFunction_t(QWidget *parent, Qt::WindowFlags fl, QgsProviderRegistry::WidgetMode widgetMode)
QFunctionPointer function(const QString &providerKey, const QString &functionName)
Gets pointer to provider function.
void buildsupportedrasterfilefilter_t(QString &fileFiltersString)
QString protocolDrivers_t()
Interface for showing messages from QGIS in GUI independent way.
int dataCapabilities_t()