Skip to content

Commit 5de2fee

Browse files
committed
add total feature count in legend, fixes #3402
1 parent 983535f commit 5de2fee

File tree

6 files changed

+84
-11
lines changed

6 files changed

+84
-11
lines changed

src/app/legend/qgslegend.cpp

+17-3
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@ QgsLegend::QgsLegend( QgsMapCanvas *canvas, QWidget * parent, const char *name )
8888
connect( this, SIGNAL( itemChanged( QTreeWidgetItem*, int ) ),
8989
this, SLOT( handleItemChange( QTreeWidgetItem*, int ) ) );
9090

91+
connect( itemDelegate(), SIGNAL( closeEditor( QWidget *, QAbstractItemDelegate::EndEditHint ) ),
92+
this, SLOT( handleCloseEditor( QWidget *, QAbstractItemDelegate::EndEditHint ) ) );
93+
9194
connect( this, SIGNAL( currentItemChanged( QTreeWidgetItem*, QTreeWidgetItem* ) ),
9295
this, SLOT( handleCurrentItemChanged( QTreeWidgetItem*, QTreeWidgetItem* ) ) );
9396

@@ -2153,6 +2156,14 @@ void QgsLegend::removePixmapHeightValue( int height )
21532156
//todo: adapt the icon size if height is the largest value and the size of the next element is higher than the minimum
21542157
}
21552158

2159+
void QgsLegend::handleCloseEditor( QWidget * editor, QAbstractItemDelegate::EndEditHint hint )
2160+
{
2161+
QgsLegendItem *item = dynamic_cast<QgsLegendItem *>( currentItem() );
2162+
if ( item )
2163+
{
2164+
item->afterEdit();
2165+
}
2166+
}
21562167

21572168
void QgsLegend::handleItemChange( QTreeWidgetItem* item, int column )
21582169
{
@@ -2185,8 +2196,10 @@ void QgsLegend::handleItemChange( QTreeWidgetItem* item, int column )
21852196
if ( ll )
21862197
{
21872198
//if the text of a QgsLegendLayer has changed, change the display names of all its maplayers
2188-
// TODO: is this still necessary?
2189-
ll->layer()->setLayerName( ll->text( 0 ) );
2199+
if ( ll->layerName() != ll->layer()->name() )
2200+
{
2201+
ll->layer()->setLayerName( ll->layerName() );
2202+
}
21902203
}
21912204

21922205
bool changing = mChanging;
@@ -2257,11 +2270,12 @@ void QgsLegend::handleItemChange( QTreeWidgetItem* item, int column )
22572270

22582271
void QgsLegend::openEditor()
22592272
{
2260-
QTreeWidgetItem* theItem = currentItem();
2273+
QgsLegendItem* theItem = dynamic_cast<QgsLegendItem*>( currentItem() );
22612274
if ( theItem )
22622275
{
22632276
if ( !groupEmbedded( theItem ) && !parentGroupEmbedded( theItem ) )
22642277
{
2278+
theItem->beforeEdit();
22652279
editItem( theItem, 0 );
22662280
}
22672281
}

src/app/legend/qgslegend.h

+1
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,7 @@ class QgsLegend : public QTreeWidget
443443
/** toogle update drawing order */
444444
void toggleDrawingOrderUpdate();
445445
void handleItemChange( QTreeWidgetItem* item, int row );
446+
void handleCloseEditor( QWidget * editor, QAbstractItemDelegate::EndEditHint hint );
446447
/** delegates current layer to map canvas */
447448
void handleCurrentItemChanged( QTreeWidgetItem* current, QTreeWidgetItem* previous );
448449
/**Calls openPersistentEditor for the current item*/

src/app/legend/qgslegenditem.h

+4
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,10 @@ class QgsLegendItem : public QTreeWidgetItem, public QObject
106106
virtual void receive( QgsLegendItem *newChild ) { Q_UNUSED( newChild ); }
107107
/**Do cleanups after a child item leaves (default empty)*/
108108
virtual void release( QgsLegendItem *formerChild ) { Q_UNUSED( formerChild ); }
109+
/**Called before edit*/
110+
virtual void beforeEdit() {}
111+
/**Called after edit*/
112+
virtual void afterEdit() {}
109113

110114
protected:
111115
LEGEND_ITEM_TYPE mType;

src/app/legend/qgslegendlayer.cpp

+44-7
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ QgsLegendLayer::QgsLegendLayer( QgsMapLayer* layer )
5151
, mLyr( layer )
5252
, mDrawingOrder( -1 )
5353
, mShowFeatureCount( false )
54+
, mFeatureCount( -1 )
5455
{
5556
mType = LEGEND_LAYER;
5657

@@ -66,7 +67,7 @@ QgsLegendLayer::QgsLegendLayer( QgsMapLayer* layer )
6667

6768
setCheckState( 0, Qt::Checked );
6869

69-
setText( 0, layer->name() );
70+
layerNameChanged();
7071
setupFont();
7172

7273
// Set the initial visibility flag for layers
@@ -296,6 +297,7 @@ void QgsLegendLayer::vectorLayerSymbologyV2( QgsVectorLayer* layer )
296297
}
297298

298299
changeSymbologySettings( layer, itemList );
300+
layerNameChanged(); // update total count
299301
}
300302
}
301303

