Skip to content

Commit

Permalink
[API] Unvirtualize layer setDataSource method
Browse files Browse the repository at this point in the history
Changes in the layer API:
* The setDatasource() methods become non-virtual public method
* The virtual private setDataSourcePrivate() method is defined and the provider setDataSource implementations have been moved to this new virtual method
  • Loading branch information
rldhont committed Apr 26, 2021
1 parent 6260d17 commit 4afa66a
Show file tree
Hide file tree
Showing 16 changed files with 176 additions and 112 deletions.
7 changes: 7 additions & 0 deletions doc/api_break.dox
Expand Up @@ -16,7 +16,14 @@ with too big impact should be deferred to a major version release.

This page tries to maintain a list with incompatible changes that happened in previous releases.

QGIS 3.20 {#qgis_api_break_3_20}
=========

setDataSource {#qgis_api_break_3_20_setdatasource}
-------------

- QgsVectorLayer::setDataSource deprecated and specific method without ProviderOptions has been removed
- QgsMapLayer::setDataSource is no longer virtual. If has been replaced with QgsMapLayer::setDataSourcePrivate. This is only relevant for subclassing QgsMapLayer, for code that only uses the subclasses (QgsVectorLayer, QgsRasterLayer, ...) this has no effect.

QGIS 3.4 {#qgis_api_break_3_4}
========
Expand Down
Expand Up @@ -96,7 +96,6 @@ QgsPointCloudLayer cannot be copied.

virtual void setTransformContext( const QgsCoordinateTransformContext &transformContext );

virtual void setDataSource( const QString &dataSource, const QString &baseName, const QString &provider, const QgsDataProvider::ProviderOptions &options, bool loadDefaultStyleFlag = false );

virtual QString encodedSource( const QString &source, const QgsReadWriteContext &context ) const;

Expand Down
1 change: 1 addition & 0 deletions python/core/auto_generated/qgsdataprovider.sip.in
Expand Up @@ -74,6 +74,7 @@ Abstract base class for spatial data provider implementations.
{
FlagTrustDataSource,
SkipFeatureCount,
FlagLoadDefaultStyle,
};
typedef QFlags<QgsDataProvider::ReadFlag> ReadFlags;

Expand Down
22 changes: 19 additions & 3 deletions python/core/auto_generated/qgsmaplayer.sip.in
Expand Up @@ -1061,13 +1061,11 @@ Write just the symbology information for the layer into the document
%End


virtual void setDataSource( const QString &dataSource, const QString &baseName, const QString &provider, const QgsDataProvider::ProviderOptions &options, bool loadDefaultStyleFlag = false );
void setDataSource( const QString &dataSource, const QString &baseName, const QString &provider, const QgsDataProvider::ProviderOptions &options, bool loadDefaultStyleFlag = false );
%Docstring
Updates the data source of the layer. The layer's renderer and legend will be preserved only
if the geometry type of the new data source matches the current geometry type of the layer.

Subclasses should override this method: default implementation does nothing.

:param dataSource: new layer data source
:param baseName: base name of the layer
:param provider: provider string
Expand All @@ -1078,6 +1076,24 @@ Subclasses should override this method: default implementation does nothing.
.. seealso:: :py:func:`dataSourceChanged`

.. versionadded:: 3.6
%End

void setDataSource( const QString &dataSource, const QString &baseName, const QString &provider, const QgsDataProvider::ProviderOptions &options, QgsDataProvider::ReadFlags flags );
%Docstring
Updates the data source of the layer. The layer's renderer and legend will be preserved only
if the geometry type of the new data source matches the current geometry type of the layer.

Subclasses should override setDataSourcePrivate: default implementation does nothing.

:param dataSource: new layer data source
:param baseName: base name of the layer
:param provider: provider string
:param options: provider options
:param flags: provider read flags

.. seealso:: :py:func:`dataSourceChanged`

.. versionadded:: 3.20
%End

QString providerType() const;
Expand Down
18 changes: 0 additions & 18 deletions python/core/auto_generated/raster/qgsrasterlayer.sip.in
Expand Up @@ -156,24 +156,6 @@ Set the data provider.
:param flags: provider flags since QGIS 3.16

.. versionadded:: 3.2
%End

virtual void setDataSource( const QString &dataSource, const QString &baseName, const QString &provider, const QgsDataProvider::ProviderOptions &options, bool loadDefaultStyleFlag = false );

%Docstring
Updates the data source of the layer. The layer's renderer and legend will be preserved only
if the geometry type of the new data source matches the current geometry type of the layer.

:param dataSource: new layer data source
:param baseName: base name of the layer
:param provider: provider string
:param options: provider options
:param loadDefaultStyleFlag: set to ``True`` to reset the layer's style to the default for the
data source

.. seealso:: :py:func:`dataSourceChanged`

.. versionadded:: 3.6
%End

LayerType rasterType();
Expand Down
17 changes: 0 additions & 17 deletions python/core/auto_generated/vector/qgsvectorlayer.sip.in
Expand Up @@ -1082,23 +1082,6 @@ Determines if this vector layer has features.
.. versionadded:: 3.4
%End

virtual void setDataSource( const QString &dataSource, const QString &baseName, const QString &provider, const QgsDataProvider::ProviderOptions &options, bool loadDefaultStyleFlag = false );

%Docstring
Updates the data source of the layer. The layer's renderer and legend will be preserved only
if the geometry type of the new data source matches the current geometry type of the layer.

:param dataSource: new layer data source
:param baseName: base name of the layer
:param provider: provider string
:param options: provider options
:param loadDefaultStyleFlag: set to ``True`` to reset the layer's style to the default for the
data source

.. seealso:: :py:func:`dataSourceChanged`

.. versionadded:: 3.2
%End

virtual QString loadDefaultStyle( bool &resultFlag /Out/ ) ${SIP_FINAL};

Expand Down
35 changes: 20 additions & 15 deletions src/core/pointcloud/qgspointcloudlayer.cpp
Expand Up @@ -44,7 +44,12 @@ QgsPointCloudLayer::QgsPointCloudLayer( const QString &uri,
if ( !uri.isEmpty() && !providerLib.isEmpty() )
{
QgsDataProvider::ProviderOptions providerOptions { options.transformContext };
setDataSource( uri, baseName, providerLib, providerOptions, options.loadDefaultStyle );
QgsDataProvider::ReadFlags providerFlags = QgsDataProvider::ReadFlags();
if ( options.loadDefaultStyle )
{
providerFlags |= QgsDataProvider::FlagLoadDefaultStyle;
}
setDataSourcePrivate( uri, baseName, providerLib, providerOptions, providerFlags );

if ( !options.skipIndexGeneration && mDataProvider && mDataProvider->isValid() )
mDataProvider.get()->generateIndex();
Expand Down Expand Up @@ -103,7 +108,12 @@ bool QgsPointCloudLayer::readXml( const QDomNode &layerNode, QgsReadWriteContext
if ( !( mReadFlags & QgsMapLayer::FlagDontResolveLayers ) )
{
QgsDataProvider::ProviderOptions providerOptions { context.transformContext() };
setDataSource( mDataSource, mLayerName, mProviderKey, providerOptions, false );
QgsDataProvider::ReadFlags flags = QgsDataProvider::ReadFlags();
if ( mReadFlags & QgsMapLayer::FlagTrustLayerMetadata )
{
flags |= QgsDataProvider::FlagTrustDataSource;
}
setDataSourcePrivate( mDataSource, mLayerName, mProviderKey, providerOptions, flags );
}

if ( !isValid() )
Expand Down Expand Up @@ -280,8 +290,8 @@ void QgsPointCloudLayer::setTransformContext( const QgsCoordinateTransformContex
invalidateWgs84Extent();
}

void QgsPointCloudLayer::setDataSource( const QString &dataSource, const QString &baseName, const QString &provider,
const QgsDataProvider::ProviderOptions &options, bool loadDefaultStyleFlag )
void QgsPointCloudLayer::setDataSourcePrivate( const QString &dataSource, const QString &baseName, const QString &provider,
const QgsDataProvider::ProviderOptions &options, QgsDataProvider::ReadFlags flags )
{
if ( mDataProvider )
{
Expand All @@ -293,18 +303,11 @@ void QgsPointCloudLayer::setDataSource( const QString &dataSource, const QString
mProviderKey = provider;
mDataSource = dataSource;

QgsDataProvider::ReadFlags flags = QgsDataProvider::ReadFlags();
if ( mReadFlags & QgsMapLayer::FlagTrustLayerMetadata )
{
flags |= QgsDataProvider::FlagTrustDataSource;
}

mDataProvider.reset( qobject_cast<QgsPointCloudDataProvider *>( QgsProviderRegistry::instance()->createProvider( provider, dataSource, options, flags ) ) );
if ( !mDataProvider )
{
QgsDebugMsg( QStringLiteral( "Unable to get point cloud data provider" ) );
setValid( false );
emit dataSourceChanged();
return;
}

Expand All @@ -315,7 +318,6 @@ void QgsPointCloudLayer::setDataSource( const QString &dataSource, const QString
if ( !isValid() )
{
QgsDebugMsg( QStringLiteral( "Invalid point cloud provider plugin %1" ).arg( QString( mDataSource.toUtf8() ) ) );
emit dataSourceChanged();
return;
}

Expand All @@ -326,6 +328,12 @@ void QgsPointCloudLayer::setDataSource( const QString &dataSource, const QString
setCrs( mDataProvider->crs() );
setExtent( mDataProvider->extent() );

bool loadDefaultStyleFlag = false;
if ( flags & QgsDataProvider::FlagLoadDefaultStyle )
{
loadDefaultStyleFlag = true;
}

if ( !mRenderer || loadDefaultStyleFlag )
{
std::unique_ptr< QgsScopedRuntimeProfile > profile;
Expand Down Expand Up @@ -356,9 +364,6 @@ void QgsPointCloudLayer::setDataSource( const QString &dataSource, const QString
setRenderer( QgsApplication::pointCloudRendererRegistry()->defaultRenderer( mDataProvider.get() ) );
}
}

emit dataSourceChanged();
triggerRepaint();
}

QString QgsPointCloudLayer::encodedSource( const QString &source, const QgsReadWriteContext &context ) const
Expand Down
3 changes: 2 additions & 1 deletion src/core/pointcloud/qgspointcloudlayer.h
Expand Up @@ -128,7 +128,7 @@ class CORE_EXPORT QgsPointCloudLayer : public QgsMapLayer
bool writeStyle( QDomNode &node, QDomDocument &doc, QString &errorMessage, const QgsReadWriteContext &context, StyleCategories categories = AllStyleCategories ) const FINAL;

void setTransformContext( const QgsCoordinateTransformContext &transformContext ) override;
void setDataSource( const QString &dataSource, const QString &baseName, const QString &provider, const QgsDataProvider::ProviderOptions &options, bool loadDefaultStyleFlag = false ) override;

QString encodedSource( const QString &source, const QgsReadWriteContext &context ) const override;
QString decodedSource( const QString &source, const QString &dataProvider, const QgsReadWriteContext &context ) const override;
QString loadDefaultStyle( bool &resultFlag SIP_OUT ) FINAL;
Expand Down Expand Up @@ -171,6 +171,7 @@ class CORE_EXPORT QgsPointCloudLayer : public QgsMapLayer

private slots:
void onPointCloudIndexGenerationStateChanged( QgsPointCloudDataProvider::PointCloudIndexGenerationState state );
void setDataSourcePrivate( const QString &dataSource, const QString &baseName, const QString &provider, const QgsDataProvider::ProviderOptions &options, QgsDataProvider::ReadFlags flags ) override;

private:

Expand Down
1 change: 1 addition & 0 deletions src/core/qgsdataprovider.h
Expand Up @@ -123,6 +123,7 @@ class CORE_EXPORT QgsDataProvider : public QObject
{
FlagTrustDataSource = 1 << 0, //!< Trust datasource config (primary key unicity, geometry type and srid, etc). Improves provider load time by skipping expensive checks like primary key unicity, geometry type and srid and by using estimated metadata on data load. Since QGIS 3.16
SkipFeatureCount = 1 << 1, //!< Make featureCount() return -1 to indicate unknown, and subLayers() to return a unknown feature count as well. Since QGIS 3.18. Only implemented by OGR provider at time of writing.
FlagLoadDefaultStyle = 1 << 2, //!< Reset the layer's style to the default for the datasource
};
Q_DECLARE_FLAGS( ReadFlags, ReadFlag )

Expand Down
38 changes: 36 additions & 2 deletions src/core/qgsmaplayer.cpp
Expand Up @@ -1638,13 +1638,47 @@ bool QgsMapLayer::writeStyle( QDomNode &node, QDomDocument &doc, QString &errorM
return false;
}

void QgsMapLayer::setDataSource( const QString &dataSource, const QString &baseName, const QString &provider, const QgsDataProvider::ProviderOptions &options, bool loadDefaultStyleFlag )
void QgsMapLayer::setDataSource( const QString &dataSource, const QString &baseName, const QString &provider,
const QgsDataProvider::ProviderOptions &options, bool loadDefaultStyleFlag )
{
QgsDataProvider::ReadFlags flags = QgsDataProvider::ReadFlags();
if ( loadDefaultStyleFlag )
{
flags |= QgsDataProvider::FlagLoadDefaultStyle;
}

if ( mReadFlags & QgsMapLayer::FlagTrustLayerMetadata )
{
flags |= QgsDataProvider::FlagTrustDataSource;
}
setDataSource( dataSource, baseName, provider, options, flags );
}


void QgsMapLayer::setDataSource( const QString &dataSource, const QString &baseName, const QString &provider,
const QgsDataProvider::ProviderOptions &options, QgsDataProvider::ReadFlags flags )
{

if ( ( mReadFlags & QgsMapLayer::FlagTrustLayerMetadata ) &&
!( flags & QgsDataProvider::FlagTrustDataSource ) )
{
flags |= QgsDataProvider::FlagTrustDataSource;
}
setDataSourcePrivate( dataSource, baseName, provider, options, flags );
emit dataSourceChanged();
emit dataChanged();
triggerRepaint();
}


void QgsMapLayer::setDataSourcePrivate( const QString &dataSource, const QString &baseName, const QString &provider,
const QgsDataProvider::ProviderOptions &options, QgsDataProvider::ReadFlags flags )
{
Q_UNUSED( dataSource )
Q_UNUSED( baseName )
Q_UNUSED( provider )
Q_UNUSED( options )
Q_UNUSED( loadDefaultStyleFlag )
Q_UNUSED( flags )
}


Expand Down
37 changes: 34 additions & 3 deletions src/core/qgsmaplayer.h
Expand Up @@ -988,8 +988,6 @@ class CORE_EXPORT QgsMapLayer : public QObject
* Updates the data source of the layer. The layer's renderer and legend will be preserved only
* if the geometry type of the new data source matches the current geometry type of the layer.
*
* Subclasses should override this method: default implementation does nothing.
*
* \param dataSource new layer data source
* \param baseName base name of the layer
* \param provider provider string
Expand All @@ -999,7 +997,23 @@ class CORE_EXPORT QgsMapLayer : public QObject
* \see dataSourceChanged()
* \since QGIS 3.6
*/
virtual void setDataSource( const QString &dataSource, const QString &baseName, const QString &provider, const QgsDataProvider::ProviderOptions &options, bool loadDefaultStyleFlag = false );
void setDataSource( const QString &dataSource, const QString &baseName, const QString &provider, const QgsDataProvider::ProviderOptions &options, bool loadDefaultStyleFlag = false );

/**
* Updates the data source of the layer. The layer's renderer and legend will be preserved only
* if the geometry type of the new data source matches the current geometry type of the layer.
*
* Subclasses should override setDataSourcePrivate: default implementation does nothing.
*
* \param dataSource new layer data source
* \param baseName base name of the layer
* \param provider provider string
* \param options provider options
* \param flags provider read flags
* \see dataSourceChanged()
* \since QGIS 3.20
*/
void setDataSource( const QString &dataSource, const QString &baseName, const QString &provider, const QgsDataProvider::ProviderOptions &options, QgsDataProvider::ReadFlags flags );

/**
* Returns the provider type (provider key) for this layer
Expand Down Expand Up @@ -1513,6 +1527,23 @@ class CORE_EXPORT QgsMapLayer : public QObject

void onNotified( const QString &message );

/**
* Updates the data source of the layer. The layer's renderer and legend will be preserved only
* if the geometry type of the new data source matches the current geometry type of the layer.
*
* Called by setDataSource()
* Subclasses should override this method: default implementation does nothing.
*
* \param dataSource new layer data source
* \param baseName base name of the layer
* \param provider provider string
* \param options provider options
* \param flags provider read flags
* \see dataSourceChanged()
* \since QGIS 3.20
*/
virtual void setDataSourcePrivate( const QString &dataSource, const QString &baseName, const QString &provider, const QgsDataProvider::ProviderOptions &options, QgsDataProvider::ReadFlags flags );

protected:

/**
Expand Down

0 comments on commit 4afa66a

Please sign in to comment.