Fix QgsLayerTreeModel naming conventions and update Python bindings

I was using a mixture of terms 'symbology items' and 'legend nodes' for the same thing which was confusing
This commit is contained in:
Martin Dobias 2014-09-05 18:33:55 +07:00
parent 854730bb59
commit 86b4fcc7be
8 changed files with 159 additions and 115 deletions

View File

@ -6,7 +6,7 @@
* The model listens to the changes in the layer tree and signals the changes as appropriate,
* so that any view that uses the model is updated accordingly.
*
* Behavior of the model can be customized with flags. For example, whether to show symbology or
* Behavior of the model can be customized with flags. For example, whether to show legend or
* whether to allow changes to the layer tree.
*
* @see QgsLayerTreeView
@ -51,13 +51,15 @@ class QgsLayerTreeModel : QAbstractItemModel
enum Flag
{
// display flags
ShowSymbology, //!< Add symbology items for layer nodes
ShowLegend, //!< Add legend nodes for layer nodes
ShowSymbology, //!< deprecated - use ShowLegend
// behavioral flags
AllowNodeReorder, //!< Allow reordering with drag'n'drop
AllowNodeRename, //!< Allow renaming of groups and layers
AllowNodeChangeVisibility, //!< Allow user to set node visibility with a check box
AllowSymbologyChangeState, //!< Allow check boxes for symbology items (if supported by layer's legend)
AllowLegendChangeState, //!< Allow check boxes for legend nodes (if supported by layer's legend)
AllowSymbologyChangeState, //!< deprecated - use AllowLegendChangeState
};
typedef QFlags<QgsLayerTreeModel::Flag> Flags;
@ -71,7 +73,7 @@ class QgsLayerTreeModel : QAbstractItemModel
bool testFlag( Flag f ) const;
//! Return layer tree node for given index. Returns root node for invalid index.
//! Returns null pointer if index does not refer to a layer tree node (e.g. it is a symbology item)
//! Returns null pointer if index does not refer to a layer tree node (e.g. it is a legend node)
QgsLayerTreeNode* index2node( const QModelIndex& index ) const;
//! Return index for a given node. If the node does not belong to the layer tree, the result is undefined
QModelIndex node2index( QgsLayerTreeNode* node ) const;
@ -79,17 +81,27 @@ class QgsLayerTreeModel : QAbstractItemModel
//! Indices that do not represent layer tree nodes are skipped.
//! @arg skipInternal If true, a node is included in the output list only if no parent node is in the list
QList<QgsLayerTreeNode*> indexes2nodes( const QModelIndexList& list, bool skipInternal = false ) const;
//! Return true if index represents a symbology node (instead of layer node)
bool isIndexSymbologyNode( const QModelIndex& index ) const;
//! Return layer node to which a symbology node belongs to. Returns null pointer if index is not a symbology node.
QgsLayerTreeLayer* layerNodeForSymbologyNode( const QModelIndex& index ) const;
//! Return legend node for given index. Returns null for invalid index
//! @note added in 2.6
static QgsLayerTreeModelLegendNode* index2legendNode( const QModelIndex& index );
//! Return index for a given legend node. If the legend node does not belong to the layer tree, the result is undefined
//! @note added in 2.6
QModelIndex legendNode2index( QgsLayerTreeModelLegendNode* legendNode );
//! Return list of legend nodes attached to a particular layer node
//! @note added in 2.6
QList<QgsLayerTreeModelLegendNode*> layerLegendNodes( QgsLayerTreeLayer* nodeLayer );
//! Return pointer to the root node of the layer tree. Always a non-null pointer.
QgsLayerTreeGroup* rootGroup();
//! Reset the model and use a new root group node
//! @note added in 2.6
void setRootGroup( QgsLayerTreeGroup* newRootGroup );
//! Force a refresh of symbology of layer node.
//! Force a refresh of legend nodes of a layer node.
//! Not necessary to call when layer's renderer is changed as the model listens to these events.
void refreshLayerSymbology( QgsLayerTreeLayer* nodeLayer );
void refreshLayerLegend( QgsLayerTreeLayer* nodeLayer );
//! Get index of the item marked as current. Item marked as current is underlined.
QModelIndex currentIndex() const;
@ -101,10 +113,29 @@ class QgsLayerTreeModel : QAbstractItemModel
//! Get font for a particular type of layer tree node. nodeType should come from QgsLayerTreeNode::NodeType enumeration
QFont layerTreeNodeFont( int nodeType ) const;
//! Set at what number of symbology nodes the layer node should be collapsed. Setting -1 disables the auto-collapse (default).
void setAutoCollapseSymbologyNodes( int nodeCount );
//! Return at what number of symbology nodes the layer node should be collapsed. -1 means no auto-collapse (default).
int autoCollapseSymbologyNodes() const;
//! Set at what number of legend nodes the layer node should be collapsed. Setting -1 disables the auto-collapse (default).
void setAutoCollapseLegendNodes( int nodeCount );
//! Return at what number of legend nodes the layer node should be collapsed. -1 means no auto-collapse (default).
int autoCollapseLegendNodes() const;
//! Force only display of legend nodes which are valid for given scale denominator.
//! Setting value <= 0 will disable the functionality
//! @note added in 2.6
void setLegendFilterByScale( double scaleDenominator );
double legendFilterByScale() const;
//! Return true if index represents a legend node (instead of layer node)
//! @deprecated use index2legendNode()
bool isIndexSymbologyNode( const QModelIndex& index ) const /Deprecated/;
//! Return layer node to which a legend node belongs to. Returns null pointer if index is not a legend node.
//! @deprecated use index2legendNode()->parent()
QgsLayerTreeLayer* layerNodeForSymbologyNode( const QModelIndex& index ) const /Deprecated/;
//! @deprecated use refreshLayerLegend()
void refreshLayerSymbology( QgsLayerTreeLayer* nodeLayer ) /Deprecated/;
//! @deprecated use setAutoCollapseLegendNodes()
void setAutoCollapseSymbologyNodes( int nodeCount ) /Deprecated/;
//! @deprecated use autoCollapseLegendNodes()
int autoCollapseSymbologyNodes() const /Deprecated/;
signals:

View File

@ -517,7 +517,7 @@ void QgsComposerLegendWidget::on_mMoveDownToolButton_clicked()
return;
QgsLayerTreeNode* node = mItemTreeView->layerTreeModel()->index2node( index );
QgsLayerTreeModelLegendNode* legendNode = mItemTreeView->layerTreeModel()->index2symnode( index );
QgsLayerTreeModelLegendNode* legendNode = mItemTreeView->layerTreeModel()->index2legendNode( index );
if ( !node && !legendNode )
return;
@ -532,7 +532,7 @@ void QgsComposerLegendWidget::on_mMoveDownToolButton_clicked()
else // legend node
{
_moveLegendNode( legendNode->parent(), index.row(), 1 );
mItemTreeView->layerTreeModel()->refreshLayerSymbology( legendNode->parent() );
mItemTreeView->layerTreeModel()->refreshLayerLegend( legendNode->parent() );
}
mItemTreeView->setCurrentIndex( mItemTreeView->layerTreeModel()->index( index.row() + 1, 0, parentIndex ) );
@ -554,7 +554,7 @@ void QgsComposerLegendWidget::on_mMoveUpToolButton_clicked()
return;
QgsLayerTreeNode* node = mItemTreeView->layerTreeModel()->index2node( index );
QgsLayerTreeModelLegendNode* legendNode = mItemTreeView->layerTreeModel()->index2symnode( index );
QgsLayerTreeModelLegendNode* legendNode = mItemTreeView->layerTreeModel()->index2legendNode( index );
if ( !node && !legendNode )
return;
@ -569,7 +569,7 @@ void QgsComposerLegendWidget::on_mMoveUpToolButton_clicked()
else // legend node
{
_moveLegendNode( legendNode->parent(), index.row(), -1 );
mItemTreeView->layerTreeModel()->refreshLayerSymbology( legendNode->parent() );
mItemTreeView->layerTreeModel()->refreshLayerLegend( legendNode->parent() );
}
mItemTreeView->setCurrentIndex( mItemTreeView->layerTreeModel()->index( index.row() - 1, 0, parentIndex ) );
@ -687,7 +687,7 @@ void QgsComposerLegendWidget::on_mRemoveToolButton_clicked()
QHash<QgsLayerTreeLayer*, QList<int> > nodesWithRemoval;
foreach ( const QPersistentModelIndex index, indexes )
{
if ( QgsLayerTreeModelLegendNode* legendNode = mItemTreeView->layerTreeModel()->index2symnode( index ) )
if ( QgsLayerTreeModelLegendNode* legendNode = mItemTreeView->layerTreeModel()->index2legendNode( index ) )
{
QgsLayerTreeLayer* nodeLayer = legendNode->parent();
nodesWithRemoval[nodeLayer].append( index.row() );
@ -706,7 +706,7 @@ void QgsComposerLegendWidget::on_mRemoveToolButton_clicked()
}
QgsMapLayerLegendUtils::setLegendNodeOrder( nodeLayer, order );
mItemTreeView->layerTreeModel()->refreshLayerSymbology( nodeLayer );
mItemTreeView->layerTreeModel()->refreshLayerLegend( nodeLayer );
}
// then remove layer tree nodes
@ -731,7 +731,7 @@ void QgsComposerLegendWidget::on_mEditPushButton_clicked()
QModelIndex idx = mItemTreeView->selectionModel()->currentIndex();
QgsLayerTreeModel* model = mItemTreeView->layerTreeModel();
QgsLayerTreeNode* currentNode = model->index2node( idx );
QgsLayerTreeModelLegendNode* legendNode = model->index2symnode( idx );
QgsLayerTreeModelLegendNode* legendNode = model->index2legendNode( idx );
QString currentText;
if ( QgsLayerTree::isGroup( currentNode ) )
@ -776,7 +776,7 @@ void QgsComposerLegendWidget::on_mEditPushButton_clicked()
QList<int> order = QgsMapLayerLegendUtils::legendNodeOrder( legendNode->parent() );
int originalIndex = ( idx.row() >= 0 && idx.row() < order.count() ? order[idx.row()] : -1 );
QgsMapLayerLegendUtils::setLegendNodeUserLabel( legendNode->parent(), originalIndex, newText );
model->refreshLayerSymbology( legendNode->parent() );
model->refreshLayerLegend( legendNode->parent() );
}
mLegend->adjustBoxSize();
@ -804,7 +804,7 @@ void QgsComposerLegendWidget::resetLayerNodeToDefaults()
if ( QgsLayerTree::isLayer( node ) )
nodeLayer = QgsLayerTree::toLayer( node );
}
if ( QgsLayerTreeModelLegendNode* legendNode = mItemTreeView->layerTreeModel()->index2symnode( currentIndex ) )
if ( QgsLayerTreeModelLegendNode* legendNode = mItemTreeView->layerTreeModel()->index2legendNode( currentIndex ) )
{
nodeLayer = legendNode->parent();
}
@ -820,7 +820,7 @@ void QgsComposerLegendWidget::resetLayerNodeToDefaults()
nodeLayer->removeCustomProperty( key );
}
mItemTreeView->layerTreeModel()->refreshLayerSymbology( nodeLayer );
mItemTreeView->layerTreeModel()->refreshLayerLegend( nodeLayer );
mLegend->update();
mLegend->adjustBoxSize();

