Renamed originalXmlProperties methods and variables

This commit is contained in:
Alessandro Pasotti 2018-10-30 14:47:00 +01:00
parent 9cfb4369f9
commit f856b4c8e3
10 changed files with 98 additions and 25 deletions

View File

@ -59,9 +59,9 @@ Returns true if any of the layers is modified
Removes layer nodes that refer to invalid layers
%End
static void storeInvalidLayersProperties( QgsLayerTreeGroup *group, const QDomDocument *doc );
static void storeOriginalLayersProperties( QgsLayerTreeGroup *group, const QDomDocument *doc );
%Docstring
Stores in a custom layer node property the layer properties XML information for an invalid layer
Stores in a layer's originalXmlProperties the layer properties information
.. versionadded:: 3.6
%End

View File

@ -1237,6 +1237,24 @@ Returns true if the refresh on provider nofification is enabled
.. versionadded:: 3.0
%End
QString 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.
The storage format for the XML is qlr
.. versionadded:: 3.6
%End
void setOriginalXmlProperties( const QString &originalXmlProperties );
%Docstring
Sets the original XML properties for the layer to ``originalXmlProperties``
The storage format for the XML is qlr
.. versionadded:: 3.6
%End
public slots:

View File

@ -20,6 +20,7 @@
#include "qgslayertreeutils.h"
#include "qgslayertreemodel.h"
#include "qgsvectorlayer.h"
#include "qgsrasterlayer.h"
#include "qgisapp.h"
#include "qgsbrowsermodel.h"
#include "qgsbrowsertreeview.h"
@ -40,14 +41,21 @@ void QgsLayerTreeViewBadLayerIndicatorProvider::onIndicatorClicked( const QModel
if ( !QgsLayerTree::isLayer( node ) )
return;
QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( QgsLayerTree::toLayer( node )->layer() );
if ( !vlayer )
// Only raster/vector for now are supported
QgsMapLayer *layer = nullptr;
if ( qobject_cast<QgsVectorLayer *>( QgsLayerTree::toLayer( node )->layer() ) ||
qobject_cast<QgsRasterLayer *>( QgsLayerTree::toLayer( node )->layer() ) )
{
layer = qobject_cast<QgsMapLayer *>( QgsLayerTree::toLayer( node )->layer() );
}
if ( !layer )
return;
// TODO: raster layers
// Get provider type
QString providerType( vlayer->providerType() );
QString providerType( layer->providerType() );
QgsMapLayer::LayerType layerType( layer->type() );
// Builds the dialog to select a new data source
QgsBrowserModel browserModel;
browserModel.initialize();
QDialog dlg;
@ -69,8 +77,8 @@ void QgsLayerTreeViewBadLayerIndicatorProvider::onIndicatorClicked( const QModel
{
if ( index.isValid() )
{
const QgsDataItem *item( browserModel.dataItem( index ) );
if ( item->mimeUri().layerType == QStringLiteral( "vector" ) && item->mimeUri().providerKey == providerType )
const QgsLayerItem *item = qobject_cast<QgsLayerItem *>( browserModel.dataItem( index ) );
if ( item && item->mapLayerType() == layerType && item->providerKey() == providerType )
{
return true;
}
@ -86,12 +94,11 @@ void QgsLayerTreeViewBadLayerIndicatorProvider::onIndicatorClicked( const QModel
dlg.setLayout( &lay );
if ( dlg.exec() == QDialog::Accepted )
{
// Get selected item(s)
QModelIndex index = browserWidget->currentIndex();
if ( isItemCompatible( index ) )
{
const QgsDataItem *item( browserModel.dataItem( index ) );
vlayer->setDataSource( item->mimeUri().uri, vlayer->name(), item->mimeUri().providerKey, QgsDataProvider::ProviderOptions() );
layer->setDataSource( item->mimeUri().uri, layer->name(), item->mimeUri().providerKey, QgsDataProvider::ProviderOptions() );
}
}
QgsSettings().setValue( QStringLiteral( "/Windows/selectDataSourceDialog/geometry" ), dlg.saveGeometry(), QgsSettings::Section::App );
@ -106,8 +113,7 @@ QString QgsLayerTreeViewBadLayerIndicatorProvider::iconName( QgsMapLayer *layer
QString QgsLayerTreeViewBadLayerIndicatorProvider::tooltipText( QgsMapLayer *layer )
{
Q_UNUSED( layer );
// TODO, click here to set a new data source.
return tr( "<b>Bad layer!</b><br>Layer data source could not be found." );
return tr( "<b>Bad layer!</b><br>Layer data source could not be found. Click to set a new data source" );
}
bool QgsLayerTreeViewBadLayerIndicatorProvider::acceptLayer( QgsMapLayer *layer )

View File

@ -636,10 +636,13 @@ QImage QgsWmsLegendNode::getLegendGraphic() const
QgsRasterLayer *layer = qobject_cast<QgsRasterLayer *>( mLayerNode->layer() );
const QgsLayerTreeModel *mod = model();
if ( ! mod ) return mImage;
if ( ! mod )
return mImage;
const QgsMapSettings *ms = mod->legendFilterMapSettings();
QgsRasterDataProvider *prov = layer->dataProvider();
if ( ! prov )
return mImage;
Q_ASSERT( ! mFetcher );
mFetcher.reset( prov->getLegendGraphicFetcher( ms ) );

View File

@ -306,7 +306,7 @@ void QgsLayerTreeUtils::removeInvalidLayers( QgsLayerTreeGroup *group )
group->removeChildNode( node );
}
void QgsLayerTreeUtils::storeInvalidLayersProperties( QgsLayerTreeGroup *group, const QDomDocument *doc )
void QgsLayerTreeUtils::storeOriginalLayersProperties( QgsLayerTreeGroup *group, const QDomDocument *doc )
{
const QDomNodeList mlNodeList( doc->documentElement()
.firstChildElement( QStringLiteral( "projectlayers" ) )
@ -316,7 +316,7 @@ void QgsLayerTreeUtils::storeInvalidLayersProperties( QgsLayerTreeGroup *group,
if ( QgsLayerTree::isLayer( node ) )
{
QgsMapLayer *l( QgsLayerTree::toLayer( node )->layer() );
if ( l && ! l->isValid( ) )
if ( l )
{
for ( int i = 0; i < mlNodeList.count(); i++ )
{
@ -332,7 +332,7 @@ void QgsLayerTreeUtils::storeInvalidLayersProperties( QgsLayerTreeGroup *group,
QString str;
QTextStream stream( &str );
document.save( stream, 4 /*indent*/ );
l->setCustomProperty( QStringLiteral( "invalidLayerProperties" ), str );
l->setOriginalXmlProperties( str );
}
}
}

View File

@ -63,10 +63,10 @@ class CORE_EXPORT QgsLayerTreeUtils
static void removeInvalidLayers( QgsLayerTreeGroup *group );
/**
* Stores in a custom layer node property the layer properties XML information for an invalid layer
* Stores in a layer's originalXmlProperties the layer properties information
* \since 3.6
*/
static void storeInvalidLayersProperties( QgsLayerTreeGroup *group, const QDomDocument *doc );
static void storeOriginalLayersProperties( QgsLayerTreeGroup *group, const QDomDocument *doc );
//! Remove subtree of embedded groups and replaces it with a custom property embedded-visible-layers
static void replaceChildrenOfEmbeddedGroups( QgsLayerTreeGroup *group );

View File

@ -1833,6 +1833,16 @@ bool QgsMapLayer::isReadOnly() const
return true;
}
QString QgsMapLayer::originalXmlProperties() const
{
return mOriginalXmlProperties;
}
void QgsMapLayer::setOriginalXmlProperties( const QString &originalXmlProperties )
{
mOriginalXmlProperties = originalXmlProperties;
}
void QgsMapLayer::setProviderType( const QString &providerType )
{
mProviderKey = providerType;

View File

@ -1101,6 +1101,24 @@ class CORE_EXPORT QgsMapLayer : public QObject
*/
bool isRefreshOnNotifyEnabled() const { return mIsRefreshOnNofifyEnabled; }
/**
* 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.
*
* The storage format for the XML is qlr
*
* \since QGIS 3.6
*/
QString originalXmlProperties() const;
/**
* Sets the original XML properties for the layer to \a originalXmlProperties
*
* The storage format for the XML is qlr
*
* \since QGIS 3.6
*/
void setOriginalXmlProperties( const QString &originalXmlProperties );
public slots:
@ -1506,6 +1524,13 @@ class CORE_EXPORT QgsMapLayer : public QObject
//! Renderer for 3D views
QgsAbstract3DRenderer *m3DRenderer = nullptr;
/**
* Stores the original XML properties of the layer when loaded from the project
*
* This information can be used to pass through the bad layers or to reset changes on a good layer
*/
QString mOriginalXmlProperties;
};
Q_DECLARE_METATYPE( QgsMapLayer * )

View File

@ -1292,8 +1292,8 @@ bool QgsProject::readProjectFile( const QString &filename )
// After bad layer handling we might still have invalid layers,
// store them in case the user wanted to handle them later
// or she wanted to pass them through when saving
QgsLayerTreeUtils::storeInvalidLayersProperties( mRootGroup, doc.get() );
// or wanted to pass them through when saving
QgsLayerTreeUtils::storeOriginalLayersProperties( mRootGroup, doc.get() );
mRootGroup->removeCustomProperty( QStringLiteral( "loading" ) );
@ -1760,17 +1760,16 @@ bool QgsProject::writeProjectFile( const QString &filename )
maplayerElem = doc->createElement( QStringLiteral( "maplayer" ) );
ml->writeLayerXml( maplayerElem, *doc, context );
}
else if ( ml->customPropertyKeys().contains( QStringLiteral( "invalidLayerProperties" ) ) )
else if ( ! ml->originalXmlProperties().isEmpty() )
{
QDomDocument document;
if ( document.setContent( ml->customProperty( QStringLiteral( "invalidLayerProperties" ) ).toString() ) )
if ( document.setContent( ml->originalXmlProperties() ) )
{
maplayerElem = document.firstChildElement();
maplayerElem.setAttribute( QStringLiteral( "invalidLayerProperties" ), QStringLiteral( "true" ) );
}
else
{
QgsDebugMsg( QStringLiteral( "Could not restore bad layer properties %1 from saved invalidLayerProperties" ).arg( ml->id() ) );
QgsDebugMsg( QStringLiteral( "Could not restore layer properties for layer %1" ).arg( ml->id() ) );
}
}

View File

@ -59,6 +59,18 @@ class TestQgsProjectBadLayers(unittest.TestCase):
project_path = os.path.join(temp_dir.path(), 'project.qgs')
self.assertTrue(p.write(project_path))
# Re-load the project, checking for the XML properties
self.assertTrue(p.read(project_path))
vector = list(p.mapLayersByName('lines'))[0]
raster = list(p.mapLayersByName('raster'))[0]
raster_copy = list(p.mapLayersByName('raster_copy'))[0]
self.assertTrue(vector.originalLayerXmlProperties() != '')
self.assertTrue(raster.originalLayerXmlProperties() != '')
self.assertTrue(raster_copy.originalLayerXmlProperties() != '')
# Test setter
raster.setOriginalLayerXmlProperties('pippo')
self.assertEqual(raster.originalLayerXmlProperties(), 'pippo')
# Now create and invalid project:
bad_project_path = os.path.join(temp_dir.path(), 'project_bad.qgs')
with open(project_path, 'r') as infile: