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 );
226 txtPython->setText( templatetxt );
227 cmbFileNames->insertItem( 0, fileName );
228 cmbFileNames->setCurrentRow( 0 );
232 void QgsExpressionBuilderWidget::on_btnNewFile_pressed()
236 tr(
"File name:" ), QLineEdit::Normal,
260 txtPython->loadScript( path );
265 txtPython->setText( code );
268 void QgsExpressionBuilderWidget::on_expressionTree_doubleClicked(
const QModelIndex &index )
281 txtExpressionString->setFocus();
302 for (
int i = 0; i < fields.
count(); ++i )
304 QString fieldName = fields[i].name();
305 fieldNames << fieldName;
314 Q_FOREACH (
const QString& fieldName, fieldValues.
keys() )
319 mFieldValues = fieldValues;
322 void QgsExpressionBuilderWidget::fillFieldValues(
const QString& fieldName,
int countLimit )
333 if ( fieldIndex < 0 )
339 Q_FOREACH (
const QVariant& value, values )
344 else if ( value.
type() == QVariant::Int || value.
type() == QVariant::Double || value.
type() == QVariant::LongLong )
348 strValues.
append( strValue );
351 mFieldValues[fieldName] = strValues;
361 item->
setData( label, Qt::UserRole );
365 if ( mExpressionGroups.
contains( group ) )
374 newgroupNode->
setData( group, Qt::UserRole );
380 mExpressionGroups.
insert( group, newgroupNode );
383 if ( highlightedItem )
387 topLevelItem->
setData( label, Qt::UserRole );
399 return mExpressionValid;
411 while ( expressions.
count() > 20 )
416 settings.
setValue( location, expressions );
424 if ( mExpressionGroups.
contains( name ) )
434 Q_FOREACH (
const QString& expression, expressions )
441 void QgsExpressionBuilderWidget::updateFunctionTree()
444 mExpressionGroups.
clear();
467 QString casestring =
"CASE WHEN condition THEN result END";
474 for (
int i = 0; i < count; i++ )
480 if ( func->
group() ==
"deprecated" )
488 if ( func->
params() != 0 )
496 for (
int i = 0; i < specials.size(); ++i )
499 registerItem( specials[i]->group(), name,
' ' + name +
' ' );
502 loadExpressionContext();
512 return txtExpressionString->text();
517 txtExpressionString->setText( expression );
522 mExpressionContext = context;
524 loadExpressionContext();
527 void QgsExpressionBuilderWidget::on_txtExpressionString_textChanged()
535 lblPreview->setText(
"" );
536 lblPreview->setStyleSheet(
"" );
537 txtExpressionString->setToolTip(
"" );
538 lblPreview->setToolTip(
"" );
566 lblPreview->setText(
"" );
585 lblPreview->setText(
tr(
"Expression is invalid <a href=""more"">(more info)</a>" ) );
586 lblPreview->setStyleSheet(
"color: rgba(255, 6, 10, 255);" );
587 txtExpressionString->setToolTip( tooltip );
588 lblPreview->setToolTip( tooltip );
594 lblPreview->setStyleSheet(
"" );
595 txtExpressionString->setToolTip(
"" );
596 lblPreview->setToolTip(
"" );
601 void QgsExpressionBuilderWidget::loadExpressionContext()
604 Q_FOREACH (
const QString& variable, variableNames )
606 registerItem(
"Variables", variable,
" @" + variable +
' ',
614 Q_FOREACH (
const QString& functionName, contextFunctions )
620 if ( func->
params() != 0 )
629 txtExpressionString->setFocus();
632 void QgsExpressionBuilderWidget::on_txtSearchEdit_textChanged()
635 if ( txtSearchEdit->text().isEmpty() )
637 expressionTree->collapseAll();
641 expressionTree->expandAll();
646 expressionTree->selectionModel()->setCurrentIndex( child, QItemSelectionModel::ClearAndSelect );
651 void QgsExpressionBuilderWidget::on_txtSearchEditValues_textChanged()
657 void QgsExpressionBuilderWidget::on_lblPreview_linkActivated(
const QString& link )
666 void QgsExpressionBuilderWidget::on_mValuesListView_doubleClicked(
const QModelIndex &index )
669 txtExpressionString->insertText(
' ' + index.
data( Qt::DisplayRole ).
toString() +
' ' );
670 txtExpressionString->setFocus();
673 void QgsExpressionBuilderWidget::operatorButtonClicked()
678 txtExpressionString->insertText(
' ' + button->
text() +
' ' );
682 void QgsExpressionBuilderWidget::showContextMenu(
QPoint pt )
695 menu->
popup( expressionTree->mapToGlobal( pt ) );
705 if ( !mLayer || !item )
708 mValueGroupBox->show();
709 fillFieldValues( item->
text(), 10 );
718 if ( !mLayer || !item )
721 mValueGroupBox->show();
722 fillFieldValues( item->
text(), -1 );
725 void QgsExpressionBuilderWidget::on_txtPython_textChanged()
727 lblAutoSave->setText(
"Saving..." );
737 if ( tabWidget->currentIndex() != 1 )
746 lblAutoSave->setText(
"Saved" );
748 lblAutoSave->setGraphicsEffect( effect );
754 anim->
start( QAbstractAnimation::DeleteWhenStopped );
757 void QgsExpressionBuilderWidget::setExpressionState(
bool state )
759 mExpressionValid = state;
762 QString QgsExpressionBuilderWidget::helpStylesheet()
const 768 style +=
" .functionname {color: #0a6099; font-weight: bold;} " 769 " .argument {font-family: monospace; color: #bf0c0c; font-style: italic; } " 770 " td.argument { padding-right: 10px; }";
777 if ( !expressionItem )
793 return "<head><style>" + helpStylesheet() +
"</style></head><body>" + helpContents +
"</body>";
802 setFilterCaseSensitivity( Qt::CaseInsensitive );
807 QModelIndex index = sourceModel()->index( source_row, 0, source_parent );
810 int count = sourceModel()->rowCount( index );
811 bool matchchild =
false;
812 for (
int i = 0; i < count; ++i )
814 if ( filterAcceptsRow( i, index ) )
834 if ( leftSort != rightSort )
835 return leftSort < rightSort;
837 QString leftString = sourceModel()->
data( left, Qt::DisplayRole ).toString();
838 QString rightString = sourceModel()->
data( right, Qt::DisplayRole ).toString();
842 leftString = leftString.
mid( 1 );
844 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)
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.
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)
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.
QString name()
The name of the function.
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
QString group()
The group the function belongs to.
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
static QList< Function * > specialColumns()
Returns a list of special Column definitions.
int params()
The number of parameters this function takes.
A generic message view for displaying QGIS messages.
const QString helptext()
The help text for the function.
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)
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)
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