Skip to content

Commit

Permalink
Port composer template saving and duplicating to layout manager
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Mar 21, 2017
1 parent 8478b7a commit 8c8ac61
Show file tree
Hide file tree
Showing 7 changed files with 85 additions and 41 deletions.
10 changes: 6 additions & 4 deletions python/core/composer/qgslayoutmanager.sip
Expand Up @@ -13,10 +13,12 @@ class QgsLayoutManager : QObject
bool removeComposition( QgsComposition* composition );

void clear();
QList< QgsComposition* > compositions() const;
QgsComposition* compositionByName( const QString& name ) const;
bool readXml( const QDomElement& element, const QDomDocument& doc );
QDomElement writeXml( QDomDocument& doc ) const;
QList< QgsComposition * > compositions() const;
QgsComposition *compositionByName( const QString &name ) const;
bool readXml( const QDomElement &element, const QDomDocument &doc );
QDomElement writeXml( QDomDocument &doc ) const;
bool saveAsTemplate( const QString &name, QDomDocument &doc ) const;
QgsComposition *duplicateComposition( const QString &name, const QString &newName );

signals:
void compositionAdded( const QString& name );
Expand Down
16 changes: 6 additions & 10 deletions src/app/composer/qgscomposer.cpp
Expand Up @@ -68,6 +68,7 @@
#include "ui_qgssvgexportoptions.h"
#include "qgspanelwidgetstack.h"
#include "qgssettings.h"
#include "qgslayoutmanager.h"

#include <QCloseEvent>
#include <QCheckBox>
Expand Down Expand Up @@ -113,7 +114,7 @@ QgsComposer::QgsComposer( QgsComposition *composition )
, mQgis( QgisApp::instance() )
{
setupUi( this );
setWindowTitle( mComposition->name() );
setTitle( mComposition->name() );
setAttribute( Qt::WA_DeleteOnClose );
#if QT_VERSION >= 0x050600
setDockOptions( dockOptions() | QMainWindow::GroupedDragging ) ;
Expand Down Expand Up @@ -2951,7 +2952,7 @@ void QgsComposer::on_mActionNewComposer_triggered()
void QgsComposer::on_mActionDuplicateComposer_triggered()
{
QString newTitle;
if ( !mQgis->uniqueComposerTitle( this, newTitle, false, title() + tr( " copy" ) ) )
if ( !mQgis->uniqueComposerTitle( this, newTitle, false, mComposition->name() + tr( " copy" ) ) )
{
return;
}
Expand Down Expand Up @@ -3015,7 +3016,7 @@ void QgsComposer::on_mActionSaveAsTemplate_triggered()
}

QDomDocument saveDocument;
templateXml( saveDocument );
QgsProject::instance()->layoutManager()->saveAsTemplate( mComposition->name(), saveDocument );

if ( templateFile.write( saveDocument.toByteArray() ) == -1 )
{
Expand Down Expand Up @@ -3360,11 +3361,11 @@ void QgsComposer::restoreWindowState()
}
}

void QgsComposer::writeXml( QDomNode &parentNode, QDomDocument &doc )
void QgsComposer::templateXml( QDomDocument &doc )
{
QDomElement composerElem = doc.createElement( QStringLiteral( "Composer" ) );
composerElem.setAttribute( QStringLiteral( "title" ), mTitle );
parentNode.appendChild( composerElem );
doc.appendChild( composerElem );

//store composition
if ( mComposition )
Expand All @@ -3376,11 +3377,6 @@ void QgsComposer::writeXml( QDomNode &parentNode, QDomDocument &doc )
mComposition->atlasComposition().writeXml( composerElem, doc );
}

void QgsComposer::templateXml( QDomDocument &doc )
{
writeXml( doc, doc );
}

void QgsComposer::createCompositionWidget()
{
if ( !mComposition )
Expand Down
3 changes: 0 additions & 3 deletions src/app/composer/qgscomposer.h
Expand Up @@ -487,9 +487,6 @@ class QgsComposer: public QMainWindow, private Ui::QgsComposerBase
//! Changes elements that are not suitable for this project
void cleanupAfterTemplateRead();

//! Writes state under DOM element
void writeXml( QDomNode &parentNode, QDomDocument &doc );

//! Removes all the item from the graphics scene and deletes them
void deleteItemWidgets();

Expand Down
31 changes: 7 additions & 24 deletions src/app/qgisapp.cpp
Expand Up @@ -6987,7 +6987,11 @@ QgsComposer *QgisApp::createNewComposer( QString title )
QgsComposition *composition = new QgsComposition( QgsProject::instance() );
composition->setName( title );
QgsProject::instance()->layoutManager()->addComposition( composition );
return openComposer( composition );
}

