37 return *sFunctionHelpTexts();
51 d->mRootNode =
::parseExpression( expression, d->mParserErrorString, d->mParserErrors );
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 ( !d->ref.deref() )
172 QgsExpression::operator QString()
const 178 : d( new QgsExpressionPrivate )
185 if ( !d->ref.deref() )
191 return ( d == other.d || d->mExp == other.d->mExp );
201 return d->mParserErrors.count() > 0;
206 return d->mParserErrorString;
211 return d->mParserErrors;
217 return QSet<QString>();
219 return d->mRootNode->referencedColumns();
225 return QSet<QString>();
227 return d->mRootNode->referencedVariables();
233 return QSet<QString>();
235 return d->mRootNode->referencedFunctions();
243 const QSet<QString> referencedFields = d->mRootNode->referencedColumns();
244 QSet<int> referencedIndexes;
246 for (
const QString &fieldName : referencedFields )
256 referencedIndexes << idx;
260 return referencedIndexes;
267 return d->mRootNode->needsGeometry();
273 if ( context && ! d->mCalc )
275 QString ellipsoid = context->
variable( QStringLiteral(
"project_ellipsoid" ) ).toString();
281 d->mCalc->setEllipsoid( ellipsoid.isEmpty() ?
geoNone() : ellipsoid );
282 d->mCalc->setSourceCrs( crs, tContext );
289 QString distanceUnitsStr = context->
variable( QStringLiteral(
"project_distance_units" ) ).toString();
290 if ( ! distanceUnitsStr.isEmpty() )
297 QString areaUnitsStr = context->
variable( QStringLiteral(
"project_area_units" ) ).toString();
298 if ( ! areaUnitsStr.isEmpty() )
303 void QgsExpression::detach()
309 ( void )d->ref.deref();
311 d =
new QgsExpressionPrivate( *d );
319 d->mCalc = std::shared_ptr<QgsDistanceArea>(
new QgsDistanceArea( *calc ) );
327 d->mEvalErrorString = QString();
333 d->mRootNode =
::parseExpression( d->mExp, d->mParserErrorString, d->mParserErrors );
338 d->mEvalErrorString = tr(
"No root node! Parsing failed?" );
342 initGeomCalculator( context );
343 d->mIsPrepared =
true;
344 return d->mRootNode->prepare(
this, context );
349 d->mEvalErrorString = QString();
352 d->mEvalErrorString = tr(
"No root node! Parsing failed?" );
356 return d->mRootNode->eval(
this, static_cast<const QgsExpressionContext *>(
nullptr ) );
361 d->mEvalErrorString = QString();
364 d->mEvalErrorString = tr(
"No root node! Parsing failed?" );
368 if ( ! d->mIsPrepared )
372 return d->mRootNode->eval(
this, context );
377 return !d->mEvalErrorString.isNull();
382 return d->mEvalErrorString;
387 d->mEvalErrorString = str;
395 return d->mRootNode->dump();
400 return d->mCalc.get();
405 return d->mDistanceUnit;
410 d->mDistanceUnit = unit;
428 while ( index < action.size() )
430 static const QRegularExpression sRegEx{ QStringLiteral(
"\\[%(.*?)%\\]" ), QRegularExpression::MultilineOption | QRegularExpression::DotMatchesEverythingOption };
432 const QRegularExpressionMatch match = sRegEx.match( action, index );
433 if ( !match.hasMatch() )
436 const int pos = action.indexOf( sRegEx, index );
437 const int start = index;
438 index = pos + match.capturedLength( 0 );
439 const QString toReplace = match.captured( 1 ).trimmed();
446 expr_action += action.midRef( start, index - start );
456 QVariant result = exp.
evaluate( context );
461 expr_action += action.midRef( start, index - start );
466 expr_action += action.mid( start, pos - start ) + result.toString();
469 expr_action += action.midRef( index );
476 QSet<QString> variables;
478 while ( index < text.size() )
480 QRegExp rx = QRegExp(
"\\[%([^\\]]+)%\\]" );
482 int pos = rx.indexIn( text, index );
486 index = pos + rx.matchedLength();
487 QString to_replace = rx.cap( 1 ).trimmed();
502 double convertedValue = QLocale().toDouble( text, &ok );
505 return convertedValue;
515 QVariant result = expr.
evaluate( &context );
516 convertedValue = result.toDouble( &ok );
519 return fallbackValue;
521 return convertedValue;
526 QgsExpression::initFunctionHelp();
528 if ( !sFunctionHelpTexts()->contains( name ) )
529 return tr(
"function help for %1 missing" ).arg( name );
531 const Help &f = ( *sFunctionHelpTexts() )[ name ];
534 if ( f.mType == tr(
"group" ) )
536 name =
group( name );
537 name = name.toLower();
540 name = name.toHtmlEscaped();
542 QString helpContents( QStringLiteral(
"<h3>%1</h3>\n<div class=\"description\"><p>%2</p></div>" )
543 .arg( tr(
"%1 %2" ).arg( f.mType, name ),
546 for (
const HelpVariant &v : qgis::as_const( f.mVariants ) )
548 if ( f.mVariants.size() > 1 )
550 helpContents += QStringLiteral(
"<h3>%1</h3>\n<div class=\"description\">%2</p></div>" ).arg( v.mName, v.mDescription );
553 if ( f.mType != tr(
"group" ) && f.mType != tr(
"expression" ) )
554 helpContents += QStringLiteral(
"<h4>%1</h4>\n<div class=\"syntax\">\n" ).arg( tr(
"Syntax" ) );
556 if ( f.mType == tr(
"operator" ) )
558 if ( v.mArguments.size() == 1 )
560 helpContents += QStringLiteral(
"<code><span class=\"functionname\">%1</span> <span class=\"argument\">%2</span></code>" )
561 .arg( name, v.mArguments[0].mArg );
563 else if ( v.mArguments.size() == 2 )
565 helpContents += QStringLiteral(
"<code><span class=\"argument\">%1</span> <span class=\"functionname\">%2</span> <span class=\"argument\">%3</span></code>" )
566 .arg( v.mArguments[0].mArg, name, v.mArguments[1].mArg );
569 else if ( f.mType != tr(
"group" ) && f.mType != tr(
"expression" ) )
571 helpContents += QStringLiteral(
"<code><span class=\"functionname\">%1</span>" ).arg( name );
573 bool hasOptionalArgs =
false;
575 if ( f.mType == tr(
"function" ) && ( f.mName[0] !=
'$' || !v.mArguments.isEmpty() || v.mVariableLenArguments ) )
580 for (
const HelpArg &a : qgis::as_const( v.mArguments ) )
586 hasOptionalArgs =
true;
587 helpContents += QStringLiteral(
"[" );
590 helpContents += delim;
591 helpContents += QStringLiteral(
"<span class=\"argument\">%2%3</span>" ).arg(
593 a.mDefaultVal.isEmpty() ? QString() :
'=' + a.mDefaultVal
597 helpContents += QStringLiteral(
"]" );
599 delim = QStringLiteral(
"," );
602 if ( v.mVariableLenArguments )
604 helpContents += QChar( 0x2026 );
610 helpContents += QLatin1String(
"</code>" );
612 if ( hasOptionalArgs )
614 helpContents += QLatin1String(
"<br/><br/>" ) + tr(
"[ ] marks optional components" );
618 if ( !v.mArguments.isEmpty() )
620 helpContents += QStringLiteral(
"<h4>%1</h4>\n<div class=\"arguments\">\n<table>" ).arg( tr(
"Arguments" ) );
622 for (
const HelpArg &a : qgis::as_const( v.mArguments ) )
627 helpContents += QStringLiteral(
"<tr><td class=\"argument\">%1</td><td>%2</td></tr>" ).arg( a.mArg, a.mDescription );
630 helpContents += QLatin1String(
"</table>\n</div>\n" );
633 if ( !v.mExamples.isEmpty() )
635 helpContents += QStringLiteral(
"<h4>%1</h4>\n<div class=\"examples\">\n<ul>\n" ).arg( tr(
"Examples" ) );
637 for (
const HelpExample &e : qgis::as_const( v.mExamples ) )
639 helpContents +=
"<li><code>" + e.mExpression +
"</code> → <code>" + e.mReturns +
"</code>";
641 if ( !e.mNote.isEmpty() )
642 helpContents += QStringLiteral(
" (%1)" ).arg( e.mNote );
644 helpContents += QLatin1String(
"</li>\n" );
647 helpContents += QLatin1String(
"</ul>\n</div>\n" );
650 if ( !v.mNotes.isEmpty() )
652 helpContents += QStringLiteral(
"<h4>%1</h4>\n<div class=\"notes\"><p>%2</p></div>\n" ).arg( tr(
"Notes" ), v.mNotes );
661 QStringList
tags = QStringList();
663 QgsExpression::initFunctionHelp();
665 if ( sFunctionHelpTexts()->contains( name ) )
667 const Help &f = ( *sFunctionHelpTexts() )[ name ];
669 for (
const HelpVariant &v : qgis::as_const( f.mVariants ) )
678 void QgsExpression::initVariableHelp()
680 if ( !sVariableHelpTexts()->isEmpty() )
684 sVariableHelpTexts()->insert( QStringLiteral(
"qgis_version" ), QCoreApplication::translate(
"variable_help",
"Current QGIS version string." ) );
685 sVariableHelpTexts()->insert( QStringLiteral(
"qgis_version_no" ), QCoreApplication::translate(
"variable_help",
"Current QGIS version number." ) );
686 sVariableHelpTexts()->insert( QStringLiteral(
"qgis_release_name" ), QCoreApplication::translate(
"variable_help",
"Current QGIS release name." ) );
687 sVariableHelpTexts()->insert( QStringLiteral(
"qgis_short_version" ), QCoreApplication::translate(
"variable_help",
"Short QGIS version string." ) );
688 sVariableHelpTexts()->insert( QStringLiteral(
"qgis_os_name" ), QCoreApplication::translate(
"variable_help",
"Operating system name, e.g., 'windows', 'linux' or 'osx'." ) );
689 sVariableHelpTexts()->insert( QStringLiteral(
"qgis_platform" ), QCoreApplication::translate(
"variable_help",
"QGIS platform, e.g., 'desktop' or 'server'." ) );
690 sVariableHelpTexts()->insert( QStringLiteral(
"qgis_locale" ), QCoreApplication::translate(
"variable_help",
"Two letter identifier for current QGIS locale." ) );
691 sVariableHelpTexts()->insert( QStringLiteral(
"user_account_name" ), QCoreApplication::translate(
"variable_help",
"Current user's operating system account name." ) );
692 sVariableHelpTexts()->insert( QStringLiteral(
"user_full_name" ), QCoreApplication::translate(
"variable_help",
"Current user's operating system user name (if available)." ) );
695 sVariableHelpTexts()->insert( QStringLiteral(
"project_title" ), QCoreApplication::translate(
"variable_help",
"Title of current project." ) );
696 sVariableHelpTexts()->insert( QStringLiteral(
"project_path" ), QCoreApplication::translate(
"variable_help",
"Full path (including file name) of current project." ) );
697 sVariableHelpTexts()->insert( QStringLiteral(
"project_folder" ), QCoreApplication::translate(
"variable_help",
"Folder for current project." ) );
698 sVariableHelpTexts()->insert( QStringLiteral(
"project_filename" ), QCoreApplication::translate(
"variable_help",
"Filename of current project." ) );
699 sVariableHelpTexts()->insert( QStringLiteral(
"project_basename" ), QCoreApplication::translate(
"variable_help",
"Base name of current project's filename (without path and extension)." ) );
700 sVariableHelpTexts()->insert( QStringLiteral(
"project_home" ), QCoreApplication::translate(
"variable_help",
"Home path of current project." ) );
701 sVariableHelpTexts()->insert( QStringLiteral(
"project_crs" ), QCoreApplication::translate(
"variable_help",
"Coordinate reference system of project (e.g., 'EPSG:4326')." ) );
702 sVariableHelpTexts()->insert( QStringLiteral(
"project_crs_definition" ), QCoreApplication::translate(
"variable_help",
"Coordinate reference system of project (full definition)." ) );
703 sVariableHelpTexts()->insert( QStringLiteral(
"project_author" ), QCoreApplication::translate(
"variable_help",
"Project author, taken from project metadata." ) );
704 sVariableHelpTexts()->insert( QStringLiteral(
"project_abstract" ), QCoreApplication::translate(
"variable_help",
"Project abstract, taken from project metadata." ) );
705 sVariableHelpTexts()->insert( QStringLiteral(
"project_creation_date" ), QCoreApplication::translate(
"variable_help",
"Project creation date, taken from project metadata." ) );
706 sVariableHelpTexts()->insert( QStringLiteral(
"project_identifier" ), QCoreApplication::translate(
"variable_help",
"Project identifier, taken from project metadata." ) );
707 sVariableHelpTexts()->insert( QStringLiteral(
"project_keywords" ), QCoreApplication::translate(
"variable_help",
"Project keywords, taken from project metadata." ) );
708 sVariableHelpTexts()->insert( QStringLiteral(
"project_area_units" ), QCoreApplication::translate(
"variable_help",
"Area unit for current project, used when calculating areas of geometries." ) );
709 sVariableHelpTexts()->insert( QStringLiteral(
"project_distance_units" ), QCoreApplication::translate(
"variable_help",
"Distance unit for current project, used when calculating lengths of geometries." ) );
710 sVariableHelpTexts()->insert( QStringLiteral(
"project_ellipsoid" ), QCoreApplication::translate(
"variable_help",
"Name of ellipsoid of current project, used when calculating geodetic areas and lengths of geometries." ) );
713 sVariableHelpTexts()->insert( QStringLiteral(
"layer_name" ), QCoreApplication::translate(
"variable_help",
"Name of current layer." ) );
714 sVariableHelpTexts()->insert( QStringLiteral(
"layer_id" ), QCoreApplication::translate(
"variable_help",
"ID of current layer." ) );
715 sVariableHelpTexts()->insert( QStringLiteral(
"layer" ), QCoreApplication::translate(
"variable_help",
"The current layer." ) );
718 sVariableHelpTexts()->insert( QStringLiteral(
"layout_name" ), QCoreApplication::translate(
"variable_help",
"Name of composition." ) );
719 sVariableHelpTexts()->insert( QStringLiteral(
"layout_numpages" ), QCoreApplication::translate(
"variable_help",
"Number of pages in composition." ) );
720 sVariableHelpTexts()->insert( QStringLiteral(
"layout_page" ), QCoreApplication::translate(
"variable_help",
"Current page number in composition." ) );
721 sVariableHelpTexts()->insert( QStringLiteral(
"layout_pageheight" ), QCoreApplication::translate(
"variable_help",
"Composition page height in mm." ) );
722 sVariableHelpTexts()->insert( QStringLiteral(
"layout_pagewidth" ), QCoreApplication::translate(
"variable_help",
"Composition page width in mm." ) );
723 sVariableHelpTexts()->insert( QStringLiteral(
"layout_dpi" ), QCoreApplication::translate(
"variable_help",
"Composition resolution (DPI)." ) );
726 sVariableHelpTexts()->insert( QStringLiteral(
"atlas_layerid" ), QCoreApplication::translate(
"variable_help",
"Current atlas coverage layer ID." ) );
727 sVariableHelpTexts()->insert( QStringLiteral(
"atlas_layername" ), QCoreApplication::translate(
"variable_help",
"Current atlas coverage layer name." ) );
728 sVariableHelpTexts()->insert( QStringLiteral(
"atlas_totalfeatures" ), QCoreApplication::translate(
"variable_help",
"Total number of features in atlas." ) );
729 sVariableHelpTexts()->insert( QStringLiteral(
"atlas_featurenumber" ), QCoreApplication::translate(
"variable_help",
"Current atlas feature number." ) );
730 sVariableHelpTexts()->insert( QStringLiteral(
"atlas_filename" ), QCoreApplication::translate(
"variable_help",
"Current atlas file name." ) );
731 sVariableHelpTexts()->insert( QStringLiteral(
"atlas_pagename" ), QCoreApplication::translate(
"variable_help",
"Current atlas page name." ) );
732 sVariableHelpTexts()->insert( QStringLiteral(
"atlas_feature" ), QCoreApplication::translate(
"variable_help",
"Current atlas feature (as feature object)." ) );
733 sVariableHelpTexts()->insert( QStringLiteral(
"atlas_featureid" ), QCoreApplication::translate(
"variable_help",
"Current atlas feature ID." ) );
734 sVariableHelpTexts()->insert( QStringLiteral(
"atlas_geometry" ), QCoreApplication::translate(
"variable_help",
"Current atlas feature geometry." ) );
737 sVariableHelpTexts()->insert( QStringLiteral(
"item_id" ), QCoreApplication::translate(
"variable_help",
"Layout item user ID (not necessarily unique)." ) );
738 sVariableHelpTexts()->insert( QStringLiteral(
"item_uuid" ), QCoreApplication::translate(
"variable_help",
"layout item unique ID." ) );
739 sVariableHelpTexts()->insert( QStringLiteral(
"item_left" ), QCoreApplication::translate(
"variable_help",
"Left position of layout item (in mm)." ) );
740 sVariableHelpTexts()->insert( QStringLiteral(
"item_top" ), QCoreApplication::translate(
"variable_help",
"Top position of layout item (in mm)." ) );
741 sVariableHelpTexts()->insert( QStringLiteral(
"item_width" ), QCoreApplication::translate(
"variable_help",
"Width of layout item (in mm)." ) );
742 sVariableHelpTexts()->insert( QStringLiteral(
"item_height" ), QCoreApplication::translate(
"variable_help",
"Height of layout item (in mm)." ) );
745 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." ) );
746 sVariableHelpTexts()->insert( QStringLiteral(
"map_rotation" ), QCoreApplication::translate(
"variable_help",
"Current rotation of map." ) );
747 sVariableHelpTexts()->insert( QStringLiteral(
"map_scale" ), QCoreApplication::translate(
"variable_help",
"Current scale of map." ) );
748 sVariableHelpTexts()->insert( QStringLiteral(
"map_extent" ), QCoreApplication::translate(
"variable_help",
"Geometry representing the current extent of the map." ) );
749 sVariableHelpTexts()->insert( QStringLiteral(
"map_extent_center" ), QCoreApplication::translate(
"variable_help",
"Center of map." ) );
750 sVariableHelpTexts()->insert( QStringLiteral(
"map_extent_width" ), QCoreApplication::translate(
"variable_help",
"Width of map." ) );
751 sVariableHelpTexts()->insert( QStringLiteral(
"map_extent_height" ), QCoreApplication::translate(
"variable_help",
"Height of map." ) );
752 sVariableHelpTexts()->insert( QStringLiteral(
"map_crs" ), QCoreApplication::translate(
"variable_help",
"Coordinate reference system of map (e.g., 'EPSG:4326')." ) );
753 sVariableHelpTexts()->insert( QStringLiteral(
"map_crs_description" ), QCoreApplication::translate(
"variable_help",
"Name of the coordinate reference system of the map." ) );
754 sVariableHelpTexts()->insert( QStringLiteral(
"map_units" ), QCoreApplication::translate(
"variable_help",
"Units for map measurements." ) );
755 sVariableHelpTexts()->insert( QStringLiteral(
"map_crs_definition" ), QCoreApplication::translate(
"variable_help",
"Coordinate reference system of map (full definition)." ) );
756 sVariableHelpTexts()->insert( QStringLiteral(
"map_crs_acronym" ), QCoreApplication::translate(
"variable_help",
"Acronym of the coordinate reference system of the map." ) );
757 sVariableHelpTexts()->insert( QStringLiteral(
"map_crs_ellipsoid" ), QCoreApplication::translate(
"variable_help",
"Acronym of the ellipsoid of the coordinate reference system of the map." ) );
758 sVariableHelpTexts()->insert( QStringLiteral(
"map_crs_proj4" ), QCoreApplication::translate(
"variable_help",
"Proj4 definition of the coordinate reference system." ) );
759 sVariableHelpTexts()->insert( QStringLiteral(
"map_crs_wkt" ), QCoreApplication::translate(
"variable_help",
"WKT definition of the coordinate reference system." ) );
760 sVariableHelpTexts()->insert( QStringLiteral(
"map_layer_ids" ), QCoreApplication::translate(
"variable_help",
"List of map layer IDs visible in the map." ) );
761 sVariableHelpTexts()->insert( QStringLiteral(
"map_layers" ), QCoreApplication::translate(
"variable_help",
"List of map layers visible in the map." ) );
763 sVariableHelpTexts()->insert( QStringLiteral(
"row_number" ), QCoreApplication::translate(
"variable_help",
"Stores the number of the current row." ) );
764 sVariableHelpTexts()->insert( QStringLiteral(
"grid_number" ), QCoreApplication::translate(
"variable_help",
"Current grid annotation value." ) );
765 sVariableHelpTexts()->insert( QStringLiteral(
"grid_axis" ), QCoreApplication::translate(
"variable_help",
"Current grid annotation axis (e.g., 'x' for longitude, 'y' for latitude)." ) );
768 sVariableHelpTexts()->insert( QStringLiteral(
"canvas_cursor_point" ), QCoreApplication::translate(
"variable_help",
"Last cursor position on the canvas in the project's geographical coordinates." ) );
771 sVariableHelpTexts()->insert( QStringLiteral(
"legend_title" ), QCoreApplication::translate(
"variable_help",
"Title of the legend." ) );
772 sVariableHelpTexts()->insert( QStringLiteral(
"legend_column_count" ), QCoreApplication::translate(
"variable_help",
"Number of column in the legend." ) );
773 sVariableHelpTexts()->insert( QStringLiteral(
"legend_split_layers" ), QCoreApplication::translate(
"variable_help",
"Boolean indicating if layers can be split in the legend." ) );
774 sVariableHelpTexts()->insert( QStringLiteral(
"legend_wrap_string" ), QCoreApplication::translate(
"variable_help",
"Characters used to wrap the legend text." ) );
775 sVariableHelpTexts()->insert( QStringLiteral(
"legend_filter_by_map" ), QCoreApplication::translate(
"variable_help",
"Boolean indicating if the content of the legend is filtered by the map." ) );
776 sVariableHelpTexts()->insert( QStringLiteral(
"legend_filter_out_atlas" ), QCoreApplication::translate(
"variable_help",
"Boolean indicating if the Atlas is filtered out of the legend." ) );
779 sVariableHelpTexts()->insert( QStringLiteral(
"scale_value" ), QCoreApplication::translate(
"variable_help",
"Current scale bar distance value." ) );
782 sVariableHelpTexts()->insert( QStringLiteral(
"snapping_results" ), QCoreApplication::translate(
"variable_help",
783 "<p>An array with an item for each snapped point.</p>" 784 "<p>Each item is a map with the following keys:</p>" 786 "<dt>valid</dt><dd>Boolean that indicates if the snapping result is valid</dd>" 787 "<dt>layer</dt><dd>The layer on which the snapped feature is</dd>" 788 "<dt>feature_id</dt><dd>The feature id of the snapped feature</dd>" 789 "<dt>vertex_index</dt><dd>The index of the snapped vertex</dd>" 790 "<dt>distance</dt><dd>The distance between the mouse cursor and the snapped point at the time of snapping</dd>" 795 sVariableHelpTexts()->insert( QStringLiteral(
"geometry_part_count" ), QCoreApplication::translate(
"variable_help",
"Number of parts in rendered feature's geometry." ) );
796 sVariableHelpTexts()->insert( QStringLiteral(
"geometry_part_num" ), QCoreApplication::translate(
"variable_help",
"Current geometry part number for feature being rendered." ) );
797 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." ) );
798 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." ) );
800 sVariableHelpTexts()->insert( QStringLiteral(
"symbol_color" ), QCoreApplication::translate(
"symbol_color",
"Color of symbol used to render the feature." ) );
801 sVariableHelpTexts()->insert( QStringLiteral(
"symbol_angle" ), QCoreApplication::translate(
"symbol_angle",
"Angle of symbol used to render the feature (valid for marker symbols only)." ) );
803 sVariableHelpTexts()->insert( QStringLiteral(
"symbol_label" ), QCoreApplication::translate(
"symbol_label",
"Label for the symbol (either a user defined label or the default autogenerated label)." ) );
804 sVariableHelpTexts()->insert( QStringLiteral(
"symbol_id" ), QCoreApplication::translate(
"symbol_id",
"Internal ID of the symbol." ) );
805 sVariableHelpTexts()->insert( QStringLiteral(
"symbol_count" ), QCoreApplication::translate(
"symbol_count",
"Total number of features represented by the symbol." ) );
808 sVariableHelpTexts()->insert( QStringLiteral(
"cluster_color" ), QCoreApplication::translate(
"cluster_color",
"Color of symbols within a cluster, or NULL if symbols have mixed colors." ) );
809 sVariableHelpTexts()->insert( QStringLiteral(
"cluster_size" ), QCoreApplication::translate(
"cluster_size",
"Number of symbols contained within a cluster." ) );
812 sVariableHelpTexts()->insert( QStringLiteral(
"algorithm_id" ), QCoreApplication::translate(
"algorithm_id",
"Unique ID for algorithm." ) );
813 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)." ) );
814 sVariableHelpTexts()->insert( QStringLiteral(
"model_folder" ), QCoreApplication::translate(
"variable_help",
"Folder containing current model (or project folder if model is embedded in a project)." ) );
815 sVariableHelpTexts()->insert( QStringLiteral(
"model_name" ), QCoreApplication::translate(
"variable_help",
"Name of current model." ) );
816 sVariableHelpTexts()->insert( QStringLiteral(
"model_group" ), QCoreApplication::translate(
"variable_help",
"Group for current model." ) );
817 sVariableHelpTexts()->insert( QStringLiteral(
"fullextent_minx" ), QCoreApplication::translate(
"fullextent_minx",
"Minimum x-value from full canvas extent (including all layers)." ) );
818 sVariableHelpTexts()->insert( QStringLiteral(
"fullextent_miny" ), QCoreApplication::translate(
"fullextent_miny",
"Minimum y-value from full canvas extent (including all layers)." ) );
819 sVariableHelpTexts()->insert( QStringLiteral(
"fullextent_maxx" ), QCoreApplication::translate(
"fullextent_maxx",
"Maximum x-value from full canvas extent (including all layers)." ) );
820 sVariableHelpTexts()->insert( QStringLiteral(
"fullextent_maxy" ), QCoreApplication::translate(
"fullextent_maxy",
"Maximum y-value from full canvas extent (including all layers)." ) );
823 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)." ) );
826 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." ) );
827 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." ) );
830 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." ) );
835 QgsExpression::initVariableHelp();
836 return sVariableHelpTexts()->value( variableName, QString() );
841 QString text = !description.isEmpty() ? QStringLiteral(
"<p>%1</p>" ).arg( description ) : QString();
845 if ( !value.isValid() )
847 valueString = QCoreApplication::translate(
"variable_help",
"not set" );
853 text.append( QCoreApplication::translate(
"variable_help",
"<p>Current value: %1</p>" ).arg( valueString ) );
860 if ( sGroups()->isEmpty() )
862 sGroups()->insert( QStringLiteral(
"Aggregates" ), tr(
"Aggregates" ) );
863 sGroups()->insert( QStringLiteral(
"Arrays" ), tr(
"Arrays" ) );
864 sGroups()->insert( QStringLiteral(
"Color" ), tr(
"Color" ) );
865 sGroups()->insert( QStringLiteral(
"Conditionals" ), tr(
"Conditionals" ) );
866 sGroups()->insert( QStringLiteral(
"Conversions" ), tr(
"Conversions" ) );
867 sGroups()->insert( QStringLiteral(
"Date and Time" ), tr(
"Date and Time" ) );
868 sGroups()->insert( QStringLiteral(
"Fields and Values" ), tr(
"Fields and Values" ) );
869 sGroups()->insert( QStringLiteral(
"Files and Paths" ), tr(
"Files and Paths" ) );
870 sGroups()->insert( QStringLiteral(
"Fuzzy Matching" ), tr(
"Fuzzy Matching" ) );
871 sGroups()->insert( QStringLiteral(
"General" ), tr(
"General" ) );
872 sGroups()->insert( QStringLiteral(
"GeometryGroup" ), tr(
"Geometry" ) );
873 sGroups()->insert( QStringLiteral(
"Map Layers" ), tr(
"Map Layers" ) );
874 sGroups()->insert( QStringLiteral(
"Maps" ), tr(
"Maps" ) );
875 sGroups()->insert( QStringLiteral(
"Math" ), tr(
"Math" ) );
876 sGroups()->insert( QStringLiteral(
"Operators" ), tr(
"Operators" ) );
877 sGroups()->insert( QStringLiteral(
"Rasters" ), tr(
"Rasters" ) );
878 sGroups()->insert( QStringLiteral(
"Record and Attributes" ), tr(
"Record and Attributes" ) );
879 sGroups()->insert( QStringLiteral(
"String" ), tr(
"String" ) );
880 sGroups()->insert( QStringLiteral(
"Variables" ), tr(
"Variables" ) );
881 sGroups()->insert( QStringLiteral(
"Recent (%1)" ), tr(
"Recent (%1)" ) );
882 sGroups()->insert( QStringLiteral(
"UserGroup" ), tr(
"User expressions" ) );
888 return sGroups()->value( name, name );
893 static const int MAX_PREVIEW = 60;
895 const QString startToken = htmlOutput ? QStringLiteral(
"<i><" ) : QStringLiteral(
"<" );
896 const QString endToken = htmlOutput ? QStringLiteral(
"></i>" ) : QStringLiteral(
">" );
903 return startToken + tr(
"empty geometry" ) + endToken;
910 return startToken + tr(
"map layer" ) + endToken;
912 else if ( !value.isValid() )
914 return htmlOutput ? tr(
"<i>NULL</i>" ) : QString();
920 return startToken + tr(
"feature: %1" ).arg( feat.
id() ) + endToken;
926 return startToken + tr(
"interval: %1 days" ).arg( interval.
days() ) + endToken;
930 return startToken + tr(
"gradient ramp" ) + endToken;
932 else if ( value.type() == QVariant::Date )
934 QDate dt = value.toDate();
935 return startToken + tr(
"date: %1" ).arg( dt.toString( QStringLiteral(
"yyyy-MM-dd" ) ) ) + endToken;
937 else if ( value.type() == QVariant::Time )
939 QTime tm = value.toTime();
940 return startToken + tr(
"time: %1" ).arg( tm.toString( QStringLiteral(
"hh:mm:ss" ) ) ) + endToken;
942 else if ( value.type() == QVariant::DateTime )
944 QDateTime dt = value.toDateTime();
945 return startToken + tr(
"datetime: %1" ).arg( dt.toString( QStringLiteral(
"yyyy-MM-dd hh:mm:ss" ) ) ) + endToken;
947 else if ( value.type() == QVariant::String )
949 const QString previewString = value.toString();
950 if ( previewString.length() > MAX_PREVIEW + 3 )
952 return tr(
"'%1…'" ).arg( previewString.left( MAX_PREVIEW ) );
956 return '\'' + previewString +
'\'';
959 else if ( value.type() == QVariant::Map )
961 QString mapStr = QStringLiteral(
"{" );
962 const QVariantMap map = value.toMap();
964 for ( QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
966 mapStr.append( separator );
967 if ( separator.isEmpty() )
968 separator = QStringLiteral(
"," );
970 mapStr.append( QStringLiteral(
" '%1': %2" ).arg( it.key(),
formatPreviewString( it.value(), htmlOutput ) ) );
971 if ( mapStr.length() > MAX_PREVIEW - 3 )
973 mapStr = tr(
"%1…" ).arg( mapStr.left( MAX_PREVIEW - 2 ) );
978 mapStr += QStringLiteral(
" " );
979 mapStr += QStringLiteral(
"}" );
982 else if ( value.type() == QVariant::List || value.type() == QVariant::StringList )
984 QString listStr = QStringLiteral(
"[" );
985 const QVariantList list = value.toList();
987 for (
const QVariant &arrayValue : list )
989 listStr.append( separator );
990 if ( separator.isEmpty() )
991 separator = QStringLiteral(
"," );
993 listStr.append(
" " );
995 if ( listStr.length() > MAX_PREVIEW - 3 )
997 listStr = QString( tr(
"%1…" ) ).arg( listStr.left( MAX_PREVIEW - 2 ) );
1001 if ( !list.empty() )
1002 listStr += QStringLiteral(
" " );
1003 listStr += QStringLiteral(
"]" );
1008 return value.toString();
1016 if ( value.isNull() )
1017 expr = QStringLiteral(
"%1 IS NULL" ).arg(
quotedColumnRef( fieldName ) );
1026 return d->mRootNode;
1036 if ( !d->mRootNode )
1037 return QList<const QgsExpressionNode *>();
1039 return d->mRootNode->nodes();
int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
void setAreaUnits(QgsUnitTypes::AreaUnit unit)
Sets the desired areal units for calculations involving geomCalculator(), e.g., "$area".
static bool isFunctionName(const QString &name)
tells whether the identifier is a name of existing function
Class for parsing and evaluation of expressions (formerly called "search strings").
bool hasParserError() const
Returns true if an error occurred when parsing the input expression.
static QString formatPreviewString(const QVariant &value, bool htmlOutput=true)
Formats an expression result for friendly display to the user.
static QString quotedColumnRef(QString name)
Returns a quoted column reference (in double quotes)
void setExpression(const QString &expression)
Set the expression string, will reset the whole internal structure.
static QString group(const QString &group)
Returns the translated name for a function group.
bool operator==(const QgsExpression &other) const
Compares two expressions.
static Q_INVOKABLE QgsUnitTypes::AreaUnit stringToAreaUnit(const QString &string, bool *ok=nullptr)
Converts a translated string to an areal unit.
QString dump() const
Returns an expression string, constructed from the internal abstract syntax tree. ...
QVariant evaluate()
Evaluate the feature and return the result.
CONSTLATIN1STRING geoNone()
Constant that holds the string representation for "No ellips/No CRS".
QgsExpression()
Create an empty expression.
static double evaluateToDouble(const QString &text, double fallbackValue)
Attempts to evaluate a text string as an expression to a resultant double value.
QgsExpressionNode * parseExpression(const QString &str, QString &parserErrorMsg, QList< QgsExpression::ParserError > &parserErrors)
QString evalErrorString() const
Returns evaluation error.
Container of fields for a vector layer.
QSet< int > referencedAttributeIndexes(const QgsFields &fields) const
Returns a list of field name indexes obtained from the provided fields.
A geometry is the spatial representation of a feature.
bool needsGeometry() const
Returns true if the expression uses feature geometry for some computation.
QList< QgsExpression::ParserError > parserErrors() const
Returns parser error details including location of error.
static QString variableHelpText(const QString &variableName)
Returns the help text for a specified variable.
static QgsExpressionContextScope * projectScope(const QgsProject *project)
Creates a new scope which contains variables and functions relating to a QGIS project.
static QStringList tags(const QString &name)
Returns a string list of search tags for a specified function.
QSet< QString > referencedColumns() const
Gets list of columns referenced by the expression.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
const QgsCoordinateReferenceSystem & crs
QPointer< QgsMapLayer > QgsWeakMapLayerPointer
Weak pointer for QgsMapLayer.
QString parserErrorString() const
Returns parser error.
QMap< QString, QString > QgsStringMap
QVariant variable(const QString &name) const
Fetches a matching variable from the context.
QSet< QString > referencedVariables() const
Returns a list of all variables which are used in this expression.
void setEvalErrorString(const QString &str)
Sets evaluation error (used internally by evaluation functions)
QgsUnitTypes::AreaUnit areaUnits() const
Returns the desired areal units for calculations involving geomCalculator(), e.g., "$area".
static int functionCount()
Returns the number of functions defined in the parser.
static bool checkExpression(const QString &text, const QgsExpressionContext *context, QString &errorMessage)
Tests whether a string is a valid expression.
QgsDistanceArea * geomCalculator()
Returns calculator used for distance and area calculations (used by $length, $area and $perimeter fun...
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context...
QgsAttributeList allAttributesList() const
Utility function to get list of attribute indexes.
static int functionIndex(const QString &name)
Returns index of the function in Functions array.
Q_GLOBAL_STATIC(QReadWriteLock, sDefinitionCacheLock)
#define QgsDebugMsgLevel(str, level)
bool isValid() const
Checks if this expression is valid.
QgsExpression & operator=(const QgsExpression &other)
Create a copy of this expression.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
static const QString ALL_ATTRIBUTES
A special attribute that if set matches all attributes.
Abstract base class for all nodes that can appear in an expression.
Contains information about the context in which a coordinate transform is executed.
QgsWkbTypes::Type wkbType() const
Returns the WKB type of the geometry.
static const QList< QgsExpressionFunction * > & Functions()
static QString createFieldEqualityExpression(const QString &fieldName, const QVariant &value)
Create an expression allowing to evaluate if a field is equal to a value.
static QString formatVariableHelp(const QString &description, bool showValue=true, const QVariant &value=QVariant())
Returns formatted help text for a variable.
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
QgsUnitTypes::DistanceUnit distanceUnits() const
Returns the desired distance units for calculations involving geomCalculator(), e.g., "$length" and "$perimeter".
QString expression() const
Returns the original, unmodified expression string.
A representation of the interval between two datetime values.
DistanceUnit
Units of distance.
double days() const
Returns the interval duration in days.
A general purpose distance and area calculator, capable of performing ellipsoid based calculations...
static Q_INVOKABLE QgsUnitTypes::DistanceUnit stringToDistanceUnit(const QString &string, bool *ok=nullptr)
Converts a translated string to a distance unit.
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 prepare(const QgsExpressionContext *context)
Gets the expression ready for evaluation - find out column indexes.
void setDistanceUnits(QgsUnitTypes::DistanceUnit unit)
Sets the desired distance units for calculations involving geomCalculator(), e.g., "$length" and "$perimeter".
static QgsProject * instance()
Returns the QgsProject singleton instance.
This class represents a coordinate reference system (CRS).
bool isField() const
Checks whether an expression consists only of a single field reference.
HelpTextHash & functionHelpTexts()
static QString quotedString(QString text)
Returns a quoted version of a string (in single quotes)
static QString displayString(Type type)
Returns a display string type for a WKB type, e.g., the geometry name used in WKT geometry representa...
static QString helpText(QString name)
Returns the help text for a specified function.
static QString quotedValue(const QVariant &value)
Returns a string representation of a literal value, including appropriate quotations where required...
Gradient color ramp, which smoothly interpolates between two colors and also supports optional extra ...
bool hasEvalError() const
Returns true if an error occurred when evaluating last input.
QList< const QgsExpressionNode * > nodes() const
Returns a list of all nodes which are used in this expression.
QSet< QString > referencedFunctions() const
Returns a list of the names of all functions which are used in this expression.
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...
bool isValid() const
Returns whether this CRS is correctly initialized and usable.