22 #include <QTextStream> 35 : QAbstractItemModel( parent )
36 , mRootNode( rootNode )
37 , mFlags( ShowLegend | AllowLegendChangeState )
38 , mAutoCollapseLegendNodesCount( -1 )
39 , mLegendFilterByScale( 0 )
40 , mLegendMapViewMupp( 0 )
41 , mLegendMapViewDpi( 0 )
42 , mLegendMapViewScale( 0 )
56 if ( !index.isValid() )
59 QObject* obj =
reinterpret_cast<QObject*
>( index.internalPointer() );
92 if ( column < 0 || column >=
columnCount( parent ) ||
93 row < 0 || row >=
rowCount( parent ) )
101 return QModelIndex();
108 return createIndex( row, column, static_cast<QObject*>( n->
children().at( row ) ) );
114 if ( !child.isValid() )
115 return QModelIndex();
128 return QModelIndex();
136 Q_ASSERT( parentNode );
139 if ( !grandParentNode )
140 return QModelIndex();
142 int row = grandParentNode->
children().indexOf( parentNode );
143 Q_ASSERT( row >= 0 );
145 return createIndex( row, 0, static_cast<QObject*>( parentNode ) );
151 if ( !index.isValid() || index.column() > 1 )
158 if ( role == Qt::DisplayRole || role == Qt::EditRole )
167 if ( nodeLayer->
customProperty(
"showFeatureCount", 0 ).toInt() && role == Qt::DisplayRole )
176 else if ( role == Qt::DecorationRole && index.column() == 0 )
227 QPixmap pixmap( icon.pixmap( 16, 16 ) );
229 QPainter painter( &pixmap );
233 icon = QIcon( pixmap );
239 else if ( role == Qt::CheckStateRole )
260 else if ( role == Qt::FontRole )
266 f.setUnderline(
true );
269 else if ( role == Qt::ToolTipRole )
274 return layer->publicSource();
284 if ( !index.isValid() )
286 Qt::ItemFlags rootFlags = 0;
288 rootFlags |= Qt::ItemIsDropEnabled;
295 Qt::ItemFlags f = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
298 f |= Qt::ItemIsEditable;
307 f |= Qt::ItemIsDragEnabled;
311 f |= Qt::ItemIsUserCheckable;
314 f |= Qt::ItemIsDropEnabled;
326 bool res = sym->
setData( value, role );
328 emit dataChanged( index, index );
336 if ( role == Qt::CheckStateRole )
344 layer->
setVisible(( Qt::CheckState )value.toInt() );
351 group->
setVisible(( Qt::CheckState )value.toInt() );
357 else if ( role == Qt::EditRole )
366 emit dataChanged( index, index );
371 emit dataChanged( index, index );
375 return QAbstractItemModel::setData( index, value, role );
381 return QModelIndex();
386 Q_ASSERT( row >= 0 );
387 return index( row, 0, parentIndex );
396 if ( child->
parent() == node )
416 QList<QgsLayerTreeNode*> nodes;
417 foreach ( QModelIndex
index, list )
430 QList<QgsLayerTreeNode*> nodesFinal;
448 return symNode ? symNode->
layerNode() : 0;
475 emit dataChanged( idx, idx );
479 beginRemoveRows( idx, 0, oldNodeCount - 1 );
501 if ( oldIndex.isValid() )
502 emit dataChanged( oldIndex, oldIndex );
503 if ( currentIndex.isValid() )
504 emit dataChanged( currentIndex, currentIndex );
608 beginInsertRows(
node2index( node ), indexFrom, indexTo );
613 QList<QgsLayerTreeNode*> children = node->
children();
614 QList<QgsLayerTreeLayer*> newLayerNodes;
615 for (
int i = indexFrom; i <= indexTo; ++i )
623 return newLayerNodes;
640 beginRemoveRows(
node2index( node ), indexFrom, indexTo );
657 emit dataChanged( index, index );
687 connect( nodeLayer, SIGNAL( layerLoaded() ),
this, SLOT(
nodeLayerLoaded() ) );
717 emit dataChanged( index, index );
731 if ( index.isValid() )
732 emit dataChanged( index, index );
738 if ( !nodeLayer->
layer() )
742 connect( nodeLayer, SIGNAL( layerLoaded() ),
this, SLOT(
nodeLayerLoaded() ) );
762 connect( layer, SIGNAL( legendChanged() ),
this, SLOT(
layerLegendChanged() ), Qt::UniqueConnection );
769 connect( layer, SIGNAL( editingStarted() ),
this, SLOT(
layerNeedsUpdate() ), Qt::UniqueConnection );
770 connect( layer, SIGNAL( editingStopped() ),
this, SLOT(
layerNeedsUpdate() ), Qt::UniqueConnection );
771 connect( layer, SIGNAL( layerModified() ),
this, SLOT(
layerNeedsUpdate() ), Qt::UniqueConnection );
772 connect( layer, SIGNAL( layerNameChanged() ),
this, SLOT(
layerNeedsUpdate() ), Qt::UniqueConnection );
797 disconnect( nodeLayer, 0,
this, 0 );
799 if ( !nodeLayer->
layer() )
810 disconnect( nodeLayer->
layer(), 0,
this, 0 );
864 int count = node->
children().count();
867 emit dataChanged(
index( 0, 0, idx ),
index( count - 1, 0, idx ) );
868 for (
int i = 0; i < count; ++i )
875 return Qt::MoveAction;
881 types <<
"application/qgis.layertreemodeldata";
888 QList<QgsLayerTreeNode*> nodesFinal =
indexes2nodes( indexes,
true );
890 if ( nodesFinal.count() == 0 )
893 QMimeData *
mimeData =
new QMimeData();
896 QDomElement rootElem = doc.createElement(
"layer_tree_model_data" );
899 doc.appendChild( rootElem );
900 QString txt = doc.toString();
902 mimeData->setData(
"application/qgis.layertreemodeldata", txt.toUtf8() );
908 if ( action == Qt::IgnoreAction )
911 if ( !data->hasFormat(
"application/qgis.layertreemodeldata" ) )
921 QByteArray encodedData = data->data(
"application/qgis.layertreemodeldata" );
924 if ( !doc.setContent( QString::fromUtf8( encodedData ) ) )
927 QDomElement rootElem = doc.documentElement();
928 if ( rootElem.tagName() !=
"layer_tree_model_data" )
931 QList<QgsLayerTreeNode*> nodes;
933 QDomElement elem = rootElem.firstChildElement();
934 while ( !elem.isNull() )
940 elem = elem.nextSiblingElement();
943 if ( nodes.count() == 0 )
946 if ( parent.isValid() && row == -1 )
985 return mFlags.testFlag( f );
1000 QList<QgsLayerTreeModelLegendNode*> filtered;
1053 if (
mLegend.contains( nodeLayer ) )
1055 qDeleteAll(
mLegend[nodeLayer].originalNodes );
1056 delete mLegend[nodeLayer].tree;
1064 if ( !nodeL->
layer() )
1076 QList<QgsLayerTreeModelLegendNode*> filteredLstNew =
filterLegendNodes( lstNew );
1078 bool isEmbedded = filteredLstNew.count() == 1 && filteredLstNew[0]->isEmbeddedInParent();
1082 n->setParent(
this );
1095 int count = data.
tree ? data.
tree->
children[0].count() : filteredLstNew.count();
1097 if ( ! isEmbedded ) beginInsertRows(
node2index( nodeL ), 0, count - 1 );
1101 if ( ! isEmbedded ) endInsertRows();
1108 bool hasParentKeys =
false;
1113 hasParentKeys =
true;
1117 if ( !hasParentKeys )
1121 QHash<QString, QgsLayerTreeModelLegendNode*> rule2node;
1122 rule2node[QString()] = 0;
1126 if ( ruleKey.isEmpty() )
1128 if ( rule2node.contains( ruleKey ) )
1130 rule2node[ruleKey] = n;
1159 int row = data.
tree->
children[parentLegendNode].indexOf( legendNode );
1160 return index( row, 0, parentIndex );
1165 int row = data.
tree->
children[0].indexOf( legendNode );
1166 return index( row, 0, parentIndex );
1171 Q_ASSERT( parentIndex.isValid() );
1174 return QModelIndex();
1175 return index( row, 0, parentIndex );
1194 if ( !
mLegend.contains( nL ) )
1207 Q_ASSERT(
mLegend.contains( nL ) );
1210 return createIndex( row, column, static_cast<QObject*>( data.tree->children[0].at( row ) ) );
1212 return createIndex( row, column, static_cast<QObject*>( data.activeNodes.at( row ) ) );
1220 return createIndex( row, column, static_cast<QObject*>( data.
tree->
children[node].at( row ) ) );
1222 return QModelIndex();
1235 int row = data.
tree->
children[grandParentNode].indexOf( parentNode );
1236 return createIndex( row, 0, static_cast<QObject*>( parentNode ) );
1250 return node->
data( role );
1256 Qt::ItemFlags f = node->
flags();
1258 f &= ~Qt::ItemIsUserCheckable;
1272 return QIcon( qvariant_cast<QPixmap>(
mLegend[nodeLayer].activeNodes[0]->
data( Qt::DecorationRole ) ) );
1278 return mLegend.value( nodeLayer ).activeNodes;
int legendNodeRowCount(QgsLayerTreeModelLegendNode *node) const
Layer tree group node serves as a container for layers and further groups.
void legendInvalidateMapBasedData()
double mLegendMapViewMupp
static const QIcon & iconGroup()
void removeChildren(int from, int count)
Remove child nodes from index "from". The nodes will be deleted.
QModelIndex parent(const QModelIndex &child) const override
QList< QgsLayerTreeModelLegendNode * > originalNodes
Data structure for storage of legend nodes.
QModelIndex legendParent(QgsLayerTreeModelLegendNode *legendNode) const
Base class for all map layer types.
void setLayerName(const QString &n)
QModelIndex currentIndex() const
Get index of the item marked as current. Item marked as current is underlined.
QMimeData * mimeData(const QModelIndexList &indexes) const override
QList< QgsLayerTreeModelLegendNode * > layerLegendNodes(QgsLayerTreeLayer *nodeLayer)
Return list of legend nodes attached to a particular layer node.
QIcon legendIconEmbeddedInParent(QgsLayerTreeLayer *nodeLayer) const
Q_DECL_DEPRECATED bool isIndexSymbologyNode(const QModelIndex &index) const
Return true if index represents a legend node (instead of layer node)
QgsMapLayer::LayerType type() const
Get the type of the layer.
void removeLegendFromLayer(QgsLayerTreeLayer *nodeLayer)
void connectToLayer(QgsLayerTreeLayer *nodeLayer)
void setCurrentIndex(const QModelIndex ¤tIndex)
Set index of the current item. May be used by view. Item marked as current is underlined.
QList< QgsLayerTreeNode * > indexes2nodes(const QModelIndexList &list, bool skipInternal=false) const
Convert a list of indexes to a list of layer tree nodes.
LayerLegendTree * tree
Optional pointer to a tree structure - see LayerLegendTree for details.
QgsLayerTreeGroup * rootGroup() const
Return pointer to the root node of the layer tree. Always a non-null pointer.
static const QIcon & iconDefault()
void nodeCustomPropertyChanged(QgsLayerTreeNode *node, const QString &key)
void addLegendToLayer(QgsLayerTreeLayer *nodeL)
static const QIcon & iconPoint()
QVariant customProperty(const QString &key, const QVariant &defaultValue=QVariant()) const
Read a custom property from layer.
QgsMapLayer * layer() const
Qt::ItemFlags legendNodeFlags(QgsLayerTreeModelLegendNode *node) const
virtual bool setData(const QVariant &value, int role)
Set some data associated with the item.
void disconnectFromRootNode()
This class provides qgis with the ability to render raster datasets onto the mapcanvas.
static QIcon getThemeIcon(const QString &theName)
Helper to get a theme icon.
static int _numLayerCount(QgsLayerTreeGroup *group, const QString &layerId)
bool legendEmbeddedInParent(QgsLayerTreeLayer *nodeLayer) const
Structure that stores tree representation of map layer's legend.
Flags flags() const
Return OR-ed combination of model flags.
QList< QgsLayerTreeModelLegendNode * > filterLegendNodes(const QList< QgsLayerTreeModelLegendNode * > &nodes)
Filter nodes from QgsMapLayerLegend according to the current filtering rules.
void recursivelyEmitDataChanged(const QModelIndex &index=QModelIndex())
emit dataChanged() for layer tree node items
static bool _isChildOfNode(QgsLayerTreeNode *child, QgsLayerTreeNode *node)
void legendNodeDataChanged()
virtual Qt::ItemFlags flags() const
Return item flags associated with the item.
static const QIcon & iconPolygon()
QScopedPointer< QgsMapSettings > mLegendFilterByMapSettings
void insertChildNodes(int index, QList< QgsLayerTreeNode * > nodes)
Insert existing nodes at specified position. The nodes must not have a parent yet. The nodes will be owned by this group.
QScopedPointer< QgsMapHitTest > mLegendFilterByMapHitTest
QVariant legendNodeData(QgsLayerTreeModelLegendNode *node, int role) const
Flags mFlags
Set of flags for the model.
virtual bool isEditable() const override
Returns true if the provider is in editing mode.
void tryBuildLegendTree(LayerLegendData &data)
static QPixmap getThemePixmap(const QString &theName)
Helper to get a theme icon as a pixmap.
virtual void writeXML(QDomElement &parentElement)=0
Write layer tree to XML.
void nodeAddedChildren(QgsLayerTreeNode *node, int indexFrom, int indexTo)
QgsLayerTreeGroup * toGroup(QgsLayerTreeNode *node)
Cast node to a group. No type checking is done - use isGroup() to find out whether this operation is ...
void nodeWillAddChildren(QgsLayerTreeNode *node, int indexFrom, int indexTo)
Allow check boxes for legend nodes (if supported by layer's legend)
void connectToLayers(QgsLayerTreeGroup *parentGroup)
void layerLegendChanged()
The QgsMapSettings class contains configuration for rendering of the map.
int rowCount(const QModelIndex &parent=QModelIndex()) const override
Allow renaming of groups and layers.
rule key of the parent legend node - for legends with tree hierarchy (QString). Added in 2...
Qt::CheckState isVisible() const
void disconnectFromLayer(QgsLayerTreeLayer *nodeLayer)
QMap< QgsLayerTreeModelLegendNode *, QgsLayerTreeModelLegendNode * > parents
Pointer to parent for each active node. Top-level nodes have null parent. Pointers are not owned...
QModelIndex legendNode2index(QgsLayerTreeModelLegendNode *legendNode)
Return index for a given legend node.
static const QIcon & iconRaster()
void disconnectFromLayers(QgsLayerTreeGroup *parentGroup)
rule key of the node (QString)
bool hasValidSettings() const
Check whether the map settings are valid and can be used for rendering.
void setLegendFilterByMap(const QgsMapSettings *settings)
Force only display of legend nodes which are valid for given map settings.
int legendRootRowCount(QgsLayerTreeLayer *nL) const
static QgsLayerTreeModelLegendNode * index2legendNode(const QModelIndex &index)
Return legend node for given index.
Qt::DropActions supportedDropActions() const override
QList< QgsLayerTreeLayer * > findLayers() const
Find all layer nodes. Searches recursively the whole sub-tree.
QgsLayerTreeNode * parent()
Get pointer to the parent. If parent is a null pointer, the node is a root node.
bool removeRows(int row, int count, const QModelIndex &parent=QModelIndex()) override
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override
int autoCollapseLegendNodes() const
Return at what number of legend nodes the layer node should be collapsed. -1 means no auto-collapse (...
void legendMapViewData(double *mapUnitsPerPixel, int *dpi, double *scale)
Get hints about map view - to be used in legend nodes.
void setName(const QString &n)
Set group's name.
void setFlags(Flags f)
Set OR-ed combination of model flags.
QgsLayerTreeLayer * layerNode() const
Return pointer to the parent layer node.
The QgsMapLayerLegend class is abstract interface for implementations of legends for one map layer...
int pendingFeatureCount()
returns feature count after commit
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.
QgsLayerTreeGroup * mRootNode
Pointer to the root node of the layer tree. Not owned by the model.
void setVisible(Qt::CheckState visible)
virtual bool isModified() const
Returns true if the provider has been modified since the last commit.
QGis::GeometryType geometryType() const
Returns point, line or polygon.
QMap< QgsLayerTreeModelLegendNode *, QList< QgsLayerTreeModelLegendNode * > > children
List of children for each active node. Top-level nodes are under null pointer key. Pointers are not owned.
static QgsLayerTreeNode * readXML(QDomElement &element)
Read layer tree from XML. Returns new instance.
QString name() const
Get group's name.
Class that runs a hit test with given map settings.
void setLegendFilterByScale(double scaleDenominator)
Force only display of legend nodes which are valid for given scale denominator.
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 setLayerTreeNodeFont(int nodeType, const QFont &font)
Set font for a particular type of layer tree node. nodeType should come from QgsLayerTreeNode::NodeTy...
Qt::CheckState isVisible() const
Return the check state of the group node.
void setFlag(Flag f, bool on=true)
Enable or disable a model flag.
static void applyLayerNodeProperties(QgsLayerTreeLayer *nodeLayer, QList< QgsLayerTreeModelLegendNode * > &nodes)
update according to layer node's custom properties (order of items, user labels for items) ...
QPersistentModelIndex mCurrentIndex
Current index - will be underlined.
Q_DECL_DEPRECATED QPixmap previewAsPixmap(QSize size, QColor bgColor=Qt::white)
Draws a preview of the rasterlayer into a pixmap.
void setRootGroup(QgsLayerTreeGroup *newRootGroup)
Reset the model and use a new root group node.
double mLegendMapViewScale
bool testFlag(Flag f) const
Check whether a flag is enabled.
double mLegendFilterByScale
scale denominator for filtering of legend nodes (<= 0 means no filtering)
void refreshLayerLegend(QgsLayerTreeLayer *nodeLayer)
Force a refresh of legend nodes of a layer node.
void setExpanded(bool expanded)
Set whether the node should be shown as expanded or collapsed in GUI.
void setLegendMapViewData(double mapUnitsPerPixel, int dpi, double scale)
Give the layer tree model hints about the currently associated map view so that legend nodes that use...
QgsMapLayerLegend * legend() const
Can be null.
static const QIcon & iconTable()
QModelIndex node2index(QgsLayerTreeNode *node) const
Return index for a given node. If the node does not belong to the layer tree, the result is undefined...
void setAutoCollapseLegendNodes(int nodeCount)
Set at what number of legend nodes the layer node should be collapsed. Setting -1 disables the auto-c...
leaf node pointing to a layer
static bool _isChildOfNodes(QgsLayerTreeNode *child, QList< QgsLayerTreeNode * > nodes)
bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole) override
int mAutoCollapseLegendNodesCount
Minimal number of nodes when legend should be automatically collapsed. -1 = disabled.
QModelIndex indexOfParentLayerTreeNode(QgsLayerTreeNode *parentNode) const
QgsLayerTreeLayer * toLayer(QgsLayerTreeNode *node)
Cast node to a layer. No type checking is done - use isLayer() to find out whether this operation is ...
void nodeRemovedChildren()
virtual bool isScaleOK(double scale) const
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
QStringList mimeTypes() const override
virtual QVariant data(int role) const =0
Return data associated with the item.
static const QIcon & iconLine()
The QgsLegendRendererItem class is abstract interface for legend items returned from QgsMapLayerLegen...
QgsLayerTreeModel(QgsLayerTreeGroup *rootNode, QObject *parent=0)
Construct a new tree model with given layer tree (root node must not be null pointer).
QgsLayerTreeLayer * findLayer(const QString &layerId) const
Find layer node representing the map layer specified by its ID. Searches recursively the whole sub-tr...
for QgsSymbolV2LegendNode only - legacy rule key (void ptr, to be cast to QgsSymbolV2 ptr) ...
Allow user to set node visibility with a check box.
QFont layerTreeNodeFont(int nodeType) const
Get font for a particular type of layer tree node. nodeType should come from QgsLayerTreeNode::NodeTy...
QgsLayerTreeNode * index2node(const QModelIndex &index) const
Return layer tree node for given index.
container of other groups and layers
int columnCount(const QModelIndex &parent=QModelIndex()) const override
QList< QgsLayerTreeModelLegendNode * > activeNodes
Active legend nodes.
For legends that support it, will show them in a tree instead of a list (needs also ShowLegend)...
QString layerName() const
Q_DECL_DEPRECATED QgsLayerTreeLayer * layerNodeForSymbologyNode(const QModelIndex &index) const
Return layer node to which a legend node belongs to.
Represents a vector layer which manages a vector based data sets.
Will use real preview of raster layer as icon (may be slow)
void setVisible(Qt::CheckState state)
Set check state of the group node - will also update children.
bool isGroup(QgsLayerTreeNode *node)
Check whether the node is a valid group node.
QModelIndex legendRootIndex(int row, int column, QgsLayerTreeLayer *nL) const
static QList< QgsLayerTreeLayer * > _layerNodesInSubtree(QgsLayerTreeNode *node, int indexFrom, int indexTo)
Allow reordering with drag'n'drop.
Add legend nodes for layer nodes.
virtual void invalidateMapBasedData()
Notification from model that information from associated map view has changed.
void nodeWillRemoveChildren(QgsLayerTreeNode *node, int indexFrom, int indexTo)
void nodeLayerWillBeUnloaded()
virtual QList< QgsLayerTreeModelLegendNode * > createLayerTreeModelLegendNodes(QgsLayerTreeLayer *nodeLayer)=0
Return list of legend nodes to be used for a particular layer tree layer node.
QMap< QgsLayerTreeLayer *, LayerLegendData > mLegend
Per layer data about layer's legend nodes.
QModelIndex legendNodeIndex(int row, int column, QgsLayerTreeModelLegendNode *node) const
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
Layer tree node points to a map layer.
void nodeVisibilityChanged(QgsLayerTreeNode *node)
Structure that stores all data associated with one map layer.