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 QRegExp rx = QRegExp(
"\\[%([^\\]]+)%\\]" );
479 int pos = rx.indexIn( action, index );
484 index = pos + rx.matchedLength();
485 QString to_replace = rx.cap( 1 ).trimmed();
492 expr_action += action.midRef( start, index - start );
502 QVariant result = exp.
evaluate( context );
507 expr_action += action.midRef( start, index - start );
511 QgsDebugMsg(
"Expression result is: " + result.toString() );
512 expr_action += action.mid( start, pos - start ) + result.toString();
515 expr_action += action.midRef( index );
522 QSet<QString> variables;
524 while ( index < text.size() )
526 QRegExp rx = QRegExp(
"\\[%([^\\]]+)%\\]" );
528 int pos = rx.indexIn( text, index );
532 index = pos + rx.matchedLength();
533 QString to_replace = rx.cap( 1 ).trimmed();
548 double convertedValue = QLocale().toDouble( text, &ok );
551 return convertedValue;
561 QVariant result = expr.
evaluate( &context );
562 convertedValue = result.toDouble( &ok );
565 return fallbackValue;
567 return convertedValue;
574 QgsExpression::initFunctionHelp();
576 if ( !sFunctionHelpTexts.contains( name ) )
577 return tr(
"function help for %1 missing" ).arg( name );
579 const Help &f = sFunctionHelpTexts[ name ];
582 if ( f.mType == tr(
"group" ) )
584 name =
group( name );
585 name = name.toLower();
588 name = name.toHtmlEscaped();
590 QString helpContents( QStringLiteral(
"<h3>%1</h3>\n<div class=\"description\"><p>%2</p></div>" )
591 .arg( tr(
"%1 %2" ).arg( f.mType, name ),
594 for (
const HelpVariant &v : qgis::as_const( f.mVariants ) )
596 if ( f.mVariants.size() > 1 )
598 helpContents += QStringLiteral(
"<h3>%1</h3>\n<div class=\"description\">%2</p></div>" ).arg( v.mName, v.mDescription );
601 if ( f.mType != tr(
"group" ) && f.mType != tr(
"expression" ) )
602 helpContents += QStringLiteral(
"<h4>%1</h4>\n<div class=\"syntax\">\n" ).arg( tr(
"Syntax" ) );
604 if ( f.mType == tr(
"operator" ) )
606 if ( v.mArguments.size() == 1 )
608 helpContents += QStringLiteral(
"<code><span class=\"functionname\">%1</span> <span class=\"argument\">%2</span></code>" )
609 .arg( name, v.mArguments[0].mArg );
611 else if ( v.mArguments.size() == 2 )
613 helpContents += QStringLiteral(
"<code><span class=\"argument\">%1</span> <span class=\"functionname\">%2</span> <span class=\"argument\">%3</span></code>" )
614 .arg( v.mArguments[0].mArg, name, v.mArguments[1].mArg );
617 else if ( f.mType != tr(
"group" ) && f.mType != tr(
"expression" ) )
619 helpContents += QStringLiteral(
"<code><span class=\"functionname\">%1</span>" ).arg( name );
621 bool hasOptionalArgs =
false;
623 if ( f.mType == tr(
"function" ) && ( f.mName[0] !=
'$' || !v.mArguments.isEmpty() || v.mVariableLenArguments ) )
628 for (
const HelpArg &a : qgis::as_const( v.mArguments ) )
634 hasOptionalArgs =
true;
635 helpContents += QStringLiteral(
"[" );
638 helpContents += delim;
639 helpContents += QStringLiteral(
"<span class=\"argument\">%2%3</span>" ).arg(
641 a.mDefaultVal.isEmpty() ? QString() :
'=' + a.mDefaultVal
645 helpContents += QStringLiteral(
"]" );
647 delim = QStringLiteral(
"," );
650 if ( v.mVariableLenArguments )
652 helpContents += QChar( 0x2026 );
658 helpContents += QLatin1String(
"</code>" );
660 if ( hasOptionalArgs )
662 helpContents += QLatin1String(
"<br/><br/>" ) + tr(
"[ ] marks optional components" );
666 if ( !v.mArguments.isEmpty() )
668 helpContents += QStringLiteral(
"<h4>%1</h4>\n<div class=\"arguments\">\n<table>" ).arg( tr(
"Arguments" ) );
670 for (
const HelpArg &a : qgis::as_const( v.mArguments ) )
675 helpContents += QStringLiteral(
"<tr><td class=\"argument\">%1</td><td>%2</td></tr>" ).arg( a.mArg, a.mDescription );
678 helpContents += QLatin1String(
"</table>\n</div>\n" );
681 if ( !v.mExamples.isEmpty() )
683 helpContents += QStringLiteral(
"<h4>%1</h4>\n<div class=\"examples\">\n<ul>\n" ).arg( tr(
"Examples" ) );
685 for (
const HelpExample &e : qgis::as_const( v.mExamples ) )
687 helpContents +=
"<li><code>" + e.mExpression +
"</code> → <code>" + e.mReturns +
"</code>";
689 if ( !e.mNote.isEmpty() )
690 helpContents += QStringLiteral(
" (%1)" ).arg( e.mNote );
692 helpContents += QLatin1String(
"</li>\n" );
695 helpContents += QLatin1String(
"</ul>\n</div>\n" );
698 if ( !v.mNotes.isEmpty() )
700 helpContents += QStringLiteral(
"<h4>%1</h4>\n<div class=\"notes\"><p>%2</p></div>\n" ).arg( tr(
"Notes" ), v.mNotes );
707 QHash<QString, QString> QgsExpression::sVariableHelpTexts;
709 void QgsExpression::initVariableHelp()
711 if ( !sVariableHelpTexts.isEmpty() )
715 sVariableHelpTexts.insert( QStringLiteral(
"qgis_version" ), QCoreApplication::translate(
"variable_help",
"Current QGIS version string." ) );
716 sVariableHelpTexts.insert( QStringLiteral(
"qgis_version_no" ), QCoreApplication::translate(
"variable_help",
"Current QGIS version number." ) );
717 sVariableHelpTexts.insert( QStringLiteral(
"qgis_release_name" ), QCoreApplication::translate(
"variable_help",
"Current QGIS release name." ) );
718 sVariableHelpTexts.insert( QStringLiteral(
"qgis_short_version" ), QCoreApplication::translate(
"variable_help",
"Short QGIS version string." ) );
719 sVariableHelpTexts.insert( QStringLiteral(
"qgis_os_name" ), QCoreApplication::translate(
"variable_help",
"Operating system name, e.g., 'windows', 'linux' or 'osx'." ) );
720 sVariableHelpTexts.insert( QStringLiteral(
"qgis_platform" ), QCoreApplication::translate(
"variable_help",
"QGIS platform, e.g., 'desktop' or 'server'." ) );
721 sVariableHelpTexts.insert( QStringLiteral(
"qgis_locale" ), QCoreApplication::translate(
"variable_help",
"Two letter identifier for current QGIS locale." ) );
722 sVariableHelpTexts.insert( QStringLiteral(
"user_account_name" ), QCoreApplication::translate(
"variable_help",
"Current user's operating system account name." ) );
723 sVariableHelpTexts.insert( QStringLiteral(
"user_full_name" ), QCoreApplication::translate(
"variable_help",
"Current user's operating system user name (if available)." ) );
726 sVariableHelpTexts.insert( QStringLiteral(
"project_title" ), QCoreApplication::translate(
"variable_help",
"Title of current project." ) );
727 sVariableHelpTexts.insert( QStringLiteral(
"project_path" ), QCoreApplication::translate(
"variable_help",
"Full path (including file name) of current project." ) );
728 sVariableHelpTexts.insert( QStringLiteral(
"project_folder" ), QCoreApplication::translate(
"variable_help",
"Folder for current project." ) );
729 sVariableHelpTexts.insert( QStringLiteral(
"project_filename" ), QCoreApplication::translate(
"variable_help",
"Filename of current project." ) );
730 sVariableHelpTexts.insert( QStringLiteral(
"project_basename" ), QCoreApplication::translate(
"variable_help",
"Base name of current project's filename (without path and extension)." ) );
731 sVariableHelpTexts.insert( QStringLiteral(
"project_home" ), QCoreApplication::translate(
"variable_help",
"Home path of current project." ) );
732 sVariableHelpTexts.insert( QStringLiteral(
"project_crs" ), QCoreApplication::translate(
"variable_help",
"Coordinate reference system of project (e.g., 'EPSG:4326')." ) );
733 sVariableHelpTexts.insert( QStringLiteral(
"project_crs_definition" ), QCoreApplication::translate(
"variable_help",
"Coordinate reference system of project (full definition)." ) );
734 sVariableHelpTexts.insert( QStringLiteral(
"project_author" ), QCoreApplication::translate(
"variable_help",
"Project author, taken from project metadata." ) );
735 sVariableHelpTexts.insert( QStringLiteral(
"project_abstract" ), QCoreApplication::translate(
"variable_help",
"Project abstract, taken from project metadata." ) );
736 sVariableHelpTexts.insert( QStringLiteral(
"project_creation_date" ), QCoreApplication::translate(
"variable_help",
"Project creation date, taken from project metadata." ) );
737 sVariableHelpTexts.insert( QStringLiteral(
"project_identifier" ), QCoreApplication::translate(
"variable_help",
"Project identifier, taken from project metadata." ) );
738 sVariableHelpTexts.insert( QStringLiteral(
"project_keywords" ), QCoreApplication::translate(
"variable_help",
"Project keywords, taken from project metadata." ) );
739 sVariableHelpTexts.insert( QStringLiteral(
"project_area_units" ), QCoreApplication::translate(
"variable_help",
"Area unit for current project, used when calculating areas of geometries." ) );
740 sVariableHelpTexts.insert( QStringLiteral(
"project_distance_units" ), QCoreApplication::translate(
"variable_help",
"Distance unit for current project, used when calculating lengths of geometries." ) );
741 sVariableHelpTexts.insert( QStringLiteral(
"project_ellipsoid" ), QCoreApplication::translate(
"variable_help",
"Name of ellipsoid of current project, used when calculating geodetic areas and lengths of geometries." ) );
744 sVariableHelpTexts.insert( QStringLiteral(
"layer_name" ), QCoreApplication::translate(
"variable_help",
"Name of current layer." ) );
745 sVariableHelpTexts.insert( QStringLiteral(
"layer_id" ), QCoreApplication::translate(
"variable_help",
"ID of current layer." ) );
746 sVariableHelpTexts.insert( QStringLiteral(
"layer" ), QCoreApplication::translate(
"variable_help",
"The current layer." ) );
749 sVariableHelpTexts.insert( QStringLiteral(
"layout_name" ), QCoreApplication::translate(
"variable_help",
"Name of composition." ) );
750 sVariableHelpTexts.insert( QStringLiteral(
"layout_numpages" ), QCoreApplication::translate(
"variable_help",
"Number of pages in composition." ) );
751 sVariableHelpTexts.insert( QStringLiteral(
"layout_page" ), QCoreApplication::translate(
"variable_help",
"Current page number in composition." ) );
752 sVariableHelpTexts.insert( QStringLiteral(
"layout_pageheight" ), QCoreApplication::translate(
"variable_help",
"Composition page height in mm." ) );
753 sVariableHelpTexts.insert( QStringLiteral(
"layout_pagewidth" ), QCoreApplication::translate(
"variable_help",
"Composition page width in mm." ) );
754 sVariableHelpTexts.insert( QStringLiteral(
"layout_dpi" ), QCoreApplication::translate(
"variable_help",
"Composition resolution (DPI)." ) );
757 sVariableHelpTexts.insert( QStringLiteral(
"atlas_layerid" ), QCoreApplication::translate(
"variable_help",
"Current atlas coverage layer ID." ) );
758 sVariableHelpTexts.insert( QStringLiteral(
"atlas_layername" ), QCoreApplication::translate(
"variable_help",
"Current atlas coverage layer name." ) );
759 sVariableHelpTexts.insert( QStringLiteral(
"atlas_totalfeatures" ), QCoreApplication::translate(
"variable_help",
"Total number of features in atlas." ) );
760 sVariableHelpTexts.insert( QStringLiteral(
"atlas_featurenumber" ), QCoreApplication::translate(
"variable_help",
"Current atlas feature number." ) );
761 sVariableHelpTexts.insert( QStringLiteral(
"atlas_filename" ), QCoreApplication::translate(
"variable_help",
"Current atlas file name." ) );
762 sVariableHelpTexts.insert( QStringLiteral(
"atlas_pagename" ), QCoreApplication::translate(
"variable_help",
"Current atlas page name." ) );
763 sVariableHelpTexts.insert( QStringLiteral(
"atlas_feature" ), QCoreApplication::translate(
"variable_help",
"Current atlas feature (as feature object)." ) );
764 sVariableHelpTexts.insert( QStringLiteral(
"atlas_featureid" ), QCoreApplication::translate(
"variable_help",
"Current atlas feature ID." ) );
765 sVariableHelpTexts.insert( QStringLiteral(
"atlas_geometry" ), QCoreApplication::translate(
"variable_help",
"Current atlas feature geometry." ) );
768 sVariableHelpTexts.insert( QStringLiteral(
"item_id" ), QCoreApplication::translate(
"variable_help",
"Layout item user ID (not necessarily unique)." ) );
769 sVariableHelpTexts.insert( QStringLiteral(
"item_uuid" ), QCoreApplication::translate(
"variable_help",
"layout item unique ID." ) );
770 sVariableHelpTexts.insert( QStringLiteral(
"item_left" ), QCoreApplication::translate(
"variable_help",
"Left position of layout item (in mm)." ) );
771 sVariableHelpTexts.insert( QStringLiteral(
"item_top" ), QCoreApplication::translate(
"variable_help",
"Top position of layout item (in mm)." ) );
772 sVariableHelpTexts.insert( QStringLiteral(
"item_width" ), QCoreApplication::translate(
"variable_help",
"Width of layout item (in mm)." ) );
773 sVariableHelpTexts.insert( QStringLiteral(
"item_height" ), QCoreApplication::translate(
"variable_help",
"Height of layout item (in mm)." ) );
776 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." ) );
777 sVariableHelpTexts.insert( QStringLiteral(
"map_rotation" ), QCoreApplication::translate(
"variable_help",
"Current rotation of map." ) );
778 sVariableHelpTexts.insert( QStringLiteral(
"map_scale" ), QCoreApplication::translate(
"variable_help",
"Current scale of map." ) );
779 sVariableHelpTexts.insert( QStringLiteral(
"map_extent" ), QCoreApplication::translate(
"variable_help",
"Geometry representing the current extent of the map." ) );
780 sVariableHelpTexts.insert( QStringLiteral(
"map_extent_center" ), QCoreApplication::translate(
"variable_help",
"Center of map." ) );
781 sVariableHelpTexts.insert( QStringLiteral(
"map_extent_width" ), QCoreApplication::translate(
"variable_help",
"Width of map." ) );
782 sVariableHelpTexts.insert( QStringLiteral(
"map_extent_height" ), QCoreApplication::translate(
"variable_help",
"Height of map." ) );
783 sVariableHelpTexts.insert( QStringLiteral(
"map_crs" ), QCoreApplication::translate(
"variable_help",
"Coordinate reference system of map (e.g., 'EPSG:4326')." ) );
784 sVariableHelpTexts.insert( QStringLiteral(
"map_crs_description" ), QCoreApplication::translate(
"variable_help",
"Name of the coordinate reference system of the map." ) );
785 sVariableHelpTexts.insert( QStringLiteral(
"map_units" ), QCoreApplication::translate(
"variable_help",
"Units for map measurements." ) );
786 sVariableHelpTexts.insert( QStringLiteral(
"map_crs_definition" ), QCoreApplication::translate(
"variable_help",
"Coordinate reference system of map (full definition)." ) );
787 sVariableHelpTexts.insert( QStringLiteral(
"map_crs_acronym" ), QCoreApplication::translate(
"variable_help",
"Acronym of the coordinate reference system of the map." ) );
788 sVariableHelpTexts.insert( QStringLiteral(
"map_crs_ellipsoid" ), QCoreApplication::translate(
"variable_help",
"Acronym of the ellipsoid of the coordinate reference system of the map." ) );
789 sVariableHelpTexts.insert( QStringLiteral(
"map_crs_proj4" ), QCoreApplication::translate(
"variable_help",
"Proj4 definition of the coordinate reference system." ) );
790 sVariableHelpTexts.insert( QStringLiteral(
"map_crs_wkt" ), QCoreApplication::translate(
"variable_help",
"WKT definition of the coordinate reference system." ) );
791 sVariableHelpTexts.insert( QStringLiteral(
"map_layer_ids" ), QCoreApplication::translate(
"variable_help",
"List of map layer IDs visible in the map." ) );
792 sVariableHelpTexts.insert( QStringLiteral(
"map_layers" ), QCoreApplication::translate(
"variable_help",
"List of map layers visible in the map." ) );
794 sVariableHelpTexts.insert( QStringLiteral(
"row_number" ), QCoreApplication::translate(
"variable_help",
"Stores the number of the current row." ) );
795 sVariableHelpTexts.insert( QStringLiteral(
"grid_number" ), QCoreApplication::translate(
"variable_help",
"Current grid annotation value." ) );
796 sVariableHelpTexts.insert( QStringLiteral(
"grid_axis" ), QCoreApplication::translate(
"variable_help",
"Current grid annotation axis (e.g., 'x' for longitude, 'y' for latitude)." ) );
799 sVariableHelpTexts.insert( QStringLiteral(
"canvas_cursor_point" ), QCoreApplication::translate(
"variable_help",
"Last cursor position on the canvas in the project's geographical coordinates." ) );
802 sVariableHelpTexts.insert( QStringLiteral(
"legend_title" ), QCoreApplication::translate(
"variable_help",
"Title of the legend." ) );
803 sVariableHelpTexts.insert( QStringLiteral(
"legend_column_count" ), QCoreApplication::translate(
"variable_help",
"Number of column in the legend." ) );
804 sVariableHelpTexts.insert( QStringLiteral(
"legend_split_layers" ), QCoreApplication::translate(
"variable_help",
"Boolean indicating if layers can be split in the legend." ) );
805 sVariableHelpTexts.insert( QStringLiteral(
"legend_wrap_string" ), QCoreApplication::translate(
"variable_help",
"Characters used to wrap the legend text." ) );
806 sVariableHelpTexts.insert( QStringLiteral(
"legend_filter_by_map" ), QCoreApplication::translate(
"variable_help",
"Boolean indicating if the content of the legend is filtered by the map." ) );
807 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(
"snapping_results" ), QCoreApplication::translate(
"variable_help",
812 "<p>An array with an item for each snapped point.</p>" 813 "<p>Each item is a map with the following keys:</p>" 815 "<dt>valid</dt><dd>Boolean that indicates if the snapping result is valid</dd>" 816 "<dt>layer</dt><dd>The layer on which the snapped feature is</dd>" 817 "<dt>feature_id</dt><dd>The feature id of the snapped feature</dd>" 818 "<dt>vertex_index</dt><dd>The index of the snapped vertex</dd>" 819 "<dt>distance</dt><dd>The distance between the mouse cursor and the snapped point at the time of snapping</dd>" 824 sVariableHelpTexts.insert( QStringLiteral(
"geometry_part_count" ), QCoreApplication::translate(
"variable_help",
"Number of parts in rendered feature's geometry." ) );
825 sVariableHelpTexts.insert( QStringLiteral(
"geometry_part_num" ), QCoreApplication::translate(
"variable_help",
"Current geometry part number for feature being rendered." ) );
826 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." ) );
827 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." ) );
829 sVariableHelpTexts.insert( QStringLiteral(
"symbol_color" ), QCoreApplication::translate(
"symbol_color",
"Color of symbol used to render the feature." ) );
830 sVariableHelpTexts.insert( QStringLiteral(
"symbol_angle" ), QCoreApplication::translate(
"symbol_angle",
"Angle of symbol used to render the feature (valid for marker symbols only)." ) );
833 sVariableHelpTexts.insert( QStringLiteral(
"cluster_color" ), QCoreApplication::translate(
"cluster_color",
"Color of symbols within a cluster, or NULL if symbols have mixed colors." ) );
834 sVariableHelpTexts.insert( QStringLiteral(
"cluster_size" ), QCoreApplication::translate(
"cluster_size",
"Number of symbols contained within a cluster." ) );
837 sVariableHelpTexts.insert( QStringLiteral(
"algorithm_id" ), QCoreApplication::translate(
"algorithm_id",
"Unique ID for algorithm." ) );
838 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)." ) );
839 sVariableHelpTexts.insert( QStringLiteral(
"model_folder" ), QCoreApplication::translate(
"variable_help",
"Folder containing current model (or project folder if model is embedded in a project)." ) );
840 sVariableHelpTexts.insert( QStringLiteral(
"model_name" ), QCoreApplication::translate(
"variable_help",
"Name of current model." ) );
841 sVariableHelpTexts.insert( QStringLiteral(
"model_group" ), QCoreApplication::translate(
"variable_help",
"Group for current model." ) );
842 sVariableHelpTexts.insert( QStringLiteral(
"fullextent_minx" ), QCoreApplication::translate(
"fullextent_minx",
"Minimum x-value from full canvas extent (including all layers)." ) );
843 sVariableHelpTexts.insert( QStringLiteral(
"fullextent_miny" ), QCoreApplication::translate(
"fullextent_miny",
"Minimum y-value from full canvas extent (including all layers)." ) );
844 sVariableHelpTexts.insert( QStringLiteral(
"fullextent_maxx" ), QCoreApplication::translate(
"fullextent_maxx",
"Maximum x-value from full canvas extent (including all layers)." ) );
845 sVariableHelpTexts.insert( QStringLiteral(
"fullextent_maxy" ), QCoreApplication::translate(
"fullextent_maxy",
"Maximum y-value from full canvas extent (including all layers)." ) );
848 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)." ) );
851 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." ) );
852 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." ) );
855 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." ) );
860 QgsExpression::initVariableHelp();
861 return sVariableHelpTexts.value( variableName, QString() );
866 QString text = !description.isEmpty() ? QStringLiteral(
"<p>%1</p>" ).arg( description ) : QString();
870 if ( !value.isValid() )
872 valueString = QCoreApplication::translate(
"variable_help",
"not set" );
878 text.append( QCoreApplication::translate(
"variable_help",
"<p>Current value: %1</p>" ).arg( valueString ) );
883 QHash<QString, QString> QgsExpression::sGroups;
887 if ( sGroups.isEmpty() )
889 sGroups.insert( QStringLiteral(
"Aggregates" ), tr(
"Aggregates" ) );
890 sGroups.insert( QStringLiteral(
"Arrays" ), tr(
"Arrays" ) );
891 sGroups.insert( QStringLiteral(
"General" ), tr(
"General" ) );
892 sGroups.insert( QStringLiteral(
"Operators" ), tr(
"Operators" ) );
893 sGroups.insert( QStringLiteral(
"Conditionals" ), tr(
"Conditionals" ) );
894 sGroups.insert( QStringLiteral(
"Fields and Values" ), tr(
"Fields and Values" ) );
895 sGroups.insert( QStringLiteral(
"Map Layers" ), tr(
"Map Layers" ) );
896 sGroups.insert( QStringLiteral(
"Maps" ), tr(
"Maps" ) );
897 sGroups.insert( QStringLiteral(
"Math" ), tr(
"Math" ) );
898 sGroups.insert( QStringLiteral(
"Conversions" ), tr(
"Conversions" ) );
899 sGroups.insert( QStringLiteral(
"Date and Time" ), tr(
"Date and Time" ) );
900 sGroups.insert( QStringLiteral(
"String" ), tr(
"String" ) );
901 sGroups.insert( QStringLiteral(
"Color" ), tr(
"Color" ) );
902 sGroups.insert( QStringLiteral(
"GeometryGroup" ), tr(
"Geometry" ) );
903 sGroups.insert( QStringLiteral(
"Rasters" ), tr(
"Rasters" ) );
904 sGroups.insert( QStringLiteral(
"Record and Attributes" ), tr(
"Record and Attributes" ) );
905 sGroups.insert( QStringLiteral(
"Variables" ), tr(
"Variables" ) );
906 sGroups.insert( QStringLiteral(
"Fuzzy Matching" ), tr(
"Fuzzy Matching" ) );
907 sGroups.insert( QStringLiteral(
"Recent (%1)" ), tr(
"Recent (%1)" ) );
913 return sGroups.value( name, name );
918 static const int MAX_PREVIEW = 60;
920 const QString startToken = htmlOutput ? QStringLiteral(
"<i><" ) : QStringLiteral(
"<" );
921 const QString endToken = htmlOutput ? QStringLiteral(
"></i>" ) : QStringLiteral(
">" );
928 return startToken + tr(
"empty geometry" ) + endToken;
935 return startToken + tr(
"map layer" ) + endToken;
937 else if ( !value.isValid() )
939 return htmlOutput ? tr(
"<i>NULL</i>" ) : QString();
945 return startToken + tr(
"feature: %1" ).arg( feat.
id() ) + endToken;
951 return startToken + tr(
"interval: %1 days" ).arg( interval.
days() ) + endToken;
955 return startToken + tr(
"gradient ramp" ) + endToken;
957 else if ( value.type() == QVariant::Date )
959 QDate dt = value.toDate();
960 return startToken + tr(
"date: %1" ).arg( dt.toString( QStringLiteral(
"yyyy-MM-dd" ) ) ) + endToken;
962 else if ( value.type() == QVariant::Time )
964 QTime tm = value.toTime();
965 return startToken + tr(
"time: %1" ).arg( tm.toString( QStringLiteral(
"hh:mm:ss" ) ) ) + endToken;
967 else if ( value.type() == QVariant::DateTime )
969 QDateTime dt = value.toDateTime();
970 return startToken + tr(
"datetime: %1" ).arg( dt.toString( QStringLiteral(
"yyyy-MM-dd hh:mm:ss" ) ) ) + endToken;
972 else if ( value.type() == QVariant::String )
974 const QString previewString = value.toString();
975 if ( previewString.length() > MAX_PREVIEW + 3 )
977 return tr(
"'%1…'" ).arg( previewString.left( MAX_PREVIEW ) );
981 return '\'' + previewString +
'\'';
984 else if ( value.type() == QVariant::Map )
986 QString mapStr = QStringLiteral(
"{" );
987 const QVariantMap map = value.toMap();
989 for ( QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
991 mapStr.append( separator );
992 if ( separator.isEmpty() )
993 separator = QStringLiteral(
"," );
995 mapStr.append( QStringLiteral(
" '%1': %2" ).arg( it.key(),
formatPreviewString( it.value(), htmlOutput ) ) );
996 if ( mapStr.length() > MAX_PREVIEW - 3 )
998 mapStr = tr(
"%1…" ).arg( mapStr.left( MAX_PREVIEW - 2 ) );
1003 mapStr += QStringLiteral(
" " );
1004 mapStr += QStringLiteral(
"}" );
1007 else if ( value.type() == QVariant::List || value.type() == QVariant::StringList )
1009 QString listStr = QStringLiteral(
"[" );
1010 const QVariantList list = value.toList();
1012 for (
const QVariant &arrayValue : list )
1014 listStr.append( separator );
1015 if ( separator.isEmpty() )
1016 separator = QStringLiteral(
"," );
1018 listStr.append(
" " );
1020 if ( listStr.length() > MAX_PREVIEW - 3 )
1022 listStr = QString( tr(
"%1…" ) ).arg( listStr.left( MAX_PREVIEW - 2 ) );
1026 if ( !list.empty() )
1027 listStr += QStringLiteral(
" " );
1028 listStr += QStringLiteral(
"]" );
1033 return value.toString();
1041 if ( value.isNull() )
1042 expr = QStringLiteral(
"%1 IS NULL" ).arg(
quotedColumnRef( fieldName ) );
1051 return d->mRootNode;
1061 if ( !d->mRootNode )
1062 return QList<const QgsExpressionNode *>();
1064 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 root node of the expression. Root node is null is parsing has failed.
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.