Skip to content

Commit

Permalink
Port a bunch of QgsLayoutManager methods to use QgsLayouts
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Dec 6, 2017
1 parent 3a0b751 commit a9896ea
Show file tree
Hide file tree
Showing 8 changed files with 315 additions and 29 deletions.
6 changes: 6 additions & 0 deletions python/core/layout/qgslayout.sip
Expand Up @@ -537,6 +537,12 @@ class QgsLayout : QGraphicsScene, QgsExpressionContextGenerator, QgsLayoutUndoOb
and updated.
%End

void nameChanged( const QString &name );
%Docstring
Emitted when the layout's name is changed.
.. seealso:: setName()
%End

};


Expand Down
1 change: 1 addition & 0 deletions src/app/layout/qgslayoutdesignerdialog.cpp
Expand Up @@ -633,6 +633,7 @@ void QgsLayoutDesignerDialog::setCurrentLayout( QgsLayout *layout )
{
mLayout->guides().clear();
} );
connect( mLayout, &QgsLayout::nameChanged, this, &QgsLayoutDesignerDialog::setWindowTitle );

mActionShowGrid->setChecked( mLayout->context().gridVisible() );
mActionSnapGrid->setChecked( mLayout->snapper().snapToGrid() );
Expand Down
6 changes: 3 additions & 3 deletions src/app/qgisapp.cpp
Expand Up @@ -7315,7 +7315,7 @@ bool QgisApp::uniqueComposerTitle( QWidget *parent, QString &composerTitle, bool
else
{
titleValid = true;
newTitle = QgsProject::instance()->layoutManager()->generateUniqueTitle();
newTitle = QgsProject::instance()->layoutManager()->generateUniqueComposerTitle();
}
}
else if ( cNames.indexOf( newTitle, 1 ) >= 0 )
Expand Down Expand Up @@ -7380,7 +7380,7 @@ bool QgisApp::uniqueLayoutTitle( QWidget *parent, QString &title, bool acceptEmp
else
{
titleValid = true;
newTitle = QgsProject::instance()->layoutManager()->generateUniqueTitle();
newTitle = QgsProject::instance()->layoutManager()->generateUniqueComposerTitle();
}
}
else if ( cNames.indexOf( newTitle, 1 ) >= 0 )
Expand All @@ -7403,7 +7403,7 @@ QgsComposer *QgisApp::createNewComposer( QString title )
{
if ( title.isEmpty() )
{
title = QgsProject::instance()->layoutManager()->generateUniqueTitle();
title = QgsProject::instance()->layoutManager()->generateUniqueComposerTitle();
}
//create new composition object
QgsComposition *composition = new QgsComposition( QgsProject::instance() );
Expand Down
90 changes: 82 additions & 8 deletions src/core/composer/qgslayoutmanager.cpp
Expand Up @@ -53,6 +53,29 @@ bool QgsLayoutManager::addComposition( QgsComposition *composition )
return true;
}

bool QgsLayoutManager::addLayout( QgsLayout *layout )
{
if ( !layout )
return false;

// check for duplicate name
for ( QgsLayout *l : qgis::as_const( mLayouts ) )
{
if ( l->name() == layout->name() )
return false;
}

connect( layout, &QgsLayout::nameChanged, this, [this, layout]( const QString & newName )
{
emit layoutRenamed( layout, newName );
} );
emit layoutAboutToBeAdded( layout->name() );
mLayouts << layout;
emit layoutAdded( layout->name() );
mProject->setDirty( true );
return true;
}

bool QgsLayoutManager::removeComposition( QgsComposition *composition )
{
if ( !composition )
Expand All @@ -70,19 +93,46 @@ bool QgsLayoutManager::removeComposition( QgsComposition *composition )
return true;
}

bool QgsLayoutManager::removeLayout( QgsLayout *layout )
{
if ( !layout )
return false;

if ( !mLayouts.contains( layout ) )
return false;

QString name = layout->name();
emit layoutAboutToBeRemoved( name );
mLayouts.removeAll( layout );
delete layout;
emit layoutRemoved( name );
mProject->setDirty( true );
return true;
}

void QgsLayoutManager::clear()
{
Q_FOREACH ( QgsComposition *c, mCompositions )
{
removeComposition( c );
}
const QList< QgsLayout * > layouts = mLayouts;
for ( QgsLayout *l : layouts )
{
removeLayout( l );
}
}

