Skip to content

Commit 83115cd

Browse files
committed
Merge row style support for attribute table
Conflicts: python/core/qgsconditionalstyle.sip python/core/qgsfielduiproperties.sip src/core/qgsfielduiproperties.cpp src/core/qgsfielduiproperties.h src/gui/attributetable/qgsattributetablemodel.cpp src/ui/qgsfieldconditionalformatwidget.ui tests/src/python/test_qgsconditionalstyle.py
2 parents b39055b + b87073e commit 83115cd

14 files changed

+1030
-887
lines changed

python/core/qgsconditionalstyle.sip

+47-3
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,12 @@ class QgsConditionalStyle
2525
*/
2626
QPixmap renderPreview();
2727

28+
/**
29+
* @brief Set the name of the style. Names are optional but handy for display
30+
* @param value The name given to the style
31+
*/
32+
void setName( QString value );
33+
2834
/**
2935
* @brief Set the rule for the style. Rules should be of QgsExpression syntax.
3036
* Special value of \@value is replaced at run time with the check value
@@ -57,15 +63,27 @@ class QgsConditionalStyle
5763
void setSymbol( QgsSymbolV2* value );
5864

5965
/**
60-
* @brief The icon set for style generated from the set symbol
61-
* @return A QPixmap that was set for the icon using the symbol
66+
* @brief The name of the style.
67+
* @return The name of the style. Names are optional so might be empty.
6268
*/
63-
QgsSymbolV2* symbol() const;
69+
QString displayText() const;
70+
71+
/**
72+
* @brief The name of the style.
73+
* @return The name of the style. Names are optional so might be empty.
74+
*/
75+
QString name() const;
6476

6577
/**
6678
* @brief The symbol used to generate the icon for the style
6779
* @return The QgsSymbolV2 used for the icon
6880
*/
81+
QgsSymbolV2* symbol() const;
82+
83+
/**
84+
* @brief The icon set for style generated from the set symbol
85+
* @return A QPixmap that was set for the icon using the symbol
86+
*/
6987
QPixmap icon() const;
7088

7189
/**
@@ -99,6 +117,32 @@ class QgsConditionalStyle
99117
*/
100118
bool isValid() const;
101119

120+
/**
121+
* @brief Find and return the matching styles for the value and feature.
122+
* If no match is found a invalid QgsCondtionalStyle is return.
123+
*
124+
* @return A condtional style that matches the value and feature.
125+
* Check with QgsCondtionalStyle::isValid()
126+
*/
127+
static QList<QgsConditionalStyle> matchingConditionalStyles( QList<QgsConditionalStyle> styles, QVariant value, QgsFeature* feature );
128+
129+
/**
130+
* @brief Find and return the matching style for the value and feature.
131+
* If no match is found a invalid QgsCondtionalStyle is return.
132+
*
133+
* @return A condtional style that matches the value and feature.
134+
* Check with QgsCondtionalStyle::isValid()
135+
*/
136+
static QgsConditionalStyle matchingConditionalStyle( QList<QgsConditionalStyle> styles, QVariant value, QgsFeature* feature );
137+
138+
/**
139+
* @brief Compress a list of styles into a single style. This can be used to stack the elements of the
140+
* styles. The font of the last style is used in the output.
141+
* @param styles The list of styles to compress down
142+
* @return A single style generated from joining each style property.
143+
*/
144+
static QgsConditionalStyle compressStyles( QList<QgsConditionalStyle> styles );
145+
102146
/** Reads vector conditional style specific state from layer Dom node.
103147
*/
104148
virtual bool readXml( const QDomNode& node );

python/core/qgsfielduiproperties.sip

+1-22
Original file line numberDiff line numberDiff line change
@@ -23,28 +23,7 @@ class QgsFieldUIProperties
2323
* @brief Returns the conditional styles set for the field UI properties
2424
* @return A list of conditional styles that have been set.
2525
*/
26-
const QList<QgsConditionalStyle> getConditionalStyles() const;
27-
28-
/**
29-
* @brief Find and return all matching styles for a value and context.
30-
* If no match is found an empty list is returned.
31-
* @param value current cell value
32-
* @param context expression context for evaluating conditional rules
33-
* @return A list of conditional styles that matches the value and context.
34-
* @see matchingConditionalStyle
35-
*/
36-
QList<QgsConditionalStyle> matchingConditionalStyles(QVariant value, QgsExpressionContext& context ) const;
37-
38-
/**
39-
* @brief Find and return the matching style for the value and context.
40-
* If no match is found a invalid QgsConditionalStyle is return.
41-
* @param value current cell value
42-
* @param context expression context for evaluating conditional rules
43-
* @return A conditional style that matches the value and context.
44-
* Check with QgsConditionalStyle::isValid()
45-
* @see matchingConditionalStyles
46-
*/
47-
QgsConditionalStyle matchingConditionalStyle( QVariant value, QgsExpressionContext& context ) const;
26+
const QList<QgsConditionalStyle> conditionalStyles();
4827

