Skip to content
Permalink
Browse files

Merge pull request #3935 from rouault/group_visibility

[FEATURE] Change of ergonomy of the visibility of layers inside groups
  • Loading branch information
rouault committed Jan 4, 2017
2 parents 46252b5 + 02b78a9 commit f67cdc3965187cc62002e005aedb6a43956ea282
Showing with 427 additions and 339 deletions.
  1. +13 −2 doc/api_break.dox
  2. +1 −10 python/core/layertree/qgslayertreegroup.sip
  3. +0 −3 python/core/layertree/qgslayertreelayer.sip
  4. +1 −0 python/core/layertree/qgslayertreemodel.sip
  5. +29 −1 python/core/layertree/qgslayertreenode.sip
  6. +2 −1 python/gui/layertree/qgscustomlayerorderwidget.sip
  7. +9 −0 python/gui/layertree/qgslayertreeviewdefaultactions.sip
  8. +1 −1 src/app/dwg/qgsdwgimportdialog.cpp
  9. +13 −17 src/app/qgisapp.cpp
  10. +6 −0 src/app/qgsapplayertreeviewmenuprovider.cpp
  11. +2 −2 src/app/qgsvectorlayerproperties.cpp
  12. +23 −128 src/core/layertree/qgslayertreegroup.cpp
  13. +5 −11 src/core/layertree/qgslayertreegroup.h
  14. +5 −17 src/core/layertree/qgslayertreelayer.cpp
  15. +0 −4 src/core/layertree/qgslayertreelayer.h
  16. +16 −14 src/core/layertree/qgslayertreemodel.cpp
  17. +1 −0 src/core/layertree/qgslayertreemodel.h
  18. +55 −2 src/core/layertree/qgslayertreenode.cpp
  19. +36 −2 src/core/layertree/qgslayertreenode.h
  20. +1 −1 src/core/layertree/qgslayertreeregistrybridge.cpp
  21. +5 −5 src/core/layertree/qgslayertreeutils.cpp
  22. +1 −1 src/core/qgsmapthemecollection.cpp
  23. +1 −1 src/core/qgsproject.cpp
  24. +3 −4 src/gui/layertree/qgscustomlayerorderwidget.cpp
  25. +2 −1 src/gui/layertree/qgscustomlayerorderwidget.h
  26. +3 −3 src/gui/layertree/qgslayertreemapcanvasbridge.cpp
  27. +22 −0 src/gui/layertree/qgslayertreeview.cpp
  28. +3 −0 src/gui/layertree/qgslayertreeview.h
  29. +54 −0 src/gui/layertree/qgslayertreeviewdefaultactions.cpp
  30. +14 −0 src/gui/layertree/qgslayertreeviewdefaultactions.h
  31. +2 −2 src/plugins/offline_editing/offline_editing_plugin_gui.cpp
  32. +98 −106 tests/src/core/testqgslayertree.cpp
