Add a clone method to QgsLayout

This commit is contained in:
Nyall Dawson 2017-12-29 09:38:30 +10:00
parent 5bc543af6a
commit 4d2f0deb1a
8 changed files with 99 additions and 10 deletions

View File

@ -56,6 +56,12 @@ called on the new layout.
~QgsLayout();
virtual QgsLayout *clone() const /Factory/;
%Docstring
Creates a clone of the layout. Ownership of the return layout
is transferred to the caller.
%End
void initializeDefaults();
%Docstring
Initializes an empty layout, e.g. by adding a default page to the layout. This should be called after creating

View File

@ -26,6 +26,9 @@ class QgsPrintLayout : QgsLayout
Constructor for QgsPrintLayout.
%End
virtual QgsPrintLayout *clone() const /Factory/;
QgsLayoutAtlas *atlas();
%Docstring
Returns the print layout's atlas.

View File

@ -283,16 +283,8 @@ QgsComposition *QgsLayoutManager::duplicateComposition( const QString &name, con
QgsLayout *QgsLayoutManager::duplicateLayout( const QgsLayout *layout, const QString &newName )
{
QDomDocument currentDoc;
QgsReadWriteContext context;
QDomElement elem = layout->writeXml( currentDoc, context );
currentDoc.appendChild( elem );
std::unique_ptr< QgsLayout > newLayout = qgis::make_unique< QgsPrintLayout >( mProject );
bool ok = false;
newLayout->loadFromTemplate( currentDoc, context, true, &ok );
if ( !ok )
std::unique_ptr< QgsLayout > newLayout( layout->clone() );
if ( !newLayout )
{
return nullptr;
}

View File

@ -75,6 +75,25 @@ QgsLayout::~QgsLayout()
mItemsModel.reset(); // manually delete, so we can control order of destruction
}
QgsLayout *QgsLayout::clone() const
{
QDomDocument currentDoc;
QgsReadWriteContext context;
QDomElement elem = writeXml( currentDoc, context );
currentDoc.appendChild( elem );
std::unique_ptr< QgsLayout > newLayout = qgis::make_unique< QgsLayout >( mProject );
bool ok = false;
newLayout->loadFromTemplate( currentDoc, context, true, &ok );
if ( !ok )
{
return nullptr;
}
return newLayout.release();
}
void QgsLayout::initializeDefaults()
{
// default to a A4 landscape page

View File

@ -83,6 +83,12 @@ class CORE_EXPORT QgsLayout : public QGraphicsScene, public QgsExpressionContext
~QgsLayout() override;
/**
* Creates a clone of the layout. Ownership of the return layout
* is transferred to the caller.
*/
virtual QgsLayout *clone() const SIP_FACTORY;
/**
* Initializes an empty layout, e.g. by adding a default page to the layout. This should be called after creating
* a new layout.

View File

@ -16,6 +16,7 @@
#include "qgsprintlayout.h"
#include "qgslayoutatlas.h"
#include "qgsreadwritecontext.h"
QgsPrintLayout::QgsPrintLayout( QgsProject *project )
: QgsLayout( project )
@ -23,6 +24,25 @@ QgsPrintLayout::QgsPrintLayout( QgsProject *project )
{
}
QgsPrintLayout *QgsPrintLayout::clone() const
{
QDomDocument currentDoc;
QgsReadWriteContext context;
QDomElement elem = writeXml( currentDoc, context );
currentDoc.appendChild( elem );
std::unique_ptr< QgsPrintLayout > newLayout = qgis::make_unique< QgsPrintLayout >( project() );
bool ok = false;
newLayout->loadFromTemplate( currentDoc, context, true, &ok );
if ( !ok )
{
return nullptr;
}
return newLayout.release();
}
QgsLayoutAtlas *QgsPrintLayout::atlas()
{
return mAtlas;

View File

@ -38,6 +38,8 @@ class CORE_EXPORT QgsPrintLayout : public QgsLayout
*/
QgsPrintLayout( QgsProject *project );
QgsPrintLayout *clone() const override SIP_FACTORY;
/**
* Returns the print layout's atlas.
*/

View File

@ -26,6 +26,8 @@
#include "qgslayoutitempolyline.h"
#include "qgslayoutitemhtml.h"
#include "qgslayoutframe.h"
#include "qgsprintlayout.h"
#include "qgslayoutatlas.h"
class TestQgsLayout: public QObject
{
@ -54,6 +56,7 @@ class TestQgsLayout: public QObject
void pageIsEmpty();
void clear();
void georeference();
void clone();
private:
QString mReport;
@ -844,6 +847,44 @@ void TestQgsLayout::georeference()
t.reset();
}
void TestQgsLayout::clone()
{
QgsProject proj;
QgsLayout l( &proj );
QgsLayoutItemPage *page = new QgsLayoutItemPage( &l );
page->setPageSize( "A4" );
l.pageCollection()->addPage( page );
QgsLayoutItemPage *page2 = new QgsLayoutItemPage( &l );
page2->setPageSize( "A4" );
l.pageCollection()->addPage( page2 );
QgsLayoutItemPage *page3 = new QgsLayoutItemPage( &l );
page3->setPageSize( "A4" );
l.pageCollection()->addPage( page3 );
//add some items to the composition
QgsLayoutItemShape *label1 = new QgsLayoutItemShape( &l );
l.addLayoutItem( label1 );
QgsLayoutItemShape *label2 = new QgsLayoutItemShape( &l );
l.addLayoutItem( label2 );
QgsLayoutItemShape *label3 = new QgsLayoutItemShape( &l );
l.addLayoutItem( label3 );
// clone and check a few poperties
std::unique_ptr< QgsLayout > cloned( l.clone() );
QVERIFY( cloned.get() );
QCOMPARE( cloned->pageCollection()->pageCount(), 3 );
QList< QgsLayoutItem * > items;
cloned->layoutItems( items );
QCOMPARE( items.count(), 6 ); // 3 pages + 3 items
// clone a print layout
QgsPrintLayout pl( &proj );
pl.atlas()->setPageNameExpression( QStringLiteral( "not a real expression" ) );
std::unique_ptr< QgsPrintLayout > plClone( pl.clone() );
QVERIFY( plClone.get() );
QCOMPARE( plClone->atlas()->pageNameExpression(), QStringLiteral( "not a real expression" ) );
}
QGSTEST_MAIN( TestQgsLayout )
#include "testqgslayout.moc"