[layout] Convert scalebar and legent from 2.x
@ -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
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "qgscompositionconverter.h"
|
||||
#include "qgsreadwritecontext.h"
|
||||
#include "qgslayout.h"
|
||||
#include "qgslayertree.h"
|
||||
#include "qgslayoutmodel.h"
|
||||
#include "qgslayoutitemgroup.h"
|
||||
#include "qgsfontutils.h"
|
||||
@ -37,10 +38,11 @@
|
||||
#include "qgslayoutitempolyline.h"
|
||||
#include "qgslayoutitemmap.h"
|
||||
#include "qgslayoutitemmapgrid.h"
|
||||
#include "qgslayoutitemscalebar.h"
|
||||
#include "qgslayoutitemlegend.h"
|
||||
|
||||
QgsPropertiesDefinition QgsCompositionConverter::sPropertyDefinitions;
|
||||
|
||||
|
||||
void QgsCompositionConverter::initPropertyDefinitions()
|
||||
{
|
||||
if ( !sPropertyDefinitions.isEmpty() )
|
||||
@ -209,10 +211,6 @@ QList<QgsLayoutItem *> QgsCompositionConverter::addItemsFromCompositionXml( QgsL
|
||||
}
|
||||
|
||||
/*
|
||||
LayoutPage, //!< Page items
|
||||
LayoutMap, //!< Map item
|
||||
LayoutLegend, //!< Legend item
|
||||
LayoutScaleBar, //!< Scale bar item
|
||||
LayoutFrame, //!< Frame item, part of a QgsLayoutMultiFrame object
|
||||
|
||||
// known multi-frame types
|
||||
@ -221,8 +219,6 @@ QList<QgsLayoutItem *> QgsCompositionConverter::addItemsFromCompositionXml( QgsL
|
||||
LayoutTextTable, //!< Preset text table
|
||||
*/
|
||||
|
||||
|
||||
|
||||
// Label
|
||||
for ( int i = 0; i < parentElement.elementsByTagName( QStringLiteral( "ComposerLabel" ) ).size(); i++ )
|
||||
{
|
||||
@ -293,6 +289,26 @@ QList<QgsLayoutItem *> QgsCompositionConverter::addItemsFromCompositionXml( QgsL
|
||||
newItems << layoutItem ;
|
||||
}
|
||||
|
||||
// Scalebar
|
||||
for ( int i = 0; i < parentElement.elementsByTagName( QStringLiteral( "ComposerScaleBar" ) ).size(); i++ )
|
||||
{
|
||||
QDomNode itemNode( parentElement.elementsByTagName( QStringLiteral( "ComposerScaleBar" ) ).at( i ) );
|
||||
QgsLayoutItemScaleBar *layoutItem = new QgsLayoutItemScaleBar( layout );
|
||||
readScaleBarXml( layoutItem, itemNode.toElement(), layout->project() );
|
||||
adjustPos( layout, layoutItem, itemNode, position, pasteInPlace, zOrderOffset, pasteShiftPos, pageNumber );
|
||||
newItems << layoutItem ;
|
||||
}
|
||||
|
||||
// Legend
|
||||
for ( int i = 0; i < parentElement.elementsByTagName( QStringLiteral( "ComposerLegend" ) ).size(); i++ )
|
||||
{
|
||||
QDomNode itemNode( parentElement.elementsByTagName( QStringLiteral( "ComposerLegend" ) ).at( i ) );
|
||||
QgsLayoutItemLegend *layoutItem = new QgsLayoutItemLegend( layout );
|
||||
readLegendXml( layoutItem, itemNode.toElement(), layout->project() );
|
||||
adjustPos( layout, layoutItem, itemNode, position, pasteInPlace, zOrderOffset, pasteShiftPos, pageNumber );
|
||||
newItems << layoutItem ;
|
||||
}
|
||||
|
||||
return newItems;
|
||||
}
|
||||
|
||||
@ -677,8 +693,6 @@ bool QgsCompositionConverter::readMapXml( QgsLayoutItemMap *layoutItem, const QD
|
||||
//mLayers
|
||||
layoutItem->mLayers.clear();
|
||||
|
||||
|
||||
|
||||
QDomNodeList layerSetNodeList = itemElem.elementsByTagName( QStringLiteral( "LayerSet" ) );
|
||||
if ( !layerSetNodeList.isEmpty() )
|
||||
{
|
||||
@ -844,6 +858,278 @@ bool QgsCompositionConverter::readMapXml( QgsLayoutItemMap *layoutItem, const QD
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QgsCompositionConverter::readScaleBarXml( QgsLayoutItemScaleBar *layoutItem, const QDomElement &itemElem, const QgsProject *project )
|
||||
{
|
||||
restoreGeneralComposeItemProperties( layoutItem, itemElem );
|
||||
|
||||
layoutItem->setHeight( itemElem.attribute( QStringLiteral( "height" ), QStringLiteral( "5.0" ) ).toDouble() );
|
||||
layoutItem->setHeight( itemElem.attribute( QStringLiteral( "height" ), QStringLiteral( "5.0" ) ).toDouble() );
|
||||
layoutItem->setLabelBarSpace( itemElem.attribute( QStringLiteral( "labelBarSpace" ), QStringLiteral( "3.0" ) ).toDouble() );
|
||||
layoutItem->setBoxContentSpace( itemElem.attribute( QStringLiteral( "boxContentSpace" ), QStringLiteral( "1.0" ) ).toDouble() );
|
||||
layoutItem->setNumberOfSegments( itemElem.attribute( QStringLiteral( "numSegments" ), QStringLiteral( "2" ) ).toInt() );
|
||||
layoutItem->setNumberOfSegmentsLeft( itemElem.attribute( QStringLiteral( "numSegmentsLeft" ), QStringLiteral( "0" ) ).toInt() );
|
||||
layoutItem->setUnitsPerSegment( itemElem.attribute( QStringLiteral( "numUnitsPerSegment" ), QStringLiteral( "1.0" ) ).toDouble() );
|
||||
layoutItem->setSegmentSizeMode( static_cast<QgsScaleBarSettings::SegmentSizeMode>( itemElem.attribute( QStringLiteral( "segmentSizeMode" ), QStringLiteral( "0" ) ).toInt() ) );
|
||||
layoutItem->setMinimumBarWidth( itemElem.attribute( QStringLiteral( "minBarWidth" ), QStringLiteral( "50" ) ).toDouble() );
|
||||
layoutItem->setMaximumBarWidth( itemElem.attribute( QStringLiteral( "maxBarWidth" ), QStringLiteral( "150" ) ).toDouble() );
|
||||
layoutItem->mSegmentMillimeters = itemElem.attribute( QStringLiteral( "segmentMillimeters" ), QStringLiteral( "0.0" ) ).toDouble();
|
||||
layoutItem->setMapUnitsPerScaleBarUnit( itemElem.attribute( QStringLiteral( "numMapUnitsPerScaleBarUnit" ), QStringLiteral( "1.0" ) ).toDouble() );
|
||||
layoutItem->setLineWidth( itemElem.attribute( QStringLiteral( "outlineWidth" ), QStringLiteral( "0.3" ) ).toDouble() );
|
||||
layoutItem->setUnitLabel( itemElem.attribute( QStringLiteral( "unitLabel" ) ) );
|
||||
layoutItem->setLineJoinStyle( QgsSymbolLayerUtils::decodePenJoinStyle( itemElem.attribute( QStringLiteral( "lineJoinStyle" ), QStringLiteral( "miter" ) ) ) );
|
||||
layoutItem->setLineCapStyle( QgsSymbolLayerUtils::decodePenCapStyle( itemElem.attribute( QStringLiteral( "lineCapStyle" ), QStringLiteral( "square" ) ) ) );
|
||||
QFont f;
|
||||
if ( !QgsFontUtils::setFromXmlChildNode( f, itemElem, QStringLiteral( "scaleBarFont" ) ) )
|
||||
{
|
||||
f.fromString( itemElem.attribute( QStringLiteral( "font" ), QLatin1String( "" ) ) );
|
||||
}
|
||||
layoutItem->setFont( f );
|
||||
|
||||
//colors
|
||||
//fill color
|
||||
QDomNodeList fillColorList = itemElem.elementsByTagName( QStringLiteral( "fillColor" ) );
|
||||
if ( !fillColorList.isEmpty() )
|
||||
{
|
||||
QDomElement fillColorElem = fillColorList.at( 0 ).toElement();
|
||||
bool redOk, greenOk, blueOk, alphaOk;
|
||||
int fillRed, fillGreen, fillBlue, fillAlpha;
|
||||
|
||||
fillRed = fillColorElem.attribute( QStringLiteral( "red" ) ).toDouble( &redOk );
|
||||
fillGreen = fillColorElem.attribute( QStringLiteral( "green" ) ).toDouble( &greenOk );
|
||||
fillBlue = fillColorElem.attribute( QStringLiteral( "blue" ) ).toDouble( &blueOk );
|
||||
fillAlpha = fillColorElem.attribute( QStringLiteral( "alpha" ) ).toDouble( &alphaOk );
|
||||
|
||||
if ( redOk && greenOk && blueOk && alphaOk )
|
||||
{
|
||||
layoutItem->setFillColor( QColor( fillRed, fillGreen, fillBlue, fillAlpha ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
layoutItem->setFillColor( QColor( itemElem.attribute( QStringLiteral( "brushColor" ), QStringLiteral( "#000000" ) ) ) );
|
||||
}
|
||||
|
||||
//fill color 2
|
||||
QDomNodeList fillColor2List = itemElem.elementsByTagName( QStringLiteral( "fillColor2" ) );
|
||||
if ( !fillColor2List.isEmpty() )
|
||||
{
|
||||
QDomElement fillColor2Elem = fillColor2List.at( 0 ).toElement();
|
||||
bool redOk, greenOk, blueOk, alphaOk;
|
||||
int fillRed, fillGreen, fillBlue, fillAlpha;
|
||||
|
||||
fillRed = fillColor2Elem.attribute( QStringLiteral( "red" ) ).toDouble( &redOk );
|
||||
fillGreen = fillColor2Elem.attribute( QStringLiteral( "green" ) ).toDouble( &greenOk );
|
||||
fillBlue = fillColor2Elem.attribute( QStringLiteral( "blue" ) ).toDouble( &blueOk );
|
||||
fillAlpha = fillColor2Elem.attribute( QStringLiteral( "alpha" ) ).toDouble( &alphaOk );
|
||||
|
||||
if ( redOk && greenOk && blueOk && alphaOk )
|
||||
{
|
||||
layoutItem->setFillColor2( QColor( fillRed, fillGreen, fillBlue, fillAlpha ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
layoutItem->setFillColor2( QColor( itemElem.attribute( QStringLiteral( "brush2Color" ), QStringLiteral( "#ffffff" ) ) ) );
|
||||
}
|
||||
|
||||
//stroke color
|
||||
QDomNodeList strokeColorList = itemElem.elementsByTagName( QStringLiteral( "strokeColor" ) );
|
||||
if ( !strokeColorList.isEmpty() )
|
||||
{
|
||||
QDomElement strokeColorElem = strokeColorList.at( 0 ).toElement();
|
||||
bool redOk, greenOk, blueOk, alphaOk;
|
||||
int strokeRed, strokeGreen, strokeBlue, strokeAlpha;
|
||||
|
||||
strokeRed = strokeColorElem.attribute( QStringLiteral( "red" ) ).toDouble( &redOk );
|
||||
strokeGreen = strokeColorElem.attribute( QStringLiteral( "green" ) ).toDouble( &greenOk );
|
||||
strokeBlue = strokeColorElem.attribute( QStringLiteral( "blue" ) ).toDouble( &blueOk );
|
||||
strokeAlpha = strokeColorElem.attribute( QStringLiteral( "alpha" ) ).toDouble( &alphaOk );
|
||||
|
||||
if ( redOk && greenOk && blueOk && alphaOk )
|
||||
{
|
||||
layoutItem->setLineColor( QColor( strokeRed, strokeGreen, strokeBlue, strokeAlpha ) );
|
||||
QPen p = layoutItem->mSettings.pen();
|
||||
p.setColor( layoutItem->mSettings.lineColor() );
|
||||
layoutItem->setPen( p );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
layoutItem->setLineColor( QColor( itemElem.attribute( QStringLiteral( "penColor" ), QStringLiteral( "#000000" ) ) ) );
|
||||
QPen p = layoutItem->mSettings.pen();
|
||||
p.setColor( layoutItem->mSettings.lineColor() );
|
||||
layoutItem->setPen( p );
|
||||
}
|
||||
|
||||
//font color
|
||||
QDomNodeList textColorList = itemElem.elementsByTagName( QStringLiteral( "textColor" ) );
|
||||
if ( !textColorList.isEmpty() )
|
||||
{
|
||||
QDomElement textColorElem = textColorList.at( 0 ).toElement();
|
||||
bool redOk, greenOk, blueOk, alphaOk;
|
||||
int textRed, textGreen, textBlue, textAlpha;
|
||||
|
||||
textRed = textColorElem.attribute( QStringLiteral( "red" ) ).toDouble( &redOk );
|
||||
textGreen = textColorElem.attribute( QStringLiteral( "green" ) ).toDouble( &greenOk );
|
||||
textBlue = textColorElem.attribute( QStringLiteral( "blue" ) ).toDouble( &blueOk );
|
||||
textAlpha = textColorElem.attribute( QStringLiteral( "alpha" ) ).toDouble( &alphaOk );
|
||||
|
||||
if ( redOk && greenOk && blueOk && alphaOk )
|
||||
{
|
||||
layoutItem->setFontColor( QColor( textRed, textGreen, textBlue, textAlpha ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
QColor c;
|
||||
c.setNamedColor( itemElem.attribute( QStringLiteral( "fontColor" ), QStringLiteral( "#000000" ) ) );
|
||||
layoutItem->setFontColor( c );
|
||||
}
|
||||
|
||||
//style
|
||||
QString styleString = itemElem.attribute( QStringLiteral( "style" ), QLatin1String( "" ) );
|
||||
layoutItem->setStyle( QObject::tr( styleString.toLocal8Bit().data() ) );
|
||||
|
||||
if ( itemElem.attribute( QStringLiteral( "unitType" ) ).isEmpty() )
|
||||
{
|
||||
QgsUnitTypes::DistanceUnit u = QgsUnitTypes::DistanceUnknownUnit;
|
||||
switch ( itemElem.attribute( QStringLiteral( "units" ) ).toInt() )
|
||||
{
|
||||
case 0:
|
||||
u = QgsUnitTypes::DistanceUnknownUnit;
|
||||
break;
|
||||
case 1:
|
||||
u = QgsUnitTypes::DistanceMeters;
|
||||
break;
|
||||
case 2:
|
||||
u = QgsUnitTypes::DistanceFeet;
|
||||
break;
|
||||
case 3:
|
||||
u = QgsUnitTypes::DistanceNauticalMiles;
|
||||
break;
|
||||
}
|
||||
layoutItem->setUnits( u );
|
||||
}
|
||||
else
|
||||
{
|
||||
layoutItem->setUnits( QgsUnitTypes::decodeDistanceUnit( itemElem.attribute( QStringLiteral( "unitType" ) ) ) );
|
||||
}
|
||||
layoutItem->setAlignment( static_cast< QgsScaleBarSettings::Alignment >( itemElem.attribute( QStringLiteral( "alignment" ), QStringLiteral( "0" ) ).toInt() ) );
|
||||
|
||||
//map TODO: map id
|
||||
int mapId = itemElem.attribute( QStringLiteral( "mapId" ), QStringLiteral( "-1" ) ).toInt();
|
||||
if ( mapId >= 0 )
|
||||
{
|
||||
/*
|
||||
const QgsComposerMap *composerMap = mComposition->getComposerMapById( mapId );
|
||||
mComposerMap = const_cast< QgsComposerMap *>( composerMap );
|
||||
if ( mComposerMap )
|
||||
{
|
||||
connect( mComposerMap, &QgsComposerMap::extentChanged, this, &QgsComposerScaleBar::updateSegmentSize );
|
||||
connect( mComposerMap, &QObject::destroyed, this, &QgsComposerScaleBar::invalidateCurrentMap );
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QgsCompositionConverter::readLegendXml( QgsLayoutItemLegend *layoutItem, const QDomElement &itemElem, const QgsProject *project )
|
||||
{
|
||||
restoreGeneralComposeItemProperties( layoutItem, itemElem );
|
||||
QgsPathResolver pathResolver;
|
||||
if ( project )
|
||||
pathResolver = project->pathResolver();
|
||||
QgsReadWriteContext context;
|
||||
context.setPathResolver( pathResolver );
|
||||
|
||||
//read general properties
|
||||
layoutItem->setTitle( itemElem.attribute( QStringLiteral( "title" ) ) );
|
||||
if ( !itemElem.attribute( QStringLiteral( "titleAlignment" ) ).isEmpty() )
|
||||
{
|
||||
layoutItem->setTitleAlignment( static_cast< Qt::AlignmentFlag >( itemElem.attribute( QStringLiteral( "titleAlignment" ) ).toInt() ) );
|
||||
}
|
||||
int colCount = itemElem.attribute( QStringLiteral( "columnCount" ), QStringLiteral( "1" ) ).toInt();
|
||||
if ( colCount < 1 ) colCount = 1;
|
||||
layoutItem->setColumnCount( colCount );
|
||||
layoutItem->setSplitLayer( itemElem.attribute( QStringLiteral( "splitLayer" ), QStringLiteral( "0" ) ).toInt() == 1 );
|
||||
layoutItem->setEqualColumnWidth( itemElem.attribute( QStringLiteral( "equalColumnWidth" ), QStringLiteral( "0" ) ).toInt() == 1 );
|
||||
|
||||
QDomNodeList stylesNodeList = itemElem.elementsByTagName( QStringLiteral( "styles" ) );
|
||||
if ( !stylesNodeList.isEmpty() )
|
||||
{
|
||||
QDomNode stylesNode = stylesNodeList.at( 0 );
|
||||
for ( int i = 0; i < stylesNode.childNodes().size(); i++ )
|
||||
{
|
||||
QDomElement styleElem = stylesNode.childNodes().at( i ).toElement();
|
||||
QgsLegendStyle style;
|
||||
style.readXml( styleElem, QDomDocument() );
|
||||
QString name = styleElem.attribute( QStringLiteral( "name" ) );
|
||||
QgsLegendStyle::Style s;
|
||||
if ( name == QLatin1String( "title" ) ) s = QgsLegendStyle::Title;
|
||||
else if ( name == QLatin1String( "group" ) ) s = QgsLegendStyle::Group;
|
||||
else if ( name == QLatin1String( "subgroup" ) ) s = QgsLegendStyle::Subgroup;
|
||||
else if ( name == QLatin1String( "symbol" ) ) s = QgsLegendStyle::Symbol;
|
||||
else if ( name == QLatin1String( "symbolLabel" ) ) s = QgsLegendStyle::SymbolLabel;
|
||||
else continue;
|
||||
layoutItem->setStyle( s, style );
|
||||
}
|
||||
}
|
||||
|
||||
//font color
|
||||
QColor fontClr;
|
||||
fontClr.setNamedColor( itemElem.attribute( QStringLiteral( "fontColor" ), QStringLiteral( "#000000" ) ) );
|
||||
layoutItem->setFontColor( fontClr );
|
||||
|
||||
//spaces
|
||||
layoutItem->setBoxSpace( itemElem.attribute( QStringLiteral( "boxSpace" ), QStringLiteral( "2.0" ) ).toDouble() );
|
||||
layoutItem->setColumnSpace( itemElem.attribute( QStringLiteral( "columnSpace" ), QStringLiteral( "2.0" ) ).toDouble() );
|
||||
|
||||
layoutItem->setSymbolWidth( itemElem.attribute( QStringLiteral( "symbolWidth" ), QStringLiteral( "7.0" ) ).toDouble() );
|
||||
layoutItem->setSymbolHeight( itemElem.attribute( QStringLiteral( "symbolHeight" ), QStringLiteral( "14.0" ) ).toDouble() );
|
||||
layoutItem->setWmsLegendWidth( itemElem.attribute( QStringLiteral( "wmsLegendWidth" ), QStringLiteral( "50" ) ).toDouble() );
|
||||
layoutItem->setWmsLegendHeight( itemElem.attribute( QStringLiteral( "wmsLegendHeight" ), QStringLiteral( "25" ) ).toDouble() );
|
||||
layoutItem->setLineSpacing( itemElem.attribute( QStringLiteral( "lineSpacing" ), QStringLiteral( "1.0" ) ).toDouble() );
|
||||
|
||||
layoutItem->setDrawRasterStroke( itemElem.attribute( QStringLiteral( "rasterBorder" ), QStringLiteral( "1" ) ) != QLatin1String( "0" ) );
|
||||
layoutItem->setRasterStrokeColor( QgsSymbolLayerUtils::decodeColor( itemElem.attribute( QStringLiteral( "rasterBorderColor" ), QStringLiteral( "0,0,0" ) ) ) );
|
||||
layoutItem->setRasterStrokeWidth( itemElem.attribute( QStringLiteral( "rasterBorderWidth" ), QStringLiteral( "0" ) ).toDouble() );
|
||||
|
||||
layoutItem->setWrapString( itemElem.attribute( QStringLiteral( "wrapChar" ) ) );
|
||||
|
||||
layoutItem->mSizeToContents = itemElem.attribute( QStringLiteral( "resizeToContents" ), QStringLiteral( "1" ) ) != QLatin1String( "0" );
|
||||
|
||||
layoutItem->mLegendFilterByMap = itemElem.attribute( QStringLiteral( "legendFilterByMap" ), QStringLiteral( "0" ) ).toInt();
|
||||
|
||||
//composer map TODO: use uuid
|
||||
/*
|
||||
if ( !itemElem.attribute( QStringLiteral( "map" ) ).isEmpty() )
|
||||
{
|
||||
layoutItem->setMap( layoutItem->layout()-> getComposerMapById( itemElem.attribute( QStringLiteral( "map" ) ).toInt() ) );
|
||||
}
|
||||
|
||||
// TODO: atlas
|
||||
mFilterOutAtlas = itemElem.attribute( QStringLiteral( "legendFilterByAtlas" ), QStringLiteral( "0" ) ).toInt();
|
||||
*/
|
||||
|
||||
// QGIS >= 2.6
|
||||
QDomElement layerTreeElem = itemElem.firstChildElement( QStringLiteral( "layer-tree" ) );
|
||||
if ( layerTreeElem.isNull() )
|
||||
layerTreeElem = itemElem.firstChildElement( QStringLiteral( "layer-tree-group" ) );
|
||||
|
||||
if ( !layerTreeElem.isNull() )
|
||||
{
|
||||
std::unique_ptr< QgsLayerTree > tree( QgsLayerTree::readXml( layerTreeElem, context ) );
|
||||
if ( project )
|
||||
tree->resolveReferences( project, true );
|
||||
layoutItem->setCustomLayerTree( tree.release() );
|
||||
}
|
||||
else
|
||||
layoutItem->setCustomLayerTree( nullptr );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T, class T2>
|
||||
bool QgsCompositionConverter::readPolyXml( T *layoutItem, const QDomElement &itemElem, const QgsProject *project )
|
||||
{
|
||||
|
@ -35,6 +35,8 @@ class QgsLayoutItemPicture;
|
||||
class QgsLayoutItemPolygon;
|
||||
class QgsLayoutItemPolyline;
|
||||
class QgsLayoutItemMap;
|
||||
class QgsLayoutItemScaleBar;
|
||||
class QgsLayoutItemLegend;
|
||||
|
||||
class CORE_EXPORT QgsCompositionConverter
|
||||
{
|
||||
@ -153,6 +155,14 @@ class CORE_EXPORT QgsCompositionConverter
|
||||
const QDomElement &itemElem,
|
||||
const QgsProject *project );
|
||||
|
||||
static bool readScaleBarXml( QgsLayoutItemScaleBar *layoutItem,
|
||||
const QDomElement &itemElem,
|
||||
const QgsProject *project );
|
||||
|
||||
static bool readLegendXml( QgsLayoutItemLegend *layoutItem,
|
||||
const QDomElement &itemElem,
|
||||
const QgsProject *project );
|
||||
|
||||
|
||||
/**
|
||||
* Sets item state from DOM element
|
||||
|
@ -505,6 +505,9 @@ class CORE_EXPORT QgsLayoutItemLegend : public QgsLayoutItem
|
||||
|
||||
//! Will be true if the legend should be resized automatically to fit contents
|
||||
bool mSizeToContents = true;
|
||||
|
||||
friend class QgsCompositionConverter;
|
||||
|
||||
};
|
||||
|
||||
#endif // QGSLAYOUTITEMLEGEND_H
|
||||
|
@ -456,6 +456,8 @@ class CORE_EXPORT QgsLayoutItemScaleBar: public QgsLayoutItem
|
||||
|
||||
QgsScaleBarRenderer::ScaleBarContext createScaleContext() const;
|
||||
|
||||
friend class QgsCompositionConverter;
|
||||
|
||||
};
|
||||
|
||||
#endif //QGSLAYOUTITEMSCALEBAR_H
|
||||
|
@ -33,6 +33,8 @@
|
||||
#include "qgslayoutitempolygon.h"
|
||||
#include "qgslayoutitempolyline.h"
|
||||
#include "qgslayoutitemmap.h"
|
||||
#include "qgslayoutitemscalebar.h"
|
||||
#include "qgslayoutitemlegend.h"
|
||||
|
||||
|
||||
class TestQgsCompositionConverter: public QObject
|
||||
@ -85,6 +87,17 @@ class TestQgsCompositionConverter: public QObject
|
||||
*/
|
||||
void importComposerTemplateMap();
|
||||
|
||||
/**
|
||||
* Test import legend from a composer template
|
||||
*/
|
||||
void importComposerTemplateLegend();
|
||||
|
||||
/**
|
||||
* Test import scalebar from a composer template
|
||||
*/
|
||||
void importComposerTemplateScaleBar();
|
||||
|
||||
|
||||
private:
|
||||
|
||||
|
||||
@ -324,6 +337,50 @@ void TestQgsCompositionConverter::importComposerTemplateMap()
|
||||
|
||||
}
|
||||
|
||||
void TestQgsCompositionConverter::importComposerTemplateLegend()
|
||||
{
|
||||
QDomElement docElem( loadComposition( "2x_template_legend.qpt" ) );
|
||||
QVERIFY( !docElem.isNull() );
|
||||
QgsProject project;
|
||||
QgsLayout *layout = QgsCompositionConverter::createLayoutFromCompositionXml( docElem, &project );
|
||||
QVERIFY( layout );
|
||||
QCOMPARE( layout->pageCollection()->pageCount(), 1 );
|
||||
|
||||
QList<QgsLayoutItemLegend *> items;
|
||||
layout->layoutItems<QgsLayoutItemLegend>( items );
|
||||
QCOMPARE( items.size(), 1 );
|
||||
|
||||
QgsLayoutItemLegend *item = items.at( 0 );
|
||||
QVERIFY( item->isVisible() );
|
||||
|
||||
checkRenderedImage( layout, QTest::currentTestFunction(), 0 );
|
||||
|
||||
qDeleteAll( items );
|
||||
|
||||
}
|
||||
|
||||
void TestQgsCompositionConverter::importComposerTemplateScaleBar()
|
||||
{
|
||||
QDomElement docElem( loadComposition( "2x_template_scalebar.qpt" ) );
|
||||
QVERIFY( !docElem.isNull() );
|
||||
QgsProject project;
|
||||
QgsLayout *layout = QgsCompositionConverter::createLayoutFromCompositionXml( docElem, &project );
|
||||
QVERIFY( layout );
|
||||
QCOMPARE( layout->pageCollection()->pageCount(), 1 );
|
||||
|
||||
QList<QgsLayoutItemScaleBar *> items;
|
||||
layout->layoutItems<QgsLayoutItemScaleBar>( items );
|
||||
QCOMPARE( items.size(), 1 );
|
||||
|
||||
QgsLayoutItemScaleBar *item = items.at( 0 );
|
||||
QVERIFY( item->isVisible() );
|
||||
|
||||
checkRenderedImage( layout, QTest::currentTestFunction(), 0 );
|
||||
|
||||
qDeleteAll( items );
|
||||
|
||||
}
|
||||
|
||||
void TestQgsCompositionConverter::importComposerTemplate()
|
||||
{
|
||||
QDomElement docElem( loadComposition( "2x_template.qpt" ) );
|
||||
@ -345,7 +402,7 @@ void TestQgsCompositionConverter::checkRenderedImage( QgsLayout *layout, const Q
|
||||
QSize size( layout->pageCollection()->page( pageNumber )->sizeWithUnits().width() * 3.77, layout->pageCollection()->page( pageNumber )->sizeWithUnits().height() * 3.77 );
|
||||
checker.setSize( size );
|
||||
checker.setControlPathPrefix( QStringLiteral( "compositionconverter" ) );
|
||||
QVERIFY( checker.testLayout( mReport, pageNumber ) );
|
||||
QVERIFY( checker.testLayout( mReport, pageNumber, 0, true ) );
|
||||
}
|
||||
|
||||
void TestQgsCompositionConverter::exportLayout( QgsLayout *layout, const QString testName )
|
||||
|
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 5.9 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 80 KiB |
After Width: | Height: | Size: 7.9 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 8.5 KiB |
After Width: | Height: | Size: 6.4 KiB |
After Width: | Height: | Size: 121 KiB |
After Width: | Height: | Size: 40 KiB |
106
tests/testdata/layouts/2x_template_legend.qpt
vendored
Normal file
@ -0,0 +1,106 @@
|
||||
<Composer>
|
||||
<Composition snapGridOffsetY="0" numPages="1" name="composer title" printAsRaster="0" snapGridOffsetX="0" snapGridResolution="10" alignmentSnap="1" resizeToContentsMarginTop="0" paperHeight="210" paperWidth="297" generateWorldFile="0" worldFileMap="" resizeToContentsMarginRight="0" smartGuides="1" resizeToContentsMarginBottom="0" snapTolerancePixels="5" guidesVisible="1" resizeToContentsMarginLeft="0" showPages="1" printResolution="305" snapping="0" gridVisible="0">
|
||||
<symbol type="fill" clip_to_extent="1" name="" alpha="1">
|
||||
<layer pass="0" enabled="1" locked="0" class="SimpleFill">
|
||||
<prop v="3x:0,0,0,0,0,0" k="border_width_map_unit_scale"/>
|
||||
<prop v="241,244,199,255" k="color"/>
|
||||
<prop v="bevel" k="joinstyle"/>
|
||||
<prop v="0,0" k="offset"/>
|
||||
<prop v="3x:0,0,0,0,0,0" k="offset_map_unit_scale"/>
|
||||
<prop v="MM" k="offset_unit"/>
|
||||
<prop v="175,179,138,255" k="outline_color"/>
|
||||
<prop v="solid" k="outline_style"/>
|
||||
<prop v="0.26" k="outline_width"/>
|
||||
<prop v="MM" k="outline_width_unit"/>
|
||||
<prop v="solid" k="style"/>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option type="QString" value="" name="name"/>
|
||||
<Option name="properties"/>
|
||||
<Option type="QString" value="collection" name="type"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
<ComposerLegend rasterBorderWidth="0" rasterBorder="1" title="My Legend" resizeToContents="1" symbolWidth="12" map="0" columnSpace="1" wmsLegendHeight="25" splitLayer="1" rasterBorderColor="0,0,0,255" columnCount="2" titleAlignment="4" fontColor="#f065ec" wmsLegendWidth="50" symbolHeight="9" boxSpace="5" wrapChar=" " legendFilterByAtlas="0" lineSpacing="1" equalColumnWidth="1">
|
||||
<styles>
|
||||
<style name="title" marginBottom="6">
|
||||
<styleFont description="MS Shell Dlg 2,36,-1,5,50,0,0,0,0,0" style=""/>
|
||||
</style>
|
||||
<style name="group" marginTop="5">
|
||||
<styleFont description="MS Shell Dlg 2,14,-1,5,50,0,0,0,0,0" style=""/>
|
||||
</style>
|
||||
<style name="subgroup" marginTop="4">
|
||||
<styleFont description="MS Shell Dlg 2,12,-1,5,50,0,0,0,0,0" style=""/>
|
||||
</style>
|
||||
<style name="symbol" marginTop="3">
|
||||
<styleFont description="MS Shell Dlg 2,8.25,-1,5,50,0,0,0,0,0" style=""/>
|
||||
</style>
|
||||
<style marginLeft="4" name="symbolLabel" marginTop="3">
|
||||
<styleFont description="MS Shell Dlg 2,12,-1,5,50,0,0,0,0,0" style=""/>
|
||||
</style>
|
||||
</styles>
|
||||
<layer-tree-group>
|
||||
<customproperties/>
|
||||
<layer-tree-layer providerKey="ogr" name="points" expanded="1" checked="Qt::Checked" id="points20171212162310546" source="../../../dev/QGIS/tests/testdata/points.shp">
|
||||
<customproperties/>
|
||||
</layer-tree-layer>
|
||||
<layer-tree-layer providerKey="ogr" name="polys" expanded="1" checked="Qt::Checked" id="polys20171212162309844" source="../../../dev/QGIS/tests/testdata/polys.shp">
|
||||
<customproperties/>
|
||||
</layer-tree-layer>
|
||||
<custom-order enabled="0"/>
|
||||
</layer-tree-group>
|
||||
<ComposerItem y="79.6503" excludeFromExports="0" frame="false" background="true" uuid="{69fb50e1-e233-4105-a97f-f95d3fa822cc}" lastValidViewScaleFactor="-1" zValue="6" frameJoinStyle="miter" id="" positionLock="false" width="70.6219" positionMode="0" itemRotation="0" page="1" outlineWidth="0.3" blendMode="0" pagey="79.6503" x="139.64" pagex="139.64" visibility="1" opacity="1" height="89.5">
|
||||
<FrameColor blue="0" green="0" red="0" alpha="255"/>
|
||||
<BackgroundColor blue="255" green="255" red="255" alpha="255"/>
|
||||
<dataDefinedProperties>
|
||||
<Option type="Map">
|
||||
<Option type="QString" value="" name="name"/>
|
||||
<Option name="properties"/>
|
||||
<Option type="QString" value="collection" name="type"/>
|
||||
</Option>
|
||||
</dataDefinedProperties>
|
||||
<customproperties/>
|
||||
</ComposerItem>
|
||||
</ComposerLegend>
|
||||
<dataDefinedProperties>
|
||||
<Option type="Map">
|
||||
<Option type="QString" value="" name="name"/>
|
||||
<Option type="Map" name="properties">
|
||||
<Option type="Map" name="dataDefinedHeight">
|
||||
<Option type="bool" value="true" name="active"/>
|
||||
<Option type="QString" value="28" name="expression"/>
|
||||
<Option type="int" value="3" name="type"/>
|
||||
</Option>
|
||||
<Option type="Map" name="dataDefinedMapScale">
|
||||
<Option type="bool" value="true" name="active"/>
|
||||
<Option type="QString" value="24126145*1.1" name="expression"/>
|
||||
<Option type="int" value="3" name="type"/>
|
||||
</Option>
|
||||
<Option type="Map" name="dataDefinedPositionX">
|
||||
<Option type="bool" value="true" name="active"/>
|
||||
<Option type="QString" value="200" name="expression"/>
|
||||
<Option type="int" value="3" name="type"/>
|
||||
</Option>
|
||||
<Option type="Map" name="dataDefinedPositionY">
|
||||
<Option type="bool" value="true" name="active"/>
|
||||
<Option type="QString" value="70" name="expression"/>
|
||||
<Option type="int" value="3" name="type"/>
|
||||
</Option>
|
||||
<Option type="Map" name="dataDefinedSource">
|
||||
<Option type="bool" value="false" name="active"/>
|
||||
<Option type="QString" value="" name="expression"/>
|
||||
<Option type="int" value="3" name="type"/>
|
||||
</Option>
|
||||
<Option type="Map" name="dataDefinedWidth">
|
||||
<Option type="bool" value="true" name="active"/>
|
||||
<Option type="QString" value="24" name="expression"/>
|
||||
<Option type="int" value="3" name="type"/>
|
||||
</Option>
|
||||
</Option>
|
||||
<Option type="QString" value="collection" name="type"/>
|
||||
</Option>
|
||||
</dataDefinedProperties>
|
||||
<customproperties/>
|
||||
</Composition>
|
||||
</Composer>
|
84
tests/testdata/layouts/2x_template_scalebar.qpt
vendored
Normal file
@ -0,0 +1,84 @@
|
||||
<Composer>
|
||||
<Composition snapGridOffsetY="0" numPages="1" name="composer title" printAsRaster="0" snapGridOffsetX="0" snapGridResolution="10" alignmentSnap="1" resizeToContentsMarginTop="0" paperHeight="210" paperWidth="297" generateWorldFile="0" worldFileMap="" resizeToContentsMarginRight="0" smartGuides="1" resizeToContentsMarginBottom="0" snapTolerancePixels="5" guidesVisible="1" resizeToContentsMarginLeft="0" showPages="1" printResolution="305" snapping="0" gridVisible="0">
|
||||
<symbol type="fill" clip_to_extent="1" name="" alpha="1">
|
||||
<layer pass="0" enabled="1" locked="0" class="SimpleFill">
|
||||
<prop v="3x:0,0,0,0,0,0" k="border_width_map_unit_scale"/>
|
||||
<prop v="241,244,199,255" k="color"/>
|
||||
<prop v="bevel" k="joinstyle"/>
|
||||
<prop v="0,0" k="offset"/>
|
||||
<prop v="3x:0,0,0,0,0,0" k="offset_map_unit_scale"/>
|
||||
<prop v="MM" k="offset_unit"/>
|
||||
<prop v="175,179,138,255" k="outline_color"/>
|
||||
<prop v="solid" k="outline_style"/>
|
||||
<prop v="0.26" k="outline_width"/>
|
||||
<prop v="MM" k="outline_width_unit"/>
|
||||
<prop v="solid" k="style"/>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option type="QString" value="" name="name"/>
|
||||
<Option name="properties"/>
|
||||
<Option type="QString" value="collection" name="type"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
<ComposerScaleBar numUnitsPerSegment="250000" labelBarSpace="5" boxContentSpace="4" mapId="0" maxBarWidth="150" numSegments="6" segmentSizeMode="0" numSegmentsLeft="3" unitType="meters" lineJoinStyle="round" style="Double Box" alignment="1" numMapUnitsPerScaleBarUnit="2000" outlineWidth="0.4" minBarWidth="50" unitLabel="hh" lineCapStyle="square" height="3" segmentMillimeters="5.64513">
|
||||
<scaleBarFont description="MS Shell Dlg 2,12,-1,5,50,0,0,0,0,0" style=""/>
|
||||
<fillColor blue="28" green="26" red="227" alpha="255"/>
|
||||
<fillColor2 blue="111" green="191" red="253" alpha="255"/>
|
||||
<strokeColor blue="0" green="127" red="255" alpha="255"/>
|
||||
<textColor blue="232" green="98" red="226" alpha="255"/>
|
||||
<ComposerItem y="184.506" excludeFromExports="0" frame="false" background="false" uuid="{2988dc5e-ea88-428f-93dd-e6aaf719dc8e}" lastValidViewScaleFactor="-1" zValue="7" frameJoinStyle="miter" id="" positionLock="false" width="62.9878" positionMode="0" itemRotation="0" page="1" outlineWidth="0.3" blendMode="0" pagey="184.506" x="140.608" pagex="140.608" visibility="1" opacity="1" height="20.2">
|
||||
<FrameColor blue="0" green="0" red="0" alpha="255"/>
|
||||
<BackgroundColor blue="255" green="255" red="255" alpha="255"/>
|
||||
<dataDefinedProperties>
|
||||
<Option type="Map">
|
||||
<Option type="QString" value="" name="name"/>
|
||||
<Option name="properties"/>
|
||||
<Option type="QString" value="collection" name="type"/>
|
||||
</Option>
|
||||
</dataDefinedProperties>
|
||||
<customproperties/>
|
||||
</ComposerItem>
|
||||
</ComposerScaleBar>
|
||||
<dataDefinedProperties>
|
||||
<Option type="Map">
|
||||
<Option type="QString" value="" name="name"/>
|
||||
<Option type="Map" name="properties">
|
||||
<Option type="Map" name="dataDefinedHeight">
|
||||
<Option type="bool" value="true" name="active"/>
|
||||
<Option type="QString" value="28" name="expression"/>
|
||||
<Option type="int" value="3" name="type"/>
|
||||
</Option>
|
||||
<Option type="Map" name="dataDefinedMapScale">
|
||||
<Option type="bool" value="true" name="active"/>
|
||||
<Option type="QString" value="24126145*1.1" name="expression"/>
|
||||
<Option type="int" value="3" name="type"/>
|
||||
</Option>
|
||||
<Option type="Map" name="dataDefinedPositionX">
|
||||
<Option type="bool" value="true" name="active"/>
|
||||
<Option type="QString" value="200" name="expression"/>
|
||||
<Option type="int" value="3" name="type"/>
|
||||
</Option>
|
||||
<Option type="Map" name="dataDefinedPositionY">
|
||||
<Option type="bool" value="true" name="active"/>
|
||||
<Option type="QString" value="70" name="expression"/>
|
||||
<Option type="int" value="3" name="type"/>
|
||||
</Option>
|
||||
<Option type="Map" name="dataDefinedSource">
|
||||
<Option type="bool" value="false" name="active"/>
|
||||
<Option type="QString" value="" name="expression"/>
|
||||
<Option type="int" value="3" name="type"/>
|
||||
</Option>
|
||||
<Option type="Map" name="dataDefinedWidth">
|
||||
<Option type="bool" value="true" name="active"/>
|
||||
<Option type="QString" value="24" name="expression"/>
|
||||
<Option type="int" value="3" name="type"/>
|
||||
</Option>
|
||||
</Option>
|
||||
<Option type="QString" value="collection" name="type"/>
|
||||
</Option>
|
||||
</dataDefinedProperties>
|
||||
<customproperties/>
|
||||
</Composition>
|
||||
</Composer>
|