QGIS API Documentation  3.14.0-Pi (9f7028fd23)
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->setMargin( 0 );
234  hl->setContentsMargins( 0, 0, 0, 0 );
235 
236  mLineEdit = new QLineEdit();
237  mLineEdit->setEnabled( false );
238  hl->addWidget( mLineEdit, 1 );
239 
240  mToolButton = new QToolButton();
241  mToolButton->setText( QString( QChar( 0x2026 ) ) );
242  hl->addWidget( mToolButton );
243 
244  setLayout( hl );
245 
246  updateSummaryText();
247 
248  connect( mToolButton, &QToolButton::clicked, this, &QgsProcessingVectorTileWriterLayersWidget::showDialog );
249 }
250 
251 void QgsProcessingVectorTileWriterLayersWidget::setValue( const QVariant &value )
252 {
253  if ( value.isValid() )
254  mValue = value.type() == QVariant::List ? value.toList() : QVariantList() << value;
255  else
256  mValue.clear();
257 
258  updateSummaryText();
259  emit changed();
260 }
261 
262 void QgsProcessingVectorTileWriterLayersWidget::setProject( QgsProject *project )
263 {
264  mProject = project;
265 }
266 
267 void QgsProcessingVectorTileWriterLayersWidget::showDialog()
268 {
270  if ( panel && panel->dockMode() )
271  {
272  QgsProcessingVectorTileWriterLayersPanelWidget *widget = new QgsProcessingVectorTileWriterLayersPanelWidget( mValue, mProject );
273  widget->setPanelTitle( tr( "Input layers" ) );
274  connect( widget, &QgsProcessingMultipleSelectionPanelWidget::selectionChanged, this, [ = ]()
275  {
276  setValue( widget->selectedOptions() );
277  } );
278  connect( widget, &QgsProcessingMultipleSelectionPanelWidget::acceptClicked, widget, &QgsPanelWidget::acceptPanel );
279  panel->openPanel( widget );
280  }
281  else
282  {
283  QDialog dlg;
284  dlg.setWindowTitle( tr( "Input layers" ) );
285  QVBoxLayout *vLayout = new QVBoxLayout();
286  QgsProcessingVectorTileWriterLayersPanelWidget *widget = new QgsProcessingVectorTileWriterLayersPanelWidget( mValue, mProject );
287  vLayout->addWidget( widget );
288  widget->buttonBox()->addButton( QDialogButtonBox::Cancel );
289  connect( widget->buttonBox(), &QDialogButtonBox::accepted, &dlg, &QDialog::accept );
290  connect( widget->buttonBox(), &QDialogButtonBox::rejected, &dlg, &QDialog::reject );
291  dlg.setLayout( vLayout );
292  if ( dlg.exec() )
293  {
294  setValue( widget->selectedOptions() );
295  }
296  }
297 }
298 
299 void QgsProcessingVectorTileWriterLayersWidget::updateSummaryText()
300 {
301  mLineEdit->setText( tr( "%1 vector layers selected" ).arg( mValue.count() ) );
302 }
303 
304 //
305 // QgsProcessingVectorTileWriterLayersWidgetWrapper
306 //
307 
308 QgsProcessingVectorTileWriterLayersWidgetWrapper::QgsProcessingVectorTileWriterLayersWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type, QWidget *parent )
309  : QgsAbstractProcessingParameterWidgetWrapper( parameter, type, parent )
310 {
311 }
312 
313 QString QgsProcessingVectorTileWriterLayersWidgetWrapper::parameterType() const
314 {
316 }
317 
318 QgsAbstractProcessingParameterWidgetWrapper *QgsProcessingVectorTileWriterLayersWidgetWrapper::createWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type )
319 {
320  return new QgsProcessingVectorTileWriterLayersWidgetWrapper( parameter, type );
321 }
322 
323 QWidget *QgsProcessingVectorTileWriterLayersWidgetWrapper::createWidget()
324 {
325  mPanel = new QgsProcessingVectorTileWriterLayersWidget( nullptr );
326  mPanel->setProject( widgetContext().project() );
327  connect( mPanel, &QgsProcessingVectorTileWriterLayersWidget::changed, this, [ = ]
328  {
329  emit widgetValueHasChanged( this );
330  } );
331  return mPanel;
332 }
333 
334 void QgsProcessingVectorTileWriterLayersWidgetWrapper::setWidgetContext( const QgsProcessingParameterWidgetContext &context )
335 {
337  if ( mPanel )
338  {
339  mPanel->setProject( context.project() );
340  }
341 }
342 
343 void QgsProcessingVectorTileWriterLayersWidgetWrapper::setWidgetValue( const QVariant &value, QgsProcessingContext &context )
344 {
345  Q_UNUSED( context )
346  if ( mPanel )
347  {
348  mPanel->setValue( value );
349  }
350 }
351 
352 QVariant QgsProcessingVectorTileWriterLayersWidgetWrapper::widgetValue() const
353 {
354  return mPanel ? mPanel->value() : QVariant();
355 }
356 
357 QStringList QgsProcessingVectorTileWriterLayersWidgetWrapper::compatibleParameterTypes() const
358 {
359  return QStringList();
360 }
361 
362 QStringList QgsProcessingVectorTileWriterLayersWidgetWrapper::compatibleOutputTypes() const
363 {
364  return QStringList();
365 }
366 
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
Definition: qgsprocessingwidgetwrapper.h:99
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
Definition: qgsprocessingparameters.h:330
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
Definition: qgsprocessingwidgetwrapper.h:266
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
Definition: qgsproject.h:92
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:29
QgsProcessingContext
Definition: qgsprocessingcontext.h:43
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:71
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:38
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
Definition: qgsvectorlayer.h:385
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
Definition: qgsvectortilewriter.h:84
QgsMapLayer::name
QString name
Definition: qgsmaplayer.h:85
qgsprocessingcontext.h
qgspanelwidget.h
QgsProcessingContext::setProject
void setProject(QgsProject *project)
Sets the project in which the algorithm will be executed.
Definition: qgsprocessingcontext.h:109
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