Skip to content

Commit

Permalink
don't recycle rulekeys when copy pasting rules in the rule-based rend…
Browse files Browse the repository at this point in the history
…er widget (#51292)

Fixes #47915
  • Loading branch information
roya0045 committed Feb 1, 2023
1 parent 5e4d278 commit 7cf5848
Show file tree
Hide file tree
Showing 8 changed files with 22 additions and 10 deletions.
Expand Up @@ -233,12 +233,13 @@ clone this rule, return new instance
%End


static QgsRuleBasedLabeling::Rule *create( const QDomElement &ruleElem, const QgsReadWriteContext &context ) /Factory/;
static QgsRuleBasedLabeling::Rule *create( const QDomElement &ruleElem, const QgsReadWriteContext &context, bool reuseId = true ) /Factory/;
%Docstring
Create a rule from an XML definition

:param ruleElem: The XML rule element
:param context: reading context
:param reuseId: set to ``True`` to create an exact copy of the original symbol or ``False`` to create a new rule with the same parameters as the original but a new unique :py:func:`~Rule.ruleKey`. (Since QGIS 3.30)

:return: A new rule
%End
Expand Down
Expand Up @@ -356,12 +356,13 @@ Stop a rendering process. Used to clean up the internal state of this rule
:param context: The rendering context
%End

static QgsRuleBasedRenderer::Rule *create( QDomElement &ruleElem, QgsSymbolMap &symbolMap ) /Factory/;
static QgsRuleBasedRenderer::Rule *create( QDomElement &ruleElem, QgsSymbolMap &symbolMap, bool reuseId = true ) /Factory/;
%Docstring
Create a rule from an XML definition

:param ruleElem: The XML rule element
:param symbolMap: Symbol map
:param reuseId: set to ``True`` to create an exact copy of the original symbol or ``False`` to create a new rule with the same parameters as the original but a new unique :py:func:`~Rule.ruleKey`. (Since QGIS 3.30)

:return: A new rule
%End
Expand Down
8 changes: 6 additions & 2 deletions src/core/labeling/qgsrulebasedlabeling.cpp
Expand Up @@ -239,7 +239,7 @@ QgsRuleBasedLabeling::Rule *QgsRuleBasedLabeling::Rule::clone() const
return newrule;
}

