Skip to content

Commit

Permalink
Merge pull request #4043 from nyalldawson/layer_composer_bridge
Browse files Browse the repository at this point in the history
Bridge map canvas layers to composer map layers
  • Loading branch information
nyalldawson committed Jan 24, 2017
2 parents 5e1339e + a188d14 commit 5e17403
Show file tree
Hide file tree
Showing 51 changed files with 209 additions and 261 deletions.
6 changes: 5 additions & 1 deletion doc/api_break.dox
Expand Up @@ -660,7 +660,10 @@ to use the QgsProperty framework objects.
QgsComposition {#qgis_api_break_3_0_QgsComposition}
--------------

- constructor requires QgsProject instance as the second argument
- The constructor no longer takes a reference to a QgsMapSettings object. This is no longer
used by compositions. To set the layers to show in composer maps, the QgsComposerMap::setLayers()
method should be used instead.
- constructor requires QgsProject instance
- addItemsFromXML() has been renamed to addItemsFromXml()
- Constructor with QgsMapRenderer parameter has been removed. Use the variant with QgsMapSettings parameter.
- mapRenderer() has been removed. Use mapSettings() instead.
Expand All @@ -674,6 +677,7 @@ were removed. Use setSnapTolerance() and snapTolerance() instead.
- worldFileMap() and setWorldFileMap() have been renamed to referenceMap() and setReferenceMap()
- dataDefinedProperty() and setDataDefinedProperty() now use the QgsProperty framework instead
of QgsDataDefined objects.
- mapSettings() was removed. Use QgsComposerMap::mapSettings() instead.


QgsCoordinateReferenceSystem {#qgis_api_break_3_0_QgsCoordinateReferenceSystem}
Expand Down
6 changes: 1 addition & 5 deletions python/core/composer/qgscomposition.sip
Expand Up @@ -40,7 +40,7 @@ class QgsComposition : QGraphicsScene, QgsExpressionContextGenerator
Landscape
};

explicit QgsComposition( const QgsMapSettings& mapSettings, QgsProject* project );
explicit QgsComposition( QgsProject* project );

/** Composition atlas modes*/
enum AtlasMode
Expand Down Expand Up @@ -366,10 +366,6 @@ class QgsComposition : QGraphicsScene, QgsExpressionContextGenerator
/** Used to enable or disable advanced effects such as blend modes in a composition */
void setUseAdvancedEffects( const bool effectsEnabled );

//! Return setting of QGIS map canvas
//! @note added in 2.4
const QgsMapSettings& mapSettings() const;

QgsComposition::PlotStyle plotStyle() const;
void setPlotStyle( const QgsComposition::PlotStyle style );

Expand Down
1 change: 1 addition & 0 deletions python/gui/layertree/qgslayertreemapcanvasbridge.sip
Expand Up @@ -63,6 +63,7 @@ class QgsLayerTreeMapCanvasBridge : QObject
signals:
void hasCustomLayerOrderChanged( bool );
void customLayerOrderChanged( const QStringList& order );
void canvasLayersChanged( const QList< QgsMapLayer* >& layers );

protected:

Expand Down
21 changes: 19 additions & 2 deletions src/app/composer/qgscomposer.cpp
Expand Up @@ -547,7 +547,7 @@ QgsComposer::QgsComposer( QgisApp *qgis, const QString& title )
connect( mActionShowRulers, SIGNAL( triggered( bool ) ), this, SLOT( toggleRulers( bool ) ) );

//init undo/redo buttons
mComposition = new QgsComposition( mQgis->mapCanvas()->mapSettings(), QgsProject::instance() );
mComposition = new QgsComposition( QgsProject::instance() );

mActionUndo->setEnabled( false );
mActionRedo->setEnabled( false );
Expand Down Expand Up @@ -934,6 +934,23 @@ bool QgsComposer::loadFromTemplate( const QDomDocument& templateDoc, bool clearE
return result;
}

void QgsComposer::onCanvasLayersChanged( const QList<QgsMapLayer*>& layers )
{
if ( !mComposition )
return;

QList< QgsComposerMap* > maps;
mComposition->composerItems( maps );

Q_FOREACH ( QgsComposerMap* map, maps )
{
if ( map->keepLayerSet() )
continue;

map->setLayers( layers );
}
}

void QgsComposer::updateStatusCursorPos( QPointF cursorPosition )
{
if ( !mComposition )
Expand Down Expand Up @@ -3543,7 +3560,7 @@ void QgsComposer::readXml( const QDomElement& composerElem, const QDomDocument&
createComposerView();

//read composition settings
mComposition = new QgsComposition( mQgis->mapCanvas()->mapSettings(), QgsProject::instance() );
mComposition = new QgsComposition( QgsProject::instance() );
QDomNodeList compositionNodeList = composerElem.elementsByTagName( QStringLiteral( "Composition" ) );
if ( compositionNodeList.size() > 0 )
{
Expand Down
10 changes: 10 additions & 0 deletions src/app/composer/qgscomposer.h
Expand Up @@ -114,6 +114,16 @@ class QgsComposer: public QMainWindow, private Ui::QgsComposerBase
*/
bool loadFromTemplate( const QDomDocument& templateDoc, bool clearExisting );

public slots:

/**
* Should be called whenever the app's canvas layers change (or layer order
* changes). Required to update composer maps which are synced to the canvas
* layer set with the new canvas layer set.
* @note added in QGIS 3.0
*/
void onCanvasLayersChanged( const QList< QgsMapLayer* >& layers );

protected:
//! Move event
virtual void moveEvent( QMoveEvent * ) override;
Expand Down
12 changes: 6 additions & 6 deletions src/app/composer/qgscomposermapwidget.cpp
Expand Up @@ -905,20 +905,20 @@ void QgsComposerMapWidget::on_mKeepLayerListCheckBox_stateChanged( int state )
return;
}

// update map
storeCurrentLayerSet();
mComposerMap->setKeepLayerSet( state == Qt::Checked );

// update gui
if ( state == Qt::Checked )
{
storeCurrentLayerSet();
mComposerMap->setKeepLayerSet( true );

// mutually exclusive with following a preset
mFollowVisibilityPresetCheckBox->setCheckState( Qt::Unchecked );
}
else
{
mComposerMap->setLayers( QList<QgsMapLayer*>() );
mComposerMap->setKeepLayerSet( false );

mKeepLayerStylesCheckBox->setChecked( Qt::Unchecked );
mComposerMap->updateCachedImage();
}

mKeepLayerStylesCheckBox->setEnabled( state == Qt::Checked );
Expand Down
15 changes: 9 additions & 6 deletions src/app/qgisapp.cpp
Expand Up @@ -6773,9 +6773,11 @@ QgsComposer* QgisApp::createNewComposer( QString title )
mPrintComposersMenu->addAction( newComposerObject->windowAction() );
newComposerObject->open();
emit composerAdded( newComposerObject->view() );
connect( newComposerObject, SIGNAL( composerAdded( QgsComposerView* ) ), this, SIGNAL( composerAdded( QgsComposerView* ) ) );
connect( newComposerObject, SIGNAL( composerWillBeRemoved( QgsComposerView* ) ), this, SIGNAL( composerWillBeRemoved( QgsComposerView* ) ) );
connect( newComposerObject, SIGNAL( atlasPreviewFeatureChanged() ), this, SLOT( refreshMapCanvas() ) );
connect( newComposerObject, &QgsComposer::composerAdded, this, &QgisApp::composerAdded );
connect( newComposerObject, &QgsComposer::composerWillBeRemoved, this, &QgisApp::composerWillBeRemoved );
connect( newComposerObject, &QgsComposer::atlasPreviewFeatureChanged, this, &QgisApp::refreshMapCanvas );
connect( mLayerTreeCanvasBridge, &QgsLayerTreeMapCanvasBridge::canvasLayersChanged, newComposerObject, &QgsComposer::onCanvasLayersChanged );

markDirty();
return newComposerObject;
}
Expand Down Expand Up @@ -6875,9 +6877,10 @@ bool QgisApp::loadComposersFromProject( const QDomDocument& doc )
composerView->updateRulers();
}
emit composerAdded( composer->view() );
connect( composer, SIGNAL( composerAdded( QgsComposerView* ) ), this, SIGNAL( composerAdded( QgsComposerView* ) ) );
connect( composer, SIGNAL( composerWillBeRemoved( QgsComposerView* ) ), this, SIGNAL( composerWillBeRemoved( QgsComposerView* ) ) );
connect( composer, SIGNAL( atlasPreviewFeatureChanged() ), this, SLOT( refreshMapCanvas() ) );
connect( composer, &QgsComposer::composerAdded, this, &QgisApp::composerAdded );
connect( composer, &QgsComposer::composerWillBeRemoved, this, &QgisApp::composerWillBeRemoved );
connect( composer, &QgsComposer::atlasPreviewFeatureChanged, this, &QgisApp::refreshMapCanvas );
connect( mLayerTreeCanvasBridge, &QgsLayerTreeMapCanvasBridge::canvasLayersChanged, composer, &QgsComposer::onCanvasLayersChanged );

QgsDebugMsg( QString( "Loaded composer %1: %2ms" ).arg( title ).arg( t.elapsed() ) );
}
Expand Down
8 changes: 2 additions & 6 deletions src/core/composer/qgscomposermap.cpp
Expand Up @@ -523,15 +523,11 @@ QList<QgsMapLayer*> QgsComposerMap::layersToRender( const QgsExpressionContext*
if ( mComposition->project()->mapThemeCollection()->hasMapTheme( presetName ) )
renderLayers = mComposition->project()->mapThemeCollection()->mapThemeVisibleLayers( presetName );
else // fallback to using map canvas layers
renderLayers = mComposition->mapSettings().layers();
}
else if ( mKeepLayerSet )
{
renderLayers = layers();
renderLayers = layers();
}
else
{
renderLayers = mComposition->mapSettings().layers();
renderLayers = layers();
}