QList<QgsComposition *> QgsLayoutManager::compositions() const
{
return mCompositions;
}

QList<QgsLayout *> QgsLayoutManager::layouts() const
{
return mLayouts;
}

QgsComposition *QgsLayoutManager::compositionByName( const QString &name ) const
{
Q_FOREACH ( QgsComposition *c, mCompositions )
Expand All @@ -93,6 +143,16 @@ QgsComposition *QgsLayoutManager::compositionByName( const QString &name ) const
return nullptr;
}

QgsLayout *QgsLayoutManager::layoutByName( const QString &name ) const
{
for ( QgsLayout *l : mLayouts )
{
if ( l->name() == name )
return l;
}
return nullptr;
}

bool QgsLayoutManager::readXml( const QDomElement &element, const QDomDocument &doc )
{
clear();
Expand Down Expand Up @@ -204,22 +264,19 @@ QgsLayout *QgsLayoutManager::duplicateLayout( const QgsLayout *layout, const QSt
}

newLayout->setName( newName );
#if 0 //TODO
if ( !addComposition( newComposition ) )
QgsLayout *l = newLayout.get();
if ( !addLayout( l ) )
{
delete newComposition;
return nullptr;
}
else
{
return newComposition;
( void )newLayout.release(); //ownership was transferred successfully
return l;
}
#endif

return newLayout.release();
}

QString QgsLayoutManager::generateUniqueTitle() const
QString QgsLayoutManager::generateUniqueComposerTitle() const
{
QStringList names;
Q_FOREACH ( QgsComposition *c, mCompositions )
Expand All @@ -236,6 +293,23 @@ QString QgsLayoutManager::generateUniqueTitle() const
return name;
}

QString QgsLayoutManager::generateUniqueTitle() const
{
QStringList names;
for ( QgsLayout *l : mLayouts )
{
names << l->name();
}
QString name;
int id = 1;
while ( name.isEmpty() || names.contains( name ) )
{
name = tr( "Layout %1" ).arg( id );
id++;
}
return name;
}

