Skip to content

Commit 3c00421

Browse files
committed
Indicate whether a layer is in editing mode and/or modified
1 parent afc65f2 commit 3c00421

File tree

2 files changed

+110
-32
lines changed

2 files changed

+110
-32
lines changed

src/gui/layertree/qgslayertreemodel.cpp

+104-31
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,14 @@ QVariant QgsLayerTreeModel::data( const QModelIndex &index, int role ) const
193193
else if ( layer->type() == QgsMapLayer::VectorLayer )
194194
{
195195
QgsVectorLayer* vlayer = static_cast<QgsVectorLayer*>( layer );
196+
if ( vlayer->isEditable() )
197+
{
198+
if ( vlayer->isModified() )
199+
return QIcon( QgsApplication::getThemePixmap( "/mIconEditableEdits.png" ) );
200+
else
201+
return QIcon( QgsApplication::getThemePixmap( "/mIconEditable.png" ) );
202+
}
203+
196204
if ( vlayer->geometryType() == QGis::Point )
197205
return QgsLayerItem::iconPoint();
198206
else if ( vlayer->geometryType() == QGis::Line )
@@ -372,29 +380,29 @@ void QgsLayerTreeModel::nodeWillAddChildren( QgsLayerTreeNode* node, int indexFr
372380
beginInsertRows( node2index( node ), indexFrom, indexTo );
373381
}
374382

383+
static QList<QgsLayerTreeLayer*> _layerNodesInSubtree( QgsLayerTreeNode* node, int indexFrom, int indexTo )
384+
{
385+
QList<QgsLayerTreeNode*> children = node->children();
386+
QList<QgsLayerTreeLayer*> newLayerNodes;
387+
for ( int i = indexFrom; i <= indexTo; ++i )
388+
{
389+
QgsLayerTreeNode* child = children.at( i );
390+
if ( QgsLayerTree::isLayer( child ) )
391+
newLayerNodes << QgsLayerTree::toLayer( child );
392+
else if ( QgsLayerTree::isGroup( child ) )
393+
newLayerNodes << QgsLayerTree::toGroup( child )->findLayers();
394+
}
395+
return newLayerNodes;
396+
}
397+
375398
void QgsLayerTreeModel::nodeAddedChildren( QgsLayerTreeNode* node, int indexFrom, int indexTo )
376399
{
377400
Q_ASSERT( node );
378401

379402
endInsertRows();
380403

381-
if ( testFlag( ShowSymbology ) )
382-
{
383-
// collect layers for which we need to add symbology
384-
QList<QgsLayerTreeLayer*> newLayerNodes;
385-
QList<QgsLayerTreeNode*> children = node->children();
386-
for ( int i = indexFrom; i <= indexTo; ++i )
387-
{
388-
QgsLayerTreeNode* child = children.at( i );
389-
if ( QgsLayerTree::isLayer( child ) )
390-
newLayerNodes << QgsLayerTree::toLayer( child );
391-
else if ( QgsLayerTree::isGroup( child ) )
392-
newLayerNodes << QgsLayerTree::toGroup( child )->findLayers();
393-
}
394-
395-
foreach ( QgsLayerTreeLayer* newLayerNode, newLayerNodes )
396-
addSymbologyToLayer( newLayerNode );
397-
}
404+
foreach ( QgsLayerTreeLayer* newLayerNode, _layerNodesInSubtree( node, indexFrom, indexTo ) )
405+
connectToLayer( newLayerNode );
398406
}
399407

400408
void QgsLayerTreeModel::nodeWillRemoveChildren( QgsLayerTreeNode* node, int indexFrom, int indexTo )
@@ -403,9 +411,9 @@ void QgsLayerTreeModel::nodeWillRemoveChildren( QgsLayerTreeNode* node, int inde
403411

404412
beginRemoveRows( node2index( node ), indexFrom, indexTo );
405413

406-
// cleanup - e.g. symbology
407-
for ( int i = indexFrom; i <= indexTo; ++i )
408-
removeSymbologyFromSubtree( node->children()[i] );
414+
// disconnect from layers and remove their symbology
415+
foreach ( QgsLayerTreeLayer* nodeLayer, _layerNodesInSubtree( node, indexFrom, indexTo ) )
416+
disconnectFromLayer( nodeLayer );
409417
}
410418

411419
void QgsLayerTreeModel::nodeRemovedChildren()
@@ -427,7 +435,8 @@ void QgsLayerTreeModel::nodeLayerLoaded()
427435
if ( !nodeLayer )
428436
return;
429437

430-
addSymbologyToLayer( nodeLayer );
438+
// deffered connection to the layer
439+
connectToLayer( nodeLayer );
431440
}
432441

433442
void QgsLayerTreeModel::layerRendererChanged()
@@ -443,13 +452,18 @@ void QgsLayerTreeModel::layerRendererChanged()
443452
refreshLayerSymbology( nodeLayer );
444453
}
445454

446-
void QgsLayerTreeModel::removeSymbologyFromSubtree( QgsLayerTreeNode* node )
455+
void QgsLayerTreeModel::layerNeedsUpdate()
447456
{
448-
if ( QgsLayerTree::isLayer( node ) )
449-
removeSymbologyFromLayer( QgsLayerTree::toLayer( node ) );
457+
QgsMapLayer* layer = qobject_cast<QgsMapLayer*>( sender() );
458+
if ( !layer )
459+
return;
460+
461+
QgsLayerTreeLayer* nodeLayer = mRootNode->findLayer( layer->id() );
462+
if ( !nodeLayer )
463+
return;
450464

451-
foreach ( QgsLayerTreeNode* child, node->children() )
452-
removeSymbologyFromSubtree( child );
465+
QModelIndex index = node2index( nodeLayer );
466+
emit dataChanged( index, index );
453467
}
454468

