Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix style constraint save when strength is NotSet #58986

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion python/PyQt6/core/auto_generated/qgsfieldconstraints.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ is not present on this field.
ConstraintStrength constraintStrength( Constraint constraint ) const;
%Docstring
Returns the strength of a field constraint, or ConstraintStrengthNotSet if the constraint
is not present on this field.
is not present on this field. If the strength is not set returns ConstraintStrengthNotSet
for anything but ConstraintExpression which returns ConstraintStrengthHard.

.. seealso:: :py:func:`constraints`

Expand Down
3 changes: 2 additions & 1 deletion python/core/auto_generated/qgsfieldconstraints.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ is not present on this field.
ConstraintStrength constraintStrength( Constraint constraint ) const;
%Docstring
Returns the strength of a field constraint, or ConstraintStrengthNotSet if the constraint
is not present on this field.
is not present on this field. If the strength is not set returns ConstraintStrengthNotSet
for anything but ConstraintExpression which returns ConstraintStrengthHard.

.. seealso:: :py:func:`constraints`

Expand Down
4 changes: 2 additions & 2 deletions src/core/qgsfieldconstraints.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ QgsFieldConstraints::ConstraintStrength QgsFieldConstraints::constraintStrength(
if ( !( mConstraints & constraint ) )
return ConstraintStrengthNotSet;

// defaults to hard strength unless explicitly set
return mConstraintStrengths.value( constraint, ConstraintStrengthHard );
// defaults to not set for all but expressions (which does not use strength)
return mConstraintStrengths.value( constraint, constraint == ConstraintExpression ? ConstraintStrengthHard : ConstraintStrengthNotSet );
}

void QgsFieldConstraints::setConstraintStrength( QgsFieldConstraints::Constraint constraint, QgsFieldConstraints::ConstraintStrength strength )
Expand Down
3 changes: 2 additions & 1 deletion src/core/qgsfieldconstraints.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@ class CORE_EXPORT QgsFieldConstraints

/**
* Returns the strength of a field constraint, or ConstraintStrengthNotSet if the constraint
* is not present on this field.
* is not present on this field. If the strength is not set returns ConstraintStrengthNotSet
* for anything but ConstraintExpression which returns ConstraintStrengthHard.
* \see constraints()
* \see setConstraintStrength()
*/
Expand Down
1 change: 1 addition & 0 deletions src/core/vector/qgsvectorlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3145,6 +3145,7 @@ bool QgsVectorLayer::writeSymbology( QDomNode &node, QDomDocument &doc, QString
constraintElem.setAttribute( QStringLiteral( "unique_strength" ), field.constraints().constraintStrength( QgsFieldConstraints::ConstraintUnique ) );
constraintElem.setAttribute( QStringLiteral( "notnull_strength" ), field.constraints().constraintStrength( QgsFieldConstraints::ConstraintNotNull ) );
constraintElem.setAttribute( QStringLiteral( "exp_strength" ), field.constraints().constraintStrength( QgsFieldConstraints::ConstraintExpression ) );

constraintsElem.appendChild( constraintElem );
}
node.appendChild( constraintsElem );
Expand Down
41 changes: 41 additions & 0 deletions tests/src/python/test_qgsvectorlayer.py
Original file line number Diff line number Diff line change
Expand Up @@ -4675,6 +4675,47 @@ def test_selection_properties(self):
self.assertEqual(vl2.selectionProperties().selectionColor(),
QColor(255, 0, 0))

def testConstraintsotSet(self):
"""Test that a NotSet constraint does not become a Hard constraint
when saving and loading a layer style, see issue GH #58431"""

# Create a memory layer with unique constraints
layer = QgsVectorLayer("Point?field=fldtxt:string&field=fldint:integer", "test_unique", "memory")
self.assertTrue(layer.isValid())

# Se not constraints on fldtxt
layer.setFieldConstraint(0, QgsFieldConstraints.Constraint.ConstraintNotNull, QgsFieldConstraints.ConstraintStrength.ConstraintStrengthSoft)
layer.setFieldConstraint(0, QgsFieldConstraints.Constraint.ConstraintUnique, QgsFieldConstraints.ConstraintStrength.ConstraintStrengthNotSet)

# Check constraints at the field level
field = layer.fields().at(0)
constraints = field.constraints()
self.assertEqual(constraints.constraintStrength(QgsFieldConstraints.Constraint.ConstraintNotNull), QgsFieldConstraints.ConstraintStrength.ConstraintStrengthSoft)
self.assertEqual(constraints.constraintStrength(QgsFieldConstraints.Constraint.ConstraintUnique), QgsFieldConstraints.ConstraintStrength.ConstraintStrengthNotSet)

# Check constraints at the layer level
constraints = layer.fieldConstraintsAndStrength(0)
self.assertEqual(constraints[QgsFieldConstraints.Constraint.ConstraintNotNull], QgsFieldConstraints.ConstraintStrength.ConstraintStrengthSoft)
self.assertEqual(constraints[QgsFieldConstraints.Constraint.ConstraintUnique], QgsFieldConstraints.ConstraintStrength.ConstraintStrengthNotSet)

# Export the style to QML and reload it
style = QgsMapLayerStyle()
temp_file = tempfile.mktemp(suffix='.qml')
layer.saveNamedStyle(temp_file)
layer.loadNamedStyle(temp_file)

# Check constraints at the field level
field = layer.fields().at(0)
constraints = field.constraints()
self.assertEqual(constraints.constraintStrength(QgsFieldConstraints.Constraint.ConstraintNotNull), QgsFieldConstraints.ConstraintStrength.ConstraintStrengthSoft)
self.assertEqual(constraints.constraintStrength(QgsFieldConstraints.Constraint.ConstraintUnique), QgsFieldConstraints.ConstraintStrength.ConstraintStrengthNotSet)

# Check constraints at the layer level
constraints = layer.fieldConstraintsAndStrength(0)
self.assertEqual(constraints[QgsFieldConstraints.Constraint.ConstraintNotNull], QgsFieldConstraints.ConstraintStrength.ConstraintStrengthSoft)
self.assertEqual(constraints[QgsFieldConstraints.Constraint.ConstraintUnique], QgsFieldConstraints.ConstraintStrength.ConstraintStrengthNotSet)


# TODO:
# - fetch rect: feat with changed geometry: 1. in rect, 2. out of rect
# - more join tests
Expand Down
Loading