Skip to content

Commit

Permalink
Implement some saving/restoring layout items to XML
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Sep 4, 2017
1 parent 66e1cf0 commit 1589b4e
Show file tree
Hide file tree
Showing 31 changed files with 986 additions and 38 deletions.
1 change: 1 addition & 0 deletions python/core/core_auto.sip
Expand Up @@ -160,6 +160,7 @@
%Include layout/qgslayoutmeasurementconverter.sip
%Include layout/qgspagesizeregistry.sip
%Include layout/qgslayoutpoint.sip
%Include layout/qgslayoutserializableobject.sip
%Include layout/qgslayoutsize.sip
%Include layout/qgslayoutsnapper.sip
%Include layout/qgslayoututils.sip
Expand Down
15 changes: 15 additions & 0 deletions python/core/layout/qgslayout.sip
Expand Up @@ -255,6 +255,21 @@ class QgsLayout : QGraphicsScene, QgsExpressionContextGenerator
method. Ownership of the item is transferred to the layout.
%End

QDomElement writeXml( QDomDocument &document, const QgsReadWriteContext &context ) const;
%Docstring
Returns the layout's state encapsulated in a DOM element.
.. seealso:: readXml()
:rtype: QDomElement
%End

bool readXml( const QDomElement &layoutElement, const QDomDocument &document, const QgsReadWriteContext &context );
%Docstring
Sets the collection's state from a DOM element. ``layoutElement`` is the DOM node corresponding to the layout.
.. seealso:: writeXml()
:rtype: bool
%End


public slots:

void updateBounds();
Expand Down
24 changes: 22 additions & 2 deletions python/core/layout/qgslayoutgridsettings.sip
Expand Up @@ -8,7 +8,7 @@



class QgsLayoutGridSettings
class QgsLayoutGridSettings : QgsLayoutSerializableObject
{
%Docstring
Contains settings relating to the appearance, spacing and offset for layout grids.
Expand All @@ -27,11 +27,15 @@ class QgsLayoutGridSettings
StyleCrosses
};

QgsLayoutGridSettings();
QgsLayoutGridSettings( QgsLayout *layout );
%Docstring
Constructor for QgsLayoutGridSettings.
%End

virtual QString stringType() const;
virtual QgsLayout *layout();


void setResolution( const QgsLayoutMeasurement &resolution );
%Docstring
Sets the page/snap grid ``resolution``.
Expand Down Expand Up @@ -92,6 +96,22 @@ class QgsLayoutGridSettings
:rtype: Style
%End

virtual bool writeXml( QDomElement &parentElement, QDomDocument &document, const QgsReadWriteContext &context ) const;

%Docstring
Stores the grid's state in a DOM element. The ``parentElement`` should refer to the parent layout's DOM element.
.. seealso:: readXml()
:rtype: bool
%End

virtual bool readXml( const QDomElement &gridElement, const QDomDocument &document, const QgsReadWriteContext &context );

%Docstring
Sets the grid's state from a DOM element. gridElement is the DOM node corresponding to the grid.
.. seealso:: writeXml()
:rtype: bool
%End

};

