Skip to content
Permalink
Browse files

Merge pull request #6492 from nyalldawson/template_converter

[backport] Automatic conversion of 2.x composition templates to 3.0
  • Loading branch information
nyalldawson committed Feb 28, 2018
2 parents 06181e6 + bf224ac commit 529903c5414a1917c7f1cbcadd396460fc98bc18
Showing with 111 additions and 4 deletions.
  1. +23 −0 src/core/layout/qgscompositionconverter.cpp
  2. +17 −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,23 @@ class CORE_EXPORT QgsCompositionConverter
QPointF *position = nullptr,
bool pasteInPlace = false );

/**
* Check if the given \a document is a composition template
* \param document a dom document
* \return true if the document is a composition template
*/
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
*/
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 529903c

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