Add API to write and read custom data to the layer in a .qgs-file.

New signals:
 * void QgsProject::writeMapLayer( QgsMapLayer*, QDomElement&,  QDomDocument& )
 * void QgsProject::readMapLayer( QgsMapLayer*, const QDomElement& )

Changed method signature:
 * bool QgsMapLayer::readXML( const QDomNode& )
   => bool QgsMapLayer::readLayerXML( const QDomElement& )
 * bool QgsMapLayer::writeXML( QDomNode&, QDomDocument& )
   => bool QgsMapLayer::writeLayerXML( QDomElement&, QDomDocument& )
This commit is contained in:
Matthias Kuhn 2013-04-28 10:53:34 +02:00
parent ee4fc4e1a6
commit def681c226
7 changed files with 91 additions and 50 deletions

View File

@ -151,7 +151,7 @@ class QgsMapLayer : QObject
@returns true if successful
*/
bool readXML( const QDomNode& layer_node );
bool readLayerXML( const QDomElement& layerElement );
/** stores state in Dom node
@ -169,7 +169,7 @@ class QgsMapLayer : QObject
@returns true if successful
*/
bool writeXML( QDomNode & layer_node, QDomDocument & document );
bool writeLayerXML( QDomElement& layerElement, QDomDocument & document );
/** Set a custom property for layer. Properties are stored in a map and saved in project file.
* @note Added in v1.4 */
@ -380,12 +380,12 @@ class QgsMapLayer : QObject
\note added in v1.5 */
void setValid( bool valid );
/** called by readXML(), used by children to read state specific to them from
/** called by readLayerXML(), used by children to read state specific to them from
project files.
*/
virtual bool readXml( const QDomNode& layer_node );
/** called by writeXML(), used by children to write state specific to them to
/** called by writeLayerXML(), used by children to write state specific to them to
project files.
*/
virtual bool writeXml( QDomNode & layer_node, QDomDocument & document );

View File

@ -297,6 +297,26 @@ class QgsProject : QObject
//! emitted when project is being written
void writeProject( QDomDocument & );
/**
* Emitted, after the basic initialisation of a layer from the project
* file is done. You can use this signal to read additional information
* from the project file.
*
* @param mapLayer The map layer which is being initialized
* @param layerNode The layer node from the project file
*/
void readMapLayer( QgsMapLayer* mapLayer, const QDomElement& layerNode );
/**
* Emitted, when a layer is being saved. You can use this method to save
* additional information to the layer.
*
* @param mapLayer The map layer which is being initialized
* @param layerNode The layer node from the project file
* @param doc The document
*/
void writeMapLayer( QgsMapLayer* mapLayer, QDomElement& layerElem, QDomDocument& doc );
//! emitted when an old project file is read.
void oldProjectVersionWarning( QString );

View File

