Skip to content
Permalink
Browse files

Merge pull request #6470 from elpaso/template-convert

[layout] Automatic conversion of 2.x composition templates to layouts
  • Loading branch information
elpaso committed Feb 27, 2018
2 parents 6bb8a9b + 27ab59c commit 91b9a69d3e64d6797ec88e384cf58115b4ce264a
Showing with 112 additions and 4 deletions.
  1. +23 −0 src/core/layout/qgscompositionconverter.cpp
  2. +18 −0 src/core/layout/qgscompositionconverter.h
  3. +12 −1 src/core/layout/qgslayout.cpp
  4. +59 −3 tests/src/core/testqgscompositionconverter.cpp
  5. BIN ...rol_images/compositionconverter/expected_importComposerAtlas_0/expected_importComposerAtlas_0.png
  6. BIN ...mages/compositionconverter/expected_importComposerAtlas_0/expected_importComposerAtlas_0_mask.png
  7. BIN ...sitionconverter/expected_importComposerTemplateArrow_0/expected_importComposerTemplateArrow_0.png
  8. BIN ...pected_importComposerTemplateAttributeTable_0/expected_importComposerTemplateAttributeTable_0.png
  9. BIN ...d_importComposerTemplateAttributeTable_0/expected_importComposerTemplateAttributeTable_0_mask.png
  10. BIN ...positionconverter/expected_importComposerTemplateHtml_0/expected_importComposerTemplateHtml_0.png
  11. BIN ...ionconverter/expected_importComposerTemplateHtml_0/expected_importComposerTemplateHtml_0_mask.png
  12. BIN ...tionconverter/expected_importComposerTemplateLegend_0/expected_importComposerTemplateLegend_0.png
  13. BIN ...onverter/expected_importComposerTemplateLegend_0/expected_importComposerTemplateLegend_0_mask.png
  14. BIN ...ompositionconverter/expected_importComposerTemplateMap_0/expected_importComposerTemplateMap_0.png
  15. BIN ...itionconverter/expected_importComposerTemplateMap_0/expected_importComposerTemplateMap_0_mask.png
  16. BIN ...onconverter/expected_importComposerTemplatePicture_0/expected_importComposerTemplatePicture_0.png
  17. BIN ...onconverter/expected_importComposerTemplatePolygon_0/expected_importComposerTemplatePolygon_0.png
  18. BIN ...converter/expected_importComposerTemplatePolyline_0/expected_importComposerTemplatePolyline_0.png
  19. BIN ...converter/expected_importComposerTemplateScaleBar_0/expected_importComposerTemplateScaleBar_0.png
  20. BIN ...sitionconverter/expected_importComposerTemplateShape_0/expected_importComposerTemplateShape_0.png
  21. BIN ...ages/compositionconverter/expected_importComposerTemplate_0/expected_importComposerTemplate_0.png
  22. BIN ...compositionconverter/expected_importComposerTemplate_0/expected_importComposerTemplate_0_mask.png
  23. BIN ...ages/compositionconverter/expected_importComposerTemplate_1/expected_importComposerTemplate_1.png
  24. BIN ...compositionconverter/expected_importComposerTemplate_1/expected_importComposerTemplate_1_mask.png
@@ -452,6 +452,29 @@ QList<QgsLayoutObject *> QgsCompositionConverter::addItemsFromCompositionXml( Qg
return newItems;
}

bool QgsCompositionConverter::isCompositionTemplate( const QDomDocument &document )
{
return document.elementsByTagName( QStringLiteral( "Composition" ) ).count() > 0;
}

QDomDocument QgsCompositionConverter::convertCompositionTemplate( const QDomDocument &document, QgsProject *project )
{
QDomDocument doc;
QgsReadWriteContext context;
if ( project )
context.setPathResolver( project->pathResolver() );
if ( document.elementsByTagName( QStringLiteral( "Composition" ) ).count( ) > 0 )
{
QDomElement composerElem = document.elementsByTagName( QStringLiteral( "Composition" ) ).at( 0 ).toElement( );

std::unique_ptr<QgsLayout> layout = createLayoutFromCompositionXml( composerElem,
project );
QDomElement elem = layout->writeXml( doc, context );
doc.appendChild( elem );
}
return doc;
}

bool QgsCompositionConverter::readLabelXml( QgsLayoutItemLabel *layoutItem, const QDomElement &itemElem, const QgsProject *project )
{
Q_UNUSED( project );
@@ -144,6 +144,24 @@ class CORE_EXPORT QgsCompositionConverter
QPointF *position = nullptr,
bool pasteInPlace = false );