/************************************************************************
Expand Down
27 changes: 26 additions & 1 deletion python/core/layout/qgslayoutguidecollection.sip
Expand Up @@ -132,7 +132,7 @@ class QgsLayoutGuide : QObject

};

class QgsLayoutGuideCollection : QAbstractTableModel
class QgsLayoutGuideCollection : QAbstractTableModel, QgsLayoutSerializableObject
{
%Docstring
Stores and manages the snap guides used by a layout.
Expand Down Expand Up @@ -160,6 +160,10 @@ class QgsLayoutGuideCollection : QAbstractTableModel
%End
~QgsLayoutGuideCollection();

virtual QString stringType() const;
virtual QgsLayout *layout();


virtual int rowCount( const QModelIndex & ) const;

virtual int columnCount( const QModelIndex & ) const;
Expand Down Expand Up @@ -188,6 +192,11 @@ class QgsLayoutGuideCollection : QAbstractTableModel
.. seealso:: clear()
%End

void setGuideLayoutPosition( QgsLayoutGuide *guide, double position );
%Docstring
Sets the absolute ``position`` (in layout coordinates) for ``guide`` within the layout.
%End

void clear();
%Docstring
Removes all guides from the collection.
Expand Down Expand Up @@ -233,6 +242,22 @@ class QgsLayoutGuideCollection : QAbstractTableModel
.. seealso:: visible()
%End

virtual bool writeXml( QDomElement &parentElement, QDomDocument &document, const QgsReadWriteContext &context ) const;

%Docstring
Stores the collection's state in a DOM element. The ``parentElement`` should refer to the parent layout's DOM element.
.. seealso:: readXml()
:rtype: bool
%End

virtual bool readXml( const QDomElement &collectionElement, const QDomDocument &document, const QgsReadWriteContext &context );

%Docstring
Sets the collection's state from a DOM element. collectionElement is the DOM node corresponding to the collection.
.. seealso:: writeXml()
:rtype: bool
%End

};


Expand Down
10 changes: 10 additions & 0 deletions python/core/layout/qgslayoutitempage.sip
Expand Up @@ -32,6 +32,16 @@ class QgsLayoutItemPage : QgsLayoutItem
%Docstring
Constructor for QgsLayoutItemPage, with the specified parent ``layout``.
%End

static QgsLayoutItemPage *create( QgsLayout *layout, const QVariantMap &settings ) /Factory/;
%Docstring
Returns a new page item for the specified ``layout``.

The caller takes responsibility for deleting the returned object.
:rtype: QgsLayoutItemPage
%End


virtual int type() const;
virtual QString stringType() const;

Expand Down
32 changes: 26 additions & 6 deletions python/core/layout/qgslayoutpagecollection.sip
Expand Up @@ -9,7 +9,7 @@



class QgsLayoutPageCollection : QObject
class QgsLayoutPageCollection : QObject, QgsLayoutSerializableObject
{
%Docstring
A manager for a collection of pages in a layout.
Expand All @@ -28,11 +28,9 @@ class QgsLayoutPageCollection : QObject

~QgsLayoutPageCollection();

QgsLayout *layout() const;
%Docstring
Returns the layout this collection belongs to.
:rtype: QgsLayout
%End
virtual QString stringType() const;
virtual QgsLayout *layout();


QList< QgsLayoutItemPage * > pages();
%Docstring
Expand Down Expand Up @@ -130,6 +128,12 @@ class QgsLayoutPageCollection : QObject
Calling deletePage() automatically triggers a reflow() of pages.
%End

QgsLayoutItemPage *takePage( QgsLayoutItemPage *page ) /TransferBack/;
%Docstring
Takes a ``page`` from the collection, returning ownership of the page to the caller.
:rtype: QgsLayoutItemPage
%End

void setPageStyleSymbol( QgsFillSymbol *symbol );
%Docstring
Sets the ``symbol`` to use for drawing pages in the collection.
Expand Down Expand Up @@ -211,6 +215,22 @@ class QgsLayoutPageCollection : QObject
:rtype: float
%End

virtual bool writeXml( QDomElement &parentElement, QDomDocument &document, const QgsReadWriteContext &context ) const;

%Docstring
Stores the collection's state in a DOM element. The ``parentElement`` should refer to the parent layout's DOM element.
.. seealso:: readXml()
:rtype: bool
%End

virtual bool readXml( const QDomElement &collectionElement, const QDomDocument &document, const QgsReadWriteContext &context );

%Docstring
Sets the collection's state from a DOM element. collectionElement is the DOM node corresponding to the collection.
.. seealso:: writeXml()
:rtype: bool
%End

public slots:

void redraw();
Expand Down
63 changes: 63 additions & 0 deletions python/core/layout/qgslayoutserializableobject.sip
@@ -0,0 +1,63 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/layout/qgslayoutserializableobject.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/





class QgsLayoutSerializableObject
{
%Docstring
An interface for layout objects which can be stored and read from DOM elements.
.. versionadded:: 3.0
%End

%TypeHeaderCode
#include "qgslayoutserializableobject.h"
%End
public:

virtual ~QgsLayoutSerializableObject();

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

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

virtual QgsLayout *layout() = 0;
%Docstring
Returns the layout the object belongs to.
:rtype: QgsLayout
%End

virtual bool writeXml( QDomElement &parentElement, QDomDocument &document, const QgsReadWriteContext &context ) const = 0;
%Docstring
Stores the objects's state in a DOM element. The ``parentElement`` should refer to the parent layout's DOM element.
.. seealso:: readXml()
:rtype: bool
%End

virtual bool readXml( const QDomElement &element, const QDomDocument &document, const QgsReadWriteContext &context ) = 0;
%Docstring
Sets the objects's state from a DOM element. ``element`` is the DOM node corresponding to the object.
.. seealso:: writeXml()
:rtype: bool
%End

};

/************************************************************************
* This file has been generated automatically from *
* *
* src/core/layout/qgslayoutserializableobject.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
22 changes: 21 additions & 1 deletion python/core/layout/qgslayoutsnapper.sip
Expand Up @@ -8,7 +8,7 @@



class QgsLayoutSnapper
class QgsLayoutSnapper: QgsLayoutSerializableObject
{
%Docstring
Manages snapping grids and preset snap lines in a layout, and handles
Expand All @@ -26,6 +26,10 @@ class QgsLayoutSnapper
Constructor for QgsLayoutSnapper, attached to the specified ``layout``.
%End

virtual QString stringType() const;
virtual QgsLayout *layout();


void setSnapTolerance( const int snapTolerance );
%Docstring
Sets the snap ``tolerance`` (in pixels) to use when snapping.
Expand Down Expand Up @@ -106,6 +110,22 @@ class QgsLayoutSnapper
:rtype: float
%End

virtual bool writeXml( QDomElement &parentElement, QDomDocument &document, const QgsReadWriteContext &context ) const;

%Docstring
Stores the snapper's state in a DOM element. The ``parentElement`` should refer to the parent layout's DOM element.
.. seealso:: readXml()
:rtype: bool
%End

virtual bool readXml( const QDomElement &gridElement, const QDomDocument &document, const QgsReadWriteContext &context );

%Docstring
Sets the snapper's state from a DOM element. snapperElement is the DOM node corresponding to the snapper.
.. seealso:: writeXml()
:rtype: bool
%End

};

/************************************************************************
Expand Down
2 changes: 2 additions & 0 deletions src/core/CMakeLists.txt
Expand Up @@ -367,6 +367,7 @@ SET(QGIS_CORE_SRCS
layout/qgslayoututils.cpp
layout/qgspagesizeregistry.cpp
layout/qgslayoutpoint.cpp
layout/qgslayoutserializableobject.cpp
layout/qgslayoutsize.cpp

pal/costcalculator.cpp
Expand Down Expand Up @@ -938,6 +939,7 @@ SET(QGIS_CORE_HDRS
layout/qgslayoutmeasurementconverter.h
layout/qgspagesizeregistry.h
layout/qgslayoutpoint.h
layout/qgslayoutserializableobject.h
layout/qgslayoutsize.h
layout/qgslayoutsnapper.h
layout/qgslayoututils.h
Expand Down
44 changes: 44 additions & 0 deletions src/core/layout/qgslayout.cpp
Expand Up @@ -22,6 +22,7 @@ QgsLayout::QgsLayout( QgsProject *project )
: QGraphicsScene()
, mProject( project )
, mSnapper( QgsLayoutSnapper( this ) )
, mGridSettings( this )
, mPageCollection( new QgsLayoutPageCollection( this ) )
, mGuideCollection( new QgsLayoutGuideCollection( this, mPageCollection.get() ) )
{
Expand Down Expand Up @@ -211,6 +212,49 @@ void QgsLayout::addLayoutItem( QgsLayoutItem *item )
updateBounds();
}

QDomElement QgsLayout::writeXml( QDomDocument &document, const QgsReadWriteContext &context ) const
{
QDomElement element = document.createElement( QStringLiteral( "Layout" ) );
auto save = [&]( const QgsLayoutSerializableObject * object )->bool
{
return object->writeXml( element, document, context );
};
save( &mSnapper );
save( &mGridSettings );
save( mPageCollection.get() );
save( mGuideCollection.get() );

mCustomProperties.writeXml( element, document );
element.setAttribute( QStringLiteral( "name" ), mName );
element.setAttribute( QStringLiteral( "units" ), QgsUnitTypes::encodeUnit( mUnits ) );

return element;
}

bool QgsLayout::readXml( const QDomElement &layoutElement, const QDomDocument &document, const QgsReadWriteContext &context )
{
if ( layoutElement.nodeName() != QString( "Layout" ) )
{
return false;
}

auto restore = [&]( QgsLayoutSerializableObject * object )->bool
{
return object->readXml( layoutElement, document, context );
};

mCustomProperties.readXml( layoutElement );
setName( layoutElement.attribute( QStringLiteral( "name" ) ) );
setUnits( QgsUnitTypes::decodeLayoutUnit( layoutElement.attribute( QStringLiteral( "units" ) ) ) );

restore( mPageCollection.get() );
restore( mGuideCollection.get() );
restore( &mSnapper );
restore( &mGridSettings );

return true;
}

void QgsLayout::updateBounds()
{
setSceneRect( layoutBounds( false, 0.05 ) );
Expand Down

0 comments on commit 1589b4e

Please sign in to comment.