QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
qgsprocessingvectortilewriterlayerswidgetwrapper.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsprocessingvectortilewriterlayerswidgetwrapper.cpp
3  ---------------------
4  Date : April 2020
5  Copyright : (C) 2020 by Martin Dobias
6  Email : wonder dot sk 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 <QBoxLayout>
19 #include <QLineEdit>
20 #include <QMessageBox>
21 #include <QPushButton>
22 #include <QStandardItemModel>
23 #include <QToolButton>
24 
25 #include "qgspanelwidget.h"
26 
27 #include "qgsprocessingcontext.h"
28 #include "qgsvectortilewriter.h"
29 
31 
33 
34 //
35 // QgsProcessingVectorTileWriteLayerDetailsWidget
36 //
37 
38 QgsProcessingVectorTileWriteLayerDetailsWidget::QgsProcessingVectorTileWriteLayerDetailsWidget( const QVariant &value, QgsProject *project )
39 {
40  setupUi( this );
41 
42  QgsProcessingContext context;
43  context.setProject( project );
44 
46  mLayer = layer.layer();
47 
48  if ( !mLayer )
49  return;
50 
51  mSpinMinZoom->setClearValue( -1, tr( "Not set" ) );
52  mSpinMaxZoom->setClearValue( -1, tr( "Not set" ) );
53  mEditFilterExpression->setMultiLine( true );
54  mEditFilterExpression->setLayer( mLayer );
55 
56  mSpinMinZoom->setValue( layer.minZoom() );
57  mSpinMaxZoom->setValue( layer.maxZoom() );
58  mEditLayerName->setText( layer.layerName() );
59  mEditLayerName->setPlaceholderText( mLayer->name() );
60  mEditFilterExpression->setExpression( layer.filterExpression() );
61 
62  connect( mSpinMinZoom, qgis::overload<int>::of( &QSpinBox::valueChanged ), this, &QgsPanelWidget::widgetChanged );
63  connect( mSpinMaxZoom, qgis::overload<int>::of( &QSpinBox::valueChanged ), this, &QgsPanelWidget::widgetChanged );
64  connect( mEditLayerName, &QLineEdit::textChanged, this, &QgsPanelWidget::widgetChanged );
65  connect( mEditFilterExpression, &QgsExpressionLineEdit::expressionChanged, this, &QgsPanelWidget::widgetChanged );
66 }
67 
68 QVariant QgsProcessingVectorTileWriteLayerDetailsWidget::value() const
69 {
70  QgsVectorTileWriter::Layer layer( mLayer );
71  layer.setMinZoom( mSpinMinZoom->value() );
72  layer.setMaxZoom( mSpinMaxZoom->value() );
73  layer.setLayerName( mEditLayerName->text() );
74  layer.setFilterExpression( mEditFilterExpression->expression() );
76 }
77 
78 //
79 // QgsProcessingVectorTileWriterLayersPanelWidget
80 //
81 
82 
83 QgsProcessingVectorTileWriterLayersPanelWidget::QgsProcessingVectorTileWriterLayersPanelWidget(
84  const QVariant &value,
85  QgsProject *project,
86  QWidget *parent )
87  : QgsProcessingMultipleSelectionPanelWidget( QVariantList(), QVariantList(), parent )
88  , mProject( project )
89 {
90 
91  connect( listView(), &QListView::doubleClicked, this, &QgsProcessingVectorTileWriterLayersPanelWidget::configureLayer );
92 
93  QPushButton *configureLayerButton = new QPushButton( tr( "Configure Layer…" ) );
94  connect( configureLayerButton, &QPushButton::clicked, this, &QgsProcessingVectorTileWriterLayersPanelWidget::configureLayer );
95  buttonBox()->addButton( configureLayerButton, QDialogButtonBox::ActionRole );
96 
97  QPushButton *copyLayerButton = new QPushButton( tr( "Copy Layer" ) );
98  connect( copyLayerButton, &QPushButton::clicked, this, &QgsProcessingVectorTileWriterLayersPanelWidget::copyLayer );
99  buttonBox()->addButton( copyLayerButton, QDialogButtonBox::ActionRole );
100 
101  // populate the list: first layers already selected, then layers from project not yet selected
102 
103  QgsProcessingContext context;
104  context.setProject( project );
105 
106  QSet<const QgsVectorLayer *> seenVectorLayers;
107  const QVariantList valueList = value.toList();
108  for ( const QVariant &v : valueList )
109  {
111  if ( !layer.layer() )
112  continue; // skip any invalid layers
113 
114  addOption( v, titleForLayer( layer ), true );
115 
116  seenVectorLayers.insert( layer.layer() );
117  }
118 
119  const QList<QgsVectorLayer *> options = QgsProcessingUtils::compatibleVectorLayers( project, QList< int >() );
120  for ( const QgsVectorLayer *layer : options )
121  {
122  if ( seenVectorLayers.contains( layer ) )
123  continue;
124 
125  QVariantMap vm;
126  vm["layer"] = layer->id();
127 
128  QString title = layer->name();
129 
130  addOption( vm, title, false );
131  }
132 }
133 
134 
135 void QgsProcessingVectorTileWriterLayersPanelWidget::configureLayer()
136 {
137  const QModelIndexList selection = listView()->selectionModel()->selectedIndexes();
138  if ( selection.size() != 1 )
139  {
140  QMessageBox::warning( this, tr( "Configure Layer" ), tr( "Please select a single layer." ) );
141  return;
142  }
143 
144  QStandardItem *item = mModel->itemFromIndex( selection[0] );
145  QVariant value = item->data( Qt::UserRole );
146 
148  if ( panel && panel->dockMode() )
149  {
150  QgsProcessingVectorTileWriteLayerDetailsWidget *widget = new QgsProcessingVectorTileWriteLayerDetailsWidget( value, mProject );
151  widget->setPanelTitle( tr( "Configure Layer" ) );
152  widget->buttonBox()->hide();
153 
154  connect( widget, &QgsProcessingVectorTileWriteLayerDetailsWidget::widgetChanged, this, [ = ]()
155  {
156  setItemValue( item, widget->value() );
157  } );
158  panel->openPanel( widget );
159  }
160  else
161  {
162  QDialog dlg;
163  dlg.setWindowTitle( tr( "Configure Layer" ) );
164  QVBoxLayout *vLayout = new QVBoxLayout();
165  QgsProcessingVectorTileWriteLayerDetailsWidget *widget = new QgsProcessingVectorTileWriteLayerDetailsWidget( value, mProject );
166  vLayout->addWidget( widget );
167  connect( widget->buttonBox(), &QDialogButtonBox::accepted, &dlg, &QDialog::accept );
168  connect( widget->buttonBox(), &QDialogButtonBox::rejected, &dlg, &QDialog::reject );
169  dlg.setLayout( vLayout );
170  if ( dlg.exec() )
171  {
172  setItemValue( item, widget->value() );
173  }
174  }
175 
176 }
177 
178 void QgsProcessingVectorTileWriterLayersPanelWidget::copyLayer()
179 {
180  const QModelIndexList selection = listView()->selectionModel()->selectedIndexes();
181  if ( selection.size() != 1 )
182  {
183  QMessageBox::warning( this, tr( "Copy Layer" ), tr( "Please select a single layer." ) );
184  return;
185  }
186 
187  QStandardItem *item = mModel->itemFromIndex( selection[0] );
188  QVariant value = item->data( Qt::UserRole );
189  mModel->insertRow( selection[0].row() + 1, item->clone() );
190 }
191 
192 void QgsProcessingVectorTileWriterLayersPanelWidget::setItemValue( QStandardItem *item, const QVariant &value )
193 {
194  QgsProcessingContext context;
195  context.setProject( mProject );
196 
198 
199  item->setText( titleForLayer( layer ) );
200  item->setData( value, Qt::UserRole );
201 }
202 
203 QString QgsProcessingVectorTileWriterLayersPanelWidget::titleForLayer( const QgsVectorTileWriter::Layer &layer )
204 {
205  QString title = layer.layer()->name();
206 
207  // add more details
208  if ( layer.minZoom() >= 0 && layer.maxZoom() >= 0 )
209  title += tr( " [zoom %1...%2]" ).arg( layer.minZoom() ).arg( layer.maxZoom() );
210  else if ( layer.minZoom() >= 0 )
211  title += tr( " [zoom >= %1]" ).arg( layer.minZoom() );
212  else if ( layer.maxZoom() >= 0 )
213  title += tr( " [zoom <= %1]" ).arg( layer.maxZoom() );
214 
215  if ( !layer.layerName().isEmpty() )
216  title += tr( " [name: %1]" ).arg( layer.layerName() );
217  if ( !layer.filterExpression().isEmpty() )
218  title += tr( " [with filter]" );
219 
220  return title;
221 }
222 
223 
224 //
225 // QgsProcessingVectorTileWriterLayersWidget
226 //
227 
228 
229 QgsProcessingVectorTileWriterLayersWidget::QgsProcessingVectorTileWriterLayersWidget( QWidget *parent )
230  : QWidget( parent )
231 {
232  QHBoxLayout *hl = new QHBoxLayout();
233  hl->setContentsMargins( 0, 0, 0, 0 );
234 
235  mLineEdit = new QLineEdit();
236  mLineEdit->setEnabled( false );
237  hl->addWidget( mLineEdit, 1 );
238 
239  mToolButton = new QToolButton();
240  mToolButton->setText( QString( QChar( 0x2026 ) ) );
241  hl->addWidget( mToolButton );
242 
243  setLayout( hl );
244 
245  updateSummaryText();
246 
247  connect( mToolButton, &QToolButton::clicked, this, &QgsProcessingVectorTileWriterLayersWidget::showDialog );
248 }
249 
250 void QgsProcessingVectorTileWriterLayersWidget::setValue( const QVariant &value )
251 {
252  if ( value.isValid() )
253  mValue = value.type() == QVariant::List ? value.toList() : QVariantList() << value;
254  else
255  mValue.clear();
256 
257  updateSummaryText();
258  emit changed();
259 }
260 
261 void QgsProcessingVectorTileWriterLayersWidget::setProject( QgsProject *project )
262 {
263  mProject = project;
264 }
265 
266 void QgsProcessingVectorTileWriterLayersWidget::showDialog()
267 {
269  if ( panel && panel->dockMode() )
270  {
271  QgsProcessingVectorTileWriterLayersPanelWidget *widget = new QgsProcessingVectorTileWriterLayersPanelWidget( mValue, mProject );
272  widget->setPanelTitle( tr( "Input layers" ) );
273  connect( widget, &QgsProcessingMultipleSelectionPanelWidget::selectionChanged, this, [ = ]()
274  {
275  setValue( widget->selectedOptions() );
276  } );
277  connect( widget, &QgsProcessingMultipleSelectionPanelWidget::acceptClicked, widget, &QgsPanelWidget::acceptPanel );
278  panel->openPanel( widget );
279  }
280  else
281  {
282  QDialog dlg;
283  dlg.setWindowTitle( tr( "Input layers" ) );
284  QVBoxLayout *vLayout = new QVBoxLayout();
285  QgsProcessingVectorTileWriterLayersPanelWidget *widget = new QgsProcessingVectorTileWriterLayersPanelWidget( mValue, mProject );
286  vLayout->addWidget( widget );
287  widget->buttonBox()->addButton( QDialogButtonBox::Cancel );
288  connect( widget->buttonBox(), &QDialogButtonBox::accepted, &dlg, &QDialog::accept );
289  connect( widget->buttonBox(), &QDialogButtonBox::rejected, &dlg, &QDialog::reject );
290  dlg.setLayout( vLayout );
291  if ( dlg.exec() )
292  {
293  setValue( widget->selectedOptions() );
294  }
295  }
296 }
297 
298 void QgsProcessingVectorTileWriterLayersWidget::updateSummaryText()
299 {
300  mLineEdit->setText( tr( "%1 vector layers selected" ).arg( mValue.count() ) );
301 }
302 
303 //
304 // QgsProcessingVectorTileWriterLayersWidgetWrapper
305 //
306 
307 QgsProcessingVectorTileWriterLayersWidgetWrapper::QgsProcessingVectorTileWriterLayersWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type, QWidget *parent )
308  : QgsAbstractProcessingParameterWidgetWrapper( parameter, type, parent )
309 {
310 }
311 
312 QString QgsProcessingVectorTileWriterLayersWidgetWrapper::parameterType() const
313 {
315 }
316 
317 QgsAbstractProcessingParameterWidgetWrapper *QgsProcessingVectorTileWriterLayersWidgetWrapper::createWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type )
318 {
319  return new QgsProcessingVectorTileWriterLayersWidgetWrapper( parameter, type );
320 }
321 
322 QWidget *QgsProcessingVectorTileWriterLayersWidgetWrapper::createWidget()
323 {
324  mPanel = new QgsProcessingVectorTileWriterLayersWidget( nullptr );
325  mPanel->setProject( widgetContext().project() );
326  connect( mPanel, &QgsProcessingVectorTileWriterLayersWidget::changed, this, [ = ]
327  {
328  emit widgetValueHasChanged( this );
329  } );
330  return mPanel;
331 }
332 
333 void QgsProcessingVectorTileWriterLayersWidgetWrapper::setWidgetContext( const QgsProcessingParameterWidgetContext &context )
334 {
336  if ( mPanel )
337  {
338  mPanel->setProject( context.project() );
339  }
340 }
341 
342 void QgsProcessingVectorTileWriterLayersWidgetWrapper::setWidgetValue( const QVariant &value, QgsProcessingContext &context )
343 {
344  Q_UNUSED( context )
345  if ( mPanel )
346  {
347  mPanel->setValue( value );
348  }
349 }
350 
351 QVariant QgsProcessingVectorTileWriterLayersWidgetWrapper::widgetValue() const
352 {
353  return mPanel ? mPanel->value() : QVariant();
354 }
355 
356 QStringList QgsProcessingVectorTileWriterLayersWidgetWrapper::compatibleParameterTypes() const
357 {
358  return QStringList();
359 }
360 
361 QStringList QgsProcessingVectorTileWriterLayersWidgetWrapper::compatibleOutputTypes() const
362 {
363  return QStringList();
364 }
365 
QgsVectorTileWriter::Layer::minZoom
int minZoom() const
Returns minimum zoom level at which this layer will be used. Negative value means no min....
Definition: qgsvectortilewriter.h:107
QgsProcessingParameterWidgetContext
Contains settings which reflect the context in which a Processing parameter widget is shown,...
Definition: qgsprocessingwidgetwrapper.h:100
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
QgsVectorTileWriter::Layer::setLayerName
void setLayerName(const QString &name)
Sets layer name in the output. If not set, layer()->name() will be used.
Definition: qgsvectortilewriter.h:104
QgsVectorTileWriter::Layer::setMinZoom
void setMinZoom(int minzoom)
Sets minimum zoom level at which this layer will be used. Negative value means no min....
Definition: qgsvectortilewriter.h:109
QgsAbstractProcessingParameterWidgetWrapper::setWidgetContext
virtual void setWidgetContext(const QgsProcessingParameterWidgetContext &context)
Sets the context in which the Processing parameter widget is shown, e.g., the parent model algorithm,...
Definition: qgsprocessingwidgetwrapper.cpp:121
QgsPanelWidget::openPanel
void openPanel(QgsPanelWidget *panel)
Open a panel or dialog depending on dock mode setting If dock mode is true this method will emit the ...
Definition: qgspanelwidget.cpp:79
QgsProcessingParameterVectorTileWriterLayers::layerAsVariantMap
static QVariantMap layerAsVariantMap(const QgsVectorTileWriter::Layer &layer)
Converts a single input layer to QVariant representation (a QVariantMap)
Definition: qgsprocessingparametervectortilewriterlayers.cpp:149
QgsProcessingParameterDefinition
Base class for the definition of processing parameters.
Definition: qgsprocessingparameters.h:331
QgsVectorTileWriter::Layer::setMaxZoom
void setMaxZoom(int maxzoom)
Sets maximum zoom level at which this layer will be used. Negative value means no max....
Definition: qgsvectortilewriter.h:114
QgsVectorTileWriter::Layer::filterExpression
QString filterExpression() const
Returns filter expression. If not empty, only features matching the expression will be used.
Definition: qgsvectortilewriter.h:97
QgsAbstractProcessingParameterWidgetWrapper
A widget wrapper for Processing parameter value widgets.
Definition: qgsprocessingwidgetwrapper.h:267
QgsVectorTileWriter::Layer::setFilterExpression
void setFilterExpression(const QString &expr)
Sets filter expression. If not empty, only features matching the expression will be used.
Definition: qgsvectortilewriter.h:99
QgsPanelWidget::dockMode
bool dockMode()
Returns the dock mode state.
Definition: qgspanelwidget.h:83
QgsProject
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Definition: qgsproject.h:95
QgsVectorTileWriter::Layer::maxZoom
int maxZoom() const
Returns maximum zoom level at which this layer will be used. Negative value means no max....
Definition: qgsvectortilewriter.h:112
QgsProcessingParameterWidgetContext::project
QgsProject * project() const
Returns the project associated with the widget.
Definition: qgsprocessingwidgetwrapper.cpp:69
QgsPanelWidget
Base class for any widget that can be shown as a inline panel.
Definition: qgspanelwidget.h:30
QgsProcessingContext
Contains information about the context in which a processing algorithm is executed.
Definition: qgsprocessingcontext.h:44
qgsprocessingparametervectortilewriterlayers.h
QgsPanelWidget::acceptPanel
void acceptPanel()
Accept the panel.
Definition: qgspanelwidget.cpp:107
QgsPanelWidget::widgetChanged
void widgetChanged()
Emitted when the widget state changes.
QgsProcessingParameterVectorTileWriterLayers::typeName
static QString typeName()
Returns the type name for the parameter class.
Definition: qgsprocessingparametervectortilewriterlayers.h:58
QgsVectorTileWriter::Layer::layer
QgsVectorLayer * layer() const
Returns vector layer of this entry.
Definition: qgsvectortilewriter.h:94
qgsvectortilewriter.h
QgsProcessingGui::WidgetType
WidgetType
Types of dialogs which Processing widgets can be created for.
Definition: qgsprocessinggui.h:39
QgsProcessingParameterVectorTileWriterLayers::variantMapAsLayer
static QgsVectorTileWriter::Layer variantMapAsLayer(const QVariantMap &layerVariantMap, QgsProcessingContext &context)
Converts a QVariant value (a QVariantMap) to a single input layer.
Definition: qgsprocessingparametervectortilewriterlayers.cpp:118
QgsVectorLayer
Represents a vector layer which manages a vector based data sets.
Definition: qgsvectorlayer.h:387
QgsProcessingUtils::compatibleVectorLayers
static QList< QgsVectorLayer * > compatibleVectorLayers(QgsProject *project, const QList< int > &sourceTypes=QList< int >(), bool sort=true)
Returns a list of vector layers from a project which are compatible with the processing framework.
Definition: qgsprocessingutils.cpp:62
QgsVectorTileWriter::Layer
Configuration of a single input vector layer to be included in the output.
Definition: qgsvectortilewriter.h:85
QgsMapLayer::name
QString name
Definition: qgsmaplayer.h:86
qgsprocessingcontext.h
qgspanelwidget.h
QgsProcessingContext::setProject
void setProject(QgsProject *project)
Sets the project in which the algorithm will be executed.
Definition: qgsprocessingcontext.h:115
QgsVectorTileWriter::Layer::layerName
QString layerName() const
Returns layer name in the output. If not set, layer()->name() will be used.
Definition: qgsvectortilewriter.h:102
QgsExpressionLineEdit::expressionChanged
void expressionChanged(const QString &expression)
Emitted when the expression is changed.
qgsprocessingvectortilewriterlayerswidgetwrapper.h