Skip to content
Permalink
Browse files
vector feature counts moved to vector layer, enabled feature counts i…
…n composer legend, fixes #6237
  • Loading branch information
blazek committed Nov 6, 2012
1 parent 4b789b8 commit 038acbc76083dae3fd29795b9e73d97cd92c3d3a
@@ -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>
Binary file not shown.
@@ -17,6 +17,7 @@

#include "qgscomposerlegendwidget.h"
#include "qgscomposerlegend.h"
#include "qgscomposerlegenditem.h"
#include "qgscomposerlegenditemdialog.h"
#include "qgscomposerlegendlayersdialog.h"
#include "qgscomposeritemwidget.h"
@@ -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>

@@ -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 );
@@ -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 )
@@ -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();
@@ -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 );
}
@@ -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 );

@@ -51,7 +51,6 @@ QgsLegendLayer::QgsLegendLayer( QgsMapLayer* layer )
, mLyr( layer )
, mDrawingOrder( -1 )
, mShowFeatureCount( false )
, mFeatureCount( -1 )
{
mType = LEGEND_LAYER;

@@ -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;
}
@@ -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() )
@@ -618,7 +618,6 @@ void QgsLegendLayer::updateAfterLayerModification( bool onlyGeomChanged )

void QgsLegendLayer::updateItemListCountV2( SymbologyList& itemList, QgsVectorLayer* layer )
{
mFeatureCount = -1;
if ( !layer )
{
return;
@@ -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] ) );
}
}

@@ -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();
@@ -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:

@@ -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
@@ -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 )
{
}

@@ -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 );
}
@@ -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();
@@ -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
@@ -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;
}
@@ -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 )
{
@@ -282,6 +297,7 @@ void QgsLegendModel::updateItem( QStandardItem* item )

void QgsLegendModel::updateLayer( QStandardItem* layerItem )
{
QgsDebugMsg( "Entered." );
QgsComposerLayerItem* lItem = dynamic_cast<QgsComposerLayerItem*>( layerItem );
if ( lItem )
{
@@ -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() )

0 comments on commit 038acbc

Please sign in to comment.