37 return *sFunctionHelpTexts();
52 d->mEvalErrorString = QString();
54 d->mIsPrepared =
false;
59 if ( !d->mExp.isNull() )
67 return QStringLiteral(
"\"%1\"" ).arg( name.replace(
'\"', QLatin1String(
"\"\"" ) ) );
72 text.replace(
'\'', QLatin1String(
"''" ) );
73 text.replace(
'\\', QLatin1String(
"\\\\" ) );
74 text.replace(
'\n', QLatin1String(
"\\n" ) );
75 text.replace(
'\t', QLatin1String(
"\\t" ) );
76 return QStringLiteral(
"'%1'" ).arg( text );
87 return QStringLiteral(
"NULL" );
92 case QVariant::LongLong:
93 case QVariant::Double:
94 return value.toString();
97 return value.toBool() ? QStringLiteral(
"TRUE" ) : QStringLiteral(
"FALSE" );
101 QStringList quotedValues;
102 const QVariantList values = value.toList();
103 quotedValues.reserve( values.count() );
104 for (
const QVariant &v : values )
108 return QStringLiteral(
"array( %1 )" ).arg( quotedValues.join( QStringLiteral(
", " ) ) );
112 case QVariant::String:
126 for (
int i = 0; i < count; i++ )
131 for (
const QString &alias : aliases )
133 if ( QString::compare( name, alias, Qt::CaseInsensitive ) == 0 )
147 : d( new QgsExpressionPrivate )
149 d->mRootNode =
::parseExpression( expr, d->mParserErrorString, d->mParserErrors );
151 Q_ASSERT( !d->mParserErrorString.isNull() || d->mRootNode );
162 if (
this != &other )
164 if ( !d->ref.deref() )
175 QgsExpression::operator QString()
const
181 : d( new QgsExpressionPrivate )
188 if ( !d->ref.deref() )
194 return ( d == other.d || d->mExp == other.d->mExp );
204 return d->mParserErrors.count() > 0;
209 return d->mParserErrorString;
214 return d->mParserErrors;
220 return QSet<QString>();
222 return d->mRootNode->referencedColumns();
228 return QSet<QString>();
230 return d->mRootNode->referencedVariables();
236 return QSet<QString>();
238 return d->mRootNode->referencedFunctions();
246 const QSet<QString> referencedFields = d->mRootNode->referencedColumns();
247 QSet<int> referencedIndexes;
249 for (
const QString &fieldName : referencedFields )
259 referencedIndexes << idx;
263 return referencedIndexes;
270 return d->mRootNode->needsGeometry();
276 if ( context && ! d->mCalc )
280 d->mDaEllipsoid = context->
variable( QStringLiteral(
"project_ellipsoid" ) ).toString();
282 d->mDaTransformContext = context->
variable( QStringLiteral(
"_project_transform_context" ) ).value<QgsCoordinateTransformContext>();
288 QString distanceUnitsStr = context->
variable( QStringLiteral(
"project_distance_units" ) ).toString();
289 if ( ! distanceUnitsStr.isEmpty() )
296 QString areaUnitsStr = context->
variable( QStringLiteral(
"project_area_units" ) ).toString();
297 if ( ! areaUnitsStr.isEmpty() )
302 void QgsExpression::detach()
308 ( void )d->ref.deref();
310 d =
new QgsExpressionPrivate( *d );
318 d->mCalc = std::shared_ptr<QgsDistanceArea>(
new QgsDistanceArea( *calc ) );
326 d->mEvalErrorString = QString();
332 d->mRootNode =
::parseExpression( d->mExp, d->mParserErrorString, d->mParserErrors );
337 d->mEvalErrorString = tr(
"No root node! Parsing failed?" );
341 initGeomCalculator( context );
342 d->mIsPrepared =
true;
343 return d->mRootNode->prepare(
this, context );
348 d->mEvalErrorString = QString();
351 d->mEvalErrorString = tr(
"No root node! Parsing failed?" );
360 d->mEvalErrorString = QString();
363 d->mEvalErrorString = tr(
"No root node! Parsing failed?" );
367 if ( ! d->mIsPrepared )
371 return d->mRootNode->eval(
this, context );
376 return !d->mEvalErrorString.isNull();
381 return d->mEvalErrorString;
386 d->mEvalErrorString = str;
394 return d->mRootNode->dump();
399 if ( !d->mCalc && d->mDaCrs.isValid() )
403 d->mCalc->setEllipsoid( d->mDaEllipsoid.isEmpty() ?
geoNone() : d->mDaEllipsoid );
404 d->mCalc->setSourceCrs( d->mDaCrs, d->mDaTransformContext );
407 return d->mCalc.get();
412 return d->mDistanceUnit;
417 d->mDistanceUnit = unit;
435 while ( index < action.size() )
437 static const QRegularExpression sRegEx{ QStringLiteral(
"\\[%(.*?)%\\]" ), QRegularExpression::MultilineOption | QRegularExpression::DotMatchesEverythingOption };
439 const QRegularExpressionMatch match = sRegEx.match( action, index );
440 if ( !match.hasMatch() )
443 const int pos = action.indexOf( sRegEx, index );
444 const int start = index;
445 index = pos + match.capturedLength( 0 );
446 const QString toReplace = match.captured( 1 ).trimmed();
453 expr_action += action.midRef( start, index - start );
463 QVariant result = exp.
evaluate( context );
468 expr_action += action.midRef( start, index - start );
473 expr_action += action.mid( start, pos - start ) + result.toString();
476 expr_action += action.midRef( index );
483 QSet<QString> variables;
485 while ( index < text.size() )
487 QRegExp rx = QRegExp(
"\\[%([^\\]]+)%\\]" );
489 int pos = rx.indexIn( text, index );
493 index = pos + rx.matchedLength();
494 QString to_replace = rx.cap( 1 ).trimmed();
509 double convertedValue = QLocale().toDouble( text, &ok );
512 return convertedValue;
522 QVariant result = expr.
evaluate( &context );
523 convertedValue = result.toDouble( &ok );
526 return fallbackValue;
528 return convertedValue;
533 QgsExpression::initFunctionHelp();
535 if ( !sFunctionHelpTexts()->contains( name ) )
536 return tr(
"function help for %1 missing" ).arg( name );
538 const Help &f = ( *sFunctionHelpTexts() )[ name ];
541 if ( f.mType == tr(
"group" ) )
543 name =
group( name );
544 name = name.toLower();
547 name = name.toHtmlEscaped();
549 QString helpContents( QStringLiteral(
"<h3>%1</h3>\n<div class=\"description\"><p>%2</p></div>" )
550 .arg( tr(
"%1 %2" ).arg( f.mType, name ),
553 for (
const HelpVariant &v : qgis::as_const( f.mVariants ) )
555 if ( f.mVariants.size() > 1 )
557 helpContents += QStringLiteral(
"<h3>%1</h3>\n<div class=\"description\">%2</p></div>" ).arg( v.mName, v.mDescription );
560 if ( f.mType != tr(
"group" ) && f.mType != tr(
"expression" ) )
561 helpContents += QStringLiteral(
"<h4>%1</h4>\n<div class=\"syntax\">\n" ).arg( tr(
"Syntax" ) );
563 if ( f.mType == tr(
"operator" ) )
565 if ( v.mArguments.size() == 1 )
567 helpContents += QStringLiteral(
"<code><span class=\"functionname\">%1</span> <span class=\"argument\">%2</span></code>" )
568 .arg( name, v.mArguments[0].mArg );
570 else if ( v.mArguments.size() == 2 )
572 helpContents += QStringLiteral(
"<code><span class=\"argument\">%1</span> <span class=\"functionname\">%2</span> <span class=\"argument\">%3</span></code>" )
573 .arg( v.mArguments[0].mArg, name, v.mArguments[1].mArg );
576 else if ( f.mType != tr(
"group" ) && f.mType != tr(
"expression" ) )
578 helpContents += QStringLiteral(
"<code><span class=\"functionname\">%1</span>" ).arg( name );
580 bool hasOptionalArgs =
false;
582 if ( f.mType == tr(
"function" ) && ( f.mName[0] !=
'$' || !v.mArguments.isEmpty() || v.mVariableLenArguments ) )
587 for (
const HelpArg &a : qgis::as_const( v.mArguments ) )
593 hasOptionalArgs =
true;
594 helpContents += QStringLiteral(
"[" );
597 helpContents += delim;
598 helpContents += QStringLiteral(
"<span class=\"argument\">%2%3</span>" ).arg(
600 a.mDefaultVal.isEmpty() ? QString() :
'=' + a.mDefaultVal
604 helpContents += QStringLiteral(
"]" );
606 delim = QStringLiteral(
"," );
609 if ( v.mVariableLenArguments )
611 helpContents += QChar( 0x2026 );
617 helpContents += QLatin1String(
"</code>" );
619 if ( hasOptionalArgs )
621 helpContents += QLatin1String(
"<br/><br/>" ) + tr(
"[ ] marks optional components" );
625 if ( !v.mArguments.isEmpty() )
627 helpContents += QStringLiteral(
"<h4>%1</h4>\n<div class=\"arguments\">\n<table>" ).arg( tr(
"Arguments" ) );
629 for (
const HelpArg &a : qgis::as_const( v.mArguments ) )
634 helpContents += QStringLiteral(
"<tr><td class=\"argument\">%1</td><td>%2</td></tr>" ).arg( a.mArg, a.mDescription );
637 helpContents += QLatin1String(
"</table>\n</div>\n" );
640 if ( !v.mExamples.isEmpty() )
642 helpContents += QStringLiteral(
"<h4>%1</h4>\n<div class=\"examples\">\n<ul>\n" ).arg( tr(
"Examples" ) );
644 for (
const HelpExample &e : qgis::as_const( v.mExamples ) )
646 helpContents +=
"<li><code>" + e.mExpression +
"</code> → <code>" + e.mReturns +
"</code>";
648 if ( !e.mNote.isEmpty() )
649 helpContents += QStringLiteral(
" (%1)" ).arg( e.mNote );
651 helpContents += QLatin1String(
"</li>\n" );
654 helpContents += QLatin1String(
"</ul>\n</div>\n" );
657 if ( !v.mNotes.isEmpty() )
659 helpContents += QStringLiteral(
"<h4>%1</h4>\n<div class=\"notes\"><p>%2</p></div>\n" ).arg( tr(
"Notes" ), v.mNotes );
668 QStringList
tags = QStringList();
670 QgsExpression::initFunctionHelp();
672 if ( sFunctionHelpTexts()->contains( name ) )
674 const Help &f = ( *sFunctionHelpTexts() )[ name ];
676 for (
const HelpVariant &v : qgis::as_const( f.mVariants ) )
685 void QgsExpression::initVariableHelp()
687 if ( !sVariableHelpTexts()->isEmpty() )
691 sVariableHelpTexts()->insert( QStringLiteral(
"qgis_version" ), QCoreApplication::translate(
"variable_help",
"Current QGIS version string." ) );
692 sVariableHelpTexts()->insert( QStringLiteral(
"qgis_version_no" ), QCoreApplication::translate(
"variable_help",
"Current QGIS version number." ) );
693 sVariableHelpTexts()->insert( QStringLiteral(
"qgis_release_name" ), QCoreApplication::translate(
"variable_help",
"Current QGIS release name." ) );
694 sVariableHelpTexts()->insert( QStringLiteral(
"qgis_short_version" ), QCoreApplication::translate(
"variable_help",
"Short QGIS version string." ) );
695 sVariableHelpTexts()->insert( QStringLiteral(
"qgis_os_name" ), QCoreApplication::translate(
"variable_help",
"Operating system name, e.g., 'windows', 'linux' or 'osx'." ) );
696 sVariableHelpTexts()->insert( QStringLiteral(
"qgis_platform" ), QCoreApplication::translate(
"variable_help",
"QGIS platform, e.g., 'desktop' or 'server'." ) );
697 sVariableHelpTexts()->insert( QStringLiteral(
"qgis_locale" ), QCoreApplication::translate(
"variable_help",
"Two letter identifier for current QGIS locale." ) );
698 sVariableHelpTexts()->insert( QStringLiteral(
"user_account_name" ), QCoreApplication::translate(
"variable_help",
"Current user's operating system account name." ) );
699 sVariableHelpTexts()->insert( QStringLiteral(
"user_full_name" ), QCoreApplication::translate(
"variable_help",
"Current user's operating system user name (if available)." ) );
702 sVariableHelpTexts()->insert( QStringLiteral(
"project_title" ), QCoreApplication::translate(
"variable_help",
"Title of current project." ) );
703 sVariableHelpTexts()->insert( QStringLiteral(
"project_path" ), QCoreApplication::translate(
"variable_help",
"Full path (including file name) of current project." ) );
704 sVariableHelpTexts()->insert( QStringLiteral(
"project_folder" ), QCoreApplication::translate(
"variable_help",
"Folder for current project." ) );
705 sVariableHelpTexts()->insert( QStringLiteral(
"project_filename" ), QCoreApplication::translate(
"variable_help",
"Filename of current project." ) );
706 sVariableHelpTexts()->insert( QStringLiteral(
"project_basename" ), QCoreApplication::translate(
"variable_help",
"Base name of current project's filename (without path and extension)." ) );
707 sVariableHelpTexts()->insert( QStringLiteral(
"project_home" ), QCoreApplication::translate(
"variable_help",
"Home path of current project." ) );
708 sVariableHelpTexts()->insert( QStringLiteral(
"project_crs" ), QCoreApplication::translate(
"variable_help",
"Coordinate reference system of project (e.g., 'EPSG:4326')." ) );
709 sVariableHelpTexts()->insert( QStringLiteral(
"project_crs_definition" ), QCoreApplication::translate(
"variable_help",
"Coordinate reference system of project (full definition)." ) );
710 sVariableHelpTexts()->insert( QStringLiteral(
"project_units" ), QCoreApplication::translate(
"variable_help",
"Unit of the project's CRS." ) );
711 sVariableHelpTexts()->insert( QStringLiteral(
"project_crs_description" ), QCoreApplication::translate(
"variable_help",
"Name of the coordinate reference system of the project." ) );
712 sVariableHelpTexts()->insert( QStringLiteral(
"project_crs_acronym" ), QCoreApplication::translate(
"variable_help",
"Acronym of the coordinate reference system of the project." ) );
713 sVariableHelpTexts()->insert( QStringLiteral(
"project_crs_ellipsoid" ), QCoreApplication::translate(
"variable_help",
"Acronym of the ellipsoid of the coordinate reference system of the project." ) );
714 sVariableHelpTexts()->insert( QStringLiteral(
"project_crs_proj4" ), QCoreApplication::translate(
"variable_help",
"Proj4 definition of the coordinate reference system of the project." ) );
715 sVariableHelpTexts()->insert( QStringLiteral(
"project_crs_wkt" ), QCoreApplication::translate(
"variable_help",
"WKT definition of the coordinate reference system of the project." ) );
716 sVariableHelpTexts()->insert( QStringLiteral(
"project_author" ), QCoreApplication::translate(
"variable_help",
"Project author, taken from project metadata." ) );
717 sVariableHelpTexts()->insert( QStringLiteral(
"project_abstract" ), QCoreApplication::translate(
"variable_help",
"Project abstract, taken from project metadata." ) );
718 sVariableHelpTexts()->insert( QStringLiteral(
"project_creation_date" ), QCoreApplication::translate(
"variable_help",
"Project creation date, taken from project metadata." ) );
719 sVariableHelpTexts()->insert( QStringLiteral(
"project_identifier" ), QCoreApplication::translate(
"variable_help",
"Project identifier, taken from project metadata." ) );
720 sVariableHelpTexts()->insert( QStringLiteral(
"project_last_saved" ), QCoreApplication::translate(
"variable_help",
"Date/time when project was last saved." ) );
721 sVariableHelpTexts()->insert( QStringLiteral(
"project_keywords" ), QCoreApplication::translate(
"variable_help",
"Project keywords, taken from project metadata." ) );
722 sVariableHelpTexts()->insert( QStringLiteral(
"project_area_units" ), QCoreApplication::translate(
"variable_help",
"Area unit for current project, used when calculating areas of geometries." ) );
723 sVariableHelpTexts()->insert( QStringLiteral(
"project_distance_units" ), QCoreApplication::translate(
"variable_help",
"Distance unit for current project, used when calculating lengths of geometries." ) );
724 sVariableHelpTexts()->insert( QStringLiteral(
"project_ellipsoid" ), QCoreApplication::translate(
"variable_help",
"Name of ellipsoid of current project, used when calculating geodetic areas and lengths of geometries." ) );
725 sVariableHelpTexts()->insert( QStringLiteral(
"layer_ids" ), QCoreApplication::translate(
"variable_help",
"List of all map layer IDs from the current project." ) );
726 sVariableHelpTexts()->insert( QStringLiteral(
"layers" ), QCoreApplication::translate(
"variable_help",
"List of all map layers from the current project." ) );
729 sVariableHelpTexts()->insert( QStringLiteral(
"layer_name" ), QCoreApplication::translate(
"variable_help",
"Name of current layer." ) );
730 sVariableHelpTexts()->insert( QStringLiteral(
"layer_id" ), QCoreApplication::translate(
"variable_help",
"ID of current layer." ) );
731 sVariableHelpTexts()->insert( QStringLiteral(
"layer" ), QCoreApplication::translate(
"variable_help",
"The current layer." ) );
734 sVariableHelpTexts()->insert( QStringLiteral(
"layout_name" ), QCoreApplication::translate(
"variable_help",
"Name of composition." ) );
735 sVariableHelpTexts()->insert( QStringLiteral(
"layout_numpages" ), QCoreApplication::translate(
"variable_help",
"Number of pages in composition." ) );
736 sVariableHelpTexts()->insert( QStringLiteral(
"layout_page" ), QCoreApplication::translate(
"variable_help",
"Current page number in composition." ) );
737 sVariableHelpTexts()->insert( QStringLiteral(
"layout_pageheight" ), QCoreApplication::translate(
"variable_help",
"Composition page height in mm." ) );
738 sVariableHelpTexts()->insert( QStringLiteral(
"layout_pagewidth" ), QCoreApplication::translate(
"variable_help",
"Composition page width in mm." ) );
739 sVariableHelpTexts()->insert( QStringLiteral(
"layout_dpi" ), QCoreApplication::translate(
"variable_help",
"Composition resolution (DPI)." ) );
742 sVariableHelpTexts()->insert( QStringLiteral(
"atlas_layerid" ), QCoreApplication::translate(
"variable_help",
"Current atlas coverage layer ID." ) );
743 sVariableHelpTexts()->insert( QStringLiteral(
"atlas_layername" ), QCoreApplication::translate(
"variable_help",
"Current atlas coverage layer name." ) );
744 sVariableHelpTexts()->insert( QStringLiteral(
"atlas_totalfeatures" ), QCoreApplication::translate(
"variable_help",
"Total number of features in atlas." ) );
745 sVariableHelpTexts()->insert( QStringLiteral(
"atlas_featurenumber" ), QCoreApplication::translate(
"variable_help",
"Current atlas feature number." ) );
746 sVariableHelpTexts()->insert( QStringLiteral(
"atlas_filename" ), QCoreApplication::translate(
"variable_help",
"Current atlas file name." ) );
747 sVariableHelpTexts()->insert( QStringLiteral(
"atlas_pagename" ), QCoreApplication::translate(
"variable_help",
"Current atlas page name." ) );
748 sVariableHelpTexts()->insert( QStringLiteral(
"atlas_feature" ), QCoreApplication::translate(
"variable_help",
"Current atlas feature (as feature object)." ) );
749 sVariableHelpTexts()->insert( QStringLiteral(
"atlas_featureid" ), QCoreApplication::translate(
"variable_help",
"Current atlas feature ID." ) );
750 sVariableHelpTexts()->insert( QStringLiteral(
"atlas_geometry" ), QCoreApplication::translate(
"variable_help",
"Current atlas feature geometry." ) );
753 sVariableHelpTexts()->insert( QStringLiteral(
"item_id" ), QCoreApplication::translate(
"variable_help",
"Layout item user ID (not necessarily unique)." ) );
754 sVariableHelpTexts()->insert( QStringLiteral(
"item_uuid" ), QCoreApplication::translate(
"variable_help",
"layout item unique ID." ) );
755 sVariableHelpTexts()->insert( QStringLiteral(
"item_left" ), QCoreApplication::translate(
"variable_help",
"Left position of layout item (in mm)." ) );
756 sVariableHelpTexts()->insert( QStringLiteral(
"item_top" ), QCoreApplication::translate(
"variable_help",
"Top position of layout item (in mm)." ) );
757 sVariableHelpTexts()->insert( QStringLiteral(
"item_width" ), QCoreApplication::translate(
"variable_help",
"Width of layout item (in mm)." ) );
758 sVariableHelpTexts()->insert( QStringLiteral(
"item_height" ), QCoreApplication::translate(
"variable_help",
"Height of layout item (in mm)." ) );
761 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." ) );
762 sVariableHelpTexts()->insert( QStringLiteral(
"map_rotation" ), QCoreApplication::translate(
"variable_help",
"Current rotation of map." ) );
763 sVariableHelpTexts()->insert( QStringLiteral(
"map_scale" ), QCoreApplication::translate(
"variable_help",
"Current scale of map." ) );
764 sVariableHelpTexts()->insert( QStringLiteral(
"map_extent" ), QCoreApplication::translate(
"variable_help",
"Geometry representing the current extent of the map." ) );
765 sVariableHelpTexts()->insert( QStringLiteral(
"map_extent_center" ), QCoreApplication::translate(
"variable_help",
"Center of map." ) );
766 sVariableHelpTexts()->insert( QStringLiteral(
"map_extent_width" ), QCoreApplication::translate(
"variable_help",
"Width of map." ) );
767 sVariableHelpTexts()->insert( QStringLiteral(
"map_extent_height" ), QCoreApplication::translate(
"variable_help",
"Height of map." ) );
768 sVariableHelpTexts()->insert( QStringLiteral(
"map_crs" ), QCoreApplication::translate(
"variable_help",
"Coordinate reference system of map (e.g., 'EPSG:4326')." ) );
769 sVariableHelpTexts()->insert( QStringLiteral(
"map_crs_description" ), QCoreApplication::translate(
"variable_help",
"Name of the coordinate reference system of the map." ) );
770 sVariableHelpTexts()->insert( QStringLiteral(
"map_units" ), QCoreApplication::translate(
"variable_help",
"Units for map measurements." ) );
771 sVariableHelpTexts()->insert( QStringLiteral(
"map_crs_definition" ), QCoreApplication::translate(
"variable_help",
"Coordinate reference system of the map (full definition)." ) );
772 sVariableHelpTexts()->insert( QStringLiteral(
"map_crs_acronym" ), QCoreApplication::translate(
"variable_help",
"Acronym of the coordinate reference system of the map." ) );
773 sVariableHelpTexts()->insert( QStringLiteral(
"map_crs_ellipsoid" ), QCoreApplication::translate(
"variable_help",
"Acronym of the ellipsoid of the coordinate reference system of the map." ) );
774 sVariableHelpTexts()->insert( QStringLiteral(
"map_crs_proj4" ), QCoreApplication::translate(
"variable_help",
"Proj4 definition of the coordinate reference system of the map." ) );
775 sVariableHelpTexts()->insert( QStringLiteral(
"map_crs_wkt" ), QCoreApplication::translate(
"variable_help",
"WKT definition of the coordinate reference system of the map." ) );
776 sVariableHelpTexts()->insert( QStringLiteral(
"map_layer_ids" ), QCoreApplication::translate(
"variable_help",
"List of map layer IDs visible in the map." ) );
777 sVariableHelpTexts()->insert( QStringLiteral(
"map_layers" ), QCoreApplication::translate(
"variable_help",
"List of map layers visible in the map." ) );
779 sVariableHelpTexts()->insert( QStringLiteral(
"map_start_time" ), QCoreApplication::translate(
"variable_help",
"Start of the map's temporal time range (as a datetime value)" ) );
780 sVariableHelpTexts()->insert( QStringLiteral(
"map_end_time" ), QCoreApplication::translate(
"variable_help",
"End of the map's temporal time range (as a datetime value)" ) );
781 sVariableHelpTexts()->insert( QStringLiteral(
"map_interval" ), QCoreApplication::translate(
"variable_help",
"Duration of the map's temporal time range (as an interval value)" ) );
783 sVariableHelpTexts()->insert( QStringLiteral(
"frame_rate" ), QCoreApplication::translate(
"variable_help",
"Number of frames per second during animation playback" ) );
784 sVariableHelpTexts()->insert( QStringLiteral(
"frame_number" ), QCoreApplication::translate(
"variable_help",
"Current frame number during animation playback" ) );
785 sVariableHelpTexts()->insert( QStringLiteral(
"frame_duration" ), QCoreApplication::translate(
"variable_help",
"Temporal duration of each animation frame (as an interval value)" ) );
786 sVariableHelpTexts()->insert( QStringLiteral(
"animation_start_time" ), QCoreApplication::translate(
"variable_help",
"Start of the animation's overall temporal time range (as a datetime value)" ) );
787 sVariableHelpTexts()->insert( QStringLiteral(
"animation_end_time" ), QCoreApplication::translate(
"variable_help",
"End of the animation's overall temporal time range (as a datetime value)" ) );
788 sVariableHelpTexts()->insert( QStringLiteral(
"animation_interval" ), QCoreApplication::translate(
"variable_help",
"Duration of the animation's overall temporal time range (as an interval value)" ) );
791 sVariableHelpTexts()->insert( QStringLiteral(
"zoom_level" ), QCoreApplication::translate(
"variable_help",
"Zoom level of the tile that is being rendered (derived from the current map scale). Normally in interval [0, 20]." ) );
793 sVariableHelpTexts()->insert( QStringLiteral(
"row_number" ), QCoreApplication::translate(
"variable_help",
"Stores the number of the current row." ) );
794 sVariableHelpTexts()->insert( QStringLiteral(
"grid_number" ), QCoreApplication::translate(
"variable_help",
"Current grid annotation value." ) );
795 sVariableHelpTexts()->insert( QStringLiteral(
"grid_axis" ), QCoreApplication::translate(
"variable_help",
"Current grid annotation axis (e.g., 'x' for longitude, 'y' for latitude)." ) );
798 sVariableHelpTexts()->insert( QStringLiteral(
"canvas_cursor_point" ), QCoreApplication::translate(
"variable_help",
"Last cursor position on the canvas in the project's geographical coordinates." ) );
801 sVariableHelpTexts()->insert( QStringLiteral(
"legend_title" ), QCoreApplication::translate(
"variable_help",
"Title of the legend." ) );
802 sVariableHelpTexts()->insert( QStringLiteral(
"legend_column_count" ), QCoreApplication::translate(
"variable_help",
"Number of column in the legend." ) );
803 sVariableHelpTexts()->insert( QStringLiteral(
"legend_split_layers" ), QCoreApplication::translate(
"variable_help",
"Boolean indicating if layers can be split in the legend." ) );
804 sVariableHelpTexts()->insert( QStringLiteral(
"legend_wrap_string" ), QCoreApplication::translate(
"variable_help",
"Characters used to wrap the legend text." ) );
805 sVariableHelpTexts()->insert( QStringLiteral(
"legend_filter_by_map" ), QCoreApplication::translate(
"variable_help",
"Boolean indicating if the content of the legend is filtered by the map." ) );
806 sVariableHelpTexts()->insert( QStringLiteral(
"legend_filter_out_atlas" ), QCoreApplication::translate(
"variable_help",
"Boolean indicating if the Atlas is filtered out of the legend." ) );
809 sVariableHelpTexts()->insert( QStringLiteral(
"scale_value" ), QCoreApplication::translate(
"variable_help",
"Current scale bar distance value." ) );
812 sVariableHelpTexts()->insert( QStringLiteral(
"snapping_results" ), QCoreApplication::translate(
"variable_help",
813 "<p>An array with an item for each snapped point.</p>"
814 "<p>Each item is a map with the following keys:</p>"
816 "<dt>valid</dt><dd>Boolean that indicates if the snapping result is valid</dd>"
817 "<dt>layer</dt><dd>The layer on which the snapped feature is</dd>"
818 "<dt>feature_id</dt><dd>The feature id of the snapped feature</dd>"
819 "<dt>vertex_index</dt><dd>The index of the snapped vertex</dd>"
820 "<dt>distance</dt><dd>The distance between the mouse cursor and the snapped point at the time of snapping</dd>"
825 sVariableHelpTexts()->insert( QStringLiteral(
"geometry_part_count" ), QCoreApplication::translate(
"variable_help",
"Number of parts in rendered feature's geometry." ) );
826 sVariableHelpTexts()->insert( QStringLiteral(
"geometry_part_num" ), QCoreApplication::translate(
"variable_help",
"Current geometry part number for feature being rendered." ) );
827 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." ) );
828 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." ) );
830 sVariableHelpTexts()->insert( QStringLiteral(
"symbol_color" ), QCoreApplication::translate(
"symbol_color",
"Color of symbol used to render the feature." ) );
831 sVariableHelpTexts()->insert( QStringLiteral(
"symbol_angle" ), QCoreApplication::translate(
"symbol_angle",
"Angle of symbol used to render the feature (valid for marker symbols only)." ) );
832 sVariableHelpTexts()->insert( QStringLiteral(
"symbol_layer_count" ), QCoreApplication::translate(
"symbol_layer_count",
"Total number of symbol layers in the symbol." ) );
833 sVariableHelpTexts()->insert( QStringLiteral(
"symbol_layer_index" ), QCoreApplication::translate(
"symbol_layer_index",
"Current symbol layer index." ) );
834 sVariableHelpTexts()->insert( QStringLiteral(
"symbol_marker_row" ), QCoreApplication::translate(
"symbol_marker_row",
"Row number for marker (valid for point pattern fills only)." ) );
835 sVariableHelpTexts()->insert( QStringLiteral(
"symbol_marker_column" ), QCoreApplication::translate(
"symbol_marker_column",
"Column number for marker (valid for point pattern fills only)." ) );
837 sVariableHelpTexts()->insert( QStringLiteral(
"symbol_label" ), QCoreApplication::translate(
"symbol_label",
"Label for the symbol (either a user defined label or the default autogenerated label)." ) );
838 sVariableHelpTexts()->insert( QStringLiteral(
"symbol_id" ), QCoreApplication::translate(
"symbol_id",
"Internal ID of the symbol." ) );
839 sVariableHelpTexts()->insert( QStringLiteral(
"symbol_count" ), QCoreApplication::translate(
"symbol_count",
"Total number of features represented by the symbol." ) );
842 sVariableHelpTexts()->insert( QStringLiteral(
"cluster_color" ), QCoreApplication::translate(
"cluster_color",
"Color of symbols within a cluster, or NULL if symbols have mixed colors." ) );
843 sVariableHelpTexts()->insert( QStringLiteral(
"cluster_size" ), QCoreApplication::translate(
"cluster_size",
"Number of symbols contained within a cluster." ) );
846 sVariableHelpTexts()->insert( QStringLiteral(
"algorithm_id" ), QCoreApplication::translate(
"algorithm_id",
"Unique ID for algorithm." ) );
847 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)." ) );
848 sVariableHelpTexts()->insert( QStringLiteral(
"model_folder" ), QCoreApplication::translate(
"variable_help",
"Folder containing current model (or project folder if model is embedded in a project)." ) );
849 sVariableHelpTexts()->insert( QStringLiteral(
"model_name" ), QCoreApplication::translate(
"variable_help",
"Name of current model." ) );
850 sVariableHelpTexts()->insert( QStringLiteral(
"model_group" ), QCoreApplication::translate(
"variable_help",
"Group for current model." ) );
851 sVariableHelpTexts()->insert( QStringLiteral(
"fullextent_minx" ), QCoreApplication::translate(
"fullextent_minx",
"Minimum x-value from full canvas extent (including all layers)." ) );
852 sVariableHelpTexts()->insert( QStringLiteral(
"fullextent_miny" ), QCoreApplication::translate(
"fullextent_miny",
"Minimum y-value from full canvas extent (including all layers)." ) );
853 sVariableHelpTexts()->insert( QStringLiteral(
"fullextent_maxx" ), QCoreApplication::translate(
"fullextent_maxx",
"Maximum x-value from full canvas extent (including all layers)." ) );
854 sVariableHelpTexts()->insert( QStringLiteral(
"fullextent_maxy" ), QCoreApplication::translate(
"fullextent_maxy",
"Maximum y-value from full canvas extent (including all layers)." ) );
857 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)." ) );
860 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." ) );
861 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." ) );
864 sVariableHelpTexts()->insert( QStringLiteral(
"current_parent_geometry" ), QCoreApplication::translate(
"current_parent_geometry",
865 "Only usable in an embedded form context, "
866 "represents the geometry of the feature currently being edited in the parent form.\n"
867 "Can be used in a form/row context to filter the related features using a value "
868 "from the feature currently edited in the parent form, to make sure that the filter "
869 "still works with standalone forms it is recommended to wrap this variable in a "
871 sVariableHelpTexts()->insert( QStringLiteral(
"current_parent_feature" ), QCoreApplication::translate(
"current_parent_feature",
872 "Only usable in an embedded form context, "
873 "represents the feature currently being edited in the parent form.\n"
874 "Can be used in a form/row context to filter the related features using a value "
875 "from the feature currently edited in the parent form, to make sure that the filter "
876 "still works with standalone forms it is recommended to wrap this variable in a "
880 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." ) );
885 QgsExpression::initVariableHelp();
886 return sVariableHelpTexts()->value( variableName, QString() );
891 QString text = !description.isEmpty() ? QStringLiteral(
"<p>%1</p>" ).arg( description ) : QString();
895 if ( !value.isValid() )
897 valueString = QCoreApplication::translate(
"variable_help",
"not set" );
903 text.append( QCoreApplication::translate(
"variable_help",
"<p>Current value: %1</p>" ).arg( valueString ) );
910 if ( sGroups()->isEmpty() )
912 sGroups()->insert( QStringLiteral(
"Aggregates" ), tr(
"Aggregates" ) );
913 sGroups()->insert( QStringLiteral(
"Arrays" ), tr(
"Arrays" ) );
914 sGroups()->insert( QStringLiteral(
"Color" ), tr(
"Color" ) );
915 sGroups()->insert( QStringLiteral(
"Conditionals" ), tr(
"Conditionals" ) );
916 sGroups()->insert( QStringLiteral(
"Conversions" ), tr(
"Conversions" ) );
917 sGroups()->insert( QStringLiteral(
"Date and Time" ), tr(
"Date and Time" ) );
918 sGroups()->insert( QStringLiteral(
"Fields and Values" ), tr(
"Fields and Values" ) );
919 sGroups()->insert( QStringLiteral(
"Files and Paths" ), tr(
"Files and Paths" ) );
920 sGroups()->insert( QStringLiteral(
"Fuzzy Matching" ), tr(
"Fuzzy Matching" ) );
921 sGroups()->insert( QStringLiteral(
"General" ), tr(
"General" ) );
922 sGroups()->insert( QStringLiteral(
"GeometryGroup" ), tr(
"Geometry" ) );
923 sGroups()->insert( QStringLiteral(
"Map Layers" ), tr(
"Map Layers" ) );
924 sGroups()->insert( QStringLiteral(
"Maps" ), tr(
"Maps" ) );
925 sGroups()->insert( QStringLiteral(
"Math" ), tr(
"Math" ) );
926 sGroups()->insert( QStringLiteral(
"Operators" ), tr(
"Operators" ) );
927 sGroups()->insert( QStringLiteral(
"Rasters" ), tr(
"Rasters" ) );
928 sGroups()->insert( QStringLiteral(
"Record and Attributes" ), tr(
"Record and Attributes" ) );
929 sGroups()->insert( QStringLiteral(
"String" ), tr(
"String" ) );
930 sGroups()->insert( QStringLiteral(
"Variables" ), tr(
"Variables" ) );
931 sGroups()->insert( QStringLiteral(
"Recent (%1)" ), tr(
"Recent (%1)" ) );
932 sGroups()->insert( QStringLiteral(
"UserGroup" ), tr(
"User expressions" ) );
938 return sGroups()->value( name, name );
943 static const int MAX_PREVIEW = 60;
945 const QString startToken = htmlOutput ? QStringLiteral(
"<i><" ) : QStringLiteral(
"<" );
946 const QString endToken = htmlOutput ? QStringLiteral(
"></i>" ) : QStringLiteral(
">" );
953 return startToken + tr(
"empty geometry" ) + endToken;
960 return startToken + tr(
"map layer" ) + endToken;
962 else if ( !value.isValid() )
964 return htmlOutput ? tr(
"<i>NULL</i>" ) : QString();
970 return startToken + tr(
"feature: %1" ).arg( feat.
id() ) + endToken;
976 return startToken + tr(
"interval: %1 days" ).arg( interval.
days() ) + endToken;
980 return startToken + tr(
"gradient ramp" ) + endToken;
982 else if ( value.type() == QVariant::Date )
984 QDate dt = value.toDate();
985 return startToken + tr(
"date: %1" ).arg( dt.toString( QStringLiteral(
"yyyy-MM-dd" ) ) ) + endToken;
987 else if ( value.type() == QVariant::Time )
989 QTime tm = value.toTime();
990 return startToken + tr(
"time: %1" ).arg( tm.toString( QStringLiteral(
"hh:mm:ss" ) ) ) + endToken;
992 else if ( value.type() == QVariant::DateTime )
994 QDateTime dt = value.toDateTime();
995 return startToken + tr(
"datetime: %1" ).arg( dt.toString( QStringLiteral(
"yyyy-MM-dd hh:mm:ss" ) ) ) + endToken;
997 else if ( value.type() == QVariant::String )
999 const QString previewString = value.toString();
1000 if ( previewString.length() > MAX_PREVIEW + 3 )
1002 return tr(
"'%1…'" ).arg( previewString.left( MAX_PREVIEW ) );
1006 return '\'' + previewString +
'\'';
1009 else if ( value.type() == QVariant::Map )
1011 QString mapStr = QStringLiteral(
"{" );
1012 const QVariantMap map = value.toMap();
1014 for ( QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
1016 mapStr.append( separator );
1017 if ( separator.isEmpty() )
1018 separator = QStringLiteral(
"," );
1020 mapStr.append( QStringLiteral(
" '%1': %2" ).arg( it.key(),
formatPreviewString( it.value(), htmlOutput ) ) );
1021 if ( mapStr.length() > MAX_PREVIEW - 3 )
1023 mapStr = tr(
"%1…" ).arg( mapStr.left( MAX_PREVIEW - 2 ) );
1028 mapStr += QStringLiteral(
" " );
1029 mapStr += QStringLiteral(
"}" );
1032 else if ( value.type() == QVariant::List || value.type() == QVariant::StringList )
1034 QString listStr = QStringLiteral(
"[" );
1035 const QVariantList list = value.toList();
1037 for (
const QVariant &arrayValue : list )
1039 listStr.append( separator );
1040 if ( separator.isEmpty() )
1041 separator = QStringLiteral(
"," );
1043 listStr.append(
" " );
1045 if ( listStr.length() > MAX_PREVIEW - 3 )
1047 listStr = QString( tr(
"%1…" ) ).arg( listStr.left( MAX_PREVIEW - 2 ) );
1051 if ( !list.empty() )
1052 listStr += QStringLiteral(
" " );
1053 listStr += QStringLiteral(
"]" );
1058 return value.toString();
1066 if ( value.isNull() )
1067 expr = QStringLiteral(
"%1 IS NULL" ).arg(
quotedColumnRef( fieldName ) );
1076 return d->mRootNode;
1086 if ( !d->mRootNode )
1087 return QList<const QgsExpressionNode *>();
1089 return d->mRootNode->nodes();