70#define TVL_True QVariant( 1 )
71#define TVL_False QVariant( 0 )
72#define TVL_Unknown QVariant()
74 static QVariant tvl2variant( TVL v )
89 static TVL getTVLValue(
const QVariant &value,
QgsExpression *parent )
96 if ( value.userType() == QMetaType::type(
"QgsGeometry" ) )
100 return geom.
isNull() ? False : True;
102 else if ( value.userType() == QMetaType::type(
"QgsFeature" ) )
106 return feat.
isValid() ? True : False;
109 if ( value.type() == QVariant::Int )
110 return value.toInt() != 0 ? True : False;
113 const double x = value.toDouble( &ok );
116 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to boolean" ).arg( value.toString() ) );
123 static inline bool isIntSafe(
const QVariant &v )
125 if ( v.type() == QVariant::Int )
127 if ( v.type() == QVariant::UInt )
129 if ( v.type() == QVariant::LongLong )
131 if ( v.type() == QVariant::ULongLong )
133 if ( v.type() == QVariant::Double )
135 if ( v.type() == QVariant::String )
138 v.toString().toInt( &ok );
144 static inline bool isDoubleSafe(
const QVariant &v )
146 if ( v.type() == QVariant::Double )
148 if ( v.type() == QVariant::Int )
150 if ( v.type() == QVariant::UInt )
152 if ( v.type() == QVariant::LongLong )
154 if ( v.type() == QVariant::ULongLong )
156 if ( v.type() == QVariant::String )
159 const double val = v.toString().toDouble( &ok );
160 ok = ok && std::isfinite( val ) && !std::isnan( val );
166 static inline bool isDateTimeSafe(
const QVariant &v )
168 return v.type() == QVariant::DateTime
169 || v.type() == QVariant::Date
170 || v.type() == QVariant::Time;
173 static inline bool isIntervalSafe(
const QVariant &v )
175 if ( v.userType() == QMetaType::type(
"QgsInterval" ) )
180 if ( v.type() == QVariant::String )
187 static inline bool isNull(
const QVariant &v )
192 static inline bool isList(
const QVariant &v )
194 return v.type() == QVariant::List || v.type() == QVariant::StringList;
198 static QString getStringValue(
const QVariant &value,
QgsExpression * )
200 return value.toString();
210 static QByteArray getBinaryValue(
const QVariant &value,
QgsExpression *parent )
212 if ( value.type() != QVariant::ByteArray )
217 return value.toByteArray();
220 static double getDoubleValue(
const QVariant &value,
QgsExpression *parent )
223 const double x = value.toDouble( &ok );
224 if ( !ok || std::isnan( x ) || !std::isfinite( x ) )
226 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to double" ).arg( value.toString() ) );
232 static qlonglong getIntValue(
const QVariant &value,
QgsExpression *parent )
235 const qlonglong x = value.toLongLong( &ok );
242 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to int" ).arg( value.toString() ) );
247 static int getNativeIntValue(
const QVariant &value,
QgsExpression *parent )
250 const qlonglong x = value.toLongLong( &ok );
251 if ( ok && x >= std::numeric_limits<int>::min() && x <= std::numeric_limits<int>::max() )
253 return static_cast<int>( x );
257 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to native int" ).arg( value.toString() ) );
262 static QDateTime getDateTimeValue(
const QVariant &value,
QgsExpression *parent )
264 QDateTime d = value.toDateTime();
271 const QTime t = value.toTime();
274 return QDateTime( QDate( 1, 1, 1 ), t );
277 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to DateTime" ).arg( value.toString() ) );
282 static QDate getDateValue(
const QVariant &value,
QgsExpression *parent )
284 QDate d = value.toDate();
291 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to Date" ).arg( value.toString() ) );
296 static QTime getTimeValue(
const QVariant &value,
QgsExpression *parent )
298 QTime t = value.toTime();
305 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to Time" ).arg( value.toString() ) );
312 if ( value.userType() == QMetaType::type(
"QgsInterval" ) )
316 if ( inter.isValid() )
322 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to interval" ).arg( value.toString() ) );
331 if ( value.userType() == QMetaType::type(
"QgsGeometry" ) )
340 if ( value.userType() == QMetaType::type(
"QgsFeature" ) )
366 qWarning(
"Raw map layer pointer stored in expression evaluation, switch to QgsWeakMapLayerPointer instead" );
375 ml = project->
mapLayer( value.toString() );
384 static std::unique_ptr<QgsVectorLayerFeatureSource> getFeatureSource(
const QVariant &value,
QgsExpression *e )
386 std::unique_ptr<QgsVectorLayerFeatureSource> featureSource;
388 auto getFeatureSource = [ &value, e, &featureSource ]
400 if ( QThread::currentThread() == qApp->thread() )
403 QMetaObject::invokeMethod( qApp, getFeatureSource, Qt::BlockingQueuedConnection );
405 return featureSource;
410 return qobject_cast<QgsVectorLayer *>( getMapLayer( value, e ) );
415 return qobject_cast<QgsRasterLayer *>( getMapLayer( value, e ) );
420 return qobject_cast<QgsMeshLayer *>( getMapLayer( value, e ) );
428 static QString getFilePathValue(
const QVariant &value,
QgsExpression *parent );
430 static QVariantList getListValue(
const QVariant &value,
QgsExpression *parent )
432 if ( value.type() == QVariant::List || value.type() == QVariant::StringList )
434 return value.toList();
438 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to array" ).arg( value.toString() ) );
439 return QVariantList();
443 static QVariantMap getMapValue(
const QVariant &value,
QgsExpression *parent )
445 if ( value.type() == QVariant::Map )
447 return value.toMap();
451 parent->
setEvalErrorString( QObject::tr(
"Cannot convert '%1' to map" ).arg( value.toString() ) );
452 return QVariantMap();
462 static QString toLocalizedString(
const QVariant &value )
464 if ( value.type() == QVariant::Int || value.type() == QVariant::UInt || value.type() == QVariant::LongLong || value.type() == QVariant::ULongLong )
469 if ( value.type() == QVariant::ULongLong )
471 res = QLocale().toString( value.toULongLong( &ok ) );
475 res = QLocale().toString( value.toLongLong( &ok ) );
484 return value.toString();
488 else if ( value.type() == QVariant::Double || value.type() ==
static_cast<QVariant::Type
>( QMetaType::Float ) )
491 const QString strVal = value.toString();
492 const int dotPosition = strVal.indexOf(
'.' );
493 const int precision = dotPosition > 0 ? strVal.length() - dotPosition - 1 : 0;
494 const QString res = QLocale().toString( value.toDouble( &ok ),
'f',
precision );
502 return value.toString();
507 return value.toString();
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...