View File

@ -397,7 +397,7 @@ void QgisApp::emitCustomSrsValidation( QgsCoordinateReferenceSystem &srs )
void QgisApp::layerTreeViewDoubleClicked( const QModelIndex& index )
{
// temporary solution for WMS legend
if ( mLayerTreeView->layerTreeModel()->isIndexSymbologyNode( index ) )
if ( mLayerTreeView->layerTreeModel()->index2legendNode( index ) )
{
QModelIndex parent = mLayerTreeView->layerTreeModel()->parent( index );
QgsLayerTreeNode* node = mLayerTreeView->layerTreeModel()->index2node( parent );
@ -2306,7 +2306,7 @@ void QgisApp::initLayerTreeView()
model->setFlag( QgsLayerTreeModel::AllowNodeReorder );
model->setFlag( QgsLayerTreeModel::AllowNodeRename );
model->setFlag( QgsLayerTreeModel::AllowNodeChangeVisibility );
model->setAutoCollapseSymbologyNodes( 10 );
model->setAutoCollapseLegendNodes( 10 );
mLayerTreeView->setModel( model );
mLayerTreeView->setMenuProvider( new QgsAppLayerTreeViewMenuProvider( mLayerTreeView, mMapCanvas ) );

View File

@ -439,7 +439,7 @@ void QgsComposerLegend::invalidateCurrentMap()
QgsLegendModelV2::QgsLegendModelV2( QgsLayerTreeGroup* rootNode, QObject* parent )
: QgsLayerTreeModel( rootNode, parent )
{
setFlag( QgsLayerTreeModel::AllowSymbologyChangeState, false );
setFlag( QgsLayerTreeModel::AllowLegendChangeState, false );
setFlag( QgsLayerTreeModel::AllowNodeReorder, true );
}
@ -468,7 +468,7 @@ QVariant QgsLegendModelV2::data( const QModelIndex& index, int role ) const
Qt::ItemFlags QgsLegendModelV2::flags( const QModelIndex& index ) const
{
// make the legend nodes selectable even if they are not by default
if ( index2symnode( index ) )
if ( index2legendNode( index ) )
return QgsLayerTreeModel::flags( index ) | Qt::ItemIsSelectable;
return QgsLayerTreeModel::flags( index );

View File

@ -33,8 +33,8 @@
QgsLayerTreeModel::QgsLayerTreeModel( QgsLayerTreeGroup* rootNode, QObject *parent )
: QAbstractItemModel( parent )
, mRootNode( rootNode )
, mFlags( ShowSymbology | AllowSymbologyChangeState )
, mAutoCollapseSymNodesCount( -1 )
, mFlags( ShowLegend | AllowLegendChangeState )
, mAutoCollapseLegendNodesCount( -1 )
{
connectToRootNode();
@ -43,10 +43,10 @@ QgsLayerTreeModel::QgsLayerTreeModel( QgsLayerTreeGroup* rootNode, QObject *pare
QgsLayerTreeModel::~QgsLayerTreeModel()
{
foreach ( QList<QgsLayerTreeModelLegendNode*> nodeL, mOriginalSymbologyNodes )
foreach ( QList<QgsLayerTreeModelLegendNode*> nodeL, mOriginalLegendNodes )
qDeleteAll( nodeL );
mOriginalSymbologyNodes.clear();
mSymbologyNodes.clear(); // does not own the nodes
mOriginalLegendNodes.clear();
mLegendNodes.clear(); // does not own the nodes
}
QgsLayerTreeNode* QgsLayerTreeModel::index2node( const QModelIndex& index ) const
@ -58,16 +58,16 @@ QgsLayerTreeNode* QgsLayerTreeModel::index2node( const QModelIndex& index ) cons
return qobject_cast<QgsLayerTreeNode*>( obj );
}
QgsLayerTreeModelLegendNode* QgsLayerTreeModel::index2symnode( const QModelIndex& index )
QgsLayerTreeModelLegendNode* QgsLayerTreeModel::index2legendNode( const QModelIndex& index )
{
return qobject_cast<QgsLayerTreeModelLegendNode*>( reinterpret_cast<QObject*>( index.internalPointer() ) );
}
QModelIndex QgsLayerTreeModel::symnode2index( QgsLayerTreeModelLegendNode* legendNode )
QModelIndex QgsLayerTreeModel::legendNode2index( QgsLayerTreeModelLegendNode* legendNode )
{
QModelIndex parentIndex = node2index( legendNode->parent() );
Q_ASSERT( parentIndex.isValid() );
int row = mSymbologyNodes[legendNode->parent()].indexOf( legendNode );
int row = mLegendNodes[legendNode->parent()].indexOf( legendNode );
Q_ASSERT( row >= 0 );
return index( row, 0, parentIndex );
}
@ -75,7 +75,7 @@ QModelIndex QgsLayerTreeModel::symnode2index( QgsLayerTreeModelLegendNode* legen
int QgsLayerTreeModel::rowCount( const QModelIndex &parent ) const
{
if ( index2symnode( parent ) )
if ( index2legendNode( parent ) )
{
return 0; // they are leaves
}
@ -89,10 +89,10 @@ int QgsLayerTreeModel::rowCount( const QModelIndex &parent ) const
{
QgsLayerTreeLayer* nL = QgsLayerTree::toLayer( n );
if ( mSymbologyNodes[nL].count() == 1 && mSymbologyNodes[nL][0]->isEmbeddedInParent() )
if ( mLegendNodes[nL].count() == 1 && mLegendNodes[nL][0]->isEmbeddedInParent() )
return 0;
return mSymbologyNodes[nL].count();
return mLegendNodes[nL].count();
}
return n->children().count();
@ -113,7 +113,7 @@ QModelIndex QgsLayerTreeModel::index( int row, int column, const QModelIndex &pa
if ( !n )
{
QgsLayerTreeModelLegendNode* sym = index2symnode( parent );
QgsLayerTreeModelLegendNode* sym = index2legendNode( parent );
Q_ASSERT( sym );
return QModelIndex(); // have no children
}
@ -121,11 +121,11 @@ QModelIndex QgsLayerTreeModel::index( int row, int column, const QModelIndex &pa
if ( !n || column != 0 || row >= rowCount( parent ) )
return QModelIndex();
if ( testFlag( ShowSymbology ) && QgsLayerTree::isLayer( n ) )
if ( testFlag( ShowLegend ) && QgsLayerTree::isLayer( n ) )
{
QgsLayerTreeLayer* nL = QgsLayerTree::toLayer( n );
Q_ASSERT( mSymbologyNodes.contains( nL ) );
return createIndex( row, column, static_cast<QObject*>( mSymbologyNodes[nL].at( row ) ) );
Q_ASSERT( mLegendNodes.contains( nL ) );
return createIndex( row, column, static_cast<QObject*>( mLegendNodes[nL].at( row ) ) );
}
return createIndex( row, column, static_cast<QObject*>( n->children().at( row ) ) );
@ -142,7 +142,7 @@ QModelIndex QgsLayerTreeModel::parent( const QModelIndex &child ) const
if ( !n )
{
QgsLayerTreeModelLegendNode* sym = index2symnode( child );
QgsLayerTreeModelLegendNode* sym = index2legendNode( child );
Q_ASSERT( sym );
parentNode = sym->parent();
}
@ -164,9 +164,9 @@ QVariant QgsLayerTreeModel::data( const QModelIndex &index, int role ) const
if ( !index.isValid() )
return QVariant();
if ( QgsLayerTreeModelLegendNode* sym = index2symnode( index ) )
if ( QgsLayerTreeModelLegendNode* sym = index2legendNode( index ) )
{
if ( role == Qt::CheckStateRole && !testFlag( AllowSymbologyChangeState ) )
if ( role == Qt::CheckStateRole && !testFlag( AllowLegendChangeState ) )
return QVariant();
return sym->data( role );
}
@ -223,8 +223,8 @@ QVariant QgsLayerTreeModel::data( const QModelIndex &index, int role ) const
}
// if there's just on legend entry that should be embedded in layer - do that!
if ( testFlag( ShowSymbology ) && mSymbologyNodes[nodeLayer].count() == 1 && mSymbologyNodes[nodeLayer][0]->isEmbeddedInParent() )
return mSymbologyNodes[nodeLayer][0]->data( Qt::DecorationRole );
if ( testFlag( ShowLegend ) && mLegendNodes[nodeLayer].count() == 1 && mLegendNodes[nodeLayer][0]->isEmbeddedInParent() )
return mLegendNodes[nodeLayer][0]->data( Qt::DecorationRole );
if ( layer->type() == QgsMapLayer::RasterLayer )
{
@ -297,10 +297,10 @@ Qt::ItemFlags QgsLayerTreeModel::flags( const QModelIndex& index ) const
return rootFlags;
}
if ( QgsLayerTreeModelLegendNode* symn = index2symnode( index ) )
if ( QgsLayerTreeModelLegendNode* symn = index2legendNode( index ) )
{
Qt::ItemFlags f = symn->flags();
if ( !testFlag( AllowSymbologyChangeState ) )
if ( !testFlag( AllowLegendChangeState ) )
f &= ~Qt::ItemIsUserCheckable;
return f;
}
@ -331,10 +331,10 @@ Qt::ItemFlags QgsLayerTreeModel::flags( const QModelIndex& index ) const
bool QgsLayerTreeModel::setData( const QModelIndex& index, const QVariant& value, int role )
{
QgsLayerTreeModelLegendNode *sym = index2symnode( index );
QgsLayerTreeModelLegendNode *sym = index2legendNode( index );
if ( sym )
{
if ( role == Qt::CheckStateRole && !testFlag( AllowSymbologyChangeState ) )
if ( role == Qt::CheckStateRole && !testFlag( AllowLegendChangeState ) )
return false;
bool res = sym->setData( value, role );
if ( res )
@ -450,18 +450,18 @@ QList<QgsLayerTreeNode*> QgsLayerTreeModel::indexes2nodes( const QModelIndexList
bool QgsLayerTreeModel::isIndexSymbologyNode( const QModelIndex& index ) const
{
return index2symnode( index ) != 0;
return index2legendNode( index ) != 0;
}
QgsLayerTreeLayer* QgsLayerTreeModel::layerNodeForSymbologyNode( const QModelIndex& index ) const
{
QgsLayerTreeModelLegendNode* symNode = index2symnode( index );
QgsLayerTreeModelLegendNode* symNode = index2legendNode( index );
return symNode ? symNode->parent() : 0;
}
QList<QgsLayerTreeModelLegendNode*> QgsLayerTreeModel::layerLegendNodes( QgsLayerTreeLayer* nodeLayer )
{
return mSymbologyNodes.value( nodeLayer );
return mLegendNodes.value( nodeLayer );
}
QgsLayerTreeGroup*QgsLayerTreeModel::rootGroup()
@ -475,8 +475,8 @@ void QgsLayerTreeModel::setRootGroup( QgsLayerTreeGroup* newRootGroup )
disconnectFromRootNode();
Q_ASSERT( mSymbologyNodes.isEmpty() );
Q_ASSERT( mOriginalSymbologyNodes.isEmpty() );
Q_ASSERT( mLegendNodes.isEmpty() );
Q_ASSERT( mOriginalLegendNodes.isEmpty() );
mRootNode = newRootGroup;
@ -485,7 +485,7 @@ void QgsLayerTreeModel::setRootGroup( QgsLayerTreeGroup* newRootGroup )
connectToRootNode();
}
void QgsLayerTreeModel::refreshLayerSymbology( QgsLayerTreeLayer* nodeLayer )
void QgsLayerTreeModel::refreshLayerLegend( QgsLayerTreeLayer* nodeLayer )
{
// update title
QModelIndex idx = node2index( nodeLayer );
@ -494,14 +494,14 @@ void QgsLayerTreeModel::refreshLayerSymbology( QgsLayerTreeLayer* nodeLayer )
// update children
int oldNodeCount = rowCount( idx );
beginRemoveRows( idx, 0, oldNodeCount - 1 );
removeSymbologyFromLayer( nodeLayer );
removeLegendFromLayer( nodeLayer );
endRemoveRows();
addSymbologyToLayer( nodeLayer );
addLegendToLayer( nodeLayer );
int newNodeCount = rowCount( idx );
// automatic collapse of symbology nodes - useful if a layer has many symbology nodes
if ( mAutoCollapseSymNodesCount != -1 && oldNodeCount != newNodeCount && newNodeCount >= mAutoCollapseSymNodesCount )
// automatic collapse of legend nodes - useful if a layer has many legend nodes
if ( mAutoCollapseLegendNodesCount != -1 && oldNodeCount != newNodeCount && newNodeCount >= mAutoCollapseLegendNodesCount )
nodeLayer->setExpanded( false );
}
@ -567,7 +567,7 @@ void QgsLayerTreeModel::setLegendFilterByScale( double scaleDenominator )
// this could be later done in more efficient way
// by just updating active legend nodes, without refreshing original legend nodes
foreach ( QgsLayerTreeLayer* nodeLayer, mRootNode->findLayers() )
refreshLayerSymbology( nodeLayer );
refreshLayerLegend( nodeLayer );
}
void QgsLayerTreeModel::nodeWillAddChildren( QgsLayerTreeNode* node, int indexFrom, int indexTo )
@ -607,7 +607,7 @@ void QgsLayerTreeModel::nodeWillRemoveChildren( QgsLayerTreeNode* node, int inde
beginRemoveRows( node2index( node ), indexFrom, indexTo );
// disconnect from layers and remove their symbology
// disconnect from layers and remove their legend
foreach ( QgsLayerTreeLayer* nodeLayer, _layerNodesInSubtree( node, indexFrom, indexTo ) )
disconnectFromLayer( nodeLayer );
}
@ -629,7 +629,7 @@ void QgsLayerTreeModel::nodeVisibilityChanged( QgsLayerTreeNode* node )
void QgsLayerTreeModel::nodeCustomPropertyChanged( QgsLayerTreeNode* node, const QString& key )
{
if ( QgsLayerTree::isLayer( node ) && key == "showFeatureCount" )
refreshLayerSymbology( QgsLayerTree::toLayer( node ) );
refreshLayerLegend( QgsLayerTree::toLayer( node ) );
}
@ -657,7 +657,7 @@ void QgsLayerTreeModel::nodeLayerWillBeUnloaded()
void QgsLayerTreeModel::layerLegendChanged()
{
if ( !testFlag( ShowSymbology ) )
if ( !testFlag( ShowLegend ) )
return;
QgsMapLayer* layer = qobject_cast<QgsMapLayer*>( sender() );
@ -668,7 +668,7 @@ void QgsLayerTreeModel::layerLegendChanged()
if ( !nodeLayer )
return;
refreshLayerSymbology( nodeLayer );
refreshLayerLegend( nodeLayer );
}
void QgsLayerTreeModel::layerNeedsUpdate()
@ -685,7 +685,7 @@ void QgsLayerTreeModel::layerNeedsUpdate()
emit dataChanged( index, index );
if ( nodeLayer->customProperty( "showFeatureCount" ).toInt() )
refreshLayerSymbology( nodeLayer );
refreshLayerLegend( nodeLayer );
}
@ -695,23 +695,23 @@ void QgsLayerTreeModel::legendNodeDataChanged()
if ( !legendNode )
return;
QModelIndex index = symnode2index( legendNode );
QModelIndex index = legendNode2index( legendNode );
emit dataChanged( index, index );
}
void QgsLayerTreeModel::removeSymbologyFromLayer( QgsLayerTreeLayer* nodeLayer )
void QgsLayerTreeModel::removeLegendFromLayer( QgsLayerTreeLayer* nodeLayer )
{
if ( mSymbologyNodes.contains( nodeLayer ) )
if ( mLegendNodes.contains( nodeLayer ) )
{
qDeleteAll( mOriginalSymbologyNodes[nodeLayer] );
mOriginalSymbologyNodes.remove( nodeLayer );
mSymbologyNodes.remove( nodeLayer );
qDeleteAll( mOriginalLegendNodes[nodeLayer] );
mOriginalLegendNodes.remove( nodeLayer );
mLegendNodes.remove( nodeLayer );
}
}
void QgsLayerTreeModel::addSymbologyToLayer( QgsLayerTreeLayer* nodeL )
void QgsLayerTreeModel::addLegendToLayer( QgsLayerTreeLayer* nodeL )
{
if ( !nodeL->layer() )
return;
@ -735,8 +735,8 @@ void QgsLayerTreeModel::addSymbologyToLayer( QgsLayerTreeLayer* nodeL )
connect( n, SIGNAL( dataChanged() ), this, SLOT( legendNodeDataChanged() ) );
}
mOriginalSymbologyNodes[nodeL] = lstNew;
mSymbologyNodes[nodeL] = filteredLstNew;
mOriginalLegendNodes[nodeL] = lstNew;
mLegendNodes[nodeL] = filteredLstNew;
endInsertRows();
}
@ -755,14 +755,14 @@ void QgsLayerTreeModel::connectToLayer( QgsLayerTreeLayer* nodeLayer )
// watch if the layer is getting removed
connect( nodeLayer, SIGNAL( layerWillBeUnloaded() ), this, SLOT( nodeLayerWillBeUnloaded() ) );
if ( testFlag( ShowSymbology ) )
if ( testFlag( ShowLegend ) )
{
addSymbologyToLayer( nodeLayer );
addLegendToLayer( nodeLayer );
// automatic collapse of symbology nodes - useful if a layer has many symbology nodes
// automatic collapse of legend nodes - useful if a layer has many legend nodes
if ( !mRootNode->customProperty( "loading" ).toBool() )
{
if ( mAutoCollapseSymNodesCount != -1 && rowCount( node2index( nodeLayer ) ) >= mAutoCollapseSymNodesCount )
if ( mAutoCollapseLegendNodesCount != -1 && rowCount( node2index( nodeLayer ) ) >= mAutoCollapseLegendNodesCount )
nodeLayer->setExpanded( false );
}
}
@ -808,9 +808,9 @@ void QgsLayerTreeModel::disconnectFromLayer( QgsLayerTreeLayer* nodeLayer )
if ( !nodeLayer->layer() )
return; // we were never connected
if ( testFlag( ShowSymbology ) )
if ( testFlag( ShowLegend ) )
{
removeSymbologyFromLayer( nodeLayer );
removeLegendFromLayer( nodeLayer );
}
if ( _numLayerCount( mRootNode, nodeLayer->layerId() ) == 1 )

View File

@ -35,7 +35,7 @@ class QgsMapLayer;
* The model listens to the changes in the layer tree and signals the changes as appropriate,
* so that any view that uses the model is updated accordingly.
*
* Behavior of the model can be customized with flags. For example, whether to show symbology or
* Behavior of the model can be customized with flags. For example, whether to show legend or
* whether to allow changes to the layer tree.
*
* @see QgsLayerTreeView
@ -70,14 +70,16 @@ class CORE_EXPORT QgsLayerTreeModel : public QAbstractItemModel
enum Flag
{
// display flags
ShowSymbology = 0x0001, //!< Add symbology items for layer nodes
ShowLegend = 0x0001, //!< Add legend nodes for layer nodes
ShowSymbology = 0x0001, //!< deprecated - use ShowLegend
ShowRasterPreviewIcon = 0x0002, //!< Will use real preview of raster layer as icon (may be slow)
// behavioral flags
AllowNodeReorder = 0x1000, //!< Allow reordering with drag'n'drop
AllowNodeRename = 0x2000, //!< Allow renaming of groups and layers
AllowNodeChangeVisibility = 0x4000, //!< Allow user to set node visibility with a check box
AllowSymbologyChangeState = 0x8000, //!< Allow check boxes for symbology items (if supported by layer's legend)
AllowLegendChangeState = 0x8000, //!< Allow check boxes for legend nodes (if supported by layer's legend)
AllowSymbologyChangeState = 0x8000, //!< deprecated - use AllowLegendChangeState
};
Q_DECLARE_FLAGS( Flags, Flag )
@ -91,7 +93,7 @@ class CORE_EXPORT QgsLayerTreeModel : public QAbstractItemModel
bool testFlag( Flag f ) const;
//! Return layer tree node for given index. Returns root node for invalid index.
//! Returns null pointer if index does not refer to a layer tree node (e.g. it is a symbology item)
//! Returns null pointer if index does not refer to a layer tree node (e.g. it is a legend node)
QgsLayerTreeNode* index2node( const QModelIndex& index ) const;
//! Return index for a given node. If the node does not belong to the layer tree, the result is undefined
QModelIndex node2index( QgsLayerTreeNode* node ) const;
@ -99,17 +101,13 @@ class CORE_EXPORT QgsLayerTreeModel : public QAbstractItemModel
//! Indices that do not represent layer tree nodes are skipped.
//! @arg skipInternal If true, a node is included in the output list only if no parent node is in the list
QList<QgsLayerTreeNode*> indexes2nodes( const QModelIndexList& list, bool skipInternal = false ) const;
//! Return true if index represents a symbology node (instead of layer node)
bool isIndexSymbologyNode( const QModelIndex& index ) const;
//! Return layer node to which a symbology node belongs to. Returns null pointer if index is not a symbology node.
QgsLayerTreeLayer* layerNodeForSymbologyNode( const QModelIndex& index ) const;
// TODO: rename to some better name
//! Return legend node for given index. Returns null for invalid index
//! @note added in 2.6
static QgsLayerTreeModelLegendNode* index2symnode( const QModelIndex& index );
static QgsLayerTreeModelLegendNode* index2legendNode( const QModelIndex& index );
//! Return index for a given legend node. If the legend node does not belong to the layer tree, the result is undefined
//! @note added in 2.6
QModelIndex symnode2index( QgsLayerTreeModelLegendNode* legendNode );
QModelIndex legendNode2index( QgsLayerTreeModelLegendNode* legendNode );
//! Return list of legend nodes attached to a particular layer node
//! @note added in 2.6
@ -121,9 +119,9 @@ class CORE_EXPORT QgsLayerTreeModel : public QAbstractItemModel
//! @note added in 2.6
void setRootGroup( QgsLayerTreeGroup* newRootGroup );
//! Force a refresh of symbology of layer node.
//! Force a refresh of legend nodes of a layer node.
//! Not necessary to call when layer's renderer is changed as the model listens to these events.
void refreshLayerSymbology( QgsLayerTreeLayer* nodeLayer );
void refreshLayerLegend( QgsLayerTreeLayer* nodeLayer );
//! Get index of the item marked as current. Item marked as current is underlined.
QModelIndex currentIndex() const;
@ -135,10 +133,10 @@ class CORE_EXPORT QgsLayerTreeModel : public QAbstractItemModel
//! Get font for a particular type of layer tree node. nodeType should come from QgsLayerTreeNode::NodeType enumeration
QFont layerTreeNodeFont( int nodeType ) const;
//! Set at what number of symbology nodes the layer node should be collapsed. Setting -1 disables the auto-collapse (default).
void setAutoCollapseSymbologyNodes( int nodeCount ) { mAutoCollapseSymNodesCount = nodeCount; }
//! Return at what number of symbology nodes the layer node should be collapsed. -1 means no auto-collapse (default).
int autoCollapseSymbologyNodes() const { return mAutoCollapseSymNodesCount; }
//! Set at what number of legend nodes the layer node should be collapsed. Setting -1 disables the auto-collapse (default).
void setAutoCollapseLegendNodes( int nodeCount ) { mAutoCollapseLegendNodesCount = nodeCount; }
//! Return at what number of legend nodes the layer node should be collapsed. -1 means no auto-collapse (default).
int autoCollapseLegendNodes() const { return mAutoCollapseLegendNodesCount; }
//! Force only display of legend nodes which are valid for given scale denominator.
//! Setting value <= 0 will disable the functionality
@ -146,6 +144,19 @@ class CORE_EXPORT QgsLayerTreeModel : public QAbstractItemModel
void setLegendFilterByScale( double scaleDenominator );
double legendFilterByScale() const { return mLegendFilterByScale; }
//! Return true if index represents a legend node (instead of layer node)
//! @deprecated use index2legendNode()
Q_DECL_DEPRECATED bool isIndexSymbologyNode( const QModelIndex& index ) const;
//! Return layer node to which a legend node belongs to. Returns null pointer if index is not a legend node.
//! @deprecated use index2legendNode()->parent()
Q_DECL_DEPRECATED QgsLayerTreeLayer* layerNodeForSymbologyNode( const QModelIndex& index ) const;
//! @deprecated use refreshLayerLegend()
Q_DECL_DEPRECATED void refreshLayerSymbology( QgsLayerTreeLayer* nodeLayer ) { refreshLayerLegend( nodeLayer ); }
//! @deprecated use setAutoCollapseLegendNodes()
Q_DECL_DEPRECATED void setAutoCollapseSymbologyNodes( int nodeCount ) { setAutoCollapseLegendNodes( nodeCount ); }
//! @deprecated use autoCollapseLegendNodes()
Q_DECL_DEPRECATED int autoCollapseSymbologyNodes() const { return autoCollapseLegendNodes(); }
signals:
protected slots:
@ -167,8 +178,8 @@ class CORE_EXPORT QgsLayerTreeModel : public QAbstractItemModel
void legendNodeDataChanged();
protected:
void removeSymbologyFromLayer( QgsLayerTreeLayer* nodeLayer );
void addSymbologyToLayer( QgsLayerTreeLayer* nodeL );
void removeLegendFromLayer( QgsLayerTreeLayer* nodeLayer );
void addLegendToLayer( QgsLayerTreeLayer* nodeL );
void connectToLayer( QgsLayerTreeLayer* nodeLayer );
void disconnectFromLayer( QgsLayerTreeLayer* nodeLayer );
@ -191,16 +202,16 @@ class CORE_EXPORT QgsLayerTreeModel : public QAbstractItemModel
QgsLayerTreeGroup* mRootNode;
//! Set of flags for the model
Flags mFlags;
//! Active symbology nodes for each layer node. May have been filtered.
//! Owner of legend nodes is still mOriginalSymbologyNodes !
QMap<QgsLayerTreeLayer*, QList<QgsLayerTreeModelLegendNode*> > mSymbologyNodes;
//! Data structure for storage of symbology nodes for each layer.
//! Active legend nodes for each layer node. May have been filtered.
//! Owner of legend nodes is still mOriginalLegendNodes !
QMap<QgsLayerTreeLayer*, QList<QgsLayerTreeModelLegendNode*> > mLegendNodes;
//! Data structure for storage of legend nodes for each layer.
//! These are nodes as received from QgsMapLayerLegend
QMap<QgsLayerTreeLayer*, QList<QgsLayerTreeModelLegendNode*> > mOriginalSymbologyNodes;
QMap<QgsLayerTreeLayer*, QList<QgsLayerTreeModelLegendNode*> > mOriginalLegendNodes;
//! Current index - will be underlined
QPersistentModelIndex mCurrentIndex;
//! Minimal number of nodes when symbology should be automatically collapsed. -1 = disabled
int mAutoCollapseSymNodesCount;
//! Minimal number of nodes when legend should be automatically collapsed. -1 = disabled
int mAutoCollapseLegendNodesCount;
QFont mFontLayer;
QFont mFontGroup;

View File

@ -17,6 +17,7 @@
#include "qgslayertree.h"
#include "qgslayertreemodel.h"
#include "qgslayertreemodellegendnode.h"
#include "qgslayertreeviewdefaultactions.h"
#include "qgsmaplayer.h"
@ -198,9 +199,10 @@ QgsMapLayer* QgsLayerTreeView::layerForIndex( const QModelIndex& index ) const
}
else
{
// possibly a symbology node
if ( layerTreeModel()->isIndexSymbologyNode( index ) )
return layerTreeModel()->layerNodeForSymbologyNode( index )->layer();
// possibly a legend node
QgsLayerTreeModelLegendNode* legendNode = layerTreeModel()->index2legendNode( index );
if ( legendNode )
return legendNode->parent()->layer();
}
return 0;
@ -259,5 +261,5 @@ void QgsLayerTreeView::refreshLayerSymbology( const QString& layerId )
{
QgsLayerTreeLayer* nodeLayer = layerTreeModel()->rootGroup()->findLayer( layerId );
if ( nodeLayer )
layerTreeModel()->refreshLayerSymbology( nodeLayer );
layerTreeModel()->refreshLayerLegend( nodeLayer );
}

View File

@ -180,7 +180,7 @@ void TestQgsLegendRenderer::testModel()
// set user text
QgsMapLayerLegendUtils::setLegendNodeUserLabel( nodeVL1, 0, "Hurray" );
legendModel.refreshLayerSymbology( nodeVL1 );
legendModel.refreshLayerLegend( nodeVL1 );
QList<QgsLayerTreeModelLegendNode*> lstNodes2 = legendModel.layerLegendNodes( nodeVL1 );
QCOMPARE( lstNodes2[0]->data( Qt::DisplayRole ).toString(), QString( "Hurray" ) );