Add API to save/restore QgsLayoutObject properties to XML

This commit is contained in:
Nyall Dawson 2017-07-18 14:53:41 +10:00
parent f121286e38
commit 09dd6db97b
4 changed files with 213 additions and 0 deletions

View File

@ -168,6 +168,26 @@ class QgsLayoutObject: QObject, QgsExpressionContextGenerator
protected:
bool writeObjectPropertiesToElement( QDomElement &parentElement, QDomDocument &document, const QgsReadWriteContext &context ) const;
%Docstring
Stores object properties within an XML DOM element.
\param parentElement is the parent DOM element to store the object's properties in
\param document DOM document
:return: true if write was successful
.. seealso:: readObjectPropertiesFromElement()
:rtype: bool
%End
bool readObjectPropertiesFromElement( const QDomElement &parentElement, const QDomDocument &document, const QgsReadWriteContext &context );
%Docstring
Sets object properties from a DOM element
\param parentElement is the parent DOM element for the object
\param document DOM document
:return: true if read was successful
.. seealso:: writeObjectPropertiesToElement()
:rtype: bool
%End

View File

@ -122,3 +122,51 @@ QgsExpressionContext QgsLayoutObject::createExpressionContext() const
return QgsExpressionContext() << QgsExpressionContextUtils::globalScope();
}
}
bool QgsLayoutObject::writeObjectPropertiesToElement( QDomElement &parentElement, QDomDocument &document, const QgsReadWriteContext & ) const
{
if ( parentElement.isNull() )
{
return false;
}
//create object element
QDomElement objectElement = document.createElement( "LayoutObject" );
QDomElement ddPropsElement = document.createElement( QStringLiteral( "dataDefinedProperties" ) );
mDataDefinedProperties.writeXml( ddPropsElement, sPropertyDefinitions );
objectElement.appendChild( ddPropsElement );
//custom properties
mCustomProperties.writeXml( objectElement, document );
parentElement.appendChild( objectElement );
return true;
}
bool QgsLayoutObject::readObjectPropertiesFromElement( const QDomElement &parentElement, const QDomDocument &document, const QgsReadWriteContext & )
{
Q_UNUSED( document );
if ( parentElement.isNull() )
{
return false;
}
QDomNodeList objectNodeList = parentElement.elementsByTagName( "LayoutObject" );
if ( objectNodeList.size() < 1 )
{
return false;
}
QDomElement objectElement = objectNodeList.at( 0 ).toElement();
QDomNode propsNode = objectElement.namedItem( QStringLiteral( "dataDefinedProperties" ) );
if ( !propsNode.isNull() )
{
mDataDefinedProperties.readXml( propsNode.toElement(), sPropertyDefinitions );
}
//custom properties
mCustomProperties.readXml( objectElement );
return true;
}

View File

@ -28,6 +28,7 @@
class QgsLayout;
class QPainter;
class QgsReadWriteContext;
/**
* \ingroup core
@ -188,6 +189,24 @@ class CORE_EXPORT QgsLayoutObject: public QObject, public QgsExpressionContextGe
protected:
/**
* Stores object properties within an XML DOM element.
* \param parentElement is the parent DOM element to store the object's properties in
* \param document DOM document
* \returns true if write was successful
* \see readObjectPropertiesFromElement()
*/
bool writeObjectPropertiesToElement( QDomElement &parentElement, QDomDocument &document, const QgsReadWriteContext &context ) const;
/**
* Sets object properties from a DOM element
* \param parentElement is the parent DOM element for the object
* \param document DOM document
* \returns true if read was successful
* \see writeObjectPropertiesToElement()
*/
bool readObjectPropertiesFromElement( const QDomElement &parentElement, const QDomDocument &document, const QgsReadWriteContext &context );
QgsLayout *mLayout = nullptr;
QgsPropertyCollection mDataDefinedProperties;

View File

