73#define TVL_True QVariant( 1 )
74#define TVL_False QVariant( 0 )
75#define TVL_Unknown QVariant()
77 static QVariant tvl2variant( TVL v )
92 static TVL getTVLValue(
const QVariant &value,
QgsExpression *parent )
99 int userType = value.userType();
100 if ( value.type() == QVariant::UserType )
102 if ( userType == qMetaTypeId< QgsGeometry>() || userType == qMetaTypeId<QgsReferencedGeometry>() )
105 const QgsGeometry geom = getGeometry( value,
nullptr );
106 return geom.
isNull() ? False : True;
108 else if ( userType == qMetaTypeId<QgsFeature>() )
112 return feat.
isValid() ? True : False;
116 if ( userType == QMetaType::Type::Int )
117 return value.toInt() != 0 ? True : False;
120 const double x = value.toDouble( &ok );
124 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to boolean" ).arg( value.toString() ) );
131 static inline bool isIntSafe(
const QVariant &v )
133 if ( v.userType() == QMetaType::Type::Int )
135 if ( v.userType() == QMetaType::Type::UInt )
137 if ( v.userType() == QMetaType::Type::LongLong )
139 if ( v.userType() == QMetaType::Type::ULongLong )
141 if ( v.userType() == QMetaType::Type::Double )
143 if ( v.userType() == QMetaType::Type::QString )
146 v.toString().toInt( &ok );
152 static inline bool isDoubleSafe(
const QVariant &v )
154 if ( v.userType() == QMetaType::Type::Double )
156 if ( v.userType() == QMetaType::Type::Int )
158 if ( v.userType() == QMetaType::Type::UInt )
160 if ( v.userType() == QMetaType::Type::LongLong )
162 if ( v.userType() == QMetaType::Type::ULongLong )
164 if ( v.userType() == QMetaType::Type::QString )
167 const double val = v.toString().toDouble( &ok );
168 ok = ok && std::isfinite( val ) && !std::isnan( val );
174 static inline bool isDateTimeSafe(
const QVariant &v )
176 return v.userType() == QMetaType::Type::QDateTime
177 || v.userType() == QMetaType::Type::QDate
178 || v.userType() == QMetaType::Type::QTime;
181 static inline bool isIntervalSafe(
const QVariant &v )
183 if ( v.userType() == qMetaTypeId<QgsInterval>() )
188 if ( v.userType() == QMetaType::Type::QString )
195 static inline bool isNull(
const QVariant &v )
200 static inline bool isList(
const QVariant &v )
202 return v.userType() == QMetaType::Type::QVariantList || v.userType() == QMetaType::Type::QStringList;
206 static QString getStringValue(
const QVariant &value,
QgsExpression * )
208 return value.toString();
218 static QByteArray getBinaryValue(
const QVariant &value,
QgsExpression *parent )
220 if ( value.userType() != QMetaType::Type::QByteArray )
226 return value.toByteArray();
229 static double getDoubleValue(
const QVariant &value,
QgsExpression *parent )
232 const double x = value.toDouble( &ok );
233 if ( !ok || std::isnan( x ) || !std::isfinite( x ) )
236 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to double" ).arg( value.toString() ) );
242 static qlonglong getIntValue(
const QVariant &value,
QgsExpression *parent )
245 const qlonglong x = value.toLongLong( &ok );
253 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to int" ).arg( value.toString() ) );
258 static int getNativeIntValue(
const QVariant &value,
QgsExpression *parent )
261 const qlonglong x = value.toLongLong( &ok );
262 if ( ok && x >= std::numeric_limits<int>::min() && x <= std::numeric_limits<int>::max() )
264 return static_cast<int>( x );
269 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to native int" ).arg( value.toString() ) );
274 static QDateTime getDateTimeValue(
const QVariant &value,
QgsExpression *parent )
276 QDateTime d = value.toDateTime();
283 const QTime t = value.toTime();
286 return QDateTime( QDate( 1, 1, 1 ), t );
290 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to DateTime" ).arg( value.toString() ) );
295 static QDate getDateValue(
const QVariant &value,
QgsExpression *parent )
297 QDate d = value.toDate();
305 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to Date" ).arg( value.toString() ) );
310 static QTime getTimeValue(
const QVariant &value,
QgsExpression *parent )
312 QTime t = value.toTime();
320 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to Time" ).arg( value.toString() ) );
325 static QColor getColorValue(
const QVariant &value,
QgsExpression *parent,
bool &isQColor );
329 if ( value.userType() == qMetaTypeId<QgsInterval>() )
333 if ( inter.isValid() )
338 if ( report_error && parent )
339 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to interval" ).arg( value.toString() ) );
348 if ( value.userType() == qMetaTypeId< QgsReferencedGeometry>() )
351 if ( value.userType() == qMetaTypeId< QgsGeometry>() )
354 if ( !tolerant && parent )
361 if ( value.userType() == qMetaTypeId<QgsFeature>() )
408 static std::unique_ptr<QgsVectorLayerFeatureSource> getFeatureSource(
const QVariant &value,
const QgsExpressionContext *context,
QgsExpression *e,
bool &foundLayer );
422 static QVariantList getListValue(
const QVariant &value,
QgsExpression *parent )
424 if ( value.userType() == QMetaType::Type::QVariantList || value.userType() == QMetaType::Type::QStringList )
426 return value.toList();
431 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to array" ).arg( value.toString() ) );
432 return QVariantList();
436 static QVariantMap getMapValue(
const QVariant &value,
QgsExpression *parent )
438 if ( value.userType() == QMetaType::Type::QVariantMap )
440 return value.toMap();
445 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to map" ).arg( value.toString() ) );
446 return QVariantMap();
456 static QString toLocalizedString(
const QVariant &value )
458 if ( value.userType() == QMetaType::Type::Int || value.userType() == QMetaType::Type::UInt || value.userType() == QMetaType::Type::LongLong || value.userType() == QMetaType::Type::ULongLong )
463 if ( value.userType() == QMetaType::Type::ULongLong )
465 res = QLocale().toString( value.toULongLong( &ok ) );
469 res = QLocale().toString( value.toLongLong( &ok ) );
478 return value.toString();
482 else if ( value.userType() == QMetaType::Type::Double || value.userType() ==
static_cast<QMetaType::Type
>( QMetaType::Float ) )
485 const QString strVal = value.toString();
486 const int dotPosition = strVal.indexOf(
'.' );
487 const int precision = dotPosition > 0 ? strVal.length() - dotPosition - 1 : 0;
488 const QString res = QLocale().toString( value.toDouble( &ok ),
'f',
precision );
496 return value.toString();
501 return value.toString();
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...