QGIS API Documentation  3.14.0-Pi (9f7028fd23)
qgsprocessingaggregatewidgets.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsprocessingaggregatewidgets.cpp
3  ---------------------
4  Date : June 2020
5  Copyright : (C) 2020 by Nyall Dawson
6  Email : nyall dot dawson 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 
19 #include "qgsfieldmappingwidget.h"
20 
21 #include <QBoxLayout>
22 #include <QLineEdit>
23 #include <QMessageBox>
24 #include <QPushButton>
25 #include <QStandardItemModel>
26 #include <QToolButton>
27 #include <QTableView>
28 #include <mutex>
29 
30 //
31 // QgsAggregateMappingModel
32 //
33 
35  QObject *parent )
36  : QAbstractTableModel( parent )
37  , mExpressionContextGenerator( new QgsFieldMappingModel::ExpressionContextGenerator( &sourceFields ) )
38 {
40 }
41 
42 QVariant QgsAggregateMappingModel::headerData( int section, Qt::Orientation orientation, int role ) const
43 {
44  if ( role == Qt::DisplayRole )
45  {
46  switch ( orientation )
47  {
48  case Qt::Horizontal:
49  {
50  switch ( static_cast<ColumnDataIndex>( section ) )
51  {
53  {
54  return tr( "Source Expression" );
55  }
57  {
58  return tr( "Aggregate Function" );
59  }
61  {
62  return tr( "Delimiter" );
63  }
65  {
66  return tr( "Name" );
67  }
69  {
70  return tr( "Type" );
71  }
73  {
74  return tr( "Length" );
75  }
77  {
78  return tr( "Precision" );
79  }
80  }
81  break;
82  }
83  case Qt::Vertical:
84  {
85  return section;
86  }
87  }
88  }
89  return QVariant();
90 }
91 
93 {
94  return mSourceFields;
95 }
96 
97 int QgsAggregateMappingModel::rowCount( const QModelIndex &parent ) const
98 {
99  if ( parent.isValid() )
100  return 0;
101  return mMapping.count();
102 }
103 
104 int QgsAggregateMappingModel::columnCount( const QModelIndex &parent ) const
105 {
106  if ( parent.isValid() )
107  return 0;
108  return 7;
109 }
110 
111 QVariant QgsAggregateMappingModel::data( const QModelIndex &index, int role ) const
112 {
113  if ( index.isValid() )
114  {
115  const ColumnDataIndex col { static_cast<ColumnDataIndex>( index.column() ) };
116  const Aggregate &agg { mMapping.at( index.row() ) };
117 
118  switch ( role )
119  {
120  case Qt::DisplayRole:
121  case Qt::EditRole:
122  {
123  switch ( col )
124  {
126  {
127  return agg.source;
128  }
130  {
131  return agg.aggregate;
132  }
134  {
135  return agg.delimiter;
136  }
138  {
139  return agg.field.displayName();
140  }
142  {
143  return static_cast<int>( agg.field.type() );
144  }
146  {
147  return agg.field.length();
148  }
150  {
151  return agg.field.precision();
152  }
153  }
154  break;
155  }
156  }
157  }
158  return QVariant();
159 }
160 
161 Qt::ItemFlags QgsAggregateMappingModel::flags( const QModelIndex &index ) const
162 {
163  if ( index.isValid() )
164  {
165  return Qt::ItemFlags( Qt::ItemIsSelectable |
166  Qt::ItemIsEditable |
167  Qt::ItemIsEnabled );
168  }
169  return Qt::ItemFlags();
170 }
171 
172 bool QgsAggregateMappingModel::setData( const QModelIndex &index, const QVariant &value, int role )
173 {
174  if ( index.isValid() )
175  {
176  if ( role == Qt::EditRole )
177  {
178  Aggregate &f = mMapping[index.row()];
179  switch ( static_cast<ColumnDataIndex>( index.column() ) )
180  {
182  {
183  const QgsExpression exp { value.toString() };
184  f.source = exp;
185  break;
186  }
188  {
189  f.aggregate = value.toString();
190  break;
191  }
193  {
194  f.delimiter = value.toString();
195  break;
196  }
198  {
199  f.field.setName( value.toString() );
200  break;
201  }
203  {
204  f.field.setType( static_cast<QVariant::Type>( value.toInt( ) ) );
205  break;
206  }
208  {
209  bool ok;
210  const int length { value.toInt( &ok ) };
211  if ( ok )
212  f.field.setLength( length );
213  break;
214  }
216  {
217  bool ok;
218  const int precision { value.toInt( &ok ) };
219  if ( ok )
221  break;
222  }
223  }
224  emit dataChanged( index, index );
225  }
226  return true;
227  }
228  else
229  {
230  return false;
231  }
232 }
233 
234 
235 bool QgsAggregateMappingModel::moveUpOrDown( const QModelIndex &index, bool up )
236 {
237  if ( ! index.isValid() && index.model() == this )
238  return false;
239 
240  // Always swap down
241  const int row { up ? index.row() - 1 : index.row() };
242  // Range checking
243  if ( row < 0 || row + 1 >= rowCount( QModelIndex() ) )
244  {
245  return false;
246  }
247  beginMoveRows( QModelIndex( ), row, row, QModelIndex(), row + 2 );
248 #if QT_VERSION < QT_VERSION_CHECK(5, 13, 0)
249  mMapping.swap( row, row + 1 );
250 #else
251  mMapping.swapItemsAt( row, row + 1 );
252 #endif
253  endMoveRows();
254  return true;
255 }
256 
258 {
259  mSourceFields = sourceFields;
260  QStringList usedFields;
261  beginResetModel();
262  mMapping.clear();
263 
264  for ( const QgsField &f : sourceFields )
265  {
266  Aggregate aggregate;
267  aggregate.field = f;
268  aggregate.source = QgsExpression::quotedColumnRef( f.name() );
269 
270  if ( f.isNumeric() )
271  aggregate.aggregate = QStringLiteral( "sum" );
272  else if ( f.type() == QVariant::String || ( f.type() == QVariant::List && f.subType() == QVariant::String ) )
273  aggregate.aggregate = QStringLiteral( "concatenate" );
274 
275  aggregate.delimiter = ',';
276 
277  mMapping.push_back( aggregate );
278  }
279  endResetModel();
280 }
281 
283 {
284  return mExpressionContextGenerator.get();
285 }
286 
288 {
289  mExpressionContextGenerator->setBaseExpressionContextGenerator( generator );
290 }
291 
292 QList<QgsAggregateMappingModel::Aggregate> QgsAggregateMappingModel::mapping() const
293 {
294  return mMapping;
295 }
296 
297 void QgsAggregateMappingModel::setMapping( const QList<QgsAggregateMappingModel::Aggregate> &mapping )
298 {
299  beginResetModel();
300  mMapping = mapping;
301  endResetModel();
302 }
303 
304 void QgsAggregateMappingModel::appendField( const QgsField &field, const QString &source, const QString &aggregate )
305 {
306  const int lastRow { rowCount( QModelIndex( ) ) };
307  beginInsertRows( QModelIndex(), lastRow, lastRow );
308  Aggregate agg;
309  agg.field = field;
310  agg.source = source;
311  agg.aggregate = aggregate;
312  agg.delimiter = ',';
313  mMapping.push_back( agg );
314  endInsertRows( );
315 }
316 
317 bool QgsAggregateMappingModel::removeField( const QModelIndex &index )
318 {
319  if ( index.isValid() && index.model() == this && index.row() < rowCount( QModelIndex() ) )
320  {
321  beginRemoveRows( QModelIndex(), index.row(), index.row() );
322  mMapping.removeAt( index.row() );
323  endRemoveRows();
324  return true;
325  }
326  else
327  {
328  return false;
329  }
330 }
331 
332 bool QgsAggregateMappingModel::moveUp( const QModelIndex &index )
333 {
334  return moveUpOrDown( index );
335 }
336 
337 bool QgsAggregateMappingModel::moveDown( const QModelIndex &index )
338 {
339  return moveUpOrDown( index, false );
340 }
341 
342 
343 //
344 // QgsAggregateMappingWidget
345 //
346 
348  const QgsFields &sourceFields )
349  : QgsPanelWidget( parent )
350 {
351  QVBoxLayout *verticalLayout = new QVBoxLayout();
352  verticalLayout->setContentsMargins( 0, 0, 0, 0 );
353  mTableView = new QTableView();
354  verticalLayout->addWidget( mTableView );
355  setLayout( verticalLayout );
356 
357  mModel = new QgsAggregateMappingModel( sourceFields, this );
358  mTableView->setModel( mModel );
359  mTableView->setItemDelegateForColumn( static_cast<int>( QgsAggregateMappingModel::ColumnDataIndex::SourceExpression ), new QgsFieldMappingWidget::ExpressionDelegate( mTableView ) );
360  mTableView->setItemDelegateForColumn( static_cast<int>( QgsAggregateMappingModel::ColumnDataIndex::Aggregate ), new QgsAggregateMappingWidget::AggregateDelegate( mTableView ) );
361  mTableView->setItemDelegateForColumn( static_cast<int>( QgsAggregateMappingModel::ColumnDataIndex::DestinationType ), new QgsFieldMappingWidget::TypeDelegate( mTableView ) );
362  updateColumns();
363  // Make sure columns are updated when rows are added
364  connect( mModel, &QgsAggregateMappingModel::rowsInserted, this, [ = ] { updateColumns(); } );
365  connect( mModel, &QgsAggregateMappingModel::modelReset, this, [ = ] { updateColumns(); } );
366  connect( mModel, &QgsAggregateMappingModel::dataChanged, this, &QgsAggregateMappingWidget::changed );
367  connect( mModel, &QgsAggregateMappingModel::rowsInserted, this, &QgsAggregateMappingWidget::changed );
368  connect( mModel, &QgsAggregateMappingModel::rowsRemoved, this, &QgsAggregateMappingWidget::changed );
369  connect( mModel, &QgsAggregateMappingModel::modelReset, this, &QgsAggregateMappingWidget::changed );
370 }
371 
373 {
374  return qobject_cast<QgsAggregateMappingModel *>( mModel );
375 }
376 
377 QList<QgsAggregateMappingModel::Aggregate> QgsAggregateMappingWidget::mapping() const
378 {
379  return model()->mapping();
380 }
381 
382 void QgsAggregateMappingWidget::setMapping( const QList<QgsAggregateMappingModel::Aggregate> &mapping )
383 {
384  model()->setMapping( mapping );
385 }
386 
388 {
389  return mTableView->selectionModel();
390 }
391 
393 {
394  model()->setSourceFields( sourceFields );
395 }
396 
397 void QgsAggregateMappingWidget::scrollTo( const QModelIndex &index ) const
398 {
399  mTableView->scrollTo( index );
400 }
401 
403 {
405 }
406 
407 void QgsAggregateMappingWidget::appendField( const QgsField &field, const QString &source, const QString &aggregate )
408 {
409  model()->appendField( field, source, aggregate );
410 }
411 
413 {
414  if ( ! mTableView->selectionModel()->hasSelection() )
415  return false;
416 
417  std::list<int> rowsToRemove { selectedRows() };
418  rowsToRemove.reverse();
419  for ( int row : rowsToRemove )
420  {
421  if ( ! model()->removeField( model()->index( row, 0, QModelIndex() ) ) )
422  {
423  return false;
424  }
425  }
426  return true;
427 }
428 
430 {
431  if ( ! mTableView->selectionModel()->hasSelection() )
432  return false;
433 
434  const std::list<int> rowsToMoveUp { selectedRows() };
435  for ( int row : rowsToMoveUp )
436  {
437  if ( ! model()->moveUp( model()->index( row, 0, QModelIndex() ) ) )
438  {
439  return false;
440  }
441  }
442  return true;
443 }
444 
446 {
447  if ( ! mTableView->selectionModel()->hasSelection() )
448  return false;
449 
450  std::list<int> rowsToMoveDown { selectedRows() };
451  rowsToMoveDown.reverse();
452  for ( int row : rowsToMoveDown )
453  {
454  if ( ! model()->moveDown( model()->index( row, 0, QModelIndex() ) ) )
455  {
456  return false;
457  }
458  }
459  return true;
460 }
461 
462 void QgsAggregateMappingWidget::updateColumns()
463 {
464  for ( int i = 0; i < mModel->rowCount(); ++i )
465  {
466  mTableView->openPersistentEditor( mModel->index( i, static_cast<int>( QgsAggregateMappingModel::ColumnDataIndex::SourceExpression ) ) );
467  mTableView->openPersistentEditor( mModel->index( i, static_cast<int>( QgsAggregateMappingModel::ColumnDataIndex::DestinationType ) ) );
468  mTableView->openPersistentEditor( mModel->index( i, static_cast<int>( QgsAggregateMappingModel::ColumnDataIndex::Aggregate ) ) );
469  }
470 
471  for ( int i = 0; i < mModel->columnCount(); ++i )
472  {
473  mTableView->resizeColumnToContents( i );
474  }
475 }
476 
477 std::list<int> QgsAggregateMappingWidget::selectedRows()
478 {
479  std::list<int> rows;
480  if ( mTableView->selectionModel()->hasSelection() )
481  {
482  const QModelIndexList constSelection { mTableView->selectionModel()->selectedIndexes() };
483  for ( const QModelIndex &index : constSelection )
484  {
485  rows.push_back( index.row() );
486  }
487  rows.sort();
488  rows.unique();
489  }
490  return rows;
491 }
492 
493 
494 
495 //
496 // AggregateDelegate
497 //
498 
499 QgsAggregateMappingWidget::AggregateDelegate::AggregateDelegate( QObject *parent )
500  : QStyledItemDelegate( parent )
501 {
502 }
503 
504 QWidget *QgsAggregateMappingWidget::AggregateDelegate::createEditor( QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex & ) const
505 {
506  Q_UNUSED( option )
507  QComboBox *editor = new QComboBox( parent );
508 
509  const QStringList aggregateList { QgsAggregateMappingWidget::AggregateDelegate::aggregates() };
510  int i = 0;
511  for ( const QString &aggregate : aggregateList )
512  {
513  editor->addItem( aggregate );
514  editor->setItemData( i, aggregate, Qt::UserRole );
515  ++i;
516  }
517 
518  connect( editor,
519  qgis::overload<int >::of( &QComboBox::currentIndexChanged ),
520  this,
521  [ = ]( int currentIndex )
522  {
523  Q_UNUSED( currentIndex )
524  const_cast< QgsAggregateMappingWidget::AggregateDelegate *>( this )->emit commitData( editor );
525  } );
526 
527  return editor;
528 }
529 
530 void QgsAggregateMappingWidget::AggregateDelegate::setEditorData( QWidget *editor, const QModelIndex &index ) const
531 {
532  QComboBox *editorWidget { qobject_cast<QComboBox *>( editor ) };
533  if ( ! editorWidget )
534  return;
535 
536  const QVariant value { index.model()->data( index, Qt::EditRole ) };
537  editorWidget->setCurrentIndex( editorWidget->findData( value ) );
538 }
539 
540 void QgsAggregateMappingWidget::AggregateDelegate::setModelData( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const
541 {
542  QComboBox *editorWidget { qobject_cast<QComboBox *>( editor ) };
543  if ( ! editorWidget )
544  return;
545 
546  const QVariant currentValue { editorWidget->currentData( ) };
547  model->setData( index, currentValue, Qt::EditRole );
548 }
549 
550 const QStringList QgsAggregateMappingWidget::AggregateDelegate::aggregates()
551 {
552  static QStringList sAggregates;
553  static std::once_flag initialized;
554  std::call_once( initialized, [ = ]( )
555  {
556  sAggregates << QStringLiteral( "first_value" );
557 
558  const QList<QgsExpressionFunction *> functions = QgsExpression::Functions();
559  for ( const QgsExpressionFunction *function : functions )
560  {
561  if ( !function || function->isDeprecated() || function->name().isEmpty() || function->name().at( 0 ) == '_' )
562  continue;
563 
564  if ( function->groups().contains( QLatin1String( "Aggregates" ) ) )
565  {
566  if ( function->name() == QLatin1String( "aggregate" )
567  || function->name() == QLatin1String( "relation_aggregate" ) )
568  continue;
569 
570  sAggregates.append( function->name() );
571  }
572 
573  std::sort( sAggregates.begin(), sAggregates.end() );
574  }
575  } );
576 
577  return sAggregates;
578 }
579 
QgsAggregateMappingWidget::appendField
void appendField(const QgsField &field, const QString &source=QString(), const QString &aggregate=QString())
Appends a new field to the model, with an optional source and aggregate.
Definition: qgsprocessingaggregatewidgets.cpp:407
QgsAggregateMappingModel::ColumnDataIndex::SourceExpression
@ SourceExpression
Expression.
QgsAggregateMappingModel::setMapping
void setMapping(const QList< QgsAggregateMappingModel::Aggregate > &mapping)
Sets the mapping to show in the model.
Definition: qgsprocessingaggregatewidgets.cpp:297
qgsexpressioncontextutils.h
QgsAggregateMappingWidget::moveSelectedFieldsDown
bool moveSelectedFieldsDown()
Moves down currently selected field.
Definition: qgsprocessingaggregatewidgets.cpp:445
QgsAggregateMappingWidget::setMapping
void setMapping(const QList< QgsAggregateMappingModel::Aggregate > &mapping)
Sets the mapping to show in the model.
Definition: qgsprocessingaggregatewidgets.cpp:382
QgsAggregateMappingWidget::QgsAggregateMappingWidget
QgsAggregateMappingWidget(QWidget *parent=nullptr, const QgsFields &sourceFields=QgsFields())
Constructs a QgsAggregateMappingWidget from a set of sourceFields.
Definition: qgsprocessingaggregatewidgets.cpp:347
QgsAggregateMappingWidget::moveSelectedFieldsUp
bool moveSelectedFieldsUp()
Moves up currently selected field.
Definition: qgsprocessingaggregatewidgets.cpp:429
QgsAggregateMappingModel::headerData
QVariant headerData(int section, Qt::Orientation orientation, int role) const override
Definition: qgsprocessingaggregatewidgets.cpp:42
QgsAggregateMappingWidget::selectionModel
QItemSelectionModel * selectionModel()
Returns the selection model.
Definition: qgsprocessingaggregatewidgets.cpp:387
QgsFields
Definition: qgsfields.h:44
QgsAggregateMappingWidget::removeSelectedFields
bool removeSelectedFields()
Removes the currently selected field from the model.
Definition: qgsprocessingaggregatewidgets.cpp:412
QgsAggregateMappingModel::contextGenerator
QgsExpressionContextGenerator * contextGenerator() const
Returns the context generator with the source fields.
Definition: qgsprocessingaggregatewidgets.cpp:282
QgsAggregateMappingModel::ColumnDataIndex::DestinationLength
@ DestinationLength
Destination field length.
QgsAggregateMappingModel::moveUp
bool moveUp(const QModelIndex &index)
Moves down the field at index.
Definition: qgsprocessingaggregatewidgets.cpp:332
QgsAggregateMappingModel::ColumnDataIndex::DestinationPrecision
@ DestinationPrecision
Destination field precision.
QgsAggregateMappingModel::appendField
void appendField(const QgsField &field, const QString &source=QString(), const QString &aggregate=QString())
Appends a new field to the model, with an optional source and aggregate.
Definition: qgsprocessingaggregatewidgets.cpp:304
QgsAggregateMappingModel::ColumnDataIndex::Delimiter
@ Delimiter
Delimeter.
QgsFieldMappingModel
Definition: qgsfieldmappingmodel.h:39
precision
int precision
Definition: qgswfsgetfeature.cpp:103
QgsAggregateMappingModel::ColumnDataIndex
ColumnDataIndex
The ColumnDataIndex enum represents the column index for the view.
Definition: qgsprocessingaggregatewidgets.h:50
QgsAggregateMappingModel::sourceFields
QgsFields sourceFields() const
Returns a list of source fields.
Definition: qgsprocessingaggregatewidgets.cpp:92
QgsPanelWidget
Base class for any widget that can be shown as a inline panel.
Definition: qgspanelwidget.h:29
QgsAggregateMappingModel::flags
Qt::ItemFlags flags(const QModelIndex &index) const override
Definition: qgsprocessingaggregatewidgets.cpp:161
QgsAggregateMappingModel::QgsAggregateMappingModel
QgsAggregateMappingModel(const QgsFields &sourceFields=QgsFields(), QObject *parent=nullptr)
Constructs a QgsAggregateMappingModel from a set of sourceFields.
Definition: qgsprocessingaggregatewidgets.cpp:34
QgsAggregateMappingWidget::registerExpressionContextGenerator
void registerExpressionContextGenerator(const QgsExpressionContextGenerator *generator)
Register an expression context generator class that will be used to retrieve an expression context fo...
Definition: qgsprocessingaggregatewidgets.cpp:402
QgsAggregateMappingModel::rowCount
int rowCount(const QModelIndex &parent=QModelIndex()) const override
Definition: qgsprocessingaggregatewidgets.cpp:97
QgsAggregateMappingModel::removeField
bool removeField(const QModelIndex &index)
Removes the field at index from the model, returns true on success.
Definition: qgsprocessingaggregatewidgets.cpp:317
qgsfieldmappingwidget.h
QgsField::setLength
void setLength(int len)
Set the field length.
Definition: qgsfield.cpp:195
QgsAggregateMappingModel::Aggregate::aggregate
QString aggregate
Aggregate name.
Definition: qgsprocessingaggregatewidgets.h:72
QgsExpression::Functions
static const QList< QgsExpressionFunction * > & Functions()
Definition: qgsexpressionfunction.cpp:5649
QgsAggregateMappingModel::ColumnDataIndex::DestinationName
@ DestinationName
Destination field name.
QgsAggregateMappingModel::moveDown
bool moveDown(const QModelIndex &index)
Moves up the field at index.
Definition: qgsprocessingaggregatewidgets.cpp:337
QgsAggregateMappingWidget::changed
void changed()
Emitted when the aggregates defined in the widget are changed.
qgsprocessingaggregatewidgets.h
QgsExpressionFunction
Definition: qgsexpressionfunction.h:40
QgsField::setPrecision
void setPrecision(int precision)
Set the field precision.
Definition: qgsfield.cpp:199
QgsAggregateMappingModel::columnCount
int columnCount(const QModelIndex &parent=QModelIndex()) const override
Definition: qgsprocessingaggregatewidgets.cpp:104
QgsAggregateMappingModel::ColumnDataIndex::DestinationType
@ DestinationType
Destination field QVariant::Type casted to (int)
QgsAggregateMappingWidget::model
QgsAggregateMappingModel * model() const
Returns the underlying mapping model.
Definition: qgsprocessingaggregatewidgets.cpp:372
QgsExpression::quotedColumnRef
static QString quotedColumnRef(QString name)
Returns a quoted column reference (in double quotes)
Definition: qgsexpression.cpp:65
QgsAggregateMappingModel::ColumnDataIndex::Aggregate
@ Aggregate
Aggregate name.
QgsAggregateMappingModel
Definition: qgsprocessingaggregatewidgets.h:40
QgsAggregateMappingModel::setBaseExpressionContextGenerator
void setBaseExpressionContextGenerator(const QgsExpressionContextGenerator *generator)
Sets the base expression context generator, which will generate the expression contexts for expressio...
Definition: qgsprocessingaggregatewidgets.cpp:287
QgsAggregateMappingModel::data
QVariant data(const QModelIndex &index, int role) const override
Definition: qgsprocessingaggregatewidgets.cpp:111
qgsfieldexpressionwidget.h
QgsAggregateMappingModel::setData
bool setData(const QModelIndex &index, const QVariant &value, int role) override
Definition: qgsprocessingaggregatewidgets.cpp:172
QgsField::setType
void setType(QVariant::Type type)
Set variant type.
Definition: qgsfield.cpp:180
QgsAggregateMappingWidget::setSourceFields
void setSourceFields(const QgsFields &sourceFields)
Set source fields of the underlying mapping model to sourceFields.
Definition: qgsprocessingaggregatewidgets.cpp:392
QgsAggregateMappingModel::Aggregate::field
QgsField field
The field in its current status (it might have been renamed)
Definition: qgsprocessingaggregatewidgets.h:78
QgsAggregateMappingWidget::mapping
QList< QgsAggregateMappingModel::Aggregate > mapping() const
Returns a list of Aggregate objects representing the current status of the underlying mapping model.
Definition: qgsprocessingaggregatewidgets.cpp:377
QgsAggregateMappingModel::setSourceFields
void setSourceFields(const QgsFields &sourceFields)
Set source fields to sourceFields.
Definition: qgsprocessingaggregatewidgets.cpp:257
QgsExpression
Definition: qgsexpression.h:113
QgsAggregateMappingModel::mapping
QList< QgsAggregateMappingModel::Aggregate > mapping() const
Returns a list of Aggregate objects representing the current status of the model.
Definition: qgsprocessingaggregatewidgets.cpp:292
QgsExpressionContextGenerator
Definition: qgsexpressioncontextgenerator.h:36
QgsField::setName
void setName(const QString &name)
Set the field name.
Definition: qgsfield.cpp:175
QgsAggregateMappingModel::Aggregate::delimiter
QString delimiter
Delimiter string.
Definition: qgsprocessingaggregatewidgets.h:75
QgsAggregateMappingWidget::scrollTo
void scrollTo(const QModelIndex &index) const
Scroll the fields view to index.
Definition: qgsprocessingaggregatewidgets.cpp:397
QgsAggregateMappingModel::Aggregate::source
QString source
The source expression used as the input for the aggregate calculation.
Definition: qgsprocessingaggregatewidgets.h:69
QgsAggregateMappingModel::Aggregate
The Aggregate struct holds information about an aggregate column.
Definition: qgsprocessingaggregatewidgets.h:66
QgsField
Definition: qgsfield.h:49