Skip to content
Permalink
Browse files

Read functions from QgsExpression. Updated FunctionDef to store group…

… name and help text. Add comments to code

NOTE: Reading functions list not working yet.
  • Loading branch information
NathanW2 committed Sep 25, 2011
1 parent c6da52c commit d90dcefd0af4535b8077bfc2032ffb828dd402d5
Showing with 106 additions and 63 deletions.
  1. +27 −27 src/core/qgsexpression.cpp
  2. +11 −3 src/core/qgsexpression.h
  3. +33 −28 src/gui/qgsexpressionbuilder.cpp
  4. +35 −5 src/gui/qgsexpressionbuilder.h
@@ -346,36 +346,36 @@ typedef QgsExpression::FunctionDef FnDef;
FnDef QgsExpression::BuiltinFunctions[] =
{
// math
FnDef( "sqrt", 1, fcnSqrt ),
FnDef( "sin", 1, fcnSin ),
FnDef( "cos", 1, fcnCos ),
FnDef( "tan", 1, fcnTan ),
FnDef( "asin", 1, fcnAsin ),
FnDef( "acos", 1, fcnAcos ),
FnDef( "atan", 1, fcnAtan ),
FnDef( "atan2", 2, fcnAtan2 ),
FnDef( "sqrt", 1, fcnSqrt, "Math"),
FnDef( "sin", 1, fcnSin, "Math" ),
FnDef( "cos", 1, fcnCos, "Math"),
FnDef( "tan", 1, fcnTan, "Math" ),
FnDef( "asin", 1, fcnAsin, "Math" ),
FnDef( "acos", 1, fcnAcos, "Math" ),
FnDef( "atan", 1, fcnAtan, "Math" ),
FnDef( "atan2", 2, fcnAtan2, "Math" ),
// casts
FnDef( "toint", 1, fcnToInt ),
FnDef( "toreal", 1, fcnToReal ),
FnDef( "tostring", 1, fcnToString ),
FnDef( "toint", 1, fcnToInt, "Conversions" ),
FnDef( "toreal", 1, fcnToReal, "Conversions" ),
FnDef( "tostring", 1, fcnToString, "Conversions" ),
// string manipulation
FnDef( "lower", 1, fcnLower ),
FnDef( "upper", 1, fcnUpper ),
FnDef( "length", 1, fcnLength ),
FnDef( "replace", 3, fcnReplace ),
FnDef( "regexp_replace", 3, fcnRegexpReplace ),
FnDef( "substr", 3, fcnSubstr ),
FnDef( "lower", 1, fcnLower, "String" ),
FnDef( "upper", 1, fcnUpper, "String" ),
FnDef( "length", 1, fcnLength, "String" ),
FnDef( "replace", 3, fcnReplace, "String" ),
FnDef( "regexp_replace", 3, fcnRegexpReplace, "String" ),
FnDef( "substr", 3, fcnSubstr, "String" ),
// geometry accessors
FnDef( "xat", 1, fcnXat, true ),
FnDef( "yat", 1, fcnYat, true ),
FnDef( "xat", 1, fcnXat, "Geometry", "", true ),
FnDef( "yat", 1, fcnYat, "Geometry", "", true ),
FnDef( "$area", 0, fcnGeomArea, "Geometry", "", true ),
FnDef( "$length", 0, fcnGeomLength, "Geometry", "", true ),
FnDef( "$perimeter", 0, fcnGeomPerimeter, "Geometry", "", true ),
FnDef( "$x", 0, fcnX, "Geometry", "", true ),
FnDef( "$y", 0, fcnY, "Geometry", "" , true ),
// special columns
FnDef( "$rownum", 0, fcnRowNumber ),
FnDef( "$area", 0, fcnGeomArea, true ),
FnDef( "$length", 0, fcnGeomLength, true ),
FnDef( "$perimeter", 0, fcnGeomPerimeter, true ),
FnDef( "$x", 0, fcnX, true ),
FnDef( "$y", 0, fcnY, true ),
FnDef( "$id", 0, fcnFeatureId ),
FnDef( "$rownum", 0, fcnRowNumber, "Record" ),
FnDef( "$id", 0, fcnFeatureId, "Record")
};


