From b04199a4afffe49154f10f4fb2729ada574357c3 Mon Sep 17 00:00:00 2001 From: Martin Dobias Date: Fri, 22 Aug 2014 12:21:41 +0700 Subject: [PATCH] Revert previous changes to QgsLegendModel and its items --- src/core/composer/qgscomposerlegenditem.cpp | 299 ++++----------- src/core/composer/qgscomposerlegenditem.h | 122 +----- src/core/composer/qgslegendmodel.cpp | 401 ++++++++++++++++---- src/core/composer/qgslegendmodel.h | 11 +- 4 files changed, 424 insertions(+), 409 deletions(-) diff --git a/src/core/composer/qgscomposerlegenditem.cpp b/src/core/composer/qgscomposerlegenditem.cpp index 97af93d19d1..1537ff6eb74 100644 --- a/src/core/composer/qgscomposerlegenditem.cpp +++ b/src/core/composer/qgscomposerlegenditem.cpp @@ -61,231 +61,121 @@ void QgsComposerLegendItem::writeXMLChildren( QDomElement& elem, QDomDocument& d } } -////////////////QgsComposerBaseSymbolItem - -QgsComposerBaseSymbolItem::QgsComposerBaseSymbolItem() - : QgsComposerLegendItem( QgsComposerLegendStyle::Symbol ) -{ - -} - - -QgsComposerLayerItem* QgsComposerBaseSymbolItem::parentLayerItem() const -{ - return dynamic_cast( parent() ); -} - -QgsMapLayer* QgsComposerBaseSymbolItem::parentMapLayer() const -{ - QgsComposerLayerItem* lItem = parentLayerItem(); - if ( !lItem ) return 0; - - return QgsMapLayerRegistry::instance()->mapLayer( lItem->layerID() ); - -} ////////////////QgsComposerSymbolV2Item #include "qgssymbolv2.h" -QgsComposerSymbolV2Item::QgsComposerSymbolV2Item() +QgsComposerSymbolV2Item::QgsComposerSymbolV2Item(): QgsComposerLegendItem( QgsComposerLegendStyle::Symbol ), mSymbolV2( 0 ) { } -QgsComposerSymbolV2Item::QgsComposerSymbolV2Item( const QgsLegendSymbolItemV2& item ) - : mItem( item ) +QgsComposerSymbolV2Item::QgsComposerSymbolV2Item( const QString& text ): QgsComposerLegendItem( text, QgsComposerLegendStyle::Symbol ), mSymbolV2( 0 ) { - setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable ); } -QgsComposerSymbolV2Item::QgsComposerSymbolV2Item( const QString& text ) +QgsComposerSymbolV2Item::QgsComposerSymbolV2Item( const QIcon& icon, const QString& text ): QgsComposerLegendItem( icon, text, QgsComposerLegendStyle::Symbol ), mSymbolV2( 0 ) { - setText( text ); -} - -QgsComposerSymbolV2Item::QgsComposerSymbolV2Item( const QIcon& icon, const QString& text ) -{ - setIcon( icon ); - setText( text ); } QgsComposerSymbolV2Item::~QgsComposerSymbolV2Item() { -} - - - -QVariant QgsComposerSymbolV2Item::data( int role ) const -{ - if ( role == Qt::DecorationRole ) - { - if ( mIcon.isNull() ) - mIcon = QgsSymbolLayerV2Utils::symbolPreviewIcon( mItem.symbol(), QSize( 30, 30 ) ); - return mIcon; - } - else if ( role == Qt::DisplayRole || role == Qt::EditRole ) - { - QString lbl = label(); - - if ( parentLayerItem()->showFeatureCount() ) - { - // Add counts to multi symbols layers only or labeled single symbols, - // so that single symbol layers are still drawn on single line - if ( parentLayerItem()->rowCount() > 1 || !lbl.isEmpty() ) - { - lbl += QString( " [%1]" ).arg( parentVectorLayer()->featureCount( mItem.legacyRuleKey() ) ); - } - } - return lbl; - } - else - return QgsComposerBaseSymbolItem::data( role ); + delete mSymbolV2; } QStandardItem* QgsComposerSymbolV2Item::clone() const { - return new QgsComposerSymbolV2Item( *this ); + QgsComposerSymbolV2Item* cloneItem = new QgsComposerSymbolV2Item(); + *cloneItem = *this; + if ( mSymbolV2 ) + { + cloneItem->setSymbolV2( mSymbolV2->clone() ); + } + return cloneItem; } void QgsComposerSymbolV2Item::writeXML( QDomElement& elem, QDomDocument& doc ) const { QDomElement vectorClassElem = doc.createElement( "VectorClassificationItemNg" ); - if ( mItem.symbol() ) + if ( mSymbolV2 ) { QgsSymbolV2Map saveSymbolMap; - saveSymbolMap.insert( "classificationSymbol", mItem.symbol() ); + saveSymbolMap.insert( "classificationSymbol", mSymbolV2 ); QDomElement symbolsElem = QgsSymbolLayerV2Utils::saveSymbols( saveSymbolMap, "symbols", doc ); vectorClassElem.appendChild( symbolsElem ); } - vectorClassElem.setAttribute( "text", mItem.label() ); + vectorClassElem.setAttribute( "text", text() ); vectorClassElem.setAttribute( "userText", userText() ); elem.appendChild( vectorClassElem ); } void QgsComposerSymbolV2Item::readXML( const QDomElement& itemElem, bool xServerAvailable ) { - Q_UNUSED( xServerAvailable ); - if ( itemElem.isNull() ) { return; } + setText( itemElem.attribute( "text", "" ) ); setUserText( itemElem.attribute( "userText", "" ) ); QDomElement symbolsElem = itemElem.firstChildElement( "symbols" ); + if ( !symbolsElem.isNull() ) + { + QgsSymbolV2Map loadSymbolMap = QgsSymbolLayerV2Utils::loadSymbols( symbolsElem ); + //we assume there is only one symbol in the map... + QgsSymbolV2Map::iterator mapIt = loadSymbolMap.begin(); + if ( mapIt != loadSymbolMap.end() ) + { + QgsSymbolV2* symbolNg = mapIt.value(); + if ( symbolNg ) + { + setSymbolV2( symbolNg ); + if ( xServerAvailable ) + { + setIcon( QgsSymbolLayerV2Utils::symbolPreviewIcon( symbolNg, QSize( 30, 30 ) ) ); + } + } + } + } } void QgsComposerSymbolV2Item::setSymbolV2( QgsSymbolV2* s ) { - Q_UNUSED( s ); + delete mSymbolV2; + mSymbolV2 = s; } - -QgsComposerSymbolV2Item* QgsComposerSymbolV2Item::findItemByRuleKey( QgsComposerLayerItem* parentLayerItem, QString ruleKey ) -{ - for ( int i = 0; i < parentLayerItem->rowCount(); ++i ) - { - if ( QgsComposerSymbolV2Item* sItem = dynamic_cast( parentLayerItem->child( 0 ) ) ) - { - if ( sItem->ruleKey() == ruleKey ) - return sItem; - } - } - return 0; -} - - -QgsVectorLayer* QgsComposerSymbolV2Item::parentVectorLayer() const -{ - return qobject_cast( parentMapLayer() ); -} - -QString QgsComposerSymbolV2Item::label() const -{ - if ( !mUserText.isEmpty() ) - { - return mUserText; - } - else - { - QgsVectorLayer* vLayer = parentVectorLayer(); - - if ( vLayer && vLayer->rendererV2() && vLayer->rendererV2()->type() == "singleSymbol" ) - { - if ( !parentLayerItem()->userText().isEmpty() ) - { - return parentLayerItem()->userText(); - } - else if ( !vLayer->title().isEmpty() ) - { - return vLayer->title(); - } - else - { - return vLayer->name(); - } - } - else - { - return mItem.label(); - } - } -} - - ////////////////////QgsComposerRasterSymbolItem -QgsComposerRasterSymbolItem::QgsComposerRasterSymbolItem() +QgsComposerRasterSymbolItem::QgsComposerRasterSymbolItem(): QgsComposerLegendItem( QgsComposerLegendStyle::Symbol ) { } -QgsComposerRasterSymbolItem::QgsComposerRasterSymbolItem( const QColor& color, const QString& label ) - : mColor( color ) - , mLabel( label ) +QgsComposerRasterSymbolItem::QgsComposerRasterSymbolItem( const QString& text ): QgsComposerLegendItem( text, QgsComposerLegendStyle::Symbol ) { } -QgsComposerRasterSymbolItem::QgsComposerRasterSymbolItem( const QString& text ) +QgsComposerRasterSymbolItem::QgsComposerRasterSymbolItem( const QIcon& icon, const QString& text ): QgsComposerLegendItem( icon, text, QgsComposerLegendStyle::Symbol ) { - setText( text ); -} - -QgsComposerRasterSymbolItem::QgsComposerRasterSymbolItem( const QIcon& icon, const QString& text ) -{ - setIcon( icon ); - setText( text ); } QgsComposerRasterSymbolItem::~QgsComposerRasterSymbolItem() { } -QVariant QgsComposerRasterSymbolItem::data( int role ) const -{ - if ( role == Qt::DisplayRole || role == Qt::EditRole ) - { - return mUserText.isEmpty() ? mLabel : mUserText; - } - else if ( role == Qt::DecorationRole ) - { - QPixmap itemPixmap( 20, 20 ); - itemPixmap.fill( mColor ); - return QIcon( itemPixmap ); - } - return QgsComposerBaseSymbolItem::data( role ); -} - QStandardItem* QgsComposerRasterSymbolItem::clone() const { QgsComposerRasterSymbolItem* cloneItem = new QgsComposerRasterSymbolItem(); *cloneItem = *this; + cloneItem->setLayerID( mLayerID ); return cloneItem; } void QgsComposerRasterSymbolItem::writeXML( QDomElement& elem, QDomDocument& doc ) const { QDomElement rasterClassElem = doc.createElement( "RasterClassificationItem" ); - rasterClassElem.setAttribute( "text", mLabel ); + rasterClassElem.setAttribute( "layerId", mLayerID ); + rasterClassElem.setAttribute( "text", text() ); rasterClassElem.setAttribute( "userText", userText() ); rasterClassElem.setAttribute( "color", mColor.name() ); elem.appendChild( rasterClassElem ); @@ -293,52 +183,23 @@ void QgsComposerRasterSymbolItem::writeXML( QDomElement& elem, QDomDocument& doc void QgsComposerRasterSymbolItem::readXML( const QDomElement& itemElem, bool xServerAvailable ) { - Q_UNUSED( xServerAvailable ); - if ( itemElem.isNull() ) { return; } - mLabel = itemElem.attribute( "text", "" ); + setText( itemElem.attribute( "text", "" ) ); setUserText( itemElem.attribute( "userText", "" ) ); + setLayerID( itemElem.attribute( "layerId", "" ) ); setColor( QColor( itemElem.attribute( "color" ) ) ); + + if ( xServerAvailable ) + { + QPixmap itemPixmap( 20, 20 ); + itemPixmap.fill( mColor ); + setIcon( QIcon( itemPixmap ) ); + } } - -////////////////////QgsComposerRasterImageItem - - -QgsComposerRasterImageItem::QgsComposerRasterImageItem() -{ -} - -QgsComposerRasterImageItem::QgsComposerRasterImageItem( const QImage& image ) - : mImage( image ) -{ - -} - -QStandardItem* QgsComposerRasterImageItem::clone() const -{ - QgsComposerRasterImageItem* cloneItem = new QgsComposerRasterImageItem( mImage ); - return cloneItem; -} - -void QgsComposerRasterImageItem::writeXML( QDomElement& elem, QDomDocument& doc ) const -{ - QDomElement rasterImageElem = doc.createElement( "RasterImageItem" ); - // TODO: also save the image??? - elem.appendChild( rasterImageElem ); -} - -void QgsComposerRasterImageItem::readXML( const QDomElement& itemElem, bool xServerAvailable ) -{ - Q_UNUSED( itemElem ); - Q_UNUSED( xServerAvailable ); -} - - - ////////////////////QgsComposerLayerItem QgsComposerLayerItem::QgsComposerLayerItem(): QgsComposerLegendItem( QgsComposerLegendStyle::Subgroup ) @@ -355,28 +216,6 @@ QgsComposerLayerItem::~QgsComposerLayerItem() { } -QVariant QgsComposerLayerItem::data( int role ) const -{ - if ( role == Qt::DisplayRole || role == Qt::EditRole ) - { - QgsMapLayer* ml = mapLayer(); - if ( !ml ) return QVariant(); - - QString label = mUserText.isEmpty() ? ml->name() : mUserText; - - if ( QgsVectorLayer* vLayer = qobject_cast( ml ) ) - { - if ( showFeatureCount() ) - { - label += QString( " [%1]" ).arg( vLayer->featureCount() ); - } - } - return label; - } - else - return QgsComposerLegendItem::data( role ); -} - QStandardItem* QgsComposerLayerItem::clone() const { QgsComposerLayerItem* cloneItem = new QgsComposerLayerItem(); @@ -389,7 +228,7 @@ void QgsComposerLayerItem::writeXML( QDomElement& elem, QDomDocument& doc ) cons { QDomElement layerItemElem = doc.createElement( "LayerItem" ); layerItemElem.setAttribute( "layerId", mLayerID ); - layerItemElem.setAttribute( "text", data( Qt::DisplayRole ).toString() ); + layerItemElem.setAttribute( "text", text() ); layerItemElem.setAttribute( "userText", userText() ); layerItemElem.setAttribute( "showFeatureCount", showFeatureCount() ); layerItemElem.setAttribute( "style", QgsComposerLegendStyle::styleName( mStyle ) ); @@ -438,10 +277,6 @@ void QgsComposerLayerItem::readXML( const QDomElement& itemElem, bool xServerAva { currentChildItem = new QgsComposerRasterSymbolItem(); } - else if ( elemTag == "RasterImageItem" ) - { - currentChildItem = new QgsComposerRasterImageItem(); - } else { continue; //unsupported child type @@ -453,15 +288,25 @@ void QgsComposerLayerItem::readXML( const QDomElement& itemElem, bool xServerAva void QgsComposerLayerItem::setDefaultStyle( double scaleDenominator, QString rule ) { - Q_UNUSED( scaleDenominator ); - Q_UNUSED( rule ); -} - - - -QgsMapLayer* QgsComposerLayerItem::mapLayer() const -{ - return QgsMapLayerRegistry::instance()->mapLayer( mLayerID ); + // set default style according to number of symbols + QgsVectorLayer* vLayer = qobject_cast( QgsMapLayerRegistry::instance()->mapLayer( layerID() ) ); + if ( vLayer ) + { + QgsFeatureRendererV2* renderer = vLayer->rendererV2(); + if ( renderer ) + { + QPair symbolItem = renderer->legendSymbolItems( scaleDenominator, rule ).value( 0 ); + if ( renderer->legendSymbolItems( scaleDenominator, rule ).size() > 1 || !symbolItem.first.isEmpty() ) + { + setStyle( QgsComposerLegendStyle::Subgroup ); + } + else + { + // Hide title by default for single symbol + setStyle( QgsComposerLegendStyle::Hidden ); + } + } + } } ////////////////////QgsComposerGroupItem @@ -489,7 +334,7 @@ void QgsComposerGroupItem::writeXML( QDomElement& elem, QDomDocument& doc ) cons { QDomElement layerGroupElem = doc.createElement( "GroupItem" ); // text is always user text, but for forward compatibility for now write both - layerGroupElem.setAttribute( "text", data( Qt::DisplayRole ).toString() ); + layerGroupElem.setAttribute( "text", text() ); layerGroupElem.setAttribute( "userText", userText() ); layerGroupElem.setAttribute( "style", QgsComposerLegendStyle::styleName( mStyle ) ); writeXMLChildren( layerGroupElem, doc ); @@ -551,8 +396,6 @@ void QgsComposerGroupItem::readXML( const QDomElement& itemElem, bool xServerAva } } - - QgsComposerStyleItem::QgsComposerStyleItem(): QStandardItem() { } diff --git a/src/core/composer/qgscomposerlegenditem.h b/src/core/composer/qgscomposerlegenditem.h index 479bc13540b..698773525b3 100644 --- a/src/core/composer/qgscomposerlegenditem.h +++ b/src/core/composer/qgscomposerlegenditem.h @@ -19,19 +19,10 @@ #define QGSCOMPOSERLEGENDITEM_H #include "qgscomposerlegendstyle.h" -#include "qgslegendsymbolitemv2.h" #include - class QDomDocument; class QDomElement; -class QgsComposerLayerItem; -class QgsLegendSettings; -class QgsMapLayer; -class QgsSymbolV2; -class QgsVectorLayer; - - /**Abstract base class for the legend item types*/ class CORE_EXPORT QgsComposerLegendItem: public QStandardItem { @@ -45,10 +36,8 @@ class CORE_EXPORT QgsComposerLegendItem: public QStandardItem { GroupItem = QStandardItem::UserType, LayerItem, - // TODO: unify all item types derived from BaseSymbol item under one value (to allow extensibility) SymbologyV2Item, RasterSymbolItem, - RasterImageItem, StyleItem }; @@ -69,6 +58,7 @@ class CORE_EXPORT QgsComposerLegendItem: public QStandardItem // Set text defined by user virtual void setUserText( const QString & text ) { mUserText = text; } + protected: void writeXMLChildren( QDomElement& elem, QDomDocument& doc ) const; @@ -78,90 +68,47 @@ class CORE_EXPORT QgsComposerLegendItem: public QStandardItem QString mUserText; }; -/** - * The QgsComposerBaseSymbolItem class is base class for implementations of custom legend items. - * - * @note added in 2.6 - */ -class CORE_EXPORT QgsComposerBaseSymbolItem : public QgsComposerLegendItem -{ - public: - QgsComposerLayerItem* parentLayerItem() const; - QgsMapLayer* parentMapLayer() const; - protected: - QgsComposerBaseSymbolItem(); +class QgsSymbolV2; -}; - - -class CORE_EXPORT QgsComposerSymbolV2Item : public QgsComposerBaseSymbolItem +class CORE_EXPORT QgsComposerSymbolV2Item: public QgsComposerLegendItem { public: QgsComposerSymbolV2Item(); - QgsComposerSymbolV2Item( const QgsLegendSymbolItemV2& item ); - //! @deprecated - Q_DECL_DEPRECATED QgsComposerSymbolV2Item( const QString& text ); - //! @deprecated - Q_DECL_DEPRECATED QgsComposerSymbolV2Item( const QIcon& icon, const QString& text ); + QgsComposerSymbolV2Item( const QString& text ); + QgsComposerSymbolV2Item( const QIcon& icon, const QString& text ); virtual ~QgsComposerSymbolV2Item(); - //! override text + lazy creation of icon - virtual QVariant data( int role ) const; - virtual QStandardItem* clone() const; virtual void writeXML( QDomElement& elem, QDomDocument& doc ) const; virtual void readXML( const QDomElement& itemElem, bool xServerAvailable = true ); - /** Set symbol (takes ownership) - @deprecated */ - Q_DECL_DEPRECATED void setSymbolV2( QgsSymbolV2* s ); - /** @deprecated */ - Q_DECL_DEPRECATED QgsSymbolV2* symbolV2() const { return mItem.symbol(); } + /**Set symbol (takes ownership)*/ + void setSymbolV2( QgsSymbolV2* s ); + QgsSymbolV2* symbolV2() {return mSymbolV2;} ItemType itemType() const { return SymbologyV2Item; } - //! @note added in 2.6 - QString ruleKey() const { return mItem.ruleKey(); } - - //! @note added in 2.6 - const QgsLegendSymbolItemV2& itemData() const { return mItem; } - - //! @note added in 2.6 - static QgsComposerSymbolV2Item* findItemByRuleKey( QgsComposerLayerItem* parentLayerItem, QString ruleKey ); - private: - - QgsVectorLayer* parentVectorLayer() const; - QString label() const; - - QgsLegendSymbolItemV2 mItem; - mutable QIcon mIcon; + QgsSymbolV2* mSymbolV2; }; -class CORE_EXPORT QgsComposerRasterSymbolItem : public QgsComposerBaseSymbolItem +class CORE_EXPORT QgsComposerRasterSymbolItem : public QgsComposerLegendItem { public: QgsComposerRasterSymbolItem(); - QgsComposerRasterSymbolItem( const QColor& color, const QString& label ); - //! @deprecated - Q_DECL_DEPRECATED QgsComposerRasterSymbolItem( const QString& text ); - //! @deprecated - Q_DECL_DEPRECATED QgsComposerRasterSymbolItem( const QIcon& icon, const QString& text ); + QgsComposerRasterSymbolItem( const QString& text ); + QgsComposerRasterSymbolItem( const QIcon& icon, const QString& text ); virtual ~QgsComposerRasterSymbolItem(); - virtual QVariant data( int role ) const; - virtual QStandardItem* clone() const; virtual void writeXML( QDomElement& elem, QDomDocument& doc ) const; virtual void readXML( const QDomElement& itemElem, bool xServerAvailable = true ); - //! @deprecated - Q_DECL_DEPRECATED void setLayerID( const QString& id ) { mLayerID = id; } - //! @deprecated - Q_DECL_DEPRECATED QString layerID() const { return mLayerID; } + void setLayerID( const QString& id ) { mLayerID = id; } + QString layerID() const { return mLayerID; } ItemType itemType() const { return RasterSymbolItem; } void setColor( const QColor& c ) { mColor = c; } @@ -169,43 +116,15 @@ class CORE_EXPORT QgsComposerRasterSymbolItem : public QgsComposerBaseSymbolItem private: QString mLayerID; - QColor mColor; - QString mLabel; }; - -/** - * Draws a raster image in the legend - * @note added in 2.6 - */ -class CORE_EXPORT QgsComposerRasterImageItem : public QgsComposerBaseSymbolItem -{ - public: - QgsComposerRasterImageItem(); - QgsComposerRasterImageItem( const QImage& image ); - - virtual QStandardItem* clone() const; - - virtual void writeXML( QDomElement& elem, QDomDocument& doc ) const; - virtual void readXML( const QDomElement& itemElem, bool xServerAvailable = true ); - - ItemType itemType() const { return RasterImageItem; } - - private: - QImage mImage; -}; - - class CORE_EXPORT QgsComposerLayerItem : public QgsComposerLegendItem { public: QgsComposerLayerItem(); QgsComposerLayerItem( const QString& text ); virtual ~QgsComposerLayerItem(); - - virtual QVariant data( int role ) const; - virtual QStandardItem* clone() const; virtual void writeXML( QDomElement& elem, QDomDocument& doc ) const; @@ -219,15 +138,9 @@ class CORE_EXPORT QgsComposerLayerItem : public QgsComposerLegendItem void setShowFeatureCount( bool show ) { mShowFeatureCount = show; } bool showFeatureCount() const { return mShowFeatureCount; } - //! @deprecated does nothing - Q_DECL_DEPRECATED void setDefaultStyle( double scaleDenominator = -1, QString rule = "" ); - - //! convenience method to obtain layer pointed at - //! @note added in 2.6 - QgsMapLayer* mapLayer() const; + void setDefaultStyle( double scaleDenominator = -1, QString rule = "" ); private: - QString mLayerID; // Show vector feature counts bool mShowFeatureCount; @@ -245,13 +158,8 @@ class CORE_EXPORT QgsComposerGroupItem: public QgsComposerLegendItem virtual void readXML( const QDomElement& itemElem, bool xServerAvailable = true ); ItemType itemType() const { return GroupItem; } - }; -/** - * Item used for 2nd column of the legend model for layers and groups to indicate - * style of the item (e.g. hidden, group, sub-group) - */ class CORE_EXPORT QgsComposerStyleItem: public QStandardItem { public: diff --git a/src/core/composer/qgslegendmodel.cpp b/src/core/composer/qgslegendmodel.cpp index 0b4437c52ca..7fa2891231e 100644 --- a/src/core/composer/qgslegendmodel.cpp +++ b/src/core/composer/qgslegendmodel.cpp @@ -20,7 +20,6 @@ #include "qgsfield.h" #include "qgslayertree.h" #include "qgsmaplayer.h" -#include "qgsmaplayerlegend.h" #include "qgsmaplayerregistry.h" #include "qgsrasterlayer.h" #include "qgsrendererv2.h" @@ -34,9 +33,7 @@ #include #include -QgsLegendModel::QgsLegendModel() - : QStandardItemModel() - , mAutoUpdate( true ) +QgsLegendModel::QgsLegendModel(): QStandardItemModel(), mAutoUpdate( true ) { setColumnCount( 2 ); @@ -142,58 +139,6 @@ void QgsLegendModel::setLayerSet( const QStringList& layerIds, double scaleDenom currentLayer = QgsMapLayerRegistry::instance()->mapLayer( *idIter ); addLayer( currentLayer, scaleDenominator, rule ); } - - // filter out items where the rule is not matching - used by WMS to get symbol icon for a particular rule - if ( !rule.isEmpty() ) - { - for ( int i = rowCount() - 1 ; i >= 0; --i ) - { - QgsComposerLayerItem* lItem = dynamic_cast( invisibleRootItem()->child( i ) ); - if ( !lItem ) - continue; - - // remove rules that do not match - bool gotMatchingRule = false; - for ( int j = 0; j < lItem->rowCount(); ++j ) - { - QgsComposerSymbolV2Item* sItem = dynamic_cast( lItem->child( j ) ); - if ( !sItem ) - continue; - - if ( sItem->itemData().label() == rule ) - { - QStandardItem* takenSItem = lItem->takeChild( j ); - lItem->removeRows( 0, lItem->rowCount() ); - lItem->setChild( 0, takenSItem ); - gotMatchingRule = true; - break; - } - } - - if ( !gotMatchingRule ) - removeRow( i ); - } - } - - if ( scaleDenominator != -1 ) - { - for ( int i = 0; i < rowCount(); ++i ) - { - QgsComposerLayerItem* lItem = dynamic_cast( invisibleRootItem()->child( i ) ); - if ( !lItem ) - continue; - - for ( int j = lItem->rowCount() - 1; j >= 0; --j ) - { - QgsComposerSymbolV2Item* sItem = dynamic_cast( lItem->child( j ) ); - if ( !sItem ) - continue; - - if ( !sItem->itemData().isScaleOK( scaleDenominator ) ) - lItem->removeRow( j ); - } - } - } } QStandardItem* QgsLegendModel::addGroup( QString text, int position, QStandardItem* parentItem ) @@ -219,6 +164,258 @@ QStandardItem* QgsLegendModel::addGroup( QString text, int position, QStandardIt return groupItem; } +int QgsLegendModel::addVectorLayerItemsV2( QStandardItem* layerItem, QgsVectorLayer* vlayer, double scaleDenominator, QString rule ) +{ + QgsComposerLayerItem* lItem = dynamic_cast( layerItem ); + + if ( !layerItem || !lItem || !vlayer ) + { + return 1; + } + + QgsFeatureRendererV2* renderer = vlayer->rendererV2(); + if ( !renderer ) + { + return 2; + } + + if ( lItem->showFeatureCount() ) + { + if ( !vlayer->countSymbolFeatures() ) + { + QgsDebugMsg( "Cannot get feature counts" ); + } + } + + QgsLegendSymbolList lst = renderer->legendSymbolItems( scaleDenominator, rule ); + QgsLegendSymbolList::const_iterator symbolIt = lst.constBegin(); + int row = 0; + for ( ; symbolIt != lst.constEnd(); ++symbolIt ) + { + if ( scaleDenominator == -1 && rule.isEmpty() ) + { + QgsComposerSymbolV2Item* currentSymbolItem = new QgsComposerSymbolV2Item( "" ); + + // Get userText from old item if exists + QgsComposerSymbolV2Item* oldSymbolItem = dynamic_cast( layerItem->child( row, 0 ) ); + if ( oldSymbolItem ) + { + currentSymbolItem->setUserText( oldSymbolItem->userText() ); + } + + currentSymbolItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable ); + if ( symbolIt->second ) + { + if ( mHasTopLevelWindow ) //only use QIcon / QPixmap if we have a running x-server + { + currentSymbolItem->setIcon( QgsSymbolLayerV2Utils::symbolPreviewIcon( symbolIt->second, QSize( 30, 30 ) ) ); + } + currentSymbolItem->setSymbolV2( symbolIt->second->clone() ); + } + layerItem->setChild( row, 0, currentSymbolItem ); + + // updateSymbolV2ItemText needs layer set + updateSymbolV2ItemText( currentSymbolItem ); + } + else + { + QgsComposerSymbolV2Item* currentSymbolItem = new QgsComposerSymbolV2Item( "" ); + if ( mHasTopLevelWindow ) //only use QIcon / QPixmap if we have a running x-server + { + currentSymbolItem->setIcon( QgsSymbolLayerV2Utils::symbolPreviewIcon( symbolIt->second, QSize( 30, 30 ) ) ); + } + currentSymbolItem->setSymbolV2( symbolIt->second->clone() ); + layerItem->setChild( row, 0, currentSymbolItem ); + currentSymbolItem->setText( symbolIt->first ); + } + + row++; + } + + // Don't remove row on getLegendGraphic (read only with filter) + if ( scaleDenominator == -1 && rule.isEmpty() ) + { + // 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 ) + { + return 1; + } + + QgsRasterLayer* rasterLayer = qobject_cast( rlayer ); + if ( !rasterLayer ) + { + return 2; + } + + QgsDebugMsg( QString( "layer providertype:: %1" ).arg( rasterLayer->providerType() ) ); + if ( rasterLayer->providerType() == "wms" ) + { + QgsComposerRasterSymbolItem* currentSymbolItem = new QgsComposerRasterSymbolItem( "" ); + // GetLegendGraphics in case of WMS service... image can return null if GetLegendGraphics + // is not supported by the server + // double currentScale = legend()->canvas()->scale(); + // BEWARE getLegendGraphic() COULD BE USED WITHOUT SCALE PARAMETER IF IT WAS ALREADY CALLED WITH + // THIS PARAMETER FROM A COMPONENT THAT CAN RECOVER CURRENT SCALE => LEGEND IN THE DESKTOP + // OTHERWISE IT RETURN A INVALID PIXMAP (QPixmap().isNull() == False) + QImage legendGraphic = rasterLayer->dataProvider()->getLegendGraphic(); + if ( !legendGraphic.isNull() ) + { + QgsDebugMsg( QString( "downloaded legend with dimension width:" ) + QString::number( legendGraphic.width() ) + QString( " and Height:" ) + QString::number( legendGraphic.height() ) ); + if ( mHasTopLevelWindow ) + { + currentSymbolItem->setIcon( QIcon( QPixmap::fromImage( legendGraphic ) ) ); + } + } + else + { + currentSymbolItem->setText( tr( "No Legend Available" ) ); + } + + currentSymbolItem->setLayerID( rasterLayer->id() ); + currentSymbolItem->setColor( QColor() ); + layerItem->removeRows( 0, layerItem->rowCount() ); + layerItem->setChild( layerItem->rowCount(), 0, currentSymbolItem ); + } + else + { + 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( layerItem->child( row, 0 ) ); + if ( oldSymbolItem ) + { + currentSymbolItem->setUserText( oldSymbolItem->userText() ); + currentSymbolItem->setText( currentSymbolItem->userText() ); + } + + if ( mHasTopLevelWindow ) + { + QPixmap itemPixmap( 20, 20 ); + itemPixmap.fill( itemIt->second ); + currentSymbolItem->setIcon( QIcon( itemPixmap ) ); + } + currentSymbolItem->setLayerID( rasterLayer->id() ); + + QColor itemColor = itemIt->second; + + //determine raster layer opacity, and adjust item color opacity to match + QgsRasterRenderer* rasterRenderer = rasterLayer->renderer(); + int opacity = 255; + if ( rasterRenderer ) + { + opacity = rasterRenderer->opacity() * 255.0; + } + itemColor.setAlpha( opacity ); + + currentSymbolItem->setColor( itemColor ); + + 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( symbolItem ); + if ( !sv2Item ) return; + + QgsComposerLayerItem* lItem = dynamic_cast( sv2Item->parent() ); + if ( !lItem ) return; + + QgsMapLayer* mapLayer = QgsMapLayerRegistry::instance()->mapLayer( lItem->layerID() ); + if ( !mapLayer ) return; + + QgsVectorLayer* vLayer = qobject_cast( mapLayer ); + if ( !vLayer ) return; + + QgsFeatureRendererV2* renderer = vLayer->rendererV2(); + if ( !renderer ) return; + + if ( lItem->showFeatureCount() ) vLayer->countSymbolFeatures(); + + QgsLegendSymbolList symbolList = renderer->legendSymbolItems(); + + QPair symbol = symbolList.value( symbolItem->row() ); + + QString label = sv2Item->userText().isEmpty() ? symbol.first : sv2Item->userText(); + + if ( renderer->type() == "singleSymbol" ) + { + if ( !sv2Item->userText().isEmpty() ) + { + label = sv2Item->userText(); + } + else if ( !lItem->userText().isEmpty() ) + { + label = lItem->userText(); + } + else if ( !vLayer->title().isEmpty() ) + { + label = vLayer->title(); + } + else + { + label = vLayer->name(); + } + } + + 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( symbolItem ); + if ( !rItem ) return; + + QgsComposerLayerItem* lItem = dynamic_cast( rItem->parent() ); + if ( !lItem ) return; + + QgsMapLayer* mapLayer = QgsMapLayerRegistry::instance()->mapLayer( lItem->layerID() ); + if ( !mapLayer ) return; + + QgsRasterLayer* rLayer = qobject_cast( 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 ) { @@ -255,7 +452,29 @@ void QgsLegendModel::updateItemText( QStandardItem* item ) return; } - emit dataChanged( cItem->index(), cItem->index() ); + QgsComposerLayerItem* lItem = dynamic_cast( cItem ); + if ( lItem ) + { + updateLayerItemText( lItem ); + return; + } + + QgsComposerSymbolV2Item* sv2Item = dynamic_cast( cItem ); + if ( sv2Item ) + { + updateSymbolV2ItemText( sv2Item ); + return; + } + + QgsComposerRasterSymbolItem* rItem = dynamic_cast( cItem ); + if ( rItem ) + { + updateRasterSymbolItemText( rItem ); + return; + } + + // group + cItem->setText( cItem->userText() ); } void QgsLegendModel::updateLayer( QStandardItem* layerItem ) @@ -264,16 +483,47 @@ void QgsLegendModel::updateLayer( QStandardItem* layerItem ) QgsComposerLayerItem* lItem = dynamic_cast( layerItem ); if ( lItem ) { - emit dataChanged( lItem->index(), lItem->index() ); - - QgsMapLayer* mapLayer = lItem->mapLayer(); - if ( mapLayer && mapLayer->legend() ) + QgsMapLayer* mapLayer = QgsMapLayerRegistry::instance()->mapLayer( lItem->layerID() ); + if ( mapLayer ) { - // mapLayer->legend()->createLegendModelItems( lItem ); + updateLayerItemText( lItem ); + + QgsVectorLayer* vLayer = qobject_cast( mapLayer ); + if ( vLayer ) + { + addVectorLayerItemsV2( lItem, vLayer ); + } + + QgsRasterLayer* rLayer = qobject_cast( mapLayer ); + if ( rLayer ) + { + addRasterLayerItems( lItem, rLayer ); + } } } } +void QgsLegendModel::updateLayerItemText( QStandardItem* layerItem ) +{ + QgsComposerLayerItem* lItem = dynamic_cast( layerItem ); + if ( !lItem ) return; + + QgsMapLayer* mapLayer = QgsMapLayerRegistry::instance()->mapLayer( lItem->layerID() ); + if ( !mapLayer ) return; + + QString label = lItem->userText().isEmpty() ? mapLayer->name() : lItem->userText(); + + QgsVectorLayer* vLayer = qobject_cast( mapLayer ); + if ( vLayer ) + { + addVectorLayerItemsV2( lItem, vLayer ); + if ( lItem->showFeatureCount() ) + { + label += QString( " [%1]" ).arg( vLayer->featureCount() ); + } + } + lItem->setText( label ); +} void QgsLegendModel::removeLayer( const QString& layerId ) { @@ -305,17 +555,11 @@ void QgsLegendModel::removeLayer( const QString& layerId ) void QgsLegendModel::addLayer( QgsMapLayer* theMapLayer, double scaleDenominator, QString rule, QStandardItem* parentItem ) { - Q_UNUSED( rule ); - if ( !theMapLayer ) { return; } - if ( scaleDenominator != -1 && theMapLayer->hasScaleBasedVisibility() && - ( theMapLayer->minimumScale() > scaleDenominator || theMapLayer->maximumScale() < scaleDenominator ) ) - return; - if ( !parentItem ) parentItem = invisibleRootItem(); @@ -326,18 +570,29 @@ void QgsLegendModel::addLayer( QgsMapLayer* theMapLayer, double scaleDenominator layerItem->setUserText( theMapLayer->title() ); } layerItem->setLayerID( theMapLayer->id() ); + layerItem->setDefaultStyle( scaleDenominator, rule ); layerItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable ); QList itemsList; itemsList << layerItem << new QgsComposerStyleItem( layerItem ); parentItem->appendRow( itemsList ); - // theMapLayer->legend()->createLegendModelItems( layerItem ); - - if ( theMapLayer->type() == QgsMapLayer::VectorLayer ) + switch ( theMapLayer->type() ) { - // hide title by default for single symbol - layerItem->setStyle( layerItem->rowCount() > 1 ? QgsComposerLegendStyle::Subgroup : QgsComposerLegendStyle::Hidden ); + case QgsMapLayer::VectorLayer: + { + QgsVectorLayer* vl = dynamic_cast( theMapLayer ); + if ( vl ) + { + addVectorLayerItemsV2( layerItem, vl, scaleDenominator, rule ); + } + break; + } + case QgsMapLayer::RasterLayer: + addRasterLayerItems( layerItem, theMapLayer ); + break; + default: + break; } if ( mAutoUpdate ) diff --git a/src/core/composer/qgslegendmodel.h b/src/core/composer/qgslegendmodel.h index 9e01fc9a8eb..95db3fc558e 100644 --- a/src/core/composer/qgslegendmodel.h +++ b/src/core/composer/qgslegendmodel.h @@ -24,7 +24,6 @@ class QDomDocument; class QDomElement; -class QgsComposerLayerItem; class QgsLayerTreeGroup; class QgsMapLayer; class QgsSymbolV2; @@ -115,6 +114,16 @@ class CORE_EXPORT QgsLegendModel : public QStandardItemModel void layersChanged(); private: + /**Adds classification items of vector layers using new symbology*/ + int addVectorLayerItemsV2( QStandardItem* layerItem, QgsVectorLayer* vlayer, double scaleDenominator = -1, QString rule = "" ); + + /**Adds item of raster layer + @return 0 in case of success*/ + int addRasterLayerItems( QStandardItem* layerItem, QgsMapLayer* rlayer ); + + void updateLayerItemText( QStandardItem* layerItem ); + void updateSymbolV2ItemText( QStandardItem* symbolItem ); + void updateRasterSymbolItemText( QStandardItem* symbolItem ); void addGroupFromLayerTree( QgsLayerTreeGroup* parentGroup, QStandardItem* parentItem );