Skip to content

Commit

Permalink
Use QgsExpression instead of QgsSearchString
Browse files Browse the repository at this point in the history
  • Loading branch information
wonder-sk committed Aug 11, 2011
1 parent e4ae11f commit 9285c0e
Show file tree
Hide file tree
Showing 8 changed files with 117 additions and 150 deletions.
3 changes: 2 additions & 1 deletion python/core/symbology-ng-core.sip
Expand Up @@ -407,14 +407,15 @@ class QgsRuleBasedRendererV2 : QgsFeatureRendererV2
~Rule();
QString dump() const;
QStringList needsFields() const;
bool isFilterOK( const QgsFieldMap& fields, QgsFeature& f ) const;
bool isFilterOK( QgsFeature& f ) const;
bool isScaleOK( double scale ) const;

QgsSymbolV2* symbol();
bool dependsOnScale() const;
int scaleMinDenom() const;
int scaleMaxDenom() const;
QString filterExpression() const;
QgsExpression* filter() const;

void setScaleMinDenom( int scaleMinDenom );
void setScaleMaxDenom( int scaleMaxDenom );
Expand Down
38 changes: 18 additions & 20 deletions src/app/attributetable/qgsattributetabledialog.cpp 100755 → 100644
Expand Up @@ -24,8 +24,7 @@
#include <qgsapplication.h>
#include <qgsvectordataprovider.h>
#include <qgsvectorlayer.h>
#include <qgssearchstring.h>
#include <qgssearchtreenode.h>
#include <qgsexpression.h>

#include "qgisapp.h"
#include "qgsaddattrdialog.h"
Expand Down Expand Up @@ -532,23 +531,21 @@ void QgsAttributeTableDialog::updateSelectionFromLayer()
void QgsAttributeTableDialog::doSearch( QString searchString )
{
// parse search string and build parsed tree
QgsSearchString search;
if ( !search.setString( searchString ) )
QgsExpression search( searchString );
if ( search.hasParserError() )
{
QMessageBox::critical( this, tr( "Search string parsing error" ), search.parserErrorMsg() );
QMessageBox::critical( this, tr( "Parsing error" ), search.parserErrorString() );
return;
}

QgsSearchTreeNode* searchTree = search.tree();
if ( searchTree == NULL )
if ( ! search.prepare( mLayer->pendingFields() ) )
{
QMessageBox::information( this, tr( "Search results" ), tr( "You've supplied an empty search string." ) );
return;
QMessageBox::critical( this, tr( "Evaluation error" ), search.evalErrorString() );
}

// TODO: fetch only necessary columns
// QStringList columns = searchTree->referencedColumns();
bool fetchGeom = searchTree->needsGeometry();
//QStringList columns = search.referencedColumns();
bool fetchGeom = search.needsGeometry();

QApplication::setOverrideCursor( Qt::WaitCursor );
mSelectedFeatures.clear();
Expand All @@ -558,11 +555,12 @@ void QgsAttributeTableDialog::doSearch( QString searchString )
QgsFeatureList selectedFeatures = mLayer->selectedFeatures();
for ( QgsFeatureList::Iterator it = selectedFeatures.begin(); it != selectedFeatures.end(); ++it )
{
if ( searchTree->checkAgainst( mLayer->pendingFields(), *it ) )
mSelectedFeatures << it->id();
QgsFeature& feat = *it;
if ( search.evaluate( &feat ).toInt() != 0 )
mSelectedFeatures << feat.id();

// check if there were errors during evaluating
if ( searchTree->hasError() )
if ( search.hasEvalError() )
break;
}
}
Expand All @@ -573,20 +571,20 @@ void QgsAttributeTableDialog::doSearch( QString searchString )

while ( mLayer->nextFeature( f ) )
{
if ( searchTree->checkAgainst( mLayer->pendingFields(), f ) )
if ( search.evaluate( &f ).toInt() != 0 )
mSelectedFeatures << f.id();

// check if there were errors during evaluating
if ( searchTree->hasError() )
if ( search.hasEvalError() )
break;
}
}

QApplication::restoreOverrideCursor();

if ( searchTree->hasError() )
if ( search.hasEvalError() )
{
QMessageBox::critical( this, tr( "Error during search" ), searchTree->errorMsg() );
QMessageBox::critical( this, tr( "Error during search" ), search.evalErrorString() );
return;
}

