QGIS API Documentation 3.99.0-Master (2fe06baccd8)
Loading...
Searching...
No Matches
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
18#include "qgsgui.h"
19
20#include <QLineEdit>
21#include <QPushButton>
22#include <QStandardItem>
23#include <QStandardItemModel>
24#include <QToolButton>
25
26#include "moc_qgsprocessingmatrixparameterdialog.cpp"
27
29
30QgsProcessingMatrixParameterPanelWidget::QgsProcessingMatrixParameterPanelWidget( QWidget *parent, const QgsProcessingParameterMatrix *param, const QVariantList &initialTable )
31 : QgsPanelWidget( parent )
32 , mParam( param )
33{
34 setupUi( this );
35
37
38 mTblView->setSelectionBehavior( QAbstractItemView::SelectRows );
39 mTblView->setSelectionMode( QAbstractItemView::ExtendedSelection );
40
41 mButtonAdd = new QPushButton( tr( "Add Row" ) );
42 mButtonBox->addButton( mButtonAdd, QDialogButtonBox::ActionRole );
43
44 mButtonRemove = new QPushButton( tr( "Remove Row(s)" ) );
45 mButtonBox->addButton( mButtonRemove, QDialogButtonBox::ActionRole );
46
47 mButtonRemoveAll = new QPushButton( tr( "Remove All" ) );
48 mButtonBox->addButton( mButtonRemoveAll, QDialogButtonBox::ActionRole );
49
50 connect( mButtonBox->button( QDialogButtonBox::Ok ), &QPushButton::clicked, this, &QgsPanelWidget::acceptPanel );
51 connect( mButtonBox->button( QDialogButtonBox::Cancel ), &QPushButton::clicked, this, [this] {
52 mWasCanceled = true;
53 acceptPanel();
54 } );
55 connect( this, &QgsPanelWidget::panelAccepted, this, [this]() {
56 // save any current cell edits
57 mTblView->setCurrentIndex( QModelIndex() );
58
59 if ( !mWasCanceled )
60 emit widgetChanged();
61 } );
62
63 connect( mButtonAdd, &QPushButton::clicked, this, &QgsProcessingMatrixParameterPanelWidget::addRow );
64 connect( mButtonRemove, &QPushButton::clicked, this, &QgsProcessingMatrixParameterPanelWidget::deleteRow );
65 connect( mButtonRemoveAll, &QPushButton::clicked, this, &QgsProcessingMatrixParameterPanelWidget::deleteAllRows );
66
67 if ( param && param->hasFixedNumberRows() )
68 {
69 mButtonAdd->setEnabled( false );
70 mButtonRemove->setEnabled( false );
71 mButtonRemoveAll->setEnabled( false );
72 }
73
74 populateTable( initialTable );
75}
76
77QVariantList QgsProcessingMatrixParameterPanelWidget::table() const
78{
79 const int cols = mModel->columnCount();
80 const int rows = mModel->rowCount();
81 // Table MUST BE 1-dimensional to match core QgsProcessingParameterMatrix expectations
82 QVariantList res;
83 res.reserve( cols * rows );
84 for ( int row = 0; row < rows; ++row )
85 {
86 for ( int col = 0; col < cols; ++col )
87 {
88 res << mModel->item( row, col )->text();
89 }
90 }
91 return res;
92}
93
94void QgsProcessingMatrixParameterPanelWidget::addRow()
95{
96 QList<QStandardItem *> items;
97 for ( int i = 0; i < mTblView->model()->columnCount(); ++i )
98 {
99 items << new QStandardItem( '0' );
100 }
101 mModel->appendRow( items );
102}
103
104void QgsProcessingMatrixParameterPanelWidget::deleteRow()
105{
106 QModelIndexList selected = mTblView->selectionModel()->selectedRows();
107 QSet<int> rows;
108 rows.reserve( selected.count() );
109 for ( const QModelIndex &i : selected )
110 rows << i.row();
111
112 QList<int> rowsToDelete = qgis::setToList( rows );
113 std::sort( rowsToDelete.begin(), rowsToDelete.end(), std::greater<int>() );
114 mTblView->setUpdatesEnabled( false );
115 for ( int i : std::as_const( rowsToDelete ) )
116 mModel->removeRows( i, 1 );
117
118 mTblView->setUpdatesEnabled( true );
119}
120
121void QgsProcessingMatrixParameterPanelWidget::deleteAllRows()
122{
123 mModel->clear();
124 if ( mParam )
125 mModel->setHorizontalHeaderLabels( mParam->headers() );
126}
127
128void QgsProcessingMatrixParameterPanelWidget::populateTable( const QVariantList &contents )
129{
130 if ( !mParam )
131 return;
132
133 const int cols = mParam->headers().count();
134 const int rows = contents.length() / cols;
135 mModel = new QStandardItemModel( rows, cols, this );
136 mModel->setHorizontalHeaderLabels( mParam->headers() );
137
138 for ( int row = 0; row < rows; ++row )
139 {
140 for ( int col = 0; col < cols; ++col )
141 {
142 QStandardItem *item = new QStandardItem( contents.at( row * cols + col ).toString() );
143 mModel->setItem( row, col, item );
144 }
145 }
146 mTblView->setModel( mModel );
147}
148
149//
150// QgsProcessingMatrixParameterPanel
151//
152
153QgsProcessingMatrixParameterPanel::QgsProcessingMatrixParameterPanel( QWidget *parent, const QgsProcessingParameterMatrix *param )
154 : QWidget( parent )
155 , mParam( param )
156{
157 QHBoxLayout *hl = new QHBoxLayout();
158 hl->setContentsMargins( 0, 0, 0, 0 );
159
160 mLineEdit = new QLineEdit();
161 mLineEdit->setEnabled( false );
162 hl->addWidget( mLineEdit, 1 );
163
164 mToolButton = new QToolButton();
165 mToolButton->setText( QString( QChar( 0x2026 ) ) );
166 hl->addWidget( mToolButton );
167
168 setLayout( hl );
169
170 if ( mParam )
171 {
172 for ( int row = 0; row < mParam->numberRows(); ++row )
173 {
174 for ( int col = 0; col < mParam->headers().count(); ++col )
175 {
176 mTable.append( '0' );
177 }
178 }
179 mLineEdit->setText( tr( "Fixed table (%1x%2)" ).arg( mParam->numberRows() ).arg( mParam->headers().count() ) );
180 }
181
182 connect( mToolButton, &QToolButton::clicked, this, &QgsProcessingMatrixParameterPanel::showDialog );
183}
184
185QVariantList QgsProcessingMatrixParameterPanel::value() const
186{
187 // if editing widget is still open, use the value currently shown in that widget
188 if ( mPanelWidget )
189 return mPanelWidget->table();
190
191 return mTable;
192}
193
194void QgsProcessingMatrixParameterPanel::setValue( const QVariantList &value )
195{
196 mTable = value;
197 updateSummaryText();
198 emit changed();
199}
200
201void QgsProcessingMatrixParameterPanel::showDialog()
202{
203 if ( QgsPanelWidget *panel = QgsPanelWidget::findParentPanel( this ) )
204 {
205 mPanelWidget = new QgsProcessingMatrixParameterPanelWidget( this, mParam, mTable );
206
207 mPanelWidget->setPanelTitle( mParam->description() );
208
209 panel->openPanel( mPanelWidget );
210
211 connect( mPanelWidget, &QgsPanelWidget::widgetChanged, this, [this] {
212 setValue( mPanelWidget->table() );
213 } );
214 }
215}
216
217void QgsProcessingMatrixParameterPanel::updateSummaryText()
218{
219 if ( mParam )
220 mLineEdit->setText( tr( "Fixed table (%1x%2)" ).arg( mTable.count() / mParam->headers().count() ).arg( mParam->headers().count() ) );
221}
222
223
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:221
Base class for any widget that can be shown as an inline panel.
void panelAccepted(QgsPanelWidget *panel)
Emitted when the panel is accepted by the user.
void widgetChanged()
Emitted when the widget state changes.
void acceptPanel()
Accept the panel.
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.