Skip to content

Commit

Permalink
vector feature counts moved to vector layer, enabled feature counts i…
Browse files Browse the repository at this point in the history
…n composer legend, fixes #6237
  • Loading branch information
blazek committed Nov 6, 2012
1 parent 4b789b8 commit 038acbc
Show file tree
Hide file tree
Showing 12 changed files with 295 additions and 77 deletions.
1 change: 1 addition & 0 deletions images/images.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@
<file>themes/default/mActionSimplify.png</file>
<file>themes/default/mActionSplitFeatures.png</file>
<file>themes/default/mActionSplitFeatures.svg</file>
<file>themes/default/mActionSum.png</file>
<file>themes/default/mActionTextAnnotation.png</file>
<file>themes/default/mActionToggleEditing.png</file>
<file>themes/default/mActionUndo.png</file>
Expand Down
Binary file added images/themes/default/mActionSum.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
77 changes: 77 additions & 0 deletions src/app/composer/qgscomposerlegendwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

#include "qgscomposerlegendwidget.h"
#include "qgscomposerlegend.h"
#include "qgscomposerlegenditem.h"
#include "qgscomposerlegenditemdialog.h"
#include "qgscomposerlegendlayersdialog.h"
#include "qgscomposeritemwidget.h"
Expand All @@ -26,8 +27,10 @@
#include "qgsapplegendinterface.h"
#include "qgisapp.h"
#include "qgsmapcanvas.h"
#include "qgsmaplayerregistry.h"
#include "qgsmaprenderer.h"
#include "qgsapplication.h"
#include "qgsvectorlayer.h"

#include <QMessageBox>

Expand All @@ -41,6 +44,7 @@ QgsComposerLegendWidget::QgsComposerLegendWidget( QgsComposerLegend* legend ): m
mRemoveToolButton->setIcon( QIcon( QgsApplication::iconPath( "symbologyRemove.png" ) ) );
mMoveUpToolButton->setIcon( QIcon( QgsApplication::iconPath( "symbologyUp.png" ) ) );
mMoveDownToolButton->setIcon( QIcon( QgsApplication::iconPath( "symbologyDown.png" ) ) );
mCountToolButton->setIcon( QIcon( QgsApplication::iconPath( "mActionSum.png" ) ) );

//add widget for item properties
QgsComposerItemWidget* itemPropertiesWidget = new QgsComposerItemWidget( this, legend );
Expand All @@ -59,6 +63,9 @@ QgsComposerLegendWidget::QgsComposerLegendWidget( QgsComposerLegend* legend ): m

setGuiElements();
connect( mItemTreeView, SIGNAL( itemChanged() ), this, SLOT( setGuiElements() ) );

connect( mItemTreeView->selectionModel(), SIGNAL( currentChanged( const QModelIndex &, const QModelIndex & ) ),
this, SLOT( selectedChanged( const QModelIndex &, const QModelIndex & ) ) );
}

QgsComposerLegendWidget::QgsComposerLegendWidget(): mLegend( 0 )
Expand Down Expand Up @@ -612,6 +619,52 @@ void QgsComposerLegendWidget::on_mUpdatePushButton_clicked()
mLegend->endCommand();
}

void QgsComposerLegendWidget::on_mCountToolButton_clicked( bool checked )
{
QgsDebugMsg( "Entered." );
if ( !mLegend )
{
return;
}

//get current item
QStandardItemModel* itemModel = qobject_cast<QStandardItemModel *>( mItemTreeView->model() );
if ( !itemModel )
{
return;
}

//get current item
QModelIndex currentIndex = mItemTreeView->currentIndex();
if ( !currentIndex.isValid() )
{
return;
}

QStandardItem* currentItem = itemModel->itemFromIndex( currentIndex );
if ( !currentItem )
{
return;
}

QgsComposerLayerItem* layerItem = dynamic_cast<QgsComposerLayerItem *>( currentItem );

if ( !layerItem )
{
return;
}

mLegend->beginCommand( tr( "Legend updated" ) );
layerItem->setShowFeatureCount( checked );
if ( mLegend->model() )
{
mLegend->model()->updateItem( currentItem );
}
mLegend->update();
mLegend->adjustBoxSize();
mLegend->endCommand();
}

