QGIS API Documentation  2.11.0-Master
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
qgsexpressionbuilderwidget.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgisexpressionbuilderwidget.cpp - A genric expression string builder widget.
3  --------------------------------------
4  Date : 29-May-2011
5  Copyright : (C) 2011 by Nathan Woodrow
6  Email : woodrow.nathan at gmail dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
17 #include "qgslogger.h"
18 #include "qgsexpression.h"
19 #include "qgsmessageviewer.h"
20 #include "qgsapplication.h"
21 #include "qgspythonrunner.h"
22 
23 #include <QSettings>
24 #include <QMenu>
25 #include <QFile>
26 #include <QTextStream>
27 #include <QDir>
28 #include <QComboBox>
29 
31  : QWidget( parent )
32  , mLayer( NULL )
33  , highlighter( NULL )
34  , mExpressionValid( false )
35 {
36  setupUi( this );
37 
38  mValueGroupBox->hide();
39  mLoadGroupBox->hide();
40 // highlighter = new QgsExpressionHighlighter( txtExpressionString->document() );
41 
42  mModel = new QStandardItemModel();
43  mProxyModel = new QgsExpressionItemSearchProxy();
44  mProxyModel->setSourceModel( mModel );
45  expressionTree->setModel( mProxyModel );
46 
47  expressionTree->setContextMenuPolicy( Qt::CustomContextMenu );
48  connect( this, SIGNAL( expressionParsed( bool ) ), this, SLOT( setExpressionState( bool ) ) );
49  connect( expressionTree, SIGNAL( customContextMenuRequested( const QPoint & ) ), this, SLOT( showContextMenu( const QPoint & ) ) );
50  connect( expressionTree->selectionModel(), SIGNAL( currentChanged( const QModelIndex &, const QModelIndex & ) ),
51  this, SLOT( currentChanged( const QModelIndex &, const QModelIndex & ) ) );
52 
53  connect( btnLoadAll, SIGNAL( pressed() ), this, SLOT( loadAllValues() ) );
54  connect( btnLoadSample, SIGNAL( pressed() ), this, SLOT( loadSampleValues() ) );
55 
56  foreach ( QPushButton* button, mOperatorsGroupBox->findChildren<QPushButton *>() )
57  {
58  connect( button, SIGNAL( pressed() ), this, SLOT( operatorButtonClicked() ) );
59  }
60 
61  txtSearchEdit->setPlaceholderText( tr( "Search" ) );
62 
63  QSettings settings;
64  splitter->restoreState( settings.value( "/windows/QgsExpressionBuilderWidget/splitter" ).toByteArray() );
65  functionsplit->restoreState( settings.value( "/windows/QgsExpressionBuilderWidget/functionsplitter" ).toByteArray() );
66 
67  txtExpressionString->setFoldingVisible( false );
68 
69  updateFunctionTree();
70 
72  {
73  QgsPythonRunner::eval( "qgis.user.expressionspath", mFunctionsPath );
75  // The scratch file gets written each time the widget opens.
76  saveFunctionFile( "scratch" );
77  updateFunctionFileList( mFunctionsPath );
78  }
79  else
80  {
81  tab_2->setEnabled( false );
82  }
83 
84  // select the first item in the function list
85  // in order to avoid a blank help widget
86  QModelIndex firstItem = mProxyModel->index( 0, 0, QModelIndex() );
87  expressionTree->setCurrentIndex( firstItem );
88 }
89 
90 
92 {
93  QSettings settings;
94  settings.setValue( "/windows/QgsExpressionBuilderWidget/splitter", splitter->saveState() );
95  settings.setValue( "/windows/QgsExpressionBuilderWidget/functionsplitter", functionsplit->saveState() );
96 }
97 
99 {
100  mLayer = layer;
101 }
102 
104 {
105  // Get the item
106  QModelIndex idx = mProxyModel->mapToSource( index );
107  QgsExpressionItem* item = dynamic_cast<QgsExpressionItem*>( mModel->itemFromIndex( idx ) );
108  if ( !item )
109  return;
110 
111  mValueListWidget->clear();
112  if ( item->getItemType() == QgsExpressionItem::Field && mFieldValues.contains( item->text() ) )
113  {
114  const QStringList& values = mFieldValues[item->text()];
115  mValueListWidget->setUpdatesEnabled( false );
116  mValueListWidget->blockSignals( true );
117  mValueListWidget->addItems( values );
118  mValueListWidget->setUpdatesEnabled( true );
119  mValueListWidget->blockSignals( false );
120  }
121 
122  mLoadGroupBox->setVisible( item->getItemType() == QgsExpressionItem::Field && mLayer );
123  mValueGroupBox->setVisible(( item->getItemType() == QgsExpressionItem::Field && mLayer ) || mValueListWidget->count() > 0 );
124 
125  // Show the help for the current item.
126  QString help = loadFunctionHelp( item );
127  txtHelpText->setText( help );
128  txtHelpText->setToolTip( txtHelpText->toPlainText() );
129 }
130 
132 {
133  saveFunctionFile( cmbFileNames->currentText() );
134  runPythonCode( txtPython->text() );
135 }
136 
137 void QgsExpressionBuilderWidget::runPythonCode( QString code )
138 {
139  if ( QgsPythonRunner::isValid() )
140  {
141  QString pythontext = code;
142  QgsPythonRunner::run( pythontext );
143  }
144  updateFunctionTree();
145  loadFieldNames();
146  loadRecent( mRecentKey );
147 }
148 
150 {
151  QDir myDir( mFunctionsPath );
152  if ( !myDir.exists() )
153  {
154  myDir.mkpath( mFunctionsPath );
155  }
156 
157  if ( !fileName.endsWith( ".py" ) )
158  {
159  fileName.append( ".py" );
160  }
161 
162  fileName = mFunctionsPath + QDir::separator() + fileName;
163  QFile myFile( fileName );
164  if ( myFile.open( QIODevice::WriteOnly ) )
165  {
166  QTextStream myFileStream( &myFile );
167  myFileStream << txtPython->text() << endl;
168  myFile.close();
169  }
170 }
171 
173 {
174  mFunctionsPath = path;
175  QDir dir( path );
176  dir.setNameFilters( QStringList() << "*.py" );
177  QStringList files = dir.entryList( QDir::Files );
178  cmbFileNames->clear();
179  foreach ( QString name, files )
180  {
181  QFileInfo info( mFunctionsPath + QDir::separator() + name );
182  if ( info.baseName() == "__init__" ) continue;
183  cmbFileNames->addItem( info.baseName() );
184  }
185 }
186 
188 {
189  QString templatetxt;
190  QgsPythonRunner::eval( "qgis.user.expressions.template", templatetxt );
191  txtPython->setText( templatetxt );
192  int index = cmbFileNames->findText( fileName );
193  if ( index == -1 )
194  cmbFileNames->setEditText( fileName );
195  else
196  cmbFileNames->setCurrentIndex( index );
197 }
198 
200 {
201  newFunctionFile();
202 }
203 
205 {
206  if ( index == -1 )
207  return;
208 
209  QString path = mFunctionsPath + QDir::separator() + cmbFileNames->currentText();
210  loadCodeFromFile( path );
211 }
212 
214 {
215  if ( !path.endsWith( ".py" ) )
216  path.append( ".py" );
217 
218  txtPython->loadScript( path );
219 }
220 
222 {
223  txtPython->setText( code );
224 }
225 
227 {
228  QString name = cmbFileNames->currentText();
229  saveFunctionFile( name );
230  int index = cmbFileNames->findText( name );
231  if ( index == -1 )
232  {
233  cmbFileNames->addItem( name );
234  cmbFileNames->setCurrentIndex( cmbFileNames->count() - 1 );
235  }
236 }
237 
239 {
240  QModelIndex idx = mProxyModel->mapToSource( index );
241  QgsExpressionItem* item = dynamic_cast<QgsExpressionItem*>( mModel->itemFromIndex( idx ) );
242  if ( item == 0 )
243  return;
244 
245  // Don't handle the double click it we are on a header node.
246  if ( item->getItemType() == QgsExpressionItem::Header )
247  return;
248 
249  // Insert the expression text or replace selected text
250  txtExpressionString->insertText( item->getExpressionText() );
251  txtExpressionString->setFocus();
252 }
253 
255 {
256  // TODO We should really return a error the user of the widget that
257  // the there is no layer set.
258  if ( !mLayer )
259  return;
260 
261  loadFieldNames( mLayer->pendingFields() );
262 }
263 
265 {
266  if ( fields.isEmpty() )
267  return;
268 
269  QStringList fieldNames;
270  //foreach ( const QgsField& field, fields )
271  for ( int i = 0; i < fields.count(); ++i )
272  {
273  QString fieldName = fields[i].name();
274  fieldNames << fieldName;
275  registerItem( "Fields and Values", fieldName, " \"" + fieldName + "\" ", "", QgsExpressionItem::Field );
276  }
277 // highlighter->addFields( fieldNames );
278 }
279 
281 {
282  QgsFields fields;
283  foreach ( const QString& fieldName, fieldValues.keys() )
284  {
285  fields.append( QgsField( fieldName ) );
286  }
287  loadFieldNames( fields );
288  mFieldValues = fieldValues;
289 }
290 
291 void QgsExpressionBuilderWidget::fillFieldValues( const QString& fieldName, int countLimit )
292 {
293  // TODO We should really return a error the user of the widget that
294  // the there is no layer set.
295  if ( !mLayer )
296  return;
297 
298  // TODO We should thread this so that we don't hold the user up if the layer is massive.
299  mValueListWidget->clear();
300 
301  int fieldIndex = mLayer->fieldNameIndex( fieldName );
302 
303  if ( fieldIndex < 0 )
304  return;
305 
306  mValueListWidget->setUpdatesEnabled( false );
307  mValueListWidget->blockSignals( true );
308 
309  QList<QVariant> values;
310  QStringList strValues;
311  mLayer->uniqueValues( fieldIndex, values, countLimit );
312  foreach ( QVariant value, values )
313  {
314  QString strValue;
315  if ( value.isNull() )
316  strValue = "NULL";
317  else if ( value.type() == QVariant::Int || value.type() == QVariant::Double || value.type() == QVariant::LongLong )
318  strValue = value.toString();
319  else
320  strValue = "'" + value.toString().replace( "'", "''" ) + "'";
321  mValueListWidget->addItem( strValue );
322  strValues.append( strValue );
323  }
324  mFieldValues[fieldName] = strValues;
325 
326  mValueListWidget->setUpdatesEnabled( true );
327  mValueListWidget->blockSignals( false );
328 }
329 
331  QString label,
332  QString expressionText,
333  QString helpText,
335 {
336  QgsExpressionItem* item = new QgsExpressionItem( label, expressionText, helpText, type );
337  item->setData( label, Qt::UserRole );
338  // Look up the group and insert the new function.
339  if ( mExpressionGroups.contains( group ) )
340  {
341  QgsExpressionItem *groupNode = mExpressionGroups.value( group );
342  groupNode->appendRow( item );
343  }
344  else
345  {
346  // If the group doesn't exist yet we make it first.
348  newgroupNode->setData( group, Qt::UserRole );
349  newgroupNode->appendRow( item );
350  mModel->appendRow( newgroupNode );
351  mExpressionGroups.insert( group, newgroupNode );
352  }
353 }
354 
356 {
357  return mExpressionValid;
358 }
359 
361 {
362  QSettings settings;
363  QString location = QString( "/expressions/recent/%1" ).arg( key );
364  QStringList expressions = settings.value( location ).toStringList();
365  expressions.removeAll( this->expressionText() );
366 
367  expressions.prepend( this->expressionText() );
368 
369  while ( expressions.count() > 20 )
370  {
371  expressions.pop_back();
372  }
373 
374  settings.setValue( location, expressions );
375  this->loadRecent( key );
376 }
377 
379 {
380  mRecentKey = key;
381  QString name = tr( "Recent (%1)" ).arg( key );
382  if ( mExpressionGroups.contains( name ) )
383  {
384  QgsExpressionItem* node = mExpressionGroups.value( name );
385  node->removeRows( 0, node->rowCount() );
386  }
387 
388  QSettings settings;
389  QString location = QString( "/expressions/recent/%1" ).arg( key );
390  QStringList expressions = settings.value( location ).toStringList();
391  foreach ( QString expression, expressions )
392  {
393  this->registerItem( name, expression, expression, expression );
394  }
395 }
396 
397 void QgsExpressionBuilderWidget::updateFunctionTree()
398 {
399  mModel->clear();
400  mExpressionGroups.clear();
401  // TODO Can we move this stuff to QgsExpression, like the functions?
402  registerItem( "Operators", "+", " + ", tr( "Addition operator" ) );
403  registerItem( "Operators", "-", " - ", tr( "Subtraction operator" ) );
404  registerItem( "Operators", "*", " * ", tr( "Multiplication operator" ) );
405  registerItem( "Operators", "/", " / ", tr( "Division operator" ) );
406  registerItem( "Operators", "%", " % ", tr( "Modulo operator" ) );
407  registerItem( "Operators", "^", " ^ ", tr( "Power operator" ) );
408  registerItem( "Operators", "=", " = ", tr( "Equal operator" ) );
409  registerItem( "Operators", ">", " > ", tr( "Greater as operator" ) );
410  registerItem( "Operators", "<", " < ", tr( "Less than operator" ) );
411  registerItem( "Operators", "<>", " <> ", tr( "Unequal operator" ) );
412  registerItem( "Operators", "<=", " <= ", tr( "Less or equal operator" ) );
413  registerItem( "Operators", ">=", " >= ", tr( "Greater or equal operator" ) );
414  registerItem( "Operators", "||", " || ",
415  QString( "<b>|| %1</b><br><i>%2</i><br><i>%3:</i>%4" )
416  .arg( tr( "(String Concatenation)" ) )
417  .arg( tr( "Joins two values together into a string" ) )
418  .arg( tr( "Usage" ) )
419  .arg( tr( "'Dia' || Diameter" ) ) );
420  registerItem( "Operators", "IN", " IN " );
421  registerItem( "Operators", "LIKE", " LIKE " );
422  registerItem( "Operators", "ILIKE", " ILIKE " );
423  registerItem( "Operators", "IS", " IS " );
424  registerItem( "Operators", "OR", " OR " );
425  registerItem( "Operators", "AND", " AND " );
426  registerItem( "Operators", "NOT", " NOT " );
427 
428  QString casestring = "CASE WHEN condition THEN result END";
429  QString caseelsestring = "CASE WHEN condition THEN result ELSE result END";
430  registerItem( "Conditionals", "CASE", casestring );
431  registerItem( "Conditionals", "CASE ELSE", caseelsestring );
432 
433  // Load the functions from the QgsExpression class
434  int count = QgsExpression::functionCount();
435  for ( int i = 0; i < count; i++ )
436  {
438  QString name = func->name();
439  if ( name.startsWith( "_" ) ) // do not display private functions
440  continue;
441  if ( func->params() != 0 )
442  name += "(";
443  else if ( !name.startsWith( "$" ) )
444  name += "()";
445  registerItem( func->group(), func->name(), " " + name + " ", func->helptext() );
446  }
447 
449  for ( int i = 0; i < specials.size(); ++i )
450  {
451  QString name = specials[i]->name();
452  registerItem( specials[i]->group(), name, " " + name + " " );
453  }
454 }
455 
457 {
458  mDa = da;
459 }
460 
462 {
463  return txtExpressionString->text();
464 }
465 
467 {
468  txtExpressionString->setText( expression );
469 }
470 
472 {
473  QString text = expressionText();
474 
475  // If the string is empty the expression will still "fail" although
476  // we don't show the user an error as it will be confusing.
477  if ( text.isEmpty() )
478  {
479  lblPreview->setText( "" );
480  lblPreview->setStyleSheet( "" );
481  txtExpressionString->setToolTip( "" );
482  lblPreview->setToolTip( "" );
483  emit expressionParsed( false );
484  return;
485  }
486 
487  QgsExpression exp( text );
488 
489  if ( mLayer )
490  {
491  // Only set calculator if we have layer, else use default.
492  exp.setGeomCalculator( mDa );
493 
494  if ( !mFeature.isValid() )
495  {
496  mLayer->getFeatures().nextFeature( mFeature );
497  }
498 
499  if ( mFeature.isValid() )
500  {
501  QVariant value = exp.evaluate( &mFeature, mLayer->pendingFields() );
502  if ( !exp.hasEvalError() )
503  lblPreview->setText( formatPreviewString( value.toString() ) );
504  }
505  else
506  {
507  // The feature is invalid because we don't have one but that doesn't mean user can't
508  // build a expression string. They just get no preview.
509  lblPreview->setText( "" );
510  }
511  }
512  else
513  {
514  // No layer defined
515  QVariant value = exp.evaluate();
516  if ( !exp.hasEvalError() )
517  {
518  lblPreview->setText( formatPreviewString( value.toString() ) );
519  }
520  }
521 
522  if ( exp.hasParserError() || exp.hasEvalError() )
523  {
524  QString tooltip = QString( "<b>%1:</b><br>%2" ).arg( tr( "Parser Error" ) ).arg( exp.parserErrorString() );
525  if ( exp.hasEvalError() )
526  tooltip += QString( "<br><br><b>%1:</b><br>%2" ).arg( tr( "Eval Error" ) ).arg( exp.evalErrorString() );
527 
528  lblPreview->setText( tr( "Expression is invalid <a href=""more"">(more info)</a>" ) );
529  lblPreview->setStyleSheet( "color: rgba(255, 6, 10, 255);" );
530  txtExpressionString->setToolTip( tooltip );
531  lblPreview->setToolTip( tooltip );
532  emit expressionParsed( false );
533  return;
534  }
535  else
536  {
537  lblPreview->setStyleSheet( "" );
538  txtExpressionString->setToolTip( "" );
539  lblPreview->setToolTip( "" );
540  emit expressionParsed( true );
541  }
542 }
543 
544 QString QgsExpressionBuilderWidget::formatPreviewString( const QString& previewString ) const
545 {
546  if ( previewString.length() > 63 )
547  {
548  return QString( tr( "%1..." ) ).arg( previewString.left( 60 ) );
549  }
550  else
551  {
552  return previewString;
553  }
554 }
555 
557 {
558  mProxyModel->setFilterWildcard( txtSearchEdit->text() );
559  if ( txtSearchEdit->text().isEmpty() )
560  expressionTree->collapseAll();
561  else
562  expressionTree->expandAll();
563 }
564 
566 {
567  Q_UNUSED( link );
568  QgsMessageViewer * mv = new QgsMessageViewer( this );
569  mv->setWindowTitle( tr( "More info on expression error" ) );
570  mv->setMessageAsHtml( txtExpressionString->toolTip() );
571  mv->exec();
572 }
573 
575 {
576  // Insert the item text or replace selected text
577  txtExpressionString->insertText( " " + item->text() + " " );
578  txtExpressionString->setFocus();
579 }
580 
582 {
583  QPushButton* button = dynamic_cast<QPushButton*>( sender() );
584 
585  // Insert the button text or replace selected text
586  txtExpressionString->insertText( " " + button->text() + " " );
587  txtExpressionString->setFocus();
588 }
589 
591 {
592  QModelIndex idx = expressionTree->indexAt( pt );
593  idx = mProxyModel->mapToSource( idx );
594  QgsExpressionItem* item = dynamic_cast<QgsExpressionItem*>( mModel->itemFromIndex( idx ) );
595  if ( !item )
596  return;
597 
598  if ( item->getItemType() == QgsExpressionItem::Field && mLayer )
599  {
600  QMenu* menu = new QMenu( this );
601  menu->addAction( tr( "Load top 10 unique values" ), this, SLOT( loadSampleValues() ) );
602  menu->addAction( tr( "Load all unique values" ), this, SLOT( loadAllValues() ) );
603  menu->popup( expressionTree->mapToGlobal( pt ) );
604  }
605 }
606 
608 {
609  QModelIndex idx = mProxyModel->mapToSource( expressionTree->currentIndex() );
610  QgsExpressionItem* item = dynamic_cast<QgsExpressionItem*>( mModel->itemFromIndex( idx ) );
611  // TODO We should really return a error the user of the widget that
612  // the there is no layer set.
613  if ( !mLayer || !item )
614  return;
615 
616  mValueGroupBox->show();
617  fillFieldValues( item->text(), 10 );
618 }
619 
621 {
622  QModelIndex idx = mProxyModel->mapToSource( expressionTree->currentIndex() );
623  QgsExpressionItem* item = dynamic_cast<QgsExpressionItem*>( mModel->itemFromIndex( idx ) );
624  // TODO We should really return a error the user of the widget that
625  // the there is no layer set.
626  if ( !mLayer || !item )
627  return;
628 
629  mValueGroupBox->show();
630  fillFieldValues( item->text(), -1 );
631 }
632 
633 void QgsExpressionBuilderWidget::setExpressionState( bool state )
634 {
635  mExpressionValid = state;
636 }
637 
638 QString QgsExpressionBuilderWidget::loadFunctionHelp( QgsExpressionItem* expressionItem )
639 {
640  if ( !expressionItem )
641  return "";
642 
643  QString helpContents = expressionItem->getHelpText();
644 
645  // Return the function help that is set for the function if there is one.
646  if ( helpContents.isEmpty() )
647  {
648  QString name = expressionItem->data( Qt::UserRole ).toString();
649 
650  if ( expressionItem->getItemType() == QgsExpressionItem::Field )
651  helpContents = QgsExpression::helptext( "Field" );
652  else
653  helpContents = QgsExpression::helptext( name );
654  }
655 
657  return "<head><style>" + myStyle + "</style></head><body>" + helpContents + "</body>";
658 }
void customContextMenuRequested(const QPoint &pos)
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const
Class for parsing and evaluation of expressions (formerly called "search strings").
Definition: qgsexpression.h:86
bool hasEvalError() const
Returns true if an error occurred when evaluating last input.
void clear()
QByteArray toByteArray() const
static unsigned index
void saveFunctionFile(QString fileName)
Save the current function editor text to the given file.
QString & append(QChar ch)
void setupUi(QWidget *widget)
bool hasParserError() const
Returns true if an error occurred when parsing the input expression.
Definition: qgsexpression.h:93
bool contains(const Key &key) const
void setNameFilters(const QStringList &nameFilters)
bool isValid() const
Returns the validity of this feature.
Definition: qgsfeature.cpp:168
QVariant evaluate(const QgsFeature *f=NULL)
Evaluate the feature and return the result.
A abstract base class for defining QgsExpression functions.
virtual void setSourceModel(QAbstractItemModel *sourceModel)
void setGeomCalculator(const QgsDistanceArea &da)
Sets geometry calculator used in distance/area calculations.
void uniqueValues(int index, QList< QVariant > &uniqueValues, int limit=-1)
Returns unique values for column.
QObject * sender() const
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest())
Query the provider for features specified in request.
void setLayer(QgsVectorLayer *layer)
Sets layer in order to get the fields and values.
static QString helptext(QString name)
void addAction(QAction *action)
static bool eval(QString command, QString &result)
Eval a python statement.
void updateFunctionFileList(QString path)
Update the list of function files found at the given path.
int exec()
Container of fields for a vector layer.
Definition: qgsfield.h:173
static QString group(QString group)
static QString reportStyleSheet()
get a standard css style sheet for reports.
void clear()
QChar separator()
QString tr(const char *sourceText, const char *disambiguation, int n)
QString text() const
void loadCodeFromFile(QString path)
Load code from the given file into the function editor.
int size() const
virtual void setData(const QVariant &value, int role)
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
bool exists() const
void append(const T &value)
Search proxy used to filter the QgsExpressionBuilderWidget tree.
void popup(const QPoint &p, QAction *atAction)
bool isNull() const
static bool run(QString command, QString messageOnError=QString())
execute a python statement
void on_mValueListWidget_itemDoubleClicked(QListWidgetItem *item)
void setFocus()
void appendRow(const QList< QStandardItem * > &items)
bool isEmpty() const
int removeAll(const T &value)
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const
void loadFunctionCode(QString code)
Load code into the function editor.
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) ...
Definition: qgsfield.cpp:233
int count() const
Return number of items.
Definition: qgsfield.cpp:283
void on_expressionTree_doubleClicked(const QModelIndex &index)
void loadFieldNames()
Loads all the field names from the layer.
void removeRows(int row, int count)
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:38
QString name()
The name of the function.
virtual bool open(QFlags< QIODevice::OpenModeFlag > mode)
void pop_back()
void newFunctionFile(QString fileName="scratch")
Create a new file in the function editor.
QgsExpressionItem::ItemType getItemType()
Get the type of expression item eg header, field, ExpressionNode.
virtual void close()
void setFilterWildcard(const QString &pattern)
General purpose distance and area calculator.
QString & replace(int position, int n, QChar after)
An expression item that can be used in the QgsExpressionBuilderWidget tree.
void currentChanged(const QModelIndex &index, const QModelIndex &)
QVariant value(const QString &key, const QVariant &defaultValue) const
virtual QModelIndex mapToSource(const QModelIndex &proxyIndex) const
QStringList toStringList() const
QString group()
The group the function belongs to.
QStandardItem * itemFromIndex(const QModelIndex &index) const
QStringList entryList(QFlags< QDir::Filter > filters, QFlags< QDir::SortFlag > sort) const
static QList< Function * > specialColumns()
Returns a list of special Column definitions.
void loadFieldsAndValues(const QMap< QString, QStringList > &fieldValues)
Loads field names and values from the specified map.
int params()
The number of parameters this function takes.
void setWindowTitle(const QString &)
A generic message view for displaying QGIS messages.
const QString helptext()
The help text for the function.
int length() const
QString expressionText()
Gets the expression string that has been set in the expression area.
void registerItem(QString group, QString label, QString expressionText, QString helpText="", QgsExpressionItem::ItemType type=QgsExpressionItem::ExpressionNode)
Registers a node item for the expression builder.
QString left(int n) const
void setGeomCalculator(const QgsDistanceArea &calc)
Sets the geometry calculator used in evaluation of expressions,.
void setExpressionText(const QString &expression)
Sets the expression string for the widget.
int rowCount() const
void prepend(const T &value)
iterator insert(const Key &key, const T &value)
const QgsFields & pendingFields() const
returns field list in the to-be-committed state
bool nextFeature(QgsFeature &f)
Type type() const
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.
void expressionParsed(bool isValid)
Emitted when the user changes the expression in the widget.
bool isEmpty() const
Check whether the container is empty.
Definition: qgsfield.cpp:278
QString parserErrorString() const
Returns parser error.
Definition: qgsexpression.h:95
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
QString getHelpText()
Get the help text that is associated with this expression item.
QString toString() 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)
QString baseName() const
virtual QVariant data(int role) const
QString text() const
bool mkpath(const QString &dirPath) const
const T value(const Key &key) const