Skip to content

Commit

Permalink
[composer] Don't use canvas map settings to determine canvas layers
Browse files Browse the repository at this point in the history
Instead make the layer tree canvas bridge advise on layer set
changes, and tie this into composer. So now composer acts
as a go-between to sync the composer map item's layer set to
the layer tree/canvas layers.

It's not an ideal solution, but avoids the hard link between
compositions and the map canvas.
  • Loading branch information
nyalldawson committed Jan 24, 2017
1 parent 9816938 commit b41f3a7
Show file tree
Hide file tree
Showing 9 changed files with 83 additions and 25 deletions.
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
17 changes: 17 additions & 0 deletions src/app/composer/qgscomposer.cpp
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
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
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

0 comments on commit b41f3a7

Please sign in to comment.