Skip to content

Commit

Permalink
[FEATURE] add clone() methods for layers
Browse files Browse the repository at this point in the history
  • Loading branch information
pblottiere committed May 18, 2017
1 parent ffe5e1c commit 7b20c2e
Show file tree
Hide file tree
Showing 9 changed files with 177 additions and 0 deletions.
47 changes: 47 additions & 0 deletions src/core/qgsmaplayer.cpp
Expand Up @@ -94,6 +94,43 @@ QgsMapLayer::~QgsMapLayer()
delete mStyleManager;
}

void QgsMapLayer::clone( QgsMapLayer *layer, bool deep ) const
{
layer->setBlendMode( blendMode() );

QMap<QString, QgsMapLayerStyle> styles = styleManager()->mapLayerStyles();
for ( QString s : styles.keys() )
{
layer->styleManager()->addStyle( s, styles.value( s ) );
}

layer->setName( name() );
layer->setShortName( shortName() );
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 );

if ( deep )
{
layer->setId( id() );
}
}

QgsMapLayer::LayerType QgsMapLayer::type() const
{
return mLayerType;
Expand All @@ -104,6 +141,11 @@ QString QgsMapLayer::id() const
return mID;
}

void QgsMapLayer::setId( const QString &id )
{
mID = id;
}

void QgsMapLayer::setName( const QString &name )
{
QString newName = capitalizeLayerName( name );
Expand Down Expand Up @@ -1583,6 +1625,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 );
Expand Down
27 changes: 27 additions & 0 deletions src/core/qgsmaplayer.h
Expand Up @@ -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.
* \param deep If true, a deep copy is done
* \returns a new layer instance
* \since QGIS 3.0
*/
virtual QgsMapLayer *clone( bool deep ) const = 0;

/** Returns the type of the layer.
*/
QgsMapLayer::LayerType type() const;
Expand Down Expand Up @@ -444,6 +451,12 @@ class CORE_EXPORT QgsMapLayer : public QObject
*/
QVariant customProperty( const QString &value, const QVariant &defaultValue = QVariant() ) const;

/** Set custom properties for layer.
* \param properties The custom properties to set.
* \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()
*/
Expand Down Expand Up @@ -916,6 +929,15 @@ class CORE_EXPORT QgsMapLayer : public QObject
void metadataChanged();

protected:

/** Copies attributes like name, short name, ... into another layer. The
* unique ID is copied too if deep parameter is true.
* \param layer The copy recipient
* \param deep To copy the unique ID or not
* \since QGIS 3.0
*/
void clone( QgsMapLayer *layer, bool deep = false ) const;

//! Set the extent
virtual void setExtent( const QgsRectangle &rect );

Expand Down Expand Up @@ -1009,6 +1031,11 @@ class CORE_EXPORT QgsMapLayer : public QObject

private:

/** Set the unique id of the layer.
* /param id the new unique id of the layer
*/
void setId( const QString &id );

/**
* This method returns true by default but can be overwritten to specify
* that a certain layer is writable.
Expand Down
5 changes: 5 additions & 0 deletions src/core/qgsmaplayerstylemanager.cpp
Expand Up @@ -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 )
Expand Down
7 changes: 7 additions & 0 deletions src/core/qgsmaplayerstylemanager.h
Expand Up @@ -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;

Expand Down
7 changes: 7 additions & 0 deletions src/core/qgspluginlayer.h
Expand Up @@ -36,6 +36,13 @@ class CORE_EXPORT QgsPluginLayer : public QgsMapLayer
QgsPluginLayer( const QString &layerType, const QString &layerName = QString() );
~QgsPluginLayer();

/** Returns a new instance equivalent to this one.
* \param deep If true, a deep copy is done
* \returns a new layer instance
* \since QGIS 3.0
*/
virtual QgsPluginLayer *clone( bool deep ) const override = 0;

//! Return plugin layer type (the same as used in QgsPluginLayerRegistry)
QString pluginLayerType();

Expand Down
58 changes: 58 additions & 0 deletions src/core/qgsvectorlayer.cpp
Expand Up @@ -85,6 +85,7 @@
#include "qgsxmlutils.h"
#include "qgsunittypes.h"
#include "qgstaskmanager.h"
#include "qgsreadwritecontext.h"

#include "diagram/qgsdiagram.h"

Expand Down Expand Up @@ -201,6 +202,63 @@ QgsVectorLayer::~QgsVectorLayer()
delete mConditionalStyles;
}

QgsVectorLayer *QgsVectorLayer::clone( bool deep ) const
{
QgsVectorLayer *layer = new QgsVectorLayer( source(), originalName(), mProviderKey );
QgsMapLayer::clone( layer, deep );

QList<QgsVectorLayerJoinInfo> joins = vectorJoins();
Q_FOREACH ( 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->setExtent( extent() );
layer->setRenderer( renderer()->clone() );
layer->setAttributeTableConfig( attributeTableConfig() );
layer->setFeatureBlendMode( featureBlendMode() );
layer->setLayerTransparency( layerTransparency() );

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 ) );
}

for ( int i = 0; i < fields().count(); i++ )
{
if ( fields().fieldOrigin( i ) == QgsFields::OriginExpression )
{
layer->addExpressionField( expressionField( i ), fields().at( i ) );
}
}

return layer;
}

QString QgsVectorLayer::storageType() const
{
if ( mDataProvider )
Expand Down
10 changes: 10 additions & 0 deletions src/core/qgsvectorlayer.h
Expand Up @@ -400,6 +400,16 @@ 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.
* \param deep If true, a deep copy is done (unique ID is copied too)
* \returns a new layer instance
* \since QGIS 3.0
*/
virtual QgsVectorLayer *clone( bool deep = false ) const override SIP_FACTORY;

//! Returns the permanent storage type for this layer as a friendly name.
QString storageType() const;

Expand Down
8 changes: 8 additions & 0 deletions src/core/raster/qgsrasterlayer.cpp
Expand Up @@ -144,6 +144,14 @@ QgsRasterLayer::~QgsRasterLayer()
// Note: provider and other interfaces are owned and deleted by pipe
}

QgsRasterLayer *QgsRasterLayer::clone( bool deep ) const
{
QgsRasterLayer *layer = new QgsRasterLayer( source(), originalName(), mProviderKey );
QgsMapLayer::clone( layer, deep );
layer->setRenderer( renderer()->clone() );
return layer;
}

//////////////////////////////////////////////////////////
//
// Static Methods and members
Expand Down
8 changes: 8 additions & 0 deletions src/core/raster/qgsrasterlayer.h
Expand Up @@ -188,6 +188,14 @@ 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.
* \param deep If true, a deep copy is done (unique ID is copy too)
* \returns a new layer instance
* \since QGIS 3.0
*/
virtual QgsRasterLayer *clone( bool deep = false ) const override SIP_FACTORY;

//! \brief This enumerator describes the types of shading that can be used
enum ColorShadingAlgorithm
{
Expand Down

0 comments on commit 7b20c2e

Please sign in to comment.