@@ -556,10 +558,41 @@ QgsMapCanvasLayer& QgsLegendLayer::canvasLayer()
556558
return mLyr;
557559
}
558560

559-
void QgsLegendLayer::layerNameChanged()
561+
QString QgsLegendLayer::label() const
560562
{
561563
QString name = mLyr.layer()->name();
562-
setText( 0, name );
564+
if ( mShowFeatureCount && mFeatureCount >= 0 )
565+
{
566+
name += QString( " [%1]" ).arg( mFeatureCount );
567+
}
568+
return name;
569+
}
570+
571+
void QgsLegendLayer::layerNameChanged()
572+
{
573+
setText( 0, label() );
574+
}
575+
576+
void QgsLegendLayer::beforeEdit()
577+
{
578+
// Reset to layer name without possible feature count
579+
setText( 0, mLyr.layer()->name() );
580+
}
581+
582+
void QgsLegendLayer::afterEdit()
583+
{
584+
// Reset label with possible feature count, important if text was not changed
585+
layerNameChanged();
586+
}
587+
588+
QString QgsLegendLayer::layerName() const
589+
{
590+
// The text could be edited (Rename), in that case we have to return the new name
591+
if ( text( 0 ) != label() && text( 0 ) != mLyr.layer()->name() )
592+
{
593+
return text( 0 );
594+
}
595+
return mLyr.layer()->name();
563596
}
564597

565598
void QgsLegendLayer::updateAfterLayerModification()
@@ -580,10 +613,12 @@ void QgsLegendLayer::updateAfterLayerModification( bool onlyGeomChanged )
580613
widthScale = canvas->map()->paintDevice().logicalDpiX() / 25.4;
581614
}
582615
refreshSymbology( mLyr.layer()->id(), widthScale );
616+
layerNameChanged();
583617
}
584618

