Save QgsProperty related objects via QVariants

This commit is contained in:
Matthias Kuhn 2017-03-09 09:46:06 +01:00
parent 1687019414
commit 0170580019
24 changed files with 481 additions and 294 deletions

View File

@ -128,10 +128,8 @@ class QgsProperty
int valueAsInt( const QgsExpressionContext& context, int defaultValue = 0, bool* ok /Out/ = nullptr ) const;
bool valueAsBool( const QgsExpressionContext& context, bool defaultValue = false, bool* ok /Out/ = nullptr ) const;
virtual bool writeXml( QDomElement& propertyElem, QDomDocument& doc ) const;
virtual bool readXml( const QDomElement& propertyElem, const QDomDocument& doc );
QVariant toVariant() const;
bool loadVariant( const QVariant &property );
void setTransformer( QgsPropertyTransformer* transformer /Transfer/ );

View File

@ -53,10 +53,10 @@ class QgsAbstractPropertyCollection
virtual bool hasDynamicProperties() const = 0;
virtual bool writeXml( QDomElement& collectionElem, QDomDocument& doc, const QgsPropertiesDefinition& definitions ) const = 0;
virtual bool readXml( const QDomElement& collectionElem, const QDomDocument& doc, const QgsPropertiesDefinition &definitions ) = 0;
virtual bool writeXml( QDomElement& collectionElem, const QgsPropertiesDefinition& definitions ) const = 0;
virtual bool readXml( const QDomElement& collectionElem, const QgsPropertiesDefinition &definitions ) = 0;
virtual QVariant toVariant( const QgsPropertiesDefinition &definitions ) const = 0;
virtual bool loadVariant( const QVariant &configuration, const QgsPropertiesDefinition &definitions ) = 0;
};
@ -88,9 +88,9 @@ class QgsPropertyCollection : QgsAbstractPropertyCollection
bool isActive( int key ) const;
bool hasActiveProperties() const;
bool hasDynamicProperties() const;
bool writeXml( QDomElement& collectionElem, QDomDocument& doc, const QgsPropertiesDefinition& definitions ) const;
bool readXml( const QDomElement& collectionElem, const QDomDocument& doc, const QgsPropertiesDefinition& definitions );
QVariant toVariant( const QgsPropertiesDefinition &definitions ) const;
bool loadVariant( const QVariant &configuration, const QgsPropertiesDefinition &definitions );
void setProperty( int key, const QgsProperty& property );
void setProperty( int key, const QVariant& value );
@ -137,7 +137,7 @@ class QgsPropertyCollectionStack : QgsAbstractPropertyCollection
QSet<int> propertyKeys() const;
bool hasProperty( int key ) const;
bool writeXml( QDomElement& collectionElem, QDomDocument& doc, const QgsPropertiesDefinition& definitions ) const;
bool readXml( const QDomElement& collectionElem, const QDomDocument& doc, const QgsPropertiesDefinition &definitions );
virtual QVariant toVariant( const QgsPropertiesDefinition &definitions ) const;
virtual bool loadVariant( const QVariant &collection, const QgsPropertiesDefinition &definitions );
};

View File

@ -29,6 +29,9 @@ class QgsCurveTransform
bool writeXml( QDomElement& transformElem, QDomDocument& doc ) const;
QVariant toVariant() const;
bool loadVariant( const QVariant &transformer );
};
class QgsPropertyTransformer
{
@ -67,10 +70,9 @@ class QgsPropertyTransformer
virtual Type transformerType() const = 0;
virtual QgsPropertyTransformer* clone() = 0 /Factory/;
virtual bool loadVariant(const QVariant &transformer );
virtual bool readXml( const QDomElement& transformerElem, const QDomDocument& doc );
virtual bool writeXml( QDomElement& transformerElem, QDomDocument& doc ) const;
virtual QVariant toVariant() const;
double minValue() const;
@ -111,8 +113,8 @@ class QgsGenericNumericTransformer : QgsPropertyTransformer
virtual Type transformerType() const;
virtual QgsGenericNumericTransformer* clone() /Factory/;
virtual bool writeXml( QDomElement& transformerElem, QDomDocument& doc ) const;
virtual bool readXml( const QDomElement& transformerElem, const QDomDocument& doc );
virtual QVariant toVariant() const;
virtual bool loadVariant( const QVariant &definition );
virtual QVariant transform( const QgsExpressionContext& context, const QVariant& value ) const;
virtual QString toExpression( const QString& baseExpression ) const;
static QgsGenericNumericTransformer* fromExpression( const QString& expression, QString& baseExpression, QString& fieldName ) /Factory/;
@ -155,8 +157,8 @@ class QgsSizeScaleTransformer : QgsPropertyTransformer
virtual Type transformerType() const;
virtual QgsSizeScaleTransformer* clone() /Factory/;
virtual bool writeXml( QDomElement& transformerElem, QDomDocument& doc ) const;
virtual bool readXml( const QDomElement& transformerElem, const QDomDocument& doc );
virtual QVariant toVariant() const;
virtual bool loadVariant( const QVariant &definition );
virtual QVariant transform( const QgsExpressionContext& context, const QVariant& value ) const;
virtual QString toExpression( const QString& baseExpression ) const;
@ -206,8 +208,8 @@ class QgsColorRampTransformer : QgsPropertyTransformer
virtual Type transformerType() const;
virtual QgsColorRampTransformer* clone() /Factory/;
virtual bool writeXml( QDomElement& transformerElem, QDomDocument& doc ) const;
virtual bool readXml( const QDomElement& transformerElem, const QDomDocument& doc );
virtual QVariant toVariant() const;
virtual bool loadVariant( const QVariant &definition );
virtual QVariant transform( const QgsExpressionContext& context, const QVariant& value ) const;
virtual QString toExpression( const QString& baseExpression ) const;

View File

@ -284,6 +284,8 @@ class QgsSymbolLayerUtils
static QgsColorRamp* loadColorRamp( QDomElement& element ) /Factory/;
static QDomElement saveColorRamp( const QString& name, QgsColorRamp* ramp, QDomDocument& doc );
static QVariant colorRampToVariant( const QString &name, QgsColorRamp *ramp );
static QgsColorRamp *loadColorRamp( const QVariant &value );
/**
* Returns a friendly display name for a color

View File

@ -21,29 +21,16 @@ class QgsEditorConfigWidget : QWidget
public:
explicit QgsEditorConfigWidget( QgsVectorLayer* vl, int fieldIdx, QWidget* parent /TransferThis/ );
/**
* Returns the field for which this configuration widget applies
*
* @return The field index
*/
int field();
/**
* Returns the layer for which this configuration widget applies
*
* @return The layer
*/
QgsVectorLayer* layer();
virtual QVariantMap config() = 0;
virtual void setConfig( const QVariantMap& config ) = 0;
int field();
QgsVectorLayer* layer();
QgsExpressionContext createExpressionContext() const;
signals:
/** Emitted when the configuration of the widget is changed.
* @note added in QGIS 3.0
*/
void changed();
protected:
void initializeDataDefinedButton( QgsPropertyOverrideButton *button, QgsWidgetWrapper::Property key );
};

View File