@@ -386,7 +386,7 @@ bool QgsExpression::isFunctionName( QString name )

int QgsExpression::functionIndex( QString name )
{
int count = sizeof( BuiltinFunctions ) / sizeof( FunctionDef );
int count = sizeof( BuiltinFunctions ) / sizeof( FunctionDef);
for ( int i = 0; i < count; i++ )
{
if ( QString::compare( name, BuiltinFunctions[i].mName, Qt::CaseInsensitive ) == 0 )
@@ -30,7 +30,7 @@ The expressions try to follow both syntax and semantics of SQL expressions.
Usage:
QgsExpression exp("gid*2 > 10 and type not in ('D','F');
QgsExpression exp("gid*2 > 10 and type not in ('D','F'));
if (exp.hasParserError())
{
// show error message with parserErrorString() and exit
@@ -170,12 +170,20 @@ class CORE_EXPORT QgsExpression

struct FunctionDef
{
FunctionDef( QString fnname, int params, FcnEval fcn, bool usesGeometry = false )
: mName( fnname ), mParams( params ), mFcn( fcn ), mUsesGeometry( usesGeometry ) {}
FunctionDef( QString fnname, int params, FcnEval fcn, QString group, QString helpText = "", bool usesGeometry = false )
: mName( fnname ), mParams( params ), mFcn( fcn ), mUsesGeometry( usesGeometry ), mGroup( group ), mHelpText( helpText ) {}
/** The name of the function. */
QString mName;
/** The number of parameters this function takes. */
int mParams;
/** Pointer to fucntion. */
FcnEval mFcn;
/** Does this function use a geometry object. */
bool mUsesGeometry;
/** The group the function belongs to. */
QString mGroup;
/** The help text for the function. */
QString mHelpText;
};

static FunctionDef BuiltinFunctions[];
@@ -15,6 +15,7 @@

#include "qgsexpressionbuilder.h"
#include "qgslogger.h"
#include "qgsexpression.h"

QgsExpressionBuilderWidget::QgsExpressionBuilderWidget(QgsVectorLayer *layer)
: QWidget(),
@@ -40,34 +41,15 @@ QgsExpressionBuilderWidget::QgsExpressionBuilderWidget(QgsVectorLayer *layer)
"<br> Joins two values together into a string " \
"<br> <i>Usage:</i><br>'Dia' || Diameter");

this->registerItem("Geometry","Area"," $area ","<b>$area</b> <br> Returns the area the object." \
"<br> Only applies to polygons.");
this->registerItem("Geometry","Length"," $length ","<b>$length</b> <br> Returns the length the object. <br> Only applies to polylines.");
this->registerItem("Geometry","Perimeter"," $perimeter ");
this->registerItem("Geometry","X"," $x ");
this->registerItem("Geometry","Y"," $y ");
this->registerItem("Geometry","XAt"," xat( ");
this->registerItem("Geometry","YAt"," yat( ");

this->registerItem("String","Lower Case"," lower( ");
this->registerItem("String","Upper Case"," upper( ");
this->registerItem("String","Length"," length( ");
this->registerItem("String","Replace"," replace(,,, ");
this->registerItem("String","Regex Replace"," regexp_replace(,,, ");
this->registerItem("String","Substring"," substr(,,, ");

this->registerItem("Math","Square Root"," sqrt( ");
this->registerItem("Math","SIN"," sin( ");
this->registerItem("Math","COS"," cos( ");
this->registerItem("Math","TAN"," tan( ");
this->registerItem("Math","ASIN"," asin( ");
this->registerItem("Math","ACOS"," acos( ");
this->registerItem("Math","ATAN"," atan( ");
this->registerItem("Math","ATAN2"," atan2(, ");

this->registerItem("Casting","To integer"," toint( ");
this->registerItem("Casting","To real"," toreal( ");
this->registerItem("Casting","To string"," tostring( ");
int count = sizeof( QgsExpression::BuiltinFunctions ) / sizeof( QgsExpression::FunctionDef);
for ( int i = 0; i < count; i++ )
{
QgsExpression::FunctionDef func = QgsExpression::BuiltinFunctions[i];
QString name = func.mName;
if ( func.mParams >= 1 )
name + "(";
this->registerItem(func.mGroup,func.mName, " " + name + " ", func.mHelpText);
};
}

QgsExpressionBuilderWidget::~QgsExpressionBuilderWidget()
@@ -191,3 +173,26 @@ void QgsExpressionBuilderWidget::setExpressionString(const QString expressionStr
this->txtExpressionString->setPlainText(expressionString);
}

bool QgsExpressionBuilderWidget::hasExpressionError()
{
QString text = this->txtExpressionString->toPlainText();
QgsExpression exp( text );
return exp.hasParserError();
}

void QgsExpressionBuilderWidget::on_txtExpressionString_textChanged()
{
QString text = this->txtExpressionString->toPlainText();
QgsExpression exp( text );
if ( exp.hasParserError())
{
this->txtExpressionString->setStyleSheet("background-color: rgba(255, 6, 10, 75);");
}
else
{
this->txtExpressionString->setStyleSheet("");
}
}



@@ -33,15 +33,20 @@ class QgsExpressionItem : public QStandardItem
ExpressionNode
};

QgsExpressionItem(QString label, QString expressionText, QString helpText, QgsExpressionItem::ItemType itemType = ExpressionNode)
QgsExpressionItem(QString label,
QString expressionText,
QString helpText,
QgsExpressionItem::ItemType itemType = ExpressionNode)
: QStandardItem(label)
{
mExpressionText = expressionText;
mHelpText = helpText;
mType = itemType;
}

QgsExpressionItem(QString label, QString expressionText, QgsExpressionItem::ItemType itemType = ExpressionNode)
QgsExpressionItem(QString label,
QString expressionText,
QgsExpressionItem::ItemType itemType = ExpressionNode)
: QStandardItem(label)
{
mExpressionText = expressionText;
@@ -51,7 +56,10 @@ class QgsExpressionItem : public QStandardItem
QString getExpressionText() { return mExpressionText; }

QString getHelpText() { return mHelpText; }

/** Set the help text for the current item
*
* @note The help text can be set as a html string.
*/
void setHelpText(QString helpText) { mHelpText = helpText; }

QgsExpressionItem::ItemType getItemType() { return mType ; }
@@ -68,19 +76,41 @@ class QgsExpressionBuilderWidget : public QWidget, private Ui::QgsExpressionBuil
QgsExpressionBuilderWidget(QgsVectorLayer * layer);
~QgsExpressionBuilderWidget();

/** Loads all the field names from the layer.
* @remarks Should this really be public couldn't we just do this for the user?
*/
void loadFieldNames();
void fillFieldValues(int fieldIndex, int countLimit);

/** Gets the expression string that has been set in the expression area.
* @returns The expression as a string. */
QString getExpressionString();

/** Sets the expression string for the widget */
void setExpressionString(const QString expressionString);

/** Registers a node item for the expression builder.
* @param group The group the item will be show in the tree view. If the group doesn't exsit it will be created.
* @param label The label that is show to the user for the item in the tree.
* @param expressionText The text that is inserted into the expression area when the user double clicks on the item.
* @param helpText The help text that the user will see when item is selected.
* @param type The type of the expression item.
*/
void registerItem(QString group, QString label,QString expressionText,
QString helpText = "",QgsExpressionItem::ItemType type = QgsExpressionItem::ExpressionNode);
QString helpText = "",
QgsExpressionItem::ItemType type = QgsExpressionItem::ExpressionNode);

/** Does the expression used in the widget have any errors */
bool hasExpressionError();

public slots:
void on_mAllPushButton_clicked();
void on_expressionTree_clicked(const QModelIndex &index);
void on_expressionTree_doubleClicked(const QModelIndex &index);
void on_txtExpressionString_textChanged();

private:
void fillFieldValues(int fieldIndex, int countLimit);

QgsVectorLayer *mLayer;
QStandardItemModel *mModel;
QMap<QString, QgsExpressionItem*> mExpressionGroups;

0 comments on commit d90dcef

Please sign in to comment.
You can’t perform that action at this time.