QgsRuleBasedLabeling::Rule *QgsRuleBasedLabeling::Rule::create( const QDomElement &ruleElem, const QgsReadWriteContext &context )
QgsRuleBasedLabeling::Rule *QgsRuleBasedLabeling::Rule::create( const QDomElement &ruleElem, const QgsReadWriteContext &context, bool reuseId )
{
QgsPalLayerSettings *settings = nullptr;
QDomElement settingsElem = ruleElem.firstChildElement( QStringLiteral( "settings" ) );
Expand All @@ -253,7 +253,11 @@ QgsRuleBasedLabeling::Rule *QgsRuleBasedLabeling::Rule::create( const QDomElemen
QString description = ruleElem.attribute( QStringLiteral( "description" ) );
int scaleMinDenom = ruleElem.attribute( QStringLiteral( "scalemindenom" ), QStringLiteral( "0" ) ).toInt();
int scaleMaxDenom = ruleElem.attribute( QStringLiteral( "scalemaxdenom" ), QStringLiteral( "0" ) ).toInt();
QString ruleKey = ruleElem.attribute( QStringLiteral( "key" ) );
QString ruleKey;
if ( reuseId )
ruleKey = ruleElem.attribute( QStringLiteral( "key" ) );
else
ruleKey = QUuid::createUuid().toString();
Rule *rule = new Rule( settings, scaleMinDenom, scaleMaxDenom, filterExp, description );

if ( !ruleKey.isEmpty() )
Expand Down
3 changes: 2 additions & 1 deletion src/core/labeling/qgsrulebasedlabeling.h
Expand Up @@ -254,9 +254,10 @@ class CORE_EXPORT QgsRuleBasedLabeling : public QgsAbstractVectorLayerLabeling
* Create a rule from an XML definition
* \param ruleElem The XML rule element
* \param context reading context
* \param reuseId set to TRUE to create an exact copy of the original symbol or FALSE to create a new rule with the same parameters as the original but a new unique ruleKey(). (Since QGIS 3.30)
* \returns A new rule
*/
static QgsRuleBasedLabeling::Rule *create( const QDomElement &ruleElem, const QgsReadWriteContext &context ) SIP_FACTORY;
static QgsRuleBasedLabeling::Rule *create( const QDomElement &ruleElem, const QgsReadWriteContext &context, bool reuseId = true ) SIP_FACTORY;

//! store labeling info to XML element
QDomElement save( QDomDocument &doc, const QgsReadWriteContext &context ) const;
Expand Down
8 changes: 6 additions & 2 deletions src/core/symbology/qgsrulebasedrenderer.cpp
Expand Up @@ -742,7 +742,7 @@ void QgsRuleBasedRenderer::Rule::stopRender( QgsRenderContext &context )
mSymbolNormZLevels.clear();
}

QgsRuleBasedRenderer::Rule *QgsRuleBasedRenderer::Rule::create( QDomElement &ruleElem, QgsSymbolMap &symbolMap )
QgsRuleBasedRenderer::Rule *QgsRuleBasedRenderer::Rule::create( QDomElement &ruleElem, QgsSymbolMap &symbolMap, bool reuseId )
{
QString symbolIdx = ruleElem.attribute( QStringLiteral( "symbol" ) );
QgsSymbol *symbol = nullptr;
Expand All @@ -763,7 +763,11 @@ QgsRuleBasedRenderer::Rule *QgsRuleBasedRenderer::Rule::create( QDomElement &rul
QString description = ruleElem.attribute( QStringLiteral( "description" ) );
int scaleMinDenom = ruleElem.attribute( QStringLiteral( "scalemindenom" ), QStringLiteral( "0" ) ).toInt();
int scaleMaxDenom = ruleElem.attribute( QStringLiteral( "scalemaxdenom" ), QStringLiteral( "0" ) ).toInt();
QString ruleKey = ruleElem.attribute( QStringLiteral( "key" ) );
QString ruleKey;
if ( reuseId )
ruleKey = ruleElem.attribute( QStringLiteral( "key" ) );
else
ruleKey = QUuid::createUuid().toString();
Rule *rule = new Rule( symbol, scaleMinDenom, scaleMaxDenom, filterExp, label, description );

if ( !ruleKey.isEmpty() )
Expand Down
3 changes: 2 additions & 1 deletion src/core/symbology/qgsrulebasedrenderer.h
Expand Up @@ -383,10 +383,11 @@ class CORE_EXPORT QgsRuleBasedRenderer : public QgsFeatureRenderer
*
* \param ruleElem The XML rule element
* \param symbolMap Symbol map
* \param reuseId set to TRUE to create an exact copy of the original symbol or FALSE to create a new rule with the same parameters as the original but a new unique ruleKey(). (Since QGIS 3.30)
*
* \returns A new rule
*/
static QgsRuleBasedRenderer::Rule *create( QDomElement &ruleElem, QgsSymbolMap &symbolMap ) SIP_FACTORY;
static QgsRuleBasedRenderer::Rule *create( QDomElement &ruleElem, QgsSymbolMap &symbolMap, bool reuseId = true ) SIP_FACTORY;

/**
* Returns all children rules of this rule
Expand Down
2 changes: 1 addition & 1 deletion src/gui/labeling/qgsrulebasedlabelingwidget.cpp
Expand Up @@ -595,7 +595,7 @@ bool QgsRuleBasedLabelingModel::dropMimeData( const QMimeData *data, Qt::DropAct
QDomElement ruleElem = rootElem.firstChildElement( QStringLiteral( "rule" ) );
if ( rootElem.attribute( QStringLiteral( "type" ) ) == QLatin1String( "renderer" ) )
_renderer2labelingRules( ruleElem ); // do some modifications so that we load the rules more nicely
QgsRuleBasedLabeling::Rule *rule = QgsRuleBasedLabeling::Rule::create( ruleElem, QgsReadWriteContext() );
QgsRuleBasedLabeling::Rule *rule = QgsRuleBasedLabeling::Rule::create( ruleElem, QgsReadWriteContext(), false );

insertRule( parent, row + rows, rule );

Expand Down
2 changes: 1 addition & 1 deletion src/gui/symbology/qgsrulebasedrendererwidget.cpp
Expand Up @@ -1260,7 +1260,7 @@ bool QgsRuleBasedRendererModel::dropMimeData( const QMimeData *data,
QDomElement ruleElem = rootElem.firstChildElement( QStringLiteral( "rule" ) );
if ( rootElem.attribute( QStringLiteral( "type" ) ) == QLatin1String( "labeling" ) )
_labeling2rendererRules( ruleElem );
QgsRuleBasedRenderer::Rule *rule = QgsRuleBasedRenderer::Rule::create( ruleElem, symbolMap );
QgsRuleBasedRenderer::Rule *rule = QgsRuleBasedRenderer::Rule::create( ruleElem, symbolMap, false );

insertRule( parent, row + rows, rule );

Expand Down

0 comments on commit 7cf5848

Please sign in to comment.