Skip to content
Permalink
Browse files

FIX - Move custom expression function help to group box (#8163)

  • Loading branch information
NathanW2 committed Oct 11, 2018
1 parent 9cad526 commit 42ea21647856496155fec3d3cf36efc65bb1ff73
Showing with 149 additions and 110 deletions.
  1. +0 −32 python/user.py
  2. +88 −50 src/gui/qgsexpressionbuilderwidget.cpp
  3. +61 −28 src/ui/qgsexpressionbuilder.ui
@@ -66,38 +66,6 @@ def load_user_expressions(path):
open(initfile, "w").close()

template = """\"\"\"
Define a new function using the @qgsfunction decorator.
The function accept the following parameters
:param [any]: Define any parameters you want to pass to your function before
the following arguments.
:param feature: The current feature
:param parent: The QgsExpression object
:param context: If there is an argument called ``context`` found at the last
position, this variable will contain a ``QgsExpressionContext``
object, that gives access to various additional information like
expression variables. E.g. ``context.variable('layer_id')``
:returns: The result of the expression.
The @qgsfunction decorator accepts the following arguments:
:param args: Defines the number of arguments. With ``args='auto'`` the number of
arguments will automatically be extracted from the signature.
With ``args=-1``, any number of arguments are accepted.
:param group: The name of the group under which this expression function will
be listed.
:param handlesnull: Set this to True if your function has custom handling for NULL values.
If False, the result will always be NULL as soon as any parameter is NULL.
Defaults to False.
:param usesgeometry: Set this to False if your function does not access
feature.geometry(). Defaults to True.
:param referenced_columns: An array of attribute names that are required to run
this function. Defaults to
[QgsFeatureRequest.ALL_ATTRIBUTES].
\"\"\"
from qgis.core import *
from qgis.gui import *
@@ -148,6 +148,44 @@ QgsExpressionBuilderWidget::QgsExpressionBuilderWidget( QWidget *parent )
txtExpressionString->setCallTipsVisible( 0 );

setExpectedOutputFormat( QString() );
mFunctionBuilderHelp->setMarginVisible( false );
mFunctionBuilderHelp->setEdgeMode( QsciScintilla::EdgeNone );
mFunctionBuilderHelp->setEdgeColumn( 0 );
mFunctionBuilderHelp->setReadOnly( true );
mFunctionBuilderHelp->setText( tr( R"("""Define a new function using the @qgsfunction decorator.
The function accepts the following parameters
: param [any]: Define any parameters you want to pass to your function before
the following arguments.
: param feature: The current feature
: param parent: The QgsExpression object
: param context: If there is an argument called ``context`` found at the last
position, this variable will contain a ``QgsExpressionContext``
object, that gives access to various additional information like
expression variables. E.g. ``context.variable( 'layer_id' )``
: returns: The result of the expression.
The @qgsfunction decorator accepts the following arguments:
: param args: Defines the number of arguments. With ``args = 'auto'`` the number of
arguments will automatically be extracted from the signature.
With ``args = -1``, any number of arguments are accepted.
: param group: The name of the group under which this expression function will
be listed.
: param handlesnull: Set this to True if your function has custom handling for NULL values.
If False, the result will always be NULL as soon as any parameter is NULL.
Defaults to False.
: param usesgeometry : Set this to False if your function does not access
feature.geometry(). Defaults to True.
: param referenced_columns: An array of attribute names that are required to run
this function. Defaults to
[QgsFeatureRequest.ALL_ATTRIBUTES].
"""")" ) );
}


@@ -826,72 +864,72 @@ void QgsExpressionBuilderWidget::createMarkers( const QgsExpressionNode *inNode
switch ( inNode->nodeType() )
{
case QgsExpressionNode::NodeType::ntFunction:
{
const QgsExpressionNodeFunction *node = static_cast<const QgsExpressionNodeFunction *>( inNode );
txtExpressionString->SendScintilla( QsciScintilla::SCI_SETINDICATORCURRENT, FUNCTION_MARKER_ID );
txtExpressionString->SendScintilla( QsciScintilla::SCI_SETINDICATORVALUE, node->fnIndex() );
int start = inNode->parserFirstColumn - 1;
int end = inNode->parserLastColumn - 1;
int start_pos = txtExpressionString->positionFromLineIndex( inNode->parserFirstLine - 1, start );
txtExpressionString->SendScintilla( QsciScintilla::SCI_INDICATORFILLRANGE, start_pos, end - start );
if ( node->args() )
{
const QList< QgsExpressionNode * > nodeList = node->args()->list();
for ( QgsExpressionNode *n : nodeList )
const QgsExpressionNodeFunction *node = static_cast<const QgsExpressionNodeFunction *>( inNode );
txtExpressionString->SendScintilla( QsciScintilla::SCI_SETINDICATORCURRENT, FUNCTION_MARKER_ID );
txtExpressionString->SendScintilla( QsciScintilla::SCI_SETINDICATORVALUE, node->fnIndex() );
int start = inNode->parserFirstColumn - 1;
int end = inNode->parserLastColumn - 1;
int start_pos = txtExpressionString->positionFromLineIndex( inNode->parserFirstLine - 1, start );
txtExpressionString->SendScintilla( QsciScintilla::SCI_INDICATORFILLRANGE, start_pos, end - start );
if ( node->args() )
{
createMarkers( n );
const QList< QgsExpressionNode * > nodeList = node->args()->list();
for ( QgsExpressionNode *n : nodeList )
{
createMarkers( n );
}
}
break;
}
break;
}
case QgsExpressionNode::NodeType::ntLiteral:
{
break;
}
{
break;
}
case QgsExpressionNode::NodeType::ntUnaryOperator:
{
const QgsExpressionNodeUnaryOperator *node = static_cast<const QgsExpressionNodeUnaryOperator *>( inNode );
createMarkers( node->operand() );
break;
}
{
const QgsExpressionNodeUnaryOperator *node = static_cast<const QgsExpressionNodeUnaryOperator *>( inNode );
createMarkers( node->operand() );
break;
}
case QgsExpressionNode::NodeType::ntBinaryOperator:
{
const QgsExpressionNodeBinaryOperator *node = static_cast<const QgsExpressionNodeBinaryOperator *>( inNode );
createMarkers( node->opLeft() );
createMarkers( node->opRight() );
break;
}
{
const QgsExpressionNodeBinaryOperator *node = static_cast<const QgsExpressionNodeBinaryOperator *>( inNode );
createMarkers( node->opLeft() );
createMarkers( node->opRight() );
break;
}
case QgsExpressionNode::NodeType::ntColumnRef:
{
break;
}
{
break;
}
case QgsExpressionNode::NodeType::ntInOperator:
{
const QgsExpressionNodeInOperator *node = static_cast<const QgsExpressionNodeInOperator *>( inNode );
if ( node->list() )
{
const QList< QgsExpressionNode * > nodeList = node->list()->list();
for ( QgsExpressionNode *n : nodeList )
const QgsExpressionNodeInOperator *node = static_cast<const QgsExpressionNodeInOperator *>( inNode );
if ( node->list() )
{
createMarkers( n );
const QList< QgsExpressionNode * > nodeList = node->list()->list();
for ( QgsExpressionNode *n : nodeList )
{
createMarkers( n );
}
}
break;
}
break;
}
case QgsExpressionNode::NodeType::ntCondition:
{
const QgsExpressionNodeCondition *node = static_cast<const QgsExpressionNodeCondition *>( inNode );
for ( QgsExpressionNodeCondition::WhenThen *cond : node->conditions() )
{
createMarkers( cond->whenExp() );
createMarkers( cond->thenExp() );
}
if ( node->elseExp() )
{
createMarkers( node->elseExp() );
const QgsExpressionNodeCondition *node = static_cast<const QgsExpressionNodeCondition *>( inNode );
for ( QgsExpressionNodeCondition::WhenThen *cond : node->conditions() )
{
createMarkers( cond->whenExp() );
createMarkers( cond->thenExp() );
}
if ( node->elseExp() )
{
createMarkers( node->elseExp() );
}
break;
}
break;
}
}
}

@@ -626,30 +626,49 @@
</property>
<widget class="QWidget" name="layoutWidget3">
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<widget class="QListWidget" name="cmbFileNames">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<property name="topMargin">
<number>0</number>
</property>
<item>
<widget class="QToolButton" name="btnNewFile">
<widget class="QPushButton" name="btnNewFile">
<property name="toolTip">
<string>Create a new function file based on the template file.

Change the name of the script and save to allow QGIS to auto load on startup.</string>
</property>
<property name="text">
<string>New file</string>
<string/>
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/console/iconTabEditorConsole.svg</normaloff>:/images/themes/default/console/iconTabEditorConsole.svg</iconset>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
<normaloff>:/images/themes/default/console/iconNewTabEditorConsole.svg</normaloff>:/images/themes/default/console/iconNewTabEditorConsole.svg</iconset>
</property>
<property name="autoRaise">
<bool>true</bool>
<property name="iconSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
</widget>
</item>
@@ -668,29 +687,13 @@ Change the name of the script and save to allow QGIS to auto load on startup.</s
</item>
</layout>
</item>
<item>
<widget class="QListWidget" name="cmbFileNames">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="layoutWidget">
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<property name="sizeConstraint">
@@ -709,7 +712,7 @@ Use this when testing your functions.
Saved scripts are auto loaded on QGIS startup.</string>
</property>
<property name="text">
<string>Load</string>
<string>Save and load functions</string>
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">
@@ -751,6 +754,30 @@ Saved scripts are auto loaded on QGIS startup.</string>
<item>
<widget class="QgsCodeEditorPython" name="txtPython" native="true"/>
</item>
<item>
<widget class="QgsCollapsibleGroupBox" name="groupBox">
<property name="title">
<string>Help</string>
</property>
<layout class="QGridLayout" name="gridLayout_4">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QgsCodeEditorPython" name="mFunctionBuilderHelp" native="true"/>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</widget>
@@ -779,6 +806,12 @@ Saved scripts are auto loaded on QGIS startup.</string>
<header>qgscodeeditorpython.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QgsCollapsibleGroupBox</class>
<extends>QGroupBox</extends>
<header>qgscollapsiblegroupbox.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources>
<include location="../../images/images.qrc"/>

0 comments on commit 42ea216

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