Skip to content

Commit

Permalink
Don't discard custom color/symbol when changing layer selection
Browse files Browse the repository at this point in the history
mode
  • Loading branch information
nyalldawson committed Jul 28, 2023
1 parent af15325 commit a7ed6a9
Show file tree
Hide file tree
Showing 10 changed files with 147 additions and 21 deletions.
7 changes: 7 additions & 0 deletions python/core/auto_additions/qgis.py
Original file line number Diff line number Diff line change
Expand Up @@ -1213,6 +1213,13 @@
Qgis.FieldMetadataProperty.__doc__ = "Standard field metadata values.\n\n.. versionadded:: 3.30\n\n" + '* ``GeometryCrs``: ' + Qgis.FieldMetadataProperty.GeometryCrs.__doc__ + '\n' + '* ``GeometryWkbType``: ' + Qgis.FieldMetadataProperty.GeometryWkbType.__doc__ + '\n' + '* ``CustomProperty``: ' + Qgis.FieldMetadataProperty.CustomProperty.__doc__
# --
Qgis.FieldMetadataProperty.baseClass = Qgis
# monkey patching scoped based enum
Qgis.SelectionRenderingMode.Default.__doc__ = "Use default symbol and selection colors"
Qgis.SelectionRenderingMode.CustomColor.__doc__ = "Use default symbol with a custom selection color"
Qgis.SelectionRenderingMode.CustomSymbol.__doc__ = "Use a custom symbol"
Qgis.SelectionRenderingMode.__doc__ = "Specifies how a selection should be rendered.\n\n.. versionadded:: 3.34\n\n" + '* ``Default``: ' + Qgis.SelectionRenderingMode.Default.__doc__ + '\n' + '* ``CustomColor``: ' + Qgis.SelectionRenderingMode.CustomColor.__doc__ + '\n' + '* ``CustomSymbol``: ' + Qgis.SelectionRenderingMode.CustomSymbol.__doc__
# --
Qgis.SelectionRenderingMode.baseClass = Qgis
QgsVectorLayer.SelectBehavior = Qgis.SelectBehavior
# monkey patching scoped based enum
QgsVectorLayer.SetSelection = Qgis.SelectBehavior.SetSelection
Expand Down
7 changes: 7 additions & 0 deletions python/core/auto_generated/qgis.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -705,6 +705,13 @@ The development version
CustomProperty,
};

enum class SelectionRenderingMode
{
Default,
CustomColor,
CustomSymbol,
};

enum class SelectBehavior
{
SetSelection,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,20 @@ Constructor for QgsVectorLayerSelectionProperties, with the specified ``parent``
virtual QgsVectorLayerSelectionProperties *clone() const /Factory/;


Qgis::SelectionRenderingMode selectionRenderingMode() const;
%Docstring
Returns the selection rendering mode to use for selected features in the layer.

.. seealso:: :py:func:`setSelectionRenderingMode`
%End

void setSelectionRenderingMode( Qgis::SelectionRenderingMode mode );
%Docstring
Sets the selection rendering ``mode`` to use for selected features in the layer.

.. seealso:: :py:func:`selectionRenderingMode`
%End

QColor selectionColor() const;
%Docstring
Returns the color to use for rendering selected features in the layer.
Expand Down
13 changes: 13 additions & 0 deletions src/core/qgis.h
Original file line number Diff line number Diff line change
Expand Up @@ -1161,6 +1161,19 @@ class CORE_EXPORT Qgis
};
Q_ENUM( FieldMetadataProperty )

/**
* Specifies how a selection should be rendered.
*
* \since QGIS 3.34
*/
enum class SelectionRenderingMode : int
{
Default, //!< Use default symbol and selection colors
CustomColor, //!< Use default symbol with a custom selection color
CustomSymbol, //!< Use a custom symbol
};
Q_ENUM( SelectionRenderingMode )

