17
17
#include " qgslogger.h"
18
18
#include " qgsexpression.h"
19
19
#include " qgsexpressionfunction.h"
20
+ #include " qgsexpressionnodeimpl.h"
20
21
#include " qgsmessageviewer.h"
21
22
#include " qgsapplication.h"
22
23
#include " qgspythonrunner.h"
@@ -118,6 +119,7 @@ QgsExpressionBuilderWidget::QgsExpressionBuilderWidget( QWidget *parent )
118
119
txtExpressionString->setWrapMode ( QsciScintilla::WrapWord );
119
120
lblAutoSave->clear ();
120
121
122
+
121
123
// Note: If you add a indicator here you should add it to clearErrors method if you need to clear it on text parse.
122
124
txtExpressionString->indicatorDefine ( QgsCodeEditor::SquiggleIndicator, QgsExpression::ParserError::FunctionUnknown );
123
125
txtExpressionString->indicatorDefine ( QgsCodeEditor::SquiggleIndicator, QgsExpression::ParserError::FunctionWrongArgs );
@@ -133,6 +135,14 @@ QgsExpressionBuilderWidget::QgsExpressionBuilderWidget( QWidget *parent )
133
135
txtExpressionString->setIndicatorForegroundColor ( QColor ( Qt::red ), -1 );
134
136
txtExpressionString->setIndicatorHoverForegroundColor ( QColor ( Qt::red ), -1 );
135
137
txtExpressionString->setIndicatorOutlineColor ( QColor ( Qt::red ), -1 );
138
+
139
+ // Hidden function markers.
140
+ txtExpressionString->indicatorDefine ( QgsCodeEditor::HiddenIndicator, FUNCTION_MARKER_ID );
141
+ txtExpressionString->setIndicatorForegroundColor ( QColor ( Qt::blue ), FUNCTION_MARKER_ID );
142
+ txtExpressionString->setIndicatorHoverForegroundColor ( QColor ( Qt::blue ), FUNCTION_MARKER_ID );
143
+ txtExpressionString->setIndicatorHoverStyle ( QgsCodeEditor::DotsIndicator, FUNCTION_MARKER_ID );
144
+
145
+ connect ( txtExpressionString, &QgsCodeEditorSQL::indicatorClicked, this , &QgsExpressionBuilderWidget::indicatorClicked );
136
146
}
137
147
138
148
@@ -384,6 +394,17 @@ void QgsExpressionBuilderWidget::fillFieldValues( const QString &fieldName, int
384
394
mFieldValues [fieldName] = strValues;
385
395
}
386
396
397
+ QString QgsExpressionBuilderWidget::getFunctionHelp ( QgsExpressionFunction *function )
398
+ {
399
+ if ( !function )
400
+ return QString ();
401
+
402
+ QString helpContents = QgsExpression::helpText ( function->name () );
403
+
404
+ return " <head><style>" + helpStylesheet () + " </style></head><body>" + helpContents + " </body>" ;
405
+
406
+ }
407
+
387
408
void QgsExpressionBuilderWidget::registerItem ( const QString &group,
388
409
const QString &label,
389
410
const QString &expressionText,
@@ -666,6 +687,7 @@ void QgsExpressionBuilderWidget::txtExpressionString_textChanged()
666
687
emit expressionParsed ( true );
667
688
setParserError ( false );
668
689
setEvalError ( false );
690
+ createMarkers ( exp .rootNode () );
669
691
}
670
692
671
693
}
@@ -767,6 +789,86 @@ void QgsExpressionBuilderWidget::showEvent( QShowEvent *e )
767
789
txtExpressionString->setFocus ();
768
790
}
769
791
792
+ void QgsExpressionBuilderWidget::createMarkers ( const QgsExpressionNode *inNode )
793
+ {
794
+ switch ( inNode->nodeType () )
795
+ {
796
+ case QgsExpressionNode::NodeType::ntFunction:
797
+ {
798
+ const QgsExpressionNodeFunction *node = static_cast <const QgsExpressionNodeFunction *>( inNode );
799
+ txtExpressionString->SendScintilla ( QsciScintilla::SCI_SETINDICATORCURRENT, FUNCTION_MARKER_ID );
800
+ txtExpressionString->SendScintilla ( QsciScintilla::SCI_SETINDICATORVALUE, node->fnIndex () );
801
+ int start = inNode->parserFirstColumn - 1 ;
802
+ int end = inNode->parserLastColumn - 1 ;
803
+ int start_pos = txtExpressionString->positionFromLineIndex ( inNode->parserFirstLine - 1 , start );
804
+ txtExpressionString->SendScintilla ( QsciScintilla::SCI_INDICATORFILLRANGE, start_pos, end - start );
805
+ if ( node->args () )
806
+ {
807
+ const QList< QgsExpressionNode * > nodeList = node->args ()->list ();
808
+ for ( QgsExpressionNode *n : nodeList )
809
+ {
810
+ createMarkers ( n );
811
+ }
812
+ }
813
+ break ;
814
+ }
815
+ case QgsExpressionNode::NodeType::ntLiteral:
816
+ {
817
+ break ;
818
+ }
819
+ case QgsExpressionNode::NodeType::ntUnaryOperator:
820
+ {
821
+ const QgsExpressionNodeUnaryOperator *node = static_cast <const QgsExpressionNodeUnaryOperator *>( inNode );
822
+ createMarkers ( node->operand () );
823
+ break ;
824
+ }
825
+ case QgsExpressionNode::NodeType::ntBinaryOperator:
826
+ {
827
+ const QgsExpressionNodeBinaryOperator *node = static_cast <const QgsExpressionNodeBinaryOperator *>( inNode );
828
+ createMarkers ( node->opLeft () );
829
+ createMarkers ( node->opRight () );
830
+ break ;
831
+ }
832
+ case QgsExpressionNode::NodeType::ntColumnRef:
833
+ {
834
+ break ;
835
+ }
836
+ case QgsExpressionNode::NodeType::ntInOperator:
837
+ {
838
+ const QgsExpressionNodeInOperator *node = static_cast <const QgsExpressionNodeInOperator *>( inNode );
839
+ if ( node->list () )
840
+ {
841
+ const QList< QgsExpressionNode * > nodeList = node->list ()->list ();
842
+ for ( QgsExpressionNode *n : nodeList )
843
+ {
844
+ createMarkers ( n );
845
+ }
846
+ }
847
+ break ;
848
+ }
849
+ case QgsExpressionNode::NodeType::ntCondition:
850
+ {
851
+ const QgsExpressionNodeCondition *node = static_cast <const QgsExpressionNodeCondition *>( inNode );
852
+ for ( QgsExpressionNodeCondition::WhenThen *cond : node->conditions () )
853
+ {
854
+ createMarkers ( cond->whenExp () );
855
+ createMarkers ( cond->thenExp () );
856
+ }
857
+ if ( node->elseExp () )
858
+ {
859
+ createMarkers ( node->elseExp () );
860
+ }
861
+ break ;
862
+ }
863
+ }
864
+ }
865
+
866
+ void QgsExpressionBuilderWidget::clearFunctionMarkers ()
867
+ {
868
+ int lastLine = txtExpressionString->lines () - 1 ;
869
+ txtExpressionString->clearIndicatorRange ( 0 , 0 , lastLine, txtExpressionString->text ( lastLine ).length () - 1 , FUNCTION_MARKER_ID );
870
+ }
871
+
770
872
void QgsExpressionBuilderWidget::clearErrors ()
771
873
{
772
874
int lastLine = txtExpressionString->lines () - 1 ;
@@ -903,6 +1005,18 @@ void QgsExpressionBuilderWidget::autosave()
903
1005
anim->start ( QAbstractAnimation::DeleteWhenStopped );
904
1006
}
905
1007
1008
+ void QgsExpressionBuilderWidget::indicatorClicked ( int line, int index, Qt::KeyboardModifiers state )
1009
+ {
1010
+ if ( state & Qt::ControlModifier )
1011
+ {
1012
+ int position = txtExpressionString->positionFromLineIndex ( line, index );
1013
+ long fncIndex = txtExpressionString->SendScintilla ( QsciScintilla::SCI_INDICATORVALUEAT, FUNCTION_MARKER_ID, ( long int )position );
1014
+ QgsExpressionFunction *func = QgsExpression::Functions ()[fncIndex];
1015
+ QString help = getFunctionHelp ( func );
1016
+ txtHelpText->setText ( help );
1017
+ }
1018
+ }
1019
+
906
1020
void QgsExpressionBuilderWidget::setExpressionState ( bool state )
907
1021
{
908
1022
mExpressionValid = state;
0 commit comments