Skip to content

Commit

Permalink
Remove deprecated methods from QgsExpression
Browse files Browse the repository at this point in the history
Now all evaluate/prepare/etc methods must be called using QgsExpressionContexts

Also remove most remaining traces of special variables. This brings some
user facing changes, such that existing expressions may need to be
updated if they used these old special variables (eg $scale,
$feature). These changes are noted in doc/qgis3_user_changes.dox
so that we can include them in the release notes.
  • Loading branch information
nyalldawson committed Aug 10, 2016
1 parent 56400b1 commit 7da8110
Show file tree
Hide file tree
Showing 21 changed files with 112 additions and 929 deletions.
24 changes: 24 additions & 0 deletions doc/api_break.dox
Expand Up @@ -243,6 +243,13 @@ be returned in place of a null pointer.</li>
<li>updateCRSCache() has been renamed to updateCrsCache</li>
</ul>

\subsection qgis_api_break_3_0_QgsDataDefined QgsDataDefined

<ul>
<li>expressionParams(), setExpressionParams() and insertExpressionParam() have been removed.
QgsExpressionContext variables should be used in their place.</li>
</ul>

\subsection qgis_api_break_3_0_QgsDataDefinedSymbolDialog QgsDataDefinedSymbolDialog

<ul>
Expand Down Expand Up @@ -290,6 +297,23 @@ place of a null pointer.</li>
<li>The ct member has been removed. Use coordinateTransform() and setCoordinateTransform() instead.
</ul>

\subsection qgis_api_break_3_0_QgsExpression QgsExpression

<ul>
<li>prepare( const QgsFields &fields ) has been removed. Use prepare( const QgsExpressionContext *context ) instead.</li>
<li>The evaluate methods which accept feature parameters have been removed. Use the version which takes a QgsExpressionContext
argument instead.</li>
<li>isValid( const QString& text, const QgsFields& fields, QString &errorMessage ) has been removed, use the QgsExpressionContext
version instead.</li>
<li>setCurrentRowNumber, currentRowNumber, scale, setScale, setSpecialColumn, unsetSpecialColumn, specialColumn, hasSpecialColumn have been
removed. Use QgsExpressionContext variables instead.</li>
<li>The replaceExpressionText version which accepts a QgsFeature argument has been removed. Use the QgsExpressionContext
version instead.</li>
<li>QgsExpression::Function::func has been modified to use a QgsExpressionContext argument rather than a QgsFeature.</li>
<li>The QgsExpression::Node::eval and prepare versions which take a QgsFeature has been removed, use the QgsExpressionContext versions instead.</li>
<li>QgsExpression::Interval has been removed. Use QgsInterval instead.</li>
</ul>

\subsection qgis_api_break_3_0_QgsFeature QgsFeature