Expand Down Expand Up @@ -625,12 +623,12 @@ void QgsAttributeTableDialog::search()
QString str;
if ( mQuery->displayText() == nullValue )
{
str = QString( "%1 IS NULL" ).arg( QgsSearchTreeNode::quotedColumnRef( fieldName ) );
str = QString( "%1 IS NULL" ).arg( QgsExpression::quotedColumnRef( fieldName ) );
}
else
{
str = QString( "%1 %2 '%3'" )
.arg( QgsSearchTreeNode::quotedColumnRef( fieldName ) )
.arg( QgsExpression::quotedColumnRef( fieldName ) )
.arg( numeric ? "=" : sensString )
.arg( numeric
? mQuery->displayText().replace( "'", "''" )
Expand Down
33 changes: 17 additions & 16 deletions src/app/qgsattributedialog.cpp
Expand Up @@ -24,8 +24,7 @@
#include "qgssymbol.h"
#include "qgsattributeeditor.h"
#include "qgshighlight.h"
#include "qgssearchstring.h"
#include "qgssearchtreenode.h"
#include "qgsexpression.h"
#include "qgspythonrunner.h"

#include "qgisapp.h"
Expand Down Expand Up @@ -205,15 +204,12 @@ QgsAttributeDialog::QgsAttributeDialog( QgsVectorLayer *vl, QgsFeature *thepFeat
QString expr = le->text();
le->setText( tr( "Error" ) );

QgsSearchString ss;
if ( !ss.setString( expr ) )
QgsExpression exp( expr );
if ( exp.hasParserError() )
continue;

QgsSearchTreeNode *st = ss.tree();
if ( !st )
continue;

if ( !mFeature->geometry() && st->needsGeometry() )
if ( !mFeature->geometry() && exp.needsGeometry() )
{
QgsFeature f;
if ( vl->featureAtId( mFeature->id(), f, true, false ) && f.geometry() )
Expand All @@ -222,19 +218,24 @@ QgsAttributeDialog::QgsAttributeDialog( QgsVectorLayer *vl, QgsFeature *thepFeat
}
}

QgsSearchTreeValue value;
st->getValue( value, st, vl->pendingFields(), *mFeature );
QVariant value = exp.evaluate( mFeature, vl->pendingFields() );

if ( !value.isError() )
if ( !exp.hasEvalError() )
{
if ( value.isNumeric() )
le->setText( QString::number( value.number() ) );
else
le->setText( value.string() );
QString text;
switch ( value.type() )
{
case QVariant::Invalid: text = "NULL"; break;
case QVariant::Int: text = QString::number( value.toInt() ); break;
case QVariant::Double: text = QString::number( value.toDouble() ); break;
case QVariant::String:
default: text = value.toString();
}
le->setText( text );
}
else
{
le->setText( tr( "Error: %1" ).arg( st->errorMsg() ) );
le->setText( tr( "Error: %1" ).arg( exp.evalErrorString() ) );
}
}
}
Expand Down
66 changes: 15 additions & 51 deletions src/app/qgsfieldcalculator.cpp
Expand Up @@ -14,8 +14,7 @@
***************************************************************************/

#include "qgsfieldcalculator.h"
#include "qgssearchtreenode.h"
#include "qgssearchstring.h"
#include "qgsexpression.h"
#include "qgsvectordataprovider.h"
#include "qgsvectorlayer.h"

Expand Down Expand Up @@ -81,19 +80,18 @@ void QgsFieldCalculator::accept()
{
QString calcString = mExpressionTextEdit->toPlainText();

//create QgsSearchString
QgsSearchString searchString;
if ( !searchString.setString( calcString ) )
//create QgsExpression
QgsExpression exp( calcString );
if ( exp.hasParserError() )
{
//expression not valid
QMessageBox::critical( 0, tr( "Syntax error" ), tr( QString( "Invalid expression syntax. The error message of the parser is: '" + searchString.parserErrorMsg() + "'" ).toLocal8Bit().data() ) );
QMessageBox::critical( 0, tr( "Syntax error" ), tr( QString( "Invalid expression syntax. The error message of the parser is: '" + exp.parserErrorString() + "'" ).toLocal8Bit().data() ) );
return;
}

//get QgsSearchTreeNode
QgsSearchTreeNode* searchTree = searchString.tree();
if ( !searchTree )
if ( ! exp.prepare( mVectorLayer->pendingFields() ) )
{
QMessageBox::critical( 0, tr( "Evaluation error" ), exp.evalErrorString() );
return;
}

Expand Down Expand Up @@ -156,7 +154,7 @@ void QgsFieldCalculator::accept()
// block layerModified signals (that would trigger table update)
mVectorLayer->blockSignals( true );

bool useGeometry = searchTree->needsGeometry();
bool useGeometry = exp.needsGeometry();
int rownum = 1;

mVectorLayer->select( mVectorLayer->pendingAllAttributesList(), QgsRectangle(), useGeometry, false );
Expand All @@ -170,52 +168,18 @@ void QgsFieldCalculator::accept()
}
}

searchTree->setCurrentRowNumber( rownum );
exp.setCurrentRowNumber( rownum );

QgsSearchTreeValue value;
searchTree->getValue( value, searchTree, mVectorLayer->pendingFields(), feature );
if ( value.isError() )
QVariant value = exp.evaluate( &feature );
if ( exp.hasEvalError() )
{
//insert NULL value for this feature and continue the calculation
if ( searchTree->errorMsg() == QObject::tr( "Division by zero." ) )
{
mVectorLayer->changeAttributeValue( feature.id(), mAttributeId, QVariant(), false );
}
else
{
calculationSuccess = false;
error = searchTree->errorMsg();
break;
}
}
else if ( value.isNumeric() )
{
const QgsField &f = mVectorLayer->pendingFields()[ mAttributeId ];
QVariant v;

if ( f.type() == QVariant::Double && f.precision() > 0 )
{
v = QString::number( value.number(), 'f', f.precision() );
}
else if ( f.type() == QVariant::Double && f.precision() == 0 )
{
v = QString::number( qRound( value.number() ) );
}
else
{
v = value.number();
}

v.convert( f.type() );
mVectorLayer->changeAttributeValue( feature.id(), mAttributeId, v, false );
}
else if ( value.isNull() )
{
mVectorLayer->changeAttributeValue( feature.id(), mAttributeId, QVariant(), false );
calculationSuccess = false;
error = exp.evalErrorString();
break;
}
else
{
mVectorLayer->changeAttributeValue( feature.id(), mAttributeId, value.string(), false );
mVectorLayer->changeAttributeValue( feature.id(), mAttributeId, value, false );
}

rownum++;
Expand Down
35 changes: 19 additions & 16 deletions src/core/symbology-ng/qgsrulebasedrendererv2.cpp
Expand Up @@ -15,7 +15,7 @@

#include "qgsrulebasedrendererv2.h"
#include "qgssymbollayerv2.h"
#include "qgssearchtreenode.h"
#include "qgsexpression.h"
#include "qgssymbollayerv2utils.h"
#include "qgsrendercontext.h"
#include "qgsvectorlayer.h"
Expand All @@ -31,32 +31,34 @@
QgsRuleBasedRendererV2::Rule::Rule( QgsSymbolV2* symbol, int scaleMinDenom, int scaleMaxDenom, QString filterExp, QString label, QString description )
: mSymbol( symbol ),
mScaleMinDenom( scaleMinDenom ), mScaleMaxDenom( scaleMaxDenom ),
mFilterExp( filterExp ), mLabel( label ), mDescription( description )
mFilterExp( filterExp ), mLabel( label ), mDescription( description ),
mFilter( NULL )
{
initFilter();
}

QgsRuleBasedRendererV2::Rule::Rule( const QgsRuleBasedRendererV2::Rule& other )
: mSymbol( NULL )
: mSymbol( NULL ), mFilter( NULL )
{
*this = other;
}

QgsRuleBasedRendererV2::Rule::~Rule()
{
delete mSymbol;
delete mFilter;
}

void QgsRuleBasedRendererV2::Rule::initFilter()
{
if ( !mFilterExp.isEmpty() )
{
mFilterParsed.setString( mFilterExp );
mFilterTree = mFilterParsed.tree(); // may be NULL if there's no input
delete mFilter;
mFilter = new QgsExpression( mFilterExp );
}
else
{
mFilterTree = NULL;
mFilter = NULL;
}
}

Expand All @@ -70,20 +72,19 @@ QString QgsRuleBasedRendererV2::Rule::dump() const

QStringList QgsRuleBasedRendererV2::Rule::needsFields() const
{
if ( ! mFilterTree )
if ( ! mFilter )
return QStringList();

return mFilterTree->referencedColumns();
return mFilter->referencedColumns();
}

bool QgsRuleBasedRendererV2::Rule::isFilterOK( const QgsFieldMap& fields, QgsFeature& f ) const
bool QgsRuleBasedRendererV2::Rule::isFilterOK( QgsFeature& f ) const
{
if ( ! mFilterTree )
if ( ! mFilter )
return true;

bool res = mFilterTree->checkAgainst( fields, f );
//print "is_ok", res, feature.id(), feature.attributeMap()
return res;
QVariant res = mFilter->evaluate( &f );
return res.toInt() != 0;
}

bool QgsRuleBasedRendererV2::Rule::isScaleOK( double scale ) const
Expand Down Expand Up @@ -141,7 +142,7 @@ void QgsRuleBasedRendererV2::renderFeature( QgsFeature& feature,
for ( QList<Rule*>::iterator it = mCurrentRules.begin(); it != mCurrentRules.end(); ++it )
{
Rule* rule = *it;
if ( rule->isFilterOK( mCurrentFields, feature ) )
if ( rule->isFilterOK( feature ) )
{
mCurrentSymbol = rule->symbol();
// will ask for mCurrentSymbol
Expand All @@ -164,11 +165,14 @@ void QgsRuleBasedRendererV2::startRender( QgsRenderContext& context, const QgsVe
mCurrentRules.append( &rule );
}

mCurrentFields = vlayer->pendingFields();
QgsFieldMap pendingFields = vlayer->pendingFields();

for ( QList<Rule*>::iterator it = mCurrentRules.begin(); it != mCurrentRules.end(); ++it )
{
Rule* rule = *it;
QgsExpression* exp = rule->filter();
if ( exp )
exp->prepare( pendingFields );
rule->symbol()->startRender( context );
}
}
Expand All @@ -182,7 +186,6 @@ void QgsRuleBasedRendererV2::stopRender( QgsRenderContext& context )
}

mCurrentRules.clear();
mCurrentFields.clear();
}

QList<QString> QgsRuleBasedRendererV2::usedAttributes()
Expand Down

0 comments on commit 9285c0e

Please sign in to comment.