14 changes: 10 additions & 4 deletions src/core/composer/qgsatlascomposition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,13 @@ void QgsAtlasComposition::setCoverageLayer( QgsVectorLayer* layer )
QgsExpression::setSpecialColumn( "$numfeatures", QVariant(( int )mFeatureIds.size() ) );

// Grab the first feature so that user can use it to test the style in rules.
QgsFeature fet;
layer->getFeatures().nextFeature( fet );
QgsExpression::setSpecialColumn( "$atlasfeatureid", fet.id() );
QgsExpression::setSpecialColumn( "$atlasgeometry", QVariant::fromValue( *fet.geometry() ) );
if( layer )
{
QgsFeature fet;
layer->getFeatures().nextFeature( fet );
QgsExpression::setSpecialColumn( "$atlasfeatureid", fet.id() );
QgsExpression::setSpecialColumn( "$atlasgeometry", QVariant::fromValue( *fet.geometry() ) );
}

emit coverageLayerChanged( layer );
}
Expand Down Expand Up @@ -663,6 +666,9 @@ void QgsAtlasComposition::setFilenamePattern( const QString& pattern )

void QgsAtlasComposition::updateFilenameExpression()
{
if ( !mCoverageLayer )
return;

const QgsFields& fields = mCoverageLayer->pendingFields();

if ( !mSingleFile && mFilenamePattern.size() > 0 )
Expand Down
50 changes: 49 additions & 1 deletion src/core/qgsexpression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2112,9 +2112,57 @@ bool QgsExpression::NodeBinaryOperator::prepare( QgsExpression* parent, const Qg
return resL && resR;
}

int QgsExpression::NodeBinaryOperator::precedence() const
{
// see left/right in qgsexpressionparser.yy
switch ( mOp )
{
case boOr:
return 1;

case boAnd:
return 2;

case boEQ:
case boNE:
case boLE:
case boGE:
case boLT:
case boGT:
case boRegexp:
case boLike:
case boIs:
case boIsNot:
return 3;

case boPlus:
case boMinus:
return 4;

case boMul:
case boDiv:
case boMod:
return 5;

case boPow:
return 6;

case boConcat:
return 7;
}
}

QString QgsExpression::NodeBinaryOperator::dump() const
{
return QString( "%1 %2 %3" ).arg( mOpLeft->dump() ).arg( BinaryOperatorText[mOp] ).arg( mOpRight->dump() );
QgsExpression::NodeBinaryOperator *lOp = dynamic_cast<QgsExpression::NodeBinaryOperator *>( mOpLeft );
QgsExpression::NodeBinaryOperator *rOp = dynamic_cast<QgsExpression::NodeBinaryOperator *>( mOpRight );

QString fmt;
fmt += lOp && lOp->precedence() < precedence() ? "(%1)" : "%1";
fmt += " %2 ";
fmt += rOp && rOp->precedence() < precedence() ? "(%3)" : "%3";

return fmt.arg( mOpLeft->dump() ).arg( BinaryOperatorText[mOp] ).arg( mOpRight->dump() );
}

//
Expand Down
2 changes: 2 additions & 0 deletions src/core/qgsexpression.h
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,8 @@ class CORE_EXPORT QgsExpression
virtual bool needsGeometry() const { return mOpLeft->needsGeometry() || mOpRight->needsGeometry(); }
virtual void accept( Visitor& v ) const { v.visit( *this ); }

int precedence() const;

protected:
bool compare( double diff );
int computeInt( int x, int y );
Expand Down
3 changes: 2 additions & 1 deletion src/gui/symbology-ng/qgsdatadefinedsymboldialog.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "qgsdatadefinedsymboldialog.h"
#include "qgsexpressionbuilderdialog.h"
#include "qgsvectorlayer.h"
#include "qgslogger.h"
#include <QCheckBox>
#include <QComboBox>
#include <QPushButton>
Expand Down Expand Up @@ -104,7 +105,7 @@ QMap< QString, QString > QgsDataDefinedSymbolDialog::dataDefinedProperties() con

void QgsDataDefinedSymbolDialog::expressionButtonClicked()
{
qWarning( "Expression button clicked" );
QgsDebugMsg( "Expression button clicked" );

//find out row
QObject* senderObj = sender();
Expand Down
12 changes: 12 additions & 0 deletions tests/src/core/testqgsexpression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,18 @@ class TestQgsExpression: public QObject
}
}

void eval_precedence()
{
QgsExpression e0( "1+2*3" );
QCOMPARE( e0.evaluate().toInt(), 7 );

QgsExpression e1( "(1+2)*(3+4)" );
QCOMPARE( e1.evaluate().toInt(), 21 );

QgsExpression e2( e1.dump() );
QCOMPARE( e2.evaluate().toInt(), 21 );
}

void eval_columns()
{
QgsFields fields;
Expand Down