QgsComposer *QgisApp::openComposer( QgsComposition *composition )
{
QgsComposer *newComposerObject = new QgsComposer( composition );
connect( newComposerObject, &QgsComposer::aboutToClose, this, [this, newComposerObject]
{
Expand Down Expand Up @@ -7016,42 +7020,21 @@ void QgisApp::deleteComposer( QgsComposer *c )

QgsComposer *QgisApp::duplicateComposer( QgsComposer *currentComposer, QString title )
{
QgsComposer *newComposer = nullptr;

// test that current composer template write is valid
QDomDocument currentDoc;
currentComposer->templateXml( currentDoc );
QDomElement compositionElem = currentDoc.documentElement().firstChildElement( QStringLiteral( "Composition" ) );
if ( compositionElem.isNull() )
{
QgsDebugMsg( "selected composer could not be stored as temporary template" );
return newComposer;
}

if ( title.isEmpty() )
{
// TODO: inject a bit of randomness in auto-titles?
title = currentComposer->title() + tr( " copy" );
}

newComposer = createNewComposer( title );
QgsComposition *newComposition = QgsProject::instance()->layoutManager()->duplicateComposition( currentComposer->composition()->name(),
title );
QgsComposer *newComposer = openComposer( newComposition );
if ( !newComposer )
{
QgsDebugMsg( "could not create new composer" );
return newComposer;
}

// hiding composer until template is loaded is much faster, provide feedback to user
newComposer->hide();
if ( !newComposer->loadFromTemplate( currentDoc, true ) )
{
deleteComposer( newComposer );
newComposer = nullptr;
QgsDebugMsg( "Error, composer could not be duplicated" );
return newComposer;
}
newComposer->activate();

return newComposer;
}

Expand Down
7 changes: 7 additions & 0 deletions src/app/qgisapp.h
Expand Up @@ -46,6 +46,7 @@ class QgsAuthManager;
class QgsBookmarks;
class QgsClipboard;
class QgsComposer;
class QgsComposition;
class QgsComposerManager;
class QgsComposerView;
class QgsContrastEnhancement;
Expand Down Expand Up @@ -332,6 +333,12 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
bool uniqueComposerTitle( QWidget *parent, QString &composerTitle, bool acceptEmpty, const QString &currentTitle = QString() );
//! Creates a new composer and returns a pointer to it
QgsComposer *createNewComposer( QString title = QString() );

/**
* Opens a composer window for an existing \a composition.
*/
QgsComposer *openComposer( QgsComposition *composition );

//! Deletes a composer and removes entry from Set
void deleteComposer( QgsComposer *c );

Expand Down
46 changes: 46 additions & 0 deletions src/core/composer/qgslayoutmanager.cpp
Expand Up @@ -15,6 +15,7 @@

#include "qgslayoutmanager.h"
#include "qgsproject.h"
#include "qgslogger.h"

QgsLayoutManager::QgsLayoutManager( QgsProject *project )
: QObject( project )
Expand Down Expand Up @@ -129,6 +130,51 @@ QDomElement QgsLayoutManager::writeXml( QDomDocument &doc ) const
return layoutsElem;
}

bool QgsLayoutManager::saveAsTemplate( const QString &name, QDomDocument &doc ) const
{
QgsComposition *c = compositionByName( name );
if ( !c )
return false;

QDomElement composerElem = doc.createElement( QStringLiteral( "Composer" ) );
doc.appendChild( composerElem );
c->writeXml( composerElem, doc );
c->atlasComposition().writeXml( composerElem, doc );
return true;
}

QgsComposition *QgsLayoutManager::duplicateComposition( const QString &name, const QString &newName )
{
QDomDocument currentDoc;
if ( !saveAsTemplate( name, currentDoc ) )
return nullptr;

QDomElement compositionElem = currentDoc.documentElement().firstChildElement( QStringLiteral( "Composition" ) );
if ( compositionElem.isNull() )
{
QgsDebugMsg( "selected composer could not be stored as temporary template" );
return nullptr;
}

QgsComposition *newComposition( new QgsComposition( mProject ) );
if ( !newComposition->loadFromTemplate( currentDoc, nullptr, false, true ) )
{
delete newComposition;
return nullptr;
}

newComposition->setName( newName );
if ( !addComposition( newComposition ) )
{
delete newComposition;
return nullptr;
}
else
{
return newComposition;
}
}

QgsComposition *QgsLayoutManager::createCompositionFromXml( const QDomElement &element, const QDomDocument &doc ) const
{
QDomNodeList compositionNodeList = element.elementsByTagName( QStringLiteral( "Composition" ) );
Expand Down
13 changes: 13 additions & 0 deletions src/core/composer/qgslayoutmanager.h
Expand Up @@ -100,6 +100,19 @@ class CORE_EXPORT QgsLayoutManager : public QObject
*/
QDomElement writeXml( QDomDocument &doc ) const;

/**
* Saves the composition with matching \a name in template format.
* Returns true if save was successful.
*/
bool saveAsTemplate( const QString &name, QDomDocument &doc ) const;

/**
* Duplicates an existing composition from the manager. The new
* composition will automatically be stored in the manager.
* Returns new composition if duplication was successful.
*/
QgsComposition *duplicateComposition( const QString &name, const QString &newName );

signals:

//! Emitted when a composition has been added to the manager
Expand Down

0 comments on commit 8c8ac61

Please sign in to comment.