Skip to content

Commit 2fbfc7f

Browse files
author
mhugent
committed
Added symbology-ng capability to composer legend
git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@13118 c8812cc2-4d05-0410-92ff-de0c093fc19c
1 parent a4c41de commit 2fbfc7f

File tree

4 files changed

+221
-16
lines changed

4 files changed

+221
-16
lines changed

src/core/composer/qgscomposerlegend.cpp

+42
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "qgsmaprenderer.h"
2222
#include "qgsrenderer.h" //for brush scaling
2323
#include "qgssymbol.h"
24+
#include "qgssymbolv2.h"
2425
#include <QDomDocument>
2526
#include <QDomElement>
2627
#include <QPainter>
@@ -218,13 +219,28 @@ void QgsComposerLegend::drawLayerChildItems( QPainter* p, QStandardItem* layerIt
218219
symbol = ( QgsSymbol* )( symbolData );
219220
}
220221

222+
//take QgsSymbolV2* from user data if there
223+
QVariant symbolNgVariant = currentItem->data( Qt::UserRole + 2 );
224+
QgsSymbolV2* symbolNg = 0;
225+
if ( symbolNgVariant.canConvert<void*>() )
226+
{
227+
void* symbolNgData = symbolNgVariant.value<void*>();
228+
symbolNg = ( QgsSymbolV2* )symbolNgData;
229+
}
230+
221231
if ( symbol ) //item with symbol?
222232
{
223233
//draw symbol
224234
drawSymbol( p, symbol, currentYCoord + ( itemHeight - mSymbolHeight ) / 2, currentXCoord, realSymbolHeight, layerOpacity );
225235
realItemHeight = std::max( realSymbolHeight, itemHeight );
226236
currentXCoord += mIconLabelSpace;
227237
}
238+
else if ( symbolNg ) //item with symbol NG?
239+
{
240+
drawSymbolV2( p, symbolNg, currentYCoord + ( itemHeight - mSymbolHeight ) / 2, currentXCoord, realSymbolHeight, layerOpacity );
241+
realItemHeight = std::max( realSymbolHeight, itemHeight );
242+
currentXCoord += mIconLabelSpace;
243+
}
228244
else //item with icon?
229245
{
230246
QIcon symbolIcon = currentItem->icon();
@@ -276,6 +292,32 @@ void QgsComposerLegend::drawSymbol( QPainter* p, QgsSymbol* s, double currentYCo
276292
}
277293
}
278294