<ul>
Expand Down
24 changes: 24 additions & 0 deletions doc/qgis3_user_changes.dox
@@ -0,0 +1,24 @@
/*! \page qgis3_user_changes QGIS 3.0 User Changes

\tableofcontents

Notes regarding user related changes for QGIS 3.0 which should be included in the release notes.

\subsection qgis3_user_changes_expressions Expressions

QGIS 3.0 brings some changes to the expression engine, which may require existing projects to
be updated so that any expressions in use have the following changes:
<ul>
<li>$rownum has been replaced by @row_number</li>
<li>$scale has been replaced by @map_scale</li>
<li>$map has been replaced by @map_id</li>
<li>$numpages has been replaced by @layout_numpages</li>
<li>$page has been replaced by @layout_page</li>
<li>$feature has been replaced by @atlas_featurenumber</li>
<li>$atlasfeatureid has been replaced by @atlas_featureid</li>
<li>$atlasfeature has been replaced by @atlas_feature</li>
<li>$atlasgeometry has been replaced by @atlas_geometry</li>
<li>$numfeatures has been replaced by @atlas_totalfeatures</li>
</ul>

*/
5 changes: 4 additions & 1 deletion python/core/__init__.py
Expand Up @@ -72,7 +72,10 @@ def __init__(self, func, name, args, group, helptext='', usesgeometry=True, refe
self.function = func
self.expandargs = expandargs

def func(self, values, feature, parent):
def func(self, values, context, parent):
feature = None
if context:
feature = context.feature()
try:
if self.expandargs:
values.append(feature)
Expand Down
6 changes: 0 additions & 6 deletions python/core/qgsdatadefined.sip
Expand Up @@ -110,12 +110,6 @@ class QgsDataDefined
*/
QString expressionOrField() const;

//! @note not available in python bindings
//QMap<QString, QVariant> expressionParams() const;
//! @note not available in python bindings
//void setExpressionParams( QMap<QString, QVariant> params );
void insertExpressionParam( const QString& key, const QVariant& param );

/** Prepares the expression using a vector layer
* @param layer vector layer
* @returns true if expression was successfully prepared
Expand Down
137 changes: 3 additions & 134 deletions python/core/qgsexpression.sip
Expand Up @@ -22,10 +22,6 @@ class QgsExpression
//! Returns root node of the expression. Root node is null is parsing has failed
const QgsExpression::Node* rootNode() const;

//! Get the expression ready for evaluation - find out column indexes.
//! @deprecated use prepare( const QgsExpressionContext *context ) instead
bool prepare( const QgsFields &fields ) /Deprecated/;

/** Get the expression ready for evaluation - find out column indexes.
* @param context context for preparing expression
* @note added in QGIS 2.12
Expand All @@ -47,28 +43,6 @@ class QgsExpression

// evaluation

//! Evaluate the feature and return the result
//! @note prepare() should be called before calling this method
//! @deprecated use evaluate( const QgsExpressionContext* context ) instead
QVariant evaluate( const QgsFeature* f ) /Deprecated/;

//! Evaluate the feature and return the result
//! @note prepare() should be called before calling this method
//! @note available in python bindings as evaluatePrepared
//! @deprecated use evaluate( const QgsExpressionContext* context ) instead
QVariant evaluate( const QgsFeature& f ) /PyName=evaluatePrepared,Deprecated/;

//! Evaluate the feature and return the result
//! @note this method does not expect that prepare() has been called on this instance
//! @deprecated use evaluate( const QgsExpressionContext* context ) instead
QVariant evaluate( const QgsFeature* f, const QgsFields& fields ) /Deprecated/;

//! Evaluate the feature and return the result
//! @note this method does not expect that prepare() has been called on this instance
//! @note not available in python bindings
//! @deprecated use evaluate( const QgsExpressionContext* context ) instead
// inline QVariant evaluate( const QgsFeature& f, const QgsFields& fields ) { return evaluate( &f, fields ); }

/** Evaluate the feature and return the result.
* @note this method does not expect that prepare() has been called on this instance
* @note added in QGIS 2.12
Expand All @@ -89,39 +63,11 @@ class QgsExpression
//! Set evaluation error (used internally by evaluation functions)
void setEvalErrorString( const QString& str );

//! Set the number for $rownum special column
//! @deprecated use QgsExpressionContext to set row number instead
void setCurrentRowNumber( int rowNumber ) /Deprecated/;
//! Return the number used for $rownum special column
//! @deprecated use QgsExpressionContext to retrieve row number instead
int currentRowNumber() /Deprecated/; //TODO QGIS 3.0: make the following methods private. They are still required for replaceExpressionText
//but should not be publicly used
/** Assign a special column
* @deprecated use global or project QgsExpressionContext variables instead
*/
static void setSpecialColumn( const QString& name, const QVariant& value ) /Deprecated/;
/** Unset a special column
* @deprecated use global or project QgsExpressionContext variables instead
*/
static void unsetSpecialColumn( const QString& name ) /Deprecated/;
/** Return the value of the given special column or a null QVariant if undefined
* @deprecated use global or project QgsExpressionContext variables instead
*/
static QVariant specialColumn( const QString& name ) /Deprecated/;

/** Check whether a special column exists
* @note added in 2.2
*/
static bool hasSpecialColumn( const QString& name );

/** Checks whether an expression consists only of a single field reference
* @note added in 2.9
*/
bool isField() const;

//! @deprecated use QgsExpressionContext variant instead
static bool isValid( const QString& text, const QgsFields& fields, QString &errorMessage ) /Deprecated/;

/** Tests whether a string is a valid expression.
* @param text string to test
* @param context optional expression context
Expand All @@ -131,10 +77,6 @@ class QgsExpression
*/
static bool isValid( const QString& text, const QgsExpressionContext* context, QString &errorMessage );

void setScale( double scale );

double scale();

//! Return the original, unmodified expression string.
//! If there was none supplied because it was constructed by sole
//! API calls, dump() will be used to create one instead.
Expand Down Expand Up @@ -192,24 +134,6 @@ class QgsExpression
*/
void setAreaUnits( QgsUnitTypes::AreaUnit unit );

/** This function currently replaces each expression between [% and %]
* in the string with the result of its evaluation on the feature
* passed as argument.
*
* Additional substitutions can be passed through the substitutionMap
* parameter
* @param action
* @param feat
* @param layer
* @param substitutionMap
* @param distanceArea optional QgsDistanceArea. If specified, the QgsDistanceArea is used for distance and area conversion
* @deprecated use QgsExpressionContext variant instead
*/
static QString replaceExpressionText( const QString &action, const QgsFeature *feat,
QgsVectorLayer *layer,
const QMap<QString, QVariant> *substitutionMap = 0,
const QgsDistanceArea* distanceArea = 0 ) /Deprecated/;

/** This function replaces each expression between [% and %]
* in the string with the result of its evaluation with the specified context
*
Expand Down Expand Up @@ -410,18 +334,13 @@ class QgsExpression
/** The help text for the function. */
const QString helptext() const;

//! @deprecated Use QgsExpressionContext variant instead
virtual QVariant func( const QVariantList& values, const QgsFeature* f, QgsExpression* parent ) /Deprecated/;

/** Returns result of evaluating the function.
* @param values list of values passed to the function
* @param context context expression is being evaluated against
* @param parent parent expression
* @returns result of function
* @note named funcV2 in Python bindings. Will be renamed to func to replace deprecated method in QGIS 3.0.
*/
//TODO QGIS 3.0 - rename python method
virtual QVariant func( const QVariantList& values, const QgsExpressionContext* context, QgsExpression* parent ) /PyName=funcV2/;
virtual QVariant func( const QVariantList& values, const QgsExpressionContext* context, QgsExpression* parent ) = 0;

virtual bool handlesNull() const;
};
Expand Down Expand Up @@ -459,11 +378,6 @@ class QgsExpression
*/
static int functionCount();

