Skip to content

Commit

Permalink
Add support for reading/writing item properties to XML
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Jul 25, 2017
1 parent 09dd6db commit a515e95
Show file tree
Hide file tree
Showing 12 changed files with 355 additions and 1 deletion.
70 changes: 70 additions & 0 deletions python/core/layout/qgslayoutitem.sip
Expand Up @@ -39,6 +39,22 @@ class QgsLayoutItem : QgsLayoutObject, QGraphicsRectItem
Constructor for QgsLayoutItem, with the specified parent ``layout``.
%End

virtual int type() const = 0;
%Docstring
Return correct graphics item type
.. seealso:: stringType()
:rtype: int
%End

virtual QString stringType() const = 0;
%Docstring
Return the item type as a string.

This string must be a unique, single word, character only representation of the item type, eg "LayoutScaleBar"
.. seealso:: type()
:rtype: str
%End

virtual void paint( QPainter *painter, const QStyleOptionGraphicsItem *itemStyle, QWidget *pWidget );

%Docstring
Expand Down Expand Up @@ -130,6 +146,32 @@ class QgsLayoutItem : QgsLayoutObject, QGraphicsRectItem
:rtype: float
%End

virtual bool writeXml( QDomElement &parentElement, QDomDocument &document, const QgsReadWriteContext &context ) const;
%Docstring
Stores the item state in a DOM element.
\param parentElement parent DOM element (e.g. 'Layout' element)
\param document DOM document
\param context read write context
.. seealso:: readXml()
.. note::

Subclasses should ensure that they call writePropertiesToElement() in their implementation.
:rtype: bool
%End

virtual bool readXml( const QDomElement &itemElement, const QDomDocument &document, const QgsReadWriteContext &context );
%Docstring
Sets the item state from a DOM element.
\param itemElement is the DOM node corresponding to item (e.g. 'LayoutItem' element)
\param document DOM document
\param context read write context
.. seealso:: writeXml()
.. note::

Subclasses should ensure that they call readPropertiesFromElement() in their implementation.
:rtype: bool
%End

public slots:

virtual void refresh();
Expand Down Expand Up @@ -230,6 +272,34 @@ class QgsLayoutItem : QgsLayoutObject, QGraphicsRectItem
:rtype: QPointF
%End

virtual bool writePropertiesToElement( QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context ) const;
%Docstring
Stores item state within an XML DOM element.
\param element is the DOM element to store the item's properties in
\param document DOM document
\param context read write context
.. seealso:: writeXml()
.. seealso:: readPropertiesFromElement()
.. note::

derived classes must call this base implementation when overriding this method
:rtype: bool
%End

virtual bool readPropertiesFromElement( const QDomElement &element, const QDomDocument &document, const QgsReadWriteContext &context );
%Docstring
Sets item state from a DOM element.
\param element is the DOM element for the item
\param document DOM document
\param context read write context
.. seealso:: writePropertiesToElement()
.. seealso:: readXml()
.. note::

derived classes must call this base implementation when overriding this method
:rtype: bool
%End

};


Expand Down
2 changes: 2 additions & 0 deletions python/core/layout/qgslayoutitemmap.sip
Expand Up @@ -24,6 +24,8 @@ class QgsLayoutItemMap : QgsLayoutItem
%Docstring
Constructor for QgsLayoutItemMap, with the specified parent ``layout``.
%End
virtual int type() const;
virtual QString stringType() const;

protected:

Expand Down
1 change: 1 addition & 0 deletions python/core/layout/qgslayoutitemregistry.sip
Expand Up @@ -101,6 +101,7 @@ class QgsLayoutItemRegistry : QObject

// known
LayoutPage,
LayoutMap,
LayoutRectangle,
LayoutEllipse,
LayoutTriangle,
Expand Down
3 changes: 3 additions & 0 deletions python/core/layout/qgslayoutitemshape.sip
Expand Up @@ -61,6 +61,7 @@ class QgsLayoutItemRectangularShape : QgsLayoutItemShape
Constructor for QgsLayoutItemRectangularShape, with the specified parent ``layout``.
%End
virtual int type() const;
virtual QString stringType() const;

