mirror of
https://github.com/qgis/QGIS.git
synced 2025-10-06 00:07:29 -04:00
Always write/read legend attributes, add flags API
This commit is contained in:
parent
3e8c2cdf14
commit
2a434da498
@ -29,6 +29,40 @@ Constructor for QgsMapLayerLegend
|
||||
%End
|
||||
|
||||
|
||||
Qgis::MapLayerLegendFlags flags() const;
|
||||
%Docstring
|
||||
Returns flags associated with the legend.
|
||||
|
||||
.. seealso:: :py:func:`setFlag`
|
||||
|
||||
.. seealso:: :py:func:`setFlags`
|
||||
|
||||
.. versionadded:: 4.0
|
||||
%End
|
||||
|
||||
void setFlag( Qgis::MapLayerLegendFlag flag, bool on = true );
|
||||
%Docstring
|
||||
Enables or disables a particular ``flag`` (other flags are not
|
||||
affected).
|
||||
|
||||
.. seealso:: :py:func:`flags`
|
||||
|
||||
.. seealso:: :py:func:`setFlags`
|
||||
|
||||
.. versionadded:: 4.0
|
||||
%End
|
||||
|
||||
void setFlags( Qgis::MapLayerLegendFlags flags );
|
||||
%Docstring
|
||||
Sets the ``flags`` associated with the legend.
|
||||
|
||||
.. seealso:: :py:func:`setFlag`
|
||||
|
||||
.. seealso:: :py:func:`flags`
|
||||
|
||||
.. versionadded:: 4.0
|
||||
%End
|
||||
|
||||
virtual void readXml( const QDomElement &elem, const QgsReadWriteContext &context );
|
||||
%Docstring
|
||||
Reads configuration from a DOM element previously written by
|
||||
@ -80,6 +114,7 @@ Create new legend implementation for a point cloud ``layer``.
|
||||
Emitted when existing items/nodes got invalid and should be replaced by
|
||||
new ones
|
||||
%End
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -29,6 +29,40 @@ Constructor for QgsMapLayerLegend
|
||||
%End
|
||||
|
||||
|
||||
Qgis::MapLayerLegendFlags flags() const;
|
||||
%Docstring
|
||||
Returns flags associated with the legend.
|
||||
|
||||
.. seealso:: :py:func:`setFlag`
|
||||
|
||||
.. seealso:: :py:func:`setFlags`
|
||||
|
||||
.. versionadded:: 4.0
|
||||
%End
|
||||
|
||||
void setFlag( Qgis::MapLayerLegendFlag flag, bool on = true );
|
||||
%Docstring
|
||||
Enables or disables a particular ``flag`` (other flags are not
|
||||
affected).
|
||||
|
||||
.. seealso:: :py:func:`flags`
|
||||
|
||||
.. seealso:: :py:func:`setFlags`
|
||||
|
||||
.. versionadded:: 4.0
|
||||
%End
|
||||
|
||||
void setFlags( Qgis::MapLayerLegendFlags flags );
|
||||
%Docstring
|
||||
Sets the ``flags`` associated with the legend.
|
||||
|
||||
.. seealso:: :py:func:`setFlag`
|
||||
|
||||
.. seealso:: :py:func:`flags`
|
||||
|
||||
.. versionadded:: 4.0
|
||||
%End
|
||||
|
||||
virtual void readXml( const QDomElement &elem, const QgsReadWriteContext &context );
|
||||
%Docstring
|
||||
Reads configuration from a DOM element previously written by
|
||||
@ -80,6 +114,7 @@ Create new legend implementation for a point cloud ``layer``.
|
||||
Emitted when existing items/nodes got invalid and should be replaced by
|
||||
new ones
|
||||
%End
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -1881,6 +1881,17 @@ bool QgsMeshLayer::readSymbology( const QDomNode &node, QString &errorMessage,
|
||||
}
|
||||
}
|
||||
|
||||
if ( categories.testFlag( Legend ) )
|
||||
{
|
||||
QgsReadWriteContextCategoryPopper p = context.enterCategory( tr( "Legend" ) );
|
||||
|
||||
const QDomElement legendElem = node.firstChildElement( QStringLiteral( "legend" ) );
|
||||
if ( QgsMapLayerLegend *l = legend(); !legendElem.isNull() )
|
||||
{
|
||||
l->readXml( legendElem, context );
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1937,6 +1948,13 @@ bool QgsMeshLayer::writeSymbology( QDomNode &node, QDomDocument &doc, QString &e
|
||||
node.appendChild( layerOpacityElem );
|
||||
}
|
||||
|
||||
if ( categories.testFlag( Legend ) && legend() )
|
||||
{
|
||||
QDomElement legendElement = legend()->writeXml( doc, context );
|
||||
if ( !legendElement.isNull() )
|
||||
node.appendChild( legendElement );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -232,6 +232,17 @@ bool QgsPointCloudLayer::readSymbology( const QDomNode &node, QString &errorMess
|
||||
if ( categories.testFlag( CustomProperties ) )
|
||||
readCustomProperties( node, QStringLiteral( "variable" ) );
|
||||
|
||||
if ( categories.testFlag( Legend ) )
|
||||
{
|
||||
QgsReadWriteContextCategoryPopper p = context.enterCategory( tr( "Legend" ) );
|
||||
|
||||
const QDomElement legendElem = node.firstChildElement( QStringLiteral( "legend" ) );
|
||||
if ( QgsMapLayerLegend *l = legend(); !legendElem.isNull() )
|
||||
{
|
||||
l->readXml( legendElem, context );
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -321,6 +332,13 @@ bool QgsPointCloudLayer::writeSymbology( QDomNode &node, QDomDocument &doc, QStr
|
||||
|
||||
( void )writeStyle( node, doc, errorMessage, context, categories );
|
||||
|
||||
if ( categories.testFlag( Legend ) && legend() )
|
||||
{
|
||||
QDomElement legendElement = legend()->writeXml( doc, context );
|
||||
if ( !legendElement.isNull() )
|
||||
node.appendChild( legendElement );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -39,17 +39,20 @@ QgsMapLayerLegend::QgsMapLayerLegend( QObject *parent )
|
||||
{
|
||||
}
|
||||
|
||||
void QgsMapLayerLegend::readXml( const QDomElement &elem, const QgsReadWriteContext &context )
|
||||
void QgsMapLayerLegend::readXml( const QDomElement &elem, const QgsReadWriteContext & )
|
||||
{
|
||||
Q_UNUSED( elem )
|
||||
Q_UNUSED( context )
|
||||
mFlags = Qgis::MapLayerLegendFlags();
|
||||
mFlags.setFlag( Qgis::MapLayerLegendFlag::ExcludeByDefault, elem.attribute( QStringLiteral( "showLabelLegend" ), QStringLiteral( "0" ) ).toInt() );
|
||||
}
|
||||
|
||||
QDomElement QgsMapLayerLegend::writeXml( QDomDocument &doc, const QgsReadWriteContext &context ) const
|
||||
QDomElement QgsMapLayerLegend::writeXml( QDomDocument &doc, const QgsReadWriteContext & ) const
|
||||
{
|
||||
Q_UNUSED( doc )
|
||||
Q_UNUSED( context )
|
||||
return QDomElement();
|
||||
QDomElement elem = doc.createElement( QStringLiteral( "legend" ) );
|
||||
|
||||
if ( mFlags.testFlag( Qgis::MapLayerLegendFlag::ExcludeByDefault ) )
|
||||
elem.setAttribute( QStringLiteral( "excludeByDefault" ), QStringLiteral( "1" ) );
|
||||
|
||||
return elem.attributes().isEmpty() ? QDomElement() : elem;
|
||||
}
|
||||
|
||||
QgsMapLayerLegend *QgsMapLayerLegend::defaultVectorLegend( QgsVectorLayer *vl )
|
||||
@ -443,6 +446,8 @@ QList<QgsLayerTreeModelLegendNode *> QgsDefaultVectorLayerLegend::createLayerTre
|
||||
|
||||
void QgsDefaultVectorLayerLegend::readXml( const QDomElement &elem, const QgsReadWriteContext &context )
|
||||
{
|
||||
QgsMapLayerLegend::readXml( elem, context );
|
||||
|
||||
mTextOnSymbolEnabled = false;
|
||||
mTextOnSymbolTextFormat = QgsTextFormat();
|
||||
mTextOnSymbolContent.clear();
|
||||
@ -467,7 +472,7 @@ void QgsDefaultVectorLayerLegend::readXml( const QDomElement &elem, const QgsRea
|
||||
|
||||
QDomElement QgsDefaultVectorLayerLegend::writeXml( QDomDocument &doc, const QgsReadWriteContext &context ) const
|
||||
{
|
||||
QDomElement elem = doc.createElement( QStringLiteral( "legend" ) );
|
||||
QDomElement elem = QgsMapLayerLegend::writeXml( doc, context );
|
||||
elem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "default-vector" ) );
|
||||
elem.setAttribute( QStringLiteral( "showLabelLegend" ), mShowLabelLegend );
|
||||
|
||||
|
@ -53,6 +53,33 @@ class CORE_EXPORT QgsMapLayerLegend : public QObject
|
||||
|
||||
// TODO: type
|
||||
|
||||
/**
|
||||
* Returns flags associated with the legend.
|
||||
*
|
||||
* \see setFlag()
|
||||
* \see setFlags()
|
||||
* \since QGIS 4.0
|
||||
*/
|
||||
Qgis::MapLayerLegendFlags flags() const { return mFlags; }
|
||||
|
||||
/**
|
||||
* Enables or disables a particular \a flag (other flags are not affected).
|
||||
*
|
||||
* \see flags()
|
||||
* \see setFlags()
|
||||
* \since QGIS 4.0
|
||||
*/
|
||||
void setFlag( Qgis::MapLayerLegendFlag flag, bool on = true ) { mFlags.setFlag( flag, on ); }
|
||||
|
||||
/**
|
||||
* Sets the \a flags associated with the legend.
|
||||
*
|
||||
* \see setFlag()
|
||||
* \see flags()
|
||||
* \since QGIS 4.0
|
||||
*/
|
||||
void setFlags( Qgis::MapLayerLegendFlags flags ) { mFlags = flags; }
|
||||
|
||||
/**
|
||||
* Reads configuration from a DOM element previously written by writeXml()
|
||||
* \since QGIS 3.2
|
||||
@ -91,6 +118,10 @@ class CORE_EXPORT QgsMapLayerLegend : public QObject
|
||||
signals:
|
||||
//! Emitted when existing items/nodes got invalid and should be replaced by new ones
|
||||
void itemsChanged();
|
||||
|
||||
private:
|
||||
|
||||
Qgis::MapLayerLegendFlags mFlags;
|
||||
};
|
||||
|
||||
|
||||
|
@ -2268,6 +2268,17 @@ bool QgsRasterLayer::readSymbology( const QDomNode &layer_node, QString &errorMe
|
||||
readRasterAttributeTableExternalPaths( layer_node, context );
|
||||
}
|
||||
|
||||
if ( categories.testFlag( Legend ) )
|
||||
{
|
||||
QgsReadWriteContextCategoryPopper p = context.enterCategory( tr( "Legend" ) );
|
||||
|
||||
const QDomElement legendElem = layer_node.firstChildElement( QStringLiteral( "legend" ) );
|
||||
if ( QgsMapLayerLegend *l = legend(); !legendElem.isNull() )
|
||||
{
|
||||
l->readXml( legendElem, context );
|
||||
}
|
||||
}
|
||||
|
||||
emit rendererChanged();
|
||||
emitStyleChanged();
|
||||
|
||||
@ -2528,6 +2539,13 @@ bool QgsRasterLayer::writeSymbology( QDomNode &layer_node, QDomDocument &documen
|
||||
layer_node.appendChild( blendModeElement );
|
||||
}
|
||||
|
||||
if ( categories.testFlag( Legend ) && legend() )
|
||||
{
|
||||
QDomElement legendElement = legend()->writeXml( document, context );
|
||||
if ( !legendElement.isNull() )
|
||||
layer_node.appendChild( legendElement );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,10 @@ QgsMapLayerStyleCategoriesModel::QgsMapLayerStyleCategoriesModel( Qgis::LayerTyp
|
||||
break;
|
||||
|
||||
case Qgis::LayerType::VectorTile:
|
||||
mCategoryList << QgsMapLayer::StyleCategory::Symbology << QgsMapLayer::StyleCategory::Labeling << QgsMapLayer::StyleCategory::AllVisualStyleCategories << QgsMapLayer::StyleCategory::AllStyleCategories;
|
||||
mCategoryList << QgsMapLayer::StyleCategory::Symbology
|
||||
<< QgsMapLayer::StyleCategory::Labeling
|
||||
<< QgsMapLayer::StyleCategory::AllVisualStyleCategories
|
||||
<< QgsMapLayer::StyleCategory::AllStyleCategories;
|
||||
break;
|
||||
|
||||
case Qgis::LayerType::Raster:
|
||||
@ -42,6 +45,7 @@ QgsMapLayerStyleCategoriesModel::QgsMapLayerStyleCategoriesModel( Qgis::LayerTyp
|
||||
<< QgsMapLayer::StyleCategory::Elevation
|
||||
<< QgsMapLayer::StyleCategory::AttributeTable
|
||||
<< QgsMapLayer::StyleCategory::Notes
|
||||
<< QgsMapLayer::StyleCategory::Legend
|
||||
<< QgsMapLayer::StyleCategory::AllVisualStyleCategories
|
||||
<< QgsMapLayer::StyleCategory::AllStyleCategories;
|
||||
break;
|
||||
|
@ -244,6 +244,7 @@ ADD_PYTHON_TEST(PyQgsPointCloudIndex test_qgspointcloudindex.py)
|
||||
ADD_PYTHON_TEST(PyQgsPointCloudDataProvider test_qgspointcloudprovider.py)
|
||||
ADD_PYTHON_TEST(PyQgsPointCloudElevationProperties test_qgspointcloudelevationproperties.py)
|
||||
ADD_PYTHON_TEST(PyQgsPointCloudExtentRenderer test_qgspointcloudextentrenderer.py)
|
||||
ADD_PYTHON_TEST(PyQgsPointCloudLayer test_qgspointcloudlayer.py)
|
||||
ADD_PYTHON_TEST(PyQgsPointCloudLayerProfileGenerator test_qgspointcloudlayerprofilegenerator.py)
|
||||
ADD_PYTHON_TEST(PyQgsPointCloudRgbRenderer test_qgspointcloudrgbrenderer.py)
|
||||
ADD_PYTHON_TEST(PyQgsPointClusterRenderer test_qgspointclusterrenderer.py)
|
||||
|
@ -6,8 +6,10 @@ the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
"""
|
||||
|
||||
from qgis.core import QgsMeshLayer, QgsMeshDatasetIndex
|
||||
from qgis.core import Qgis, QgsProject, QgsMeshLayer, QgsMeshDatasetIndex
|
||||
import unittest
|
||||
import tempfile
|
||||
|
||||
from qgis.testing import start_app, QgisTestCase
|
||||
|
||||
start_app()
|
||||
@ -63,6 +65,35 @@ class TestQgsMeshLayer(QgisTestCase):
|
||||
layer.datasetGroupMetadata(QgsMeshDatasetIndex(4)).parentQuantityName()
|
||||
)
|
||||
|
||||
def test_legend_settings(self):
|
||||
ml = QgsMeshLayer(
|
||||
self.get_test_data_path("mesh/netcdf_parent_quantity.nc").as_posix(),
|
||||
"test",
|
||||
"mdal",
|
||||
)
|
||||
self.assertTrue(ml.isValid())
|
||||
|
||||
self.assertFalse(ml.legend().flags() & Qgis.MapLayerLegendFlag.ExcludeByDefault)
|
||||
ml.legend().setFlag(Qgis.MapLayerLegendFlag.ExcludeByDefault)
|
||||
self.assertTrue(ml.legend().flags() & Qgis.MapLayerLegendFlag.ExcludeByDefault)
|
||||
|
||||
p = QgsProject()
|
||||
p.addMapLayer(ml)
|
||||
|
||||
# test saving and restoring
|
||||
with tempfile.TemporaryDirectory() as temp:
|
||||
self.assertTrue(p.write(temp + "/test.qgs"))
|
||||
|
||||
p2 = QgsProject()
|
||||
self.assertTrue(p2.read(temp + "/test.qgs"))
|
||||
|
||||
ml2 = list(p2.mapLayers().values())[0]
|
||||
self.assertEqual(ml2.name(), ml.name())
|
||||
|
||||
self.assertTrue(
|
||||
ml2.legend().flags() & Qgis.MapLayerLegendFlag.ExcludeByDefault
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
59
tests/src/python/test_qgspointcloudlayer.py
Normal file
59
tests/src/python/test_qgspointcloudlayer.py
Normal file
@ -0,0 +1,59 @@
|
||||
"""QGIS Unit tests for QgsPointCloudLayer
|
||||
|
||||
.. note:: This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
"""
|
||||
|
||||
from qgis.core import QgsPointCloudLayer, QgsProviderRegistry, Qgis, QgsProject
|
||||
import unittest
|
||||
import tempfile
|
||||
from qgis.testing import start_app, QgisTestCase
|
||||
|
||||
start_app()
|
||||
|
||||
|
||||
class TestQgsPointCloudLayer(QgisTestCase):
|
||||
|
||||
@unittest.skipIf(
|
||||
"ept" not in QgsProviderRegistry.instance().providerList(),
|
||||
"EPT provider not available",
|
||||
)
|
||||
def test_legend_settings(self):
|
||||
ml = QgsPointCloudLayer(
|
||||
(
|
||||
self.get_test_data_path("point_clouds")
|
||||
/ "ept"
|
||||
/ "sunshine-coast"
|
||||
/ "ept.json"
|
||||
).as_posix(),
|
||||
"test",
|
||||
"ept",
|
||||
)
|
||||
self.assertTrue(ml.isValid())
|
||||
|
||||
self.assertFalse(ml.legend().flags() & Qgis.MapLayerLegendFlag.ExcludeByDefault)
|
||||
ml.legend().setFlag(Qgis.MapLayerLegendFlag.ExcludeByDefault)
|
||||
self.assertTrue(ml.legend().flags() & Qgis.MapLayerLegendFlag.ExcludeByDefault)
|
||||
|
||||
p = QgsProject()
|
||||
p.addMapLayer(ml)
|
||||
|
||||
# test saving and restoring
|
||||
with tempfile.TemporaryDirectory() as temp:
|
||||
self.assertTrue(p.write(temp + "/test.qgs"))
|
||||
|
||||
p2 = QgsProject()
|
||||
self.assertTrue(p2.read(temp + "/test.qgs"))
|
||||
|
||||
ml2 = list(p2.mapLayers().values())[0]
|
||||
self.assertEqual(ml2.name(), ml.name())
|
||||
|
||||
self.assertTrue(
|
||||
ml2.legend().flags() & Qgis.MapLayerLegendFlag.ExcludeByDefault
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
@ -16,6 +16,7 @@ __copyright__ = "Copyright 2012, The QGIS Project"
|
||||
import filecmp
|
||||
import os
|
||||
from shutil import copyfile
|
||||
import tempfile
|
||||
|
||||
import numpy
|
||||
import numpy as np
|
||||
@ -1524,6 +1525,37 @@ class TestQgsRasterLayerTransformContext(QgisTestCase):
|
||||
self.assertEqual(arrays.shape, (1, 4, 4))
|
||||
self.assertEqual(arrays[0].dtype, np.float64)
|
||||
|
||||
def test_legend_settings(self):
|
||||
rl = QgsRasterLayer(
|
||||
os.path.join(
|
||||
unitTestDataPath("raster"), "rnd_percentile_raster5_float64.tif"
|
||||
),
|
||||
"test",
|
||||
"gdal",
|
||||
)
|
||||
self.assertTrue(rl.isValid())
|
||||
|
||||
self.assertFalse(rl.legend().flags() & Qgis.MapLayerLegendFlag.ExcludeByDefault)
|
||||
rl.legend().setFlag(Qgis.MapLayerLegendFlag.ExcludeByDefault)
|
||||
self.assertTrue(rl.legend().flags() & Qgis.MapLayerLegendFlag.ExcludeByDefault)
|
||||
|
||||
p = QgsProject()
|
||||
p.addMapLayer(rl)
|
||||
|
||||
# test saving and restoring
|
||||
with tempfile.TemporaryDirectory() as temp:
|
||||
self.assertTrue(p.write(temp + "/test.qgs"))
|
||||
|
||||
p2 = QgsProject()
|
||||
self.assertTrue(p2.read(temp + "/test.qgs"))
|
||||
|
||||
rl2 = list(p2.mapLayers().values())[0]
|
||||
self.assertEqual(rl2.name(), rl.name())
|
||||
|
||||
self.assertTrue(
|
||||
rl2.legend().flags() & Qgis.MapLayerLegendFlag.ExcludeByDefault
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
@ -5787,6 +5787,35 @@ class TestQgsVectorLayerTransformContext(QgisTestCase):
|
||||
QgsFieldConstraints.ConstraintStrength.ConstraintStrengthNotSet,
|
||||
)
|
||||
|
||||
def test_legend_settings(self):
|
||||
vl = QgsVectorLayer(
|
||||
"Point?crs=epsg:3111&field=field_default:integer&field=field_dupe:integer&field=field_unset:integer&field=field_ratio:integer",
|
||||
"test",
|
||||
"memory",
|
||||
)
|
||||
self.assertTrue(vl.isValid())
|
||||
|
||||
self.assertFalse(vl.legend().flags() & Qgis.MapLayerLegendFlag.ExcludeByDefault)
|
||||
vl.legend().setFlag(Qgis.MapLayerLegendFlag.ExcludeByDefault)
|
||||
self.assertTrue(vl.legend().flags() & Qgis.MapLayerLegendFlag.ExcludeByDefault)
|
||||
|
||||
p = QgsProject()
|
||||
p.addMapLayer(vl)
|
||||
|
||||
# test saving and restoring
|
||||
with tempfile.TemporaryDirectory() as temp:
|
||||
self.assertTrue(p.write(temp + "/test.qgs"))
|
||||
|
||||
p2 = QgsProject()
|
||||
self.assertTrue(p2.read(temp + "/test.qgs"))
|
||||
|
||||
vl2 = list(p2.mapLayers().values())[0]
|
||||
self.assertEqual(vl2.name(), vl.name())
|
||||
|
||||
self.assertTrue(
|
||||
vl2.legend().flags() & Qgis.MapLayerLegendFlag.ExcludeByDefault
|
||||
)
|
||||
|
||||
|
||||
# TODO:
|
||||
# - fetch rect: feat with changed geometry: 1. in rect, 2. out of rect
|
||||
|
Loading…
x
Reference in New Issue
Block a user