fix duplicate layer

This commit is contained in:
Julien Cabieces 2022-11-08 16:12:57 +01:00
parent a1b2eac2d7
commit f8c1c16ec7
7 changed files with 110 additions and 17 deletions

View File

@ -803,7 +803,7 @@ Returns the units used for the offset of the shapeburst fill.
QgsShapeburstFillSymbolLayer( const QgsShapeburstFillSymbolLayer &other );
};
class QgsImageFillSymbolLayer: QgsFillSymbolLayer
class QgsImageFillSymbolLayer: QgsFillSymbolLayer /Abstract/
{
%Docstring(signature="appended")
Base class for polygon renderers generating texture images
@ -2818,8 +2818,6 @@ Sets whether point markers should be ``clipped`` to the current part boundary on
QgsCentroidFillSymbolLayer( const QgsCentroidFillSymbolLayer &other );
};
/************************************************************************
* This file has been generated automatically from *
* *

View File

@ -1049,6 +1049,27 @@ to new ones.
%Docstring
Remove recursively unique id from all ``symbol`` symbol layers and set an empty string instead
.. versionadded:: 3.30
%End
static void clearSymbolLayerIds( QgsSymbolLayer *symbolLayer );
%Docstring
Remove recursively unique id from ``symbolLayer`` and its children and set an empty string instead
.. versionadded:: 3.30
%End
static void resetSymbolLayerIds( QgsSymbol *symbol );
%Docstring
Regenerate recursively unique id from all ``symbol`` symbol layers
.. versionadded:: 3.30
%End
static void resetSymbolLayerIds( QgsSymbolLayer *symbolLayer );
%Docstring
Regenerate recursively unique id from ``symbolLayer`` and its children
.. versionadded:: 3.30
%End

View File

@ -776,7 +776,7 @@ class CORE_EXPORT QgsShapeburstFillSymbolLayer : public QgsFillSymbolLayer
* \ingroup core
* \brief Base class for polygon renderers generating texture images
*/
class CORE_EXPORT QgsImageFillSymbolLayer: public QgsFillSymbolLayer
class CORE_EXPORT QgsImageFillSymbolLayer: public QgsFillSymbolLayer SIP_ABSTRACT
{
public:
@ -2550,5 +2550,3 @@ class CORE_EXPORT QgsCentroidFillSymbolLayer : public QgsFillSymbolLayer
};
#endif

View File

@ -5446,20 +5446,43 @@ void QgsSymbolLayerUtils::fixOldSymbolLayerReferences( const QMap<QString, QgsMa
}
}
void QgsSymbolLayerUtils::clearSymbolLayerIds( QgsSymbol *symbol )
template <typename Functor>
void changeSymbolLayerIds( QgsSymbolLayer *sl, Functor &&generateId )
{
sl->setId( generateId() );
// recurse over sub symbols
QgsSymbol *subSymbol = sl->subSymbol();
if ( subSymbol )
changeSymbolLayerIds( subSymbol, generateId );
}
template <typename Functor>
void changeSymbolLayerIds( QgsSymbol *symbol, Functor &&generateId )
{
if ( !symbol )
return;
for ( int idx = 0; idx < symbol->symbolLayerCount(); idx++ )
{
QgsSymbolLayer *sl = symbol->symbolLayer( idx );
sl->setId( QString() );
// recurse over sub symbols
QgsSymbol *subSymbol = const_cast<QgsSymbolLayer *>( sl )->subSymbol();
if ( subSymbol )
clearSymbolLayerIds( subSymbol );
}
changeSymbolLayerIds( symbol->symbolLayer( idx ), generateId );
}
void QgsSymbolLayerUtils::clearSymbolLayerIds( QgsSymbol *symbol )
{
changeSymbolLayerIds( symbol, []() { return QString(); } );
}
void QgsSymbolLayerUtils::clearSymbolLayerIds( QgsSymbolLayer *symbolLayer )
{
changeSymbolLayerIds( symbolLayer, []() { return QString(); } );
}
void QgsSymbolLayerUtils::resetSymbolLayerIds( QgsSymbolLayer *symbolLayer )
{
changeSymbolLayerIds( symbolLayer, []() { return QUuid::createUuid().toString(); } );
}
void QgsSymbolLayerUtils::resetSymbolLayerIds( QgsSymbol *symbol )
{
changeSymbolLayerIds( symbol, []() { return QUuid::createUuid().toString(); } );
}

View File

@ -943,6 +943,24 @@ class CORE_EXPORT QgsSymbolLayerUtils
*/
static void clearSymbolLayerIds( QgsSymbol *symbol );
/**
* Remove recursively unique id from \a symbolLayer and its children and set an empty string instead
* \since QGIS 3.30
*/
static void clearSymbolLayerIds( QgsSymbolLayer *symbolLayer );
/**
* Regenerate recursively unique id from all \a symbol symbol layers
* \since QGIS 3.30
*/
static void resetSymbolLayerIds( QgsSymbol *symbol );
/**
* Regenerate recursively unique id from \a symbolLayer and its children
* \since QGIS 3.30
*/
static void resetSymbolLayerIds( QgsSymbolLayer *symbolLayer );
///@cond PRIVATE
#ifndef SIP_RUN
static QgsProperty rotateWholeSymbol( double additionalRotation, const QgsProperty &property )

View File

@ -721,6 +721,7 @@ void QgsSymbolSelectorWidget::duplicateLayer()
QgsSymbol *parentSymbol = item->symbol();
QgsSymbolLayer *newLayer = source->clone();
QgsSymbolLayerUtils::resetSymbolLayerIds( newLayer );
if ( insertIdx == -1 )
parentSymbol->appendSymbolLayer( newLayer );
else

View File

@ -736,6 +736,40 @@ class PyQgsSymbolLayerUtils(unittest.TestCase):
self.assertEqual(res_size.width(), int(exp_width))
self.assertAlmostEqual(res_angle, exp_angle)
def test_clear_symbollayer_ids(self):
"""
Test we manage to clear all symbol layer ids on a symbol
"""
source = QgsVectorLayer("Polygon?crs=EPSG:4326", 'layer', "memory")
self.assertTrue(source.isValid())
layer = QgsLinePatternFillSymbolLayer()
fill_symbol = QgsFillSymbol([layer])
sub_renderer = QgsSingleSymbolRenderer(fill_symbol)
source.setRenderer(sub_renderer)
self.assertEqual(len(fill_symbol.symbolLayers()), 1)
subsymbol = fill_symbol.symbolLayers()[0].subSymbol()
self.assertTrue(subsymbol)
self.assertEqual(len(subsymbol.symbolLayers()), 1)
child_sl = subsymbol.symbolLayers()[0]
self.assertTrue(child_sl)
old_id = child_sl.id()
self.assertTrue(child_sl.id())
QgsSymbolLayerUtils.resetSymbolLayerIds(fill_symbol)
self.assertTrue(child_sl.id())
self.assertTrue(child_sl.id() != old_id)
QgsSymbolLayerUtils.clearSymbolLayerIds(fill_symbol)
self.assertFalse(child_sl.id())
if __name__ == '__main__':
unittest.main()