static QgsLayoutItemRectangularShape *create( QgsLayout *layout, const QVariantMap &settings ) /Factory/;
%Docstring
Expand Down Expand Up @@ -107,6 +108,7 @@ class QgsLayoutItemEllipseShape : QgsLayoutItemShape
Constructor for QgsLayoutItemEllipseShape, with the specified parent ``layout``.
%End
virtual int type() const;
virtual QString stringType() const;

static QgsLayoutItemEllipseShape *create( QgsLayout *layout, const QVariantMap &settings ) /Factory/;
%Docstring
Expand Down Expand Up @@ -140,6 +142,7 @@ class QgsLayoutItemTriangleShape : QgsLayoutItemShape
Constructor for QgsLayoutItemTriangleShape, with the specified parent ``layout``.
%End
virtual int type() const;
virtual QString stringType() const;

static QgsLayoutItemTriangleShape *create( QgsLayout *layout, const QVariantMap &settings ) /Factory/;
%Docstring
Expand Down
2 changes: 2 additions & 0 deletions python/core/layout/qgslayoutobject.sip
Expand Up @@ -173,6 +173,7 @@ class QgsLayoutObject: QObject, QgsExpressionContextGenerator
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
\param context read write context
:return: true if write was successful
.. seealso:: readObjectPropertiesFromElement()
:rtype: bool
Expand All @@ -183,6 +184,7 @@ class QgsLayoutObject: QObject, QgsExpressionContextGenerator
Sets object properties from a DOM element
\param parentElement is the parent DOM element for the object
\param document DOM document
\param context read write context
:return: true if read was successful
.. seealso:: writeObjectPropertiesToElement()
:rtype: bool
Expand Down
95 changes: 95 additions & 0 deletions src/core/layout/qgslayoutitem.cpp
Expand Up @@ -208,6 +208,27 @@ double QgsLayoutItem::itemRotation() const
return rotation();
}

bool QgsLayoutItem::writeXml( QDomElement &parentElement, QDomDocument &doc, const QgsReadWriteContext &context ) const
{
QDomElement element = doc.createElement( "LayoutItem" );
element.setAttribute( "type", stringType() );

writePropertiesToElement( element, doc, context );
parentElement.appendChild( element );

return true;
}

bool QgsLayoutItem::readXml( const QDomElement &itemElem, const QDomDocument &doc, const QgsReadWriteContext &context )
{
if ( itemElem.nodeName() != QString( "LayoutItem" ) || itemElem.attribute( "type" ) != stringType() )
{
return false;
}

return readPropertiesFromElement( itemElem, doc, context );
}

