QGIS API Documentation  2.9.0-Master
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
qgsdatadefined.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsdatadefined.cpp - Data defined container class
3  --------------------------------------
4  Date : 9-May-2013
5  Copyright : (C) 2013 by Larry Shaffer
6  Email : larrys at dakcarto dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
16 #include "qgsdatadefined.h"
17 
18 #include "qgslogger.h"
19 #include "qgsexpression.h"
20 #include "qgsfield.h"
21 #include "qgsvectorlayer.h"
22 
24  bool useexpr,
25  const QString& expr,
26  const QString& field )
27  : mActive( active )
28  , mUseExpression( useexpr )
29  , mExpressionString( expr )
30  , mField( field )
31 {
32  mExpression = 0;
33  mExpressionPrepared = false;
34 }
35 
37  : mActive( bool( expression ) )
38  , mUseExpression( expression && expression->rootNode() && !dynamic_cast<const QgsExpression::NodeColumnRef*>( expression->rootNode() ) )
39  , mExpressionString( mUseExpression ? expression->expression() : "" )
40  , mField( !mUseExpression ? ( expression ? expression->expression() : "" ) : "" )
41 {
42  mExpression = 0;
43  mExpressionPrepared = false;
44 }
45 
47 {
48  mExpressionParams.clear();
49  delete mExpression;
50 }
51 
53 {
54  return ( !mActive && !mUseExpression && mExpressionString.isEmpty() && mField.isEmpty() );
55 }
56 
57 void QgsDataDefined::setExpressionString( const QString &expr )
58 {
59  mExpressionString = expr;
60  mExpressionPrepared = false;
61 }
62 
64 {
65  if ( !mUseExpression || mExpressionString.isEmpty() )
66  {
67  return false;
68  }
69 
70  mExpression = new QgsExpression( mExpressionString );
71  if ( mExpression->hasParserError() )
72  {
73  QgsDebugMsg( "Parser error:" + mExpression->parserErrorString() );
74  return false;
75  }
76 
77  // setup expression parameters
78  QVariant scaleV = mExpressionParams.value( "scale" );
79  if ( scaleV.isValid() )
80  {
81  bool ok;
82  double scale = scaleV.toDouble( &ok );
83  if ( ok )
84  {
85  mExpression->setScale( scale );
86  }
87  }
88 
89  if ( layer )
90  {
91  mExpression->prepare( layer->pendingFields() );
92  }
93  else
94  {
95  //preparing expression without a layer set, so pass empty field list
96  QgsFields empty;
97  mExpression->prepare( empty );
98  }
99 
100  if ( mExpression->hasEvalError() )
101  {
102  QgsDebugMsg( "Prepare error:" + mExpression->evalErrorString() );
103  return false;
104  }
105 
106  mExpressionPrepared = true;
107  mExprRefColmuns = mExpression->referencedColumns();
108 
109  return true;
110 }
111 
113 {
114  if ( !mExprRefColmuns.isEmpty() )
115  {
116  return mExprRefColmuns;
117  }
118 
119  if ( mUseExpression )
120  {
121  if ( !mExpression || !mExpressionPrepared )
122  {
123  prepareExpression( layer );
124  }
125  }
126  else if ( !mField.isEmpty() )
127  {
128  mExprRefColmuns << mField;
129  }
130 
131  return mExprRefColmuns;
132 }
133 
134 void QgsDataDefined::insertExpressionParam( QString key, QVariant param )
135 {
136  mExpressionParams.insert( key, param );
137 }
138 
139 QMap< QString, QString > QgsDataDefined::toMap()
140 {
141  QMap< QString, QString > map;
142  map.insert( "active", ( mActive ? "1" : "0" ) );
143  map.insert( "useexpr", ( mUseExpression ? "1" : "0" ) );
144  map.insert( "expression", mExpressionString );
145  map.insert( "field", mField );
146 
147  return map;
148 }
149 
150 QDomElement QgsDataDefined::toXmlElement( QDomDocument &document, const QString& elementName ) const
151 {
152  QDomElement element = document.createElement( elementName );
153  element.setAttribute( "active", mActive ? "true" : "false" );
154  element.setAttribute( "useExpr", mUseExpression ? "true" : "false" );
155  element.setAttribute( "expr", mExpressionString );
156  element.setAttribute( "field", mField );
157  return element;
158 }
159 
160 bool QgsDataDefined::setFromXmlElement( const QDomElement &element )
161 {
162  if ( element.isNull() )
163  {
164  return false;
165  }
166 
167  mActive = element.attribute( "active" ).compare( "true", Qt::CaseInsensitive ) == 0;
168  mUseExpression = element.attribute( "useExpr" ).compare( "true", Qt::CaseInsensitive ) == 0;
169  mField = element.attribute( "field" );
170  setExpressionString( element.attribute( "expr" ) );
171  return true;
172 }
173 
174 bool QgsDataDefined::operator==( const QgsDataDefined &other ) const
175 {
176  return other.isActive() == mActive && other.useExpression() == mUseExpression &&
177  other.field() == mField && other.expressionString() == mExpressionString;
178 }
179 
180 bool QgsDataDefined::operator!=( const QgsDataDefined &other ) const
181 {
182  return !( *this == other );
183 }
Class for parsing and evaluation of expressions (formerly called "search strings").
Definition: qgsexpression.h:87
bool hasEvalError() const
Returns true if an error occurred when evaluating last input.
bool hasParserError() const
Returns true if an error occurred when parsing the input expression.
Definition: qgsexpression.h:94
QStringList referencedColumns() const
Get list of columns referenced by the expression.
A container class for data source field mapping or expression.
bool operator!=(const QgsDataDefined &other) const
QString field() const
bool prepare(const QgsFields &fields)
Get the expression ready for evaluation - find out column indexes.
#define QgsDebugMsg(str)
Definition: qgslogger.h:33
void insertExpressionParam(QString key, QVariant param)
Container of fields for a vector layer.
Definition: qgsfield.h:172
QString expressionString() const
bool setFromXmlElement(const QDomElement &element)
Sets the properties of the data defined container from an XML element.
QMap< QString, QString > toMap()
QDomElement toXmlElement(QDomDocument &document, const QString &elementName) const
Returns a DOM element containing the properties of the data defined container.
bool operator==(const QgsDataDefined &other) const
bool useExpression() const
QgsDataDefined(bool active=false, bool useexpr=false, const QString &expr=QString(), const QString &field=QString())
Construct a new data defined object.
bool prepareExpression(QgsVectorLayer *layer)
bool hasDefaultValues() const
Returns whether the data defined container is set to all the default values, ie, disabled, with empty expression and no assigned field.
const QgsFields & pendingFields() const
returns field list in the to-be-committed state
void setScale(double scale)
Represents a vector layer which manages a vector based data sets.
QString parserErrorString() const
Returns parser error.
Definition: qgsexpression.h:96
QString evalErrorString() const
Returns evaluation error.
void setExpressionString(const QString &expr)
bool isActive() const
QStringList referencedColumns(QgsVectorLayer *layer)