Skip to content

Commit 0170580

Browse files
committedMar 9, 2017
Save QgsProperty related objects via QVariants
1 parent 1687019 commit 0170580

24 files changed

+483
-296
lines changed
 

‎python/core/qgsproperty.sip

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -128,10 +128,8 @@ class QgsProperty
128128
int valueAsInt( const QgsExpressionContext& context, int defaultValue = 0, bool* ok /Out/ = nullptr ) const;
129129

130130
bool valueAsBool( const QgsExpressionContext& context, bool defaultValue = false, bool* ok /Out/ = nullptr ) const;
131-
132-
virtual bool writeXml( QDomElement& propertyElem, QDomDocument& doc ) const;
133-
134-
virtual bool readXml( const QDomElement& propertyElem, const QDomDocument& doc );
131+
QVariant toVariant() const;
132+
bool loadVariant( const QVariant &property );
135133

136134
void setTransformer( QgsPropertyTransformer* transformer /Transfer/ );
137135

‎python/core/qgspropertycollection.sip

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,10 @@ class QgsAbstractPropertyCollection
5353

5454
virtual bool hasDynamicProperties() const = 0;
5555

56-
virtual bool writeXml( QDomElement& collectionElem, QDomDocument& doc, const QgsPropertiesDefinition& definitions ) const = 0;
57-
58-
virtual bool readXml( const QDomElement& collectionElem, const QDomDocument& doc, const QgsPropertiesDefinition &definitions ) = 0;
59-
56+
virtual bool writeXml( QDomElement& collectionElem, const QgsPropertiesDefinition& definitions ) const = 0;
57+
virtual bool readXml( const QDomElement& collectionElem, const QgsPropertiesDefinition &definitions ) = 0;
58+
virtual QVariant toVariant( const QgsPropertiesDefinition &definitions ) const = 0;
59+
virtual bool loadVariant( const QVariant &configuration, const QgsPropertiesDefinition &definitions ) = 0;
6060
};
6161

6262

@@ -88,9 +88,9 @@ class QgsPropertyCollection : QgsAbstractPropertyCollection
8888
bool isActive( int key ) const;
8989
bool hasActiveProperties() const;
9090
bool hasDynamicProperties() const;
91-
bool writeXml( QDomElement& collectionElem, QDomDocument& doc, const QgsPropertiesDefinition& definitions ) const;
92-
bool readXml( const QDomElement& collectionElem, const QDomDocument& doc, const QgsPropertiesDefinition& definitions );
9391

92+
QVariant toVariant( const QgsPropertiesDefinition &definitions ) const;
93+
bool loadVariant( const QVariant &configuration, const QgsPropertiesDefinition &definitions );
9494
void setProperty( int key, const QgsProperty& property );
9595

9696
void setProperty( int key, const QVariant& value );
@@ -137,7 +137,7 @@ class QgsPropertyCollectionStack : QgsAbstractPropertyCollection
137137

138138
QSet<int> propertyKeys() const;
139139
bool hasProperty( int key ) const;
140-
bool writeXml( QDomElement& collectionElem, QDomDocument& doc, const QgsPropertiesDefinition& definitions ) const;
141-
bool readXml( const QDomElement& collectionElem, const QDomDocument& doc, const QgsPropertiesDefinition &definitions );
140+
virtual QVariant toVariant( const QgsPropertiesDefinition &definitions ) const;
141+
virtual bool loadVariant( const QVariant &collection, const QgsPropertiesDefinition &definitions );
142142
};
143143

‎python/core/qgspropertytransformer.sip

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ class QgsCurveTransform
2929

3030
bool writeXml( QDomElement& transformElem, QDomDocument& doc ) const;
3131

32+
QVariant toVariant() const;
33+
34+
bool loadVariant( const QVariant &transformer );
3235
};
3336
class QgsPropertyTransformer
3437
{
@@ -67,10 +70,9 @@ class QgsPropertyTransformer
6770
virtual Type transformerType() const = 0;
6871

6972
virtual QgsPropertyTransformer* clone() = 0 /Factory/;
73+
virtual bool loadVariant(const QVariant &transformer );
7074

71-
virtual bool readXml( const QDomElement& transformerElem, const QDomDocument& doc );
72-
73-
virtual bool writeXml( QDomElement& transformerElem, QDomDocument& doc ) const;
75+
virtual QVariant toVariant() const;
7476

7577
double minValue() const;
7678

@@ -111,8 +113,8 @@ class QgsGenericNumericTransformer : QgsPropertyTransformer
111113

112114
virtual Type transformerType() const;
113115
virtual QgsGenericNumericTransformer* clone() /Factory/;
114-
virtual bool writeXml( QDomElement& transformerElem, QDomDocument& doc ) const;
115-
virtual bool readXml( const QDomElement& transformerElem, const QDomDocument& doc );
116+
virtual QVariant toVariant() const;
117+
virtual bool loadVariant( const QVariant &definition );
116118
virtual QVariant transform( const QgsExpressionContext& context, const QVariant& value ) const;
117119
virtual QString toExpression( const QString& baseExpression ) const;
118120
static QgsGenericNumericTransformer* fromExpression( const QString& expression, QString& baseExpression, QString& fieldName ) /Factory/;
@@ -155,8 +157,8 @@ class QgsSizeScaleTransformer : QgsPropertyTransformer
155157

156158
virtual Type transformerType() const;
157159
virtual QgsSizeScaleTransformer* clone() /Factory/;
158-
virtual bool writeXml( QDomElement& transformerElem, QDomDocument& doc ) const;
159-
virtual bool readXml( const QDomElement& transformerElem, const QDomDocument& doc );
160+
virtual QVariant toVariant() const;
161+
virtual bool loadVariant( const QVariant &definition );
160162
virtual QVariant transform( const QgsExpressionContext& context, const QVariant& value ) const;
161163
virtual QString toExpression( const QString& baseExpression ) const;
162164

@@ -206,8 +208,8 @@ class QgsColorRampTransformer : QgsPropertyTransformer
206208

207209
virtual Type transformerType() const;
208210
virtual QgsColorRampTransformer* clone() /Factory/;
209-
virtual bool writeXml( QDomElement& transformerElem, QDomDocument& doc ) const;
210-
virtual bool readXml( const QDomElement& transformerElem, const QDomDocument& doc );
211+
virtual QVariant toVariant() const;
212+
virtual bool loadVariant( const QVariant &definition );
211213
virtual QVariant transform( const QgsExpressionContext& context, const QVariant& value ) const;
212214
virtual QString toExpression( const QString& baseExpression ) const;
213215

‎python/core/symbology-ng/qgssymbollayerutils.sip

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,8 @@ class QgsSymbolLayerUtils
284284

285285
static QgsColorRamp* loadColorRamp( QDomElement& element ) /Factory/;
286286
static QDomElement saveColorRamp( const QString& name, QgsColorRamp* ramp, QDomDocument& doc );
287+
static QVariant colorRampToVariant( const QString &name, QgsColorRamp *ramp );
288+
static QgsColorRamp *loadColorRamp( const QVariant &value );
287289

288290
/**
289291
* Returns a friendly display name for a color

‎python/gui/editorwidgets/core/qgseditorconfigwidget.sip

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -21,29 +21,16 @@ class QgsEditorConfigWidget : QWidget
2121

2222
public:
2323
explicit QgsEditorConfigWidget( QgsVectorLayer* vl, int fieldIdx, QWidget* parent /TransferThis/ );
24-
25-
/**
26-
* Returns the field for which this configuration widget applies
27-
*
28-
* @return The field index
29-
*/
30-
int field();
31-
32-
/**
33-
* Returns the layer for which this configuration widget applies
34-
*
35-
* @return The layer
36-
*/
37-
QgsVectorLayer* layer();
38-
3924
virtual QVariantMap config() = 0;
4025
virtual void setConfig( const QVariantMap& config ) = 0;
26+
int field();
27+
QgsVectorLayer* layer();
28+
QgsExpressionContext createExpressionContext() const;
4129

4230
signals:
43-
44-
/** Emitted when the configuration of the widget is changed.
45-
* @note added in QGIS 3.0
46-
*/
4731
void changed();
32+
33+
protected:
34+
void initializeDataDefinedButton( QgsPropertyOverrideButton *button, QgsWidgetWrapper::Property key );
4835
};
4936

‎python/gui/editorwidgets/core/qgswidgetwrapper.sip

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ class QgsWidgetWrapper : QObject
4747
%End
4848

4949
public:
50+
enum Property
51+
{
52+
RootPath = 0,
53+
};
54+
static const QgsPropertiesDefinition &propertyDefinitions();
5055
/**
5156
* Create a new widget wrapper
5257
*
@@ -131,6 +136,8 @@ class QgsWidgetWrapper : QObject
131136
*/
132137
virtual bool valid() const = 0;
133138

