74#define TVL_True QVariant( 1 )
75#define TVL_False QVariant( 0 )
76#define TVL_Unknown QVariant()
78 static QVariant tvl2variant( TVL v )
93 static TVL getTVLValue(
const QVariant &value,
QgsExpression *parent )
100 int userType = value.userType();
101 if ( value.type() == QVariant::UserType )
103 if ( userType == qMetaTypeId< QgsGeometry>() || userType == qMetaTypeId<QgsReferencedGeometry>() )
106 const QgsGeometry geom = getGeometry( value,
nullptr );
107 return geom.
isNull() ? False : True;
109 else if ( userType == qMetaTypeId<QgsFeature>() )
113 return feat.
isValid() ? True : False;
117 if ( userType == QMetaType::Type::Int )
118 return value.toInt() != 0 ? True : False;
121 const double x = value.toDouble( &ok );
125 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to boolean" ).arg( value.toString() ) );
132 static inline bool isIntSafe(
const QVariant &v )
134 if ( v.userType() == QMetaType::Type::Int )
136 if ( v.userType() == QMetaType::Type::UInt )
138 if ( v.userType() == QMetaType::Type::LongLong )
140 if ( v.userType() == QMetaType::Type::ULongLong )
142 if ( v.userType() == QMetaType::Type::Double )
144 if ( v.userType() == QMetaType::Type::QString )
147 v.toString().toInt( &ok );
153 static inline bool isDoubleSafe(
const QVariant &v )
155 if ( v.userType() == QMetaType::Type::Double )
157 if ( v.userType() == QMetaType::Type::Int )
159 if ( v.userType() == QMetaType::Type::UInt )
161 if ( v.userType() == QMetaType::Type::LongLong )
163 if ( v.userType() == QMetaType::Type::ULongLong )
165 if ( v.userType() == QMetaType::Type::QString )
168 const double val = v.toString().toDouble( &ok );
169 ok = ok && std::isfinite( val ) && !std::isnan( val );
175 static inline bool isDateTimeSafe(
const QVariant &v )
177 return v.userType() == QMetaType::Type::QDateTime
178 || v.userType() == QMetaType::Type::QDate
179 || v.userType() == QMetaType::Type::QTime;
182 static inline bool isIntervalSafe(
const QVariant &v )
184 if ( v.userType() == qMetaTypeId<QgsInterval>() )
189 if ( v.userType() == QMetaType::Type::QString )
196 static inline bool isNull(
const QVariant &v )
201 static inline bool isList(
const QVariant &v )
203 return v.userType() == QMetaType::Type::QVariantList || v.userType() == QMetaType::Type::QStringList;
207 static QString getStringValue(
const QVariant &value,
QgsExpression * )
209 return value.toString();
219 static QByteArray getBinaryValue(
const QVariant &value,
QgsExpression *parent )
221 if ( value.userType() != QMetaType::Type::QByteArray )
227 return value.toByteArray();
230 static double getDoubleValue(
const QVariant &value,
QgsExpression *parent )
233 const double x = value.toDouble( &ok );
234 if ( !ok || std::isnan( x ) || !std::isfinite( x ) )
237 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to double" ).arg( value.toString() ) );
243 static qlonglong getIntValue(
const QVariant &value,
QgsExpression *parent )
246 const qlonglong x = value.toLongLong( &ok );
254 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to int" ).arg( value.toString() ) );
259 static int getNativeIntValue(
const QVariant &value,
QgsExpression *parent )
262 const qlonglong x = value.toLongLong( &ok );
263 if ( ok && x >= std::numeric_limits<int>::min() && x <= std::numeric_limits<int>::max() )
265 return static_cast<int>( x );
270 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to native int" ).arg( value.toString() ) );
275 static QDateTime getDateTimeValue(
const QVariant &value,
QgsExpression *parent )
277 QDateTime d = value.toDateTime();
284 const QTime t = value.toTime();
287 return QDateTime( QDate( 1, 1, 1 ), t );
291 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to DateTime" ).arg( value.toString() ) );
296 static QDate getDateValue(
const QVariant &value,
QgsExpression *parent )
298 QDate d = value.toDate();
306 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to Date" ).arg( value.toString() ) );
311 static QTime getTimeValue(
const QVariant &value,
QgsExpression *parent )
313 QTime t = value.toTime();
321 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to Time" ).arg( value.toString() ) );
326 static QColor getColorValue(
const QVariant &value,
QgsExpression *parent,
bool &isQColor );
330 if ( value.userType() == qMetaTypeId<QgsInterval>() )
334 if ( inter.isValid() )
339 if ( report_error && parent )
340 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to interval" ).arg( value.toString() ) );
349 if ( value.userType() == qMetaTypeId< QgsReferencedGeometry>() )
352 if ( value.userType() == qMetaTypeId< QgsGeometry>() )
355 if ( !tolerant && parent )
362 if ( value.userType() == qMetaTypeId<QgsFeature>() )
382 static QTimeZone getTimeZoneValue(
const QVariant &value,
QgsExpression *parent );
416 static std::unique_ptr<QgsVectorLayerFeatureSource> getFeatureSource(
const QVariant &value,
const QgsExpressionContext *context,
QgsExpression *e,
bool &foundLayer );
430 static QVariantList getListValue(
const QVariant &value,
QgsExpression *parent )
432 if ( value.userType() == QMetaType::Type::QVariantList || value.userType() == QMetaType::Type::QStringList )
434 return value.toList();
439 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to array" ).arg( value.toString() ) );
440 return QVariantList();
444 static QVariantMap getMapValue(
const QVariant &value,
QgsExpression *parent )
446 if ( value.userType() == QMetaType::Type::QVariantMap )
448 return value.toMap();
453 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to map" ).arg( value.toString() ) );
454 return QVariantMap();
464 static QString toLocalizedString(
const QVariant &value )
466 if ( value.userType() == QMetaType::Type::Int || value.userType() == QMetaType::Type::UInt || value.userType() == QMetaType::Type::LongLong || value.userType() == QMetaType::Type::ULongLong )
471 if ( value.userType() == QMetaType::Type::ULongLong )
473 res = QLocale().toString( value.toULongLong( &ok ) );
477 res = QLocale().toString( value.toLongLong( &ok ) );
486 return value.toString();
490 else if ( value.userType() == QMetaType::Type::Double || value.userType() ==
static_cast<QMetaType::Type
>( QMetaType::Float ) )
493 const QString strVal = value.toString();
494 const int dotPosition = strVal.indexOf(
'.' );
495 const int precision = dotPosition > 0 ? strVal.length() - dotPosition - 1 : 0;
496 const QString res = QLocale().toString( value.toDouble( &ok ),
'f', precision );
504 return value.toString();
509 return value.toString();
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...