31#include <QRegularExpression>
39HelpTextHash QgsExpression::sFunctionHelpTexts;
40QRecursiveMutex QgsExpression::sFunctionsMutex;
41QMap< QString, int> QgsExpression::sFunctionIndexMap;
44HelpTextHash &QgsExpression::functionHelpTexts()
46 return sFunctionHelpTexts;
62 d->mEvalErrorString = QString();
64 d->mIsPrepared =
false;
69 if ( !d->mExp.isNull() )
77 return QStringLiteral(
"\"%1\"" ).arg( name.replace(
'\"', QLatin1String(
"\"\"" ) ) );
82 text.replace(
'\'', QLatin1String(
"''" ) );
83 text.replace(
'\\', QLatin1String(
"\\\\" ) );
84 text.replace(
'\n', QLatin1String(
"\\n" ) );
85 text.replace(
'\t', QLatin1String(
"\\t" ) );
86 return QStringLiteral(
"'%1'" ).arg( text );
91 return quotedValue( value,
static_cast<QMetaType::Type
>( value.userType() ) );
97 return QStringLiteral(
"NULL" );
101 case QMetaType::Type::Int:
102 case QMetaType::Type::LongLong:
103 case QMetaType::Type::Double:
104 return value.toString();
106 case QMetaType::Type::Bool:
107 return value.toBool() ? QStringLiteral(
"TRUE" ) : QStringLiteral(
"FALSE" );
109 case QMetaType::Type::QVariantList:
110 case QMetaType::Type::QStringList:
112 QStringList quotedValues;
113 const QVariantList values = value.toList();
114 quotedValues.reserve( values.count() );
115 for (
const QVariant &v : values )
119 return QStringLiteral(
"array( %1 )" ).arg( quotedValues.join( QLatin1String(
", " ) ) );
123 case QMetaType::Type::QString:
141 QMutexLocker locker( &sFunctionsMutex );
143 auto it = sFunctionIndexMap.constFind( name );
144 if ( it != sFunctionIndexMap.constEnd() )
151 if ( QString::compare( name, function->name(), Qt::CaseInsensitive ) == 0 )
153 sFunctionIndexMap.insert( name, i );
156 const QStringList aliases = function->aliases();
157 for (
const QString &alias : aliases )
159 if ( QString::compare( name, alias, Qt::CaseInsensitive ) == 0 )
161 sFunctionIndexMap.insert( name, i );
177 : d( new QgsExpressionPrivate )
179 d->mRootNode =
::parseExpression( expr, d->mParserErrorString, d->mParserErrors );
181 Q_ASSERT( !d->mParserErrorString.isNull() || d->mRootNode );
192 if (
this != &other )
194 if ( !d->ref.deref() )
205QgsExpression::operator QString()
const
211 : d( new QgsExpressionPrivate )
218 if ( !d->ref.deref() )
224 return ( d == other.d || d->mExp == other.d->mExp );
234 return d->mParserErrors.count() > 0;
239 return d->mParserErrorString;
244 return d->mParserErrors;
250 return QSet<QString>();
252 return d->mRootNode->referencedColumns();
258 return QSet<QString>();
260 return d->mRootNode->referencedVariables();
266 return QSet<QString>();
268 return d->mRootNode->referencedFunctions();
276 const QSet<QString> referencedFields = d->mRootNode->referencedColumns();
277 QSet<int> referencedIndexes;
279 for (
const QString &fieldName : referencedFields )
284 referencedIndexes = QSet<int>( attributesList.begin(), attributesList.end() );
290 referencedIndexes << idx;
294 return referencedIndexes;
301 return d->mRootNode->needsGeometry();
307 if ( context && ! d->mCalc )
311 d->mDaEllipsoid = context->
variable( QStringLiteral(
"project_ellipsoid" ) ).toString();
312 d->mDaCrs = std::make_unique<QgsCoordinateReferenceSystem>( context->
variable( QStringLiteral(
"_layer_crs" ) ).value<QgsCoordinateReferenceSystem>() );
313 d->mDaTransformContext = std::make_unique<QgsCoordinateTransformContext>( context->
variable( QStringLiteral(
"_project_transform_context" ) ).value<QgsCoordinateTransformContext>() );
319 QString distanceUnitsStr = context->
variable( QStringLiteral(
"project_distance_units" ) ).toString();
320 if ( ! distanceUnitsStr.isEmpty() )
327 QString areaUnitsStr = context->
variable( QStringLiteral(
"project_area_units" ) ).toString();
328 if ( ! areaUnitsStr.isEmpty() )
333void QgsExpression::detach()
339 ( void )d->ref.deref();
341 d =
new QgsExpressionPrivate( *d );
349 d->mCalc = std::shared_ptr<QgsDistanceArea>(
new QgsDistanceArea( *calc ) );
357 d->mEvalErrorString = QString();
363 d->mRootNode =
::parseExpression( d->mExp, d->mParserErrorString, d->mParserErrors );
368 d->mEvalErrorString = tr(
"No root node! Parsing failed?" );
372 initGeomCalculator( context );
373 d->mIsPrepared =
true;
374 return d->mRootNode->prepare(
this, context );
379 d->mEvalErrorString = QString();
382 d->mEvalErrorString = tr(
"No root node! Parsing failed?" );
391 d->mEvalErrorString = QString();
394 d->mEvalErrorString = tr(
"No root node! Parsing failed?" );
398 if ( ! d->mIsPrepared )
402 return d->mRootNode->eval(
this, context );
407 return !d->mEvalErrorString.isNull();
412 return d->mEvalErrorString;
417 d->mEvalErrorString =
str;
425 return d->mRootNode->dump();
430 if ( !d->mCalc && d->mDaCrs && d->mDaCrs->isValid() && d->mDaTransformContext )
434 d->mCalc->setEllipsoid( d->mDaEllipsoid.isEmpty() ?
geoNone() : d->mDaEllipsoid );
435 d->mCalc->setSourceCrs( *d->mDaCrs.get(), *d->mDaTransformContext.get() );
438 return d->mCalc.get();
443 return d->mDistanceUnit;
448 d->mDistanceUnit = unit;
466 while ( index < action.size() )
468 static const QRegularExpression sRegEx{ QStringLiteral(
"\\[%(.*?)%\\]" ), QRegularExpression::MultilineOption | QRegularExpression::DotMatchesEverythingOption };
470 const QRegularExpressionMatch match = sRegEx.match( action, index );
471 if ( !match.hasMatch() )
474 const int pos = action.indexOf( sRegEx, index );
475 const int start = index;
476 index = pos + match.capturedLength( 0 );
477 const QString toReplace = match.captured( 1 ).trimmed();
484 expr_action += QStringView {action} .mid( start, index - start );
494 QVariant result = exp.
evaluate( context );
499 expr_action += QStringView {action} .mid( start, index - start );
503 QString resultString;
505 resultString = result.toString();
509 expr_action += action.mid( start, pos - start ) + resultString;
512 expr_action += QStringView {action} .mid( index ).toString();
518 QSet<QString> variables;
520 while ( index < text.size() )
522 const thread_local QRegularExpression rx(
"\\[%([^\\]]+)%\\]" );
523 const QRegularExpressionMatch match = rx.match( text );
524 if ( !match.hasMatch() )
527 index = match.capturedStart() + match.capturedLength();
528 QString to_replace = match.captured( 1 ).trimmed();
543 double convertedValue = QLocale().toDouble( text, &ok );
546 return convertedValue;
556 QVariant result = expr.
evaluate( &context );
557 convertedValue = result.toDouble( &ok );
560 return fallbackValue;
562 return convertedValue;
567 QgsExpression::initFunctionHelp();
569 if ( !sFunctionHelpTexts.contains( name ) )
570 return tr(
"function help for %1 missing" ).arg( name );
572 const Help &f = sFunctionHelpTexts[ name ];
575 if ( f.mType == tr(
"group" ) )
577 name =
group( name );
578 name = name.toLower();
581 name = name.toHtmlEscaped();
583 QString helpContents( QStringLiteral(
"<h3>%1</h3>\n<div class=\"description\"><p>%2</p></div>" )
584 .arg( tr(
"%1 %2" ).arg( f.mType, name ),
587 for (
const HelpVariant &v : std::as_const( f.mVariants ) )
589 if ( f.mVariants.size() > 1 )
591 helpContents += QStringLiteral(
"<h3>%1</h3>\n<div class=\"description\">%2</p></div>" ).arg( v.mName, v.mDescription );
594 if ( f.mType != tr(
"group" ) && f.mType != tr(
"expression" ) )
595 helpContents += QStringLiteral(
"<h4>%1</h4>\n<div class=\"syntax\">\n" ).arg( tr(
"Syntax" ) );
597 if ( f.mType == tr(
"operator" ) )
599 if ( v.mArguments.size() == 1 )
601 helpContents += QStringLiteral(
"<code><span class=\"functionname\">%1</span> <span class=\"argument\">%2</span></code>" )
602 .arg( name, v.mArguments[0].mArg );
604 else if ( v.mArguments.size() == 2 )
606 helpContents += QStringLiteral(
"<code><span class=\"argument\">%1</span> <span class=\"functionname\">%2</span> <span class=\"argument\">%3</span></code>" )
607 .arg( v.mArguments[0].mArg, name, v.mArguments[1].mArg );
610 else if ( f.mType != tr(
"group" ) && f.mType != tr(
"expression" ) )
612 helpContents += QStringLiteral(
"<code><span class=\"functionname\">%1</span>" ).arg( name );
614 bool hasOptionalArgs =
false;
616 if ( f.mType == tr(
"function" ) && ( f.mName[0] !=
'$' || !v.mArguments.isEmpty() || v.mVariableLenArguments ) )
621 for (
const HelpArg &a : std::as_const( v.mArguments ) )
627 hasOptionalArgs =
true;
628 helpContents += QLatin1Char(
'[' );
631 helpContents += delim;
632 helpContents += QStringLiteral(
"<span class=\"argument\">%2%3</span>" ).arg(
634 a.mDefaultVal.isEmpty() ? QString() :
":=" + a.mDefaultVal
638 helpContents += QLatin1Char(
']' );
640 delim = QStringLiteral(
"," );
643 if ( v.mVariableLenArguments )
645 helpContents += QChar( 0x2026 );
651 helpContents += QLatin1String(
"</code>" );
653 if ( hasOptionalArgs )
655 helpContents += QLatin1String(
"<br/><br/>" ) + tr(
"[ ] marks optional components" );
659 if ( !v.mArguments.isEmpty() )
661 helpContents += QStringLiteral(
"<h4>%1</h4>\n<div class=\"arguments\">\n<table>" ).arg( tr(
"Arguments" ) );
663 for (
const HelpArg &a : std::as_const( v.mArguments ) )
668 helpContents += QStringLiteral(
"<tr><td class=\"argument\">%1</td><td>%2</td></tr>" ).arg( a.mArg, a.mDescription );
671 helpContents += QLatin1String(
"</table>\n</div>\n" );
674 if ( !v.mExamples.isEmpty() )
676 helpContents += QStringLiteral(
"<h4>%1</h4>\n<div class=\"examples\">\n<ul>\n" ).arg( tr(
"Examples" ) );
678 for (
const HelpExample &e : std::as_const( v.mExamples ) )
680 helpContents +=
"<li><code>" + e.mExpression +
"</code> → <code>" + e.mReturns +
"</code>";
682 if ( !e.mNote.isEmpty() )
683 helpContents += QStringLiteral(
" (%1)" ).arg( e.mNote );
685 helpContents += QLatin1String(
"</li>\n" );
688 helpContents += QLatin1String(
"</ul>\n</div>\n" );
691 if ( !v.mNotes.isEmpty() )
693 helpContents += QStringLiteral(
"<h4>%1</h4>\n<div class=\"notes\"><p>%2</p></div>\n" ).arg( tr(
"Notes" ), v.mNotes );
702 QStringList
tags = QStringList();
704 QgsExpression::initFunctionHelp();
706 if ( sFunctionHelpTexts.contains( name ) )
708 const Help &f = sFunctionHelpTexts[ name ];
710 for (
const HelpVariant &v : std::as_const( f.mVariants ) )
719void QgsExpression::initVariableHelp()
721 if ( !sVariableHelpTexts()->isEmpty() )
725 sVariableHelpTexts()->insert( QStringLiteral(
"qgis_version" ), QCoreApplication::translate(
"variable_help",
"Current QGIS version string." ) );
726 sVariableHelpTexts()->insert( QStringLiteral(
"qgis_version_no" ), QCoreApplication::translate(
"variable_help",
"Current QGIS version number." ) );
727 sVariableHelpTexts()->insert( QStringLiteral(
"qgis_release_name" ), QCoreApplication::translate(
"variable_help",
"Current QGIS release name." ) );
728 sVariableHelpTexts()->insert( QStringLiteral(
"qgis_short_version" ), QCoreApplication::translate(
"variable_help",
"Short QGIS version string." ) );
729 sVariableHelpTexts()->insert( QStringLiteral(
"qgis_os_name" ), QCoreApplication::translate(
"variable_help",
"Operating system name, e.g., 'windows', 'linux' or 'osx'." ) );
730 sVariableHelpTexts()->insert( QStringLiteral(
"qgis_platform" ), QCoreApplication::translate(
"variable_help",
"QGIS platform, e.g., 'desktop' or 'server'." ) );
731 sVariableHelpTexts()->insert( QStringLiteral(
"qgis_locale" ), QCoreApplication::translate(
"variable_help",
"Two letter identifier for current QGIS locale." ) );
732 sVariableHelpTexts()->insert( QStringLiteral(
"user_account_name" ), QCoreApplication::translate(
"variable_help",
"Current user's operating system account name." ) );
733 sVariableHelpTexts()->insert( QStringLiteral(
"user_full_name" ), QCoreApplication::translate(
"variable_help",
"Current user's operating system user name (if available)." ) );
736 sVariableHelpTexts()->insert( QStringLiteral(
"project_title" ), QCoreApplication::translate(
"variable_help",
"Title of current project." ) );
737 sVariableHelpTexts()->insert( QStringLiteral(
"project_path" ), QCoreApplication::translate(
"variable_help",
"Full path (including file name) of current project." ) );
738 sVariableHelpTexts()->insert( QStringLiteral(
"project_folder" ), QCoreApplication::translate(
"variable_help",
"Folder for current project." ) );
739 sVariableHelpTexts()->insert( QStringLiteral(
"project_filename" ), QCoreApplication::translate(
"variable_help",
"Filename of current project." ) );
740 sVariableHelpTexts()->insert( QStringLiteral(
"project_basename" ), QCoreApplication::translate(
"variable_help",
"Base name of current project's filename (without path and extension)." ) );
741 sVariableHelpTexts()->insert( QStringLiteral(
"project_home" ), QCoreApplication::translate(
"variable_help",
"Home path of current project." ) );
742 sVariableHelpTexts()->insert( QStringLiteral(
"project_crs" ), QCoreApplication::translate(
"variable_help",
"Identifier for the coordinate reference system of project (e.g., 'EPSG:4326')." ) );
743 sVariableHelpTexts()->insert( QStringLiteral(
"project_crs_definition" ), QCoreApplication::translate(
"variable_help",
"Coordinate reference system of project (full definition)." ) );
744 sVariableHelpTexts()->insert( QStringLiteral(
"project_units" ), QCoreApplication::translate(
"variable_help",
"Unit of the project's CRS." ) );
745 sVariableHelpTexts()->insert( QStringLiteral(
"project_crs_description" ), QCoreApplication::translate(
"variable_help",
"Name of the coordinate reference system of the project." ) );
746 sVariableHelpTexts()->insert( QStringLiteral(
"project_crs_acronym" ), QCoreApplication::translate(
"variable_help",
"Acronym of the coordinate reference system of the project." ) );
747 sVariableHelpTexts()->insert( QStringLiteral(
"project_crs_ellipsoid" ), QCoreApplication::translate(
"variable_help",
"Acronym of the ellipsoid of the coordinate reference system of the project." ) );
748 sVariableHelpTexts()->insert( QStringLiteral(
"project_crs_proj4" ), QCoreApplication::translate(
"variable_help",
"Proj4 definition of the coordinate reference system of the project." ) );
749 sVariableHelpTexts()->insert( QStringLiteral(
"project_crs_wkt" ), QCoreApplication::translate(
"variable_help",
"WKT definition of the coordinate reference system of the project." ) );
751 sVariableHelpTexts()->insert( QStringLiteral(
"project_vertical_crs" ), QCoreApplication::translate(
"variable_help",
"Identifier for the vertical coordinate reference system of the project (e.g., 'EPSG:5703')." ) );
752 sVariableHelpTexts()->insert( QStringLiteral(
"project_vertical_crs_definition" ), QCoreApplication::translate(
"variable_help",
"Vertical coordinate reference system of project (full definition)." ) );
753 sVariableHelpTexts()->insert( QStringLiteral(
"project_vertical_crs_description" ), QCoreApplication::translate(
"variable_help",
"Name of the vertical coordinate reference system of the project." ) );
754 sVariableHelpTexts()->insert( QStringLiteral(
"project_vertical_crs_wkt" ), QCoreApplication::translate(
"variable_help",
"WKT definition of the vertical coordinate reference system of the project." ) );
756 sVariableHelpTexts()->insert( QStringLiteral(
"project_author" ), QCoreApplication::translate(
"variable_help",
"Project author, taken from project metadata." ) );
757 sVariableHelpTexts()->insert( QStringLiteral(
"project_abstract" ), QCoreApplication::translate(
"variable_help",
"Project abstract, taken from project metadata." ) );
758 sVariableHelpTexts()->insert( QStringLiteral(
"project_creation_date" ), QCoreApplication::translate(
"variable_help",
"Project creation date, taken from project metadata." ) );
759 sVariableHelpTexts()->insert( QStringLiteral(
"project_identifier" ), QCoreApplication::translate(
"variable_help",
"Project identifier, taken from project metadata." ) );
760 sVariableHelpTexts()->insert( QStringLiteral(
"project_last_saved" ), QCoreApplication::translate(
"variable_help",
"Date/time when project was last saved." ) );
761 sVariableHelpTexts()->insert( QStringLiteral(
"project_keywords" ), QCoreApplication::translate(
"variable_help",
"Project keywords, taken from project metadata." ) );
762 sVariableHelpTexts()->insert( QStringLiteral(
"project_area_units" ), QCoreApplication::translate(
"variable_help",
"Area unit for current project, used when calculating areas of geometries." ) );
763 sVariableHelpTexts()->insert( QStringLiteral(
"project_distance_units" ), QCoreApplication::translate(
"variable_help",
"Distance unit for current project, used when calculating lengths of geometries." ) );
764 sVariableHelpTexts()->insert( QStringLiteral(
"project_ellipsoid" ), QCoreApplication::translate(
"variable_help",
"Name of ellipsoid of current project, used when calculating geodetic areas and lengths of geometries." ) );
765 sVariableHelpTexts()->insert( QStringLiteral(
"layer_ids" ), QCoreApplication::translate(
"variable_help",
"List of all map layer IDs from the current project." ) );
766 sVariableHelpTexts()->insert( QStringLiteral(
"layers" ), QCoreApplication::translate(
"variable_help",
"List of all map layers from the current project." ) );
769 sVariableHelpTexts()->insert( QStringLiteral(
"layer_name" ), QCoreApplication::translate(
"variable_help",
"Name of current layer." ) );
770 sVariableHelpTexts()->insert( QStringLiteral(
"layer_id" ), QCoreApplication::translate(
"variable_help",
"ID of current layer." ) );
771 sVariableHelpTexts()->insert( QStringLiteral(
"layer_crs" ), QCoreApplication::translate(
"variable_help",
"CRS Authority ID of current layer." ) );
772 sVariableHelpTexts()->insert( QStringLiteral(
"layer" ), QCoreApplication::translate(
"variable_help",
"The current layer." ) );
773 sVariableHelpTexts()->insert( QStringLiteral(
"layer_crs_ellipsoid" ), QCoreApplication::translate(
"variable_help",
"Ellipsoid acronym of current layer CRS." ) );
776 sVariableHelpTexts()->insert( QStringLiteral(
"feature" ), QCoreApplication::translate(
"variable_help",
"The current feature being evaluated. This can be used with the 'attribute' function to evaluate attribute values from the current feature." ) );
777 sVariableHelpTexts()->insert( QStringLiteral(
"id" ), QCoreApplication::translate(
"variable_help",
"The ID of the current feature being evaluated." ) );
778 sVariableHelpTexts()->insert( QStringLiteral(
"geometry" ), QCoreApplication::translate(
"variable_help",
"The geometry of the current feature being evaluated." ) );
781 sVariableHelpTexts()->insert( QStringLiteral(
"layout_name" ), QCoreApplication::translate(
"variable_help",
"Name of composition." ) );
782 sVariableHelpTexts()->insert( QStringLiteral(
"layout_numpages" ), QCoreApplication::translate(
"variable_help",
"Number of pages in composition." ) );
783 sVariableHelpTexts()->insert( QStringLiteral(
"layout_page" ), QCoreApplication::translate(
"variable_help",
"Current page number in composition." ) );
784 sVariableHelpTexts()->insert( QStringLiteral(
"layout_pageheight" ), QCoreApplication::translate(
"variable_help",
"Composition page height in mm (or specified custom units)." ) );
785 sVariableHelpTexts()->insert( QStringLiteral(
"layout_pagewidth" ), QCoreApplication::translate(
"variable_help",
"Composition page width in mm (or specified custom units)." ) );
786 sVariableHelpTexts()->insert( QStringLiteral(
"layout_pageoffsets" ), QCoreApplication::translate(
"variable_help",
"Array of Y coordinate of the top of each page." ) );
787 sVariableHelpTexts()->insert( QStringLiteral(
"layout_dpi" ), QCoreApplication::translate(
"variable_help",
"Composition resolution (DPI)." ) );
790 sVariableHelpTexts()->insert( QStringLiteral(
"atlas_layerid" ), QCoreApplication::translate(
"variable_help",
"Current atlas coverage layer ID." ) );
791 sVariableHelpTexts()->insert( QStringLiteral(
"atlas_layername" ), QCoreApplication::translate(
"variable_help",
"Current atlas coverage layer name." ) );
792 sVariableHelpTexts()->insert( QStringLiteral(
"atlas_totalfeatures" ), QCoreApplication::translate(
"variable_help",
"Total number of features in atlas." ) );
793 sVariableHelpTexts()->insert( QStringLiteral(
"atlas_featurenumber" ), QCoreApplication::translate(
"variable_help",
"Current atlas feature number." ) );
794 sVariableHelpTexts()->insert( QStringLiteral(
"atlas_filename" ), QCoreApplication::translate(
"variable_help",
"Current atlas file name." ) );
795 sVariableHelpTexts()->insert( QStringLiteral(
"atlas_pagename" ), QCoreApplication::translate(
"variable_help",
"Current atlas page name." ) );
796 sVariableHelpTexts()->insert( QStringLiteral(
"atlas_feature" ), QCoreApplication::translate(
"variable_help",
"Current atlas feature (as feature object)." ) );
797 sVariableHelpTexts()->insert( QStringLiteral(
"atlas_featureid" ), QCoreApplication::translate(
"variable_help",
"Current atlas feature ID." ) );
798 sVariableHelpTexts()->insert( QStringLiteral(
"atlas_geometry" ), QCoreApplication::translate(
"variable_help",
"Current atlas feature geometry." ) );
801 sVariableHelpTexts()->insert( QStringLiteral(
"item_id" ), QCoreApplication::translate(
"variable_help",
"Layout item user-assigned ID (not necessarily unique)." ) );
802 sVariableHelpTexts()->insert( QStringLiteral(
"item_uuid" ), QCoreApplication::translate(
"variable_help",
"layout item unique ID." ) );
803 sVariableHelpTexts()->insert( QStringLiteral(
"item_left" ), QCoreApplication::translate(
"variable_help",
"Left position of layout item (in mm)." ) );
804 sVariableHelpTexts()->insert( QStringLiteral(
"item_top" ), QCoreApplication::translate(
"variable_help",
"Top position of layout item (in mm)." ) );
805 sVariableHelpTexts()->insert( QStringLiteral(
"item_width" ), QCoreApplication::translate(
"variable_help",
"Width of layout item (in mm)." ) );
806 sVariableHelpTexts()->insert( QStringLiteral(
"item_height" ), QCoreApplication::translate(
"variable_help",
"Height of layout item (in mm)." ) );
809 sVariableHelpTexts()->insert( QStringLiteral(
"map_id" ), QCoreApplication::translate(
"variable_help",
"ID of current map destination. This will be 'canvas' for canvas renders, and the item ID for layout map renders." ) );
810 sVariableHelpTexts()->insert( QStringLiteral(
"map_rotation" ), QCoreApplication::translate(
"variable_help",
"Current rotation of map." ) );
811 sVariableHelpTexts()->insert( QStringLiteral(
"map_scale" ), QCoreApplication::translate(
"variable_help",
"Current scale of map." ) );
812 sVariableHelpTexts()->insert( QStringLiteral(
"map_extent" ), QCoreApplication::translate(
"variable_help",
"Geometry representing the current extent of the map." ) );
813 sVariableHelpTexts()->insert( QStringLiteral(
"map_extent_center" ), QCoreApplication::translate(
"variable_help",
"Center of map." ) );
814 sVariableHelpTexts()->insert( QStringLiteral(
"map_extent_width" ), QCoreApplication::translate(
"variable_help",
"Width of map." ) );
815 sVariableHelpTexts()->insert( QStringLiteral(
"map_extent_height" ), QCoreApplication::translate(
"variable_help",
"Height of map." ) );
816 sVariableHelpTexts()->insert( QStringLiteral(
"map_crs" ), QCoreApplication::translate(
"variable_help",
"Coordinate reference system of map (e.g., 'EPSG:4326')." ) );
817 sVariableHelpTexts()->insert( QStringLiteral(
"map_crs_description" ), QCoreApplication::translate(
"variable_help",
"Name of the coordinate reference system of the map." ) );
818 sVariableHelpTexts()->insert( QStringLiteral(
"map_units" ), QCoreApplication::translate(
"variable_help",
"Units for map measurements." ) );
819 sVariableHelpTexts()->insert( QStringLiteral(
"map_crs_definition" ), QCoreApplication::translate(
"variable_help",
"Coordinate reference system of the map (full definition)." ) );
820 sVariableHelpTexts()->insert( QStringLiteral(
"map_crs_acronym" ), QCoreApplication::translate(
"variable_help",
"Acronym of the coordinate reference system of the map." ) );
821 sVariableHelpTexts()->insert( QStringLiteral(
"map_crs_projection" ), QCoreApplication::translate(
"variable_help",
"Projection method used by the coordinate reference system of the map." ) );
822 sVariableHelpTexts()->insert( QStringLiteral(
"map_crs_ellipsoid" ), QCoreApplication::translate(
"variable_help",
"Acronym of the ellipsoid of the coordinate reference system of the map." ) );
823 sVariableHelpTexts()->insert( QStringLiteral(
"map_crs_proj4" ), QCoreApplication::translate(
"variable_help",
"Proj4 definition of the coordinate reference system of the map." ) );
824 sVariableHelpTexts()->insert( QStringLiteral(
"map_crs_wkt" ), QCoreApplication::translate(
"variable_help",
"WKT definition of the coordinate reference system of the map." ) );
825 sVariableHelpTexts()->insert( QStringLiteral(
"map_layer_ids" ), QCoreApplication::translate(
"variable_help",
"List of map layer IDs visible in the map." ) );
826 sVariableHelpTexts()->insert( QStringLiteral(
"map_layers" ), QCoreApplication::translate(
"variable_help",
"List of map layers visible in the map." ) );
828 sVariableHelpTexts()->insert( QStringLiteral(
"map_start_time" ), QCoreApplication::translate(
"variable_help",
"Start of the map's temporal time range (as a datetime value)" ) );
829 sVariableHelpTexts()->insert( QStringLiteral(
"map_end_time" ), QCoreApplication::translate(
"variable_help",
"End of the map's temporal time range (as a datetime value)" ) );
830 sVariableHelpTexts()->insert( QStringLiteral(
"map_interval" ), QCoreApplication::translate(
"variable_help",
"Duration of the map's temporal time range (as an interval value)" ) );
831 sVariableHelpTexts()->insert( QStringLiteral(
"map_z_range_lower" ), QCoreApplication::translate(
"variable_help",
"Lower elevation of the map's elevation range" ) );
832 sVariableHelpTexts()->insert( QStringLiteral(
"map_z_range_upper" ), QCoreApplication::translate(
"variable_help",
"Upper elevation of the map's elevation range" ) );
834 sVariableHelpTexts()->insert( QStringLiteral(
"frame_rate" ), QCoreApplication::translate(
"variable_help",
"Number of frames per second during animation playback" ) );
835 sVariableHelpTexts()->insert( QStringLiteral(
"frame_number" ), QCoreApplication::translate(
"variable_help",
"Current frame number during animation playback" ) );
836 sVariableHelpTexts()->insert( QStringLiteral(
"frame_duration" ), QCoreApplication::translate(
"variable_help",
"Temporal duration of each animation frame (as an interval value)" ) );
837 sVariableHelpTexts()->insert( QStringLiteral(
"frame_timestep" ), QCoreApplication::translate(
"variable_help",
"Frame time step during animation playback" ) );
838 sVariableHelpTexts()->insert( QStringLiteral(
"frame_timestep_unit" ), QCoreApplication::translate(
"variable_help",
"Unit value of the frame time step during animation playback" ) );
839 sVariableHelpTexts()->insert( QStringLiteral(
"frame_timestep_units" ), QCoreApplication::translate(
"variable_help",
"String representation of the frame time step unit during animation playback" ) );
840 sVariableHelpTexts()->insert( QStringLiteral(
"animation_start_time" ), QCoreApplication::translate(
"variable_help",
"Start of the animation's overall temporal time range (as a datetime value)" ) );
841 sVariableHelpTexts()->insert( QStringLiteral(
"animation_end_time" ), QCoreApplication::translate(
"variable_help",
"End of the animation's overall temporal time range (as a datetime value)" ) );
842 sVariableHelpTexts()->insert( QStringLiteral(
"animation_interval" ), QCoreApplication::translate(
"variable_help",
"Duration of the animation's overall temporal time range (as an interval value)" ) );
845 sVariableHelpTexts()->insert( QStringLiteral(
"zoom_level" ), QCoreApplication::translate(
"variable_help",
"Vector tile zoom level of the map that is being rendered (derived from the current map scale). Normally in interval [0, 20]." ) );
846 sVariableHelpTexts()->insert( QStringLiteral(
"vector_tile_zoom" ), QCoreApplication::translate(
"variable_help",
"Exact vector tile zoom level of the map that is being rendered (derived from the current map scale). Normally in interval [0, 20]. Unlike @zoom_level, this variable is a floating point value which can be used to interpolate values between two integer zoom levels." ) );
848 sVariableHelpTexts()->insert( QStringLiteral(
"row_number" ), QCoreApplication::translate(
"variable_help",
"Stores the number of the current row." ) );
849 sVariableHelpTexts()->insert( QStringLiteral(
"grid_number" ), QCoreApplication::translate(
"variable_help",
"Current grid annotation value." ) );
850 sVariableHelpTexts()->insert( QStringLiteral(
"grid_axis" ), QCoreApplication::translate(
"variable_help",
"Current grid annotation axis (e.g., 'x' for longitude, 'y' for latitude)." ) );
851 sVariableHelpTexts()->insert( QStringLiteral(
"column_number" ), QCoreApplication::translate(
"variable_help",
"Stores the number of the current column." ) );
854 sVariableHelpTexts()->insert( QStringLiteral(
"canvas_cursor_point" ), QCoreApplication::translate(
"variable_help",
"Last cursor position on the canvas in the project's geographical coordinates." ) );
855 sVariableHelpTexts()->insert( QStringLiteral(
"layer_cursor_point" ), QCoreApplication::translate(
"variable_help",
"Last cursor position on the canvas in the current layers's geographical coordinates. QGIS Server: When used in a maptip expression for a raster layer, this variable holds the GetFeatureInfo position." ) );
858 sVariableHelpTexts()->insert( QStringLiteral(
"legend_title" ), QCoreApplication::translate(
"variable_help",
"Title of the legend." ) );
859 sVariableHelpTexts()->insert( QStringLiteral(
"legend_column_count" ), QCoreApplication::translate(
"variable_help",
"Number of column in the legend." ) );
860 sVariableHelpTexts()->insert( QStringLiteral(
"legend_split_layers" ), QCoreApplication::translate(
"variable_help",
"Boolean indicating if layers can be split in the legend." ) );
861 sVariableHelpTexts()->insert( QStringLiteral(
"legend_wrap_string" ), QCoreApplication::translate(
"variable_help",
"Characters used to wrap the legend text." ) );
862 sVariableHelpTexts()->insert( QStringLiteral(
"legend_filter_by_map" ), QCoreApplication::translate(
"variable_help",
"Boolean indicating if the content of the legend is filtered by the map." ) );
863 sVariableHelpTexts()->insert( QStringLiteral(
"legend_filter_out_atlas" ), QCoreApplication::translate(
"variable_help",
"Boolean indicating if the Atlas is filtered out of the legend." ) );
866 sVariableHelpTexts()->insert( QStringLiteral(
"scale_value" ), QCoreApplication::translate(
"variable_help",
"Current scale bar distance value." ) );
869 sVariableHelpTexts()->insert( QStringLiteral(
"snapping_results" ), QCoreApplication::translate(
"variable_help",
870 "<p>An array with an item for each snapped point.</p>"
871 "<p>Each item is a map with the following keys:</p>"
873 "<dt>valid</dt><dd>Boolean that indicates if the snapping result is valid</dd>"
874 "<dt>layer</dt><dd>The layer on which the snapped feature is</dd>"
875 "<dt>feature_id</dt><dd>The feature id of the snapped feature</dd>"
876 "<dt>vertex_index</dt><dd>The index of the snapped vertex</dd>"
877 "<dt>distance</dt><dd>The distance between the mouse cursor and the snapped point at the time of snapping</dd>"
882 sVariableHelpTexts()->insert( QStringLiteral(
"geometry_part_count" ), QCoreApplication::translate(
"variable_help",
"Number of parts in rendered feature's geometry." ) );
883 sVariableHelpTexts()->insert( QStringLiteral(
"geometry_part_num" ), QCoreApplication::translate(
"variable_help",
"Current geometry part number for feature being rendered." ) );
884 sVariableHelpTexts()->insert( QStringLiteral(
"geometry_ring_num" ), QCoreApplication::translate(
"variable_help",
"Current geometry ring number for feature being rendered (for polygon features only). The exterior ring has a value of 0." ) );
885 sVariableHelpTexts()->insert( QStringLiteral(
"geometry_point_count" ), QCoreApplication::translate(
"variable_help",
"Number of points in the rendered geometry's part. It is only meaningful for line geometries and for symbol layers that set this variable." ) );
886 sVariableHelpTexts()->insert( QStringLiteral(
"geometry_point_num" ), QCoreApplication::translate(
"variable_help",
"Current point number in the rendered geometry's part. It is only meaningful for line geometries and for symbol layers that set this variable." ) );
888 sVariableHelpTexts()->insert( QStringLiteral(
"symbol_color" ), QCoreApplication::translate(
"symbol_color",
"Color of symbol used to render the feature." ) );
889 sVariableHelpTexts()->insert( QStringLiteral(
"symbol_angle" ), QCoreApplication::translate(
"symbol_angle",
"Angle of symbol used to render the feature (valid for marker symbols only)." ) );
890 sVariableHelpTexts()->insert( QStringLiteral(
"symbol_layer_count" ), QCoreApplication::translate(
"symbol_layer_count",
"Total number of symbol layers in the symbol." ) );
891 sVariableHelpTexts()->insert( QStringLiteral(
"symbol_layer_index" ), QCoreApplication::translate(
"symbol_layer_index",
"Current symbol layer index." ) );
892 sVariableHelpTexts()->insert( QStringLiteral(
"symbol_marker_row" ), QCoreApplication::translate(
"symbol_marker_row",
"Row number for marker (valid for point pattern fills only)." ) );
893 sVariableHelpTexts()->insert( QStringLiteral(
"symbol_marker_column" ), QCoreApplication::translate(
"symbol_marker_column",
"Column number for marker (valid for point pattern fills only)." ) );
894 sVariableHelpTexts()->insert( QStringLiteral(
"symbol_frame" ), QCoreApplication::translate(
"symbol_frame",
"Frame number (for animated symbols only)." ) );
896 sVariableHelpTexts()->insert( QStringLiteral(
"symbol_label" ), QCoreApplication::translate(
"symbol_label",
"Label for the symbol (either a user defined label or the default autogenerated label)." ) );
897 sVariableHelpTexts()->insert( QStringLiteral(
"symbol_id" ), QCoreApplication::translate(
"symbol_id",
"Internal ID of the symbol." ) );
898 sVariableHelpTexts()->insert( QStringLiteral(
"symbol_count" ), QCoreApplication::translate(
"symbol_count",
"Total number of features represented by the symbol." ) );
901 sVariableHelpTexts()->insert( QStringLiteral(
"cluster_color" ), QCoreApplication::translate(
"cluster_color",
"Color of symbols within a cluster, or NULL if symbols have mixed colors." ) );
902 sVariableHelpTexts()->insert( QStringLiteral(
"cluster_size" ), QCoreApplication::translate(
"cluster_size",
"Number of symbols contained within a cluster." ) );
905 sVariableHelpTexts()->insert( QStringLiteral(
"algorithm_id" ), QCoreApplication::translate(
"algorithm_id",
"Unique ID for algorithm." ) );
906 sVariableHelpTexts()->insert( QStringLiteral(
"model_path" ), QCoreApplication::translate(
"variable_help",
"Full path (including file name) of current model (or project path if model is embedded in a project)." ) );
907 sVariableHelpTexts()->insert( QStringLiteral(
"model_folder" ), QCoreApplication::translate(
"variable_help",
"Folder containing current model (or project folder if model is embedded in a project)." ) );
908 sVariableHelpTexts()->insert( QStringLiteral(
"model_name" ), QCoreApplication::translate(
"variable_help",
"Name of current model." ) );
909 sVariableHelpTexts()->insert( QStringLiteral(
"model_group" ), QCoreApplication::translate(
"variable_help",
"Group for current model." ) );
910 sVariableHelpTexts()->insert( QStringLiteral(
"fullextent_minx" ), QCoreApplication::translate(
"fullextent_minx",
"Minimum x-value from full canvas extent (including all layers)." ) );
911 sVariableHelpTexts()->insert( QStringLiteral(
"fullextent_miny" ), QCoreApplication::translate(
"fullextent_miny",
"Minimum y-value from full canvas extent (including all layers)." ) );
912 sVariableHelpTexts()->insert( QStringLiteral(
"fullextent_maxx" ), QCoreApplication::translate(
"fullextent_maxx",
"Maximum x-value from full canvas extent (including all layers)." ) );
913 sVariableHelpTexts()->insert( QStringLiteral(
"fullextent_maxy" ), QCoreApplication::translate(
"fullextent_maxy",
"Maximum y-value from full canvas extent (including all layers)." ) );
916 sVariableHelpTexts()->insert( QStringLiteral(
"notification_message" ), QCoreApplication::translate(
"notification_message",
"Content of the notification message sent by the provider (available only for actions triggered by provider notifications)." ) );
919 sVariableHelpTexts()->insert( QStringLiteral(
"current_geometry" ), QCoreApplication::translate(
"current_geometry",
"Represents the geometry of the feature currently being edited in the form or the table row. Can be used in a form/row context to filter the related features." ) );
920 sVariableHelpTexts()->insert( QStringLiteral(
"current_feature" ), QCoreApplication::translate(
"current_feature",
"Represents the feature currently being edited in the form or the table row. Can be used in a form/row context to filter the related features." ) );
923 sVariableHelpTexts()->insert( QStringLiteral(
"current_parent_geometry" ), QCoreApplication::translate(
"current_parent_geometry",
924 "Only usable in an embedded form context, "
925 "represents the geometry of the feature currently being edited in the parent form.\n"
926 "Can be used in a form/row context to filter the related features using a value "
927 "from the feature currently edited in the parent form, to make sure that the filter "
928 "still works with standalone forms it is recommended to wrap this variable in a "
930 sVariableHelpTexts()->insert( QStringLiteral(
"current_parent_feature" ), QCoreApplication::translate(
"current_parent_feature",
931 "Only usable in an embedded form context, "
932 "represents the feature currently being edited in the parent form.\n"
933 "Can be used in a form/row context to filter the related features using a value "
934 "from the feature currently edited in the parent form, to make sure that the filter "
935 "still works with standalone forms it is recommended to wrap this variable in a "
939 sVariableHelpTexts()->insert( QStringLiteral(
"form_mode" ), QCoreApplication::translate(
"form_mode",
"What the form is used for, like AddFeatureMode, SingleEditMode, MultiEditMode, SearchMode, AggregateSearchMode or IdentifyMode as string." ) );
942 sVariableHelpTexts()->insert( QStringLiteral(
"plot_axis" ), QCoreApplication::translate(
"plot_axis",
"The associated plot axis, e.g. 'x' or 'y'." ) );
943 sVariableHelpTexts()->insert( QStringLiteral(
"plot_axis_value" ), QCoreApplication::translate(
"plot_axis_value",
"The current value for the plot axis." ) );
949 if ( sVariableHelpTexts()->contains( name ) )
953 sVariableHelpTexts()->insert( name, description );
959 QgsExpression::initVariableHelp();
960 return sVariableHelpTexts()->value( variableName, QString() );
965 QString text = !description.isEmpty() ? QStringLiteral(
"<p>%1</p>" ).arg( description ) : QString();
969 if ( !value.isValid() )
971 valueString = QCoreApplication::translate(
"variable_help",
"not set" );
977 text.append( QCoreApplication::translate(
"variable_help",
"<p>Current value: %1</p>" ).arg( valueString ) );
984 if ( sGroups()->isEmpty() )
986 sGroups()->insert( QStringLiteral(
"Aggregates" ), tr(
"Aggregates" ) );
987 sGroups()->insert( QStringLiteral(
"Arrays" ), tr(
"Arrays" ) );
988 sGroups()->insert( QStringLiteral(
"Color" ), tr(
"Color" ) );
989 sGroups()->insert( QStringLiteral(
"Conditionals" ), tr(
"Conditionals" ) );
990 sGroups()->insert( QStringLiteral(
"Conversions" ), tr(
"Conversions" ) );
991 sGroups()->insert( QStringLiteral(
"Date and Time" ), tr(
"Date and Time" ) );
992 sGroups()->insert( QStringLiteral(
"Fields and Values" ), tr(
"Fields and Values" ) );
993 sGroups()->insert( QStringLiteral(
"Files and Paths" ), tr(
"Files and Paths" ) );
994 sGroups()->insert( QStringLiteral(
"Fuzzy Matching" ), tr(
"Fuzzy Matching" ) );
995 sGroups()->insert( QStringLiteral(
"General" ), tr(
"General" ) );
996 sGroups()->insert( QStringLiteral(
"GeometryGroup" ), tr(
"Geometry" ) );
997 sGroups()->insert( QStringLiteral(
"Map Layers" ), tr(
"Map Layers" ) );
998 sGroups()->insert( QStringLiteral(
"Maps" ), tr(
"Maps" ) );
999 sGroups()->insert( QStringLiteral(
"Math" ), tr(
"Math" ) );
1000 sGroups()->insert( QStringLiteral(
"Operators" ), tr(
"Operators" ) );
1001 sGroups()->insert( QStringLiteral(
"Rasters" ), tr(
"Rasters" ) );
1002 sGroups()->insert( QStringLiteral(
"Record and Attributes" ), tr(
"Record and Attributes" ) );
1003 sGroups()->insert( QStringLiteral(
"String" ), tr(
"String" ) );
1004 sGroups()->insert( QStringLiteral(
"Variables" ), tr(
"Variables" ) );
1005 sGroups()->insert( QStringLiteral(
"Recent (%1)" ), tr(
"Recent (%1)" ) );
1006 sGroups()->insert( QStringLiteral(
"UserGroup" ), tr(
"User expressions" ) );
1012 return sGroups()->value( name, name );
1017 const QString startToken = htmlOutput ? QStringLiteral(
"<i><" ) : QStringLiteral(
"<" );
1018 const QString endToken = htmlOutput ? QStringLiteral(
"></i>" ) : QStringLiteral(
">" );
1020 if ( value.userType() == qMetaTypeId< QgsGeometry>() )
1025 return startToken + tr(
"empty geometry" ) + endToken;
1032 return startToken + tr(
"map layer" ) + endToken;
1034 else if ( !value.isValid() )
1036 return htmlOutput ? tr(
"<i>NULL</i>" ) : QString();
1038 else if ( value.userType() == qMetaTypeId< QgsFeature>() )
1042 return startToken + tr(
"feature: %1" ).arg( feat.
id() ) + endToken;
1044 else if ( value.userType() == qMetaTypeId< QgsInterval>() )
1047 if ( interval.
days() > 1 )
1049 return startToken + tr(
"interval: %1 days" ).arg( interval.
days() ) + endToken;
1051 else if ( interval.
hours() > 1 )
1053 return startToken + tr(
"interval: %1 hours" ).arg( interval.
hours() ) + endToken;
1055 else if ( interval.
minutes() > 1 )
1057 return startToken + tr(
"interval: %1 minutes" ).arg( interval.
minutes() ) + endToken;
1061 return startToken + tr(
"interval: %1 seconds" ).arg( interval.
seconds() ) + endToken;
1064 else if ( value.userType() == qMetaTypeId< QgsGradientColorRamp>() )
1066 return startToken + tr(
"gradient ramp" ) + endToken;
1068 else if ( value.userType() == QMetaType::Type::QDate )
1070 const QDate dt = value.toDate();
1071 return startToken + tr(
"date: %1" ).arg( dt.toString( QStringLiteral(
"yyyy-MM-dd" ) ) ) + endToken;
1073 else if ( value.userType() == QMetaType::Type::QTime )
1075 const QTime tm = value.toTime();
1076 return startToken + tr(
"time: %1" ).arg( tm.toString( QStringLiteral(
"hh:mm:ss" ) ) ) + endToken;
1078 else if ( value.userType() == QMetaType::Type::QDateTime )
1080 const QDateTime dt = value.toDateTime();
1081 return startToken + tr(
"datetime: %1 (%2)" ).arg( dt.toString( QStringLiteral(
"yyyy-MM-dd hh:mm:ss" ) ), dt.timeZoneAbbreviation() ) + endToken;
1083 else if ( value.userType() == QMetaType::Type::QString )
1085 const QString previewString = value.toString();
1086 if ( previewString.length() > maximumPreviewLength + 3 )
1088 return tr(
"'%1…'" ).arg( previewString.left( maximumPreviewLength ) );
1092 return '\'' + previewString +
'\'';
1095 else if ( value.userType() == QMetaType::Type::QVariantMap )
1097 QString mapStr = QStringLiteral(
"{" );
1098 const QVariantMap map = value.toMap();
1100 for ( QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
1102 mapStr.append( separator );
1103 if ( separator.isEmpty() )
1104 separator = QStringLiteral(
"," );
1106 mapStr.append( QStringLiteral(
" '%1': %2" ).arg( it.key(),
formatPreviewString( it.value(), htmlOutput ) ) );
1107 if ( mapStr.length() > maximumPreviewLength - 3 )
1109 mapStr = tr(
"%1…" ).arg( mapStr.left( maximumPreviewLength - 2 ) );
1114 mapStr += QLatin1Char(
' ' );
1115 mapStr += QLatin1Char(
'}' );
1118 else if ( value.userType() == QMetaType::Type::QVariantList || value.userType() == QMetaType::Type::QStringList )
1120 QString listStr = QStringLiteral(
"[" );
1121 const QVariantList list = value.toList();
1123 for (
const QVariant &arrayValue : list )
1125 listStr.append( separator );
1126 if ( separator.isEmpty() )
1127 separator = QStringLiteral(
"," );
1129 listStr.append(
" " );
1131 if ( listStr.length() > maximumPreviewLength - 3 )
1133 listStr = QString( tr(
"%1…" ) ).arg( listStr.left( maximumPreviewLength - 2 ) );
1137 if ( !list.empty() )
1138 listStr += QLatin1Char(
' ' );
1139 listStr += QLatin1Char(
']' );
1142 else if ( value.userType() == QMetaType::Type::Int ||
1143 value.userType() == QMetaType::Type::UInt ||
1144 value.userType() == QMetaType::Type::LongLong ||
1145 value.userType() == QMetaType::Type::ULongLong ||
1146 value.userType() == QMetaType::Type::Double ||
1148 value.userType() ==
static_cast<QMetaType::Type
>( QMetaType::Float ) )
1150 return QgsExpressionUtils::toLocalizedString( value );
1154 QString
str { value.toString() };
1155 if (
str.length() > maximumPreviewLength - 3 )
1157 str = tr(
"%1…" ).arg(
str.left( maximumPreviewLength - 2 ) );
1168 expr = QStringLiteral(
"%1 IS NULL" ).arg(
quotedColumnRef( fieldName ) );
1169 else if ( fieldType == QMetaType::Type::UnknownType )
1195 if ( columnRef && literal )
1197 field = columnRef->
name();
1198 value = literal->
value();
1208 if ( expressions.empty() )
1214 for (
const QString &
expression : expressions )
1225 else if ( field != inField )
1241 if ( inOp->isNotIn() )
1250 inField = columnRef->
name();
1253 else if ( columnRef->
name() != inField )
1260 const QList<QgsExpressionNode *>
nodes = nodeList->list();
1278 QStringList orParts;
1283 orParts.append( collectOrs( leftOrOp->opLeft(), leftOrOp->opRight() ) );
1287 orParts.append( leftOrOp->dump() );
1292 orParts.append( leftInOp->dump() );
1303 orParts.append( collectOrs( rightOrOp->opLeft(), rightOrOp->opRight() ) );
1307 orParts.append( rightOrOp->dump() );
1312 orParts.append( rightInOp->dump() );
1325 const QStringList orParts = collectOrs( orOp->opLeft(), orOp->opRight() );
1326 if ( orParts.isEmpty() )
1332 QString orPartsResult;
1337 if ( ! inExp.rootNode() )
1349 const QString innerInfield { inOpInner->node()->
referencedColumns().values().first() };
1353 inField = innerInfield;
1357 if ( innerInfield != inField )
1363 const auto constInnerValuesList { inOpInner->list()->list() };
1364 for (
const auto &innerInValueNode : std::as_const( constInnerValuesList ) )
1366 values.append( innerInValueNode->dump() );
1393 result = QStringLiteral(
"%1 IN (%2)" ).arg(
quotedColumnRef( inField ), values.join(
',' ) );
1399 return d->mRootNode;
1414 if ( attrIndex >= 0 )
1421 const QString fieldName = qgis::down_cast<const QgsExpressionNodeColumnRef *>( candidate.
rootNode() )->name();
1433 if ( !
expression.contains(
'\"' ) && fieldIndex != -1 )
1446 if ( !d->mRootNode )
1447 return QList<const QgsExpressionNode *>();
1449 return d->mRootNode->nodes();
DistanceUnit
Units of distance.
@ Unknown
Unknown distance unit.
@ Unknown
Unknown areal unit.
Qgis::WkbType wkbType() const
Returns the WKB type of the geometry.
A general purpose distance and area calculator, capable of performing ellipsoid based calculations.
static QgsExpressionContextScope * projectScope(const QgsProject *project)
Creates a new scope which contains variables and functions relating to a QGIS project.
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
QVariant variable(const QString &name) const
Fetches a matching variable from the context.
A abstract base class for defining QgsExpression functions.
A binary expression operator, which operates on two values.
An expression node which takes it value from a feature's field.
QString name() const
The name of the column.
An expression node for value IN or NOT IN clauses.
An expression node for literal values.
QVariant value() const
The value of the literal.
A list of expression nodes.
QList< QgsExpressionNode * > list()
Gets a list of all the nodes.
Abstract base class for all nodes that can appear in an expression.
Class for parsing and evaluation of expressions (formerly called "search strings").
bool prepare(const QgsExpressionContext *context)
Gets the expression ready for evaluation - find out column indexes.
static const QList< QgsExpressionFunction * > & Functions()
QgsExpression & operator=(const QgsExpression &other)
Create a copy of this expression.
QString expression() const
Returns the original, unmodified expression string.
Qgis::DistanceUnit distanceUnits() const
Returns the desired distance units for calculations involving geomCalculator(), e....
static QString quotedValue(const QVariant &value)
Returns a string representation of a literal value, including appropriate quotations where required.
void setExpression(const QString &expression)
Set the expression string, will reset the whole internal structure.
static int functionIndex(const QString &name)
Returns index of the function in Functions array.
static double evaluateToDouble(const QString &text, double fallbackValue)
Attempts to evaluate a text string as an expression to a resultant double value.
static QString quoteFieldExpression(const QString &expression, const QgsVectorLayer *layer)
Validate if the expression is a field in the layer and ensure it is quoted.
static int functionCount()
Returns the number of functions defined in the parser.
QList< const QgsExpressionNode * > nodes() const
Returns a list of all nodes which are used in this expression.
static QString quotedString(QString text)
Returns a quoted version of a string (in single quotes)
QSet< QString > referencedVariables() const
Returns a list of all variables which are used in this expression.
static bool isFunctionName(const QString &name)
tells whether the identifier is a name of existing function
bool hasParserError() const
Returns true if an error occurred when parsing the input expression.
static QString variableHelpText(const QString &variableName)
Returns the help text for a specified variable.
QList< QgsExpression::ParserError > parserErrors() const
Returns parser error details including location of error.
QString evalErrorString() const
Returns evaluation error.
bool operator==(const QgsExpression &other) const
Compares two expressions.
QString parserErrorString() const
Returns parser error.
static QString formatPreviewString(const QVariant &value, bool htmlOutput=true, int maximumPreviewLength=60)
Formats an expression result for friendly display to the user.
static QString replaceExpressionText(const QString &action, const QgsExpressionContext *context, const QgsDistanceArea *distanceArea=nullptr)
This function replaces each expression between [% and %] in the string with the result of its evaluat...
static QStringList tags(const QString &name)
Returns a string list of search tags for a specified function.
bool isField() const
Checks whether an expression consists only of a single field reference.
QSet< QString > referencedColumns() const
Gets list of columns referenced by the expression.
QgsExpression()
Create an empty expression.
QString dump() const
Returns an expression string, constructed from the internal abstract syntax tree.
static PRIVATE QString helpText(QString name)
Returns the help text for a specified function.
static QString createFieldEqualityExpression(const QString &fieldName, const QVariant &value, QMetaType::Type fieldType=QMetaType::Type::UnknownType)
Create an expression allowing to evaluate if a field is equal to a value.
void setDistanceUnits(Qgis::DistanceUnit unit)
Sets the desired distance units for calculations involving geomCalculator(), e.g.,...
void setAreaUnits(Qgis::AreaUnit unit)
Sets the desired areal units for calculations involving geomCalculator(), e.g., "$area".
static bool isFieldEqualityExpression(const QString &expression, QString &field, QVariant &value)
Returns true if the given expression is a simple "field=value" type expression.
Qgis::AreaUnit areaUnits() const
Returns the desired areal units for calculations involving geomCalculator(), e.g.,...
QSet< QString > referencedFunctions() const
Returns a list of the names of all functions which are used in this expression.
static QString group(const QString &group)
Returns the translated name for a function group.
void setEvalErrorString(const QString &str)
Sets evaluation error (used internally by evaluation functions)
static QString quotedColumnRef(QString name)
Returns a quoted column reference (in double quotes)
void setGeomCalculator(const QgsDistanceArea *calc)
Sets the geometry calculator used for distance and area calculations in expressions.
const QgsExpressionNode * rootNode() const
Returns the root node of the expression.
bool hasEvalError() const
Returns true if an error occurred when evaluating last input.
static QString formatVariableHelp(const QString &description, bool showValue=true, const QVariant &value=QVariant())
Returns formatted help text for a variable.
static int expressionToLayerFieldIndex(const QString &expression, const QgsVectorLayer *layer)
Attempts to resolve an expression to a field index from the given layer.
bool needsGeometry() const
Returns true if the expression uses feature geometry for some computation.
QVariant evaluate()
Evaluate the feature and return the result.
static bool attemptReduceToInClause(const QStringList &expressions, QString &result)
Attempts to reduce a list of expressions to a single "field IN (val1, val2, ... )" type expression.
bool isValid() const
Checks if this expression is valid.
static bool addVariableHelpText(const QString name, const QString &description)
Adds a help string for a custom variable.
QgsDistanceArea * geomCalculator()
Returns calculator used for distance and area calculations (used by $length, $area and $perimeter fun...
QSet< int > referencedAttributeIndexes(const QgsFields &fields) const
Returns a list of field name indexes obtained from the provided fields.
static bool checkExpression(const QString &text, const QgsExpressionContext *context, QString &errorMessage)
Tests whether a string is a valid expression.
static const QString ALL_ATTRIBUTES
A special attribute that if set matches all attributes.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Container of fields for a vector layer.
QgsAttributeList allAttributesList() const
Utility function to get list of attribute indexes.
QgsField at(int i) const
Returns the field at particular index (must be in range 0..N-1).
Q_INVOKABLE int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
A geometry is the spatial representation of a feature.
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
A representation of the interval between two datetime values.
double days() const
Returns the interval duration in days.
double seconds() const
Returns the interval duration in seconds.
double hours() const
Returns the interval duration in hours.
double minutes() const
Returns the interval duration in minutes.
static QgsProject * instance()
Returns the QgsProject singleton instance.
static Q_INVOKABLE Qgis::DistanceUnit stringToDistanceUnit(const QString &string, bool *ok=nullptr)
Converts a translated string to a distance unit.
static Q_INVOKABLE Qgis::AreaUnit stringToAreaUnit(const QString &string, bool *ok=nullptr)
Converts a translated string to an areal unit.
static QMetaType::Type variantTypeToMetaType(QVariant::Type variantType)
Converts a QVariant::Type to a QMetaType::Type.
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.
Represents a vector layer which manages a vector based data sets.
static QString displayString(Qgis::WkbType type)
Returns a non-translated display string type for a WKB type, e.g., the geometry name used in WKT geom...
CONSTLATIN1STRING geoNone()
Constant that holds the string representation for "No ellips/No CRS".
QMap< QString, QString > QgsStringMap
Q_GLOBAL_STATIC(QReadWriteLock, sDefinitionCacheLock)
QgsExpressionNode * parseExpression(const QString &str, QString &parserErrorMsg, QList< QgsExpression::ParserError > &parserErrors)
QList< int > QgsAttributeList
#define QgsDebugMsgLevel(str, level)
#define QgsDebugError(str)
QPointer< QgsMapLayer > QgsWeakMapLayerPointer
Weak pointer for QgsMapLayer.