QGIS API Documentation  2.2.0-Valmiera
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
qgsexpression.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsexpression.cpp
3  -------------------
4  begin : August 2011
5  copyright : (C) 2011 Martin Dobias
6  email : wonder.sk at gmail 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 "qgsexpression.h"
17 
18 #include <QtDebug>
19 #include <QDomDocument>
20 #include <QSettings>
21 #include <QDate>
22 #include <QRegExp>
23 #include <QColor>
24 #include <QUuid>
25 
26 #include <math.h>
27 #include <limits>
28 
29 #include "qgsdistancearea.h"
30 #include "qgsfeature.h"
31 #include "qgsgeometry.h"
32 #include "qgslogger.h"
33 #include "qgsogcutils.h"
34 #include "qgsvectorlayer.h"
35 #include "qgssymbollayerv2utils.h"
36 #include "qgsvectorcolorrampv2.h"
37 #include "qgsstylev2.h"
38 
39 // from parser
40 extern QgsExpression::Node* parseExpression( const QString& str, QString& parserErrorMsg );
41 
43 
45 {
47  inter.setValid( false );
48  return inter;
49 }
50 
52 {
53  int seconds = 0;
54  QRegExp rx( "(\\d?\\.?\\d+\\s+[a-z]+)", Qt::CaseInsensitive );
55  QStringList list;
56  int pos = 0;
57 
58  while (( pos = rx.indexIn( string, pos ) ) != -1 )
59  {
60  list << rx.cap( 1 );
61  pos += rx.matchedLength();
62  }
63 
64  foreach ( QString match, list )
65  {
66  QStringList split = match.split( QRegExp( "\\s+" ) );
67  bool ok;
68  int value = split.at( 0 ).toInt( &ok );
69  if ( !ok )
70  {
71  continue;
72  }
73 
74  if ( match.contains( "day", Qt::CaseInsensitive ) ||
75  match.contains( QObject::tr( "day", "Note: Word is part matched in code" ), Qt::CaseInsensitive ) ||
76  match.contains( QObject::tr( "days", "Note: Word is part matched in code" ), Qt::CaseInsensitive ) )
77  seconds += value * QgsExpression::Interval::DAY;
78  if ( match.contains( "week", Qt::CaseInsensitive ) ||
79  match.contains( QObject::tr( "week", "Note: Word is part matched in code" ), Qt::CaseInsensitive ) ||
80  match.contains( QObject::tr( "weeks", "Note: Word is part matched in code" ), Qt::CaseInsensitive ) )
81  seconds += value * QgsExpression::Interval::WEEKS;
82  if ( match.contains( "month", Qt::CaseInsensitive ) ||
83  match.contains( QObject::tr( "month", "Note: Word is part matched in code" ), Qt::CaseInsensitive ) ||
84  match.contains( QObject::tr( "months", "Note: Word is part matched in code" ), Qt::CaseInsensitive ) )
85  seconds += value * QgsExpression::Interval::MONTHS;
86  if ( match.contains( "year", Qt::CaseInsensitive ) ||
87  match.contains( QObject::tr( "year", "Note: Word is part matched in code" ), Qt::CaseInsensitive ) ||
88  match.contains( QObject::tr( "years", "Note: Word is part matched in code" ), Qt::CaseInsensitive ) )
89  seconds += value * QgsExpression::Interval::YEARS;
90  if ( match.contains( "second", Qt::CaseInsensitive ) ||
91  match.contains( QObject::tr( "second", "Note: Word is part matched in code" ), Qt::CaseInsensitive ) ||
92  match.contains( QObject::tr( "seconds", "Note: Word is part matched in code" ), Qt::CaseInsensitive ) )
93  seconds += value;
94  if ( match.contains( "minute", Qt::CaseInsensitive ) ||
95  match.contains( QObject::tr( "minute", "Note: Word is part matched in code" ), Qt::CaseInsensitive ) ||
96  match.contains( QObject::tr( "minutes", "Note: Word is part matched in code" ), Qt::CaseInsensitive ) )
97  seconds += value * QgsExpression::Interval::MINUTE;
98  if ( match.contains( "hour", Qt::CaseInsensitive ) ||
99  match.contains( QObject::tr( "hour", "Note: Word is part matched in code" ), Qt::CaseInsensitive ) ||
100  match.contains( QObject::tr( "hours", "Note: Word is part matched in code" ), Qt::CaseInsensitive ) )
101  seconds += value * QgsExpression::Interval::HOUR;
102  }
103 
104  // If we can't parse the string at all then we just return invalid
105  if ( seconds == 0 )
107 
108  return QgsExpression::Interval( seconds );
109 }
110 
112 {
113  return ( mSeconds == other.mSeconds );
114 }
115 
117 // three-value logic
118 
119 enum TVL
120 {
124 };
125 
126 static TVL AND[3][3] =
127 {
128  // false true unknown
129  { False, False, False }, // false
130  { False, True, Unknown }, // true
131  { False, Unknown, Unknown } // unknown
132 };
133 
134 static TVL OR[3][3] =
135 {
136  { False, True, Unknown }, // false
137  { True, True, True }, // true
138  { Unknown, True, Unknown } // unknown
139 };
140 
141 static TVL NOT[3] = { True, False, Unknown };
142 
143 static QVariant tvl2variant( TVL v )
144 {
145  switch ( v )
146  {
147  case False: return 0;
148  case True: return 1;
149  case Unknown:
150  default:
151  return QVariant();
152  }
153 }
154 
155 #define TVL_True QVariant(1)
156 #define TVL_False QVariant(0)
157 #define TVL_Unknown QVariant()
158 
160 // QVariant checks and conversions
161 
162 inline bool isIntSafe( const QVariant& v )
163 {
164  if ( v.type() == QVariant::Int ) return true;
165  if ( v.type() == QVariant::Double ) return false;
166  if ( v.type() == QVariant::String ) { bool ok; v.toString().toInt( &ok ); return ok; }
167  return false;
168 }
169 inline bool isDoubleSafe( const QVariant& v )
170 {
171  if ( v.type() == QVariant::Double || v.type() == QVariant::Int ) return true;
172  if ( v.type() == QVariant::String ) { bool ok; v.toString().toDouble( &ok ); return ok; }
173  return false;
174 }
175 
176 inline bool isDateTimeSafe( const QVariant& v )
177 {
178  return v.type() == QVariant::DateTime || v.type() == QVariant::Date ||
179  v.type() == QVariant::Time;
180 }
181 
182 inline bool isIntervalSafe( const QVariant& v )
183 {
184  if ( v.canConvert<QgsExpression::Interval>() )
185  {
186  return true;
187  }
188 
189  if ( v.type() == QVariant::String )
190  {
191  return QgsExpression::Interval::fromString( v.toString() ).isValid();
192  }
193  return false;
194 }
195 
196 inline bool isNull( const QVariant& v ) { return v.isNull(); }
197 
199 // evaluation error macros
200 
201 #define ENSURE_NO_EVAL_ERROR { if (parent->hasEvalError()) return QVariant(); }
202 #define SET_EVAL_ERROR(x) { parent->setEvalErrorString(x); return QVariant(); }
203 
205 // operators
206 
207 const char* QgsExpression::BinaryOperatorText[] =
208 {
209  "OR", "AND",
210  "=", "<>", "<=", ">=", "<", ">", "~", "LIKE", "NOT LIKE", "ILIKE", "NOT ILIKE", "IS", "IS NOT",
211  "+", "-", "*", "/", "%", "^",
212  "||"
213 };
214 
215 const char* QgsExpression::UnaryOperatorText[] =
216 {
217  "NOT", "-"
218 };
219 
221 // functions
222 
223 // implicit conversion to string
224 static QString getStringValue( const QVariant& value, QgsExpression* )
225 {
226  return value.toString();
227 }
228 
229 static double getDoubleValue( const QVariant& value, QgsExpression* parent )
230 {
231  bool ok;
232  double x = value.toDouble( &ok );
233  if ( !ok )
234  {
235  parent->setEvalErrorString( QObject::tr( "Cannot convert '%1' to double" ).arg( value.toString() ) );
236  return 0;
237  }
238  return x;
239 }
240 
241 static int getIntValue( const QVariant& value, QgsExpression* parent )
242 {
243  bool ok;
244  qint64 x = value.toLongLong( &ok );
246  {
247  return x;
248  }
249  else
250  {
251  parent->setEvalErrorString( QObject::tr( "Cannot convert '%1' to int" ).arg( value.toString() ) );
252  return 0;
253  }
254 }
255 
256 static QDateTime getDateTimeValue( const QVariant& value, QgsExpression* parent )
257 {
258  QDateTime d = value.toDateTime();
259  if ( d.isValid() )
260  {
261  return d;
262  }
263  else
264  {
265  parent->setEvalErrorString( QObject::tr( "Cannot convert '%1' to DateTime" ).arg( value.toString() ) );
266  return QDateTime();
267  }
268 }
269 
270 static QDate getDateValue( const QVariant& value, QgsExpression* parent )
271 {
272  QDate d = value.toDate();
273  if ( d.isValid() )
274  {
275  return d;
276  }
277  else
278  {
279  parent->setEvalErrorString( QObject::tr( "Cannot convert '%1' to Date" ).arg( value.toString() ) );
280  return QDate();
281  }
282 }
283 
284 static QTime getTimeValue( const QVariant& value, QgsExpression* parent )
285 {
286  QTime t = value.toTime();
287  if ( t.isValid() )
288  {
289  return t;
290  }
291  else
292  {
293  parent->setEvalErrorString( QObject::tr( "Cannot convert '%1' to Time" ).arg( value.toString() ) );
294  return QTime();
295  }
296 }
297 
298 static QgsExpression::Interval getInterval( const QVariant& value, QgsExpression* parent, bool report_error = false )
299 {
300  if ( value.canConvert<QgsExpression::Interval>() )
301  return value.value<QgsExpression::Interval>();
302 
304  if ( inter.isValid() )
305  {
306  return inter;
307  }
308  // If we get here then we can't convert so we just error and return invalid.
309  if ( report_error )
310  parent->setEvalErrorString( QObject::tr( "Cannot convert '%1' to Interval" ).arg( value.toString() ) );
311 
313 }
314 static QgsGeometry getGeometry( const QVariant& value, QgsExpression* parent )
315 {
316  if ( value.canConvert<QgsGeometry>() )
317  return value.value<QgsGeometry>();
318 
319  parent->setEvalErrorString( "Cannot convert to QgsGeometry" );
320  return QgsGeometry();
321 }
322 
323 
324 // this handles also NULL values
325 static TVL getTVLValue( const QVariant& value, QgsExpression* parent )
326 {
327  // we need to convert to TVL
328  if ( value.isNull() )
329  return Unknown;
330 
331  if ( value.type() == QVariant::Int )
332  return value.toInt() != 0 ? True : False;
333 
334  bool ok;
335  double x = value.toDouble( &ok );
336  if ( !ok )
337  {
338  parent->setEvalErrorString( QObject::tr( "Cannot convert '%1' to boolean" ).arg( value.toString() ) );
339  return Unknown;
340  }
341  return x != 0 ? True : False;
342 }
343 
345 
346 static QVariant fcnSqrt( const QVariantList& values, const QgsFeature* /*f*/, QgsExpression* parent )
347 {
348  double x = getDoubleValue( values.at( 0 ), parent );
349  return QVariant( sqrt( x ) );
350 }
351 
352 static QVariant fcnAbs( const QVariantList& values, const QgsFeature*, QgsExpression* parent )
353 {
354  double val = getDoubleValue( values.at( 0 ), parent );
355  return QVariant( fabs( val ) );
356 }
357 
358 static QVariant fcnSin( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
359 {
360  double x = getDoubleValue( values.at( 0 ), parent );
361  return QVariant( sin( x ) );
362 }
363 static QVariant fcnCos( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
364 {
365  double x = getDoubleValue( values.at( 0 ), parent );
366  return QVariant( cos( x ) );
367 }
368 static QVariant fcnTan( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
369 {
370  double x = getDoubleValue( values.at( 0 ), parent );
371  return QVariant( tan( x ) );
372 }
373 static QVariant fcnAsin( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
374 {
375  double x = getDoubleValue( values.at( 0 ), parent );
376  return QVariant( asin( x ) );
377 }
378 static QVariant fcnAcos( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
379 {
380  double x = getDoubleValue( values.at( 0 ), parent );
381  return QVariant( acos( x ) );
382 }
383 static QVariant fcnAtan( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
384 {
385  double x = getDoubleValue( values.at( 0 ), parent );
386  return QVariant( atan( x ) );
387 }
388 static QVariant fcnAtan2( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
389 {
390  double y = getDoubleValue( values.at( 0 ), parent );
391  double x = getDoubleValue( values.at( 1 ), parent );
392  return QVariant( atan2( y, x ) );
393 }
394 static QVariant fcnExp( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
395 {
396  double x = getDoubleValue( values.at( 0 ), parent );
397  return QVariant( exp( x ) );
398 }
399 static QVariant fcnLn( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
400 {
401  double x = getDoubleValue( values.at( 0 ), parent );
402  if ( x <= 0 )
403  return QVariant();
404  return QVariant( log( x ) );
405 }
406 static QVariant fcnLog10( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
407 {
408  double x = getDoubleValue( values.at( 0 ), parent );
409  if ( x <= 0 )
410  return QVariant();
411  return QVariant( log10( x ) );
412 }
413 static QVariant fcnLog( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
414 {
415  double b = getDoubleValue( values.at( 0 ), parent );
416  double x = getDoubleValue( values.at( 1 ), parent );
417  if ( x <= 0 || b <= 0 )
418  return QVariant();
419  return QVariant( log( x ) / log( b ) );
420 }
421 static QVariant fcnRndF( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
422 {
423  double min = getDoubleValue( values.at( 0 ), parent );
424  double max = getDoubleValue( values.at( 1 ), parent );
425  if ( max < min )
426  return QVariant();
427 
428  // Return a random double in the range [min, max] (inclusive)
429  double f = ( double )rand() / RAND_MAX;
430  return QVariant( min + f * ( max - min ) ) ;
431 }
432 static QVariant fcnRnd( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
433 {
434  int min = getIntValue( values.at( 0 ), parent );
435  int max = getIntValue( values.at( 1 ), parent );
436  if ( max < min )
437  return QVariant();
438 
439  // Return a random integer in the range [min, max] (inclusive)
440  return QVariant( min + ( rand() % ( int )( max - min + 1 ) ) );
441 }
442 
443 static QVariant fcnLinearScale( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
444 {
445  double val = getDoubleValue( values.at( 0 ), parent );
446  double domainMin = getDoubleValue( values.at( 1 ), parent );
447  double domainMax = getDoubleValue( values.at( 2 ), parent );
448  double rangeMin = getDoubleValue( values.at( 3 ), parent );
449  double rangeMax = getDoubleValue( values.at( 4 ), parent );
450 
451  if ( domainMin >= domainMax )
452  {
453  parent->setEvalErrorString( QObject::tr( "Domain max must be greater than domain min" ) );
454  return QVariant();
455  }
456 
457  // outside of domain?
458  if ( val >= domainMax )
459  {
460  return rangeMax;
461  }
462  else if ( val <= domainMin )
463  {
464  return rangeMin;
465  }
466 
467  // calculate linear scale
468  double m = ( rangeMax - rangeMin ) / ( domainMax - domainMin );
469  double c = rangeMin - ( domainMin * m );
470 
471  // Return linearly scaled value
472  return QVariant( m * val + c );
473 }
474 
475 static QVariant fcnExpScale( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
476 {
477  double val = getDoubleValue( values.at( 0 ), parent );
478  double domainMin = getDoubleValue( values.at( 1 ), parent );
479  double domainMax = getDoubleValue( values.at( 2 ), parent );
480  double rangeMin = getDoubleValue( values.at( 3 ), parent );
481  double rangeMax = getDoubleValue( values.at( 4 ), parent );
482  double exponent = getDoubleValue( values.at( 5 ), parent );
483 
484  if ( domainMin >= domainMax )
485  {
486  parent->setEvalErrorString( QObject::tr( "Domain max must be greater than domain min" ) );
487  return QVariant();
488  }
489  if ( exponent <= 0 )
490  {
491  parent->setEvalErrorString( QObject::tr( "Exponent must be greater than 0" ) );
492  return QVariant();
493  }
494 
495  // outside of domain?
496  if ( val >= domainMax )
497  {
498  return rangeMax;
499  }
500  else if ( val <= domainMin )
501  {
502  return rangeMin;
503  }
504 
505  // Return exponentially scaled value
506  return QVariant((( rangeMax - rangeMin ) / pow( domainMax - domainMin, exponent ) ) * pow( val - domainMin, exponent ) + rangeMin );
507 }
508 
509 static QVariant fcnMax( const QVariantList& values, const QgsFeature* , QgsExpression *parent )
510 {
511  //initially set max as first value
512  double maxVal = getDoubleValue( values.at( 0 ), parent );
513 
514  //check against all other values
515  for ( int i = 1; i < values.length(); ++i )
516  {
517  double testVal = getDoubleValue( values[i], parent );
518  if ( testVal > maxVal )
519  {
520  maxVal = testVal;
521  }
522  }
523 
524  return QVariant( maxVal );
525 }
526 
527 static QVariant fcnMin( const QVariantList& values, const QgsFeature* , QgsExpression *parent )
528 {
529  //initially set min as first value
530  double minVal = getDoubleValue( values.at( 0 ), parent );
531 
532  //check against all other values
533  for ( int i = 1; i < values.length(); ++i )
534  {
535  double testVal = getDoubleValue( values[i], parent );
536  if ( testVal < minVal )
537  {
538  minVal = testVal;
539  }
540  }
541 
542  return QVariant( minVal );
543 }
544 
545 static QVariant fcnClamp( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
546 {
547  double minValue = getDoubleValue( values.at( 0 ), parent );
548  double testValue = getDoubleValue( values.at( 1 ), parent );
549  double maxValue = getDoubleValue( values.at( 2 ), parent );
550 
551  // force testValue to sit inside the range specified by the min and max value
552  if ( testValue <= minValue )
553  {
554  return QVariant( minValue );
555  }
556  else if ( testValue >= maxValue )
557  {
558  return QVariant( maxValue );
559  }
560  else
561  {
562  return QVariant( testValue );
563  }
564 }
565 
566 static QVariant fcnFloor( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
567 {
568  double x = getDoubleValue( values.at( 0 ), parent );
569  return QVariant( floor( x ) );
570 }
571 
572 static QVariant fcnCeil( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
573 {
574  double x = getDoubleValue( values.at( 0 ), parent );
575  return QVariant( ceil( x ) );
576 }
577 
578 static QVariant fcnToInt( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
579 {
580  return QVariant( getIntValue( values.at( 0 ), parent ) );
581 }
582 static QVariant fcnToReal( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
583 {
584  return QVariant( getDoubleValue( values.at( 0 ), parent ) );
585 }
586 static QVariant fcnToString( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
587 {
588  return QVariant( getStringValue( values.at( 0 ), parent ) );
589 }
590 
591 static QVariant fcnToDateTime( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
592 {
593  return QVariant( getDateTimeValue( values.at( 0 ), parent ) );
594 }
595 
596 static QVariant fcnCoalesce( const QVariantList& values, const QgsFeature* , QgsExpression* )
597 {
598  foreach ( const QVariant &value, values )
599  {
600  if ( value.isNull() )
601  continue;
602  return value;
603  }
604  return QVariant();
605 }
606 static QVariant fcnLower( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
607 {
608  QString str = getStringValue( values.at( 0 ), parent );
609  return QVariant( str.toLower() );
610 }
611 static QVariant fcnUpper( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
612 {
613  QString str = getStringValue( values.at( 0 ), parent );
614  return QVariant( str.toUpper() );
615 }
616 static QVariant fcnTitle( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
617 {
618  QString str = getStringValue( values.at( 0 ), parent );
619  QStringList elems = str.split( " " );
620  for ( int i = 0; i < elems.size(); i++ )
621  {
622  if ( elems[i].size() > 1 )
623  elems[i] = elems[i].left( 1 ).toUpper() + elems[i].mid( 1 ).toLower();
624  }
625  return QVariant( elems.join( " " ) );
626 }
627 
628 static QVariant fcnTrim( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
629 {
630  QString str = getStringValue( values.at( 0 ), parent );
631  return QVariant( str.trimmed() );
632 }
633 
634 static QVariant fcnLength( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
635 {
636  QString str = getStringValue( values.at( 0 ), parent );
637  return QVariant( str.length() );
638 }
639 static QVariant fcnReplace( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
640 {
641  QString str = getStringValue( values.at( 0 ), parent );
642  QString before = getStringValue( values.at( 1 ), parent );
643  QString after = getStringValue( values.at( 2 ), parent );
644  return QVariant( str.replace( before, after ) );
645 }
646 static QVariant fcnRegexpReplace( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
647 {
648  QString str = getStringValue( values.at( 0 ), parent );
649  QString regexp = getStringValue( values.at( 1 ), parent );
650  QString after = getStringValue( values.at( 2 ), parent );
651 
652  QRegExp re( regexp );
653  if ( !re.isValid() )
654  {
655  parent->setEvalErrorString( QObject::tr( "Invalid regular expression '%1': %2" ).arg( regexp ).arg( re.errorString() ) );
656  return QVariant();
657  }
658  return QVariant( str.replace( re, after ) );
659 }
660 
661 static QVariant fcnRegexpMatch( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
662 {
663  QString str = getStringValue( values.at( 0 ), parent );
664  QString regexp = getStringValue( values.at( 1 ), parent );
665 
666  QRegExp re( regexp );
667  if ( !re.isValid() )
668  {
669  parent->setEvalErrorString( QObject::tr( "Invalid regular expression '%1': %2" ).arg( regexp ).arg( re.errorString() ) );
670  return QVariant();
671  }
672  return QVariant( str.contains( re ) ? 1 : 0 );
673 }
674 
675 static QVariant fcnRegexpSubstr( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
676 {
677  QString str = getStringValue( values.at( 0 ), parent );
678  QString regexp = getStringValue( values.at( 1 ), parent );
679 
680  QRegExp re( regexp );
681  if ( !re.isValid() )
682  {
683  parent->setEvalErrorString( QObject::tr( "Invalid regular expression '%1': %2" ).arg( regexp ).arg( re.errorString() ) );
684  return QVariant();
685  }
686 
687  // extract substring
688  re.indexIn( str );
689  if ( re.captureCount() > 0 )
690  {
691  // return first capture
692  return QVariant( re.capturedTexts()[1] );
693  }
694  else
695  {
696  return QVariant( "" );
697  }
698 }
699 
700 static QVariant fcnUuid( const QVariantList&, const QgsFeature* , QgsExpression* )
701 {
702  return QUuid::createUuid().toString();
703 }
704 
705 static QVariant fcnSubstr( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
706 {
707  QString str = getStringValue( values.at( 0 ), parent );
708  int from = getIntValue( values.at( 1 ), parent );
709  int len = getIntValue( values.at( 2 ), parent );
710  return QVariant( str.mid( from -1, len ) );
711 }
712 
713 static QVariant fcnRowNumber( const QVariantList& , const QgsFeature* , QgsExpression* parent )
714 {
715  return QVariant( parent->currentRowNumber() );
716 }
717 
718 static QVariant fcnFeatureId( const QVariantList& , const QgsFeature* f, QgsExpression* )
719 {
720  // TODO: handling of 64-bit feature ids?
721  return f ? QVariant(( int )f->id() ) : QVariant();
722 }
723 
724 static QVariant fcnConcat( const QVariantList& values, const QgsFeature* , QgsExpression *parent )
725 {
726  QString concat;
727  foreach ( const QVariant &value, values )
728  {
729  concat += getStringValue( value, parent );
730  }
731  return concat;
732 }
733 
734 static QVariant fcnStrpos( const QVariantList& values, const QgsFeature* , QgsExpression *parent )
735 {
736  QString string = getStringValue( values.at( 0 ), parent );
737  return string.indexOf( QRegExp( getStringValue( values.at( 1 ), parent ) ) );
738 }
739 
740 static QVariant fcnRight( const QVariantList& values, const QgsFeature* , QgsExpression *parent )
741 {
742  QString string = getStringValue( values.at( 0 ), parent );
743  int pos = getIntValue( values.at( 1 ), parent );
744  return string.right( pos );
745 }
746 
747 static QVariant fcnLeft( const QVariantList& values, const QgsFeature* , QgsExpression *parent )
748 {
749  QString string = getStringValue( values.at( 0 ), parent );
750  int pos = getIntValue( values.at( 1 ), parent );
751  return string.left( pos );
752 }
753 
754 static QVariant fcnRPad( const QVariantList& values, const QgsFeature* , QgsExpression *parent )
755 {
756  QString string = getStringValue( values.at( 0 ), parent );
757  int length = getIntValue( values.at( 1 ), parent );
758  QString fill = getStringValue( values.at( 2 ), parent );
759  return string.leftJustified( length, fill.at( 0 ), true );
760 }
761 
762 static QVariant fcnLPad( const QVariantList& values, const QgsFeature* , QgsExpression *parent )
763 {
764  QString string = getStringValue( values.at( 0 ), parent );
765  int length = getIntValue( values.at( 1 ), parent );
766  QString fill = getStringValue( values.at( 2 ), parent );
767  return string.rightJustified( length, fill.at( 0 ), true );
768 }
769 
770 static QVariant fcnFormatString( const QVariantList& values, const QgsFeature* , QgsExpression *parent )
771 {
772  QString string = getStringValue( values.at( 0 ), parent );
773  for ( int n = 1; n < values.length(); n++ )
774  {
775  string = string.arg( getStringValue( values.at( n ), parent ) );
776  }
777  return string;
778 }
779 
780 
781 static QVariant fcnNow( const QVariantList&, const QgsFeature* , QgsExpression * )
782 {
783  return QVariant( QDateTime::currentDateTime() );
784 }
785 
786 static QVariant fcnToDate( const QVariantList& values, const QgsFeature* , QgsExpression * parent )
787 {
788  return QVariant( getDateValue( values.at( 0 ), parent ) );
789 }
790 
791 static QVariant fcnToTime( const QVariantList& values, const QgsFeature* , QgsExpression * parent )
792 {
793  return QVariant( getTimeValue( values.at( 0 ), parent ) );
794 }
795 
796 static QVariant fcnToInterval( const QVariantList& values, const QgsFeature* , QgsExpression * parent )
797 {
798  return QVariant::fromValue( getInterval( values.at( 0 ), parent ) );
799 }
800 
801 static QVariant fcnAge( const QVariantList& values, const QgsFeature* , QgsExpression *parent )
802 {
803  QDateTime d1 = getDateTimeValue( values.at( 0 ), parent );
804  QDateTime d2 = getDateTimeValue( values.at( 1 ), parent );
805  int seconds = d2.secsTo( d1 );
806  return QVariant::fromValue( QgsExpression::Interval( seconds ) );
807 }
808 
809 static QVariant fcnDay( const QVariantList& values, const QgsFeature* , QgsExpression *parent )
810 {
811  QVariant value = values.at( 0 );
812  QgsExpression::Interval inter = getInterval( value, parent, false );
813  if ( inter.isValid() )
814  {
815  return QVariant( inter.days() );
816  }
817  else
818  {
819  QDateTime d1 = getDateTimeValue( value, parent );
820  return QVariant( d1.date().day() );
821  }
822 }
823 
824 static QVariant fcnYear( const QVariantList& values, const QgsFeature* , QgsExpression *parent )
825 {
826  QVariant value = values.at( 0 );
827  QgsExpression::Interval inter = getInterval( value, parent, false );
828  if ( inter.isValid() )
829  {
830  return QVariant( inter.years() );
831  }
832  else
833  {
834  QDateTime d1 = getDateTimeValue( value, parent );
835  return QVariant( d1.date().year() );
836  }
837 }
838 
839 static QVariant fcnMonth( const QVariantList& values, const QgsFeature* , QgsExpression *parent )
840 {
841  QVariant value = values.at( 0 );
842  QgsExpression::Interval inter = getInterval( value, parent, false );
843  if ( inter.isValid() )
844  {
845  return QVariant( inter.months() );
846  }
847  else
848  {
849  QDateTime d1 = getDateTimeValue( value, parent );
850  return QVariant( d1.date().month() );
851  }
852 }
853 
854 static QVariant fcnWeek( const QVariantList& values, const QgsFeature* , QgsExpression *parent )
855 {
856  QVariant value = values.at( 0 );
857  QgsExpression::Interval inter = getInterval( value, parent, false );
858  if ( inter.isValid() )
859  {
860  return QVariant( inter.weeks() );
861  }
862  else
863  {
864  QDateTime d1 = getDateTimeValue( value, parent );
865  return QVariant( d1.date().weekNumber() );
866  }
867 }
868 
869 static QVariant fcnHour( const QVariantList& values, const QgsFeature* , QgsExpression *parent )
870 {
871  QVariant value = values.at( 0 );
872  QgsExpression::Interval inter = getInterval( value, parent, false );
873  if ( inter.isValid() )
874  {
875  return QVariant( inter.hours() );
876  }
877  else
878  {
879  QDateTime d1 = getDateTimeValue( value, parent );
880  return QVariant( d1.time().hour() );
881  }
882 }
883 
884 static QVariant fcnMinute( const QVariantList& values, const QgsFeature* , QgsExpression *parent )
885 {
886  QVariant value = values.at( 0 );
887  QgsExpression::Interval inter = getInterval( value, parent, false );
888  if ( inter.isValid() )
889  {
890  return QVariant( inter.minutes() );
891  }
892  else
893  {
894  QDateTime d1 = getDateTimeValue( value, parent );
895  return QVariant( d1.time().minute() );
896  }
897 }
898 
899 static QVariant fcnSeconds( const QVariantList& values, const QgsFeature* , QgsExpression *parent )
900 {
901  QVariant value = values.at( 0 );
902  QgsExpression::Interval inter = getInterval( value, parent, false );
903  if ( inter.isValid() )
904  {
905  return QVariant( inter.seconds() );
906  }
907  else
908  {
909  QDateTime d1 = getDateTimeValue( value, parent );
910  return QVariant( d1.time().second() );
911  }
912 }
913 
914 
915 #define ENSURE_GEOM_TYPE(f, g, geomtype) if (!f) return QVariant(); \
916  QgsGeometry* g = f->geometry(); \
917  if (!g || g->type() != geomtype) return QVariant();
918 
919 
920 static QVariant fcnX( const QVariantList& , const QgsFeature* f, QgsExpression* )
921 {
922  ENSURE_GEOM_TYPE( f, g, QGis::Point );
923  if ( g->isMultipart() )
924  {
925  return g->asMultiPoint()[ 0 ].x();
926  }
927  else
928  {
929  return g->asPoint().x();
930  }
931 }
932 static QVariant fcnY( const QVariantList& , const QgsFeature* f, QgsExpression* )
933 {
934  ENSURE_GEOM_TYPE( f, g, QGis::Point );
935  if ( g->isMultipart() )
936  {
937  return g->asMultiPoint()[ 0 ].y();
938  }
939  else
940  {
941  return g->asPoint().y();
942  }
943 }
944 
945 static QVariant pointAt( const QVariantList& values, const QgsFeature* f, QgsExpression* parent ) // helper function
946 {
947  int idx = getIntValue( values.at( 0 ), parent );
948  ENSURE_GEOM_TYPE( f, g, QGis::Line );
949  QgsPolyline polyline = g->asPolyline();
950  if ( idx < 0 )
951  idx += polyline.count();
952 
953  if ( idx < 0 || idx >= polyline.count() )
954  {
955  parent->setEvalErrorString( QObject::tr( "Index is out of range" ) );
956  return QVariant();
957  }
958  return QVariant( QPointF( polyline[idx].x(), polyline[idx].y() ) );
959 }
960 
961 static QVariant fcnXat( const QVariantList& values, const QgsFeature* f, QgsExpression* parent )
962 {
963  QVariant v = pointAt( values, f, parent );
964  if ( v.type() == QVariant::PointF )
965  return QVariant( v.toPointF().x() );
966  else
967  return QVariant();
968 }
969 static QVariant fcnYat( const QVariantList& values, const QgsFeature* f, QgsExpression* parent )
970 {
971  QVariant v = pointAt( values, f, parent );
972  if ( v.type() == QVariant::PointF )
973  return QVariant( v.toPointF().y() );
974  else
975  return QVariant();
976 }
977 static QVariant fcnGeometry( const QVariantList& , const QgsFeature* f, QgsExpression* )
978 {
979  QgsGeometry* geom = f ? f->geometry() : 0;
980  if ( geom )
981  return QVariant::fromValue( *geom );
982  else
983  return QVariant();
984 }
985 static QVariant fcnGeomFromWKT( const QVariantList& values, const QgsFeature*, QgsExpression* parent )
986 {
987  QString wkt = getStringValue( values.at( 0 ), parent );
988  QgsGeometry* geom = QgsGeometry::fromWkt( wkt );
989  if ( geom )
990  return QVariant::fromValue( *geom );
991  else
992  return QVariant();
993 }
994 static QVariant fcnGeomFromGML( const QVariantList& values, const QgsFeature*, QgsExpression* parent )
995 {
996  QString gml = getStringValue( values.at( 0 ), parent );
998 
999  if ( geom )
1000  return QVariant::fromValue( *geom );
1001  else
1002  return QVariant();
1003 }
1004 
1005 static QVariant fcnGeomArea( const QVariantList& , const QgsFeature* f, QgsExpression* parent )
1006 {
1008  QgsDistanceArea* calc = parent->geomCalculator();
1009  return QVariant( calc->measure( f->geometry() ) );
1010 }
1011 static QVariant fcnGeomLength( const QVariantList& , const QgsFeature* f, QgsExpression* parent )
1012 {
1013  ENSURE_GEOM_TYPE( f, g, QGis::Line );
1014  QgsDistanceArea* calc = parent->geomCalculator();
1015  return QVariant( calc->measure( f->geometry() ) );
1016 }
1017 static QVariant fcnGeomPerimeter( const QVariantList& , const QgsFeature* f, QgsExpression* parent )
1018 {
1020  QgsDistanceArea* calc = parent->geomCalculator();
1021  return QVariant( calc->measurePerimeter( f->geometry() ) );
1022 }
1023 
1024 static QVariant fcnBbox( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
1025 {
1026  QgsGeometry fGeom = getGeometry( values.at( 0 ), parent );
1027  QgsGeometry sGeom = getGeometry( values.at( 1 ), parent );
1028  return fGeom.intersects( sGeom.boundingBox() ) ? TVL_True : TVL_False;
1029 }
1030 static QVariant fcnDisjoint( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
1031 {
1032  QgsGeometry fGeom = getGeometry( values.at( 0 ), parent );
1033  QgsGeometry sGeom = getGeometry( values.at( 1 ), parent );
1034  return fGeom.disjoint( &sGeom ) ? TVL_True : TVL_False;
1035 }
1036 static QVariant fcnIntersects( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
1037 {
1038  QgsGeometry fGeom = getGeometry( values.at( 0 ), parent );
1039  QgsGeometry sGeom = getGeometry( values.at( 1 ), parent );
1040  return fGeom.intersects( &sGeom ) ? TVL_True : TVL_False;
1041 }
1042 static QVariant fcnTouches( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
1043 {
1044  QgsGeometry fGeom = getGeometry( values.at( 0 ), parent );
1045  QgsGeometry sGeom = getGeometry( values.at( 1 ), parent );
1046  return fGeom.touches( &sGeom ) ? TVL_True : TVL_False;
1047 }
1048 static QVariant fcnCrosses( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
1049 {
1050  QgsGeometry fGeom = getGeometry( values.at( 0 ), parent );
1051  QgsGeometry sGeom = getGeometry( values.at( 1 ), parent );
1052  return fGeom.crosses( &sGeom ) ? TVL_True : TVL_False;
1053 }
1054 static QVariant fcnContains( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
1055 {
1056  QgsGeometry fGeom = getGeometry( values.at( 0 ), parent );
1057  QgsGeometry sGeom = getGeometry( values.at( 1 ), parent );
1058  return fGeom.contains( &sGeom ) ? TVL_True : TVL_False;
1059 }
1060 static QVariant fcnOverlaps( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
1061 {
1062  QgsGeometry fGeom = getGeometry( values.at( 0 ), parent );
1063  QgsGeometry sGeom = getGeometry( values.at( 1 ), parent );
1064  return fGeom.overlaps( &sGeom ) ? TVL_True : TVL_False;
1065 }
1066 static QVariant fcnWithin( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
1067 {
1068  QgsGeometry fGeom = getGeometry( values.at( 0 ), parent );
1069  QgsGeometry sGeom = getGeometry( values.at( 1 ), parent );
1070  return fGeom.within( &sGeom ) ? TVL_True : TVL_False;
1071 }
1072 static QVariant fcnBuffer( const QVariantList& values, const QgsFeature*, QgsExpression* parent )
1073 {
1074  if ( values.length() < 2 || values.length() > 3 )
1075  return QVariant();
1076 
1077  QgsGeometry fGeom = getGeometry( values.at( 0 ), parent );
1078  double dist = getDoubleValue( values.at( 1 ), parent );
1079  int seg = 8;
1080  if ( values.length() == 3 )
1081  seg = getIntValue( values.at( 2 ), parent );
1082 
1083  QgsGeometry* geom = fGeom.buffer( dist, seg );
1084  if ( geom )
1085  return QVariant::fromValue( *geom );
1086  return QVariant();
1087 }
1088 static QVariant fcnCentroid( const QVariantList& values, const QgsFeature*, QgsExpression* parent )
1089 {
1090  QgsGeometry fGeom = getGeometry( values.at( 0 ), parent );
1091  QgsGeometry* geom = fGeom.centroid();
1092  if ( geom )
1093  return QVariant::fromValue( *geom );
1094  return QVariant();
1095 }
1096 static QVariant fcnConvexHull( const QVariantList& values, const QgsFeature*, QgsExpression* parent )
1097 {
1098  QgsGeometry fGeom = getGeometry( values.at( 0 ), parent );
1099  QgsGeometry* geom = fGeom.convexHull();
1100  if ( geom )
1101  return QVariant::fromValue( *geom );
1102  return QVariant();
1103 }
1104 static QVariant fcnDifference( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
1105 {
1106  QgsGeometry fGeom = getGeometry( values.at( 0 ), parent );
1107  QgsGeometry sGeom = getGeometry( values.at( 1 ), parent );
1108  QgsGeometry* geom = fGeom.difference( &sGeom );
1109  if ( geom )
1110  return QVariant::fromValue( *geom );
1111  return QVariant();
1112 }
1113 static QVariant fcnDistance( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
1114 {
1115  QgsGeometry fGeom = getGeometry( values.at( 0 ), parent );
1116  QgsGeometry sGeom = getGeometry( values.at( 1 ), parent );
1117  return QVariant( fGeom.distance( sGeom ) );
1118 }
1119 static QVariant fcnIntersection( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
1120 {
1121  QgsGeometry fGeom = getGeometry( values.at( 0 ), parent );
1122  QgsGeometry sGeom = getGeometry( values.at( 1 ), parent );
1123  QgsGeometry* geom = fGeom.intersection( &sGeom );
1124  if ( geom )
1125  return QVariant::fromValue( *geom );
1126  return QVariant();
1127 }
1128 static QVariant fcnSymDifference( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
1129 {
1130  QgsGeometry fGeom = getGeometry( values.at( 0 ), parent );
1131  QgsGeometry sGeom = getGeometry( values.at( 1 ), parent );
1132  QgsGeometry* geom = fGeom.symDifference( &sGeom );
1133  if ( geom )
1134  return QVariant::fromValue( *geom );
1135  return QVariant();
1136 }
1137 static QVariant fcnCombine( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
1138 {
1139  QgsGeometry fGeom = getGeometry( values.at( 0 ), parent );
1140  QgsGeometry sGeom = getGeometry( values.at( 1 ), parent );
1141  QgsGeometry* geom = fGeom.combine( &sGeom );
1142  if ( geom )
1143  return QVariant::fromValue( *geom );
1144  return QVariant();
1145 }
1146 static QVariant fcnGeomToWKT( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
1147 {
1148  QgsGeometry fGeom = getGeometry( values.at( 0 ), parent );
1149  QString wkt = fGeom.exportToWkt();
1150  return QVariant( wkt );
1151 }
1152 
1153 static QVariant fcnRound( const QVariantList& values , const QgsFeature *f, QgsExpression* parent )
1154 {
1155  Q_UNUSED( f );
1156  if ( values.length() == 2 )
1157  {
1158  double number = getDoubleValue( values.at( 0 ), parent );
1159  double scaler = pow( 10.0, getIntValue( values.at( 1 ), parent ) );
1160  return QVariant( qRound( number * scaler ) / scaler );
1161  }
1162 
1163  if ( values.length() == 1 )
1164  {
1165  double number = getIntValue( values.at( 0 ), parent );
1166  return QVariant( qRound( number ) ).toInt();
1167  }
1168 
1169  return QVariant();
1170 }
1171 
1172 static QVariant fcnPi( const QVariantList& values , const QgsFeature *f, QgsExpression* parent )
1173 {
1174  Q_UNUSED( values );
1175  Q_UNUSED( f );
1176  Q_UNUSED( parent );
1177  return M_PI;
1178 }
1179 
1180 static QVariant fcnScale( const QVariantList&, const QgsFeature*, QgsExpression* parent )
1181 {
1182  return QVariant( parent->scale() );
1183 }
1184 
1185 static QVariant fcnFormatNumber( const QVariantList& values, const QgsFeature*, QgsExpression* parent )
1186 {
1187  double value = getDoubleValue( values.at( 0 ), parent );
1188  int places = getIntValue( values.at( 1 ), parent );
1189  return QString( "%L1" ).arg( value, 0, 'f', places );
1190 }
1191 
1192 static QVariant fcnFormatDate( const QVariantList& values, const QgsFeature*, QgsExpression* parent )
1193 {
1194  QDateTime dt = getDateTimeValue( values.at( 0 ), parent );
1195  QString format = getStringValue( values.at( 1 ), parent );
1196  return dt.toString( format );
1197 }
1198 
1199 static QVariant fcnColorRgb( const QVariantList &values, const QgsFeature *, QgsExpression *parent )
1200 {
1201  int red = getIntValue( values.at( 0 ), parent );
1202  int green = getIntValue( values.at( 1 ), parent );
1203  int blue = getIntValue( values.at( 2 ), parent );
1204  QColor color = QColor( red, green, blue );
1205  if ( ! color.isValid() )
1206  {
1207  parent->setEvalErrorString( QObject::tr( "Cannot convert '%1:%2:%3' to color" ).arg( red ).arg( green ).arg( blue ) );
1208  color = QColor( 0, 0, 0 );
1209  }
1210 
1211  return QString( "%1,%2,%3" ).arg( color.red() ).arg( color.green() ).arg( color.blue() );
1212 }
1213 
1214 static QVariant fncColorRgba( const QVariantList &values, const QgsFeature *, QgsExpression *parent )
1215 {
1216  int red = getIntValue( values.at( 0 ), parent );
1217  int green = getIntValue( values.at( 1 ), parent );
1218  int blue = getIntValue( values.at( 2 ), parent );
1219  int alpha = getIntValue( values.at( 3 ), parent );
1220  QColor color = QColor( red, green, blue, alpha );
1221  if ( ! color.isValid() )
1222  {
1223  parent->setEvalErrorString( QObject::tr( "Cannot convert '%1:%2:%3:%4' to color" ).arg( red ).arg( green ).arg( blue ).arg( alpha ) );
1224  color = QColor( 0, 0, 0 );
1225  }
1226  return QgsSymbolLayerV2Utils::encodeColor( color );
1227 }
1228 
1229 QVariant fcnRampColor( const QVariantList &values, const QgsFeature *, QgsExpression *parent )
1230 {
1231  QString rampName = getStringValue( values.at( 0 ), parent );
1232  const QgsVectorColorRampV2 *mRamp = QgsStyleV2::defaultStyle()->colorRampRef( rampName );
1233  if ( ! mRamp )
1234  {
1235  parent->setEvalErrorString( QObject::tr( "\"%1\" is not a valid color ramp" ).arg( rampName ) );
1236  return QColor( 0, 0, 0 ).name();
1237  }
1238  double value = getDoubleValue( values.at( 1 ), parent );
1239  QColor color = mRamp->color( value );
1240  return QgsSymbolLayerV2Utils::encodeColor( color );
1241 }
1242 
1243 static QVariant fcnColorHsl( const QVariantList &values, const QgsFeature *, QgsExpression *parent )
1244 {
1245  // Hue ranges from 0 - 360
1246  double hue = getIntValue( values.at( 0 ), parent ) / 360.0;
1247  // Saturation ranges from 0 - 100
1248  double saturation = getIntValue( values.at( 1 ), parent ) / 100.0;
1249  // Lightness ranges from 0 - 100
1250  double lightness = getIntValue( values.at( 2 ), parent ) / 100.0;
1251 
1252  QColor color = QColor::fromHslF( hue, saturation, lightness );
1253 
1254  if ( ! color.isValid() )
1255  {
1256  parent->setEvalErrorString( QObject::tr( "Cannot convert '%1:%2:%3' to color" ).arg( hue ).arg( saturation ).arg( lightness ) );
1257  color = QColor( 0, 0, 0 );
1258  }
1259 
1260  return QString( "%1,%2,%3" ).arg( color.red() ).arg( color.green() ).arg( color.blue() );
1261 }
1262 
1263 static QVariant fncColorHsla( const QVariantList &values, const QgsFeature *, QgsExpression *parent )
1264 {
1265  // Hue ranges from 0 - 360
1266  double hue = getIntValue( values.at( 0 ), parent ) / 360.0;
1267  // Saturation ranges from 0 - 100
1268  double saturation = getIntValue( values.at( 1 ), parent ) / 100.0;
1269  // Lightness ranges from 0 - 100
1270  double lightness = getIntValue( values.at( 2 ), parent ) / 100.0;
1271  // Alpha ranges from 0 - 255
1272  double alpha = getIntValue( values.at( 3 ), parent ) / 255.0;
1273 
1274  QColor color = QColor::fromHslF( hue, saturation, lightness, alpha );
1275  if ( ! color.isValid() )
1276  {
1277  parent->setEvalErrorString( QObject::tr( "Cannot convert '%1:%2:%3:%4' to color" ).arg( hue ).arg( saturation ).arg( lightness ).arg( alpha ) );
1278  color = QColor( 0, 0, 0 );
1279  }
1280  return QgsSymbolLayerV2Utils::encodeColor( color );
1281 }
1282 
1283 static QVariant fcnColorHsv( const QVariantList &values, const QgsFeature *, QgsExpression *parent )
1284 {
1285  // Hue ranges from 0 - 360
1286  double hue = getIntValue( values.at( 0 ), parent ) / 360.0;
1287  // Saturation ranges from 0 - 100
1288  double saturation = getIntValue( values.at( 1 ), parent ) / 100.0;
1289  // Value ranges from 0 - 100
1290  double value = getIntValue( values.at( 2 ), parent ) / 100.0;
1291 
1292  QColor color = QColor::fromHsvF( hue, saturation, value );
1293 
1294  if ( ! color.isValid() )
1295  {
1296  parent->setEvalErrorString( QObject::tr( "Cannot convert '%1:%2:%3' to color" ).arg( hue ).arg( saturation ).arg( value ) );
1297  color = QColor( 0, 0, 0 );
1298  }
1299 
1300  return QString( "%1,%2,%3" ).arg( color.red() ).arg( color.green() ).arg( color.blue() );
1301 }
1302 
1303 static QVariant fncColorHsva( const QVariantList &values, const QgsFeature *, QgsExpression *parent )
1304 {
1305  // Hue ranges from 0 - 360
1306  double hue = getIntValue( values.at( 0 ), parent ) / 360.0;
1307  // Saturation ranges from 0 - 100
1308  double saturation = getIntValue( values.at( 1 ), parent ) / 100.0;
1309  // Value ranges from 0 - 100
1310  double value = getIntValue( values.at( 2 ), parent ) / 100.0;
1311  // Alpha ranges from 0 - 255
1312  double alpha = getIntValue( values.at( 3 ), parent ) / 255.0;
1313 
1314  QColor color = QColor::fromHsvF( hue, saturation, value, alpha );
1315  if ( ! color.isValid() )
1316  {
1317  parent->setEvalErrorString( QObject::tr( "Cannot convert '%1:%2:%3:%4' to color" ).arg( hue ).arg( saturation ).arg( value ).arg( alpha ) );
1318  color = QColor( 0, 0, 0 );
1319  }
1320  return QgsSymbolLayerV2Utils::encodeColor( color );
1321 }
1322 
1323 static QVariant fcnColorCmyk( const QVariantList &values, const QgsFeature *, QgsExpression *parent )
1324 {
1325  // Cyan ranges from 0 - 100
1326  double cyan = getIntValue( values.at( 0 ), parent ) / 100.0;
1327  // Magenta ranges from 0 - 100
1328  double magenta = getIntValue( values.at( 1 ), parent ) / 100.0;
1329  // Yellow ranges from 0 - 100
1330  double yellow = getIntValue( values.at( 2 ), parent ) / 100.0;
1331  // Black ranges from 0 - 100
1332  double black = getIntValue( values.at( 3 ), parent ) / 100.0;
1333 
1334  QColor color = QColor::fromCmykF( cyan, magenta, yellow, black );
1335 
1336  if ( ! color.isValid() )
1337  {
1338  parent->setEvalErrorString( QObject::tr( "Cannot convert '%1:%2:%3:%4' to color" ).arg( cyan ).arg( magenta ).arg( yellow ).arg( black ) );
1339  color = QColor( 0, 0, 0 );
1340  }
1341 
1342  return QString( "%1,%2,%3" ).arg( color.red() ).arg( color.green() ).arg( color.blue() );
1343 }
1344 
1345 static QVariant fncColorCmyka( const QVariantList &values, const QgsFeature *, QgsExpression *parent )
1346 {
1347  // Cyan ranges from 0 - 100
1348  double cyan = getIntValue( values.at( 0 ), parent ) / 100.0;
1349  // Magenta ranges from 0 - 100
1350  double magenta = getIntValue( values.at( 1 ), parent ) / 100.0;
1351  // Yellow ranges from 0 - 100
1352  double yellow = getIntValue( values.at( 2 ), parent ) / 100.0;
1353  // Black ranges from 0 - 100
1354  double black = getIntValue( values.at( 3 ), parent ) / 100.0;
1355  // Alpha ranges from 0 - 255
1356  double alpha = getIntValue( values.at( 4 ), parent ) / 255.0;
1357 
1358  QColor color = QColor::fromCmykF( cyan, magenta, yellow, black, alpha );
1359  if ( ! color.isValid() )
1360  {
1361  parent->setEvalErrorString( QObject::tr( "Cannot convert '%1:%2:%3:%4:%5' to color" ).arg( cyan ).arg( magenta ).arg( yellow ).arg( black ).arg( alpha ) );
1362  color = QColor( 0, 0, 0 );
1363  }
1364  return QgsSymbolLayerV2Utils::encodeColor( color );
1365 }
1366 
1367 static QVariant fcnSpecialColumn( const QVariantList& values, const QgsFeature* /*f*/, QgsExpression* parent )
1368 {
1369  QString varName = getStringValue( values.at( 0 ), parent );
1370  return QgsExpression::specialColumn( varName );
1371 }
1372 
1374 {
1375  int fnIdx = functionIndex( function->name() );
1376  if ( fnIdx != -1 )
1377  {
1378  return false;
1379  }
1380  QgsExpression::gmFunctions.append( function );
1381  return true;
1382 }
1383 
1385 {
1386  // You can never override the built in functions.
1387  if ( QgsExpression::BuiltinFunctions().contains( name ) )
1388  {
1389  return false;
1390  }
1391  int fnIdx = functionIndex( name );
1392  if ( fnIdx != -1 )
1393  {
1394  QgsExpression::gmFunctions.removeAt( fnIdx );
1395  return true;
1396  }
1397  return false;
1398 }
1399 
1400 
1401 
1403 
1405 {
1406  if ( gmBuiltinFunctions.isEmpty() )
1407  {
1409  << "abs" << "sqrt" << "cos" << "sin" << "tan"
1410  << "asin" << "acos" << "atan" << "atan2"
1411  << "exp" << "ln" << "log10" << "log"
1412  << "round" << "rand" << "randf" << "max" << "min" << "clamp"
1413  << "scale_linear" << "scale_exp" << "floor" << "ceil"
1414  << "toint" << "toreal" << "tostring"
1415  << "todatetime" << "todate" << "totime" << "tointerval"
1416  << "coalesce" << "regexp_match" << "$now" << "age" << "year"
1417  << "month" << "week" << "day" << "hour"
1418  << "minute" << "second" << "lower" << "upper"
1419  << "title" << "length" << "replace" << "trim"
1420  << "regexp_replace" << "regexp_substr"
1421  << "substr" << "concat" << "strpos" << "left"
1422  << "right" << "rpad" << "lpad"
1423  << "format_number" << "format_date"
1424  << "color_rgb" << "color_rgba" << "ramp_color"
1425  << "color_hsl" << "color_hsla" << "color_hsv" << "color_hsva"
1426  << "color_cymk" << "color_cymka"
1427  << "xat" << "yat" << "$area"
1428  << "$length" << "$perimeter" << "$x" << "$y"
1429  << "$rownum" << "$id" << "$scale" << "_specialcol_";
1430  }
1431  return gmBuiltinFunctions;
1432 }
1433 
1434 QList<QgsExpression::Function*> QgsExpression::gmFunctions;
1435 
1436 const QList<QgsExpression::Function*> &QgsExpression::Functions()
1437 {
1438  if ( gmFunctions.isEmpty() )
1439  {
1440  gmFunctions
1441  << new StaticFunction( "sqrt", 1, fcnSqrt, "Math" )
1442  << new StaticFunction( "abs", 1, fcnAbs, "Math" )
1443  << new StaticFunction( "cos", 1, fcnCos, "Math" )
1444  << new StaticFunction( "sin", 1, fcnSin, "Math" )
1445  << new StaticFunction( "tan", 1, fcnTan, "Math" )
1446  << new StaticFunction( "asin", 1, fcnAsin, "Math" )
1447  << new StaticFunction( "acos", 1, fcnAcos, "Math" )
1448  << new StaticFunction( "atan", 1, fcnAtan, "Math" )
1449  << new StaticFunction( "atan2", 2, fcnAtan2, "Math" )
1450  << new StaticFunction( "exp", 1, fcnExp, "Math" )
1451  << new StaticFunction( "ln", 1, fcnLn, "Math" )
1452  << new StaticFunction( "log10", 1, fcnLog10, "Math" )
1453  << new StaticFunction( "log", 2, fcnLog, "Math" )
1454  << new StaticFunction( "round", -1, fcnRound, "Math" )
1455  << new StaticFunction( "rand", 2, fcnRnd, "Math" )
1456  << new StaticFunction( "randf", 2, fcnRndF, "Math" )
1457  << new StaticFunction( "max", -1, fcnMax, "Math" )
1458  << new StaticFunction( "min", -1, fcnMin, "Math" )
1459  << new StaticFunction( "clamp", 3, fcnClamp, "Math" )
1460  << new StaticFunction( "scale_linear", 5, fcnLinearScale, "Math" )
1461  << new StaticFunction( "scale_exp", 6, fcnExpScale, "Math" )
1462  << new StaticFunction( "floor", 1, fcnFloor, "Math" )
1463  << new StaticFunction( "ceil", 1, fcnCeil, "Math" )
1464  << new StaticFunction( "$pi", 0, fcnPi, "Math" )
1465  << new StaticFunction( "toint", 1, fcnToInt, "Conversions" )
1466  << new StaticFunction( "toreal", 1, fcnToReal, "Conversions" )
1467  << new StaticFunction( "tostring", 1, fcnToString, "Conversions" )
1468  << new StaticFunction( "todatetime", 1, fcnToDateTime, "Conversions" )
1469  << new StaticFunction( "todate", 1, fcnToDate, "Conversions" )
1470  << new StaticFunction( "totime", 1, fcnToTime, "Conversions" )
1471  << new StaticFunction( "tointerval", 1, fcnToInterval, "Conversions" )
1472  << new StaticFunction( "coalesce", -1, fcnCoalesce, "Conditionals" )
1473  << new StaticFunction( "regexp_match", 2, fcnRegexpMatch, "Conditionals" )
1474  << new StaticFunction( "$now", 0, fcnNow, "Date and Time" )
1475  << new StaticFunction( "age", 2, fcnAge, "Date and Time" )
1476  << new StaticFunction( "year", 1, fcnYear, "Date and Time" )
1477  << new StaticFunction( "month", 1, fcnMonth, "Date and Time" )
1478  << new StaticFunction( "week", 1, fcnWeek, "Date and Time" )
1479  << new StaticFunction( "day", 1, fcnDay, "Date and Time" )
1480  << new StaticFunction( "hour", 1, fcnHour, "Date and Time" )
1481  << new StaticFunction( "minute", 1, fcnMinute, "Date and Time" )
1482  << new StaticFunction( "second", 1, fcnSeconds, "Date and Time" )
1483  << new StaticFunction( "lower", 1, fcnLower, "String" )
1484  << new StaticFunction( "upper", 1, fcnUpper, "String" )
1485  << new StaticFunction( "title", 1, fcnTitle, "String" )
1486  << new StaticFunction( "trim", 1, fcnTrim, "String" )
1487  << new StaticFunction( "length", 1, fcnLength, "String" )
1488  << new StaticFunction( "replace", 3, fcnReplace, "String" )
1489  << new StaticFunction( "regexp_replace", 3, fcnRegexpReplace, "String" )
1490  << new StaticFunction( "regexp_substr", 2, fcnRegexpSubstr, "String" )
1491  << new StaticFunction( "substr", 3, fcnSubstr, "String" )
1492  << new StaticFunction( "concat", -1, fcnConcat, "String" )
1493  << new StaticFunction( "strpos", 2, fcnStrpos, "String" )
1494  << new StaticFunction( "left", 2, fcnLeft, "String" )
1495  << new StaticFunction( "right", 2, fcnRight, "String" )
1496  << new StaticFunction( "rpad", 3, fcnRPad, "String" )
1497  << new StaticFunction( "lpad", 3, fcnLPad, "String" )
1498  << new StaticFunction( "format", -1, fcnFormatString, "String" )
1499  << new StaticFunction( "format_number", 2, fcnFormatNumber, "String" )
1500  << new StaticFunction( "format_date", 2, fcnFormatDate, "String" )
1501  << new StaticFunction( "color_rgb", 3, fcnColorRgb, "Color" )
1502  << new StaticFunction( "color_rgba", 4, fncColorRgba, "Color" )
1503  << new StaticFunction( "ramp_color", 2, fcnRampColor, "Color" )
1504  << new StaticFunction( "color_hsl", 3, fcnColorHsl, "Color" )
1505  << new StaticFunction( "color_hsla", 4, fncColorHsla, "Color" )
1506  << new StaticFunction( "color_hsv", 3, fcnColorHsv, "Color" )
1507  << new StaticFunction( "color_hsva", 4, fncColorHsva, "Color" )
1508  << new StaticFunction( "color_cmyk", 4, fcnColorCmyk, "Color" )
1509  << new StaticFunction( "color_cmyka", 5, fncColorCmyka, "Color" )
1510  << new StaticFunction( "xat", 1, fcnXat, "Geometry", "", true )
1511  << new StaticFunction( "yat", 1, fcnYat, "Geometry", "", true )
1512  << new StaticFunction( "$area", 0, fcnGeomArea, "Geometry", "", true )
1513  << new StaticFunction( "$length", 0, fcnGeomLength, "Geometry", "", true )
1514  << new StaticFunction( "$perimeter", 0, fcnGeomPerimeter, "Geometry", "", true )
1515  << new StaticFunction( "$x", 0, fcnX, "Geometry", "", true )
1516  << new StaticFunction( "$y", 0, fcnY, "Geometry", "" , true )
1517  << new StaticFunction( "$geometry", 0, fcnGeometry, "Geometry", "" , true )
1518  << new StaticFunction( "geomFromWKT", 1, fcnGeomFromWKT, "Geometry" )
1519  << new StaticFunction( "geomFromGML", 1, fcnGeomFromGML, "Geometry" )
1520  << new StaticFunction( "bbox", 2, fcnBbox, "Geometry" )
1521  << new StaticFunction( "disjoint", 2, fcnDisjoint, "Geometry" )
1522  << new StaticFunction( "intersects", 2, fcnIntersects, "Geometry" )
1523  << new StaticFunction( "touches", 2, fcnTouches, "Geometry" )
1524  << new StaticFunction( "crosses", 2, fcnCrosses, "Geometry" )
1525  << new StaticFunction( "contains", 2, fcnContains, "Geometry" )
1526  << new StaticFunction( "overlaps", 2, fcnOverlaps, "Geometry" )
1527  << new StaticFunction( "within", 2, fcnWithin, "Geometry" )
1528  << new StaticFunction( "buffer", -1, fcnBuffer, "Geometry" )
1529  << new StaticFunction( "centroid", 1, fcnCentroid, "Geometry" )
1530  << new StaticFunction( "convexHull", 1, fcnConvexHull, "Geometry" )
1531  << new StaticFunction( "difference", 2, fcnDifference, "Geometry" )
1532  << new StaticFunction( "distance", 2, fcnDistance, "Geometry" )
1533  << new StaticFunction( "intersection", 2, fcnIntersection, "Geometry" )
1534  << new StaticFunction( "symDifference", 2, fcnSymDifference, "Geometry" )
1535  << new StaticFunction( "combine", 2, fcnCombine, "Geometry" )
1536  << new StaticFunction( "union", 2, fcnCombine, "Geometry" )
1537  << new StaticFunction( "geomToWKT", 1, fcnGeomToWKT, "Geometry" )
1538  << new StaticFunction( "$rownum", 0, fcnRowNumber, "Record" )
1539  << new StaticFunction( "$id", 0, fcnFeatureId, "Record" )
1540  << new StaticFunction( "$scale", 0, fcnScale, "Record" )
1541  << new StaticFunction( "$uuid", 0, fcnUuid, "Record" )
1542  << new StaticFunction( "_specialcol_", 1, fcnSpecialColumn, "Special" )
1543  ;
1544  }
1545  return gmFunctions;
1546 }
1547 
1548 QMap<QString, QVariant> QgsExpression::gmSpecialColumns;
1549 
1550 void QgsExpression::setSpecialColumn( const QString& name, QVariant variant )
1551 {
1552  int fnIdx = functionIndex( name );
1553  if ( fnIdx != -1 )
1554  {
1555  // function of the same name already exists
1556  return;
1557  }
1558  gmSpecialColumns[ name ] = variant;
1559 }
1560 
1561 void QgsExpression::unsetSpecialColumn( const QString& name )
1562 {
1563  QMap<QString, QVariant>::iterator fit = gmSpecialColumns.find( name );
1564  if ( fit != gmSpecialColumns.end() )
1565  {
1566  gmSpecialColumns.erase( fit );
1567  }
1568 }
1569 
1570 QVariant QgsExpression::specialColumn( const QString& name )
1571 {
1572  int fnIdx = functionIndex( name );
1573  if ( fnIdx != -1 )
1574  {
1575  // function of the same name already exists
1576  return QVariant();
1577  }
1578  QMap<QString, QVariant>::iterator it = gmSpecialColumns.find( name );
1579  if ( it == gmSpecialColumns.end() )
1580  {
1581  return QVariant();
1582  }
1583  return it.value();
1584 }
1585 
1586 bool QgsExpression::hasSpecialColumn( const QString& name )
1587 {
1588  static bool initialized = false;
1589  if ( !initialized )
1590  {
1591  // Pre-register special columns that will exist within QGIS so that expressions that may use them are parsed correctly.
1592  // This is really sub-optimal, we should get rid of the special columns and instead have contexts in which some values
1593  // are defined and some are not ($rownum makes sense only in field calculator, $scale only when rendering, $page only for composer etc.)
1594 
1595  QStringList lst;
1596  lst << "$page" << "$feature" << "$numpages" << "$numfeatures" << "$atlasfeatureid" << "$atlasgeometry" << "$map";
1597  foreach ( QString c, lst )
1598  setSpecialColumn( c, QVariant() );
1599 
1600  initialized = true;
1601  }
1602 
1603  if ( functionIndex( name ) != -1 )
1604  return false;
1605  return gmSpecialColumns.contains( name );
1606 }
1607 
1608 QList<QgsExpression::Function*> QgsExpression::specialColumns()
1609 {
1610  QList<Function*> defs;
1611  for ( QMap<QString, QVariant>::const_iterator it = gmSpecialColumns.begin(); it != gmSpecialColumns.end(); ++it )
1612  {
1613  defs << new StaticFunction( it.key(), 0, 0, "Record" );
1614  }
1615  return defs;
1616 }
1617 
1618 bool QgsExpression::isFunctionName( QString name )
1619 {
1620  return functionIndex( name ) != -1;
1621 }
1622 
1623 int QgsExpression::functionIndex( QString name )
1624 {
1625  int count = functionCount();
1626  for ( int i = 0; i < count; i++ )
1627  {
1628  if ( QString::compare( name, Functions()[i]->name(), Qt::CaseInsensitive ) == 0 )
1629  return i;
1630  }
1631  return -1;
1632 }
1633 
1635 {
1636  return Functions().size();
1637 }
1638 
1639 
1640 QgsExpression::QgsExpression( const QString& expr )
1641  : mRowNumber( 0 )
1642  , mScale( 0 )
1643  , mExp( expr )
1644  , mCalc( 0 )
1645 {
1647 
1648  if ( mParserErrorString.isNull() )
1649  Q_ASSERT( mRootNode );
1650 }
1651 
1653 {
1654  delete mCalc;
1655  delete mRootNode;
1656 }
1657 
1659 {
1660  if ( !mRootNode )
1661  return QStringList();
1662  QStringList columns = mRootNode->referencedColumns();
1663 
1664  // filter out duplicates
1665  for ( int i = 0; i < columns.count(); i++ )
1666  {
1667  QString col = columns.at( i );
1668  for ( int j = i + 1; j < columns.count(); j++ )
1669  {
1670  if ( QString::compare( col, columns[j], Qt::CaseInsensitive ) == 0 )
1671  {
1672  // this column is repeated: remove it!
1673  columns.removeAt( j-- );
1674  }
1675  }
1676  }
1677 
1678  return columns;
1679 }
1680 
1682 {
1683  if ( !mRootNode )
1684  return false;
1685  return mRootNode->needsGeometry();
1686 }
1687 
1689 {
1690  if ( mCalc )
1691  return;
1692 
1693  // Use planimetric as default
1694  mCalc = new QgsDistanceArea();
1695  mCalc->setEllipsoidalMode( false );
1696 }
1697 
1699 {
1700  delete mCalc;
1701  mCalc = new QgsDistanceArea( calc );
1702 }
1703 
1704 bool QgsExpression::prepare( const QgsFields& fields )
1705 {
1706  mEvalErrorString = QString();
1707  if ( !mRootNode )
1708  {
1709  mEvalErrorString = QObject::tr( "No root node! Parsing failed?" );
1710  return false;
1711  }
1712 
1713  return mRootNode->prepare( this, fields );
1714 }
1715 
1717 {
1718  mEvalErrorString = QString();
1719  if ( !mRootNode )
1720  {
1721  mEvalErrorString = QObject::tr( "No root node! Parsing failed?" );
1722  return QVariant();
1723  }
1724 
1725  return mRootNode->eval( this, f );
1726 }
1727 
1728 QVariant QgsExpression::evaluate( const QgsFeature* f, const QgsFields& fields )
1729 {
1730  // first prepare
1731  bool res = prepare( fields );
1732  if ( !res )
1733  return QVariant();
1734 
1735  // then evaluate
1736  return evaluate( f );
1737 }
1738 
1739 QString QgsExpression::dump() const
1740 {
1741  if ( !mRootNode )
1742  return QObject::tr( "(no root)" );
1743 
1744  return mRootNode->dump();
1745 }
1746 
1748 {
1749  if ( mRootNode )
1750  mRootNode->accept( v );
1751 }
1752 
1753 QString QgsExpression::replaceExpressionText( const QString &action, const QgsFeature *feat,
1754  QgsVectorLayer *layer,
1755  const QMap<QString, QVariant> *substitutionMap )
1756 {
1757  QString expr_action;
1758 
1759  QMap<QString, QVariant> savedValues;
1760  if ( substitutionMap )
1761  {
1762  // variables with a local scope (must be restored after evaluation)
1763  for ( QMap<QString, QVariant>::const_iterator sit = substitutionMap->begin(); sit != substitutionMap->end(); ++sit )
1764  {
1765  QVariant oldValue = QgsExpression::specialColumn( sit.key() );
1766  if ( !oldValue.isNull() )
1767  savedValues.insert( sit.key(), oldValue );
1768 
1769  // set the new value
1770  QgsExpression::setSpecialColumn( sit.key(), sit.value() );
1771  }
1772  }
1773 
1774  int index = 0;
1775  while ( index < action.size() )
1776  {
1777  QRegExp rx = QRegExp( "\\[%([^\\]]+)%\\]" );
1778 
1779  int pos = rx.indexIn( action, index );
1780  if ( pos < 0 )
1781  break;
1782 
1783  int start = index;
1784  index = pos + rx.matchedLength();
1785  QString to_replace = rx.cap( 1 ).trimmed();
1786  QgsDebugMsg( "Found expression: " + to_replace );
1787 
1788  QgsExpression exp( to_replace );
1789  if ( exp.hasParserError() )
1790  {
1791  QgsDebugMsg( "Expression parser error: " + exp.parserErrorString() );
1792  expr_action += action.mid( start, index - start );
1793  continue;
1794  }
1795 
1796  QVariant result;
1797  if ( layer )
1798  {
1799  result = exp.evaluate( feat, layer->pendingFields() );
1800  }
1801  else
1802  {
1803  result = exp.evaluate( feat );
1804  }
1805  if ( exp.hasEvalError() )
1806  {
1807  QgsDebugMsg( "Expression parser eval error: " + exp.evalErrorString() );
1808  expr_action += action.mid( start, index - start );
1809  continue;
1810  }
1811 
1812  QgsDebugMsg( "Expression result is: " + result.toString() );
1813  expr_action += action.mid( start, pos - start ) + result.toString();
1814  }
1815 
1816  expr_action += action.mid( index );
1817 
1818  // restore overwritten local values
1819  for ( QMap<QString, QVariant>::const_iterator sit = savedValues.begin(); sit != savedValues.end(); ++sit )
1820  {
1821  QgsExpression::setSpecialColumn( sit.key(), sit.value() );
1822  }
1823 
1824  return expr_action;
1825 }
1826 
1827 
1829 // nodes
1830 
1832 {
1833  QString msg; bool first = true;
1834  foreach ( Node* n, mList )
1835  {
1836  if ( !first ) msg += ", "; else first = false;
1837  msg += n->dump();
1838  }
1839  return msg;
1840 }
1841 
1842 
1843 //
1844 
1846 {
1847  QVariant val = mOperand->eval( parent, f );
1849 
1850  switch ( mOp )
1851  {
1852  case uoNot:
1853  {
1854  TVL tvl = getTVLValue( val, parent );
1856  return tvl2variant( NOT[tvl] );
1857  }
1858 
1859  case uoMinus:
1860  if ( isIntSafe( val ) )
1861  return QVariant( - getIntValue( val, parent ) );
1862  else if ( isDoubleSafe( val ) )
1863  return QVariant( - getDoubleValue( val, parent ) );
1864  else
1865  SET_EVAL_ERROR( QObject::tr( "Unary minus only for numeric values." ) );
1866  break;
1867  default:
1868  Q_ASSERT( 0 && "unknown unary operation" );
1869  }
1870  return QVariant();
1871 }
1872 
1874 {
1875  return mOperand->prepare( parent, fields );
1876 }
1877 
1879 {
1880  return QString( "%1 %2" ).arg( UnaryOperatorText[mOp] ).arg( mOperand->dump() );
1881 }
1882 
1883 //
1884 
1886 {
1887  QVariant vL = mOpLeft->eval( parent, f );
1889  QVariant vR = mOpRight->eval( parent, f );
1891 
1892  switch ( mOp )
1893  {
1894  case boPlus:
1895  case boMinus:
1896  case boMul:
1897  case boDiv:
1898  case boMod:
1899  if ( isNull( vL ) || isNull( vR ) )
1900  return QVariant();
1901  else if ( isIntSafe( vL ) && isIntSafe( vR ) )
1902  {
1903  // both are integers - let's use integer arithmetics
1904  int iL = getIntValue( vL, parent ); ENSURE_NO_EVAL_ERROR;
1905  int iR = getIntValue( vR, parent ); ENSURE_NO_EVAL_ERROR;
1906  if ( mOp == boDiv && iR == 0 ) return QVariant(); // silently handle division by zero and return NULL
1907  return QVariant( computeInt( iL, iR ) );
1908  }
1909  else if ( isDateTimeSafe( vL ) && isIntervalSafe( vR ) )
1910  {
1911  QDateTime dL = getDateTimeValue( vL, parent ); ENSURE_NO_EVAL_ERROR;
1913  if ( mOp == boDiv || mOp == boMul || mOp == boMod )
1914  {
1915  parent->setEvalErrorString( QObject::tr( "Can't preform /, *, or % on DateTime and Interval" ) );
1916  return QVariant();
1917  }
1918  return QVariant( computeDateTimeFromInterval( dL, &iL ) );
1919  }
1920  else
1921  {
1922  // general floating point arithmetic
1923  double fL = getDoubleValue( vL, parent ); ENSURE_NO_EVAL_ERROR;
1924  double fR = getDoubleValue( vR, parent ); ENSURE_NO_EVAL_ERROR;
1925  if ( mOp == boDiv && fR == 0 )
1926  return QVariant(); // silently handle division by zero and return NULL
1927  return QVariant( computeDouble( fL, fR ) );
1928  }
1929 
1930  case boPow:
1931  if ( isNull( vL ) || isNull( vR ) )
1932  return QVariant();
1933  else
1934  {
1935  double fL = getDoubleValue( vL, parent ); ENSURE_NO_EVAL_ERROR;
1936  double fR = getDoubleValue( vR, parent ); ENSURE_NO_EVAL_ERROR;
1937  return QVariant( pow( fL, fR ) );
1938  }
1939 
1940  case boAnd:
1941  {
1942  TVL tvlL = getTVLValue( vL, parent ), tvlR = getTVLValue( vR, parent );
1944  return tvl2variant( AND[tvlL][tvlR] );
1945  }
1946 
1947  case boOr:
1948  {
1949  TVL tvlL = getTVLValue( vL, parent ), tvlR = getTVLValue( vR, parent );
1951  return tvl2variant( OR[tvlL][tvlR] );
1952  }
1953 
1954  case boEQ:
1955  case boNE:
1956  case boLT:
1957  case boGT:
1958  case boLE:
1959  case boGE:
1960  if ( isNull( vL ) || isNull( vR ) )
1961  {
1962  return TVL_Unknown;
1963  }
1964  else if ( isDoubleSafe( vL ) && isDoubleSafe( vR ) )
1965  {
1966  // do numeric comparison if both operators can be converted to numbers
1967  double fL = getDoubleValue( vL, parent ); ENSURE_NO_EVAL_ERROR;
1968  double fR = getDoubleValue( vR, parent ); ENSURE_NO_EVAL_ERROR;
1969  return compare( fL - fR ) ? TVL_True : TVL_False;
1970  }
1971  else
1972  {
1973  // do string comparison otherwise
1974  QString sL = getStringValue( vL, parent ); ENSURE_NO_EVAL_ERROR;
1975  QString sR = getStringValue( vR, parent ); ENSURE_NO_EVAL_ERROR;
1976  int diff = QString::compare( sL, sR );
1977  return compare( diff ) ? TVL_True : TVL_False;
1978  }
1979 
1980  case boIs:
1981  case boIsNot:
1982  if ( isNull( vL ) && isNull( vR ) ) // both operators null
1983  return ( mOp == boIs ? TVL_True : TVL_False );
1984  else if ( isNull( vL ) || isNull( vR ) ) // one operator null
1985  return ( mOp == boIs ? TVL_False : TVL_True );
1986  else // both operators non-null
1987  {
1988  bool equal = false;
1989  if ( isDoubleSafe( vL ) && isDoubleSafe( vR ) )
1990  {
1991  double fL = getDoubleValue( vL, parent ); ENSURE_NO_EVAL_ERROR;
1992  double fR = getDoubleValue( vR, parent ); ENSURE_NO_EVAL_ERROR;
1993  equal = fL == fR;
1994  }
1995  else
1996  {
1997  QString sL = getStringValue( vL, parent ); ENSURE_NO_EVAL_ERROR;
1998  QString sR = getStringValue( vR, parent ); ENSURE_NO_EVAL_ERROR;
1999  equal = QString::compare( sL, sR ) == 0;
2000  }
2001  if ( equal )
2002  return mOp == boIs ? TVL_True : TVL_False;
2003  else
2004  return mOp == boIs ? TVL_False : TVL_True;
2005  }
2006 
2007  case boRegexp:
2008  case boLike:
2009  case boNotLike:
2010  case boILike:
2011  case boNotILike:
2012  if ( isNull( vL ) || isNull( vR ) )
2013  return TVL_Unknown;
2014  else
2015  {
2016  QString str = getStringValue( vL, parent ); ENSURE_NO_EVAL_ERROR;
2017  QString regexp = getStringValue( vR, parent ); ENSURE_NO_EVAL_ERROR;
2018  // TODO: cache QRegExp in case that regexp is a literal string (i.e. it will stay constant)
2019  bool matches;
2020  if ( mOp == boLike || mOp == boILike || mOp == boNotLike || mOp == boNotILike ) // change from LIKE syntax to regexp
2021  {
2022  QString esc_regexp = QRegExp::escape( regexp );
2023  // XXX escape % and _ ???
2024  esc_regexp.replace( "%", ".*" );
2025  esc_regexp.replace( "_", "." );
2026  matches = QRegExp( esc_regexp, mOp == boLike || mOp == boNotLike ? Qt::CaseSensitive : Qt::CaseInsensitive ).exactMatch( str );
2027  }
2028  else
2029  {
2030  matches = QRegExp( regexp ).indexIn( str ) != -1;
2031  }
2032 
2033  if ( mOp == boNotLike || mOp == boNotILike )
2034  {
2035  matches = !matches;
2036  }
2037 
2038  return matches ? TVL_True : TVL_False;
2039  }
2040 
2041  case boConcat:
2042  if ( isNull( vL ) || isNull( vR ) )
2043  return QVariant();
2044  else
2045  {
2046  QString sL = getStringValue( vL, parent ); ENSURE_NO_EVAL_ERROR;
2047  QString sR = getStringValue( vR, parent ); ENSURE_NO_EVAL_ERROR;
2048  return QVariant( sL + sR );
2049  }
2050 
2051  default: break;
2052  }
2053  Q_ASSERT( false );
2054  return QVariant();
2055 }
2056 
2058 {
2059  switch ( mOp )
2060  {
2061  case boEQ: return diff == 0;
2062  case boNE: return diff != 0;
2063  case boLT: return diff < 0;
2064  case boGT: return diff > 0;
2065  case boLE: return diff <= 0;
2066  case boGE: return diff >= 0;
2067  default: Q_ASSERT( false ); return false;
2068  }
2069 }
2070 
2072 {
2073  switch ( mOp )
2074  {
2075  case boPlus: return x+y;
2076  case boMinus: return x-y;
2077  case boMul: return x*y;
2078  case boDiv: return x/y;
2079  case boMod: return x%y;
2080  default: Q_ASSERT( false ); return 0;
2081  }
2082 }
2083 
2085 {
2086  switch ( mOp )
2087  {
2088  case boPlus: return d.addSecs( i->seconds() );
2089  case boMinus: return d.addSecs( -i->seconds() );
2090  default: Q_ASSERT( false ); return QDateTime();
2091  }
2092 }
2093 
2095 {
2096  switch ( mOp )
2097  {
2098  case boPlus: return x+y;
2099  case boMinus: return x-y;
2100  case boMul: return x*y;
2101  case boDiv: return x/y;
2102  case boMod: return fmod( x,y );
2103  default: Q_ASSERT( false ); return 0;
2104  }
2105 }
2106 
2107 
2109 {
2110  bool resL = mOpLeft->prepare( parent, fields );
2111  bool resR = mOpRight->prepare( parent, fields );
2112  return resL && resR;
2113 }
2114 
2116 {
2117  return QString( "%1 %2 %3" ).arg( mOpLeft->dump() ).arg( BinaryOperatorText[mOp] ).arg( mOpRight->dump() );
2118 }
2119 
2120 //
2121 
2123 {
2124  if ( mList->count() == 0 )
2125  return mNotIn ? TVL_True : TVL_False;
2126  QVariant v1 = mNode->eval( parent, f );
2128  if ( isNull( v1 ) )
2129  return TVL_Unknown;
2130 
2131  bool listHasNull = false;
2132 
2133  foreach ( Node* n, mList->list() )
2134  {
2135  QVariant v2 = n->eval( parent, f );
2137  if ( isNull( v2 ) )
2138  listHasNull = true;
2139  else
2140  {
2141  bool equal = false;
2142  // check whether they are equal
2143  if ( isDoubleSafe( v1 ) && isDoubleSafe( v2 ) )
2144  {
2145  double f1 = getDoubleValue( v1, parent ); ENSURE_NO_EVAL_ERROR;
2146  double f2 = getDoubleValue( v2, parent ); ENSURE_NO_EVAL_ERROR;
2147  equal = f1 == f2;
2148  }
2149  else
2150  {
2151  QString s1 = getStringValue( v1, parent ); ENSURE_NO_EVAL_ERROR;
2152  QString s2 = getStringValue( v2, parent ); ENSURE_NO_EVAL_ERROR;
2153  equal = QString::compare( s1, s2 ) == 0;
2154  }
2155 
2156  if ( equal ) // we know the result
2157  return mNotIn ? TVL_False : TVL_True;
2158  }
2159  }
2160 
2161  // item not found
2162  if ( listHasNull )
2163  return TVL_Unknown;
2164  else
2165  return mNotIn ? TVL_True : TVL_False;
2166 }
2167 
2169 {
2170  bool res = mNode->prepare( parent, fields );
2171  foreach ( Node* n, mList->list() )
2172  {
2173  res = res && n->prepare( parent, fields );
2174  }
2175  return res;
2176 }
2177 
2179 {
2180  return QString( "%1 IN (%2)" ).arg( mNode->dump() ).arg( mList->dump() );
2181 }
2182 
2183 //
2184 
2186 {
2187  Function* fd = Functions()[mFnIndex];
2188 
2189  // evaluate arguments
2190  QVariantList argValues;
2191  if ( mArgs )
2192  {
2193  foreach ( Node* n, mArgs->list() )
2194  {
2195  QVariant v = n->eval( parent, f );
2197  if ( isNull( v ) && fd->name() != "coalesce" )
2198  return QVariant(); // all "normal" functions return NULL, when any parameter is NULL (so coalesce is abnormal)
2199  argValues.append( v );
2200  }
2201  }
2202 
2203  // run the function
2204  QVariant res = fd->func( argValues, f, parent );
2206 
2207  // everything went fine
2208  return res;
2209 }
2210 
2212 {
2213  bool res = true;
2214  if ( mArgs )
2215  {
2216  foreach ( Node* n, mArgs->list() )
2217  {
2218  res = res && n->prepare( parent, fields );
2219  }
2220  }
2221  return res;
2222 }
2223 
2225 {
2226  Function* fd = Functions()[mFnIndex];
2227  if ( fd->params() == 0 )
2228  return fd->name(); // special column
2229  else
2230  return QString( "%1(%2)" ).arg( fd->name() ).arg( mArgs ? mArgs->dump() : QString() ); // function
2231 }
2232 
2233 //
2234 
2236 {
2237  return mValue;
2238 }
2239 
2240 bool QgsExpression::NodeLiteral::prepare( QgsExpression* /*parent*/, const QgsFields& /*fields*/ )
2241 {
2242  return true;
2243 }
2244 
2245 
2247 {
2248  if ( mValue.isNull() )
2249  return "NULL";
2250 
2251  switch ( mValue.type() )
2252  {
2253  case QVariant::Int: return QString::number( mValue.toInt() );
2254  case QVariant::Double: return QString::number( mValue.toDouble() );
2255  case QVariant::String: return QString( "'%1'" ).arg( mValue.toString() );
2256  default: return QObject::tr( "[unsupported type;%1; value:%2]" ).arg( mValue.typeName() ).arg( mValue.toString() );
2257  }
2258 }
2259 
2260 //
2261 
2263 {
2264  if ( f )
2265  {
2266  if ( mIndex >= 0 )
2267  return f->attribute( mIndex );
2268  else
2269  return f->attribute( mName );
2270  }
2271  return QVariant( "[" + mName + "]" );
2272 }
2273 
2275 {
2276  for ( int i = 0; i < fields.count(); ++i )
2277  {
2278  if ( QString::compare( fields[i].name(), mName, Qt::CaseInsensitive ) == 0 )
2279  {
2280  mIndex = i;
2281  return true;
2282  }
2283  }
2284  parent->mEvalErrorString = QObject::tr( "Column '%1' not found" ).arg( mName );
2285  mIndex = -1;
2286  return false;
2287 }
2288 
2290 {
2291  return QRegExp( "^[A-Za-z_\x80-\xff][A-Za-z0-9_\x80-\xff]*$" ).exactMatch( mName ) ? mName : quotedColumnRef( mName );
2292 }
2293 
2294 //
2295 
2297 {
2298  foreach ( WhenThen* cond, mConditions )
2299  {
2300  QVariant vWhen = cond->mWhenExp->eval( parent, f );
2301  TVL tvl = getTVLValue( vWhen, parent );
2303  if ( tvl == True )
2304  {
2305  QVariant vRes = cond->mThenExp->eval( parent, f );
2307  return vRes;
2308  }
2309  }
2310 
2311  if ( mElseExp )
2312  {
2313  QVariant vElse = mElseExp->eval( parent, f );
2315  return vElse;
2316  }
2317 
2318  // return NULL if no condition is matching
2319  return QVariant();
2320 }
2321 
2323 {
2324  bool res;
2325  foreach ( WhenThen* cond, mConditions )
2326  {
2327  res = cond->mWhenExp->prepare( parent, fields )
2328  & cond->mThenExp->prepare( parent, fields );
2329  if ( !res ) return false;
2330  }
2331 
2332  if ( mElseExp )
2333  return mElseExp->prepare( parent, fields );
2334 
2335  return true;
2336 }
2337 
2339 {
2340  QString msg = QString( "CASE " );
2341  foreach ( WhenThen* cond, mConditions )
2342  {
2343  msg += QString( "WHEN %1 THEN %2" ).arg( cond->mWhenExp->dump() ).arg( cond->mThenExp->dump() );
2344  }
2345  if ( mElseExp )
2346  msg += QString( "ELSE %1" ).arg( mElseExp->dump() );
2347  msg += QString( " END" );
2348  return msg;
2349 }
2350 
2352 {
2353  QStringList lst;
2354  foreach ( WhenThen* cond, mConditions )
2355  {
2356  lst += cond->mWhenExp->referencedColumns() + cond->mThenExp->referencedColumns();
2357  }
2358 
2359  if ( mElseExp )
2360  lst += mElseExp->referencedColumns();
2361 
2362  return lst;
2363 }
2364 
2366 {
2367  foreach ( WhenThen* cond, mConditions )
2368  {
2369  if ( cond->mWhenExp->needsGeometry() ||
2370  cond->mThenExp->needsGeometry() )
2371  return true;
2372  }
2373 
2374  if ( mElseExp && mElseExp->needsGeometry() )
2375  return true;
2376 
2377  return false;
2378 }
2379 
2380 QString QgsExpression::helptext( QString name )
2381 {
2383  return gFunctionHelpTexts.value( name, QObject::tr( "function help for %1 missing" ).arg( name ) );
2384 }
2385 
2386 QHash<QString, QString> QgsExpression::gGroups;
2387 
2388 QString QgsExpression::group( QString name )
2389 {
2390  if ( gGroups.isEmpty() )
2391  {
2392  gGroups.insert( "Operators", QObject::tr( "Operators" ) );
2393  gGroups.insert( "Conditionals", QObject::tr( "Conditionals" ) );
2394  gGroups.insert( "Fields and Values", QObject::tr( "Fields and Values" ) );
2395  gGroups.insert( "Math", QObject::tr( "Math" ) );
2396  gGroups.insert( "Conversions", QObject::tr( "Conversions" ) );
2397  gGroups.insert( "Date and Time", QObject::tr( "Date and Time" ) );
2398  gGroups.insert( "String", QObject::tr( "String" ) );
2399  gGroups.insert( "Color", QObject::tr( "Color" ) );
2400  gGroups.insert( "Geometry", QObject::tr( "Geometry" ) );
2401  gGroups.insert( "Record", QObject::tr( "Record" ) );
2402  }
2403 
2404  //return the translated name for this group. If group does not
2405  //have a translated name in the gGroups hash, return the name
2406  //unchanged
2407  return gGroups.value( name, name );
2408 }