Skip to content

Commit

Permalink
[layouts] Rework API for item export to multi-layered exports
Browse files Browse the repository at this point in the history
Reworks the QgsLayoutItem API for handling multi-layered exports
to work as an iterator. The advantage with this is that it avoids
items needing to calculate in advance how many layers they require
in the output file.
  • Loading branch information
nyalldawson committed Aug 13, 2019
1 parent 07c8c54 commit 5660912
Show file tree
Hide file tree
Showing 13 changed files with 425 additions and 128 deletions.
37 changes: 36 additions & 1 deletion python/core/auto_generated/layout/qgslayoutitem.sip.in
Expand Up @@ -405,7 +405,7 @@ Returns the behavior of this item during exporting to layered exports (e.g. SVG)
.. versionadded:: 3.10
%End

virtual int numberExportLayers() const;
virtual int numberExportLayers() const /Deprecated/;
%Docstring
Returns the number of layers that this item requires for exporting during layered exports (e.g. SVG).
Returns 0 if this item is to be placed on the same layer as the previous item,
Expand All @@ -417,6 +417,41 @@ their rendering to determine which layer should be drawn.
.. seealso:: :py:func:`exportLayerBehavior`

.. seealso:: :py:func:`exportLayerDetails`

.. deprecated:: Use nextExportPart() and exportLayerBehavior() instead.
%End

virtual void startLayeredExport();
%Docstring
Starts a multi-layer export operation.

.. seealso:: :py:func:`stopLayeredExport`

.. seealso:: :py:func:`nextExportPart`

.. versionadded:: 3.10
%End

virtual void stopLayeredExport();
%Docstring
Stops a multi-layer export operation.

.. seealso:: :py:func:`startLayeredExport`

.. seealso:: :py:func:`nextExportPart`

.. versionadded:: 3.10
%End

virtual bool nextExportPart();
%Docstring
Moves to the next export part for a multi-layered export item, during a multi-layered export.

.. seealso:: :py:func:`startLayeredExport`

.. seealso:: :py:func:`stopLayeredExport`

.. versionadded:: 3.10
%End

struct ExportLayerDetail
Expand Down
6 changes: 6 additions & 0 deletions python/core/auto_generated/layout/qgslayoutitemmap.sip.in
Expand Up @@ -89,6 +89,12 @@ The caller takes responsibility for deleting the returned object.

virtual int numberExportLayers() const;

virtual void startLayeredExport();

virtual void stopLayeredExport();

virtual bool nextExportPart();

virtual ExportLayerBehavior exportLayerBehavior() const;

virtual QgsLayoutItem::ExportLayerDetail exportLayerDetails( int layer ) const;
Expand Down
10 changes: 8 additions & 2 deletions python/core/auto_generated/layout/qgslayoutrendercontext.sip.in
Expand Up @@ -183,7 +183,7 @@ whether they will be rendered in layout exports.
.. seealso:: :py:func:`setPagesVisible`
%End

void setCurrentExportLayer( int layer = -1 );
void setCurrentExportLayer( int layer = -1 ) /Deprecated/;
%Docstring
Sets the current item ``layer`` to draw while exporting. QgsLayoutItem subclasses
which support multi-layer SVG exports must check the currentExportLayer()
Expand All @@ -192,9 +192,12 @@ and customize their rendering based on the layer.
If ``layer`` is -1, all item layers will be rendered.

.. seealso:: :py:func:`currentExportLayer`

.. deprecated:: Items should now handle this themselves, via QgsLayoutItem.exportLayerBehavior() and
returning :py:func:`QgsLayoutItem.nextExportPart()`
%End

int currentExportLayer() const;
int currentExportLayer() const /Deprecated/;
%Docstring
Returns the current item layer to draw while exporting. QgsLayoutItem subclasses
which support multi-layer SVG exports must check this
Expand All @@ -203,6 +206,9 @@ and customize their rendering based on the layer.
If ``layer`` is -1, all item layers should be rendered.

.. seealso:: :py:func:`setCurrentExportLayer`

.. deprecated:: Items should now handle this themselves, via QgsLayoutItem.exportLayerBehavior() and
returning :py:func:`QgsLayoutItem.nextExportPart()`
%End