139+
const QgsPropertyCollection &dataDefinedProperties() const;
140+
void setDataDefinedProperties( const QgsPropertyCollection &collection );
134141
protected:
135142
/**
136143
* This method should create a new widget with the provided parent. This will only be called

‎src/core/composer/qgscomposerobject.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ bool QgsComposerObject::writeXml( QDomElement &elem, QDomDocument &doc ) const
117117
}
118118

119119
QDomElement ddPropsElement = doc.createElement( QStringLiteral( "dataDefinedProperties" ) );
120-
mDataDefinedProperties.writeXml( ddPropsElement, doc, sPropertyDefinitions );
120+
mDataDefinedProperties.writeXml( ddPropsElement, sPropertyDefinitions );
121121
elem.appendChild( ddPropsElement );
122122

123123
//custom properties
@@ -140,7 +140,7 @@ bool QgsComposerObject::readXml( const QDomElement &itemElem, const QDomDocument
140140
QDomNode propsNode = itemElem.namedItem( QStringLiteral( "dataDefinedProperties" ) );
141141
if ( !propsNode.isNull() )
142142
{
143-
mDataDefinedProperties.readXml( propsNode.toElement(), doc, sPropertyDefinitions );
143+
mDataDefinedProperties.readXml( propsNode.toElement(), sPropertyDefinitions );
144144
}
145145

146146
//custom properties

‎src/core/composer/qgscomposition.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -903,7 +903,7 @@ bool QgsComposition::writeXml( QDomElement &composerElem, QDomDocument &doc )
903903

904904
//data defined properties
905905
QDomElement ddPropsElement = doc.createElement( QStringLiteral( "dataDefinedProperties" ) );
906-
mDataDefinedProperties.writeXml( ddPropsElement, doc, QgsComposerObject::propertyDefinitions() );
906+
mDataDefinedProperties.writeXml( ddPropsElement, QgsComposerObject::propertyDefinitions() );
907907
compositionElem.appendChild( ddPropsElement );
908908

909909
composerElem.appendChild( compositionElem );
@@ -990,7 +990,7 @@ bool QgsComposition::readXml( const QDomElement &compositionElem, const QDomDocu
990990
QDomNode propsNode = compositionElem.namedItem( QStringLiteral( "dataDefinedProperties" ) );
991991
if ( !propsNode.isNull() )
992992
{
993-
mDataDefinedProperties.readXml( propsNode.toElement(), doc, QgsComposerObject::propertyDefinitions() );
993+
mDataDefinedProperties.readXml( propsNode.toElement(), QgsComposerObject::propertyDefinitions() );
994994
}
995995

996996
//custom properties

‎src/core/qgsdiagramrenderer.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ void QgsDiagramLayerSettings::readXml( const QDomElement &elem, const QgsVectorL
111111
QDomNodeList propertyElems = elem.elementsByTagName( "properties" );
112112
if ( !propertyElems.isEmpty() )
113113
{
114-
( void )mDataDefinedProperties.readXml( propertyElems.at( 0 ).toElement(), elem.ownerDocument(), sPropertyDefinitions );
114+
( void )mDataDefinedProperties.readXml( propertyElems.at( 0 ).toElement(), sPropertyDefinitions );
115115
}
116116
else
117117
{
@@ -154,7 +154,7 @@ void QgsDiagramLayerSettings::writeXml( QDomElement &layerElem, QDomDocument &do
154154

155155
QDomElement diagramLayerElem = doc.createElement( QStringLiteral( "DiagramLayerSettings" ) );
156156
QDomElement propertiesElem = doc.createElement( "properties" );
157-
( void )mDataDefinedProperties.writeXml( propertiesElem, doc, sPropertyDefinitions );
157+
( void )mDataDefinedProperties.writeXml( propertiesElem, sPropertyDefinitions );
158158
diagramLayerElem.appendChild( propertiesElem );
159159
diagramLayerElem.setAttribute( QStringLiteral( "placement" ), mPlacement );
160160
diagramLayerElem.setAttribute( QStringLiteral( "linePlacementFlags" ), mPlacementFlags );

‎src/core/qgspallabeling.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -669,7 +669,7 @@ void QgsPalLayerSettings::readFromLayer( QgsVectorLayer *layer )
669669
QDomDocument doc( QStringLiteral( "dd" ) );
670670
doc.setContent( layer->customProperty( QStringLiteral( "labeling/ddProperties" ) ).toString() );
671671
QDomElement elem = doc.firstChildElement( QStringLiteral( "properties" ) );
672-
mDataDefinedProperties.readXml( elem, doc, sPropertyDefinitions );
672+
mDataDefinedProperties.readXml( elem, sPropertyDefinitions );
673673
}
674674
else
675675
{
@@ -760,7 +760,7 @@ void QgsPalLayerSettings::writeToLayer( QgsVectorLayer *layer )
760760

761761
doc = QDomDocument( QStringLiteral( "dd" ) );
762762
QDomElement ddElem = doc.createElement( QStringLiteral( "properties" ) );
763-
mDataDefinedProperties.writeXml( ddElem, doc, sPropertyDefinitions );
763+
mDataDefinedProperties.writeXml( ddElem, sPropertyDefinitions );
764764
QString ddProps;
765765
QTextStream streamProps( &ddProps );
766766
ddElem.save( streamProps, -1 );
@@ -876,7 +876,7 @@ void QgsPalLayerSettings::readXml( QDomElement &elem )
876876
QDomElement ddElem = elem.firstChildElement( QStringLiteral( "dd_properties" ) );
877877
if ( !ddElem.isNull() )
878878
{
879-
mDataDefinedProperties.readXml( ddElem, ddElem.ownerDocument(), sPropertyDefinitions );
879+
mDataDefinedProperties.readXml( ddElem, sPropertyDefinitions );
880880
}
881881
else
882882
{
@@ -965,7 +965,7 @@ QDomElement QgsPalLayerSettings::writeXml( QDomDocument &doc )
965965
renderingElem.setAttribute( QStringLiteral( "zIndex" ), zIndex );
966966

967967
QDomElement ddElem = doc.createElement( QStringLiteral( "dd_properties" ) );
968-
mDataDefinedProperties.writeXml( ddElem, doc, sPropertyDefinitions );
968+
mDataDefinedProperties.writeXml( ddElem, sPropertyDefinitions );
969969

970970
QDomElement elem = doc.createElement( QStringLiteral( "settings" ) );
971971
elem.appendChild( textStyleElem );

‎src/core/qgsproperty.cpp

Lines changed: 34 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -636,24 +636,26 @@ bool QgsProperty::valueAsBool( const QgsExpressionContext &context, bool default
636636
return val.toBool();
637637
}
638638

639-
bool QgsProperty::writeXml( QDomElement &propertyElem, QDomDocument &doc ) const
639+
QVariant QgsProperty::toVariant() const
640640
{
641-
propertyElem.setAttribute( "active", d->active ? "1" : "0" );
642-
propertyElem.setAttribute( "type", d->type );
641+
QVariantMap propertyMap;
642+
643+
propertyMap.insert( QStringLiteral( "active" ), d->active );
644+
propertyMap.insert( QStringLiteral( "type" ), d->type );
643645

644646
switch ( d->type )
645647
{
646648
case StaticProperty:
647-
propertyElem.setAttribute( "valType", d->staticValue.typeName() );
648-
propertyElem.setAttribute( "val", d->staticValue.toString() );
649+
// propertyMap.insert( QStringLiteral( "valType" ), d->staticValue.typeName() );
650+
propertyMap.insert( QStringLiteral( "val" ), d->staticValue.toString() );
649651
break;
650652

651653
case FieldBasedProperty:
652-
propertyElem.setAttribute( "field", d->fieldName );
654+
propertyMap.insert( QStringLiteral( "field" ), d->fieldName );
653655
break;
654656

655657
case ExpressionBasedProperty:
656-
propertyElem.setAttribute( "expression", d->expressionString );
658+
propertyMap.insert( QStringLiteral( "expression" ), d->expressionString );
657659
break;
658660

659661
case InvalidProperty:
@@ -662,36 +664,39 @@ bool QgsProperty::writeXml( QDomElement &propertyElem, QDomDocument &doc ) const
662664

663665
if ( d->transformer )
664666
{
665-
QDomElement transformerElem = doc.createElement( "transformer" );
666-
transformerElem.setAttribute( "t", static_cast< int >( d->transformer->transformerType() ) );
667-
if ( d->transformer->writeXml( transformerElem, doc ) )
668-
propertyElem.appendChild( transformerElem );
667+
QVariantMap transformer;
668+
transformer.insert( QStringLiteral( "t" ), d->transformer->transformerType() );
669+
transformer.insert( QStringLiteral( "d" ), d->transformer->toVariant() );
670+
671+
propertyMap.insert( QStringLiteral( "transformer" ), transformer );
669672
}
670673

671-
return true;
674+
return propertyMap;
672675
}
673676

674-
bool QgsProperty::readXml( const QDomElement &propertyElem, const QDomDocument &doc )
677+
bool QgsProperty::loadVariant( const QVariant &property )
675678
{
679+
QVariantMap propertyMap = property.toMap();
680+
676681
d.detach();
677-
d->active = static_cast< bool >( propertyElem.attribute( "active", "1" ).toInt() );
678-
d->type = static_cast< Type >( propertyElem.attribute( "type", "0" ).toInt() );
682+
d->active = propertyMap.value( QStringLiteral( "active" ) ).toBool();
683+
d->type = static_cast< Type >( propertyMap.value( QStringLiteral( "type" ), InvalidProperty ).toInt() );
679684

680685
switch ( d->type )
681686
{
682687
case StaticProperty:
683-
d->staticValue = QVariant( propertyElem.attribute( "val", "" ) );
684-
d->staticValue.convert( QVariant::nameToType( propertyElem.attribute( "valType", "QString" ).toLocal8Bit().constData() ) );
688+
d->staticValue = propertyMap.value( QStringLiteral( "val" ) );
689+
// d->staticValue.convert( QVariant::nameToType( propertyElem.attribute( "valType", "QString" ).toLocal8Bit().constData() ) );
685690
break;
686691

687692
case FieldBasedProperty:
688-
d->fieldName = propertyElem.attribute( "field" );
693+
d->fieldName = propertyMap.value( QStringLiteral( "field" ) ).toString();
689694
if ( d->fieldName.isEmpty() )
690695
d->active = false;
691696
break;
692697

693698
case ExpressionBasedProperty:
694-
d->expressionString = propertyElem.attribute( "expression" );
699+
d->expressionString = propertyMap.value( QStringLiteral( "expression" ) ).toString();
695700
if ( d->expressionString.isEmpty() )
696701
d->active = false;
697702

@@ -709,15 +714,20 @@ bool QgsProperty::readXml( const QDomElement &propertyElem, const QDomDocument &
709714
if ( d->transformer )
710715
delete d->transformer;
711716
d->transformer = nullptr;
712-
QDomNodeList transformerNodeList = propertyElem.elementsByTagName( "transformer" );
713-
if ( !transformerNodeList.isEmpty() )
717+
718+
719+
QVariant transform = propertyMap.value( QStringLiteral( "transformer" ) );
720+
721+
if ( transform.isValid() )
714722
{
715-
QDomElement transformerElem = transformerNodeList.at( 0 ).toElement();
716-
QgsPropertyTransformer::Type type = static_cast< QgsPropertyTransformer::Type >( transformerElem.attribute( "t", "0" ).toInt() );
723+
QVariantMap transformerMap = transform.toMap();
724+
725+
QgsPropertyTransformer::Type type = static_cast< QgsPropertyTransformer::Type >( transformerMap.value( QStringLiteral( "t" ), QgsPropertyTransformer::GenericNumericTransformer ).toInt() );
717726
std::unique_ptr< QgsPropertyTransformer > transformer( QgsPropertyTransformer::create( type ) );
727+
718728
if ( transformer )
719729
{
720-
if ( transformer->readXml( transformerElem, doc ) )
730+
if ( transformer->loadVariant( transformerMap.value( QStringLiteral( "d" ) ) ) )
721731
d->transformer = transformer.release();
722732
}
723733
}

‎src/core/qgsproperty.h

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -396,20 +396,20 @@ class CORE_EXPORT QgsProperty
396396
bool valueAsBool( const QgsExpressionContext &context, bool defaultValue = false, bool *ok = nullptr ) const;
397397

398398
/**
399-
* Writes the current state of the property into an XML element
400-
* @param propertyElem destination element for the property's state
401-
* @param doc DOM document
402-
* @see readXml()
403-
*/
404-
bool writeXml( QDomElement &propertyElem, QDomDocument &doc ) const;
405-
406-
/**
407-
* Reads property state from an XML element.
408-
* @param propertyElem source DOM element for property's state
409-
* @param doc DOM document
410-
* @see writeXml()
411-
*/
412-
bool readXml( const QDomElement &propertyElem, const QDomDocument &doc );
399+
* Saves this property to a QVariantMap, wrapped in a QVariant.
400+
* You can use QgsXmlUtils::writeVariant to save it to an XML document.
401+
*
402+
* @see loadVariant()
403+
*/
404+
QVariant toVariant() const;
405+
406+
/**
407+
* Loads this property from a QVariantMap, wrapped in a QVariant.
408+
* You can use QgsXmlUtils::readVariant to load it from an XML document.
409+
*
410+
* @see toVariant()
411+
*/
412+
bool loadVariant( const QVariant &property );
413413

