[layout] Converter: shapes

This commit is contained in:
Alessandro Pasotti 2017-12-16 11:01:22 +01:00
parent da3636e566
commit af8a2296dc
6 changed files with 144 additions and 64 deletions

View File

@ -43,16 +43,16 @@ void QgsCompositionConverter::initPropertyDefinitions()
{
{ QgsCompositionConverter::TestProperty, QgsPropertyDefinition( "dataDefinedProperty", QgsPropertyDefinition::DataTypeString, "invalid property", QString() ) },
{
QgsCompositionConverter::PresetPaperSize, QgsPropertyDefinition( "dataDefinedPaperSize", QgsPropertyDefinition::DataTypeString, QObject::tr( "Paper size" ), QObject::tr( "string " ) + QLatin1String( "[<b>A5</b>|<b>A4</b>|<b>A3</b>|<b>A2</b>|<b>A1</b>|<b>A0</b>"
QgsCompositionConverter::PresetPaperSize, QgsPropertyDefinition( "dataDefinedPaperSize", QgsPropertyDefinition::DataTypeString, QObject::tr( "Paper size" ), QObject::tr( "string " ) + QStringLiteral( "[<b>A5</b>|<b>A4</b>|<b>A3</b>|<b>A2</b>|<b>A1</b>|<b>A0</b>"
"<b>B5</b>|<b>B4</b>|<b>B3</b>|<b>B2</b>|<b>B1</b>|<b>B0</b>"
"<b>Legal</b>|<b>Ansi A</b>|<b>Ansi B</b>|<b>Ansi C</b>|<b>Ansi D</b>|<b>Ansi E</b>"
"<b>Arch A</b>|<b>Arch B</b>|<b>Arch C</b>|<b>Arch D</b>|<b>Arch E</b>|<b>Arch E1</b>]"
) )
) )
},
{ QgsCompositionConverter::PaperWidth, QgsPropertyDefinition( "dataDefinedPaperWidth", QObject::tr( "Page width" ), QgsPropertyDefinition::DoublePositive ) },
{ QgsCompositionConverter::PaperHeight, QgsPropertyDefinition( "dataDefinedPaperHeight", QObject::tr( "Page height" ), QgsPropertyDefinition::DoublePositive ) },
{ QgsCompositionConverter::NumPages, QgsPropertyDefinition( "dataDefinedNumPages", QObject::tr( "Number of pages" ), QgsPropertyDefinition::IntegerPositive ) },
{ QgsCompositionConverter::PaperOrientation, QgsPropertyDefinition( "dataDefinedPaperOrientation", QgsPropertyDefinition::DataTypeString, QObject::tr( "Symbol size" ), QObject::tr( "string " ) + QLatin1String( "[<b>portrait</b>|<b>landscape</b>]" ) ) },
{ QgsCompositionConverter::PaperOrientation, QgsPropertyDefinition( "dataDefinedPaperOrientation", QgsPropertyDefinition::DataTypeString, QObject::tr( "Symbol size" ), QObject::tr( "string " ) + QStringLiteral( "[<b>portrait</b>|<b>landscape</b>]" ) ) },
{ QgsCompositionConverter::PageNumber, QgsPropertyDefinition( "dataDefinedPageNumber", QObject::tr( "Page number" ), QgsPropertyDefinition::IntegerPositive ) },
{ QgsCompositionConverter::PositionX, QgsPropertyDefinition( "dataDefinedPositionX", QObject::tr( "Position (X)" ), QgsPropertyDefinition::Double ) },
{ QgsCompositionConverter::PositionY, QgsPropertyDefinition( "dataDefinedPositionY", QObject::tr( "Position (Y)" ), QgsPropertyDefinition::Double ) },
@ -145,6 +145,29 @@ void QgsCompositionConverter::adjustPos( QgsLayout *layout, QgsLayoutItem *layou
layoutItem->setZValue( layoutItem->zValue() + zOrderOffset );
}
void QgsCompositionConverter::restoreGeneralComposeItemProperties( QgsLayoutItem *layoutItem, const QDomElement &itemElem )
{
//restore general composer item properties
QDomNodeList composerItemList = itemElem.elementsByTagName( QStringLiteral( "ComposerItem" ) );
if ( !composerItemList.isEmpty() )
{
QDomElement composerItemElem = composerItemList.at( 0 ).toElement();
//rotation
if ( !qgsDoubleNear( composerItemElem.attribute( QStringLiteral( "rotation" ), QStringLiteral( "0" ) ).toDouble(), 0.0 ) )
{
//check for old (pre 2.1) rotation attribute
layoutItem->setItemRotation( composerItemElem.attribute( QStringLiteral( "rotation" ), QStringLiteral( "0" ) ).toDouble(), false );
}
QgsCompositionConverter::readXml( layoutItem, composerItemElem );
// Frame color
// Background color
}
}
QList<QgsLayoutItem *> QgsCompositionConverter::addItemsFromCompositionXml( QgsLayout *layout, const QDomElement &parentElement, const QgsReadWriteContext &context, QPointF *position, bool pasteInPlace )
{
@ -227,6 +250,8 @@ bool QgsCompositionConverter::readLabelXml( QgsLayoutItemLabel *label, const QDo
return false;
}
restoreGeneralComposeItemProperties( label, itemElem );
//restore label specific properties
//text
@ -277,21 +302,6 @@ bool QgsCompositionConverter::readLabelXml( QgsLayoutItemLabel *label, const QDo
label->setFontColor( QColor( 0, 0, 0 ) );
}
//restore general composer item properties
QDomNodeList composerItemList = itemElem.elementsByTagName( QStringLiteral( "ComposerItem" ) );
if ( !composerItemList.isEmpty() )
{
QDomElement composerItemElem = composerItemList.at( 0 ).toElement();
//rotation
if ( !qgsDoubleNear( composerItemElem.attribute( QStringLiteral( "rotation" ), QStringLiteral( "0" ) ).toDouble(), 0.0 ) )
{
//check for old (pre 2.1) rotation attribute
label->setItemRotation( composerItemElem.attribute( QStringLiteral( "rotation" ), QStringLiteral( "0" ) ).toDouble(), false );
}
QgsCompositionConverter::readXml( label, composerItemElem );
}
return true;
}
@ -300,30 +310,24 @@ bool QgsCompositionConverter::readShapeXml( QgsLayoutItemShape *layoutItem, cons
layoutItem->setShapeType( static_cast<QgsLayoutItemShape::Shape>( itemElem.attribute( QStringLiteral( "shapeType" ), QStringLiteral( "0" ) ).toInt() ) );
layoutItem->setCornerRadius( QgsLayoutMeasurement( itemElem.attribute( QStringLiteral( "cornerRadius" ), QStringLiteral( "0" ) ).toDouble() ) );
//restore general composer item properties
QDomNodeList composerItemList = itemElem.elementsByTagName( QStringLiteral( "ComposerItem" ) );
if ( !composerItemList.isEmpty() )
{
QDomElement composerItemElem = composerItemList.at( 0 ).toElement();
restoreGeneralComposeItemProperties( layoutItem, itemElem );
//rotation
if ( !qgsDoubleNear( composerItemElem.attribute( QStringLiteral( "rotation" ), QStringLiteral( "0" ) ).toDouble(), 0.0 ) )
{
//check for old (pre 2.1) rotation attribute
layoutItem->setItemRotation( composerItemElem.attribute( QStringLiteral( "rotation" ), QStringLiteral( "0" ) ).toDouble() );
}
readXml( layoutItem, composerItemElem );
}
QgsReadWriteContext context;
context.setPathResolver( QgsProject::instance()->pathResolver() );
if ( itemElem.elementsByTagName( QStringLiteral( "symbol" ) ).size() )
{
QDomElement symbolElement = itemElem.elementsByTagName( QStringLiteral( "symbol" ) ).at( 0 ).toElement();
QgsFillSymbol *shapeStyleSymbol = QgsSymbolLayerUtils::loadSymbol<QgsFillSymbol>( symbolElement, context );
if ( shapeStyleSymbol )
layoutItem->setSymbol( shapeStyleSymbol );
} /*
QDomElement shapeStyleSymbolElem = itemElem.firstChildElement( QStringLiteral( "symbol" ) );
if ( !shapeStyleSymbolElem.isNull() )
{
layoutItem->setSymbol( QgsSymbolLayerUtils::loadSymbol<QgsFillSymbol>( shapeStyleSymbolElem, context ) );
}
} */
else
{
//upgrade project file from 2.0 to use symbol styling
@ -399,6 +403,8 @@ bool QgsCompositionConverter::readShapeXml( QgsLayoutItemShape *layoutItem, cons
layoutItem->setSymbol( QgsFillSymbol::createSimple( properties ) );
}
return true;
}
@ -418,23 +424,23 @@ bool QgsCompositionConverter::readXml( QgsLayoutItem *layoutItem, const QDomElem
layoutItem->mTemplateUuid = itemElem.attribute( QStringLiteral( "templateUuid" ) );
//id
QString id = itemElem.attribute( QStringLiteral( "id" ), QLatin1String( "" ) );
QString id = itemElem.attribute( QStringLiteral( "id" ), QStringLiteral( "" ) );
layoutItem->setId( id );
//frame
QString frame = itemElem.attribute( QStringLiteral( "frame" ) );
layoutItem->setFrameEnabled( frame.compare( QLatin1String( "true" ), Qt::CaseInsensitive ) == 0 ) ;
layoutItem->setFrameEnabled( frame.compare( QStringLiteral( "true" ), Qt::CaseInsensitive ) == 0 ) ;
//frame
QString background = itemElem.attribute( QStringLiteral( "background" ) );
layoutItem->setBackgroundEnabled( background.compare( QLatin1String( "true" ), Qt::CaseInsensitive ) == 0 );
layoutItem->setBackgroundEnabled( background.compare( QStringLiteral( "true" ), Qt::CaseInsensitive ) == 0 );
//position lock for mouse moves/resizes
QString positionLock = itemElem.attribute( QStringLiteral( "positionLock" ) );
layoutItem->setLocked( positionLock.compare( QLatin1String( "true" ), Qt::CaseInsensitive ) == 0 );
layoutItem->setLocked( positionLock.compare( QStringLiteral( "true" ), Qt::CaseInsensitive ) == 0 );
//visibility
layoutItem->setVisibility( itemElem.attribute( QStringLiteral( "visibility" ), QStringLiteral( "1" ) ) != QLatin1String( "0" ) );
layoutItem->setVisibility( itemElem.attribute( QStringLiteral( "visibility" ), QStringLiteral( "1" ) ) != QStringLiteral( "0" ) );
layoutItem->mParentGroupUuid = itemElem.attribute( QStringLiteral( "groupUuid" ) );
if ( !layoutItem->mParentGroupUuid.isEmpty() )
@ -636,7 +642,7 @@ QgsProperty QgsCompositionConverter::readOldDataDefinedProperty( const QgsCompos
QString active = ddElem.attribute( QStringLiteral( "active" ) );
bool isActive = false;
if ( active.compare( QLatin1String( "true" ), Qt::CaseInsensitive ) == 0 )
if ( active.compare( QStringLiteral( "true" ), Qt::CaseInsensitive ) == 0 )
{
isActive = true;
}
@ -645,7 +651,7 @@ QgsProperty QgsCompositionConverter::readOldDataDefinedProperty( const QgsCompos
QString useExpr = ddElem.attribute( QStringLiteral( "useExpr" ) );
bool isExpression = false;
if ( useExpr.compare( QLatin1String( "true" ), Qt::CaseInsensitive ) == 0 )
if ( useExpr.compare( QStringLiteral( "true" ), Qt::CaseInsensitive ) == 0 )
{
isExpression = true;
}

View File

@ -151,6 +151,9 @@ class CORE_EXPORT QgsCompositionConverter
//! Make some common import adjustments
static void adjustPos( QgsLayout *layout, QgsLayoutItem *layoutItem, QDomNode &itemNode, QPointF *position, bool &pasteInPlace, int zOrderOffset, QPointF &pasteShiftPos, int &pageNumber );
//! Restore general composer item properties
static void restoreGeneralComposeItemProperties( QgsLayoutItem *layoutItem, const QDomElement &itemElem );
};
#endif // QGSCOMPOSITIONCONVERTER_H

View File

@ -19,11 +19,15 @@
#include "qgstest.h"
#include "qgslayout.h"
#include "qgslayoutitemlabel.h"
#include "qgscompositionconverter.h"
#include "qgsproject.h"
#include "qgsreadwritecontext.h"
#include "qgslayoutexporter.h"
#include "qgsmultirenderchecker.h"
#include "qgslayoutitemlabel.h"
#include "qgslayoutitemshape.h"
class TestQgsCompositionConverter: public QObject
{
@ -40,6 +44,11 @@ class TestQgsCompositionConverter: public QObject
*/
void importComposerTemplateLabel();
/**
* Test import shape from a composer template
*/
void importComposerTemplateShape();
/**
* Test import multiple ements from a composer template
*/
@ -94,27 +103,24 @@ void TestQgsCompositionConverter::importComposerTemplateLabel()
}
file.close();
QDomElement docElem = doc.documentElement();
QDomNodeList nodes( doc.elementsByTagName( QStringLiteral( "Composition" ) ) );
QVERIFY( nodes.length() > 0 );
QDomElement docElem = nodes.at( 0 ).toElement();
QgsProject project;
QgsLayout layout( &project );
QgsReadWriteContext context;
QDomElement parentElement = docElem.firstChild().toElement();
QList<QgsLayoutItem *> items( QgsCompositionConverter::addItemsFromCompositionXml( &layout,
parentElement,
context ) );
QgsLayout *layout = QgsCompositionConverter::createLayoutFromCompositionXml( docElem, context );
QVERIFY( layout );
QCOMPARE( layout->pageCollection()->pageCount(), 1 );
QList<QgsLayoutItemLabel *> items;
layout->layoutItems<QgsLayoutItemLabel>( items );
QVERIFY( items.size() > 0 );
exportLayout( &layout, QString( "ComposerTemplateLabel" ) );
exportLayout( layout, QStringLiteral( "ComposerTemplateLabel" ) );
// Check the label
const QgsLayoutItemLabel *label = nullptr;
for ( const auto &item : items )
{
label = qobject_cast<QgsLayoutItemLabel *>( item );
if ( label )
break;
}
const QgsLayoutItemLabel *label = items.at( 0 );
QVERIFY( label );
QCOMPARE( label->text(), QStringLiteral( "QGIS" ) );
QCOMPARE( label->pos().x(), 55.5333 );
@ -126,13 +132,64 @@ void TestQgsCompositionConverter::importComposerTemplateLabel()
QCOMPARE( label->frameStrokeWidth().length(), 0.2 );
QCOMPARE( ( int )label->rotation(), 4 );
/*
QgsCompositionChecker checker( QStringLiteral( "ComposerTemplateLabel" ), composition );
checker.setSize( QSize( 774, 641 ) );
checker.setControlPathPrefix( QStringLiteral( "compositionconverter" ) );
QVERIFY( checker.testComposition( mReport ) );
*/
qDeleteAll( items );
}
void TestQgsCompositionConverter::importComposerTemplateShape()
{
QString templatePath( QStringLiteral( TEST_DATA_DIR ) + "/layouts/2x_template_shape.qpt" );
QDomDocument doc( "mydocument" );
QFile file( templatePath );
QVERIFY( file.open( QIODevice::ReadOnly ) );
if ( !doc.setContent( &file ) )
{
file.close();
return;
}
file.close();
QDomNodeList nodes( doc.elementsByTagName( QStringLiteral( "Composition" ) ) );
QVERIFY( nodes.length() > 0 );
QDomElement docElem = nodes.at( 0 ).toElement();
QgsReadWriteContext context;
QgsLayout *layout = QgsCompositionConverter::createLayoutFromCompositionXml( docElem, context );
QVERIFY( layout );
QCOMPARE( layout->pageCollection()->pageCount(), 1 );
QList<QgsLayoutItemShape *> items;
layout->layoutItems<QgsLayoutItemShape>( items );
QVERIFY( items.size() > 0 );
exportLayout( layout, QString( "ComposerTemplateShape" ) );
// Check the shape
const QgsLayoutItemShape *shape = items.at( 0 );
QCOMPARE( shape->pos().x(), 261.132 );
QCOMPARE( shape->pos().y(), 83.1791 );
QCOMPARE( shape->sizeWithUnits().width(), 12.0988 );
QCOMPARE( shape->sizeWithUnits().height(), 33.2716 );
QCOMPARE( shape->referencePoint(), QgsLayoutItem::ReferencePoint::MiddleRight );
QCOMPARE( shape->frameStrokeColor(), QColor( 0, 0, 0, 255 ) );
QCOMPARE( shape->frameStrokeWidth().length(), 0.3 );
QCOMPARE( shape->backgroundColor(), QColor( 255, 255, 255, 255 ) );
QCOMPARE( ( int )shape->rotation(), 0 );
QCOMPARE( shape->hasFrame(), false );
qDeleteAll( items );
}
void TestQgsCompositionConverter::importComposerTemplate()
{
QString templatePath( QStringLiteral( TEST_DATA_DIR ) + "/layouts/2x_template_portrait.qpt" );
QString templatePath( QStringLiteral( TEST_DATA_DIR ) + "/layouts/2x_template.qpt" );
QDomDocument doc( "mydocument" );
QFile file( templatePath );
QVERIFY( file.open( QIODevice::ReadOnly ) );
@ -153,7 +210,6 @@ void TestQgsCompositionConverter::importComposerTemplate()
QVERIFY( layout );
QCOMPARE( layout->pageCollection()->pageCount(), 2 );
// Check that we have 2 labels
exportLayout( layout, QString( "ComposerTemplate" ) );
delete layout;

View File

@ -1,6 +1,8 @@
<Composer>
<Composition paperHeight="210" resizeToContentsMarginRight="0" guidesVisible="1" numPages="2" snapTolerancePixels="5" printResolution="305" snapGridOffsetX="0" showPages="1" smartGuides="1"
worldFileMap="" alignmentSnap="1" name="composer title" snapGridResolution="10" snapGridOffsetY="0" generateWorldFile="0" snapping="0" gridVisible="0"
<Composition paperHeight="210" resizeToContentsMarginRight="0" guidesVisible="1" numPages="2" snapTolerancePixels="5" printResolution="305"
snapGridOffsetX="0" showPages="1" smartGuides="1"
worldFileMap="" alignmentSnap="1" name="composer title" snapGridResolution="10" snapGridOffsetY="0" generateWorldFile="0" snapping="0"
gridVisible="0"
paperWidth="297" resizeToContentsMarginTop="0" printAsRaster="0" resizeToContentsMarginLeft="0" resizeToContentsMarginBottom="0">
<symbol clip_to_extent="1" name="" alpha="1" type="fill">
<layer class="SimpleFill" enabled="1" locked="0" pass="0">
@ -202,7 +204,10 @@
<node x="50.9157" y="22.1811"/>
<node x="64.0227" y="0"/>
</nodes>
<ComposerItem pagex="22.6852" positionLock="false" width="64.0227" frame="false" excludeFromExports="0" x="22.6852" background="true" positionMode="0" blendMode="0" page="2" id="" lastValidViewScaleFactor="-1" visibility="1" pagey="86.5024" height="22.1811" frameJoinStyle="miter" y="306.502" zValue="12" outlineWidth="0.3" uuid="{d5db4748-2b62-4b79-a785-46a6cb8df967}" opacity="1" itemRotation="0">
<ComposerItem pagex="22.6852" positionLock="false" width="64.0227" frame="false" excludeFromExports="0" x="22.6852" background="true"
positionMode="0" blendMode="0" page="2" id="" lastValidViewScaleFactor="-1" visibility="1"
pagey="86.5024" height="22.1811" frameJoinStyle="miter" y="306.502" zValue="12" outlineWidth="0.3"
uuid="{d5db4748-2b62-4b79-a785-46a6cb8df967}" opacity="1" itemRotation="0">
<FrameColor green="0" blue="0" red="0" alpha="255"/>
<BackgroundColor green="255" blue="255" red="255" alpha="255"/>
<dataDefinedProperties>

View File

@ -24,7 +24,10 @@
</data_defined_properties>
</layer>
</symbol>
<LayoutItem excludeFromExports="0" positionOnPage="0,0,mm" frame="false" groupUuid="" uuid="{17064c28-2959-4d93-bd12-56258342e897}" background="true" opacity="1" outlineWidthM="0.3,mm" id="" type="65638" referencePoint="0" position="0,0,mm" positionLock="false" visibility="1" size="297,210,mm" templateUuid="{17064c28-2959-4d93-bd12-56258342e897}" frameJoinStyle="miter" itemRotation="0" zValue="0" blendMode="0">
<LayoutItem excludeFromExports="0" positionOnPage="0,0,mm" frame="false" groupUuid="" uuid="{17064c28-2959-4d93-bd12-56258342e897}"
background="true" opacity="1" outlineWidthM="0.3,mm" id="" type="65638" referencePoint="0" position="0,0,mm"
positionLock="false" visibility="1" size="297,210,mm" templateUuid="{17064c28-2959-4d93-bd12-56258342e897}"
frameJoinStyle="miter" itemRotation="0" zValue="0" blendMode="0">
<FrameColor green="0" alpha="255" red="0" blue="0"/>
<BackgroundColor green="255" alpha="255" red="255" blue="255"/>
<LayoutObject>
@ -40,7 +43,11 @@
</LayoutItem>
<GuideCollection visible="1"/>
</PageCollection>
<LayoutItem excludeFromExports="0" labelText="Lorem ipsum" positionOnPage="68.981,56.526,mm" frame="false" groupUuid="" uuid="{7fd8a6f0-6ff5-4da4-9e46-38ec3b239661}" background="false" opacity="1" outlineWidthM="0.3,mm" halign="8" id="" marginY="0" type="65641" marginX="0" referencePoint="0" position="68.981,56.526,mm" valign="32" positionLock="false" visibility="1" size="146.584,43.113,mm" templateUuid="{7fd8a6f0-6ff5-4da4-9e46-38ec3b239661}" frameJoinStyle="miter" itemRotation="0" htmlState="0" zValue="1" blendMode="0">
<LayoutItem excludeFromExports="0" labelText="Lorem ipsum" positionOnPage="68.981,56.526,mm" frame="false" groupUuid=""
uuid="{7fd8a6f0-6ff5-4da4-9e46-38ec3b239661}" background="false" opacity="1" outlineWidthM="0.3,mm" halign="8" id="" marginY="0"
type="65641" marginX="0" referencePoint="0" position="68.981,56.526,mm" valign="32" positionLock="false" visibility="1"
size="146.584,43.113,mm" templateUuid="{7fd8a6f0-6ff5-4da4-9e46-38ec3b239661}" frameJoinStyle="miter" itemRotation="0" htmlState="0"
zValue="1" blendMode="0">
<FrameColor green="0" alpha="255" red="0" blue="0"/>
<BackgroundColor green="255" alpha="255" red="255" blue="255"/>
<LayoutObject>

View File

@ -70,7 +70,10 @@
<LabelFont description="Ubuntu,48,-1,5,25,1,0,0,0,0,Light Italic" style="Light Italic"/>
<FontColor blue="43" red="201" green="240"/>
</LayoutItem>
<LayoutItem outlineWidthM="0.3,mm" type="65641" opacity="1" id="" size="146.584,43.113,mm" referencePoint="4" frameJoinStyle="miter" zValue="1" uuid="{8ebacd90-f769-4ffc-8369-b8248ecde556}" positionOnPage="83.6899,40.644,mm" frame="false" marginY="0" itemRotation="0" labelText="Lorem ipsum" positionLock="false" marginX="0" halign="8" templateUuid="{8ebacd90-f769-4ffc-8369-b8248ecde556}" valign="32" position="156.982,62.2005,mm" visibility="1" background="false" htmlState="0" excludeFromExports="0" blendMode="0" groupUuid="">
<LayoutItem outlineWidthM="0.3,mm" type="65641" opacity="1" id="" size="146.584,43.113,mm" referencePoint="4" frameJoinStyle="miter" zValue="1"
uuid="{8ebacd90-f769-4ffc-8369-b8248ecde556}" positionOnPage="83.6899,40.644,mm" frame="false" marginY="0" itemRotation="0"
labelText="Lorem ipsum" positionLock="false" marginX="0" halign="8" templateUuid="{8ebacd90-f769-4ffc-8369-b8248ecde556}"
valign="32" position="156.982,62.2005,mm" visibility="1" background="false" htmlState="0" excludeFromExports="0" blendMode="0" groupUuid="">
<FrameColor blue="0" alpha="255" red="0" green="0"/>
<BackgroundColor blue="255" alpha="255" red="255" green="255"/>
<LayoutObject>