/**
* Specifies how a selection should be applied.
*
Expand Down
27 changes: 21 additions & 6 deletions src/core/vector/qgsvectorlayerrenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,28 @@ QgsVectorLayerRenderer::QgsVectorLayerRenderer( QgsVectorLayer *layer, QgsRender
{
std::unique_ptr< QgsFeatureRenderer > mainRenderer( layer->renderer() ? layer->renderer()->clone() : nullptr );

// overwrite default selection color if layer has a specific selection color set
const QColor layerSelectionColor = qobject_cast< QgsVectorLayerSelectionProperties * >( layer->selectionProperties() )->selectionColor();
if ( layerSelectionColor.isValid() )
context.setSelectionColor( layerSelectionColor );
QgsVectorLayerSelectionProperties *selectionProperties = qobject_cast< QgsVectorLayerSelectionProperties * >( layer->selectionProperties() );
switch ( selectionProperties->selectionRenderingMode() )
{
case Qgis::SelectionRenderingMode::Default:
break;

case Qgis::SelectionRenderingMode::CustomColor:
{
// overwrite default selection color if layer has a specific selection color set
const QColor layerSelectionColor = selectionProperties->selectionColor();
if ( layerSelectionColor.isValid() )
context.setSelectionColor( layerSelectionColor );
break;
}

if ( QgsSymbol *selectionSymbol = qobject_cast< QgsVectorLayerSelectionProperties * >( layer->selectionProperties() )->selectionSymbol() )
mSelectionSymbol.reset( selectionSymbol->clone() );
case Qgis::SelectionRenderingMode::CustomSymbol:
{
if ( QgsSymbol *selectionSymbol = qobject_cast< QgsVectorLayerSelectionProperties * >( layer->selectionProperties() )->selectionSymbol() )
mSelectionSymbol.reset( selectionSymbol->clone() );
break;
}
}

if ( !mainRenderer )
return;
Expand Down
14 changes: 14 additions & 0 deletions src/core/vector/qgsvectorlayerselectionproperties.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ QDomElement QgsVectorLayerSelectionProperties::writeXml( QDomElement &parentElem
{
QDomElement element = document.createElement( QStringLiteral( "selection" ) );

element.setAttribute( QStringLiteral( "mode" ), qgsEnumValueToKey( mSelectionRenderingMode ) );

QgsColorUtils::writeXml( mSelectionColor, QStringLiteral( "selectionColor" ), document, element, context );

if ( mSelectionSymbol )
Expand All @@ -50,6 +52,7 @@ bool QgsVectorLayerSelectionProperties::readXml( const QDomElement &element, con
if ( selectionElement.isNull() )
return false;

mSelectionRenderingMode = qgsEnumKeyToValue( selectionElement.attribute( QStringLiteral( "mode" ) ), Qgis::SelectionRenderingMode::Default );
mSelectionColor = QgsColorUtils::readXml( selectionElement, QStringLiteral( "selectionColor" ), context );

{
Expand All @@ -62,6 +65,7 @@ bool QgsVectorLayerSelectionProperties::readXml( const QDomElement &element, con
QgsVectorLayerSelectionProperties *QgsVectorLayerSelectionProperties::clone() const
{
std::unique_ptr< QgsVectorLayerSelectionProperties > res = std::make_unique< QgsVectorLayerSelectionProperties >( nullptr );
res->mSelectionRenderingMode = mSelectionRenderingMode;
res->mSelectionColor = mSelectionColor;
res->mSelectionSymbol.reset( mSelectionSymbol ? mSelectionSymbol->clone() : nullptr );
return res.release();
Expand All @@ -86,3 +90,13 @@ void QgsVectorLayerSelectionProperties::setSelectionSymbol( QgsSymbol *symbol )
{
mSelectionSymbol.reset( symbol );
}

Qgis::SelectionRenderingMode QgsVectorLayerSelectionProperties::selectionRenderingMode() const
{
return mSelectionRenderingMode;
}

void QgsVectorLayerSelectionProperties::setSelectionRenderingMode( Qgis::SelectionRenderingMode mode )
{
mSelectionRenderingMode = mode;
}
15 changes: 15 additions & 0 deletions src/core/vector/qgsvectorlayerselectionproperties.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,20 @@ class CORE_EXPORT QgsVectorLayerSelectionProperties : public QgsMapLayerSelectio
bool readXml( const QDomElement &element, const QgsReadWriteContext &context ) override;
QgsVectorLayerSelectionProperties *clone() const override SIP_FACTORY;

/**
* Returns the selection rendering mode to use for selected features in the layer.
*
* \see setSelectionRenderingMode()
*/
Qgis::SelectionRenderingMode selectionRenderingMode() const;