/**
* Returns a list of special Column definitions
*/
static QList<QgsExpression::Function *> specialColumns();

/** Returns a quoted column reference (in double quotes)
* @see quotedString()
* @see quotedValue()
Expand Down Expand Up @@ -534,33 +448,19 @@ class QgsExpression
*/
virtual QgsExpression::NodeType nodeType() const = 0;

/**
* Abstract virtual eval method
* Errors are reported to the parent
* @deprecated use QgsExpressionContext variant instead
*/
virtual QVariant eval( QgsExpression* parent, const QgsFeature* f ) /Deprecated/;

/**
* Abstract virtual eval method
* Errors are reported to the parent
* @note added in QGIS 2.12
*/
virtual QVariant eval( QgsExpression* parent, const QgsExpressionContext* context );

/**
* Abstract virtual preparation method
* Errors are reported to the parent
* @deprecated use QgsExpressionContext variant instead
*/
virtual bool prepare( QgsExpression* parent, const QgsFields &fields ) /Deprecated/;
virtual QVariant eval( QgsExpression* parent, const QgsExpressionContext* context ) = 0;

/**
* Abstract virtual preparation method
* Errors are reported to the parent
* @note added in QGIS 2.12
*/
virtual bool prepare( QgsExpression* parent, const QgsExpressionContext* context );
virtual bool prepare( QgsExpression* parent, const QgsExpressionContext* context ) = 0;

