29 #include <QApplication> 30 #include <QDomDocument> 31 #include <QDomElement> 34 #include <QMessageBox> 46 QWidgetList topLevelWidgets = QApplication::topLevelWidgets();
57 addGroupFromLayerTree( rootGroup, invisibleRootItem() );
60 void QgsLegendModel::addGroupFromLayerTree(
QgsLayerTreeGroup* parentGroup, QStandardItem* parentItem )
67 QStandardItem* groupItem =
addGroup( nodeGroup->
name(), -1, parentItem );
68 addGroupFromLayerTree( nodeGroup, groupItem );
73 if ( nodeLayer->
layer() )
83 QStandardItem* currentItem = 0;
84 QStandardItem* currentGroupItem = 0;
87 QList< GroupLayerInfo >::const_iterator infoIt = groupInfo.constBegin();
88 for ( ; infoIt != groupInfo.constEnd() && i < invisibleRootItem()->rowCount(); )
90 currentItem = invisibleRootItem()->child( i, 0 );
91 QString infoKey = infoIt->first;
92 if ( infoKey.isNull() )
98 currentGroupItem =
addGroup( infoKey, i );
100 QList<QString> layerList = infoIt->second;
101 QList<QString>::const_iterator groupLayerIt = layerList.constBegin();
102 for ( ; currentItem && ( groupLayerIt != layerList.constEnd() ); ++groupLayerIt )
110 QString layerID = layerItem->
layerID();
111 if ( layerList.contains( layerID ) )
114 currentGroupItem->setChild( currentGroupItem->rowCount(), 0, currentItem );
120 currentItem = invisibleRootItem()->child( i, 0 );
134 QStringList::const_iterator idIter =
mLayerIds.constBegin();
137 for ( ; idIter !=
mLayerIds.constEnd(); ++idIter )
140 addLayer( currentLayer, scaleDenominator, rule );
147 text =
tr(
"Group" );
150 parentItem = invisibleRootItem();
155 if ( position == -1 )
157 position = parentItem->rowCount();
159 QList<QStandardItem *> itemsList;
161 parentItem->insertRow( position, itemsList );
167 int QgsLegendModel::addVectorLayerItemsV2( QStandardItem* layerItem,
QgsVectorLayer* vlayer,
double scaleDenominator, QString rule )
171 if ( !layerItem || !lItem || !vlayer )
191 QgsLegendSymbolList::const_iterator symbolIt = lst.constBegin();
193 for ( ; symbolIt != lst.constEnd(); ++symbolIt )
195 if ( scaleDenominator == -1 && rule.isEmpty() )
206 currentSymbolItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );
207 if ( symbolIt->second )
213 currentSymbolItem->
setSymbolV2( symbolIt->second->clone() );
215 layerItem->setChild( row, 0, currentSymbolItem );
218 updateSymbolV2ItemText( currentSymbolItem );
227 currentSymbolItem->
setSymbolV2( symbolIt->second->clone() );
228 layerItem->setChild( row, 0, currentSymbolItem );
229 currentSymbolItem->setText( symbolIt->first );
236 if ( scaleDenominator == -1 && rule.isEmpty() )
239 for (
int i = layerItem->rowCount() - 1; i >= row; --i )
241 layerItem->removeRow( i );
248 int QgsLegendModel::addRasterLayerItems( QStandardItem* layerItem,
QgsMapLayer* rlayer )
250 if ( !layerItem || !rlayer )
272 if ( !legendGraphic.isNull() )
274 QgsDebugMsg( QString(
"downloaded legend with dimension width:" ) + QString::number( legendGraphic.width() ) + QString(
" and Height:" ) + QString::number( legendGraphic.height() ) );
277 currentSymbolItem->setIcon( QIcon( QPixmap::fromImage( legendGraphic ) ) );
282 currentSymbolItem->setText(
tr(
"No Legend Available" ) );
286 currentSymbolItem->
setColor( QColor() );
287 layerItem->removeRows( 0, layerItem->rowCount() );
288 layerItem->setChild( layerItem->rowCount(), 0, currentSymbolItem );
293 QList< QPair< QString, QColor > >::const_iterator itemIt = rasterItemList.constBegin();
295 for ( ; itemIt != rasterItemList.constEnd(); ++itemIt )
303 currentSymbolItem->setText( currentSymbolItem->
userText() );
308 QPixmap itemPixmap( 20, 20 );
309 itemPixmap.fill( itemIt->second );
310 currentSymbolItem->setIcon( QIcon( itemPixmap ) );
314 QColor itemColor = itemIt->second;
319 if ( rasterRenderer )
321 opacity = rasterRenderer->
opacity() * 255.0;
323 itemColor.setAlpha( opacity );
325 currentSymbolItem->
setColor( itemColor );
327 int currentRowCount = layerItem->rowCount();
328 layerItem->setChild( currentRowCount, 0, currentSymbolItem );
333 for (
int i = layerItem->rowCount() - 1; i >= row; --i )
335 layerItem->removeRow( i );
342 void QgsLegendModel::updateSymbolV2ItemText( QStandardItem* symbolItem )
345 if ( !sv2Item )
return;
348 if ( !lItem )
return;
351 if ( !mapLayer )
return;
354 if ( !vLayer )
return;
357 if ( !renderer )
return;
363 QPair<QString, QgsSymbolV2*> symbol = symbolList.value( symbolItem->row() );
365 QString label = sv2Item->
userText().isEmpty() ? symbol.first : sv2Item->
userText();
367 if ( renderer->
type() ==
"singleSymbol" )
369 if ( !sv2Item->
userText().isEmpty() )
373 else if ( !lItem->
userText().isEmpty() )
377 else if ( !vLayer->
title().isEmpty() )
379 label = vLayer->
title();
383 label = vLayer->
name();
391 if ( symbolList.size() > 1 || !label.isEmpty() )
393 label += QString(
" [%1]" ).arg( vLayer->
featureCount( symbol.second ) );
396 symbolItem->setText( label );
399 void QgsLegendModel::updateRasterSymbolItemText( QStandardItem* symbolItem )
402 if ( !rItem )
return;
405 if ( !lItem )
return;
408 if ( !mapLayer )
return;
411 if ( !rLayer )
return;
415 QString label = rItem->
userText().isEmpty() ? symbol.first : rItem->
userText();
417 symbolItem->setText( label );
458 updateLayerItemText( lItem );
465 updateSymbolV2ItemText( sv2Item );
472 updateRasterSymbolItemText( rItem );
477 cItem->setText( cItem->
userText() );
489 updateLayerItemText( lItem );
494 addVectorLayerItemsV2( lItem, vLayer );
500 addRasterLayerItems( lItem, rLayer );
506 void QgsLegendModel::updateLayerItemText( QStandardItem* layerItem )
509 if ( !lItem )
return;
512 if ( !mapLayer )
return;
519 addVectorLayerItemsV2( lItem, vLayer );
522 label += QString(
" [%1]" ).arg( vLayer->
featureCount() );
525 lItem->setText( label );
530 int numRootItems = rowCount();
531 for (
int i = 0; i < numRootItems ; ++i )
539 if ( layerId == lItem->
layerID() )
546 disconnect( layer, SIGNAL( rendererChanged() ),
this, SLOT(
updateLayer() ) );
564 parentItem = invisibleRootItem();
567 if ( theMapLayer->
title() !=
"" )
569 layerItem->setText( theMapLayer->
title() );
574 layerItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );
576 QList<QStandardItem *> itemsList;
578 parentItem->appendRow( itemsList );
580 switch ( theMapLayer->
type() )
587 addVectorLayerItemsV2( layerItem, vl, scaleDenominator, rule );
592 addRasterLayerItems( layerItem, theMapLayer );
600 connect( theMapLayer, SIGNAL( rendererChanged() ),
this, SLOT(
updateLayer() ) );
608 QString layerId = qobject_cast<
QgsMapLayer*>( QObject::sender() )->
id();
610 for (
int i = 0, n = rowCount(); i < n ; ++i )
613 if ( lItem && layerId == lItem->
layerID() )
624 if ( composerLegendElem.isNull() )
629 QDomElement legendModelElem = doc.createElement(
"Model" );
630 legendModelElem.setAttribute(
"autoUpdate",
mAutoUpdate );
631 int nTopLevelItems = invisibleRootItem()->rowCount();
632 QStandardItem* currentItem = 0;
635 for (
int i = 0; i < nTopLevelItems; ++i )
637 currentItem = invisibleRootItem()->child( i, 0 );
639 if ( currentLegendItem )
641 currentLegendItem->
writeXML( legendModelElem, doc );
645 composerLegendElem.appendChild( legendModelElem );
653 if ( legendModelElem.isNull() )
663 QDomNodeList topLevelItemList = legendModelElem.childNodes();
664 QDomElement currentElem;
666 int nTopLevelItems = topLevelItemList.size();
667 for (
int i = 0; i < nTopLevelItems; ++i )
669 currentElem = topLevelItemList.at( i ).toElement();
670 if ( currentElem.isNull() )
677 if ( currentElem.tagName() ==
"LayerItem" )
681 else if ( currentElem.tagName() ==
"GroupItem" )
691 QList<QStandardItem *> itemsList;
693 appendRow( itemsList );
696 setAutoUpdate( legendModelElem.attribute(
"autoUpdate",
"1" ).toInt() );
702 return Qt::MoveAction;
707 Qt::ItemFlags
flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
708 if ( !index.isValid() )
710 flags |= Qt::ItemIsDropEnabled;
714 QStandardItem* item = itemFromIndex( index );
722 flags |= Qt::ItemIsDragEnabled;
723 flags |= Qt::ItemIsDropEnabled;
727 flags |= Qt::ItemIsDragEnabled;
730 if ( index.column() == 1 && item )
733 QStandardItem* firstColumnItem = 0;
734 if ( item->parent() )
736 firstColumnItem = item->parent()->child( index.row(), 0 );
740 firstColumnItem = QgsLegendModel::item( index.row(), 0 );
749 flags |= Qt::ItemIsEditable;
763 if ( parent.isValid() )
765 for (
int i = row + count - 1; i >= row; --i )
767 QStandardItem* item = itemFromIndex( parent );
776 for (
int i = row + count - 1; i >= row; --i )
786 QMimeData*
mimeData =
new QMimeData();
787 QByteArray encodedData;
789 QDomElement xmlRootElement = xmlDoc.createElement(
"LegendModelDragData" );
790 xmlDoc.appendChild( xmlRootElement );
792 QModelIndexList::const_iterator indexIt = indexes.constBegin();
793 for ( ; indexIt != indexes.constEnd(); ++indexIt )
795 QStandardItem* sItem = itemFromIndex( *indexIt );
801 mItem->
writeXML( xmlRootElement, xmlDoc );
805 mimeData->setData(
"text/xml", xmlDoc.toByteArray() );
821 if ( !data->hasFormat(
"text/xml" ) )
826 QStandardItem* dropIntoItem = 0;
827 if ( parent.isValid() )
829 dropIntoItem = itemFromIndex( parent );
833 dropIntoItem = invisibleRootItem();
837 QByteArray encodedData = data->data(
"text/xml" );
839 xmlDoc.setContent( encodedData );
841 QDomElement dragDataElem = xmlDoc.documentElement();
842 if ( dragDataElem.tagName() !=
"LegendModelDragData" )
847 QDomNodeList nodeList = dragDataElem.childNodes();
848 int nChildNodes = nodeList.size();
849 QDomElement currentElem;
850 QString currentTagName;
853 for (
int i = 0; i < nChildNodes; ++i )
855 currentElem = nodeList.at( i ).toElement();
856 if ( currentElem.isNull() )
860 currentTagName = currentElem.tagName();
861 if ( currentTagName ==
"LayerItem" )
865 else if ( currentTagName ==
"GroupItem" )
873 currentItem->
readXML( currentElem );
877 index = dropIntoItem->rowCount();
883 QList<QStandardItem *> itemsList;
885 dropIntoItem->insertRow( index, itemsList );
906 for (
int i = 0, n = rowCount(); i < n ; ++i )
914 connect( layer, SIGNAL( rendererChanged() ),
this, SLOT(
updateLayer() ) );
927 for (
int i = 0, n = rowCount(); i < n ; ++i )
935 disconnect( layer, SIGNAL( rendererChanged() ),
this, SLOT(
updateLayer() ) );
void removeLayer(const QString &layerId)
Layer tree group node serves as a container for layers and further groups.
virtual void readXML(const QDomElement &itemElem, bool xServerAvailable=true)=0
Read item content from xml.
QgsFeatureRendererV2 * rendererV2()
Return renderer V2.
Base class for all map layer types.
QStandardItem * addGroup(QString text=QString::null, int position=-1, QStandardItem *parentItem=0)
Adds a group.
QgsMapLayer::LayerType type() const
Get the type of the layer.
void setLayerID(const QString &id)
void updateItemText(QStandardItem *item)
Update single item text using item userText and other properties like showFeatureCount.
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override
Implements the drop operation.
QStringList mimeTypes() const override
QgsMapLayer * layer() const
bool mHasTopLevelWindow
True if this application has toplevel windows (normally true).
This class provides qgis with the ability to render raster datasets onto the mapcanvas.
void updateItem(QStandardItem *item)
Tries to automatically update a model entry (e.g.
static QgsMapLayerRegistry * instance()
void setLayerSetAndGroups(QgsLayerTreeGroup *rootGroup)
Set layers and groups from a layer tree.
virtual QgsLegendSymbolList legendSymbolItems(double scaleDenominator=-1, QString rule="")
return a list of item text / symbol
virtual QString userText() const
Qt::ItemFlags flags(const QModelIndex &index) const override
virtual QImage getLegendGraphic(double scale=0, bool forceRefresh=false, const QgsRectangle *visibleExtent=0)
Returns the legend rendered as pixmap.
virtual bool removeRows(int row, int count, const QModelIndex &parent=QModelIndex()) override
Implemented to support drag operations.
void setLayerID(const QString &id)
QgsLayerTreeGroup * toGroup(QgsLayerTreeNode *node)
Cast node to a group. No type checking is done - use isGroup() to find out whether this operation is ...
const QString & name() const
Get the display name of the layer.
static QIcon symbolPreviewIcon(QgsSymbolV2 *symbol, QSize size)
void setDefaultStyle(double scaleDenominator=-1, QString rule="")
void setLayerSet(const QStringList &layerIds, double scaleDenominator=-1, QString rule="")
QgsRasterRenderer * renderer() const
void setAutoUpdate(bool autoUpdate)
virtual void writeXML(QDomElement &elem, QDomDocument &doc) const =0
This class is a base class for nodes in a layer tree.
QString id() const
Get this layer's unique ID, this ID is used to access this layer from map layer registry.
Qt::DropActions supportedDropActions() const override
bool showFeatureCount() const
QString name() const
Get group's name.
bool writeXML(QDomElement &composerLegendElem, QDomDocument &doc) const
QList< QgsLayerTreeNode * > children()
Get list of children of the node. Children are owned by the parent.
bool isLayer(QgsLayerTreeNode *node)
Check whether the node is a valid layer node.
void setSymbolV2(QgsSymbolV2 *s)
Set symbol (takes ownership)
bool mAutoUpdate
True if the legend is auto updated when layers are added or removed from the map canvas.
Abstract base class for the legend item types.
bool readXML(const QDomElement &legendModelElem, const QDomDocument &doc)
bool countSymbolFeatures(bool showProgress=true)
Count features for symbols.
void addLayer(QgsMapLayer *theMapLayer, double scaleDenominator=-1, QString rule="", QStandardItem *parentItem=0)
virtual long featureCount() const
Number of features in the layer.
QgsLayerTreeLayer * toLayer(QgsLayerTreeNode *node)
Cast node to a layer. No type checking is done - use isLayer() to find out whether this operation is ...
virtual ItemType itemType() const =0
void setColor(const QColor &c)
QgsMapLayer * mapLayer(QString theLayerId)
Retrieve a pointer to a loaded layer by id.
QgsRasterDataProvider * dataProvider()
Returns the data provider.
QString providerType() const
[ data provider interface ] Which provider is being used for this Raster Layer?
void updateLayer(QStandardItem *layerItem)
Updates the whole symbology of a layer.
QgsLegendColorList legendSymbologyItems() const
Returns a list with classification items (Text and color)
Represents a vector layer which manages a vector based data sets.
QList< QPair< QString, QgsSymbolV2 * > > QgsLegendSymbolList
bool isGroup(QgsLayerTreeNode *node)
Check whether the node is a valid group node.
const QString & title() const
virtual void setUserText(const QString &text)
Raster renderer pipe that applies colors to a raster.
QMimeData * mimeData(const QModelIndexList &indexes) const override
For the drag operation.
Layer tree node points to a map layer.