414414
/**
415415
* Sets an optional transformer to use for manipulating the calculated values for the property.

‎src/core/qgspropertycollection.cpp

Lines changed: 58 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
#include "qgspropertycollection.h"
1717
#include "qgsproperty.h"
18+
#include "qgsxmlutils.h"
1819

1920
//
2021
// QgsAbstractPropertyCollection
@@ -83,6 +84,21 @@ bool QgsAbstractPropertyCollection::valueAsBool( int key, const QgsExpressionCon
8384
return prop.valueAsBool( context, defaultValue, ok );
8485
}
8586

87+
bool QgsAbstractPropertyCollection::writeXml( QDomElement &collectionElem, const QgsPropertiesDefinition &definitions ) const
88+
{
89+
QVariant collection = toVariant( definitions );
90+
QDomDocument doc = collectionElem.ownerDocument();
91+
QDomElement element = QgsXmlUtils::writeVariant( collection, doc );
92+
collectionElem.appendChild( element );
93+
return true;
94+
}
95+
96+
bool QgsAbstractPropertyCollection::readXml( const QDomElement &collectionElem, const QgsPropertiesDefinition &definitions )
97+
{
98+
QVariant collection = QgsXmlUtils::readVariant( collectionElem.firstChild().toElement() );
99+
return loadVariant( collection.toMap(), definitions );
100+
}
101+
86102

87103

88104
//
@@ -276,47 +292,45 @@ bool QgsPropertyCollection::hasDynamicProperties() const
276292
return mHasDynamicProperties;
277293
}
278294

279-
bool QgsPropertyCollection::writeXml( QDomElement &collectionElem, QDomDocument &doc, const QgsPropertiesDefinition &definitions ) const
295+
QVariant QgsPropertyCollection::toVariant( const QgsPropertiesDefinition &definitions ) const
280296
{
281-
collectionElem.setAttribute( "name", name() );
282-
collectionElem.setAttribute( "type", "collection" );
297+
QVariantMap collection;
298+
299+
collection.insert( QStringLiteral( "name" ), name() );
300+
collection.insert( QStringLiteral( "type" ), QStringLiteral( "collection" ) );
301+
302+
QVariantMap properties;
303+
283304
QHash<int, QgsProperty>::const_iterator it = mProperties.constBegin();
284305
for ( ; it != mProperties.constEnd(); ++it )
285306
{
286307
if ( it.value() )
287308
{
288-
QDomElement propertyElement = doc.createElement( "p" );
289-
int key = it.key();
290-
QString propName = definitions.value( key ).name();
291-
propertyElement.setAttribute( "n", propName );
292-
it.value().writeXml( propertyElement, doc );
293-
collectionElem.appendChild( propertyElement );
309+
properties.insert( definitions.value( it.key() ).name(), it.value().toVariant() );
294310
}
295311
}
296-
return true;
312+
collection.insert( QStringLiteral( "properties" ), properties );
313+
return collection;
297314
}
298315

299-
bool QgsPropertyCollection::readXml( const QDomElement &collectionElem, const QDomDocument &doc, const QgsPropertiesDefinition &definitions )
316+
bool QgsPropertyCollection::loadVariant( const QVariant &collection, const QgsPropertiesDefinition &definitions )
300317
{
301318
clear();
302319

303-
setName( collectionElem.attribute( "name" ) );
320+
QVariantMap collectionMap = collection.toMap();
321+
322+
setName( collectionMap.value( QStringLiteral( "name" ) ).toString() );
304323

305324
mCount = 0;
306-
QDomNodeList propertyNodeList = collectionElem.elementsByTagName( "p" );
307-
for ( int i = 0; i < propertyNodeList.size(); ++i )
325+
QVariantMap properties = collectionMap.value( QStringLiteral( "properties" ) ).toMap();
326+
for ( auto propertyIterator = properties.constBegin(); propertyIterator != properties.constEnd(); ++propertyIterator )
308327
{
309-
QDomElement propertyElem = propertyNodeList.at( i ).toElement();
310-
QString propName = propertyElem.attribute( "n" );
311-
if ( propName.isEmpty() )
312-
continue;
313-
314328
// match name to int key
315329
int key = -1;
316330
QgsPropertiesDefinition::const_iterator it = definitions.constBegin();
317331
for ( ; it != definitions.constEnd(); ++it )
318332
{
319-
if ( it->name() == propName )
333+
if ( it->name() == propertyIterator.key() )
320334
{
321335
key = it.key();
322336
break;
@@ -327,10 +341,11 @@ bool QgsPropertyCollection::readXml( const QDomElement &collectionElem, const QD
327341
continue;
328342

329343
QgsProperty prop;
330-
prop.readXml( propertyElem, doc );
344+
prop.loadVariant( propertyIterator.value() );
331345
mProperties.insert( key, prop );
332346

333347
mCount++;
348+
334349
mHasActiveProperties = mHasActiveProperties || prop.isActive();
335350
mHasDynamicProperties = mHasDynamicProperties ||
336351
( prop.isActive() &&
@@ -504,34 +519,40 @@ bool QgsPropertyCollectionStack::hasProperty( int key ) const
504519
return false;
505520
}
506521

507-
bool QgsPropertyCollectionStack::writeXml( QDomElement &collectionElem, QDomDocument &doc, const QgsPropertiesDefinition &definitions ) const
522+
QVariant QgsPropertyCollectionStack::toVariant( const QgsPropertiesDefinition &definitions ) const
508523
{
509-
collectionElem.setAttribute( "type", "stack" );
510-
collectionElem.setAttribute( "name", name() );
524+
QVariantMap collection;
525+
collection.insert( QStringLiteral( "type" ), QStringLiteral( "stack" ) );
526+
collection.insert( QStringLiteral( "name" ), name() );
527+
528+
QVariantList properties;
511529

512530
Q_FOREACH ( QgsPropertyCollection *child, mStack )
513531
{
514-
QDomElement childElement = doc.createElement( "props" );
515-
if ( !child->writeXml( childElement, doc, definitions ) )
516-
return false;
517-
collectionElem.appendChild( childElement );
532+
properties.append( child->toVariant( definitions ) );
518533
}
519-
return true;
534+
535+
collection.insert( QStringLiteral( "properties" ), properties );
536+
537+
return collection;
520538
}
521539

522-
bool QgsPropertyCollectionStack::readXml( const QDomElement &collectionElem, const QDomDocument &doc, const QgsPropertiesDefinition &definitions )
540+
bool QgsPropertyCollectionStack::loadVariant( const QVariant &collection, const QgsPropertiesDefinition &definitions )
523541
{
524542
clear();
525543

526-
setName( collectionElem.attribute( "name" ) );
544+
QVariantMap collectionMap = collection.toMap();
545+
546+
setName( collectionMap.value( QStringLiteral( "name" ) ).toString() );
527547

528-
QDomNodeList childNodeList = collectionElem.elementsByTagName( "props" );
529-
for ( int i = 0; i < childNodeList.size(); ++i )
548+
QVariantList properties = collectionMap.value( QStringLiteral( "properties" ) ).toList();
549+
550+
Q_FOREACH ( const QVariant &property, properties )
530551
{
531-
QDomElement childElem = childNodeList.at( i ).toElement();
532-
QgsPropertyCollection *child = new QgsPropertyCollection();
533-
child->readXml( childElem, doc, definitions );
534-
mStack.append( child );
552+
QgsPropertyCollection *propertyCollection = new QgsPropertyCollection();
553+
propertyCollection->loadVariant( property.toMap(), definitions );
554+
mStack.append( propertyCollection );
535555
}
556+
536557
return true;
537558
}

‎src/core/qgspropertycollection.h

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -219,20 +219,34 @@ class CORE_EXPORT QgsAbstractPropertyCollection
219219
/**
220220
* Writes the current state of the property collection into an XML element
221221
* @param collectionElem destination element for the property collection's state
222-
* @param doc DOM document
223222
* @param definitions property definitions
224223
* @see readXml()
225224
*/
226-
virtual bool writeXml( QDomElement &collectionElem, QDomDocument &doc, const QgsPropertiesDefinition &definitions ) const = 0;
225+
virtual bool writeXml( QDomElement &collectionElem, const QgsPropertiesDefinition &definitions ) const;
227226