/**
* Sets the selection rendering \a mode to use for selected features in the layer.
*
* \see selectionRenderingMode()
*/
void setSelectionRenderingMode( Qgis::SelectionRenderingMode mode );

/**
* Returns the color to use for rendering selected features in the layer.
*
Expand Down Expand Up @@ -92,6 +106,7 @@ class CORE_EXPORT QgsVectorLayerSelectionProperties : public QgsMapLayerSelectio

private:

Qgis::SelectionRenderingMode mSelectionRenderingMode = Qgis::SelectionRenderingMode::Default;
QColor mSelectionColor;
std::unique_ptr< QgsSymbol > mSelectionSymbol;
};
Expand Down
56 changes: 42 additions & 14 deletions src/gui/vector/qgsvectorlayerproperties.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -591,19 +591,43 @@ void QgsVectorLayerProperties::syncToLayer()
mSimplifyDrawingSpinBox->setClearValue( 1.0 );

QgsVectorLayerSelectionProperties *selectionProperties = qobject_cast< QgsVectorLayerSelectionProperties *>( mLayer->selectionProperties() );
if ( QgsSymbol *symbol = selectionProperties->selectionSymbol() )
if ( selectionProperties->selectionColor().isValid() )
{
mRadioOverrideSelectionSymbol->setChecked( true );
mSelectionSymbolButton->setSymbol( symbol->clone() );
mSelectionColorButton->setColor( selectionProperties->selectionColor() );
}
else if ( selectionProperties->selectionColor().isValid() )
if ( QgsSymbol *symbol = selectionProperties->selectionSymbol() )
{
mSelectionColorButton->setColor( selectionProperties->selectionColor() );
mRadioOverrideSelectionColor->setChecked( true );
mSelectionSymbolButton->setSymbol( symbol->clone() );
}
else
switch ( selectionProperties->selectionRenderingMode() )
{
mRadioDefaultSelectionColor->setChecked( true );
case Qgis::SelectionRenderingMode::Default:
mRadioDefaultSelectionColor->setChecked( true );
break;

case Qgis::SelectionRenderingMode::CustomColor:
{
if ( selectionProperties->selectionColor().isValid() )
{
mRadioOverrideSelectionColor->setChecked( true );
}
else
{
mRadioDefaultSelectionColor->setChecked( true );
}
break;
}

case Qgis::SelectionRenderingMode::CustomSymbol:
if ( QgsSymbol *symbol = selectionProperties->selectionSymbol() )
{
mRadioOverrideSelectionSymbol->setChecked( true );
}
else
{
mRadioDefaultSelectionColor->setChecked( true );
}
break;
}

QString remark = QStringLiteral( " (%1)" ).arg( tr( "Not supported" ) );
Expand Down Expand Up @@ -872,20 +896,24 @@ void QgsVectorLayerProperties::apply()


QgsVectorLayerSelectionProperties *selectionProperties = qobject_cast< QgsVectorLayerSelectionProperties *>( mLayer->selectionProperties() );
if ( mSelectionColorButton->color() != mSelectionColorButton->defaultColor() )
selectionProperties->setSelectionColor( mSelectionColorButton->color() );
else
selectionProperties->setSelectionColor( QColor() );
if ( QgsSymbol *symbol = mSelectionSymbolButton->symbol() )
selectionProperties->setSelectionSymbol( symbol->clone() );

if ( mRadioOverrideSelectionSymbol->isChecked() )
{
selectionProperties->setSelectionColor( QColor() );
selectionProperties->setSelectionSymbol( mSelectionSymbolButton->symbol()->clone() );
selectionProperties->setSelectionRenderingMode( Qgis::SelectionRenderingMode::CustomSymbol );
}
else if ( mRadioOverrideSelectionColor->isChecked() )
{
selectionProperties->setSelectionColor( mSelectionColorButton->color() );
selectionProperties->setSelectionSymbol( nullptr );
selectionProperties->setSelectionRenderingMode( Qgis::SelectionRenderingMode::CustomColor );
}
else
{
selectionProperties->setSelectionColor( QColor() );
selectionProperties->setSelectionSymbol( nullptr );
selectionProperties->setSelectionRenderingMode( Qgis::SelectionRenderingMode::Default );
}

mLayer->setAutoRefreshInterval( mRefreshLayerIntervalSpinBox->value() * 1000.0 );
Expand Down
8 changes: 7 additions & 1 deletion tests/src/python/test_qgsvectorlayer.py
Original file line number Diff line number Diff line change
Expand Up @@ -4543,6 +4543,8 @@ def test_selection_properties(self):
)
self.assertEqual(vl.selectionProperties().selectionColor(),
QColor(255, 0, 0))
vl.selectionProperties().setSelectionRenderingMode(
Qgis.SelectionRenderingMode.CustomColor)

p = QgsProject()
p.addMapLayer(vl)
Expand All @@ -4557,6 +4559,9 @@ def test_selection_properties(self):
vl2 = list(p2.mapLayers().values())[0]
self.assertEqual(vl2.name(), vl.name())

self.assertEqual(vl2.selectionProperties().selectionRenderingMode(),
Qgis.SelectionRenderingMode.CustomColor)

self.assertEqual(vl2.selectionProperties().selectionColor(),
QColor(255, 0, 0))

Expand All @@ -4577,7 +4582,8 @@ def test_selection_properties(self):

self.assertEqual(vl2.selectionProperties().selectionSymbol().color(),
QColor(25, 26, 27))

self.assertEqual(vl2.selectionProperties().selectionColor(),
QColor(255, 0, 0))

# TODO:
# - fetch rect: feat with changed geometry: 1. in rect, 2. out of rect
Expand Down
7 changes: 7 additions & 0 deletions tests/src/python/test_qgsvectorlayerrenderer.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from qgis.PyQt.QtGui import QColor

from qgis.core import (
Qgis,
QgsCategorizedSymbolRenderer,
QgsCentroidFillSymbolLayer,
QgsCoordinateReferenceSystem,
Expand Down Expand Up @@ -726,6 +727,9 @@ def testRenderWithSelectedFeatureColor(self):
poly_layer.selectionProperties().setSelectionColor(
QColor(255, 0, 0)
)
poly_layer.selectionProperties().setSelectionRenderingMode(
Qgis.SelectionRenderingMode.CustomColor
)

mapsettings = QgsMapSettings()
mapsettings.setOutputSize(QSize(400, 400))
Expand Down Expand Up @@ -755,6 +759,9 @@ def testRenderWithSelectedFeatureSymbol(self):
poly_layer.selectionProperties().setSelectionSymbol(
QgsFillSymbol.createSimple({'style': 'no', 'outline_color': '#6666ff', 'outline_width': '3'})
)
poly_layer.selectionProperties().setSelectionRenderingMode(
Qgis.SelectionRenderingMode.CustomSymbol
)

mapsettings = QgsMapSettings()
mapsettings.setOutputSize(QSize(400, 400))
Expand Down

0 comments on commit a7ed6a9

Please sign in to comment.