Skip to content
Permalink
Browse files

[FEATURE] Add ability to create user defined Python (and C++) express…

…ion functions
  • Loading branch information
NathanW2 committed Nov 10, 2012
1 parent d5dc331 commit a7699e2696efcb471ab84871aae7af406ca2a375
@@ -117,29 +117,33 @@ class QgsExpression
// static const char* BinaryOgcOperatorText[];
// static const char* UnaryOgcOperatorText[];

struct FunctionDef /NoDefaultCtors/
class Function
{
//FunctionDef( QString fnname, int params, FcnEval fcn, QString group, QString helpText = QString(), bool usesGeometry = false );
/** The name of the function. */
QString mName;
/** The number of parameters this function takes. */
int mParams;
/** Pointer to function. */
//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;
public:
Function( QString fnname, int params, QString group, QString helpText = QString(), bool usesGeometry = false );
/** The name of the function. */
QString name();
/** The number of parameters this function takes. */
int params();
/** Does this function use a geometry object. */
bool usesgeometry();
/** The group the function belongs to. */
QString group();
/** The help text for the function. */
QString helptext();

virtual QVariant func(const QVariantList& values, QgsFeature* f, QgsExpression* parent) = 0;
};

static const QList<QgsExpression::FunctionDef> &BuiltinFunctions();
static const QList<QgsExpression::Function *> &Functions();

static bool registerFunction(Function* function);
static bool unregisterFunction(QString name);

// tells whether the identifier is a name of existing function
static bool isFunctionName( QString name );

// return index of the function in BuiltinFunctions array
// return index of the function in Functions array
static int functionIndex( QString name );

/** Returns the number of functions defined in the parser
@@ -150,7 +154,7 @@ class QgsExpression
/**
* Returns a list of special Column definitions
*/
static QList<QgsExpression::FunctionDef> specialColumns();
static QList<QgsExpression::Function *> specialColumns();

//! return quoted column reference (in double quotes)
static QString quotedColumnRef( QString name );
@@ -28,8 +28,9 @@
"""

from PyQt4.QtCore import QCoreApplication,QLocale
from qgis.core import QGis
from PyQt4.QtCore import QCoreApplication,QLocale, QString
from qgis.core import QGis, QgsExpression
from string import Template
import sys
import traceback
import glob
@@ -371,6 +372,59 @@ def closeProjectMacro():
mod.closeProject()


def qgsfunction(args, group, **kwargs):
"""
Decorator function used to define a user expression function.
Custom functions should take (values, feature, parent) as args,
they can also shortcut naming feature and parent args by using *args
if they are not needed in the function.
Functions should return a value compatible with QVariant
Eval errors can be raised using parent.setEvalErrorString()
Functions must be unregistered when no longer needed using
QgsExpression.unregisterFunction
Example:
@qgsfunction(2, 'test'):
def add(values, feature, parent):
pass
Will create and register a function in QgsExpression called 'add' in the
'test' group that takes two arguments.
or not using feature and parent:
@qgsfunction(2, 'test'):
def add(values, *args):
pass
"""
helptemplate = Template("""<h3>$name function</h3><br>$doc""")
class QgsExpressionFunction(QgsExpression.Function):
def __init__(self, name, args, group, helptext=''):
QgsExpression.Function.__init__(self, name, args, group, QString(helptext))

def func(self, values, feature, parent):
pass

def wrapper(func):
name = kwargs.get('name', func.__name__)
help = func.__doc__ or ''
help = help.strip()
if args == 0 and not name[0] == '$':
name = '${0}'.format(name)
func.__name__ = name
help = helptemplate.safe_substitute(name=name, doc=help)
f = QgsExpressionFunction(name, args, group, help)
f.func = func
register = kwargs.get('register', True)
if register:
QgsExpression.registerFunction(f)
return f
return wrapper

#######################
# IMPORT wrapper

0 comments on commit a7699e2

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