50 if ( transferOwnership )
102 d->mRootNode =
::parseExpression( expression, d->mParserErrorString, d->mParserErrors );
103 d->mEvalErrorString = QString();
109 if ( !d->mExp.isNull() )
117 return QStringLiteral(
"\"%1\"" ).arg( name.replace(
'\"', QLatin1String(
"\"\"" ) ) );
122 text.replace(
'\'', QLatin1String(
"''" ) );
123 text.replace(
'\\', QLatin1String(
"\\\\" ) );
124 text.replace(
'\n', QLatin1String(
"\\n" ) );
125 text.replace(
'\t', QLatin1String(
"\\t" ) );
126 return QStringLiteral(
"'%1'" ).arg( text );
136 if ( value.isNull() )
137 return QStringLiteral(
"NULL" );
142 case QVariant::LongLong:
143 case QVariant::Double:
144 return value.toString();
147 return value.toBool() ? QStringLiteral(
"TRUE" ) : QStringLiteral(
"FALSE" );
151 QStringList quotedValues;
152 const QVariantList values = value.toList();
153 for (
const QVariant &v : values )
157 return QStringLiteral(
"array( %1 )" ).arg( quotedValues.join( QStringLiteral(
", " ) ) );
161 case QVariant::String:
175 for (
int i = 0; i < count; i++ )
180 for (
const QString &alias : aliases )
182 if ( QString::compare( name, alias, Qt::CaseInsensitive ) == 0 )
196 : d( new QgsExpressionPrivate )
198 d->mRootNode =
::parseExpression( expr, d->mParserErrorString, d->mParserErrors );
200 Q_ASSERT( !d->mParserErrorString.isNull() || d->mRootNode );
211 if ( !d->ref.deref() )
221 QgsExpression::operator QString()
const 227 : d( new QgsExpressionPrivate )
234 if ( !d->ref.deref() )
240 return ( d == other.d || d->mExp == other.d->mExp );
250 return d->mParserErrors.count() > 0;
255 return d->mParserErrorString;
260 return d->mParserErrors;
266 return QSet<QString>();
268 return d->mRootNode->referencedColumns();
274 return QSet<QString>();
276 return d->mRootNode->referencedVariables();
282 return QSet<QString>();
284 return d->mRootNode->referencedFunctions();
292 const QSet<QString> referencedFields = d->mRootNode->referencedColumns();
293 QSet<int> referencedIndexes;
295 for (
const QString &fieldName : referencedFields )
302 referencedIndexes << fields.
lookupField( fieldName );
305 return referencedIndexes;
312 return d->mRootNode->needsGeometry();
315 void QgsExpression::initGeomCalculator()
324 void QgsExpression::detach()
330 ( void )d->ref.deref();
332 d =
new QgsExpressionPrivate( *d );
340 d->mCalc = std::shared_ptr<QgsDistanceArea>(
new QgsDistanceArea( *calc ) );
348 d->mEvalErrorString = QString();
354 d->mRootNode =
::parseExpression( d->mExp, d->mParserErrorString, d->mParserErrors );
359 d->mEvalErrorString = tr(
"No root node! Parsing failed?" );
363 return d->mRootNode->prepare(
this, context );
368 d->mEvalErrorString = QString();
371 d->mEvalErrorString = tr(
"No root node! Parsing failed?" );
375 return d->mRootNode->eval(
this, static_cast<const QgsExpressionContext *>(
nullptr ) );
380 d->mEvalErrorString = QString();
383 d->mEvalErrorString = tr(
"No root node! Parsing failed?" );
387 return d->mRootNode->eval(
this, context );
392 return !d->mEvalErrorString.isNull();
397 return d->mEvalErrorString;
402 d->mEvalErrorString = str;
410 return d->mRootNode->dump();
415 return d->mCalc.get();
420 return d->mDistanceUnit;
425 d->mDistanceUnit = unit;
443 while ( index < action.size() )
445 QRegExp rx = QRegExp(
"\\[%([^\\]]+)%\\]" );
447 int pos = rx.indexIn( action, index );
452 index = pos + rx.matchedLength();
453 QString to_replace = rx.cap( 1 ).trimmed();
460 expr_action += action.midRef( start, index - start );
470 QVariant result = exp.
evaluate( context );
475 expr_action += action.midRef( start, index - start );
479 QgsDebugMsg(
"Expression result is: " + result.toString() );
480 expr_action += action.mid( start, pos - start ) + result.toString();
483 expr_action += action.midRef( index );
490 QSet<QString> variables;
492 while ( index < text.size() )
494 QRegExp rx = QRegExp(
"\\[%([^\\]]+)%\\]" );
496 int pos = rx.indexIn( text, index );
500 index = pos + rx.matchedLength();
501 QString to_replace = rx.cap( 1 ).trimmed();
516 double convertedValue = QLocale().toDouble( text, &ok );
519 return convertedValue;
529 QVariant result = expr.
evaluate( &context );
530 convertedValue = result.toDouble( &ok );
533 return fallbackValue;
535 return convertedValue;
542 QgsExpression::initFunctionHelp();
544 if ( !sFunctionHelpTexts.contains( name ) )
545 return tr(
"function help for %1 missing" ).arg( name );
547 const Help &f = sFunctionHelpTexts[ name ];
550 if ( f.mType == tr(
"group" ) )
551 name =
group( name );
553 name = name.toHtmlEscaped();
555 QString helpContents( QStringLiteral(
"<h3>%1</h3>\n<div class=\"description\"><p>%2</p></div>" )
556 .arg( tr(
"%1 %2" ).arg( f.mType, name ),
559 for (
const HelpVariant &v : qgis::as_const( f.mVariants ) )
561 if ( f.mVariants.size() > 1 )
563 helpContents += QStringLiteral(
"<h3>%1</h3>\n<div class=\"description\">%2</p></div>" ).arg( v.mName, v.mDescription );
566 if ( f.mType != tr(
"group" ) && f.mType != tr(
"expression" ) )
567 helpContents += QStringLiteral(
"<h4>%1</h4>\n<div class=\"syntax\">\n" ).arg( tr(
"Syntax" ) );
569 if ( f.mType == tr(
"operator" ) )
571 if ( v.mArguments.size() == 1 )
573 helpContents += QStringLiteral(
"<code><span class=\"functionname\">%1</span> <span class=\"argument\">%2</span></code>" )
574 .arg( name, v.mArguments[0].mArg );
576 else if ( v.mArguments.size() == 2 )
578 helpContents += QStringLiteral(
"<code><span class=\"argument\">%1</span> <span class=\"functionname\">%2</span> <span class=\"argument\">%3</span></code>" )
579 .arg( v.mArguments[0].mArg, name, v.mArguments[1].mArg );
582 else if ( f.mType != tr(
"group" ) && f.mType != tr(
"expression" ) )
584 helpContents += QStringLiteral(
"<code><span class=\"functionname\">%1</span>" ).arg( name );
586 bool hasOptionalArgs =
false;
588 if ( f.mType == tr(
"function" ) && ( f.mName[0] !=
'$' || !v.mArguments.isEmpty() || v.mVariableLenArguments ) )
593 for (
const HelpArg &a : qgis::as_const( v.mArguments ) )
599 hasOptionalArgs =
true;
600 helpContents += QStringLiteral(
"[" );
603 helpContents += delim;
604 helpContents += QStringLiteral(
"<span class=\"argument\">%2%3</span>" ).arg(
606 a.mDefaultVal.isEmpty() ? QLatin1String(
"" ) :
'=' + a.mDefaultVal
610 helpContents += QStringLiteral(
"]" );
612 delim = QStringLiteral(
"," );
615 if ( v.mVariableLenArguments )
617 helpContents += QChar( 0x2026 );
623 helpContents += QLatin1String(
"</code>" );
625 if ( hasOptionalArgs )
627 helpContents += QLatin1String(
"<br/><br/>" ) + tr(
"[ ] marks optional components" );
631 if ( !v.mArguments.isEmpty() )
633 helpContents += QStringLiteral(
"<h4>%1</h4>\n<div class=\"arguments\">\n<table>" ).arg( tr(
"Arguments" ) );
635 for (
const HelpArg &a : qgis::as_const( v.mArguments ) )
640 helpContents += QStringLiteral(
"<tr><td class=\"argument\">%1</td><td>%2</td></tr>" ).arg( a.mArg, a.mDescription );
643 helpContents += QLatin1String(
"</table>\n</div>\n" );
646 if ( !v.mExamples.isEmpty() )
648 helpContents += QStringLiteral(
"<h4>%1</h4>\n<div class=\"examples\">\n<ul>\n" ).arg( tr(
"Examples" ) );
650 for (
const HelpExample &e : qgis::as_const( v.mExamples ) )
652 helpContents +=
"<li><code>" + e.mExpression +
"</code> → <code>" + e.mReturns +
"</code>";
654 if ( !e.mNote.isEmpty() )
655 helpContents += QStringLiteral(
" (%1)" ).arg( e.mNote );
657 helpContents += QLatin1String(
"</li>\n" );
660 helpContents += QLatin1String(
"</ul>\n</div>\n" );
663 if ( !v.mNotes.isEmpty() )
665 helpContents += QStringLiteral(
"<h4>%1</h4>\n<div class=\"notes\"><p>%2</p></div>\n" ).arg( tr(
"Notes" ), v.mNotes );
672 QHash<QString, QString> QgsExpression::sVariableHelpTexts;
674 void QgsExpression::initVariableHelp()
676 if ( !sVariableHelpTexts.isEmpty() )
680 sVariableHelpTexts.insert( QStringLiteral(
"qgis_version" ), QCoreApplication::translate(
"variable_help",
"Current QGIS version string." ) );
681 sVariableHelpTexts.insert( QStringLiteral(
"qgis_version_no" ), QCoreApplication::translate(
"variable_help",
"Current QGIS version number." ) );
682 sVariableHelpTexts.insert( QStringLiteral(
"qgis_release_name" ), QCoreApplication::translate(
"variable_help",
"Current QGIS release name." ) );
683 sVariableHelpTexts.insert( QStringLiteral(
"qgis_os_name" ), QCoreApplication::translate(
"variable_help",
"Operating system name, e.g., 'windows', 'linux' or 'osx'." ) );
684 sVariableHelpTexts.insert( QStringLiteral(
"qgis_platform" ), QCoreApplication::translate(
"variable_help",
"QGIS platform, e.g., 'desktop' or 'server'." ) );
685 sVariableHelpTexts.insert( QStringLiteral(
"user_account_name" ), QCoreApplication::translate(
"variable_help",
"Current user's operating system account name." ) );
686 sVariableHelpTexts.insert( QStringLiteral(
"user_full_name" ), QCoreApplication::translate(
"variable_help",
"Current user's operating system user name (if available)." ) );
689 sVariableHelpTexts.insert( QStringLiteral(
"project_title" ), QCoreApplication::translate(
"variable_help",
"Title of current project." ) );
690 sVariableHelpTexts.insert( QStringLiteral(
"project_path" ), QCoreApplication::translate(
"variable_help",
"Full path (including file name) of current project." ) );
691 sVariableHelpTexts.insert( QStringLiteral(
"project_folder" ), QCoreApplication::translate(
"variable_help",
"Folder for current project." ) );
692 sVariableHelpTexts.insert( QStringLiteral(
"project_filename" ), QCoreApplication::translate(
"variable_help",
"Filename of current project." ) );
693 sVariableHelpTexts.insert( QStringLiteral(
"project_basename" ), QCoreApplication::translate(
"variable_help",
"Base name of current project's filename (without path and extension)." ) );
694 sVariableHelpTexts.insert( QStringLiteral(
"project_home" ), QCoreApplication::translate(
"variable_help",
"Home path of current project." ) );
695 sVariableHelpTexts.insert( QStringLiteral(
"project_crs" ), QCoreApplication::translate(
"variable_help",
"Coordinate reference system of project (e.g., 'EPSG:4326')." ) );
696 sVariableHelpTexts.insert( QStringLiteral(
"project_crs_definition" ), QCoreApplication::translate(
"variable_help",
"Coordinate reference system of project (full definition)." ) );
697 sVariableHelpTexts.insert( QStringLiteral(
"project_author" ), QCoreApplication::translate(
"variable_help",
"Project author, taken from project metadata." ) );
698 sVariableHelpTexts.insert( QStringLiteral(
"project_abstract" ), QCoreApplication::translate(
"variable_help",
"Project abstract, taken from project metadata." ) );
699 sVariableHelpTexts.insert( QStringLiteral(
"project_creation_date" ), QCoreApplication::translate(
"variable_help",
"Project creation date, taken from project metadata." ) );
700 sVariableHelpTexts.insert( QStringLiteral(
"project_identifier" ), QCoreApplication::translate(
"variable_help",
"Project identifier, taken from project metadata." ) );
701 sVariableHelpTexts.insert( QStringLiteral(
"project_keywords" ), QCoreApplication::translate(
"variable_help",
"Project keywords, taken from project metadata." ) );
704 sVariableHelpTexts.insert( QStringLiteral(
"layer_name" ), QCoreApplication::translate(
"variable_help",
"Name of current layer." ) );
705 sVariableHelpTexts.insert( QStringLiteral(
"layer_id" ), QCoreApplication::translate(
"variable_help",
"ID of current layer." ) );
706 sVariableHelpTexts.insert( QStringLiteral(
"layer" ), QCoreApplication::translate(
"variable_help",
"The current layer." ) );
709 sVariableHelpTexts.insert( QStringLiteral(
"layout_name" ), QCoreApplication::translate(
"variable_help",
"Name of composition." ) );
710 sVariableHelpTexts.insert( QStringLiteral(
"layout_numpages" ), QCoreApplication::translate(
"variable_help",
"Number of pages in composition." ) );
711 sVariableHelpTexts.insert( QStringLiteral(
"layout_page" ), QCoreApplication::translate(
"variable_help",
"Current page number in composition." ) );
712 sVariableHelpTexts.insert( QStringLiteral(
"layout_pageheight" ), QCoreApplication::translate(
"variable_help",
"Composition page height in mm." ) );
713 sVariableHelpTexts.insert( QStringLiteral(
"layout_pagewidth" ), QCoreApplication::translate(
"variable_help",
"Composition page width in mm." ) );
714 sVariableHelpTexts.insert( QStringLiteral(
"layout_dpi" ), QCoreApplication::translate(
"variable_help",
"Composition resolution (DPI)." ) );
717 sVariableHelpTexts.insert( QStringLiteral(
"atlas_layerid" ), QCoreApplication::translate(
"variable_help",
"Current atlas coverage layer ID." ) );
718 sVariableHelpTexts.insert( QStringLiteral(
"atlas_layername" ), QCoreApplication::translate(
"variable_help",
"Current atlas coverage layer name." ) );
719 sVariableHelpTexts.insert( QStringLiteral(
"atlas_totalfeatures" ), QCoreApplication::translate(
"variable_help",
"Total number of features in atlas." ) );
720 sVariableHelpTexts.insert( QStringLiteral(
"atlas_featurenumber" ), QCoreApplication::translate(
"variable_help",
"Current atlas feature number." ) );
721 sVariableHelpTexts.insert( QStringLiteral(
"atlas_filename" ), QCoreApplication::translate(
"variable_help",
"Current atlas file name." ) );
722 sVariableHelpTexts.insert( QStringLiteral(
"atlas_pagename" ), QCoreApplication::translate(
"variable_help",
"Current atlas page name." ) );
723 sVariableHelpTexts.insert( QStringLiteral(
"atlas_feature" ), QCoreApplication::translate(
"variable_help",
"Current atlas feature (as feature object)." ) );
724 sVariableHelpTexts.insert( QStringLiteral(
"atlas_featureid" ), QCoreApplication::translate(
"variable_help",
"Current atlas feature ID." ) );
725 sVariableHelpTexts.insert( QStringLiteral(
"atlas_geometry" ), QCoreApplication::translate(
"variable_help",
"Current atlas feature geometry." ) );
728 sVariableHelpTexts.insert( QStringLiteral(
"item_id" ), QCoreApplication::translate(
"variable_help",
"Layout item user ID (not necessarily unique)." ) );
729 sVariableHelpTexts.insert( QStringLiteral(
"item_uuid" ), QCoreApplication::translate(
"variable_help",
"layout item unique ID." ) );
730 sVariableHelpTexts.insert( QStringLiteral(
"item_left" ), QCoreApplication::translate(
"variable_help",
"Left position of layout item (in mm)." ) );
731 sVariableHelpTexts.insert( QStringLiteral(
"item_top" ), QCoreApplication::translate(
"variable_help",
"Top position of layout item (in mm)." ) );
732 sVariableHelpTexts.insert( QStringLiteral(
"item_width" ), QCoreApplication::translate(
"variable_help",
"Width of layout item (in mm)." ) );
733 sVariableHelpTexts.insert( QStringLiteral(
"item_height" ), QCoreApplication::translate(
"variable_help",
"Height of layout item (in mm)." ) );
736 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." ) );
737 sVariableHelpTexts.insert( QStringLiteral(
"map_rotation" ), QCoreApplication::translate(
"variable_help",
"Current rotation of map." ) );
738 sVariableHelpTexts.insert( QStringLiteral(
"map_scale" ), QCoreApplication::translate(
"variable_help",
"Current scale of map." ) );
739 sVariableHelpTexts.insert( QStringLiteral(
"map_extent" ), QCoreApplication::translate(
"variable_help",
"Geometry representing the current extent of the map." ) );
740 sVariableHelpTexts.insert( QStringLiteral(
"map_extent_center" ), QCoreApplication::translate(
"variable_help",
"Center of map." ) );
741 sVariableHelpTexts.insert( QStringLiteral(
"map_extent_width" ), QCoreApplication::translate(
"variable_help",
"Width of map." ) );
742 sVariableHelpTexts.insert( QStringLiteral(
"map_extent_height" ), QCoreApplication::translate(
"variable_help",
"Height of map." ) );
743 sVariableHelpTexts.insert( QStringLiteral(
"map_crs" ), QCoreApplication::translate(
"variable_help",
"Coordinate reference system of map (e.g., 'EPSG:4326')." ) );
744 sVariableHelpTexts.insert( QStringLiteral(
"map_crs_definition" ), QCoreApplication::translate(
"variable_help",
"Coordinate reference system of map (full definition)." ) );
745 sVariableHelpTexts.insert( QStringLiteral(
"map_units" ), QCoreApplication::translate(
"variable_help",
"Units for map measurements." ) );
747 sVariableHelpTexts.insert( QStringLiteral(
"row_number" ), QCoreApplication::translate(
"variable_help",
"Stores the number of the current row." ) );
748 sVariableHelpTexts.insert( QStringLiteral(
"grid_number" ), QCoreApplication::translate(
"variable_help",
"Current grid annotation value." ) );
749 sVariableHelpTexts.insert( QStringLiteral(
"grid_axis" ), QCoreApplication::translate(
"variable_help",
"Current grid annotation axis (e.g., 'x' for longitude, 'y' for latitude)." ) );
752 sVariableHelpTexts.insert( QStringLiteral(
"snapping_results" ), QCoreApplication::translate(
"variable_help",
753 "<p>An array with an item for each snapped point.</p>" 754 "<p>Each item is a map with the following keys:</p>" 756 "<dt>valid</dt><dd>Boolean that indicates if the snapping result is valid</dd>" 757 "<dt>layer</dt><dd>The layer on which the snapped feature is</dd>" 758 "<dt>feature_id</dt><dd>The feature id of the snapped feature</dd>" 759 "<dt>vertex_index</dt><dd>The index of the snapped vertex</dd>" 760 "<dt>distance</dt><dd>The distance between the mouse cursor and the snapped point at the time of snapping</dd>" 765 sVariableHelpTexts.insert( QStringLiteral(
"geometry_part_count" ), QCoreApplication::translate(
"variable_help",
"Number of parts in rendered feature's geometry." ) );
766 sVariableHelpTexts.insert( QStringLiteral(
"geometry_part_num" ), QCoreApplication::translate(
"variable_help",
"Current geometry part number for feature being rendered." ) );
767 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." ) );
768 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." ) );
770 sVariableHelpTexts.insert( QStringLiteral(
"symbol_color" ), QCoreApplication::translate(
"symbol_color",
"Color of symbol used to render the feature." ) );
771 sVariableHelpTexts.insert( QStringLiteral(
"symbol_angle" ), QCoreApplication::translate(
"symbol_angle",
"Angle of symbol used to render the feature (valid for marker symbols only)." ) );
774 sVariableHelpTexts.insert( QStringLiteral(
"cluster_color" ), QCoreApplication::translate(
"cluster_color",
"Color of symbols within a cluster, or NULL if symbols have mixed colors." ) );
775 sVariableHelpTexts.insert( QStringLiteral(
"cluster_size" ), QCoreApplication::translate(
"cluster_size",
"Number of symbols contained within a cluster." ) );
778 sVariableHelpTexts.insert( QStringLiteral(
"algorithm_id" ), QCoreApplication::translate(
"algorithm_id",
"Unique ID for algorithm." ) );
781 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)." ) );
784 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." ) );
785 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." ) );
790 QgsExpression::initVariableHelp();
791 return sVariableHelpTexts.value( variableName, QString() );
796 QString text = !description.isEmpty() ? QStringLiteral(
"<p>%1</p>" ).arg( description ) : QString();
800 if ( !value.isValid() )
802 valueString = QCoreApplication::translate(
"variable_help",
"not set" );
808 text.append( QCoreApplication::translate(
"variable_help",
"<p>Current value: %1</p>" ).arg( valueString ) );
813 QHash<QString, QString> QgsExpression::sGroups;
817 if ( sGroups.isEmpty() )
819 sGroups.insert( QStringLiteral(
"General" ), tr(
"General" ) );
820 sGroups.insert( QStringLiteral(
"Operators" ), tr(
"Operators" ) );
821 sGroups.insert( QStringLiteral(
"Conditionals" ), tr(
"Conditionals" ) );
822 sGroups.insert( QStringLiteral(
"Fields and Values" ), tr(
"Fields and Values" ) );
823 sGroups.insert( QStringLiteral(
"Math" ), tr(
"Math" ) );
824 sGroups.insert( QStringLiteral(
"Conversions" ), tr(
"Conversions" ) );
825 sGroups.insert( QStringLiteral(
"Date and Time" ), tr(
"Date and Time" ) );
826 sGroups.insert( QStringLiteral(
"String" ), tr(
"String" ) );
827 sGroups.insert( QStringLiteral(
"Color" ), tr(
"Color" ) );
828 sGroups.insert( QStringLiteral(
"GeometryGroup" ), tr(
"Geometry" ) );
829 sGroups.insert( QStringLiteral(
"Record" ), tr(
"Record" ) );
830 sGroups.insert( QStringLiteral(
"Variables" ), tr(
"Variables" ) );
831 sGroups.insert( QStringLiteral(
"Fuzzy Matching" ), tr(
"Fuzzy Matching" ) );
832 sGroups.insert( QStringLiteral(
"Recent (%1)" ), tr(
"Recent (%1)" ) );
838 return sGroups.value( name, name );
843 static const int MAX_PREVIEW = 60;
850 return tr(
"<i><empty geometry></i>" );
854 else if ( !value.isValid() )
856 return tr(
"<i>NULL</i>" );
862 return tr(
"<i><feature: %1></i>" ).arg( feat.
id() );
868 return tr(
"<i><interval: %1 days></i>" ).arg( interval.
days() );
872 return tr(
"<i><gradient ramp></i>" );
874 else if ( value.type() == QVariant::Date )
876 QDate dt = value.toDate();
877 return tr(
"<i><date: %1></i>" ).arg( dt.toString( QStringLiteral(
"yyyy-MM-dd" ) ) );
879 else if ( value.type() == QVariant::Time )
881 QTime tm = value.toTime();
882 return tr(
"<i><time: %1></i>" ).arg( tm.toString( QStringLiteral(
"hh:mm:ss" ) ) );
884 else if ( value.type() == QVariant::DateTime )
886 QDateTime dt = value.toDateTime();
887 return tr(
"<i><datetime: %1></i>" ).arg( dt.toString( QStringLiteral(
"yyyy-MM-dd hh:mm:ss" ) ) );
889 else if ( value.type() == QVariant::String )
891 QString previewString = value.toString();
892 if ( previewString.length() > MAX_PREVIEW + 3 )
894 return tr(
"'%1…'" ).arg( previewString.left( MAX_PREVIEW ) );
898 return previewString.prepend(
'\'' ).append(
'\'' );
901 else if ( value.type() == QVariant::Map )
904 const QVariantMap map = value.toMap();
905 for ( QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
907 if ( !mapStr.isEmpty() ) mapStr.append(
", " );
909 if ( mapStr.length() > MAX_PREVIEW + 3 )
911 mapStr = QString( tr(
"%1…" ) ).arg( mapStr.left( MAX_PREVIEW ) );
915 return tr(
"<i><map: %1></i>" ).arg( mapStr );
917 else if ( value.type() == QVariant::List || value.type() == QVariant::StringList )
920 const QVariantList list = value.toList();
921 for ( QVariantList::const_iterator it = list.constBegin(); it != list.constEnd(); ++it )
923 if ( !listStr.isEmpty() ) listStr.append(
", " );
925 if ( listStr.length() > MAX_PREVIEW + 3 )
927 listStr = QString( tr(
"%1…" ) ).arg( listStr.left( MAX_PREVIEW ) );
931 return tr(
"<i><array: %1></i>" ).arg( listStr );
935 return value.toString();
943 if ( value.isNull() )
944 expr = QStringLiteral(
"%1 IS NULL" ).arg(
quotedColumnRef( fieldName ) );
964 return QList<const QgsExpressionNode *>();
966 return d->mRootNode->nodes();
int lookupField(const QString &fieldName) const
Look 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 QList< QgsExpressionFunction * > sOwnedFunctions
List of functions owned by the expression engine.
static QString quotedColumnRef(QString name)
Returns a quoted column reference (in double quotes)
bool isNull() const
Returns true if the geometry is null (ie, contains no underlying geometry accessible via geometry() )...
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.
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...
static QString formatPreviewString(const QVariant &value)
Formats an expression result for friendly display to the user.
QString parserErrorString() const
Returns parser error.
QSet< QString > referencedVariables() const
Returns a list of all variables which are used in this expression.
static QStringList sBuiltinFunctions
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
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...
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.
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...