Skip to content

Commit d90dcef

Browse files
committed
Read functions from QgsExpression. Updated FunctionDef to store group name and help text. Add comments to code
NOTE: Reading functions list not working yet.
1 parent c6da52c commit d90dcef

File tree

4 files changed

+106
-63
lines changed

4 files changed

+106
-63
lines changed

src/core/qgsexpression.cpp

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -346,36 +346,36 @@ typedef QgsExpression::FunctionDef FnDef;
346346
FnDef QgsExpression::BuiltinFunctions[] =
347347
{
348348
// math
349-
FnDef( "sqrt", 1, fcnSqrt ),
350-
FnDef( "sin", 1, fcnSin ),
351-
FnDef( "cos", 1, fcnCos ),
352-
FnDef( "tan", 1, fcnTan ),
353-
FnDef( "asin", 1, fcnAsin ),
354-
FnDef( "acos", 1, fcnAcos ),
355-
FnDef( "atan", 1, fcnAtan ),
356-
FnDef( "atan2", 2, fcnAtan2 ),
349+
FnDef( "sqrt", 1, fcnSqrt, "Math"),
350+
FnDef( "sin", 1, fcnSin, "Math" ),
351+
FnDef( "cos", 1, fcnCos, "Math"),
352+
FnDef( "tan", 1, fcnTan, "Math" ),
353+
FnDef( "asin", 1, fcnAsin, "Math" ),
354+
FnDef( "acos", 1, fcnAcos, "Math" ),
355+
FnDef( "atan", 1, fcnAtan, "Math" ),
356+
FnDef( "atan2", 2, fcnAtan2, "Math" ),
357357
// casts
358-
FnDef( "toint", 1, fcnToInt ),
359-
FnDef( "toreal", 1, fcnToReal ),
360-
FnDef( "tostring", 1, fcnToString ),
358+
FnDef( "toint", 1, fcnToInt, "Conversions" ),
359+
FnDef( "toreal", 1, fcnToReal, "Conversions" ),
360+
FnDef( "tostring", 1, fcnToString, "Conversions" ),
361361
// string manipulation
362-
FnDef( "lower", 1, fcnLower ),
363-
FnDef( "upper", 1, fcnUpper ),
364-
FnDef( "length", 1, fcnLength ),
365-
FnDef( "replace", 3, fcnReplace ),
366-
FnDef( "regexp_replace", 3, fcnRegexpReplace ),
367-
FnDef( "substr", 3, fcnSubstr ),
362+
FnDef( "lower", 1, fcnLower, "String" ),
363+
FnDef( "upper", 1, fcnUpper, "String" ),
364+
FnDef( "length", 1, fcnLength, "String" ),
365+
FnDef( "replace", 3, fcnReplace, "String" ),
366+
FnDef( "regexp_replace", 3, fcnRegexpReplace, "String" ),
367+
FnDef( "substr", 3, fcnSubstr, "String" ),
368368
// geometry accessors
369-
FnDef( "xat", 1, fcnXat, true ),
370-
FnDef( "yat", 1, fcnYat, true ),
369+
FnDef( "xat", 1, fcnXat, "Geometry", "", true ),
370+
FnDef( "yat", 1, fcnYat, "Geometry", "", true ),
371+
FnDef( "$area", 0, fcnGeomArea, "Geometry", "", true ),
372+
FnDef( "$length", 0, fcnGeomLength, "Geometry", "", true ),
373+
FnDef( "$perimeter", 0, fcnGeomPerimeter, "Geometry", "", true ),
374+
FnDef( "$x", 0, fcnX, "Geometry", "", true ),
375+
FnDef( "$y", 0, fcnY, "Geometry", "" , true ),
371376
// special columns
372-
FnDef( "$rownum", 0, fcnRowNumber ),
373-
FnDef( "$area", 0, fcnGeomArea, true ),
374-
FnDef( "$length", 0, fcnGeomLength, true ),
375-
FnDef( "$perimeter", 0, fcnGeomPerimeter, true ),
376-
FnDef( "$x", 0, fcnX, true ),
377-
FnDef( "$y", 0, fcnY, true ),
378-
FnDef( "$id", 0, fcnFeatureId ),
377+
FnDef( "$rownum", 0, fcnRowNumber, "Record" ),
378+
FnDef( "$id", 0, fcnFeatureId, "Record")
379379
};
380380

