Make QgsConditionalLayerStyles a QObject

and add a "changed" signal to it, so that we can tell when the
layer's conditional styles change
This commit is contained in:
Nyall Dawson 2019-09-25 08:05:10 +10:00
parent d43834e999
commit b1ee295a95
7 changed files with 121 additions and 47 deletions

View File

@ -12,7 +12,7 @@
typedef QList<QgsConditionalStyle> QgsConditionalStyles;
class QgsConditionalLayerStyles
class QgsConditionalLayerStyles : QObject
{
%Docstring
The QgsConditionalLayerStyles class holds conditional style information
@ -23,43 +23,64 @@ for a layer. This includes field styles and full row styles.
#include "qgsconditionalstyle.h"
%End
public:
QgsConditionalLayerStyles();
QList<QgsConditionalStyle> rowStyles();
void setRowStyles( const QList<QgsConditionalStyle> &styles );
QgsConditionalLayerStyles( QObject *parent = 0 );
%Docstring
Set the conditional styles that apply to full rows of data in the attribute table.
Constructor for QgsConditionalLayerStyles, with the specified ``parent`` object.
%End
QgsConditionalStyles rowStyles() const;
%Docstring
Returns a list of row styles associated with the layer.
.. seealso:: :py:func:`setRowStyles`
%End
void setRowStyles( const QgsConditionalStyles &styles );
%Docstring
Sets the conditional ``styles`` that apply to full rows of data in the attribute table.
Each row will check be checked against each rule.
:param styles: The styles to assign to all the rows
.. seealso:: :py:func:`rowStyles`
.. versionadded:: 2.12
%End
void setFieldStyles( const QString &fieldName, const QList<QgsConditionalStyle> &styles );
%Docstring
Set the conditional styles for the field UI properties.
Set the conditional ``styles`` for a field, with the specified ``fieldName``.
:param fieldName: name of field
:param styles:
.. seealso:: :py:func:`fieldStyles`
%End
QList<QgsConditionalStyle> fieldStyles( const QString &fieldName );
QList<QgsConditionalStyle> fieldStyles( const QString &fieldName ) const;
%Docstring
Returns the conditional styles set for the field UI properties
Returns the conditional styles set for the field with matching ``fieldName``.
:return: A list of conditional styles that have been set.
.. seealso:: :py:func:`setFieldStyles`
%End
bool readXml( const QDomNode &node, const QgsReadWriteContext &context );
%Docstring
Reads field ui properties specific state from Dom node.
Reads the condition styles state from a DOM node.
.. seealso:: :py:func:`writeXml`
%End
bool writeXml( QDomNode &node, QDomDocument &doc, const QgsReadWriteContext &context ) const;
%Docstring
Write field ui properties specific state from Dom node.
Writes the condition styles state to a DOM node.
.. seealso:: :py:func:`readXml`
%End
signals:
void changed();
%Docstring
Emitted when the conditional styles are changed.
.. versionadded:: 3.10
%End
};

View File

@ -25,7 +25,6 @@
%Include auto_generated/qgscolorramp.sip
%Include auto_generated/qgscolorscheme.sip
%Include auto_generated/qgscolorschemeregistry.sip
%Include auto_generated/qgsconditionalstyle.sip
%Include auto_generated/qgscoordinateformatter.sip
%Include auto_generated/qgscoordinatetransform.sip
%Include auto_generated/qgscoordinatetransformcontext.sip
@ -346,6 +345,7 @@
%Include auto_generated/qgsbookmarkmodel.sip
%Include auto_generated/qgsbrowsermodel.sip
%Include auto_generated/qgsbrowserproxymodel.sip
%Include auto_generated/qgsconditionalstyle.sip
%Include auto_generated/qgscoordinatereferencesystem.sip
%Include auto_generated/qgscredentials.sip
%Include auto_generated/qgsdataitem.sip

View File