bool ok = false;
Expand Down
30 changes: 26 additions & 4 deletions src/core/composer/qgscomposermap.h
Expand Up @@ -202,14 +202,36 @@ class CORE_EXPORT QgsComposerMap : public QgsComposerItem
PreviewMode previewMode() const {return mPreviewMode;}
void setPreviewMode( PreviewMode m );

//! Getter for flag that determines if the stored layer set should be used or the current layer set of the qgis mapcanvas
/**
* Getter for flag that determines if a stored layer set should be used
* or the current layer set of the QGIS map canvas.
* @see setKeepLayerSet()
* @see layers()
*/
bool keepLayerSet() const {return mKeepLayerSet;}
//! Setter for flag that determines if the stored layer set should be used or the current layer set of the qgis mapcanvas

/**
* Setter for flag that determines if the stored layer set should be used
* or the current layer set of the QGIS map canvas.
* @see keepLayerSet()
* @see layers()
*/
void setKeepLayerSet( bool enabled ) {mKeepLayerSet = enabled;}

//! Getter for stored layer set that is used if mKeepLayerSet is true
/**
* Getter for stored layer set. This will usually be synchronized with the main app canvas
* layer set (and layer order), unless the keepLayerSet() flag is true.
* @see setLayers()
* @see keepLayerSet()
*/
QList<QgsMapLayer*> layers() const;
//! Setter for stored layer set that is used if mKeepLayerSet is true

