mirror of
https://github.com/qgis/QGIS.git
synced 2025-02-26 00:02:08 -05:00
Add group support for QLR files
Add class for handling QLR files. Add sip bindings Funded by Nicholas Duggan
This commit is contained in:
parent
2011951d60
commit
8944ff7a48
11
python/core/qgslayerdefinition.sip
Normal file
11
python/core/qgslayerdefinition.sip
Normal file
@ -0,0 +1,11 @@
|
||||
class CORE_EXPORT QgsLayerDefinition
|
||||
{
|
||||
%TypeHeaderCode
|
||||
#include <qgslayerdefinition.h>
|
||||
%End
|
||||
public:
|
||||
static bool openLayerDefinition( const QString & path, QgsLayerTreeGroup* rootGroup, QString &errorMessage /Out/ );
|
||||
static bool openLayerDefinition( QDomDocument doc, QgsLayerTreeGroup* rootGroup, QString &errorMessage /Out/ );
|
||||
static bool exportLayerDefinition( QString path, QList<QgsLayerTreeNode*> selectedTreeNodes, QString &errorMessage /Out/ );
|
||||
};
|
||||
|
@ -138,6 +138,7 @@
|
||||
#include "qgsgpsinformationwidget.h"
|
||||
#include "qgsguivectorlayertools.h"
|
||||
#include "qgslabelinggui.h"
|
||||
#include "qgslayerdefinition.h"
|
||||
#include "qgslayertree.h"
|
||||
#include "qgslayertreemapcanvasbridge.h"
|
||||
#include "qgslayertreemodel.h"
|
||||
@ -4124,8 +4125,13 @@ void QgisApp::dxfExport()
|
||||
|
||||
void QgisApp::openLayerDefinition( const QString & path )
|
||||
{
|
||||
QList<QgsMapLayer*> layers = QgsMapLayer::fromLayerDefinitionFile( path );
|
||||
QgsMapLayerRegistry::instance()->addMapLayers( layers );
|
||||
QString errorMessage;
|
||||
bool loaded = QgsLayerDefinition::loadLayerDefinition( path, QgsProject::instance()->layerTreeRoot(), errorMessage );
|
||||
if ( !loaded )
|
||||
{
|
||||
QgsDebugMsg( errorMessage );
|
||||
messageBar()->pushMessage( tr( "Error loading layer definition" ), errorMessage, QgsMessageBar::WARNING );
|
||||
}
|
||||
}
|
||||
|
||||
// Open the project file corresponding to the
|
||||
@ -5038,26 +5044,17 @@ void QgisApp::saveAsFile()
|
||||
|
||||
void QgisApp::saveAsLayerDefinition()
|
||||
{
|
||||
QList<QgsMapLayer*> layers = mLayerTreeView->selectedLayers();
|
||||
|
||||
if ( layers.isEmpty() )
|
||||
return;
|
||||
|
||||
QString path = QFileDialog::getSaveFileName( this, "Save as Layer Definition File", QDir::home().path(), "*.qlr" );
|
||||
QgsDebugMsg( path );
|
||||
if ( path.isEmpty() )
|
||||
return;
|
||||
|
||||
if ( !path.endsWith( ".qlr" ) )
|
||||
path = path.append( ".qlr" );
|
||||
|
||||
QFile file( path );
|
||||
QFileInfo fileinfo( file );
|
||||
QDomDocument doc = QgsMapLayer::asLayerDefinition( layers, fileinfo.canonicalFilePath() );
|
||||
if ( file.open( QFile::WriteOnly | QFile::Truncate ) )
|
||||
QString errorMessage;
|
||||
bool saved = QgsLayerDefinition::exportLayerDefinition( path, mLayerTreeView->selectedNodes(), errorMessage );
|
||||
if ( !saved )
|
||||
{
|
||||
QTextStream qlayerstream( &file );
|
||||
doc.save( qlayerstream, 2 );
|
||||
messageBar()->pushMessage( tr( "Error saving layer definintion file" ), errorMessage, QgsMessageBar::WARNING );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -56,6 +56,8 @@ QMenu* QgsAppLayerTreeViewMenuProvider::createContextMenu()
|
||||
if ( mView->selectedNodes( true ).count() >= 2 )
|
||||
menu->addAction( actions->actionGroupSelected( menu ) );
|
||||
|
||||
menu->addAction( tr( "Save As Layer Definition File..." ), QgisApp::instance(), SLOT( saveAsLayerDefinition() ) );
|
||||
|
||||
menu->addAction( actions->actionAddGroup( menu ) );
|
||||
}
|
||||
else if ( QgsLayerTree::isLayer( node ) )
|
||||
|
@ -95,6 +95,7 @@ SET(QGIS_CORE_SRCS
|
||||
qgsgeometryvalidator.cpp
|
||||
qgsgml.cpp
|
||||
qgsgmlschema.cpp
|
||||
qgslayerdefinition.cpp
|
||||
qgslabel.cpp
|
||||
qgslabelattributes.cpp
|
||||
qgslabelsearchtree.cpp
|
||||
@ -480,6 +481,7 @@ SET(QGIS_CORE_HDRS
|
||||
qgsfontutils.h
|
||||
qgsgeometry.h
|
||||
qgsgeometrycache.h
|
||||
qgslayerdefinition.h
|
||||
qgslabel.h
|
||||
qgslabelattributes.h
|
||||
qgslabelsearchtree.h
|
||||
|
122
src/core/qgslayerdefinition.cpp
Normal file
122
src/core/qgslayerdefinition.cpp
Normal file
@ -0,0 +1,122 @@
|
||||
#include <QDomNode>
|
||||
#include <QFileInfo>
|
||||
#include <QFile>
|
||||
#include <QDir>
|
||||
#include <QTextStream>
|
||||
|
||||
#include "qgslogger.h"
|
||||
#include "qgsmaplayer.h"
|
||||
#include "qgslayertree.h"
|
||||
#include "qgsmaplayerregistry.h"
|
||||
#include "qgslayerdefinition.h"
|
||||
|
||||
bool QgsLayerDefinition::loadLayerDefinition( const QString &path, QgsLayerTreeGroup *rootGroup, QString &errorMessage )
|
||||
{
|
||||
QFile file( path );
|
||||
if ( !file.open( QIODevice::ReadOnly ) )
|
||||
{
|
||||
errorMessage = QString( "Can not open file" );
|
||||
return false;
|
||||
}
|
||||
|
||||
QDomDocument doc;
|
||||
QString message;
|
||||
if ( !doc.setContent( &file, &message ) )
|
||||
{
|
||||
errorMessage = message;
|
||||
return false;
|
||||
}
|
||||
|
||||
QFileInfo fileinfo( file );
|
||||
QDir::setCurrent( fileinfo.absoluteDir().path() );
|
||||
|
||||
return loadLayerDefinition( doc, rootGroup, errorMessage );
|
||||
}
|
||||
|
||||
bool QgsLayerDefinition::loadLayerDefinition( QDomDocument doc, QgsLayerTreeGroup *rootGroup, QString &errorMessage )
|
||||
{
|
||||
QgsLayerTreeGroup* root = new QgsLayerTreeGroup;
|
||||
// We have to replace the IDs before we load them because it's too late once they are loaded
|
||||
QDomNodeList ids = doc.elementsByTagName( "id" );
|
||||
for ( int i = 0; i < ids.size(); ++i )
|
||||
{
|
||||
QDomNode idnode = ids.at( i );
|
||||
QDomElement idElem = idnode.toElement();
|
||||
QString oldid = idElem.text();
|
||||
// Strip the date part because we will replace it.
|
||||
QString layername = oldid.left( oldid.length() - 17 );
|
||||
QDateTime dt = QDateTime::currentDateTime();
|
||||
QString newid = layername + dt.toString( "yyyyMMddhhmmsszzz" );
|
||||
idElem.firstChild().setNodeValue( newid );
|
||||
QDomNodeList treeLayerNodes = doc.elementsByTagName( "layer-tree-layer" );
|
||||
|
||||
for ( int i = 0; i < treeLayerNodes.count(); ++i )
|
||||
{
|
||||
QDomNode layerNode = treeLayerNodes.at( i );
|
||||
QDomElement layerElem = layerNode.toElement();
|
||||
if ( layerElem.attribute( "id" ) == oldid )
|
||||
{
|
||||
layerNode.toElement().setAttribute( "id", newid );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QDomElement layerTreeElem = doc.documentElement().firstChildElement( "layer-tree-group" );
|
||||
bool loadInLegend = true;
|
||||
if ( !layerTreeElem.isNull() )
|
||||
{
|
||||
root->readChildrenFromXML( layerTreeElem );
|
||||
loadInLegend = false;
|
||||
}
|
||||
|
||||
QList<QgsMapLayer*> layers = QgsMapLayer::fromLayerDefinition( doc );
|
||||
QgsMapLayerRegistry::instance()->addMapLayers( layers, loadInLegend );
|
||||
|
||||
QList<QgsLayerTreeNode*> nodes = root->children();
|
||||
rootGroup->insertChildNodes( -1, nodes );
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool QgsLayerDefinition::exportLayerDefinition( QString path, QList<QgsLayerTreeNode*> selectedTreeNodes, QString &errorMessage )
|
||||
{
|
||||
if ( !path.endsWith( ".qlr" ) )
|
||||
path = path.append( ".qlr" );
|
||||
|
||||
QFile file( path );
|
||||
QFileInfo fileinfo( file );
|
||||
|
||||
QDomDocument doc( "qgis-layer-definition" );
|
||||
QDomElement qgiselm = doc.createElement( "qlr" );
|
||||
doc.appendChild( qgiselm );
|
||||
QList<QgsLayerTreeNode*> nodes = selectedTreeNodes;
|
||||
QgsLayerTreeGroup* root = new QgsLayerTreeGroup;
|
||||
foreach ( QgsLayerTreeNode* node, nodes )
|
||||
{
|
||||
QgsLayerTreeNode* newnode = node->clone();
|
||||
root->addChildNode( newnode );
|
||||
}
|
||||
root->writeXML( qgiselm );
|
||||
|
||||
QDomElement layerselm = doc.createElement( "maplayers" );
|
||||
QList<QgsLayerTreeLayer*> layers = root->findLayers();
|
||||
foreach ( QgsLayerTreeLayer* layer, layers )
|
||||
{
|
||||
QDomElement layerelm = doc.createElement( "maplayer" );
|
||||
layer->layer()->writeLayerXML( layerelm, doc, fileinfo.canonicalFilePath() );
|
||||
layerselm.appendChild( layerelm );
|
||||
}
|
||||
qgiselm.appendChild( layerselm );
|
||||
|
||||
if ( file.open( QFile::WriteOnly | QFile::Truncate ) )
|
||||
{
|
||||
QTextStream qlayerstream( &file );
|
||||
doc.save( qlayerstream, 2 );
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
errorMessage = file.errorString();
|
||||
return false;
|
||||
}
|
||||
}
|
20
src/core/qgslayerdefinition.h
Normal file
20
src/core/qgslayerdefinition.h
Normal file
@ -0,0 +1,20 @@
|
||||
#ifndef QGSLAYERDEFINITION_H
|
||||
#define QGSLAYERDEFINITION_H
|
||||
|
||||
#include "qgslayertreegroup.h"
|
||||
|
||||
/**
|
||||
* @brief The QgsLayerDefinition class holds generic methods for loading/exporting QLR files.
|
||||
*/
|
||||
class CORE_EXPORT QgsLayerDefinition
|
||||
{
|
||||
public:
|
||||
/* Loads the QLR at path into QGIS. New layers are added to rootGroup and the map layer registry*/
|
||||
static bool loadLayerDefinition( const QString & path, QgsLayerTreeGroup* rootGroup, QString &errorMessage);
|
||||
/* Loads the QLR from the XML document. New layers are added to rootGroup and the map layer registry */
|
||||
static bool loadLayerDefinition( QDomDocument doc, QgsLayerTreeGroup* rootGroup, QString &errorMessage);
|
||||
/* Export the selected layer tree nodes to a QLR file */
|
||||
static bool exportLayerDefinition( QString path, QList<QgsLayerTreeNode*> selectedTreeNodes, QString &errorMessage );
|
||||
};
|
||||
|
||||
#endif // QGSLAYERDEFINITION_H
|
@ -617,15 +617,16 @@ bool QgsMapLayer::writeLayerXML( QDomElement& layerElement, QDomDocument& docume
|
||||
QDomDocument QgsMapLayer::asLayerDefinition( QList<QgsMapLayer *> layers, QString relativeBasePath )
|
||||
{
|
||||
QDomDocument doc( "qgis-layer-definition" );
|
||||
QDomElement qgiselm = doc.createElement( "qlr" );
|
||||
doc.appendChild( qgiselm );
|
||||
QDomElement layerselm = doc.createElement( "maplayers" );
|
||||
foreach ( QgsMapLayer* layer, layers )
|
||||
{
|
||||
QDomElement layerelm = doc.createElement( "maplayer" );
|
||||
layer->writeLayerXML( layerelm, doc, relativeBasePath );
|
||||
layerelm.removeChild( layerelm.firstChildElement( "id" ) );
|
||||
layerselm.appendChild( layerelm );
|
||||
}
|
||||
doc.appendChild( layerselm );
|
||||
qgiselm.appendChild( layerselm );
|
||||
return doc;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user