Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Added symbology-ng capability to composer legend
git-svn-id: http://svn.osgeo.org/qgis/trunk@13118 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
mhugent committed Mar 20, 2010
1 parent acc710b commit 3eb3654
Show file tree
Hide file tree
Showing 4 changed files with 221 additions and 16 deletions.
42 changes: 42 additions & 0 deletions src/core/composer/qgscomposerlegend.cpp
Expand Up @@ -21,6 +21,7 @@
#include "qgsmaprenderer.h"
#include "qgsrenderer.h" //for brush scaling
#include "qgssymbol.h"
#include "qgssymbolv2.h"
#include <QDomDocument>
#include <QDomElement>
#include <QPainter>
Expand Down Expand Up @@ -218,13 +219,28 @@ void QgsComposerLegend::drawLayerChildItems( QPainter* p, QStandardItem* layerIt
symbol = ( QgsSymbol* )( symbolData );
}

//take QgsSymbolV2* from user data if there
QVariant symbolNgVariant = currentItem->data( Qt::UserRole + 2 );
QgsSymbolV2* symbolNg = 0;
if ( symbolNgVariant.canConvert<void*>() )
{
void* symbolNgData = symbolNgVariant.value<void*>();
symbolNg = ( QgsSymbolV2* )symbolNgData;
}

if ( symbol ) //item with symbol?
{
//draw symbol
drawSymbol( p, symbol, currentYCoord + ( itemHeight - mSymbolHeight ) / 2, currentXCoord, realSymbolHeight, layerOpacity );
realItemHeight = std::max( realSymbolHeight, itemHeight );
currentXCoord += mIconLabelSpace;
}
else if ( symbolNg ) //item with symbol NG?
{
drawSymbolV2( p, symbolNg, currentYCoord + ( itemHeight - mSymbolHeight ) / 2, currentXCoord, realSymbolHeight, layerOpacity );
realItemHeight = std::max( realSymbolHeight, itemHeight );
currentXCoord += mIconLabelSpace;
}
else //item with icon?
{
QIcon symbolIcon = currentItem->icon();
Expand Down Expand Up @@ -276,6 +292,32 @@ void QgsComposerLegend::drawSymbol( QPainter* p, QgsSymbol* s, double currentYCo
}
}

void QgsComposerLegend::drawSymbolV2( QPainter* p, QgsSymbolV2* s, double currentYCoord, double& currentXPosition, double& symbolHeight, int layerOpacity ) const
{
if ( !p || !s )
{
return;
}

double rasterScaleFactor = 1.0;
if ( p )
{
QPaintDevice* paintDevice = p->device();
if ( !paintDevice )
{
return;
}
rasterScaleFactor = ( paintDevice->logicalDpiX() + paintDevice->logicalDpiY() ) / 2.0 / 25.4;
}
p->save();
p->translate( currentXPosition, currentYCoord );
p->scale( 1.0 / rasterScaleFactor, 1.0 / rasterScaleFactor );
s->drawPreviewIcon( p, QSize( mSymbolWidth * rasterScaleFactor, mSymbolHeight * rasterScaleFactor ) );
p->restore();
currentXPosition += mSymbolWidth;
symbolHeight = mSymbolHeight;
}

