Merge pull request #4567 from pblottiere/clone

Add clone() methods for layers
This commit is contained in:
Matthias Kuhn 2017-05-19 07:10:49 +02:00 committed by GitHub
commit 95ac7d0f7b
18 changed files with 481 additions and 36 deletions

View File

@ -1696,6 +1696,7 @@ QgsPluginLayer {#qgis_api_break_3_0_QgsPluginLayer}
--------------
- createMapRenderer(): default implementation (which called plugin's draw() method) has been removed. Plugin layers must implement createMapRenderer().
- clone(): new pure virtual method. Plugin layer must implement clone().
QgsPluginLayerRegistry {#qgis_api_break_3_0_QgsPluginLayerRegistry}

View File

@ -67,6 +67,15 @@ class QgsMapLayer : QObject
virtual ~QgsMapLayer();
virtual QgsMapLayer *clone() const = 0;
%Docstring
Returns a new instance equivalent to this one except for the id which
is still unique.
:return: a new layer instance
.. versionadded:: 3.0
:rtype: QgsMapLayer
%End
QgsMapLayer::LayerType type() const;
%Docstring
Returns the type of the layer.
@ -470,6 +479,12 @@ Invoked by QgsProject.read().
:rtype: QVariant
%End
void setCustomProperties( const QgsObjectCustomProperties &properties );
%Docstring
Set custom properties for layer. Current properties are dropped.
.. versionadded:: 3.0
%End
void removeCustomProperty( const QString &key );
%Docstring
Remove a custom property from layer. Properties are stored in a map and saved in project file.
@ -1028,6 +1043,14 @@ Signal emitted when the blend mode is changed, through QgsMapLayer.setBlendMode(
%End
protected:
void clone( QgsMapLayer *layer ) const;
%Docstring
Copies attributes like name, short name, ... into another layer.
\param layer The copy recipient
.. versionadded:: 3.0
%End
virtual void setExtent( const QgsRectangle &rect );
%Docstring
Set the extent

View File

@ -133,6 +133,15 @@ Write configuration (for project saving)
Return list of all defined style names
:rtype: list of str
%End
QMap<QString, QgsMapLayerStyle> mapLayerStyles() const;
%Docstring
Gets available styles for the associated map layer.
:return: A map of map layer style by style name
.. versionadded:: 3.0
:rtype: QMap<str, QgsMapLayerStyle>
%End
QgsMapLayerStyle style( const QString &name ) const;
%Docstring
Return data of a stored style - accessed by its unique name

View File

@ -26,6 +26,14 @@ In order to be readable from project files, they should set these attributes in
QgsPluginLayer( const QString &layerType, const QString &layerName = QString() );
~QgsPluginLayer();
virtual QgsPluginLayer *clone() const = 0;
%Docstring
Returns a new instance equivalent to this one.
:return: a new layer instance
.. versionadded:: 3.0
:rtype: QgsPluginLayer
%End
QString pluginLayerType();
%Docstring
Return plugin layer type (the same as used in QgsPluginLayerRegistry)

View File

@ -334,6 +334,17 @@ class QgsVectorLayer : QgsMapLayer, QgsExpressionContextGenerator, QgsFeatureSin
virtual ~QgsVectorLayer();
virtual QgsVectorLayer *clone() const /Factory/;
%Docstring
Returns a new instance equivalent to this one. A new provider is
created for the same data source and renderers for features and diagrams
are cloned too. Moreover, each attributes (transparency, extent, selected
features and so on) are identicals.
:return: a new layer instance
.. versionadded:: 3.0
:rtype: QgsVectorLayer
%End
QString storageType() const;
%Docstring
Returns the permanent storage type for this layer as a friendly name.
@ -496,6 +507,7 @@ Setup the coordinate system transformation for the layer
:rtype: QgsActionManager
%End
int selectedFeatureCount() const;
%Docstring
The number of features that are selected in this layer
@ -1418,6 +1430,14 @@ Assembles mUpdatedFields considering provider fields, joined fields and added fi
:rtype: QgsFieldConstraints.Constraints
%End
QMap< QgsFieldConstraints::Constraint, QgsFieldConstraints::ConstraintStrength> fieldConstraintsAndStrength( int fieldIndex ) const;
%Docstring
Returns a map of constraint with their strength for a specific field of the layer.
\param fieldIndex field index
.. versionadded:: 3.0
:rtype: QMap< QgsFieldConstraints.Constraint, QgsFieldConstraints.ConstraintStrength>
%End
void setFieldConstraint( int index, QgsFieldConstraints::Constraint constraint, QgsFieldConstraints::ConstraintStrength strength = QgsFieldConstraints::ConstraintStrengthHard );
%Docstring
Sets a constraint for a specified field index. Any constraints inherited from the layer's

View File

@ -41,6 +41,13 @@ class QgsRasterLayer : QgsMapLayer
/** \brief The destructor */
~QgsRasterLayer();
/** Returns a new instance equivalent to this one. A new provider is
* created for the same data source and renderer is cloned too.
* \returns a new layer instance
* \since QGIS 3.0
*/
virtual QgsRasterLayer *clone() const /Factory/;
/** \brief This enumerator describes the types of shading that can be used */
enum ColorShadingAlgorithm
{

View File

@ -8984,39 +8984,7 @@ void QgisApp::duplicateLayers( const QList<QgsMapLayer *> &lyrList )
}
else if ( vlayer )
{
QgsVectorLayer *dupVLayer = new QgsVectorLayer( vlayer->source(), layerDupName, vlayer->providerType() );
if ( vlayer->dataProvider() )
{
dupVLayer->setProviderEncoding( vlayer->dataProvider()->encoding() );
}
//add variables defined in layer properties
QStringList variableNames = vlayer->customProperty( QStringLiteral( "variableNames" ) ).toStringList();
QStringList variableValues = vlayer->customProperty( QStringLiteral( "variableValues" ) ).toStringList();
int varIndex = 0;
Q_FOREACH ( const QString &variableName, variableNames )
{
if ( varIndex >= variableValues.length() )
{
break;
}
QVariant varValue = variableValues.at( varIndex );
varIndex++;
QgsExpressionContextUtils::setLayerVariable( dupVLayer, variableName, varValue );
}
Q_FOREACH ( const QgsVectorLayerJoinInfo &join, vlayer->vectorJoins() )
dupVLayer->addJoin( join );
for ( int fld = 0; fld < vlayer->fields().count(); fld++ )
{
if ( vlayer->fields().fieldOrigin( fld ) == QgsFields::OriginExpression )
dupVLayer->addExpressionField( vlayer->expressionField( fld ), vlayer->fields().at( fld ) );
}
dupLayer = dupVLayer;
dupLayer = vlayer->clone();
}
}
@ -9025,7 +8993,7 @@ void QgisApp::duplicateLayers( const QList<QgsMapLayer *> &lyrList )
QgsRasterLayer *rlayer = qobject_cast<QgsRasterLayer *>( selectedLyr );
if ( rlayer )
{
dupLayer = new QgsRasterLayer( rlayer->source(), layerDupName );
dupLayer = rlayer->clone();
}
}

View File

@ -94,6 +94,38 @@ QgsMapLayer::~QgsMapLayer()
delete mStyleManager;
}
void QgsMapLayer::clone( QgsMapLayer *layer ) const
{
layer->setBlendMode( blendMode() );
Q_FOREACH ( const QString &s, styleManager()->styles() )
{
layer->styleManager()->addStyle( s, styleManager()->style( s ) );
}
layer->setName( name() );
layer->setShortName( shortName() );
layer->setExtent( extent() );
layer->setMinimumScale( minimumScale() );
layer->setMaximumScale( maximumScale() );
layer->setScaleBasedVisibility( hasScaleBasedVisibility() );
layer->setTitle( title() );
layer->setAbstract( abstract() );
layer->setKeywordList( keywordList() );
layer->setDataUrl( dataUrl() );
layer->setDataUrlFormat( dataUrlFormat() );
layer->setAttribution( attribution() );
layer->setAttributionUrl( attributionUrl() );
layer->setMetadataUrl( metadataUrl() );
layer->setMetadataUrlType( metadataUrlType() );
layer->setMetadataUrlFormat( metadataUrlFormat() );
layer->setLegendUrl( legendUrl() );
layer->setLegendUrlFormat( legendUrlFormat() );
layer->setDependencies( dependencies() );
layer->setCrs( crs() );
layer->setCustomProperties( mCustomProperties );
}
QgsMapLayer::LayerType QgsMapLayer::type() const
{
return mLayerType;
@ -1583,6 +1615,11 @@ void QgsMapLayer::setCustomProperty( const QString &key, const QVariant &value )
mCustomProperties.setValue( key, value );
}
void QgsMapLayer::setCustomProperties( const QgsObjectCustomProperties &properties )
{
mCustomProperties = properties;
}
QVariant QgsMapLayer::customProperty( const QString &value, const QVariant &defaultValue ) const
{
return mCustomProperties.value( value, defaultValue );

View File

@ -110,6 +110,13 @@ class CORE_EXPORT QgsMapLayer : public QObject
//! QgsMapLayer cannot be copied
QgsMapLayer &operator=( QgsMapLayer const & ) = delete;
/** Returns a new instance equivalent to this one except for the id which
* is still unique.
* \returns a new layer instance
* \since QGIS 3.0
*/
virtual QgsMapLayer *clone() const = 0;
/** Returns the type of the layer.
*/
QgsMapLayer::LayerType type() const;
@ -444,6 +451,11 @@ class CORE_EXPORT QgsMapLayer : public QObject
*/
QVariant customProperty( const QString &value, const QVariant &defaultValue = QVariant() ) const;
/** Set custom properties for layer. Current properties are dropped.
* \since QGIS 3.0
*/
void setCustomProperties( const QgsObjectCustomProperties &properties );
/** Remove a custom property from layer. Properties are stored in a map and saved in project file.
* \see setCustomProperty()
*/
@ -916,6 +928,13 @@ class CORE_EXPORT QgsMapLayer : public QObject
void metadataChanged();
protected:
/** Copies attributes like name, short name, ... into another layer.
* \param layer The copy recipient
* \since QGIS 3.0
*/
void clone( QgsMapLayer *layer ) const;
//! Set the extent
virtual void setExtent( const QgsRectangle &rect );

View File

@ -70,6 +70,11 @@ QStringList QgsMapLayerStyleManager::styles() const
return mStyles.keys();
}
QMap<QString, QgsMapLayerStyle> QgsMapLayerStyleManager::mapLayerStyles() const
{
return mStyles;
}
QgsMapLayerStyle QgsMapLayerStyleManager::style( const QString &name ) const
{
if ( name == mCurrentStyle )

View File

@ -110,6 +110,13 @@ class CORE_EXPORT QgsMapLayerStyleManager : public QObject
//! Return list of all defined style names
QStringList styles() const;
/** Gets available styles for the associated map layer.
* \returns A map of map layer style by style name
* \since QGIS 3.0
*/
QMap<QString, QgsMapLayerStyle> mapLayerStyles() const;
//! Return data of a stored style - accessed by its unique name
QgsMapLayerStyle style( const QString &name ) const;

View File

@ -36,6 +36,12 @@ class CORE_EXPORT QgsPluginLayer : public QgsMapLayer
QgsPluginLayer( const QString &layerType, const QString &layerName = QString() );
~QgsPluginLayer();
/** Returns a new instance equivalent to this one.
* \returns a new layer instance
* \since QGIS 3.0
*/
virtual QgsPluginLayer *clone() const override = 0;
//! Return plugin layer type (the same as used in QgsPluginLayerRegistry)
QString pluginLayerType();

View File

@ -201,6 +201,79 @@ QgsVectorLayer::~QgsVectorLayer()
delete mConditionalStyles;
}
QgsVectorLayer *QgsVectorLayer::clone() const
{
QgsVectorLayer *layer = new QgsVectorLayer( source(), originalName(), mProviderKey );
QgsMapLayer::clone( layer );
QList<QgsVectorLayerJoinInfo> joins = vectorJoins();
Q_FOREACH ( const QgsVectorLayerJoinInfo &join, joins )
{
layer->addJoin( join );
}
layer->setProviderEncoding( dataProvider()->encoding() );
layer->setDisplayExpression( displayExpression() );
layer->setMapTipTemplate( mapTipTemplate() );
layer->setReadOnly( isReadOnly() );
layer->selectByIds( selectedFeatureIds() );
layer->setExcludeAttributesWms( excludeAttributesWms() );
layer->setExcludeAttributesWfs( excludeAttributesWfs() );
layer->setAttributeTableConfig( attributeTableConfig() );
layer->setFeatureBlendMode( featureBlendMode() );
layer->setLayerTransparency( layerTransparency() );
Q_FOREACH ( const QgsAction &action, actions()->actions() )
{
layer->actions()->addAction( action );
}
if ( renderer() )
{
layer->setRenderer( renderer()->clone() );
}
if ( labeling() )
{
layer->setLabeling( labeling()->clone() );
}
layer->setSimplifyMethod( simplifyMethod() );
if ( diagramRenderer() )
{
layer->setDiagramRenderer( diagramRenderer()->clone() );
}
if ( diagramLayerSettings() )
{
QgsDiagramLayerSettings *dls = new QgsDiagramLayerSettings( *diagramLayerSettings() );
layer->setDiagramLayerSettings( *dls );
}
for ( int i = 0; i < fields().count(); i++ )
{
layer->setFieldAlias( i, attributeAlias( i ) );
layer->setEditorWidgetSetup( i, editorWidgetSetup( i ) );
layer->setConstraintExpression( i, constraintExpression( i ), constraintDescription( i ) );
layer->setDefaultValueExpression( i, defaultValueExpression( i ) );
QMap< QgsFieldConstraints::Constraint, QgsFieldConstraints::ConstraintStrength> constraints = fieldConstraintsAndStrength( i );
for ( QgsFieldConstraints::Constraint c : constraints.keys() )
{
layer->setFieldConstraint( i, c, constraints.value( c ) );
}
if ( fields().fieldOrigin( i ) == QgsFields::OriginExpression )
{
layer->addExpressionField( expressionField( i ), fields().at( i ) );
}
}
layer->setEditFormConfig( editFormConfig() );
return layer;
}
QString QgsVectorLayer::storageType() const
{
if ( mDataProvider )
@ -4141,6 +4214,26 @@ QgsFieldConstraints::Constraints QgsVectorLayer::fieldConstraints( int fieldInde
return constraints;
}
QMap< QgsFieldConstraints::Constraint, QgsFieldConstraints::ConstraintStrength> QgsVectorLayer::fieldConstraintsAndStrength( int fieldIndex ) const
{
QMap< QgsFieldConstraints::Constraint, QgsFieldConstraints::ConstraintStrength > m;
if ( fieldIndex < 0 || fieldIndex >= mFields.count() )
return m;
QString name = mFields.at( fieldIndex ).name();
for ( QPair< QString, QgsFieldConstraints::Constraint > p : mFieldConstraintStrength.keys() )
{
if ( p.first == name )
{
m[ p.second ] = mFieldConstraintStrength.value( p );
}
}
return m;
}
void QgsVectorLayer::setFieldConstraint( int index, QgsFieldConstraints::Constraint constraint, QgsFieldConstraints::ConstraintStrength strength )
{
if ( index < 0 || index >= mFields.count() )

View File

@ -400,6 +400,15 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
//! QgsVectorLayer cannot be copied.
QgsVectorLayer &operator=( QgsVectorLayer const &rhs ) = delete;
/** Returns a new instance equivalent to this one. A new provider is
* created for the same data source and renderers for features and diagrams
* are cloned too. Moreover, each attributes (transparency, extent, selected
* features and so on) are identicals.
* \returns a new layer instance
* \since QGIS 3.0
*/
virtual QgsVectorLayer *clone() const override SIP_FACTORY;
//! Returns the permanent storage type for this layer as a friendly name.
QString storageType() const;
@ -529,6 +538,13 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
*/
QgsActionManager *actions() { return mActions; }
/**
* Get all layer actions defined on this layer.
*
* The pointer which is returned is const.
*/
const QgsActionManager *actions() const SIP_SKIP { return mActions; }
/**
* The number of features that are selected in this layer
*
@ -1331,6 +1347,13 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
*/
QgsFieldConstraints::Constraints fieldConstraints( int fieldIndex ) const;
/**
* Returns a map of constraint with their strength for a specific field of the layer.
* \param fieldIndex field index
* \since QGIS 3.0
*/
QMap< QgsFieldConstraints::Constraint, QgsFieldConstraints::ConstraintStrength> fieldConstraintsAndStrength( int fieldIndex ) const;
/**
* Sets a constraint for a specified field index. Any constraints inherited from the layer's
* data provider will be kept intact and cannot be modified. Ie, calling this method only allows for new

View File

@ -144,6 +144,21 @@ QgsRasterLayer::~QgsRasterLayer()
// Note: provider and other interfaces are owned and deleted by pipe
}
QgsRasterLayer *QgsRasterLayer::clone() const
{
QgsRasterLayer *layer = new QgsRasterLayer( source(), originalName(), mProviderKey );
QgsMapLayer::clone( layer );
// do not clone data provider which is the first element in pipe
for ( int i = 1; i < mPipe.size(); i++ )
{
if ( mPipe.at( i ) )
layer->pipe()->set( mPipe.at( i )->clone() );
}
return layer;
}
//////////////////////////////////////////////////////////
//
// Static Methods and members

View File

@ -188,6 +188,13 @@ class CORE_EXPORT QgsRasterLayer : public QgsMapLayer
~QgsRasterLayer();
/** Returns a new instance equivalent to this one. A new provider is
* created for the same data source and renderer is cloned too.
* \returns a new layer instance
* \since QGIS 3.0
*/
virtual QgsRasterLayer *clone() const override SIP_FACTORY;
//! \brief This enumerator describes the types of shading that can be used
enum ColorShadingAlgorithm
{

View File

@ -23,6 +23,7 @@ from qgis.PyQt.QtXml import QDomDocument
from qgis.core import (QgsRaster,
QgsRasterLayer,
QgsReadWriteContext,
QgsColorRampShader,
QgsContrastEnhancement,
QgsProject,
@ -655,6 +656,44 @@ class TestQgsRasterLayer(unittest.TestCase):
self.assertEqual(renderer.nColors(), 2)
self.assertEqual(renderer.usesBands(), [1])
def testClone(self):
myPath = os.path.join(unitTestDataPath('raster'),
'band1_float32_noct_epsg4326.tif')
myFileInfo = QFileInfo(myPath)
myBaseName = myFileInfo.baseName()
layer = QgsRasterLayer(myPath, myBaseName)
renderer = layer.renderer().clone()
renderer.setOpacity(33.3)
layer.setRenderer(renderer)
# clone layer
clone = layer.clone()
# generate xml from layer
layer_doc = QDomDocument("doc")
layer_elem = layer_doc.createElement("maplayer")
layer.writeLayerXml(layer_elem, layer_doc, QgsReadWriteContext())
# generate xml from clone
clone_doc = QDomDocument("doc")
clone_elem = clone_doc.createElement("maplayer")
clone.writeLayerXml(clone_elem, clone_doc, QgsReadWriteContext())
# replace id within xml of clone
clone_id_elem = clone_elem.firstChildElement("id")
clone_id_elem_patch = clone_doc.createElement("id")
clone_id_elem_patch_value = clone_doc.createTextNode(layer.id())
clone_id_elem_patch.appendChild(clone_id_elem_patch_value)
clone_elem.replaceChild(clone_id_elem_patch, clone_id_elem)
# update doc
clone_doc.appendChild(clone_elem)
layer_doc.appendChild(layer_elem)
# compare xml documents
self.assertEqual(layer_doc.toString(), clone_doc.toString())
if __name__ == '__main__':
unittest.main()

View File

@ -16,11 +16,13 @@ import qgis # NOQA
import os
from qgis.PyQt.QtCore import QVariant
from qgis.PyQt.QtCore import QVariant, Qt
from qgis.PyQt.QtGui import QPainter
from qgis.PyQt.QtXml import QDomDocument
from qgis.core import (QgsWkbTypes,
QgsAction,
QgsEditorWidgetSetup,
QgsVectorLayer,
QgsRectangle,
QgsFeature,
@ -41,7 +43,15 @@ from qgis.core import (QgsWkbTypes,
QgsPointV2,
QgsExpressionContext,
QgsExpressionContextScope,
QgsExpressionContextUtils)
QgsExpressionContextUtils,
QgsLineSymbol,
QgsMapLayerStyle,
QgsMapLayerDependency,
QgsPalLayerSettings,
QgsVectorLayerSimpleLabeling,
QgsSingleCategoryDiagramRenderer,
QgsDiagramLayerSettings,
QgsTextFormat)
from qgis.testing import start_app, unittest
from utilities import unitTestDataPath
start_app()
@ -2091,6 +2101,154 @@ class TestQgsVectorLayer(unittest.TestCase):
self.assertEqual(len(list(layer.getFeatures(req))), 2)
layer.rollBack()
def testClone(self):
# init crs
srs = QgsCoordinateReferenceSystem(3111, QgsCoordinateReferenceSystem.EpsgCrsId)
# init map layer styles
tmplayer = createLayerWithTwoPoints()
sym1 = QgsLineSymbol()
sym1.setColor(Qt.magenta)
tmplayer.setRenderer(QgsSingleSymbolRenderer(sym1))
style0 = QgsMapLayerStyle()
style0.readFromLayer(tmplayer)
style1 = QgsMapLayerStyle()
style1.readFromLayer(tmplayer)
# init dependencies layers
ldep = createLayerWithTwoPoints()
dep = QgsMapLayerDependency(ldep.id())
# init layer
layer = createLayerWithTwoPoints()
layer.setBlendMode(QPainter.CompositionMode_Screen)
layer.styleManager().addStyle('style0', style0)
layer.styleManager().addStyle('style1', style1)
layer.setName('MyName')
layer.setShortName('MyShortName')
layer.setMinimumScale(0.5)
layer.setMaximumScale(1.5)
layer.setScaleBasedVisibility(True)
layer.setTitle('MyTitle')
layer.setAbstract('MyAbstract')
layer.setKeywordList('MyKeywordList')
layer.setDataUrl('MyDataUrl')
layer.setDataUrlFormat('MyDataUrlFormat')
layer.setAttribution('MyAttribution')
layer.setAttributionUrl('MyAttributionUrl')
layer.setMetadataUrl('MyMetadataUrl')
layer.setMetadataUrlType('MyMetadataUrlType')
layer.setMetadataUrlFormat('MyMetadataUrlFormat')
layer.setLegendUrl('MyLegendUrl')
layer.setLegendUrlFormat('MyLegendUrlFormat')
layer.setDependencies([dep])
layer.setCrs(srs)
layer.setCustomProperty('MyKey0', 'MyValue0')
layer.setCustomProperty('MyKey1', 'MyValue1')
layer.setLayerTransparency(33)
layer.setProviderEncoding('latin9')
layer.setDisplayExpression('MyDisplayExpression')
layer.setMapTipTemplate('MyMapTipTemplate')
layer.setExcludeAttributesWfs(['MyExcludeAttributeWFS'])
layer.setExcludeAttributesWms(['MyExcludeAttributeWMS'])
layer.setFeatureBlendMode(QPainter.CompositionMode_Xor)
sym = QgsLineSymbol()
sym.setColor(Qt.magenta)
layer.setRenderer(QgsSingleSymbolRenderer(sym))
simplify = layer.simplifyMethod()
simplify.setTolerance(33.3)
simplify.setThreshold(0.333)
layer.setSimplifyMethod(simplify)
layer.setFieldAlias(0, 'MyAlias0')
layer.setFieldAlias(1, 'MyAlias1')
jl0 = createLayerWithTwoPoints()
j0 = QgsVectorLayerJoinInfo()
j0.setJoinLayer(jl0)
jl1 = createLayerWithTwoPoints()
j1 = QgsVectorLayerJoinInfo()
j1.setJoinLayer(jl1)
layer.addJoin(j0)
layer.addJoin(j1)
fids = layer.allFeatureIds()
selected_fids = fids[0:3]
layer.selectByIds(selected_fids)
cfg = layer.attributeTableConfig()
cfg.setSortOrder(Qt.DescendingOrder) # by default AscendingOrder
layer.setAttributeTableConfig(cfg)
pal = QgsPalLayerSettings()
text_format = QgsTextFormat()
text_format.setSize(33)
text_format.setColor(Qt.magenta)
pal.setFormat(text_format)
labeling = QgsVectorLayerSimpleLabeling(pal)
layer.setLabeling(labeling)
diag_renderer = QgsSingleCategoryDiagramRenderer()
diag_renderer.setAttributeLegend(False) # true by default
diag_renderer.setSizeLegend(True) # false by default
layer.setDiagramRenderer(diag_renderer)
diag_settings = QgsDiagramLayerSettings()
diag_settings.setPriority(3)
diag_settings.setZIndex(0.33)
layer.setDiagramLayerSettings(diag_settings)
edit_form_config = layer.editFormConfig()
edit_form_config.setUiForm("MyUiForm")
edit_form_config.setInitFilePath("MyInitFilePath")
layer.setEditFormConfig(edit_form_config)
widget_setup = QgsEditorWidgetSetup("MyWidgetSetupType", {})
layer.setEditorWidgetSetup(0, widget_setup)
layer.setConstraintExpression(0, "MyFieldConstraintExpression")
layer.setFieldConstraint(0, QgsFieldConstraints.ConstraintUnique, QgsFieldConstraints.ConstraintStrengthHard)
layer.setDefaultValueExpression(0, "MyDefaultValueExpression")
action = QgsAction(QgsAction.Unix, "MyActionDescription", "MyActionCmd")
layer.actions().addAction(action)
# clone layer
clone = layer.clone()
# generate xml from layer
layer_doc = QDomDocument("doc")
layer_elem = layer_doc.createElement("maplayer")
layer.writeLayerXml(layer_elem, layer_doc, QgsReadWriteContext())
# generate xml from clone
clone_doc = QDomDocument("doc")
clone_elem = clone_doc.createElement("maplayer")
clone.writeLayerXml(clone_elem, clone_doc, QgsReadWriteContext())
# replace id within xml of clone
clone_id_elem = clone_elem.firstChildElement("id")
clone_id_elem_patch = clone_doc.createElement("id")
clone_id_elem_patch_value = clone_doc.createTextNode(layer.id())
clone_id_elem_patch.appendChild(clone_id_elem_patch_value)
clone_elem.replaceChild(clone_id_elem_patch, clone_id_elem)
# update doc
clone_doc.appendChild(clone_elem)
layer_doc.appendChild(layer_elem)
# compare xml documents
self.assertEqual(layer_doc.toString(), clone_doc.toString())
# TODO:
# - fetch rect: feat with changed geometry: 1. in rect, 2. out of rect