@ -47,6 +47,11 @@ class QgsWidgetWrapper : QObject
%End
public:
enum Property
{
RootPath = 0,
};
static const QgsPropertiesDefinition &propertyDefinitions();
/**
* Create a new widget wrapper
*
@ -131,6 +136,8 @@ class QgsWidgetWrapper : QObject
*/
virtual bool valid() const = 0;
const QgsPropertyCollection &dataDefinedProperties() const;
void setDataDefinedProperties( const QgsPropertyCollection &collection );
protected:
/**
* This method should create a new widget with the provided parent. This will only be called

View File

@ -117,7 +117,7 @@ bool QgsComposerObject::writeXml( QDomElement &elem, QDomDocument &doc ) const
}
QDomElement ddPropsElement = doc.createElement( QStringLiteral( "dataDefinedProperties" ) );
mDataDefinedProperties.writeXml( ddPropsElement, doc, sPropertyDefinitions );
mDataDefinedProperties.writeXml( ddPropsElement, sPropertyDefinitions );
elem.appendChild( ddPropsElement );
//custom properties
@ -140,7 +140,7 @@ bool QgsComposerObject::readXml( const QDomElement &itemElem, const QDomDocument
QDomNode propsNode = itemElem.namedItem( QStringLiteral( "dataDefinedProperties" ) );
if ( !propsNode.isNull() )
{
mDataDefinedProperties.readXml( propsNode.toElement(), doc, sPropertyDefinitions );
mDataDefinedProperties.readXml( propsNode.toElement(), sPropertyDefinitions );
}
//custom properties

View File

@ -903,7 +903,7 @@ bool QgsComposition::writeXml( QDomElement &composerElem, QDomDocument &doc )
//data defined properties
QDomElement ddPropsElement = doc.createElement( QStringLiteral( "dataDefinedProperties" ) );
mDataDefinedProperties.writeXml( ddPropsElement, doc, QgsComposerObject::propertyDefinitions() );
mDataDefinedProperties.writeXml( ddPropsElement, QgsComposerObject::propertyDefinitions() );
compositionElem.appendChild( ddPropsElement );
composerElem.appendChild( compositionElem );
@ -990,7 +990,7 @@ bool QgsComposition::readXml( const QDomElement &compositionElem, const QDomDocu
QDomNode propsNode = compositionElem.namedItem( QStringLiteral( "dataDefinedProperties" ) );
if ( !propsNode.isNull() )
{
mDataDefinedProperties.readXml( propsNode.toElement(), doc, QgsComposerObject::propertyDefinitions() );
mDataDefinedProperties.readXml( propsNode.toElement(), QgsComposerObject::propertyDefinitions() );
}
//custom properties

View File

@ -111,7 +111,7 @@ void QgsDiagramLayerSettings::readXml( const QDomElement &elem, const QgsVectorL
QDomNodeList propertyElems = elem.elementsByTagName( "properties" );
if ( !propertyElems.isEmpty() )
{
( void )mDataDefinedProperties.readXml( propertyElems.at( 0 ).toElement(), elem.ownerDocument(), sPropertyDefinitions );
( void )mDataDefinedProperties.readXml( propertyElems.at( 0 ).toElement(), sPropertyDefinitions );
}
else
{
@ -154,7 +154,7 @@ void QgsDiagramLayerSettings::writeXml( QDomElement &layerElem, QDomDocument &do
QDomElement diagramLayerElem = doc.createElement( QStringLiteral( "DiagramLayerSettings" ) );
QDomElement propertiesElem = doc.createElement( "properties" );
( void )mDataDefinedProperties.writeXml( propertiesElem, doc, sPropertyDefinitions );
( void )mDataDefinedProperties.writeXml( propertiesElem, sPropertyDefinitions );
diagramLayerElem.appendChild( propertiesElem );
diagramLayerElem.setAttribute( QStringLiteral( "placement" ), mPlacement );
diagramLayerElem.setAttribute( QStringLiteral( "linePlacementFlags" ), mPlacementFlags );

View File

@ -669,7 +669,7 @@ void QgsPalLayerSettings::readFromLayer( QgsVectorLayer *layer )
QDomDocument doc( QStringLiteral( "dd" ) );
doc.setContent( layer->customProperty( QStringLiteral( "labeling/ddProperties" ) ).toString() );
QDomElement elem = doc.firstChildElement( QStringLiteral( "properties" ) );
mDataDefinedProperties.readXml( elem, doc, sPropertyDefinitions );
mDataDefinedProperties.readXml( elem, sPropertyDefinitions );
}
else
{
@ -760,7 +760,7 @@ void QgsPalLayerSettings::writeToLayer( QgsVectorLayer *layer )
doc = QDomDocument( QStringLiteral( "dd" ) );
QDomElement ddElem = doc.createElement( QStringLiteral( "properties" ) );
mDataDefinedProperties.writeXml( ddElem, doc, sPropertyDefinitions );
mDataDefinedProperties.writeXml( ddElem, sPropertyDefinitions );
QString ddProps;
QTextStream streamProps( &ddProps );
ddElem.save( streamProps, -1 );
@ -876,7 +876,7 @@ void QgsPalLayerSettings::readXml( QDomElement &elem )
QDomElement ddElem = elem.firstChildElement( QStringLiteral( "dd_properties" ) );
if ( !ddElem.isNull() )
{
mDataDefinedProperties.readXml( ddElem, ddElem.ownerDocument(), sPropertyDefinitions );
mDataDefinedProperties.readXml( ddElem, sPropertyDefinitions );
}
else
{
@ -965,7 +965,7 @@ QDomElement QgsPalLayerSettings::writeXml( QDomDocument &doc )
renderingElem.setAttribute( QStringLiteral( "zIndex" ), zIndex );
QDomElement ddElem = doc.createElement( QStringLiteral( "dd_properties" ) );
mDataDefinedProperties.writeXml( ddElem, doc, sPropertyDefinitions );
mDataDefinedProperties.writeXml( ddElem, sPropertyDefinitions );
QDomElement elem = doc.createElement( QStringLiteral( "settings" ) );
elem.appendChild( textStyleElem );

View File

@ -636,24 +636,26 @@ bool QgsProperty::valueAsBool( const QgsExpressionContext &context, bool default
return val.toBool();
}
bool QgsProperty::writeXml( QDomElement &propertyElem, QDomDocument &doc ) const
QVariant QgsProperty::toVariant() const
{
propertyElem.setAttribute( "active", d->active ? "1" : "0" );
propertyElem.setAttribute( "type", d->type );
QVariantMap propertyMap;
propertyMap.insert( QStringLiteral( "active" ), d->active );
propertyMap.insert( QStringLiteral( "type" ), d->type );
switch ( d->type )
{
case StaticProperty:
propertyElem.setAttribute( "valType", d->staticValue.typeName() );
propertyElem.setAttribute( "val", d->staticValue.toString() );
// propertyMap.insert( QStringLiteral( "valType" ), d->staticValue.typeName() );
propertyMap.insert( QStringLiteral( "val" ), d->staticValue.toString() );
break;
case FieldBasedProperty:
propertyElem.setAttribute( "field", d->fieldName );
propertyMap.insert( QStringLiteral( "field" ), d->fieldName );
break;
case ExpressionBasedProperty:
propertyElem.setAttribute( "expression", d->expressionString );
propertyMap.insert( QStringLiteral( "expression" ), d->expressionString );
break;
case InvalidProperty:
@ -662,36 +664,39 @@ bool QgsProperty::writeXml( QDomElement &propertyElem, QDomDocument &doc ) const
if ( d->transformer )
{
QDomElement transformerElem = doc.createElement( "transformer" );
transformerElem.setAttribute( "t", static_cast< int >( d->transformer->transformerType() ) );
if ( d->transformer->writeXml( transformerElem, doc ) )
propertyElem.appendChild( transformerElem );
QVariantMap transformer;
transformer.insert( QStringLiteral( "t" ), d->transformer->transformerType() );
transformer.insert( QStringLiteral( "d" ), d->transformer->toVariant() );
propertyMap.insert( QStringLiteral( "transformer" ), transformer );
}
return true;
return propertyMap;
}
bool QgsProperty::readXml( const QDomElement &propertyElem, const QDomDocument &doc )
bool QgsProperty::loadVariant( const QVariant &property )
{
QVariantMap propertyMap = property.toMap();
d.detach();
d->active = static_cast< bool >( propertyElem.attribute( "active", "1" ).toInt() );
d->type = static_cast< Type >( propertyElem.attribute( "type", "0" ).toInt() );
d->active = propertyMap.value( QStringLiteral( "active" ) ).toBool();
d->type = static_cast< Type >( propertyMap.value( QStringLiteral( "type" ), InvalidProperty ).toInt() );
switch ( d->type )
{
case StaticProperty:
d->staticValue = QVariant( propertyElem.attribute( "val", "" ) );
d->staticValue.convert( QVariant::nameToType( propertyElem.attribute( "valType", "QString" ).toLocal8Bit().constData() ) );
d->staticValue = propertyMap.value( QStringLiteral( "val" ) );
// d->staticValue.convert( QVariant::nameToType( propertyElem.attribute( "valType", "QString" ).toLocal8Bit().constData() ) );
break;
case FieldBasedProperty:
d->fieldName = propertyElem.attribute( "field" );
d->fieldName = propertyMap.value( QStringLiteral( "field" ) ).toString();
if ( d->fieldName.isEmpty() )
d->active = false;
break;
case ExpressionBasedProperty:
d->expressionString = propertyElem.attribute( "expression" );
d->expressionString = propertyMap.value( QStringLiteral( "expression" ) ).toString();
if ( d->expressionString.isEmpty() )
d->active = false;
@ -709,15 +714,20 @@ bool QgsProperty::readXml( const QDomElement &propertyElem, const QDomDocument &
if ( d->transformer )
delete d->transformer;
d->transformer = nullptr;
QDomNodeList transformerNodeList = propertyElem.elementsByTagName( "transformer" );
if ( !transformerNodeList.isEmpty() )
QVariant transform = propertyMap.value( QStringLiteral( "transformer" ) );
if ( transform.isValid() )
{
QDomElement transformerElem = transformerNodeList.at( 0 ).toElement();
QgsPropertyTransformer::Type type = static_cast< QgsPropertyTransformer::Type >( transformerElem.attribute( "t", "0" ).toInt() );
QVariantMap transformerMap = transform.toMap();
QgsPropertyTransformer::Type type = static_cast< QgsPropertyTransformer::Type >( transformerMap.value( QStringLiteral( "t" ), QgsPropertyTransformer::GenericNumericTransformer ).toInt() );
std::unique_ptr< QgsPropertyTransformer > transformer( QgsPropertyTransformer::create( type ) );
if ( transformer )
{
if ( transformer->readXml( transformerElem, doc ) )
if ( transformer->loadVariant( transformerMap.value( QStringLiteral( "d" ) ) ) )
d->transformer = transformer.release();
}
}

View File

@ -396,20 +396,20 @@ class CORE_EXPORT QgsProperty
bool valueAsBool( const QgsExpressionContext &context, bool defaultValue = false, bool *ok = nullptr ) const;
/**
* Writes the current state of the property into an XML element
* @param propertyElem destination element for the property's state
* @param doc DOM document
* @see readXml()
*/
bool writeXml( QDomElement &propertyElem, QDomDocument &doc ) const;
* Saves this property to a QVariantMap, wrapped in a QVariant.
* You can use QgsXmlUtils::writeVariant to save it to an XML document.
*
* @see loadVariant()
*/
QVariant toVariant() const;
/**
* Reads property state from an XML element.
* @param propertyElem source DOM element for property's state
* @param doc DOM document
* @see writeXml()
*/
bool readXml( const QDomElement &propertyElem, const QDomDocument &doc );
* Loads this property from a QVariantMap, wrapped in a QVariant.
* You can use QgsXmlUtils::readVariant to load it from an XML document.
*
* @see toVariant()
*/
bool loadVariant( const QVariant &property );
/**
* Sets an optional transformer to use for manipulating the calculated values for the property.

View File

@ -15,6 +15,7 @@
#include "qgspropertycollection.h"
#include "qgsproperty.h"
#include "qgsxmlutils.h"
//
// QgsAbstractPropertyCollection
@ -83,6 +84,21 @@ bool QgsAbstractPropertyCollection::valueAsBool( int key, const QgsExpressionCon
return prop.valueAsBool( context, defaultValue, ok );
}
bool QgsAbstractPropertyCollection::writeXml( QDomElement &collectionElem, const QgsPropertiesDefinition &definitions ) const
{
QVariant collection = toVariant( definitions );
QDomDocument doc = collectionElem.ownerDocument();
QDomElement element = QgsXmlUtils::writeVariant( collection, doc );
collectionElem.appendChild( element );
return true;
}
bool QgsAbstractPropertyCollection::readXml( const QDomElement &collectionElem, const QgsPropertiesDefinition &definitions )
{
QVariant collection = QgsXmlUtils::readVariant( collectionElem.firstChild().toElement() );
return loadVariant( collection.toMap(), definitions );
}
//
@ -276,47 +292,45 @@ bool QgsPropertyCollection::hasDynamicProperties() const
return mHasDynamicProperties;
}
bool QgsPropertyCollection::writeXml( QDomElement &collectionElem, QDomDocument &doc, const QgsPropertiesDefinition &definitions ) const
QVariant QgsPropertyCollection::toVariant( const QgsPropertiesDefinition &definitions ) const
{
collectionElem.setAttribute( "name", name() );
collectionElem.setAttribute( "type", "collection" );
QVariantMap collection;
collection.insert( QStringLiteral( "name" ), name() );
collection.insert( QStringLiteral( "type" ), QStringLiteral( "collection" ) );
QVariantMap properties;
QHash<int, QgsProperty>::const_iterator it = mProperties.constBegin();
for ( ; it != mProperties.constEnd(); ++it )
{
if ( it.value() )
{
QDomElement propertyElement = doc.createElement( "p" );
int key = it.key();
QString propName = definitions.value( key ).name();
propertyElement.setAttribute( "n", propName );
it.value().writeXml( propertyElement, doc );
collectionElem.appendChild( propertyElement );
properties.insert( definitions.value( it.key() ).name(), it.value().toVariant() );
}
}
return true;
collection.insert( QStringLiteral( "properties" ), properties );
return collection;
}
bool QgsPropertyCollection::readXml( const QDomElement &collectionElem, const QDomDocument &doc, const QgsPropertiesDefinition &definitions )
bool QgsPropertyCollection::loadVariant( const QVariant &collection, const QgsPropertiesDefinition &definitions )
{
clear();
setName( collectionElem.attribute( "name" ) );
QVariantMap collectionMap = collection.toMap();
setName( collectionMap.value( QStringLiteral( "name" ) ).toString() );
mCount = 0;
QDomNodeList propertyNodeList = collectionElem.elementsByTagName( "p" );
for ( int i = 0; i < propertyNodeList.size(); ++i )
QVariantMap properties = collectionMap.value( QStringLiteral( "properties" ) ).toMap();
for ( auto propertyIterator = properties.constBegin(); propertyIterator != properties.constEnd(); ++propertyIterator )
{
QDomElement propertyElem = propertyNodeList.at( i ).toElement();
QString propName = propertyElem.attribute( "n" );
if ( propName.isEmpty() )
continue;
// match name to int key
int key = -1;
QgsPropertiesDefinition::const_iterator it = definitions.constBegin();
for ( ; it != definitions.constEnd(); ++it )
{
if ( it->name() == propName )
if ( it->name() == propertyIterator.key() )
{
key = it.key();
break;
@ -327,10 +341,11 @@ bool QgsPropertyCollection::readXml( const QDomElement &collectionElem, const QD
continue;
QgsProperty prop;
prop.readXml( propertyElem, doc );
prop.loadVariant( propertyIterator.value() );
mProperties.insert( key, prop );
mCount++;
mHasActiveProperties = mHasActiveProperties || prop.isActive();
mHasDynamicProperties = mHasDynamicProperties ||
( prop.isActive() &&
@ -504,34 +519,40 @@ bool QgsPropertyCollectionStack::hasProperty( int key ) const
return false;
}
bool QgsPropertyCollectionStack::writeXml( QDomElement &collectionElem, QDomDocument &doc, const QgsPropertiesDefinition &definitions ) const
QVariant QgsPropertyCollectionStack::toVariant( const QgsPropertiesDefinition &definitions ) const
{
collectionElem.setAttribute( "type", "stack" );
collectionElem.setAttribute( "name", name() );
QVariantMap collection;
collection.insert( QStringLiteral( "type" ), QStringLiteral( "stack" ) );
collection.insert( QStringLiteral( "name" ), name() );
QVariantList properties;
Q_FOREACH ( QgsPropertyCollection *child, mStack )
{
QDomElement childElement = doc.createElement( "props" );
if ( !child->writeXml( childElement, doc, definitions ) )
return false;
collectionElem.appendChild( childElement );
properties.append( child->toVariant( definitions ) );
}
return true;
collection.insert( QStringLiteral( "properties" ), properties );
return collection;
}
bool QgsPropertyCollectionStack::readXml( const QDomElement &collectionElem, const QDomDocument &doc, const QgsPropertiesDefinition &definitions )
bool QgsPropertyCollectionStack::loadVariant( const QVariant &collection, const QgsPropertiesDefinition &definitions )
{
clear();
setName( collectionElem.attribute( "name" ) );
QVariantMap collectionMap = collection.toMap();
QDomNodeList childNodeList = collectionElem.elementsByTagName( "props" );
for ( int i = 0; i < childNodeList.size(); ++i )
setName( collectionMap.value( QStringLiteral( "name" ) ).toString() );
QVariantList properties = collectionMap.value( QStringLiteral( "properties" ) ).toList();
Q_FOREACH ( const QVariant &property, properties )
{
QDomElement childElem = childNodeList.at( i ).toElement();
QgsPropertyCollection *child = new QgsPropertyCollection();
child->readXml( childElem, doc, definitions );
mStack.append( child );
QgsPropertyCollection *propertyCollection = new QgsPropertyCollection();
propertyCollection->loadVariant( property.toMap(), definitions );
mStack.append( propertyCollection );
}
return true;
}

View File

@ -219,20 +219,34 @@ class CORE_EXPORT QgsAbstractPropertyCollection
/**
* Writes the current state of the property collection into an XML element
* @param collectionElem destination element for the property collection's state
* @param doc DOM document
* @param definitions property definitions
* @see readXml()
*/
virtual bool writeXml( QDomElement &collectionElem, QDomDocument &doc, const QgsPropertiesDefinition &definitions ) const = 0;
virtual bool writeXml( QDomElement &collectionElem, const QgsPropertiesDefinition &definitions ) const;
/**
* Reads property collection state from an XML element.
* @param collectionElem source DOM element for property collection's state
* @param doc DOM document
* @param definitions property definitions
* @see writeXml()
*/
virtual bool readXml( const QDomElement &collectionElem, const QDomDocument &doc, const QgsPropertiesDefinition &definitions ) = 0;
virtual bool readXml( const QDomElement &collectionElem, const QgsPropertiesDefinition &definitions );
/**
* Saves this property collection to a QVariantMap, wrapped in a QVariant.
* You can use QgsXmlUtils::writeVariant to save it to an XML document.
*
* @see loadVariant()
*/
virtual QVariant toVariant( const QgsPropertiesDefinition &definitions ) const = 0;
/**
* Loads this property collection from a QVariantMap, wrapped in a QVariant.
* You can use QgsXmlUtils::readVariant to save it to an XML document.
*
* @see toVariant()
*/
virtual bool loadVariant( const QVariant &configuration, const QgsPropertiesDefinition &definitions ) = 0;
private:
@ -292,8 +306,9 @@ class CORE_EXPORT QgsPropertyCollection : public QgsAbstractPropertyCollection
bool isActive( int key ) const override;
bool hasActiveProperties() const override;
bool hasDynamicProperties() const override;
bool writeXml( QDomElement &collectionElem, QDomDocument &doc, const QgsPropertiesDefinition &definitions ) const override;
bool readXml( const QDomElement &collectionElem, const QDomDocument &doc, const QgsPropertiesDefinition &definitions ) override;
QVariant toVariant( const QgsPropertiesDefinition &definitions ) const override;
bool loadVariant( const QVariant &configuration, const QgsPropertiesDefinition &definitions ) override;
/**
* Adds a property to the collection and takes ownership of it.
@ -439,8 +454,10 @@ class CORE_EXPORT QgsPropertyCollectionStack : public QgsAbstractPropertyCollect
QSet<int> propertyKeys() const override;
bool hasProperty( int key ) const override;
bool writeXml( QDomElement &collectionElem, QDomDocument &doc, const QgsPropertiesDefinition &definitions ) const override;
bool readXml( const QDomElement &collectionElem, const QDomDocument &doc, const QgsPropertiesDefinition &definitions ) override;
virtual QVariant toVariant( const QgsPropertiesDefinition &definitions ) const override;
virtual bool loadVariant( const QVariant &collection, const QgsPropertiesDefinition &definitions ) override;
private:

View File

@ -64,19 +64,37 @@ QgsPropertyTransformer &QgsPropertyTransformer::operator=( const QgsPropertyTran
return *this;
}
bool QgsPropertyTransformer::writeXml( QDomElement &transformerElem, QDomDocument &doc ) const
bool QgsPropertyTransformer::loadVariant( const QVariant &transformer )
{
Q_UNUSED( doc );
transformerElem.setAttribute( "minValue", QString::number( mMinValue ) );
transformerElem.setAttribute( "maxValue", QString::number( mMaxValue ) );
QVariantMap transformerMap = transformer.toMap();
mMinValue = transformerMap.value( QStringLiteral( "minValue" ), 0.0 ).toDouble();
mMaxValue = transformerMap.value( QStringLiteral( "maxValue" ), 1.0 ).toDouble();
mCurveTransform.reset( nullptr );
QVariantMap curve = transformerMap.value( "curve" ).toMap();
if ( !curve.isEmpty() )
{
mCurveTransform.reset( new QgsCurveTransform() );
mCurveTransform->loadVariant( curve );
}
return true;
}
QVariant QgsPropertyTransformer::toVariant() const
{
QVariantMap transformerMap;
transformerMap.insert( QStringLiteral( "minValue" ), mMinValue );
transformerMap.insert( QStringLiteral( "maxValue" ), mMaxValue );
if ( mCurveTransform )
{
QDomElement curveElement = doc.createElement( "curve" );
mCurveTransform->writeXml( curveElement, doc );
transformerElem.appendChild( curveElement );
transformerMap.insert( QStringLiteral( "curve" ), mCurveTransform->toVariant() );
}
return true;
return transformerMap;
}
QgsPropertyTransformer *QgsPropertyTransformer::fromExpression( const QString &expression, QString &baseExpression, QString &fieldName )
@ -104,23 +122,6 @@ double QgsPropertyTransformer::transformNumeric( double input ) const
return mMinValue + ( mMaxValue - mMinValue ) * mCurveTransform->y( scaledInput );
}
bool QgsPropertyTransformer::readXml( const QDomElement &transformerElem, const QDomDocument &doc )
{
Q_UNUSED( doc );
mMinValue = transformerElem.attribute( "minValue", "0.0" ).toDouble();
mMaxValue = transformerElem.attribute( "maxValue", "1.0" ).toDouble();
mCurveTransform.reset( nullptr );
QDomNodeList curveNodeList = transformerElem.elementsByTagName( "curve" );
if ( !curveNodeList.isEmpty() )
{
QDomElement curveElem = curveNodeList.at( 0 ).toElement();
mCurveTransform.reset( new QgsCurveTransform() );
mCurveTransform->readXml( curveElem, doc );
}
return true;
}
//
// QgsGenericNumericTransformer
@ -165,28 +166,28 @@ QgsGenericNumericTransformer *QgsGenericNumericTransformer::clone()
return t.release();
}
bool QgsGenericNumericTransformer::writeXml( QDomElement &transformerElem, QDomDocument &doc ) const
QVariant QgsGenericNumericTransformer::toVariant() const
{
if ( !QgsPropertyTransformer::writeXml( transformerElem, doc ) )
return false;
QVariantMap transformerMap = QgsPropertyTransformer::toVariant().toMap();
transformerElem.setAttribute( "minOutput", QString::number( mMinOutput ) );
transformerElem.setAttribute( "maxOutput", QString::number( mMaxOutput ) );
transformerElem.setAttribute( "nullOutput", QString::number( mNullOutput ) );
transformerElem.setAttribute( "exponent", QString::number( mExponent ) );
transformerMap.insert( QStringLiteral( "minOutput" ), mMinOutput );
transformerMap.insert( QStringLiteral( "maxOutput" ), mMaxOutput );
transformerMap.insert( QStringLiteral( "nullOutput" ), mNullOutput );
transformerMap.insert( QStringLiteral( "exponent" ), mExponent );
return true;
return transformerMap;
}
bool QgsGenericNumericTransformer::readXml( const QDomElement &transformerElem, const QDomDocument &doc )
bool QgsGenericNumericTransformer::loadVariant( const QVariant &transformer )
{
if ( !QgsPropertyTransformer::readXml( transformerElem, doc ) )
return false;
QgsPropertyTransformer::loadVariant( transformer );
mMinOutput = transformerElem.attribute( "minOutput", "0.0" ).toDouble();
mMaxOutput = transformerElem.attribute( "maxOutput", "1.0" ).toDouble();
mNullOutput = transformerElem.attribute( "nullOutput", "0.0" ).toDouble();
mExponent = transformerElem.attribute( "exponent", "1.0" ).toDouble();
QVariantMap transformerMap = transformer.toMap();
mMinOutput = transformerMap.value( QStringLiteral( "minOutput" ), 0.0 ).toDouble();
mMaxOutput = transformerMap.value( QStringLiteral( "maxOutput" ), 1.0 ).toDouble();
mNullOutput = transformerMap.value( QStringLiteral( "nullOutput" ), 0.0 ).toDouble();
mExponent = transformerMap.value( QStringLiteral( "exponent" ), 1.0 ).toDouble();
return true;
}
@ -358,30 +359,31 @@ QgsSizeScaleTransformer *QgsSizeScaleTransformer::clone()
return t.release();
}
bool QgsSizeScaleTransformer::writeXml( QDomElement &transformerElem, QDomDocument &doc ) const
QVariant QgsSizeScaleTransformer::toVariant() const
{
if ( !QgsPropertyTransformer::writeXml( transformerElem, doc ) )
return false;
QVariantMap transformerMap = QgsPropertyTransformer::toVariant().toMap();
transformerElem.setAttribute( "scaleType", QString::number( static_cast< int >( mType ) ) );
transformerElem.setAttribute( "minSize", QString::number( mMinSize ) );
transformerElem.setAttribute( "maxSize", QString::number( mMaxSize ) );
transformerElem.setAttribute( "nullSize", QString::number( mNullSize ) );
transformerElem.setAttribute( "exponent", QString::number( mExponent ) );
transformerMap.insert( QStringLiteral( "scaleType" ), static_cast< int >( mType ) );
transformerMap.insert( QStringLiteral( "minSize" ), mMinSize );
transformerMap.insert( QStringLiteral( "maxSize" ), mMaxSize );
transformerMap.insert( QStringLiteral( "nullSize" ), mNullSize );
transformerMap.insert( QStringLiteral( "exponent" ), mExponent );
return true;
return transformerMap;
}
bool QgsSizeScaleTransformer::readXml( const QDomElement &transformerElem, const QDomDocument &doc )
bool QgsSizeScaleTransformer::loadVariant( const QVariant &transformer )
{
if ( !QgsPropertyTransformer::readXml( transformerElem, doc ) )
return false;
QgsPropertyTransformer::loadVariant( transformer );
QVariantMap transformerMap = transformer.toMap();
mType = static_cast< ScaleType >( transformerMap.value( "scaleType", Linear ).toInt() );
mMinSize = transformerMap.value( "minSize", 0.0 ).toDouble();
mMaxSize = transformerMap.value( "maxSize", 1.0 ).toDouble();
mNullSize = transformerMap.value( "nullSize", 0.0 ).toDouble();
mExponent = transformerMap.value( "exponent", 1.0 ).toDouble();
mType = static_cast< ScaleType >( transformerElem.attribute( "scaleType", "0" ).toInt() );
mMinSize = transformerElem.attribute( "minSize", "0.0" ).toDouble();
mMaxSize = transformerElem.attribute( "maxSize", "1.0" ).toDouble();
mNullSize = transformerElem.attribute( "nullSize", "0.0" ).toDouble();
mExponent = transformerElem.attribute( "exponent", "1.0" ).toDouble();
return true;
}
@ -595,36 +597,34 @@ QgsColorRampTransformer *QgsColorRampTransformer::clone()
return c.release();
}
bool QgsColorRampTransformer::writeXml( QDomElement &transformerElem, QDomDocument &doc ) const
QVariant QgsColorRampTransformer::toVariant() const
{
if ( !QgsPropertyTransformer::writeXml( transformerElem, doc ) )
return false;
QVariantMap transformerMap = QgsPropertyTransformer::toVariant().toMap();
if ( mGradientRamp )
{
QDomElement colorRampElem = QgsSymbolLayerUtils::saveColorRamp( "[source]", mGradientRamp.get(), doc );
transformerElem.appendChild( colorRampElem );
transformerMap.insert( QStringLiteral( "colorramp" ), QgsSymbolLayerUtils::colorRampToVariant( QStringLiteral( "[source]" ), mGradientRamp.get() ) );
}
transformerElem.setAttribute( "nullColor", QgsSymbolLayerUtils::encodeColor( mNullColor ) );
transformerElem.setAttribute( "rampName", mRampName );
transformerMap.insert( QStringLiteral( "nullColor" ), QgsSymbolLayerUtils::encodeColor( mNullColor ) );
transformerMap.insert( QStringLiteral( "rampName" ), mRampName );
return true;
return transformerMap;
}
bool QgsColorRampTransformer::readXml( const QDomElement &transformerElem, const QDomDocument &doc )
bool QgsColorRampTransformer::loadVariant( const QVariant &definition )
{
if ( !QgsPropertyTransformer::readXml( transformerElem, doc ) )
return false;
QVariantMap transformerMap = definition.toMap();
QgsPropertyTransformer::loadVariant( definition );
mGradientRamp.reset( nullptr );
QDomElement sourceColorRampElem = transformerElem.firstChildElement( "colorramp" );
if ( !sourceColorRampElem.isNull() && sourceColorRampElem.attribute( "name" ) == "[source]" )
if ( transformerMap.contains( QStringLiteral( "colorramp" ) ) )
{
setColorRamp( QgsSymbolLayerUtils::loadColorRamp( sourceColorRampElem ) );
setColorRamp( QgsSymbolLayerUtils::loadColorRamp( transformerMap.value( QStringLiteral( "colorramp" ) ).toMap() ) );
}
mNullColor = QgsSymbolLayerUtils::decodeColor( transformerElem.attribute( "nullColor", "0,0,0,0" ) );
mRampName = transformerElem.attribute( "rampName", QString() );
mNullColor = QgsSymbolLayerUtils::decodeColor( transformerMap.value( QStringLiteral( "nullColor" ), QStringLiteral( "0,0,0,0" ) ).toString() );
mRampName = transformerMap.value( QStringLiteral( "rampName" ) ).toString();
return true;
}
@ -945,6 +945,52 @@ bool QgsCurveTransform::writeXml( QDomElement &transformElem, QDomDocument & ) c
return true;
}
QVariant QgsCurveTransform::toVariant() const
{
QVariantMap transformMap;
QStringList x;
QStringList y;
Q_FOREACH ( const QgsPoint &p, mControlPoints )
{
x << qgsDoubleToString( p.x() );
y << qgsDoubleToString( p.y() );
}
transformMap.insert( QStringLiteral( "x" ), x.join( ',' ) );
transformMap.insert( QStringLiteral( "y" ), y.join( ',' ) );
return transformMap;
}
bool QgsCurveTransform::loadVariant( const QVariant &transformer )
{
QVariantMap transformMap = transformer.toMap();
QString xString = transformMap.value( QStringLiteral( "x" ) ).toString();
QString yString = transformMap.value( QStringLiteral( "y" ) ).toString();
QStringList xVals = xString.split( ',' );
QStringList yVals = yString.split( ',' );
if ( xVals.count() != yVals.count() )
return false;
QList< QgsPoint > newPoints;
bool ok = false;
for ( int i = 0; i < xVals.count(); ++i )
{
double x = xVals.at( i ).toDouble( &ok );
if ( !ok )
return false;
double y = yVals.at( i ).toDouble( &ok );
if ( !ok )
return false;
newPoints << QgsPoint( x, y );
}
setControlPoints( newPoints );
return true;
}
// this code is adapted from https://github.com/OpenFibers/Photoshop-Curves
// which in turn was adapted from
// http://www.developpez.net/forums/d331608-3/autres-langages/algorithmes/contribuez/image-interpolation-spline-cubique/#post3513925 //#spellok

View File

@ -134,6 +134,22 @@ class CORE_EXPORT QgsCurveTransform
*/
bool writeXml( QDomElement &transformElem, QDomDocument &doc ) const;
/**
* Saves this curve transformer to a QVariantMap, wrapped in a QVariant.
* You can use QgsXmlUtils::writeVariant to save it to an XML document.
*
* @see loadVariant()
*/
QVariant toVariant() const;
/**
* Load this curve transformer from a QVariantMap, wrapped in a QVariant.
* You can use QgsXmlUtils::writeVariant to load it from an XML document.
*
* @see toVariant()
*/
bool loadVariant( const QVariant &transformer );
private:
void calcSecondDerivativeArray();
@ -196,20 +212,20 @@ class CORE_EXPORT QgsPropertyTransformer
virtual QgsPropertyTransformer *clone() = 0;
/**
* Reads transformer's state from an XML element.
* @param transformerElem source DOM element for transformer's state
* @param doc DOM document
* @see writeXml()
*/
virtual bool readXml( const QDomElement &transformerElem, const QDomDocument &doc );
* Loads this transformer from a QVariantMap, wrapped in a QVariant.
* You can use QgsXmlUtils::writeVariant to save it to an XML document.
*
* @see loadVariant()
*/
virtual bool loadVariant( const QVariant &transformer );
/**
* Writes the current state of the transformer into an XML element
* @param transformerElem destination element for the transformer's state
* @param doc DOM document
* @see readXml()
*/
virtual bool writeXml( QDomElement &transformerElem, QDomDocument &doc ) const;
* Saves this transformer to a QVariantMap, wrapped in a QVariant.
* You can use QgsXmlUtils::writeVariant to save it to an XML document.
*
* @see toVariant()
*/
virtual QVariant toVariant() const;
/**
* Returns the minimum value expected by the transformer.
@ -338,8 +354,8 @@ class CORE_EXPORT QgsGenericNumericTransformer : public QgsPropertyTransformer
virtual Type transformerType() const override { return GenericNumericTransformer; }
virtual QgsGenericNumericTransformer *clone() override;
virtual bool writeXml( QDomElement &transformerElem, QDomDocument &doc ) const override;
virtual bool readXml( const QDomElement &transformerElem, const QDomDocument &doc ) override;
virtual QVariant toVariant() const override;
virtual bool loadVariant( const QVariant &definition ) override;
virtual QVariant transform( const QgsExpressionContext &context, const QVariant &value ) const override;
virtual QString toExpression( const QString &baseExpression ) const override;
@ -474,8 +490,8 @@ class CORE_EXPORT QgsSizeScaleTransformer : public QgsPropertyTransformer
virtual Type transformerType() const override { return SizeScaleTransformer; }
virtual QgsSizeScaleTransformer *clone() override;
virtual bool writeXml( QDomElement &transformerElem, QDomDocument &doc ) const override;
virtual bool readXml( const QDomElement &transformerElem, const QDomDocument &doc ) override;
virtual QVariant toVariant() const override;
virtual bool loadVariant( const QVariant &definition ) override;
virtual QVariant transform( const QgsExpressionContext &context, const QVariant &value ) const override;
virtual QString toExpression( const QString &baseExpression ) const override;
@ -611,8 +627,8 @@ class CORE_EXPORT QgsColorRampTransformer : public QgsPropertyTransformer
virtual Type transformerType() const override { return ColorRampTransformer; }
virtual QgsColorRampTransformer *clone() override;
virtual bool writeXml( QDomElement &transformerElem, QDomDocument &doc ) const override;
virtual bool readXml( const QDomElement &transformerElem, const QDomDocument &doc ) override;
virtual QVariant toVariant() const override;
virtual bool loadVariant( const QVariant &definition ) override;
virtual QVariant transform( const QgsExpressionContext &context, const QVariant &value ) const override;
virtual QString toExpression( const QString &baseExpression ) const override;

View File

@ -119,6 +119,19 @@ QDomElement QgsXmlUtils::writeVariant( const QVariant &value, QDomDocument &doc
break;
}
case QVariant::List:
{
QVariantList list = value.toList();
Q_FOREACH ( const QVariant &value, list )
{
QDomElement valueElement = writeVariant( value, doc );
element.appendChild( valueElement );
element.setAttribute( QStringLiteral( "type" ), QStringLiteral( "List" ) );
}
break;
}
case QVariant::Int:
case QVariant::Bool:
case QVariant::Double:
@ -169,6 +182,18 @@ QVariant QgsXmlUtils::readVariant( const QDomElement &element )
}
return map;
}
else if ( type == QLatin1String( "List" ) )
{
QVariantList list;
QDomNodeList values = element.childNodes();
for ( int i = 0; i < values.count(); ++i )
{
QDomElement elem = values.at( i ).toElement();
if ( elem.tagName() == QLatin1String( "e" ) )
list.append( readVariant( elem ) );
}
return list;
}
else
{
return QVariant();

View File

@ -906,7 +906,7 @@ QgsSymbolLayer *QgsSymbolLayerUtils::loadSymbolLayer( QDomElement &element )
QDomElement ddProps = element.firstChildElement( QStringLiteral( "data_defined_properties" ) );
if ( !ddProps.isNull() )
{
layer->dataDefinedProperties().readXml( ddProps, element.ownerDocument(), QgsSymbolLayer::propertyDefinitions() );
layer->dataDefinedProperties().readXml( ddProps, QgsSymbolLayer::propertyDefinitions() );
}
return layer;
@ -957,7 +957,7 @@ QDomElement QgsSymbolLayerUtils::saveSymbol( const QString &name, QgsSymbol *sym
layer->paintEffect()->saveProperties( doc, layerEl );
QDomElement ddProps = doc.createElement( QStringLiteral( "data_defined_properties" ) );
layer->dataDefinedProperties().writeXml( ddProps, doc, QgsSymbolLayer::propertyDefinitions() );
layer->dataDefinedProperties().writeXml( ddProps, QgsSymbolLayer::propertyDefinitions() );
layerEl.appendChild( ddProps );
if ( layer->subSymbol() )
@ -2810,6 +2810,57 @@ QDomElement QgsSymbolLayerUtils::saveColorRamp( const QString &name, QgsColorRam
return rampEl;
}
QVariant QgsSymbolLayerUtils::colorRampToVariant( const QString &name, QgsColorRamp *ramp )
{
QVariantMap rampMap;
rampMap.insert( QStringLiteral( "type" ), ramp->type() );
rampMap.insert( QStringLiteral( "name" ), name );
QgsStringMap properties = ramp->properties();
QVariantMap propertyMap;
for ( auto property = properties.constBegin(); property != properties.constEnd(); ++property )
{
propertyMap.insert( property.key(), property.value() );
}
rampMap.insert( QStringLiteral( "properties" ), propertyMap );
return rampMap;
}
QgsColorRamp *QgsSymbolLayerUtils::loadColorRamp( const QVariant &value )
{
QVariantMap rampMap = value.toMap();
QString rampType = rampMap.value( QStringLiteral( "type" ) ).toString();
// parse properties
QVariantMap propertyMap = rampMap.value( QStringLiteral( "properties" ) ).toMap();
QgsStringMap props;
for ( auto property = propertyMap.constBegin(); property != propertyMap.constEnd(); ++property )
{
props.insert( property.key(), property.value().toString() );
}
if ( rampType == QLatin1String( "gradient" ) )
return QgsGradientColorRamp::create( props );
else if ( rampType == QLatin1String( "random" ) )
return QgsLimitedRandomColorRamp::create( props );
else if ( rampType == QLatin1String( "colorbrewer" ) )
return QgsColorBrewerColorRamp::create( props );
else if ( rampType == QLatin1String( "cpt-city" ) )
return QgsCptCityColorRamp::create( props );
else if ( rampType == QLatin1String( "preset" ) )
return QgsPresetSchemeColorRamp::create( props );
else
{
QgsDebugMsg( "unknown colorramp type " + rampType );
return nullptr;
}
}
QString QgsSymbolLayerUtils::colorToName( const QColor &color )
{
if ( !color.isValid() )

View File

@ -364,6 +364,22 @@ class CORE_EXPORT QgsSymbolLayerUtils
*/
static QDomElement saveColorRamp( const QString &name, QgsColorRamp *ramp, QDomDocument &doc );
/**
* Saves a color ramp to a QVariantMap, wrapped in a QVariant.
* You can use QgsXmlUtils::writeVariant to save it to an XML document.
*
* @see loadColorRamp( const QVariant &value )
*/
static QVariant colorRampToVariant( const QString &name, QgsColorRamp *ramp );
/**
* Load a color ramp from a QVariantMap, wrapped in a QVariant.
* You can use QgsXmlUtils::readVariant to load it from an XML document.
*
* @see colorRampToVariant()
*/
static QgsColorRamp *loadColorRamp( const QVariant &value );
/**
* Returns a friendly display name for a color
* @param color source color

View File

@ -19,12 +19,18 @@
#include <QWidget>
QgsPropertiesDefinition QgsWidgetWrapper::sPropertyDefinitions;
const QgsPropertiesDefinition &QgsWidgetWrapper::propertyDefinitions()
{
QgsWidgetWrapper::initPropertyDefinitions();
return sPropertyDefinitions;
static QgsPropertiesDefinition properties;
if ( properties.isEmpty() )
{
properties =
{
{ RootPath, QgsPropertyDefinition( "propertyRootPath", QgsPropertyDefinition::DataTypeString, QObject::tr( "Root path" ), QString() ) }
};
}
return properties;
}
QgsWidgetWrapper::QgsWidgetWrapper( QgsVectorLayer *vl, QWidget *editor, QWidget *parent )
@ -99,14 +105,3 @@ void QgsWidgetWrapper::setEnabled( bool enabled )
{
Q_UNUSED( enabled );
}
void QgsWidgetWrapper::initPropertyDefinitions()
{
if ( !sPropertyDefinitions.isEmpty() )
return;
sPropertyDefinitions = QgsPropertiesDefinition
{
{ RootPath, QgsPropertyDefinition( "propertyRootPath", QgsPropertyDefinition::DataTypeString, QObject::tr( "Root path" ), QString() ) }
};
}

View File

@ -218,11 +218,6 @@ class GUI_EXPORT QgsWidgetWrapper : public QObject
QWidget *mParent = nullptr;
QgsVectorLayer *mLayer = nullptr;
bool mInitialized;
//! Property definitions
static QgsPropertiesDefinition sPropertyDefinitions;
static void initPropertyDefinitions();
};
// We'll use this class inside a QVariant in the widgets properties

View File

@ -100,6 +100,7 @@ void QgsExternalResourceConfigDlg::chooseDefaultPath()
void QgsExternalResourceConfigDlg::rootPathPropertyChanged()
{
QgsProperty prop = mRootPathPropertyOverrideButton->toProperty();
mPropertyCollection.setProperty( QgsWidgetWrapper::RootPath, prop );
setRootPathExpression( prop );
mRootPathExpression->setVisible( prop.isActive() );
@ -146,15 +147,13 @@ QVariantMap QgsExternalResourceConfigDlg::config()
cfg.insert( QStringLiteral( "FullUrl" ), mFullUrl->isChecked() );
}
if ( mRootPathPropertyOverrideButton->isActive() )
cfg.insert( QStringLiteral( "DefaultRootStyle" ), QStringLiteral( "expression" ) );
else
cfg.insert( QStringLiteral( "DefaultRootStyle" ), QStringLiteral( "path" ) );
cfg.insert( QStringLiteral( "PropertyCollection" ), mPropertyCollection.toVariant( QgsWidgetWrapper::propertyDefinitions() ) );
if ( !mRootPath->text().isEmpty() )
cfg.insert( QStringLiteral( "DefaultRoot" ), mRootPath->text() );
cfg.insert( QStringLiteral( "RootPathProperty" ), mRootPathPropertyOverrideButton->toProperty().toVariant() );
// Save Storage Mode
cfg.insert( QStringLiteral( "StorageMode" ), mStorageButtonGroup->checkedId() );
@ -205,6 +204,8 @@ void QgsExternalResourceConfigDlg::setConfig( const QVariantMap &config )
mFullUrl->setChecked( true );
}
mPropertyCollection.loadVariant( config.value( QStringLiteral( "PropertyCollection" ) ), QgsWidgetWrapper::propertyDefinitions() );
setRootPathExpression( mPropertyCollection.property( QgsWidgetWrapper::RootPath ) );
mRootPath->setText( config.value( QStringLiteral( "DefaultRoot" ) ).toString() );
rootPathPropertyChanged();
@ -254,6 +255,7 @@ void QgsExternalResourceConfigDlg::setConfig( const QVariantMap &config )
void QgsExternalResourceConfigDlg::setRootPathExpression( const QgsProperty &property )
{
mRootPathPropertyOverrideButton->setToProperty( property );
mRootPathExpression->setToolTip( property.asExpression() );
QgsExpressionContext ctx = layer()->createExpressionContext();

View File

@ -87,7 +87,6 @@ void QgsExternalResourceWidgetWrapper::setFeature( const QgsFeature &feature )
QString path = mPropertyCollection.valueAsString( QgsEditorWidgetWrapper::RootPath, expressionContext, QString(), &ok );
if ( ok )
{
qWarning() << "Default root << " << path;
mQgsWidget->setDefaultRoot( path );
}
}
@ -132,7 +131,7 @@ void QgsExternalResourceWidgetWrapper::initWidget( QWidget *editor )
mQgsWidget->fileWidget()->setFullUrl( cfg.value( QStringLiteral( "FullUrl" ) ).toBool() );
}
qWarning() << "Default root style " << cfg.value( QStringLiteral( "DefaultRootStyle" ) );
mPropertyCollection.loadVariant( cfg.value( "PropertyCollection" ), propertyDefinitions() );
if ( !mPropertyCollection.isActive( QgsWidgetWrapper::RootPath ) )
{
mQgsWidget->setDefaultRoot( cfg.value( QStringLiteral( "DefaultRoot" ) ).toString() );

View File

@ -297,36 +297,35 @@ void TestQgsProperty::staticProperty()
p1.setStaticValue( "test" );
p1.setTransformer( new TestTransformer( 10, 20 ) );
QDomElement element = doc.createElement( "prop" );
p1.writeXml( element, doc );
QVariant element = p1.toVariant();
QgsProperty r1;
r1.readXml( element, doc );
r1.loadVariant( element );
QVERIFY( r1.isActive() );
QVERIFY( r1.transformer() );
QCOMPARE( r1.staticValue(), QVariant( "test" ) );
p1.setActive( false );
p1.writeXml( element, doc );
r1.readXml( element, doc );
element = p1.toVariant();
r1.loadVariant( element );
QVERIFY( !r1.isActive() );
//saving/restoring different types
p1.setStaticValue( QVariant( 5 ) ); //int
p1.writeXml( element, doc );
r1.readXml( element, doc );
element = p1.toVariant();
r1.loadVariant( element );
QCOMPARE( r1.staticValue(), p1.staticValue() );
p1.setStaticValue( QVariant( 5.7 ) ); //double
p1.writeXml( element, doc );
r1.readXml( element, doc );
element = p1.toVariant();
r1.loadVariant( element );
QCOMPARE( r1.staticValue(), p1.staticValue() );
p1.setStaticValue( QVariant( true ) ); //bool
p1.writeXml( element, doc );
r1.readXml( element, doc );
element = p1.toVariant();
r1.loadVariant( element );
QCOMPARE( r1.staticValue(), p1.staticValue() );
p1.setStaticValue( QVariant( 5LL ) ); //longlong
p1.writeXml( element, doc );
r1.readXml( element, doc );
element = p1.toVariant();
r1.loadVariant( element );
QCOMPARE( r1.staticValue(), p1.staticValue() );
// test copying a static property
@ -413,22 +412,22 @@ void TestQgsProperty::fieldBasedProperty()
p1.setActive( true );
p1.setField( "test_field" );
QDomElement element = doc.createElement( "prop" );
QVariant element;
QgsProperty r1;
//try reading from an empty element
r1.readXml( element, doc );
r1.loadVariant( element );
QVERIFY( !r1.isActive() );
QVERIFY( r1.field().isEmpty() );
// now populate element and re-read
p1.writeXml( element, doc );
r1.readXml( element, doc );
element = p1.toVariant();
r1.loadVariant( element );
QVERIFY( r1.isActive() );
QCOMPARE( r1.field(), QStringLiteral( "test_field" ) );
p1.setActive( false );
p1.writeXml( element, doc );
r1.readXml( element, doc );
element = p1.toVariant();
r1.loadVariant( element );
QVERIFY( !r1.isActive() );
// test copying a field based property
@ -520,24 +519,24 @@ void TestQgsProperty::expressionBasedProperty()
p1.setActive( true );
p1.setExpressionString( "4+5" );
QDomElement element = doc.createElement( "prop" );
QVariant element;
QgsProperty r1;
//try reading from an empty element
r1.readXml( element, doc );
r1.loadVariant( element );
QVERIFY( !r1.isActive() );
QVERIFY( r1.expressionString().isEmpty() );
QCOMPARE( r1.value( context, -1 ).toInt(), -1 );
// now populate element and re-read
p1.writeXml( element, doc );
r1.readXml( element, doc );
element = p1.toVariant();
r1.loadVariant( element );
QVERIFY( r1.isActive() );
QCOMPARE( r1.expressionString(), QStringLiteral( "4+5" ) );
QCOMPARE( r1.value( context, -1 ).toInt(), 9 );
p1.setActive( false );
p1.writeXml( element, doc );
r1.readXml( element, doc );
element = p1.toVariant();
r1.loadVariant( element );
QVERIFY( !r1.isActive() );
QCOMPARE( r1.value( context, -1 ).toInt(), -1 );
@ -627,10 +626,10 @@ void TestQgsProperty::propertyTransformer()
QDomDocument doc( documentType );
TestTransformer t1( -5, 6 );
QDomElement element = doc.createElement( "transform" );
QVariant element;
TestTransformer r1( -99, -98 );
QVERIFY( t1.writeXml( element, doc ) );
QVERIFY( r1.readXml( element, doc ) );
element = t1.toVariant();
QVERIFY( r1.loadVariant( element ) );
QCOMPARE( r1.minValue(), -5.0 );
QCOMPARE( r1.maxValue(), 6.0 );
@ -646,11 +645,11 @@ void TestQgsProperty::propertyTransformer()
QCOMPARE( p1.value( context, -99 ).toDouble(), 22.0 );
//test that transform is saved/restored with property
QDomElement propElement = doc.createElement( "property" );
QVariant propElement;
QgsProperty p2;
QVERIFY( !p2.transformer() );
QVERIFY( p1.writeXml( propElement, doc ) );
QVERIFY( p2.readXml( propElement, doc ) );
propElement = p1.toVariant();
p2.loadVariant( propElement );
QVERIFY( p2.transformer() );
QCOMPARE( p2.transformer()->minValue(), 10.0 );
QCOMPARE( p2.transformer()->maxValue(), 20.0 );
@ -755,10 +754,10 @@ void TestQgsProperty::genericNumericTransformer()
99 );
t2.setCurveTransform( new QgsCurveTransform( QList< QgsPoint >() << QgsPoint( 0, 0.8 ) << QgsPoint( 1, 0.2 ) ) );
QDomElement element = doc.createElement( "xform" );
QVERIFY( t2.writeXml( element, doc ) );
QVariant element;
element = t2.toVariant();
QgsGenericNumericTransformer r1;
QVERIFY( r1.readXml( element, doc ) );
QVERIFY( r1.loadVariant( element ) );
QCOMPARE( r1.minValue(), 15.0 );
QCOMPARE( r1.maxValue(), 25.0 );
QCOMPARE( r1.minOutputValue(), 150.0 );
@ -949,10 +948,10 @@ void TestQgsProperty::sizeScaleTransformer()
99 );
t1.setCurveTransform( new QgsCurveTransform( QList< QgsPoint >() << QgsPoint( 0, 0.8 ) << QgsPoint( 1, 0.2 ) ) );
QDomElement element = doc.createElement( "xform" );
QVERIFY( t1.writeXml( element, doc ) );
QVariant element;
element = t1.toVariant();
QgsSizeScaleTransformer r1;
QVERIFY( r1.readXml( element, doc ) );
QVERIFY( r1.loadVariant( element ) );
QCOMPARE( r1.minValue(), 15.0 );
QCOMPARE( r1.maxValue(), 25.0 );
QCOMPARE( r1.minSize(), 150.0 );
@ -1177,10 +1176,10 @@ void TestQgsProperty::colorRampTransformer()
t1.setRampName( "rampname " );
t1.setCurveTransform( new QgsCurveTransform( QList< QgsPoint >() << QgsPoint( 0, 0.8 ) << QgsPoint( 1, 0.2 ) ) );
QDomElement element = doc.createElement( "xform" );
QVERIFY( t1.writeXml( element, doc ) );
QVariant element;
element = t1.toVariant();
QgsColorRampTransformer r1;
QVERIFY( r1.readXml( element, doc ) );
QVERIFY( r1.loadVariant( element ) );
QCOMPARE( r1.minValue(), 15.0 );
QCOMPARE( r1.maxValue(), 25.0 );
QCOMPARE( r1.nullColor(), QColor( 100, 150, 200 ) );
@ -1415,11 +1414,10 @@ void TestQgsProperty::propertyCollection()
DomImplementation.createDocumentType(
"qgis", "http://mrcc.com/qgis.dtd", "SYSTEM" );
QDomDocument doc( documentType );
QDomElement element = doc.createElement( "collection" );
collection.writeXml( element, doc, mDefinitions );
QVariant collectionElement = collection.toVariant( mDefinitions );
QgsPropertyCollection restoredCollection;
restoredCollection.readXml( element, doc, mDefinitions );
restoredCollection.loadVariant( collectionElement, mDefinitions );
QCOMPARE( restoredCollection.name(), QStringLiteral( "collection" ) );
QCOMPARE( restoredCollection.count(), 4 );
QCOMPARE( restoredCollection.property( Property1 ).propertyType(), QgsProperty::StaticProperty );