72#define TVL_True QVariant( 1 )
73#define TVL_False QVariant( 0 )
74#define TVL_Unknown QVariant()
76 static QVariant tvl2variant( TVL v )
91 static TVL getTVLValue(
const QVariant &value,
QgsExpression *parent )
98 int userType = value.userType();
99 if ( value.type() == QVariant::UserType )
101 if ( userType == qMetaTypeId< QgsGeometry>() || userType == qMetaTypeId<QgsReferencedGeometry>() )
104 const QgsGeometry geom = getGeometry( value,
nullptr );
105 return geom.
isNull() ? False : True;
107 else if ( userType == qMetaTypeId<QgsFeature>() )
111 return feat.
isValid() ? True : False;
115 if ( userType == QMetaType::Type::Int )
116 return value.toInt() != 0 ? True : False;
119 const double x = value.toDouble( &ok );
123 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to boolean" ).arg( value.toString() ) );
130 static inline bool isIntSafe(
const QVariant &v )
132 if ( v.userType() == QMetaType::Type::Int )
134 if ( v.userType() == QMetaType::Type::UInt )
136 if ( v.userType() == QMetaType::Type::LongLong )
138 if ( v.userType() == QMetaType::Type::ULongLong )
140 if ( v.userType() == QMetaType::Type::Double )
142 if ( v.userType() == QMetaType::Type::QString )
145 v.toString().toInt( &ok );
151 static inline bool isDoubleSafe(
const QVariant &v )
153 if ( v.userType() == QMetaType::Type::Double )
155 if ( v.userType() == QMetaType::Type::Int )
157 if ( v.userType() == QMetaType::Type::UInt )
159 if ( v.userType() == QMetaType::Type::LongLong )
161 if ( v.userType() == QMetaType::Type::ULongLong )
163 if ( v.userType() == QMetaType::Type::QString )
166 const double val = v.toString().toDouble( &ok );
167 ok = ok && std::isfinite( val ) && !std::isnan( val );
173 static inline bool isDateTimeSafe(
const QVariant &v )
175 return v.userType() == QMetaType::Type::QDateTime
176 || v.userType() == QMetaType::Type::QDate
177 || v.userType() == QMetaType::Type::QTime;
180 static inline bool isIntervalSafe(
const QVariant &v )
182 if ( v.userType() == qMetaTypeId<QgsInterval>() )
187 if ( v.userType() == QMetaType::Type::QString )
194 static inline bool isNull(
const QVariant &v )
199 static inline bool isList(
const QVariant &v )
201 return v.userType() == QMetaType::Type::QVariantList || v.userType() == QMetaType::Type::QStringList;
205 static QString getStringValue(
const QVariant &value,
QgsExpression * )
207 return value.toString();
217 static QByteArray getBinaryValue(
const QVariant &value,
QgsExpression *parent )
219 if ( value.userType() != QMetaType::Type::QByteArray )
225 return value.toByteArray();
228 static double getDoubleValue(
const QVariant &value,
QgsExpression *parent )
231 const double x = value.toDouble( &ok );
232 if ( !ok || std::isnan( x ) || !std::isfinite( x ) )
235 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to double" ).arg( value.toString() ) );
241 static qlonglong getIntValue(
const QVariant &value,
QgsExpression *parent )
244 const qlonglong x = value.toLongLong( &ok );
252 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to int" ).arg( value.toString() ) );
257 static int getNativeIntValue(
const QVariant &value,
QgsExpression *parent )
260 const qlonglong x = value.toLongLong( &ok );
261 if ( ok && x >= std::numeric_limits<int>::min() && x <= std::numeric_limits<int>::max() )
263 return static_cast<int>( x );
268 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to native int" ).arg( value.toString() ) );
273 static QDateTime getDateTimeValue(
const QVariant &value,
QgsExpression *parent )
275 QDateTime d = value.toDateTime();
282 const QTime t = value.toTime();
285 return QDateTime( QDate( 1, 1, 1 ), t );
289 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to DateTime" ).arg( value.toString() ) );
294 static QDate getDateValue(
const QVariant &value,
QgsExpression *parent )
296 QDate d = value.toDate();
304 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to Date" ).arg( value.toString() ) );
309 static QTime getTimeValue(
const QVariant &value,
QgsExpression *parent )
311 QTime t = value.toTime();
319 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to Time" ).arg( value.toString() ) );
324 static QColor getColorValue(
const QVariant &value,
QgsExpression *parent,
bool &isQColor );
328 if ( value.userType() == qMetaTypeId<QgsInterval>() )
332 if ( inter.isValid() )
337 if ( report_error && parent )
338 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to interval" ).arg( value.toString() ) );
347 if ( value.userType() == qMetaTypeId< QgsReferencedGeometry>() )
350 if ( value.userType() == qMetaTypeId< QgsGeometry>() )
353 if ( !tolerant && parent )
360 if ( value.userType() == qMetaTypeId<QgsFeature>() )
400 static std::unique_ptr<QgsVectorLayerFeatureSource> getFeatureSource(
const QVariant &value,
const QgsExpressionContext *context,
QgsExpression *e,
bool &foundLayer );
414 static QVariantList getListValue(
const QVariant &value,
QgsExpression *parent )
416 if ( value.userType() == QMetaType::Type::QVariantList || value.userType() == QMetaType::Type::QStringList )
418 return value.toList();
423 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to array" ).arg( value.toString() ) );
424 return QVariantList();
428 static QVariantMap getMapValue(
const QVariant &value,
QgsExpression *parent )
430 if ( value.userType() == QMetaType::Type::QVariantMap )
432 return value.toMap();
437 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to map" ).arg( value.toString() ) );
438 return QVariantMap();
448 static QString toLocalizedString(
const QVariant &value )
450 if ( value.userType() == QMetaType::Type::Int || value.userType() == QMetaType::Type::UInt || value.userType() == QMetaType::Type::LongLong || value.userType() == QMetaType::Type::ULongLong )
455 if ( value.userType() == QMetaType::Type::ULongLong )
457 res = QLocale().toString( value.toULongLong( &ok ) );
461 res = QLocale().toString( value.toLongLong( &ok ) );
470 return value.toString();
474 else if ( value.userType() == QMetaType::Type::Double || value.userType() ==
static_cast<QMetaType::Type
>( QMetaType::Float ) )
477 const QString strVal = value.toString();
478 const int dotPosition = strVal.indexOf(
'.' );
479 const int precision = dotPosition > 0 ? strVal.length() - dotPosition - 1 : 0;
480 const QString res = QLocale().toString( value.toDouble( &ok ),
'f',
precision );
488 return value.toString();
493 return value.toString();
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...