Skip to content

Commit eeff02f

Browse files
committed
[processing] Port matrix widget wrapper to newer c++ API
Allows matrix parameters to be correctly set for model child algorithms Fixes #20914
1 parent c6f3d5f commit eeff02f

8 files changed

+598
-0
lines changed

src/gui/CMakeLists.txt

+2
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ SET(QGIS_GUI_SRCS
199199
processing/qgsprocessingalgorithmdialogbase.cpp
200200
processing/qgsprocessingconfigurationwidgets.cpp
201201
processing/qgsprocessingguiregistry.cpp
202+
processing/qgsprocessingmatrixparameterdialog.cpp
202203
processing/qgsprocessingmodelerparameterwidget.cpp
203204
processing/qgsprocessingrecentalgorithmlog.cpp
204205
processing/qgsprocessingtoolboxmodel.cpp
@@ -741,6 +742,7 @@ SET(QGIS_GUI_MOC_HDRS
741742
processing/qgsprocessingalgorithmconfigurationwidget.h
742743
processing/qgsprocessingalgorithmdialogbase.h
743744
processing/qgsprocessingconfigurationwidgets.h
745+
processing/qgsprocessingmatrixparameterdialog.h
744746
processing/qgsprocessingmodelerparameterwidget.h
745747
processing/qgsprocessingrecentalgorithmlog.h
746748
processing/qgsprocessingtoolboxmodel.h

src/gui/processing/qgsprocessingguiregistry.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ QgsProcessingGuiRegistry::QgsProcessingGuiRegistry()
3434
addParameterWidgetFactory( new QgsProcessingDistanceWidgetWrapper() );
3535
addParameterWidgetFactory( new QgsProcessingRangeWidgetWrapper() );
3636
addParameterWidgetFactory( new QgsProcessingAuthConfigWidgetWrapper() );
37+
addParameterWidgetFactory( new QgsProcessingMatrixWidgetWrapper() );
3738
}
3839

3940
QgsProcessingGuiRegistry::~QgsProcessingGuiRegistry()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
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+
16+
#include "qgsprocessingmatrixparameterdialog.h"
17+
#include "qgsgui.h"
18+
#include <QStandardItemModel>
19+
#include <QStandardItem>
20+
#include <QPushButton>
21+
#include <QLineEdit>
22+
#include <QToolButton>
23+
24+
///@cond NOT_STABLE
25+
26+
QgsProcessingMatrixParameterDialog::QgsProcessingMatrixParameterDialog( QWidget *parent, Qt::WindowFlags flags, const QgsProcessingParameterMatrix *param, const QVariantList &initialTable )
27+
: QDialog( parent, flags )
28+
, mParam( param )
29+
{
30+
setupUi( this );
31+
32+
QgsGui::enableAutoGeometryRestore( this );
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( mButtonAdd, &QPushButton::clicked, this, &QgsProcessingMatrixParameterDialog::addRow );
47+
connect( mButtonRemove, &QPushButton::clicked, this, &QgsProcessingMatrixParameterDialog::deleteRow );
48+
connect( mButtonRemoveAll, &QPushButton::clicked, this, &QgsProcessingMatrixParameterDialog::deleteAllRows );
49+
50+
if ( param && param->hasFixedNumberRows() )
51+
{
52+
mButtonAdd->setEnabled( false );
53+
mButtonRemove->setEnabled( false );
54+
mButtonRemoveAll->setEnabled( false );
55+
}
56+
57+
populateTable( initialTable );
58+
}
59+
60+
QVariantList QgsProcessingMatrixParameterDialog::table() const
61+
{
62+
const int cols = mModel->columnCount();
63+
const int rows = mModel->rowCount();
64+
// Table MUST BE 1-dimensional to match core QgsProcessingParameterMatrix expectations
65+
QVariantList res;
66+
res.reserve( cols * rows );
67+
for ( int row = 0; row < rows; ++row )
68+
{
69+
for ( int col = 0; col < cols; ++col )
70+
{
71+
res << mModel->item( row, col )->text();
72+
}
73+
}
74+
return res;
75+
}
76+
77+
void QgsProcessingMatrixParameterDialog::addRow()
78+
{
79+
QList< QStandardItem * > items;
80+
for ( int i = 0; i < mTblView->model()->columnCount(); ++i )
81+
{
82+
items << new QStandardItem( '0' );
83+
}
84+
mModel->appendRow( items );
85+
}
86+
87+
void QgsProcessingMatrixParameterDialog::deleteRow()
88+
{
89+
QModelIndexList selected = mTblView->selectionModel()->selectedRows();
90+
QSet< int > rows;
91+
rows.reserve( selected.count() );
92+
for ( const QModelIndex &i : selected )
93+
rows << i.row();
94+
95+
QList< int > rowsToDelete = rows.toList();
96+
std::sort( rowsToDelete.begin(), rowsToDelete.end(), std::greater<int>() );
97+
mTblView->setUpdatesEnabled( false );
98+
for ( int i : qgis::as_const( rowsToDelete ) )
99+
mModel->removeRows( i, 1 );
100+
101+
mTblView->setUpdatesEnabled( true );
102+
}
103+
104+
void QgsProcessingMatrixParameterDialog::deleteAllRows()
105+
{
106+
mModel->clear();
107+
if ( mParam )
108+
mModel->setHorizontalHeaderLabels( mParam->headers() );
109+
}
110+
111+
void QgsProcessingMatrixParameterDialog::populateTable( const QVariantList &contents )
112+
{
113+
if ( !mParam )
114+
return;
115+
116+
const int cols = mParam->headers().count();
117+
const int rows = contents.length() / cols;
118+
mModel = new QStandardItemModel( rows, cols, this );
119+
mModel->setHorizontalHeaderLabels( mParam->headers() );
120+
121+
for ( int row = 0; row < rows; ++row )
122+
{
123+
for ( int col = 0; col < cols; ++col )
124+
{
125+
QStandardItem *item = new QStandardItem( contents.at( row * cols + col ).toString() );
126+
mModel->setItem( row, col, item );
127+
}
128+
}
129+
mTblView->setModel( mModel );
130+
}
131+
132+
//
133+
// QgsProcessingMatrixParameterPanel
134+
//
135+
136+
QgsProcessingMatrixParameterPanel::QgsProcessingMatrixParameterPanel( QWidget *parent, const QgsProcessingParameterMatrix *param )
137+
: QWidget( parent )
138+
, mParam( param )
139+
{
140+
QHBoxLayout *hl = new QHBoxLayout();
141+
hl->setMargin( 0 );
142+
hl->setContentsMargins( 0, 0, 0, 0 );
143+
144+
mLineEdit = new QLineEdit();
145+
mLineEdit->setEnabled( false );
146+
hl->addWidget( mLineEdit, 1 );
147+
148+
mToolButton = new QToolButton();
149+
mToolButton->setText( tr( "" ) );
150+
hl->addWidget( mToolButton );
151+
152+
setLayout( hl );
153+
154+
if ( mParam )
155+
{
156+
for ( int row = 0; row < mParam->numberRows(); ++row )
157+
{
158+
for ( int col = 0; col < mParam->headers().count(); ++col )
159+
{
160+
mTable.append( '0' );
161+
}
162+
}
163+
mLineEdit->setText( tr( "Fixed table (%1x%2)" ).arg( mParam->numberRows() ).arg( mParam->headers().count() ) );
164+
}
165+
166+
connect( mToolButton, &QToolButton::clicked, this, &QgsProcessingMatrixParameterPanel::showDialog );
167+
}
168+
169+
void QgsProcessingMatrixParameterPanel::setValue( const QVariantList &value )
170+
{
171+
mTable = value;
172+
updateSummaryText();
173+
emit changed();
174+
}
175+
176+
void QgsProcessingMatrixParameterPanel::showDialog()
177+
{
178+
QgsProcessingMatrixParameterDialog dlg( this, nullptr, mParam, mTable );
179+
if ( dlg.exec() )
180+
{
181+
setValue( dlg.table() );
182+
}
183+
}
184+
185+
void QgsProcessingMatrixParameterPanel::updateSummaryText()
186+
{
187+
if ( mParam )
188+
mLineEdit->setText( tr( "Fixed table (%1x%2)" ).arg( mTable.count() / mParam->headers().count() ).arg( mParam->headers().count() ) );
189+
}
190+
191+
192+
///@endcond
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/***************************************************************************
2+
qgsprocessingmatrixparameterdialog.h
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+
16+
#ifndef QGSPROCESSINGMATRIXPARAMETERDIALOG_H
17+
#define QGSPROCESSINGMATRIXPARAMETERDIALOG_H
18+
19+
#include "qgis.h"
20+
#include "qgis_gui.h"
21+
#include "ui_qgsprocessingmatrixparameterdialogbase.h"
22+
#include "qgsprocessingparameters.h"
23+
24+
#define SIP_NO_FILE
25+
26+
class QStandardItemModel;
27+
class QToolButton;
28+
29+
///@cond NOT_STABLE
30+
31+
/**
32+
* \ingroup gui
33+
* \brief Dialog for configuration of a matrix (fixed table) parameter.
34+
* \note Not stable API
35+
* \since QGIS 3.6
36+
*/
37+
class GUI_EXPORT QgsProcessingMatrixParameterDialog : public QDialog, private Ui::QgsProcessingMatrixParameterDialogBase
38+
{
39+
Q_OBJECT
40+
41+
public:
42+
43+
/**
44+
* Constructor for QgsProcessingMatrixParameterDialog.
45+
*/
46+
QgsProcessingMatrixParameterDialog( QWidget *parent SIP_TRANSFERTHIS = nullptr, Qt::WindowFlags flags = nullptr, const QgsProcessingParameterMatrix *param = nullptr,
47+
const QVariantList &initialTable = QVariantList() );
48+
49+
/**
50+
* Returns the table's contents as a 1 dimensional array.
51+
*/
52+
QVariantList table() const;
53+
54+
private slots:
55+
56+
void addRow();
57+
void deleteRow();
58+
void deleteAllRows();
59+
60+
private:
61+
62+
QPushButton *mButtonAdd = nullptr;
63+
QPushButton *mButtonRemove = nullptr;
64+
QPushButton *mButtonRemoveAll = nullptr;
65+
const QgsProcessingParameterMatrix *mParam = nullptr;
66+
QStandardItemModel *mModel = nullptr;
67+
68+
void populateTable( const QVariantList &contents );
69+
70+
friend class TestProcessingGui;
71+
};
72+
73+
74+
/**
75+
* \ingroup gui
76+
* \brief Widget for configuration of a matrix (fixed table) parameter.
77+
* \note Not stable API
78+
* \since QGIS 3.6
79+
*/
80+
class GUI_EXPORT QgsProcessingMatrixParameterPanel : public QWidget
81+
{
82+
Q_OBJECT
83+
84+
public:
85+
86+
QgsProcessingMatrixParameterPanel( QWidget *parent = nullptr, const QgsProcessingParameterMatrix *param = nullptr );
87+
88+
QVariantList value() const { return mTable; }
89+
90+
void setValue( const QVariantList &value );
91+
92+
signals:
93+
94+
void changed();
95+
96+
private slots:
97+
98+
void showDialog();
99+
100+
private:
101+
102+
void updateSummaryText();
103+
104+
const QgsProcessingParameterMatrix *mParam = nullptr;
105+
QLineEdit *mLineEdit = nullptr;
106+
QToolButton *mToolButton = nullptr;
107+
108+
QVariantList mTable;
109+
110+
friend class TestProcessingGui;
111+
};
112+
113+
///@endcond
114+
115+
#endif // QGSPROCESSINGMATRIXPARAMETERDIALOG_H

0 commit comments

Comments
 (0)