/**
* Setter for stored layer set. This will usually be synchronized with the main app canvas
* layer set (and layer order), unless the keepLayerSet() flag is true.
* @see layers()
* @see keepLayerSet()
*/
void setLayers( const QList<QgsMapLayer*> layers );

//! Getter for flag that determines if current styles of layers should be overridden by previously stored styles. @note added in 2.8
Expand Down
3 changes: 1 addition & 2 deletions src/core/composer/qgscomposition.cpp
Expand Up @@ -60,9 +60,8 @@
#include "gdal.h"
#include "cpl_conv.h"

QgsComposition::QgsComposition( const QgsMapSettings& mapSettings, QgsProject* project )
QgsComposition::QgsComposition( QgsProject* project )
: QGraphicsScene( nullptr )
, mMapSettings( mapSettings )
, mProject( project )
, mAtlasComposition( this )
{
Expand Down
12 changes: 4 additions & 8 deletions src/core/composer/qgscomposition.h
Expand Up @@ -104,8 +104,10 @@ class CORE_EXPORT QgsComposition : public QGraphicsScene, public QgsExpressionCo
Landscape
};

//! Construct a composition, using given map settings and project
explicit QgsComposition( const QgsMapSettings& mapSettings, QgsProject* project );
/**
* Construct a new composition linked to the specified project.
*/
explicit QgsComposition( QgsProject* project );

