QGIS API Documentation  2.12.0-Lyon
qgslayerdefinition.cpp
Go to the documentation of this file.
1 #include <QDomNode>
2 #include <QFileInfo>
3 #include <QFile>
4 #include <QDir>
5 #include <QTextStream>
6 
7 #include "qgslogger.h"
8 #include "qgsmaplayer.h"
9 #include "qgslayertree.h"
10 #include "qgsmaplayerregistry.h"
11 #include "qgslayerdefinition.h"
12 
13 bool QgsLayerDefinition::loadLayerDefinition( const QString &path, QgsLayerTreeGroup *rootGroup, QString &errorMessage )
14 {
15  QFile file( path );
16  if ( !file.open( QIODevice::ReadOnly ) )
17  {
18  errorMessage = QLatin1String( "Can not open file" );
19  return false;
20  }
21 
22  QDomDocument doc;
23  QString message;
24  if ( !doc.setContent( &file, &message ) )
25  {
26  errorMessage = message;
27  return false;
28  }
29 
30  QFileInfo fileinfo( file );
31  QDir::setCurrent( fileinfo.absoluteDir().path() );
32 
33  return loadLayerDefinition( doc, rootGroup, errorMessage );
34 }
35 
37 {
38  Q_UNUSED( errorMessage );
39 
41 
42  // We have to replace the IDs before we load them because it's too late once they are loaded
43  QDomNodeList ids = doc.elementsByTagName( "id" );
44  for ( int i = 0; i < ids.size(); ++i )
45  {
46  QDomNode idnode = ids.at( i );
47  QDomElement idElem = idnode.toElement();
48  QString oldid = idElem.text();
49  // Strip the date part because we will replace it.
50  QString layername = oldid.left( oldid.length() - 17 );
52  QString newid = layername + dt.toString( "yyyyMMddhhmmsszzz" ) + QString::number( qrand() );
53  idElem.firstChild().setNodeValue( newid );
54  QDomNodeList treeLayerNodes = doc.elementsByTagName( "layer-tree-layer" );
55 
56  for ( int i = 0; i < treeLayerNodes.count(); ++i )
57  {
58  QDomNode layerNode = treeLayerNodes.at( i );
59  QDomElement layerElem = layerNode.toElement();
60  if ( layerElem.attribute( "id" ) == oldid )
61  {
62  layerNode.toElement().setAttribute( "id", newid );
63  }
64  }
65  }
66 
67  QDomElement layerTreeElem = doc.documentElement().firstChildElement( "layer-tree-group" );
68  bool loadInLegend = true;
69  if ( !layerTreeElem.isNull() )
70  {
71  root->readChildrenFromXML( layerTreeElem );
72  loadInLegend = false;
73  }
74 
76  QgsMapLayerRegistry::instance()->addMapLayers( layers, loadInLegend );
77 
78  QList<QgsLayerTreeNode*> nodes = root->children();
79  Q_FOREACH ( QgsLayerTreeNode *node, nodes )
80  root->takeChild( node );
81  delete root;
82 
83  rootGroup->insertChildNodes( -1, nodes );
84 
85  return true;
86 
87 }
88 
89 bool QgsLayerDefinition::exportLayerDefinition( QString path, const QList<QgsLayerTreeNode*>& selectedTreeNodes, QString &errorMessage )
90 {
91  if ( !path.endsWith( ".qlr" ) )
92  path = path.append( ".qlr" );
93 
94  QFile file( path );
95  QFileInfo fileinfo( file );
96 
97  QDomDocument doc( "qgis-layer-definition" );
98  QDomElement qgiselm = doc.createElement( "qlr" );
99  doc.appendChild( qgiselm );
100  QList<QgsLayerTreeNode*> nodes = selectedTreeNodes;
102  Q_FOREACH ( QgsLayerTreeNode* node, nodes )
103  {
104  QgsLayerTreeNode* newnode = node->clone();
105  root->addChildNode( newnode );
106  }
107  root->writeXML( qgiselm );
108 
109  QDomElement layerselm = doc.createElement( "maplayers" );
110  QList<QgsLayerTreeLayer*> layers = root->findLayers();
111  Q_FOREACH ( QgsLayerTreeLayer* layer, layers )
112  {
113  QDomElement layerelm = doc.createElement( "maplayer" );
114  layer->layer()->writeLayerXML( layerelm, doc, fileinfo.canonicalFilePath() );
115  layerselm.appendChild( layerelm );
116  }
117  qgiselm.appendChild( layerselm );
118 
119  if ( file.open( QFile::WriteOnly | QFile::Truncate ) )
120  {
121  QTextStream qlayerstream( &file );
122  doc.save( qlayerstream, 2 );
123  return true;
124  }
125  else
126  {
127  errorMessage = file.errorString();
128  return false;
129  }
130 }
Layer tree group node serves as a container for layers and further groups.
QString toString(Qt::DateFormat format) const
QString & append(QChar ch)
void readChildrenFromXML(QDomElement &element)
Read children from XML and append them to the group.
QDomNode appendChild(const QDomNode &newChild)
QList< QgsMapLayer * > addMapLayers(const QList< QgsMapLayer * > &theMapLayers, bool addToLegend=true, bool takeOwnership=true)
Add a list of layers to the map of loaded layers.
bool takeChild(QgsLayerTreeNode *node)
Remove a child from a node.
QString attribute(const QString &name, const QString &defValue) const
QgsMapLayer * layer() const
QString errorString() const
virtual QgsLayerTreeNode * clone() const =0
Create a copy of the node. Returns new instance.
QDomElement documentElement() const
bool writeLayerXML(QDomElement &layerElement, QDomDocument &document, const QString &relativeBasePath=QString::null)
Stores state in Dom node.
QDomElement toElement() const
QString canonicalFilePath() const
int count() const
QString number(int n, int base)
QString text() const
QString path() const
void setAttribute(const QString &name, const QString &value)
QList< QgsLayerTreeLayer * > findLayers() const
Find all layer nodes. Searches recursively the whole sub-tree.
QDomNodeList elementsByTagName(const QString &tagname) const
void setNodeValue(const QString &v)
QDir absoluteDir() const
bool endsWith(const QString &s, Qt::CaseSensitivity cs) const
This class is a base class for nodes in a layer tree.
bool setCurrent(const QString &path)
static bool exportLayerDefinition(QString path, const QList< QgsLayerTreeNode * > &selectedTreeNodes, QString &errorMessage)
Export the selected layer tree nodes to a QLR file.
QList< QgsLayerTreeNode * > children()
Get list of children of the node. Children are owned by the parent.
virtual bool open(QFlags< QIODevice::OpenModeFlag > mode)
virtual void writeXML(QDomElement &parentElement) override
Write group (tree) as XML element and add it to the given parent element...
void insertChildNodes(int index, const 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.
bool isNull() const
QDateTime currentDateTime()
void save(QTextStream &str, int indent) const
QDomNode firstChild() const
static QgsMapLayerRegistry * instance()
Returns the instance pointer, creating the object on the first call.
QDomElement firstChildElement(const QString &tagName) const
void addChildNode(QgsLayerTreeNode *node)
Append an existing node. The node must not have a parent yet. The node will be owned by this group...
int length() const
QString left(int n) const
static QList< QgsMapLayer * > fromLayerDefinition(QDomDocument &document)
Creates a new layer from a layer defininition document.
int size() const
QDomElement createElement(const QString &tagName)
static bool loadLayerDefinition(const QString &path, QgsLayerTreeGroup *rootGroup, QString &errorMessage)
Loads the QLR at path into QGIS.
Layer tree node points to a map layer.
QDomNode at(int index) const
bool setContent(const QByteArray &data, bool namespaceProcessing, QString *errorMsg, int *errorLine, int *errorColumn)