Skip to content

Commit

Permalink
Merge pull request #5913 from elpaso/layouts-import-from-2
Browse files Browse the repository at this point in the history
[layouts] import from 2.x
  • Loading branch information
elpaso committed Jan 9, 2018
2 parents 5babec5 + 6332fc6 commit 03400dd
Show file tree
Hide file tree
Showing 68 changed files with 6,336 additions and 35 deletions.
4 changes: 4 additions & 0 deletions .ci/travis/linux/blacklist.txt
Expand Up @@ -37,3 +37,7 @@ PyQgsLocator
PyQgsAuthManagerPKIPostgresTest
PyQgsAuthManagerPasswordPostgresTest
PyQgsAuthManagerOgrPostgresTest

# temporary disable for composition -> layout transition
PyQgsServerWMS
PyQgsServerWMSGetPrint
1 change: 1 addition & 0 deletions python/core/layout/qgslayout.sip
Expand Up @@ -87,6 +87,7 @@ Returns the items model attached to the layout.
%End



QList<QgsLayoutItem *> selectedLayoutItems( const bool includeLockedItems = true );
%Docstring
Returns list of selected layout items.
Expand Down
2 changes: 1 addition & 1 deletion python/core/layout/qgslayoutitemattributetable.sip
Expand Up @@ -63,7 +63,7 @@ Returns the source for attributes shown in the table body.
.. seealso:: :py:func:`setSource()`
%End

QgsVectorLayer *sourceLayer();
QgsVectorLayer *sourceLayer() const;
%Docstring
Returns the source layer for the table, considering the table source mode. For example,
if the table is set to atlas feature mode, then the source layer will be the
Expand Down
2 changes: 1 addition & 1 deletion python/core/layout/qgslayoutitemlabel.sip
Expand Up @@ -61,7 +61,7 @@ Returns the required item size (in layout units) for the label's text to fill th
.. seealso:: :py:func:`adjustSizeToText()`
%End

QString text();
QString text() const;
%Docstring
Returns the label's preset text.

Expand Down
8 changes: 8 additions & 0 deletions python/core/layout/qgslayoutitemshape.sip
Expand Up @@ -34,6 +34,14 @@ class QgsLayoutItemShape : QgsLayoutItem
Constructor for QgsLayoutItemShape, with the specified parent ``layout``.
%End

static QgsLayoutItemShape *create( QgsLayout *layout ) /Factory/;
%Docstring
Returns a new shape item for the specified ``layout``.

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


virtual int type() const;

virtual QIcon icon() const;
Expand Down
5 changes: 4 additions & 1 deletion python/core/qgsmultirenderchecker.sip
Expand Up @@ -163,13 +163,16 @@ Constructor for QgsLayoutChecker.
Sets the output (reference) image ``size``.
%End

bool testLayout( QString &report, int page = 0, int pixelDiff = 0 );
bool testLayout( QString &report, int page = 0, int pixelDiff = 0, bool createReferenceImage = false );
%Docstring
Runs a render check on the layout, adding results to the specified ``report``.

The maximum number of allowable pixels differing from the reference image is
specified via the ``pixelDiff`` argument.

A reference image can be created by setting ``createReferenceImage`` to true
in this case the test will always return true.

The page number is specified via ``page``, where 0 corresponds to the first
page in the layout.

Expand Down
3 changes: 3 additions & 0 deletions scripts/spell_check/.agignore
Expand Up @@ -62,3 +62,6 @@ src/server/qgis_wms.xmi
tests/testdata/qgis_server_accesscontrol/Hello.qml
tests/testdata/qgis_server_accesscontrol/project.qgs
tests/testdata/qgis_server/ets-wms13/project.qgs
tests/testdata/layouts/sample_project.qgs
tests/testdata/layouts/2x_template_attributetable.qpt

