QGIS API Documentation 4.1.0-Master (5bf3c20f3c9)
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
49
50QModelIndex QgsLayoutAttributeTableColumnModelBase::index( int row, int column, const QModelIndex &parent ) const
51{
52 if ( !hasIndex( row, column, parent ) )
53 return QModelIndex();
54
55 if ( !parent.isValid() )
56 {
57 return createIndex( row, column );
58 }
59
60 return QModelIndex();
61}
62
63QModelIndex QgsLayoutAttributeTableColumnModelBase::parent( const QModelIndex &child ) const
64{
65 Q_UNUSED( child )
66 return QModelIndex();
67}
68
70{
71 if ( parent.isValid() )
72 return 0;
73
74 return columns().length();
75}
76
78{
79 Q_UNUSED( parent )
80 return displayedColumns().count();
81}
82
83QVariant QgsLayoutAttributeTableColumnModelBase::data( const QModelIndex &index, int role ) const
84{
85 if ( !index.isValid() || ( role != Qt::DisplayRole && role != Qt::EditRole && role != Qt::UserRole ) )
86 {
87 return QVariant();
88 }
89
90 if ( index.row() >= columns().length() )
91 {
92 return QVariant();
93 }
94
95 // get layout column for index
96 const QgsLayoutTableColumn column = columns().value( index.row() );
97
98 const Column col = displayedColumns()[index.column()];
99 switch ( col )
100 {
101 case Attribute:
102 return column.attribute();
103 case Heading:
104 return column.heading();
105 case Alignment:
106 {
107 if ( role == Qt::DisplayRole )
108 {
109 switch ( column.hAlignment() )
110 {
111 case Qt::AlignHCenter:
112 switch ( column.vAlignment() )
113 {
114 case Qt::AlignTop:
115 return tr( "Top center" );
116 case Qt::AlignBottom:
117 return tr( "Bottom center" );
118 default:
119 return tr( "Middle center" );
120 }
121 case Qt::AlignRight:
122 switch ( column.vAlignment() )
123 {
124 case Qt::AlignTop:
125 return tr( "Top right" );
126 case Qt::AlignBottom:
127 return tr( "Bottom right" );
128 default:
129 return tr( "Middle right" );
130 }
131 case Qt::AlignLeft:
132 default:
133 switch ( column.vAlignment() )
134 {
135 case Qt::AlignTop:
136 return tr( "Top left" );
137 case Qt::AlignBottom:
138 return tr( "Bottom left" );
139 default:
140 return tr( "Middle left" );
141 }
142 }
143 }
144 else
145 {
146 //edit role
147 return int( column.hAlignment() | column.vAlignment() );
148 }
149 }
150 case Width:
151 {
152 if ( role == Qt::DisplayRole )
153 {
154 return column.width() <= 0 ? tr( "Automatic" ) : tr( "%L1 mm" ).arg( column.width(), 0, 'f', 2 );
155 }
156 else
157 {
158 //edit role
159 return column.width();
160 }
161 }
162 case SortOrder:
163 if ( role == Qt::DisplayRole )
164 {
165 switch ( column.sortOrder() )
166 {
167 case Qt::DescendingOrder:
168 return tr( "Descending" );
169 case Qt::AscendingOrder:
170 default:
171 return tr( "Ascending" );
172 }
173 }
174 else
175 {
176 //edit role
177 return column.sortOrder();
178 }
179 }
180
181 return QVariant();
182}
183
184QVariant QgsLayoutAttributeTableColumnModelBase::headerData( int section, Qt::Orientation orientation, int role ) const
185{
186 if ( !mTable )
187 {
188 return QVariant();
189 }
190
191 if ( role == Qt::DisplayRole )
192 {
193 if ( orientation == Qt::Vertical ) //row
194 {
195 return QVariant( section );
196 }
197 else
198 {
199 const Column col = displayedColumns()[section];
200 switch ( col )
201 {
202 case Attribute:
203 return QVariant( tr( "Attribute" ) );
204
205 case Heading:
206 return QVariant( tr( "Heading" ) );
207
208 case Alignment:
209 return QVariant( tr( "Alignment" ) );
210
211 case Width:
212 return QVariant( tr( "Width" ) );
213
214 case SortOrder:
215 return QVariant( tr( "Sort Order" ) );
216 }
217 }
218 }
219
220 return QVariant();
221}
222
223bool QgsLayoutAttributeTableColumnModelBase::setData( const QModelIndex &index, const QVariant &value, int role )
224{
225 if ( !index.isValid() || role != Qt::EditRole || !mTable )
226 return false;
227
228 if ( index.row() >= columns().length() )
229 return false;
230
231 if ( index.column() > displayedColumns().count() )
232 return false;
233
234 QgsLayoutTableColumn &colToUpdate = columns()[index.row()];
235
236 const Column col = displayedColumns()[index.column()];
237 switch ( col )
238 {
239 case Attribute:
240 // also update column's heading, if it hasn't been customized
241 if ( colToUpdate.heading().isEmpty() || ( colToUpdate.heading() == colToUpdate.attribute() ) )
242 {
243 colToUpdate.setHeading( value.toString() );
244 emit dataChanged( createIndex( index.row(), 1 ), createIndex( index.row(), 1 ) );
245 }
246 colToUpdate.setAttribute( value.toString() );
247 emit dataChanged( index, index );
248 return true;
249
250 case Heading:
251 colToUpdate.setHeading( value.toString() );
252 emit dataChanged( index, index );
253 return true;
254
255 case Alignment:
256 colToUpdate.setHAlignment( Qt::AlignmentFlag( value.toInt() & Qt::AlignHorizontal_Mask ) );
257 colToUpdate.setVAlignment( Qt::AlignmentFlag( value.toInt() & Qt::AlignVertical_Mask ) );
258 emit dataChanged( index, index );
259 return true;
260
261 case Width:
262 colToUpdate.setWidth( value.toDouble() );
263 emit dataChanged( index, index );
264 return true;
265
266 case SortOrder:
267 colToUpdate.setSortOrder( static_cast<Qt::SortOrder>( value.toInt() ) );
268 emit dataChanged( index, index );
269 return true;
270 }
271
272 return false;
273}
274
275Qt::ItemFlags QgsLayoutAttributeTableColumnModelBase::flags( const QModelIndex &index ) const
276{
277 Qt::ItemFlags flags = QAbstractTableModel::flags( index );
278
279 if ( index.isValid() )
280 {
281 return flags | Qt::ItemIsEditable;
282 }
283 else
284 {
285 return flags;
286 }
287}
288
289bool QgsLayoutAttributeTableColumnModelBase::removeRows( int row, int count, const QModelIndex &parent )
290{
291 Q_UNUSED( parent )
292
293 const int maxRow = std::min<int>( row + count - 1, columns().length() - 1 );
294 beginRemoveRows( QModelIndex(), row, maxRow );
295 //move backwards through rows, removing each corresponding QgsComposerTableColumn
296 for ( int i = maxRow; i >= row; --i )
297 {
298 columns().removeAt( i );
299 }
300 endRemoveRows();
301 return true;
302}
303
304bool QgsLayoutAttributeTableColumnModelBase::insertRows( int row, int count, const QModelIndex &parent )
305{
306 Q_UNUSED( parent )
307 beginInsertRows( QModelIndex(), row, row + count - 1 );
308 //create new QgsComposerTableColumns for each inserted row
309 for ( int i = row; i < row + count; ++i )
310 {
311 columns().insert( i, QgsLayoutTableColumn() );
312 }
313 endInsertRows();
314 return true;
315}
316
318{
319 if ( ( direction == ShiftUp && row <= 0 ) || ( direction == ShiftDown && row >= rowCount() - 1 ) )
320 {
321 //row is already at top/bottom
322 return false;
323 }
324
325 //we shift a row by removing the next row up/down, then reinserting it before/after the target row
326 const int swapWithRow = direction == ShiftUp ? row - 1 : row + 1;
327
328 //remove row
329 beginRemoveRows( QModelIndex(), swapWithRow, swapWithRow );
330 const QgsLayoutTableColumn temp = columns().takeAt( swapWithRow );
331 endRemoveRows();
332
333 //insert row
334 beginInsertRows( QModelIndex(), row, row );
335 columns().insert( row, temp );
336 endInsertRows();
337
338 return true;
339}
340
341// QgsLayoutAttributeTableColumnModel
342
343QVector<QgsLayoutTableColumn> &QgsLayoutAttributeTableColumnModel::columns() const
344{
345 return mTable->columns();
346}
347
349{
350 beginResetModel();
351 mTable->resetColumns();
352 endResetModel();
353}
354
355
356// QgsLayoutTableSortModel
357
358QVector<QgsLayoutTableColumn> &QgsLayoutTableSortModel::columns() const
359{
360 return mTable->sortColumns();
361}
362
363// QgsLayoutColumnAlignmentDelegate
364
366 : QItemDelegate( parent )
367{}
368
369QWidget *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
393void 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
402void 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
409void 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
418QgsLayoutColumnSourceDelegate::QgsLayoutColumnSourceDelegate( QgsVectorLayer *vlayer, QObject *parent, const QgsLayoutObject *layoutObject, bool forceExpressions )
419 : QItemDelegate( parent )
420 , mVectorLayer( vlayer )
421 , mLayoutObject( layoutObject )
422 , mForceExpressions( forceExpressions )
423{}
424
426{
427 if ( !mLayoutObject )
428 {
429 return QgsExpressionContext();
430 }
431
432 QgsExpressionContext expContext = mLayoutObject->createExpressionContext();
433 expContext.lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( u"row_number"_s, 1, true ) );
434 expContext.setHighlightedVariables( QStringList() << u"row_number"_s );
435 return expContext;
436}
437
438QWidget *QgsLayoutColumnSourceDelegate::createEditor( QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index ) const
439{
440 Q_UNUSED( option )
441 Q_UNUSED( index )
442
443 QgsFieldExpressionWidget *fieldExpression = new QgsFieldExpressionWidget( parent );
444 fieldExpression->setLayer( mVectorLayer );
445 fieldExpression->registerExpressionContextGenerator( this );
446
447 //listen out for field changes
448 connect( fieldExpression, static_cast<void ( QgsFieldExpressionWidget::* )( const QString & )>( &QgsFieldExpressionWidget::fieldChanged ), this, [this] {
449 const_cast<QgsLayoutColumnSourceDelegate *>( this )->commitAndCloseEditor();
450 } );
451 return fieldExpression;
452}
453
454void 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
463void 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
471void QgsLayoutColumnSourceDelegate::updateEditorGeometry( QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index ) const
472{
473 Q_UNUSED( index )
474 editor->setGeometry( option.rect );
475}
476
477void QgsLayoutColumnSourceDelegate::commitAndCloseEditor()
478{
479 QgsFieldExpressionWidget *fieldExpression = qobject_cast<QgsFieldExpressionWidget *>( sender() );
480 emit commitData( fieldExpression );
481}
482
483
484// QgsLayoutColumnSortOrderDelegate
485
487 : QItemDelegate( parent )
488{}
489
490QWidget *QgsLayoutColumnSortOrderDelegate::createEditor( QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index ) const
491{
492 Q_UNUSED( option )
493 Q_UNUSED( index )
494
495 QComboBox *comboBox = new QComboBox( parent );
496 QStringList sortOrders;
497 sortOrders << tr( "Ascending" ) << tr( "Descending" );
498 comboBox->addItems( sortOrders );
499 return comboBox;
500}
501
502void QgsLayoutColumnSortOrderDelegate::setEditorData( QWidget *editor, const QModelIndex &index ) const
503{
504 const Qt::SortOrder order = ( Qt::SortOrder ) index.model()->data( index, Qt::EditRole ).toInt();
505
506 //set the value for the combobox
507 QComboBox *comboBox = static_cast<QComboBox *>( editor );
508 switch ( order )
509 {
510 case Qt::DescendingOrder:
511 comboBox->setCurrentIndex( 1 );
512 break;
513 case Qt::AscendingOrder:
514 default:
515 comboBox->setCurrentIndex( 0 );
516 break;
517 }
518}
519
520void QgsLayoutColumnSortOrderDelegate::setModelData( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const
521{
522 QComboBox *comboBox = static_cast<QComboBox *>( editor );
523 const int value = comboBox->currentIndex();
524 Qt::SortOrder order;
525 switch ( value )
526 {
527 case 1:
528 order = Qt::DescendingOrder;
529 break;
530 case 0:
531 default:
532 order = Qt::AscendingOrder;
533 break;
534 }
535
536 model->setData( index, order, Qt::EditRole );
537}
538
539void QgsLayoutColumnSortOrderDelegate::updateEditorGeometry( QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index ) const
540{
541 Q_UNUSED( index )
542 editor->setGeometry( option.rect );
543}
544
545
546//
547// QgsLayoutColumnWidthDelegate
548//
549
551 : QItemDelegate( parent )
552{}
553
554QWidget *QgsLayoutColumnWidthDelegate::createEditor( QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index ) const
555{
556 Q_UNUSED( index )
557 Q_UNUSED( option )
558 QgsDoubleSpinBox *editor = new QgsDoubleSpinBox( parent );
559 editor->setMinimum( 0 );
560 editor->setMaximum( 1000 );
561 editor->setDecimals( 2 );
562 editor->setSuffix( tr( " mm" ) );
563 editor->setSpecialValueText( tr( "Automatic" ) );
564 editor->setShowClearButton( true );
565 return editor;
566}
567
568void QgsLayoutColumnWidthDelegate::setEditorData( QWidget *editor, const QModelIndex &index ) const
569{
570 const int value = index.model()->data( index, Qt::EditRole ).toInt();
571
572 QgsDoubleSpinBox *spinBox = static_cast<QgsDoubleSpinBox *>( editor );
573 spinBox->setValue( value );
574}
575
576void QgsLayoutColumnWidthDelegate::setModelData( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const
577{
578 QgsDoubleSpinBox *spinBox = static_cast<QgsDoubleSpinBox *>( editor );
579 spinBox->interpretText();
580 const int value = spinBox->value();
581
582 model->setData( index, value, Qt::EditRole );
583}
584
585void QgsLayoutColumnWidthDelegate::updateEditorGeometry( QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index ) const
586{
587 Q_UNUSED( index )
588 editor->setGeometry( option.rect );
589}
590
591
592// QgsLayoutAttributeSelectionDialog
593
595 : QDialog( parent, f )
596 , mTable( table )
597
598{
599 setupUi( this );
601
602 connect( mRemoveColumnPushButton, &QPushButton::clicked, this, &QgsLayoutAttributeSelectionDialog::mRemoveColumnPushButton_clicked );
603 connect( mAddColumnPushButton, &QPushButton::clicked, this, &QgsLayoutAttributeSelectionDialog::mAddColumnPushButton_clicked );
604 connect( mColumnUpPushButton, &QPushButton::clicked, this, &QgsLayoutAttributeSelectionDialog::mColumnUpPushButton_clicked );
605 connect( mColumnDownPushButton, &QPushButton::clicked, this, &QgsLayoutAttributeSelectionDialog::mColumnDownPushButton_clicked );
606 connect( mResetColumnsPushButton, &QPushButton::clicked, this, &QgsLayoutAttributeSelectionDialog::mResetColumnsPushButton_clicked );
607 connect( mClearColumnsPushButton, &QPushButton::clicked, this, &QgsLayoutAttributeSelectionDialog::mClearColumnsPushButton_clicked );
608 connect( mAddSortColumnPushButton, &QPushButton::clicked, this, &QgsLayoutAttributeSelectionDialog::mAddSortColumnPushButton_clicked );
609 connect( mRemoveSortColumnPushButton, &QPushButton::clicked, this, &QgsLayoutAttributeSelectionDialog::mRemoveSortColumnPushButton_clicked );
610 connect( mSortColumnUpPushButton, &QPushButton::clicked, this, &QgsLayoutAttributeSelectionDialog::mSortColumnUpPushButton_clicked );
611 connect( mSortColumnDownPushButton, &QPushButton::clicked, this, &QgsLayoutAttributeSelectionDialog::mSortColumnDownPushButton_clicked );
612 connect( buttonBox, &QDialogButtonBox::helpRequested, this, &QgsLayoutAttributeSelectionDialog::showHelp );
613
614 if ( mTable )
615 {
616 //set up models, views and delegates
617 mColumnModel = new QgsLayoutAttributeTableColumnModel( mTable, mColumnsTableView );
618 mColumnsTableView->setModel( mColumnModel );
619 mColumnsTableView->horizontalHeader()->setSectionResizeMode( QHeaderView::Stretch );
620 mColumnSourceDelegate = new QgsLayoutColumnSourceDelegate( vLayer, mColumnsTableView, mTable );
621 mColumnsTableView->setItemDelegateForColumn( 0, mColumnSourceDelegate );
622 mColumnAlignmentDelegate = new QgsLayoutColumnAlignmentDelegate( mColumnsTableView );
623 mColumnsTableView->setItemDelegateForColumn( 2, mColumnAlignmentDelegate );
624 mColumnWidthDelegate = new QgsLayoutColumnWidthDelegate( mColumnsTableView );
625 mColumnsTableView->setItemDelegateForColumn( 3, mColumnWidthDelegate );
626
627 mSortColumnModel = new QgsLayoutTableSortModel( mTable, mSortColumnTableView );
628 mSortColumnTableView->setModel( mSortColumnModel );
629 mSortColumnTableView->horizontalHeader()->setSectionResizeMode( QHeaderView::Stretch );
630 mSortColumnSourceDelegate = new QgsLayoutColumnSourceDelegate( vLayer, mSortColumnTableView, mTable, true );
631 mSortColumnTableView->setItemDelegateForColumn( 0, mSortColumnSourceDelegate );
632 mSortColumnOrderDelegate = new QgsLayoutColumnSortOrderDelegate( mSortColumnTableView );
633 mSortColumnTableView->setItemDelegateForColumn( 1, mSortColumnOrderDelegate );
634 }
635}
636
637void QgsLayoutAttributeSelectionDialog::mRemoveColumnPushButton_clicked()
638{
639 //remove selected rows from model
640 const QModelIndexList indexes = mColumnsTableView->selectionModel()->selectedRows();
641 const int count = indexes.count();
642
643 for ( int i = count; i > 0; --i )
644 mColumnModel->removeRow( indexes.at( i - 1 ).row(), QModelIndex() );
645}
646
647void QgsLayoutAttributeSelectionDialog::mAddColumnPushButton_clicked()
648{
649 //add a new row to the model
650 mColumnModel->insertRow( mColumnModel->rowCount() );
651}
652
653void QgsLayoutAttributeSelectionDialog::mColumnUpPushButton_clicked()
654{
655 //move selected row up
656
657 QModelIndexList indexes = mColumnsTableView->selectionModel()->selectedRows();
658 const int count = indexes.count();
659
660 std::reverse( indexes.begin(), indexes.end() );
661 for ( int i = count; i > 0; --i )
662 mColumnModel->moveRow( indexes.at( i - 1 ).row(), QgsLayoutAttributeTableColumnModelBase::ShiftUp );
663}
664
665void QgsLayoutAttributeSelectionDialog::mColumnDownPushButton_clicked()
666{
667 //move selected row down
668 const QModelIndexList indexes = mColumnsTableView->selectionModel()->selectedRows();
669 const int count = indexes.count();
670
671 for ( int i = count; i > 0; --i )
672 mColumnModel->moveRow( indexes.at( i - 1 ).row(), QgsLayoutAttributeTableColumnModelBase::ShiftDown );
673}
674
675void QgsLayoutAttributeSelectionDialog::mResetColumnsPushButton_clicked()
676{
677 //reset columns to match vector layer's fields
678 mColumnModel->resetToLayer();
679}
680
681void QgsLayoutAttributeSelectionDialog::mClearColumnsPushButton_clicked()
682{
683 //remove all columns
684 mColumnModel->removeRows( 0, mColumnModel->rowCount() );
685}
686
687void QgsLayoutAttributeSelectionDialog::mAddSortColumnPushButton_clicked()
688{
689 //add a new row to the model
690 mSortColumnModel->insertRow( mSortColumnModel->rowCount() );
691}
692
693void QgsLayoutAttributeSelectionDialog::mRemoveSortColumnPushButton_clicked()
694{
695 //remove selected rows from model
696 const QModelIndexList indexes = mSortColumnTableView->selectionModel()->selectedRows();
697 const int count = indexes.count();
698
699 for ( int i = count; i > 0; --i )
700 mSortColumnModel->removeRow( indexes.at( i - 1 ).row(), QModelIndex() );
701}
702
703void QgsLayoutAttributeSelectionDialog::showHelp()
704{
705 QgsHelp::openHelp( u"print_composer/composer_items/composer_attribute_table.html"_s );
706}
707
708void QgsLayoutAttributeSelectionDialog::mSortColumnDownPushButton_clicked()
709{
710 //move selected row down
711 const QModelIndexList indexes = mSortColumnTableView->selectionModel()->selectedRows();
712 const int count = indexes.count();
713
714 for ( int i = count; i > 0; --i )
715 mSortColumnModel->moveRow( indexes.at( i - 1 ).row(), QgsLayoutTableSortModel::ShiftDown );
716}
717
718void QgsLayoutAttributeSelectionDialog::mSortColumnUpPushButton_clicked()
719{
720 //move selected row up
721 const QModelIndexList indexes = mSortColumnTableView->selectionModel()->selectedRows();
722 const int count = indexes.count();
723
724 for ( int i = count; i > 0; --i )
725 mSortColumnModel->moveRow( indexes.at( i - 1 ).row(), QgsLayoutTableSortModel::ShiftUp );
726}
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.