@ -660,6 +660,7 @@ SET(QGIS_CORE_MOC_HDRS
qgsbookmarkmodel.h
qgsbrowsermodel.h
qgsbrowserproxymodel.h
qgsconditionalstyle.h
qgscoordinatereferencesystem.h
qgscoordinateutils.h
qgscredentials.h
@ -931,7 +932,6 @@ SET(QGIS_CORE_HDRS
qgscolorscheme.h
qgscolorschemeregistry.h
qgsconnectionpool.h
qgsconditionalstyle.h
qgscoordinateformatter.h
qgscoordinatetransform.h
qgscoordinatetransformcontext.h

View File

@ -20,32 +20,36 @@
#include "qgssymbollayerutils.h"
#include "qgsmarkersymbollayer.h"
QgsConditionalLayerStyles::QgsConditionalLayerStyles()
: mRowStyles( QList<QgsConditionalStyle>() )
QgsConditionalLayerStyles::QgsConditionalLayerStyles( QObject *parent )
: QObject( parent )
{}
QList<QgsConditionalStyle> QgsConditionalLayerStyles::rowStyles()
QgsConditionalStyles QgsConditionalLayerStyles::rowStyles() const
{
return mRowStyles;
}
void QgsConditionalLayerStyles::setRowStyles( const QList<QgsConditionalStyle> &styles )
void QgsConditionalLayerStyles::setRowStyles( const QgsConditionalStyles &styles )
{
if ( styles == mRowStyles )
return;
mRowStyles = styles;
emit changed();
}
void QgsConditionalLayerStyles::setFieldStyles( const QString &fieldName, const QList<QgsConditionalStyle> &styles )
{
if ( mFieldStyles.value( fieldName ) == styles )
return;
mFieldStyles.insert( fieldName, styles );
emit changed();
}
QList<QgsConditionalStyle> QgsConditionalLayerStyles::fieldStyles( const QString &fieldName )
QList<QgsConditionalStyle> QgsConditionalLayerStyles::fieldStyles( const QString &fieldName ) const
{
if ( mFieldStyles.contains( fieldName ) )
{
return mFieldStyles[fieldName];
}
return QList<QgsConditionalStyle>();
return mFieldStyles.value( fieldName );
}
bool QgsConditionalLayerStyles::writeXml( QDomNode &node, QDomDocument &doc, const QgsReadWriteContext &context ) const

View File

@ -35,47 +35,73 @@ typedef QList<QgsConditionalStyle> QgsConditionalStyles;
* \brief The QgsConditionalLayerStyles class holds conditional style information
* for a layer. This includes field styles and full row styles.
*/
class CORE_EXPORT QgsConditionalLayerStyles
class CORE_EXPORT QgsConditionalLayerStyles : public QObject
{
public:
QgsConditionalLayerStyles();
Q_OBJECT
QList<QgsConditionalStyle> rowStyles();
public:
/**
* \brief Set the conditional styles that apply to full rows of data in the attribute table.
* Constructor for QgsConditionalLayerStyles, with the specified \a parent object.
*/
QgsConditionalLayerStyles( QObject *parent = nullptr );
/**
* Returns a list of row styles associated with the layer.
*
* \see setRowStyles()
*/
QgsConditionalStyles rowStyles() const;
/**
* Sets the conditional \a styles that apply to full rows of data in the attribute table.
* Each row will check be checked against each rule.
* \param styles The styles to assign to all the rows
*
* \see rowStyles()
* \since QGIS 2.12
*/
void setRowStyles( const QList<QgsConditionalStyle> &styles );
void setRowStyles( const QgsConditionalStyles &styles );
/**
* \brief Set the conditional styles for the field UI properties.
* \param fieldName name of field
* \param styles
* Set the conditional \a styles for a field, with the specified \a fieldName.
*
* \see fieldStyles()
*/
void setFieldStyles( const QString &fieldName, const QList<QgsConditionalStyle> &styles );
/**
* \brief Returns the conditional styles set for the field UI properties
* \returns A list of conditional styles that have been set.
* Returns the conditional styles set for the field with matching \a fieldName.
*
* \see setFieldStyles()
*/
QList<QgsConditionalStyle> fieldStyles( const QString &fieldName );
QList<QgsConditionalStyle> fieldStyles( const QString &fieldName ) const;
/**
* Reads field ui properties specific state from Dom node.
* Reads the condition styles state from a DOM node.
*
* \see writeXml()
*/
bool readXml( const QDomNode &node, const QgsReadWriteContext &context );
/**
* Write field ui properties specific state from Dom node.
* Writes the condition styles state to a DOM node.
*
* \see readXml()
*/
bool writeXml( QDomNode &node, QDomDocument &doc, const QgsReadWriteContext &context ) const;
signals:
/**
* Emitted when the conditional styles are changed.
*
* \since QGIS 3.10
*/
void changed();
private:
QHash<QString, QgsConditionalStyles> mFieldStyles;
QList<QgsConditionalStyle> mRowStyles;
QgsConditionalStyles mRowStyles;
};
/**

View File

@ -158,7 +158,7 @@ QgsVectorLayer::QgsVectorLayer( const QString &vectorLayerPath,
mGeometryOptions = qgis::make_unique<QgsGeometryOptions>();
mActions = new QgsActionManager( this );
mConditionalStyles = new QgsConditionalLayerStyles();
mConditionalStyles = new QgsConditionalLayerStyles( this );
mStoredExpressionManager = new QgsStoredExpressionManager();
mStoredExpressionManager->setParent( this );

View File

@ -46,17 +46,17 @@ class TestPyQgsConditionalStyle(unittest.TestCase):
def test_MatchesReturnsTrueForSimpleMatch(self):
style = QgsConditionalStyle("@value > 10")
context = QgsExpressionContextUtils.createFeatureBasedContext(QgsFeature(), QgsFields())
assert style.matches(20, context)
self.assertTrue(style.matches(20, context))
def test_MatchesReturnsTrueForComplexMatch(self):
style = QgsConditionalStyle("@value > 10 and @value = 20")
context = QgsExpressionContextUtils.createFeatureBasedContext(QgsFeature(), QgsFields())
assert style.matches(20, context)
self.assertTrue(style.matches(20, context))
def test_MatchesTrueForFields(self):
style = QgsConditionalStyle('"testfield" = @value')
context = self.new_context()
assert style.matches(20, context)
self.assertTrue(style.matches(20, context))
def test_MatchingStylesReturnsListOfCorrectStyles(self):
styles = []
@ -120,6 +120,29 @@ class TestPyQgsConditionalStyle(unittest.TestCase):
self.assertNotEqual(c, c2)
self.assertTrue(c != c2)
def testLayerStyles(self):
styles = QgsConditionalLayerStyles()
self.assertFalse(styles.rowStyles())
self.assertFalse(styles.fieldStyles('test'))
spy = QSignalSpy(styles.changed)
styles.setRowStyles([QgsConditionalStyle("@value > 10"), QgsConditionalStyle("@value > 20")])
self.assertEqual(len(spy), 1)
self.assertEqual(styles.rowStyles(), [QgsConditionalStyle("@value > 10"), QgsConditionalStyle("@value > 20")])
styles.setRowStyles(styles.rowStyles())
self.assertEqual(len(spy), 1)
styles.setFieldStyles('test', [QgsConditionalStyle("@value > 30"), QgsConditionalStyle("@value > 40")])
self.assertEqual(len(spy), 2)
self.assertEqual(styles.fieldStyles('test'), [QgsConditionalStyle("@value > 30"), QgsConditionalStyle("@value > 40")])
styles.setFieldStyles('test', styles.fieldStyles('test'))
self.assertEqual(len(spy), 2)
self.assertFalse(styles.fieldStyles('test2'))
styles.setFieldStyles('test2', [QgsConditionalStyle("@value > 50")])
self.assertEqual(len(spy), 3)
self.assertEqual(styles.fieldStyles('test'), [QgsConditionalStyle("@value > 30"), QgsConditionalStyle("@value > 40")])
self.assertEqual(styles.fieldStyles('test2'), [QgsConditionalStyle("@value > 50")])
if __name__ == '__main__':
unittest.main()