71#define TVL_True QVariant( 1 )
72#define TVL_False QVariant( 0 )
73#define TVL_Unknown QVariant()
75 static QVariant tvl2variant( TVL v )
90 static TVL getTVLValue(
const QVariant &value,
QgsExpression *parent )
97 if ( value.type() == QVariant::UserType )
99 if ( value.userType() == qMetaTypeId< QgsGeometry>() )
103 return geom.
isNull() ? False : True;
105 else if ( value.userType() == qMetaTypeId<QgsFeature>() )
109 return feat.
isValid() ? True : False;
113 if ( value.userType() == QMetaType::Type::Int )
114 return value.toInt() != 0 ? True : False;
117 const double x = value.toDouble( &ok );
120 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to boolean" ).arg( value.toString() ) );
127 static inline bool isIntSafe(
const QVariant &v )
129 if ( v.userType() == QMetaType::Type::Int )
131 if ( v.userType() == QMetaType::Type::UInt )
133 if ( v.userType() == QMetaType::Type::LongLong )
135 if ( v.userType() == QMetaType::Type::ULongLong )
137 if ( v.userType() == QMetaType::Type::Double )
139 if ( v.userType() == QMetaType::Type::QString )
142 v.toString().toInt( &ok );
148 static inline bool isDoubleSafe(
const QVariant &v )
150 if ( v.userType() == QMetaType::Type::Double )
152 if ( v.userType() == QMetaType::Type::Int )
154 if ( v.userType() == QMetaType::Type::UInt )
156 if ( v.userType() == QMetaType::Type::LongLong )
158 if ( v.userType() == QMetaType::Type::ULongLong )
160 if ( v.userType() == QMetaType::Type::QString )
163 const double val = v.toString().toDouble( &ok );
164 ok = ok && std::isfinite( val ) && !std::isnan( val );
170 static inline bool isDateTimeSafe(
const QVariant &v )
172 return v.userType() == QMetaType::Type::QDateTime
173 || v.userType() == QMetaType::Type::QDate
174 || v.userType() == QMetaType::Type::QTime;
177 static inline bool isIntervalSafe(
const QVariant &v )
179 if ( v.userType() == qMetaTypeId<QgsInterval>() )
184 if ( v.userType() == QMetaType::Type::QString )
191 static inline bool isNull(
const QVariant &v )
196 static inline bool isList(
const QVariant &v )
198 return v.userType() == QMetaType::Type::QVariantList || v.userType() == QMetaType::Type::QStringList;
202 static QString getStringValue(
const QVariant &value,
QgsExpression * )
204 return value.toString();
214 static QByteArray getBinaryValue(
const QVariant &value,
QgsExpression *parent )
216 if ( value.userType() != QMetaType::Type::QByteArray )
221 return value.toByteArray();
224 static double getDoubleValue(
const QVariant &value,
QgsExpression *parent )
227 const double x = value.toDouble( &ok );
228 if ( !ok || std::isnan( x ) || !std::isfinite( x ) )
230 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to double" ).arg( value.toString() ) );
236 static qlonglong getIntValue(
const QVariant &value,
QgsExpression *parent )
239 const qlonglong x = value.toLongLong( &ok );
246 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to int" ).arg( value.toString() ) );
251 static int getNativeIntValue(
const QVariant &value,
QgsExpression *parent )
254 const qlonglong x = value.toLongLong( &ok );
255 if ( ok && x >= std::numeric_limits<int>::min() && x <= std::numeric_limits<int>::max() )
257 return static_cast<int>( x );
261 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to native int" ).arg( value.toString() ) );
266 static QDateTime getDateTimeValue(
const QVariant &value,
QgsExpression *parent )
268 QDateTime d = value.toDateTime();
275 const QTime t = value.toTime();
278 return QDateTime( QDate( 1, 1, 1 ), t );
281 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to DateTime" ).arg( value.toString() ) );
286 static QDate getDateValue(
const QVariant &value,
QgsExpression *parent )
288 QDate d = value.toDate();
295 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to Date" ).arg( value.toString() ) );
300 static QTime getTimeValue(
const QVariant &value,
QgsExpression *parent )
302 QTime t = value.toTime();
309 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to Time" ).arg( value.toString() ) );
316 if ( value.userType() == qMetaTypeId<QgsInterval>() )
320 if ( inter.isValid() )
326 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to interval" ).arg( value.toString() ) );
335 if ( value.userType() == qMetaTypeId< QgsGeometry>() )
344 if ( value.userType() == qMetaTypeId<QgsFeature>() )
382 static std::unique_ptr<QgsVectorLayerFeatureSource> getFeatureSource(
const QVariant &value,
const QgsExpressionContext *context,
QgsExpression *e,
bool &foundLayer );
396 static QVariantList getListValue(
const QVariant &value,
QgsExpression *parent )
398 if ( value.userType() == QMetaType::Type::QVariantList || value.userType() == QMetaType::Type::QStringList )
400 return value.toList();
404 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to array" ).arg( value.toString() ) );
405 return QVariantList();
409 static QVariantMap getMapValue(
const QVariant &value,
QgsExpression *parent )
411 if ( value.userType() == QMetaType::Type::QVariantMap )
413 return value.toMap();
417 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to map" ).arg( value.toString() ) );
418 return QVariantMap();
428 static QString toLocalizedString(
const QVariant &value )
430 if ( value.userType() == QMetaType::Type::Int || value.userType() == QMetaType::Type::UInt || value.userType() == QMetaType::Type::LongLong || value.userType() == QMetaType::Type::ULongLong )
435 if ( value.userType() == QMetaType::Type::ULongLong )
437 res = QLocale().toString( value.toULongLong( &ok ) );
441 res = QLocale().toString( value.toLongLong( &ok ) );
450 return value.toString();
454 else if ( value.userType() == QMetaType::Type::Double || value.userType() ==
static_cast<QMetaType::Type
>( QMetaType::Float ) )
457 const QString strVal = value.toString();
458 const int dotPosition = strVal.indexOf(
'.' );
459 const int precision = dotPosition > 0 ? strVal.length() - dotPosition - 1 : 0;
460 const QString res = QLocale().toString( value.toDouble( &ok ),
'f',
precision );
468 return value.toString();
473 return value.toString();
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...