@ -157,25 +157,23 @@ void QgsMapLayer::drawLabels( QgsRenderContext& rendererContext )
// QgsDebugMsg("entered.");
}
bool QgsMapLayer::readXML( const QDomNode& layer_node )
bool QgsMapLayer::readLayerXML( const QDomElement& layerElement )
{
QgsCoordinateReferenceSystem savedCRS;
CUSTOM_CRS_VALIDATION savedValidation;
bool layerError;
QDomElement element = layer_node.toElement();
QDomNode mnl;
QDomElement mne;
// read provider
QString provider;
mnl = layer_node.namedItem( "provider" );
mnl = layerElement.namedItem( "provider" );
mne = mnl.toElement();
provider = mne.text();
// set data source
mnl = layer_node.namedItem( "datasource" );
mnl = layerElement.namedItem( "datasource" );
mne = mnl.toElement();
mDataSource = mne.text();
@ -292,10 +290,10 @@ bool QgsMapLayer::readXML( const QDomNode& layer_node )
// Make it the saved CRS to have WMS layer projected correctly.
// We will still overwrite whatever GDAL etc picks up anyway
// further down this function.
mnl = layer_node.namedItem( "layername" );
mnl = layerElement.namedItem( "layername" );
mne = mnl.toElement();
QDomNode srsNode = layer_node.namedItem( "srs" );
QDomNode srsNode = layerElement.namedItem( "srs" );
mCRS->readXML( srsNode );
mCRS->setValidationHint( tr( "Specify CRS for layer %1" ).arg( mne.text() ) );
mCRS->validate();
@ -307,7 +305,7 @@ bool QgsMapLayer::readXML( const QDomNode& layer_node )
QgsCoordinateReferenceSystem::setCustomSrsValidation( NULL );
// now let the children grab what they need from the Dom node.
layerError = !readXml( layer_node );
layerError = !readXml( layerElement );
// overwrite CRS with what we read from project file before the raster/vector
// file readnig functions changed it. They will if projections is specfied in the file.
@ -326,7 +324,7 @@ bool QgsMapLayer::readXML( const QDomNode& layer_node )
//internalName = dataSourceFileInfo.baseName();
// set ID
mnl = layer_node.namedItem( "id" );
mnl = layerElement.namedItem( "id" );
if ( ! mnl.isNull() )
{
mne = mnl.toElement();
@ -337,24 +335,24 @@ bool QgsMapLayer::readXML( const QDomNode& layer_node )
}
// use scale dependent visibility flag
toggleScaleBasedVisibility( element.attribute( "hasScaleBasedVisibilityFlag" ).toInt() == 1 );
setMinimumScale( element.attribute( "minimumScale" ).toFloat() );
setMaximumScale( element.attribute( "maximumScale" ).toFloat() );
toggleScaleBasedVisibility( layerElement.attribute( "hasScaleBasedVisibilityFlag" ).toInt() == 1 );
setMinimumScale( layerElement.attribute( "minimumScale" ).toFloat() );
setMaximumScale( layerElement.attribute( "maximumScale" ).toFloat() );
// set name
mnl = layer_node.namedItem( "layername" );
mnl = layerElement.namedItem( "layername" );
mne = mnl.toElement();
setLayerName( mne.text() );
//title
QDomElement titleElem = layer_node.firstChildElement( "title" );
QDomElement titleElem = layerElement.firstChildElement( "title" );
if ( !titleElem.isNull() )
{
mTitle = titleElem.text();
}
//abstract
QDomElement abstractElem = layer_node.firstChildElement( "abstract" );
QDomElement abstractElem = layerElement.firstChildElement( "abstract" );
if ( !abstractElem.isNull() )
{
mAbstract = abstractElem.text();
@ -372,7 +370,7 @@ bool QgsMapLayer::readXML( const QDomNode& layer_node )
}
#endif
readCustomProperties( layer_node );
readCustomProperties( layerElement );
return true;
} // void QgsMapLayer::readXML
@ -388,22 +386,19 @@ bool QgsMapLayer::readXml( const QDomNode& layer_node )
bool QgsMapLayer::writeXML( QDomNode & layer_node, QDomDocument & document )
bool QgsMapLayer::writeLayerXML( QDomElement& layerElement, QDomDocument& document )
{
// general layer metadata
QDomElement maplayer = document.createElement( "maplayer" );
// use scale dependent visibility flag
maplayer.setAttribute( "hasScaleBasedVisibilityFlag", hasScaleBasedVisibility() ? 1 : 0 );
maplayer.setAttribute( "minimumScale", QString::number( minimumScale() ) );
maplayer.setAttribute( "maximumScale", QString::number( maximumScale() ) );
layerElement.setAttribute( "hasScaleBasedVisibilityFlag", hasScaleBasedVisibility() ? 1 : 0 );
layerElement.setAttribute( "minimumScale", QString::number( minimumScale() ) );
layerElement.setAttribute( "maximumScale", QString::number( maximumScale() ) );
// ID
QDomElement layerId = document.createElement( "id" );
QDomText layerIdText = document.createTextNode( id() );
layerId.appendChild( layerIdText );
maplayer.appendChild( layerId );
layerElement.appendChild( layerId );
// data source
QDomElement dataSource = document.createElement( "datasource" );
@ -440,7 +435,7 @@ bool QgsMapLayer::writeXML( QDomNode & layer_node, QDomDocument & document )
QDomText dataSourceText = document.createTextNode( src );
dataSource.appendChild( dataSourceText );
maplayer.appendChild( dataSource );
layerElement.appendChild( dataSource );
// layer name
@ -458,9 +453,9 @@ bool QgsMapLayer::writeXML( QDomNode & layer_node, QDomDocument & document )
QDomText layerAbstractText = document.createTextNode( abstract() );
layerAbstract.appendChild( layerAbstractText );
maplayer.appendChild( layerName );
maplayer.appendChild( layerTitle );
maplayer.appendChild( layerAbstract );
layerElement.appendChild( layerName );
layerElement.appendChild( layerTitle );
layerElement.appendChild( layerAbstract );
// timestamp if supported
if ( timestamp() > QDateTime() )
@ -468,10 +463,10 @@ bool QgsMapLayer::writeXML( QDomNode & layer_node, QDomDocument & document )
QDomElement stamp = document.createElement( "timestamp" );
QDomText stampText = document.createTextNode( timestamp().toString( Qt::ISODate ) );
stamp.appendChild( stampText );
maplayer.appendChild( stamp );
layerElement.appendChild( stamp );
}
maplayer.appendChild( layerName );
layerElement.appendChild( layerName );
// zorder
// This is no longer stored in the project file. It is superfluous since the layers
@ -480,7 +475,7 @@ bool QgsMapLayer::writeXML( QDomNode & layer_node, QDomDocument & document )
// spatial reference system id
QDomElement mySrsElement = document.createElement( "srs" );
mCRS->writeXML( mySrsElement, document );
maplayer.appendChild( mySrsElement );
layerElement.appendChild( mySrsElement );
#if 0
// <transparencyLevelInt>
@ -492,16 +487,13 @@ bool QgsMapLayer::writeXML( QDomNode & layer_node, QDomDocument & document )
// now append layer node to map layer node
layer_node.appendChild( maplayer );
writeCustomProperties( layerElement, document );
writeCustomProperties( maplayer, document );
return writeXml( maplayer, document );
return writeXml( layerElement, document );
} // bool QgsMapLayer::writeXML
bool QgsMapLayer::writeXml( QDomNode & layer_node, QDomDocument & document )
{
Q_UNUSED( layer_node );

View File

@ -155,7 +155,7 @@ class CORE_EXPORT QgsMapLayer : public QObject
virtual bool isEditable() const;
/** sets state from Dom document
@param layer_node is Dom node corresponding to ``maplayer'' tag
@param layerElement The Dom element corresponding to ``maplayer'' tag
@note
The Dom node corresponds to a Dom document project file XML element read
@ -168,12 +168,12 @@ class CORE_EXPORT QgsMapLayer : public QObject
@returns true if successful
*/
bool readXML( const QDomNode& layer_node );
bool readLayerXML( const QDomElement& layerElement );
/** stores state in Dom node
@param layer_node is Dom node corresponding to ``projectlayers'' tag
@param document is Dom document
@param layerElement is a Dom element corresponding to ``maplayer'' tag
@param document is a the dom document being written
@note
The Dom node corresponds to a Dom document project file XML element to be
@ -186,7 +186,7 @@ class CORE_EXPORT QgsMapLayer : public QObject
@returns true if successful
*/
bool writeXML( QDomNode & layer_node, QDomDocument & document );
bool writeLayerXML( QDomElement& layerElement, QDomDocument& document );
/** Set a custom property for layer. Properties are stored in a map and saved in project file.
* @note Added in v1.4 */
@ -406,12 +406,12 @@ class CORE_EXPORT QgsMapLayer : public QObject
\note added in v1.5 */
void setValid( bool valid );
/** called by readXML(), used by children to read state specific to them from
/** called by readLayerXML(), used by children to read state specific to them from
project files.
*/
virtual bool readXml( const QDomNode& layer_node );
/** called by writeXML(), used by children to write state specific to them to
/** called by writeLayerXML(), used by children to write state specific to them to
project files.
*/
virtual bool writeXml( QDomNode & layer_node, QDomDocument & document );

View File

@ -748,8 +748,10 @@ bool QgsProject::addLayer( const QDomElement& layerElem, QList<QDomNode>& broken
Q_CHECK_PTR( mapLayer );
// have the layer restore state that is stored in Dom node
if ( mapLayer->readXML( layerElem ) && mapLayer->isValid() )
if ( mapLayer->readLayerXML( layerElem ) && mapLayer->isValid() )
{
emit readMapLayer( mapLayer, layerElem );
QList<QgsMapLayer *> myLayers;
myLayers << mapLayer;
QgsMapLayerRegistry::instance()->addMapLayers( myLayers );
@ -1002,7 +1004,14 @@ bool QgsProject::write()
QHash< QString, QPair< QString, bool> >::const_iterator emIt = mEmbeddedLayers.find( ml->id() );
if ( emIt == mEmbeddedLayers.constEnd() )
{
ml->writeXML( projectLayersNode, *doc );
// general layer metadata
QDomElement maplayerElem = doc->createElement( "maplayer" );
ml->writeLayerXML( maplayerElem, *doc );
emit writeMapLayer( ml, maplayerElem, *doc );
projectLayersNode.appendChild( maplayerElem );
}
else //layer defined in an external project file
{

View File

@ -337,6 +337,26 @@ class CORE_EXPORT QgsProject : public QObject
//! emitted when project is being written
void writeProject( QDomDocument & );
/**
* Emitted, after the basic initialisation of a layer from the project
* file is done. You can use this signal to read additional information
* from the project file.
*
* @param mapLayer The map layer which is being initialized
* @param layerNode The layer node from the project file
*/
void readMapLayer( QgsMapLayer* mapLayer, const QDomElement& layerNode );
/**
* Emitted, when a layer is being saved. You can use this method to save
* additional information to the layer.
*
* @param mapLayer The map layer which is being initialized
* @param layerNode The layer node from the project file
* @param doc The document
*/
void writeMapLayer( QgsMapLayer* mapLayer, QDomElement& layerElem, QDomDocument& doc );
//! emitted when the project file has been written and closed
void projectSaved();

View File

@ -473,7 +473,7 @@ void QgsProjectFileTransform::transform1800to1900()
QgsRasterLayer rasterLayer;
// TODO: We have to use more data from project file to read the layer it correctly,
// OTOH, we should not read it until it was converted
rasterLayer.readXML( layerNode );
rasterLayer.readLayerXML( layerNode.toElement() );
convertRasterProperties( mDom, layerNode, rasterPropertiesElem, &rasterLayer );
}