34#include <QRegularExpression>
42HelpTextHash QgsExpression::sFunctionHelpTexts;
43QRecursiveMutex QgsExpression::sFunctionsMutex;
44QMap< QString, int> QgsExpression::sFunctionIndexMap;
47HelpTextHash &QgsExpression::functionHelpTexts()
49 return sFunctionHelpTexts;
65 d->mEvalErrorString = QString();
67 d->mIsPrepared =
false;
72 if ( !d->mExp.isNull() )
80 return QStringLiteral(
"\"%1\"" ).arg( name.replace(
'\"', QLatin1String(
"\"\"" ) ) );
85 text.replace(
'\'', QLatin1String(
"''" ) );
86 text.replace(
'\\', QLatin1String(
"\\\\" ) );
87 text.replace(
'\n', QLatin1String(
"\\n" ) );
88 text.replace(
'\t', QLatin1String(
"\\t" ) );
89 return QStringLiteral(
"'%1'" ).arg( text );
94 return quotedValue( value,
static_cast<QMetaType::Type
>( value.userType() ) );
100 return QStringLiteral(
"NULL" );
104 case QMetaType::Type::Int:
105 case QMetaType::Type::LongLong:
106 case QMetaType::Type::Double:
107 return value.toString();
109 case QMetaType::Type::Bool:
110 return value.toBool() ? QStringLiteral(
"TRUE" ) : QStringLiteral(
"FALSE" );
112 case QMetaType::Type::QVariantList:
113 case QMetaType::Type::QStringList:
115 QStringList quotedValues;
116 const QVariantList values = value.toList();
117 quotedValues.reserve( values.count() );
118 for (
const QVariant &v : values )
122 return QStringLiteral(
"array( %1 )" ).arg( quotedValues.join( QLatin1String(
", " ) ) );
126 case QMetaType::Type::QString:
144 QMutexLocker locker( &sFunctionsMutex );
146 auto it = sFunctionIndexMap.constFind( name );
147 if ( it != sFunctionIndexMap.constEnd() )
154 if ( QString::compare( name, function->name(), Qt::CaseInsensitive ) == 0 )
156 sFunctionIndexMap.insert( name, i );
159 const QStringList aliases = function->aliases();
160 for (
const QString &alias : aliases )
162 if ( QString::compare( name, alias, Qt::CaseInsensitive ) == 0 )
164 sFunctionIndexMap.insert( name, i );
180 : d( new QgsExpressionPrivate )
182 d->mRootNode.reset(
::parseExpression( expr, d->mParserErrorString, d->mParserErrors ) );
184 Q_ASSERT( !d->mParserErrorString.isNull() || d->mRootNode );
195 if (
this != &other )
197 if ( !d->ref.deref() )
208QgsExpression::operator QString()
const
214 : d( new QgsExpressionPrivate )
221 if ( !d->ref.deref() )
227 return ( d == other.d || d->mExp == other.d->mExp );
232 return d->mRootNode.get();
237 return d->mParserErrors.count() > 0;
242 return d->mParserErrorString.replace(
"syntax error, unexpected end of file",
243 tr(
"Incomplete expression. You might not have finished the full expression." ) );
248 return d->mParserErrors;
254 return QSet<QString>();
256 return d->mRootNode->referencedColumns();
262 return QSet<QString>();
264 return d->mRootNode->referencedVariables();
270 return QSet<QString>();
272 return d->mRootNode->referencedFunctions();
280 const QSet<QString> referencedFields = d->mRootNode->referencedColumns();
281 QSet<int> referencedIndexes;
283 for (
const QString &fieldName : referencedFields )
288 referencedIndexes = QSet<int>( attributesList.begin(), attributesList.end() );
294 referencedIndexes << idx;
298 return referencedIndexes;
305 return d->mRootNode->needsGeometry();
311 if ( context && ! d->mCalc )
315 d->mDaEllipsoid = context->
variable( QStringLiteral(
"project_ellipsoid" ) ).toString();
316 d->mDaCrs = std::make_unique<QgsCoordinateReferenceSystem>( context->
variable( QStringLiteral(
"_layer_crs" ) ).value<QgsCoordinateReferenceSystem>() );
317 d->mDaTransformContext = std::make_unique<QgsCoordinateTransformContext>( context->
variable( QStringLiteral(
"_project_transform_context" ) ).value<QgsCoordinateTransformContext>() );
323 QString distanceUnitsStr = context->
variable( QStringLiteral(
"project_distance_units" ) ).toString();
324 if ( ! distanceUnitsStr.isEmpty() )
331 QString areaUnitsStr = context->
variable( QStringLiteral(
"project_area_units" ) ).toString();
332 if ( ! areaUnitsStr.isEmpty() )
337void QgsExpression::detach()
343 ( void )d->ref.deref();
345 d =
new QgsExpressionPrivate( *d );
349void QgsExpression::initFunctionHelp()
351 static std::once_flag initialized;
352 std::call_once( initialized, buildFunctionHelp );
359 d->mCalc = std::make_shared<QgsDistanceArea>( *calc );
367 d->mEvalErrorString = QString();
373 d->mRootNode.reset(
::parseExpression( d->mExp, d->mParserErrorString, d->mParserErrors ) );
378 d->mEvalErrorString = tr(
"No root node! Parsing failed?" );
382 initGeomCalculator( context );
383 d->mIsPrepared =
true;
384 return d->mRootNode->prepare(
this, context );
389 d->mEvalErrorString = QString();
392 d->mEvalErrorString = tr(
"No root node! Parsing failed?" );
401 d->mEvalErrorString = QString();
404 d->mEvalErrorString = tr(
"No root node! Parsing failed?" );
408 if ( ! d->mIsPrepared )
412 return d->mRootNode->eval(
this, context );
417 return !d->mEvalErrorString.isNull();
422 return d->mEvalErrorString;
427 d->mEvalErrorString = str;
435 return d->mRootNode->dump();
440 if ( !d->mCalc && d->mDaCrs && d->mDaCrs->isValid() && d->mDaTransformContext )
443 d->mCalc = std::make_shared<QgsDistanceArea>( );
444 d->mCalc->setEllipsoid( d->mDaEllipsoid.isEmpty() ?
Qgis::geoNone() : d->mDaEllipsoid );
445 d->mCalc->setSourceCrs( *d->mDaCrs.get(), *d->mDaTransformContext.get() );
448 return d->mCalc.get();
453 return d->mDistanceUnit;
458 d->mDistanceUnit = unit;
476 while ( index < action.size() )
478 static const QRegularExpression sRegEx{ QStringLiteral(
"\\[%(.*?)%\\]" ), QRegularExpression::MultilineOption | QRegularExpression::DotMatchesEverythingOption };
480 const QRegularExpressionMatch match = sRegEx.match( action, index );
481 if ( !match.hasMatch() )
484 const int pos = action.indexOf( sRegEx, index );
485 const int start = index;
486 index = pos + match.capturedLength( 0 );
487 const QString toReplace = match.captured( 1 ).trimmed();
494 expr_action += QStringView {action} .mid( start, index - start );
504 QVariant result = exp.
evaluate( context );
509 expr_action += QStringView {action} .mid( start, index - start );
513 QString resultString;
515 resultString = result.toString();
519 expr_action += action.mid( start, pos - start ) + resultString;
522 expr_action += QStringView {action} .mid( index ).toString();
528 QSet<QString> variables;
530 while ( index < text.size() )
532 const thread_local QRegularExpression rx(
"\\[%([^\\]]+)%\\]" );
533 const QRegularExpressionMatch match = rx.match( text );
534 if ( !match.hasMatch() )
537 index = match.capturedStart() + match.capturedLength();
538 QString to_replace = match.captured( 1 ).trimmed();
553 double convertedValue = QLocale().toDouble( text, &ok );
556 return convertedValue;
566 QVariant result = expr.
evaluate( &context );
567 convertedValue = result.toDouble( &ok );
570 return fallbackValue;
572 return convertedValue;
577 QgsExpression::initFunctionHelp();
579 if ( !sFunctionHelpTexts.contains( name ) )
580 return tr(
"function help for %1 missing" ).arg( name );
582 const Help &f = sFunctionHelpTexts[ name ];
585 if ( f.mType == tr(
"group" ) )
587 name =
group( name );
588 name = name.toLower();
591 name = name.toHtmlEscaped();
593 QString helpContents( QStringLiteral(
"<h3>%1</h3>\n<div class=\"description\"><p>%2</p></div>" )
594 .arg( tr(
"%1 %2" ).arg( f.mType, name ),
597 for (
const HelpVariant &v : std::as_const( f.mVariants ) )
599 if ( f.mVariants.size() > 1 )
601 helpContents += QStringLiteral(
"<h3>%1</h3>\n<div class=\"description\">%2</p></div>" ).arg( v.mName, v.mDescription );
604 if ( f.mType != tr(
"group" ) && f.mType != tr(
"expression" ) )
605 helpContents += QStringLiteral(
"<h4>%1</h4>\n<div class=\"syntax\">\n" ).arg( tr(
"Syntax" ) );
607 if ( f.mType == tr(
"operator" ) )
609 if ( v.mArguments.size() == 1 )
611 helpContents += QStringLiteral(
"<code><span class=\"functionname\">%1</span> <span class=\"argument\">%2</span></code>" )
612 .arg( name, v.mArguments[0].mArg );
614 else if ( v.mArguments.size() == 2 )
616 helpContents += QStringLiteral(
"<code><span class=\"argument\">%1</span> <span class=\"functionname\">%2</span> <span class=\"argument\">%3</span></code>" )
617 .arg( v.mArguments[0].mArg, name, v.mArguments[1].mArg );
620 else if ( f.mType != tr(
"group" ) && f.mType != tr(
"expression" ) )
622 helpContents += QStringLiteral(
"<code><span class=\"functionname\">%1</span>" ).arg( name );
624 bool hasOptionalArgs =
false;
626 if ( f.mType == tr(
"function" ) && ( f.mName[0] !=
'$' || !v.mArguments.isEmpty() || v.mVariableLenArguments ) )
631 for (
const HelpArg &a : std::as_const( v.mArguments ) )
637 hasOptionalArgs =
true;
638 helpContents += QLatin1Char(
'[' );
641 helpContents += delim;
642 helpContents += QStringLiteral(
"<span class=\"argument\">%2%3</span>" ).arg(
644 a.mDefaultVal.isEmpty() ? QString() :
":=" + a.mDefaultVal
648 helpContents += QLatin1Char(
']' );
650 delim = QStringLiteral(
"," );
653 if ( v.mVariableLenArguments )
655 helpContents += QChar( 0x2026 );
661 helpContents += QLatin1String(
"</code>" );
663 if ( hasOptionalArgs )
665 helpContents += QLatin1String(
"<br/><br/>" ) + tr(
"[ ] marks optional components" );
669 if ( !v.mArguments.isEmpty() )
671 helpContents += QStringLiteral(
"<h4>%1</h4>\n<div class=\"arguments\">\n<table>" ).arg( tr(
"Arguments" ) );
673 for (
const HelpArg &a : std::as_const( v.mArguments ) )
678 helpContents += QStringLiteral(
"<tr><td class=\"argument\">%1</td><td>%2</td></tr>" ).arg( a.mArg, a.mDescription );
681 helpContents += QLatin1String(
"</table>\n</div>\n" );
684 if ( !v.mExamples.isEmpty() )
686 helpContents += QStringLiteral(
"<h4>%1</h4>\n<div class=\"examples\">\n<ul>\n" ).arg( tr(
"Examples" ) );
688 for (
const HelpExample &e : std::as_const( v.mExamples ) )
690 helpContents +=
"<li><code>" + e.mExpression +
"</code> → <code>" + e.mReturns +
"</code>";
692 if ( !e.mNote.isEmpty() )
693 helpContents += QStringLiteral(
" (%1)" ).arg( e.mNote );
695 helpContents += QLatin1String(
"</li>\n" );
698 helpContents += QLatin1String(
"</ul>\n</div>\n" );
701 if ( !v.mNotes.isEmpty() )
703 helpContents += QStringLiteral(
"<h4>%1</h4>\n<div class=\"notes\"><p>%2</p></div>\n" ).arg( tr(
"Notes" ), v.mNotes );
712 QStringList
tags = QStringList();
714 QgsExpression::initFunctionHelp();
716 if ( sFunctionHelpTexts.contains( name ) )
718 const Help &f = sFunctionHelpTexts[ name ];
720 for (
const HelpVariant &v : std::as_const( f.mVariants ) )
729void QgsExpression::initVariableHelp()
731 static std::once_flag initialized;
732 std::call_once( initialized, buildVariableHelp );
735void QgsExpression::buildVariableHelp()
738 sVariableHelpTexts()->insert( QStringLiteral(
"qgis_version" ), QCoreApplication::translate(
"variable_help",
"Current QGIS version string." ) );
739 sVariableHelpTexts()->insert( QStringLiteral(
"qgis_version_no" ), QCoreApplication::translate(
"variable_help",
"Current QGIS version number." ) );
740 sVariableHelpTexts()->insert( QStringLiteral(
"qgis_release_name" ), QCoreApplication::translate(
"variable_help",
"Current QGIS release name." ) );
741 sVariableHelpTexts()->insert( QStringLiteral(
"qgis_short_version" ), QCoreApplication::translate(
"variable_help",
"Short QGIS version string." ) );
742 sVariableHelpTexts()->insert( QStringLiteral(
"qgis_os_name" ), QCoreApplication::translate(
"variable_help",
"Operating system name, e.g., 'windows', 'linux' or 'osx'." ) );
743 sVariableHelpTexts()->insert( QStringLiteral(
"qgis_platform" ), QCoreApplication::translate(
"variable_help",
"QGIS platform, e.g., 'desktop' or 'server'." ) );
744 sVariableHelpTexts()->insert( QStringLiteral(
"qgis_locale" ), QCoreApplication::translate(
"variable_help",
"Two letter identifier for current QGIS locale." ) );
745 sVariableHelpTexts()->insert( QStringLiteral(
"user_account_name" ), QCoreApplication::translate(
"variable_help",
"Current user's operating system account name." ) );
746 sVariableHelpTexts()->insert( QStringLiteral(
"user_full_name" ), QCoreApplication::translate(
"variable_help",
"Current user's operating system user name (if available)." ) );
749 sVariableHelpTexts()->insert( QStringLiteral(
"project_title" ), QCoreApplication::translate(
"variable_help",
"Title of current project." ) );
750 sVariableHelpTexts()->insert( QStringLiteral(
"project_path" ), QCoreApplication::translate(
"variable_help",
"Full path (including file name) of current project." ) );
751 sVariableHelpTexts()->insert( QStringLiteral(
"project_folder" ), QCoreApplication::translate(
"variable_help",
"Folder for current project." ) );
752 sVariableHelpTexts()->insert( QStringLiteral(
"project_filename" ), QCoreApplication::translate(
"variable_help",
"Filename of current project." ) );
753 sVariableHelpTexts()->insert( QStringLiteral(
"project_basename" ), QCoreApplication::translate(
"variable_help",
"Base name of current project's filename (without path and extension)." ) );
754 sVariableHelpTexts()->insert( QStringLiteral(
"project_home" ), QCoreApplication::translate(
"variable_help",
"Home path of current project." ) );
755 sVariableHelpTexts()->insert( QStringLiteral(
"project_crs" ), QCoreApplication::translate(
"variable_help",
"Identifier for the coordinate reference system of project (e.g., 'EPSG:4326')." ) );
756 sVariableHelpTexts()->insert( QStringLiteral(
"project_crs_definition" ), QCoreApplication::translate(
"variable_help",
"Coordinate reference system of project (full definition)." ) );
757 sVariableHelpTexts()->insert( QStringLiteral(
"project_units" ), QCoreApplication::translate(
"variable_help",
"Unit of the project's CRS." ) );
758 sVariableHelpTexts()->insert( QStringLiteral(
"project_crs_description" ), QCoreApplication::translate(
"variable_help",
"Name of the coordinate reference system of the project." ) );
759 sVariableHelpTexts()->insert( QStringLiteral(
"project_crs_acronym" ), QCoreApplication::translate(
"variable_help",
"Acronym of the coordinate reference system of the project." ) );
760 sVariableHelpTexts()->insert( QStringLiteral(
"project_crs_ellipsoid" ), QCoreApplication::translate(
"variable_help",
"Acronym of the ellipsoid of the coordinate reference system of the project." ) );
761 sVariableHelpTexts()->insert( QStringLiteral(
"project_crs_proj4" ), QCoreApplication::translate(
"variable_help",
"Proj4 definition of the coordinate reference system of the project." ) );
762 sVariableHelpTexts()->insert( QStringLiteral(
"project_crs_wkt" ), QCoreApplication::translate(
"variable_help",
"WKT definition of the coordinate reference system of the project." ) );
764 sVariableHelpTexts()->insert( QStringLiteral(
"project_vertical_crs" ), QCoreApplication::translate(
"variable_help",
"Identifier for the vertical coordinate reference system of the project (e.g., 'EPSG:5703')." ) );
765 sVariableHelpTexts()->insert( QStringLiteral(
"project_vertical_crs_definition" ), QCoreApplication::translate(
"variable_help",
"Vertical coordinate reference system of project (full definition)." ) );
766 sVariableHelpTexts()->insert( QStringLiteral(
"project_vertical_crs_description" ), QCoreApplication::translate(
"variable_help",
"Name of the vertical coordinate reference system of the project." ) );
767 sVariableHelpTexts()->insert( QStringLiteral(
"project_vertical_crs_wkt" ), QCoreApplication::translate(
"variable_help",
"WKT definition of the vertical coordinate reference system of the project." ) );
769 sVariableHelpTexts()->insert( QStringLiteral(
"project_author" ), QCoreApplication::translate(
"variable_help",
"Project author, taken from project metadata." ) );
770 sVariableHelpTexts()->insert( QStringLiteral(
"project_abstract" ), QCoreApplication::translate(
"variable_help",
"Project abstract, taken from project metadata." ) );
771 sVariableHelpTexts()->insert( QStringLiteral(
"project_creation_date" ), QCoreApplication::translate(
"variable_help",
"Project creation date, taken from project metadata." ) );
772 sVariableHelpTexts()->insert( QStringLiteral(
"project_identifier" ), QCoreApplication::translate(
"variable_help",
"Project identifier, taken from project metadata." ) );
773 sVariableHelpTexts()->insert( QStringLiteral(
"project_last_saved" ), QCoreApplication::translate(
"variable_help",
"Date/time when project was last saved." ) );
774 sVariableHelpTexts()->insert( QStringLiteral(
"project_keywords" ), QCoreApplication::translate(
"variable_help",
"Project keywords, taken from project metadata." ) );
775 sVariableHelpTexts()->insert( QStringLiteral(
"project_area_units" ), QCoreApplication::translate(
"variable_help",
"Area unit for current project, used when calculating areas of geometries." ) );
776 sVariableHelpTexts()->insert( QStringLiteral(
"project_distance_units" ), QCoreApplication::translate(
"variable_help",
"Distance unit for current project, used when calculating lengths of geometries." ) );
777 sVariableHelpTexts()->insert( QStringLiteral(
"project_ellipsoid" ), QCoreApplication::translate(
"variable_help",
"Name of ellipsoid of current project, used when calculating geodetic areas and lengths of geometries." ) );
778 sVariableHelpTexts()->insert( QStringLiteral(
"layer_ids" ), QCoreApplication::translate(
"variable_help",
"List of all map layer IDs from the current project." ) );
779 sVariableHelpTexts()->insert( QStringLiteral(
"layers" ), QCoreApplication::translate(
"variable_help",
"List of all map layers from the current project." ) );
782 sVariableHelpTexts()->insert( QStringLiteral(
"layer_name" ), QCoreApplication::translate(
"variable_help",
"Name of current layer." ) );
783 sVariableHelpTexts()->insert( QStringLiteral(
"layer_id" ), QCoreApplication::translate(
"variable_help",
"ID of current layer." ) );
784 sVariableHelpTexts()->insert( QStringLiteral(
"layer_crs" ), QCoreApplication::translate(
"variable_help",
"CRS Authority ID of current layer." ) );
785 sVariableHelpTexts()->insert( QStringLiteral(
"layer" ), QCoreApplication::translate(
"variable_help",
"The current layer." ) );
786 sVariableHelpTexts()->insert( QStringLiteral(
"layer_crs_ellipsoid" ), QCoreApplication::translate(
"variable_help",
"Ellipsoid acronym of current layer CRS." ) );
788 sVariableHelpTexts()->insert( QStringLiteral(
"layer_vertical_crs" ), QCoreApplication::translate(
"variable_help",
"Identifier for the vertical coordinate reference system of the layer (e.g., 'EPSG:5703')." ) );
789 sVariableHelpTexts()->insert( QStringLiteral(
"layer_vertical_crs_definition" ), QCoreApplication::translate(
"variable_help",
"Vertical coordinate reference system of layer (full definition)." ) );
790 sVariableHelpTexts()->insert( QStringLiteral(
"layer_vertical_crs_description" ), QCoreApplication::translate(
"variable_help",
"Name of the vertical coordinate reference system of the layer." ) );
791 sVariableHelpTexts()->insert( QStringLiteral(
"layer_vertical_crs_wkt" ), QCoreApplication::translate(
"variable_help",
"WKT definition of the vertical coordinate reference system of the layer." ) );
794 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." ) );
795 sVariableHelpTexts()->insert( QStringLiteral(
"id" ), QCoreApplication::translate(
"variable_help",
"The ID of the current feature being evaluated." ) );
796 sVariableHelpTexts()->insert( QStringLiteral(
"geometry" ), QCoreApplication::translate(
"variable_help",
"The geometry of the current feature being evaluated." ) );
799 sVariableHelpTexts()->insert( QStringLiteral(
"layout_name" ), QCoreApplication::translate(
"variable_help",
"Name of composition." ) );
800 sVariableHelpTexts()->insert( QStringLiteral(
"layout_numpages" ), QCoreApplication::translate(
"variable_help",
"Number of pages in composition." ) );
801 sVariableHelpTexts()->insert( QStringLiteral(
"layout_page" ), QCoreApplication::translate(
"variable_help",
"Current page number in composition." ) );
802 sVariableHelpTexts()->insert( QStringLiteral(
"layout_pageheight" ), QCoreApplication::translate(
"variable_help",
"Composition page height in mm (or specified custom units)." ) );
803 sVariableHelpTexts()->insert( QStringLiteral(
"layout_pagewidth" ), QCoreApplication::translate(
"variable_help",
"Composition page width in mm (or specified custom units)." ) );
804 sVariableHelpTexts()->insert( QStringLiteral(
"layout_pageoffsets" ), QCoreApplication::translate(
"variable_help",
"Array of Y coordinate of the top of each page." ) );
805 sVariableHelpTexts()->insert( QStringLiteral(
"layout_dpi" ), QCoreApplication::translate(
"variable_help",
"Composition resolution (DPI)." ) );
808 sVariableHelpTexts()->insert( QStringLiteral(
"atlas_layerid" ), QCoreApplication::translate(
"variable_help",
"Current atlas coverage layer ID." ) );
809 sVariableHelpTexts()->insert( QStringLiteral(
"atlas_layername" ), QCoreApplication::translate(
"variable_help",
"Current atlas coverage layer name." ) );
810 sVariableHelpTexts()->insert( QStringLiteral(
"atlas_totalfeatures" ), QCoreApplication::translate(
"variable_help",
"Total number of features in atlas." ) );
811 sVariableHelpTexts()->insert( QStringLiteral(
"atlas_featurenumber" ), QCoreApplication::translate(
"variable_help",
"Current atlas feature number." ) );
812 sVariableHelpTexts()->insert( QStringLiteral(
"atlas_filename" ), QCoreApplication::translate(
"variable_help",
"Current atlas file name." ) );
813 sVariableHelpTexts()->insert( QStringLiteral(
"atlas_pagename" ), QCoreApplication::translate(
"variable_help",
"Current atlas page name." ) );
814 sVariableHelpTexts()->insert( QStringLiteral(
"atlas_feature" ), QCoreApplication::translate(
"variable_help",
"Current atlas feature (as feature object)." ) );
815 sVariableHelpTexts()->insert( QStringLiteral(
"atlas_featureid" ), QCoreApplication::translate(
"variable_help",
"Current atlas feature ID." ) );
816 sVariableHelpTexts()->insert( QStringLiteral(
"atlas_geometry" ), QCoreApplication::translate(
"variable_help",
"Current atlas feature geometry." ) );
819 sVariableHelpTexts()->insert( QStringLiteral(
"item_id" ), QCoreApplication::translate(
"variable_help",
"Layout item user-assigned ID (not necessarily unique)." ) );
820 sVariableHelpTexts()->insert( QStringLiteral(
"item_uuid" ), QCoreApplication::translate(
"variable_help",
"layout item unique ID." ) );
821 sVariableHelpTexts()->insert( QStringLiteral(
"item_left" ), QCoreApplication::translate(
"variable_help",
"Left position of layout item (in mm)." ) );
822 sVariableHelpTexts()->insert( QStringLiteral(
"item_top" ), QCoreApplication::translate(
"variable_help",
"Top position of layout item (in mm)." ) );
823 sVariableHelpTexts()->insert( QStringLiteral(
"item_width" ), QCoreApplication::translate(
"variable_help",
"Width of layout item (in mm)." ) );
824 sVariableHelpTexts()->insert( QStringLiteral(
"item_height" ), QCoreApplication::translate(
"variable_help",
"Height of layout item (in mm)." ) );
827 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." ) );
828 sVariableHelpTexts()->insert( QStringLiteral(
"map_rotation" ), QCoreApplication::translate(
"variable_help",
"Current rotation of map." ) );
829 sVariableHelpTexts()->insert( QStringLiteral(
"map_scale" ), QCoreApplication::translate(
"variable_help",
"Current scale of map." ) );
830 sVariableHelpTexts()->insert( QStringLiteral(
"map_extent" ), QCoreApplication::translate(
"variable_help",
"Geometry representing the current extent of the map." ) );
831 sVariableHelpTexts()->insert( QStringLiteral(
"map_extent_center" ), QCoreApplication::translate(
"variable_help",
"Center of map." ) );
832 sVariableHelpTexts()->insert( QStringLiteral(
"map_extent_width" ), QCoreApplication::translate(
"variable_help",
"Width of map." ) );
833 sVariableHelpTexts()->insert( QStringLiteral(
"map_extent_height" ), QCoreApplication::translate(
"variable_help",
"Height of map." ) );
834 sVariableHelpTexts()->insert( QStringLiteral(
"map_crs" ), QCoreApplication::translate(
"variable_help",
"Coordinate reference system of map (e.g., 'EPSG:4326')." ) );
835 sVariableHelpTexts()->insert( QStringLiteral(
"map_crs_description" ), QCoreApplication::translate(
"variable_help",
"Name of the coordinate reference system of the map." ) );
836 sVariableHelpTexts()->insert( QStringLiteral(
"map_units" ), QCoreApplication::translate(
"variable_help",
"Units for map measurements." ) );
837 sVariableHelpTexts()->insert( QStringLiteral(
"map_crs_definition" ), QCoreApplication::translate(
"variable_help",
"Coordinate reference system of the map (full definition)." ) );
838 sVariableHelpTexts()->insert( QStringLiteral(
"map_crs_acronym" ), QCoreApplication::translate(
"variable_help",
"Acronym of the coordinate reference system of the map." ) );
839 sVariableHelpTexts()->insert( QStringLiteral(
"map_crs_projection" ), QCoreApplication::translate(
"variable_help",
"Projection method used by the coordinate reference system of the map." ) );
840 sVariableHelpTexts()->insert( QStringLiteral(
"map_crs_ellipsoid" ), QCoreApplication::translate(
"variable_help",
"Acronym of the ellipsoid of the coordinate reference system of the map." ) );
841 sVariableHelpTexts()->insert( QStringLiteral(
"map_crs_proj4" ), QCoreApplication::translate(
"variable_help",
"Proj4 definition of the coordinate reference system of the map." ) );
842 sVariableHelpTexts()->insert( QStringLiteral(
"map_crs_wkt" ), QCoreApplication::translate(
"variable_help",
"WKT definition of the coordinate reference system of the map." ) );
843 sVariableHelpTexts()->insert( QStringLiteral(
"map_layer_ids" ), QCoreApplication::translate(
"variable_help",
"List of map layer IDs visible in the map." ) );
844 sVariableHelpTexts()->insert( QStringLiteral(
"map_layers" ), QCoreApplication::translate(
"variable_help",
"List of map layers visible in the map." ) );
846 sVariableHelpTexts()->insert( QStringLiteral(
"map_start_time" ), QCoreApplication::translate(
"variable_help",
"Start of the map's temporal time range (as a datetime value)" ) );
847 sVariableHelpTexts()->insert( QStringLiteral(
"map_end_time" ), QCoreApplication::translate(
"variable_help",
"End of the map's temporal time range (as a datetime value)" ) );
848 sVariableHelpTexts()->insert( QStringLiteral(
"map_interval" ), QCoreApplication::translate(
"variable_help",
"Duration of the map's temporal time range (as an interval value)" ) );
849 sVariableHelpTexts()->insert( QStringLiteral(
"map_z_range_lower" ), QCoreApplication::translate(
"variable_help",
"Lower elevation of the map's elevation range" ) );
850 sVariableHelpTexts()->insert( QStringLiteral(
"map_z_range_upper" ), QCoreApplication::translate(
"variable_help",
"Upper elevation of the map's elevation range" ) );
852 sVariableHelpTexts()->insert( QStringLiteral(
"frame_rate" ), QCoreApplication::translate(
"variable_help",
"Number of frames per second during animation playback" ) );
853 sVariableHelpTexts()->insert( QStringLiteral(
"frame_number" ), QCoreApplication::translate(
"variable_help",
"Current frame number during animation playback" ) );
854 sVariableHelpTexts()->insert( QStringLiteral(
"frame_duration" ), QCoreApplication::translate(
"variable_help",
"Temporal duration of each animation frame (as an interval value)" ) );
855 sVariableHelpTexts()->insert( QStringLiteral(
"frame_timestep" ), QCoreApplication::translate(
"variable_help",
"Frame time step during animation playback" ) );
856 sVariableHelpTexts()->insert( QStringLiteral(
"frame_timestep_unit" ), QCoreApplication::translate(
"variable_help",
"Unit value of the frame time step during animation playback" ) );
857 sVariableHelpTexts()->insert( QStringLiteral(
"frame_timestep_units" ), QCoreApplication::translate(
"variable_help",
"String representation of the frame time step unit during animation playback" ) );
858 sVariableHelpTexts()->insert( QStringLiteral(
"animation_start_time" ), QCoreApplication::translate(
"variable_help",
"Start of the animation's overall temporal time range (as a datetime value)" ) );
859 sVariableHelpTexts()->insert( QStringLiteral(
"animation_end_time" ), QCoreApplication::translate(
"variable_help",
"End of the animation's overall temporal time range (as a datetime value)" ) );
860 sVariableHelpTexts()->insert( QStringLiteral(
"animation_interval" ), QCoreApplication::translate(
"variable_help",
"Duration of the animation's overall temporal time range (as an interval value)" ) );
863 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]." ) );
864 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." ) );
866 sVariableHelpTexts()->insert( QStringLiteral(
"row_number" ), QCoreApplication::translate(
"variable_help",
"Stores the number of the current row." ) + QStringLiteral(
"\n\n" ) + QCoreApplication::translate(
"variable_help",
"When used for calculations within the attribute table the row number will respect the original order of features from the underlying data source." ) + QStringLiteral(
"\n\n" ) + QCoreApplication::translate(
"variable_help",
"When used from the field calculator the row numbering starts at 1, otherwise (e.g. from Processing tools) the row numbering starts from 0." ) );
867 sVariableHelpTexts()->insert( QStringLiteral(
"grid_number" ), QCoreApplication::translate(
"variable_help",
"Current grid annotation value." ) );
868 sVariableHelpTexts()->insert( QStringLiteral(
"grid_axis" ), QCoreApplication::translate(
"variable_help",
"Current grid annotation axis (e.g., 'x' for longitude, 'y' for latitude)." ) );
869 sVariableHelpTexts()->insert( QStringLiteral(
"grid_count" ), QCoreApplication::translate(
"variable_help",
"Total number of visible grid lines for the current grid axis." ) );
870 sVariableHelpTexts()->insert( QStringLiteral(
"grid_index" ), QCoreApplication::translate(
"variable_help",
"The index of the grid line currently being drawn (starting at 1 for the first grid line). The index is specific to the current grid axis." ) );
871 sVariableHelpTexts()->insert( QStringLiteral(
"column_number" ), QCoreApplication::translate(
"variable_help",
"Stores the number of the current column." ) );
874 sVariableHelpTexts()->insert( QStringLiteral(
"canvas_cursor_point" ), QCoreApplication::translate(
"variable_help",
"Last cursor position on the canvas in the project's geographical coordinates." ) );
875 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." ) );
878 sVariableHelpTexts()->insert( QStringLiteral(
"legend_title" ), QCoreApplication::translate(
"variable_help",
"Title of the legend." ) );
879 sVariableHelpTexts()->insert( QStringLiteral(
"legend_column_count" ), QCoreApplication::translate(
"variable_help",
"Number of column in the legend." ) );
880 sVariableHelpTexts()->insert( QStringLiteral(
"legend_split_layers" ), QCoreApplication::translate(
"variable_help",
"Boolean indicating if layers can be split in the legend." ) );
881 sVariableHelpTexts()->insert( QStringLiteral(
"legend_wrap_string" ), QCoreApplication::translate(
"variable_help",
"Characters used to wrap the legend text." ) );
882 sVariableHelpTexts()->insert( QStringLiteral(
"legend_filter_by_map" ), QCoreApplication::translate(
"variable_help",
"Boolean indicating if the content of the legend is filtered by the map." ) );
883 sVariableHelpTexts()->insert( QStringLiteral(
"legend_filter_out_atlas" ), QCoreApplication::translate(
"variable_help",
"Boolean indicating if the Atlas is filtered out of the legend." ) );
886 sVariableHelpTexts()->insert( QStringLiteral(
"scale_value" ), QCoreApplication::translate(
"variable_help",
"Current scale bar distance value." ) );
889 sVariableHelpTexts()->insert( QStringLiteral(
"snapping_results" ), QCoreApplication::translate(
"variable_help",
890 "<p>An array with an item for each snapped point.</p>"
891 "<p>Each item is a map with the following keys:</p>"
893 "<dt>valid</dt><dd>Boolean that indicates if the snapping result is valid</dd>"
894 "<dt>layer</dt><dd>The layer on which the snapped feature is</dd>"
895 "<dt>feature_id</dt><dd>The feature id of the snapped feature</dd>"
896 "<dt>vertex_index</dt><dd>The index of the snapped vertex</dd>"
897 "<dt>distance</dt><dd>The distance between the mouse cursor and the snapped point at the time of snapping</dd>"
902 sVariableHelpTexts()->insert( QStringLiteral(
"geometry_part_count" ), QCoreApplication::translate(
"variable_help",
"Number of parts in rendered feature's geometry." ) );
903 sVariableHelpTexts()->insert( QStringLiteral(
"geometry_part_num" ), QCoreApplication::translate(
"variable_help",
"Current geometry part number for feature being rendered." ) );
904 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." ) );
905 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." ) );
906 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." ) );
908 sVariableHelpTexts()->insert( QStringLiteral(
"symbol_color" ), QCoreApplication::translate(
"symbol_color",
"Color of symbol used to render the feature." ) );
909 sVariableHelpTexts()->insert( QStringLiteral(
"symbol_angle" ), QCoreApplication::translate(
"symbol_angle",
"Angle of symbol used to render the feature (valid for marker symbols only)." ) );
910 sVariableHelpTexts()->insert( QStringLiteral(
"symbol_layer_count" ), QCoreApplication::translate(
"symbol_layer_count",
"Total number of symbol layers in the symbol." ) );
911 sVariableHelpTexts()->insert( QStringLiteral(
"symbol_layer_index" ), QCoreApplication::translate(
"symbol_layer_index",
"Current symbol layer index." ) );
912 sVariableHelpTexts()->insert( QStringLiteral(
"symbol_marker_row" ), QCoreApplication::translate(
"symbol_marker_row",
"Row number for marker (valid for point pattern fills only)." ) );
913 sVariableHelpTexts()->insert( QStringLiteral(
"symbol_marker_column" ), QCoreApplication::translate(
"symbol_marker_column",
"Column number for marker (valid for point pattern fills only)." ) );
914 sVariableHelpTexts()->insert( QStringLiteral(
"symbol_frame" ), QCoreApplication::translate(
"symbol_frame",
"Frame number (for animated symbols only)." ) );
916 sVariableHelpTexts()->insert( QStringLiteral(
"symbol_label" ), QCoreApplication::translate(
"symbol_label",
"Label for the symbol (either a user defined label or the default autogenerated label)." ) );
917 sVariableHelpTexts()->insert( QStringLiteral(
"symbol_id" ), QCoreApplication::translate(
"symbol_id",
"Internal ID of the symbol." ) );
918 sVariableHelpTexts()->insert( QStringLiteral(
"symbol_count" ), QCoreApplication::translate(
"symbol_count",
"Total number of features represented by the symbol." ) );
921 sVariableHelpTexts()->insert( QStringLiteral(
"cluster_color" ), QCoreApplication::translate(
"cluster_color",
"Color of symbols within a cluster, or NULL if symbols have mixed colors." ) );
922 sVariableHelpTexts()->insert( QStringLiteral(
"cluster_size" ), QCoreApplication::translate(
"cluster_size",
"Number of symbols contained within a cluster." ) );
925 sVariableHelpTexts()->insert( QStringLiteral(
"algorithm_id" ), QCoreApplication::translate(
"algorithm_id",
"Unique ID for algorithm." ) );
926 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)." ) );
927 sVariableHelpTexts()->insert( QStringLiteral(
"model_folder" ), QCoreApplication::translate(
"variable_help",
"Folder containing current model (or project folder if model is embedded in a project)." ) );
928 sVariableHelpTexts()->insert( QStringLiteral(
"model_name" ), QCoreApplication::translate(
"variable_help",
"Name of current model." ) );
929 sVariableHelpTexts()->insert( QStringLiteral(
"model_group" ), QCoreApplication::translate(
"variable_help",
"Group for current model." ) );
930 sVariableHelpTexts()->insert( QStringLiteral(
"fullextent_minx" ), QCoreApplication::translate(
"fullextent_minx",
"Minimum x-value from full canvas extent (including all layers)." ) );
931 sVariableHelpTexts()->insert( QStringLiteral(
"fullextent_miny" ), QCoreApplication::translate(
"fullextent_miny",
"Minimum y-value from full canvas extent (including all layers)." ) );
932 sVariableHelpTexts()->insert( QStringLiteral(
"fullextent_maxx" ), QCoreApplication::translate(
"fullextent_maxx",
"Maximum x-value from full canvas extent (including all layers)." ) );
933 sVariableHelpTexts()->insert( QStringLiteral(
"fullextent_maxy" ), QCoreApplication::translate(
"fullextent_maxy",
"Maximum y-value from full canvas extent (including all layers)." ) );
936 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)." ) );
939 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." ) );
940 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." ) );
943 sVariableHelpTexts()->insert( QStringLiteral(
"current_parent_geometry" ), QCoreApplication::translate(
"current_parent_geometry",
944 "Only usable in an embedded form context, "
945 "represents the geometry of the feature currently being edited in the parent form.\n"
946 "Can be used in a form/row context to filter the related features using a value "
947 "from the feature currently edited in the parent form, to make sure that the filter "
948 "still works with standalone forms it is recommended to wrap this variable in a "
950 sVariableHelpTexts()->insert( QStringLiteral(
"current_parent_feature" ), QCoreApplication::translate(
"current_parent_feature",
951 "Only usable in an embedded form context, "
952 "represents the feature currently being edited in the parent form.\n"
953 "Can be used in a form/row context to filter the related features using a value "
954 "from the feature currently edited in the parent form, to make sure that the filter "
955 "still works with standalone forms it is recommended to wrap this variable in a "
959 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." ) );
962 sVariableHelpTexts()->insert( QStringLiteral(
"plot_axis" ), QCoreApplication::translate(
"plot_axis",
"The associated plot axis, e.g. 'x' or 'y'." ) );
963 sVariableHelpTexts()->insert( QStringLiteral(
"plot_axis_value" ), QCoreApplication::translate(
"plot_axis_value",
"The current value for the plot axis grid line." ) );
964 sVariableHelpTexts()->insert( QStringLiteral(
"chart_category" ), QCoreApplication::translate(
"plot_axis",
"The chart item category, e.g. 'fruit' or 'june'." ) );
965 sVariableHelpTexts()->insert( QStringLiteral(
"chart_value" ), QCoreApplication::translate(
"plot_axis_value",
"The chart item value." ) );
970 QgsExpression::initVariableHelp();
971 if ( sVariableHelpTexts()->contains( name ) )
975 sVariableHelpTexts()->insert( name, description );
981 QgsExpression::initVariableHelp();
982 return sVariableHelpTexts()->value( variableName, QString() );
987 QString text = !description.isEmpty() ? QStringLiteral(
"<p>%1</p>" ).arg( description ) : QString();
991 if ( !value.isValid() )
993 valueString = QCoreApplication::translate(
"variable_help",
"not set" );
999 text.append( QCoreApplication::translate(
"variable_help",
"<p>Current value: %1</p>" ).arg( valueString ) );
1006 if ( sGroups()->isEmpty() )
1008 sGroups()->insert( QStringLiteral(
"Aggregates" ), tr(
"Aggregates" ) );
1009 sGroups()->insert( QStringLiteral(
"Arrays" ), tr(
"Arrays" ) );
1010 sGroups()->insert( QStringLiteral(
"Color" ), tr(
"Color" ) );
1011 sGroups()->insert( QStringLiteral(
"Conditionals" ), tr(
"Conditionals" ) );
1012 sGroups()->insert( QStringLiteral(
"Conversions" ), tr(
"Conversions" ) );
1013 sGroups()->insert( QStringLiteral(
"Date and Time" ), tr(
"Date and Time" ) );
1014 sGroups()->insert( QStringLiteral(
"Fields and Values" ), tr(
"Fields and Values" ) );
1015 sGroups()->insert( QStringLiteral(
"Files and Paths" ), tr(
"Files and Paths" ) );
1016 sGroups()->insert( QStringLiteral(
"Fuzzy Matching" ), tr(
"Fuzzy Matching" ) );
1017 sGroups()->insert( QStringLiteral(
"General" ), tr(
"General" ) );
1018 sGroups()->insert( QStringLiteral(
"GeometryGroup" ), tr(
"Geometry" ) );
1019 sGroups()->insert( QStringLiteral(
"Map Layers" ), tr(
"Map Layers" ) );
1020 sGroups()->insert( QStringLiteral(
"Maps" ), tr(
"Maps" ) );
1021 sGroups()->insert( QStringLiteral(
"Math" ), tr(
"Math" ) );
1022 sGroups()->insert( QStringLiteral(
"Operators" ), tr(
"Operators" ) );
1023 sGroups()->insert( QStringLiteral(
"Rasters" ), tr(
"Rasters" ) );
1024 sGroups()->insert( QStringLiteral(
"Record and Attributes" ), tr(
"Record and Attributes" ) );
1025 sGroups()->insert( QStringLiteral(
"String" ), tr(
"String" ) );
1026 sGroups()->insert( QStringLiteral(
"Variables" ), tr(
"Variables" ) );
1027 sGroups()->insert( QStringLiteral(
"Recent (%1)" ), tr(
"Recent (%1)" ) );
1028 sGroups()->insert( QStringLiteral(
"UserGroup" ), tr(
"User expressions" ) );
1034 return sGroups()->value( name, name );
1039 const QString startToken = htmlOutput ? QStringLiteral(
"<i><" ) : QStringLiteral(
"<" );
1040 const QString endToken = htmlOutput ? QStringLiteral(
"></i>" ) : QStringLiteral(
">" );
1042 QgsGeometry geom = QgsExpressionUtils::getGeometry( value,
nullptr );
1047 return startToken + tr(
"empty geometry" ) + endToken;
1054 return startToken + tr(
"map layer" ) + endToken;
1056 else if ( !value.isValid() )
1058 return htmlOutput ? tr(
"<i>NULL</i>" ) : QString();
1060 else if ( value.userType() == qMetaTypeId< QgsFeature>() )
1064 return startToken + tr(
"feature: %1" ).arg( feat.
id() ) + endToken;
1066 else if ( value.userType() == qMetaTypeId< QgsCoordinateReferenceSystem>() )
1071 else if ( value.userType() == qMetaTypeId< QTimeZone>() )
1073 const QTimeZone tz = value.value<QTimeZone>();
1074#if QT_FEATURE_timezone > 0
1075 return startToken + tr(
"time zone: %1" ).arg( tz.isValid() ? tz.displayName( QTimeZone::GenericTime, QTimeZone::ShortName ) : tr(
"invalid" ) ) + endToken;
1077 QgsDebugError( QStringLiteral(
"Qt is built without Qt timezone support, timezone preview not available" ) );
1080 else if ( value.userType() == qMetaTypeId< QgsInterval>() )
1083 if ( interval.
days() > 1 )
1085 return startToken + tr(
"interval: %1 days" ).arg( interval.
days() ) + endToken;
1087 else if ( interval.
hours() > 1 )
1089 return startToken + tr(
"interval: %1 hours" ).arg( interval.
hours() ) + endToken;
1091 else if ( interval.
minutes() > 1 )
1093 return startToken + tr(
"interval: %1 minutes" ).arg( interval.
minutes() ) + endToken;
1097 return startToken + tr(
"interval: %1 seconds" ).arg( interval.
seconds() ) + endToken;
1100 else if ( value.userType() == qMetaTypeId< QgsGradientColorRamp>() )
1102 return startToken + tr(
"gradient ramp" ) + endToken;
1104 else if ( value.userType() == QMetaType::Type::QDate )
1106 const QDate dt = value.toDate();
1107 return startToken + tr(
"date: %1" ).arg( dt.toString( QStringLiteral(
"yyyy-MM-dd" ) ) ) + endToken;
1109 else if ( value.userType() == QMetaType::Type::QTime )
1111 const QTime tm = value.toTime();
1112 return startToken + tr(
"time: %1" ).arg( tm.toString( QStringLiteral(
"hh:mm:ss" ) ) ) + endToken;
1114 else if ( value.userType() == QMetaType::Type::QDateTime )
1116 const QDateTime dt = value.toDateTime();
1117 return startToken + tr(
"datetime: %1 (%2)" ).arg( dt.toString( QStringLiteral(
"yyyy-MM-dd hh:mm:ss" ) ), dt.timeZoneAbbreviation() ) + endToken;
1119 else if ( value.userType() == QMetaType::Type::QString )
1121 const QString previewString = value.toString();
1122 if ( previewString.length() > maximumPreviewLength + 3 )
1124 return tr(
"'%1…'" ).arg( previewString.left( maximumPreviewLength ) );
1128 return '\'' + previewString +
'\'';
1131 else if ( value.userType() == QMetaType::Type::QVariantMap )
1133 QString mapStr = QStringLiteral(
"{" );
1134 const QVariantMap map = value.toMap();
1136 for ( QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
1138 mapStr.append( separator );
1139 if ( separator.isEmpty() )
1140 separator = QStringLiteral(
"," );
1142 mapStr.append( QStringLiteral(
" '%1': %2" ).arg( it.key(),
formatPreviewString( it.value(), htmlOutput ) ) );
1143 if ( mapStr.length() > maximumPreviewLength - 3 )
1145 mapStr = tr(
"%1…" ).arg( mapStr.left( maximumPreviewLength - 2 ) );
1150 mapStr += QLatin1Char(
' ' );
1151 mapStr += QLatin1Char(
'}' );
1154 else if ( value.userType() == QMetaType::Type::QVariantList || value.userType() == QMetaType::Type::QStringList )
1156 QString listStr = QStringLiteral(
"[" );
1157 const QVariantList list = value.toList();
1159 for (
const QVariant &arrayValue : list )
1161 listStr.append( separator );
1162 if ( separator.isEmpty() )
1163 separator = QStringLiteral(
"," );
1165 listStr.append(
" " );
1167 if ( listStr.length() > maximumPreviewLength - 3 )
1169 listStr = QString( tr(
"%1…" ) ).arg( listStr.left( maximumPreviewLength - 2 ) );
1173 if ( !list.empty() )
1174 listStr += QLatin1Char(
' ' );
1175 listStr += QLatin1Char(
']' );
1178 else if ( value.type() == QVariant::Color )
1180 const QColor color = value.value<QColor>();
1182 if ( !color.isValid() )
1184 return tr(
"<i>Invalid</i>" );
1187 switch ( color.spec() )
1189 case QColor::Spec::Cmyk:
1190 return QStringLiteral(
"CMYKA: %1,%2,%3,%4,%5" )
1191 .arg( color.cyanF(), 0,
'f', 2 ).arg( color.magentaF(), 0,
'f', 2 )
1192 .arg( color.yellowF(), 0,
'f', 2 ).arg( color.blackF(), 0,
'f', 2 )
1193 .arg( color.alphaF(), 0,
'f', 2 );
1195 case QColor::Spec::Hsv:
1196 return QStringLiteral(
"HSVA: %1,%2,%3,%4" )
1197 .arg( color.hsvHueF(), 0,
'f', 2 ).arg( color.hsvSaturationF(), 0,
'f', 2 )
1198 .arg( color.valueF(), 0,
'f', 2 ).arg( color.alphaF(), 0,
'f', 2 );
1200 case QColor::Spec::Hsl:
1201 return QStringLiteral(
"HSLA: %1,%2,%3,%4" )
1202 .arg( color.hslHueF(), 0,
'f', 2 ).arg( color.hslSaturationF(), 0,
'f', 2 )
1203 .arg( color.lightnessF(), 0,
'f', 2 ).arg( color.alphaF(), 0,
'f', 2 );
1205 case QColor::Spec::Rgb:
1206 case QColor::Spec::ExtendedRgb:
1207 return QStringLiteral(
"RGBA: %1,%2,%3,%4" )
1208 .arg( color.redF(), 0,
'f', 2 ).arg( color.greenF(), 0,
'f', 2 )
1209 .arg( color.blueF(), 0,
'f', 2 ).arg( color.alphaF(), 0,
'f', 2 );
1211 case QColor::Spec::Invalid:
1212 return tr(
"<i>Invalid</i>" );
1214 QgsDebugError( QStringLiteral(
"Unknown color format: %1" ).arg( color.spec() ) );
1215 return tr(
"<i>Unknown color format: %1</i>" ).arg( color.spec() );
1217 else if ( value.userType() == QMetaType::Type::Int ||
1218 value.userType() == QMetaType::Type::UInt ||
1219 value.userType() == QMetaType::Type::LongLong ||
1220 value.userType() == QMetaType::Type::ULongLong ||
1221 value.userType() == QMetaType::Type::Double ||
1223 value.userType() ==
static_cast<QMetaType::Type
>( QMetaType::Float ) )
1225 return QgsExpressionUtils::toLocalizedString( value );
1229 QString str { value.toString() };
1230 if ( str.length() > maximumPreviewLength - 3 )
1232 str = tr(
"%1…" ).arg( str.left( maximumPreviewLength - 2 ) );
1243 expr = QStringLiteral(
"%1 IS NULL" ).arg(
quotedColumnRef( fieldName ) );
1244 else if ( fieldType == QMetaType::Type::UnknownType )
1270 if ( columnRef && literal )
1272 field = columnRef->
name();
1273 value = literal->
value();
1283 if ( expressions.empty() )
1289 for (
const QString &
expression : expressions )
1300 else if ( field != inField )
1316 if ( inOp->isNotIn() )
1325 inField = columnRef->
name();
1328 else if ( columnRef->
name() != inField )
1335 const QList<QgsExpressionNode *>
nodes = nodeList->list();
1353 QStringList orParts;
1358 orParts.append( collectOrs( leftOrOp->opLeft(), leftOrOp->opRight() ) );
1362 orParts.append( leftOrOp->dump() );
1367 orParts.append( leftInOp->dump() );
1378 orParts.append( collectOrs( rightOrOp->opLeft(), rightOrOp->opRight() ) );
1382 orParts.append( rightOrOp->dump() );
1387 orParts.append( rightInOp->dump() );
1400 const QStringList orParts = collectOrs( orOp->opLeft(), orOp->opRight() );
1401 if ( orParts.isEmpty() )
1407 QString orPartsResult;
1424 const QString innerInfield { inOpInner->node()->referencedColumns().values().first() };
1428 inField = innerInfield;
1432 if ( innerInfield != inField )
1438 const auto constInnerValuesList { inOpInner->list()->list() };
1439 for (
const auto &innerInValueNode : std::as_const( constInnerValuesList ) )
1441 values.append( innerInValueNode->dump() );
1468 result = QStringLiteral(
"%1 IN (%2)" ).arg(
quotedColumnRef( inField ), values.join(
',' ) );
1474 return d->mRootNode.get();
1489 if ( attrIndex >= 0 )
1496 const QString fieldName = qgis::down_cast<const QgsExpressionNodeColumnRef *>( candidate.
rootNode() )->name();
1508 if ( !
expression.contains(
'\"' ) && fieldIndex != -1 )
1521 if ( !d->mRootNode )
1522 return QList<const QgsExpressionNode *>();
1524 return d->mRootNode->nodes();
DistanceUnit
Units of distance.
@ Unknown
Unknown distance unit.
@ Unknown
Unknown areal unit.
static QString geoNone()
Constant that holds the string representation for "No ellipse/No CRS".
Qgis::WkbType wkbType() const
Returns the WKB type of the geometry.
Represents a coordinate reference system (CRS).
QString userFriendlyIdentifier(Qgis::CrsIdentifierType type=Qgis::CrsIdentifierType::MediumString) const
Returns a user friendly identifier for the CRS.
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.
An abstract base class for defining QgsExpression functions.
A binary expression operator, which operates on two values.
An expression node which takes its 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.
virtual QgsExpressionNode::NodeType nodeType() const =0
Gets the type of this node.
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.
QgsExpression(const QString &expr)
Creates a new expression based on the provided string.
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 dataset.
static Q_INVOKABLE 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...
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.