@@ -691,6 +691,13 @@ QgsCptCitySelectionItem {#qgis_api_break_3_0_QgsCptCitySelectionItem}

- parseXML() has been renamed to parseXml()


QgsCustomLayerOrderWidget {#qgis_api_break_3_0_QgsCustomLayerOrderWidget}
-------------------------

- the signature of the visibilityChanged() signal is changed to visibilityChanged( QgsLayerTreeNode *node )


QgsCRSCache {#qgis_api_break_3_0_QgsCRSCache}
-----------

@@ -1075,12 +1082,16 @@ QgsLayerTreeGroup {#qgis_api_break_3_0_QgsLayerTreeGroup}
-----------------

- readChildrenFromXML() has been renamed to readChildrenFromXml()

- isVisible() is moved to QgsLayerTreeNode
- setVisible() is replaced by QgsLayerTreeNode::setItemVisibilityChecked()
- protected methods updateVisibilityFromChildren() and updateChildVisibility() removed

QgsLayerTreeLayer {#qgis_api_break_3_0_QgsLayerTreeLayer}
-----------------

- setLayerName(), layerName() were renamed to setName(), name()
- isVisible() is moved to QgsLayerTreeNode
- setVisible() is replaced by QgsLayerTreeNode::setItemVisibilityChecked()


QgsLayerTreeModel {#qgis_api_break_3_0_QgsLayerTreeMode}
@@ -1106,7 +1117,7 @@ QgsLayerTreeNode {#qgis_api_break_3_0_QgsLayerTreeNode}

- readCommonXML() has been renamed to readCommonXml()
- writeCommonXML() has been renamed to writeCommonXml()

- the signature of the visibilityChanged() signal is changed to visibilityChanged( QgsLayerTreeNode *node )

QgsLimitedRandomColorRampDialog {#qgis_api_break_3_0_QgsLimitedRandomRampDialog}
-------------------------------
@@ -71,11 +71,6 @@ class QgsLayerTreeGroup : QgsLayerTreeNode
//! Return a clone of the group. The children are cloned too.
virtual QgsLayerTreeGroup* clone() const /Factory/;

//! Return the check state of the group node
Qt::CheckState isVisible() const;
//! Set check state of the group node - will also update children
void setVisible( Qt::CheckState state );

//! Return whether the group is mutually exclusive (only one child can be checked at a time)
//! @note added in 2.12
bool isMutuallyExclusive() const;
@@ -86,14 +81,10 @@ class QgsLayerTreeGroup : QgsLayerTreeNode
void setIsMutuallyExclusive( bool enabled, int initialChildIndex = -1 );

protected slots:
void layerDestroyed();
void nodeVisibilityChanged( QgsLayerTreeNode* node );

protected:
//! Set check state of this group from its children
void updateVisibilityFromChildren();
//! Set check state of children (when this group's check state changes) - if not mutually exclusive
void updateChildVisibility();

//! Set check state of children - if mutually exclusive
void updateChildVisibilityMutuallyExclusive();

@@ -38,9 +38,6 @@ class QgsLayerTreeLayer : QgsLayerTreeNode
//! @note added in 3.0
void setName( const QString& n );

Qt::CheckState isVisible() const;
void setVisible( Qt::CheckState visible );

static QgsLayerTreeLayer* readXml( QDomElement& element ) /Factory/;
virtual void writeXml( QDomElement& parentElement );

@@ -61,6 +61,7 @@ class QgsLayerTreeModel : QAbstractItemModel
AllowNodeRename, //!< Allow renaming of groups and layers
AllowNodeChangeVisibility, //!< Allow user to set node visibility with a check box
AllowLegendChangeState, //!< Allow check boxes for legend nodes (if supported by layer's legend)
ActionHierarchical, //!< Check/uncheck action has consequences on children (or parents for leaf node)
};
typedef QFlags<QgsLayerTreeModel::Flag> Flags;

@@ -94,6 +94,34 @@ class QgsLayerTreeNode : QObject
//! Create a copy of the node. Returns new instance
virtual QgsLayerTreeNode *clone() const = 0 /Factory/;

//! Returns whether a node is really visible (ie checked and all its ancestors checked as well)
//! @note added in 3.0
bool isVisible() const;

//! Returns whether a node is checked (independantly of its ancestors or children)
//! @note added in 3.0
bool itemVisibilityChecked() const;

//! Check or uncheck a node (independantly of its ancestors or children)
//! @note added in 3.0
void setItemVisibilityChecked( bool checked );

//! Check or uncheck a node and all its children (taking into account exclusion rules)
//! @note added in 3.0
virtual void setItemVisibilityCheckedRecursive( bool checked );

//! Check or uncheck a node and all its parents
//! @note added in 3.0
void setItemVisibilityCheckedParentRecursive( bool checked );

//! Return whether this node is checked and all its children.
//! @note added in 3.0
bool isItemVisibilityCheckedRecursive() const;

//! Return whether this node is unchecked and all its children.
//! @note added in 3.0
bool isItemVisibilityUncheckedRecursive() const;

//! Return whether the node should be shown as expanded or collapsed in GUI
bool isExpanded() const;
//! Set whether the node should be shown as expanded or collapsed in GUI
@@ -121,7 +149,7 @@ class QgsLayerTreeNode : QObject
//! Emitted when one or more nodes has been removed from a node within the tree
void removedChildren( QgsLayerTreeNode *node, int indexFrom, int indexTo );
//! Emitted when check state of a node within the tree has been changed
void visibilityChanged( QgsLayerTreeNode *node, Qt::CheckState state );
void visibilityChanged( QgsLayerTreeNode *node );
//! Emitted when a custom property of a node within the tree has been changed or removed
void customPropertyChanged( QgsLayerTreeNode *node, const QString& key );
//! Emitted when the collapsed/expanded state of a node within the tree has been changed
@@ -20,7 +20,8 @@ class QgsCustomLayerOrderWidget : QWidget
protected slots:
void bridgeHasCustomLayerOrderChanged( bool state );
void bridgeCustomLayerOrderChanged( const QStringList& order );
void nodeVisibilityChanged( QgsLayerTreeNode* node, Qt::CheckState state );
//! Slot triggered when the ivsibility of a node changes
void nodeVisibilityChanged( QgsLayerTreeNode* node );

void modelUpdated();
};
@@ -20,6 +20,15 @@ class QgsLayerTreeViewDefaultActions : QObject
QAction* actionRenameGroupOrLayer( QObject* parent = 0 ) /Factory/;
QAction* actionShowFeatureCount( QObject* parent = 0 ) /Factory/;

//! Action to check a group and all its children
QAction* actionCheckAndAllChildren( QObject* parent = nullptr );

//! Action to uncheck a group and all its children
QAction* actionUncheckAndAllChildren( QObject* parent = nullptr );

//! Action to check a group and all its parents
QAction* actionCheckAndAllParents( QObject* parent = nullptr );

QAction* actionZoomToLayer( QgsMapCanvas* canvas, QObject* parent = 0 ) /Factory/;
QAction* actionZoomToGroup( QgsMapCanvas* canvas, QObject* parent = 0 ) /Factory/;
// TODO: zoom to selected
@@ -422,7 +422,7 @@ void QgsDwgImportDialog::createGroup( QgsLayerTreeGroup *group, QString name, QS
if ( !layerGroup->children().isEmpty() )
{
layerGroup->setExpanded( false );
layerGroup->setVisible( visible ? Qt::Checked : Qt::Unchecked );
layerGroup->setItemVisibilityChecked( visible );
}
else
{
@@ -2808,7 +2808,7 @@ void QgisApp::setupConnections()
this, SLOT( markDirty() ) );
connect( mLayerTreeView->layerTreeModel()->rootGroup(), SIGNAL( removedChildren( QgsLayerTreeNode*, int, int ) ),
this, SLOT( updateNewLayerInsertionPoint() ) );
connect( mLayerTreeView->layerTreeModel()->rootGroup(), SIGNAL( visibilityChanged( QgsLayerTreeNode*, Qt::CheckState ) ),
connect( mLayerTreeView->layerTreeModel()->rootGroup(), SIGNAL( visibilityChanged( QgsLayerTreeNode* ) ),
this, SLOT( markDirty() ) );
connect( mLayerTreeView->layerTreeModel()->rootGroup(), SIGNAL( customPropertyChanged( QgsLayerTreeNode*, QString ) ),
this, SLOT( markDirty() ) );
@@ -5759,19 +5759,16 @@ void QgisApp::stopRendering()
void QgisApp::hideAllLayers()
{
QgsDebugMsg( "hiding all layers!" );
mLayerTreeView->layerTreeModel()->rootGroup()->setItemVisibilityCheckedRecursive( false );

Q_FOREACH ( QgsLayerTreeLayer* nodeLayer, mLayerTreeView->layerTreeModel()->rootGroup()->findLayers() )
nodeLayer->setVisible( Qt::Unchecked );
}


// reimplements method from base (gui) class
void QgisApp::showAllLayers()
{
QgsDebugMsg( "Showing all layers!" );

Q_FOREACH ( QgsLayerTreeLayer* nodeLayer, mLayerTreeView->layerTreeModel()->rootGroup()->findLayers() )
nodeLayer->setVisible( Qt::Checked );
mLayerTreeView->layerTreeModel()->rootGroup()->setItemVisibilityCheckedRecursive( true );
}

//reimplements method from base (gui) class
@@ -5781,10 +5778,7 @@ void QgisApp::hideSelectedLayers()

Q_FOREACH ( QgsLayerTreeNode* node, mLayerTreeView->selectedNodes() )
{
if ( QgsLayerTree::isGroup( node ) )
QgsLayerTree::toGroup( node )->setVisible( Qt::Unchecked );
else if ( QgsLayerTree::isLayer( node ) )
QgsLayerTree::toLayer( node )->setVisible( Qt::Unchecked );
node->setItemVisibilityChecked( false );
}
}

@@ -5796,7 +5790,7 @@ void QgisApp::hideDeselectedLayers()
{
if ( selectedLayerNodes.contains( nodeLayer ) )
continue;
nodeLayer->setVisible( Qt::Unchecked );
nodeLayer->setItemVisibilityChecked( false );
}
}

@@ -5807,10 +5801,12 @@ void QgisApp::showSelectedLayers()

Q_FOREACH ( QgsLayerTreeNode* node, mLayerTreeView->selectedNodes() )
{
if ( QgsLayerTree::isGroup( node ) )
QgsLayerTree::toGroup( node )->setVisible( Qt::Checked );
else if ( QgsLayerTree::isLayer( node ) )
QgsLayerTree::toLayer( node )->setVisible( Qt::Checked );
QgsLayerTreeNode* nodeIter = node;
while ( nodeIter )
{
nodeIter->setItemVisibilityChecked( true );
nodeIter = nodeIter->parent();
}
}
}

@@ -8373,7 +8369,7 @@ void QgisApp::layerSubsetString()
// hide the old layer
QgsLayerTreeLayer* vLayerTreeLayer = QgsProject::instance()->layerTreeRoot()->findLayer( vlayer->id() );
if ( vLayerTreeLayer )
vLayerTreeLayer->setVisible( Qt::Unchecked );
vLayerTreeLayer->setItemVisibilityChecked( false );
vlayer = newLayer;
}
else
@@ -8663,7 +8659,7 @@ void QgisApp::duplicateLayers( const QList<QgsMapLayer *>& lyrList )
QgsLayerTreeLayer* nodeDupLayer = parentGroup->insertLayer( parentGroup->children().indexOf( nodeSelectedLyr ) + 1, dupLayer );

// always set duplicated layers to not visible so layer can be configured before being turned on
nodeDupLayer->setVisible( Qt::Unchecked );
nodeDupLayer->setItemVisibilityChecked( false );

// duplicate the layer style
QString errMsg;
@@ -80,6 +80,10 @@ QMenu* QgsAppLayerTreeViewMenuProvider::createContextMenu()

menu->addAction( actions->actionMutuallyExclusiveGroup( menu ) );

menu->addAction( actions->actionCheckAndAllChildren( menu ) );

menu->addAction( actions->actionUncheckAndAllChildren( menu ) );

if ( mView->selectedNodes( true ).count() >= 2 )
menu->addAction( actions->actionGroupSelected( menu ) );

@@ -125,6 +129,8 @@ QMenu* QgsAppLayerTreeViewMenuProvider::createContextMenu()
if ( !layer->isInScaleRange( mCanvas->scale() ) )
menu->addAction( tr( "Zoom to &Visible Scale" ), QgisApp::instance(), SLOT( zoomToLayerScale() ) );

menu->addAction( actions->actionCheckAndAllParents( menu ) );

// set layer crs
menu->addAction( QgsApplication::getThemeIcon( QStringLiteral( "/mActionSetCRS.png" ) ), tr( "Set Layer CRS" ), QgisApp::instance(), SLOT( setLayerCrs() ) );

@@ -309,7 +309,7 @@ QgsVectorLayerProperties::QgsVectorLayerProperties(
// use visibility as selection
mLayersDependenciesTreeModel->setFlag( QgsLayerTreeModel::AllowNodeChangeVisibility );

mLayersDependenciesTreeGroup->setVisible( Qt::Unchecked );
mLayersDependenciesTreeGroup->setItemVisibilityChecked( false );

QSet<QString> dependencySources;
Q_FOREACH ( const QgsMapLayerDependency& dep, mLayer->dependencies() )
@@ -318,7 +318,7 @@ QgsVectorLayerProperties::QgsVectorLayerProperties(
}
Q_FOREACH ( QgsLayerTreeLayer* layer, mLayersDependenciesTreeGroup->findLayers() )
{
layer->setVisible( dependencySources.contains( layer->layerId() ) ? Qt::Checked : Qt::Unchecked );
layer->setItemVisibilityChecked( dependencySources.contains( layer->layerId() ) );
}

mLayersDependenciesTreeView->setModel( mLayersDependenciesTreeModel.data() );

0 comments on commit f67cdc3

Please sign in to comment.
You can’t perform that action at this time.