2 changes: 2 additions & 0 deletions src/core/CMakeLists.txt
Expand Up @@ -418,6 +418,7 @@ SET(QGIS_CORE_SRCS
layout/qgsreport.cpp
layout/qgsreportsectionfieldgroup.cpp
layout/qgsreportsectionlayout.cpp
layout/qgscompositionconverter.cpp

pal/costcalculator.cpp
pal/feature.cpp
Expand Down Expand Up @@ -1052,6 +1053,7 @@ SET(QGIS_CORE_HDRS
layout/qgslayoututils.h
layout/qgsreportsectionfieldgroup.h
layout/qgsreportsectionlayout.h
layout/qgscompositionconverter.h

metadata/qgslayermetadata.h
metadata/qgslayermetadatavalidator.h
Expand Down
1 change: 1 addition & 0 deletions src/core/composer/qgscomposerlegend.h
Expand Up @@ -350,6 +350,7 @@ class CORE_EXPORT QgsComposerLegend : public QgsComposerItem

//! Will be true if the legend should be resized automatically to fit contents
bool mSizeToContents = true;

};

#endif
Expand Down
1,676 changes: 1,676 additions & 0 deletions src/core/layout/qgscompositionconverter.cpp

Large diffs are not rendered by default.

231 changes: 231 additions & 0 deletions src/core/layout/qgscompositionconverter.h
@@ -0,0 +1,231 @@
/***************************************************************************
qgscompositionconverter.h - Convert a QGIS 2.x composition to a layout
---------------------
begin : 13.12.2017
copyright : (C) 2017 by Alessandro Pasotti
email : elpaso at itopen dot it
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSCOMPOSITIONCONVERTER_H
#define QGSCOMPOSITIONCONVERTER_H


#include <QDomDocument>
#include <QDomElement>

#include "qgis.h"
#include "qgis_sip.h"

#define SIP_NO_FILE

#include "qgspropertycollection.h"

class QgsPrintLayout;
class QgsLayoutItem;
class QgsLayoutObject;
class QgsReadWriteContext;
class QgsProperty;
class QgsPropertyCollection;

class QgsLayoutItemLabel;
class QgsLayoutItemShape;
class QgsLayoutItemPicture;
class QgsLayoutItemPolygon;
class QgsLayoutItemPolyline;
class QgsLayoutItemMap;
class QgsLayoutItemScaleBar;
class QgsLayoutItemLegend;
class QgsLayoutItemHtml;
class QgsLayoutItemAttributeTable;


/**
* QgsCompositionConverter class converts a QGIS 2.x composition to a QGIS 3.x layout
* \since QGIS 3.0
* \note Not available in Python bindings.
* \ingroup core
*/
class CORE_EXPORT QgsCompositionConverter
{
public:

/**
* Composition data defined properties for different item types
*/
enum DataDefinedProperty
{
NoProperty = 0, //!< No property
AllProperties, //!< All properties for item
TestProperty, //!< Dummy property with no effect on item
//composer page properties
PresetPaperSize, //!< Preset paper size for composition
PaperWidth, //!< Paper width
PaperHeight, //!< Paper height
NumPages, //!< Number of pages in composition
PaperOrientation, //!< Paper orientation
//general composer item properties
PageNumber, //!< Page number for item placement
PositionX, //!< X position on page
PositionY, //!< Y position on page
ItemWidth, //!< Width of item
ItemHeight, //!< Height of item
ItemRotation, //!< Rotation of item
Transparency, //!< Item transparency (deprecated)
Opacity, //!< Item opacity
BlendMode, //!< Item blend mode
ExcludeFromExports, //!< Exclude item from exports
FrameColor, //!< Item frame color
BackgroundColor, //!< Item background color
//composer map
MapRotation, //!< Map rotation
MapScale, //!< Map scale
MapXMin, //!< Map extent x minimum
MapYMin, //!< Map extent y minimum
MapXMax, //!< Map extent x maximum
MapYMax, //!< Map extent y maximum
MapAtlasMargin, //!< Map atlas margin
MapLayers, //!< Map layer set
MapStylePreset, //!< Layer and style map theme
//composer picture
PictureSource, //!< Picture source url
PictureSvgBackgroundColor, //!< SVG background color
PictureSvgStrokeColor, //!< SVG stroke color
PictureSvgStrokeWidth, //!< SVG stroke width
//html item
SourceUrl, //!< Html source url
//legend item
LegendTitle, //!< Legend title
LegendColumnCount, //!< Legend column count
//scalebar item
ScalebarFillColor, //!< Scalebar fill color
ScalebarFillColor2, //!< Scalebar secondary fill color
ScalebarLineColor, //!< Scalebar line color
ScalebarLineWidth, //!< Scalebar line width
};

/**
* The MarkerMode enum is the old QGIS 2.x arrow marker mode
*/
enum MarkerMode
{
DefaultMarker,
NoMarker,
SVGMarker
};


/**
* createLayoutFromCompositionXml is a factory that creates layout instances from a
* QGIS 2.x XML composition \a parentElement and a QGIS \a project
* \return a QgsPrintLayout instance
*/
static std::unique_ptr<QgsPrintLayout> createLayoutFromCompositionXml( const QDomElement &composerElement,
QgsProject *project );


/**
* addItemsFromCompositionXml parse a QGIS 2.x composition XML in the \a parentElement,
* converts the 2.x items to the new layout elements and add them to the \a layout
* \param layout where the items will be added
* \param parentElement parent DOM element
* \param position for pasting
* \param pasteInPlace if true element position is translated to \a position
* \return list of layout object items that have been added to the layout
*/
static QList<QgsLayoutObject *> addItemsFromCompositionXml( QgsPrintLayout *layout,
const QDomElement &parentElement,
QPointF *position = nullptr,
bool pasteInPlace = false );

private:


//! Property definitions
static QgsPropertiesDefinition sPropertyDefinitions;


static bool readLabelXml( QgsLayoutItemLabel *layoutItem,
const QDomElement &itemElem,
const QgsProject *project );

static bool readShapeXml( QgsLayoutItemShape *layoutItem,
const QDomElement &itemElem,
const QgsProject *project );

static bool readPictureXml( QgsLayoutItemPicture *layoutItem,
const QDomElement &itemElem,
const QgsProject *project,
const QgsStringMap &mapId2Uuid );

//! For both polylines and polygons
template <class T, class T2> static bool readPolyXml( T *layoutItem,
const QDomElement &itemElem,
const QgsProject *project );

static bool readArrowXml( QgsLayoutItemPolyline *layoutItem,
const QDomElement &itemElem,
const QgsProject *project );

static bool readMapXml( QgsLayoutItemMap *layoutItem,
const QDomElement &itemElem,
const QgsProject *project,
QgsStringMap &mapId2Uuid );

static bool readScaleBarXml( QgsLayoutItemScaleBar *layoutItem,
const QDomElement &itemElem,
const QgsProject *project,
const QgsStringMap &mapId2Uuid );

static bool readLegendXml( QgsLayoutItemLegend *layoutItem,
const QDomElement &itemElem,
const QgsProject *project,
const QgsStringMap &mapId2Uuid );

static bool readAtlasXml( QgsLayoutAtlas *atlasItem,
const QDomElement &itemElem,
const QgsProject *project );

static bool readHtmlXml( QgsLayoutItemHtml *layoutItem,
const QDomElement &itemElem,
const QgsProject *project );

static bool readTableXml( QgsLayoutItemAttributeTable *layoutItem,
const QDomElement &itemElem,
const QgsProject *project );

static bool readOldComposerObjectXml( QgsLayoutObject *layoutItem, const QDomElement &itemElem );

static void readOldDataDefinedPropertyMap( const QDomElement &itemElem,
QgsPropertyCollection &dataDefinedProperties );

static QgsProperty readOldDataDefinedProperty( const DataDefinedProperty property, const QDomElement &ddElem );

static void initPropertyDefinitions();

static QgsPropertiesDefinition propertyDefinitions();

//! Reads parameter that are not subclass specific in document. Usually called from readXml methods of subclasses
static bool readXml( QgsLayoutItem *layoutItem, const QDomElement &itemElem );

//! Make some common import adjustments
static void adjustPos( QgsPrintLayout *layout, QgsLayoutItem *layoutItem, QPointF *position, bool &pasteInPlace, int zOrderOffset, QPointF &pasteShiftPos, int &pageNumber );

//! Restore general composer item properties
static void restoreGeneralComposeItemProperties( QgsLayoutItem *layoutItem, const QDomElement &itemElem );

//! Get item position
static QRectF itemPosition( QgsLayoutItem *layoutItem, const QDomElement &itemElem );

//! Calculates the item minimum position from an xml string
static QPointF minPointFromXml( const QDomElement &elem );

};

#endif // QGSCOMPOSITIONCONVERTER_H
28 changes: 28 additions & 0 deletions src/core/layout/qgslayout.h
Expand Up @@ -133,6 +133,33 @@ class CORE_EXPORT QgsLayout : public QGraphicsScene, public QgsExpressionContext
}
}