void QgsComposerLegendWidget::on_mUpdateAllPushButton_clicked()
{
updateLegend();
Expand Down Expand Up @@ -715,3 +768,27 @@ void QgsComposerLegendWidget::showEvent( QShowEvent * event )
refreshMapComboBox();
QWidget::showEvent( event );
}

void QgsComposerLegendWidget::selectedChanged( const QModelIndex & current, const QModelIndex & previous )
{
Q_UNUSED( previous );
QgsDebugMsg( "Entered" );

mCountToolButton->setChecked( false );
mCountToolButton->setEnabled( false );

QStandardItemModel* itemModel = qobject_cast<QStandardItemModel *>( mItemTreeView->model() );
if ( !itemModel ) return;

QStandardItem* currentItem = itemModel->itemFromIndex( current );
if ( !currentItem ) return;

QgsComposerLayerItem* layerItem = dynamic_cast<QgsComposerLayerItem *>( currentItem );
if ( !layerItem ) return;

QgsVectorLayer* vectorLayer = dynamic_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( layerItem->layerID() ) );
if ( !vectorLayer ) return;

mCountToolButton->setChecked( layerItem->showFeatureCount() );
mCountToolButton->setEnabled( true );
}
3 changes: 3 additions & 0 deletions src/app/composer/qgscomposerlegendwidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,13 @@ class QgsComposerLegendWidget: public QWidget, private Ui::QgsComposerLegendWidg
void on_mRemoveToolButton_clicked();
void on_mAddToolButton_clicked();
void on_mEditPushButton_clicked();
void on_mCountToolButton_clicked( bool checked );
void on_mUpdatePushButton_clicked();
void on_mUpdateAllPushButton_clicked();
void on_mAddGroupButton_clicked();

void selectedChanged( const QModelIndex & current, const QModelIndex & previous );

protected:
void showEvent( QShowEvent * event );

Expand Down
68 changes: 13 additions & 55 deletions src/app/legend/qgslegendlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ QgsLegendLayer::QgsLegendLayer( QgsMapLayer* layer )
, mLyr( layer )
, mDrawingOrder( -1 )
, mShowFeatureCount( false )
, mFeatureCount( -1 )
{
mType = LEGEND_LAYER;

Expand Down Expand Up @@ -558,12 +557,13 @@ QgsMapCanvasLayer& QgsLegendLayer::canvasLayer()
return mLyr;
}

QString QgsLegendLayer::label() const
QString QgsLegendLayer::label()
{
QString name = mLyr.layer()->name();
if ( mShowFeatureCount && mFeatureCount >= 0 )
QgsVectorLayer *vlayer = dynamic_cast<QgsVectorLayer *>( mLyr.layer() );
if ( mShowFeatureCount && vlayer && vlayer->featureCount() >= 0 )
{
name += QString( " [%1]" ).arg( mFeatureCount );
name += QString( " [%1]" ).arg( vlayer->featureCount() );
}
return name;
}
Expand All @@ -585,7 +585,7 @@ void QgsLegendLayer::afterEdit()
layerNameChanged();
}

