Skip to content

Commit

Permalink
Read functions from QgsExpression. Updated FunctionDef to store group…
Browse files Browse the repository at this point in the history
… 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 d90dcef
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 63 deletions.
54 changes: 27 additions & 27 deletions src/core/qgsexpression.cpp
Expand Up @@ -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")
};


Expand All @@ -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 )
Expand Down
14 changes: 11 additions & 3 deletions src/core/qgsexpression.h
Expand Up @@ -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
Expand Down Expand Up @@ -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[];
Expand Down
61 changes: 33 additions & 28 deletions src/gui/qgsexpressionbuilder.cpp
Expand Up @@ -15,6 +15,7 @@

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

QgsExpressionBuilderWidget::QgsExpressionBuilderWidget(QgsVectorLayer *layer)
: QWidget(),
Expand All @@ -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()
Expand Down Expand Up @@ -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("");
}
}



40 changes: 35 additions & 5 deletions src/gui/qgsexpressionbuilder.h
Expand Up @@ -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;
Expand All @@ -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 ; }
Expand All @@ -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;
Expand Down

0 comments on commit d90dcef

Please sign in to comment.