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