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
Class for parsing and evaluation of expressions (formerly called "search strings").
bool hasEvalError() const
Returns true if an error occurred when evaluating last input.
bool isHighlightedVariable(const QString &name) const
Returns true if the specified variable name is intended to be highlighted to the user.
QByteArray toByteArray() const
QString getExpressionText() const
QString & append(QChar ch)
void setFilterCaseSensitivity(Qt::CaseSensitivity cs)
bool hasParserError() const
Returns true if an error occurred when parsing the input expression.
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.
int localeAwareCompare(const QString &other) const
QString getHelpText() const
Get the help text that is associated with this expression item.
bool isValid() const
Returns the validity of this feature.
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.
QgsFields fields() const
Returns the list of fields of this layer.
void setBackground(const QBrush &brush)
void uniqueValues(int index, QList< QVariant > &uniqueValues, int limit=-1)
Returns unique values for column.
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.
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()
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)
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.
void appendRow(const QList< QStandardItem * > &items)
bool isContextual() const
Returns whether the function is only available if provided by a QgsExpressionContext object...
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) ...
int count() const
Return number of items.
QStringList functionNames() const
Retrieves a list of function names contained in the context.
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.
void setFilterWildcard(const QString &pattern)
General purpose distance and area calculator.
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 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.
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.
QStringList filteredVariableNames() const
Returns a filtered list of variables names set by all scopes in the context.
A generic message view for displaying QGIS messages.
const QString helptext()
The help text for the function.
void setEndValue(const QVariant &value)
void setDuration(int msecs)
void setGeomCalculator(const QgsDistanceArea &calc)
Sets the geometry calculator used for distance and area calculations in expressions.
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)
QgsExpression::Function * function(const QString &name) const
Fetches a matching function from the context.
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)
Represents a vector layer which manages a vector based data sets.
int fieldNameIndex(const QString &fieldName) const
Returns the index of a field name or -1 if the field does not exist.
bool isEmpty() const
Check whether the container is empty.
QString parserErrorString() const
Returns parser error.
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
QString evalErrorString() const
Returns evaluation error.
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
bool mkpath(const QString &dirPath) const
QgsExpressionItem::ItemType getItemType() const
Get the type of expression item eg header, field, ExpressionNode.
const T value(const Key &key) const