381381

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

387387
int QgsExpression::functionIndex( QString name )
388388
{
389-
int count = sizeof( BuiltinFunctions ) / sizeof( FunctionDef );
389+
int count = sizeof( BuiltinFunctions ) / sizeof( FunctionDef);
390390
for ( int i = 0; i < count; i++ )
391391
{
392392
if ( QString::compare( name, BuiltinFunctions[i].mName, Qt::CaseInsensitive ) == 0 )

src/core/qgsexpression.h

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ The expressions try to follow both syntax and semantics of SQL expressions.
3030
3131
Usage:
3232
33-
QgsExpression exp("gid*2 > 10 and type not in ('D','F');
33+
QgsExpression exp("gid*2 > 10 and type not in ('D','F'));
3434
if (exp.hasParserError())
3535
{
3636
// show error message with parserErrorString() and exit
@@ -170,12 +170,20 @@ class CORE_EXPORT QgsExpression
170170

171171
struct FunctionDef
172172
{
173-
FunctionDef( QString fnname, int params, FcnEval fcn, bool usesGeometry = false )
174-
: mName( fnname ), mParams( params ), mFcn( fcn ), mUsesGeometry( usesGeometry ) {}
173+
FunctionDef( QString fnname, int params, FcnEval fcn, QString group, QString helpText = "", bool usesGeometry = false )
174+
: mName( fnname ), mParams( params ), mFcn( fcn ), mUsesGeometry( usesGeometry ), mGroup( group ), mHelpText( helpText ) {}
175+
/** The name of the function. */
175176
QString mName;
177+
/** The number of parameters this function takes. */
176178
int mParams;
179+
/** Pointer to fucntion. */
177180
FcnEval mFcn;
181+
/** Does this function use a geometry object. */
178182
bool mUsesGeometry;
183+
/** The group the function belongs to. */
184+
QString mGroup;
185+
/** The help text for the function. */
186+
QString mHelpText;
179187
};
180188

181189
static FunctionDef BuiltinFunctions[];

src/gui/qgsexpressionbuilder.cpp

Lines changed: 33 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
#include "qgsexpressionbuilder.h"
1717
#include "qgslogger.h"
18+
#include "qgsexpression.h"
1819

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

43-
this->registerItem("Geometry","Area"," $area ","<b>$area</b> <br> Returns the area the object." \
44-
"<br> Only applies to polygons.");
45-
this->registerItem("Geometry","Length"," $length ","<b>$length</b> <br> Returns the length the object. <br> Only applies to polylines.");
46-
this->registerItem("Geometry","Perimeter"," $perimeter ");
47-
this->registerItem("Geometry","X"," $x ");
48-
this->registerItem("Geometry","Y"," $y ");
49-
this->registerItem("Geometry","XAt"," xat( ");
50-
this->registerItem("Geometry","YAt"," yat( ");
51-
52-
this->registerItem("String","Lower Case"," lower( ");
53-
this->registerItem("String","Upper Case"," upper( ");
54-
this->registerItem("String","Length"," length( ");
55-
this->registerItem("String","Replace"," replace(,,, ");
56-
this->registerItem("String","Regex Replace"," regexp_replace(,,, ");
57-
this->registerItem("String","Substring"," substr(,,, ");
58-
59-
this->registerItem("Math","Square Root"," sqrt( ");
60-
this->registerItem("Math","SIN"," sin( ");
61-
this->registerItem("Math","COS"," cos( ");
62-
this->registerItem("Math","TAN"," tan( ");
63-
this->registerItem("Math","ASIN"," asin( ");
64-
this->registerItem("Math","ACOS"," acos( ");
65-
this->registerItem("Math","ATAN"," atan( ");
66-
this->registerItem("Math","ATAN2"," atan2(, ");
67-
68-
this->registerItem("Casting","To integer"," toint( ");
69-
this->registerItem("Casting","To real"," toreal( ");
70-
this->registerItem("Casting","To string"," tostring( ");
44+
int count = sizeof( QgsExpression::BuiltinFunctions ) / sizeof( QgsExpression::FunctionDef);
45+
for ( int i = 0; i < count; i++ )
46+
{
47+
QgsExpression::FunctionDef func = QgsExpression::BuiltinFunctions[i];
48+
QString name = func.mName;
49+
if ( func.mParams >= 1 )
50+
name + "(";
51+
this->registerItem(func.mGroup,func.mName, " " + name + " ", func.mHelpText);
52+
};
7153
}
7254

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

176+
bool QgsExpressionBuilderWidget::hasExpressionError()
177+
{
178+
QString text = this->txtExpressionString->toPlainText();
179+
QgsExpression exp( text );
180+
return exp.hasParserError();
181+
}
182+
183+
void QgsExpressionBuilderWidget::on_txtExpressionString_textChanged()
184+
{
185+
QString text = this->txtExpressionString->toPlainText();
186+
QgsExpression exp( text );
187+
if ( exp.hasParserError())
188+
{
189+
this->txtExpressionString->setStyleSheet("background-color: rgba(255, 6, 10, 75);");
190+
}
191+
else
192+
{
193+
this->txtExpressionString->setStyleSheet("");
194+
}
195+
}
196+
197+
198+

src/gui/qgsexpressionbuilder.h

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,20 @@ class QgsExpressionItem : public QStandardItem
3333
ExpressionNode
3434
};
3535

36-
QgsExpressionItem(QString label, QString expressionText, QString helpText, QgsExpressionItem::ItemType itemType = ExpressionNode)
36+
QgsExpressionItem(QString label,
37+
QString expressionText,
38+
QString helpText,
39+
QgsExpressionItem::ItemType itemType = ExpressionNode)
3740
: QStandardItem(label)
3841
{
3942
mExpressionText = expressionText;
4043
mHelpText = helpText;
4144
mType = itemType;
4245
}
4346

44-
QgsExpressionItem(QString label, QString expressionText, QgsExpressionItem::ItemType itemType = ExpressionNode)
47+
QgsExpressionItem(QString label,
48+
QString expressionText,
49+
QgsExpressionItem::ItemType itemType = ExpressionNode)
4550
: QStandardItem(label)
4651
{
4752
mExpressionText = expressionText;
@@ -51,7 +56,10 @@ class QgsExpressionItem : public QStandardItem
5156
QString getExpressionText() { return mExpressionText; }
5257

5358
QString getHelpText() { return mHelpText; }
54-
59+
/** Set the help text for the current item
60+
*
61+
* @note The help text can be set as a html string.
62+
*/
5563
void setHelpText(QString helpText) { mHelpText = helpText; }
5664

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

79+
/** Loads all the field names from the layer.
80+
* @remarks Should this really be public couldn't we just do this for the user?
81+
*/
7182
void loadFieldNames();
72-
void fillFieldValues(int fieldIndex, int countLimit);
83+
84+
/** Gets the expression string that has been set in the expression area.
85+
* @returns The expression as a string. */
7386
QString getExpressionString();
87+
88+
/** Sets the expression string for the widget */
7489
void setExpressionString(const QString expressionString);
90+
91+
/** Registers a node item for the expression builder.
92+
* @param group The group the item will be show in the tree view. If the group doesn't exsit it will be created.
93+
* @param label The label that is show to the user for the item in the tree.
94+
* @param expressionText The text that is inserted into the expression area when the user double clicks on the item.
95+
* @param helpText The help text that the user will see when item is selected.
96+
* @param type The type of the expression item.
97+
*/
7598
void registerItem(QString group, QString label,QString expressionText,
76-
QString helpText = "",QgsExpressionItem::ItemType type = QgsExpressionItem::ExpressionNode);
99+
QString helpText = "",
100+
QgsExpressionItem::ItemType type = QgsExpressionItem::ExpressionNode);
101+
102+
/** Does the expression used in the widget have any errors */
103+
bool hasExpressionError();
77104

78105
public slots:
79106
void on_mAllPushButton_clicked();
80107
void on_expressionTree_clicked(const QModelIndex &index);
81108
void on_expressionTree_doubleClicked(const QModelIndex &index);
109+
void on_txtExpressionString_textChanged();
82110

83111
private:
112+
void fillFieldValues(int fieldIndex, int countLimit);
113+
84114
QgsVectorLayer *mLayer;
85115
QStandardItemModel *mModel;
86116
QMap<QString, QgsExpressionItem*> mExpressionGroups;

0 commit comments

Comments
 (0)