4928
/** Reads field ui properties specific state from Dom node.
5029
*/

src/core/qgsconditionalstyle.cpp

+49
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ QgsConditionalStyle::QgsConditionalStyle( const QgsConditionalStyle &other )
2525
, mBackColor( other.mBackColor )
2626
, mTextColor( other.mTextColor )
2727
, mIcon( other.mIcon )
28+
, mName( other.mName )
2829
{
2930
if ( other.mSymbol.data() )
3031
mSymbol.reset( other.mSymbol->clone() );
@@ -38,6 +39,7 @@ QgsConditionalStyle& QgsConditionalStyle::operator=( const QgsConditionalStyle &
3839
mBackColor = other.mBackColor;
3940
mTextColor = other.mTextColor;
4041
mIcon = other.mIcon;
42+
mName = other.mName;
4143
if ( other.mSymbol.data() )
4244
{
4345
mSymbol.reset( other.mSymbol->clone() );
@@ -53,6 +55,14 @@ QgsConditionalStyle::~QgsConditionalStyle()
5355
{
5456
}
5557

58+
QString QgsConditionalStyle::displayText() const
59+
{
60+
if ( name().isEmpty() )
61+
return rule();
62+
else
63+
return QString( "%1 \n%2" ).arg( name() ).arg( rule() );
64+
}
65+
5666
void QgsConditionalStyle::setSymbol( QgsSymbolV2* value )
5767
{
5868
mValid = true;
@@ -103,10 +113,48 @@ QPixmap QgsConditionalStyle::renderPreview()
103113
return pixmap;
104114
}
105115

116+
QList<QgsConditionalStyle> QgsConditionalStyle::matchingConditionalStyles( QList<QgsConditionalStyle> styles, QVariant value, QgsFeature *feature )
117+
{
118+
QList<QgsConditionalStyle> matchingstyles;
119+
foreach ( QgsConditionalStyle style, styles )
120+
{
121+
if ( style.matches( value, feature ) )
122+
matchingstyles.append( style );
123+
}
124+
return matchingstyles;
125+
}
126+
127+
QgsConditionalStyle QgsConditionalStyle::matchingConditionalStyle( QList<QgsConditionalStyle> styles, QVariant value, QgsFeature *feature )
128+
{
129+
foreach ( QgsConditionalStyle style, styles )
130+
{
131+
if ( style.matches( value, feature ) )
132+
return style;
133+
}
134+
return QgsConditionalStyle();
135+
}
136+
137+
QgsConditionalStyle QgsConditionalStyle::compressStyles( QList<QgsConditionalStyle> styles )
138+
{
139+
QgsConditionalStyle style;
140+
foreach ( QgsConditionalStyle s, styles )
141+
{
142+
style.setFont( s.font() );
143+
if ( s.backgroundColor().isValid() && s.backgroundColor().alpha() != 0 )
144+
style.setBackgroundColor( s.backgroundColor() );
145+
if ( s.textColor().isValid() && s.textColor().alpha() != 0 )
146+
style.setTextColor( s.textColor() );
147+
if ( s.symbol() )
148+
style.setSymbol( s.symbol() );
149+
}
150+
return style;
151+
}
152+
106153
bool QgsConditionalStyle::writeXml( QDomNode &node, QDomDocument &doc )
107154
{
108155
QDomElement stylesel = doc.createElement( "style" );
109156
stylesel.setAttribute( "rule", mRule );
157+
stylesel.setAttribute( "name", mName );
110158
stylesel.setAttribute( "background_color", mBackColor.name() );
111159
stylesel.setAttribute( "text_color", mTextColor.name() );
112160
QDomElement labelFontElem = QgsFontUtils::toXmlElement( mFont, doc, "font" );
@@ -124,6 +172,7 @@ bool QgsConditionalStyle::readXml( const QDomNode &node )
124172
{
125173
QDomElement styleElm = node.toElement();
126174
setRule( styleElm.attribute( "rule" ) );
175+
setName( styleElm.attribute( "name" ) );
127176
setBackgroundColor( QColor( styleElm.attribute( "background_color" ) ) );
128177
setTextColor( QColor( styleElm.attribute( "text_color" ) ) );
129178
QgsFontUtils::setFromXmlChildNode( mFont, styleElm, "font" );

src/core/qgsconditionalstyle.h

+46
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@ class CORE_EXPORT QgsConditionalStyle
3737
*/
3838
QPixmap renderPreview();
3939

40+
/**
41+
* @brief Set the name of the style. Names are optional but handy for display
42+
* @param value The name given to the style
43+
*/
44+
void setName( QString value ) { mName = value; mValid = true; }
45+
4046
/**
4147
* @brief Set the rule for the style. Rules should be of QgsExpression syntax.
4248
* Special value of \@value is replaced at run time with the check value
@@ -68,6 +74,18 @@ class CORE_EXPORT QgsConditionalStyle
6874
*/
6975
void setSymbol( QgsSymbolV2* value );
7076

77+
/**
78+
* @brief The name of the style.
79+
* @return The name of the style. Names are optional so might be empty.
80+
*/
81+
QString displayText() const;
82+
83+
/**
84+
* @brief The name of the style.
85+
* @return The name of the style. Names are optional so might be empty.
86+
*/
87+
QString name() const { return mName; }
88+
7189
/**
7290
* @brief The icon set for style generated from the set symbol
7391
* @return A QPixmap that was set for the icon using the symbol
@@ -111,6 +129,32 @@ class CORE_EXPORT QgsConditionalStyle
111129
*/
112130
bool isValid() const { return mValid; }
113131

132+
/**
133+
* @brief Find and return the matching styles for the value and feature.
134+
* If no match is found a invalid QgsCondtionalStyle is return.
135+
*
136+
* @return A condtional style that matches the value and feature.
137+
* Check with QgsCondtionalStyle::isValid()
138+
*/
139+
static QList<QgsConditionalStyle> matchingConditionalStyles( QList<QgsConditionalStyle> styles, QVariant value, QgsFeature* feature );
140+
141+
/**
142+
* @brief Find and return the matching style for the value and feature.
143+
* If no match is found a invalid QgsCondtionalStyle is return.
144+
*
145+
* @return A condtional style that matches the value and feature.
146+
* Check with QgsCondtionalStyle::isValid()
147+
*/
148+
static QgsConditionalStyle matchingConditionalStyle( QList<QgsConditionalStyle> styles, QVariant value, QgsFeature* feature );
149+
150+
/**
151+
* @brief Compress a list of styles into a single style. This can be used to stack the elements of the
152+
* styles. The font of the last style is used in the output.
153+
* @param styles The list of styles to compress down
154+
* @return A single style generated from joining each style property.
155+
*/
156+
static QgsConditionalStyle compressStyles( QList<QgsConditionalStyle> styles );
157+
114158
/** Reads vector conditional style specific state from layer Dom node.
115159
*/
116160
virtual bool readXml( const QDomNode& node );
@@ -119,9 +163,11 @@ class CORE_EXPORT QgsConditionalStyle
119163
*/
120164
virtual bool writeXml( QDomNode & node, QDomDocument & doc );
121165

166+
122167
private:
123168

124169
bool mValid;
170+
QString mName;
125171
QString mRule;
126172
QScopedPointer<QgsSymbolV2> mSymbol;
127173
QFont mFont;

src/core/qgsfielduiproperties.cpp

+1-22
Original file line numberDiff line numberDiff line change
@@ -13,32 +13,11 @@ void QgsFieldUIProperties::setConditionalStyles( QList<QgsConditionalStyle> styl
1313
mStyles = styles;
1414
}
1515

16-
QList<QgsConditionalStyle> QgsFieldUIProperties::getConditionalStyles() const
16+
QList<QgsConditionalStyle> QgsFieldUIProperties::conditionalStyles()
1717
{
1818
return mStyles;
1919
}
2020

21-
QList<QgsConditionalStyle> QgsFieldUIProperties::matchingConditionalStyles( QVariant value, QgsExpressionContext& context ) const
22-
{
23-
QList<QgsConditionalStyle> styles;
24-
foreach ( QgsConditionalStyle style, mStyles )
25-
{
26-
if ( style.matches( value, context ) )
27-
styles.append( style );
28-
}
29-
return styles;
30-
}
31-
32-
QgsConditionalStyle QgsFieldUIProperties::matchingConditionalStyle( QVariant value, QgsExpressionContext& context ) const
33-
{
34-
foreach ( QgsConditionalStyle style, mStyles )
35-
{
36-
if ( style.matches( value, context ) )
37-
return style;
38-
}
39-
return QgsConditionalStyle();
40-
}
41-
4221
bool QgsFieldUIProperties::writeXml( QDomNode &node, QDomDocument &doc ) const
4322
{
4423
QDomElement stylesel = doc.createElement( "conditionalstyles" );

src/core/qgsfielduiproperties.h

+1-22
Original file line numberDiff line numberDiff line change
@@ -30,28 +30,7 @@ class CORE_EXPORT QgsFieldUIProperties
3030
* @brief Returns the conditional styles set for the field UI properties
3131
* @return A list of conditional styles that have been set.
3232
*/
33-
QList<QgsConditionalStyle> getConditionalStyles() const;
34-
35-
/**
36-
* @brief Find and return all matching styles for a value and context.
37-
* If no match is found an empty list is returned.
38-
* @param value current cell value
39-
* @param context expression context for evaluating conditional rules
40-
* @return A list of conditional styles that matches the value and context.
41-
* @see matchingConditionalStyle
42-
*/
43-
QList<QgsConditionalStyle> matchingConditionalStyles( QVariant value, QgsExpressionContext& context ) const;
44-
45-
/**
46-
* @brief Find and return the matching style for the value and context.
47-
* If no match is found a invalid QgsConditionalStyle is return.
48-
* @param value current cell value
49-
* @param context expression context for evaluating conditional rules
50-
* @return A conditional style that matches the value and context.
51-
* Check with QgsConditionalStyle::isValid()
52-
* @see matchingConditionalStyles
53-
*/
54-
QgsConditionalStyle matchingConditionalStyle( QVariant value, QgsExpressionContext& context ) const;
33+
QList<QgsConditionalStyle> conditionalStyles();
5534

5635
/** Reads field ui properties specific state from Dom node.
5736
*/

src/core/qgsvectorlayer.cpp

+10
Original file line numberDiff line numberDiff line change
@@ -2044,6 +2044,16 @@ QgsFieldUIProperties QgsVectorLayer::fieldUIProperties( QString fieldName )
20442044
return QgsFieldUIProperties();
20452045
}
20462046

2047+
QList<QgsConditionalStyle> QgsVectorLayer::rowStyles()
2048+
{
2049+
return mRowStyles;
2050+
}
2051+
2052+
void QgsVectorLayer::setRowStyles( QList<QgsConditionalStyle> styles )
2053+
{
2054+
mRowStyles = styles;
2055+
}
2056+
20472057
void QgsVectorLayer::setFieldUIProperties( QString fieldName, QgsFieldUIProperties props )
20482058
{
20492059
mFieldProperties.insert( fieldName, props );

src/core/qgsvectorlayer.h

+12
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
#include "qgis.h"
2929
#include "qgsmaplayer.h"
30+
#include "qgsconditionalstyle.h"
3031
#include "qgsfeature.h"
3132
#include "qgsfeatureiterator.h"
3233
#include "qgseditorwidgetconfig.h"
@@ -1764,6 +1765,16 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
17641765
*/
17651766
QgsFieldUIProperties fieldUIProperties( QString fieldName );
17661767

1768+
QList<QgsConditionalStyle> rowStyles();
1769+
1770+
/**
1771+
* @brief Set the conditional styles that apply to full rows of data in the attribute table.
1772+
* Each row will check be checked against each rule.
1773+
* @param styles The styles to assign to all the rows
1774+
* @note added in QGIS 2.12
1775+
*/
1776+
void setRowStyles( QList<QgsConditionalStyle> styles );
1777+
17671778
/**
17681779
* @brief Set the the field UI properties for a given field.
17691780
* @param fieldName The field name.
@@ -2026,6 +2037,7 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
20262037
private: // Private attributes
20272038

20282039
QHash<QString, QgsFieldUIProperties> mFieldProperties;
2040+
QList<QgsConditionalStyle> mRowStyles;
20292041

20302042
/** Pointer to data provider derived from the abastract base class QgsDataProvider */
20312043
QgsVectorDataProvider *mDataProvider;

0 commit comments

Comments
 (0)