585619
void QgsLegendLayer::updateItemListCountV2( SymbologyList& itemList, QgsVectorLayer* layer )
586620
{
621+
mFeatureCount = -1;
587622
if ( !layer )
588623
{
589624
return;
@@ -598,12 +633,12 @@ void QgsLegendLayer::updateItemListCountV2( SymbologyList& itemList, QgsVectorLa
598633
renderer->startRender( dummyContext, layer );
599634

600635
//create map holding the symbol count
601-
QMap< QgsSymbolV2*, int > mSymbolCountMap;
636+
QMap< QgsSymbolV2*, int > symbolCountMap;
602637
QgsLegendSymbolList symbolList = renderer->legendSymbolItems();
603638
QgsLegendSymbolList::const_iterator symbolIt = symbolList.constBegin();
604639
for ( ; symbolIt != symbolList.constEnd(); ++symbolIt )
605640
{
606-
mSymbolCountMap.insert( symbolIt->second, 0 );
641+
symbolCountMap.insert( symbolIt->second, 0 );
607642
}
608643

609644
//go through all features and count the number of occurrences
@@ -625,7 +660,7 @@ void QgsLegendLayer::updateItemListCountV2( SymbologyList& itemList, QgsVectorLa
625660
QgsSymbolV2List symbolList = renderer->symbolsForFeature( f );
626661
for ( QgsSymbolV2List::iterator symbolIt = symbolList.begin(); symbolIt != symbolList.end(); ++symbolIt )
627662
{
628-
mSymbolCountMap[*symbolIt] += 1;
663+
symbolCountMap[*symbolIt] += 1;
629664
}
630665
++featuresCounted;
631666
if ( featuresCounted % 50 == 0 )
@@ -637,9 +672,11 @@ void QgsLegendLayer::updateItemListCountV2( SymbologyList& itemList, QgsVectorLa
637672
p.setValue( featuresCounted );
638673
if ( p.wasCanceled() )
639674
{
675+
mFeatureCount = -1;
640676
return;
641677
}
642678
}
679+
mFeatureCount++;
643680
}
644681
renderer->stopRender( renderContext );
645682
p.setValue( nFeatures );
@@ -655,7 +692,7 @@ void QgsLegendLayer::updateItemListCountV2( SymbologyList& itemList, QgsVectorLa
655692
symbolIt = symbolList.constBegin();
656693
for ( ; symbolIt != symbolList.constEnd(); ++symbolIt )
657694
{
658-
itemList.push_back( qMakePair( symbolIt->first + " [" + QString::number( mSymbolCountMap[symbolIt->second] ) + "]", itemMap[symbolIt->first] ) );
695+
itemList.push_back( qMakePair( symbolIt->first + " [" + QString::number( symbolCountMap[symbolIt->second] ) + "]", itemMap[symbolIt->first] ) );
659696
}
660697
}
661698

src/app/legend/qgslegendlayer.h

+15
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,15 @@ class QgsLegendLayer : public QgsLegendItem
7575
void setDrawingOrder( int order );
7676
int drawingOrder() const { return mDrawingOrder; }
7777

78+
/** Get layer name currently set in legend */
79+
QString layerName() const;
80+
81+
/**Called before edit*/
82+
void beforeEdit();
83+
84+
/**Called after edit*/
85+
void afterEdit();
86+
7887
public slots:
7988

8089
/**Toggle show in overview*/
@@ -120,6 +129,9 @@ class QgsLegendLayer : public QgsLegendItem
120129
*/
121130
void setupFont();
122131

132+
/** Label, may be layer name or layer name + [feature count] */
133+
QString label() const;
134+
123135
protected:
124136

125137
/** layer identified by its layer id */
@@ -130,6 +142,9 @@ class QgsLegendLayer : public QgsLegendItem
130142

131143
/**True if number of features per legend class should is shown in the legend items*/
132144
bool mShowFeatureCount;
145+
146+
/** Last vector features count, -1 if not counted */
147+
int mFeatureCount;
133148
};
134149

135150
#endif

src/core/qgsmaplayer.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,9 @@ QString QgsMapLayer::id() const
103103
void QgsMapLayer::setLayerName( const QString & name )
104104
{
105105
QgsDebugMsg( "new name is '" + name + "'" );
106-
mLayerName = capitaliseLayerName( name );
106+
QString newName = capitaliseLayerName( name );
107+
if ( newName == mLayerName ) return;
108+
mLayerName = newName;
107109
emit layerNameChanged();
108110
}
109111

0 commit comments

Comments
 (0)