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(); ~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(); void initializeDefaults();
%Docstring %Docstring
Initializes an empty layout, e.g. by adding a default page to the layout. This should be called after creating 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. Constructor for QgsPrintLayout.
%End %End
virtual QgsPrintLayout *clone() const /Factory/;
QgsLayoutAtlas *atlas(); QgsLayoutAtlas *atlas();
%Docstring %Docstring
Returns the print layout's atlas. 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 ) QgsLayout *QgsLayoutManager::duplicateLayout( const QgsLayout *layout, const QString &newName )
{ {
QDomDocument currentDoc; std::unique_ptr< QgsLayout > newLayout( layout->clone() );
if ( !newLayout )
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 )
{ {
return nullptr; return nullptr;
} }

View File

@ -75,6 +75,25 @@ QgsLayout::~QgsLayout()
mItemsModel.reset(); // manually delete, so we can control order of destruction 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() void QgsLayout::initializeDefaults()
{ {
// default to a A4 landscape page // default to a A4 landscape page

View File

@ -83,6 +83,12 @@ class CORE_EXPORT QgsLayout : public QGraphicsScene, public QgsExpressionContext
~QgsLayout() override; ~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 * Initializes an empty layout, e.g. by adding a default page to the layout. This should be called after creating
* a new layout. * a new layout.

View File

@ -16,6 +16,7 @@
#include "qgsprintlayout.h" #include "qgsprintlayout.h"
#include "qgslayoutatlas.h" #include "qgslayoutatlas.h"
#include "qgsreadwritecontext.h"
QgsPrintLayout::QgsPrintLayout( QgsProject *project ) QgsPrintLayout::QgsPrintLayout( QgsProject *project )
: QgsLayout( 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() QgsLayoutAtlas *QgsPrintLayout::atlas()
{ {
return mAtlas; return mAtlas;

View File

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

View File

@ -26,6 +26,8 @@
#include "qgslayoutitempolyline.h" #include "qgslayoutitempolyline.h"
#include "qgslayoutitemhtml.h" #include "qgslayoutitemhtml.h"
#include "qgslayoutframe.h" #include "qgslayoutframe.h"
#include "qgsprintlayout.h"
#include "qgslayoutatlas.h"
class TestQgsLayout: public QObject class TestQgsLayout: public QObject
{ {
@ -54,6 +56,7 @@ class TestQgsLayout: public QObject
void pageIsEmpty(); void pageIsEmpty();
void clear(); void clear();
void georeference(); void georeference();
void clone();
private: private:
QString mReport; QString mReport;
@ -844,6 +847,44 @@ void TestQgsLayout::georeference()
t.reset(); 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 ) QGSTEST_MAIN( TestQgsLayout )
#include "testqgslayout.moc" #include "testqgslayout.moc"