From 2bd06b45d90e2be2dd4836ef5df86c0c560f2feb Mon Sep 17 00:00:00 2001 From: wonder Date: Fri, 6 Nov 2009 13:04:20 +0000 Subject: [PATCH] generic solution for legend symbology items git-svn-id: http://svn.osgeo.org/qgis/branches/symbology-ng-branch@11934 c8812cc2-4d05-0410-92ff-de0c093fc19c --- python/core/symbology-ng-core.sip | 51 +++++++++++++++ src/app/legend/qgslegendlayer.cpp | 65 ++----------------- src/app/legend/qgslegendlayer.h | 2 +- .../qgscategorizedsymbolrendererv2.cpp | 23 +++++++ .../qgscategorizedsymbolrendererv2.h | 3 + .../qgsgraduatedsymbolrendererv2.cpp | 22 +++++++ .../qgsgraduatedsymbolrendererv2.h | 3 + src/core/symbology-ng/qgsrendererv2.cpp | 7 ++ src/core/symbology-ng/qgsrendererv2.h | 7 ++ .../qgssinglesymbolrendererv2.cpp | 9 +++ .../symbology-ng/qgssinglesymbolrendererv2.h | 3 + .../symbology-ng/qgssymbollayerv2utils.cpp | 8 ++- src/core/symbology-ng/qgssymbollayerv2utils.h | 1 + 13 files changed, 141 insertions(+), 63 deletions(-) diff --git a/python/core/symbology-ng-core.sip b/python/core/symbology-ng-core.sip index 7be5ebef268a..7a041a2068e5 100644 --- a/python/core/symbology-ng-core.sip +++ b/python/core/symbology-ng-core.sip @@ -1,6 +1,8 @@ typedef QList QgsSymbolV2List; +typedef QList< QPair > QgsLegendSymbologyList; + /////////////// /* @@ -60,6 +62,15 @@ public: bool usingSymbolLevels() const; void setUsingSymbolLevels(bool usingSymbolLevels); + //! create a renderer from XML element + static QgsFeatureRendererV2* load(QDomElement& symbologyElem); + + //! store renderer info to XML element + virtual QDomElement save(QDomDocument& doc); + + //! return a list of symbology items for the legend + virtual QgsLegendSymbologyList legendSymbologyItems(QSize iconSize); + protected: QgsFeatureRendererV2(QString type); @@ -93,6 +104,16 @@ public: virtual QString dump(); virtual QgsFeatureRendererV2* clone() /Factory/; + + //! create a renderer from XML element + static QgsFeatureRendererV2* load(QDomElement& symbologyElem) /Factory/; + + //! store renderer info to XML element + virtual QDomElement save(QDomDocument& doc); + + //! return a list of symbology items for the legend + virtual QgsLegendSymbologyList legendSymbologyItems(QSize iconSize); + }; ////////// @@ -159,9 +180,24 @@ public: bool deleteCategory(int catIndex); void deleteAllCategories(); + //! create a renderer from XML element + static QgsFeatureRendererV2* load(QDomElement& symbologyElem) /Factory/; + + //! store renderer info to XML element + virtual QDomElement save(QDomDocument& doc); + + //! return a list of symbology items for the legend + virtual QgsLegendSymbologyList legendSymbologyItems(QSize iconSize); + QString classAttribute() const; void setClassAttribute(QString attr); + QgsSymbolV2* sourceSymbol(); + void setSourceSymbol(QgsSymbolV2* sym /Transfer/); + + QgsVectorColorRampV2* sourceColorRamp(); + void setSourceColorRamp(QgsVectorColorRampV2* ramp /Transfer/); + protected: QgsSymbolV2* symbolForValue(QVariant value); @@ -244,6 +280,21 @@ public: QgsSymbolV2* symbol, QgsVectorColorRampV2* ramp); + //! create a renderer from XML element + static QgsFeatureRendererV2* load(QDomElement& symbologyElem) /Factory/; + + //! store renderer info to XML element + virtual QDomElement save(QDomDocument& doc); + + //! return a list of symbology items for the legend + virtual QgsLegendSymbologyList legendSymbologyItems(QSize iconSize); + + QgsSymbolV2* sourceSymbol(); + void setSourceSymbol(QgsSymbolV2* sym /Transfer/); + + QgsVectorColorRampV2* sourceColorRamp(); + void setSourceColorRamp(QgsVectorColorRampV2* ramp /Transfer/); + protected: QgsSymbolV2* symbolForValue(double value); }; diff --git a/src/app/legend/qgslegendlayer.cpp b/src/app/legend/qgslegendlayer.cpp index dd8db068602d..0baa74870f26 100644 --- a/src/app/legend/qgslegendlayer.cpp +++ b/src/app/legend/qgslegendlayer.cpp @@ -369,7 +369,7 @@ void QgsLegendLayer::vectorLayerSymbology( const QgsVectorLayer* layer, double w } QPixmap pix = QPixmap::fromImage( img ); // convert to pixmap - itemList.push_back( std::make_pair( values, pix ) ); + itemList.append( qMakePair( values, pix ) ); } @@ -388,7 +388,7 @@ void QgsLegendLayer::vectorLayerSymbology( const QgsVectorLayer* layer, double w { classfieldname = fields[*it].name(); } - itemList.push_front( std::make_pair( classfieldname, QPixmap() ) ); + itemList.append( qMakePair( classfieldname, QPixmap() ) ); } } } @@ -396,72 +396,15 @@ void QgsLegendLayer::vectorLayerSymbology( const QgsVectorLayer* layer, double w changeSymbologySettings( layer, itemList ); } -static QPixmap _symbolPreviewPixmap(QgsSymbolV2* sym, QSize iconSize) -{ - QPainter p; - QPixmap pix(iconSize); - pix.fill(Qt::white); - p.begin(&pix); - p.setRenderHint(QPainter::Antialiasing); - sym->drawPreviewIcon(&p, iconSize); - p.end(); - return pix; -} void QgsLegendLayer::vectorLayerSymbologyV2( QgsVectorLayer* layer ) { - SymbologyList itemList; - QSize iconSize(16,16); QSettings settings; bool showClassifiers = settings.value( "/qgis/showLegendClassifiers", false ).toBool(); - QgsFeatureRendererV2* renderer = layer->rendererV2(); - QString rendererType = renderer->type(); - if (rendererType == "singleSymbol") - { - QgsSingleSymbolRendererV2* r = static_cast(renderer); - QPixmap pix = _symbolPreviewPixmap(r->symbol(), iconSize); - - itemList.push_back( std::make_pair( "", pix ) ); - } - else if (rendererType == "categorizedSymbol") - { - QgsCategorizedSymbolRendererV2* r = static_cast(renderer); - if (showClassifiers) - { - itemList.push_back( std::make_pair( r->classAttribute(), QPixmap() ) ); - } - - int count = r->categories().count(); - for (int i = 0; i < count; i++) - { - const QgsRendererCategoryV2& cat = r->categories()[i]; - QPixmap pix = _symbolPreviewPixmap( cat.symbol(), iconSize ); - itemList.push_back( std::make_pair( cat.label(), pix ) ); - } - } - else if (rendererType == "graduatedSymbol") - { - QgsGraduatedSymbolRendererV2* r = static_cast(renderer); - if (showClassifiers) - { - itemList.push_back( std::make_pair( r->classAttribute(), QPixmap() ) ); - } - - int count = r->ranges().count(); - for (int i = 0; i < count; i++) - { - const QgsRendererRangeV2& range = r->ranges()[i]; - QPixmap pix = _symbolPreviewPixmap( range.symbol(), iconSize ); - itemList.push_back( std::make_pair( range.label(), pix ) ); - } - } - else - { - // nothing for unknown renderers - } + SymbologyList itemList = layer->rendererV2()->legendSymbologyItems(iconSize); changeSymbologySettings( layer, itemList ); } @@ -470,7 +413,7 @@ void QgsLegendLayer::rasterLayerSymbology( QgsRasterLayer* layer ) { SymbologyList itemList; QPixmap legendpixmap = layer->legendAsPixmap( true ).scaled( 20, 20, Qt::KeepAspectRatio ); - itemList.push_back( std::make_pair( "", legendpixmap ) ); + itemList.append( qMakePair( QString(), legendpixmap ) ); changeSymbologySettings( layer, itemList ); diff --git a/src/app/legend/qgslegendlayer.h b/src/app/legend/qgslegendlayer.h index bca46ce308ce..ba7f87a03caf 100644 --- a/src/app/legend/qgslegendlayer.h +++ b/src/app/legend/qgslegendlayer.h @@ -33,7 +33,7 @@ class QgsVectorLayer; class QTreeWidget; -typedef std::list< std::pair > SymbologyList; +typedef QList< QPair > SymbologyList; /** Container for layer, including layer file(s), symbology class breaks and properties diff --git a/src/core/symbology-ng/qgscategorizedsymbolrendererv2.cpp b/src/core/symbology-ng/qgscategorizedsymbolrendererv2.cpp index 034ebd5aad4e..00e69f7ce1f6 100644 --- a/src/core/symbology-ng/qgscategorizedsymbolrendererv2.cpp +++ b/src/core/symbology-ng/qgscategorizedsymbolrendererv2.cpp @@ -10,6 +10,7 @@ #include #include +#include // for legend QgsRendererCategoryV2::QgsRendererCategoryV2(QVariant value, QgsSymbolV2* symbol, QString label) : mValue(value), mSymbol(symbol), mLabel(label) @@ -335,6 +336,28 @@ QDomElement QgsCategorizedSymbolRendererV2::save(QDomDocument& doc) return rendererElem; } +QgsLegendSymbologyList QgsCategorizedSymbolRendererV2::legendSymbologyItems(QSize iconSize) +{ + QSettings settings; + bool showClassifiers = settings.value( "/qgis/showLegendClassifiers", false ).toBool(); + + QgsLegendSymbologyList lst; + if (showClassifiers) + { + lst << qMakePair( classAttribute(), QPixmap() ); + } + + int count = categories().count(); + for (int i = 0; i < count; i++) + { + const QgsRendererCategoryV2& cat = categories()[i]; + QPixmap pix = QgsSymbolLayerV2Utils::symbolPreviewPixmap( cat.symbol(), iconSize ); + lst << qMakePair( cat.label(), pix ); + } + return lst; +} + + QgsSymbolV2* QgsCategorizedSymbolRendererV2::sourceSymbol() { return mSourceSymbol; diff --git a/src/core/symbology-ng/qgscategorizedsymbolrendererv2.h b/src/core/symbology-ng/qgscategorizedsymbolrendererv2.h index 385d9eeb21f6..c3ed9a244f17 100644 --- a/src/core/symbology-ng/qgscategorizedsymbolrendererv2.h +++ b/src/core/symbology-ng/qgscategorizedsymbolrendererv2.h @@ -79,6 +79,9 @@ class QgsCategorizedSymbolRendererV2 : public QgsFeatureRendererV2 //! store renderer info to XML element virtual QDomElement save(QDomDocument& doc); + //! return a list of symbology items for the legend + virtual QgsLegendSymbologyList legendSymbologyItems(QSize iconSize); + QgsSymbolV2* sourceSymbol(); void setSourceSymbol(QgsSymbolV2* sym); diff --git a/src/core/symbology-ng/qgsgraduatedsymbolrendererv2.cpp b/src/core/symbology-ng/qgsgraduatedsymbolrendererv2.cpp index 5cb95de0ddfa..b6507cc38383 100644 --- a/src/core/symbology-ng/qgsgraduatedsymbolrendererv2.cpp +++ b/src/core/symbology-ng/qgsgraduatedsymbolrendererv2.cpp @@ -10,6 +10,7 @@ #include #include +#include // for legend QgsRendererRangeV2::QgsRendererRangeV2(double lowerValue, double upperValue, QgsSymbolV2* symbol, QString label) : mLowerValue(lowerValue), mUpperValue(upperValue), mSymbol(symbol), mLabel(label) @@ -432,6 +433,27 @@ QDomElement QgsGraduatedSymbolRendererV2::save(QDomDocument& doc) return rendererElem; } +QgsLegendSymbologyList QgsGraduatedSymbolRendererV2::legendSymbologyItems(QSize iconSize) +{ + QSettings settings; + bool showClassifiers = settings.value( "/qgis/showLegendClassifiers", false ).toBool(); + + QgsLegendSymbologyList lst; + if (showClassifiers) + { + lst << qMakePair( classAttribute(), QPixmap() ); + } + + int count = ranges().count(); + for (int i = 0; i < count; i++) + { + const QgsRendererRangeV2& range = ranges()[i]; + QPixmap pix = QgsSymbolLayerV2Utils::symbolPreviewPixmap( range.symbol(), iconSize ); + lst << qMakePair( range.label(), pix ); + } + return lst; +} + QgsSymbolV2* QgsGraduatedSymbolRendererV2::sourceSymbol() { return mSourceSymbol; diff --git a/src/core/symbology-ng/qgsgraduatedsymbolrendererv2.h b/src/core/symbology-ng/qgsgraduatedsymbolrendererv2.h index ee2c7165a04a..6613e4d47d56 100644 --- a/src/core/symbology-ng/qgsgraduatedsymbolrendererv2.h +++ b/src/core/symbology-ng/qgsgraduatedsymbolrendererv2.h @@ -87,6 +87,9 @@ class QgsGraduatedSymbolRendererV2 : public QgsFeatureRendererV2 //! store renderer info to XML element virtual QDomElement save(QDomDocument& doc); + //! return a list of symbology items for the legend + virtual QgsLegendSymbologyList legendSymbologyItems(QSize iconSize); + QgsSymbolV2* sourceSymbol(); void setSourceSymbol(QgsSymbolV2* sym); diff --git a/src/core/symbology-ng/qgsrendererv2.cpp b/src/core/symbology-ng/qgsrendererv2.cpp index 25e29f53b358..37898dab67b8 100644 --- a/src/core/symbology-ng/qgsrendererv2.cpp +++ b/src/core/symbology-ng/qgsrendererv2.cpp @@ -281,6 +281,13 @@ QDomElement QgsFeatureRendererV2::save(QDomDocument& doc) return doc.createElement(RENDERER_TAG_NAME); } +QgsLegendSymbologyList QgsFeatureRendererV2::legendSymbologyItems(QSize iconSize) +{ + // empty list by default + return QgsLegendSymbologyList(); +} + + int QgsFeatureRendererV2::fieldNameIndex( const QgsFieldMap& fields, const QString& fieldName ) { for ( QgsFieldMap::const_iterator it = fields.constBegin(); it != fields.constEnd(); ++it ) diff --git a/src/core/symbology-ng/qgsrendererv2.h b/src/core/symbology-ng/qgsrendererv2.h index f0c9fa5d6dbd..b5e86b784c84 100644 --- a/src/core/symbology-ng/qgsrendererv2.h +++ b/src/core/symbology-ng/qgsrendererv2.h @@ -8,6 +8,8 @@ #include #include #include +#include +#include class QDomDocument; class QDomElement; @@ -19,6 +21,8 @@ class QgsFeature; typedef QList QgsSymbolV2List; typedef QMap QgsSymbolV2Map; +typedef QList< QPair > QgsLegendSymbologyList; + #define RENDERER_TAG_NAME "renderer-v2" //////// @@ -84,6 +88,9 @@ class QgsFeatureRendererV2 //! store renderer info to XML element virtual QDomElement save(QDomDocument& doc); + + //! return a list of symbology items for the legend + virtual QgsLegendSymbologyList legendSymbologyItems(QSize iconSize); /** Returns the index of a field name or -1 if the field does not exist * copied from QgsVectorDataProvider... d'oh... probably should be elsewhere diff --git a/src/core/symbology-ng/qgssinglesymbolrendererv2.cpp b/src/core/symbology-ng/qgssinglesymbolrendererv2.cpp index 6f2b9e987f9f..4cf687088bb1 100644 --- a/src/core/symbology-ng/qgssinglesymbolrendererv2.cpp +++ b/src/core/symbology-ng/qgssinglesymbolrendererv2.cpp @@ -100,3 +100,12 @@ QDomElement QgsSingleSymbolRendererV2::save(QDomDocument& doc) return rendererElem; } + +QgsLegendSymbologyList QgsSingleSymbolRendererV2::legendSymbologyItems(QSize iconSize) +{ + QPixmap pix = QgsSymbolLayerV2Utils::symbolPreviewPixmap(mSymbol, iconSize); + + QgsLegendSymbologyList lst; + lst << qMakePair( QString(), pix ); + return lst; +} diff --git a/src/core/symbology-ng/qgssinglesymbolrendererv2.h b/src/core/symbology-ng/qgssinglesymbolrendererv2.h index 09b7fe4f2dcf..f056935d0e1a 100644 --- a/src/core/symbology-ng/qgssinglesymbolrendererv2.h +++ b/src/core/symbology-ng/qgssinglesymbolrendererv2.h @@ -34,6 +34,9 @@ class QgsSingleSymbolRendererV2 : public QgsFeatureRendererV2 //! store renderer info to XML element virtual QDomElement save(QDomDocument& doc); + //! return a list of symbology items for the legend + virtual QgsLegendSymbologyList legendSymbologyItems(QSize iconSize); + protected: QgsSymbolV2* mSymbol; }; diff --git a/src/core/symbology-ng/qgssymbollayerv2utils.cpp b/src/core/symbology-ng/qgssymbollayerv2utils.cpp index d1056e342227..e73a02ddd804 100644 --- a/src/core/symbology-ng/qgssymbollayerv2utils.cpp +++ b/src/core/symbology-ng/qgssymbollayerv2utils.cpp @@ -145,6 +145,11 @@ QPointF QgsSymbolLayerV2Utils::decodePoint(QString str) } QIcon QgsSymbolLayerV2Utils::symbolPreviewIcon(QgsSymbolV2* symbol, QSize size) +{ + return QIcon(symbolPreviewPixmap(symbol, size)); +} + +QPixmap QgsSymbolLayerV2Utils::symbolPreviewPixmap(QgsSymbolV2* symbol, QSize size) { QPixmap pixmap(size); QPainter painter; @@ -153,9 +158,10 @@ QIcon QgsSymbolLayerV2Utils::symbolPreviewIcon(QgsSymbolV2* symbol, QSize size) painter.eraseRect(QRect(QPoint(0,0),size)); symbol->drawPreviewIcon(&painter, size); painter.end(); - return QIcon(pixmap); + return pixmap; } + QIcon QgsSymbolLayerV2Utils::symbolLayerPreviewIcon(QgsSymbolLayerV2* layer, QSize size) { QPixmap pixmap(size); diff --git a/src/core/symbology-ng/qgssymbollayerv2utils.h b/src/core/symbology-ng/qgssymbollayerv2utils.h index 4e33de807288..3332f81208b0 100644 --- a/src/core/symbology-ng/qgssymbollayerv2utils.h +++ b/src/core/symbology-ng/qgssymbollayerv2utils.h @@ -47,6 +47,7 @@ class QgsSymbolLayerV2Utils static QIcon symbolLayerPreviewIcon(QgsSymbolLayerV2* layer, QSize size); static QIcon colorRampPreviewIcon(QgsVectorColorRampV2* ramp, QSize size); + static QPixmap symbolPreviewPixmap(QgsSymbolV2* symbol, QSize size); static QPixmap colorRampPreviewPixmap(QgsVectorColorRampV2* ramp, QSize size); static QgsSymbolV2* loadSymbol(QDomElement& element);