29 #include <QDialogButtonBox> 30 #include <QGridLayout> 33 #include <QPushButton> 35 #include <QSortFilterProxyModel> 42 : QAbstractTableModel( parent )
49 if ( hasIndex( row, column, parent ) )
51 if ( ( mTable->
columns() )[row] )
53 return createIndex( row, column, ( mTable->
columns() )[row] );
67 if ( parent.isValid() )
70 return mTable->
columns().length();
81 if ( !index.isValid() ||
82 ( role != Qt::DisplayRole && role != Qt::EditRole && role != Qt::UserRole ) )
87 if ( index.row() >= mTable->
columns().length() )
99 if ( role == Qt::UserRole )
102 return qVariantFromValue( column );
105 switch ( index.column() )
113 if ( role == Qt::DisplayRole )
117 case Qt::AlignHCenter:
121 return tr(
"Top center" );
122 case Qt::AlignBottom:
123 return tr(
"Bottom center" );
125 return tr(
"Middle center" );
131 return tr(
"Top right" );
132 case Qt::AlignBottom:
133 return tr(
"Bottom right" );
135 return tr(
"Middle right" );
142 return tr(
"Top left" );
143 case Qt::AlignBottom:
144 return tr(
"Bottom left" );
146 return tr(
"Middle left" );
158 if ( role == Qt::DisplayRole )
160 return column->
width() <= 0 ? tr(
"Automatic" ) : QString( tr(
"%1 mm" ) ).arg( column->
width(), 0,
'f', 2 );
165 return column->
width();
181 if ( role == Qt::DisplayRole )
183 if ( orientation == Qt::Vertical )
185 return QVariant( section );
192 return QVariant( tr(
"Attribute" ) );
195 return QVariant( tr(
"Heading" ) );
198 return QVariant( tr(
"Alignment" ) );
201 return QVariant( tr(
"Width" ) );
216 if ( !index.isValid() || role != Qt::EditRole || !mTable )
220 if ( index.row() >= mTable->
columns().length() )
232 switch ( index.column() )
239 emit dataChanged( createIndex( index.row(), 1 ), createIndex( index.row(), 1 ) );
242 emit dataChanged( index, index );
246 emit dataChanged( index, index );
249 column->
setHAlignment( Qt::AlignmentFlag( value.toInt() & Qt::AlignHorizontal_Mask ) );
250 column->
setVAlignment( Qt::AlignmentFlag( value.toInt() & Qt::AlignVertical_Mask ) );
251 emit dataChanged( index, index );
254 column->
setWidth( value.toDouble() );
255 emit dataChanged( index, index );
266 Qt::ItemFlags
flags = QAbstractTableModel::flags( index );
268 if ( index.isValid() )
270 return flags | Qt::ItemIsEditable;
282 int maxRow = std::min( row + count - 1, mTable->
columns().length() - 1 );
283 beginRemoveRows( QModelIndex(), row, maxRow );
285 for (
int i = maxRow; i >= row; --i )
287 delete ( mTable->
columns() )[i];
288 mTable->
columns().removeAt( i );
297 beginInsertRows( QModelIndex(), row, row + count - 1 );
299 for (
int i = row; i < row + count; ++i )
302 mTable->
columns().insert( i, col );
310 if ( ( direction ==
ShiftUp && row <= 0 ) ||
318 int swapWithRow = direction ==
ShiftUp ? row - 1 : row + 1;
321 beginRemoveRows( QModelIndex(), swapWithRow, swapWithRow );
326 beginInsertRows( QModelIndex(), row, row );
327 mTable->
columns().insert( row, temp );
350 return QModelIndex();
353 int r = mTable->
columns().indexOf( column );
355 QModelIndex idx =
index( r, 0, QModelIndex() );
361 return QModelIndex();
366 if ( !column || !mTable )
373 for (
auto columnIt = mTable->
columns().constBegin(); columnIt != mTable->
columns().constEnd(); ++columnIt )
375 highestRank = std::max( highestRank, ( *columnIt )->sortByRank() );
382 emit dataChanged( idx, idx );
387 if ( !mTable || !column )
394 emit dataChanged( idx, idx );
404 if ( !mTable || !column )
416 QVector<QgsLayoutTableColumn *> sortedColumns;
420 if ( currentColumn->sortByRank() > 0 )
422 sortedColumns.append( currentColumn );
425 std::stable_sort( sortedColumns.begin(), sortedColumns.end(), columnsBySortRank );
426 int columnPos = sortedColumns.indexOf( column );
428 if ( ( columnPos == 0 && direction ==
ShiftUp )
429 || ( ( columnPos == sortedColumns.length() - 1 ) && direction ==
ShiftDown ) )
436 sortedColumns[ columnPos - 1]
437 : sortedColumns[ columnPos + 1];
444 emit dataChanged( idx, idx );
447 emit dataChanged( idxSwap, idxSwap );
457 : QSortFilterProxyModel( parent )
459 , mFilterType( filterType )
461 setDynamicSortFilter(
true );
467 QModelIndex index = sourceModel()->index( source_row, 0, source_parent );
490 QModelIndex sourceIndex = mapToSource( index );
497 QVariant columnAsVariant = sourceModel()->data( sourceIndex, Qt::UserRole );
525 if ( ( role != Qt::DisplayRole && role != Qt::EditRole ) || !index.isValid() )
536 switch ( index.column() )
541 if ( role == Qt::DisplayRole )
545 case Qt::DescendingOrder:
546 return tr(
"Descending" );
547 case Qt::AscendingOrder:
549 return tr(
"Ascending" );
570 if ( role == Qt::DisplayRole )
572 if ( orientation == Qt::Vertical )
574 return QVariant( section );
581 return QVariant( tr(
"Attribute" ) );
584 return QVariant( tr(
"Sort Order" ) );
599 Qt::ItemFlags
flags = QSortFilterProxyModel::flags( index );
601 if ( index.column() == 1 )
604 flags |= Qt::ItemIsEditable;
612 if ( !index.isValid() || role != Qt::EditRole )
626 if ( index.column() == 1 )
628 column->
setSortOrder( static_cast< Qt::SortOrder >( value.toInt() ) );
629 emit dataChanged( index, index );
638 QModelIndex proxyIndex = index( row, 0 );
661 QComboBox *comboBox =
new QComboBox( parent );
663 comboBox->addItem( tr(
"Top left" ),
int( Qt::AlignTop | Qt::AlignLeft ) );
664 comboBox->addItem( tr(
"Top center" ),
int( Qt::AlignTop | Qt::AlignHCenter ) );
665 comboBox->addItem( tr(
"Top right" ),
int( Qt::AlignTop | Qt::AlignRight ) );
666 comboBox->addItem( tr(
"Middle left" ),
int( Qt::AlignVCenter | Qt::AlignLeft ) );
667 comboBox->addItem( tr(
"Middle center" ),
int( Qt::AlignVCenter | Qt::AlignHCenter ) );
668 comboBox->addItem( tr(
"Middle right" ),
int( Qt::AlignVCenter | Qt::AlignRight ) );
669 comboBox->addItem( tr(
"Bottom left" ),
int( Qt::AlignBottom | Qt::AlignLeft ) );
670 comboBox->addItem( tr(
"Bottom center" ),
int( Qt::AlignBottom | Qt::AlignHCenter ) );
671 comboBox->addItem( tr(
"Bottom right" ),
int( Qt::AlignBottom | Qt::AlignRight ) );
673 Qt::AlignmentFlag alignment = ( Qt::AlignmentFlag )index.model()->data( index, Qt::EditRole ).toInt();
674 comboBox->setCurrentIndex( comboBox->findData( alignment ) );
681 Qt::AlignmentFlag alignment = ( Qt::AlignmentFlag )index.model()->data( index, Qt::EditRole ).toInt();
684 QComboBox *comboBox =
static_cast<QComboBox *
>( editor );
685 comboBox->setCurrentIndex( comboBox->findData( alignment ) );
690 QComboBox *comboBox =
static_cast<QComboBox *
>( editor );
691 Qt::AlignmentFlag alignment = ( Qt::AlignmentFlag ) comboBox->currentData().toInt();
692 model->setData( index, alignment, Qt::EditRole );
698 editor->setGeometry( option.rect );
705 : QItemDelegate( parent )
706 , mVectorLayer( vlayer )
707 , mLayoutObject( layoutObject )
714 if ( !mLayoutObject )
731 fieldExpression->
setLayer( mVectorLayer );
736 return fieldExpression;
741 QString field = index.model()->data( index, Qt::EditRole ).toString();
753 model->setData( index, field, Qt::EditRole );
759 editor->setGeometry( option.rect );
762 void QgsLayoutColumnSourceDelegate::commitAndCloseEditor()
765 emit commitData( fieldExpression );
781 QComboBox *comboBox =
new QComboBox( parent );
782 QStringList sortOrders;
783 sortOrders << tr(
"Ascending" ) << tr(
"Descending" );
784 comboBox->addItems( sortOrders );
790 Qt::SortOrder order = ( Qt::SortOrder )index.model()->data( index, Qt::EditRole ).toInt();
793 QComboBox *comboBox =
static_cast<QComboBox *
>( editor );
796 case Qt::DescendingOrder:
797 comboBox->setCurrentIndex( 1 );
799 case Qt::AscendingOrder:
801 comboBox->setCurrentIndex( 0 );
808 QComboBox *comboBox =
static_cast<QComboBox *
>( editor );
809 int value = comboBox->currentIndex();
814 order = Qt::DescendingOrder;
818 order = Qt::AscendingOrder;
822 model->setData( index, order, Qt::EditRole );
828 editor->setGeometry( option.rect );
837 : QItemDelegate( parent )
847 editor->setMinimum( 0 );
848 editor->setMaximum( 1000 );
849 editor->setDecimals( 2 );
850 editor->setSuffix( tr(
" mm" ) );
858 int value = index.model()->data( index, Qt::EditRole ).toInt();
861 spinBox->setValue( value );
867 spinBox->interpretText();
868 int value = spinBox->value();
870 model->setData( index, value, Qt::EditRole );
876 editor->setGeometry( option.rect );
883 QWidget *parent, Qt::WindowFlags f )
884 : QDialog( parent, f )
886 , mVectorLayer( vLayer )
892 connect( mRemoveColumnPushButton, &QPushButton::clicked,
this, &QgsLayoutAttributeSelectionDialog::mRemoveColumnPushButton_clicked );
893 connect( mAddColumnPushButton, &QPushButton::clicked,
this, &QgsLayoutAttributeSelectionDialog::mAddColumnPushButton_clicked );
894 connect( mColumnUpPushButton, &QPushButton::clicked,
this, &QgsLayoutAttributeSelectionDialog::mColumnUpPushButton_clicked );
895 connect( mColumnDownPushButton, &QPushButton::clicked,
this, &QgsLayoutAttributeSelectionDialog::mColumnDownPushButton_clicked );
896 connect( mResetColumnsPushButton, &QPushButton::clicked,
this, &QgsLayoutAttributeSelectionDialog::mResetColumnsPushButton_clicked );
897 connect( mClearColumnsPushButton, &QPushButton::clicked,
this, &QgsLayoutAttributeSelectionDialog::mClearColumnsPushButton_clicked );
898 connect( mAddSortColumnPushButton, &QPushButton::clicked,
this, &QgsLayoutAttributeSelectionDialog::mAddSortColumnPushButton_clicked );
899 connect( mRemoveSortColumnPushButton, &QPushButton::clicked,
this, &QgsLayoutAttributeSelectionDialog::mRemoveSortColumnPushButton_clicked );
900 connect( mSortColumnUpPushButton, &QPushButton::clicked,
this, &QgsLayoutAttributeSelectionDialog::mSortColumnUpPushButton_clicked );
901 connect( mSortColumnDownPushButton, &QPushButton::clicked,
this, &QgsLayoutAttributeSelectionDialog::mSortColumnDownPushButton_clicked );
902 connect( buttonBox, &QDialogButtonBox::helpRequested,
this, &QgsLayoutAttributeSelectionDialog::showHelp );
908 mColumnsTableView->setModel( mColumnModel );
909 mColumnsTableView->horizontalHeader()->setSectionResizeMode( QHeaderView::Stretch );
912 mColumnsTableView->setItemDelegateForColumn( 0, mColumnSourceDelegate );
914 mColumnsTableView->setItemDelegateForColumn( 2, mColumnAlignmentDelegate );
916 mColumnsTableView->setItemDelegateForColumn( 3, mColumnWidthDelegate );
919 mAvailableSortProxyModel->setSourceModel( mColumnModel );
920 mSortColumnComboBox->setModel( mAvailableSortProxyModel );
921 mSortColumnComboBox->setModelColumn( 0 );
924 mSortColumnTableView->setItemDelegateForColumn( 1, mColumnSortOrderDelegate );
927 mSortedProxyModel->setSourceModel( mColumnModel );
928 mSortedProxyModel->sort( 0, Qt::AscendingOrder );
929 mSortColumnTableView->setSortingEnabled(
false );
930 mSortColumnTableView->setModel( mSortedProxyModel );
931 mSortColumnTableView->horizontalHeader()->setSectionResizeMode( QHeaderView::Stretch );
934 mOrderComboBox->insertItem( 0, tr(
"Ascending" ) );
935 mOrderComboBox->insertItem( 1, tr(
"Descending" ) );
938 void QgsLayoutAttributeSelectionDialog::mRemoveColumnPushButton_clicked()
941 QModelIndexList indexes = mColumnsTableView->selectionModel()->selectedRows();
942 int count = indexes.count();
944 for (
int i = count; i > 0; --i )
945 mColumnModel->removeRow( indexes.at( i - 1 ).row(), QModelIndex() );
948 void QgsLayoutAttributeSelectionDialog::mAddColumnPushButton_clicked()
951 mColumnModel->insertRow( mColumnModel->
rowCount() );
954 void QgsLayoutAttributeSelectionDialog::mColumnUpPushButton_clicked()
958 QModelIndexList indexes = mColumnsTableView->selectionModel()->selectedRows();
959 int count = indexes.count();
961 std::reverse( indexes.begin(), indexes.end() );
962 for (
int i = count; i > 0; --i )
966 void QgsLayoutAttributeSelectionDialog::mColumnDownPushButton_clicked()
969 QModelIndexList indexes = mColumnsTableView->selectionModel()->selectedRows();
970 int count = indexes.count();
972 for (
int i = count; i > 0; --i )
976 void QgsLayoutAttributeSelectionDialog::mResetColumnsPushButton_clicked()
980 mSortColumnComboBox->setCurrentIndex( 0 );
983 void QgsLayoutAttributeSelectionDialog::mClearColumnsPushButton_clicked()
987 mSortColumnComboBox->setCurrentIndex( 0 );
990 void QgsLayoutAttributeSelectionDialog::mAddSortColumnPushButton_clicked()
999 mColumnModel->
setColumnAsSorted( column, mOrderComboBox->currentIndex() == 0 ? Qt::AscendingOrder : Qt::DescendingOrder );
1005 void QgsLayoutAttributeSelectionDialog::mRemoveSortColumnPushButton_clicked()
1008 QItemSelection sortSelection( mSortColumnTableView->selectionModel()->selection() );
1009 if ( sortSelection.length() < 1 )
1013 QModelIndex selectedIndex = sortSelection.indexes().at( 0 );
1014 int rowToRemove = selectedIndex.row();
1028 mSortColumnTableView->selectRow( rowToRemove );
1031 void QgsLayoutAttributeSelectionDialog::showHelp()
1033 QgsHelp::openHelp( QStringLiteral(
"print_composer/composer_items/composer_attribute_table.html" ) );
1036 void QgsLayoutAttributeSelectionDialog::mSortColumnUpPushButton_clicked()
1039 QItemSelection sortSelection( mSortColumnTableView->selectionModel()->selection() );
1040 if ( sortSelection.length() < 1 )
1044 QModelIndex selectedIndex = sortSelection.indexes().at( 0 );
1055 void QgsLayoutAttributeSelectionDialog::mSortColumnDownPushButton_clicked()
1058 QItemSelection sortSelection( mSortColumnTableView->selectionModel()->selection() );
1059 if ( sortSelection.length() < 1 )
1064 QModelIndex selectedIndex = sortSelection.indexes().at( 0 );
The QgsSpinBox is a spin box with a clear button that will set the value to the defined clear value...
bool moveRow(int row, ShiftDirection direction)
Moves the specified row up or down in the model.
QgsLayoutAttributeTableColumnModel(QgsLayoutItemAttributeTable *table, QObject *parent=nullptr)
Constructor for QgsLayoutAttributeTableColumnModel.
QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override
Single variable definition for use within a QgsExpressionContextScope.
bool moveColumnInSortRank(QgsLayoutTableColumn *column, ShiftDirection direction)
Moves a column up or down in the sort rank for the QgsLayoutItemAttributeTable.
void resetToLayer()
Resets the attribute table's columns to match the source layer's fields.
bool insertRows(int row, int count, const QModelIndex &parent=QModelIndex()) override
bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole) override
QgsExpressionContext createExpressionContext() const override
Creates an expression context relating to the objects' current state.
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override
Qt::ItemFlags flags(const QModelIndex &index) const override
ColumnFilterType
Controls whether the proxy model shows sorted or unsorted columns.
QgsLayoutColumnWidthDelegate(QObject *parent=nullptr)
constructor
QgsLayoutColumnSortOrderDelegate(QObject *parent=nullptr)
constructor
QgsLayoutTableColumn * columnFromIndex(const QModelIndex &index) const
Returns the QgsLayoutTableColumn corresponding to an index in the proxy model.
QModelIndex indexFromColumn(QgsLayoutTableColumn *column)
Returns a QModelIndex corresponding to a QgsLayoutTableColumn in the model.
void setShowClearButton(bool showClearButton)
Sets whether the widget will show a clear button.
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override
QVariant data(const QModelIndex &index, int role) const override
QVector< QgsLayoutTableColumn *> QgsLayoutTableColumns
List of column definitions for a QgsLayoutTable.
QgsLayoutTableColumn * columnFromIndex(const QModelIndex &index) const
Returns the QgsLayoutTableColumn corresponding to an index in the model.
void setHeading(const QString &heading)
Sets the heading for a column, which is the value displayed in the column's header cell...
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...
QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override
QVariant data(const QModelIndex &index, int role) const override
bool lessThan(const QModelIndex &left, const QModelIndex &right) const override
void addVariable(const QgsExpressionContextScope::StaticVariable &variable)
Adds a variable into the context scope.
A model for displaying columns shown in a QgsLayoutAttributeTable.
Show only unsorted columns.
Stores properties of a column for a QgsLayoutTable.
void setAttribute(const QString &attribute)
Sets the attribute name or expression used for the column's values.
void resetFilter()
Invalidates the current filter used by the proxy model.
A delegate for showing column alignment as a combo box.
QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override
void resetColumns()
Resets the attribute table's columns to match the vector layer's fields.
Qt::AlignmentFlag hAlignment() const
Returns the horizontal alignment for a column, which controls the alignment used for drawing column v...
QgsLayoutTableColumn * columnFromRow(int row)
Returns the QgsLayoutTableColumn corresponding to a row in the proxy model.
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override
Qt::AlignmentFlag vAlignment() const
Returns the vertical alignment for a column, which controls the alignment used for drawing column val...
int sortByRank() const
Returns the sort rank for the column.
A delegate for showing column attribute source as a QgsFieldExpressionWidget.
QgsExpressionContextScope * lastScope()
Returns the last scope added to the context.
int columnCount(const QModelIndex &parent=QModelIndex()) const override
QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override
ShiftDirection
Controls whether a row/column is shifted up or down.
void setEditorData(QWidget *editor, const QModelIndex &index) const override
void setHAlignment(Qt::AlignmentFlag alignment)
Sets the horizontal alignment for a column, which controls the alignment used for drawing column valu...
void setSortByRank(int rank)
Sets the sort rank for the column.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override
double width() const
Returns the width for the column in mm, or 0 if column width is automatically calculated.
A layout table subclass that displays attributes from a vector layer.
void setColumnAsUnsorted(QgsLayoutTableColumn *column)
Sets a specified column as an unsorted column in the QgsLayoutItemAttributeTable. ...
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override
Allows for filtering QgsComposerAttributeTable columns by columns which are sorted or unsorted...
Qt::ItemFlags flags(const QModelIndex &index) const override
Shift the row/column down.
QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override
Qt::SortOrder sortOrder() const
Returns the sort order for the column.
QModelIndex index(int row, int column, const QModelIndex &parent) const override
A delegate for showing column sort order as a combo box.
QModelIndex parent(const QModelIndex &child) const override
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override
A delegate for showing column width as a spin box.
bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole) override
Show only sorted columns.
int columnCount(const QModelIndex &parent=QModelIndex()) const override
QgsLayoutColumnAlignmentDelegate(QObject *parent=nullptr)
constructor
void setEditorData(QWidget *editor, const QModelIndex &index) const override
QgsLayoutAttributeSelectionDialog(QgsLayoutItemAttributeTable *table, QgsVectorLayer *vLayer, QWidget *parent=nullptr, Qt::WindowFlags f=nullptr)
constructor
void setWidth(const double width)
Sets the width for a column in mm.
QgsLayoutTableSortColumnsProxyModel(QgsLayoutItemAttributeTable *table, ColumnFilterType filterType, QObject *parent=nullptr)
Constructor for QgsLayoutTableSortColumnsProxyModel.
void setEditorData(QWidget *editor, const QModelIndex &index) const override
void setColumnAsSorted(QgsLayoutTableColumn *column, Qt::SortOrder order)
Sets a specified column as a sorted column in the QgsLayoutItemAttributeTable.
QString attribute() const
Returns the attribute name or expression used for the column's values.
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...
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override
A base class for objects which belong to a layout.
void setHighlightedVariables(const QStringList &variableNames)
Sets the list of variable names within the context intended to be highlighted to the user...
int rowCount(const QModelIndex &parent=QModelIndex()) const override
void setVAlignment(Qt::AlignmentFlag alignment)
Sets the vertical alignment for a column, which controls the alignment used for drawing column values...
QgsLayoutTableColumn * columnFromSourceIndex(const QModelIndex &sourceIndex) const
Returns the QgsLayoutTableColumn corresponding to an index from the source QgsLayoutItemAttributeTabl...
QgsLayoutColumnSourceDelegate(QgsVectorLayer *vlayer, QObject *parent=nullptr, const QgsLayoutObject *layoutObject=nullptr)
constructor
QgsLayoutTableColumns & columns()
Returns a reference to the list of QgsLayoutTableColumns shown in the table.
void setSortOrder(Qt::SortOrder order)
Sets the sort order for the column.
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override
Represents a vector layer which manages a vector based data sets.
void setEditorData(QWidget *editor, const QModelIndex &index) const override
QString heading() const
Returns the heading for a column, which is the value displayed in the column's header cell...
bool removeRows(int row, int count, const QModelIndex &parent=QModelIndex()) override
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override