QgsSourceSelectProviderRegistry delayed initialization

Due to QgsGui being initialized after data provider.
This commit is contained in:
Alessandro Pasotti 2017-09-04 09:10:56 +02:00
parent 42bd913f57
commit 1816087485
3 changed files with 65 additions and 33 deletions

View File

@ -17,6 +17,12 @@ class QgsSourceSelectProviderRegistry
QgsSourceSelectProviderRegistry is not usually directly created, but rather accessed through
QgsGui.sourceSelectProviderRegistry().
.. note::
This class access to QgsProviderRegistry instance to initialize, but QgsProviderRegistry is
typically initialized after QgsGui is constructed, for this reason a delayed initialization has been
implemented in the class.
.. versionadded:: 3.0
%End
@ -29,7 +35,7 @@ class QgsSourceSelectProviderRegistry
~QgsSourceSelectProviderRegistry();
QList< QgsSourceSelectProvider *> providers() const;
QList< QgsSourceSelectProvider *> providers();
%Docstring
Get list of available providers
:rtype: list of QgsSourceSelectProvider
@ -45,13 +51,13 @@ Add a provider implementation. Takes ownership of the object.
Remove provider implementation from the list (provider object is deleted)
%End
QgsSourceSelectProvider *providerByName( const QString &name ) const;
QgsSourceSelectProvider *providerByName( const QString &name );
%Docstring
Return a provider by name or None if not found
:rtype: QgsSourceSelectProvider
%End
QList<QgsSourceSelectProvider *> providersByKey( const QString &providerKey ) const;
QList<QgsSourceSelectProvider *> providersByKey( const QString &providerKey );
%Docstring
Return a (possibly empty) list of providers by data provider's key
:rtype: list of QgsSourceSelectProvider

View File

@ -24,26 +24,7 @@ typedef QList<QgsSourceSelectProvider *> *sourceSelectProviders_t();
QgsSourceSelectProviderRegistry::QgsSourceSelectProviderRegistry()
{
QStringList providersList = QgsProviderRegistry::instance()->providerList();
Q_FOREACH ( const QString &key, providersList )
{
std::unique_ptr< QLibrary > library( QgsProviderRegistry::instance()->createProviderLibrary( key ) );
if ( !library )
continue;
sourceSelectProviders_t *sourceSelectProvidersFn = reinterpret_cast< sourceSelectProviders_t * >( cast_to_fptr( library->resolve( "sourceSelectProviders" ) ) );
if ( sourceSelectProvidersFn )
{
QList<QgsSourceSelectProvider *> *providerList = sourceSelectProvidersFn();
// the function is a factory - we keep ownership of the returned providers
for ( auto provider : qgsAsConst( *providerList ) )
{
addProvider( provider );
}
delete providerList;
}
}
// Initialization is delayed
}
QgsSourceSelectProviderRegistry::~QgsSourceSelectProviderRegistry()
@ -51,6 +32,12 @@ QgsSourceSelectProviderRegistry::~QgsSourceSelectProviderRegistry()
qDeleteAll( mProviders );
}
QList<QgsSourceSelectProvider *> QgsSourceSelectProviderRegistry::providers()
{
init();
return mProviders;
}
void QgsSourceSelectProviderRegistry::addProvider( QgsSourceSelectProvider *provider )
{
mProviders.append( provider );
@ -67,9 +54,10 @@ void QgsSourceSelectProviderRegistry::removeProvider( QgsSourceSelectProvider *p
delete mProviders.takeAt( index );
}
QgsSourceSelectProvider *QgsSourceSelectProviderRegistry::providerByName( const QString &name ) const
QgsSourceSelectProvider *QgsSourceSelectProviderRegistry::providerByName( const QString &name )
{
for ( const auto provider : qgsAsConst( mProviders ) )
const QList<QgsSourceSelectProvider *> providerList = providers();
for ( const auto provider : providerList )
{
if ( provider->name() == name )
{
@ -79,15 +67,45 @@ QgsSourceSelectProvider *QgsSourceSelectProviderRegistry::providerByName( const
return nullptr;
}
QList<QgsSourceSelectProvider *> QgsSourceSelectProviderRegistry::providersByKey( const QString &providerKey ) const
QList<QgsSourceSelectProvider *> QgsSourceSelectProviderRegistry::providersByKey( const QString &providerKey )
{
QList<QgsSourceSelectProvider *> providerList;
for ( const auto provider : qgsAsConst( mProviders ) )
QList<QgsSourceSelectProvider *> result;
const QList<QgsSourceSelectProvider *> providerList = providers();
for ( const auto provider : providerList )
{
if ( provider->providerKey() == providerKey )
{
providerList << provider;
result << provider;
}
}
return providerList;
return result;
}
void QgsSourceSelectProviderRegistry::init()
{
if ( mInitialized )
{
return;
}
QStringList providersList = QgsProviderRegistry::instance()->providerList();
Q_FOREACH ( const QString &key, providersList )
{
std::unique_ptr< QLibrary > library( QgsProviderRegistry::instance()->createProviderLibrary( key ) );
if ( !library )
continue;
sourceSelectProviders_t *sourceSelectProvidersFn = reinterpret_cast< sourceSelectProviders_t * >( cast_to_fptr( library->resolve( "sourceSelectProviders" ) ) );
if ( sourceSelectProvidersFn )
{
QList<QgsSourceSelectProvider *> *providerList = sourceSelectProvidersFn();
// the function is a factory - we keep ownership of the returned providers
for ( auto provider : qgsAsConst( *providerList ) )
{
addProvider( provider );
}
delete providerList;
}
}
mInitialized = true;
}

View File

@ -28,6 +28,10 @@ class QgsSourceSelectProvider;
* QgsSourceSelectProviderRegistry is not usually directly created, but rather accessed through
* QgsGui::sourceSelectProviderRegistry().
*
* \note This class access to QgsProviderRegistry instance to initialize, but QgsProviderRegistry is
* typically initialized after QgsGui is constructed, for this reason a delayed initialization has been
* implemented in the class.
*
* \since QGIS 3.0
*/
class GUI_EXPORT QgsSourceSelectProviderRegistry
@ -43,7 +47,7 @@ class GUI_EXPORT QgsSourceSelectProviderRegistry
QgsSourceSelectProviderRegistry &operator=( const QgsSourceSelectProviderRegistry &rh ) = delete;
//! Get list of available providers
QList< QgsSourceSelectProvider *> providers() const { return mProviders; }
QList< QgsSourceSelectProvider *> providers();
//! Add a provider implementation. Takes ownership of the object.
void addProvider( QgsSourceSelectProvider *provider SIP_TRANSFER );
@ -52,13 +56,17 @@ class GUI_EXPORT QgsSourceSelectProviderRegistry
void removeProvider( QgsSourceSelectProvider *provider );
//! Return a provider by name or nullptr if not found
QgsSourceSelectProvider *providerByName( const QString &name ) const;
QgsSourceSelectProvider *providerByName( const QString &name );
//! Return a (possibly empty) list of providers by data provider's key
QList<QgsSourceSelectProvider *> providersByKey( const QString &providerKey ) const;
QList<QgsSourceSelectProvider *> providersByKey( const QString &providerKey );
private:
//! Populate the providers list, this needs to happen after the data provider
//! registry has been initialized.
void init();
bool mInitialized = false;
#ifdef SIP_RUN
QgsSourceSelectProviderRegistry( const QgsSourceSelectProviderRegistry &rh );
#endif