Skip to content

Commit

Permalink
Add load and saving a Layer Definition file. Fix #9688
Browse files Browse the repository at this point in the history
  • Loading branch information
NathanW2 committed Mar 9, 2014
1 parent 1ee6703 commit 3c38721
Show file tree
Hide file tree
Showing 7 changed files with 129 additions and 1 deletion.
12 changes: 12 additions & 0 deletions python/core/qgsmaplayer.sip
Expand Up @@ -204,6 +204,18 @@ class QgsMapLayer : QObject
*/
bool writeLayerXML( QDomElement& layerElement, QDomDocument& document );

/** Returns the layer as a layer definition document
Layer definitions store the data source as well as styling and custom properties.

Layer definitions can be used to load a layer and styling all from a single file.
*/
QDomDocument asLayerDefinition ( );

/** Creates a new layer from a layer defininition document
*/
static QgsMapLayer* fromLayerDefinition( QDomDocument& document );
static QgsMapLayer* fromLayerDefinitionFile(const QString qlrfile );

/** Set a custom property for layer. Properties are stored in a map and saved in project file.
* @note Added in v1.4 */
void setCustomProperty( const QString& key, const QVariant& value );
Expand Down
2 changes: 2 additions & 0 deletions src/app/legend/qgslegendlayer.cpp
Expand Up @@ -435,6 +435,7 @@ void QgsLegendLayer::addToPopupMenu( QMenu& theMenu )

// save as vector file
theMenu.addAction( tr( "Save As..." ), QgisApp::instance(), SLOT( saveAsFile() ) );
theMenu.addAction( tr( "Save As Layer Definition File..." ), QgisApp::instance(), SLOT( saveAsLayerDefinition() ) );

if ( !vlayer->isEditable() && vlayer->dataProvider()->supportsSubsetString() && vlayer->vectorJoins().isEmpty() )
theMenu.addAction( tr( "&Filter..." ), QgisApp::instance(), SLOT( layerSubsetString() ) );
Expand All @@ -450,6 +451,7 @@ void QgsLegendLayer::addToPopupMenu( QMenu& theMenu )
else if ( lyr->type() == QgsMapLayer::RasterLayer )
{
theMenu.addAction( tr( "Save As..." ), QgisApp::instance(), SLOT( saveAsRasterFile() ) );
theMenu.addAction( tr( "Save As Layer Definition File..." ), QgisApp::instance(), SLOT( saveAsLayerDefinition() ) );
}
else if ( lyr->type() == QgsMapLayer::PluginLayer && legend()->selectedLayers().count() == 1 )
{
Expand Down
32 changes: 32 additions & 0 deletions src/app/qgisapp.cpp
Expand Up @@ -1050,6 +1050,7 @@ void QgisApp::createActions()
connect( mActionNewSpatiaLiteLayer, SIGNAL( triggered() ), this, SLOT( newSpatialiteLayer() ) );
connect( mActionShowRasterCalculator, SIGNAL( triggered() ), this, SLOT( showRasterCalculator() ) );
connect( mActionEmbedLayers, SIGNAL( triggered() ) , this, SLOT( embedLayers() ) );
connect( mActionAddLayerDefinition, SIGNAL( triggered() ), this, SLOT( addLayerDefinition () ) );
connect( mActionAddOgrLayer, SIGNAL( triggered() ), this, SLOT( addVectorLayer() ) );
connect( mActionAddRasterLayer, SIGNAL( triggered() ), this, SLOT( addRasterLayer() ) );
connect( mActionAddPgLayer, SIGNAL( triggered() ), this, SLOT( addDatabaseLayer() ) );
Expand Down Expand Up @@ -2456,6 +2457,17 @@ void QgisApp::about()
abt->activateWindow();
}

void QgisApp::addLayerDefinition ()
{
QString path = QFileDialog::getOpenFileName( this, "Add Layer Definition File", QDir::home().path(), "*.qlr" );
if ( path.isEmpty() )
return;

QgsMapLayer* layer = QgsMapLayer::fromLayerDefinitionFile( path );
if ( layer && layer->isValid() )
QgsMapLayerRegistry::instance()->addMapLayer( layer );
}

/**
This method prompts the user for a list of vector file names with a dialog.
*/
Expand Down Expand Up @@ -4590,6 +4602,26 @@ void QgisApp::saveAsFile()
}
}

void QgisApp::saveAsLayerDefinition()
{
QgsMapLayer* layer = activeLayer();
if ( !layer )
return;

QString path = QFileDialog::getSaveFileName( this, "Save as Layer Definition File", QDir::home().path(), "*.qlr" );
QgsDebugMsg( path );
if ( path.isEmpty() )
return;

QDomDocument doc = layer->asLayerDefinition();
QFile file( path );
if ( file.open( QFile::WriteOnly | QFile::Truncate ) )
{
QTextStream qlayerstream( &file );
doc.save( qlayerstream, 2 );
}
}

