QGIS API Documentation  2.12.0-Lyon
qgsconditionalstyle.cpp
Go to the documentation of this file.
1 #include <QPainter>
2 
3 #include "qgsconditionalstyle.h"
4 #include "qgsexpression.h"
5 #include "qgsfontutils.h"
8 
10  : mRowStyles( QList<QgsConditionalStyle>() )
11 {}
12 
14 {
15  return mRowStyles;
16 }
17 
19 {
20  mRowStyles = styles;
21 }
22 
24 {
25  mFieldStyles.insert( fieldName, styles );
26 }
27 
29 {
30  if ( mFieldStyles.contains( fieldName ) )
31  {
32  return mFieldStyles[fieldName];
33  }
35 }
36 
38 {
39  QDomElement stylesel = doc.createElement( "conditionalstyles" );
40  QDomElement rowel = doc.createElement( "rowstyles" );
41  Q_FOREACH ( const QgsConditionalStyle& style, mRowStyles )
42  {
43  style.writeXml( rowel, doc );
44  }
45 
46  stylesel.appendChild( rowel );
47 
48  QDomElement fieldsel = doc.createElement( "fieldstyles" );
49  Q_FOREACH ( const QString field, mFieldStyles.keys() )
50  {
51  QDomElement fieldel = doc.createElement( "fieldstyle" );
52  fieldel.setAttribute( "fieldname", field );
53  QgsConditionalStyles styles = mFieldStyles[field];
54  Q_FOREACH ( const QgsConditionalStyle& style, styles )
55  {
56  style.writeXml( fieldel, doc );
57  }
58  fieldsel.appendChild( fieldel );
59  }
60 
61  stylesel.appendChild( fieldsel );
62 
63  node.appendChild( stylesel );
64  return true;
65 }
66 
68 {
69  QDomElement condel = node.firstChildElement( "conditionalstyles" );
70  mRowStyles.clear();
71  mFieldStyles.clear();
72  QDomElement rowstylesel = condel.firstChildElement( "rowstyles" );
73  QDomNodeList nodelist = rowstylesel.toElement().elementsByTagName( "style" );
74  for ( int i = 0;i < nodelist.count(); i++ )
75  {
76  QDomElement styleElm = nodelist.at( i ).toElement();
78  style.readXml( styleElm );
79  mRowStyles.append( style );
80  }
81 
82  QDomElement fieldstylesel = condel.firstChildElement( "fieldstyles" );
83  nodelist = fieldstylesel.toElement().elementsByTagName( "fieldstyle" );
85  for ( int i = 0;i < nodelist.count(); i++ )
86  {
87  styles.clear();
88  QDomElement fieldel = nodelist.at( i ).toElement();
89  QString fieldName = fieldel.attribute( "fieldname" );
90  QDomNodeList stylenodelist = fieldel.toElement().elementsByTagName( "style" );
91  styles.reserve( stylenodelist.count() );
92  for ( int i = 0;i < stylenodelist.count(); i++ )
93  {
94  QDomElement styleElm = stylenodelist.at( i ).toElement();
96  style.readXml( styleElm );
97  styles.append( style );
98  }
99  mFieldStyles.insert( fieldName, styles );
100  }
101 
102  return true;
103 }
104 
106  : mValid( false )
107  , mSymbol( 0 )
108  , mBackColor( QColor( 0, 0, 0, 0 ) )
109  , mTextColor( Qt::black )
110 {}
111 
113  : mValid( false )
114  , mSymbol( 0 )
115  , mBackColor( QColor( 0, 0, 0, 0 ) )
116  , mTextColor( Qt::black )
117 {
118  setRule( rule );
119 }
120 
122  : mValid( other.mValid )
123  , mName( other.mName )
124  , mRule( other.mRule )
125  , mFont( other.mFont )
126  , mBackColor( other.mBackColor )
127  , mTextColor( other.mTextColor )
128  , mIcon( other.mIcon )
129 {
130  if ( other.mSymbol.data() )
131  mSymbol.reset( other.mSymbol->clone() );
132 }
133 
135 {
136  mValid = other.mValid;
137  mRule = other.mRule;
138  mFont = other.mFont;
139  mBackColor = other.mBackColor;
140  mTextColor = other.mTextColor;
141  mIcon = other.mIcon;
142  mName = other.mName;
143  if ( other.mSymbol.data() )
144  {
145  mSymbol.reset( other.mSymbol->clone() );
146  }
147  else
148  {
149  mSymbol.reset();
150  }
151  return ( *this );
152 }
153 
155 {
156 }
157 
159 {
160  if ( name().isEmpty() )
161  return rule();
162  else
163  return QString( "%1 \n%2" ).arg( name(), rule() );
164 }
165 
167 {
168  mValid = true;
169  if ( value )
170  {
171  mSymbol.reset( value->clone() );
172  mIcon = QgsSymbolLayerV2Utils::symbolPreviewPixmap( mSymbol.data(), QSize( 16, 16 ) );
173  }
174  else
175  {
176  mSymbol.reset();
177  }
178 }
179 
180 bool QgsConditionalStyle::matches( const QVariant& value, QgsExpressionContext& context ) const
181 {
182  QgsExpression exp( mRule );
183  context.lastScope()->setVariable( "value", value );
184  return exp.evaluate( &context ).toBool();
185 }
186 
188 {
189  QPixmap pixmap( 64, 32 );
190  pixmap.fill( Qt::transparent );
191 
192  QPainter painter( &pixmap );
193 
194  if ( validBackgroundColor() )
195  painter.setBrush( mBackColor );
196 
197  QRect rect = QRect( 0, 0, 64, 32 );
198  painter.setPen( Qt::NoPen );
199  painter.drawRect( rect );
200  painter.drawPixmap( 8, 8, icon() );
201 
202  if ( validTextColor() )
203  painter.setPen( mTextColor );
204  else
205  painter.setPen( Qt::black );
206 
207  painter.setRenderHint( QPainter::Antialiasing );
208  painter.setRenderHint( QPainter::HighQualityAntialiasing );
209  painter.setFont( font() );
210  rect = QRect( 32, 0, 32, 32 );
211  painter.drawText( rect, Qt::AlignCenter, "abc\n123" );
212  painter.end();
213  return pixmap;
214 }
215 
217 {
218  return ( backgroundColor().isValid() && backgroundColor().alpha() != 0 );
219 }
220 
222 {
223  return ( textColor().isValid() && textColor().alpha() != 0 );
224 }
225 
227 {
228  QList<QgsConditionalStyle> matchingstyles;
229  Q_FOREACH ( const QgsConditionalStyle& style, styles )
230  {
231  if ( style.matches( value, context ) )
232  matchingstyles.append( style );
233  }
234  return matchingstyles;
235 }
236 
238 {
239  Q_FOREACH ( const QgsConditionalStyle& style, styles )
240  {
241  if ( style.matches( value, context ) )
242  return style;
243  }
244  return QgsConditionalStyle();
245 }
246 
248 {
249  QgsConditionalStyle style;
250  Q_FOREACH ( const QgsConditionalStyle& s, styles )
251  {
252  style.setFont( s.font() );
253  if ( s.backgroundColor().isValid() && s.backgroundColor().alpha() != 0 )
254  style.setBackgroundColor( s.backgroundColor() );
255  if ( s.textColor().isValid() && s.textColor().alpha() != 0 )
256  style.setTextColor( s.textColor() );
257  if ( s.symbol() )
258  style.setSymbol( s.symbol() );
259  }
260  return style;
261 }
262 
264 {
265  QDomElement stylesel = doc.createElement( "style" );
266  stylesel.setAttribute( "rule", mRule );
267  stylesel.setAttribute( "name", mName );
268  stylesel.setAttribute( "background_color", mBackColor.name() );
269  stylesel.setAttribute( "text_color", mTextColor.name() );
270  QDomElement labelFontElem = QgsFontUtils::toXmlElement( mFont, doc, "font" );
271  stylesel.appendChild( labelFontElem );
272  if ( ! mSymbol.isNull() )
273  {
274  QDomElement symbolElm = QgsSymbolLayerV2Utils::saveSymbol( "icon", mSymbol.data(), doc );
275  stylesel.appendChild( symbolElm );
276  }
277  node.appendChild( stylesel );
278  return true;
279 }
280 
282 {
283  QDomElement styleElm = node.toElement();
284  setRule( styleElm.attribute( "rule" ) );
285  setName( styleElm.attribute( "name" ) );
286  setBackgroundColor( QColor( styleElm.attribute( "background_color" ) ) );
287  setTextColor( QColor( styleElm.attribute( "text_color" ) ) );
288  QgsFontUtils::setFromXmlChildNode( mFont, styleElm, "font" );
289  QDomElement symbolElm = styleElm.firstChildElement( "symbol" );
290  if ( !symbolElm.isNull() )
291  {
292  QgsSymbolV2* symbol = QgsSymbolLayerV2Utils::loadSymbol<QgsMarkerSymbolV2>( symbolElm );
293  setSymbol( symbol );
294  }
295  return true;
296 }
297 
Class for parsing and evaluation of expressions (formerly called "search strings").
Definition: qgsexpression.h:92
void clear()
QDomNodeList elementsByTagName(const QString &tagname) const
void setName(const QString &value)
Set the name of the style.
bool end()
Q_DECL_DEPRECATED QVariant evaluate(const QgsFeature *f)
Evaluate the feature and return the result.
bool validTextColor() const
Check if the text color is valid for render.
void setRenderHint(RenderHint hint, bool on)
QDomNode appendChild(const QDomNode &newChild)
void fill(const QColor &color)
QString name() const
QColor textColor() const
The text color set for style.
bool validBackgroundColor() const
Check if the background color is valid for render.
QString attribute(const QString &name, const QString &defValue) const
void setRule(const QString &value)
Set the rule for the style.
void reserve(int alloc)
QFont font() const
The font for the style.
virtual QgsSymbolV2 * clone() const =0
QList< QgsConditionalStyle > fieldStyles(const QString &fieldName)
Returns the conditional styles set for the field UI properties.
static QDomElement saveSymbol(const QString &symbolName, QgsSymbolV2 *symbol, QDomDocument &doc)
bool writeXml(QDomNode &node, QDomDocument &doc) const
Write field ui properties specific state from Dom node.
void setVariable(const QString &name, const QVariant &value)
Convenience method for setting a variable in the context scope by name and value. ...
QgsConditionalStyle & operator=(const QgsConditionalStyle &other)
void reset(T *other)
QDomElement toElement() const
void drawRect(const QRectF &rectangle)
QList< QgsConditionalStyle > rowStyles()
void setFont(const QFont &font)
QgsExpressionContextScope * lastScope()
Returns the last scope added to the context.
int count() const
void append(const T &value)
QPixmap icon() const
The icon set for style generated from the set symbol.
Conditional styling for a rule.
bool matches(const QVariant &value, QgsExpressionContext &context) const
Check if the rule matches using the given value and feature.
void setPen(const QColor &color)
void setAttribute(const QString &name, const QString &value)
void drawPixmap(const QRectF &target, const QPixmap &pixmap, const QRectF &source)
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
static QList< QgsConditionalStyle > matchingConditionalStyles(const QList< QgsConditionalStyle > &styles, const QVariant &value, QgsExpressionContext &context)
Find and return the matching styles for the value and feature.
void setBrush(const QBrush &brush)
void drawText(const QPointF &position, const QString &text)
QColor backgroundColor() const
The background color for style.
static bool setFromXmlChildNode(QFont &font, const QDomElement &element, const QString &childNode)
Sets the properties of a font to match the properties stored in an XML child node.
static QgsConditionalStyle compressStyles(const QList< QgsConditionalStyle > &styles)
Compress a list of styles into a single style.
QString name() const
The name of the style.
int alpha() const
T * data() const
void setBackgroundColor(const QColor &value)
Set the background color for the style.
QPixmap renderPreview() const
Render a preview icon of the rule.
bool isNull() const
virtual bool writeXml(QDomNode &node, QDomDocument &doc) const
Write vector conditional style specific state from layer Dom node.
void setFont(const QFont &value)
Set the font for the the style.
bool isNull() const
void setRowStyles(const QList< QgsConditionalStyle > &styles)
Set the conditional styles that apply to full rows of data in the attribute table.
void setSymbol(QgsSymbolV2 *value)
Set the icon for the style.
static QgsConditionalStyle matchingConditionalStyle(const QList< QgsConditionalStyle > &styles, const QVariant &value, QgsExpressionContext &context)
Find and return the matching style for the value and feature.
virtual bool readXml(const QDomNode &node)
Reads vector conditional style specific state from layer Dom node.
bool readXml(const QDomNode &node)
Reads field ui properties specific state from Dom node.
QDomElement firstChildElement(const QString &tagName) const
bool toBool() const
QString rule() const
The condition rule set for the style.
bool isValid() const
isValid Check if this rule is valid.
static QDomElement toXmlElement(const QFont &font, QDomDocument &document, const QString &elementName)
Returns a DOM element containing the properties of the font.
QDomElement createElement(const QString &tagName)
void setFieldStyles(const QString &fieldName, const QList< QgsConditionalStyle > &styles)
Set the conditional styles for the field UI properties.
static QPixmap symbolPreviewPixmap(QgsSymbolV2 *symbol, QSize size, QgsRenderContext *customContext=0)
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
QString displayText() const
The name of the style.
QgsSymbolV2 * symbol() const
The symbol used to generate the icon for the style.
bool isValid() const
QDomNode at(int index) const
void setTextColor(const QColor &value)
Set the text color for the style.