@@ -799,6 +799,19 @@ static QVariant fcnFormatNumber( const QVariantList& values, QgsFeature*, QgsExp
799
799
return QString ( " %L1" ).arg ( value, 0 , ' f' , places );
800
800
}
801
801
802
+ static QVariant fcnFormatDate ( const QVariantList& values, QgsFeature*, QgsExpression* parent )
803
+ {
804
+ QDateTime dt = getDateTimeValue ( values.at ( 0 ), parent );
805
+ QString format = getStringValue ( values.at ( 1 ), parent );
806
+ return dt.toString ( format );
807
+ }
808
+
809
+ static QVariant fcnSpecialColumn ( const QVariantList& values, QgsFeature* /* f*/ , QgsExpression* parent )
810
+ {
811
+ QString varName = getStringValue ( values.at ( 0 ), parent );
812
+ return QgsExpression::specialColumn ( varName );
813
+ }
814
+
802
815
QList<QgsExpression::FunctionDef> QgsExpression::gmBuiltinFunctions;
803
816
804
817
const QList<QgsExpression::FunctionDef> &QgsExpression::BuiltinFunctions ()
@@ -855,6 +868,7 @@ const QList<QgsExpression::FunctionDef> &QgsExpression::BuiltinFunctions()
855
868
<< FunctionDef ( " rpad" , 3 , fcnRPad, QObject::tr ( " String" ) )
856
869
<< FunctionDef ( " lpad" , 3 , fcnLPad, QObject::tr ( " String" ) )
857
870
<< FunctionDef ( " format_number" , 2 , fcnFormatNumber, QObject::tr ( " String" ) )
871
+ << FunctionDef ( " format_date" , 2 , fcnFormatDate, QObject::tr ( " String" ) )
858
872
859
873
// geometry accessors
860
874
<< FunctionDef ( " xat" , 1 , fcnXat, QObject::tr ( " Geometry" ), " " , true )
@@ -868,12 +882,61 @@ const QList<QgsExpression::FunctionDef> &QgsExpression::BuiltinFunctions()
868
882
<< FunctionDef ( " $rownum" , 0 , fcnRowNumber, QObject::tr ( " Record" ) )
869
883
<< FunctionDef ( " $id" , 0 , fcnFeatureId, QObject::tr ( " Record" ) )
870
884
<< FunctionDef ( " $scale" , 0 , fcnScale, QObject::tr ( " Record" ) )
885
+ // private functions
886
+ << FunctionDef ( " _specialcol_" , 1 , fcnSpecialColumn, QObject::tr ( " Special" ) )
871
887
;
872
888
}
873
889
874
890
return gmBuiltinFunctions;
875
891
}
876
892
893
+ QMap<QString, QVariant> QgsExpression::gmSpecialColumns;
894
+
895
+ void QgsExpression::setSpecialColumn ( const QString& name, QVariant variant )
896
+ {
897
+ int fnIdx = functionIndex ( name );
898
+ if ( fnIdx != -1 )
899
+ {
900
+ // function of the same name already exists
901
+ return ;
902
+ }
903
+ gmSpecialColumns[ name ] = variant;
904
+ }
905
+
906
+ void QgsExpression::unsetSpecialColumn ( const QString& name )
907
+ {
908
+ QMap<QString, QVariant>::iterator fit = gmSpecialColumns.find ( name );
909
+ if ( fit != gmSpecialColumns.end () )
910
+ {
911
+ gmSpecialColumns.erase ( fit );
912
+ }
913
+ }
914
+
915
+ QVariant QgsExpression::specialColumn ( const QString& name )
916
+ {
917
+ int fnIdx = functionIndex ( name );
918
+ if ( fnIdx != -1 )
919
+ {
920
+ // function of the same name already exists
921
+ return QVariant ();
922
+ }
923
+ QMap<QString, QVariant>::iterator it = gmSpecialColumns.find ( name );
924
+ if ( it == gmSpecialColumns.end () )
925
+ {
926
+ return QVariant ();
927
+ }
928
+ return it.value ();
929
+ }
930
+
931
+ QList<QgsExpression::FunctionDef> QgsExpression::specialColumns ()
932
+ {
933
+ QList<FunctionDef> defs;
934
+ for ( QMap<QString, QVariant>::const_iterator it = gmSpecialColumns.begin (); it != gmSpecialColumns.end (); ++it )
935
+ {
936
+ defs << FunctionDef ( it.key (), 0 , 0 , QObject::tr ( " Record" ));
937
+ }
938
+ return defs;
939
+ }
877
940
878
941
bool QgsExpression::isFunctionName ( QString name )
879
942
{
@@ -1049,12 +1112,27 @@ void QgsExpression::acceptVisitor( QgsExpression::Visitor& v )
1049
1112
mRootNode ->accept ( v );
1050
1113
}
1051
1114
1052
- QString QgsExpression::replaceExpressionText ( QString action, QgsFeature & feat,
1115
+ QString QgsExpression::replaceExpressionText ( QString action, QgsFeature* feat,
1053
1116
QgsVectorLayer* layer,
1054
1117
const QMap<QString, QVariant> *substitutionMap )
1055
1118
{
1056
1119
QString expr_action;
1057
1120
1121
+ QMap<QString, QVariant> savedValues;
1122
+ if ( substitutionMap )
1123
+ {
1124
+ // variables with a local scope (must be restored after evaluation)
1125
+ for ( QMap<QString, QVariant>::const_iterator sit = substitutionMap->begin (); sit != substitutionMap->end (); ++sit )
1126
+ {
1127
+ QVariant oldValue = QgsExpression::specialColumn ( sit.key () );
1128
+ if ( !oldValue.isNull () )
1129
+ savedValues.insert ( sit.key (), oldValue );
1130
+
1131
+ // set the new value
1132
+ QgsExpression::setSpecialColumn ( sit.key (), sit.value () );
1133
+ }
1134
+ }
1135
+
1058
1136
int index = 0 ;
1059
1137
while ( index < action.size () )
1060
1138
{
@@ -1070,12 +1148,6 @@ QString QgsExpression::replaceExpressionText( QString action, QgsFeature &feat,
1070
1148
QString to_replace = rx.cap ( 1 ).trimmed ();
1071
1149
QgsDebugMsg ( " Found expression: " + to_replace );
1072
1150
1073
- if ( substitutionMap && substitutionMap->contains ( to_replace ) )
1074
- {
1075
- expr_action += action.mid ( start, pos - start ) + substitutionMap->value ( to_replace ).toString ();
1076
- continue ;
1077
- }
1078
-
1079
1151
QgsExpression exp ( to_replace );
1080
1152
if ( exp.hasParserError () )
1081
1153
{
@@ -1084,7 +1156,15 @@ QString QgsExpression::replaceExpressionText( QString action, QgsFeature &feat,
1084
1156
continue ;
1085
1157
}
1086
1158
1087
- QVariant result = exp.evaluate ( &feat, layer->pendingFields () );
1159
+ QVariant result;
1160
+ if ( layer )
1161
+ {
1162
+ result = exp.evaluate ( feat, layer->pendingFields () );
1163
+ }
1164
+ else
1165
+ {
1166
+ result = exp.evaluate ( feat );
1167
+ }
1088
1168
if ( exp.hasEvalError () )
1089
1169
{
1090
1170
QgsDebugMsg ( " Expression parser eval error: " + exp.evalErrorString () );
@@ -1097,10 +1177,24 @@ QString QgsExpression::replaceExpressionText( QString action, QgsFeature &feat,
1097
1177
}
1098
1178
1099
1179
expr_action += action.mid ( index );
1180
+
1181
+ // restore overwritten local values
1182
+ for ( QMap<QString, QVariant>::const_iterator sit = savedValues.begin (); sit != savedValues.end (); ++sit )
1183
+ {
1184
+ QgsExpression::setSpecialColumn ( sit.key (), sit.value () );
1185
+ }
1186
+
1100
1187
return expr_action;
1101
1188
}
1102
1189
1103
1190
1191
+ QString QgsExpression::replaceExpressionText ( QString action, QgsFeature& feat,
1192
+ QgsVectorLayer* layer,
1193
+ const QMap<QString, QVariant> *substitutionMap )
1194
+ {
1195
+ return replaceExpressionText ( action, &feat, layer, substitutionMap );
1196
+ }
1197
+
1104
1198
QgsExpression::Node* QgsExpression::Node::createFromOgcFilter ( QDomElement &element, QString &errorMessage )
1105
1199
{
1106
1200
if ( element.isNull () )
@@ -2048,7 +2142,11 @@ QgsExpression::Node* QgsExpression::NodeLiteral::createFromOgcFilter( QDomElemen
2048
2142
2049
2143
QVariant QgsExpression::NodeColumnRef::eval ( QgsExpression* /* parent*/ , QgsFeature* f )
2050
2144
{
2051
- return f->attributeMap ()[mIndex ];
2145
+ if ( f )
2146
+ {
2147
+ return f->attributeMap ()[mIndex ];
2148
+ }
2149
+ return QVariant (" [" + mName + " ]" );
2052
2150
}
2053
2151
2054
2152
bool QgsExpression::NodeColumnRef::prepare ( QgsExpression* parent, const QgsFieldMap& fields )
0 commit comments