228227
/**
229228
* Reads property collection state from an XML element.
230229
* @param collectionElem source DOM element for property collection's state
231-
* @param doc DOM document
232230
* @param definitions property definitions
233231
* @see writeXml()
234232
*/
235-
virtual bool readXml( const QDomElement &collectionElem, const QDomDocument &doc, const QgsPropertiesDefinition &definitions ) = 0;
233+
virtual bool readXml( const QDomElement &collectionElem, const QgsPropertiesDefinition &definitions );
234+
235+
/**
236+
* Saves this property collection to a QVariantMap, wrapped in a QVariant.
237+
* You can use QgsXmlUtils::writeVariant to save it to an XML document.
238+
*
239+
* @see loadVariant()
240+
*/
241+
virtual QVariant toVariant( const QgsPropertiesDefinition &definitions ) const = 0;
242+
243+
/**
244+
* Loads this property collection from a QVariantMap, wrapped in a QVariant.
245+
* You can use QgsXmlUtils::readVariant to save it to an XML document.
246+
*
247+
* @see toVariant()
248+
*/
249+
virtual bool loadVariant( const QVariant &configuration, const QgsPropertiesDefinition &definitions ) = 0;
236250

237251
private:
238252

@@ -292,8 +306,9 @@ class CORE_EXPORT QgsPropertyCollection : public QgsAbstractPropertyCollection
292306
bool isActive( int key ) const override;
293307
bool hasActiveProperties() const override;
294308
bool hasDynamicProperties() const override;
295-
bool writeXml( QDomElement &collectionElem, QDomDocument &doc, const QgsPropertiesDefinition &definitions ) const override;
296-
bool readXml( const QDomElement &collectionElem, const QDomDocument &doc, const QgsPropertiesDefinition &definitions ) override;
309+
310+
QVariant toVariant( const QgsPropertiesDefinition &definitions ) const override;
311+
bool loadVariant( const QVariant &configuration, const QgsPropertiesDefinition &definitions ) override;
297312