455469

@@ -468,12 +482,7 @@ void QgsLayerTreeModel::removeSymbologyFromLayer( QgsLayerTreeLayer* nodeLayer )
468482
void QgsLayerTreeModel::addSymbologyToLayer( QgsLayerTreeLayer* nodeL )
469483
{
470484
if ( !nodeL->layer() )
471-
{
472-
// skip creation of symbology if the layer is not (yet?) loaded
473-
// but keep an eye on it: once loaded, we will add the symbology
474-
connect( nodeL, SIGNAL( layerLoaded() ), this, SLOT( nodeLayerLoaded() ) );
475485
return;
476-
}
477486

478487
if ( nodeL->layer()->type() == QgsMapLayer::VectorLayer )
479488
{
@@ -592,6 +601,70 @@ void QgsLayerTreeModel::addSymbologyToPluginLayer( QgsLayerTreeLayer* nodeL )
592601
}
593602

594603

604+
void QgsLayerTreeModel::connectToLayer( QgsLayerTreeLayer* nodeLayer )
605+
{
606+
if ( !nodeLayer->layer() )
607+
{
608+
// in order to connect to layer, we need to have it loaded.
609+
// keep an eye on the layer ID: once loaded, we will use it
610+
connect( nodeLayer, SIGNAL( layerLoaded() ), this, SLOT( nodeLayerLoaded() ) );
611+
return;
612+
}
613+
614+
if ( testFlag( ShowSymbology ) )
615+
{
616+
addSymbologyToLayer( nodeLayer );
617+
}
618+
619+
QgsMapLayer* layer = nodeLayer->layer();
620+
if ( layer->type() == QgsMapLayer::VectorLayer )
621+
{
622+
// using unique connection because there may be temporarily more nodes for a layer than just one
623+
// which would create multiple connections, however disconnect() would disconnect all multiple connections
624+
// even if we wanted to disconnect just one connection in each call.
625+
connect( layer, SIGNAL( editingStarted() ), this, SLOT( layerNeedsUpdate() ), Qt::UniqueConnection );
626+
connect( layer, SIGNAL( editingStopped() ), this, SLOT( layerNeedsUpdate() ), Qt::UniqueConnection );
627+
connect( layer, SIGNAL( layerModified() ), this, SLOT( layerNeedsUpdate() ), Qt::UniqueConnection );
628+
}
629+
}
630+
631+
// try to find out if the layer ID is present in the tree multiple times
632+
static int _numLayerCount( QgsLayerTreeGroup* group, const QString& layerId )
633+
{
634+
int count = 0;
635+
foreach ( QgsLayerTreeNode* child, group->children() )
636+
{
637+
if ( QgsLayerTree::isLayer( child ) )
638+
{
639+
if ( QgsLayerTree::toLayer( child )->layerId() == layerId )
640+
count++;
641+
}
642+
else if ( QgsLayerTree::isGroup( child ) )
643+
{
644+
count += _numLayerCount( QgsLayerTree::toGroup( child ), layerId );
645+
}
646+
}
647+
return count;
648+
}
649+
650+
void QgsLayerTreeModel::disconnectFromLayer( QgsLayerTreeLayer* nodeLayer )
651+
{
652+
if ( !nodeLayer->layer() )
653+
return; // we were never connected
654+
655+
if ( testFlag( ShowSymbology ) )
656+
{
657+
removeSymbologyFromLayer( nodeLayer );
658+
}
659+
660+
if ( _numLayerCount( mRootNode, nodeLayer->layerId() ) == 1 )
661+
{
662+
// last instance of the layer in the tree: disconnect from all signals from layer!
663+
disconnect( nodeLayer->layer(), 0, this, 0 );
664+
}
665+
}
666+
667+
595668
Qt::DropActions QgsLayerTreeModel::supportedDropActions() const
596669
{
597670
return /*Qt::CopyAction |*/ Qt::MoveAction;

src/gui/layertree/qgslayertreemodel.h

+6-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
class QgsLayerTreeNode;
2323
class QgsLayerTreeGroup;
2424
class QgsLayerTreeLayer;
25+
class QgsMapLayer;
2526

2627
/** internal class, not in public API */
2728
class QgsLayerTreeModelSymbologyNode : public QObject
@@ -104,14 +105,18 @@ class GUI_EXPORT QgsLayerTreeModel : public QAbstractItemModel
104105
void nodeLayerLoaded();
105106
void layerRendererChanged();
106107

108+
void layerNeedsUpdate();
109+
107110
protected:
108-
void removeSymbologyFromSubtree( QgsLayerTreeNode* node );
109111
void removeSymbologyFromLayer( QgsLayerTreeLayer* nodeLayer );
110112
void addSymbologyToLayer( QgsLayerTreeLayer* nodeL );
111113
void addSymbologyToVectorLayer( QgsLayerTreeLayer* nodeL );
112114
void addSymbologyToRasterLayer( QgsLayerTreeLayer* nodeL );
113115
void addSymbologyToPluginLayer( QgsLayerTreeLayer* nodeL );
114116

117+
void connectToLayer( QgsLayerTreeLayer* nodeLayer );
118+
void disconnectFromLayer( QgsLayerTreeLayer* nodeLayer );
119+
115120
protected:
116121
QgsLayerTreeGroup* mRootNode; // not owned!
117122
Flags mFlags;

0 commit comments

Comments
 (0)