/**
* Check if the given \a document is a composition template
* \return true if the document is a composition template
* \since QGIS 3.0.1
*/
static bool isCompositionTemplate( const QDomDocument &document );

/**
* Convert a composition template \a document to a layout template
* \param document containing a composition
* \param project
* \return dom document with the converted template
* \since QGIS 3.0.1
*/
static QDomDocument convertCompositionTemplate( const QDomDocument
&document, QgsProject *project );


private:


@@ -27,6 +27,7 @@
#include "qgslayoutmultiframe.h"
#include "qgslayoutitemmap.h"
#include "qgslayoutundostack.h"
#include "qgscompositionconverter.h"

QgsLayout::QgsLayout( QgsProject *project )
: mProject( project )
@@ -609,7 +610,17 @@ QList< QgsLayoutItem * > QgsLayout::loadFromTemplate( const QDomDocument &docume
clear();
}

QDomDocument doc = document;
QDomDocument doc;

// If this is a 2.x composition template, convert it to a layout template
if ( QgsCompositionConverter::isCompositionTemplate( document ) )
{
doc = QgsCompositionConverter::convertCompositionTemplate( document, mProject );
}
else
{
doc = document;
}

// remove all uuid attributes since we don't want duplicates UUIDS
QDomNodeList itemsNodes = doc.elementsByTagName( QStringLiteral( "LayoutItem" ) );
@@ -44,6 +44,16 @@
#include "qgslayoutitemattributetable.h"


// Debug output for dom nodes
QDebug operator<<( QDebug dbg, const QDomNode &node )
{
QString s;
QTextStream str( &s, QIODevice::WriteOnly );
node.save( str, 2 );
dbg << qPrintable( s );
return dbg;
}

class TestQgsCompositionConverter: public QObject
{
Q_OBJECT
@@ -125,7 +135,17 @@ class TestQgsCompositionConverter: public QObject
/**
* Test automatic conversion from a composer template
*/
void convertComposerTemplate();
void convertComposition();

/**
* Test if a composition template can be detected from a dom document
*/
void isCompositionTemplate();

/**
* Test if a composition template can be converted to a layout template
*/
void convertCompositionTemplate();


private:
@@ -523,7 +543,7 @@ void TestQgsCompositionConverter::importComposerTemplateScaleBar()
}


void TestQgsCompositionConverter::convertComposerTemplate()
void TestQgsCompositionConverter::convertComposition()
{

QgsProject project;
@@ -541,6 +561,42 @@ void TestQgsCompositionConverter::convertComposerTemplate()

}

void TestQgsCompositionConverter::isCompositionTemplate()
{
QString templatePath( QStringLiteral( TEST_DATA_DIR ) + "/layouts/2x_template.qpt" );
QDomDocument doc( "mydocument" );
QFile file( templatePath );
file.open( QIODevice::ReadOnly );
doc.setContent( &file );
file.close();

QVERIFY( QgsCompositionConverter::isCompositionTemplate( doc ) );

}

void TestQgsCompositionConverter::convertCompositionTemplate()
{
QString templatePath( QStringLiteral( TEST_DATA_DIR ) + "/layouts/2x_template.qpt" );
QDomDocument doc( "mydocument" );
QFile file( templatePath );
file.open( QIODevice::ReadOnly );
doc.setContent( &file );
file.close();

QgsProject project;

QDomDocument layoutDoc = QgsCompositionConverter::convertCompositionTemplate( doc, &project );
//qDebug() << layoutDoc;
QCOMPARE( layoutDoc.elementsByTagName( QStringLiteral( "Layout" ) ).count(), 1 );

std::unique_ptr<QgsLayout> layout = qgis::make_unique<QgsLayout>( &project );
QgsReadWriteContext context;
context.setPathResolver( project.pathResolver() );
layout->readXml( layoutDoc.elementsByTagName( QStringLiteral( "Layout" ) ).at( 0 ).toElement(), layoutDoc, context );
QVERIFY( layout.get() );
QCOMPARE( layout->pageCollection()->pageCount(), 2 );
}

void TestQgsCompositionConverter::importComposerTemplate()
{
QDomElement composerElem( loadComposer( "2x_template.qpt" ) );
@@ -646,7 +702,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, 0, true ) );
QVERIFY( checker.testLayout( mReport, pageNumber, 0, false ) );
}


Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

0 comments on commit 91b9a69

Please sign in to comment.
You can’t perform that action at this time.