298313
/**
299314
* Adds a property to the collection and takes ownership of it.
@@ -439,8 +454,10 @@ class CORE_EXPORT QgsPropertyCollectionStack : public QgsAbstractPropertyCollect
439454

440455
QSet<int> propertyKeys() const override;
441456
bool hasProperty( int key ) const override;
442-
bool writeXml( QDomElement &collectionElem, QDomDocument &doc, const QgsPropertiesDefinition &definitions ) const override;
443-
bool readXml( const QDomElement &collectionElem, const QDomDocument &doc, const QgsPropertiesDefinition &definitions ) override;
457+
458+
virtual QVariant toVariant( const QgsPropertiesDefinition &definitions ) const override;
459+
460+
virtual bool loadVariant( const QVariant &collection, const QgsPropertiesDefinition &definitions ) override;
444461

445462
private:
446463

‎src/core/qgspropertytransformer.cpp

Lines changed: 119 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -64,21 +64,39 @@ QgsPropertyTransformer &QgsPropertyTransformer::operator=( const QgsPropertyTran
6464
return *this;
6565
}
6666

67-
bool QgsPropertyTransformer::writeXml( QDomElement &transformerElem, QDomDocument &doc ) const
67+
bool QgsPropertyTransformer::loadVariant( const QVariant &transformer )
6868
{
69-
Q_UNUSED( doc );
70-
transformerElem.setAttribute( "minValue", QString::number( mMinValue ) );
71-
transformerElem.setAttribute( "maxValue", QString::number( mMaxValue ) );
69+
QVariantMap transformerMap = transformer.toMap();
7270

73-
if ( mCurveTransform )
71+
mMinValue = transformerMap.value( QStringLiteral( "minValue" ), 0.0 ).toDouble();
72+
mMaxValue = transformerMap.value( QStringLiteral( "maxValue" ), 1.0 ).toDouble();
73+
mCurveTransform.reset( nullptr );
74+
75+
QVariantMap curve = transformerMap.value( "curve" ).toMap();
76+
77+
if ( !curve.isEmpty() )
7478
{
75-
QDomElement curveElement = doc.createElement( "curve" );
76-
mCurveTransform->writeXml( curveElement, doc );
77-
transformerElem.appendChild( curveElement );
79+
mCurveTransform.reset( new QgsCurveTransform() );
80+
mCurveTransform->loadVariant( curve );
7881
}
82+
7983
return true;
8084
}
8185

86+
QVariant QgsPropertyTransformer::toVariant() const
87+
{
88+
QVariantMap transformerMap;
89+
90+
transformerMap.insert( QStringLiteral( "minValue" ), mMinValue );
91+
transformerMap.insert( QStringLiteral( "maxValue" ), mMaxValue );
92+
93+
if ( mCurveTransform )
94+
{
95+
transformerMap.insert( QStringLiteral( "curve" ), mCurveTransform->toVariant() );
96+
}
97+
return transformerMap;
98+
}
99+
82100
QgsPropertyTransformer *QgsPropertyTransformer::fromExpression( const QString &expression, QString &baseExpression, QString &fieldName )
83101
{
84102
baseExpression.clear();
@@ -104,23 +122,6 @@ double QgsPropertyTransformer::transformNumeric( double input ) const
104122
return mMinValue + ( mMaxValue - mMinValue ) * mCurveTransform->y( scaledInput );
105123
}
106124

107-
bool QgsPropertyTransformer::readXml( const QDomElement &transformerElem, const QDomDocument &doc )
108-
{
109-
Q_UNUSED( doc );
110-
mMinValue = transformerElem.attribute( "minValue", "0.0" ).toDouble();
111-
mMaxValue = transformerElem.attribute( "maxValue", "1.0" ).toDouble();
112-
mCurveTransform.reset( nullptr );
113-
114-
QDomNodeList curveNodeList = transformerElem.elementsByTagName( "curve" );
115-
if ( !curveNodeList.isEmpty() )
116-
{
117-
QDomElement curveElem = curveNodeList.at( 0 ).toElement();
118-
mCurveTransform.reset( new QgsCurveTransform() );
119-
mCurveTransform->readXml( curveElem, doc );
120-
}
121-
122-
return true;
123-
}
124125

125126
//
126127
// QgsGenericNumericTransformer
@@ -165,28 +166,28 @@ QgsGenericNumericTransformer *QgsGenericNumericTransformer::clone()
165166
return t.release();
166167
}
167168

168-
bool QgsGenericNumericTransformer::writeXml( QDomElement &transformerElem, QDomDocument &doc ) const
169+
QVariant QgsGenericNumericTransformer::toVariant() const
169170
{
170-
if ( !QgsPropertyTransformer::writeXml( transformerElem, doc ) )
171-
return false;
171+
QVariantMap transformerMap = QgsPropertyTransformer::toVariant().toMap();
172172

173-
transformerElem.setAttribute( "minOutput", QString::number( mMinOutput ) );
174-
transformerElem.setAttribute( "maxOutput", QString::number( mMaxOutput ) );
175-
transformerElem.setAttribute( "nullOutput", QString::number( mNullOutput ) );
176-
transformerElem.setAttribute( "exponent", QString::number( mExponent ) );
173+
transformerMap.insert( QStringLiteral( "minOutput" ), mMinOutput );
174+
transformerMap.insert( QStringLiteral( "maxOutput" ), mMaxOutput );
175+
transformerMap.insert( QStringLiteral( "nullOutput" ), mNullOutput );
176+
transformerMap.insert( QStringLiteral( "exponent" ), mExponent );
177177

178-
return true;
178+
return transformerMap;
179179
}
180180

181-
bool QgsGenericNumericTransformer::readXml( const QDomElement &transformerElem, const QDomDocument &doc )
181+
bool QgsGenericNumericTransformer::loadVariant( const QVariant &transformer )
182182
{
183-
if ( !QgsPropertyTransformer::readXml( transformerElem, doc ) )
184-
return false;
183+
QgsPropertyTransformer::loadVariant( transformer );
185184

186-
mMinOutput = transformerElem.attribute( "minOutput", "0.0" ).toDouble();
187-
mMaxOutput = transformerElem.attribute( "maxOutput", "1.0" ).toDouble();
188-
mNullOutput = transformerElem.attribute( "nullOutput", "0.0" ).toDouble();
189-
mExponent = transformerElem.attribute( "exponent", "1.0" ).toDouble();
185+
QVariantMap transformerMap = transformer.toMap();
186+
187+
mMinOutput = transformerMap.value( QStringLiteral( "minOutput" ), 0.0 ).toDouble();
188+
mMaxOutput = transformerMap.value( QStringLiteral( "maxOutput" ), 1.0 ).toDouble();
189+
mNullOutput = transformerMap.value( QStringLiteral( "nullOutput" ), 0.0 ).toDouble();
190+
mExponent = transformerMap.value( QStringLiteral( "exponent" ), 1.0 ).toDouble();
190191
return true;
191192
}
192193

@@ -358,30 +359,31 @@ QgsSizeScaleTransformer *QgsSizeScaleTransformer::clone()
358359
return t.release();
359360
}
360361

361-
bool QgsSizeScaleTransformer::writeXml( QDomElement &transformerElem, QDomDocument &doc ) const
362+
QVariant QgsSizeScaleTransformer::toVariant() const
362363
{
363-
if ( !QgsPropertyTransformer::writeXml( transformerElem, doc ) )
364-
return false;
364+
QVariantMap transformerMap = QgsPropertyTransformer::toVariant().toMap();
365365

366-
transformerElem.setAttribute( "scaleType", QString::number( static_cast< int >( mType ) ) );
367-
transformerElem.setAttribute( "minSize", QString::number( mMinSize ) );
368-
transformerElem.setAttribute( "maxSize", QString::number( mMaxSize ) );
369-
transformerElem.setAttribute( "nullSize", QString::number( mNullSize ) );
370-
transformerElem.setAttribute( "exponent", QString::number( mExponent ) );
366+
transformerMap.insert( QStringLiteral( "scaleType" ), static_cast< int >( mType ) );
367+
transformerMap.insert( QStringLiteral( "minSize" ), mMinSize );
368+
transformerMap.insert( QStringLiteral( "maxSize" ), mMaxSize );
369+
transformerMap.insert( QStringLiteral( "nullSize" ), mNullSize );
370+
transformerMap.insert( QStringLiteral( "exponent" ), mExponent );
371371

372-
return true;
372+
return transformerMap;
373373
}
374374

375-
bool QgsSizeScaleTransformer::readXml( const QDomElement &transformerElem, const QDomDocument &doc )
375+
bool QgsSizeScaleTransformer::loadVariant( const QVariant &transformer )
376376
{
377-
if ( !QgsPropertyTransformer::readXml( transformerElem, doc ) )
378-
return false;
377+
QgsPropertyTransformer::loadVariant( transformer );
378+
379+
QVariantMap transformerMap = transformer.toMap();
380+
381+
mType = static_cast< ScaleType >( transformerMap.value( "scaleType", Linear ).toInt() );
382+
mMinSize = transformerMap.value( "minSize", 0.0 ).toDouble();
383+
mMaxSize = transformerMap.value( "maxSize", 1.0 ).toDouble();
384+
mNullSize = transformerMap.value( "nullSize", 0.0 ).toDouble();
385+
mExponent = transformerMap.value( "exponent", 1.0 ).toDouble();
379386

380-
mType = static_cast< ScaleType >( transformerElem.attribute( "scaleType", "0" ).toInt() );
381-
mMinSize = transformerElem.attribute( "minSize", "0.0" ).toDouble();
382-
mMaxSize = transformerElem.attribute( "maxSize", "1.0" ).toDouble();
383-
mNullSize = transformerElem.attribute( "nullSize", "0.0" ).toDouble();
384-
mExponent = transformerElem.attribute( "exponent", "1.0" ).toDouble();
385387
return true;
386388
}
387389

@@ -595,36 +597,34 @@ QgsColorRampTransformer *QgsColorRampTransformer::clone()
595597
return c.release();
596598
}
597599

598-
bool QgsColorRampTransformer::writeXml( QDomElement &transformerElem, QDomDocument &doc ) const
600+
QVariant QgsColorRampTransformer::toVariant() const
599601
{
600-
if ( !QgsPropertyTransformer::writeXml( transformerElem, doc ) )
601-
return false;
602+
QVariantMap transformerMap = QgsPropertyTransformer::toVariant().toMap();
602603

603604
if ( mGradientRamp )
604605
{
605-
QDomElement colorRampElem = QgsSymbolLayerUtils::saveColorRamp( "[source]", mGradientRamp.get(), doc );
606-
transformerElem.appendChild( colorRampElem );
606+
transformerMap.insert( QStringLiteral( "colorramp" ), QgsSymbolLayerUtils::colorRampToVariant( QStringLiteral( "[source]" ), mGradientRamp.get() ) );
607607
}
608-
transformerElem.setAttribute( "nullColor", QgsSymbolLayerUtils::encodeColor( mNullColor ) );
609-
transformerElem.setAttribute( "rampName", mRampName );
608+
transformerMap.insert( QStringLiteral( "nullColor" ), QgsSymbolLayerUtils::encodeColor( mNullColor ) );
609+
transformerMap.insert( QStringLiteral( "rampName" ), mRampName );
610610

611-
return true;
611+
return transformerMap;
612612
}
613613

614-
bool QgsColorRampTransformer::readXml( const QDomElement &transformerElem, const QDomDocument &doc )
614+
bool QgsColorRampTransformer::loadVariant( const QVariant &definition )
615615
{
616-
if ( !QgsPropertyTransformer::readXml( transformerElem, doc ) )
617-
return false;
616+
QVariantMap transformerMap = definition.toMap();
617+
618+
QgsPropertyTransformer::loadVariant( definition );
618619

619620
mGradientRamp.reset( nullptr );
620-
QDomElement sourceColorRampElem = transformerElem.firstChildElement( "colorramp" );
621-
if ( !sourceColorRampElem.isNull() && sourceColorRampElem.attribute( "name" ) == "[source]" )
621+
if ( transformerMap.contains( QStringLiteral( "colorramp" ) ) )
622622
{
623-
setColorRamp( QgsSymbolLayerUtils::loadColorRamp( sourceColorRampElem ) );
623+
setColorRamp( QgsSymbolLayerUtils::loadColorRamp( transformerMap.value( QStringLiteral( "colorramp" ) ).toMap() ) );
624624
}
625625

626-
mNullColor = QgsSymbolLayerUtils::decodeColor( transformerElem.attribute( "nullColor", "0,0,0,0" ) );
627-
mRampName = transformerElem.attribute( "rampName", QString() );
626+
mNullColor = QgsSymbolLayerUtils::decodeColor( transformerMap.value( QStringLiteral( "nullColor" ), QStringLiteral( "0,0,0,0" ) ).toString() );
627+
mRampName = transformerMap.value( QStringLiteral( "rampName" ) ).toString();
628628
return true;
629629
}
630630

@@ -945,6 +945,52 @@ bool QgsCurveTransform::writeXml( QDomElement &transformElem, QDomDocument & ) c
945945
return true;
946946
}
947947

948+
QVariant QgsCurveTransform::toVariant() const
949+
{
950+
QVariantMap transformMap;
951+
952+
QStringList x;
953+
QStringList y;
954+
Q_FOREACH ( const QgsPoint &p, mControlPoints )
955+
{
956+
x << qgsDoubleToString( p.x() );
957+
y << qgsDoubleToString( p.y() );
958+
}
959+
960+
transformMap.insert( QStringLiteral( "x" ), x.join( ',' ) );
961+
transformMap.insert( QStringLiteral( "y" ), y.join( ',' ) );
962+
963+
return transformMap;
964+
}
965+
966+
bool QgsCurveTransform::loadVariant( const QVariant &transformer )
967+
{
968+
QVariantMap transformMap = transformer.toMap();
969+
970+
QString xString = transformMap.value( QStringLiteral( "x" ) ).toString();
971+
QString yString = transformMap.value( QStringLiteral( "y" ) ).toString();
972+
973+
QStringList xVals = xString.split( ',' );
974+
QStringList yVals = yString.split( ',' );
975+
if ( xVals.count() != yVals.count() )
976+
return false;
977+
978+
QList< QgsPoint > newPoints;
979+
bool ok = false;
980+
for ( int i = 0; i < xVals.count(); ++i )
981+
{
982+
double x = xVals.at( i ).toDouble( &ok );
983+
if ( !ok )
984+
return false;
985+
double y = yVals.at( i ).toDouble( &ok );
986+
if ( !ok )
987+
return false;
988+
newPoints << QgsPoint( x, y );
989+
}
990+
setControlPoints( newPoints );
991+
return true;
992+
}
993+
948994
// this code is adapted from https://github.com/OpenFibers/Photoshop-Curves
949995
// which in turn was adapted from
950996
// http://www.developpez.net/forums/d331608-3/autres-langages/algorithmes/contribuez/image-interpolation-spline-cubique/#post3513925 //#spellok

‎src/core/qgspropertytransformer.h

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,22 @@ class CORE_EXPORT QgsCurveTransform
134134
*/
135135
bool writeXml( QDomElement &transformElem, QDomDocument &doc ) const;
136136

