34#include <QRegularExpression>
37using namespace Qt::StringLiterals;
45HelpTextHash QgsExpression::sFunctionHelpTexts;
46QRecursiveMutex QgsExpression::sFunctionsMutex;
47QMap< QString, int> QgsExpression::sFunctionIndexMap;
50HelpTextHash &QgsExpression::functionHelpTexts()
52 return sFunctionHelpTexts;
68 d->mEvalErrorString = QString();
70 d->mIsPrepared =
false;
75 if ( !d->mExp.isNull() )
83 return u
"\"%1\""_s.arg( name.replace(
'\"',
"\"\""_L1 ) );
88 text.replace(
'\'',
"''"_L1 );
89 text.replace(
'\\',
"\\\\"_L1 );
90 text.replace(
'\n',
"\\n"_L1 );
91 text.replace(
'\t',
"\\t"_L1 );
92 return u
"'%1'"_s.arg( text );
97 return quotedValue( value,
static_cast<QMetaType::Type
>( value.userType() ) );
107 case QMetaType::Type::Int:
108 case QMetaType::Type::LongLong:
109 case QMetaType::Type::Double:
110 return value.toString();
112 case QMetaType::Type::Bool:
113 return value.toBool() ? u
"TRUE"_s : u
"FALSE"_s;
115 case QMetaType::Type::QVariantList:
116 case QMetaType::Type::QStringList:
118 QStringList quotedValues;
119 const QVariantList values = value.toList();
120 quotedValues.reserve( values.count() );
121 for (
const QVariant &v : values )
125 return u
"array( %1 )"_s.arg( quotedValues.join(
", "_L1 ) );
129 case QMetaType::Type::QString:
147 QMutexLocker locker( &sFunctionsMutex );
149 auto it = sFunctionIndexMap.constFind( name );
150 if ( it != sFunctionIndexMap.constEnd() )
157 if ( QString::compare( name, function->name(), Qt::CaseInsensitive ) == 0 )
159 sFunctionIndexMap.insert( name, i );
162 const QStringList aliases = function->aliases();
163 for (
const QString &alias : aliases )
165 if ( QString::compare( name, alias, Qt::CaseInsensitive ) == 0 )
167 sFunctionIndexMap.insert( name, i );
183 : d( new QgsExpressionPrivate )
185 d->mRootNode.reset(
::parseExpression( expr, d->mParserErrorString, d->mParserErrors ) );
187 Q_ASSERT( !d->mParserErrorString.isNull() || d->mRootNode );
198 if (
this != &other )
200 if ( !d->ref.deref() )
211QgsExpression::operator QString()
const
217 : d( new QgsExpressionPrivate )
224 if ( !d->ref.deref() )
230 return ( d == other.d || d->mExp == other.d->mExp );
235 return d->mRootNode.get();
240 return d->mParserErrors.count() > 0;
245 return d->mParserErrorString.replace(
"syntax error, unexpected end of file",
246 tr(
"Incomplete expression. You might not have finished the full expression." ) );
251 return d->mParserErrors;
257 return QSet<QString>();
259 return d->mRootNode->referencedColumns();
265 return QSet<QString>();
267 return d->mRootNode->referencedVariables();
273 return QSet<QString>();
275 return d->mRootNode->referencedFunctions();
283 const QSet<QString> referencedFields = d->mRootNode->referencedColumns();
284 QSet<int> referencedIndexes;
286 for (
const QString &fieldName : referencedFields )
291 referencedIndexes = QSet<int>( attributesList.begin(), attributesList.end() );
297 referencedIndexes << idx;
301 return referencedIndexes;
308 return d->mRootNode->needsGeometry();
314 if ( context && ! d->mCalc )
318 d->mDaEllipsoid = context->
variable( u
"project_ellipsoid"_s ).toString();
326 QString distanceUnitsStr = context->
variable( u
"project_distance_units"_s ).toString();
327 if ( ! distanceUnitsStr.isEmpty() )
334 QString areaUnitsStr = context->
variable( u
"project_area_units"_s ).toString();
335 if ( ! areaUnitsStr.isEmpty() )
340void QgsExpression::detach()
346 ( void )d->ref.deref();
348 d =
new QgsExpressionPrivate( *d );
352void QgsExpression::initFunctionHelp()
354 static std::once_flag initialized;
355 std::call_once( initialized, buildFunctionHelp );
362 d->mCalc = std::make_shared<QgsDistanceArea>( *calc );
370 d->mEvalErrorString = QString();
376 d->mRootNode.reset(
::parseExpression( d->mExp, d->mParserErrorString, d->mParserErrors ) );
381 d->mEvalErrorString = tr(
"No root node! Parsing failed?" );
385 initGeomCalculator( context );
386 d->mIsPrepared =
true;
387 return d->mRootNode->prepare(
this, context );
392 d->mEvalErrorString = QString();
395 d->mEvalErrorString = tr(
"No root node! Parsing failed?" );
404 d->mEvalErrorString = QString();
407 d->mEvalErrorString = tr(
"No root node! Parsing failed?" );
411 if ( ! d->mIsPrepared )
415 return d->mRootNode->eval(
this, context );
420 return !d->mEvalErrorString.isNull();
425 return d->mEvalErrorString;
430 d->mEvalErrorString = str;
438 return d->mRootNode->dump();
443 if ( !d->mCalc && d->mDaCrs && d->mDaCrs->isValid() && d->mDaTransformContext )
446 d->mCalc = std::make_shared<QgsDistanceArea>( );
447 d->mCalc->setEllipsoid( d->mDaEllipsoid.isEmpty() ?
Qgis::geoNone() : d->mDaEllipsoid );
448 d->mCalc->setSourceCrs( *d->mDaCrs.get(), *d->mDaTransformContext.get() );
451 return d->mCalc.get();
456 return d->mDistanceUnit;
461 d->mDistanceUnit = unit;
479 while ( index < action.size() )
481 static const QRegularExpression sRegEx{ u
"\\[%(.*?)%\\]"_s, QRegularExpression::MultilineOption | QRegularExpression::DotMatchesEverythingOption };
483 const QRegularExpressionMatch match = sRegEx.match( action, index );
484 if ( !match.hasMatch() )
487 const int pos = action.indexOf( sRegEx, index );
488 const int start = index;
489 index = pos + match.capturedLength( 0 );
490 const QString toReplace = match.captured( 1 ).trimmed();
497 expr_action += QStringView {action} .mid( start, index - start );
507 QVariant result = exp.
evaluate( context );
512 expr_action += QStringView {action} .mid( start, index - start );
516 QString resultString;
518 resultString = result.toString();
522 expr_action += action.mid( start, pos - start ) + resultString;
525 expr_action += QStringView {action} .mid( index ).toString();
531 QSet<QString> variables;
533 while ( index < text.size() )
535 const thread_local QRegularExpression rx(
"\\[%([^\\]]+)%\\]" );
536 const QRegularExpressionMatch match = rx.match( text );
537 if ( !match.hasMatch() )
540 index = match.capturedStart() + match.capturedLength();
541 QString to_replace = match.captured( 1 ).trimmed();
556 double convertedValue = QLocale().toDouble( text, &ok );
559 return convertedValue;
569 QVariant result = expr.
evaluate( &context );
570 convertedValue = result.toDouble( &ok );
573 return fallbackValue;
575 return convertedValue;
580 QgsExpression::initFunctionHelp();
582 if ( !sFunctionHelpTexts.contains( name ) )
583 return tr(
"function help for %1 missing" ).arg( name );
585 const Help &f = sFunctionHelpTexts[ name ];
588 if ( f.mType == tr(
"group" ) )
590 name =
group( name );
591 name = name.toLower();
594 name = name.toHtmlEscaped();
596 QString helpContents( u
"<h3>%1</h3>\n<div class=\"description\"><p>%2</p></div>"_s
597 .arg( tr(
"%1 %2" ).arg( f.mType, name ),
600 for (
const HelpVariant &v : std::as_const( f.mVariants ) )
602 if ( f.mVariants.size() > 1 )
604 helpContents += u
"<h3>%1</h3>\n<div class=\"description\">%2</p></div>"_s.arg( v.mName, v.mDescription );
607 if ( f.mType != tr(
"group" ) && f.mType != tr(
"expression" ) )
608 helpContents += u
"<h4>%1</h4>\n<div class=\"syntax\">\n"_s.arg( tr(
"Syntax" ) );
610 if ( f.mType == tr(
"operator" ) )
612 if ( v.mArguments.size() == 1 )
614 helpContents += u
"<code><span class=\"functionname\">%1</span> <span class=\"argument\">%2</span></code>"_s
615 .arg( name, v.mArguments[0].mArg );
617 else if ( v.mArguments.size() == 2 )
619 helpContents += u
"<code><span class=\"argument\">%1</span> <span class=\"functionname\">%2</span> <span class=\"argument\">%3</span></code>"_s
620 .arg( v.mArguments[0].mArg, name, v.mArguments[1].mArg );
623 else if ( f.mType != tr(
"group" ) && f.mType != tr(
"expression" ) )
625 helpContents += u
"<code><span class=\"functionname\">%1</span>"_s.arg( name );
627 bool hasOptionalArgs =
false;
629 if ( f.mType == tr(
"function" ) && ( f.mName[0] !=
'$' || !v.mArguments.isEmpty() || v.mVariableLenArguments ) )
634 for (
const HelpArg &a : std::as_const( v.mArguments ) )
640 hasOptionalArgs =
true;
641 helpContents +=
'['_L1;
644 helpContents += delim;
645 helpContents += u
"<span class=\"argument\">%2%3</span>"_s.arg(
647 a.mDefaultVal.isEmpty() ? QString() :
":=" + a.mDefaultVal
651 helpContents +=
']'_L1;
656 if ( v.mVariableLenArguments )
658 helpContents += QChar( 0x2026 );
664 helpContents +=
"</code>"_L1;
666 if ( hasOptionalArgs )
668 helpContents +=
"<br/><br/>"_L1 + tr(
"[ ] marks optional components" );
672 if ( !v.mArguments.isEmpty() )
674 helpContents += u
"<h4>%1</h4>\n<div class=\"arguments\">\n<table>"_s.arg( tr(
"Arguments" ) );
676 for (
const HelpArg &a : std::as_const( v.mArguments ) )
681 helpContents += u
"<tr><td class=\"argument\">%1</td><td>%2</td></tr>"_s.arg( a.mArg, a.mDescription );
684 helpContents +=
"</table>\n</div>\n"_L1;
687 if ( !v.mExamples.isEmpty() )
689 helpContents += u
"<h4>%1</h4>\n<div class=\"examples\">\n<ul>\n"_s.arg( tr(
"Examples" ) );
691 for (
const HelpExample &e : std::as_const( v.mExamples ) )
693 helpContents +=
"<li><code>" + e.mExpression +
"</code> → <code>" + e.mReturns +
"</code>";
695 if ( !e.mNote.isEmpty() )
696 helpContents += u
" (%1)"_s.arg( e.mNote );
698 helpContents +=
"</li>\n"_L1;
701 helpContents +=
"</ul>\n</div>\n"_L1;
704 if ( !v.mNotes.isEmpty() )
706 helpContents += u
"<h4>%1</h4>\n<div class=\"notes\"><p>%2</p></div>\n"_s.arg( tr(
"Notes" ), v.mNotes );
715 QStringList
tags = QStringList();
717 QgsExpression::initFunctionHelp();
719 if ( sFunctionHelpTexts.contains( name ) )
721 const Help &f = sFunctionHelpTexts[ name ];
723 for (
const HelpVariant &v : std::as_const( f.mVariants ) )
732void QgsExpression::initVariableHelp()
734 static std::once_flag initialized;
735 std::call_once( initialized, buildVariableHelp );
738void QgsExpression::buildVariableHelp()
741 sVariableHelpTexts()->insert( u
"qgis_version"_s, QCoreApplication::translate(
"variable_help",
"Current QGIS version string." ) );
742 sVariableHelpTexts()->insert( u
"qgis_version_no"_s, QCoreApplication::translate(
"variable_help",
"Current QGIS version number." ) );
743 sVariableHelpTexts()->insert( u
"qgis_release_name"_s, QCoreApplication::translate(
"variable_help",
"Current QGIS release name." ) );
744 sVariableHelpTexts()->insert( u
"qgis_short_version"_s, QCoreApplication::translate(
"variable_help",
"Short QGIS version string." ) );
745 sVariableHelpTexts()->insert( u
"qgis_os_name"_s, QCoreApplication::translate(
"variable_help",
"Operating system name, e.g., 'windows', 'linux' or 'osx'." ) );
746 sVariableHelpTexts()->insert( u
"qgis_platform"_s, QCoreApplication::translate(
"variable_help",
"QGIS platform, e.g., 'desktop' or 'server'." ) );
747 sVariableHelpTexts()->insert( u
"qgis_locale"_s, QCoreApplication::translate(
"variable_help",
"Two letter identifier for current QGIS locale." ) );
748 sVariableHelpTexts()->insert( u
"user_account_name"_s, QCoreApplication::translate(
"variable_help",
"Current user's operating system account name." ) );
749 sVariableHelpTexts()->insert( u
"user_full_name"_s, QCoreApplication::translate(
"variable_help",
"Current user's operating system user name (if available)." ) );
752 sVariableHelpTexts()->insert( u
"project_title"_s, QCoreApplication::translate(
"variable_help",
"Title of current project." ) );
753 sVariableHelpTexts()->insert( u
"project_path"_s, QCoreApplication::translate(
"variable_help",
"Full path (including file name) of current project." ) );
754 sVariableHelpTexts()->insert( u
"project_folder"_s, QCoreApplication::translate(
"variable_help",
"Folder for current project." ) );
755 sVariableHelpTexts()->insert( u
"project_filename"_s, QCoreApplication::translate(
"variable_help",
"Filename of current project." ) );
756 sVariableHelpTexts()->insert( u
"project_basename"_s, QCoreApplication::translate(
"variable_help",
"Base name of current project's filename (without path and extension)." ) );
757 sVariableHelpTexts()->insert( u
"project_home"_s, QCoreApplication::translate(
"variable_help",
"Home path of current project." ) );
758 sVariableHelpTexts()->insert( u
"project_crs"_s, QCoreApplication::translate(
"variable_help",
"Identifier for the coordinate reference system of project (e.g., 'EPSG:4326')." ) );
759 sVariableHelpTexts()->insert( u
"project_crs_definition"_s, QCoreApplication::translate(
"variable_help",
"Coordinate reference system of project (full definition)." ) );
760 sVariableHelpTexts()->insert( u
"project_units"_s, QCoreApplication::translate(
"variable_help",
"Unit of the project's CRS." ) );
761 sVariableHelpTexts()->insert( u
"project_crs_description"_s, QCoreApplication::translate(
"variable_help",
"Name of the coordinate reference system of the project." ) );
762 sVariableHelpTexts()->insert( u
"project_crs_acronym"_s, QCoreApplication::translate(
"variable_help",
"Acronym of the coordinate reference system of the project." ) );
763 sVariableHelpTexts()->insert( u
"project_crs_ellipsoid"_s, QCoreApplication::translate(
"variable_help",
"Acronym of the ellipsoid of the coordinate reference system of the project." ) );
764 sVariableHelpTexts()->insert( u
"project_crs_proj4"_s, QCoreApplication::translate(
"variable_help",
"Proj4 definition of the coordinate reference system of the project." ) );
765 sVariableHelpTexts()->insert( u
"project_crs_wkt"_s, QCoreApplication::translate(
"variable_help",
"WKT definition of the coordinate reference system of the project." ) );
767 sVariableHelpTexts()->insert( u
"project_vertical_crs"_s, QCoreApplication::translate(
"variable_help",
"Identifier for the vertical coordinate reference system of the project (e.g., 'EPSG:5703')." ) );
768 sVariableHelpTexts()->insert( u
"project_vertical_crs_definition"_s, QCoreApplication::translate(
"variable_help",
"Vertical coordinate reference system of project (full definition)." ) );
769 sVariableHelpTexts()->insert( u
"project_vertical_crs_description"_s, QCoreApplication::translate(
"variable_help",
"Name of the vertical coordinate reference system of the project." ) );
770 sVariableHelpTexts()->insert( u
"project_vertical_crs_wkt"_s, QCoreApplication::translate(
"variable_help",
"WKT definition of the vertical coordinate reference system of the project." ) );
772 sVariableHelpTexts()->insert( u
"project_author"_s, QCoreApplication::translate(
"variable_help",
"Project author, taken from project metadata." ) );
773 sVariableHelpTexts()->insert( u
"project_abstract"_s, QCoreApplication::translate(
"variable_help",
"Project abstract, taken from project metadata." ) );
774 sVariableHelpTexts()->insert( u
"project_creation_date"_s, QCoreApplication::translate(
"variable_help",
"Project creation date, taken from project metadata." ) );
775 sVariableHelpTexts()->insert( u
"project_identifier"_s, QCoreApplication::translate(
"variable_help",
"Project identifier, taken from project metadata." ) );
776 sVariableHelpTexts()->insert( u
"project_last_saved"_s, QCoreApplication::translate(
"variable_help",
"Date/time when project was last saved." ) );
777 sVariableHelpTexts()->insert( u
"project_keywords"_s, QCoreApplication::translate(
"variable_help",
"Project keywords, taken from project metadata." ) );
778 sVariableHelpTexts()->insert( u
"project_area_units"_s, QCoreApplication::translate(
"variable_help",
"Area unit for current project, used when calculating areas of geometries." ) );
779 sVariableHelpTexts()->insert( u
"project_distance_units"_s, QCoreApplication::translate(
"variable_help",
"Distance unit for current project, used when calculating lengths of geometries." ) );
780 sVariableHelpTexts()->insert( u
"project_ellipsoid"_s, QCoreApplication::translate(
"variable_help",
"Name of ellipsoid of current project, used when calculating geodetic areas and lengths of geometries." ) );
781 sVariableHelpTexts()->insert( u
"layer_ids"_s, QCoreApplication::translate(
"variable_help",
"List of all map layer IDs from the current project." ) );
782 sVariableHelpTexts()->insert( u
"layers"_s, QCoreApplication::translate(
"variable_help",
"List of all map layers from the current project." ) );
785 sVariableHelpTexts()->insert( u
"layer_name"_s, QCoreApplication::translate(
"variable_help",
"Name of current layer." ) );
786 sVariableHelpTexts()->insert( u
"layer_id"_s, QCoreApplication::translate(
"variable_help",
"ID of current layer." ) );
787 sVariableHelpTexts()->insert( u
"layer_crs"_s, QCoreApplication::translate(
"variable_help",
"CRS Authority ID of current layer." ) );
788 sVariableHelpTexts()->insert( u
"layer"_s, QCoreApplication::translate(
"variable_help",
"The current layer." ) );
789 sVariableHelpTexts()->insert( u
"layer_crs_ellipsoid"_s, QCoreApplication::translate(
"variable_help",
"Ellipsoid acronym of current layer CRS." ) );
791 sVariableHelpTexts()->insert( u
"layer_vertical_crs"_s, QCoreApplication::translate(
"variable_help",
"Identifier for the vertical coordinate reference system of the layer (e.g., 'EPSG:5703')." ) );
792 sVariableHelpTexts()->insert( u
"layer_vertical_crs_definition"_s, QCoreApplication::translate(
"variable_help",
"Vertical coordinate reference system of layer (full definition)." ) );
793 sVariableHelpTexts()->insert( u
"layer_vertical_crs_description"_s, QCoreApplication::translate(
"variable_help",
"Name of the vertical coordinate reference system of the layer." ) );
794 sVariableHelpTexts()->insert( u
"layer_vertical_crs_wkt"_s, QCoreApplication::translate(
"variable_help",
"WKT definition of the vertical coordinate reference system of the layer." ) );
797 sVariableHelpTexts()->insert( u
"feature"_s, QCoreApplication::translate(
"variable_help",
"The current feature being evaluated. This can be used with the 'attribute' function to evaluate attribute values from the current feature." ) );
798 sVariableHelpTexts()->insert( u
"id"_s, QCoreApplication::translate(
"variable_help",
"The ID of the current feature being evaluated." ) );
799 sVariableHelpTexts()->insert( u
"geometry"_s, QCoreApplication::translate(
"variable_help",
"The geometry of the current feature being evaluated." ) );
802 sVariableHelpTexts()->insert( u
"layout_name"_s, QCoreApplication::translate(
"variable_help",
"Name of composition." ) );
803 sVariableHelpTexts()->insert( u
"layout_numpages"_s, QCoreApplication::translate(
"variable_help",
"Number of pages in composition." ) );
804 sVariableHelpTexts()->insert( u
"layout_page"_s, QCoreApplication::translate(
"variable_help",
"Current page number in composition." ) );
805 sVariableHelpTexts()->insert( u
"layout_pageheight"_s, QCoreApplication::translate(
"variable_help",
"Composition page height in mm (or specified custom units)." ) );
806 sVariableHelpTexts()->insert( u
"layout_pagewidth"_s, QCoreApplication::translate(
"variable_help",
"Composition page width in mm (or specified custom units)." ) );
807 sVariableHelpTexts()->insert( u
"layout_pageoffsets"_s, QCoreApplication::translate(
"variable_help",
"Array of Y coordinate of the top of each page." ) );
808 sVariableHelpTexts()->insert( u
"layout_dpi"_s, QCoreApplication::translate(
"variable_help",
"Composition resolution (DPI)." ) );
811 sVariableHelpTexts()->insert( u
"atlas_layerid"_s, QCoreApplication::translate(
"variable_help",
"Current atlas coverage layer ID." ) );
812 sVariableHelpTexts()->insert( u
"atlas_layername"_s, QCoreApplication::translate(
"variable_help",
"Current atlas coverage layer name." ) );
813 sVariableHelpTexts()->insert( u
"atlas_totalfeatures"_s, QCoreApplication::translate(
"variable_help",
"Total number of features in atlas." ) );
814 sVariableHelpTexts()->insert( u
"atlas_featurenumber"_s, QCoreApplication::translate(
"variable_help",
"Current atlas feature number." ) );
815 sVariableHelpTexts()->insert( u
"atlas_filename"_s, QCoreApplication::translate(
"variable_help",
"Current atlas file name." ) );
816 sVariableHelpTexts()->insert( u
"atlas_pagename"_s, QCoreApplication::translate(
"variable_help",
"Current atlas page name." ) );
817 sVariableHelpTexts()->insert( u
"atlas_feature"_s, QCoreApplication::translate(
"variable_help",
"Current atlas feature (as feature object)." ) );
818 sVariableHelpTexts()->insert( u
"atlas_featureid"_s, QCoreApplication::translate(
"variable_help",
"Current atlas feature ID." ) );
819 sVariableHelpTexts()->insert( u
"atlas_geometry"_s, QCoreApplication::translate(
"variable_help",
"Current atlas feature geometry." ) );
822 sVariableHelpTexts()->insert( u
"item_id"_s, QCoreApplication::translate(
"variable_help",
"Layout item user-assigned ID (not necessarily unique)." ) );
823 sVariableHelpTexts()->insert( u
"item_uuid"_s, QCoreApplication::translate(
"variable_help",
"layout item unique ID." ) );
824 sVariableHelpTexts()->insert( u
"item_left"_s, QCoreApplication::translate(
"variable_help",
"Left position of layout item (in mm)." ) );
825 sVariableHelpTexts()->insert( u
"item_top"_s, QCoreApplication::translate(
"variable_help",
"Top position of layout item (in mm)." ) );
826 sVariableHelpTexts()->insert( u
"item_width"_s, QCoreApplication::translate(
"variable_help",
"Width of layout item (in mm)." ) );
827 sVariableHelpTexts()->insert( u
"item_height"_s, QCoreApplication::translate(
"variable_help",
"Height of layout item (in mm)." ) );
830 sVariableHelpTexts()->insert( u
"map_id"_s, QCoreApplication::translate(
"variable_help",
"ID of current map destination. This will be 'canvas' for canvas renders, and the item ID for layout map renders." ) );
831 sVariableHelpTexts()->insert( u
"map_rotation"_s, QCoreApplication::translate(
"variable_help",
"Current rotation of map." ) );
832 sVariableHelpTexts()->insert( u
"map_scale"_s, QCoreApplication::translate(
"variable_help",
"Current scale of map." ) );
833 sVariableHelpTexts()->insert( u
"map_extent"_s, QCoreApplication::translate(
"variable_help",
"Geometry representing the current extent of the map." ) );
834 sVariableHelpTexts()->insert( u
"map_extent_center"_s, QCoreApplication::translate(
"variable_help",
"Center of map." ) );
835 sVariableHelpTexts()->insert( u
"map_extent_width"_s, QCoreApplication::translate(
"variable_help",
"Width of map." ) );
836 sVariableHelpTexts()->insert( u
"map_extent_height"_s, QCoreApplication::translate(
"variable_help",
"Height of map." ) );
837 sVariableHelpTexts()->insert( u
"map_crs"_s, QCoreApplication::translate(
"variable_help",
"Coordinate reference system of map (e.g., 'EPSG:4326')." ) );
838 sVariableHelpTexts()->insert( u
"map_crs_description"_s, QCoreApplication::translate(
"variable_help",
"Name of the coordinate reference system of the map." ) );
839 sVariableHelpTexts()->insert( u
"map_units"_s, QCoreApplication::translate(
"variable_help",
"Units for map measurements." ) );
840 sVariableHelpTexts()->insert( u
"map_crs_definition"_s, QCoreApplication::translate(
"variable_help",
"Coordinate reference system of the map (full definition)." ) );
841 sVariableHelpTexts()->insert( u
"map_crs_acronym"_s, QCoreApplication::translate(
"variable_help",
"Acronym of the coordinate reference system of the map." ) );
842 sVariableHelpTexts()->insert( u
"map_crs_projection"_s, QCoreApplication::translate(
"variable_help",
"Projection method used by the coordinate reference system of the map." ) );
843 sVariableHelpTexts()->insert( u
"map_crs_ellipsoid"_s, QCoreApplication::translate(
"variable_help",
"Acronym of the ellipsoid of the coordinate reference system of the map." ) );
844 sVariableHelpTexts()->insert( u
"map_crs_proj4"_s, QCoreApplication::translate(
"variable_help",
"Proj4 definition of the coordinate reference system of the map." ) );
845 sVariableHelpTexts()->insert( u
"map_crs_wkt"_s, QCoreApplication::translate(
"variable_help",
"WKT definition of the coordinate reference system of the map." ) );
846 sVariableHelpTexts()->insert( u
"map_layer_ids"_s, QCoreApplication::translate(
"variable_help",
"List of map layer IDs visible in the map." ) );
847 sVariableHelpTexts()->insert( u
"map_layers"_s, QCoreApplication::translate(
"variable_help",
"List of map layers visible in the map." ) );
849 sVariableHelpTexts()->insert( u
"map_start_time"_s, QCoreApplication::translate(
"variable_help",
"Start of the map's temporal time range (as a datetime value)" ) );
850 sVariableHelpTexts()->insert( u
"map_end_time"_s, QCoreApplication::translate(
"variable_help",
"End of the map's temporal time range (as a datetime value)" ) );
851 sVariableHelpTexts()->insert( u
"map_interval"_s, QCoreApplication::translate(
"variable_help",
"Duration of the map's temporal time range (as an interval value)" ) );
852 sVariableHelpTexts()->insert( u
"map_z_range_lower"_s, QCoreApplication::translate(
"variable_help",
"Lower elevation of the map's elevation range" ) );
853 sVariableHelpTexts()->insert( u
"map_z_range_upper"_s, QCoreApplication::translate(
"variable_help",
"Upper elevation of the map's elevation range" ) );
855 sVariableHelpTexts()->insert( u
"frame_rate"_s, QCoreApplication::translate(
"variable_help",
"Number of frames per second during animation playback" ) );
856 sVariableHelpTexts()->insert( u
"frame_number"_s, QCoreApplication::translate(
"variable_help",
"Current frame number during animation playback" ) );
857 sVariableHelpTexts()->insert( u
"frame_duration"_s, QCoreApplication::translate(
"variable_help",
"Temporal duration of each animation frame (as an interval value)" ) );
858 sVariableHelpTexts()->insert( u
"frame_timestep"_s, QCoreApplication::translate(
"variable_help",
"Frame time step during animation playback" ) );
859 sVariableHelpTexts()->insert( u
"frame_timestep_unit"_s, QCoreApplication::translate(
"variable_help",
"Unit value of the frame time step during animation playback" ) );
860 sVariableHelpTexts()->insert( u
"frame_timestep_units"_s, QCoreApplication::translate(
"variable_help",
"String representation of the frame time step unit during animation playback" ) );
861 sVariableHelpTexts()->insert( u
"animation_start_time"_s, QCoreApplication::translate(
"variable_help",
"Start of the animation's overall temporal time range (as a datetime value)" ) );
862 sVariableHelpTexts()->insert( u
"animation_end_time"_s, QCoreApplication::translate(
"variable_help",
"End of the animation's overall temporal time range (as a datetime value)" ) );
863 sVariableHelpTexts()->insert( u
"animation_interval"_s, QCoreApplication::translate(
"variable_help",
"Duration of the animation's overall temporal time range (as an interval value)" ) );
866 sVariableHelpTexts()->insert( u
"zoom_level"_s, QCoreApplication::translate(
"variable_help",
"Vector tile zoom level of the map that is being rendered (derived from the current map scale). Normally in interval [0, 20]." ) );
867 sVariableHelpTexts()->insert( u
"vector_tile_zoom"_s, QCoreApplication::translate(
"variable_help",
"Exact vector tile zoom level of the map that is being rendered (derived from the current map scale). Normally in interval [0, 20]. Unlike @zoom_level, this variable is a floating point value which can be used to interpolate values between two integer zoom levels." ) );
869 sVariableHelpTexts()->insert( u
"row_number"_s, QCoreApplication::translate(
"variable_help",
"Stores the number of the current row." ) + u
"\n\n"_s + QCoreApplication::translate(
"variable_help",
"When used for calculations within the attribute table the row number will respect the original order of features from the underlying data source." ) + u
"\n\n"_s + QCoreApplication::translate(
"variable_help",
"When used from the field calculator the row numbering starts at 1, otherwise (e.g. from Processing tools) the row numbering starts from 0." ) );
870 sVariableHelpTexts()->insert( u
"grid_number"_s, QCoreApplication::translate(
"variable_help",
"Current grid annotation value." ) );
871 sVariableHelpTexts()->insert( u
"grid_axis"_s, QCoreApplication::translate(
"variable_help",
"Current grid annotation axis (e.g., 'x' for longitude, 'y' for latitude)." ) );
872 sVariableHelpTexts()->insert( u
"grid_count"_s, QCoreApplication::translate(
"variable_help",
"Total number of visible grid lines for the current grid axis." ) );
873 sVariableHelpTexts()->insert( u
"grid_index"_s, QCoreApplication::translate(
"variable_help",
"The index of the grid line currently being drawn (starting at 1 for the first grid line). The index is specific to the current grid axis." ) );
874 sVariableHelpTexts()->insert( u
"column_number"_s, QCoreApplication::translate(
"variable_help",
"Stores the number of the current column." ) );
877 sVariableHelpTexts()->insert( u
"canvas_cursor_point"_s, QCoreApplication::translate(
"variable_help",
"Last cursor position on the canvas in the project's geographical coordinates." ) );
878 sVariableHelpTexts()->insert( u
"layer_cursor_point"_s, QCoreApplication::translate(
"variable_help",
"Last cursor position on the canvas in the current layers's geographical coordinates. QGIS Server: When used in a maptip expression for a raster layer, this variable holds the GetFeatureInfo position." ) );
881 sVariableHelpTexts()->insert( u
"legend_title"_s, QCoreApplication::translate(
"variable_help",
"Title of the legend." ) );
882 sVariableHelpTexts()->insert( u
"legend_column_count"_s, QCoreApplication::translate(
"variable_help",
"Number of column in the legend." ) );
883 sVariableHelpTexts()->insert( u
"legend_split_layers"_s, QCoreApplication::translate(
"variable_help",
"Boolean indicating if layers can be split in the legend." ) );
884 sVariableHelpTexts()->insert( u
"legend_wrap_string"_s, QCoreApplication::translate(
"variable_help",
"Characters used to wrap the legend text." ) );
885 sVariableHelpTexts()->insert( u
"legend_filter_by_map"_s, QCoreApplication::translate(
"variable_help",
"Boolean indicating if the content of the legend is filtered by the map." ) );
886 sVariableHelpTexts()->insert( u
"legend_filter_out_atlas"_s, QCoreApplication::translate(
"variable_help",
"Boolean indicating if the Atlas is filtered out of the legend." ) );
889 sVariableHelpTexts()->insert( u
"scale_value"_s, QCoreApplication::translate(
"variable_help",
"Current scale bar distance value." ) );
892 sVariableHelpTexts()->insert( u
"snapping_results"_s, QCoreApplication::translate(
"variable_help",
893 "<p>An array with an item for each snapped point.</p>"
894 "<p>Each item is a map with the following keys:</p>"
896 "<dt>valid</dt><dd>Boolean that indicates if the snapping result is valid</dd>"
897 "<dt>layer</dt><dd>The layer on which the snapped feature is</dd>"
898 "<dt>feature_id</dt><dd>The feature id of the snapped feature</dd>"
899 "<dt>vertex_index</dt><dd>The index of the snapped vertex</dd>"
900 "<dt>distance</dt><dd>The distance between the mouse cursor and the snapped point at the time of snapping</dd>"
905 sVariableHelpTexts()->insert( u
"geometry_part_count"_s, QCoreApplication::translate(
"variable_help",
"Number of parts in rendered feature's geometry." ) );
906 sVariableHelpTexts()->insert( u
"geometry_part_num"_s, QCoreApplication::translate(
"variable_help",
"Current geometry part number for feature being rendered." ) );
907 sVariableHelpTexts()->insert( u
"geometry_ring_num"_s, QCoreApplication::translate(
"variable_help",
"Current geometry ring number for feature being rendered (for polygon features only). The exterior ring has a value of 0." ) );
908 sVariableHelpTexts()->insert( u
"geometry_point_count"_s, 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." ) );
909 sVariableHelpTexts()->insert( u
"geometry_point_num"_s, 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." ) );
911 sVariableHelpTexts()->insert( u
"symbol_color"_s, QCoreApplication::translate(
"symbol_color",
"Color of symbol used to render the feature." ) );
912 sVariableHelpTexts()->insert( u
"symbol_angle"_s, QCoreApplication::translate(
"symbol_angle",
"Angle of symbol used to render the feature (valid for marker symbols only)." ) );
913 sVariableHelpTexts()->insert( u
"symbol_layer_count"_s, QCoreApplication::translate(
"symbol_layer_count",
"Total number of symbol layers in the symbol." ) );
914 sVariableHelpTexts()->insert( u
"symbol_layer_index"_s, QCoreApplication::translate(
"symbol_layer_index",
"Current symbol layer index." ) );
915 sVariableHelpTexts()->insert( u
"symbol_marker_row"_s, QCoreApplication::translate(
"symbol_marker_row",
"Row number for marker (valid for point pattern fills only)." ) );
916 sVariableHelpTexts()->insert( u
"symbol_marker_column"_s, QCoreApplication::translate(
"symbol_marker_column",
"Column number for marker (valid for point pattern fills only)." ) );
917 sVariableHelpTexts()->insert( u
"symbol_frame"_s, QCoreApplication::translate(
"symbol_frame",
"Frame number (for animated symbols only)." ) );
919 sVariableHelpTexts()->insert( u
"symbol_label"_s, QCoreApplication::translate(
"symbol_label",
"Label for the symbol (either a user defined label or the default autogenerated label)." ) );
920 sVariableHelpTexts()->insert( u
"symbol_id"_s, QCoreApplication::translate(
"symbol_id",
"Internal ID of the symbol." ) );
921 sVariableHelpTexts()->insert( u
"symbol_count"_s, QCoreApplication::translate(
"symbol_count",
"Total number of features represented by the symbol." ) );
924 sVariableHelpTexts()->insert( u
"cluster_color"_s, QCoreApplication::translate(
"cluster_color",
"Color of symbols within a cluster, or NULL if symbols have mixed colors." ) );
925 sVariableHelpTexts()->insert( u
"cluster_size"_s, QCoreApplication::translate(
"cluster_size",
"Number of symbols contained within a cluster." ) );
928 sVariableHelpTexts()->insert( u
"algorithm_id"_s, QCoreApplication::translate(
"algorithm_id",
"Unique ID for algorithm." ) );
929 sVariableHelpTexts()->insert( u
"model_path"_s, QCoreApplication::translate(
"variable_help",
"Full path (including file name) of current model (or project path if model is embedded in a project)." ) );
930 sVariableHelpTexts()->insert( u
"model_folder"_s, QCoreApplication::translate(
"variable_help",
"Folder containing current model (or project folder if model is embedded in a project)." ) );
931 sVariableHelpTexts()->insert( u
"model_name"_s, QCoreApplication::translate(
"variable_help",
"Name of current model." ) );
932 sVariableHelpTexts()->insert( u
"model_group"_s, QCoreApplication::translate(
"variable_help",
"Group for current model." ) );
933 sVariableHelpTexts()->insert( u
"fullextent_minx"_s, QCoreApplication::translate(
"fullextent_minx",
"Minimum x-value from full canvas extent (including all layers)." ) );
934 sVariableHelpTexts()->insert( u
"fullextent_miny"_s, QCoreApplication::translate(
"fullextent_miny",
"Minimum y-value from full canvas extent (including all layers)." ) );
935 sVariableHelpTexts()->insert( u
"fullextent_maxx"_s, QCoreApplication::translate(
"fullextent_maxx",
"Maximum x-value from full canvas extent (including all layers)." ) );
936 sVariableHelpTexts()->insert( u
"fullextent_maxy"_s, QCoreApplication::translate(
"fullextent_maxy",
"Maximum y-value from full canvas extent (including all layers)." ) );
939 sVariableHelpTexts()->insert( u
"notification_message"_s, QCoreApplication::translate(
"notification_message",
"Content of the notification message sent by the provider (available only for actions triggered by provider notifications)." ) );
942 sVariableHelpTexts()->insert( u
"current_geometry"_s, 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." ) );
943 sVariableHelpTexts()->insert( u
"current_feature"_s, 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." ) );
946 sVariableHelpTexts()->insert( u
"current_parent_geometry"_s, QCoreApplication::translate(
"current_parent_geometry",
947 "Only usable in an embedded form context, "
948 "represents the geometry of the feature currently being edited in the parent form.\n"
949 "Can be used in a form/row context to filter the related features using a value "
950 "from the feature currently edited in the parent form, to make sure that the filter "
951 "still works with standalone forms it is recommended to wrap this variable in a "
953 sVariableHelpTexts()->insert( u
"current_parent_feature"_s, QCoreApplication::translate(
"current_parent_feature",
954 "Only usable in an embedded form context, "
955 "represents the feature currently being edited in the parent form.\n"
956 "Can be used in a form/row context to filter the related features using a value "
957 "from the feature currently edited in the parent form, to make sure that the filter "
958 "still works with standalone forms it is recommended to wrap this variable in a "
962 sVariableHelpTexts()->insert( u
"form_mode"_s, QCoreApplication::translate(
"form_mode",
"What the form is used for, like AddFeatureMode, SingleEditMode, MultiEditMode, SearchMode, AggregateSearchMode or IdentifyMode as string." ) );
965 sVariableHelpTexts()->insert( u
"plot_axis"_s, QCoreApplication::translate(
"plot_axis",
"The associated plot axis, e.g. 'x' or 'y'." ) );
966 sVariableHelpTexts()->insert( u
"plot_axis_value"_s, QCoreApplication::translate(
"plot_axis_value",
"The current value for the plot axis grid line." ) );
967 sVariableHelpTexts()->insert( u
"chart_category"_s, QCoreApplication::translate(
"plot_axis",
"The chart item category, e.g. 'fruit' or 'june'." ) );
968 sVariableHelpTexts()->insert( u
"chart_value"_s, QCoreApplication::translate(
"plot_axis_value",
"The chart item value." ) );
973 QgsExpression::initVariableHelp();
974 if ( sVariableHelpTexts()->contains( name ) )
978 sVariableHelpTexts()->insert( name, description );
984 QgsExpression::initVariableHelp();
985 return sVariableHelpTexts()->value( variableName, QString() );
990 QString text = !description.isEmpty() ? u
"<p>%1</p>"_s.arg( description ) : QString();
994 if ( !value.isValid() )
996 valueString = QCoreApplication::translate(
"variable_help",
"not set" );
1002 text.append( QCoreApplication::translate(
"variable_help",
"<p>Current value: %1</p>" ).arg( valueString ) );
1009 if ( sGroups()->isEmpty() )
1011 sGroups()->insert( u
"Aggregates"_s, tr(
"Aggregates" ) );
1012 sGroups()->insert( u
"Arrays"_s, tr(
"Arrays" ) );
1013 sGroups()->insert( u
"Color"_s, tr(
"Color" ) );
1014 sGroups()->insert( u
"Conditionals"_s, tr(
"Conditionals" ) );
1015 sGroups()->insert( u
"Conversions"_s, tr(
"Conversions" ) );
1016 sGroups()->insert( u
"Date and Time"_s, tr(
"Date and Time" ) );
1017 sGroups()->insert( u
"Fields and Values"_s, tr(
"Fields and Values" ) );
1018 sGroups()->insert( u
"Files and Paths"_s, tr(
"Files and Paths" ) );
1019 sGroups()->insert( u
"Fuzzy Matching"_s, tr(
"Fuzzy Matching" ) );
1020 sGroups()->insert( u
"General"_s, tr(
"General" ) );
1021 sGroups()->insert( u
"GeometryGroup"_s, tr(
"Geometry" ) );
1022 sGroups()->insert( u
"Map Layers"_s, tr(
"Map Layers" ) );
1023 sGroups()->insert( u
"Maps"_s, tr(
"Maps" ) );
1024 sGroups()->insert( u
"Math"_s, tr(
"Math" ) );
1025 sGroups()->insert( u
"Operators"_s, tr(
"Operators" ) );
1026 sGroups()->insert( u
"Rasters"_s, tr(
"Rasters" ) );
1027 sGroups()->insert( u
"Record and Attributes"_s, tr(
"Record and Attributes" ) );
1028 sGroups()->insert( u
"String"_s, tr(
"String" ) );
1029 sGroups()->insert( u
"MagneticModels"_s, tr(
"Magnetic Models" ) );
1030 sGroups()->insert( u
"Variables"_s, tr(
"Variables" ) );
1031 sGroups()->insert( u
"Recent (%1)"_s, tr(
"Recent (%1)" ) );
1032 sGroups()->insert( u
"UserGroup"_s, tr(
"User expressions" ) );
1038 return sGroups()->value( name, name );
1043 const QString startToken = htmlOutput ? u
"<i><"_s : u
"<"_s;
1044 const QString endToken = htmlOutput ? u
"></i>"_s : u
">"_s;
1046 QgsGeometry geom = QgsExpressionUtils::getGeometry( value,
nullptr );
1051 return startToken + tr(
"empty geometry" ) + endToken;
1058 return startToken + tr(
"map layer" ) + endToken;
1060 else if ( !value.isValid() )
1062 return htmlOutput ? tr(
"<i>NULL</i>" ) : QString();
1064 else if ( value.userType() == qMetaTypeId< QgsFeature>() )
1068 return startToken + tr(
"feature: %1" ).arg( feat.
id() ) + endToken;
1070 else if ( value.userType() == qMetaTypeId< QgsCoordinateReferenceSystem>() )
1075 else if ( value.userType() == qMetaTypeId< QTimeZone>() )
1077 const QTimeZone tz = value.value<QTimeZone>();
1078#if QT_FEATURE_timezone > 0
1079 return startToken + tr(
"time zone: %1" ).arg( tz.isValid() ? tz.displayName( QTimeZone::GenericTime, QTimeZone::ShortName ) : tr(
"invalid" ) ) + endToken;
1081 QgsDebugError( u
"Qt is built without Qt timezone support, timezone preview not available"_s );
1084 else if ( value.userType() == qMetaTypeId< QgsInterval>() )
1087 if ( interval.
days() > 1 )
1089 return startToken + tr(
"interval: %1 days" ).arg( interval.
days() ) + endToken;
1091 else if ( interval.
hours() > 1 )
1093 return startToken + tr(
"interval: %1 hours" ).arg( interval.
hours() ) + endToken;
1095 else if ( interval.
minutes() > 1 )
1097 return startToken + tr(
"interval: %1 minutes" ).arg( interval.
minutes() ) + endToken;
1101 return startToken + tr(
"interval: %1 seconds" ).arg( interval.
seconds() ) + endToken;
1104 else if ( value.userType() == qMetaTypeId< QgsGradientColorRamp>() )
1106 return startToken + tr(
"gradient ramp" ) + endToken;
1108 else if ( value.userType() == QMetaType::Type::QDate )
1110 const QDate dt = value.toDate();
1111 return startToken + tr(
"date: %1" ).arg( dt.toString( u
"yyyy-MM-dd"_s ) ) + endToken;
1113 else if ( value.userType() == QMetaType::Type::QTime )
1115 const QTime tm = value.toTime();
1116 return startToken + tr(
"time: %1" ).arg( tm.toString( u
"hh:mm:ss"_s ) ) + endToken;
1118 else if ( value.userType() == QMetaType::Type::QDateTime )
1120 const QDateTime dt = value.toDateTime();
1121 return startToken + tr(
"datetime: %1 (%2)" ).arg( dt.toString( u
"yyyy-MM-dd hh:mm:ss"_s ), dt.timeZoneAbbreviation() ) + endToken;
1123 else if ( value.userType() == QMetaType::Type::QString )
1125 const QString previewString = value.toString();
1126 if ( previewString.length() > maximumPreviewLength + 3 )
1128 return tr(
"'%1…'" ).arg( previewString.left( maximumPreviewLength ) );
1132 return '\'' + previewString +
'\'';
1135 else if ( value.userType() == QMetaType::Type::QVariantMap )
1137 QString mapStr = u
"{"_s;
1138 const QVariantMap map = value.toMap();
1140 for ( QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
1142 mapStr.append( separator );
1143 if ( separator.isEmpty() )
1146 mapStr.append( u
" '%1': %2"_s.arg( it.key(),
formatPreviewString( it.value(), htmlOutput ) ) );
1147 if ( mapStr.length() > maximumPreviewLength - 3 )
1149 mapStr = tr(
"%1…" ).arg( mapStr.left( maximumPreviewLength - 2 ) );
1158 else if ( value.userType() == QMetaType::Type::QVariantList || value.userType() == QMetaType::Type::QStringList )
1160 QString listStr = u
"["_s;
1161 const QVariantList list = value.toList();
1163 for (
const QVariant &arrayValue : list )
1165 listStr.append( separator );
1166 if ( separator.isEmpty() )
1169 listStr.append(
" " );
1171 if ( listStr.length() > maximumPreviewLength - 3 )
1173 listStr = QString( tr(
"%1…" ) ).arg( listStr.left( maximumPreviewLength - 2 ) );
1177 if ( !list.empty() )
1182 else if ( value.type() == QVariant::Color )
1184 const QColor color = value.value<QColor>();
1186 if ( !color.isValid() )
1188 return tr(
"<i>Invalid</i>" );
1191 switch ( color.spec() )
1193 case QColor::Spec::Cmyk:
1194 return u
"CMYKA: %1,%2,%3,%4,%5"_s
1195 .arg( color.cyanF(), 0,
'f', 2 ).arg( color.magentaF(), 0,
'f', 2 )
1196 .arg( color.yellowF(), 0,
'f', 2 ).arg( color.blackF(), 0,
'f', 2 )
1197 .arg( color.alphaF(), 0,
'f', 2 );
1199 case QColor::Spec::Hsv:
1200 return u
"HSVA: %1,%2,%3,%4"_s
1201 .arg( color.hsvHueF(), 0,
'f', 2 ).arg( color.hsvSaturationF(), 0,
'f', 2 )
1202 .arg( color.valueF(), 0,
'f', 2 ).arg( color.alphaF(), 0,
'f', 2 );
1204 case QColor::Spec::Hsl:
1205 return u
"HSLA: %1,%2,%3,%4"_s
1206 .arg( color.hslHueF(), 0,
'f', 2 ).arg( color.hslSaturationF(), 0,
'f', 2 )
1207 .arg( color.lightnessF(), 0,
'f', 2 ).arg( color.alphaF(), 0,
'f', 2 );
1209 case QColor::Spec::Rgb:
1210 case QColor::Spec::ExtendedRgb:
1211 return u
"RGBA: %1,%2,%3,%4"_s
1212 .arg( color.redF(), 0,
'f', 2 ).arg( color.greenF(), 0,
'f', 2 )
1213 .arg( color.blueF(), 0,
'f', 2 ).arg( color.alphaF(), 0,
'f', 2 );
1215 case QColor::Spec::Invalid:
1216 return tr(
"<i>Invalid</i>" );
1218 QgsDebugError( u
"Unknown color format: %1"_s.arg( color.spec() ) );
1219 return tr(
"<i>Unknown color format: %1</i>" ).arg( color.spec() );
1221 else if ( value.userType() == QMetaType::Type::Int ||
1222 value.userType() == QMetaType::Type::UInt ||
1223 value.userType() == QMetaType::Type::LongLong ||
1224 value.userType() == QMetaType::Type::ULongLong ||
1225 value.userType() == QMetaType::Type::Double ||
1227 value.userType() ==
static_cast<QMetaType::Type
>( QMetaType::Float ) )
1229 return QgsExpressionUtils::toLocalizedString( value );
1233 QString str { value.toString() };
1234 if ( str.length() > maximumPreviewLength - 3 )
1236 str = tr(
"%1…" ).arg( str.left( maximumPreviewLength - 2 ) );
1248 else if ( fieldType == QMetaType::Type::UnknownType )
1274 if ( columnRef && literal )
1276 field = columnRef->
name();
1277 value = literal->
value();
1287 if ( expressions.empty() )
1293 for (
const QString &
expression : expressions )
1304 else if ( field != inField )
1320 if ( inOp->isNotIn() )
1329 inField = columnRef->
name();
1332 else if ( columnRef->
name() != inField )
1339 const QList<QgsExpressionNode *>
nodes = nodeList->list();
1357 QStringList orParts;
1362 orParts.append( collectOrs( leftOrOp->opLeft(), leftOrOp->opRight() ) );
1366 orParts.append( leftOrOp->dump() );
1371 orParts.append( leftInOp->dump() );
1382 orParts.append( collectOrs( rightOrOp->opLeft(), rightOrOp->opRight() ) );
1386 orParts.append( rightOrOp->dump() );
1391 orParts.append( rightInOp->dump() );
1404 const QStringList orParts = collectOrs( orOp->opLeft(), orOp->opRight() );
1405 if ( orParts.isEmpty() )
1411 QString orPartsResult;
1428 const QString innerInfield { inOpInner->node()->referencedColumns().values().first() };
1432 inField = innerInfield;
1436 if ( innerInfield != inField )
1442 const auto constInnerValuesList { inOpInner->list()->list() };
1443 for (
const auto &innerInValueNode : std::as_const( constInnerValuesList ) )
1445 values.append( innerInValueNode->dump() );
1472 result = u
"%1 IN (%2)"_s.arg(
quotedColumnRef( inField ), values.join(
',' ) );
1478 return d->mRootNode.get();
1493 if ( attrIndex >= 0 )
1500 const QString fieldName = qgis::down_cast<const QgsExpressionNodeColumnRef *>( candidate.
rootNode() )->name();
1512 if ( !
expression.contains(
'\"' ) && fieldIndex != -1 )
1525 if ( !d->mRootNode )
1526 return QList<const QgsExpressionNode *>();
1528 return d->mRootNode->nodes();
DistanceUnit
Units of distance.
@ Unknown
Unknown distance unit.
@ Unknown
Unknown areal unit.
static QString geoNone()
Constant that holds the string representation for "No ellipse/No CRS".
Qgis::WkbType wkbType() const
Returns the WKB type of the geometry.
Represents a coordinate reference system (CRS).
QString userFriendlyIdentifier(Qgis::CrsIdentifierType type=Qgis::CrsIdentifierType::MediumString) const
Returns a user friendly identifier for the CRS.
Contains information about the context in which a coordinate transform is executed.
A general purpose distance and area calculator, capable of performing ellipsoid based calculations.
static QgsExpressionContextScope * projectScope(const QgsProject *project)
Creates a new scope which contains variables and functions relating to a QGIS project.
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
QVariant variable(const QString &name) const
Fetches a matching variable from the context.
An abstract base class for defining QgsExpression functions.
A binary expression operator, which operates on two values.
An expression node which takes its value from a feature's field.
QString name() const
The name of the column.
An expression node for value IN or NOT IN clauses.
An expression node for literal values.
QVariant value() const
The value of the literal.
A list of expression nodes.
QList< QgsExpressionNode * > list()
Gets a list of all the nodes.
Abstract base class for all nodes that can appear in an expression.
virtual QgsExpressionNode::NodeType nodeType() const =0
Gets the type of this node.
bool prepare(const QgsExpressionContext *context)
Gets the expression ready for evaluation - find out column indexes.
static const QList< QgsExpressionFunction * > & Functions()
QgsExpression & operator=(const QgsExpression &other)
Create a copy of this expression.
QString expression() const
Returns the original, unmodified expression string.
Qgis::DistanceUnit distanceUnits() const
Returns the desired distance units for calculations involving geomCalculator(), e....
static QString quotedValue(const QVariant &value)
Returns a string representation of a literal value, including appropriate quotations where required.
void setExpression(const QString &expression)
Set the expression string, will reset the whole internal structure.
static int functionIndex(const QString &name)
Returns index of the function in Functions array.
static double evaluateToDouble(const QString &text, double fallbackValue)
Attempts to evaluate a text string as an expression to a resultant double value.
static QString quoteFieldExpression(const QString &expression, const QgsVectorLayer *layer)
Validate if the expression is a field in the layer and ensure it is quoted.
static int functionCount()
Returns the number of functions defined in the parser.
QList< const QgsExpressionNode * > nodes() const
Returns a list of all nodes which are used in this expression.
static QString quotedString(QString text)
Returns a quoted version of a string (in single quotes).
QSet< QString > referencedVariables() const
Returns a list of all variables which are used in this expression.
static bool isFunctionName(const QString &name)
tells whether the identifier is a name of existing function
bool hasParserError() const
Returns true if an error occurred when parsing the input expression.
static QString variableHelpText(const QString &variableName)
Returns the help text for a specified variable.
QList< QgsExpression::ParserError > parserErrors() const
Returns parser error details including location of error.
QString evalErrorString() const
Returns evaluation error.
bool operator==(const QgsExpression &other) const
Compares two expressions.
QString parserErrorString() const
Returns parser error.
static QString formatPreviewString(const QVariant &value, bool htmlOutput=true, int maximumPreviewLength=60)
Formats an expression result for friendly display to the user.
static QString replaceExpressionText(const QString &action, const QgsExpressionContext *context, const QgsDistanceArea *distanceArea=nullptr)
This function replaces each expression between [% and %] in the string with the result of its evaluat...
static QStringList tags(const QString &name)
Returns a string list of search tags for a specified function.
bool isField() const
Checks whether an expression consists only of a single field reference.
QSet< QString > referencedColumns() const
Gets list of columns referenced by the expression.
QgsExpression()
Create an empty expression.
QString dump() const
Returns an expression string, constructed from the internal abstract syntax tree.
static PRIVATE QString helpText(QString name)
Returns the help text for a specified function.
static QString createFieldEqualityExpression(const QString &fieldName, const QVariant &value, QMetaType::Type fieldType=QMetaType::Type::UnknownType)
Create an expression allowing to evaluate if a field is equal to a value.
void setDistanceUnits(Qgis::DistanceUnit unit)
Sets the desired distance units for calculations involving geomCalculator(), e.g.,...
void setAreaUnits(Qgis::AreaUnit unit)
Sets the desired areal units for calculations involving geomCalculator(), e.g., "$area".
static bool isFieldEqualityExpression(const QString &expression, QString &field, QVariant &value)
Returns true if the given expression is a simple "field=value" type expression.
Qgis::AreaUnit areaUnits() const
Returns the desired areal units for calculations involving geomCalculator(), e.g.,...
QSet< QString > referencedFunctions() const
Returns a list of the names of all functions which are used in this expression.
static QString group(const QString &group)
Returns the translated name for a function group.
void setEvalErrorString(const QString &str)
Sets evaluation error (used internally by evaluation functions).
static QString quotedColumnRef(QString name)
Returns a quoted column reference (in double quotes).
void setGeomCalculator(const QgsDistanceArea *calc)
Sets the geometry calculator used for distance and area calculations in expressions.
const QgsExpressionNode * rootNode() const
Returns the root node of the expression.
bool hasEvalError() const
Returns true if an error occurred when evaluating last input.
static QString formatVariableHelp(const QString &description, bool showValue=true, const QVariant &value=QVariant())
Returns formatted help text for a variable.
QgsExpression(const QString &expr)
Creates a new expression based on the provided string.
static int expressionToLayerFieldIndex(const QString &expression, const QgsVectorLayer *layer)
Attempts to resolve an expression to a field index from the given layer.
bool needsGeometry() const
Returns true if the expression uses feature geometry for some computation.
QVariant evaluate()
Evaluate the feature and return the result.
static bool attemptReduceToInClause(const QStringList &expressions, QString &result)
Attempts to reduce a list of expressions to a single "field IN (val1, val2, ... )" type expression.
bool isValid() const
Checks if this expression is valid.
static bool addVariableHelpText(const QString name, const QString &description)
Adds a help string for a custom variable.
QgsDistanceArea * geomCalculator()
Returns calculator used for distance and area calculations (used by $length, $area and $perimeter fun...
QSet< int > referencedAttributeIndexes(const QgsFields &fields) const
Returns a list of field name indexes obtained from the provided fields.
static bool checkExpression(const QString &text, const QgsExpressionContext *context, QString &errorMessage)
Tests whether a string is a valid expression.
static const QString ALL_ATTRIBUTES
A special attribute that if set matches all attributes.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Container of fields for a vector layer.
QgsAttributeList allAttributesList() const
Utility function to get list of attribute indexes.
QgsField at(int i) const
Returns the field at particular index (must be in range 0..N-1).
Q_INVOKABLE int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
A geometry is the spatial representation of a feature.
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
A representation of the interval between two datetime values.
double days() const
Returns the interval duration in days.
double seconds() const
Returns the interval duration in seconds.
double hours() const
Returns the interval duration in hours.
double minutes() const
Returns the interval duration in minutes.
static QgsProject * instance()
Returns the QgsProject singleton instance.
static Q_INVOKABLE Qgis::DistanceUnit stringToDistanceUnit(const QString &string, bool *ok=nullptr)
Converts a translated string to a distance unit.
static Q_INVOKABLE Qgis::AreaUnit stringToAreaUnit(const QString &string, bool *ok=nullptr)
Converts a translated string to an areal unit.
static QMetaType::Type variantTypeToMetaType(QVariant::Type variantType)
Converts a QVariant::Type to a QMetaType::Type.
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.
Represents a vector layer which manages a vector based dataset.
static Q_INVOKABLE QString displayString(Qgis::WkbType type)
Returns a non-translated display string type for a WKB type, e.g., the geometry name used in WKT geom...
QMap< QString, QString > QgsStringMap
Q_GLOBAL_STATIC(QReadWriteLock, sDefinitionCacheLock)
QgsExpressionNode * parseExpression(const QString &str, QString &parserErrorMsg, QList< QgsExpression::ParserError > &parserErrors)
QList< int > QgsAttributeList
#define QgsDebugMsgLevel(str, level)
#define QgsDebugError(str)
QPointer< QgsMapLayer > QgsWeakMapLayerPointer
Weak pointer for QgsMapLayer.