void QgsComposerLegend::drawPointSymbol( QPainter* p, QgsSymbol* s, double currentYCoord, double& currentXPosition, double& symbolHeight, int opacity ) const
{
if ( !s )
Expand Down
2 changes: 2 additions & 0 deletions src/core/composer/qgscomposerlegend.h
Expand Up @@ -22,6 +22,7 @@
#include "qgslegendmodel.h"

class QgsSymbol;
class QgsSymbolV2;

/** \ingroup MapComposer
* A legend that can be placed onto a map composition
Expand Down Expand Up @@ -133,6 +134,7 @@ class CORE_EXPORT QgsComposerLegend: public QgsComposerItem
/**Draws a symbol at the current y position and returns the new x position. Returns real symbol height, because for points,
it is possible that it differs from mSymbolHeight*/
void drawSymbol( QPainter* p, QgsSymbol* s, double currentYCoord, double& currentXPosition, double& symbolHeight, int layerOpacity = 255 ) const;
void drawSymbolV2( QPainter* p, QgsSymbolV2* s, double currentYCoord, double& currentXPosition, double& symbolHeight, int layerOpacity = 255 ) const;
void drawPointSymbol( QPainter*, QgsSymbol* s, double currentYCoord, double& currentXPosition, double& symbolHeight, int opacity = 255 ) const;
void drawLineSymbol( QPainter*, QgsSymbol* s, double currentYCoord, double& currentXPosition, int opacity = 255 ) const;
void drawPolygonSymbol( QPainter* p, QgsSymbol* s, double currentYCoord, double& currentXPosition, int opacity = 255 ) const;
Expand Down
180 changes: 165 additions & 15 deletions src/core/composer/qgslegendmodel.cpp
Expand Up @@ -21,6 +21,8 @@
#include "qgsmaplayerregistry.h"
#include "qgsrasterlayer.h"
#include "qgsrenderer.h"
#include "qgsrendererv2.h"
#include "qgssymbollayerv2utils.h"
#include "qgssymbol.h"
#include "qgsvectordataprovider.h"
#include "qgsvectorlayer.h"
Expand All @@ -40,6 +42,7 @@ QgsLegendModel::QgsLegendModel(): QStandardItemModel()
QgsLegendModel::~QgsLegendModel()
{
removeAllSymbols();
removeAllSymbolsV2();
}

void QgsLegendModel::setLayerSet( const QStringList& layerIds )
Expand All @@ -48,6 +51,8 @@ void QgsLegendModel::setLayerSet( const QStringList& layerIds )

//for now clear the model and add the new entries
clear();
removeAllSymbols();
removeAllSymbolsV2();

QStringList::const_iterator idIter = mLayerIds.constBegin();
QgsMapLayer* currentLayer = 0;
Expand All @@ -67,8 +72,21 @@ void QgsLegendModel::setLayerSet( const QStringList& layerIds )
switch ( currentLayer->type() )
{
case QgsMapLayer::VectorLayer:
addVectorLayerItems( layerItem, currentLayer );
{
QgsVectorLayer* vl = dynamic_cast<QgsVectorLayer*>( currentLayer );
if ( vl )
{
if ( vl->isUsingRendererV2() )
{
addVectorLayerItemsV2( layerItem, vl );
}
else
{
addVectorLayerItems( layerItem, vl );
}
}
break;
}
case QgsMapLayer::RasterLayer:
addRasterLayerItem( layerItem, currentLayer );
break;
Expand All @@ -79,21 +97,47 @@ void QgsLegendModel::setLayerSet( const QStringList& layerIds )

}

int QgsLegendModel::addVectorLayerItems( QStandardItem* layerItem, QgsMapLayer* vlayer )
int QgsLegendModel::addVectorLayerItemsV2( QStandardItem* layerItem, QgsVectorLayer* vlayer )
{
if ( !layerItem || !vlayer )
{
return 1;
}

QgsVectorLayer* vectorLayer = qobject_cast<QgsVectorLayer *>( vlayer );
if ( !vectorLayer )
QgsFeatureRendererV2* renderer = vlayer->rendererV2();
if ( !renderer )
{
return 2;
}
int opacity = vectorLayer->getTransparency();

const QgsRenderer* vectorRenderer = vectorLayer->renderer();
QgsLegendSymbolList lst = renderer->legendSymbolItems();
QgsLegendSymbolList::const_iterator symbolIt = lst.constBegin();
for ( ; symbolIt != lst.constEnd(); ++symbolIt )
{
QStandardItem* currentSymbolItem = new QStandardItem( symbolIt->first );
if ( symbolIt->second )
{
currentSymbolItem->setIcon( QgsSymbolLayerV2Utils::symbolPreviewIcon( symbolIt->second, QSize( 30, 30 ) ) );
//reserve Qt::UserRole + 2 for symbology-ng
QgsSymbolV2* newSymbol = symbolIt->second->clone();
insertSymbolV2( newSymbol );
currentSymbolItem->setData( QVariant::fromValue(( void* )( newSymbol ) ), Qt::UserRole + 2 );
}
currentSymbolItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );
layerItem->setChild( layerItem->rowCount(), 0, currentSymbolItem );
}
}