void QgisApp::saveAsVectorFileGeneral( QgsVectorLayer* vlayer, bool symbologyOption )
{
if ( !mMapLegend )
Expand Down
4 changes: 4 additions & 0 deletions src/app/qgisapp.h
Expand Up @@ -1019,6 +1019,8 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
void hasCrsTransformEnabled( bool theFlag );
void destinationCrsChanged();
// void debugHook();
//! Add a Layer Definition file
void addLayerDefinition ();
//! Add a vector layer to the map
void addVectorLayer();
//! Exit Qgis
Expand Down Expand Up @@ -1087,6 +1089,8 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
//! save current vector layer
void saveAsFile();

void saveAsLayerDefinition();

//! save current raster layer
void saveAsRasterFile();

Expand Down
60 changes: 60 additions & 0 deletions src/core/qgsmaplayer.cpp
Expand Up @@ -36,9 +36,12 @@
#include "qgscoordinatereferencesystem.h"
#include "qgsapplication.h"
#include "qgsproject.h"
#include "qgspluginlayerregistry.h"
#include "qgsprojectfiletransform.h"
#include "qgsdatasourceuri.h"
#include "qgsvectorlayer.h"
#include "qgsrasterlayer.h"
#include "qgspluginlayer.h"
#include "qgsproviderregistry.h"

QgsMapLayer::QgsMapLayer( QgsMapLayer::LayerType type,
Expand Down Expand Up @@ -574,6 +577,63 @@ bool QgsMapLayer::writeLayerXML( QDomElement& layerElement, QDomDocument& docume

} // bool QgsMapLayer::writeXML

QDomDocument QgsMapLayer::asLayerDefinition ()
{
QDomDocument doc( "qgis-layer-definition");
QDomElement maplayer = doc.createElement( "maplayer" );
this->writeLayerXML( maplayer, doc );
maplayer.removeChild( maplayer.firstChildElement( "id" ) );
doc.appendChild( maplayer );
return doc;
}

QgsMapLayer* QgsMapLayer::fromLayerDefinition( QDomDocument& document )
{
QDomNode layernode = document.elementsByTagName( "maplayer" ).at(0);
QDomElement layerElem = layernode.toElement();

QString type = layerElem.attribute( "type" );
QgsDebugMsg(type);
QgsMapLayer *layer = NULL;

if ( type == "vector" )
{
layer = new QgsVectorLayer;
}
else if ( type == "raster" )
{
layer = new QgsRasterLayer;
}
else if ( type == "plugin" )
{
QString typeName = layerElem.attribute( "name" );
layer = QgsPluginLayerRegistry::instance()->createLayer( typeName );
}

bool ok = layer->readLayerXML( layerElem );
if ( ok )
return layer;
}

QgsMapLayer* QgsMapLayer::fromLayerDefinitionFile( const QString qlrfile )
{
QFile file( qlrfile );
if ( !file.open( QIODevice::ReadOnly ) )
{
QgsDebugMsg("Can't open file");
return 0;
}

QDomDocument doc;
if ( !doc.setContent( &file ) )
{
QgsDebugMsg("Can't set content");
return 0;
}

return QgsMapLayer::fromLayerDefinition( doc );
}


bool QgsMapLayer::writeXml( QDomNode & layer_node, QDomDocument & document )
{
Expand Down
12 changes: 12 additions & 0 deletions src/core/qgsmaplayer.h
Expand Up @@ -217,6 +217,18 @@ class CORE_EXPORT QgsMapLayer : public QObject
*/
bool writeLayerXML( QDomElement& layerElement, QDomDocument& document );

/** Returns the layer as a layer definition document
Layer definitions store the data source as well as styling and custom properties.
Layer definitions can be used to load a layer and styling all from a single file.
*/
QDomDocument asLayerDefinition ( );

/** Creates a new layer from a layer defininition document
*/
static QgsMapLayer* fromLayerDefinition( QDomDocument& document );
static QgsMapLayer* fromLayerDefinitionFile(const QString qlrfile );

/** Set a custom property for layer. Properties are stored in a map and saved in project file.
* @note Added in v1.4 */
void setCustomProperty( const QString& key, const QVariant& value );
Expand Down
8 changes: 7 additions & 1 deletion src/ui/qgisapp.ui
Expand Up @@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>1050</width>
<height>487</height>
<height>506</height>
</rect>
</property>
<widget class="QWidget" name="centralwidget"/>
Expand Down Expand Up @@ -123,6 +123,7 @@
</widget>
<addaction name="mNewLayerMenu"/>
<addaction name="mActionEmbedLayers"/>
<addaction name="mActionAddLayerDefinition"/>
<addaction name="mActionAddOgrLayer"/>
<addaction name="mActionAddRasterLayer"/>
<addaction name="mActionAddPgLayer"/>
Expand Down Expand Up @@ -2160,6 +2161,11 @@ Acts on currently active editable layer</string>
<action name="mActionResetUIdefaults">
<property name="text">
<string>Reset UI defaults</string>
</property>
</action>
<action name="mActionAddLayerDefinition">
<property name="text">
<string>Add from Layer Definition File..</string>
</property>
</action>
</widget>
Expand Down

0 comments on commit 3c38721

Please sign in to comment.