50 if ( transferOwnership )
102 d->mRootNode =
::parseExpression( expression, d->mParserErrorString, d->mParserErrors );
103 d->mEvalErrorString = QString();
105 d->mIsPrepared =
false;
110 if ( !d->mExp.isNull() )
118 return QStringLiteral(
"\"%1\"" ).arg( name.replace(
'\"', QLatin1String(
"\"\"" ) ) );
123 text.replace(
'\'', QLatin1String(
"''" ) );
124 text.replace(
'\\', QLatin1String(
"\\\\" ) );
125 text.replace(
'\n', QLatin1String(
"\\n" ) );
126 text.replace(
'\t', QLatin1String(
"\\t" ) );
127 return QStringLiteral(
"'%1'" ).arg( text );
137 if ( value.isNull() )
138 return QStringLiteral(
"NULL" );
143 case QVariant::LongLong:
144 case QVariant::Double:
145 return value.toString();
148 return value.toBool() ? QStringLiteral(
"TRUE" ) : QStringLiteral(
"FALSE" );
152 QStringList quotedValues;
153 const QVariantList values = value.toList();
154 quotedValues.reserve( values.count() );
155 for (
const QVariant &v : values )
159 return QStringLiteral(
"array( %1 )" ).arg( quotedValues.join( QStringLiteral(
", " ) ) );
163 case QVariant::String:
177 for (
int i = 0; i < count; i++ )
182 for (
const QString &alias : aliases )
184 if ( QString::compare( name, alias, Qt::CaseInsensitive ) == 0 )
198 : d( new QgsExpressionPrivate )
200 d->mRootNode =
::parseExpression( expr, d->mParserErrorString, d->mParserErrors );
202 Q_ASSERT( !d->mParserErrorString.isNull() || d->mRootNode );
213 if ( !d->ref.deref() )
223 QgsExpression::operator QString()
const 229 : d( new QgsExpressionPrivate )
236 if ( !d->ref.deref() )
242 return ( d == other.d || d->mExp == other.d->mExp );
252 return d->mParserErrors.count() > 0;
257 return d->mParserErrorString;
262 return d->mParserErrors;
268 return QSet<QString>();
270 return d->mRootNode->referencedColumns();
276 return QSet<QString>();
278 return d->mRootNode->referencedVariables();
284 return QSet<QString>();
286 return d->mRootNode->referencedFunctions();
294 const QSet<QString> referencedFields = d->mRootNode->referencedColumns();
295 QSet<int> referencedIndexes;
297 for (
const QString &fieldName : referencedFields )
304 referencedIndexes << fields.
lookupField( fieldName );
307 return referencedIndexes;
314 return d->mRootNode->needsGeometry();
320 if ( context && ! d->mCalc )
322 QString ellipsoid = context->
variable( QStringLiteral(
"project_ellipsoid" ) ).toString();
328 d->mCalc->setEllipsoid( ellipsoid.isEmpty() ?
GEO_NONE : ellipsoid );
329 d->mCalc->setSourceCrs( crs, tContext );
336 QString distanceUnitsStr = context->
variable( QStringLiteral(
"project_distance_units" ) ).toString();
337 if ( ! distanceUnitsStr.isEmpty() )
344 QString areaUnitsStr = context->
variable( QStringLiteral(
"project_area_units" ) ).toString();
345 if ( ! areaUnitsStr.isEmpty() )
350 void QgsExpression::detach()
356 ( void )d->ref.deref();
358 d =
new QgsExpressionPrivate( *d );
366 d->mCalc = std::shared_ptr<QgsDistanceArea>(
new QgsDistanceArea( *calc ) );
374 d->mEvalErrorString = QString();
380 d->mRootNode =
::parseExpression( d->mExp, d->mParserErrorString, d->mParserErrors );
385 d->mEvalErrorString = tr(
"No root node! Parsing failed?" );
389 initGeomCalculator( context );
390 d->mIsPrepared =
true;
391 return d->mRootNode->prepare(
this, context );
396 d->mEvalErrorString = QString();
399 d->mEvalErrorString = tr(
"No root node! Parsing failed?" );
403 return d->mRootNode->eval(
this, static_cast<const QgsExpressionContext *>(
nullptr ) );
408 d->mEvalErrorString = QString();
411 d->mEvalErrorString = tr(
"No root node! Parsing failed?" );
415 if ( ! d->mIsPrepared )
419 return d->mRootNode->eval(
this, context );
424 return !d->mEvalErrorString.isNull();
429 return d->mEvalErrorString;
434 d->mEvalErrorString = str;
442 return d->mRootNode->dump();
447 return d->mCalc.get();
452 return d->mDistanceUnit;
457 d->mDistanceUnit = unit;
475 while ( index < action.size() )
477 static const QRegularExpression sRegEx{ QStringLiteral(
"\\[%(.*?)%\\]" ), QRegularExpression::MultilineOption | QRegularExpression::DotMatchesEverythingOption };
479 const QRegularExpressionMatch match = sRegEx.match( action, index );
480 if ( !match.hasMatch() )
483 const int pos = action.indexOf( sRegEx, index );
484 const int start = index;
485 index = pos + match.capturedLength( 0 );
486 const QString toReplace = match.captured( 1 ).trimmed();
493 expr_action += action.midRef( start, index - start );
503 QVariant result = exp.
evaluate( context );
508 expr_action += action.midRef( start, index - start );
512 QgsDebugMsg(
"Expression result is: " + result.toString() );
513 expr_action += action.mid( start, pos - start ) + result.toString();
516 expr_action += action.midRef( index );
523 QSet<QString> variables;
525 while ( index < text.size() )
527 QRegExp rx = QRegExp(
"\\[%([^\\]]+)%\\]" );
529 int pos = rx.indexIn( text, index );
533 index = pos + rx.matchedLength();
534 QString to_replace = rx.cap( 1 ).trimmed();
549 double convertedValue = QLocale().toDouble( text, &ok );
552 return convertedValue;
562 QVariant result = expr.
evaluate( &context );
563 convertedValue = result.toDouble( &ok );
566 return fallbackValue;
568 return convertedValue;
575 QgsExpression::initFunctionHelp();
577 if ( !sFunctionHelpTexts.contains( name ) )
578 return tr(
"function help for %1 missing" ).arg( name );
580 const Help &f = sFunctionHelpTexts[ name ];
583 if ( f.mType == tr(
"group" ) )
585 name =
group( name );
586 name = name.toLower();
589 name = name.toHtmlEscaped();
591 QString helpContents( QStringLiteral(
"<h3>%1</h3>\n<div class=\"description\"><p>%2</p></div>" )
592 .arg( tr(
"%1 %2" ).arg( f.mType, name ),
595 for (
const HelpVariant &v : qgis::as_const( f.mVariants ) )
597 if ( f.mVariants.size() > 1 )
599 helpContents += QStringLiteral(
"<h3>%1</h3>\n<div class=\"description\">%2</p></div>" ).arg( v.mName, v.mDescription );
602 if ( f.mType != tr(
"group" ) && f.mType != tr(
"expression" ) )
603 helpContents += QStringLiteral(
"<h4>%1</h4>\n<div class=\"syntax\">\n" ).arg( tr(
"Syntax" ) );
605 if ( f.mType == tr(
"operator" ) )
607 if ( v.mArguments.size() == 1 )
609 helpContents += QStringLiteral(
"<code><span class=\"functionname\">%1</span> <span class=\"argument\">%2</span></code>" )
610 .arg( name, v.mArguments[0].mArg );
612 else if ( v.mArguments.size() == 2 )
614 helpContents += QStringLiteral(
"<code><span class=\"argument\">%1</span> <span class=\"functionname\">%2</span> <span class=\"argument\">%3</span></code>" )
615 .arg( v.mArguments[0].mArg, name, v.mArguments[1].mArg );
618 else if ( f.mType != tr(
"group" ) && f.mType != tr(
"expression" ) )
620 helpContents += QStringLiteral(
"<code><span class=\"functionname\">%1</span>" ).arg( name );
622 bool hasOptionalArgs =
false;
624 if ( f.mType == tr(
"function" ) && ( f.mName[0] !=
'$' || !v.mArguments.isEmpty() || v.mVariableLenArguments ) )
629 for (
const HelpArg &a : qgis::as_const( v.mArguments ) )
635 hasOptionalArgs =
true;
636 helpContents += QStringLiteral(
"[" );
639 helpContents += delim;
640 helpContents += QStringLiteral(
"<span class=\"argument\">%2%3</span>" ).arg(
642 a.mDefaultVal.isEmpty() ? QString() :
'=' + a.mDefaultVal
646 helpContents += QStringLiteral(
"]" );
648 delim = QStringLiteral(
"," );
651 if ( v.mVariableLenArguments )
653 helpContents += QChar( 0x2026 );
659 helpContents += QLatin1String(
"</code>" );
661 if ( hasOptionalArgs )
663 helpContents += QLatin1String(
"<br/><br/>" ) + tr(
"[ ] marks optional components" );
667 if ( !v.mArguments.isEmpty() )
669 helpContents += QStringLiteral(
"<h4>%1</h4>\n<div class=\"arguments\">\n<table>" ).arg( tr(
"Arguments" ) );
671 for (
const HelpArg &a : qgis::as_const( v.mArguments ) )
676 helpContents += QStringLiteral(
"<tr><td class=\"argument\">%1</td><td>%2</td></tr>" ).arg( a.mArg, a.mDescription );
679 helpContents += QLatin1String(
"</table>\n</div>\n" );
682 if ( !v.mExamples.isEmpty() )
684 helpContents += QStringLiteral(
"<h4>%1</h4>\n<div class=\"examples\">\n<ul>\n" ).arg( tr(
"Examples" ) );
686 for (
const HelpExample &e : qgis::as_const( v.mExamples ) )
688 helpContents +=
"<li><code>" + e.mExpression +
"</code> → <code>" + e.mReturns +
"</code>";
690 if ( !e.mNote.isEmpty() )
691 helpContents += QStringLiteral(
" (%1)" ).arg( e.mNote );
693 helpContents += QLatin1String(
"</li>\n" );
696 helpContents += QLatin1String(
"</ul>\n</div>\n" );
699 if ( !v.mNotes.isEmpty() )
701 helpContents += QStringLiteral(
"<h4>%1</h4>\n<div class=\"notes\"><p>%2</p></div>\n" ).arg( tr(
"Notes" ), v.mNotes );
708 QHash<QString, QString> QgsExpression::sVariableHelpTexts;
710 void QgsExpression::initVariableHelp()
712 if ( !sVariableHelpTexts.isEmpty() )
716 sVariableHelpTexts.insert( QStringLiteral(
"qgis_version" ), QCoreApplication::translate(
"variable_help",
"Current QGIS version string." ) );
717 sVariableHelpTexts.insert( QStringLiteral(
"qgis_version_no" ), QCoreApplication::translate(
"variable_help",
"Current QGIS version number." ) );
718 sVariableHelpTexts.insert( QStringLiteral(
"qgis_release_name" ), QCoreApplication::translate(
"variable_help",
"Current QGIS release name." ) );
719 sVariableHelpTexts.insert( QStringLiteral(
"qgis_short_version" ), QCoreApplication::translate(
"variable_help",
"Short QGIS version string." ) );
720 sVariableHelpTexts.insert( QStringLiteral(
"qgis_os_name" ), QCoreApplication::translate(
"variable_help",
"Operating system name, e.g., 'windows', 'linux' or 'osx'." ) );
721 sVariableHelpTexts.insert( QStringLiteral(
"qgis_platform" ), QCoreApplication::translate(
"variable_help",
"QGIS platform, e.g., 'desktop' or 'server'." ) );
722 sVariableHelpTexts.insert( QStringLiteral(
"qgis_locale" ), QCoreApplication::translate(
"variable_help",
"Two letter identifier for current QGIS locale." ) );
723 sVariableHelpTexts.insert( QStringLiteral(
"user_account_name" ), QCoreApplication::translate(
"variable_help",
"Current user's operating system account name." ) );
724 sVariableHelpTexts.insert( QStringLiteral(
"user_full_name" ), QCoreApplication::translate(
"variable_help",
"Current user's operating system user name (if available)." ) );
727 sVariableHelpTexts.insert( QStringLiteral(
"project_title" ), QCoreApplication::translate(
"variable_help",
"Title of current project." ) );
728 sVariableHelpTexts.insert( QStringLiteral(
"project_path" ), QCoreApplication::translate(
"variable_help",
"Full path (including file name) of current project." ) );
729 sVariableHelpTexts.insert( QStringLiteral(
"project_folder" ), QCoreApplication::translate(
"variable_help",
"Folder for current project." ) );
730 sVariableHelpTexts.insert( QStringLiteral(
"project_filename" ), QCoreApplication::translate(
"variable_help",
"Filename of current project." ) );
731 sVariableHelpTexts.insert( QStringLiteral(
"project_basename" ), QCoreApplication::translate(
"variable_help",
"Base name of current project's filename (without path and extension)." ) );
732 sVariableHelpTexts.insert( QStringLiteral(
"project_home" ), QCoreApplication::translate(
"variable_help",
"Home path of current project." ) );
733 sVariableHelpTexts.insert( QStringLiteral(
"project_crs" ), QCoreApplication::translate(
"variable_help",
"Coordinate reference system of project (e.g., 'EPSG:4326')." ) );
734 sVariableHelpTexts.insert( QStringLiteral(
"project_crs_definition" ), QCoreApplication::translate(
"variable_help",
"Coordinate reference system of project (full definition)." ) );
735 sVariableHelpTexts.insert( QStringLiteral(
"project_author" ), QCoreApplication::translate(
"variable_help",
"Project author, taken from project metadata." ) );
736 sVariableHelpTexts.insert( QStringLiteral(
"project_abstract" ), QCoreApplication::translate(
"variable_help",
"Project abstract, taken from project metadata." ) );
737 sVariableHelpTexts.insert( QStringLiteral(
"project_creation_date" ), QCoreApplication::translate(
"variable_help",
"Project creation date, taken from project metadata." ) );
738 sVariableHelpTexts.insert( QStringLiteral(
"project_identifier" ), QCoreApplication::translate(
"variable_help",
"Project identifier, taken from project metadata." ) );
739 sVariableHelpTexts.insert( QStringLiteral(
"project_keywords" ), QCoreApplication::translate(
"variable_help",
"Project keywords, taken from project metadata." ) );
740 sVariableHelpTexts.insert( QStringLiteral(
"project_area_units" ), QCoreApplication::translate(
"variable_help",
"Area unit for current project, used when calculating areas of geometries." ) );
741 sVariableHelpTexts.insert( QStringLiteral(
"project_distance_units" ), QCoreApplication::translate(
"variable_help",
"Distance unit for current project, used when calculating lengths of geometries." ) );
742 sVariableHelpTexts.insert( QStringLiteral(
"project_ellipsoid" ), QCoreApplication::translate(
"variable_help",
"Name of ellipsoid of current project, used when calculating geodetic areas and lengths of geometries." ) );
745 sVariableHelpTexts.insert( QStringLiteral(
"layer_name" ), QCoreApplication::translate(
"variable_help",
"Name of current layer." ) );
746 sVariableHelpTexts.insert( QStringLiteral(
"layer_id" ), QCoreApplication::translate(
"variable_help",
"ID of current layer." ) );
747 sVariableHelpTexts.insert( QStringLiteral(
"layer" ), QCoreApplication::translate(
"variable_help",
"The current layer." ) );
750 sVariableHelpTexts.insert( QStringLiteral(
"layout_name" ), QCoreApplication::translate(
"variable_help",
"Name of composition." ) );
751 sVariableHelpTexts.insert( QStringLiteral(
"layout_numpages" ), QCoreApplication::translate(
"variable_help",
"Number of pages in composition." ) );
752 sVariableHelpTexts.insert( QStringLiteral(
"layout_page" ), QCoreApplication::translate(
"variable_help",
"Current page number in composition." ) );
753 sVariableHelpTexts.insert( QStringLiteral(
"layout_pageheight" ), QCoreApplication::translate(
"variable_help",
"Composition page height in mm." ) );
754 sVariableHelpTexts.insert( QStringLiteral(
"layout_pagewidth" ), QCoreApplication::translate(
"variable_help",
"Composition page width in mm." ) );
755 sVariableHelpTexts.insert( QStringLiteral(
"layout_dpi" ), QCoreApplication::translate(
"variable_help",
"Composition resolution (DPI)." ) );
758 sVariableHelpTexts.insert( QStringLiteral(
"atlas_layerid" ), QCoreApplication::translate(
"variable_help",
"Current atlas coverage layer ID." ) );
759 sVariableHelpTexts.insert( QStringLiteral(
"atlas_layername" ), QCoreApplication::translate(
"variable_help",
"Current atlas coverage layer name." ) );
760 sVariableHelpTexts.insert( QStringLiteral(
"atlas_totalfeatures" ), QCoreApplication::translate(
"variable_help",
"Total number of features in atlas." ) );
761 sVariableHelpTexts.insert( QStringLiteral(
"atlas_featurenumber" ), QCoreApplication::translate(
"variable_help",
"Current atlas feature number." ) );
762 sVariableHelpTexts.insert( QStringLiteral(
"atlas_filename" ), QCoreApplication::translate(
"variable_help",
"Current atlas file name." ) );
763 sVariableHelpTexts.insert( QStringLiteral(
"atlas_pagename" ), QCoreApplication::translate(
"variable_help",
"Current atlas page name." ) );
764 sVariableHelpTexts.insert( QStringLiteral(
"atlas_feature" ), QCoreApplication::translate(
"variable_help",
"Current atlas feature (as feature object)." ) );
765 sVariableHelpTexts.insert( QStringLiteral(
"atlas_featureid" ), QCoreApplication::translate(
"variable_help",
"Current atlas feature ID." ) );
766 sVariableHelpTexts.insert( QStringLiteral(
"atlas_geometry" ), QCoreApplication::translate(
"variable_help",
"Current atlas feature geometry." ) );
769 sVariableHelpTexts.insert( QStringLiteral(
"item_id" ), QCoreApplication::translate(
"variable_help",
"Layout item user ID (not necessarily unique)." ) );
770 sVariableHelpTexts.insert( QStringLiteral(
"item_uuid" ), QCoreApplication::translate(
"variable_help",
"layout item unique ID." ) );
771 sVariableHelpTexts.insert( QStringLiteral(
"item_left" ), QCoreApplication::translate(
"variable_help",
"Left position of layout item (in mm)." ) );
772 sVariableHelpTexts.insert( QStringLiteral(
"item_top" ), QCoreApplication::translate(
"variable_help",
"Top position of layout item (in mm)." ) );
773 sVariableHelpTexts.insert( QStringLiteral(
"item_width" ), QCoreApplication::translate(
"variable_help",
"Width of layout item (in mm)." ) );
774 sVariableHelpTexts.insert( QStringLiteral(
"item_height" ), QCoreApplication::translate(
"variable_help",
"Height of layout item (in mm)." ) );
777 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." ) );
778 sVariableHelpTexts.insert( QStringLiteral(
"map_rotation" ), QCoreApplication::translate(
"variable_help",
"Current rotation of map." ) );
779 sVariableHelpTexts.insert( QStringLiteral(
"map_scale" ), QCoreApplication::translate(
"variable_help",
"Current scale of map." ) );
780 sVariableHelpTexts.insert( QStringLiteral(
"map_extent" ), QCoreApplication::translate(
"variable_help",
"Geometry representing the current extent of the map." ) );
781 sVariableHelpTexts.insert( QStringLiteral(
"map_extent_center" ), QCoreApplication::translate(
"variable_help",
"Center of map." ) );
782 sVariableHelpTexts.insert( QStringLiteral(
"map_extent_width" ), QCoreApplication::translate(
"variable_help",
"Width of map." ) );
783 sVariableHelpTexts.insert( QStringLiteral(
"map_extent_height" ), QCoreApplication::translate(
"variable_help",
"Height of map." ) );
784 sVariableHelpTexts.insert( QStringLiteral(
"map_crs" ), QCoreApplication::translate(
"variable_help",
"Coordinate reference system of map (e.g., 'EPSG:4326')." ) );
785 sVariableHelpTexts.insert( QStringLiteral(
"map_crs_description" ), QCoreApplication::translate(
"variable_help",
"Name of the coordinate reference system of the map." ) );
786 sVariableHelpTexts.insert( QStringLiteral(
"map_units" ), QCoreApplication::translate(
"variable_help",
"Units for map measurements." ) );
787 sVariableHelpTexts.insert( QStringLiteral(
"map_crs_definition" ), QCoreApplication::translate(
"variable_help",
"Coordinate reference system of map (full definition)." ) );
788 sVariableHelpTexts.insert( QStringLiteral(
"map_crs_acronym" ), QCoreApplication::translate(
"variable_help",
"Acronym of the coordinate reference system of the map." ) );
789 sVariableHelpTexts.insert( QStringLiteral(
"map_crs_ellipsoid" ), QCoreApplication::translate(
"variable_help",
"Acronym of the ellipsoid of the coordinate reference system of the map." ) );
790 sVariableHelpTexts.insert( QStringLiteral(
"map_crs_proj4" ), QCoreApplication::translate(
"variable_help",
"Proj4 definition of the coordinate reference system." ) );
791 sVariableHelpTexts.insert( QStringLiteral(
"map_crs_wkt" ), QCoreApplication::translate(
"variable_help",
"WKT definition of the coordinate reference system." ) );
792 sVariableHelpTexts.insert( QStringLiteral(
"map_layer_ids" ), QCoreApplication::translate(
"variable_help",
"List of map layer IDs visible in the map." ) );
793 sVariableHelpTexts.insert( QStringLiteral(
"map_layers" ), QCoreApplication::translate(
"variable_help",
"List of map layers visible in the map." ) );
795 sVariableHelpTexts.insert( QStringLiteral(
"row_number" ), QCoreApplication::translate(
"variable_help",
"Stores the number of the current row." ) );
796 sVariableHelpTexts.insert( QStringLiteral(
"grid_number" ), QCoreApplication::translate(
"variable_help",
"Current grid annotation value." ) );
797 sVariableHelpTexts.insert( QStringLiteral(
"grid_axis" ), QCoreApplication::translate(
"variable_help",
"Current grid annotation axis (e.g., 'x' for longitude, 'y' for latitude)." ) );
800 sVariableHelpTexts.insert( QStringLiteral(
"canvas_cursor_point" ), QCoreApplication::translate(
"variable_help",
"Last cursor position on the canvas in the project's geographical coordinates." ) );
803 sVariableHelpTexts.insert( QStringLiteral(
"legend_title" ), QCoreApplication::translate(
"variable_help",
"Title of the legend." ) );
804 sVariableHelpTexts.insert( QStringLiteral(
"legend_column_count" ), QCoreApplication::translate(
"variable_help",
"Number of column in the legend." ) );
805 sVariableHelpTexts.insert( QStringLiteral(
"legend_split_layers" ), QCoreApplication::translate(
"variable_help",
"Boolean indicating if layers can be split in the legend." ) );
806 sVariableHelpTexts.insert( QStringLiteral(
"legend_wrap_string" ), QCoreApplication::translate(
"variable_help",
"Characters used to wrap the legend text." ) );
807 sVariableHelpTexts.insert( QStringLiteral(
"legend_filter_by_map" ), QCoreApplication::translate(
"variable_help",
"Boolean indicating if the content of the legend is filtered by the map." ) );
808 sVariableHelpTexts.insert( QStringLiteral(
"legend_filter_out_atlas" ), QCoreApplication::translate(
"variable_help",
"Boolean indicating if the Atlas is filtered out of the legend." ) );
811 sVariableHelpTexts.insert( QStringLiteral(
"scale_value" ), QCoreApplication::translate(
"variable_help",
"Current scale bar distance value." ) );
814 sVariableHelpTexts.insert( QStringLiteral(
"snapping_results" ), QCoreApplication::translate(
"variable_help",
815 "<p>An array with an item for each snapped point.</p>" 816 "<p>Each item is a map with the following keys:</p>" 818 "<dt>valid</dt><dd>Boolean that indicates if the snapping result is valid</dd>" 819 "<dt>layer</dt><dd>The layer on which the snapped feature is</dd>" 820 "<dt>feature_id</dt><dd>The feature id of the snapped feature</dd>" 821 "<dt>vertex_index</dt><dd>The index of the snapped vertex</dd>" 822 "<dt>distance</dt><dd>The distance between the mouse cursor and the snapped point at the time of snapping</dd>" 827 sVariableHelpTexts.insert( QStringLiteral(
"geometry_part_count" ), QCoreApplication::translate(
"variable_help",
"Number of parts in rendered feature's geometry." ) );
828 sVariableHelpTexts.insert( QStringLiteral(
"geometry_part_num" ), QCoreApplication::translate(
"variable_help",
"Current geometry part number for feature being rendered." ) );
829 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." ) );
830 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." ) );
832 sVariableHelpTexts.insert( QStringLiteral(
"symbol_color" ), QCoreApplication::translate(
"symbol_color",
"Color of symbol used to render the feature." ) );
833 sVariableHelpTexts.insert( QStringLiteral(
"symbol_angle" ), QCoreApplication::translate(
"symbol_angle",
"Angle of symbol used to render the feature (valid for marker symbols only)." ) );
835 sVariableHelpTexts.insert( QStringLiteral(
"symbol_label" ), QCoreApplication::translate(
"symbol_label",
"Label for the symbol (either a user defined label or the default autogenerated label)." ) );
836 sVariableHelpTexts.insert( QStringLiteral(
"symbol_id" ), QCoreApplication::translate(
"symbol_id",
"Internal ID of the symbol." ) );
837 sVariableHelpTexts.insert( QStringLiteral(
"symbol_count" ), QCoreApplication::translate(
"symbol_count",
"Total number of features represented by the symbol." ) );
840 sVariableHelpTexts.insert( QStringLiteral(
"cluster_color" ), QCoreApplication::translate(
"cluster_color",
"Color of symbols within a cluster, or NULL if symbols have mixed colors." ) );
841 sVariableHelpTexts.insert( QStringLiteral(
"cluster_size" ), QCoreApplication::translate(
"cluster_size",
"Number of symbols contained within a cluster." ) );
844 sVariableHelpTexts.insert( QStringLiteral(
"algorithm_id" ), QCoreApplication::translate(
"algorithm_id",
"Unique ID for algorithm." ) );
845 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)." ) );
846 sVariableHelpTexts.insert( QStringLiteral(
"model_folder" ), QCoreApplication::translate(
"variable_help",
"Folder containing current model (or project folder if model is embedded in a project)." ) );
847 sVariableHelpTexts.insert( QStringLiteral(
"model_name" ), QCoreApplication::translate(
"variable_help",
"Name of current model." ) );
848 sVariableHelpTexts.insert( QStringLiteral(
"model_group" ), QCoreApplication::translate(
"variable_help",
"Group for current model." ) );
849 sVariableHelpTexts.insert( QStringLiteral(
"fullextent_minx" ), QCoreApplication::translate(
"fullextent_minx",
"Minimum x-value from full canvas extent (including all layers)." ) );
850 sVariableHelpTexts.insert( QStringLiteral(
"fullextent_miny" ), QCoreApplication::translate(
"fullextent_miny",
"Minimum y-value from full canvas extent (including all layers)." ) );
851 sVariableHelpTexts.insert( QStringLiteral(
"fullextent_maxx" ), QCoreApplication::translate(
"fullextent_maxx",
"Maximum x-value from full canvas extent (including all layers)." ) );
852 sVariableHelpTexts.insert( QStringLiteral(
"fullextent_maxy" ), QCoreApplication::translate(
"fullextent_maxy",
"Maximum y-value from full canvas extent (including all layers)." ) );
855 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)." ) );
858 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." ) );
859 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." ) );
862 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." ) );
867 QgsExpression::initVariableHelp();
868 return sVariableHelpTexts.value( variableName, QString() );
873 QString text = !description.isEmpty() ? QStringLiteral(
"<p>%1</p>" ).arg( description ) : QString();
877 if ( !value.isValid() )
879 valueString = QCoreApplication::translate(
"variable_help",
"not set" );
885 text.append( QCoreApplication::translate(
"variable_help",
"<p>Current value: %1</p>" ).arg( valueString ) );
890 QHash<QString, QString> QgsExpression::sGroups;
894 if ( sGroups.isEmpty() )
896 sGroups.insert( QStringLiteral(
"Aggregates" ), tr(
"Aggregates" ) );
897 sGroups.insert( QStringLiteral(
"Arrays" ), tr(
"Arrays" ) );
898 sGroups.insert( QStringLiteral(
"Color" ), tr(
"Color" ) );
899 sGroups.insert( QStringLiteral(
"Conditionals" ), tr(
"Conditionals" ) );
900 sGroups.insert( QStringLiteral(
"Conversions" ), tr(
"Conversions" ) );
901 sGroups.insert( QStringLiteral(
"Date and Time" ), tr(
"Date and Time" ) );
902 sGroups.insert( QStringLiteral(
"Fields and Values" ), tr(
"Fields and Values" ) );
903 sGroups.insert( QStringLiteral(
"Files and Paths" ), tr(
"Files and Paths" ) );
904 sGroups.insert( QStringLiteral(
"Fuzzy Matching" ), tr(
"Fuzzy Matching" ) );
905 sGroups.insert( QStringLiteral(
"General" ), tr(
"General" ) );
906 sGroups.insert( QStringLiteral(
"GeometryGroup" ), tr(
"Geometry" ) );
907 sGroups.insert( QStringLiteral(
"Map Layers" ), tr(
"Map Layers" ) );
908 sGroups.insert( QStringLiteral(
"Maps" ), tr(
"Maps" ) );
909 sGroups.insert( QStringLiteral(
"Math" ), tr(
"Math" ) );
910 sGroups.insert( QStringLiteral(
"Operators" ), tr(
"Operators" ) );
911 sGroups.insert( QStringLiteral(
"Rasters" ), tr(
"Rasters" ) );
912 sGroups.insert( QStringLiteral(
"Record and Attributes" ), tr(
"Record and Attributes" ) );
913 sGroups.insert( QStringLiteral(
"String" ), tr(
"String" ) );
914 sGroups.insert( QStringLiteral(
"Variables" ), tr(
"Variables" ) );
915 sGroups.insert( QStringLiteral(
"Recent (%1)" ), tr(
"Recent (%1)" ) );
921 return sGroups.value( name, name );
926 static const int MAX_PREVIEW = 60;
928 const QString startToken = htmlOutput ? QStringLiteral(
"<i><" ) : QStringLiteral(
"<" );
929 const QString endToken = htmlOutput ? QStringLiteral(
"></i>" ) : QStringLiteral(
">" );
936 return startToken + tr(
"empty geometry" ) + endToken;
943 return startToken + tr(
"map layer" ) + endToken;
945 else if ( !value.isValid() )
947 return htmlOutput ? tr(
"<i>NULL</i>" ) : QString();
953 return startToken + tr(
"feature: %1" ).arg( feat.
id() ) + endToken;
959 return startToken + tr(
"interval: %1 days" ).arg( interval.
days() ) + endToken;
963 return startToken + tr(
"gradient ramp" ) + endToken;
965 else if ( value.type() == QVariant::Date )
967 QDate dt = value.toDate();
968 return startToken + tr(
"date: %1" ).arg( dt.toString( QStringLiteral(
"yyyy-MM-dd" ) ) ) + endToken;
970 else if ( value.type() == QVariant::Time )
972 QTime tm = value.toTime();
973 return startToken + tr(
"time: %1" ).arg( tm.toString( QStringLiteral(
"hh:mm:ss" ) ) ) + endToken;
975 else if ( value.type() == QVariant::DateTime )
977 QDateTime dt = value.toDateTime();
978 return startToken + tr(
"datetime: %1" ).arg( dt.toString( QStringLiteral(
"yyyy-MM-dd hh:mm:ss" ) ) ) + endToken;
980 else if ( value.type() == QVariant::String )
982 const QString previewString = value.toString();
983 if ( previewString.length() > MAX_PREVIEW + 3 )
985 return tr(
"'%1…'" ).arg( previewString.left( MAX_PREVIEW ) );
989 return '\'' + previewString +
'\'';
992 else if ( value.type() == QVariant::Map )
994 QString mapStr = QStringLiteral(
"{" );
995 const QVariantMap map = value.toMap();
997 for ( QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
999 mapStr.append( separator );
1000 if ( separator.isEmpty() )
1001 separator = QStringLiteral(
"," );
1003 mapStr.append( QStringLiteral(
" '%1': %2" ).arg( it.key(),
formatPreviewString( it.value(), htmlOutput ) ) );
1004 if ( mapStr.length() > MAX_PREVIEW - 3 )
1006 mapStr = tr(
"%1…" ).arg( mapStr.left( MAX_PREVIEW - 2 ) );
1011 mapStr += QStringLiteral(
" " );
1012 mapStr += QStringLiteral(
"}" );
1015 else if ( value.type() == QVariant::List || value.type() == QVariant::StringList )
1017 QString listStr = QStringLiteral(
"[" );
1018 const QVariantList list = value.toList();
1020 for (
const QVariant &arrayValue : list )
1022 listStr.append( separator );
1023 if ( separator.isEmpty() )
1024 separator = QStringLiteral(
"," );
1026 listStr.append(
" " );
1028 if ( listStr.length() > MAX_PREVIEW - 3 )
1030 listStr = QString( tr(
"%1…" ) ).arg( listStr.left( MAX_PREVIEW - 2 ) );
1034 if ( !list.empty() )
1035 listStr += QStringLiteral(
" " );
1036 listStr += QStringLiteral(
"]" );
1041 return value.toString();
1049 if ( value.isNull() )
1050 expr = QStringLiteral(
"%1 IS NULL" ).arg(
quotedColumnRef( fieldName ) );
1059 return d->mRootNode;
1069 if ( !d->mRootNode )
1070 return QList<const QgsExpressionNode *>();
1072 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 QList< QgsExpressionFunction * > sOwnedFunctions
List of functions owned by the expression engine.
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 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.
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.
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.
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.
static QStringList sBuiltinFunctions
const QString GEO_NONE
Constant that holds the string representation for "No ellips/No CRS".
void setEvalErrorString(const QString &str)
Sets evaluation error (used internally by evaluation functions)
static const QStringList & BuiltinFunctions()
static bool unregisterFunction(const QString &name)
Unregisters a function from the expression engine.
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.
bool isValid() const
Checks if this expression is valid.
static void cleanRegisteredFunctions()
Deletes all registered functions whose ownership have been transferred to the expression engine...
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 bool registerFunction(QgsExpressionFunction *function, bool transferOwnership=false)
Registers a function to the expression engine.
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.
static QList< QgsExpressionFunction * > sFunctions
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.
A abstract base class for defining QgsExpression functions.
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.
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.