int QgsLegendModel::addVectorLayerItems( QStandardItem* layerItem, QgsVectorLayer* vlayer )
{
if ( !layerItem || !vlayer )
{
return 1;
}

int opacity = vlayer->getTransparency();

const QgsRenderer* vectorRenderer = vlayer->renderer();
if ( !vectorRenderer )
{
return 3;
Expand All @@ -103,15 +147,15 @@ int QgsLegendModel::addVectorLayerItems( QStandardItem* layerItem, QgsMapLayer*
QSettings settings;
if ( settings.value( "/qgis/showLegendClassifiers", false ).toBool() )
{
QgsFieldMap layerFields = vectorLayer->pendingFields();
QgsFieldMap layerFields = vlayer->pendingFields();
QgsAttributeList attributes = vectorRenderer->classificationAttributes();
QgsAttributeList::const_iterator att_it = attributes.constBegin();
for ( ; att_it != attributes.constEnd(); ++att_it )
{
QgsFieldMap::const_iterator fieldIt = layerFields.find( *att_it );
if ( fieldIt != layerFields.constEnd() )
{
QString attributeName = vectorLayer->attributeDisplayName( fieldIt.key() );
QString attributeName = vlayer->attributeDisplayName( fieldIt.key() );
QStandardItem* attributeItem = new QStandardItem( attributeName );
layerItem->setChild( layerItem->rowCount(), 0, attributeItem );
}
Expand Down Expand Up @@ -172,11 +216,26 @@ void QgsLegendModel::insertSymbol( QgsSymbol* s )
mSymbols.insert( s );
}

void QgsLegendModel::insertSymbolV2( QgsSymbolV2* s )
{
QSet<QgsSymbolV2*>::iterator it = mSymbolsV2.find( s );
if ( it != mSymbolsV2.end() )
{
delete( *it ); //very unlikely
}
mSymbolsV2.insert( s );
}

void QgsLegendModel::removeSymbol( QgsSymbol* s )
{
mSymbols.remove( s );
}

void QgsLegendModel::removeSymbolV2( QgsSymbolV2* s )
{
mSymbolsV2.remove( s );
}

void QgsLegendModel::removeAllSymbols()
{
QSet<QgsSymbol*>::iterator it = mSymbols.begin();
Expand All @@ -187,6 +246,16 @@ void QgsLegendModel::removeAllSymbols()
mSymbols.clear();
}

void QgsLegendModel::removeAllSymbolsV2()
{
QSet<QgsSymbolV2*>::iterator it = mSymbolsV2.begin();
for ( ; it != mSymbolsV2.end(); ++it )
{
delete *it;
}
mSymbolsV2.clear();
}

void QgsLegendModel::updateItem( QStandardItem* item )
{
if ( !item )
Expand All @@ -211,10 +280,22 @@ void QgsLegendModel::updateItem( QStandardItem* item )
symbol = ( QgsSymbol* )( symbolData );
}

QVariant symbolNgVariant = item->data( Qt::UserRole + 2 );
QgsSymbolV2* symbolNg = 0;
if ( symbolNgVariant.canConvert<void*>() )
{
void* symbolNgData = symbolVariant.value<void*>();
symbolNg = ( QgsSymbolV2* )symbolNgData;
}

if ( symbol ) //vector classification item
{
updateVectorClassificationItem( item, symbol, item->text() );
}
else if ( symbolNg )
{
updateVectorV2ClassificationItem( item, symbolNg, item->text() );
}
else if ( !item->icon().isNull() ) //raster classification item
{
updateRasterClassificationItem( item );
Expand Down Expand Up @@ -243,8 +324,21 @@ void QgsLegendModel::updateLayer( QStandardItem* layerItem )
switch ( mapLayer->type() )
{
case QgsMapLayer::VectorLayer:
addVectorLayerItems( layerItem, mapLayer );
break;
{
QgsVectorLayer* vLayer = dynamic_cast<QgsVectorLayer*>( mapLayer );
if ( vLayer )
{
if ( vLayer->isUsingRendererV2() )
{
addVectorLayerItemsV2( layerItem, vLayer );
}
else
{
addVectorLayerItems( layerItem, vLayer );
}
}
}
break;
case QgsMapLayer::RasterLayer:
addRasterLayerItem( layerItem, mapLayer );
break;
Expand Down Expand Up @@ -334,6 +428,11 @@ void QgsLegendModel::updateVectorClassificationItem( QStandardItem* classificati
}
}

void QgsLegendModel::updateVectorV2ClassificationItem( QStandardItem* classificationItem, QgsSymbolV2* symbol, QString itemText )
{
//todo...
}


void QgsLegendModel::updateRasterClassificationItem( QStandardItem* classificationItem )
{
Expand Down Expand Up @@ -406,8 +505,21 @@ void QgsLegendModel::addLayer( QgsMapLayer* theMapLayer )
switch ( theMapLayer->type() )
{
case QgsMapLayer::VectorLayer:
addVectorLayerItems( layerItem, theMapLayer );
{
QgsVectorLayer* vl = dynamic_cast<QgsVectorLayer*>( theMapLayer );
if ( vl )
{
if ( vl->isUsingRendererV2() )
{
addVectorLayerItemsV2( layerItem, vl );
}
else
{
addVectorLayerItems( layerItem, vl );
}
}
break;
}
case QgsMapLayer::RasterLayer:
addRasterLayerItem( layerItem, theMapLayer );
break;
Expand Down Expand Up @@ -522,17 +634,38 @@ bool QgsLegendModel::writeXML( QDomElement& composerLegendElem, QDomDocument& do

//store text and QgsSymbol for vector classification items
QVariant symbolVariant = currentClassificationItem->data();
QVariant symbolNgVariant = currentClassificationItem->data( Qt::UserRole + 2 );
QgsSymbol* symbol = 0;
QgsSymbolV2* symbolNg = 0;

if ( symbolVariant.canConvert<void*>() )
{
void* symbolData = symbolVariant.value<void*>();
symbol = ( QgsSymbol* )( symbolData );
symbol = ( QgsSymbol* )symbolData;
}
if ( symbol )
else if ( symbolNgVariant.canConvert<void*>() )
{
QDomElement vectorClassElem = doc.createElement( "VectorClassificationItem" );
void* symbolNgData = symbolNgVariant.value<void*>();
symbolNg = ( QgsSymbolV2* )symbolNgData;
}

if ( symbol || symbolNg )
{
QDomElement vectorClassElem;
if ( symbol )
{
vectorClassElem = doc.createElement( "VectorClassificationItem" );
symbol->writeXML( vectorClassElem, doc, 0 );
}
else if ( symbolNg )
{
vectorClassElem = doc.createElement( "VectorClassificationItemNg" );
QgsSymbolV2Map saveSymbolMap;
saveSymbolMap.insert( "classificationSymbol", symbolNg );
QDomElement symbolsElem = QgsSymbolLayerV2Utils::saveSymbols( saveSymbolMap, "symbols", doc );
vectorClassElem.appendChild( symbolsElem );
}
vectorClassElem.setAttribute( "text", currentClassificationItem->text() );
symbol->writeXML( vectorClassElem, doc, 0 );
newLayerItem.appendChild( vectorClassElem );
continue;
}
Expand Down Expand Up @@ -639,6 +772,23 @@ bool QgsLegendModel::readXML( const QDomElement& legendModelElem, const QDomDocu
}
layerItem->setChild( layerItem->rowCount(), 0, childItem );
}
else if ( currentChildElement.tagName() == "VectorClassificationItemNg" )
{
QDomElement symbolNgElem = currentChildElement.firstChildElement( "symbols" );
if ( !symbolNgElem.isNull() )
{
QgsSymbolV2Map loadSymbolMap = QgsSymbolLayerV2Utils::loadSymbols( symbolNgElem );
//we assume there is only one symbol in the map...
QgsSymbolV2Map::iterator mapIt = loadSymbolMap.begin();
if ( mapIt != loadSymbolMap.end() )
{
QgsSymbolV2* symbolNg = mapIt.value();
childItem->setData( QVariant::fromValue(( void* )symbolNg ), Qt::UserRole + 2 );
childItem->setIcon( QgsSymbolLayerV2Utils::symbolPreviewIcon( symbolNg, QSize( 30, 30 ) ) );
}
layerItem->setChild( layerItem->rowCount(), 0, childItem );
}
}
else if ( currentChildElement.tagName() == "TextItem" )
{
layerItem->setChild( layerItem->rowCount(), 0, childItem );
Expand Down

0 comments on commit 3eb3654

Please sign in to comment.