22 #include <QDomElement> 25 static void _readOldLegendGroup(
const QDomElement &groupElem,
QgsLayerTreeGroup *parent );
26 static void _readOldLegendLayer(
const QDomElement &layerElem,
QgsLayerTreeGroup *parent );
30 if ( legendElem.isNull() )
33 QDomNodeList legendChildren = legendElem.childNodes();
35 for (
int i = 0; i < legendChildren.size(); ++i )
37 QDomElement currentChildElem = legendChildren.at( i ).toElement();
38 if ( currentChildElem.tagName() == QLatin1String(
"legendlayer" ) )
40 _readOldLegendLayer( currentChildElem, root );
42 else if ( currentChildElem.tagName() == QLatin1String(
"legendgroup" ) )
44 _readOldLegendGroup( currentChildElem, root );
53 static bool _readOldLegendLayerOrderGroup(
const QDomElement &groupElem, QMap<int, QString> &layerIndexes )
55 QDomNodeList legendChildren = groupElem.childNodes();
57 for (
int i = 0; i < legendChildren.size(); ++i )
59 QDomElement currentChildElem = legendChildren.at( i ).toElement();
60 if ( currentChildElem.tagName() == QLatin1String(
"legendlayer" ) )
62 QDomElement layerFileElem = currentChildElem.firstChildElement( QStringLiteral(
"filegroup" ) ).firstChildElement( QStringLiteral(
"legendlayerfile" ) );
64 int layerIndex = currentChildElem.attribute( QStringLiteral(
"drawingOrder" ) ).toInt();
65 if ( layerIndex == -1 )
67 layerIndexes.insert( layerIndex, layerFileElem.attribute( QStringLiteral(
"layerid" ) ) );
69 else if ( currentChildElem.tagName() == QLatin1String(
"legendgroup" ) )
71 if ( !_readOldLegendLayerOrderGroup( currentChildElem, layerIndexes ) )
82 if ( legendElem.isNull() )
85 hasCustomOrder = legendElem.attribute( QStringLiteral(
"updateDrawingOrder" ) ) == QLatin1String(
"false" );
88 QMap<int, QString> layerIndexes;
91 bool res = _readOldLegendLayerOrderGroup( legendElem, layerIndexes );
93 if ( !res && hasCustomOrder )
96 const auto constLayerIndexes = layerIndexes;
97 for (
const QString &layerId : constLayerIndexes )
100 order.append( layerId );
107 static QDomElement _writeOldLegendLayer( QDomDocument &doc,
QgsLayerTreeLayer *nodeLayer,
bool hasCustomOrder,
const QList<QgsMapLayer *> &order )
109 int drawingOrder = -1;
110 if ( hasCustomOrder )
111 drawingOrder = order.indexOf( nodeLayer->
layer() );
113 QDomElement layerElem = doc.createElement( QStringLiteral(
"legendlayer" ) );
114 layerElem.setAttribute( QStringLiteral(
"drawingOrder" ), drawingOrder );
115 layerElem.setAttribute( QStringLiteral(
"open" ), nodeLayer->
isExpanded() ? QStringLiteral(
"true" ) : QStringLiteral(
"false" ) );
117 layerElem.setAttribute( QStringLiteral(
"name" ), nodeLayer->
name() );
118 layerElem.setAttribute( QStringLiteral(
"showFeatureCount" ), nodeLayer->
customProperty( QStringLiteral(
"showFeatureCount" ) ).toInt() );
120 QDomElement fileGroupElem = doc.createElement( QStringLiteral(
"filegroup" ) );
121 fileGroupElem.setAttribute( QStringLiteral(
"open" ), nodeLayer->
isExpanded() ?
"true" :
"false" );
122 fileGroupElem.setAttribute( QStringLiteral(
"hidden" ), QStringLiteral(
"false" ) );
124 QDomElement layerFileElem = doc.createElement( QStringLiteral(
"legendlayerfile" ) );
125 layerFileElem.setAttribute( QStringLiteral(
"isInOverview" ), nodeLayer->
customProperty( QStringLiteral(
"overview" ) ).toInt() );
126 layerFileElem.setAttribute( QStringLiteral(
"layerid" ), nodeLayer->
layerId() );
127 layerFileElem.setAttribute( QStringLiteral(
"visible" ), nodeLayer->
isVisible() ? 1 : 0 );
129 layerElem.appendChild( fileGroupElem );
130 fileGroupElem.appendChild( layerFileElem );
135 static void _writeOldLegendGroupChildren( QDomDocument &doc, QDomElement &groupElem,
QgsLayerTreeGroup *nodeGroup,
bool hasCustomOrder,
const QList<QgsMapLayer *> &order );
137 static QDomElement _writeOldLegendGroup( QDomDocument &doc,
QgsLayerTreeGroup *nodeGroup,
bool hasCustomOrder,
const QList<QgsMapLayer *> &order )
139 QDomElement groupElem = doc.createElement( QStringLiteral(
"legendgroup" ) );
140 groupElem.setAttribute( QStringLiteral(
"open" ), nodeGroup->
isExpanded() ?
"true" :
"false" );
141 groupElem.setAttribute( QStringLiteral(
"name" ), nodeGroup->
name() );
144 if ( nodeGroup->
customProperty( QStringLiteral(
"embedded" ) ).toInt() )
146 groupElem.setAttribute( QStringLiteral(
"embedded" ), 1 );
147 groupElem.setAttribute( QStringLiteral(
"project" ), nodeGroup->
customProperty( QStringLiteral(
"embedded_project" ) ).toString() );
150 _writeOldLegendGroupChildren( doc, groupElem, nodeGroup, hasCustomOrder, order );
155 static void _writeOldLegendGroupChildren( QDomDocument &doc, QDomElement &groupElem,
QgsLayerTreeGroup *nodeGroup,
bool hasCustomOrder,
const QList<QgsMapLayer *> &order )
157 const auto constChildren = nodeGroup->
children();
162 groupElem.appendChild( _writeOldLegendGroup( doc,
QgsLayerTree::toGroup( node ), hasCustomOrder, order ) );
166 groupElem.appendChild( _writeOldLegendLayer( doc,
QgsLayerTree::toLayer( node ), hasCustomOrder, order ) );
174 QDomElement legendElem = doc.createElement( QStringLiteral(
"legend" ) );
175 legendElem.setAttribute( QStringLiteral(
"updateDrawingOrder" ), hasCustomOrder ? QStringLiteral(
"false" ) : QStringLiteral(
"true" ) );
177 _writeOldLegendGroupChildren( doc, legendElem, root, hasCustomOrder, order );
188 return QStringLiteral(
"Qt::Unchecked" );
189 case Qt::PartiallyChecked:
190 return QStringLiteral(
"Qt::PartiallyChecked" );
193 return QStringLiteral(
"Qt::Checked" );
199 if ( txt == QLatin1String(
"Qt::Unchecked" ) )
200 return Qt::Unchecked;
201 else if ( txt == QLatin1String(
"Qt::PartiallyChecked" ) )
202 return Qt::PartiallyChecked;
209 static void _readOldLegendGroup(
const QDomElement &groupElem,
QgsLayerTreeGroup *parent )
211 QDomNodeList groupChildren = groupElem.childNodes();
216 groupNode->
setExpanded( groupElem.attribute( QStringLiteral(
"open" ) ) == QLatin1String(
"true" ) );
218 if ( groupElem.attribute( QStringLiteral(
"embedded" ) ) == QLatin1String(
"1" ) )
221 groupNode->
setCustomProperty( QStringLiteral(
"embedded_project" ), groupElem.attribute( QStringLiteral(
"project" ) ) );
224 for (
int i = 0; i < groupChildren.size(); ++i )
226 QDomElement currentChildElem = groupChildren.at( i ).toElement();
227 if ( currentChildElem.tagName() == QLatin1String(
"legendlayer" ) )
229 _readOldLegendLayer( currentChildElem, groupNode );
231 else if ( currentChildElem.tagName() == QLatin1String(
"legendgroup" ) )
233 _readOldLegendGroup( currentChildElem, groupNode );
240 static void _readOldLegendLayer(
const QDomElement &layerElem,
QgsLayerTreeGroup *parent )
242 QDomElement layerFileElem = layerElem.firstChildElement( QStringLiteral(
"filegroup" ) ).firstChildElement( QStringLiteral(
"legendlayerfile" ) );
243 QString layerId = layerFileElem.attribute( QStringLiteral(
"layerid" ) );
247 layerNode->
setExpanded( layerElem.attribute( QStringLiteral(
"open" ) ) == QLatin1String(
"true" ) );
249 if ( layerFileElem.attribute( QStringLiteral(
"isInOverview" ) ) == QLatin1String(
"1" ) )
252 if ( layerElem.attribute( QStringLiteral(
"embedded" ) ) == QLatin1String(
"1" ) )
255 if ( layerElem.attribute( QStringLiteral(
"showFeatureCount" ) ) == QLatin1String(
"1" ) )
267 const auto constLayerNodes = layerNodes;
282 const auto constLayerNodes = layerNodes;
297 QList<QgsLayerTreeNode *> nodesToRemove;
298 const auto constChildren = group->
children();
306 nodesToRemove << node;
310 const auto constNodesToRemove = nodesToRemove;
317 const QDomNodeList mlNodeList( doc->documentElement()
318 .firstChildElement( QStringLiteral(
"projectlayers" ) )
319 .elementsByTagName( QStringLiteral(
"maplayer" ) ) );
321 std::function<void ( QgsLayerTreeNode * )> _store = [ & ](
QgsLayerTreeNode * node )
328 for (
int i = 0; i < mlNodeList.count(); i++ )
330 QDomNode mlNode( mlNodeList.at( i ) );
331 QString id( mlNode.firstChildElement( QStringLiteral(
"id" ) ).firstChild().nodeValue() );
334 QDomImplementation DomImplementation;
335 QDomDocumentType documentType = DomImplementation.createDocumentType( QStringLiteral(
"qgis" ), QStringLiteral(
"http://mrcc.com/qgis.dtd" ), QStringLiteral(
"SYSTEM" ) );
336 QDomDocument document( documentType );
337 QDomElement element = mlNode.toElement();
338 document.appendChild( element );
340 QTextStream stream( &str );
341 document.save( stream, 4 );
349 const QList<QgsLayerTreeNode *> constChildren( node->children( ) );
350 for (
const auto &childNode : constChildren )
388 const auto constChildren = group->
children();
393 if ( child->customProperty( QStringLiteral(
"embedded" ) ).toInt() )
395 child->setCustomProperty( QStringLiteral(
"embedded-invisible-layers" ),
invisibleLayerList( child ) );
409 const auto constChildren = group->
children();
412 if ( !node->customProperty( QStringLiteral(
"embedded_project" ) ).toString().isEmpty() )
415 QString newPath = project->
writePath( node->customProperty( QStringLiteral(
"embedded_project" ) ).toString() );
416 node->setCustomProperty( QStringLiteral(
"embedded_project" ), newPath );
429 layer.
setCustomProperty( QStringLiteral(
"legend/expressionFilterEnabled" ), enabled );
435 *enabled = layer.
customProperty( QStringLiteral(
"legend/expressionFilterEnabled" ),
"" ).toBool();
436 return layer.
customProperty( QStringLiteral(
"legend/expressionFilter" ),
"" ).toString();
441 const auto constFindLayers = group.
findLayers();
446 if ( exprEnabled && !expr.isEmpty() )
476 static void _collectMapLayers(
const QList<QgsLayerTreeNode *> &nodes, QSet<QgsMapLayer *> &layersSet )
483 if ( nodeLayer->
layer() )
484 layersSet << nodeLayer->
layer();
495 QSet<QgsMapLayer *> layersSet;
496 _collectMapLayers( nodes, layersSet );
510 const QList<QgsLayerTreeNode *> children = tree->
children();
static bool readOldLegendLayerOrder(const QDomElement &legendElem, bool &hasCustomOrder, QStringList &order)
Try to load custom layer order from.
static int countMapLayerInTree(QgsLayerTreeNode *tree, QgsMapLayer *layer)
Returns how many occurrences of a map layer are there in a layer tree.
Layer tree group node serves as a container for layers and further groups.
static bool layersEditable(const QList< QgsLayerTreeLayer *> &layerNodes)
Returns true if any of the layers is editable.
static QgsLayerTreeLayer * toLayer(QgsLayerTreeNode *node)
Cast node to a layer.
Base class for all map layer types.
static void removeInvalidLayers(QgsLayerTreeGroup *group)
Removes layer nodes that refer to invalid layers.
static QString checkStateToXml(Qt::CheckState state)
Convert Qt::CheckState to QString.
static bool isGroup(QgsLayerTreeNode *node)
Check whether the node is a valid group node.
bool itemVisibilityChecked() const
Returns whether a node is checked (independently of its ancestors or children)
void removeAllChildren()
Remove all child nodes.
static QgsLayerTreeGroup * toGroup(QgsLayerTreeNode *node)
Cast node to a group.
QString writePath(const QString &filename) const
Prepare a filename to save it to the project file.
static bool readOldLegend(QgsLayerTreeGroup *root, const QDomElement &legendElem)
Try to load layer tree from.
static bool layersModified(const QList< QgsLayerTreeLayer *> &layerNodes)
Returns true if any of the layers is modified.
void removeChildNode(QgsLayerTreeNode *node)
Remove a child node from this group.
bool isVisible() const
Returns whether a node is really visible (ie checked and all its ancestors checked as well) ...
bool isExpanded() const
Returns whether the node should be shown as expanded or collapsed in GUI.
QString layerId() const
Returns the ID for the map layer associated with this node.
bool isEditable() const FINAL
Returns true if the provider is in editing mode.
QString name() const override
Returns the layer's name.
QString id() const
Returns the layer's unique ID, which is used to access this layer from QgsProject.
QList< QgsLayerTreeNode * > children()
Gets list of children of the node. Children are owned by the parent.
void setOriginalXmlProperties(const QString &originalXmlProperties)
Sets the original XML properties for the layer to originalXmlProperties.
static QDomElement writeOldLegend(QDomDocument &doc, QgsLayerTreeGroup *root, bool hasCustomOrder, const QList< QgsMapLayer *> &order)
Returns.
QgsLayerTreeLayer * insertLayer(int index, QgsMapLayer *layer)
Insert a new layer node for given map layer at specified position.
QgsLayerTreeNode * parent()
Gets pointer to the parent. If parent is nullptr, the node is a root node.
QVariant customProperty(const QString &key, const QVariant &defaultValue=QVariant()) const
Read a custom property from layer. Properties are stored in a map and saved in project file...
static void replaceChildrenOfEmbeddedGroups(QgsLayerTreeGroup *group)
Remove subtree of embedded groups and replaces it with a custom property embedded-visible-layers.
static bool isLayer(const QgsLayerTreeNode *node)
Check whether the node is a valid layer node.
This class is a base class for nodes in a layer tree.
static Qt::CheckState checkStateFromXml(const QString &txt)
Convert QString to Qt::CheckState.
Reads and writes project states.
static bool hasLegendFilterExpression(const QgsLayerTreeGroup &group)
Test if one of the layers in a group has an expression filter.
static QSet< QgsMapLayer * > collectMapLayersRecursive(const QList< QgsLayerTreeNode *> &nodes)
Returns map layers from the given list of layer tree nodes.
void setExpanded(bool expanded)
Sets whether the node should be shown as expanded or collapsed in GUI.
QgsMapLayer * layer() const
Returns the map layer associated with this node.
Leaf node pointing to a layer.
static QgsLayerTreeLayer * insertLayerBelow(QgsLayerTreeGroup *group, const QgsMapLayer *refLayer, QgsMapLayer *layerToInsert)
Insert a QgsMapLayer just below another one.
static void setLegendFilterByExpression(QgsLayerTreeLayer &layer, const QString &expr, bool enabled=true)
Sets the expression filter of a legend layer.
static void storeOriginalLayersProperties(QgsLayerTreeGroup *group, const QDomDocument *doc)
Stores in a layer's originalXmlProperties the layer properties information.
virtual bool isModified() const
Returns true if the provider has been modified since the last commit.
void addChildNode(QgsLayerTreeNode *node)
Append an existing node.
void setItemVisibilityChecked(bool checked)
Check or uncheck a node (independently of its ancestors or children)
QString name() const override
Returns the group's name.
static QgsLayerTreeGroup * firstGroupWithoutCustomProperty(QgsLayerTreeGroup *group, const QString &property)
Returns the first parent which doesn't have the given custom property or the group itself if it doesn...
QList< QgsLayerTreeLayer * > findLayers() const
Find all layer nodes.
QgsLayerTreeLayer * findLayer(QgsMapLayer *layer) const
Find layer node representing the map layer.
Represents a vector layer which manages a vector based data sets.
static QStringList invisibleLayerList(QgsLayerTreeNode *node)
Gets invisible layers.
static QString legendFilterByExpression(const QgsLayerTreeLayer &layer, bool *enabled=nullptr)
Returns the expression filter of a legend layer.
static void updateEmbeddedGroupsProjectPath(QgsLayerTreeGroup *group, const QgsProject *project)
Updates an embedded group from a project.
void setCustomProperty(const QString &key, const QVariant &value)
Sets a custom property for the node. Properties are stored in a map and saved in project file...
Layer tree node points to a map layer.