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