QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
qgslayoutattributeselectiondialog.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgslayoutattributeselectiondialog.cpp
3  -------------------------------------
4  begin : November 2017
5  copyright : (C) 2017 by Nyall Dawson
6  email : nyall dot dawson at gmail dot com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
20 #include "qgsvectorlayer.h"
22 #include "qgsdoublespinbox.h"
23 #include "qgssettings.h"
24 #include "qgsgui.h"
25 #include "qgslayouttablecolumn.h"
26 #include "qgshelp.h"
27 
28 #include <QCheckBox>
29 #include <QDialogButtonBox>
30 #include <QGridLayout>
31 #include <QLabel>
32 #include <QLineEdit>
33 #include <QPushButton>
34 #include <QSpinBox>
35 #include <QSortFilterProxyModel>
36 
37 
38 
39 // QgsLayoutAttributeTableColumnModelBase
40 
42  : QAbstractTableModel( parent )
43  , mTable( table )
44 {
45 }
46 
47 QModelIndex QgsLayoutAttributeTableColumnModelBase::index( int row, int column, const QModelIndex &parent ) const
48 {
49  if ( !hasIndex( row, column, parent ) )
50  return QModelIndex();
51 
52  if ( !parent.isValid() )
53  {
54  return createIndex( row, column );
55  }
56 
57  return QModelIndex();
58 }
59 
60 QModelIndex QgsLayoutAttributeTableColumnModelBase::parent( const QModelIndex &child ) const
61 {
62  Q_UNUSED( child )
63  return QModelIndex();
64 }
65 
66 int QgsLayoutAttributeTableColumnModelBase::rowCount( const QModelIndex &parent ) const
67 {
68  if ( parent.isValid() )
69  return 0;
70 
71  return columns().length();
72 }
73 
74 int QgsLayoutAttributeTableColumnModelBase::columnCount( const QModelIndex &parent ) const
75 {
76  Q_UNUSED( parent )
77  return displayedColumns().count();
78 }
79 
80 QVariant QgsLayoutAttributeTableColumnModelBase::data( const QModelIndex &index, int role ) const
81 {
82  if ( !index.isValid() ||
83  ( role != Qt::DisplayRole && role != Qt::EditRole && role != Qt::UserRole ) )
84  {
85  return QVariant();
86  }
87 
88  if ( index.row() >= columns().length() )
89  {
90  return QVariant();
91  }
92 
93  // get layout column for index
94  const QgsLayoutTableColumn column = columns().value( index.row() );
95 
96  const Column col = displayedColumns()[index.column()];
97  switch ( col )
98  {
99  case Attribute:
100  return column.attribute();
101  case Heading:
102  return column.heading();
103  case Alignment:
104  {
105  if ( role == Qt::DisplayRole )
106  {
107  switch ( column.hAlignment() )
108  {
109  case Qt::AlignHCenter:
110  switch ( column.vAlignment() )
111  {
112  case Qt::AlignTop:
113  return tr( "Top center" );
114  case Qt::AlignBottom:
115  return tr( "Bottom center" );
116  default:
117  return tr( "Middle center" );
118  }
119  case Qt::AlignRight:
120  switch ( column.vAlignment() )
121  {
122  case Qt::AlignTop:
123  return tr( "Top right" );
124  case Qt::AlignBottom:
125  return tr( "Bottom right" );
126  default:
127  return tr( "Middle right" );
128  }
129  case Qt::AlignLeft:
130  default:
131  switch ( column.vAlignment() )
132  {
133  case Qt::AlignTop:
134  return tr( "Top left" );
135  case Qt::AlignBottom:
136  return tr( "Bottom left" );
137  default:
138  return tr( "Middle left" );
139  }
140  }
141  }
142  else
143  {
144  //edit role
145  return int( column.hAlignment() | column.vAlignment() );
146  }
147  }
148  case Width:
149  {
150  if ( role == Qt::DisplayRole )
151  {
152  return column.width() <= 0 ? tr( "Automatic" ) : tr( "%1 mm" ).arg( column.width(), 0, 'f', 2 );
153  }
154  else
155  {
156  //edit role
157  return column.width();
158  }
159  }
160  case SortOrder:
161  if ( role == Qt::DisplayRole )
162  {
163  switch ( column.sortOrder() )
164  {
165  case Qt::DescendingOrder:
166  return tr( "Descending" );
167  case Qt::AscendingOrder:
168  default:
169  return tr( "Ascending" );
170  }
171  }
172  else
173  {
174  //edit role
175  return column.sortOrder();
176  }
177  }
178 
179  return QVariant();
180 }
181 
182 QVariant QgsLayoutAttributeTableColumnModelBase::headerData( int section, Qt::Orientation orientation, int role ) const
183 {
184  if ( !mTable )
185  {
186  return QVariant();
187  }
188 
189  if ( role == Qt::DisplayRole )
190  {
191  if ( orientation == Qt::Vertical ) //row
192  {
193  return QVariant( section );
194  }
195  else
196  {
197  const Column col = displayedColumns()[section];
198  switch ( col )
199  {
200  case Attribute:
201  return QVariant( tr( "Attribute" ) );
202 
203  case Heading:
204  return QVariant( tr( "Heading" ) );
205 
206  case Alignment:
207  return QVariant( tr( "Alignment" ) );
208 
209  case Width:
210  return QVariant( tr( "Width" ) );
211 
212  case SortOrder:
213  return QVariant( tr( "Sort Order" ) );
214  }
215  }
216  }
217 
218  return QVariant();
219 }
220 
221 bool QgsLayoutAttributeTableColumnModelBase::setData( const QModelIndex &index, const QVariant &value, int role )
222 {
223  if ( !index.isValid() || role != Qt::EditRole || !mTable )
224  return false;
225 
226  if ( index.row() >= columns().length() )
227  return false;
228 
229  if ( index.column() > displayedColumns().count() )
230  return false;
231 
232  QgsLayoutTableColumn &colToUpdate = columns()[index.row()];
233 
234  const Column col = displayedColumns()[index.column()];
235  switch ( col )
236  {
237  case Attribute:
238  // also update column's heading, if it hasn't been customized
239  if ( colToUpdate.heading().isEmpty() || ( colToUpdate.heading() == colToUpdate.attribute() ) )
240  {
241  colToUpdate.setHeading( value.toString() );
242  emit dataChanged( createIndex( index.row(), 1 ), createIndex( index.row(), 1 ) );
243  }
244  colToUpdate.setAttribute( value.toString() );
245  emit dataChanged( index, index );
246  return true;
247 
248  case Heading:
249  colToUpdate.setHeading( value.toString() );
250  emit dataChanged( index, index );
251  return true;
252 
253  case Alignment:
254  colToUpdate.setHAlignment( Qt::AlignmentFlag( value.toInt() & Qt::AlignHorizontal_Mask ) );
255  colToUpdate.setVAlignment( Qt::AlignmentFlag( value.toInt() & Qt::AlignVertical_Mask ) );
256  emit dataChanged( index, index );
257  return true;
258 
259  case Width:
260  colToUpdate.setWidth( value.toDouble() );
261  emit dataChanged( index, index );
262  return true;
263 
264  case SortOrder:
265  colToUpdate.setSortOrder( static_cast< Qt::SortOrder >( value.toInt() ) );
266  emit dataChanged( index, index );
267  return true;
268  }
269 
270  return false;
271 }
272 
273 Qt::ItemFlags QgsLayoutAttributeTableColumnModelBase::flags( const QModelIndex &index ) const
274 {
275  Qt::ItemFlags flags = QAbstractTableModel::flags( index );
276 
277  if ( index.isValid() )
278  {
279  return flags | Qt::ItemIsEditable;
280  }
281  else
282  {
283  return flags;
284  }
285 }
286 
287 bool QgsLayoutAttributeTableColumnModelBase::removeRows( int row, int count, const QModelIndex &parent )
288 {
289  Q_UNUSED( parent )
290 
291  const int maxRow = std::min< int >( row + count - 1, columns().length() - 1 );
292  beginRemoveRows( QModelIndex(), row, maxRow );
293  //move backwards through rows, removing each corresponding QgsComposerTableColumn
294  for ( int i = maxRow; i >= row; --i )
295  {
296  columns().removeAt( i );
297  }
298  endRemoveRows();
299  return true;
300 }
301 
302 bool QgsLayoutAttributeTableColumnModelBase::insertRows( int row, int count, const QModelIndex &parent )
303 {
304  Q_UNUSED( parent )
305  beginInsertRows( QModelIndex(), row, row + count - 1 );
306  //create new QgsComposerTableColumns for each inserted row
307  for ( int i = row; i < row + count; ++i )
308  {
309  columns().insert( i, QgsLayoutTableColumn() );
310  }
311  endInsertRows();
312  return true;
313 }
314 
316 {
317  if ( ( direction == ShiftUp && row <= 0 ) ||
318  ( direction == ShiftDown && row >= rowCount() - 1 ) )
319  {
320  //row is already at top/bottom
321  return false;
322  }
323 
324  //we shift a row by removing the next row up/down, then reinserting it before/after the target row
325  const int swapWithRow = direction == ShiftUp ? row - 1 : row + 1;
326 
327  //remove row
328  beginRemoveRows( QModelIndex(), swapWithRow, swapWithRow );
329  const QgsLayoutTableColumn temp = columns().takeAt( swapWithRow );
330  endRemoveRows();
331 
332  //insert row
333  beginInsertRows( QModelIndex(), row, row );
334  columns().insert( row, temp );
335  endInsertRows();
336 
337  return true;
338 }
339 
340 // QgsLayoutAttributeTableColumnModel
341 
342 QVector<QgsLayoutTableColumn> &QgsLayoutAttributeTableColumnModel::columns() const
343 {
344  return mTable->columns();
345 }
346 
348 {
349  beginResetModel();
350  mTable->resetColumns();
351  endResetModel();
352 }
353 
354 
355 // QgsLayoutTableSortModel
356 
357 QVector<QgsLayoutTableColumn> &QgsLayoutTableSortModel::columns() const
358 {
359  return mTable->sortColumns();
360 }
361 
362 // QgsLayoutColumnAlignmentDelegate
363 
364 QgsLayoutColumnAlignmentDelegate::QgsLayoutColumnAlignmentDelegate( QObject *parent ) : QItemDelegate( parent )
365 {
366 
367 }
368 
369 QWidget *QgsLayoutColumnAlignmentDelegate::createEditor( QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index ) const
370 {
371  Q_UNUSED( option )
372  Q_UNUSED( index )
373 
374  //create a combo box showing alignment options
375  QComboBox *comboBox = new QComboBox( parent );
376 
377  comboBox->addItem( tr( "Top Left" ), int( Qt::AlignTop | Qt::AlignLeft ) );
378  comboBox->addItem( tr( "Top Center" ), int( Qt::AlignTop | Qt::AlignHCenter ) );
379  comboBox->addItem( tr( "Top Right" ), int( Qt::AlignTop | Qt::AlignRight ) );
380  comboBox->addItem( tr( "Middle Left" ), int( Qt::AlignVCenter | Qt::AlignLeft ) );
381  comboBox->addItem( tr( "Middle Center" ), int( Qt::AlignVCenter | Qt::AlignHCenter ) );
382  comboBox->addItem( tr( "Middle Right" ), int( Qt::AlignVCenter | Qt::AlignRight ) );
383  comboBox->addItem( tr( "Bottom Left" ), int( Qt::AlignBottom | Qt::AlignLeft ) );
384  comboBox->addItem( tr( "Bottom Center" ), int( Qt::AlignBottom | Qt::AlignHCenter ) );
385  comboBox->addItem( tr( "Bottom Right" ), int( Qt::AlignBottom | Qt::AlignRight ) );
386 
387  const Qt::AlignmentFlag alignment = ( Qt::AlignmentFlag )index.model()->data( index, Qt::EditRole ).toInt();
388  comboBox->setCurrentIndex( comboBox->findData( alignment ) );
389 
390  return comboBox;
391 }
392 
393 void QgsLayoutColumnAlignmentDelegate::setEditorData( QWidget *editor, const QModelIndex &index ) const
394 {
395  const Qt::AlignmentFlag alignment = ( Qt::AlignmentFlag )index.model()->data( index, Qt::EditRole ).toInt();
396 
397  //set the value for the combobox
398  QComboBox *comboBox = static_cast<QComboBox *>( editor );
399  comboBox->setCurrentIndex( comboBox->findData( alignment ) );
400 }
401 
402 void QgsLayoutColumnAlignmentDelegate::setModelData( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const
403 {
404  QComboBox *comboBox = static_cast<QComboBox *>( editor );
405  const Qt::AlignmentFlag alignment = ( Qt::AlignmentFlag ) comboBox->currentData().toInt();
406  model->setData( index, alignment, Qt::EditRole );
407 }
408 
409 void QgsLayoutColumnAlignmentDelegate::updateEditorGeometry( QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index ) const
410 {
411  Q_UNUSED( index )
412  editor->setGeometry( option.rect );
413 }
414 
415 
416 // QgsLayoutColumnSourceDelegate
417 
418 QgsLayoutColumnSourceDelegate::QgsLayoutColumnSourceDelegate( QgsVectorLayer *vlayer, QObject *parent, const QgsLayoutObject *layoutObject, bool forceExpressions )
419  : QItemDelegate( parent )
420  , mVectorLayer( vlayer )
421  , mLayoutObject( layoutObject )
422  , mForceExpressions( forceExpressions )
423 {
424 
425 }
426 
427 QgsExpressionContext QgsLayoutColumnSourceDelegate::createExpressionContext() const
428 {
429  if ( !mLayoutObject )
430  {
431  return QgsExpressionContext();
432  }
433 
434  QgsExpressionContext expContext = mLayoutObject->createExpressionContext();
435  expContext.lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "row_number" ), 1, true ) );
436  expContext.setHighlightedVariables( QStringList() << QStringLiteral( "row_number" ) );
437  return expContext;
438 }
439 
440 QWidget *QgsLayoutColumnSourceDelegate::createEditor( QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index ) const
441 {
442  Q_UNUSED( option )
443  Q_UNUSED( index )
444 
445  QgsFieldExpressionWidget *fieldExpression = new QgsFieldExpressionWidget( parent );
446  fieldExpression->setLayer( mVectorLayer );
447  fieldExpression->registerExpressionContextGenerator( this );
448 
449  //listen out for field changes
450  connect( fieldExpression, static_cast < void ( QgsFieldExpressionWidget::* )( const QString & ) >( &QgsFieldExpressionWidget::fieldChanged ), this, [ = ] { const_cast< QgsLayoutColumnSourceDelegate * >( this )->commitAndCloseEditor(); } );
451  return fieldExpression;
452 }
453 
454 void QgsLayoutColumnSourceDelegate::setEditorData( QWidget *editor, const QModelIndex &index ) const
455 {
456  const QString field = index.model()->data( index, Qt::EditRole ).toString();
457 
458  //set the value for the field combobox
459  QgsFieldExpressionWidget *fieldExpression = static_cast<QgsFieldExpressionWidget *>( editor );
460  fieldExpression->setField( field );
461 }
462 
463 void QgsLayoutColumnSourceDelegate::setModelData( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const
464 {
465  QgsFieldExpressionWidget *fieldExpression = static_cast<QgsFieldExpressionWidget *>( editor );
466  const QString field = mForceExpressions ? fieldExpression->asExpression() : fieldExpression->currentField();
467 
468  model->setData( index, field, Qt::EditRole );
469 }
470 
471 void QgsLayoutColumnSourceDelegate::updateEditorGeometry( QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index ) const
472 {
473  Q_UNUSED( index )
474  editor->setGeometry( option.rect );
475 }
476 
477 void QgsLayoutColumnSourceDelegate::commitAndCloseEditor()
478 {
479  QgsFieldExpressionWidget *fieldExpression = qobject_cast<QgsFieldExpressionWidget *>( sender() );
480  emit commitData( fieldExpression );
481 }
482 
483 
484 // QgsLayoutColumnSortOrderDelegate
485 
486 QgsLayoutColumnSortOrderDelegate::QgsLayoutColumnSortOrderDelegate( QObject *parent ) : QItemDelegate( parent )
487 {
488 
489 }
490 
491 QWidget *QgsLayoutColumnSortOrderDelegate::createEditor( QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index ) const
492 {
493  Q_UNUSED( option )
494  Q_UNUSED( index )
495 
496  QComboBox *comboBox = new QComboBox( parent );
497  QStringList sortOrders;
498  sortOrders << tr( "Ascending" ) << tr( "Descending" );
499  comboBox->addItems( sortOrders );
500  return comboBox;
501 }
502 
503 void QgsLayoutColumnSortOrderDelegate::setEditorData( QWidget *editor, const QModelIndex &index ) const
504 {
505  const Qt::SortOrder order = ( Qt::SortOrder )index.model()->data( index, Qt::EditRole ).toInt();
506 
507  //set the value for the combobox
508  QComboBox *comboBox = static_cast<QComboBox *>( editor );
509  switch ( order )
510  {
511  case Qt::DescendingOrder:
512  comboBox->setCurrentIndex( 1 );
513  break;
514  case Qt::AscendingOrder:
515  default:
516  comboBox->setCurrentIndex( 0 );
517  break;
518  }
519 }
520 
521 void QgsLayoutColumnSortOrderDelegate::setModelData( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const
522 {
523  QComboBox *comboBox = static_cast<QComboBox *>( editor );
524  const int value = comboBox->currentIndex();
525  Qt::SortOrder order;
526  switch ( value )
527  {
528  case 1:
529  order = Qt::DescendingOrder;
530  break;
531  case 0:
532  default:
533  order = Qt::AscendingOrder;
534  break;
535  }
536 
537  model->setData( index, order, Qt::EditRole );
538 }
539 
540 void QgsLayoutColumnSortOrderDelegate::updateEditorGeometry( QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index ) const
541 {
542  Q_UNUSED( index )
543  editor->setGeometry( option.rect );
544 }
545 
546 
547 //
548 // QgsLayoutColumnWidthDelegate
549 //
550 
552  : QItemDelegate( parent )
553 {
554 
555 }
556 
557 QWidget *QgsLayoutColumnWidthDelegate::createEditor( QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index ) const
558 {
559  Q_UNUSED( index )
560  Q_UNUSED( option )
561  QgsDoubleSpinBox *editor = new QgsDoubleSpinBox( parent );
562  editor->setMinimum( 0 );
563  editor->setMaximum( 1000 );
564  editor->setDecimals( 2 );
565  editor->setSuffix( tr( " mm" ) );
566  editor->setSpecialValueText( tr( "Automatic" ) );
567  editor->setShowClearButton( true );
568  return editor;
569 }
570 
571 void QgsLayoutColumnWidthDelegate::setEditorData( QWidget *editor, const QModelIndex &index ) const
572 {
573  const int value = index.model()->data( index, Qt::EditRole ).toInt();
574 
575  QgsDoubleSpinBox *spinBox = static_cast<QgsDoubleSpinBox *>( editor );
576  spinBox->setValue( value );
577 }
578 
579 void QgsLayoutColumnWidthDelegate::setModelData( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const
580 {
581  QgsDoubleSpinBox *spinBox = static_cast<QgsDoubleSpinBox *>( editor );
582  spinBox->interpretText();
583  const int value = spinBox->value();
584 
585  model->setData( index, value, Qt::EditRole );
586 }
587 
588 void QgsLayoutColumnWidthDelegate::updateEditorGeometry( QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index ) const
589 {
590  Q_UNUSED( index )
591  editor->setGeometry( option.rect );
592 }
593 
594 
595 // QgsLayoutAttributeSelectionDialog
596 
598  QWidget *parent, Qt::WindowFlags f )
599  : QDialog( parent, f )
600  , mTable( table )
601  , mVectorLayer( vLayer )
602 
603 {
604  setupUi( this );
606 
607  connect( mRemoveColumnPushButton, &QPushButton::clicked, this, &QgsLayoutAttributeSelectionDialog::mRemoveColumnPushButton_clicked );
608  connect( mAddColumnPushButton, &QPushButton::clicked, this, &QgsLayoutAttributeSelectionDialog::mAddColumnPushButton_clicked );
609  connect( mColumnUpPushButton, &QPushButton::clicked, this, &QgsLayoutAttributeSelectionDialog::mColumnUpPushButton_clicked );
610  connect( mColumnDownPushButton, &QPushButton::clicked, this, &QgsLayoutAttributeSelectionDialog::mColumnDownPushButton_clicked );
611  connect( mResetColumnsPushButton, &QPushButton::clicked, this, &QgsLayoutAttributeSelectionDialog::mResetColumnsPushButton_clicked );
612  connect( mClearColumnsPushButton, &QPushButton::clicked, this, &QgsLayoutAttributeSelectionDialog::mClearColumnsPushButton_clicked );
613  connect( mAddSortColumnPushButton, &QPushButton::clicked, this, &QgsLayoutAttributeSelectionDialog::mAddSortColumnPushButton_clicked );
614  connect( mRemoveSortColumnPushButton, &QPushButton::clicked, this, &QgsLayoutAttributeSelectionDialog::mRemoveSortColumnPushButton_clicked );
615  connect( mSortColumnUpPushButton, &QPushButton::clicked, this, &QgsLayoutAttributeSelectionDialog::mSortColumnUpPushButton_clicked );
616  connect( mSortColumnDownPushButton, &QPushButton::clicked, this, &QgsLayoutAttributeSelectionDialog::mSortColumnDownPushButton_clicked );
617  connect( buttonBox, &QDialogButtonBox::helpRequested, this, &QgsLayoutAttributeSelectionDialog::showHelp );
618 
619  if ( mTable )
620  {
621  //set up models, views and delegates
622  mColumnModel = new QgsLayoutAttributeTableColumnModel( mTable, mColumnsTableView );
623  mColumnsTableView->setModel( mColumnModel );
624  mColumnsTableView->horizontalHeader()->setSectionResizeMode( QHeaderView::Stretch );
625  mColumnSourceDelegate = new QgsLayoutColumnSourceDelegate( vLayer, mColumnsTableView, mTable );
626  mColumnsTableView->setItemDelegateForColumn( 0, mColumnSourceDelegate );
627  mColumnAlignmentDelegate = new QgsLayoutColumnAlignmentDelegate( mColumnsTableView );
628  mColumnsTableView->setItemDelegateForColumn( 2, mColumnAlignmentDelegate );
629  mColumnWidthDelegate = new QgsLayoutColumnWidthDelegate( mColumnsTableView );
630  mColumnsTableView->setItemDelegateForColumn( 3, mColumnWidthDelegate );
631 
632  mSortColumnModel = new QgsLayoutTableSortModel( mTable, mSortColumnTableView );
633  mSortColumnTableView->setModel( mSortColumnModel );
634  mSortColumnTableView->horizontalHeader()->setSectionResizeMode( QHeaderView::Stretch );
635  mSortColumnSourceDelegate = new QgsLayoutColumnSourceDelegate( vLayer, mSortColumnTableView, mTable, true );
636  mSortColumnTableView->setItemDelegateForColumn( 0, mSortColumnSourceDelegate );
637  mSortColumnOrderDelegate = new QgsLayoutColumnSortOrderDelegate( mSortColumnTableView );
638  mSortColumnTableView->setItemDelegateForColumn( 1, mSortColumnOrderDelegate );
639  }
640 }
641 
642 void QgsLayoutAttributeSelectionDialog::mRemoveColumnPushButton_clicked()
643 {
644  //remove selected rows from model
645  const QModelIndexList indexes = mColumnsTableView->selectionModel()->selectedRows();
646  const int count = indexes.count();
647 
648  for ( int i = count; i > 0; --i )
649  mColumnModel->removeRow( indexes.at( i - 1 ).row(), QModelIndex() );
650 }
651 
652 void QgsLayoutAttributeSelectionDialog::mAddColumnPushButton_clicked()
653 {
654  //add a new row to the model
655  mColumnModel->insertRow( mColumnModel->rowCount() );
656 }
657 
658 void QgsLayoutAttributeSelectionDialog::mColumnUpPushButton_clicked()
659 {
660  //move selected row up
661 
662  QModelIndexList indexes = mColumnsTableView->selectionModel()->selectedRows();
663  const int count = indexes.count();
664 
665  std::reverse( indexes.begin(), indexes.end() );
666  for ( int i = count; i > 0; --i )
667  mColumnModel->moveRow( indexes.at( i - 1 ).row(), QgsLayoutAttributeTableColumnModelBase::ShiftUp );
668 }
669 
670 void QgsLayoutAttributeSelectionDialog::mColumnDownPushButton_clicked()
671 {
672  //move selected row down
673  const QModelIndexList indexes = mColumnsTableView->selectionModel()->selectedRows();
674  const int count = indexes.count();
675 
676  for ( int i = count; i > 0; --i )
677  mColumnModel->moveRow( indexes.at( i - 1 ).row(), QgsLayoutAttributeTableColumnModelBase::ShiftDown );
678 }
679 
680 void QgsLayoutAttributeSelectionDialog::mResetColumnsPushButton_clicked()
681 {
682  //reset columns to match vector layer's fields
683  mColumnModel->resetToLayer();
684 }
685 
686 void QgsLayoutAttributeSelectionDialog::mClearColumnsPushButton_clicked()
687 {
688  //remove all columns
689  mColumnModel->removeRows( 0, mColumnModel->rowCount() );
690 }
691 
692 void QgsLayoutAttributeSelectionDialog::mAddSortColumnPushButton_clicked()
693 {
694  //add a new row to the model
695  mSortColumnModel->insertRow( mSortColumnModel->rowCount() );
696 }
697 
698 void QgsLayoutAttributeSelectionDialog::mRemoveSortColumnPushButton_clicked()
699 {
700  //remove selected rows from model
701  const QModelIndexList indexes = mSortColumnTableView->selectionModel()->selectedRows();
702  const int count = indexes.count();
703 
704  for ( int i = count; i > 0; --i )
705  mSortColumnModel->removeRow( indexes.at( i - 1 ).row(), QModelIndex() );
706 }
707 
708 void QgsLayoutAttributeSelectionDialog::showHelp()
709 {
710  QgsHelp::openHelp( QStringLiteral( "print_composer/composer_items/composer_attribute_table.html" ) );
711 }
712 
713 void QgsLayoutAttributeSelectionDialog::mSortColumnDownPushButton_clicked()
714 {
715  //move selected row down
716  const QModelIndexList indexes = mSortColumnTableView->selectionModel()->selectedRows();
717  const int count = indexes.count();
718 
719  for ( int i = count; i > 0; --i )
720  mSortColumnModel->moveRow( indexes.at( i - 1 ).row(), QgsLayoutTableSortModel::ShiftDown );
721 }
722 
723 void QgsLayoutAttributeSelectionDialog::mSortColumnUpPushButton_clicked()
724 {
725  //move selected row up
726  const QModelIndexList indexes = mSortColumnTableView->selectionModel()->selectedRows();
727  const int count = indexes.count();
728 
729  for ( int i = count; i > 0; --i )
730  mSortColumnModel->moveRow( indexes.at( i - 1 ).row(), QgsLayoutTableSortModel::ShiftUp );
731 }
732 
733 
QgsExpressionContext
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
Definition: qgsexpressioncontext.h:406
QgsFieldExpressionWidget::asExpression
QString asExpression() const
Returns the currently selected field or expression.
Definition: qgsfieldexpressionwidget.cpp:123
QgsLayoutColumnSortOrderDelegate::setModelData
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override
Definition: qgslayoutattributeselectiondialog.cpp:521
qgslayoutitemattributetable.h
QgsLayoutAttributeTableColumnModelBase::removeRows
bool removeRows(int row, int count, const QModelIndex &parent=QModelIndex()) override
Definition: qgslayoutattributeselectiondialog.cpp:287
qgsdoublespinbox.h
QgsLayoutAttributeTableColumnModelBase::flags
Qt::ItemFlags flags(const QModelIndex &index) const override
Definition: qgslayoutattributeselectiondialog.cpp:273
QgsLayoutColumnAlignmentDelegate::updateEditorGeometry
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override
Definition: qgslayoutattributeselectiondialog.cpp:409
QgsExpressionContextScope::addVariable
void addVariable(const QgsExpressionContextScope::StaticVariable &variable)
Adds a variable into the context scope.
Definition: qgsexpressioncontext.cpp:97
QgsLayoutTableSortModel::columns
QVector< QgsLayoutTableColumn > & columns() const override
To be reimplemented to provide the display or the sort columns.
Definition: qgslayoutattributeselectiondialog.cpp:357
qgslayoutattributeselectiondialog.h
QgsLayoutAttributeTableColumnModelBase::moveRow
bool moveRow(int row, ShiftDirection direction)
Moves the specified row up or down in the model.
Definition: qgslayoutattributeselectiondialog.cpp:315
QgsLayoutColumnAlignmentDelegate::createEditor
QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override
Definition: qgslayoutattributeselectiondialog.cpp:369
qgsgui.h
QgsFieldExpressionWidget::currentField
QString currentField(bool *isExpression=nullptr, bool *isValid=nullptr) const
currentField returns the currently selected field or expression if allowed
Definition: qgsfieldexpressionwidget.cpp:144
QgsLayoutColumnSortOrderDelegate
A delegate for showing column sort order as a combo box.
Definition: qgslayoutattributeselectiondialog.h:266
QgsLayoutAttributeTableColumnModelBase::Column
Column
Available columns for the configuration table to be used by the model.
Definition: qgslayoutattributeselectiondialog.h:71
QgsLayoutTable::sortColumns
QgsLayoutTableSortColumns & sortColumns()
Returns a reference to the list of QgsLayoutTableSortColumns shown in the table.
Definition: qgslayouttable.h:501
QgsExpressionContext::lastScope
QgsExpressionContextScope * lastScope()
Returns the last scope added to the context.
Definition: qgsexpressioncontext.cpp:377
QgsLayoutTableColumn::width
double width() const
Returns the width for the column in mm, or 0 if column width is automatically calculated.
Definition: qgslayouttablecolumn.h:80
QgsLayoutTable::columns
QgsLayoutTableColumns & columns()
Returns a reference to the list of QgsLayoutTableColumns shown in the table.
Definition: qgslayouttable.h:482
QgsLayoutAttributeTableColumnModelBase::parent
QModelIndex parent(const QModelIndex &child) const override
Definition: qgslayoutattributeselectiondialog.cpp:60
QgsLayoutAttributeTableColumnModelBase::QgsLayoutAttributeTableColumnModelBase
QgsLayoutAttributeTableColumnModelBase(QgsLayoutItemAttributeTable *table, QObject *parent=nullptr)
Constructor for QgsLayoutAttributeTableColumnModel.
Definition: qgslayoutattributeselectiondialog.cpp:41
QgsLayoutAttributeTableColumnModelBase::ShiftUp
@ ShiftUp
Shift the row/column up.
Definition: qgslayoutattributeselectiondialog.h:64
QgsLayoutAttributeTableColumnModelBase::columns
virtual QVector< QgsLayoutTableColumn > & columns() const =0
To be reimplemented to provide the display or the sort columns.
QgsLayoutColumnSortOrderDelegate::createEditor
QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override
Definition: qgslayoutattributeselectiondialog.cpp:491
QgsLayoutAttributeTableColumnModelBase::Heading
@ Heading
Defines the title of the column.
Definition: qgslayoutattributeselectiondialog.h:74
field
const QgsField & field
Definition: qgsfield.h:463
QgsLayoutColumnWidthDelegate::setModelData
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override
Definition: qgslayoutattributeselectiondialog.cpp:579
QgsLayoutColumnSourceDelegate
A delegate for showing column attribute source as a QgsFieldExpressionWidget.
Definition: qgslayoutattributeselectiondialog.h:211
QgsLayoutColumnWidthDelegate::setEditorData
void setEditorData(QWidget *editor, const QModelIndex &index) const override
Definition: qgslayoutattributeselectiondialog.cpp:571
QgsFieldExpressionWidget::registerExpressionContextGenerator
void registerExpressionContextGenerator(const QgsExpressionContextGenerator *generator)
Register an expression context generator class that will be used to retrieve an expression context fo...
Definition: qgsfieldexpressionwidget.cpp:165
QgsGui::enableAutoGeometryRestore
static void enableAutoGeometryRestore(QWidget *widget, const QString &key=QString())
Register the widget to allow its position to be automatically saved and restored when open and closed...
Definition: qgsgui.cpp:180
QgsLayoutColumnSourceDelegate::createEditor
QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override
Definition: qgslayoutattributeselectiondialog.cpp:440
QgsLayoutAttributeTableColumnModelBase::insertRows
bool insertRows(int row, int count, const QModelIndex &parent=QModelIndex()) override
Definition: qgslayoutattributeselectiondialog.cpp:302
QgsLayoutAttributeTableColumnModelBase::displayedColumns
virtual QList< Column > displayedColumns() const =0
To be reimplemented to choose which column should be used by the model.
QgsLayoutAttributeTableColumnModelBase::Width
@ Width
Defines the width of the column.
Definition: qgslayoutattributeselectiondialog.h:76
QgsLayoutAttributeTableColumnModelBase::Attribute
@ Attribute
Attribute for a field or an expression.
Definition: qgslayoutattributeselectiondialog.h:73
QgsLayoutColumnSortOrderDelegate::QgsLayoutColumnSortOrderDelegate
QgsLayoutColumnSortOrderDelegate(QObject *parent=nullptr)
constructor
Definition: qgslayoutattributeselectiondialog.cpp:486
QgsLayoutTableSortModel
Allows for filtering QgsComposerAttributeTable columns by columns which are sorted or unsorted.
Definition: qgslayoutattributeselectiondialog.h:161
QgsLayoutAttributeTableColumnModelBase::setData
bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole) override
Definition: qgslayoutattributeselectiondialog.cpp:221
QgsLayoutAttributeTableColumnModel::resetToLayer
void resetToLayer()
Resets the attribute table's columns to match the source layer's fields.
Definition: qgslayoutattributeselectiondialog.cpp:347
QgsLayoutTableColumn::vAlignment
Qt::AlignmentFlag vAlignment() const
Returns the vertical alignment for a column, which controls the alignment used for drawing column val...
Definition: qgslayouttablecolumn.h:124
QgsFieldExpressionWidget::fieldChanged
void fieldChanged(const QString &fieldName)
Emitted when the currently selected field changes.
QgsLayoutTableColumn::heading
QString heading() const
Returns the heading for a column, which is the value displayed in the column's header cell.
Definition: qgslayouttablecolumn.h:93
QgsLayoutColumnSortOrderDelegate::setEditorData
void setEditorData(QWidget *editor, const QModelIndex &index) const override
Definition: qgslayoutattributeselectiondialog.cpp:503
QgsLayoutTableColumn::setHAlignment
void setHAlignment(Qt::AlignmentFlag alignment)
Sets the horizontal alignment for a column, which controls the alignment used for drawing column valu...
Definition: qgslayouttablecolumn.h:116
QgsLayoutColumnSourceDelegate::setModelData
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override
Definition: qgslayoutattributeselectiondialog.cpp:463
QgsLayoutColumnAlignmentDelegate::QgsLayoutColumnAlignmentDelegate
QgsLayoutColumnAlignmentDelegate(QObject *parent=nullptr)
constructor
Definition: qgslayoutattributeselectiondialog.cpp:364
QgsLayoutItemAttributeTable
A layout table subclass that displays attributes from a vector layer.
Definition: qgslayoutitemattributetable.h:34
QgsLayoutTableColumn::setAttribute
void setAttribute(const QString &attribute)
Sets the attribute name or expression used for the column's values.
Definition: qgslayouttablecolumn.h:148
QgsLayoutTableColumn::attribute
QString attribute() const
Returns the attribute name or expression used for the column's values.
Definition: qgslayouttablecolumn.h:140
QgsLayoutAttributeTableColumnModelBase::Alignment
@ Alignment
Defines the alignment of the column.
Definition: qgslayoutattributeselectiondialog.h:75
QgsLayoutColumnSourceDelegate::setEditorData
void setEditorData(QWidget *editor, const QModelIndex &index) const override
Definition: qgslayoutattributeselectiondialog.cpp:454
QgsDoubleSpinBox::setShowClearButton
void setShowClearButton(bool showClearButton)
Sets whether the widget will show a clear button.
Definition: qgsdoublespinbox.cpp:55
QgsLayoutTableColumn::sortOrder
Qt::SortOrder sortOrder() const
Returns the sort order for the column.
Definition: qgslayouttablecolumn.h:157
QgsLayoutAttributeTableColumnModelBase::columnCount
int columnCount(const QModelIndex &parent=QModelIndex()) const override
Definition: qgslayoutattributeselectiondialog.cpp:74
QgsLayoutAttributeTableColumnModelBase::index
QModelIndex index(int row, int column, const QModelIndex &parent) const override
Definition: qgslayoutattributeselectiondialog.cpp:47
QgsFieldExpressionWidget::setField
void setField(const QString &fieldName)
sets the current field or expression in the widget
Definition: qgsfieldexpressionwidget.cpp:188
QgsLayoutAttributeTableColumnModelBase::rowCount
int rowCount(const QModelIndex &parent=QModelIndex()) const override
Definition: qgslayoutattributeselectiondialog.cpp:66
qgsvectorlayer.h
QgsLayoutAttributeTableColumnModelBase::headerData
QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override
Definition: qgslayoutattributeselectiondialog.cpp:182
QgsLayoutTableColumn::setVAlignment
void setVAlignment(Qt::AlignmentFlag alignment)
Sets the vertical alignment for a column, which controls the alignment used for drawing column values...
Definition: qgslayouttablecolumn.h:132
QgsLayoutObject::createExpressionContext
QgsExpressionContext createExpressionContext() const override
Creates an expression context relating to the objects' current state.
Definition: qgslayoutobject.cpp:246
QgsLayoutTableColumn::setHeading
void setHeading(const QString &heading)
Sets the heading for a column, which is the value displayed in the column's header cell.
Definition: qgslayouttablecolumn.h:100
QgsLayoutAttributeTableColumnModelBase::ShiftDown
@ ShiftDown
Shift the row/column down.
Definition: qgslayoutattributeselectiondialog.h:65
QgsDoubleSpinBox::setSpecialValueText
void setSpecialValueText(const QString &txt)
Set the special-value text to be txt If set, the spin box will display this text instead of a numeric...
Definition: qgsdoublespinbox.cpp:172
QgsLayoutTableColumn::setWidth
void setWidth(const double width)
Sets the width for a column in mm.
Definition: qgslayouttablecolumn.h:86
QgsLayoutTableColumn::hAlignment
Qt::AlignmentFlag hAlignment() const
Returns the horizontal alignment for a column, which controls the alignment used for drawing column v...
Definition: qgslayouttablecolumn.h:108
QgsLayoutColumnWidthDelegate::updateEditorGeometry
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override
Definition: qgslayoutattributeselectiondialog.cpp:588
QgsLayoutColumnAlignmentDelegate::setModelData
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override
Definition: qgslayoutattributeselectiondialog.cpp:402
QgsLayoutTableColumn::setSortOrder
void setSortOrder(Qt::SortOrder order)
Sets the sort order for the column.
Definition: qgslayouttablecolumn.h:166
QgsLayoutColumnSourceDelegate::QgsLayoutColumnSourceDelegate
QgsLayoutColumnSourceDelegate(QgsVectorLayer *vlayer, QObject *parent=nullptr, const QgsLayoutObject *layoutObject=nullptr, bool forceExpressions=false)
Constructor for QgsLayoutColumnSourceDelegate.
Definition: qgslayoutattributeselectiondialog.cpp:418
QgsHelp::openHelp
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
Definition: qgshelp.cpp:36
QgsVectorLayer
Represents a vector layer which manages a vector based data sets.
Definition: qgsvectorlayer.h:391
QgsLayoutColumnSourceDelegate::updateEditorGeometry
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override
Definition: qgslayoutattributeselectiondialog.cpp:471
qgslayouttablecolumn.h
qgssettings.h
QgsLayoutColumnWidthDelegate::QgsLayoutColumnWidthDelegate
QgsLayoutColumnWidthDelegate(QObject *parent=nullptr)
constructor
Definition: qgslayoutattributeselectiondialog.cpp:551
QgsLayoutAttributeTableColumnModelBase::ShiftDirection
ShiftDirection
Controls whether a row/column is shifted up or down.
Definition: qgslayoutattributeselectiondialog.h:62
QgsDoubleSpinBox
The QgsSpinBox is a spin box with a clear button that will set the value to the defined clear value....
Definition: qgsdoublespinbox.h:42
QgsExpressionContext::setHighlightedVariables
void setHighlightedVariables(const QStringList &variableNames)
Sets the list of variable names within the context intended to be highlighted to the user.
Definition: qgsexpressioncontext.cpp:328
QgsLayoutColumnWidthDelegate
A delegate for showing column width as a spin box.
Definition: qgslayoutattributeselectiondialog.h:245
QgsLayoutAttributeTableColumnModel
A model for displaying columns shown in a QgsLayoutAttributeTable.
Definition: qgslayoutattributeselectiondialog.h:125
qgsfieldexpressionwidget.h
QgsLayoutColumnSortOrderDelegate::updateEditorGeometry
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override
Definition: qgslayoutattributeselectiondialog.cpp:540
QgsLayoutColumnWidthDelegate::createEditor
QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override
Definition: qgslayoutattributeselectiondialog.cpp:557
QgsLayoutAttributeTableColumnModelBase::SortOrder
@ SortOrder
Defines the sort order.
Definition: qgslayoutattributeselectiondialog.h:77
QgsLayoutTableColumn
Stores properties of a column for a QgsLayoutTable.
Definition: qgslayouttablecolumn.h:37
QgsLayoutColumnAlignmentDelegate::setEditorData
void setEditorData(QWidget *editor, const QModelIndex &index) const override
Definition: qgslayoutattributeselectiondialog.cpp:393
QgsExpressionContextScope::StaticVariable
Single variable definition for use within a QgsExpressionContextScope.
Definition: qgsexpressioncontext.h:120
QgsLayoutAttributeTableColumnModelBase::data
QVariant data(const QModelIndex &index, int role) const override
Definition: qgslayoutattributeselectiondialog.cpp:80
QgsFieldExpressionWidget
The QgsFieldExpressionWidget class reates a widget to choose fields and edit expressions It contains ...
Definition: qgsfieldexpressionwidget.h:46
QgsFieldExpressionWidget::setLayer
void setLayer(QgsMapLayer *layer)
Sets the layer used to display the fields and expression.
Definition: qgsfieldexpressionwidget.cpp:170
QgsLayoutAttributeTableColumnModelBase::mTable
QgsLayoutItemAttributeTable * mTable
Definition: qgslayoutattributeselectiondialog.h:114
qgshelp.h
QgsLayoutItemAttributeTable::resetColumns
void resetColumns()
Resets the attribute table's columns to match the vector layer's fields.
Definition: qgslayoutitemattributetable.cpp:168
QgsLayoutObject
A base class for objects which belong to a layout.
Definition: qgslayoutobject.h:39
QgsLayoutColumnAlignmentDelegate
A delegate for showing column alignment as a combo box.
Definition: qgslayoutattributeselectiondialog.h:191
QgsLayoutAttributeSelectionDialog::QgsLayoutAttributeSelectionDialog
QgsLayoutAttributeSelectionDialog(QgsLayoutItemAttributeTable *table, QgsVectorLayer *vLayer, QWidget *parent=nullptr, Qt::WindowFlags f=Qt::WindowFlags())
constructor
Definition: qgslayoutattributeselectiondialog.cpp:597
QgsLayoutAttributeTableColumnModel::columns
QVector< QgsLayoutTableColumn > & columns() const override
To be reimplemented to provide the display or the sort columns.
Definition: qgslayoutattributeselectiondialog.cpp:342