QGIS API Documentation 3.99.0-Master (26c88405ac0)
Loading...
Searching...
No Matches
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 "qgspanelwidget.h"
20#include "qgsvectortilewriter.h"
21
22#include <QBoxLayout>
23#include <QLineEdit>
24#include <QMessageBox>
25#include <QPushButton>
26#include <QStandardItemModel>
27#include <QToolButton>
28
29#include "moc_qgsprocessingvectortilewriterlayerswidgetwrapper.cpp"
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)
86 : QgsProcessingMultipleSelectionPanelWidget( QVariantList(), QVariantList(), parent )
87 , mProject( project )
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, [this, item, widget]() {
150 setItemValue( item, widget->value() );
151 } );
152 panel->openPanel( widget );
153 }
154 else
155 {
156 QDialog dlg;
157 dlg.setWindowTitle( tr( "Configure Layer" ) );
158 QVBoxLayout *vLayout = new QVBoxLayout();
159 QgsProcessingVectorTileWriteLayerDetailsWidget *widget = new QgsProcessingVectorTileWriteLayerDetailsWidget( value, mProject );
160 vLayout->addWidget( widget );
161 connect( widget->buttonBox(), &QDialogButtonBox::accepted, &dlg, &QDialog::accept );
162 connect( widget->buttonBox(), &QDialogButtonBox::rejected, &dlg, &QDialog::reject );
163 dlg.setLayout( vLayout );
164 if ( dlg.exec() )
165 {
166 setItemValue( item, widget->value() );
167 }
168 }
169}
170
171void QgsProcessingVectorTileWriterLayersPanelWidget::copyLayer()
172{
173 const QModelIndexList selection = listView()->selectionModel()->selectedIndexes();
174 if ( selection.size() != 1 )
175 {
176 QMessageBox::warning( this, tr( "Copy Layer" ), tr( "Please select a single layer." ) );
177 return;
178 }
179
180 QStandardItem *item = mModel->itemFromIndex( selection[0] );
181 mModel->insertRow( selection[0].row() + 1, item->clone() );
182}
183
184void QgsProcessingVectorTileWriterLayersPanelWidget::setItemValue( QStandardItem *item, const QVariant &value )
185{
186 mContext.setProject( mProject );
187
189
190 item->setText( titleForLayer( layer ) );
191 item->setData( value, Qt::UserRole );
192}
193
194QString QgsProcessingVectorTileWriterLayersPanelWidget::titleForLayer( const QgsVectorTileWriter::Layer &layer )
195{
196 QString title = layer.layer()->name();
197
198 // add more details
199 if ( layer.minZoom() >= 0 && layer.maxZoom() >= 0 )
200 title += tr( " [zoom %1...%2]" ).arg( layer.minZoom() ).arg( layer.maxZoom() );
201 else if ( layer.minZoom() >= 0 )
202 title += tr( " [zoom >= %1]" ).arg( layer.minZoom() );
203 else if ( layer.maxZoom() >= 0 )
204 title += tr( " [zoom <= %1]" ).arg( layer.maxZoom() );
205
206 if ( !layer.layerName().isEmpty() )
207 title += tr( " [name: %1]" ).arg( layer.layerName() );
208 if ( !layer.filterExpression().isEmpty() )
209 title += tr( " [with filter]" );
210
211 return title;
212}
213
214
215//
216// QgsProcessingVectorTileWriterLayersWidget
217//
218
219
220QgsProcessingVectorTileWriterLayersWidget::QgsProcessingVectorTileWriterLayersWidget( QWidget *parent )
221 : QWidget( parent )
222{
223 QHBoxLayout *hl = new QHBoxLayout();
224 hl->setContentsMargins( 0, 0, 0, 0 );
225
226 mLineEdit = new QLineEdit();
227 mLineEdit->setEnabled( false );
228 hl->addWidget( mLineEdit, 1 );
229
230 mToolButton = new QToolButton();
231 mToolButton->setText( QString( QChar( 0x2026 ) ) );
232 hl->addWidget( mToolButton );
233
234 setLayout( hl );
235
236 updateSummaryText();
237
238 connect( mToolButton, &QToolButton::clicked, this, &QgsProcessingVectorTileWriterLayersWidget::showDialog );
239}
240
241void QgsProcessingVectorTileWriterLayersWidget::setValue( const QVariant &value )
242{
243 if ( value.isValid() )
244 mValue = value.userType() == QMetaType::Type::QVariantList ? value.toList() : QVariantList() << value;
245 else
246 mValue.clear();
247
248 updateSummaryText();
249 emit changed();
250}
251
252void QgsProcessingVectorTileWriterLayersWidget::setProject( QgsProject *project )
253{
254 mProject = project;
255}
256
257void QgsProcessingVectorTileWriterLayersWidget::showDialog()
258{
260 if ( panel && panel->dockMode() )
261 {
262 QgsProcessingVectorTileWriterLayersPanelWidget *widget = new QgsProcessingVectorTileWriterLayersPanelWidget( mValue, mProject );
263 widget->setPanelTitle( tr( "Input layers" ) );
264 connect( widget, &QgsProcessingMultipleSelectionPanelWidget::selectionChanged, this, [this, widget]() {
265 setValue( widget->selectedOptions() );
266 } );
267 connect( widget, &QgsProcessingMultipleSelectionPanelWidget::acceptClicked, widget, &QgsPanelWidget::acceptPanel );
268 panel->openPanel( widget );
269 }
270 else
271 {
272 QDialog dlg;
273 dlg.setWindowTitle( tr( "Input layers" ) );
274 QVBoxLayout *vLayout = new QVBoxLayout();
275 QgsProcessingVectorTileWriterLayersPanelWidget *widget = new QgsProcessingVectorTileWriterLayersPanelWidget( mValue, mProject );
276 vLayout->addWidget( widget );
277 widget->buttonBox()->addButton( QDialogButtonBox::Cancel );
278 connect( widget->buttonBox(), &QDialogButtonBox::accepted, &dlg, &QDialog::accept );
279 connect( widget->buttonBox(), &QDialogButtonBox::rejected, &dlg, &QDialog::reject );
280 dlg.setLayout( vLayout );
281 if ( dlg.exec() )
282 {
283 setValue( widget->selectedOptions() );
284 }
285 }
286}
287
288void QgsProcessingVectorTileWriterLayersWidget::updateSummaryText()
289{
290 mLineEdit->setText( tr( "%n vector layer(s) selected", nullptr, mValue.count() ) );
291}
292
293//
294// QgsProcessingVectorTileWriterLayersWidgetWrapper
295//
296
297QgsProcessingVectorTileWriterLayersWidgetWrapper::QgsProcessingVectorTileWriterLayersWidgetWrapper( const QgsProcessingParameterDefinition *parameter, Qgis::ProcessingMode type, QWidget *parent )
298 : QgsAbstractProcessingParameterWidgetWrapper( parameter, type, parent )
299{
300}
301
302QString QgsProcessingVectorTileWriterLayersWidgetWrapper::parameterType() const
303{
305}
306
307QgsAbstractProcessingParameterWidgetWrapper *QgsProcessingVectorTileWriterLayersWidgetWrapper::createWidgetWrapper( const QgsProcessingParameterDefinition *parameter, Qgis::ProcessingMode type )
308{
309 return new QgsProcessingVectorTileWriterLayersWidgetWrapper( parameter, type );
310}
311
312QWidget *QgsProcessingVectorTileWriterLayersWidgetWrapper::createWidget()
313{
314 mPanel = new QgsProcessingVectorTileWriterLayersWidget( nullptr );
315 mPanel->setProject( widgetContext().project() );
316 connect( mPanel, &QgsProcessingVectorTileWriterLayersWidget::changed, this, [this] {
317 emit widgetValueHasChanged( this );
318 } );
319 return mPanel;
320}
321
322void QgsProcessingVectorTileWriterLayersWidgetWrapper::setWidgetContext( const QgsProcessingParameterWidgetContext &context )
323{
325 if ( mPanel )
326 {
327 mPanel->setProject( context.project() );
328 }
329}
330
331void QgsProcessingVectorTileWriterLayersWidgetWrapper::setWidgetValue( const QVariant &value, QgsProcessingContext &context )
332{
333 Q_UNUSED( context )
334 if ( mPanel )
335 {
336 mPanel->setValue( value );
337 }
338}
339
340QVariant QgsProcessingVectorTileWriterLayersWidgetWrapper::widgetValue() const
341{
342 return mPanel ? mPanel->value() : QVariant();
343}
344
ProcessingMode
Types of modes which Processing widgets can be created for.
Definition qgis.h:3671
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:84
Base class for any widget that can be shown as an 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 ...
bool dockMode() const
Returns the dock mode state.
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.
Contains information about the context in which a processing algorithm is executed.
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:109
Represents a vector layer which manages a vector based dataset.
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....