Skip to content

Commit

Permalink
composer legend: store user defined labels separately, fixes partialy #…
Browse files Browse the repository at this point in the history
  • Loading branch information
blazek committed May 8, 2013
1 parent 1877eb5 commit 4c7f51e
Show file tree
Hide file tree
Showing 9 changed files with 218 additions and 41 deletions.
1 change: 1 addition & 0 deletions images/images.qrc
Expand Up @@ -121,6 +121,7 @@
<file>themes/default/mActionAddArrow.png</file>
<file>themes/default/mActionAddBasicShape.png</file>
<file>themes/default/mActionAddGPSLayer.png</file>
<file>themes/default/mActionAddGroup.png</file>
<file>themes/default/mActionAddHtml.png</file>
<file>themes/default/mActionAddImage.png</file>
<file>themes/default/mActionAddLayer.png</file>
Expand Down
Binary file added images/themes/default/mActionAddGroup.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 4 additions & 3 deletions src/app/composer/qgscomposerlegendwidget.cpp
Expand Up @@ -716,7 +716,7 @@ void QgsComposerLegendWidget::on_mEditPushButton_clicked()
return;
}

QStandardItem* currentItem = itemModel->itemFromIndex( currentIndex );
QgsComposerLegendItem* currentItem = dynamic_cast<QgsComposerLegendItem *>( itemModel->itemFromIndex( currentIndex ) );
if ( !currentItem )
{
return;
Expand All @@ -725,7 +725,8 @@ void QgsComposerLegendWidget::on_mEditPushButton_clicked()
QgsComposerLegendItemDialog itemDialog( currentItem );
if ( itemDialog.exec() == QDialog::Accepted )
{
currentItem->setText( itemDialog.itemText() );
currentItem->setUserText( itemDialog.itemText() );
mLegend->model()->updateItemText( currentItem );
}

mLegend->beginCommand( tr( "Legend item edited" ) );
Expand Down Expand Up @@ -822,7 +823,7 @@ void QgsComposerLegendWidget::on_mUpdateAllPushButton_clicked()
updateLegend();
}

void QgsComposerLegendWidget::on_mAddGroupButton_clicked()
void QgsComposerLegendWidget::on_mAddGroupToolButton_clicked()
{
if ( mLegend && mLegend->model() )
{
Expand Down
2 changes: 1 addition & 1 deletion src/app/composer/qgscomposerlegendwidget.h
Expand Up @@ -82,7 +82,7 @@ class QgsComposerLegendWidget: public QWidget, private Ui::QgsComposerLegendWidg
void on_mCountToolButton_clicked( bool checked );
void on_mUpdatePushButton_clicked();
void on_mUpdateAllPushButton_clicked();
void on_mAddGroupButton_clicked();
void on_mAddGroupToolButton_clicked();

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

Expand Down
17 changes: 16 additions & 1 deletion src/core/composer/qgscomposerlegenditem.cpp
Expand Up @@ -105,6 +105,7 @@ void QgsComposerSymbolV2Item::writeXML( QDomElement& elem, QDomDocument& doc ) c
vectorClassElem.appendChild( symbolsElem );
}
vectorClassElem.setAttribute( "text", text() );
vectorClassElem.setAttribute( "userText", userText() );
elem.appendChild( vectorClassElem );
}

Expand All @@ -116,6 +117,7 @@ void QgsComposerSymbolV2Item::readXML( const QDomElement& itemElem, bool xServer
}