/**
* Returns a list of layout objects (items and multiframes) of a specific type.
* \note not available in Python bindings
*/
template<class T> void layoutObjects( QList<T *> &objectList ) const SIP_SKIP
{
objectList.clear();
const QList<QGraphicsItem *> itemList( items() );
const QList<QgsLayoutMultiFrame *> frameList( multiFrames() );
for ( const auto &obj : itemList )
{
T *item = dynamic_cast<T *>( obj );
if ( item )
{
objectList.push_back( item );
}
}
for ( const auto &obj : frameList )
{
T *item = dynamic_cast<T *>( obj );
if ( item )
{
objectList.push_back( item );
}
}
}

/**
* Returns list of selected layout items.
*
Expand Down Expand Up @@ -678,6 +705,7 @@ class CORE_EXPORT QgsLayout : public QGraphicsScene, public QgsExpressionContext
friend class QgsLayoutItemGroupUndoCommand;
friend class QgsLayoutModel;
friend class QgsLayoutMultiFrame;
friend class QgsCompositionConverter;
};

#endif //QGSLAYOUT_H
1 change: 1 addition & 0 deletions src/core/layout/qgslayoutitem.h
Expand Up @@ -1084,6 +1084,7 @@ class CORE_EXPORT QgsLayoutItem : public QgsLayoutObject, public QGraphicsRectIt
friend class TestQgsLayoutItem;
friend class TestQgsLayoutView;
friend class QgsLayoutItemGroup;
friend class QgsCompositionConverter;
};

#endif //QGSLAYOUTITEM_H
Expand Down
2 changes: 1 addition & 1 deletion src/core/layout/qgslayoutitemattributetable.cpp
Expand Up @@ -549,7 +549,7 @@ QVariant QgsLayoutItemAttributeTable::replaceWrapChar( const QVariant &variant )
return replaced;
}

QgsVectorLayer *QgsLayoutItemAttributeTable::sourceLayer()
QgsVectorLayer *QgsLayoutItemAttributeTable::sourceLayer() const
{
switch ( mSource )
{
Expand Down
2 changes: 1 addition & 1 deletion src/core/layout/qgslayoutitemattributetable.h
Expand Up @@ -82,7 +82,7 @@ class CORE_EXPORT QgsLayoutItemAttributeTable: public QgsLayoutTable
* atlas coverage layer. If the table is set to layer attributes mode, then
* the source layer will be the user specified vector layer.
*/
QgsVectorLayer *sourceLayer();
QgsVectorLayer *sourceLayer() const;

/**
* Sets the vector \a layer from which to display feature attributes.
Expand Down

0 comments on commit 03400dd

Please sign in to comment.