137+
/**
138+
* Saves this curve transformer to a QVariantMap, wrapped in a QVariant.
139+
* You can use QgsXmlUtils::writeVariant to save it to an XML document.
140+
*
141+
* @see loadVariant()
142+
*/
143+
QVariant toVariant() const;
144+
145+
/**
146+
* Load this curve transformer from a QVariantMap, wrapped in a QVariant.
147+
* You can use QgsXmlUtils::writeVariant to load it from an XML document.
148+
*
149+
* @see toVariant()
150+
*/
151+
bool loadVariant( const QVariant &transformer );
152+
137153
private:
138154

139155
void calcSecondDerivativeArray();
@@ -196,20 +212,20 @@ class CORE_EXPORT QgsPropertyTransformer
196212
virtual QgsPropertyTransformer *clone() = 0;
197213

198214
/**
199-
* Reads transformer's state from an XML element.
200-
* @param transformerElem source DOM element for transformer's state
201-
* @param doc DOM document
202-
* @see writeXml()
203-
*/
204-
virtual bool readXml( const QDomElement &transformerElem, const QDomDocument &doc );
215+
* Loads this transformer from a QVariantMap, wrapped in a QVariant.
216+
* You can use QgsXmlUtils::writeVariant to save it to an XML document.
217+
*
218+
* @see loadVariant()
219+
*/
220+
virtual bool loadVariant( const QVariant &transformer );
205221

206222
/**
207-
* Writes the current state of the transformer into an XML element
208-
* @param transformerElem destination element for the transformer's state
209-
* @param doc DOM document
210-
* @see readXml()
211-
*/
212-
virtual bool writeXml( QDomElement &transformerElem, QDomDocument &doc ) const;
223+
* Saves this transformer to a QVariantMap, wrapped in a QVariant.
224+
* You can use QgsXmlUtils::writeVariant to save it to an XML document.
225+
*
226+
* @see toVariant()
227+
*/
228+
virtual QVariant toVariant() const;
213229

214230
/**
215231
* Returns the minimum value expected by the transformer.
@@ -338,8 +354,8 @@ class CORE_EXPORT QgsGenericNumericTransformer : public QgsPropertyTransformer
338354

339355
virtual Type transformerType() const override { return GenericNumericTransformer; }
340356
virtual QgsGenericNumericTransformer *clone() override;
341-
virtual bool writeXml( QDomElement &transformerElem, QDomDocument &doc ) const override;
342-
virtual bool readXml( const QDomElement &transformerElem, const QDomDocument &doc ) override;
357+
virtual QVariant toVariant() const override;
358+
virtual bool loadVariant( const QVariant &definition ) override;
343359
virtual QVariant transform( const QgsExpressionContext &context, const QVariant &value ) const override;
344360
virtual QString toExpression( const QString &baseExpression ) const override;
345361

@@ -474,8 +490,8 @@ class CORE_EXPORT QgsSizeScaleTransformer : public QgsPropertyTransformer
474490

475491
virtual Type transformerType() const override { return SizeScaleTransformer; }
476492
virtual QgsSizeScaleTransformer *clone() override;
477-
virtual bool writeXml( QDomElement &transformerElem, QDomDocument &doc ) const override;
478-
virtual bool readXml( const QDomElement &transformerElem, const QDomDocument &doc ) override;
493+
virtual QVariant toVariant() const override;
494+
virtual bool loadVariant( const QVariant &definition ) override;
479495
virtual QVariant transform( const QgsExpressionContext &context, const QVariant &value ) const override;
480496
virtual QString toExpression( const QString &baseExpression ) const override;
481497

@@ -611,8 +627,8 @@ class CORE_EXPORT QgsColorRampTransformer : public QgsPropertyTransformer
611627

612628
virtual Type transformerType() const override { return ColorRampTransformer; }
613629
virtual QgsColorRampTransformer *clone() override;
614-
virtual bool writeXml( QDomElement &transformerElem, QDomDocument &doc ) const override;
615-
virtual bool readXml( const QDomElement &transformerElem, const QDomDocument &doc ) override;
630+
virtual QVariant toVariant() const override;
631+
virtual bool loadVariant( const QVariant &definition ) override;
616632
virtual QVariant transform( const QgsExpressionContext &context, const QVariant &value ) const override;
617633
virtual QString toExpression( const QString &baseExpression ) const override;
618634

‎src/core/qgsxmlutils.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,19 @@ QDomElement QgsXmlUtils::writeVariant( const QVariant &value, QDomDocument &doc
119119
break;
120120
}
121121

122+
case QVariant::List:
123+
{
124+
QVariantList list = value.toList();
125+
126+
Q_FOREACH ( const QVariant &value, list )
127+
{
128+
QDomElement valueElement = writeVariant( value, doc );
129+
element.appendChild( valueElement );
130+
element.setAttribute( QStringLiteral( "type" ), QStringLiteral( "List" ) );
131+
}
132+
break;
133+
}
134+
122135
case QVariant::Int:
123136
case QVariant::Bool:
124137
case QVariant::Double:
@@ -169,6 +182,18 @@ QVariant QgsXmlUtils::readVariant( const QDomElement &element )
169182
}
170183
return map;
171184
}
185+
else if ( type == QLatin1String( "List" ) )
186+
{
187+
QVariantList list;
188+
QDomNodeList values = element.childNodes();
189+
for ( int i = 0; i < values.count(); ++i )
190+
{
191+
QDomElement elem = values.at( i ).toElement();
192+
if ( elem.tagName() == QLatin1String( "e" ) )
193+
list.append( readVariant( elem ) );
194+
}
195+
return list;
196+
}
172197
else
173198
{
174199
return QVariant();

‎src/core/symbology-ng/qgssymbollayerutils.cpp

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -906,7 +906,7 @@ QgsSymbolLayer *QgsSymbolLayerUtils::loadSymbolLayer( QDomElement &element )
906906
QDomElement ddProps = element.firstChildElement( QStringLiteral( "data_defined_properties" ) );
907907
if ( !ddProps.isNull() )
908908
{
909-
layer->dataDefinedProperties().readXml( ddProps, element.ownerDocument(), QgsSymbolLayer::propertyDefinitions() );
909+
layer->dataDefinedProperties().readXml( ddProps, QgsSymbolLayer::propertyDefinitions() );
910910
}
911911

912912
return layer;
@@ -957,7 +957,7 @@ QDomElement QgsSymbolLayerUtils::saveSymbol( const QString &name, QgsSymbol *sym
957957
layer->paintEffect()->saveProperties( doc, layerEl );
958958

959959
QDomElement ddProps = doc.createElement( QStringLiteral( "data_defined_properties" ) );
960-
layer->dataDefinedProperties().writeXml( ddProps, doc, QgsSymbolLayer::propertyDefinitions() );
960+
layer->dataDefinedProperties().writeXml( ddProps, QgsSymbolLayer::propertyDefinitions() );
961961
layerEl.appendChild( ddProps );
962962

963963
if ( layer->subSymbol() )
@@ -2810,6 +2810,57 @@ QDomElement QgsSymbolLayerUtils::saveColorRamp( const QString &name, QgsColorRam
28102810
return rampEl;
28112811
}
28122812

2813+
QVariant QgsSymbolLayerUtils::colorRampToVariant( const QString &name, QgsColorRamp *ramp )
2814+
{
2815+
QVariantMap rampMap;
2816+
2817+
rampMap.insert( QStringLiteral( "type" ), ramp->type() );
2818+
rampMap.insert( QStringLiteral( "name" ), name );
2819+
2820+
QgsStringMap properties = ramp->properties();
2821+
2822+
QVariantMap propertyMap;
2823+
for ( auto property = properties.constBegin(); property != properties.constEnd(); ++property )
2824+
{
2825+
propertyMap.insert( property.key(), property.value() );
2826+
}
2827+
2828+
rampMap.insert( QStringLiteral( "properties" ), propertyMap );
2829+
return rampMap;
2830+
}
2831+
2832+
QgsColorRamp *QgsSymbolLayerUtils::loadColorRamp( const QVariant &value )
2833+
{
2834+
QVariantMap rampMap = value.toMap();
2835+
2836+
QString rampType = rampMap.value( QStringLiteral( "type" ) ).toString();
2837+
2838+
// parse properties
2839+
QVariantMap propertyMap = rampMap.value( QStringLiteral( "properties" ) ).toMap();
2840+
QgsStringMap props;
2841+
2842+
for ( auto property = propertyMap.constBegin(); property != propertyMap.constEnd(); ++property )
2843+
{
2844+
props.insert( property.key(), property.value().toString() );
2845+
}
2846+
2847+
if ( rampType == QLatin1String( "gradient" ) )
2848+
return QgsGradientColorRamp::create( props );
2849+
else if ( rampType == QLatin1String( "random" ) )
2850+
return QgsLimitedRandomColorRamp::create( props );
2851+
else if ( rampType == QLatin1String( "colorbrewer" ) )
2852+
return QgsColorBrewerColorRamp::create( props );
2853+
else if ( rampType == QLatin1String( "cpt-city" ) )
2854+
return QgsCptCityColorRamp::create( props );
2855+
else if ( rampType == QLatin1String( "preset" ) )
2856+
return QgsPresetSchemeColorRamp::create( props );
2857+
else
2858+
{
2859+
QgsDebugMsg( "unknown colorramp type " + rampType );
2860+
return nullptr;
2861+
}
2862+
}
2863+
28132864
QString QgsSymbolLayerUtils::colorToName( const QColor &color )
28142865
{
28152866
if ( !color.isValid() )

‎src/core/symbology-ng/qgssymbollayerutils.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,22 @@ class CORE_EXPORT QgsSymbolLayerUtils
364364
*/
365365
static QDomElement saveColorRamp( const QString &name, QgsColorRamp *ramp, QDomDocument &doc );
366366