setText( itemElem.attribute( "text", "" ) );
setUserText( itemElem.attribute( "userText", "" ) );
QDomElement symbolsElem = itemElem.firstChildElement( "symbols" );
if ( !symbolsElem.isNull() )
{
Expand Down Expand Up @@ -174,6 +176,7 @@ void QgsComposerRasterSymbolItem::writeXML( QDomElement& elem, QDomDocument& doc
QDomElement rasterClassElem = doc.createElement( "RasterClassificationItem" );
rasterClassElem.setAttribute( "layerId", mLayerID );
rasterClassElem.setAttribute( "text", text() );
rasterClassElem.setAttribute( "userText", userText() );
rasterClassElem.setAttribute( "color", mColor.name() );
elem.appendChild( rasterClassElem );
}
Expand All @@ -185,6 +188,7 @@ void QgsComposerRasterSymbolItem::readXML( const QDomElement& itemElem, bool xSe
return;
}
setText( itemElem.attribute( "text", "" ) );
setUserText( itemElem.attribute( "userText", "" ) );
setLayerID( itemElem.attribute( "layerId", "" ) );
setColor( QColor( itemElem.attribute( "color" ) ) );

Expand Down Expand Up @@ -225,6 +229,7 @@ void QgsComposerLayerItem::writeXML( QDomElement& elem, QDomDocument& doc ) cons
QDomElement layerItemElem = doc.createElement( "LayerItem" );
layerItemElem.setAttribute( "layerId", mLayerID );
layerItemElem.setAttribute( "text", text() );
layerItemElem.setAttribute( "userText", userText() );
layerItemElem.setAttribute( "showFeatureCount", showFeatureCount() );
layerItemElem.setAttribute( "style", QgsComposerLegendStyle::styleName( mStyle ) );
writeXMLChildren( layerItemElem, doc );
Expand All @@ -238,6 +243,7 @@ void QgsComposerLayerItem::readXML( const QDomElement& itemElem, bool xServerAva
return;
}
setText( itemElem.attribute( "text", "" ) );
setUserText( itemElem.attribute( "userText", "" ) );
setLayerID( itemElem.attribute( "layerId", "" ) );
setShowFeatureCount( itemElem.attribute( "showFeatureCount", "" ) == "1" ? true : false );
setStyle( QgsComposerLegendStyle::styleFromName( itemElem.attribute( "style", "subgroup" ) ) );
Expand Down Expand Up @@ -327,7 +333,9 @@ QStandardItem* QgsComposerGroupItem::clone() const
void QgsComposerGroupItem::writeXML( QDomElement& elem, QDomDocument& doc ) const
{
QDomElement layerGroupElem = doc.createElement( "GroupItem" );
// text is always user text, but for forward compatibility for now write both
layerGroupElem.setAttribute( "text", text() );
layerGroupElem.setAttribute( "userText", userText() );
layerGroupElem.setAttribute( "style", QgsComposerLegendStyle::styleName( mStyle ) );
writeXMLChildren( layerGroupElem, doc );
elem.appendChild( layerGroupElem );
Expand All @@ -339,7 +347,14 @@ void QgsComposerGroupItem::readXML( const QDomElement& itemElem, bool xServerAva
{
return;
}
setText( itemElem.attribute( "text", "" ) );
// text is always user text but for backward compatibility we read also text
QString userText = itemElem.attribute( "userText", "" );
if ( userText.isEmpty() )
{
userText = itemElem.attribute( "text", "" );
}
setText( userText );
setUserText( userText );

setStyle( QgsComposerLegendStyle::styleFromName( itemElem.attribute( "style", "group" ) ) );

Expand Down
9 changes: 9 additions & 0 deletions src/core/composer/qgscomposerlegenditem.h
Expand Up @@ -53,10 +53,19 @@ class CORE_EXPORT QgsComposerLegendItem: public QStandardItem
QgsComposerLegendStyle::Style style() const { return mStyle; }
void setStyle( QgsComposerLegendStyle::Style style ) { mStyle = style; }

// Get text defined by user
virtual QString userText() const { return mUserText; }
// Set text defined by user
virtual void setUserText( const QString & text ) { mUserText = text; }


protected:
void writeXMLChildren( QDomElement& elem, QDomDocument& doc ) const;

QgsComposerLegendStyle::Style mStyle;

// User defined text
QString mUserText;
};


Expand Down
181 changes: 155 additions & 26 deletions src/core/composer/qgslegendmodel.cpp
Expand Up @@ -121,6 +121,7 @@ QStandardItem* QgsLegendModel::addGroup( QString text, int position )
text = tr( "Group" );

QgsComposerGroupItem* groupItem = new QgsComposerGroupItem( text );
groupItem->setUserText( text );

if ( position == -1 )
{
Expand Down Expand Up @@ -159,19 +160,18 @@ int QgsLegendModel::addVectorLayerItemsV2( QStandardItem* layerItem, QgsVectorLa

QgsLegendSymbolList lst = renderer->legendSymbolItems();
QgsLegendSymbolList::const_iterator symbolIt = lst.constBegin();
int row = 0;
for ( ; symbolIt != lst.constEnd(); ++symbolIt )
{
QString label = symbolIt->first;
if ( lItem->showFeatureCount() )
QgsComposerSymbolV2Item* currentSymbolItem = new QgsComposerSymbolV2Item( "" );

// Get userText from old item if exists
QgsComposerSymbolV2Item* oldSymbolItem = dynamic_cast<QgsComposerSymbolV2Item*>( layerItem->child( row, 0 ) );
if ( oldSymbolItem )
{
// Add counts to multi symbols layers only or labeled single symbols,
// so that single symbol layers are still drawn on single line
if ( lst.size() > 1 || !label.isEmpty() )
{
label += QString( " [%1]" ).arg( vlayer->featureCount( symbolIt->second ) );
}
currentSymbolItem->setUserText( oldSymbolItem->userText() );
}
QgsComposerSymbolV2Item* currentSymbolItem = new QgsComposerSymbolV2Item( label );

currentSymbolItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );
if ( symbolIt->second )
{
Expand All @@ -181,14 +181,23 @@ int QgsLegendModel::addVectorLayerItemsV2( QStandardItem* layerItem, QgsVectorLa
}
currentSymbolItem->setSymbolV2( symbolIt->second->clone() );
}
layerItem->setChild( layerItem->rowCount(), 0, currentSymbolItem );
layerItem->setChild( row, 0, currentSymbolItem );

// updateSymbolV2ItemText needs layer set
updateSymbolV2ItemText( currentSymbolItem );

row++;
}

// Delete following old items (if current number of items decreased)
for ( int i = layerItem->rowCount() - 1; i >= row; --i )
{
layerItem->removeRow( i );
}

return 0;
}



int QgsLegendModel::addRasterLayerItems( QStandardItem* layerItem, QgsMapLayer* rlayer )
{
if ( !layerItem || !rlayer )
Expand All @@ -204,9 +213,18 @@ int QgsLegendModel::addRasterLayerItems( QStandardItem* layerItem, QgsMapLayer*

QList< QPair< QString, QColor > > rasterItemList = rasterLayer->legendSymbologyItems();
QList< QPair< QString, QColor > >::const_iterator itemIt = rasterItemList.constBegin();
int row = 0;
for ( ; itemIt != rasterItemList.constEnd(); ++itemIt )
{
QgsComposerRasterSymbolItem* currentSymbolItem = new QgsComposerRasterSymbolItem( itemIt->first );

QgsComposerRasterSymbolItem* oldSymbolItem = dynamic_cast<QgsComposerRasterSymbolItem*>( layerItem->child( row, 0 ) );
if ( oldSymbolItem )
{
currentSymbolItem->setUserText( oldSymbolItem->userText() );
currentSymbolItem->setText( currentSymbolItem->userText() );
}

if ( mHasTopLevelWindow )
{
QPixmap itemPixmap( 20, 20 );
Expand All @@ -217,11 +235,76 @@ int QgsLegendModel::addRasterLayerItems( QStandardItem* layerItem, QgsMapLayer*
currentSymbolItem->setColor( itemIt->second );
int currentRowCount = layerItem->rowCount();
layerItem->setChild( currentRowCount, 0, currentSymbolItem );
row++;
}

// Delete following old items (if current number of items decreased)
for ( int i = layerItem->rowCount() - 1; i >= row; --i )
{
layerItem->removeRow( i );
}

return 0;
}

void QgsLegendModel::updateSymbolV2ItemText( QStandardItem* symbolItem )
{
QgsComposerSymbolV2Item* sv2Item = dynamic_cast<QgsComposerSymbolV2Item*>( symbolItem );
if ( !sv2Item ) return;

QgsComposerLayerItem* lItem = dynamic_cast<QgsComposerLayerItem*>( sv2Item->parent() );
if ( !lItem ) return;

QgsMapLayer* mapLayer = QgsMapLayerRegistry::instance()->mapLayer( lItem->layerID() );
if ( !mapLayer ) return;

QgsVectorLayer* vLayer = qobject_cast<QgsVectorLayer*>( mapLayer );
if ( !vLayer ) return;

QgsFeatureRendererV2* renderer = vLayer->rendererV2();
if ( !renderer ) return;

if ( lItem->showFeatureCount() ) vLayer->countSymbolFeatures();

QgsLegendSymbolList symbolList = renderer->legendSymbolItems();

QPair<QString, QgsSymbolV2*> symbol = symbolList.value( symbolItem->row() );

QString label = sv2Item->userText().isEmpty() ? symbol.first : sv2Item->userText();

if ( lItem->showFeatureCount() )
{
// Add counts to multi symbols layers only or labeled single symbols,
// so that single symbol layers are still drawn on single line
if ( symbolList.size() > 1 || !label.isEmpty() )
{
label += QString( " [%1]" ).arg( vLayer->featureCount( symbol.second ) );
}
}
symbolItem->setText( label );
}

void QgsLegendModel::updateRasterSymbolItemText( QStandardItem* symbolItem )
{
QgsComposerRasterSymbolItem* rItem = dynamic_cast<QgsComposerRasterSymbolItem*>( symbolItem );
if ( !rItem ) return;

QgsComposerLayerItem* lItem = dynamic_cast<QgsComposerLayerItem*>( rItem->parent() );
if ( !lItem ) return;

QgsMapLayer* mapLayer = QgsMapLayerRegistry::instance()->mapLayer( lItem->layerID() );
if ( !mapLayer ) return;

QgsRasterLayer* rLayer = qobject_cast<QgsRasterLayer*>( mapLayer );
if ( !rLayer ) return;

QPair< QString, QColor> symbol = rLayer->legendSymbologyItems().value( symbolItem->row() );

QString label = rItem->userText().isEmpty() ? symbol.first : rItem->userText();

symbolItem->setText( label );
}

void QgsLegendModel::updateItem( QStandardItem* item )
{
if ( !item )
Expand All @@ -243,6 +326,45 @@ void QgsLegendModel::updateItem( QStandardItem* item )
}
}

void QgsLegendModel::updateItemText( QStandardItem* item )
{
if ( !item )
{
return;
}

//only layer items are supported for update
QgsComposerLegendItem* cItem = dynamic_cast<QgsComposerLegendItem*>( item );
if ( ! cItem )
{
return;
}

QgsComposerLayerItem* lItem = dynamic_cast<QgsComposerLayerItem*>( cItem );
if ( lItem )
{
updateLayerItemText( lItem );
return;
}

QgsComposerSymbolV2Item* sv2Item = dynamic_cast<QgsComposerSymbolV2Item*>( cItem );
if ( sv2Item )
{
updateSymbolV2ItemText( sv2Item );
return;
}

QgsComposerRasterSymbolItem* rItem = dynamic_cast<QgsComposerRasterSymbolItem*>( cItem );
if ( rItem )
{
updateRasterSymbolItemText( rItem );
return;
}

// group
cItem->setText( cItem->userText() );
}

void QgsLegendModel::updateLayer( QStandardItem* layerItem )
{
QgsDebugMsg( "Entered." );
Expand All @@ -252,22 +374,9 @@ void QgsLegendModel::updateLayer( QStandardItem* layerItem )
QgsMapLayer* mapLayer = QgsMapLayerRegistry::instance()->mapLayer( lItem->layerID() );
if ( mapLayer )
{
//delete all the entries under layer item
int currentRowCount = lItem->rowCount();
for ( int i = currentRowCount - 1; i >= 0; --i )
{
lItem->removeRow( i );
}

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

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

if ( vLayer )
{
Expand All @@ -283,6 +392,26 @@ void QgsLegendModel::updateLayer( QStandardItem* layerItem )
}
}

void QgsLegendModel::updateLayerItemText( QStandardItem* layerItem )
{
QgsComposerLayerItem* lItem = dynamic_cast<QgsComposerLayerItem*>( layerItem );
if ( !lItem ) return;

QgsMapLayer* mapLayer = QgsMapLayerRegistry::instance()->mapLayer( lItem->layerID() );
if ( !mapLayer ) return;

QgsVectorLayer* vLayer = qobject_cast<QgsVectorLayer*>( mapLayer );
if ( !vLayer ) return;

QString label = lItem->userText().isEmpty() ? mapLayer->name() : lItem->userText();

if ( vLayer && lItem->showFeatureCount() )
{
label += QString( " [%1]" ).arg( vLayer->featureCount() );
}
lItem->setText( label );
}

void QgsLegendModel::removeLayer( const QString& layerId )
{
int numRootItems = rowCount();
Expand Down

0 comments on commit 4c7f51e

Please sign in to comment.