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