QString QgsLegendLayer::layerName() const
QString QgsLegendLayer::layerName()
{
// The text could be edited (Rename), in that case we have to return the new name
if ( text( 0 ) != label() && text( 0 ) != mLyr.layer()->name() )
Expand Down Expand Up @@ -618,7 +618,6 @@ void QgsLegendLayer::updateAfterLayerModification( bool onlyGeomChanged )

void QgsLegendLayer::updateItemListCountV2( SymbologyList& itemList, QgsVectorLayer* layer )
{
mFeatureCount = -1;
if ( !layer )
{
return;
Expand All @@ -629,70 +628,29 @@ void QgsLegendLayer::updateItemListCountV2( SymbologyList& itemList, QgsVectorLa
{
return;
}
QgsRenderContext dummyContext;
renderer->startRender( dummyContext, layer );

//create map holding the symbol count
QMap< QgsSymbolV2*, int > symbolCountMap;
QgsLegendSymbolList symbolList = renderer->legendSymbolItems();
QgsLegendSymbolList::const_iterator symbolIt = symbolList.constBegin();
for ( ; symbolIt != symbolList.constEnd(); ++symbolIt )
{
symbolCountMap.insert( symbolIt->second, 0 );
}

//go through all features and count the number of occurrences
int nFeatures = layer->pendingFeatureCount();
QProgressDialog p( tr( "Updating feature count for layer %1" ).arg( layer->name() ), tr( "Abort" ), 0, nFeatures );
p.setWindowModality( Qt::WindowModal );
int featuresCounted = 0;

layer->select( layer->pendingAllAttributesList(), QgsRectangle(), false, false );
QgsFeature f;

// Renderer (rule based) may depend on context scale, with scale is ignored if 0
QgsRenderContext renderContext;
renderContext.setRendererScale( 0 );
renderer->startRender( renderContext, layer );

while ( layer->nextFeature( f ) )
// Count features
if ( !layer->countSymbolFeatures() )
{
QgsSymbolV2List symbolList = renderer->symbolsForFeature( f );
for ( QgsSymbolV2List::iterator symbolIt = symbolList.begin(); symbolIt != symbolList.end(); ++symbolIt )
{
symbolCountMap[*symbolIt] += 1;
}
++featuresCounted;
if ( featuresCounted % 50 == 0 )
{
if ( featuresCounted > nFeatures ) //sometimes the feature count is not correct
{
p.setMaximum( 0 );
}
p.setValue( featuresCounted );
if ( p.wasCanceled() )
{
mFeatureCount = -1;
return;
}
}
mFeatureCount++;
QgsDebugMsg( "Cannot get feature counts" );
return;
}
renderer->stopRender( renderContext );
p.setValue( nFeatures );

QMap<QString, QPixmap> itemMap;
SymbologyList::const_iterator symbologyIt = itemList.constBegin();
for ( ; symbologyIt != itemList.constEnd(); ++ symbologyIt )
{
itemMap.insert( symbologyIt->first, symbologyIt->second );
}

itemList.clear();

QgsLegendSymbolList symbolList = renderer->legendSymbolItems();
QgsLegendSymbolList::const_iterator symbolIt = symbolList.constBegin();
symbolIt = symbolList.constBegin();
for ( ; symbolIt != symbolList.constEnd(); ++symbolIt )
{
itemList.push_back( qMakePair( symbolIt->first + " [" + QString::number( symbolCountMap[symbolIt->second] ) + "]", itemMap[symbolIt->first] ) );
itemList.push_back( qMakePair( symbolIt->first + " [" + QString::number( layer->featureCount( symbolIt->second ) ) + "]", itemMap[symbolIt->first] ) );
}
}

Expand Down
7 changes: 2 additions & 5 deletions src/app/legend/qgslegendlayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ class QgsLegendLayer : public QgsLegendItem
int drawingOrder() const { return mDrawingOrder; }

/** Get layer name currently set in legend */
QString layerName() const;
QString layerName();

/**Called before edit*/
void beforeEdit();
Expand Down Expand Up @@ -130,7 +130,7 @@ class QgsLegendLayer : public QgsLegendItem
void setupFont();

/** Label, may be layer name or layer name + [feature count] */
QString label() const;
QString label();

protected:

Expand All @@ -142,9 +142,6 @@ class QgsLegendLayer : public QgsLegendItem

/**True if number of features per legend class should is shown in the legend items*/
bool mShowFeatureCount;

/** Last vector features count, -1 if not counted */
int mFeatureCount;
};

#endif
4 changes: 4 additions & 0 deletions src/core/composer/qgscomposerlegenditem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -288,10 +288,12 @@ void QgsComposerRasterSymbolItem::readXML( const QDomElement& itemElem, bool xSe
////////////////////QgsComposerLayerItem

QgsComposerLayerItem::QgsComposerLayerItem(): QgsComposerLegendItem()
, mShowFeatureCount( false )
{
}

QgsComposerLayerItem::QgsComposerLayerItem( const QString& text ): QgsComposerLegendItem( text )
, mShowFeatureCount( false )
{
}

Expand All @@ -312,6 +314,7 @@ void QgsComposerLayerItem::writeXML( QDomElement& elem, QDomDocument& doc ) cons
QDomElement layerItemElem = doc.createElement( "LayerItem" );
layerItemElem.setAttribute( "layerId", mLayerID );
layerItemElem.setAttribute( "text", text() );
layerItemElem.setAttribute( "showFeatureCount", showFeatureCount() );
writeXMLChildren( layerItemElem, doc );
elem.appendChild( layerItemElem );
}
Expand All @@ -324,6 +327,7 @@ void QgsComposerLayerItem::readXML( const QDomElement& itemElem, bool xServerAva
}
setText( itemElem.attribute( "text", "" ) );
setLayerID( itemElem.attribute( "layerId", "" ) );
setShowFeatureCount( itemElem.attribute( "showFeatureCount", "" ) == "1" ? true : false );

//now call readXML for all the child items
QDomNodeList childList = itemElem.childNodes();
Expand Down
5 changes: 5 additions & 0 deletions src/core/composer/qgscomposerlegenditem.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,13 @@ class CORE_EXPORT QgsComposerLayerItem: public QgsComposerLegendItem
void setLayerID( const QString& id ) { mLayerID = id; }
QString layerID() const { return mLayerID; }

void setShowFeatureCount( bool show ) { mShowFeatureCount = show; }
bool showFeatureCount() const { return mShowFeatureCount; }

private:
QString mLayerID;
// Show vector feature counts
bool mShowFeatureCount;
};

class CORE_EXPORT QgsComposerGroupItem: public QgsComposerLegendItem
Expand Down
30 changes: 26 additions & 4 deletions src/core/composer/qgslegendmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,9 @@ QStandardItem* QgsLegendModel::addGroup( QString text, int position )

int QgsLegendModel::addVectorLayerItemsV2( QStandardItem* layerItem, QgsVectorLayer* vlayer )
{
if ( !layerItem || !vlayer )
QgsComposerLayerItem* lItem = dynamic_cast<QgsComposerLayerItem*>( layerItem );

if ( !layerItem || !lItem || !vlayer )
{
return 1;
}
Expand All @@ -147,11 +149,24 @@ int QgsLegendModel::addVectorLayerItemsV2( QStandardItem* layerItem, QgsVectorLa
return 2;
}

if ( lItem->showFeatureCount() )
{
if ( !vlayer->countSymbolFeatures() )
{
QgsDebugMsg( "Cannot get feature counts" );
}
}

QgsLegendSymbolList lst = renderer->legendSymbolItems();
QgsLegendSymbolList::const_iterator symbolIt = lst.constBegin();
for ( ; symbolIt != lst.constEnd(); ++symbolIt )
{
QgsComposerSymbolV2Item* currentSymbolItem = new QgsComposerSymbolV2Item( symbolIt->first );
QString label = symbolIt->first;
if ( lItem->showFeatureCount() )
{
label += QString( " [%1]" ).arg( vlayer->featureCount( symbolIt->second ) );
}
QgsComposerSymbolV2Item* currentSymbolItem = new QgsComposerSymbolV2Item( label );
currentSymbolItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );
if ( symbolIt->second )
{
Expand Down Expand Up @@ -282,6 +297,7 @@ void QgsLegendModel::updateItem( QStandardItem* item )

void QgsLegendModel::updateLayer( QStandardItem* layerItem )
{
QgsDebugMsg( "Entered." );
QgsComposerLayerItem* lItem = dynamic_cast<QgsComposerLayerItem*>( layerItem );
if ( lItem )
{
Expand All @@ -295,10 +311,16 @@ void QgsLegendModel::updateLayer( QStandardItem* layerItem )
lItem->removeRow( i );
}

QgsVectorLayer* vLayer = qobject_cast<QgsVectorLayer*>( mapLayer );

//set layer name as item text
layerItem->setText( mapLayer->name() );
QString label = mapLayer->name();
if ( vLayer && lItem->showFeatureCount() )
{
label += QString( " [%1]" ).arg( vLayer->featureCount() );
}
layerItem->setText( label );

QgsVectorLayer* vLayer = qobject_cast<QgsVectorLayer*>( mapLayer );
if ( vLayer )
{
if ( vLayer->isUsingRendererV2() )
Expand Down
Loading

0 comments on commit 038acbc

Please sign in to comment.