QgsLayoutPoint QgsLayoutItem::applyDataDefinedPosition( const QgsLayoutPoint &position )
{
if ( !mLayout )
Expand Down Expand Up @@ -387,6 +408,80 @@ QPointF QgsLayoutItem::positionAtReferencePoint( const QgsLayoutItem::ReferenceP
return mapToScene( pointWithinItem );
}

bool QgsLayoutItem::writePropertiesToElement( QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context ) const
{
// element.setAttribute( "uuid", mUuid );
// element.setAttribute( "id", mId );
element.setAttribute( QStringLiteral( "referencePoint" ), QString::number( static_cast< int >( mReferencePoint ) ) );
element.setAttribute( QStringLiteral( "position" ), mItemPosition.encodePoint() );
element.setAttribute( QStringLiteral( "size" ), mItemSize.encodeSize() );
element.setAttribute( QStringLiteral( "rotation" ), QString::number( rotation() ) );

//TODO
/*
composerItemElem.setAttribute( "zValue", QString::number( zValue() ) );
composerItemElem.setAttribute( "visibility", isVisible() );
//position lock for mouse moves/resizes
if ( mItemPositionLocked )
{
composerItemElem.setAttribute( "positionLock", "true" );
}
else
{
composerItemElem.setAttribute( "positionLock", "false" );
}
*/

//blend mode
// composerItemElem.setAttribute( "blendMode", QgsMapRenderer::getBlendModeEnum( mBlendMode ) );

//transparency
// composerItemElem.setAttribute( "transparency", QString::number( mTransparency ) );

// composerItemElem.setAttribute( "excludeFromExports", mExcludeFromExports );

writeObjectPropertiesToElement( element, document, context );
return true;
}

bool QgsLayoutItem::readPropertiesFromElement( const QDomElement &element, const QDomDocument &document, const QgsReadWriteContext &context )
{
readObjectPropertiesFromElement( element, document, context );

// mUuid = element.attribute( "uuid", QUuid::createUuid().toString() );
// setId( element.attribute( "id" ) );
mReferencePoint = static_cast< ReferencePoint >( element.attribute( QStringLiteral( "referencePoint" ) ).toInt() );
attemptMove( QgsLayoutPoint::decodePoint( element.attribute( QStringLiteral( "position" ) ) ) );
attemptResize( QgsLayoutSize::decodeSize( element.attribute( QStringLiteral( "size" ) ) ) );
setItemRotation( element.attribute( QStringLiteral( "rotation" ), QStringLiteral( "0" ) ).toDouble() );

//TODO
/*
// temporary for groups imported from templates
mTemplateUuid = itemElem.attribute( "templateUuid" );
//position lock for mouse moves/resizes
QString positionLock = itemElem.attribute( "positionLock" );
if ( positionLock.compare( "true", Qt::CaseInsensitive ) == 0 )
{
setPositionLock( true );
}
else
{
setPositionLock( false );
}
//visibility
setVisibility( itemElem.attribute( "visibility", "1" ) != "0" );
setZValue( itemElem.attribute( "zValue" ).toDouble() );
//blend mode
setBlendMode( QgsMapRenderer::getCompositionMode(( QgsMapRenderer::BlendMode ) itemElem.attribute( "blendMode", "0" ).toUInt() ) );
//transparency
setTransparency( itemElem.attribute( "transparency", "0" ).toInt() );
mExcludeFromExports = itemElem.attribute( "excludeFromExports", "0" ).toInt();
mEvaluatedExcludeFromExports = mExcludeFromExports;
*/
return true;
}

void QgsLayoutItem::initConnectionsToLayout()
{
if ( !mLayout )
Expand Down
56 changes: 56 additions & 0 deletions src/core/layout/qgslayoutitem.h
Expand Up @@ -59,6 +59,20 @@ class CORE_EXPORT QgsLayoutItem : public QgsLayoutObject, public QGraphicsRectIt
*/
explicit QgsLayoutItem( QgsLayout *layout );

/**
* Return correct graphics item type
* \see stringType()
*/
virtual int type() const = 0;

/**
* Return the item type as a string.
*
* This string must be a unique, single word, character only representation of the item type, eg "LayoutScaleBar"
* \see type()
*/
virtual QString stringType() const = 0;

/**
* Handles preparing a paint surface for the layout item and painting the item's
* content. Derived classes must not override this method, but instead implement
Expand Down Expand Up @@ -146,6 +160,26 @@ class CORE_EXPORT QgsLayoutItem : public QgsLayoutObject, public QGraphicsRectIt
//TODO
double itemRotation() const;

/**
* Stores the item state in a DOM element.
* \param parentElement parent DOM element (e.g. 'Layout' element)
* \param document DOM document
* \param context read write context
* \see readXml()
* \note Subclasses should ensure that they call writePropertiesToElement() in their implementation.
*/
virtual bool writeXml( QDomElement &parentElement, QDomDocument &document, const QgsReadWriteContext &context ) const;

/**
* Sets the item state from a DOM element.
* \param itemElement is the DOM node corresponding to item (e.g. 'LayoutItem' element)
* \param document DOM document
* \param context read write context
* \see writeXml()
* \note Subclasses should ensure that they call readPropertiesFromElement() in their implementation.
*/
virtual bool readXml( const QDomElement &itemElement, const QDomDocument &document, const QgsReadWriteContext &context );

public slots:

/**
Expand Down Expand Up @@ -242,6 +276,28 @@ class CORE_EXPORT QgsLayoutItem : public QgsLayoutObject, public QGraphicsRectIt
*/
QPointF positionAtReferencePoint( const ReferencePoint &reference ) const;

/**
* Stores item state within an XML DOM element.
* \param element is the DOM element to store the item's properties in
* \param document DOM document
* \param context read write context
* \see writeXml()
* \see readPropertiesFromElement()
* \note derived classes must call this base implementation when overriding this method
*/
virtual bool writePropertiesToElement( QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context ) const;

/**
* Sets item state from a DOM element.
* \param element is the DOM element for the item
* \param document DOM document
* \param context read write context
* \see writePropertiesToElement()
* \see readXml()
* \note derived classes must call this base implementation when overriding this method
*/
virtual bool readPropertiesFromElement( const QDomElement &element, const QDomDocument &document, const QgsReadWriteContext &context );

private:

ReferencePoint mReferencePoint = UpperLeft;
Expand Down
3 changes: 3 additions & 0 deletions src/core/layout/qgslayoutitemmap.h
Expand Up @@ -19,6 +19,7 @@

#include "qgis_core.h"
#include "qgslayoutitem.h"
#include "qgslayoutitemregistry.h"

/**
* \ingroup core
Expand All @@ -37,6 +38,8 @@ class CORE_EXPORT QgsLayoutItemMap : public QgsLayoutItem
* Constructor for QgsLayoutItemMap, with the specified parent \a layout.
*/
explicit QgsLayoutItemMap( QgsLayout *layout );
int type() const override { return QgsLayoutItemRegistry::LayoutMap; }
QString stringType() const override { return QStringLiteral( "ItemMap" ); }

protected:

Expand Down
2 changes: 2 additions & 0 deletions src/core/layout/qgslayoutitemregistry.h
Expand Up @@ -183,6 +183,7 @@ class CORE_EXPORT QgsLayoutItemRegistry : public QObject

// known item types
LayoutPage, //!< Page items
LayoutMap, //!< Map item
LayoutRectangle, //!< Rectangular shape item
LayoutEllipse, //!< Ellipse shape item
LayoutTriangle, //!< Triangle shape item
Expand Down Expand Up @@ -271,6 +272,7 @@ class TestLayoutItem : public QgsLayoutItem

//implement pure virtual methods
int type() const { return QgsLayoutItemRegistry::LayoutItem + 102; }
QString stringType() const override { return QStringLiteral( "ItemTest" ); }
void draw( QgsRenderContext &context, const QStyleOptionGraphicsItem *itemStyle = nullptr );

private:
Expand Down
5 changes: 4 additions & 1 deletion src/core/layout/qgslayoutitemshape.h
Expand Up @@ -77,7 +77,8 @@ class CORE_EXPORT QgsLayoutItemRectangularShape : public QgsLayoutItemShape
* Constructor for QgsLayoutItemRectangularShape, with the specified parent \a layout.
*/
explicit QgsLayoutItemRectangularShape( QgsLayout *layout );
virtual int type() const override { return QgsLayoutItemRegistry::LayoutRectangle; }
int type() const override { return QgsLayoutItemRegistry::LayoutRectangle; }
QString stringType() const override { return QStringLiteral( "ItemRect" ); }

/**
* Returns a new rectangular item for the specified \a layout.
Expand Down Expand Up @@ -124,6 +125,7 @@ class CORE_EXPORT QgsLayoutItemEllipseShape : public QgsLayoutItemShape
*/
explicit QgsLayoutItemEllipseShape( QgsLayout *layout );
virtual int type() const override { return QgsLayoutItemRegistry::LayoutEllipse; }
QString stringType() const override { return QStringLiteral( "ItemEllipse" ); }

/**
* Returns a new ellipse item for the specified \a layout.
Expand Down Expand Up @@ -156,6 +158,7 @@ class CORE_EXPORT QgsLayoutItemTriangleShape : public QgsLayoutItemShape
*/
explicit QgsLayoutItemTriangleShape( QgsLayout *layout );
virtual int type() const override { return QgsLayoutItemRegistry::LayoutTriangle; }
QString stringType() const override { return QStringLiteral( "ItemTriangle" ); }

/**
* Returns a new triangle item for the specified \a layout.
Expand Down

0 comments on commit a515e95

Please sign in to comment.