Skip to content

Commit

Permalink
FIX - Move custom expression function help to group box (#8163)
Browse files Browse the repository at this point in the history
  • Loading branch information
NathanW2 committed Oct 11, 2018
1 parent 9cad526 commit 42ea216
Show file tree
Hide file tree
Showing 3 changed files with 149 additions and 110 deletions.
32 changes: 0 additions & 32 deletions python/user.py
Expand Up @@ -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 *
Expand Down
138 changes: 88 additions & 50 deletions src/gui/qgsexpressionbuilderwidget.cpp
Expand Up @@ -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].
"""")" ) );
}


Expand Down Expand Up @@ -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;
}
}
}

Expand Down
89 changes: 61 additions & 28 deletions src/ui/qgsexpressionbuilder.ui
Expand Up @@ -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>
Expand All @@ -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">
Expand All @@ -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">
Expand Down Expand Up @@ -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>
Expand Down Expand Up @@ -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"/>
Expand Down

0 comments on commit 42ea216

Please sign in to comment.