295+
void QgsComposerLegend::drawSymbolV2( QPainter* p, QgsSymbolV2* s, double currentYCoord, double& currentXPosition, double& symbolHeight, int layerOpacity ) const
296+
{
297+
if ( !p || !s )
298+
{
299+
return;
300+
}
301+
302+
double rasterScaleFactor = 1.0;
303+
if ( p )
304+
{
305+
QPaintDevice* paintDevice = p->device();
306+
if ( !paintDevice )
307+
{
308+
return;
309+
}
310+
rasterScaleFactor = ( paintDevice->logicalDpiX() + paintDevice->logicalDpiY() ) / 2.0 / 25.4;
311+
}
312+
p->save();
313+
p->translate( currentXPosition, currentYCoord );
314+
p->scale( 1.0 / rasterScaleFactor, 1.0 / rasterScaleFactor );
315+
s->drawPreviewIcon( p, QSize( mSymbolWidth * rasterScaleFactor, mSymbolHeight * rasterScaleFactor ) );
316+
p->restore();
317+
currentXPosition += mSymbolWidth;
318+
symbolHeight = mSymbolHeight;
319+
}
320+
279321
void QgsComposerLegend::drawPointSymbol( QPainter* p, QgsSymbol* s, double currentYCoord, double& currentXPosition, double& symbolHeight, int opacity ) const
280322
{
281323
if ( !s )

src/core/composer/qgscomposerlegend.h

+2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "qgslegendmodel.h"
2323

2424
class QgsSymbol;
25+
class QgsSymbolV2;
2526

2627
/** \ingroup MapComposer
2728
* A legend that can be placed onto a map composition
@@ -133,6 +134,7 @@ class CORE_EXPORT QgsComposerLegend: public QgsComposerItem
133134
/**Draws a symbol at the current y position and returns the new x position. Returns real symbol height, because for points,
134135
it is possible that it differs from mSymbolHeight*/
135136
void drawSymbol( QPainter* p, QgsSymbol* s, double currentYCoord, double& currentXPosition, double& symbolHeight, int layerOpacity = 255 ) const;
137+
void drawSymbolV2( QPainter* p, QgsSymbolV2* s, double currentYCoord, double& currentXPosition, double& symbolHeight, int layerOpacity = 255 ) const;
136138
void drawPointSymbol( QPainter*, QgsSymbol* s, double currentYCoord, double& currentXPosition, double& symbolHeight, int opacity = 255 ) const;
137139
void drawLineSymbol( QPainter*, QgsSymbol* s, double currentYCoord, double& currentXPosition, int opacity = 255 ) const;
138140
void drawPolygonSymbol( QPainter* p, QgsSymbol* s, double currentYCoord, double& currentXPosition, int opacity = 255 ) const;

src/core/composer/qgslegendmodel.cpp

+165-15
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
#include "qgsmaplayerregistry.h"
2222
#include "qgsrasterlayer.h"
2323
#include "qgsrenderer.h"
24+
#include "qgsrendererv2.h"
25+
#include "qgssymbollayerv2utils.h"
2426
#include "qgssymbol.h"
2527
#include "qgsvectordataprovider.h"
2628
#include "qgsvectorlayer.h"
@@ -40,6 +42,7 @@ QgsLegendModel::QgsLegendModel(): QStandardItemModel()
4042
QgsLegendModel::~QgsLegendModel()
4143
{
4244
removeAllSymbols();
45+
removeAllSymbolsV2();
4346
}
4447

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

4952
//for now clear the model and add the new entries
5053
clear();
54+
removeAllSymbols();
55+
removeAllSymbolsV2();
5156

5257
QStringList::const_iterator idIter = mLayerIds.constBegin();
5358
QgsMapLayer* currentLayer = 0;
@@ -67,8 +72,21 @@ void QgsLegendModel::setLayerSet( const QStringList& layerIds )
6772
switch ( currentLayer->type() )
6873
{
6974
case QgsMapLayer::VectorLayer:
70-
addVectorLayerItems( layerItem, currentLayer );
75+
{
76+
QgsVectorLayer* vl = dynamic_cast<QgsVectorLayer*>( currentLayer );
77+
if ( vl )
78+
{
79+
if ( vl->isUsingRendererV2() )
80+
{
81+
addVectorLayerItemsV2( layerItem, vl );
82+
}
83+
else
84+
{
85+
addVectorLayerItems( layerItem, vl );
86+
}
87+
}
7188
break;
89+
}
7290
case QgsMapLayer::RasterLayer:
7391
addRasterLayerItem( layerItem, currentLayer );
7492
break;
@@ -79,21 +97,47 @@ void QgsLegendModel::setLayerSet( const QStringList& layerIds )
7997

8098
}
8199

82-
int QgsLegendModel::addVectorLayerItems( QStandardItem* layerItem, QgsMapLayer* vlayer )
100+
int QgsLegendModel::addVectorLayerItemsV2( QStandardItem* layerItem, QgsVectorLayer* vlayer )
83101
{
84102
if ( !layerItem || !vlayer )
85103
{
86104
return 1;
87105
}
88106

89-
QgsVectorLayer* vectorLayer = qobject_cast<QgsVectorLayer *>( vlayer );
90-
if ( !vectorLayer )
107+
QgsFeatureRendererV2* renderer = vlayer->rendererV2();
108+
if ( !renderer )
91109
{
92110
return 2;
93111
}
94-
int opacity = vectorLayer->getTransparency();
95112

96-
const QgsRenderer* vectorRenderer = vectorLayer->renderer();
113+
QgsLegendSymbolList lst = renderer->legendSymbolItems();
114+
QgsLegendSymbolList::const_iterator symbolIt = lst.constBegin();
115+
for ( ; symbolIt != lst.constEnd(); ++symbolIt )
116+
{
117+
QStandardItem* currentSymbolItem = new QStandardItem( symbolIt->first );
118+
if ( symbolIt->second )
119+
{
120+
currentSymbolItem->setIcon( QgsSymbolLayerV2Utils::symbolPreviewIcon( symbolIt->second, QSize( 30, 30 ) ) );
121+
//reserve Qt::UserRole + 2 for symbology-ng
122+
QgsSymbolV2* newSymbol = symbolIt->second->clone();
123+
insertSymbolV2( newSymbol );
124+
currentSymbolItem->setData( QVariant::fromValue(( void* )( newSymbol ) ), Qt::UserRole + 2 );
125+
}
126+
currentSymbolItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );
127+
layerItem->setChild( layerItem->rowCount(), 0, currentSymbolItem );
128+
}
129+
}
130+
131+
int QgsLegendModel::addVectorLayerItems( QStandardItem* layerItem, QgsVectorLayer* vlayer )
132+
{
133+
if ( !layerItem || !vlayer )
134+
{
135+
return 1;
136+
}
137+
138+
int opacity = vlayer->getTransparency();
139+
140+
const QgsRenderer* vectorRenderer = vlayer->renderer();
97141
if ( !vectorRenderer )
98142
{
99143
return 3;
@@ -103,15 +147,15 @@ int QgsLegendModel::addVectorLayerItems( QStandardItem* layerItem, QgsMapLayer*
103147
QSettings settings;
104148
if ( settings.value( "/qgis/showLegendClassifiers", false ).toBool() )
105149
{
106-
QgsFieldMap layerFields = vectorLayer->pendingFields();
150+
QgsFieldMap layerFields = vlayer->pendingFields();
107151
QgsAttributeList attributes = vectorRenderer->classificationAttributes();
108152
QgsAttributeList::const_iterator att_it = attributes.constBegin();
109153
for ( ; att_it != attributes.constEnd(); ++att_it )
110154
{
111155
QgsFieldMap::const_iterator fieldIt = layerFields.find( *att_it );
112156
if ( fieldIt != layerFields.constEnd() )
113157
{
114-
QString attributeName = vectorLayer->attributeDisplayName( fieldIt.key() );
158+
QString attributeName = vlayer->attributeDisplayName( fieldIt.key() );
115159
QStandardItem* attributeItem = new QStandardItem( attributeName );
116160
layerItem->setChild( layerItem->rowCount(), 0, attributeItem );
117161
}
@@ -172,11 +216,26 @@ void QgsLegendModel::insertSymbol( QgsSymbol* s )
172216
mSymbols.insert( s );
173217
}
174218

219+
void QgsLegendModel::insertSymbolV2( QgsSymbolV2* s )
220+
{
221+
QSet<QgsSymbolV2*>::iterator it = mSymbolsV2.find( s );
222+
if ( it != mSymbolsV2.end() )
223+
{
224+
delete( *it ); //very unlikely
225+
}
226+
mSymbolsV2.insert( s );
227+
}
228+
175229
void QgsLegendModel::removeSymbol( QgsSymbol* s )
176230
{
177231
mSymbols.remove( s );
178232
}
179233

234+
void QgsLegendModel::removeSymbolV2( QgsSymbolV2* s )
235+
{
236+
mSymbolsV2.remove( s );
237+
}
238+
180239
void QgsLegendModel::removeAllSymbols()
181240
{
182241
QSet<QgsSymbol*>::iterator it = mSymbols.begin();
@@ -187,6 +246,16 @@ void QgsLegendModel::removeAllSymbols()
187246
mSymbols.clear();
188247
}
189248

249+
void QgsLegendModel::removeAllSymbolsV2()
250+
{
251+
QSet<QgsSymbolV2*>::iterator it = mSymbolsV2.begin();
252+
for ( ; it != mSymbolsV2.end(); ++it )
253+
{
254+
delete *it;
255+
}
256+
mSymbolsV2.clear();
257+
}
258+
190259
void QgsLegendModel::updateItem( QStandardItem* item )
191260
{
192261
if ( !item )
@@ -211,10 +280,22 @@ void QgsLegendModel::updateItem( QStandardItem* item )
211280
symbol = ( QgsSymbol* )( symbolData );
212281
}
213282

283+
QVariant symbolNgVariant = item->data( Qt::UserRole + 2 );
284+
QgsSymbolV2* symbolNg = 0;
285+
if ( symbolNgVariant.canConvert<void*>() )
286+
{
287+
void* symbolNgData = symbolVariant.value<void*>();
288+
symbolNg = ( QgsSymbolV2* )symbolNgData;
289+
}
290+
214291
if ( symbol ) //vector classification item
215292
{
216293
updateVectorClassificationItem( item, symbol, item->text() );
217294
}
295+
else if ( symbolNg )
296+
{
297+
updateVectorV2ClassificationItem( item, symbolNg, item->text() );
298+
}
218299
else if ( !item->icon().isNull() ) //raster classification item
219300
{
220301
updateRasterClassificationItem( item );
@@ -243,8 +324,21 @@ void QgsLegendModel::updateLayer( QStandardItem* layerItem )
243324
switch ( mapLayer->type() )
244325
{
245326
case QgsMapLayer::VectorLayer:
246-
addVectorLayerItems( layerItem, mapLayer );
247-
break;
327+
{
328+
QgsVectorLayer* vLayer = dynamic_cast<QgsVectorLayer*>( mapLayer );
329+
if ( vLayer )
330+
{
331+
if ( vLayer->isUsingRendererV2() )
332+
{
333+
addVectorLayerItemsV2( layerItem, vLayer );
334+
}
335+
else
336+
{
337+
addVectorLayerItems( layerItem, vLayer );
338+
}
339+
}
340+
}
341+
break;
248342
case QgsMapLayer::RasterLayer:
249343
addRasterLayerItem( layerItem, mapLayer );
250344
break;
@@ -334,6 +428,11 @@ void QgsLegendModel::updateVectorClassificationItem( QStandardItem* classificati
334428
}
335429
}
336430

431+
void QgsLegendModel::updateVectorV2ClassificationItem( QStandardItem* classificationItem, QgsSymbolV2* symbol, QString itemText )
432+
{
433+
//todo...
434+
}
435+
337436

338437
void QgsLegendModel::updateRasterClassificationItem( QStandardItem* classificationItem )
339438
{
@@ -406,8 +505,21 @@ void QgsLegendModel::addLayer( QgsMapLayer* theMapLayer )
406505
switch ( theMapLayer->type() )
407506
{
408507
case QgsMapLayer::VectorLayer:
409-
addVectorLayerItems( layerItem, theMapLayer );
508+
{
509+
QgsVectorLayer* vl = dynamic_cast<QgsVectorLayer*>( theMapLayer );
510+
if ( vl )
511+
{
512+
if ( vl->isUsingRendererV2() )
513+
{
514+
addVectorLayerItemsV2( layerItem, vl );
515+
}
516+
else
517+
{
518+
addVectorLayerItems( layerItem, vl );
519+
}
520+
}
410521
break;
522+
}
411523
case QgsMapLayer::RasterLayer:
412524
addRasterLayerItem( layerItem, theMapLayer );
413525
break;
@@ -522,17 +634,38 @@ bool QgsLegendModel::writeXML( QDomElement& composerLegendElem, QDomDocument& do
522634

523635
//store text and QgsSymbol for vector classification items
524636
QVariant symbolVariant = currentClassificationItem->data();
637+
QVariant symbolNgVariant = currentClassificationItem->data( Qt::UserRole + 2 );
525638
QgsSymbol* symbol = 0;
639+
QgsSymbolV2* symbolNg = 0;
640+
526641
if ( symbolVariant.canConvert<void*>() )
527642
{
528643
void* symbolData = symbolVariant.value<void*>();
529-
symbol = ( QgsSymbol* )( symbolData );
644+
symbol = ( QgsSymbol* )symbolData;
530645
}
531-
if ( symbol )
646+
else if ( symbolNgVariant.canConvert<void*>() )
532647
{
533-
QDomElement vectorClassElem = doc.createElement( "VectorClassificationItem" );
648+
void* symbolNgData = symbolNgVariant.value<void*>();
649+
symbolNg = ( QgsSymbolV2* )symbolNgData;
650+
}
651+
652+
if ( symbol || symbolNg )
653+
{
654+
QDomElement vectorClassElem;
655+
if ( symbol )
656+
{
657+
vectorClassElem = doc.createElement( "VectorClassificationItem" );
658+
symbol->writeXML( vectorClassElem, doc, 0 );
659+
}
660+
else if ( symbolNg )
661+
{
662+
vectorClassElem = doc.createElement( "VectorClassificationItemNg" );
663+
QgsSymbolV2Map saveSymbolMap;
664+
saveSymbolMap.insert( "classificationSymbol", symbolNg );
665+
QDomElement symbolsElem = QgsSymbolLayerV2Utils::saveSymbols( saveSymbolMap, "symbols", doc );
666+
vectorClassElem.appendChild( symbolsElem );
667+
}
534668
vectorClassElem.setAttribute( "text", currentClassificationItem->text() );
535-
symbol->writeXML( vectorClassElem, doc, 0 );
536669
newLayerItem.appendChild( vectorClassElem );
537670
continue;
538671
}
@@ -639,6 +772,23 @@ bool QgsLegendModel::readXML( const QDomElement& legendModelElem, const QDomDocu
639772
}
640773
layerItem->setChild( layerItem->rowCount(), 0, childItem );
641774
}
775+
else if ( currentChildElement.tagName() == "VectorClassificationItemNg" )
776+
{
777+
QDomElement symbolNgElem = currentChildElement.firstChildElement( "symbols" );
778+
if ( !symbolNgElem.isNull() )
779+
{
780+
QgsSymbolV2Map loadSymbolMap = QgsSymbolLayerV2Utils::loadSymbols( symbolNgElem );
781+
//we assume there is only one symbol in the map...
782+
QgsSymbolV2Map::iterator mapIt = loadSymbolMap.begin();
783+
if ( mapIt != loadSymbolMap.end() )
784+
{
785+
QgsSymbolV2* symbolNg = mapIt.value();
786+
childItem->setData( QVariant::fromValue(( void* )symbolNg ), Qt::UserRole + 2 );
787+
childItem->setIcon( QgsSymbolLayerV2Utils::symbolPreviewIcon( symbolNg, QSize( 30, 30 ) ) );
788+
}
789+
layerItem->setChild( layerItem->rowCount(), 0, childItem );
790+
}
791+
}
642792
else if ( currentChildElement.tagName() == "TextItem" )
643793
{
644794
layerItem->setChild( layerItem->rowCount(), 0, childItem );

0 commit comments

Comments
 (0)