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  registerItem( "Fields and Values", "NULL", "NULL" );
434 
435  // Load the functions from the QgsExpression class
436  int count = QgsExpression::functionCount();
437  for ( int i = 0; i < count; i++ )
438  {
440  QString name = func->name();
441  if ( name.startsWith( "_" ) ) // do not display private functions
442  continue;
443  if ( func->params() != 0 )
444  name += "(";
445  else if ( !name.startsWith( "$" ) )
446  name += "()";
447  registerItem( func->group(), func->name(), " " + name + " ", func->helptext() );
448  }
449 
451  for ( int i = 0; i < specials.size(); ++i )
452  {
453  QString name = specials[i]->name();
454  registerItem( specials[i]->group(), name, " " + name + " " );
455  }
456 }
457 
459 {
460  mDa = da;
461 }
462 
464 {
465  return txtExpressionString->text();
466 }
467 
469 {
470  txtExpressionString->setText( expression );
471 }
472 
474 {
475  QString text = expressionText();
476 
477  // If the string is empty the expression will still "fail" although
478  // we don't show the user an error as it will be confusing.
479  if ( text.isEmpty() )
480  {
481  lblPreview->setText( "" );
482  lblPreview->setStyleSheet( "" );
483  txtExpressionString->setToolTip( "" );
484  lblPreview->setToolTip( "" );
485  emit expressionParsed( false );
486  return;
487  }
488 
489  QgsExpression exp( text );
490 
491  if ( mLayer )
492  {
493  // Only set calculator if we have layer, else use default.
494  exp.setGeomCalculator( mDa );
495 
496  if ( !mFeature.isValid() )
497  {
498  mLayer->getFeatures().nextFeature( mFeature );
499  }
500 
501  if ( mFeature.isValid() )
502  {
503  QVariant value = exp.evaluate( &mFeature, mLayer->pendingFields() );
504  if ( !exp.hasEvalError() )
505  lblPreview->setText( formatPreviewString( value.toString() ) );
506  }
507  else
508  {
509  // The feature is invalid because we don't have one but that doesn't mean user can't
510  // build a expression string. They just get no preview.
511  lblPreview->setText( "" );
512  }
513  }
514  else
515  {
516  // No layer defined
517  QVariant value = exp.evaluate();
518  if ( !exp.hasEvalError() )
519  {
520  lblPreview->setText( formatPreviewString( value.toString() ) );
521  }
522  }
523 
524  if ( exp.hasParserError() || exp.hasEvalError() )
525  {
526  QString tooltip = QString( "<b>%1:</b><br>%2" ).arg( tr( "Parser Error" ) ).arg( exp.parserErrorString() );
527  if ( exp.hasEvalError() )
528  tooltip += QString( "<br><br><b>%1:</b><br>%2" ).arg( tr( "Eval Error" ) ).arg( exp.evalErrorString() );
529 
530  lblPreview->setText( tr( "Expression is invalid <a href=""more"">(more info)</a>" ) );
531  lblPreview->setStyleSheet( "color: rgba(255, 6, 10, 255);" );
532  txtExpressionString->setToolTip( tooltip );
533  lblPreview->setToolTip( tooltip );
534  emit expressionParsed( false );
535  return;
536  }
537  else
538  {
539  lblPreview->setStyleSheet( "" );
540  txtExpressionString->setToolTip( "" );
541  lblPreview->setToolTip( "" );
542  emit expressionParsed( true );
543  }
544 }
545 
546 QString QgsExpressionBuilderWidget::formatPreviewString( const QString& previewString ) const
547 {
548  if ( previewString.length() > 63 )
549  {
550  return QString( tr( "%1..." ) ).arg( previewString.left( 60 ) );
551  }
552  else
553  {
554  return previewString;
555  }
556 }
557 
559 {
560  mProxyModel->setFilterWildcard( txtSearchEdit->text() );
561  if ( txtSearchEdit->text().isEmpty() )
562  expressionTree->collapseAll();
563  else
564  expressionTree->expandAll();
565 }
566 
568 {
569  Q_UNUSED( link );
570  QgsMessageViewer * mv = new QgsMessageViewer( this );
571  mv->setWindowTitle( tr( "More info on expression error" ) );
572  mv->setMessageAsHtml( txtExpressionString->toolTip() );
573  mv->exec();
574 }
575 
577 {
578  // Insert the item text or replace selected text
579  txtExpressionString->insertText( " " + item->text() + " " );
580  txtExpressionString->setFocus();
581 }
582 
584 {
585  QPushButton* button = dynamic_cast<QPushButton*>( sender() );
586 
587  // Insert the button text or replace selected text
588  txtExpressionString->insertText( " " + button->text() + " " );
589  txtExpressionString->setFocus();
590 }
591 
593 {
594  QModelIndex idx = expressionTree->indexAt( pt );
595  idx = mProxyModel->mapToSource( idx );
596  QgsExpressionItem* item = dynamic_cast<QgsExpressionItem*>( mModel->itemFromIndex( idx ) );
597  if ( !item )
598  return;
599 
600  if ( item->getItemType() == QgsExpressionItem::Field && mLayer )
601  {
602  QMenu* menu = new QMenu( this );
603  menu->addAction( tr( "Load top 10 unique values" ), this, SLOT( loadSampleValues() ) );
604  menu->addAction( tr( "Load all unique values" ), this, SLOT( loadAllValues() ) );
605  menu->popup( expressionTree->mapToGlobal( pt ) );
606  }
607 }
608 
610 {
611  QModelIndex idx = mProxyModel->mapToSource( expressionTree->currentIndex() );
612  QgsExpressionItem* item = dynamic_cast<QgsExpressionItem*>( mModel->itemFromIndex( idx ) );
613  // TODO We should really return a error the user of the widget that
614  // the there is no layer set.
615  if ( !mLayer || !item )
616  return;
617 
618  mValueGroupBox->show();
619  fillFieldValues( item->text(), 10 );
620 }
621 
623 {
624  QModelIndex idx = mProxyModel->mapToSource( expressionTree->currentIndex() );
625  QgsExpressionItem* item = dynamic_cast<QgsExpressionItem*>( mModel->itemFromIndex( idx ) );
626  // TODO We should really return a error the user of the widget that
627  // the there is no layer set.
628  if ( !mLayer || !item )
629  return;
630 
631  mValueGroupBox->show();
632  fillFieldValues( item->text(), -1 );
633 }
634 
635 void QgsExpressionBuilderWidget::setExpressionState( bool state )
636 {
637  mExpressionValid = state;
638 }
639 
640 QString QgsExpressionBuilderWidget::loadFunctionHelp( QgsExpressionItem* expressionItem )
641 {
642  if ( !expressionItem )
643  return "";
644 
645  QString helpContents = expressionItem->getHelpText();
646 
647  // Return the function help that is set for the function if there is one.
648  if ( helpContents.isEmpty() )
649  {
650  QString name = expressionItem->data( Qt::UserRole ).toString();
651 
652  if ( expressionItem->getItemType() == QgsExpressionItem::Field )
653  helpContents = QgsExpression::helptext( "Field" );
654  else
655  helpContents = QgsExpression::helptext( name );
656  }
657 
659  return "<head><style>" + myStyle + "</style></head><body>" + helpContents + "</body>";
660 }
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)
const QgsFields & pendingFields() const
Returns the list of fields of this layer.
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)
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