27 #include <QInputDialog> 40 layerRec.expandedLayerNode = nodeLayer->
isExpanded();
41 layerRec.expandedLegendItems = nodeLayer->
customProperty( QStringLiteral(
"expandedLegendNodes" ) ).toStringList().toSet();
44 bool hasCheckableItems =
false;
45 bool someItemsUnchecked =
false;
46 QSet<QString> checkedItems;
49 if ( legendNode->
flags() & Qt::ItemIsUserCheckable )
51 hasCheckableItems =
true;
53 if ( legendNode->
data( Qt::CheckStateRole ).toInt() == Qt::Checked )
56 someItemsUnchecked =
true;
60 if ( hasCheckableItems && someItemsUnchecked )
62 layerRec.usingLegendItems =
true;
63 layerRec.checkedLegendItems = checkedItems;
73 lst.prepend( node->
name() );
76 return lst.join(
'/' );
87 rec.mExpandedGroupNodes.insert( _groupId( node ) );
93 rec.mLayerRecords << createThemeLayerRecord( nodeLayer, model );
110 if ( lr.
layer() == layer )
122 bool isVisible = findRecordForLayer( nodeLayer->
layer(), rec, layerRec );
145 Qt::CheckState shouldHaveState = layerRec.
checkedLegendItems.contains( ruleKey ) ? Qt::Checked : Qt::Unchecked;
146 if ( ( legendNode->
flags() & Qt::ItemIsUserCheckable ) &&
147 legendNode->
data( Qt::CheckStateRole ).toInt() != shouldHaveState )
148 legendNode->
setData( shouldHaveState, Qt::CheckStateRole );
156 if ( ( legendNode->
flags() & Qt::ItemIsUserCheckable ) &&
157 legendNode->
data( Qt::CheckStateRole ).toInt() != Qt::Checked )
158 legendNode->
setData( Qt::Checked, Qt::CheckStateRole );
202 if ( project == mProject )
214 return QList< QgsMapLayer * >();
224 if ( allLayers.isEmpty() )
227 return visibleLayers;
231 QList< QgsMapLayer * > orderedVisibleLayers;
234 if ( visibleLayers.contains( layer ) )
235 orderedVisibleLayers << layer;
237 return orderedVisibleLayers;
244 return mMapThemes.contains( name );
249 mMapThemes.insert( name, state );
251 reconnectToLayersStyleManager();
258 if ( !mMapThemes.contains( name ) )
261 mMapThemes[name] = state;
263 reconnectToLayersStyleManager();
270 if ( !mMapThemes.contains( name ) )
273 mMapThemes.remove( name );
275 reconnectToLayersStyleManager();
283 reconnectToLayersStyleManager();
289 return mMapThemes.keys();
294 QStringList layerIds;
297 layerIds << layer->
id();
304 QList<QgsMapLayer *> layers;
305 const QList<MapThemeLayerRecord> &recs = mMapThemes.value( name ).mLayerRecords;
307 if ( layerOrder.isEmpty() )
312 if ( layerRec.
layer() )
313 layers << layerRec.
layer();
322 if ( layerRec.
layer() == layer )
323 layers << layerRec.
layer();
335 if ( !vlayer || !vlayer->
renderer() )
348 if ( checked != shouldBeChecked )
356 QMap<QString, QString> styleOverrides;
357 if ( !mMapThemes.contains( presetName ) )
358 return styleOverrides;
360 Q_FOREACH (
const MapThemeLayerRecord &layerRec, mMapThemes.value( presetName ).mLayerRecords )
362 if ( !layerRec.
layer() )
372 applyMapThemeCheckedLegendNodesToLayer( layerRec, layer );
377 styleOverrides[layer->
id()] = layerStyle.
xmlData();
380 return styleOverrides;
383 void QgsMapThemeCollection::reconnectToLayersStyleManager()
387 QSet<QgsMapLayer *> layers;
392 if ( layerRec.
layer() )
393 layers << layerRec.
layer();
407 QDomElement visPresetsElem = doc.firstChildElement( QStringLiteral(
"qgis" ) ).firstChildElement( QStringLiteral(
"visibility-presets" ) );
408 if ( visPresetsElem.isNull() )
411 QDomElement visPresetElem = visPresetsElem.firstChildElement( QStringLiteral(
"visibility-preset" ) );
412 while ( !visPresetElem.isNull() )
414 QHash<QString, MapThemeLayerRecord> layerRecords;
416 bool expandedStateInfo =
false;
417 if ( visPresetElem.hasAttribute( QStringLiteral(
"has-expanded-info" ) ) )
418 expandedStateInfo = visPresetElem.attribute( QStringLiteral(
"has-expanded-info" ) ).toInt();
420 QString presetName = visPresetElem.attribute( QStringLiteral(
"name" ) );
421 QDomElement visPresetLayerElem = visPresetElem.firstChildElement( QStringLiteral(
"layer" ) );
422 while ( !visPresetLayerElem.isNull() )
424 QString layerID = visPresetLayerElem.attribute( QStringLiteral(
"id" ) );
429 if ( visPresetLayerElem.hasAttribute( QStringLiteral(
"style" ) ) )
431 layerRecords[layerID].usingCurrentStyle =
true;
432 layerRecords[layerID].currentStyle = visPresetLayerElem.attribute( QStringLiteral(
"style" ) );
435 if ( visPresetLayerElem.hasAttribute( QStringLiteral(
"expanded" ) ) )
436 layerRecords[layerID].expandedLayerNode = visPresetLayerElem.attribute( QStringLiteral(
"expanded" ) ).toInt();
438 visPresetLayerElem = visPresetLayerElem.nextSiblingElement( QStringLiteral(
"layer" ) );
441 QDomElement checkedLegendNodesElem = visPresetElem.firstChildElement( QStringLiteral(
"checked-legend-nodes" ) );
442 while ( !checkedLegendNodesElem.isNull() )
444 QSet<QString> checkedLegendNodes;
446 QDomElement checkedLegendNodeElem = checkedLegendNodesElem.firstChildElement( QStringLiteral(
"checked-legend-node" ) );
447 while ( !checkedLegendNodeElem.isNull() )
449 checkedLegendNodes << checkedLegendNodeElem.attribute( QStringLiteral(
"id" ) );
450 checkedLegendNodeElem = checkedLegendNodeElem.nextSiblingElement( QStringLiteral(
"checked-legend-node" ) );
453 QString layerID = checkedLegendNodesElem.attribute( QStringLiteral(
"id" ) );
454 if ( mProject->
mapLayer( layerID ) )
456 layerRecords[layerID].usingLegendItems =
true;
457 layerRecords[layerID].checkedLegendItems = checkedLegendNodes;
459 checkedLegendNodesElem = checkedLegendNodesElem.nextSiblingElement( QStringLiteral(
"checked-legend-nodes" ) );
462 QSet<QString> expandedGroupNodes;
463 if ( expandedStateInfo )
466 QDomElement expandedLegendNodesElem = visPresetElem.firstChildElement( QStringLiteral(
"expanded-legend-nodes" ) );
467 while ( !expandedLegendNodesElem.isNull() )
469 QSet<QString> expandedLegendNodes;
471 QDomElement expandedLegendNodeElem = expandedLegendNodesElem.firstChildElement( QStringLiteral(
"expanded-legend-node" ) );
472 while ( !expandedLegendNodeElem.isNull() )
474 expandedLegendNodes << expandedLegendNodeElem.attribute( QStringLiteral(
"id" ) );
475 expandedLegendNodeElem = expandedLegendNodeElem.nextSiblingElement( QStringLiteral(
"expanded-legend-node" ) );
478 QString layerID = expandedLegendNodesElem.attribute( QStringLiteral(
"id" ) );
479 if ( mProject->
mapLayer( layerID ) )
481 layerRecords[layerID].expandedLegendItems = expandedLegendNodes;
483 expandedLegendNodesElem = expandedLegendNodesElem.nextSiblingElement( QStringLiteral(
"expanded-legend-nodes" ) );
487 QDomElement expandedGroupNodesElem = visPresetElem.firstChildElement( QStringLiteral(
"expanded-group-nodes" ) );
488 if ( !expandedGroupNodesElem.isNull() )
490 QDomElement expandedGroupNodeElem = expandedGroupNodesElem.firstChildElement( QStringLiteral(
"expanded-group-node" ) );
491 while ( !expandedGroupNodeElem.isNull() )
493 expandedGroupNodes << expandedGroupNodeElem.attribute( QStringLiteral(
"id" ) );
494 expandedGroupNodeElem = expandedGroupNodeElem.nextSiblingElement( QStringLiteral(
"expanded-group-node" ) );
503 mMapThemes.insert( presetName, rec );
506 visPresetElem = visPresetElem.nextSiblingElement( QStringLiteral(
"visibility-preset" ) );
509 reconnectToLayersStyleManager();
515 QDomElement visPresetsElem = doc.createElement( QStringLiteral(
"visibility-presets" ) );
516 MapThemeRecordMap::const_iterator it = mMapThemes.constBegin();
517 for ( ; it != mMapThemes.constEnd(); ++ it )
519 QString grpName = it.key();
521 QDomElement visPresetElem = doc.createElement( QStringLiteral(
"visibility-preset" ) );
522 visPresetElem.setAttribute( QStringLiteral(
"name" ), grpName );
524 visPresetElem.setAttribute( QStringLiteral(
"has-expanded-info" ), QStringLiteral(
"1" ) );
527 if ( !layerRec.
layer() )
529 QString layerID = layerRec.
layer()->
id();
530 QDomElement layerElem = doc.createElement( QStringLiteral(
"layer" ) );
531 layerElem.setAttribute( QStringLiteral(
"id" ), layerID );
533 layerElem.setAttribute( QStringLiteral(
"style" ), layerRec.
currentStyle );
534 visPresetElem.appendChild( layerElem );
538 QDomElement checkedLegendNodesElem = doc.createElement( QStringLiteral(
"checked-legend-nodes" ) );
539 checkedLegendNodesElem.setAttribute( QStringLiteral(
"id" ), layerID );
542 QDomElement checkedLegendNodeElem = doc.createElement( QStringLiteral(
"checked-legend-node" ) );
543 checkedLegendNodeElem.setAttribute( QStringLiteral(
"id" ), checkedLegendNode );
544 checkedLegendNodesElem.appendChild( checkedLegendNodeElem );
546 visPresetElem.appendChild( checkedLegendNodesElem );
551 layerElem.setAttribute( QStringLiteral(
"expanded" ), layerRec.
expandedLayerNode ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
553 QDomElement expandedLegendNodesElem = doc.createElement( QStringLiteral(
"expanded-legend-nodes" ) );
554 expandedLegendNodesElem.setAttribute( QStringLiteral(
"id" ), layerID );
557 QDomElement expandedLegendNodeElem = doc.createElement( QStringLiteral(
"expanded-legend-node" ) );
558 expandedLegendNodeElem.setAttribute( QStringLiteral(
"id" ), expandedLegendNode );
559 expandedLegendNodesElem.appendChild( expandedLegendNodeElem );
561 visPresetElem.appendChild( expandedLegendNodesElem );
567 QDomElement expandedGroupElems = doc.createElement( QStringLiteral(
"expanded-group-nodes" ) );
569 for (
const QString &groupId : expandedGroupNodes )
571 QDomElement expandedGroupElem = doc.createElement( QStringLiteral(
"expanded-group-node" ) );
572 expandedGroupElem.setAttribute( QStringLiteral(
"id" ), groupId );
573 expandedGroupElems.appendChild( expandedGroupElem );
575 visPresetElem.appendChild( expandedGroupElems );
578 visPresetsElem.appendChild( visPresetElem );
581 doc.firstChildElement( QStringLiteral(
"qgis" ) ).appendChild( visPresetsElem );
584 void QgsMapThemeCollection::registryLayersRemoved(
const QStringList &layerIDs )
588 QSet< QString > changedThemes;
589 MapThemeRecordMap::iterator it = mMapThemes.begin();
590 for ( ; it != mMapThemes.end(); ++it )
593 for (
int i = 0; i < rec.mLayerRecords.count(); ++i )
596 if ( layerRec.
layer() && layerIDs.contains( layerRec.
layer()->
id() ) )
598 rec.mLayerRecords.removeAt( i-- );
599 changedThemes << it.key();
604 Q_FOREACH (
const QString &theme, changedThemes )
611 void QgsMapThemeCollection::layerStyleRenamed(
const QString &oldName,
const QString &newName )
617 QSet< QString > changedThemes;
619 MapThemeRecordMap::iterator it = mMapThemes.begin();
620 for ( ; it != mMapThemes.end(); ++it )
623 for (
int i = 0; i < rec.mLayerRecords.count(); ++i )
631 changedThemes << it.key();
636 Q_FOREACH (
const QString &theme, changedThemes )
645 for (
int i = 0; i < mLayerRecords.length(); ++i )
647 if ( mLayerRecords.at( i ).layer() == layer )
648 mLayerRecords.removeAt( i );
654 mLayerRecords.append( record );
659 QHash<QgsMapLayer *, MapThemeLayerRecord> validSet;
662 if ( layerRec.
layer() )
663 validSet.insert( layerRec.
layer(), layerRec );
Layer tree group node serves as a container for layers and further groups.
static QgsLayerTreeLayer * toLayer(QgsLayerTreeNode *node)
Cast node to a layer.
Base class for all map layer types.
void setLayer(QgsMapLayer *layer)
Sets the map layer for this record.
void setProject(QgsProject *project)
The QgsProject on which this map theme collection works.
virtual QString name() const =0
Returns name of the node.
static bool isGroup(QgsLayerTreeNode *node)
Check whether the node is a valid group node.
void styleRenamed(const QString &oldName, const QString &newName)
Emitted when a style has been renamed.
QSet< QString > expandedGroupNodes() const
Returns a set of group identifiers for group nodes that should have expanded state (other group nodes...
virtual bool legendSymbolItemsCheckable() const
items of symbology items in legend should be checkable
QMap< QString, QString > mapThemeStyleOverrides(const QString &name)
Gets layer style overrides (for QgsMapSettings) of the visible layers for given map theme...
Restore overridden layer style on destruction.
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...
QHash< QgsMapLayer *, QgsMapThemeCollection::MapThemeLayerRecord > validLayerRecords() const
Returns set with only records for valid layers.
QgsMapLayer * layer() const
Returns the map layer associated with this node.
virtual bool setData(const QVariant &value, int role)
Sets some data associated with the item. Default implementation does nothing and returns false...
static QgsLayerTreeGroup * toGroup(QgsLayerTreeNode *node)
Cast node to a group.
QgsMapLayerStyleManager * styleManager() const
Gets access to the layer's style manager.
Individual map theme record of visible layers and styles.
void update(const QString &name, const QgsMapThemeCollection::MapThemeRecord &state)
Updates a map theme within the collection.
virtual QgsLegendSymbolList legendSymbolItems() const
Returns a list of symbology items for the legend.
QList< QgsMapLayer * > checkedLayers() const
Returns a list of any checked layers which belong to this node or its children.
virtual Qt::ItemFlags flags() const
Returns item flags associated with the item. Default implementation returns Qt::ItemIsEnabled.
QList< QgsMapLayer * > mapThemeVisibleLayers(const QString &name) const
Returns the list of layers that are visible for the specified map theme.
void clear()
Remove all map themes from the collection.
void setExpandedGroupNodes(const QSet< QString > &expandedGroupNodes)
Sets a set of group identifiers for group nodes that should have expanded state.
Individual record of a visible layer in a map theme record.
void mapThemesChanged()
Emitted when map themes within the collection are changed.
void setHasExpandedStateInfo(bool hasInfo)
Sets whether the map theme contains valid expanded/collapsed state of nodes.
void removeLayerRecord(QgsMapLayer *layer)
Removes a record for layer if present.
void readXml(const QDomDocument &doc)
Reads the map theme collection state from XML.
void projectChanged()
Emitted when the project changes.
void readFromLayer(QgsMapLayer *layer)
Store layer's active style information in the instance.
bool isVisible() const
Returns whether a node is really visible (ie checked and all its ancestors checked as well) ...
The QgsLayerTreeModel class is model implementation for Qt item views framework.
Stores style information (renderer, opacity, labeling, diagrams etc.) applicable to a map layer...
bool hasMapTheme(const QString &name) const
Returns whether a map theme with a matching name exists.
void mapThemeChanged(const QString &theme)
Emitted when a map theme changes definition.
QList< QgsLayerTreeNode * > children()
Gets list of children of the node. Children are owned by the parent.
QgsMapThemeCollection(QgsProject *project=nullptr)
Create map theme collection that handles themes of the given project.
Rule key of the node (QString)
void removeMapTheme(const QString &name)
Remove an existing map theme from collection.
QgsLayerTreeNode * parent()
Gets pointer to the parent. If parent is a null pointer, the node is a root node. ...
QList< QgsMapLayer * > layerOrder() const
The order in which layers will be rendered on the canvas.
void setLayerRecords(const QList< QgsMapThemeCollection::MapThemeLayerRecord > &records)
Sets layer records for the theme.
QString currentStyle() const
Returns name of the current style.
QSet< QString > checkedLegendItems
Rule keys of check legend items in layer tree model.
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.
QString id() const
Returns the layer's unique ID, which is used to access this layer from QgsProject.
Reads and writes project states.
QList< QgsMapLayer * > masterLayerOrder() const
Returns the master layer order (this will always match the project's QgsProject::layerOrder() )...
virtual bool legendSymbolItemChecked(const QString &key)
items of symbology items in legend is checked
QgsFeatureRenderer * renderer()
Returns renderer.
bool isExpanded() const
Returns whether the node should be shown as expanded or collapsed in GUI.
QgsMapLayer * layer() const
Gets pointer to the associated map layer.
void applyTheme(const QString &name, QgsLayerTreeGroup *root, QgsLayerTreeModel *model)
Apply theme given by its name and modify layer tree, current style of layers and checked legend items...
virtual void checkLegendSymbolItem(const QString &key, bool state=true)
item in symbology was checked
QString xmlData() const
Returns XML content of the style.
void setExpanded(bool expanded)
Sets whether the node should be shown as expanded or collapsed in GUI.
void insert(const QString &name, const QgsMapThemeCollection::MapThemeRecord &state)
Inserts a new map theme to the collection.
void setItemVisibilityCheckedParentRecursive(bool checked)
Check or uncheck a node and all its parents.
QgsMapLayer * layer() const
Returns map layer or null if the layer does not exist anymore.
The class stores information about one class/rule of a vector layer renderer in a unified way that ca...
QgsMapThemeCollection::MapThemeRecord mapThemeState(const QString &name) const
Returns the recorded state of a map theme.
QStringList mapThemeVisibleLayerIds(const QString &name) const
Returns the list of layer IDs that are visible for the specified map theme.
void layersWillBeRemoved(const QStringList &layerIds)
Emitted when one or more layers are about to be removed from the registry.
QgsProject * project()
The QgsProject on which this map theme collection works.
QSet< QString > expandedLegendItems
Rule keys of expanded legend items in layer tree view.
QgsMapLayer * mapLayer(const QString &layerId) const
Retrieve a pointer to a registered layer by layer ID.
QList< QgsMapLayer * > masterVisibleLayers() const
Returns the master list of visible layers.
virtual QVariant data(int role) const =0
Returns data associated with the item. Must be implemented in derived class.
The QgsLegendRendererItem class is abstract interface for legend items returned from QgsMapLayerLegen...
QList< QgsLayerTreeModelLegendNode * > layerLegendNodes(QgsLayerTreeLayer *nodeLayer, bool skipNodeEmbeddedInParent=false)
Returns filtered list of active legend nodes attached to a particular layer node (by default it retur...
void setItemVisibilityChecked(bool checked)
Check or uncheck a node (independently of its ancestors or children)
bool expandedLayerNode
Whether the layer's tree node is expanded (only to be applied if the parent MapThemeRecord has the in...
bool hasExpandedStateInfo() const
Returns whether information about expanded/collapsed state of nodes has been recorded and thus whethe...
QString ruleKey() const
Returns unique identifier of the rule for identification of the item within renderer.
QgsLayerTree * layerTreeRoot() const
Returns pointer to the root (invisible) node of the project's layer tree.
void setOverrideStyle(const QString &style)
Temporarily apply a different style to the layer.
static QgsMapThemeCollection::MapThemeRecord createThemeFromCurrentState(QgsLayerTreeGroup *root, QgsLayerTreeModel *model)
Static method to create theme from the current state of layer visibilities in layer tree...
Management of styles for use with one map layer.
Represents a vector layer which manages a vector based data sets.
QString currentStyle
Name of the current style of the layer.
bool usingCurrentStyle
Whether current style is valid and should be applied.
void writeXml(QDomDocument &doc)
Writes the map theme collection state to XML.
void addLayerRecord(const QgsMapThemeCollection::MapThemeLayerRecord &record)
Add a new record for a layer.
bool setCurrentStyle(const QString &name)
Set a different style as the current style - will apply it to the layer.
bool usingLegendItems
Whether checkedLegendItems should be applied.
QStringList mapThemes() const
Returns a list of existing map theme names.
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.