QGIS API Documentation  3.6.0-Noosa (5873452)
qgsprocessingconfigurationwidgets.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsprocessingconfigurationwidgets.cpp
3  ---------------------
4  begin : April 2018
5  copyright : (C) 2018 by Matthias Kuhn
6  email : [email protected]
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
18 
20 #include "qgsprocessingalgorithm.h"
21 #include "qgsexpressionlineedit.h"
22 #include "qgsapplication.h"
23 #include "qgsgui.h"
25 
26 #include <QTableWidget>
27 #include <QGridLayout>
28 #include <QToolButton>
29 #include <QLabel>
30 #include <QCheckBox>
31 #include <QHeaderView>
32 
34 
35 QgsFilterAlgorithmConfigurationWidget::QgsFilterAlgorithmConfigurationWidget( QWidget *parent )
37 {
38  setContentsMargins( 0, 0, 0, 0 );
39 
40  mOutputExpressionWidget = new QTableWidget();
41  mOutputExpressionWidget->setColumnCount( 3 );
42  mOutputExpressionWidget->setHorizontalHeaderItem( 0, new QTableWidgetItem( tr( "Output Name" ) ) );
43  mOutputExpressionWidget->setHorizontalHeaderItem( 1, new QTableWidgetItem( tr( "Filter Expression" ) ) );
44  mOutputExpressionWidget->setHorizontalHeaderItem( 2, new QTableWidgetItem( tr( "Final Output" ) ) );
45  mOutputExpressionWidget->horizontalHeader()->setResizeMode( 1, QHeaderView::Stretch );
46  QGridLayout *layout = new QGridLayout();
47  setLayout( layout );
48 
49  layout->addWidget( new QLabel( tr( "Outputs and filters" ) ), 0, 0, 1, 2 );
50  layout->addWidget( mOutputExpressionWidget, 1, 0, 4, 1 );
51  QToolButton *addOutputButton = new QToolButton();
52  addOutputButton->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddLayer.svg" ) ) );
53  addOutputButton->setText( tr( "Add Output" ) );
54 
55  QToolButton *removeOutputButton = new QToolButton();
56  removeOutputButton->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionRemoveLayer.svg" ) ) );
57  removeOutputButton->setToolTip( tr( "Remove Selected Outputs" ) );
58 
59  layout->addWidget( addOutputButton, 2, 1, 1, 1 );
60  layout->addWidget( removeOutputButton, 3, 1, 1, 1 );
61 
62  connect( addOutputButton, &QToolButton::clicked, this, &QgsFilterAlgorithmConfigurationWidget::addOutput );
63  connect( removeOutputButton, &QToolButton::clicked, this, &QgsFilterAlgorithmConfigurationWidget::removeSelectedOutputs );
64 
65  connect( mOutputExpressionWidget->selectionModel(), &QItemSelectionModel::selectionChanged, this, [removeOutputButton, this]
66  {
67  removeOutputButton->setEnabled( !mOutputExpressionWidget->selectionModel()->selectedIndexes().isEmpty() );
68  } );
69 }
70 
71 QVariantMap QgsFilterAlgorithmConfigurationWidget::configuration() const
72 {
73  QVariantList outputs;
74 
75  for ( int i = 0; i < mOutputExpressionWidget->rowCount(); ++i )
76  {
77  QVariantMap output;
78  output.insert( QStringLiteral( "name" ), mOutputExpressionWidget->item( i, 0 )->text() );
79  output.insert( QStringLiteral( "expression" ), qobject_cast<QgsExpressionLineEdit *>( mOutputExpressionWidget->cellWidget( i, 1 ) )->expression() );
80  output.insert( QStringLiteral( "isModelOutput" ), qobject_cast<QCheckBox *>( mOutputExpressionWidget->cellWidget( i, 2 ) )->isChecked() );
81  outputs.append( output );
82  }
83 
84  QVariantMap map;
85  map.insert( "outputs", outputs );
86 
87  return map;
88 }
89 
90 
91 void QgsFilterAlgorithmConfigurationWidget::setConfiguration( const QVariantMap &configuration )
92 {
93  mOutputExpressionWidget->setRowCount( 0 );
94  int currentRow = 0;
95  const QVariantList outputs = configuration.value( "outputs" ).toList();
96 
97  for ( const QVariant &outputvar : outputs )
98  {
99  const QVariantMap output = outputvar.toMap();
100  mOutputExpressionWidget->insertRow( currentRow );
101  mOutputExpressionWidget->setItem( currentRow, 0, new QTableWidgetItem( output.value( "name" ).toString() ) );
102  QgsExpressionLineEdit *expressionBuilder = new QgsExpressionLineEdit();
103  expressionBuilder->registerExpressionContextGenerator( this );
104  expressionBuilder->setExpression( output.value( "expression" ).toString() );
105  mOutputExpressionWidget->setCellWidget( currentRow, 1, expressionBuilder );
106  QCheckBox *isModelOutput = new QCheckBox();
107  isModelOutput->setChecked( output.value( "isModelOutput" ).toBool() );
108  mOutputExpressionWidget->setCellWidget( currentRow, 2, isModelOutput );
109 
110  currentRow++;
111  }
112 
113  if ( outputs.isEmpty() )
114  addOutput();
115 }
116 
117 void QgsFilterAlgorithmConfigurationWidget::removeSelectedOutputs()
118 {
119  QItemSelection selection( mOutputExpressionWidget->selectionModel()->selection() );
120 
121  QList<int> rows;
122  const QModelIndexList indexes = selection.indexes();
123  for ( const QModelIndex &index : indexes )
124  {
125  rows.append( index.row() );
126  }
127 
128  std::sort( rows.begin(), rows.end() );
129 
130  int prev = -1;
131  for ( int i = rows.count() - 1; i >= 0; i -= 1 )
132  {
133  int current = rows[i];
134  if ( current != prev )
135  {
136  mOutputExpressionWidget->removeRow( current );
137  prev = current;
138  }
139  }
140 }
141 
142 void QgsFilterAlgorithmConfigurationWidget::addOutput()
143 {
144  int rowIndex = mOutputExpressionWidget->rowCount();
145  mOutputExpressionWidget->setRowCount( rowIndex + 1 );
146  QgsExpressionLineEdit *expressionBuilder = new QgsExpressionLineEdit();
147  expressionBuilder->registerExpressionContextGenerator( this );
148  mOutputExpressionWidget->setItem( rowIndex, 0, new QTableWidgetItem( QString() ) );
149  mOutputExpressionWidget->setCellWidget( rowIndex, 1, expressionBuilder );
150  mOutputExpressionWidget->setCellWidget( rowIndex, 2, new QCheckBox() );
151 }
152 
153 QgsProcessingAlgorithmConfigurationWidget *QgsFilterAlgorithmConfigurationWidgetFactory::create( const QgsProcessingAlgorithm *algorithm ) const
154 {
155  if ( algorithm->name() == QStringLiteral( "filter" ) )
156  return new QgsFilterAlgorithmConfigurationWidget();
157  else
158  return nullptr;
159 }
160 
161 bool QgsFilterAlgorithmConfigurationWidgetFactory::canCreateFor( const QgsProcessingAlgorithm *algorithm ) const
162 {
163  return algorithm->name() == QStringLiteral( "filter" );
164 }
165 
virtual QString name() const =0
Returns the algorithm name, used for identifying the algorithm.
static QIcon getThemeIcon(const QString &name)
Helper to get a theme icon.
Abstract base class for processing algorithms.
void setExpression(const QString &expression)
Sets the current expression to show in the widget.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into allowing algorithms to be written in pure substantial changes are required in order to port existing x Processing algorithms for QGIS x The most significant changes are outlined not GeoAlgorithm For algorithms which operate on features one by consider subclassing the QgsProcessingFeatureBasedAlgorithm class This class allows much of the boilerplate code for looping over features from a vector layer to be bypassed and instead requires implementation of a processFeature method Ensure that your algorithm(or algorithm 's parent class) implements the new pure virtual createInstance(self) call
A configuration widget for processing algorithms allows providing additional configuration options di...
The QgsExpressionLineEdit widget includes a line edit for entering expressions together with a button...
void registerExpressionContextGenerator(const QgsExpressionContextGenerator *generator)
Register an expression context generator class that will be used to retrieve an expression context fo...