28 #include <QTextStream> 30 #include <QInputDialog> 32 #include <QGraphicsOpacityEffect> 33 #include <QPropertyAnimation> 41 , highlighter( nullptr )
42 , mExpressionValid( false )
46 mValueGroupBox->hide();
47 mLoadGroupBox->hide();
54 expressionTree->setModel( mProxyModel );
55 expressionTree->setSortingEnabled(
true );
56 expressionTree->sortByColumn( 0, Qt::AscendingOrder );
58 expressionTree->setContextMenuPolicy( Qt::CustomContextMenu );
69 connect( button, SIGNAL( pressed() ),
this, SLOT( operatorButtonClicked() ) );
72 txtSearchEdit->setPlaceholderText(
tr(
"Search" ) );
77 mValuesListView->setModel( mProxyValues );
78 txtSearchEditValues->setPlaceholderText(
tr(
"Search" ) );
81 splitter->restoreState( settings.
value(
"/windows/QgsExpressionBuilderWidget/splitter" ).
toByteArray() );
82 editorSplit->restoreState( settings.
value(
"/windows/QgsExpressionBuilderWidget/editorsplitter" ).
toByteArray() );
83 functionsplit->restoreState( settings.
value(
"/windows/QgsExpressionBuilderWidget/functionsplitter" ).
toByteArray() );
85 txtExpressionString->setFoldingVisible(
false );
102 expressionTree->setCurrentIndex( firstItem );
104 lblAutoSave->setText(
"" );
111 settings.
setValue(
"/windows/QgsExpressionBuilderWidget/splitter", splitter->saveState() );
112 settings.
setValue(
"/windows/QgsExpressionBuilderWidget/editorsplitter", editorSplit->saveState() );
113 settings.
setValue(
"/windows/QgsExpressionBuilderWidget/functionsplitter", functionsplit->saveState() );
133 txtSearchEditValues->setText(
QString(
"" ) );
151 QString help = loadFunctionHelp( item );
152 txtHelpText->setText( help );
155 void QgsExpressionBuilderWidget::on_btnRun_pressed()
157 if ( !cmbFileNames->currentItem() )
160 QString file = cmbFileNames->currentItem()->text();
162 runPythonCode( txtPython->text() );
165 void QgsExpressionBuilderWidget::runPythonCode(
const QString& code )
172 updateFunctionTree();
179 QDir myDir( mFunctionsPath );
182 myDir.
mkpath( mFunctionsPath );
191 QFile myFile( fileName );
192 if ( myFile.
open( QIODevice::WriteOnly | QFile::Truncate ) )
195 myFileStream << txtPython->text() << endl;
202 mFunctionsPath = path;
206 cmbFileNames->
clear();
210 if ( info.
baseName() ==
"__init__" )
continue;
212 cmbFileNames->addItem( item );
214 if ( !cmbFileNames->currentItem() )
215 cmbFileNames->setCurrentRow( 0 );
225 cmbFileNames->insertItem( 0, item );
226 cmbFileNames->setCurrentRow( 0 );
230 txtPython->setText( templatetxt );
234 void QgsExpressionBuilderWidget::on_btnNewFile_pressed()
238 tr(
"File name:" ), QLineEdit::Normal,
262 txtPython->loadScript( path );
267 txtPython->setText( code );
270 void QgsExpressionBuilderWidget::on_expressionTree_doubleClicked(
const QModelIndex &index )
283 txtExpressionString->setFocus();
304 for (
int i = 0; i < fields.
count(); ++i )
307 fieldNames << fieldName;
316 Q_FOREACH (
const QString& fieldName, fieldValues.
keys() )
321 mFieldValues = fieldValues;
324 void QgsExpressionBuilderWidget::fillFieldValues(
const QString& fieldName,
int countLimit )
335 if ( fieldIndex < 0 )
341 Q_FOREACH (
const QVariant& value, values )
346 else if ( value.
type() == QVariant::Int || value.
type() == QVariant::Double || value.
type() == QVariant::LongLong )
350 strValues.
append( strValue );
353 mFieldValues[fieldName] = strValues;
363 item->
setData( label, Qt::UserRole );
367 if ( mExpressionGroups.
contains( group ) )
376 newgroupNode->
setData( group, Qt::UserRole );
382 mExpressionGroups.
insert( group, newgroupNode );
385 if ( highlightedItem )
389 topLevelItem->
setData( label, Qt::UserRole );
401 return mExpressionValid;
413 while ( expressions.
count() > 20 )
418 settings.
setValue( location, expressions );
424 mRecentKey = collection;
426 if ( mExpressionGroups.
contains( name ) )
436 Q_FOREACH (
const QString& expression, expressions )
443 void QgsExpressionBuilderWidget::updateFunctionTree()
446 mExpressionGroups.
clear();
469 QString casestring =
"CASE WHEN condition THEN result END";
476 for (
int i = 0; i < count; i++ )
490 if ( func->
params() != 0 )
494 registerItemForAllGroups( func->
groups(), func->
name(),
' ' + name +
' ', func->
helptext() );
497 loadExpressionContext();
507 return txtExpressionString->text();
512 txtExpressionString->setText( expression );
517 mExpressionContext = context;
519 updateFunctionTree();
524 void QgsExpressionBuilderWidget::on_txtExpressionString_textChanged()
532 lblPreview->setText(
"" );
533 lblPreview->setStyleSheet(
"" );
534 txtExpressionString->setToolTip(
"" );
535 lblPreview->setToolTip(
"" );
563 lblPreview->setText(
"" );
582 lblPreview->setText(
tr(
"Expression is invalid <a href=""more"">(more info)</a>" ) );
583 lblPreview->setStyleSheet(
"color: rgba(255, 6, 10, 255);" );
584 txtExpressionString->setToolTip( tooltip );
585 lblPreview->setToolTip( tooltip );
591 lblPreview->setStyleSheet(
"" );
592 txtExpressionString->setToolTip(
"" );
593 lblPreview->setToolTip(
"" );
598 void QgsExpressionBuilderWidget::loadExpressionContext()
601 Q_FOREACH (
const QString& variable, variableNames )
603 registerItem(
"Variables", variable,
" @" + variable +
' ',
611 Q_FOREACH (
const QString& functionName, contextFunctions )
617 if ( func->
params() != 0 )
619 registerItemForAllGroups( func->
groups(), func->
name(),
' ' + name +
' ', func->
helptext() );
625 Q_FOREACH (
const QString& group, groups )
627 registerItem( group, label, expressionText, helpText, type, highlightedItem, sortOrder );
634 txtExpressionString->setFocus();
637 void QgsExpressionBuilderWidget::on_txtSearchEdit_textChanged()
640 if ( txtSearchEdit->text().isEmpty() )
642 expressionTree->collapseAll();
646 expressionTree->expandAll();
651 expressionTree->selectionModel()->setCurrentIndex( child, QItemSelectionModel::ClearAndSelect );
656 void QgsExpressionBuilderWidget::on_txtSearchEditValues_textChanged()
662 void QgsExpressionBuilderWidget::on_lblPreview_linkActivated(
const QString& link )
671 void QgsExpressionBuilderWidget::on_mValuesListView_doubleClicked(
const QModelIndex &index )
674 txtExpressionString->insertText(
' ' + index.
data( Qt::DisplayRole ).
toString() +
' ' );
675 txtExpressionString->setFocus();
678 void QgsExpressionBuilderWidget::operatorButtonClicked()
683 txtExpressionString->insertText(
' ' + button->
text() +
' ' );
687 void QgsExpressionBuilderWidget::showContextMenu(
QPoint pt )
700 menu->
popup( expressionTree->mapToGlobal( pt ) );
710 if ( !mLayer || !item )
713 mValueGroupBox->show();
714 fillFieldValues( item->
text(), 10 );
723 if ( !mLayer || !item )
726 mValueGroupBox->show();
727 fillFieldValues( item->
text(), -1 );
730 void QgsExpressionBuilderWidget::on_txtPython_textChanged()
732 lblAutoSave->setText(
"Saving..." );
742 if ( tabWidget->currentIndex() != 1 )
751 lblAutoSave->setText(
"Saved" );
753 lblAutoSave->setGraphicsEffect( effect );
759 anim->
start( QAbstractAnimation::DeleteWhenStopped );
762 void QgsExpressionBuilderWidget::setExpressionState(
bool state )
764 mExpressionValid = state;
767 QString QgsExpressionBuilderWidget::helpStylesheet()
const 773 style +=
" .functionname {color: #0a6099; font-weight: bold;} " 774 " .argument {font-family: monospace; color: #bf0c0c; font-style: italic; } " 775 " td.argument { padding-right: 10px; }";
782 if ( !expressionItem )
798 return "<head><style>" + helpStylesheet() +
"</style></head><body>" + helpContents +
"</body>";
807 setFilterCaseSensitivity( Qt::CaseInsensitive );
812 QModelIndex index = sourceModel()->index( source_row, 0, source_parent );
815 int count = sourceModel()->rowCount( index );
816 bool matchchild =
false;
817 for (
int i = 0; i < count; ++i )
819 if ( filterAcceptsRow( i, index ) )
839 if ( leftSort != rightSort )
840 return leftSort < rightSort;
842 QString leftString = sourceModel()->
data( left, Qt::DisplayRole ).toString();
843 QString rightString = sourceModel()->
data( right, Qt::DisplayRole ).toString();
847 leftString = leftString.
mid( 1 );
849 rightString = rightString.
mid( 1 );
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const
QObject * child(const char *objName, const char *inheritsClass, bool recursiveSearch) const
bool isValid() const
Returns the validity of this feature.
Class for parsing and evaluation of expressions (formerly called "search strings").
bool hasParserError() const
Returns true if an error occurred when parsing the input expression.
QByteArray toByteArray() const
QString & append(QChar ch)
void setFilterCaseSensitivity(Qt::CaseSensitivity cs)
const QString helptext() const
The help text for the function.
void setEasingCurve(const QEasingCurve &easing)
bool contains(const Key &key) const
void setNameFilters(const QStringList &nameFilters)
Q_DECL_DEPRECATED QVariant evaluate(const QgsFeature *f)
Evaluate the feature and return the result.
QStringList filteredVariableNames() const
Returns a filtered list of variables names set by all scopes in the context.
int localeAwareCompare(const QString &other) const
static QString group(const QString &group)
Returns the translated name for a function group.
static const int CustomSortRole
Custom sort order role.
A abstract base class for defining QgsExpression functions.
virtual void setSourceModel(QAbstractItemModel *sourceModel)
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
void setBackground(const QBrush &brush)
void uniqueValues(int index, QList< QVariant > &uniqueValues, int limit=-1)
Calculates a list of unique values contained within an attribute in the layer.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest())
Query the provider for features specified in request.
static QIcon getThemeIcon(const QString &theName)
Helper to get a theme icon.
static QString helptext(QString name)
Returns the help text for a specified function.
QString evalErrorString() const
Returns evaluation error.
Container of fields for a vector layer.
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override
static QString formatPreviewString(const QVariant &value)
Formats an expression result for friendly display to the user.
static QString reportStyleSheet()
get a standard css style sheet for reports.
QgsExpressionItemSearchProxy()
int count() const
Return number of items.
QString parserErrorString() const
Returns parser error.
QString tr(const char *sourceText, const char *disambiguation, int n)
void setStartValue(const QVariant &value)
QVariant variable(const QString &name) const
Fetches a matching variable from the context.
const QgsField & at(int i) const
Get field at particular index (must be in range 0..N-1)
virtual void setData(const QVariant &value, int role)
QgsFields fields() const
Returns the list of fields of this layer.
void setBold(bool enable)
static const QList< Function * > & Functions()
QList< T > findChildren(const QString &name) const
QList< Key > keys() const
void setMessageAsHtml(const QString &msg)
void setValue(const QString &key, const QVariant &value)
static int functionCount()
Returns the number of functions defined in the parser.
const char * name() const
int count(const T &value) const
void append(const T &value)
Search proxy used to filter the QgsExpressionBuilderWidget tree.
bool isHighlightedVariable(const QString &name) const
Returns true if the specified variable name is intended to be highlighted to the user.
void appendRow(const QList< QStandardItem * > &items)
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
int removeAll(const T &value)
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const
void setDynamicSortFilter(bool enable)
QString name() const
The name of the function.
bool endsWith(const QString &s, Qt::CaseSensitivity cs) const
bool append(const QgsField &field, FieldOrigin origin=OriginProvider, int originIndex=-1)
Append a field. The field must have unique name, otherwise it is rejected (returns false) ...
bool isContextual() const
Returns whether the function is only available if provided by a QgsExpressionContext object...
void removeRows(int row, int count)
Encapsulate a field in an attribute table or data source.
virtual bool open(QFlags< QIODevice::OpenModeFlag > mode)
void setFont(const QFont &font)
virtual bool hasChildren(const QModelIndex &parent) const
QString getText(QWidget *parent, const QString &title, const QString &label, QLineEdit::EchoMode mode, const QString &text, bool *ok, QFlags< Qt::WindowType > flags, QFlags< Qt::InputMethodHint > inputMethodHints)
static bool eval(const QString &command, QString &result)
Eval a python statement.
QgsExpressionItem::ItemType getItemType() const
Get the type of expression item eg header, field, ExpressionNode.
void setFilterWildcard(const QString &pattern)
General purpose distance and area calculator.
QgsExpression::Function * function(const QString &name) const
Fetches a matching function from the context.
virtual bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
QString & replace(int position, int n, QChar after)
An expression item that can be used in the QgsExpressionBuilderWidget tree.
QVariant value(const QString &key, const QVariant &defaultValue) const
virtual QModelIndex mapToSource(const QModelIndex &proxyIndex) const
QString mid(int position, int n) const
QStringList functionNames() const
Retrieves a list of function names contained in the context.
QStringList toStringList() const
QVariant data(int role) const
static bool run(const QString &command, const QString &messageOnError=QString())
Execute a python statement.
QString getExpressionText() const
QStandardItem * itemFromIndex(const QModelIndex &index) const
static const int ItemTypeRole
Item type role.
bool lessThan(const QModelIndex &left, const QModelIndex &right) const override
QStringList entryList(QFlags< QDir::Filter > filters, QFlags< QDir::SortFlag > sort) const
A generic message view for displaying QGIS messages.
void setEndValue(const QVariant &value)
bool isEmpty() const
Check whether the container is empty.
void setDuration(int msecs)
void setGeomCalculator(const QgsDistanceArea &calc)
Sets the geometry calculator used for distance and area calculations in expressions.
QString getHelpText() const
Get the help text that is associated with this expression item.
void prepend(const T &value)
static QString variableHelpText(const QString &variableName, bool showValue=true, const QVariant &value=QVariant())
Returns the help text for a specified variable.
iterator insert(const Key &key, const T &value)
int params() const
The number of parameters this function takes.
void start(QAbstractAnimation::DeletionPolicy policy)
static QgsExpressionContextScope * layerScope(const QgsMapLayer *layer)
Creates a new scope which contains variables and functions relating to a QgsMapLayer.
bool nextFeature(QgsFeature &f)
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QStringList groups() const
Returns a list of the groups the function belongs to.
bool hasEvalError() const
Returns true if an error occurred when evaluating last input.
Represents a vector layer which manages a vector based data sets.
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
static bool isValid()
Returns true if the runner has an instance (and thus is able to run commands)
void appendRow(const QList< QStandardItem * > &items)
void setStringList(const QStringList &strings)
virtual QVariant data(int role) const
int fieldNameIndex(const QString &fieldName) const
Returns the index of a field name or -1 if the field does not exist.
bool mkpath(const QString &dirPath) const
const T value(const Key &key) const
virtual bool isDeprecated() const
Returns true if the function is deprecated and should not be presented as a valid option to users in ...