88#define TVL_True QVariant( 1 )
89#define TVL_False QVariant( 0 )
90#define TVL_Unknown QVariant()
92 static QVariant tvl2variant( TVL v )
107 static TVL getTVLValue(
const QVariant &value,
QgsExpression *parent )
114 int userType = value.userType();
115 if ( value.type() == QVariant::UserType )
117 if ( userType == qMetaTypeId< QgsGeometry>() || userType == qMetaTypeId<QgsReferencedGeometry>() )
120 const QgsGeometry geom = getGeometry( value,
nullptr );
121 return geom.
isNull() ? False : True;
123 else if ( userType == qMetaTypeId<QgsFeature>() )
127 return feat.
isValid() ? True : False;
131 if ( userType == QMetaType::Type::Int )
132 return value.toInt() != 0 ? True : False;
135 const double x = value.toDouble( &ok );
139 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to boolean" ).arg( value.toString() ) );
146 static inline bool isIntSafe(
const QVariant &v )
148 if ( v.userType() == QMetaType::Type::Int )
150 if ( v.userType() == QMetaType::Type::UInt )
152 if ( v.userType() == QMetaType::Type::LongLong )
154 if ( v.userType() == QMetaType::Type::ULongLong )
156 if ( v.userType() == QMetaType::Type::Double )
158 if ( v.userType() == QMetaType::Type::QString )
161 v.toString().toInt( &ok );
167 static inline bool isDoubleSafe(
const QVariant &v )
169 if ( v.userType() == QMetaType::Type::Double )
171 if ( v.userType() == QMetaType::Type::Int )
173 if ( v.userType() == QMetaType::Type::UInt )
175 if ( v.userType() == QMetaType::Type::LongLong )
177 if ( v.userType() == QMetaType::Type::ULongLong )
179 if ( v.userType() == QMetaType::Type::QString )
182 const double val = v.toString().toDouble( &ok );
183 ok = ok && std::isfinite( val ) && !std::isnan( val );
189 static inline bool isDateTimeSafe(
const QVariant &v )
191 return v.userType() == QMetaType::Type::QDateTime || v.userType() == QMetaType::Type::QDate || v.userType() == QMetaType::Type::QTime;
194 static inline bool isIntervalSafe(
const QVariant &v )
196 if ( v.userType() == qMetaTypeId<QgsInterval>() )
201 if ( v.userType() == QMetaType::Type::QString )
208 static inline bool isNull(
const QVariant &v )
213 static inline bool isList(
const QVariant &v )
215 return v.userType() == QMetaType::Type::QVariantList || v.userType() == QMetaType::Type::QStringList;
219 static QString getStringValue(
const QVariant &value,
QgsExpression * )
221 return value.toString();
231 static QByteArray getBinaryValue(
const QVariant &value,
QgsExpression *parent )
233 if ( value.userType() != QMetaType::Type::QByteArray )
239 return value.toByteArray();
242 static double getDoubleValue(
const QVariant &value,
QgsExpression *parent )
245 const double x = value.toDouble( &ok );
246 if ( !ok || std::isnan( x ) || !std::isfinite( x ) )
249 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to double" ).arg( value.toString() ) );
255 static qlonglong getIntValue(
const QVariant &value,
QgsExpression *parent )
258 const qlonglong x = value.toLongLong( &ok );
266 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to int" ).arg( value.toString() ) );
271 static int getNativeIntValue(
const QVariant &value,
QgsExpression *parent )
274 const qlonglong x = value.toLongLong( &ok );
275 if ( ok && x >= std::numeric_limits<int>::min() && x <= std::numeric_limits<int>::max() )
277 return static_cast<int>( x );
282 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to native int" ).arg( value.toString() ) );
287 static QDateTime getDateTimeValue(
const QVariant &value,
QgsExpression *parent )
289 QDateTime d = value.toDateTime();
296 const QTime t = value.toTime();
299 return QDateTime( QDate( 1, 1, 1 ), t );
303 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to DateTime" ).arg( value.toString() ) );
308 static QDate getDateValue(
const QVariant &value,
QgsExpression *parent )
310 QDate d = value.toDate();
318 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to Date" ).arg( value.toString() ) );
323 static QTime getTimeValue(
const QVariant &value,
QgsExpression *parent )
325 QTime t = value.toTime();
333 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to Time" ).arg( value.toString() ) );
338 static QColor getColorValue(
const QVariant &value,
QgsExpression *parent,
bool &isQColor );
342 if ( value.userType() == qMetaTypeId<QgsInterval>() )
346 if ( inter.isValid() )
351 if ( report_error && parent )
352 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to interval" ).arg( value.toString() ) );
361 if ( value.userType() == qMetaTypeId< QgsReferencedGeometry>() )
364 if ( value.userType() == qMetaTypeId< QgsGeometry>() )
367 if ( !tolerant && parent )
374 if ( value.userType() == qMetaTypeId<QgsFeature>() )
394 static QTimeZone getTimeZoneValue(
const QVariant &value,
QgsExpression *parent );
423 static QVariant runMapLayerFunctionThreadSafe(
430 static std::unique_ptr<QgsVectorLayerFeatureSource> getFeatureSource(
const QVariant &value,
const QgsExpressionContext *context,
QgsExpression *e,
bool &foundLayer );
444 static QVariantList getListValue(
const QVariant &value,
QgsExpression *parent )
446 if ( value.userType() == QMetaType::Type::QVariantList || value.userType() == QMetaType::Type::QStringList )
448 return value.toList();
453 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to array" ).arg( value.toString() ) );
454 return QVariantList();
458 static QVariantMap getMapValue(
const QVariant &value,
QgsExpression *parent )
460 if ( value.userType() == QMetaType::Type::QVariantMap )
462 return value.toMap();
467 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to map" ).arg( value.toString() ) );
468 return QVariantMap();
478 static QString toLocalizedString(
const QVariant &value )
480 if ( value.userType() == QMetaType::Type::Int || value.userType() == QMetaType::Type::UInt || value.userType() == QMetaType::Type::LongLong || value.userType() == QMetaType::Type::ULongLong )
485 if ( value.userType() == QMetaType::Type::ULongLong )
487 res = QLocale().toString( value.toULongLong( &ok ) );
491 res = QLocale().toString( value.toLongLong( &ok ) );
500 return value.toString();
504 else if ( value.userType() == QMetaType::Type::Double || value.userType() ==
static_cast<QMetaType::Type
>( QMetaType::Float ) )
507 const QString strVal = value.toString();
508 const int dotPosition = strVal.indexOf(
'.' );
509 const int precision = dotPosition > 0 ? strVal.length() - dotPosition - 1 : 0;
510 const QString res = QLocale().toString( value.toDouble( &ok ),
'f', precision );
518 return value.toString();
523 return value.toString();
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...