//! Composition atlas modes
enum AtlasMode
Expand Down Expand Up @@ -443,10 +445,6 @@ class CORE_EXPORT QgsComposition : public QGraphicsScene, public QgsExpressionCo
//! Used to enable or disable advanced effects such as blend modes in a composition
void setUseAdvancedEffects( const bool effectsEnabled );

//! Return setting of QGIS map canvas
//! @note added in 2.4
const QgsMapSettings& mapSettings() const { return mMapSettings; }

QgsComposition::PlotStyle plotStyle() const { return mPlotStyle; }
void setPlotStyle( const QgsComposition::PlotStyle style ) { mPlotStyle = style; }

Expand Down Expand Up @@ -862,8 +860,6 @@ class CORE_EXPORT QgsComposition : public QGraphicsScene, public QgsExpressionCo


private:
//! Reference to map settings of QGIS main map
const QgsMapSettings& mMapSettings;

//! Pointer to associated project (not null)
QgsProject* mProject;
Expand Down
8 changes: 5 additions & 3 deletions src/gui/layertree/qgslayertreemapcanvasbridge.cpp
Expand Up @@ -34,9 +34,9 @@ QgsLayerTreeMapCanvasBridge::QgsLayerTreeMapCanvasBridge( QgsLayerTreeGroup *roo
, mAutoEnableCrsTransform( true )
, mLastLayerCount( !root->findLayers().isEmpty() )
{
connect( root, SIGNAL( addedChildren( QgsLayerTreeNode*, int, int ) ), this, SLOT( nodeAddedChildren( QgsLayerTreeNode*, int, int ) ) );
connect( root, SIGNAL( customPropertyChanged( QgsLayerTreeNode*, QString ) ), this, SLOT( nodeCustomPropertyChanged( QgsLayerTreeNode*, QString ) ) );
connect( root, SIGNAL( removedChildren( QgsLayerTreeNode*, int, int ) ), this, SLOT( nodeRemovedChildren() ) );
connect( root, &QgsLayerTreeGroup::addedChildren, this, &QgsLayerTreeMapCanvasBridge::nodeAddedChildren );
connect( root, &QgsLayerTreeGroup::customPropertyChanged, this, &QgsLayerTreeMapCanvasBridge::nodeCustomPropertyChanged );
connect( root, &QgsLayerTreeGroup::removedChildren, this, &QgsLayerTreeMapCanvasBridge::nodeRemovedChildren );
connect( root, &QgsLayerTreeNode::visibilityChanged, this, &QgsLayerTreeMapCanvasBridge::nodeVisibilityChanged );

setCanvasLayers();
Expand Down Expand Up @@ -205,6 +205,8 @@ void QgsLayerTreeMapCanvasBridge::setCanvasLayers()
mFirstCRS = QgsCoordinateReferenceSystem();

mPendingCanvasUpdate = false;

emit canvasLayersChanged( canvasLayers );
}

void QgsLayerTreeMapCanvasBridge::readProject( const QDomDocument& doc )
Expand Down
7 changes: 7 additions & 0 deletions src/gui/layertree/qgslayertreemapcanvasbridge.h
Expand Up @@ -92,6 +92,13 @@ class GUI_EXPORT QgsLayerTreeMapCanvasBridge : public QObject
void hasCustomLayerOrderChanged( bool );
void customLayerOrderChanged( const QStringList& order );

/**
* Emitted when the set of layers (or order of layers) visible in the
* canvas changes.
* @note added in QGIS 3.0
*/
void canvasLayersChanged( const QList< QgsMapLayer* >& layers );

protected:

void defaultLayerOrder( QgsLayerTreeNode* node, QStringList& order ) const;
Expand Down
4 changes: 2 additions & 2 deletions src/plugins/georeferencer/qgsgeorefplugingui.cpp
Expand Up @@ -1522,7 +1522,7 @@ bool QgsGeorefPluginGui::writePDFMapFile( const QString& fileName, const QgsGeor
double paperHeight = s.value( QStringLiteral( "/Plugin-GeoReferencer/Config/HeightPDFMap" ), "420" ).toDouble();

//create composition
QgsComposition* composition = new QgsComposition( mCanvas->mapSettings(), QgsProject::instance() );
QgsComposition* composition = new QgsComposition( QgsProject::instance() );
if ( mapRatio >= 1 )
{
composition->setPaperSize( paperHeight, paperWidth );
Expand Down Expand Up @@ -1589,7 +1589,7 @@ bool QgsGeorefPluginGui::writePDFReportFile( const QString& fileName, const QgsG
}

//create composition A4 with 300 dpi
QgsComposition* composition = new QgsComposition( mCanvas->mapSettings(), QgsProject::instance() );
QgsComposition* composition = new QgsComposition( QgsProject::instance() );
composition->setPaperSize( 210, 297 ); //A4
composition->setPrintResolution( 300 );
composition->setNumPages( 2 );
Expand Down
5 changes: 4 additions & 1 deletion src/server/qgswmsprojectparser.cpp
Expand Up @@ -26,6 +26,7 @@
#include "qgspallabeling.h"
#include "qgsrenderer.h"
#include "qgsvectorlayer.h"
#include "qgsmapsettings.h"

#include "qgscomposition.h"
#include "qgscomposerarrow.h"
Expand Down Expand Up @@ -475,7 +476,7 @@ QgsComposition* QgsWmsProjectParser::initComposition( const QString& composerTem
return nullptr;
}

QgsComposition* composition = new QgsComposition( mapSettings, QgsProject::instance() ); //set resolution, paper size from composer element attributes
QgsComposition* composition = new QgsComposition( QgsProject::instance() ); //set resolution, paper size from composer element attributes
if ( !composition->readXml( compositionElem, *( mProjectParser->xmlDocument() ) ) )
{
delete composition;
Expand Down Expand Up @@ -503,6 +504,8 @@ QgsComposition* QgsWmsProjectParser::initComposition( const QString& composerTem
QgsComposerMap* map = qobject_cast< QgsComposerMap *>( *itemIt );
if ( map )
{
if ( !map->keepLayerSet() )
map->setLayers( mapSettings.layers() );
mapList.push_back( map );
continue;
}
Expand Down
3 changes: 2 additions & 1 deletion tests/src/core/testqgs25drenderer.cpp
Expand Up @@ -126,10 +126,11 @@ void TestQgs25DRenderer::render()

void TestQgs25DRenderer::renderComposition()
{
QgsComposition* composition = new QgsComposition( mMapSettings, QgsProject::instance() );
QgsComposition* composition = new QgsComposition( QgsProject::instance() );
composition->setPaperSize( 297, 210 ); //A4 landscape
QgsComposerMap* map = new QgsComposerMap( composition, 20, 20, 200, 100 );
map->setFrameEnabled( true );
map->setLayers( QList< QgsMapLayer* >() << mpPolysLayer );
composition->addComposerMap( map );

map->setNewExtent( mpPolysLayer->extent() );
Expand Down

0 comments on commit 5e17403

Please sign in to comment.