QgsComposition *QgsLayoutManager::createCompositionFromXml( const QDomElement &element, const QDomDocument &doc ) const
{
QDomNodeList compositionNodeList = element.elementsByTagName( QStringLiteral( "Composition" ) );
Expand Down
66 changes: 60 additions & 6 deletions src/core/composer/qgslayoutmanager.h
Expand Up @@ -19,6 +19,7 @@
#include "qgis_core.h"
#include "qgis.h"
#include "qgscomposition.h"
#include "qgslayout.h"
#include <QObject>

class QgsProject;
Expand All @@ -28,13 +29,13 @@ class QgsProject;
* \class QgsLayoutManager
* \since QGIS 3.0
*
* \brief Manages storage of a set of compositions.
* \brief Manages storage of a set of layouts.
*
* QgsLayoutManager handles the storage, serializing and deserializing
* of QgsCompositions. Usually this class is not constructed directly, but
* of QgsLayouts. Usually this class is not constructed directly, but
* rather accessed through a QgsProject via QgsProject::layoutManager().
*
* QgsLayoutManager retains ownership of all the compositions contained
* QgsLayoutManager retains ownership of all the layouts contained
* in the manager.
*/

Expand All @@ -61,6 +62,15 @@ class CORE_EXPORT QgsLayoutManager : public QObject
*/
bool addComposition( QgsComposition *composition SIP_TRANSFER );

/**
* Adds a \a layout to the manager. Ownership of the layout is transferred to the manager.
* Returns true if the addition was successful, or false if the layout could not be added (eg
* as a result of a duplicate layout name).
* \see removeLayout()
* \see layoutAdded()
*/
bool addLayout( QgsLayout *layout SIP_TRANSFER );

/**
* Removes a composition from the manager. The composition is deleted.
* Returns true if the removal was successful, or false if the removal failed (eg as a result
Expand All @@ -73,8 +83,19 @@ class CORE_EXPORT QgsLayoutManager : public QObject
bool removeComposition( QgsComposition *composition );

/**
* Removes and deletes all compositions from the manager.
* \see removeComposition()
* Removes a \a layout from the manager. The layout is deleted.
* Returns true if the removal was successful, or false if the removal failed (eg as a result
* of removing a layout which is not contained in the manager).
* \see addLayout()
* \see layoutRemoved()
* \see layoutAboutToBeRemoved()
* \see clear()
*/
bool removeLayout( QgsLayout *layout );

/**
* Removes and deletes all layouts from the manager.
* \see removeLayout()
*/
void clear();

Expand All @@ -83,14 +104,25 @@ class CORE_EXPORT QgsLayoutManager : public QObject
*/
QList< QgsComposition * > compositions() const;

/**
* Returns a list of all layouts contained in the manager.
*/
QList< QgsLayout * > layouts() const;

/**
* Returns the composition with a matching name, or nullptr if no matching compositions
* were found.
*/
QgsComposition *compositionByName( const QString &name ) const;

/**
* Reads the manager's state from a DOM element, restoring all compositions
* Returns the layout with a matching name, or nullptr if no matching layouts
* were found.
*/
QgsLayout *layoutByName( const QString &name ) const;

/**
* Reads the manager's state from a DOM element, restoring all layouts
* present in the XML document.
* \see writeXml()
*/
Expand Down Expand Up @@ -126,30 +158,52 @@ class CORE_EXPORT QgsLayoutManager : public QObject
* Generates a unique title for a new composition, which does not
* clash with any already contained by the manager.
*/
QString generateUniqueComposerTitle() const;

/**
* Generates a unique title for a new layout, which does not
* clash with any already contained by the manager.
*/
QString generateUniqueTitle() const;

signals:

//! Emitted when a composition is about to be added to the manager
void compositionAboutToBeAdded( const QString &name );

//! Emitted when a layout is about to be added to the manager
void layoutAboutToBeAdded( const QString &name );

//! Emitted when a composition has been added to the manager
void compositionAdded( const QString &name );

//! Emitted when a layout has been added to the manager
void layoutAdded( const QString &name );

//! Emitted when a composition was removed from the manager
void compositionRemoved( const QString &name );

//! Emitted when a layout was removed from the manager
void layoutRemoved( const QString &name );

//! Emitted when a composition is about to be removed from the manager
void compositionAboutToBeRemoved( const QString &name );

//! Emitted when a layout is about to be removed from the manager
void layoutAboutToBeRemoved( const QString &name );

//! Emitted when a composition is renamed
void compositionRenamed( QgsComposition *composition, const QString &newName );

//! Emitted when a layout is renamed
void layoutRenamed( QgsLayout *layout, const QString &newName );

private:

QgsProject *mProject = nullptr;

QList< QgsComposition * > mCompositions;
QList< QgsLayout * > mLayouts;

QgsComposition *createCompositionFromXml( const QDomElement &element, const QDomDocument &doc ) const;

Expand Down
6 changes: 6 additions & 0 deletions src/core/layout/qgslayout.cpp
Expand Up @@ -117,6 +117,12 @@ QgsLayoutExporter &QgsLayout::exporter()
return mExporter;
}

void QgsLayout::setName( const QString &name )
{
mName = name;
emit nameChanged( name );
}

QList<QgsLayoutItem *> QgsLayout::selectedLayoutItems( const bool includeLockedItems )
{
QList<QgsLayoutItem *> layoutItemList;
Expand Down
9 changes: 8 additions & 1 deletion src/core/layout/qgslayout.h
Expand Up @@ -40,6 +40,7 @@ class QgsLayoutMultiFrame;
class CORE_EXPORT QgsLayout : public QGraphicsScene, public QgsExpressionContextGenerator, public QgsLayoutUndoObjectInterface
{
Q_OBJECT
Q_PROPERTY( QString name READ name WRITE setName NOTIFY nameChanged )

public:

Expand Down Expand Up @@ -108,7 +109,7 @@ class CORE_EXPORT QgsLayout : public QGraphicsScene, public QgsExpressionContext
* Sets the layout's name.
* \see name()
*/
void setName( const QString &name ) { mName = name; }
void setName( const QString &name );

/**
* Returns a list of layout items of a specific type.
Expand Down Expand Up @@ -585,6 +586,12 @@ class CORE_EXPORT QgsLayout : public QGraphicsScene, public QgsExpressionContext
*/
void refreshed();

/**
* Emitted when the layout's name is changed.
* \see setName()
*/
void nameChanged( const QString &name );

private:

QgsProject *mProject = nullptr;
Expand Down

0 comments on commit a9896ea

Please sign in to comment.