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