/**
* Abstract virtual dump method
Expand Down Expand Up @@ -671,37 +571,6 @@ class QgsExpression
virtual QString dump() const;
};

//TODO QGIS 3.0 - remove
//! @deprecated use QgsInterval instead
class Interval
{
public:
Interval( int seconds = 0 );

//! interval length in years
double years() const;
//! interval length in months
double months() const;
//! interval length in weeks
double weeks() const;
//! interval length in days
double days() const;
//! interval length in hours
double hours() const;
//! interval length in minutus
double minutes() const;
//! interval length in seconds
double seconds() const;
//! getter interval validity
bool isValid() const;
//! setter interval validity
void setValid( bool valid );
//! compare two intervals
bool operator==( QgsExpression::Interval other ) const;
//! convert a string to an interval
static QgsExpression::Interval fromString( const QString& string );
};

class NodeUnaryOperator : QgsExpression::Node
{
public:
Expand Down
7 changes: 4 additions & 3 deletions python/plugins/processing/algs/qgis/ui/FieldsMappingPanel.py
Expand Up @@ -35,7 +35,7 @@
from qgis.PyQt.QtCore import QItemSelectionModel
from qgis.PyQt.QtCore import QAbstractTableModel, QModelIndex, QVariant, Qt, pyqtSlot

from qgis.core import QgsExpression
from qgis.core import QgsExpression, QgsExpressionContextUtils
from qgis.gui import QgsFieldExpressionWidget

from processing.tools import dataobjects
Expand Down Expand Up @@ -92,9 +92,10 @@ def testExpression(self, row):
return
if self._layer is None:
return
dp = self._layer.dataProvider()
context = QgsExpressionContextUtils.createFeatureBasedContext(QgsFeature(), self._layer.fields())
for feature in dp.getFeatures():
expression.evaluate(feature, dp.fields())
context.setFeature(feature)
expression.evaluate(context)
if expression.hasEvalError():
self._errors[row] = expression.evalErrorString()
return
Expand Down
29 changes: 0 additions & 29 deletions src/core/qgsdatadefined.cpp
Expand Up @@ -142,17 +142,6 @@ QString QgsDataDefined::expressionOrField() const
return d->useExpression ? d->expressionString : QString( "\"%1\"" ).arg( d->field );
}

QMap<QString, QVariant> QgsDataDefined::expressionParams() const
{
return d->expressionParams;
}

void QgsDataDefined::setExpressionParams( const QMap<QString, QVariant>& params )
{
d.detach();
d->expressionParams = params;
}

bool QgsDataDefined::prepareExpression( QgsVectorLayer* layer )
{
if ( layer )
Expand Down Expand Up @@ -188,18 +177,6 @@ bool QgsDataDefined::prepareExpression( const QgsExpressionContext& context )
return false;
}

// setup expression parameters
QVariant scaleV = d->expressionParams.value( "scale" );
if ( scaleV.isValid() )
{
bool ok;
double scale = scaleV.toDouble( &ok );
if ( ok )
{
d->expression->setScale( scale );
}
}

d->expression->prepare( &context );
d->exprRefColumns = d->expression->referencedColumns();

Expand Down Expand Up @@ -286,12 +263,6 @@ void QgsDataDefined::setField( const QString &field )
d->exprRefColumns.clear();
}

void QgsDataDefined::insertExpressionParam( const QString& key, const QVariant& param )
{
d.detach();
d->expressionParams.insert( key, param );
}

QgsStringMap QgsDataDefined::toMap( const QString &baseName ) const
{
QgsStringMap map;
Expand Down
6 changes: 0 additions & 6 deletions src/core/qgsdatadefined.h
Expand Up @@ -136,12 +136,6 @@ class CORE_EXPORT QgsDataDefined
*/
QString expressionOrField() const;

//! @note not available in python bindings
QMap<QString, QVariant> expressionParams() const;
//! @note not available in python bindings
void setExpressionParams( const QMap<QString, QVariant>& params );
void insertExpressionParam( const QString& key, const QVariant& param );

/** Prepares the expression using a vector layer
* @param layer vector layer
* @returns true if expression was successfully prepared
Expand Down

0 comments on commit 7da8110

Please sign in to comment.