QGIS API Documentation  3.14.0-Pi (9f7028fd23)
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 
26 QgsProcessingMatrixParameterPanelWidget::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 
70 QVariantList 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 
87 void 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 
97 void 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 : qgis::as_const( rowsToDelete ) )
109  mModel->removeRows( i, 1 );
110 
111  mTblView->setUpdatesEnabled( true );
112 }
113 
114 void QgsProcessingMatrixParameterPanelWidget::deleteAllRows()
115 {
116  mModel->clear();
117  if ( mParam )
118  mModel->setHorizontalHeaderLabels( mParam->headers() );
119 }
120 
121 void 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 
146 QgsProcessingMatrixParameterPanel::QgsProcessingMatrixParameterPanel( QWidget *parent, const QgsProcessingParameterMatrix *param )
147  : QWidget( parent )
148  , mParam( param )
149 {
150  QHBoxLayout *hl = new QHBoxLayout();
151  hl->setMargin( 0 );
152  hl->setContentsMargins( 0, 0, 0, 0 );
153 
154  mLineEdit = new QLineEdit();
155  mLineEdit->setEnabled( false );
156  hl->addWidget( mLineEdit, 1 );
157 
158  mToolButton = new QToolButton();
159  mToolButton->setText( QString( QChar( 0x2026 ) ) );
160  hl->addWidget( mToolButton );
161 
162  setLayout( hl );
163 
164  if ( mParam )
165  {
166  for ( int row = 0; row < mParam->numberRows(); ++row )
167  {
168  for ( int col = 0; col < mParam->headers().count(); ++col )
169  {
170  mTable.append( '0' );
171  }
172  }
173  mLineEdit->setText( tr( "Fixed table (%1x%2)" ).arg( mParam->numberRows() ).arg( mParam->headers().count() ) );
174  }
175 
176  connect( mToolButton, &QToolButton::clicked, this, &QgsProcessingMatrixParameterPanel::showDialog );
177 }
178 
179 void QgsProcessingMatrixParameterPanel::setValue( const QVariantList &value )
180 {
181  mTable = value;
182  updateSummaryText();
183  emit changed();
184 }
185 
186 void QgsProcessingMatrixParameterPanel::showDialog()
187 {
188  if ( QgsPanelWidget *panel = QgsPanelWidget::findParentPanel( this ) )
189  {
190  QgsProcessingMatrixParameterPanelWidget *widget = new QgsProcessingMatrixParameterPanelWidget( this, mParam, mTable );
191 
192  widget->setPanelTitle( mParam->description() );
193 
194  panel->openPanel( widget );
195 
196  connect( widget, &QgsPanelWidget::widgetChanged, this, [ = ]
197  {
198  setValue( widget->table() );
199  } );
200  }
201 }
202 
203 void QgsProcessingMatrixParameterPanel::updateSummaryText()
204 {
205  if ( mParam )
206  mLineEdit->setText( tr( "Fixed table (%1x%2)" ).arg( mTable.count() / mParam->headers().count() ).arg( mParam->headers().count() ) );
207 }
208 
209 
QgsProcessingParameterMatrix
Definition: qgsprocessingparameters.h:1670
QgsPanelWidget::findParentPanel
static QgsPanelWidget * findParentPanel(QWidget *widget)
Traces through the parents of a widget to find if it is contained within a QgsPanelWidget widget.
Definition: qgspanelwidget.cpp:49
qgsgui.h
QgsGui::enableAutoGeometryRestore
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:133
QgsPanelWidget
Base class for any widget that can be shown as a inline panel.
Definition: qgspanelwidget.h:29
QgsPanelWidget::widgetChanged
void widgetChanged()
Emitted when the widget state changes.
QgsProcessingParameterMatrix::hasFixedNumberRows
bool hasFixedNumberRows() const
Returns whether the table has a fixed number of rows.
Definition: qgsprocessingparameters.cpp:3029
qgsprocessingmatrixparameterdialog.h