367+
/**
368+
* Saves a color ramp to a QVariantMap, wrapped in a QVariant.
369+
* You can use QgsXmlUtils::writeVariant to save it to an XML document.
370+
*
371+
* @see loadColorRamp( const QVariant &value )
372+
*/
373+
static QVariant colorRampToVariant( const QString &name, QgsColorRamp *ramp );
374+
375+
/**
376+
* Load a color ramp from a QVariantMap, wrapped in a QVariant.
377+
* You can use QgsXmlUtils::readVariant to load it from an XML document.
378+
*
379+
* @see colorRampToVariant()
380+
*/
381+
static QgsColorRamp *loadColorRamp( const QVariant &value );
382+
367383
/**
368384
* Returns a friendly display name for a color
369385
* @param color source color

‎src/gui/editorwidgets/core/qgswidgetwrapper.cpp

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,18 @@
1919
#include <QWidget>
2020

2121

22-
QgsPropertiesDefinition QgsWidgetWrapper::sPropertyDefinitions;
23-
2422
const QgsPropertiesDefinition &QgsWidgetWrapper::propertyDefinitions()
2523
{
26-
QgsWidgetWrapper::initPropertyDefinitions();
27-
return sPropertyDefinitions;
24+
static QgsPropertiesDefinition properties;
25+
26+
if ( properties.isEmpty() )
27+
{
28+
properties =
29+
{
30+
{ RootPath, QgsPropertyDefinition( "propertyRootPath", QgsPropertyDefinition::DataTypeString, QObject::tr( "Root path" ), QString() ) }
31+
};
32+
}
33+
return properties;
2834
}
2935

3036
QgsWidgetWrapper::QgsWidgetWrapper( QgsVectorLayer *vl, QWidget *editor, QWidget *parent )
@@ -99,14 +105,3 @@ void QgsWidgetWrapper::setEnabled( bool enabled )
99105
{
100106
Q_UNUSED( enabled );
101107
}
102-
103-
void QgsWidgetWrapper::initPropertyDefinitions()
104-
{
105-
if ( !sPropertyDefinitions.isEmpty() )
106-
return;
107-
108-
sPropertyDefinitions = QgsPropertiesDefinition
109-
{
110-
{ RootPath, QgsPropertyDefinition( "propertyRootPath", QgsPropertyDefinition::DataTypeString, QObject::tr( "Root path" ), QString() ) }
111-
};
112-
}

‎src/gui/editorwidgets/core/qgswidgetwrapper.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -218,11 +218,6 @@ class GUI_EXPORT QgsWidgetWrapper : public QObject
218218
QWidget *mParent = nullptr;
219219
QgsVectorLayer *mLayer = nullptr;
220220
bool mInitialized;
221-
222-
//! Property definitions
223-
static QgsPropertiesDefinition sPropertyDefinitions;
224-
225-
static void initPropertyDefinitions();
226221
};
227222

228223
// We'll use this class inside a QVariant in the widgets properties

‎src/gui/editorwidgets/qgsexternalresourceconfigdlg.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ void QgsExternalResourceConfigDlg::chooseDefaultPath()
100100
void QgsExternalResourceConfigDlg::rootPathPropertyChanged()
101101
{
102102
QgsProperty prop = mRootPathPropertyOverrideButton->toProperty();
103+
mPropertyCollection.setProperty( QgsWidgetWrapper::RootPath, prop );
103104
setRootPathExpression( prop );
104105

105106
mRootPathExpression->setVisible( prop.isActive() );
@@ -146,15 +147,13 @@ QVariantMap QgsExternalResourceConfigDlg::config()
146147
cfg.insert( QStringLiteral( "FullUrl" ), mFullUrl->isChecked() );
147148
}
148149

149-
if ( mRootPathPropertyOverrideButton->isActive() )
150-
cfg.insert( QStringLiteral( "DefaultRootStyle" ), QStringLiteral( "expression" ) );
151-
else
152-
cfg.insert( QStringLiteral( "DefaultRootStyle" ), QStringLiteral( "path" ) );
153-
150+
cfg.insert( QStringLiteral( "PropertyCollection" ), mPropertyCollection.toVariant( QgsWidgetWrapper::propertyDefinitions() ) );
154151

155152
if ( !mRootPath->text().isEmpty() )
156153
cfg.insert( QStringLiteral( "DefaultRoot" ), mRootPath->text() );
157154

155+
cfg.insert( QStringLiteral( "RootPathProperty" ), mRootPathPropertyOverrideButton->toProperty().toVariant() );
156+
158157
// Save Storage Mode
159158
cfg.insert( QStringLiteral( "StorageMode" ), mStorageButtonGroup->checkedId() );
160159

@@ -205,6 +204,8 @@ void QgsExternalResourceConfigDlg::setConfig( const QVariantMap &config )
205204
mFullUrl->setChecked( true );
206205
}
207206

207+
mPropertyCollection.loadVariant( config.value( QStringLiteral( "PropertyCollection" ) ), QgsWidgetWrapper::propertyDefinitions() );
208+
setRootPathExpression( mPropertyCollection.property( QgsWidgetWrapper::RootPath ) );
208209
mRootPath->setText( config.value( QStringLiteral( "DefaultRoot" ) ).toString() );
209210

210211
rootPathPropertyChanged();
@@ -254,6 +255,7 @@ void QgsExternalResourceConfigDlg::setConfig( const QVariantMap &config )
254255

255256
void QgsExternalResourceConfigDlg::setRootPathExpression( const QgsProperty &property )
256257
{
258+
mRootPathPropertyOverrideButton->setToProperty( property );
257259
mRootPathExpression->setToolTip( property.asExpression() );
258260

259261
QgsExpressionContext ctx = layer()->createExpressionContext();

‎src/gui/editorwidgets/qgsexternalresourcewidgetwrapper.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@ void QgsExternalResourceWidgetWrapper::setFeature( const QgsFeature &feature )
8787
QString path = mPropertyCollection.valueAsString( QgsEditorWidgetWrapper::RootPath, expressionContext, QString(), &ok );
8888
if ( ok )
8989
{
90-
qWarning() << "Default root << " << path;
9190
mQgsWidget->setDefaultRoot( path );
9291
}
9392
}
@@ -132,7 +131,7 @@ void QgsExternalResourceWidgetWrapper::initWidget( QWidget *editor )
132131
mQgsWidget->fileWidget()->setFullUrl( cfg.value( QStringLiteral( "FullUrl" ) ).toBool() );
133132
}
134133

135-
qWarning() << "Default root style " << cfg.value( QStringLiteral( "DefaultRootStyle" ) );
134+
mPropertyCollection.loadVariant( cfg.value( "PropertyCollection" ), propertyDefinitions() );
136135
if ( !mPropertyCollection.isActive( QgsWidgetWrapper::RootPath ) )
137136
{
138137
mQgsWidget->setDefaultRoot( cfg.value( QStringLiteral( "DefaultRoot" ) ).toString() );

‎tests/src/core/testqgsproperty.cpp

Lines changed: 41 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -297,36 +297,35 @@ void TestQgsProperty::staticProperty()
297297
p1.setStaticValue( "test" );
298298
p1.setTransformer( new TestTransformer( 10, 20 ) );
299299

300-
QDomElement element = doc.createElement( "prop" );
301-
p1.writeXml( element, doc );
300+
QVariant element = p1.toVariant();
302301

303302
QgsProperty r1;
304-
r1.readXml( element, doc );
303+
r1.loadVariant( element );
305304
QVERIFY( r1.isActive() );
306305
QVERIFY( r1.transformer() );
307306
QCOMPARE( r1.staticValue(), QVariant( "test" ) );
308307

309308
p1.setActive( false );
310-
p1.writeXml( element, doc );
311-
r1.readXml( element, doc );
309+
element = p1.toVariant();
310+
r1.loadVariant( element );
312311
QVERIFY( !r1.isActive() );
313312

314313
//saving/restoring different types
315314
p1.setStaticValue( QVariant( 5 ) ); //int
316-
p1.writeXml( element, doc );
317-
r1.readXml( element, doc );
315+
element = p1.toVariant();
316+
r1.loadVariant( element );
318317
QCOMPARE( r1.staticValue(), p1.staticValue() );
319318
p1.setStaticValue( QVariant( 5.7 ) ); //double
320-
p1.writeXml( element, doc );
321-
r1.readXml( element, doc );
319+
element = p1.toVariant();
320+
r1.loadVariant( element );
322321
QCOMPARE( r1.staticValue(), p1.staticValue() );
323322
p1.setStaticValue( QVariant( true ) ); //bool
324-
p1.writeXml( element, doc );
325-
r1.readXml( element, doc );
323+
element = p1.toVariant();
324+
r1.loadVariant( element );
326325
QCOMPARE( r1.staticValue(), p1.staticValue() );
327326
p1.setStaticValue( QVariant( 5LL ) ); //longlong
328-
p1.writeXml( element, doc );
329-
r1.readXml( element, doc );
327+
element = p1.toVariant();
328+
r1.loadVariant( element );
330329
QCOMPARE( r1.staticValue(), p1.staticValue() );
331330

332331
// test copying a static property
@@ -413,22 +412,22 @@ void TestQgsProperty::fieldBasedProperty()
413412
p1.setActive( true );
414413
p1.setField( "test_field" );
415414

416-
QDomElement element = doc.createElement( "prop" );
415+
QVariant element;
417416
QgsProperty r1;
418417
//try reading from an empty element
419-
r1.readXml( element, doc );
418+
r1.loadVariant( element );
420419
QVERIFY( !r1.isActive() );
421420
QVERIFY( r1.field().isEmpty() );
422421

423422
// now populate element and re-read
424-
p1.writeXml( element, doc );
425-
r1.readXml( element, doc );
423+
element = p1.toVariant();
424+
r1.loadVariant( element );
426425
QVERIFY( r1.isActive() );
427426
QCOMPARE( r1.field(), QStringLiteral( "test_field" ) );
428427

429428
p1.setActive( false );
430-
p1.writeXml( element, doc );
431-
r1.readXml( element, doc );
429+
element = p1.toVariant();
430+
r1.loadVariant( element );
432431
QVERIFY( !r1.isActive() );
433432

434433
// test copying a field based property
@@ -520,24 +519,24 @@ void TestQgsProperty::expressionBasedProperty()
520519
p1.setActive( true );
521520
p1.setExpressionString( "4+5" );
522521

523-
QDomElement element = doc.createElement( "prop" );
522+
QVariant element;
524523
QgsProperty r1;
525524
//try reading from an empty element
526-
r1.readXml( element, doc );
525+
r1.loadVariant( element );
527526
QVERIFY( !r1.isActive() );
528527
QVERIFY( r1.expressionString().isEmpty() );
529528
QCOMPARE( r1.value( context, -1 ).toInt(), -1 );
530529

531530
// now populate element and re-read
532-
p1.writeXml( element, doc );
533-
r1.readXml( element, doc );
531+
element = p1.toVariant();
532+
r1.loadVariant( element );
534533
QVERIFY( r1.isActive() );
535534
QCOMPARE( r1.expressionString(), QStringLiteral( "4+5" ) );
536535
QCOMPARE( r1.value( context, -1 ).toInt(), 9 );
537536

538537
p1.setActive( false );
539-
p1.writeXml( element, doc );
540-
r1.readXml( element, doc );
538+
element = p1.toVariant();
539+
r1.loadVariant( element );
541540
QVERIFY( !r1.isActive() );
542541
QCOMPARE( r1.value( context, -1 ).toInt(), -1 );
543542

@@ -627,10 +626,10 @@ void TestQgsProperty::propertyTransformer()
627626
QDomDocument doc( documentType );
628627

629628
TestTransformer t1( -5, 6 );
630-
QDomElement element = doc.createElement( "transform" );
629+
QVariant element;
631630
TestTransformer r1( -99, -98 );
632-
QVERIFY( t1.writeXml( element, doc ) );
633-
QVERIFY( r1.readXml( element, doc ) );
631+
element = t1.toVariant();
632+
QVERIFY( r1.loadVariant( element ) );
634633
QCOMPARE( r1.minValue(), -5.0 );
635634
QCOMPARE( r1.maxValue(), 6.0 );
636635

@@ -646,11 +645,11 @@ void TestQgsProperty::propertyTransformer()
646645
QCOMPARE( p1.value( context, -99 ).toDouble(), 22.0 );
647646

648647
//test that transform is saved/restored with property
649-
QDomElement propElement = doc.createElement( "property" );
648+
QVariant propElement;
650649
QgsProperty p2;
651650
QVERIFY( !p2.transformer() );
652-
QVERIFY( p1.writeXml( propElement, doc ) );
653-
QVERIFY( p2.readXml( propElement, doc ) );
651+
propElement = p1.toVariant();
652+
p2.loadVariant( propElement );
654653
QVERIFY( p2.transformer() );
655654
QCOMPARE( p2.transformer()->minValue(), 10.0 );
656655
QCOMPARE( p2.transformer()->maxValue(), 20.0 );
@@ -755,10 +754,10 @@ void TestQgsProperty::genericNumericTransformer()
755754
99 );
756755
t2.setCurveTransform( new QgsCurveTransform( QList< QgsPoint >() << QgsPoint( 0, 0.8 ) << QgsPoint( 1, 0.2 ) ) );
757756

758-
QDomElement element = doc.createElement( "xform" );
759-
QVERIFY( t2.writeXml( element, doc ) );
757+
QVariant element;
758+
element = t2.toVariant();
760759
QgsGenericNumericTransformer r1;
761-
QVERIFY( r1.readXml( element, doc ) );
760+
QVERIFY( r1.loadVariant( element ) );
762761
QCOMPARE( r1.minValue(), 15.0 );
763762
QCOMPARE( r1.maxValue(), 25.0 );
764763
QCOMPARE( r1.minOutputValue(), 150.0 );
@@ -949,10 +948,10 @@ void TestQgsProperty::sizeScaleTransformer()
949948
99 );
950949
t1.setCurveTransform( new QgsCurveTransform( QList< QgsPoint >() << QgsPoint( 0, 0.8 ) << QgsPoint( 1, 0.2 ) ) );
951950

952-
QDomElement element = doc.createElement( "xform" );
953-
QVERIFY( t1.writeXml( element, doc ) );
951+
QVariant element;
952+
element = t1.toVariant();
954953
QgsSizeScaleTransformer r1;
955-
QVERIFY( r1.readXml( element, doc ) );
954+
QVERIFY( r1.loadVariant( element ) );
956955
QCOMPARE( r1.minValue(), 15.0 );
957956
QCOMPARE( r1.maxValue(), 25.0 );
958957
QCOMPARE( r1.minSize(), 150.0 );
@@ -1177,10 +1176,10 @@ void TestQgsProperty::colorRampTransformer()
11771176
t1.setRampName( "rampname " );
11781177
t1.setCurveTransform( new QgsCurveTransform( QList< QgsPoint >() << QgsPoint( 0, 0.8 ) << QgsPoint( 1, 0.2 ) ) );
11791178

1180-
QDomElement element = doc.createElement( "xform" );
1181-
QVERIFY( t1.writeXml( element, doc ) );
1179+
QVariant element;
1180+
element = t1.toVariant();
11821181
QgsColorRampTransformer r1;
1183-
QVERIFY( r1.readXml( element, doc ) );
1182+
QVERIFY( r1.loadVariant( element ) );
11841183
QCOMPARE( r1.minValue(), 15.0 );
11851184
QCOMPARE( r1.maxValue(), 25.0 );
11861185
QCOMPARE( r1.nullColor(), QColor( 100, 150, 200 ) );
@@ -1415,11 +1414,10 @@ void TestQgsProperty::propertyCollection()
14151414
DomImplementation.createDocumentType(
14161415
"qgis", "http://mrcc.com/qgis.dtd", "SYSTEM" );
14171416
QDomDocument doc( documentType );
1418-
QDomElement element = doc.createElement( "collection" );
1419-
collection.writeXml( element, doc, mDefinitions );
1417+
QVariant collectionElement = collection.toVariant( mDefinitions );
14201418

14211419
QgsPropertyCollection restoredCollection;
1422-
restoredCollection.readXml( element, doc, mDefinitions );
1420+
restoredCollection.loadVariant( collectionElement, mDefinitions );
14231421
QCOMPARE( restoredCollection.name(), QStringLiteral( "collection" ) );
14241422
QCOMPARE( restoredCollection.count(), 4 );
14251423
QCOMPARE( restoredCollection.property( Property1 ).propertyType(), QgsProperty::StaticProperty );

0 commit comments

Comments
 (0)
Please sign in to comment.