QgsRenderContext::TextRenderFormat textRenderFormat() const;
Expand Down
19 changes: 18 additions & 1 deletion src/core/layout/qgslayoutexporter.cpp
Expand Up @@ -307,6 +307,7 @@ class LayoutContextSettingsRestorer
{
public:

Q_NOWARN_DEPRECATED_PUSH
LayoutContextSettingsRestorer( QgsLayout *layout )
: mLayout( layout )
, mPreviousDpi( layout->renderContext().dpi() )
Expand All @@ -316,13 +317,16 @@ class LayoutContextSettingsRestorer
, mPreviousSimplifyMethod( layout->renderContext().simplifyMethod() )
{
}
Q_NOWARN_DEPRECATED_POP

~LayoutContextSettingsRestorer()
{
mLayout->renderContext().setDpi( mPreviousDpi );
mLayout->renderContext().setFlags( mPreviousFlags );
mLayout->renderContext().setTextRenderFormat( mPreviousTextFormat );
Q_NOWARN_DEPRECATED_PUSH
mLayout->renderContext().setCurrentExportLayer( mPreviousExportLayer );
Q_NOWARN_DEPRECATED_POP
mLayout->renderContext().setSimplifyMethod( mPreviousSimplifyMethod );
}

Expand Down Expand Up @@ -1582,16 +1586,29 @@ QgsLayoutExporter::ExportResult QgsLayoutExporter::handleLayeredExport( const QL

if ( layoutItem && layoutItem->exportLayerBehavior() == QgsLayoutItem::ItemContainsSubLayers )
{
for ( int layoutItemLayerIdx = 0; layoutItemLayerIdx < layoutItem->numberExportLayers(); layoutItemLayerIdx++ )
int layoutItemLayerIdx = 0;
Q_NOWARN_DEPRECATED_PUSH
mLayout->renderContext().setCurrentExportLayer( layoutItemLayerIdx );
Q_NOWARN_DEPRECATED_POP
layoutItem->startLayeredExport();
while ( layoutItem->nextExportPart() )
{
Q_NOWARN_DEPRECATED_PUSH
mLayout->renderContext().setCurrentExportLayer( layoutItemLayerIdx );
Q_NOWARN_DEPRECATED_POP

layerDetails = layoutItem->exportLayerDetails( layoutItemLayerIdx );
ExportResult result = exportFunc( layerId, layerDetails );
if ( result != Success )
return result;
layerId++;

layoutItemLayerIdx++;
}
Q_NOWARN_DEPRECATED_PUSH
mLayout->renderContext().setCurrentExportLayer( -1 );
Q_NOWARN_DEPRECATED_POP
layoutItem->stopLayeredExport();
currentLayerItems.clear();
}
else
Expand Down
28 changes: 28 additions & 0 deletions src/core/layout/qgslayoutitem.cpp
Expand Up @@ -249,6 +249,34 @@ QgsLayoutItem::ExportLayerBehavior QgsLayoutItem::exportLayerBehavior() const
return CanGroupWithAnyOtherItem;
}

int QgsLayoutItem::numberExportLayers() const
{
return 0;
}

void QgsLayoutItem::startLayeredExport()
{

}

void QgsLayoutItem::stopLayeredExport()
{

}

bool QgsLayoutItem::nextExportPart()
{
Q_NOWARN_DEPRECATED_PUSH
if ( !mLayout || mLayout->renderContext().currentExportLayer() == -1 )
return false;

// QGIS 4- return false from base class implementation

const int layers = numberExportLayers();
return mLayout->renderContext().currentExportLayer() < layers;
Q_NOWARN_DEPRECATED_POP
}

QgsLayoutItem::ExportLayerDetail QgsLayoutItem::exportLayerDetails( int ) const
{
return QgsLayoutItem::ExportLayerDetail();
Expand Down
31 changes: 30 additions & 1 deletion src/core/layout/qgslayoutitem.h
Expand Up @@ -444,8 +444,37 @@ class CORE_EXPORT QgsLayoutItem : public QgsLayoutObject, public QGraphicsRectIt
*
* \see exportLayerBehavior()
* \see exportLayerDetails()
*
* \deprecated Use nextExportPart() and exportLayerBehavior() instead.
*/
Q_DECL_DEPRECATED virtual int numberExportLayers() const SIP_DEPRECATED;

/**
* Starts a multi-layer export operation.
*
* \see stopLayeredExport()
* \see nextExportPart()
* \since QGIS 3.10
*/
virtual void startLayeredExport();

/**
* Stops a multi-layer export operation.
*
* \see startLayeredExport()
* \see nextExportPart()
* \since QGIS 3.10
*/
virtual void stopLayeredExport();

/**
* Moves to the next export part for a multi-layered export item, during a multi-layered export.
*
* \see startLayeredExport()
* \see stopLayeredExport()
* \since QGIS 3.10
*/
virtual int numberExportLayers() const { return 0; }
virtual bool nextExportPart();

/**
* Contains details of a particular export layer relating to a layout item.
Expand Down

0 comments on commit 5660912

Please sign in to comment.