QGIS API Documentation 3.28.0-Firenze (ed3ad0430f)
qgsprocessingmatrixparameterdialog.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsprocessingmatrixparameterdialog.cpp
3 ------------------------------------
4 Date : February 2019
5 Copyright : (C) 2019 Nyall Dawson
6 Email : nyall dot dawson at gmail dot com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
17#include "qgsgui.h"
18#include <QStandardItemModel>
19#include <QStandardItem>
20#include <QPushButton>
21#include <QLineEdit>
22#include <QToolButton>
23
25
26QgsProcessingMatrixParameterPanelWidget::QgsProcessingMatrixParameterPanelWidget( QWidget *parent, const QgsProcessingParameterMatrix *param, const QVariantList &initialTable )
27 : QgsPanelWidget( parent )
28 , mParam( param )
29{
30 setupUi( this );
31
33
34 mTblView->setSelectionBehavior( QAbstractItemView::SelectRows );
35 mTblView->setSelectionMode( QAbstractItemView::ExtendedSelection );
36
37 mButtonAdd = new QPushButton( tr( "Add Row" ) );
38 mButtonBox->addButton( mButtonAdd, QDialogButtonBox::ActionRole );
39
40 mButtonRemove = new QPushButton( tr( "Remove Row(s)" ) );
41 mButtonBox->addButton( mButtonRemove, QDialogButtonBox::ActionRole );
42
43 mButtonRemoveAll = new QPushButton( tr( "Remove All" ) );
44 mButtonBox->addButton( mButtonRemoveAll, QDialogButtonBox::ActionRole );
45
46 connect( mButtonBox->button( QDialogButtonBox::Ok ), &QPushButton::clicked, this, [ = ]
47 {
48 emit widgetChanged();
49 acceptPanel();
50 } );
51 connect( mButtonBox->button( QDialogButtonBox::Cancel ), &QPushButton::clicked, this, [ = ]
52 {
53 acceptPanel();
54 } );
55
56 connect( mButtonAdd, &QPushButton::clicked, this, &QgsProcessingMatrixParameterPanelWidget::addRow );
57 connect( mButtonRemove, &QPushButton::clicked, this, &QgsProcessingMatrixParameterPanelWidget::deleteRow );
58 connect( mButtonRemoveAll, &QPushButton::clicked, this, &QgsProcessingMatrixParameterPanelWidget::deleteAllRows );
59
60 if ( param && param->hasFixedNumberRows() )
61 {
62 mButtonAdd->setEnabled( false );
63 mButtonRemove->setEnabled( false );
64 mButtonRemoveAll->setEnabled( false );
65 }
66
67 populateTable( initialTable );
68}
69
70QVariantList QgsProcessingMatrixParameterPanelWidget::table() const
71{
72 const int cols = mModel->columnCount();
73 const int rows = mModel->rowCount();
74 // Table MUST BE 1-dimensional to match core QgsProcessingParameterMatrix expectations
75 QVariantList res;
76 res.reserve( cols * rows );
77 for ( int row = 0; row < rows; ++row )
78 {
79 for ( int col = 0; col < cols; ++col )
80 {
81 res << mModel->item( row, col )->text();
82 }
83 }
84 return res;
85}
86
87void QgsProcessingMatrixParameterPanelWidget::addRow()
88{
89 QList< QStandardItem * > items;
90 for ( int i = 0; i < mTblView->model()->columnCount(); ++i )
91 {
92 items << new QStandardItem( '0' );
93 }
94 mModel->appendRow( items );
95}
96
97void QgsProcessingMatrixParameterPanelWidget::deleteRow()
98{
99 QModelIndexList selected = mTblView->selectionModel()->selectedRows();
100 QSet< int > rows;
101 rows.reserve( selected.count() );
102 for ( const QModelIndex &i : selected )
103 rows << i.row();
104
105 QList< int > rowsToDelete = qgis::setToList( rows );
106 std::sort( rowsToDelete.begin(), rowsToDelete.end(), std::greater<int>() );
107 mTblView->setUpdatesEnabled( false );
108 for ( int i : std::as_const( rowsToDelete ) )
109 mModel->removeRows( i, 1 );
110
111 mTblView->setUpdatesEnabled( true );
112}
113
114void QgsProcessingMatrixParameterPanelWidget::deleteAllRows()
115{
116 mModel->clear();
117 if ( mParam )
118 mModel->setHorizontalHeaderLabels( mParam->headers() );
119}
120
121void QgsProcessingMatrixParameterPanelWidget::populateTable( const QVariantList &contents )
122{
123 if ( !mParam )
124 return;
125
126 const int cols = mParam->headers().count();
127 const int rows = contents.length() / cols;
128 mModel = new QStandardItemModel( rows, cols, this );
129 mModel->setHorizontalHeaderLabels( mParam->headers() );
130
131 for ( int row = 0; row < rows; ++row )
132 {
133 for ( int col = 0; col < cols; ++col )
134 {
135 QStandardItem *item = new QStandardItem( contents.at( row * cols + col ).toString() );
136 mModel->setItem( row, col, item );
137 }
138 }
139 mTblView->setModel( mModel );
140}
141
142//
143// QgsProcessingMatrixParameterPanel
144//
145
146QgsProcessingMatrixParameterPanel::QgsProcessingMatrixParameterPanel( QWidget *parent, const QgsProcessingParameterMatrix *param )
147 : QWidget( parent )
148 , mParam( param )
149{
150 QHBoxLayout *hl = new QHBoxLayout();
151 hl->setContentsMargins( 0, 0, 0, 0 );
152
153 mLineEdit = new QLineEdit();
154 mLineEdit->setEnabled( false );
155 hl->addWidget( mLineEdit, 1 );
156
157 mToolButton = new QToolButton();
158 mToolButton->setText( QString( QChar( 0x2026 ) ) );
159 hl->addWidget( mToolButton );
160
161 setLayout( hl );
162
163 if ( mParam )
164 {
165 for ( int row = 0; row < mParam->numberRows(); ++row )
166 {
167 for ( int col = 0; col < mParam->headers().count(); ++col )
168 {
169 mTable.append( '0' );
170 }
171 }
172 mLineEdit->setText( tr( "Fixed table (%1x%2)" ).arg( mParam->numberRows() ).arg( mParam->headers().count() ) );
173 }
174
175 connect( mToolButton, &QToolButton::clicked, this, &QgsProcessingMatrixParameterPanel::showDialog );
176}
177
178void QgsProcessingMatrixParameterPanel::setValue( const QVariantList &value )
179{
180 mTable = value;
181 updateSummaryText();
182 emit changed();
183}
184
185void QgsProcessingMatrixParameterPanel::showDialog()
186{
187 if ( QgsPanelWidget *panel = QgsPanelWidget::findParentPanel( this ) )
188 {
189 QgsProcessingMatrixParameterPanelWidget *widget = new QgsProcessingMatrixParameterPanelWidget( this, mParam, mTable );
190
191 widget->setPanelTitle( mParam->description() );
192
193 panel->openPanel( widget );
194
195 connect( widget, &QgsPanelWidget::widgetChanged, this, [ = ]
196 {
197 setValue( widget->table() );
198 } );
199 }
200}
201
202void QgsProcessingMatrixParameterPanel::updateSummaryText()
203{
204 if ( mParam )
205 mLineEdit->setText( tr( "Fixed table (%1x%2)" ).arg( mTable.count() / mParam->headers().count() ).arg( mParam->headers().count() ) );
206}
207
208
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:178
Base class for any widget that can be shown as a inline panel.
void widgetChanged()
Emitted when the widget state changes.
static QgsPanelWidget * findParentPanel(QWidget *widget)
Traces through the parents of a widget to find if it is contained within a QgsPanelWidget widget.
A table (matrix) parameter for processing algorithms.
bool hasFixedNumberRows() const
Returns whether the table has a fixed number of rows.