add API to select section of layer style when reading/writing

This commit is contained in:
Denis Rouzaud 2018-09-07 14:32:59 -04:00 committed by Nyall Dawson
parent 3875adf77f
commit 51e9be0575
18 changed files with 292 additions and 168 deletions

View File

@ -0,0 +1,4 @@
# The following has been generated automatically from src/core/qgsmaplayerstyle.h
QgsMapLayerStyle.StyleCategory.baseClass = QgsMapLayerStyle
QgsMapLayerStyle.StyleCategories.baseClass = QgsMapLayerStyle
StyleCategories = QgsMapLayerStyle # dirty hack since SIP seems to introduce the flags in module

View File

@ -109,10 +109,10 @@ QgsMeshLayer cannot be copied.
virtual QgsMapLayerRenderer *createMapRenderer( QgsRenderContext &rendererContext ) /Factory/;
virtual bool readSymbology( const QDomNode &node, QString &errorMessage, QgsReadWriteContext &context );
virtual bool writeSymbology( QDomNode &node, QDomDocument &doc, QString &errorMessage, const QgsReadWriteContext &context ) const;
virtual bool readSymbology( const QDomNode &node, QString &errorMessage,
QgsReadWriteContext &context, QgsMapLayerStyle::StyleCategories categories = QgsMapLayerStyle::All );
virtual bool writeSymbology( QDomNode &node, QDomDocument &doc, QString &errorMessage,
const QgsReadWriteContext &context, QgsMapLayerStyle::StyleCategories categories = QgsMapLayerStyle::All ) const;
virtual QString encodedSource( const QString &source, const QgsReadWriteContext &context ) const;
virtual QString decodedSource( const QString &source, const QString &provider, const QgsReadWriteContext &context ) const;

View File

@ -503,8 +503,8 @@ Sets state from Dom document
The Dom node corresponds to a Dom document project file XML element read
by :py:class:`QgsProject`.
This, in turn, calls readXml(), which is over-rideable by sub-classes so
that they can read their own specific state from the given Dom node.
This, in turn, calls readXml() (and then readSymbology()), which is over-rideable
by sub-classes so that they can read their own specific state from the given Dom node.
Invoked by :py:func:`QgsProject.read()`
@ -523,8 +523,8 @@ Stores state in Dom node
The Dom node corresponds to a Dom document project file XML element to be
written by :py:class:`QgsProject`.
This, in turn, calls writeXml(), which is over-rideable by sub-classes so
that they can write their own specific state to the given Dom node.
This, in turn, calls writeXml() (and then writeSymbology), which is over-rideable
by sub-classes so that they can write their own specific state to the given Dom node.
Invoked by :py:func:`QgsProject.write()`
@ -783,7 +783,8 @@ Import the properties of this layer from a QDomDocument
.. versionadded:: 2.8
%End
virtual void exportNamedStyle( QDomDocument &doc, QString &errorMsg /Out/ ) const;
virtual void exportNamedStyle( QDomDocument &doc, QString &errorMsg /Out/, QgsReadWriteContext &context,
QgsMapLayerStyle::StyleCategories categories = QgsMapLayerStyle::All ) const;
%Docstring
Export the properties of this layer as named style in a QDomDocument
@ -865,7 +866,8 @@ Attempts to style the layer using the formatting from an SLD type file.
virtual bool readSymbology( const QDomNode &node, QString &errorMessage, QgsReadWriteContext &context ) = 0;
virtual bool readSymbology( const QDomNode &node, QString &errorMessage,
QgsReadWriteContext &context, QgsMapLayerStyle::StyleCategories categories = QgsMapLayerStyle::All ) = 0;
%Docstring
Read the symbology for the current layer from the Dom node supplied.
@ -876,7 +878,8 @@ Read the symbology for the current layer from the Dom node supplied.
:return: true in case of success.
%End
virtual bool readStyle( const QDomNode &node, QString &errorMessage, QgsReadWriteContext &context );
virtual bool readStyle( const QDomNode &node, QString &errorMessage,
QgsReadWriteContext &context, QgsMapLayerStyle::StyleCategories categories = QgsMapLayerStyle::All );
%Docstring
Read the style for the current layer from the Dom node supplied.
@ -893,21 +896,27 @@ Read the style for the current layer from the Dom node supplied.
.. versionadded:: 2.16
%End
virtual bool writeSymbology( QDomNode &node, QDomDocument &doc, QString &errorMessage, const QgsReadWriteContext &context ) const = 0;
virtual bool writeSymbology( QDomNode &node, QDomDocument &doc, QString &errorMessage, const QgsReadWriteContext &context,
QgsMapLayerStyle::StyleCategories categories = QgsMapLayerStyle::All ) const = 0;
%Docstring
Write the symbology for the layer into the docment provided.
Write the style for the layer into the docment provided.
:param node: the node that will have the style element added to it.
:param doc: the document that will have the QDomNode added.
:param errorMessage: reference to string that will be updated with any error messages
:param context: writing context (used for transform from absolute to relative paths)
.. note::
There is a confusion of terms with the GUI. This method actually writes what is called a style in the application.
:return: true in case of success.
%End
virtual bool writeStyle( QDomNode &node, QDomDocument &doc, QString &errorMessage, const QgsReadWriteContext &context ) const;
virtual bool writeStyle( QDomNode &node, QDomDocument &doc, QString &errorMessage, const QgsReadWriteContext &context,
QgsMapLayerStyle::StyleCategories categories = QgsMapLayerStyle::All ) const;
%Docstring
Write just the style information for the layer into the document
Write just the symbology information for the layer into the document
:param node: the node that will have the style element added to it.
:param doc: the document that will have the QDomNode added.
@ -920,6 +929,10 @@ Write just the style information for the layer into the document
To be implemented in subclasses. Default implementation does nothing and returns false.
.. note::
There is a confusion of terms with the GUI. This method actually writes what is known as the symbology in the application.
.. versionadded:: 2.16
%End
@ -1475,14 +1488,17 @@ Read style manager's configuration (if any). To be called by subclasses.
Write style manager's configuration (if exists). To be called by subclasses.
%End
void writeCommonStyle( QDomElement &layerElement, QDomDocument &document, const QgsReadWriteContext &context ) const;
void writeCommonStyle( QDomElement &layerElement, QDomDocument &document,
const QgsReadWriteContext &context,
QgsMapLayerStyle::StyleCategories categories = QgsMapLayerStyle::All ) const;
%Docstring
Write style data common to all layer types
.. versionadded:: 3.0
%End
void readCommonStyle( const QDomElement &layerElement, const QgsReadWriteContext &context );
void readCommonStyle( const QDomElement &layerElement, const QgsReadWriteContext &context,
QgsMapLayerStyle::StyleCategories categories = QgsMapLayerStyle::All );
%Docstring
Read style data common to all layer types