@ -19,6 +19,7 @@
#include "qgslayout.h"
#include "qgstest.h"
#include "qgsproject.h"
#include "qgsreadwritecontext.h"
class TestQgsLayoutObject: public QObject
{
@ -33,6 +34,10 @@ class TestQgsLayoutObject: public QObject
void layout(); //test fetching layout from QgsLayoutObject
void customProperties();
void context();
void writeReadXml();
void writeRetrieveDDProperty(); //test writing and retrieving dd properties from xml
void writeRetrieveCustomProperties(); //test writing/retreiving custom properties from xml
private:
QString mReport;
@ -138,6 +143,127 @@ void TestQgsLayoutObject::context()
delete object;
}
void TestQgsLayoutObject::writeReadXml()
{
QgsProject p;
QgsLayout l( &p );
QgsLayoutObject *object = new QgsLayoutObject( &l );
QDomImplementation DomImplementation;
QDomDocumentType documentType =
DomImplementation.createDocumentType(
"qgis", "http://mrcc.com/qgis.dtd", "SYSTEM" );
QDomDocument doc( documentType );
//test writing with no parent node
QDomElement rootNode = doc.createElement( "qgis" );
QDomElement noNode;
QCOMPARE( object->writeObjectPropertiesToElement( noNode, doc, QgsReadWriteContext() ), false );
//test writing with node
QDomElement layoutObjectElem = doc.createElement( "item" );
rootNode.appendChild( layoutObjectElem );
QVERIFY( object->writeObjectPropertiesToElement( layoutObjectElem, doc, QgsReadWriteContext() ) );
//check if object node was written
QDomNodeList evalNodeList = rootNode.elementsByTagName( "LayoutObject" );
QCOMPARE( evalNodeList.count(), 1 );
//test reading node
QgsLayoutObject *readObject = new QgsLayoutObject( &l );
//test reading with no node
QCOMPARE( readObject->readObjectPropertiesFromElement( noNode, doc, QgsReadWriteContext() ), false );
//test node with no layout object child
QDomElement badLayoutObjectElem = doc.createElement( "item" );
rootNode.appendChild( badLayoutObjectElem );
QCOMPARE( readObject->readObjectPropertiesFromElement( badLayoutObjectElem, doc, QgsReadWriteContext() ), false );
//test reading node
QVERIFY( readObject->readObjectPropertiesFromElement( layoutObjectElem, doc, QgsReadWriteContext() ) );
delete object;
delete readObject;
}
void TestQgsLayoutObject::writeRetrieveDDProperty()
{
QgsProject p;
QgsLayout l( &p );
QgsLayoutObject *object = new QgsLayoutObject( &l );
object->dataDefinedProperties().setProperty( QgsLayoutObject::TestProperty, QgsProperty::fromExpression( QStringLiteral( "10 + 40" ) ) );
//test writing object with dd settings
QDomImplementation DomImplementation;
QDomDocumentType documentType =
DomImplementation.createDocumentType(
QStringLiteral( "qgis" ), QStringLiteral( "http://mrcc.com/qgis.dtd" ), QStringLiteral( "SYSTEM" ) );
QDomDocument doc( documentType );
QDomElement rootNode = doc.createElement( QStringLiteral( "qgis" ) );
QVERIFY( object->writeObjectPropertiesToElement( rootNode, doc, QgsReadWriteContext() ) );
//check if object node was written
QDomNodeList evalNodeList = rootNode.elementsByTagName( QStringLiteral( "LayoutObject" ) );
QCOMPARE( evalNodeList.count(), 1 );
//test reading node containing dd settings
QgsLayoutObject *readObject = new QgsLayoutObject( &l );
QVERIFY( readObject->readObjectPropertiesFromElement( rootNode, doc, QgsReadWriteContext() ) );
//test getting not set dd from restored object
QgsProperty dd = readObject->dataDefinedProperties().property( QgsLayoutObject::BlendMode );
QVERIFY( !dd );
//test getting good property
dd = readObject->dataDefinedProperties().property( QgsLayoutObject::TestProperty );
QVERIFY( dd );
QVERIFY( dd.isActive() );
QCOMPARE( dd.propertyType(), QgsProperty::ExpressionBasedProperty );
delete object;
delete readObject;
}
void TestQgsLayoutObject::writeRetrieveCustomProperties()
{
QgsProject p;
QgsLayout l( &p );
QgsLayoutObject *object = new QgsLayoutObject( &l );
object->setCustomProperty( QStringLiteral( "testprop" ), "testval" );
object->setCustomProperty( QStringLiteral( "testprop2" ), 5 );
//test writing object with custom properties
QDomImplementation DomImplementation;
QDomDocumentType documentType =
DomImplementation.createDocumentType(
QStringLiteral( "qgis" ), QStringLiteral( "http://mrcc.com/qgis.dtd" ), QStringLiteral( "SYSTEM" ) );
QDomDocument doc( documentType );
QDomElement rootNode = doc.createElement( QStringLiteral( "qgis" ) );
QVERIFY( object->writeObjectPropertiesToElement( rootNode, doc, QgsReadWriteContext() ) );
//check if object node was written
QDomNodeList evalNodeList = rootNode.elementsByTagName( QStringLiteral( "LayoutObject" ) );
QCOMPARE( evalNodeList.count(), 1 );
//test reading node containing custom properties
QgsLayoutObject *readObject = new QgsLayoutObject( &l );
QVERIFY( readObject->readObjectPropertiesFromElement( rootNode, doc, QgsReadWriteContext() ) );
//test retrieved custom properties
QCOMPARE( readObject->customProperties().length(), 2 );
QVERIFY( readObject->customProperties().contains( QString( "testprop" ) ) );
QVERIFY( readObject->customProperties().contains( QString( "testprop2" ) ) );
QCOMPARE( readObject->customProperty( "testprop" ).toString(), QString( "testval" ) );
QCOMPARE( readObject->customProperty( "testprop2" ).toInt(), 5 );
delete object;
delete readObject;
}
QGSTEST_MAIN( TestQgsLayoutObject )
#include "testqgslayoutobject.moc"