QGIS API Documentation 3.29.0-Master (19d7edcfed)
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
37QgsProcessingVectorTileWriteLayerDetailsWidget::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
66QVariant 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
81QgsProcessingVectorTileWriterLayersPanelWidget::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
130void 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
172void 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
185void 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
195QString 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
221QgsProcessingVectorTileWriterLayersWidget::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
242void 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
253void QgsProcessingVectorTileWriterLayersWidget::setProject( QgsProject *project )
254{
255 mProject = project;
256}
257
258void 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
290void QgsProcessingVectorTileWriterLayersWidget::updateSummaryText()
291{
292 mLineEdit->setText( tr( "%n vector layer(s) selected", nullptr, mValue.count() ) );
293}
294
295//
296// QgsProcessingVectorTileWriterLayersWidgetWrapper
297//
298
299QgsProcessingVectorTileWriterLayersWidgetWrapper::QgsProcessingVectorTileWriterLayersWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type, QWidget *parent )
300 : QgsAbstractProcessingParameterWidgetWrapper( parameter, type, parent )
301{
302}
303
304QString QgsProcessingVectorTileWriterLayersWidgetWrapper::parameterType() const
305{
307}
308
309QgsAbstractProcessingParameterWidgetWrapper *QgsProcessingVectorTileWriterLayersWidgetWrapper::createWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type )
310{
311 return new QgsProcessingVectorTileWriterLayersWidgetWrapper( parameter, type );
312}
313
314QWidget *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
325void QgsProcessingVectorTileWriterLayersWidgetWrapper::setWidgetContext( const QgsProcessingParameterWidgetContext &context )
326{
328 if ( mPanel )
329 {
330 mPanel->setProject( context.project() );
331 }
332}
333
334void QgsProcessingVectorTileWriterLayersWidgetWrapper::setWidgetValue( const QVariant &value, QgsProcessingContext &context )
335{
336 Q_UNUSED( context )
337 if ( mPanel )
338 {
339 mPanel->setValue( value );
340 }
341}
342
343QVariant QgsProcessingVectorTileWriterLayersWidgetWrapper::widgetValue() const
344{
345 return mPanel ? mPanel->value() : QVariant();
346}
347
348QStringList QgsProcessingVectorTileWriterLayersWidgetWrapper::compatibleParameterTypes() const
349{
350 return QStringList();
351}
352
353QStringList QgsProcessingVectorTileWriterLayersWidgetWrapper::compatibleOutputTypes() const
354{
355 return QStringList();
356}
357
A widget wrapper for Processing parameter value widgets.
virtual void setWidgetContext(const QgsProcessingParameterWidgetContext &context)
Sets the context in which the Processing parameter widget is shown, e.g., the parent model algorithm,...
void expressionChanged(const QString &expression)
Emitted when the expression is changed.
QString name
Definition: qgsmaplayer.h:76
Base class for any widget that can be shown as a inline panel.
void openPanel(QgsPanelWidget *panel)
Open a panel or dialog depending on dock mode setting If dock mode is true this method will emit the ...
void widgetChanged()
Emitted when the widget state changes.
void acceptPanel()
Accept the panel.
static QgsPanelWidget * findParentPanel(QWidget *widget)
Traces through the parents of a widget to find if it is contained within a QgsPanelWidget widget.
bool dockMode()
Returns the dock mode state.
Contains information about the context in which a processing algorithm is executed.
WidgetType
Types of dialogs which Processing widgets can be created for.
Base class for the definition of processing parameters.
static QgsVectorTileWriter::Layer variantMapAsLayer(const QVariantMap &layerVariantMap, QgsProcessingContext &context)
Converts a QVariant value (a QVariantMap) to a single input layer.
static QVariantMap layerAsVariantMap(const QgsVectorTileWriter::Layer &layer)
Converts a single input layer to QVariant representation (a QVariantMap)
static QString typeName()
Returns the type name for the parameter class.
Contains settings which reflect the context in which a Processing parameter widget is shown,...
QgsProject * project() const
Returns the project associated with the widget.
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.
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Definition: qgsproject.h:105
Represents a vector layer which manages a vector based data sets.
Configuration of a single input vector layer to be included in the output.
QString layerName() const
Returns layer name in the output. If not set, layer()->name() will be used.
void setLayerName(const QString &name)
Sets layer name in the output. If not set, layer()->name() will be used.
QgsVectorLayer * layer() const
Returns vector layer of this entry.
void setMaxZoom(int maxzoom)
Sets maximum zoom level at which this layer will be used. Negative value means no max....
void setFilterExpression(const QString &expr)
Sets filter expression. If not empty, only features matching the expression will be used.
void setMinZoom(int minzoom)
Sets minimum zoom level at which this layer will be used. Negative value means no min....
QString filterExpression() const
Returns filter expression. If not empty, only features matching the expression will be used.
int maxZoom() const
Returns maximum zoom level at which this layer will be used. Negative value means no max....
int minZoom() const
Returns minimum zoom level at which this layer will be used. Negative value means no min....