View File

@ -26,6 +26,27 @@ only possible to read or write layer's current style.
#include "qgsmaplayerstyle.h"
%End
public:
static const QMetaObject staticMetaObject;
public:
enum StyleCategory
{
LayerConfiguration,
Symbology,
Labels,
Fields,
Forms,
Actions,
Tooltips,
Diagrams,
AttributeTable,
Rendering,
CustomProperties,
All
};
typedef QFlags<QgsMapLayerStyle::StyleCategory> StyleCategories;
QgsMapLayerStyle();
%Docstring
@ -72,6 +93,9 @@ Write style configuration (for project file writing)
};
QFlags<QgsMapLayerStyle::StyleCategory> operator|(QgsMapLayerStyle::StyleCategory f1, QFlags<QgsMapLayerStyle::StyleCategory> f2);
class QgsMapLayerStyleOverride
{

View File

@ -870,8 +870,8 @@ Returns the current auxiliary layer.
%End
virtual bool readSymbology( const QDomNode &layerNode, QString &errorMessage, QgsReadWriteContext &context );
virtual bool readSymbology( const QDomNode &layerNode, QString &errorMessage,
QgsReadWriteContext &context, QgsMapLayerStyle::StyleCategories categories = QgsMapLayerStyle::All );
%Docstring
Read the symbology for the current layer from the Dom node supplied.
@ -882,8 +882,8 @@ Read the symbology for the current layer from the Dom node supplied.
:return: true in case of success.
%End
virtual bool readStyle( const QDomNode &node, QString &errorMessage, QgsReadWriteContext &context );
virtual bool readStyle( const QDomNode &node, QString &errorMessage,
QgsReadWriteContext &context, QgsMapLayerStyle::StyleCategories categories = QgsMapLayerStyle::All );
%Docstring
Read the style for the current layer from the Dom node supplied.
@ -894,8 +894,8 @@ Read the style for the current layer from the Dom node supplied.
:return: true in case of success.
%End
virtual bool writeSymbology( QDomNode &node, QDomDocument &doc, QString &errorMessage, const QgsReadWriteContext &context ) const;
virtual bool writeSymbology( QDomNode &node, QDomDocument &doc, QString &errorMessage,
const QgsReadWriteContext &context, QgsMapLayerStyle::StyleCategories categories = QgsMapLayerStyle::All ) const;
%Docstring
Write the symbology for the layer into the docment provided.
@ -907,8 +907,8 @@ Write the symbology for the layer into the docment provided.
:return: true in case of success.
%End
virtual bool writeStyle( QDomNode &node, QDomDocument &doc, QString &errorMessage, const QgsReadWriteContext &context ) const;
virtual bool writeStyle( QDomNode &node, QDomDocument &doc, QString &errorMessage,
const QgsReadWriteContext &context, QgsMapLayerStyle::StyleCategories categories = QgsMapLayerStyle::All ) const;
%Docstring
Write just the style information for the layer into the document

View File

@ -348,16 +348,16 @@ Draws a preview of the rasterlayer into a QImage
void showStatusMessage( const QString &message );
protected:
virtual bool readSymbology( const QDomNode &node, QString &errorMessage, QgsReadWriteContext &context );
virtual bool readSymbology( const QDomNode &node, QString &errorMessage, QgsReadWriteContext &context, QgsMapLayerStyle::StyleCategories categories = QgsMapLayerStyle::All );
virtual bool readStyle( const QDomNode &node, QString &errorMessage, QgsReadWriteContext &context );
virtual bool readStyle( const QDomNode &node, QString &errorMessage, QgsReadWriteContext &context, QgsMapLayerStyle::StyleCategories categories = QgsMapLayerStyle::All );
virtual bool readXml( const QDomNode &layer_node, QgsReadWriteContext &context );
virtual bool writeSymbology( QDomNode &, QDomDocument &doc, QString &errorMessage, const QgsReadWriteContext &context ) const;
virtual bool writeStyle( QDomNode &node, QDomDocument &doc, QString &errorMessage, const QgsReadWriteContext &context ) const;
virtual bool writeSymbology( QDomNode &, QDomDocument &doc, QString &errorMessage,
const QgsReadWriteContext &context, QgsMapLayerStyle::StyleCategories categories = QgsMapLayerStyle::All ) const;
virtual bool writeStyle( QDomNode &node, QDomDocument &doc, QString &errorMessage,
const QgsReadWriteContext &context, QgsMapLayerStyle::StyleCategories categories = QgsMapLayerStyle::All ) const;
virtual bool writeXml( QDomNode &layer_node, QDomDocument &doc, const QgsReadWriteContext &context ) const;
virtual QString encodedSource( const QString &source, const QgsReadWriteContext &context ) const;

View File

@ -8855,7 +8855,8 @@ void QgisApp::copyStyle( QgsMapLayer *sourceLayer )
{
QString errorMsg;
QDomDocument doc( QStringLiteral( "qgis" ) );
selectionLayer->exportNamedStyle( doc, errorMsg );
QgsReadWriteContext context;
selectionLayer->exportNamedStyle( doc, errorMsg, context );
if ( !errorMsg.isEmpty() )
@ -9730,7 +9731,8 @@ void QgisApp::duplicateLayers( const QList<QgsMapLayer *> &lyrList )
// duplicate the layer style
QString errMsg;
QDomDocument style;
selectedLyr->exportNamedStyle( style, errMsg );
QgsReadWriteContext context;
selectedLyr->exportNamedStyle( style, errMsg, context );
if ( errMsg.isEmpty() )
dupLayer->importNamedStyle( style, errMsg );
if ( !errMsg.isEmpty() )

View File

@ -242,10 +242,12 @@ QgsMapLayerRenderer *QgsMeshLayer::createMapRenderer( QgsRenderContext &renderer
return new QgsMeshLayerRenderer( this, rendererContext );
}
bool QgsMeshLayer::readSymbology( const QDomNode &node, QString &errorMessage, QgsReadWriteContext &context )
bool QgsMeshLayer::readSymbology( const QDomNode &node, QString &errorMessage,
QgsReadWriteContext &context, QgsMapLayerStyle::StyleCategories categories )
{
Q_UNUSED( errorMessage );
Q_UNUSED( context );
Q_UNUSED( categories );
QDomElement elem = node.toElement();
QDomElement elemRendererSettings = elem.firstChildElement( "mesh-renderer-settings" );
@ -255,10 +257,12 @@ bool QgsMeshLayer::readSymbology( const QDomNode &node, QString &errorMessage, Q
return true;
}
bool QgsMeshLayer::writeSymbology( QDomNode &node, QDomDocument &doc, QString &errorMessage, const QgsReadWriteContext &context ) const
bool QgsMeshLayer::writeSymbology( QDomNode &node, QDomDocument &doc, QString &errorMessage,
const QgsReadWriteContext &context, QgsMapLayerStyle::StyleCategories categories ) const
{
Q_UNUSED( errorMessage );
Q_UNUSED( context );
Q_UNUSED( categories );
QDomElement elem = node.toElement();
QDomElement elemRendererSettings = mRendererSettings.writeXml( doc );

View File

@ -125,8 +125,10 @@ class CORE_EXPORT QgsMeshLayer : public QgsMapLayer
QgsMeshLayer *clone() const override SIP_FACTORY;
QgsRectangle extent() const override;
QgsMapLayerRenderer *createMapRenderer( QgsRenderContext &rendererContext ) override SIP_FACTORY;
bool readSymbology( const QDomNode &node, QString &errorMessage, QgsReadWriteContext &context ) override;
bool writeSymbology( QDomNode &node, QDomDocument &doc, QString &errorMessage, const QgsReadWriteContext &context ) const override;
bool readSymbology( const QDomNode &node, QString &errorMessage,
QgsReadWriteContext &context, QgsMapLayerStyle::StyleCategories categories = QgsMapLayerStyle::All ) override;
bool writeSymbology( QDomNode &node, QDomDocument &doc, QString &errorMessage,
const QgsReadWriteContext &context, QgsMapLayerStyle::StyleCategories categories = QgsMapLayerStyle::All ) const override;
QString encodedSource( const QString &source, const QgsReadWriteContext &context ) const override;
QString decodedSource( const QString &source, const QString &provider, const QgsReadWriteContext &context ) const override;
bool readXml( const QDomNode &layer_node, QgsReadWriteContext &context ) override;

View File

@ -220,7 +220,7 @@ QPainter::CompositionMode QgsMapLayer::blendMode() const
}
bool QgsMapLayer::readLayerXml( const QDomElement &layerElement, QgsReadWriteContext &context )
bool QgsMapLayer::readLayerXml( const QDomElement &layerElement, QgsReadWriteContext &context )
{
bool layerError;
@ -270,10 +270,6 @@ bool QgsMapLayer::readLayerXml( const QDomElement &layerElement, QgsReadWriteCo
savedValidation = QgsCoordinateReferenceSystem::customCrsValidation();
QgsCoordinateReferenceSystem::setCustomCrsValidation( nullptr );
// read custom properties before passing reading further to a subclass, so that
// the subclass can also read custom properties
readCustomProperties( layerElement );
QgsReadWriteContextCategoryPopper p = context.enterCategory( tr( "Layer" ), mne.text() );
// now let the children grab what they need from the Dom node.
@ -306,20 +302,6 @@ bool QgsMapLayer::readLayerXml( const QDomElement &layerElement, QgsReadWriteCo
}
}
// use scale dependent visibility flag
setScaleBasedVisibility( layerElement.attribute( QStringLiteral( "hasScaleBasedVisibilityFlag" ) ).toInt() == 1 );
if ( layerElement.hasAttribute( QStringLiteral( "minimumScale" ) ) )
{
// older element, when scales were reversed
setMaximumScale( layerElement.attribute( QStringLiteral( "minimumScale" ) ).toDouble() );
setMinimumScale( layerElement.attribute( QStringLiteral( "maximumScale" ) ).toDouble() );
}
else
{
setMaximumScale( layerElement.attribute( QStringLiteral( "maxScale" ) ).toDouble() );
setMinimumScale( layerElement.attribute( QStringLiteral( "minScale" ) ).toDouble() );
}
setAutoRefreshInterval( layerElement.attribute( QStringLiteral( "autoRefreshTime" ), QStringLiteral( "0" ) ).toInt() );
setAutoRefreshEnabled( layerElement.attribute( QStringLiteral( "autoRefreshEnabled" ), QStringLiteral( "0" ) ).toInt() );
setRefreshOnNofifyMessage( layerElement.attribute( QStringLiteral( "refreshOnNotifyMessage" ), QString() ) );
@ -403,25 +385,6 @@ bool QgsMapLayer::readLayerXml( const QDomElement &layerElement, QgsReadWriteCo
QDomElement metadataElem = layerElement.firstChildElement( QStringLiteral( "resourceMetadata" ) );
mMetadata.readMetadataXml( metadataElem );
// flags
QDomElement flagsElem = layerElement.firstChildElement( QStringLiteral( "flags" ) );
QMetaEnum metaEnum = QMetaEnum::fromType<QgsMapLayer::LayerFlag>();
LayerFlags flags = mFlags;
for ( int idx = 0; idx < metaEnum.keyCount(); ++idx )
{
const char *enumKey = metaEnum.key( idx );
QDomNode flagNode = flagsElem.namedItem( QString( enumKey ) );
if ( flagNode.isNull() )
continue;
bool flagValue = flagNode.toElement().text() == "1" ? true : false;
QgsMapLayer::LayerFlag enumValue = static_cast<QgsMapLayer::LayerFlag>( metaEnum.keyToValue( enumKey ) );
if ( flags.testFlag( enumValue ) && !flagValue )
flags &= ~enumValue;
else if ( !flags.testFlag( enumValue ) && flagValue )
flags |= enumValue;
}
setFlags( flags );
return true;
} // bool QgsMapLayer::readLayerXML
@ -436,14 +399,8 @@ bool QgsMapLayer::readXml( const QDomNode &layer_node, QgsReadWriteContext &cont
} // void QgsMapLayer::readXml
bool QgsMapLayer::writeLayerXml( QDomElement &layerElement, QDomDocument &document, const QgsReadWriteContext &context ) const
{
// use scale dependent visibility flag
layerElement.setAttribute( QStringLiteral( "hasScaleBasedVisibilityFlag" ), hasScaleBasedVisibility() ? 1 : 0 );
layerElement.setAttribute( QStringLiteral( "maxScale" ), QString::number( maximumScale() ) );
layerElement.setAttribute( QStringLiteral( "minScale" ), QString::number( minimumScale() ) );
if ( !extent().isNull() )
{
layerElement.appendChild( QgsXmlUtils::writeRectangle( mExtent, document ) );
@ -587,27 +544,52 @@ bool QgsMapLayer::writeLayerXml( QDomElement &layerElement, QDomDocument &docume
mMetadata.writeMetadataXml( myMetadataElem, document );
layerElement.appendChild( myMetadataElem );
// flags
// this code is saving automatically all the flags entries
QDomElement layerFlagsElem = document.createElement( QStringLiteral( "flags" ) );
QMetaEnum metaEnum = QMetaEnum::fromType<QgsMapLayer::LayerFlag>();
for ( int idx = 0; idx < metaEnum.keyCount(); ++idx )
{
const char *enumKey = metaEnum.key( idx );
QgsMapLayer::LayerFlag enumValue = static_cast<QgsMapLayer::LayerFlag>( metaEnum.keyToValue( enumKey ) );
bool flagValue = mFlags.testFlag( enumValue );
QDomElement flagElem = document.createElement( enumKey );
flagElem.appendChild( document.createTextNode( QString::number( flagValue ) ) );
layerFlagsElem.appendChild( flagElem );
}
layerElement.appendChild( layerFlagsElem );
// now append layer node to map layer node
writeCustomProperties( layerElement, document );
return writeXml( layerElement, document, context );
}
void QgsMapLayer::writeCommonStyle( QDomElement &layerElement, QDomDocument &document,
const QgsReadWriteContext &context, QgsMapLayerStyle::StyleCategories categories ) const
{
if ( categories.testFlag( QgsMapLayerStyle::Rendering ) )
{
// use scale dependent visibility flag
layerElement.setAttribute( QStringLiteral( "hasScaleBasedVisibilityFlag" ), hasScaleBasedVisibility() ? 1 : 0 );
layerElement.setAttribute( QStringLiteral( "maxScale" ), QString::number( maximumScale() ) );
layerElement.setAttribute( QStringLiteral( "minScale" ), QString::number( minimumScale() ) );
}
if ( m3DRenderer )
{
QDomElement renderer3DElem = document.createElement( QStringLiteral( "renderer-3d" ) );
renderer3DElem.setAttribute( QStringLiteral( "type" ), m3DRenderer->type() );
m3DRenderer->writeXml( renderer3DElem, context );
layerElement.appendChild( renderer3DElem );
}
if ( categories.testFlag( QgsMapLayerStyle::LayerConfiguration ) )
{
// flags
// this code is saving automatically all the flags entries
QDomElement layerFlagsElem = document.createElement( QStringLiteral( "flags" ) );
QMetaEnum metaEnum = QMetaEnum::fromType<QgsMapLayer::LayerFlag>();
for ( int idx = 0; idx < metaEnum.keyCount(); ++idx )
{
const char *enumKey = metaEnum.key( idx );
QgsMapLayer::LayerFlag enumValue = static_cast<QgsMapLayer::LayerFlag>( metaEnum.keyToValue( enumKey ) );
bool flagValue = mFlags.testFlag( enumValue );
QDomElement flagElem = document.createElement( enumKey );
flagElem.appendChild( document.createTextNode( QString::number( flagValue ) ) );
layerFlagsElem.appendChild( flagElem );
}
layerElement.appendChild( layerFlagsElem );
}
// custom properties
if ( categories.testFlag( QgsMapLayerStyle::CustomProperties ) )
{
writeCustomProperties( layerElement, document );
}
}
@ -1120,7 +1102,7 @@ void QgsMapLayer::exportNamedMetadata( QDomDocument &doc, QString &errorMsg ) co
doc = myDocument;
}
void QgsMapLayer::exportNamedStyle( QDomDocument &doc, QString &errorMsg ) const
void QgsMapLayer::exportNamedStyle( QDomDocument &doc, QString &errorMsg, QgsReadWriteContext &context, QgsMapLayerStyle::StyleCategories categories ) const
{
QDomImplementation DomImplementation;
QDomDocumentType documentType = DomImplementation.createDocumentType( QStringLiteral( "qgis" ), QStringLiteral( "http://mrcc.com/qgis.dtd" ), QStringLiteral( "SYSTEM" ) );
@ -1130,11 +1112,7 @@ void QgsMapLayer::exportNamedStyle( QDomDocument &doc, QString &errorMsg ) const
myRootNode.setAttribute( QStringLiteral( "version" ), Qgis::QGIS_VERSION );
myDocument.appendChild( myRootNode );
myRootNode.setAttribute( QStringLiteral( "hasScaleBasedVisibilityFlag" ), hasScaleBasedVisibility() ? 1 : 0 );
myRootNode.setAttribute( QStringLiteral( "maxScale" ), QString::number( maximumScale() ) );
myRootNode.setAttribute( QStringLiteral( "minScale" ), QString::number( minimumScale() ) );
if ( !writeSymbology( myRootNode, myDocument, errorMsg, QgsReadWriteContext() ) ) // TODO: support relative paths in QML?
if ( !writeSymbology( myRootNode, myDocument, errorMsg, QgsReadWriteContext(), categories ) ) // TODO: support relative paths in QML?
{
errorMsg = QObject::tr( "Could not save symbology because:\n%1" ).arg( errorMsg );
return;
@ -1215,7 +1193,8 @@ QString QgsMapLayer::saveNamedProperty( const QString &uri, QgsMapLayer::Propert
break;
case Style:
exportNamedStyle( myDocument, myErrorMessage );
QgsReadWriteContext context;
exportNamedStyle( myDocument, myErrorMessage, context );
break;
}
@ -1579,7 +1558,7 @@ QString QgsMapLayer::loadSldStyle( const QString &uri, bool &resultFlag )
return QString();
}
bool QgsMapLayer::readStyle( const QDomNode &node, QString &errorMessage, QgsReadWriteContext &context )
bool QgsMapLayer::readStyle( const QDomNode &node, QString &errorMessage, QgsReadWriteContext &context, QgsMapLayerStyle::StyleCategories categories )
{
Q_UNUSED( node );
Q_UNUSED( errorMessage );
@ -1587,7 +1566,8 @@ bool QgsMapLayer::readStyle( const QDomNode &node, QString &errorMessage, QgsRea
return false;
}
bool QgsMapLayer::writeStyle( QDomNode &node, QDomDocument &doc, QString &errorMessage, const QgsReadWriteContext &context ) const
bool QgsMapLayer::writeStyle( QDomNode &node, QDomDocument &doc, QString &errorMessage,
const QgsReadWriteContext &context, QgsMapLayerStyle::StyleCategories categories ) const
{
Q_UNUSED( node );
Q_UNUSED( doc );
@ -1596,19 +1576,8 @@ bool QgsMapLayer::writeStyle( QDomNode &node, QDomDocument &doc, QString &errorM
return false;
}
void QgsMapLayer::writeCommonStyle( QDomElement &layerElement, QDomDocument &document, const QgsReadWriteContext &context ) const
{
if ( m3DRenderer )
{
QDomElement renderer3DElem = document.createElement( QStringLiteral( "renderer-3d" ) );
renderer3DElem.setAttribute( QStringLiteral( "type" ), m3DRenderer->type() );
m3DRenderer->writeXml( renderer3DElem, context );
layerElement.appendChild( renderer3DElem );
}
}
void QgsMapLayer::readCommonStyle( const QDomElement &layerElement, const QgsReadWriteContext &context )
void QgsMapLayer::readCommonStyle( const QDomElement &layerElement, const QgsReadWriteContext &context,
QgsMapLayerStyle::StyleCategories categories )
{
QgsAbstract3DRenderer *r3D = nullptr;
QDomElement renderer3DElem = layerElement.firstChildElement( QStringLiteral( "renderer-3d" ) );
@ -1622,6 +1591,43 @@ void QgsMapLayer::readCommonStyle( const QDomElement &layerElement, const QgsRea
}
}
setRenderer3D( r3D );
// read custom properties before passing reading further to a subclass, so that
// the subclass can also read custom properties
readCustomProperties( layerElement );
// use scale dependent visibility flag
setScaleBasedVisibility( layerElement.attribute( QStringLiteral( "hasScaleBasedVisibilityFlag" ) ).toInt() == 1 );
if ( layerElement.hasAttribute( QStringLiteral( "minimumScale" ) ) )
{
// older element, when scales were reversed
setMaximumScale( layerElement.attribute( QStringLiteral( "minimumScale" ) ).toDouble() );
setMinimumScale( layerElement.attribute( QStringLiteral( "maximumScale" ) ).toDouble() );
}
else
{
setMaximumScale( layerElement.attribute( QStringLiteral( "maxScale" ) ).toDouble() );
setMinimumScale( layerElement.attribute( QStringLiteral( "minScale" ) ).toDouble() );
}
// flags
QDomElement flagsElem = layerElement.firstChildElement( QStringLiteral( "flags" ) );
QMetaEnum metaEnum = QMetaEnum::fromType<QgsMapLayer::LayerFlag>();
LayerFlags flags = mFlags;
for ( int idx = 0; idx < metaEnum.keyCount(); ++idx )
{
const char *enumKey = metaEnum.key( idx );
QDomNode flagNode = flagsElem.namedItem( QString( enumKey ) );
if ( flagNode.isNull() )
continue;
bool flagValue = flagNode.toElement().text() == "1" ? true : false;
QgsMapLayer::LayerFlag enumValue = static_cast<QgsMapLayer::LayerFlag>( metaEnum.keyToValue( enumKey ) );
if ( flags.testFlag( enumValue ) && !flagValue )
flags &= ~enumValue;
else if ( !flags.testFlag( enumValue ) && flagValue )
flags |= enumValue;
}
setFlags( flags );
}
QUndoStack *QgsMapLayer::undoStack()

View File

@ -35,6 +35,7 @@
#include "qgsrendercontext.h"
#include "qgsmaplayerdependency.h"
#include "qgslayermetadata.h"
#include "qgsmaplayerstyle.h"
class QgsAbstract3DRenderer;
class QgsDataProvider;
@ -489,19 +490,19 @@ class CORE_EXPORT QgsMapLayer : public QObject
/**
* Sets state from Dom document
\param layerElement The Dom element corresponding to ``maplayer'' tag
\param context writing context (e.g. for conversion between relative and absolute paths)
\note
The Dom node corresponds to a Dom document project file XML element read
by QgsProject.
This, in turn, calls readXml(), which is over-rideable by sub-classes so
that they can read their own specific state from the given Dom node.
Invoked by QgsProject::read().
\returns true if successful
* \param layerElement The Dom element corresponding to ``maplayer'' tag
* \param context writing context (e.g. for conversion between relative and absolute paths)
* \note
*
* The Dom node corresponds to a Dom document project file XML element read
* by QgsProject.
*
* This, in turn, calls readXml() (and then readSymbology()), which is over-rideable
* by sub-classes so that they can read their own specific state from the given Dom node.
*
* Invoked by QgsProject::read().
*
* \returns true if successful
*/
bool readLayerXml( const QDomElement &layerElement, QgsReadWriteContext &context );
@ -515,8 +516,8 @@ class CORE_EXPORT QgsMapLayer : public QObject
* The Dom node corresponds to a Dom document project file XML element to be
* written by QgsProject.
*
* This, in turn, calls writeXml(), which is over-rideable by sub-classes so
* that they can write their own specific state to the given Dom node.
* This, in turn, calls writeXml() (and then writeSymbology), which is over-rideable
* by sub-classes so that they can write their own specific state to the given Dom node.
*
* Invoked by QgsProject::write().
*
@ -736,7 +737,8 @@ class CORE_EXPORT QgsMapLayer : public QObject
* \param errorMsg this QString will be initialized on error
* during the execution of writeSymbology
*/
virtual void exportNamedStyle( QDomDocument &doc, QString &errorMsg SIP_OUT ) const;
virtual void exportNamedStyle( QDomDocument &doc, QString &errorMsg SIP_OUT, QgsReadWriteContext &context,
QgsMapLayerStyle::StyleCategories categories = QgsMapLayerStyle::All ) const;
/**
@ -806,7 +808,8 @@ class CORE_EXPORT QgsMapLayer : public QObject
* \param context reading context (used for transform from relative to absolute paths)
* \returns true in case of success.
*/
virtual bool readSymbology( const QDomNode &node, QString &errorMessage, QgsReadWriteContext &context ) = 0;
virtual bool readSymbology( const QDomNode &node, QString &errorMessage,
QgsReadWriteContext &context, QgsMapLayerStyle::StyleCategories categories = QgsMapLayerStyle::All ) = 0;
/**
* Read the style for the current layer from the Dom node supplied.
@ -817,29 +820,34 @@ class CORE_EXPORT QgsMapLayer : public QObject
* \note To be implemented in subclasses. Default implementation does nothing and returns false.
* \since QGIS 2.16
*/
virtual bool readStyle( const QDomNode &node, QString &errorMessage, QgsReadWriteContext &context );
virtual bool readStyle( const QDomNode &node, QString &errorMessage,
QgsReadWriteContext &context, QgsMapLayerStyle::StyleCategories categories = QgsMapLayerStyle::All );
/**
* Write the symbology for the layer into the docment provided.
* Write the style for the layer into the docment provided.
* \param node the node that will have the style element added to it.
* \param doc the document that will have the QDomNode added.
* \param errorMessage reference to string that will be updated with any error messages
* \param context writing context (used for transform from absolute to relative paths)
* \note There is a confusion of terms with the GUI. This method actually writes what is called a style in the application.
* \returns true in case of success.
*/
virtual bool writeSymbology( QDomNode &node, QDomDocument &doc, QString &errorMessage, const QgsReadWriteContext &context ) const = 0;
virtual bool writeSymbology( QDomNode &node, QDomDocument &doc, QString &errorMessage, const QgsReadWriteContext &context,
QgsMapLayerStyle::StyleCategories categories = QgsMapLayerStyle::All ) const = 0;
/**
* Write just the style information for the layer into the document
* Write just the symbology information for the layer into the document
* \param node the node that will have the style element added to it.
* \param doc the document that will have the QDomNode added.
* \param errorMessage reference to string that will be updated with any error messages
* \param context writing context (used for transform from absolute to relative paths)
* \returns true in case of success.
* \note To be implemented in subclasses. Default implementation does nothing and returns false.
* \note There is a confusion of terms with the GUI. This method actually writes what is known as the symbology in the application.
* \since QGIS 2.16
*/
virtual bool writeStyle( QDomNode &node, QDomDocument &doc, QString &errorMessage, const QgsReadWriteContext &context ) const;
virtual bool writeStyle( QDomNode &node, QDomDocument &doc, QString &errorMessage, const QgsReadWriteContext &context,
QgsMapLayerStyle::StyleCategories categories = QgsMapLayerStyle::All ) const;
//! Returns pointer to layer's undo stack
QUndoStack *undoStack();
@ -1284,13 +1292,16 @@ class CORE_EXPORT QgsMapLayer : public QObject
* Write style data common to all layer types
* \since QGIS 3.0
*/
void writeCommonStyle( QDomElement &layerElement, QDomDocument &document, const QgsReadWriteContext &context ) const;
void writeCommonStyle( QDomElement &layerElement, QDomDocument &document,
const QgsReadWriteContext &context,
QgsMapLayerStyle::StyleCategories categories = QgsMapLayerStyle::All ) const;
/**
* Read style data common to all layer types
* \since QGIS 3.0
*/
void readCommonStyle( const QDomElement &layerElement, const QgsReadWriteContext &context );
void readCommonStyle( const QDomElement &layerElement, const QgsReadWriteContext &context,
QgsMapLayerStyle::StyleCategories categories = QgsMapLayerStyle::All );
#ifndef SIP_RUN
#if 0

View File

@ -15,6 +15,7 @@
#include "qgsmaplayerstyle.h"
#include "qgsmaplayerstylemanager.h"
#include "qgsreadwritecontext.h"
#include "qgslogger.h"
@ -46,7 +47,8 @@ void QgsMapLayerStyle::readFromLayer( QgsMapLayer *layer )
{
QString errorMsg;
QDomDocument doc;
layer->exportNamedStyle( doc, errorMsg );
QgsReadWriteContext context;
layer->exportNamedStyle( doc, errorMsg, context );
if ( !errorMsg.isEmpty() )
{
QgsDebugMsg( "Failed to export style from layer: " + errorMsg );

View File

@ -18,7 +18,6 @@
#include "qgis_core.h"
#include "qgis_sip.h"
#include "qgsmaplayer.h"
#include <QByteArray>
#include <QMap>
@ -27,6 +26,7 @@
class QDomElement;
class QgsMapLayer;
/**
* \ingroup core
@ -39,8 +39,33 @@ class QDomElement;
*/
class CORE_EXPORT QgsMapLayerStyle
{
Q_GADGET
public:
/**
* Categories of style to distinguish appropriate sections for import/export
* \since QGIS 3.4
*/
enum StyleCategory
{
LayerConfiguration = 1 << 0, //!< Flags,
Symbology = 1 << 1,
Labels = 1 << 2,
Fields = 1 << 3, //!< Aliases, WMS/WFS, expressions, constraints, virtual fields
Forms = 1 << 4,
Actions = 1 << 5,
Tooltips = 1 << 6,
Diagrams = 1 << 2,
AttributeTable = 7 << 8,
Rendering = 1 << 9, //!< Scale visibility, simplify method
CustomProperties = 1 << 10,
All = LayerConfiguration | Symbology | Labels | Fields | Forms | Actions |
Tooltips | Diagrams | AttributeTable | Rendering | CustomProperties,
};
Q_ENUM( StyleCategory )
Q_DECLARE_FLAGS( StyleCategories, StyleCategory )
Q_FLAG( StyleCategories )
//! construct invalid style
QgsMapLayerStyle() = default;
@ -70,6 +95,8 @@ class CORE_EXPORT QgsMapLayerStyle
QString mXmlData;
};
Q_DECLARE_OPERATORS_FOR_FLAGS( QgsMapLayerStyle::StyleCategories )
/**
* \ingroup core

View File

@ -968,7 +968,8 @@ void QgsOfflineEditing::copySymbology( QgsVectorLayer *sourceLayer, QgsVectorLay
{
QString error;
QDomDocument doc;
sourceLayer->exportNamedStyle( doc, error );
QgsReadWriteContext context;
sourceLayer->exportNamedStyle( doc, error, context );
if ( error.isEmpty() )
{

View File

@ -1857,8 +1857,11 @@ void QgsVectorLayer::resolveReferences( QgsProject *project )
}
bool QgsVectorLayer::readSymbology( const QDomNode &layerNode, QString &errorMessage, QgsReadWriteContext &context )
bool QgsVectorLayer::readSymbology( const QDomNode &layerNode, QString &errorMessage,
QgsReadWriteContext &context, QgsMapLayerStyle::StyleCategories categories )
{
Q_UNUSED( categories );
QgsReadWriteContextCategoryPopper p = context.enterCategory( tr( "Symbology" ) );
if ( !mExpressionFieldBuffer )
@ -2076,8 +2079,10 @@ bool QgsVectorLayer::readSymbology( const QDomNode &layerNode, QString &errorMes
return true;
}
bool QgsVectorLayer::readStyle( const QDomNode &node, QString &errorMessage, QgsReadWriteContext &context )
bool QgsVectorLayer::readStyle( const QDomNode &node, QString &errorMessage, QgsReadWriteContext &context, QgsMapLayerStyle::StyleCategories categories )
{
Q_UNUSED( categories );
bool result = true;
emit readCustomSymbology( node.toElement(), errorMessage );
@ -2243,8 +2248,11 @@ bool QgsVectorLayer::readStyle( const QDomNode &node, QString &errorMessage, Qgs
}
bool QgsVectorLayer::writeSymbology( QDomNode &node, QDomDocument &doc, QString &errorMessage, const QgsReadWriteContext &context ) const
bool QgsVectorLayer::writeSymbology( QDomNode &node, QDomDocument &doc, QString &errorMessage,
const QgsReadWriteContext &context, QgsMapLayerStyle::StyleCategories categories ) const
{
Q_UNUSED( categories );
QDomElement layerElement = node.toElement();
writeCommonStyle( layerElement, doc, context );
@ -2391,8 +2399,10 @@ bool QgsVectorLayer::writeSymbology( QDomNode &node, QDomDocument &doc, QString
return true;
}
bool QgsVectorLayer::writeStyle( QDomNode &node, QDomDocument &doc, QString &errorMessage, const QgsReadWriteContext &context ) const
bool QgsVectorLayer::writeStyle( QDomNode &node, QDomDocument &doc, QString &errorMessage,
const QgsReadWriteContext &context, QgsMapLayerStyle::StyleCategories categories ) const
{
Q_UNUSED( categories );
QDomElement mapLayerNode = node.toElement();
emit writeCustomSymbology( mapLayerNode, doc, errorMessage );
@ -4251,7 +4261,10 @@ QString QgsVectorLayer::htmlMetadata() const
// feature count
QLocale locale = QLocale();
locale.setNumberOptions( locale.numberOptions() &= ~QLocale::NumberOption::OmitGroupSeparator );
myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Feature count" ) + QStringLiteral( "</td><td>" ) + ( featureCount() == -1 ? tr( "unknown" ) : locale.toString( ( qlonglong )featureCount() ) ) + QStringLiteral( "</td></tr>\n" );
myMetadata += QStringLiteral( "<tr><td class=\"highlight\">" )
+ tr( "Feature count" ) + QStringLiteral( "</td><td>" )
+ ( featureCount() == -1 ? tr( "unknown" ) : locale.toString( static_cast<qlonglong>( featureCount() ) ) )
+ QStringLiteral( "</td></tr>\n" );
// End Provider section
myMetadata += QLatin1String( "</table>\n<br><br>" );
@ -4453,7 +4466,8 @@ void QgsVectorLayer::saveStyleToDatabase( const QString &name, const QString &de
}
QDomDocument qmlDocument, sldDocument;
this->exportNamedStyle( qmlDocument, msgError );
QgsReadWriteContext context;
exportNamedStyle( qmlDocument, msgError, context );
if ( !msgError.isNull() )
{
return;

View File

@ -880,7 +880,8 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
* \param context reading context (used for transform from relative to absolute paths)
* \returns true in case of success.
*/
bool readSymbology( const QDomNode &layerNode, QString &errorMessage, QgsReadWriteContext &context ) override;
bool readSymbology( const QDomNode &layerNode, QString &errorMessage,
QgsReadWriteContext &context, QgsMapLayerStyle::StyleCategories categories = QgsMapLayerStyle::All ) override;
/**
* Read the style for the current layer from the Dom node supplied.
@ -889,7 +890,8 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
* \param context reading context (used for transform from relative to absolute paths)
* \returns true in case of success.
*/
bool readStyle( const QDomNode &node, QString &errorMessage, QgsReadWriteContext &context ) override;
bool readStyle( const QDomNode &node, QString &errorMessage,
QgsReadWriteContext &context, QgsMapLayerStyle::StyleCategories categories = QgsMapLayerStyle::All ) override;
/**
* Write the symbology for the layer into the docment provided.
@ -899,7 +901,8 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
* \param context writing context (used for transform from absolute to relative paths)
* \returns true in case of success.
*/
bool writeSymbology( QDomNode &node, QDomDocument &doc, QString &errorMessage, const QgsReadWriteContext &context ) const override;
bool writeSymbology( QDomNode &node, QDomDocument &doc, QString &errorMessage,
const QgsReadWriteContext &context, QgsMapLayerStyle::StyleCategories categories = QgsMapLayerStyle::All ) const override;
/**
* Write just the style information for the layer into the document
@ -909,7 +912,8 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
* \param context writing context (used for transform from absolute to relative paths)
* \returns true in case of success.
*/
bool writeStyle( QDomNode &node, QDomDocument &doc, QString &errorMessage, const QgsReadWriteContext &context ) const override;
bool writeStyle( QDomNode &node, QDomDocument &doc, QString &errorMessage,
const QgsReadWriteContext &context, QgsMapLayerStyle::StyleCategories categories = QgsMapLayerStyle::All ) const override;
/**
* Writes the symbology of the layer into the document provided in SLD 1.1 format

View File

@ -1306,9 +1306,12 @@ QImage QgsRasterLayer::previewAsImage( QSize size, const QColor &bgColor, QImage
* \param errorMessage reference to string that will be updated with any error messages
* \return true in case of success.
*/
bool QgsRasterLayer::readSymbology( const QDomNode &layer_node, QString &errorMessage, QgsReadWriteContext &context )
bool QgsRasterLayer::readSymbology( const QDomNode &layer_node, QString &errorMessage,
QgsReadWriteContext &context, QgsMapLayerStyle::StyleCategories categories )
{
Q_UNUSED( errorMessage );
Q_UNUSED( categories );
QDomElement rasterRendererElem;
QDomElement layerElement = layer_node.toElement();
@ -1398,9 +1401,9 @@ bool QgsRasterLayer::readSymbology( const QDomNode &layer_node, QString &errorMe
return true;
}
bool QgsRasterLayer::readStyle( const QDomNode &node, QString &errorMessage, QgsReadWriteContext &context )
bool QgsRasterLayer::readStyle( const QDomNode &node, QString &errorMessage, QgsReadWriteContext &context, QgsMapLayerStyle::StyleCategories categories )
{
return readSymbology( node, errorMessage, context );
return readSymbology( node, errorMessage, context, categories );
}
bool QgsRasterLayer::readXml( const QDomNode &layer_node, QgsReadWriteContext &context )
@ -1545,9 +1548,11 @@ bool QgsRasterLayer::readXml( const QDomNode &layer_node, QgsReadWriteContext &c
* \param errorMessage reference to string that will be updated with any error messages
* \return true in case of success.
*/
bool QgsRasterLayer::writeSymbology( QDomNode &layer_node, QDomDocument &document, QString &errorMessage, const QgsReadWriteContext &context ) const
bool QgsRasterLayer::writeSymbology( QDomNode &layer_node, QDomDocument &document, QString &errorMessage,
const QgsReadWriteContext &context, QgsMapLayerStyle::StyleCategories categories ) const
{
Q_UNUSED( errorMessage );
Q_UNUSED( categories );
QDomElement layerElement = layer_node.toElement();
writeCommonStyle( layerElement, document, context );
@ -1574,9 +1579,9 @@ bool QgsRasterLayer::writeSymbology( QDomNode &layer_node, QDomDocument &documen
return true;
}
bool QgsRasterLayer::writeStyle( QDomNode &node, QDomDocument &doc, QString &errorMessage, const QgsReadWriteContext &context ) const
bool QgsRasterLayer::writeStyle( QDomNode &node, QDomDocument &doc, QString &errorMessage, const QgsReadWriteContext &context, QgsMapLayerStyle::StyleCategories categories ) const
{
return writeSymbology( node, doc, errorMessage, context );
return writeSymbology( node, doc, errorMessage, context, categories );
} // bool QgsRasterLayer::writeSymbology

View File

@ -404,11 +404,13 @@ class CORE_EXPORT QgsRasterLayer : public QgsMapLayer
void showStatusMessage( const QString &message );
protected:
bool readSymbology( const QDomNode &node, QString &errorMessage, QgsReadWriteContext &context ) override;
bool readStyle( const QDomNode &node, QString &errorMessage, QgsReadWriteContext &context ) override;
bool readSymbology( const QDomNode &node, QString &errorMessage, QgsReadWriteContext &context, QgsMapLayerStyle::StyleCategories categories = QgsMapLayerStyle::All ) override;
bool readStyle( const QDomNode &node, QString &errorMessage, QgsReadWriteContext &context, QgsMapLayerStyle::StyleCategories categories = QgsMapLayerStyle::All ) override;
bool readXml( const QDomNode &layer_node, QgsReadWriteContext &context ) override;
bool writeSymbology( QDomNode &, QDomDocument &doc, QString &errorMessage, const QgsReadWriteContext &context ) const override;
bool writeStyle( QDomNode &node, QDomDocument &doc, QString &errorMessage, const QgsReadWriteContext &context ) const override;
bool writeSymbology( QDomNode &, QDomDocument &doc, QString &errorMessage,
const QgsReadWriteContext &context, QgsMapLayerStyle::StyleCategories categories = QgsMapLayerStyle::All ) const override;
bool writeStyle( QDomNode &node, QDomDocument &doc, QString &errorMessage,
const QgsReadWriteContext &context, QgsMapLayerStyle::StyleCategories categories = QgsMapLayerStyle::All ) const override;
bool writeXml( QDomNode &layer_node, QDomDocument &doc, const QgsReadWriteContext &context ) const override;
QString encodedSource( const QString &source, const QgsReadWriteContext &context ) const override;
QString decodedSource( const QString &source, const QString &provider, const QgsReadWriteContext &context ) const override;