Store original style as QDomDocument instead of an XML string

This commit is contained in:
Alessandro Pasotti 2018-11-03 09:41:00 +01:00
parent bc8574ce5c
commit eb02004b60
7 changed files with 24 additions and 39 deletions

View File

@ -1237,7 +1237,7 @@ Returns true if the refresh on provider nofification is enabled
.. versionadded:: 3.0
%End
QString originalXmlProperties() const;
QDomDocument originalXmlProperties() const;
%Docstring
Returns the XML properties of the original layer as they were when the layer
was first read from the project file. In case of new layers this is normally empty.
@ -1247,7 +1247,7 @@ The storage format for the XML is qlr
.. versionadded:: 3.6
%End
void setOriginalXmlProperties( const QString &originalXmlProperties );
void setOriginalXmlProperties( const QDomDocument &originalXmlProperties );
%Docstring
Sets the original XML properties for the layer to ``originalXmlProperties``

View File

@ -6955,26 +6955,17 @@ void QgisApp::changeDataSource( QgsMapLayer *layer )
bool layerIsValid( layer->isValid() );
layer->setDataSource( uri.uri, layer->name(), uri.providerKey, QgsDataProvider::ProviderOptions() );
// Re-apply style
if ( !( layerIsValid || layer->originalXmlProperties().isEmpty() ) )
if ( !( layerIsValid || layer->originalXmlProperties().isNull() ) )
{
QgsReadWriteContext context;
context.setPathResolver( QgsProject::instance()->pathResolver() );
context.setProjectTranslator( QgsProject::instance() );
QString errorMsg;
QDomDocument doc;
if ( doc.setContent( layer->originalXmlProperties() ) )
QDomDocument doc( layer->originalXmlProperties() );
QDomNode layer_node( doc.firstChild( ) );
if ( ! layer->readSymbology( layer_node, errorMsg, context ) )
{
QDomNode layer_node( doc.firstChild( ) );
if ( ! layer->readSymbology( layer_node, errorMsg, context ) )
{
QgsDebugMsg( QStringLiteral( "Failed to restore original layer style from stored XML for layer %1: %2" )
.arg( layer->name( ) )
.arg( errorMsg ) );
}
}
else
{
QgsDebugMsg( QStringLiteral( "Failed to create XML QDomDocument for layer %1: %2" )
QgsDebugMsg( QStringLiteral( "Failed to restore original layer style from stored XML for layer %1: %2" )
.arg( layer->name( ) )
.arg( errorMsg ) );
}

View File

@ -329,10 +329,7 @@ void QgsLayerTreeUtils::storeOriginalLayersProperties( QgsLayerTreeGroup *group,
QDomDocument document( documentType );
QDomElement element = mlNode.toElement();
document.appendChild( element );
QString str;
QTextStream stream( &str );
document.save( stream, 4 /*indent*/ );
l->setOriginalXmlProperties( str );
l->setOriginalXmlProperties( document );
}
}
}

View File

@ -1833,12 +1833,12 @@ bool QgsMapLayer::isReadOnly() const
return true;
}
QString QgsMapLayer::originalXmlProperties() const
QDomDocument QgsMapLayer::originalXmlProperties() const
{
return mOriginalXmlProperties;
}
void QgsMapLayer::setOriginalXmlProperties( const QString &originalXmlProperties )
void QgsMapLayer::setOriginalXmlProperties( const QDomDocument &originalXmlProperties )
{
mOriginalXmlProperties = originalXmlProperties;
}

View File

@ -1109,7 +1109,7 @@ class CORE_EXPORT QgsMapLayer : public QObject
*
* \since QGIS 3.6
*/
QString originalXmlProperties() const;
QDomDocument originalXmlProperties() const;
/**
* Sets the original XML properties for the layer to \a originalXmlProperties
@ -1118,7 +1118,7 @@ class CORE_EXPORT QgsMapLayer : public QObject
*
* \since QGIS 3.6
*/
void setOriginalXmlProperties( const QString &originalXmlProperties );
void setOriginalXmlProperties( const QDomDocument &originalXmlProperties );
public slots:
@ -1529,7 +1529,7 @@ class CORE_EXPORT QgsMapLayer : public QObject
*
* This information can be used to pass through the bad layers or to reset changes on a good layer
*/
QString mOriginalXmlProperties;
QDomDocument mOriginalXmlProperties;
};

View File

@ -1774,17 +1774,10 @@ bool QgsProject::writeProjectFile( const QString &filename )
maplayerElem = doc->createElement( QStringLiteral( "maplayer" ) );
ml->writeLayerXml( maplayerElem, *doc, context );
}
else if ( ! ml->originalXmlProperties().isEmpty() )
else if ( ! ml->originalXmlProperties().isNull() )
{
QDomDocument document;
if ( document.setContent( ml->originalXmlProperties() ) )
{
maplayerElem = document.firstChildElement();
}
else
{
QgsDebugMsg( QStringLiteral( "Could not restore layer properties for layer %1" ).arg( ml->id() ) );
}
QDomDocument document( ml->originalXmlProperties() );
maplayerElem = document.firstChildElement();
}
emit writeMapLayer( ml, maplayerElem, *doc );

View File

@ -35,6 +35,7 @@ from qgis.gui import (QgsLayerTreeMapCanvasBridge,
from qgis.PyQt.QtGui import QFont, QColor
from qgis.PyQt.QtTest import QSignalSpy
from qgis.PyQt.QtCore import QT_VERSION_STR, QTemporaryDir, QSize
from qgis.PyQt.QtXml import QDomDocument, QDomNode, QDomImplementation
from qgis.testing import start_app, unittest
from utilities import (unitTestDataPath, renderMapToImage)
@ -99,8 +100,12 @@ class TestQgsProjectBadLayers(unittest.TestCase):
self.assertTrue(raster.originalXmlProperties() != '')
self.assertTrue(raster_copy.originalXmlProperties() != '')
# Test setter
raster.setOriginalXmlProperties('pippo')
self.assertEqual(raster.originalXmlProperties(), 'pippo')
domimp = QDomImplementation()
documentType = domimp.createDocumentType("qgis", "http://mrcc.com/qgis.dtd", "SYSTEM")
document = QDomDocument(documentType)
document.setContent("<pippo>pluto</pippo>")
raster.setOriginalXmlProperties(document)
self.assertEqual(raster.originalXmlProperties(), document)
# Now create and invalid project:
bad_project_path = os.path.join(temp_dir.path(), 'project_bad.qgs')
@ -144,7 +149,7 @@ class TestQgsProjectBadLayers(unittest.TestCase):
self.assertTrue(raster_copy.isValid())
def test_project_relations(self):
"""Tests that a project with bad layers and relations can be saved with relations"""
"""Tests that a project with bad layers and relations can be maintained"""
temp_dir = QTemporaryDir()
p = QgsProject.instance()
@ -235,7 +240,6 @@ class TestQgsProjectBadLayers(unittest.TestCase):
p = QgsProject.instance()
project_path = os.path.join(temp_dir.path(), 'good_layers_test.qgs')
copyfile(os.path.join(TEST_DATA_DIR, 'projects', 'good_layers_test.qgs'), project_path)
copyfile(os.path.join(TEST_DATA_DIR, 'projects', 'bad_layers_test.gpkg'), os.path.join(temp_dir.path(), 'bad_layers_test.gpkg'))
for f in (
'bad_layer_raster_test.tfw',
'bad_layer_raster_test.tiff',