QGIS API Documentation 4.1.0-Master (5bf3c20f3c9)
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( const QVariant &value, QgsProject *project, QWidget *parent )
82 : QgsProcessingMultipleSelectionPanelWidget( QVariantList(), QVariantList(), parent )
83 , mProject( project )
84{
85 connect( listView(), &QListView::doubleClicked, this, &QgsProcessingVectorTileWriterLayersPanelWidget::configureLayer );
86
87 QPushButton *configureLayerButton = new QPushButton( tr( "Configure Layer…" ) );
88 connect( configureLayerButton, &QPushButton::clicked, this, &QgsProcessingVectorTileWriterLayersPanelWidget::configureLayer );
89 buttonBox()->addButton( configureLayerButton, QDialogButtonBox::ActionRole );
90
91 QPushButton *copyLayerButton = new QPushButton( tr( "Copy Layer" ) );
92 connect( copyLayerButton, &QPushButton::clicked, this, &QgsProcessingVectorTileWriterLayersPanelWidget::copyLayer );
93 buttonBox()->addButton( copyLayerButton, QDialogButtonBox::ActionRole );
94
95 // populate the list: first layers already selected, then layers from project not yet selected
96 mContext.setProject( project );
97
98 QSet<const QgsVectorLayer *> seenVectorLayers;
99 const QVariantList valueList = value.toList();
100 for ( const QVariant &v : valueList )
101 {
103 if ( !layer.layer() )
104 continue; // skip any invalid layers
105
106 addOption( v, titleForLayer( layer ), true );
107
108 seenVectorLayers.insert( layer.layer() );
109 }
110
111 const QList<QgsVectorLayer *> options = QgsProcessingUtils::compatibleVectorLayers( project, QList<int>() );
112 for ( const QgsVectorLayer *layer : options )
113 {
114 if ( seenVectorLayers.contains( layer ) )
115 continue;
116
117 QVariantMap vm;
118 vm["layer"] = layer->id();
119
120 const QString title = layer->name();
121
122 addOption( vm, title, false );
123 }
124}
125
126void QgsProcessingVectorTileWriterLayersPanelWidget::configureLayer()
127{
128 const QModelIndexList selection = listView()->selectionModel()->selectedIndexes();
129 if ( selection.size() != 1 )
130 {
131 QMessageBox::warning( this, tr( "Configure Layer" ), tr( "Please select a single layer." ) );
132 return;
133 }
134
135 QStandardItem *item = mModel->itemFromIndex( selection[0] );
136 const QVariant value = item->data( Qt::UserRole );
137
139 if ( panel && panel->dockMode() )
140 {
141 QgsProcessingVectorTileWriteLayerDetailsWidget *widget = new QgsProcessingVectorTileWriteLayerDetailsWidget( value, mProject );
142 widget->setPanelTitle( tr( "Configure Layer" ) );
143 widget->buttonBox()->hide();
144
145 connect( widget, &QgsProcessingVectorTileWriteLayerDetailsWidget::widgetChanged, this, [this, item, widget]() { setItemValue( item, widget->value() ); } );
146 panel->openPanel( widget );
147 }
148 else
149 {
150 QDialog dlg;
151 dlg.setWindowTitle( tr( "Configure Layer" ) );
152 QVBoxLayout *vLayout = new QVBoxLayout();
153 QgsProcessingVectorTileWriteLayerDetailsWidget *widget = new QgsProcessingVectorTileWriteLayerDetailsWidget( value, mProject );
154 vLayout->addWidget( widget );
155 connect( widget->buttonBox(), &QDialogButtonBox::accepted, &dlg, &QDialog::accept );
156 connect( widget->buttonBox(), &QDialogButtonBox::rejected, &dlg, &QDialog::reject );
157 dlg.setLayout( vLayout );
158 if ( dlg.exec() )
159 {
160 setItemValue( item, widget->value() );
161 }
162 }
163}
164
165void QgsProcessingVectorTileWriterLayersPanelWidget::copyLayer()
166{
167 const QModelIndexList selection = listView()->selectionModel()->selectedIndexes();
168 if ( selection.size() != 1 )
169 {
170 QMessageBox::warning( this, tr( "Copy Layer" ), tr( "Please select a single layer." ) );
171 return;
172 }
173
174 QStandardItem *item = mModel->itemFromIndex( selection[0] );
175 mModel->insertRow( selection[0].row() + 1, item->clone() );
176}
177
178void QgsProcessingVectorTileWriterLayersPanelWidget::setItemValue( QStandardItem *item, const QVariant &value )
179{
180 mContext.setProject( mProject );
181
183
184 item->setText( titleForLayer( layer ) );
185 item->setData( value, Qt::UserRole );
186}
187
188QString QgsProcessingVectorTileWriterLayersPanelWidget::titleForLayer( const QgsVectorTileWriter::Layer &layer )
189{
190 QString title = layer.layer()->name();
191
192 // add more details
193 if ( layer.minZoom() >= 0 && layer.maxZoom() >= 0 )
194 title += tr( " [zoom %1...%2]" ).arg( layer.minZoom() ).arg( layer.maxZoom() );
195 else if ( layer.minZoom() >= 0 )
196 title += tr( " [zoom >= %1]" ).arg( layer.minZoom() );
197 else if ( layer.maxZoom() >= 0 )
198 title += tr( " [zoom <= %1]" ).arg( layer.maxZoom() );
199
200 if ( !layer.layerName().isEmpty() )
201 title += tr( " [name: %1]" ).arg( layer.layerName() );
202 if ( !layer.filterExpression().isEmpty() )
203 title += tr( " [with filter]" );
204
205 return title;
206}
207
208
209//
210// QgsProcessingVectorTileWriterLayersWidget
211//
212
213
214QgsProcessingVectorTileWriterLayersWidget::QgsProcessingVectorTileWriterLayersWidget( QWidget *parent )
215 : QWidget( parent )
216{
217 QHBoxLayout *hl = new QHBoxLayout();
218 hl->setContentsMargins( 0, 0, 0, 0 );
219
220 mLineEdit = new QLineEdit();
221 mLineEdit->setEnabled( false );
222 hl->addWidget( mLineEdit, 1 );
223
224 mToolButton = new QToolButton();
225 mToolButton->setText( QString( QChar( 0x2026 ) ) );
226 hl->addWidget( mToolButton );
227
228 setLayout( hl );
229
230 updateSummaryText();
231
232 connect( mToolButton, &QToolButton::clicked, this, &QgsProcessingVectorTileWriterLayersWidget::showDialog );
233}
234
235void QgsProcessingVectorTileWriterLayersWidget::setValue( const QVariant &value )
236{
237 if ( value.isValid() )
238 mValue = value.userType() == QMetaType::Type::QVariantList ? value.toList() : QVariantList() << value;
239 else
240 mValue.clear();
241
242 updateSummaryText();
243 emit changed();
244}
245
246void QgsProcessingVectorTileWriterLayersWidget::setProject( QgsProject *project )
247{
248 mProject = project;
249}
250
251void QgsProcessingVectorTileWriterLayersWidget::showDialog()
252{
254 if ( panel && panel->dockMode() )
255 {
256 QgsProcessingVectorTileWriterLayersPanelWidget *widget = new QgsProcessingVectorTileWriterLayersPanelWidget( mValue, mProject );
257 widget->setPanelTitle( tr( "Input layers" ) );
258 connect( widget, &QgsProcessingMultipleSelectionPanelWidget::selectionChanged, this, [this, widget]() { setValue( widget->selectedOptions() ); } );
259 connect( widget, &QgsProcessingMultipleSelectionPanelWidget::acceptClicked, widget, &QgsPanelWidget::acceptPanel );
260 panel->openPanel( widget );
261 }
262 else
263 {
264 QDialog dlg;
265 dlg.setWindowTitle( tr( "Input layers" ) );
266 QVBoxLayout *vLayout = new QVBoxLayout();
267 QgsProcessingVectorTileWriterLayersPanelWidget *widget = new QgsProcessingVectorTileWriterLayersPanelWidget( mValue, mProject );
268 vLayout->addWidget( widget );
269 widget->buttonBox()->addButton( QDialogButtonBox::Cancel );
270 connect( widget->buttonBox(), &QDialogButtonBox::accepted, &dlg, &QDialog::accept );
271 connect( widget->buttonBox(), &QDialogButtonBox::rejected, &dlg, &QDialog::reject );
272 dlg.setLayout( vLayout );
273 if ( dlg.exec() )
274 {
275 setValue( widget->selectedOptions() );
276 }
277 }
278}
279
280void QgsProcessingVectorTileWriterLayersWidget::updateSummaryText()
281{
282 mLineEdit->setText( tr( "%n vector layer(s) selected", nullptr, mValue.count() ) );
283}
284
285//
286// QgsProcessingVectorTileWriterLayersWidgetWrapper
287//
288
289QgsProcessingVectorTileWriterLayersWidgetWrapper::QgsProcessingVectorTileWriterLayersWidgetWrapper( const QgsProcessingParameterDefinition *parameter, Qgis::ProcessingMode type, QWidget *parent )
290 : QgsAbstractProcessingParameterWidgetWrapper( parameter, type, parent )
291{}
292
293QString QgsProcessingVectorTileWriterLayersWidgetWrapper::parameterType() const
294{
296}
297
298QgsAbstractProcessingParameterWidgetWrapper *QgsProcessingVectorTileWriterLayersWidgetWrapper::createWidgetWrapper( const QgsProcessingParameterDefinition *parameter, Qgis::ProcessingMode type )
299{
300 return new QgsProcessingVectorTileWriterLayersWidgetWrapper( parameter, type );
301}
302
303QWidget *QgsProcessingVectorTileWriterLayersWidgetWrapper::createWidget()
304{
305 mPanel = new QgsProcessingVectorTileWriterLayersWidget( nullptr );
306 mPanel->setProject( widgetContext().project() );
307 connect( mPanel, &QgsProcessingVectorTileWriterLayersWidget::changed, this, [this] { emit widgetValueHasChanged( this ); } );
308 return mPanel;
309}
310
311void QgsProcessingVectorTileWriterLayersWidgetWrapper::setWidgetContext( const QgsProcessingParameterWidgetContext &context )
312{
314 if ( mPanel )
315 {
316 mPanel->setProject( context.project() );
317 }
318}
319
320void QgsProcessingVectorTileWriterLayersWidgetWrapper::setWidgetValue( const QVariant &value, QgsProcessingContext &context )
321{
322 Q_UNUSED( context )
323 if ( mPanel )
324 {
325 mPanel->setValue( value );
326 }
327}
328
329QVariant QgsProcessingVectorTileWriterLayersWidgetWrapper::widgetValue() const
330{
331 return mPanel ? mPanel->value() : QVariant();
332}
333
ProcessingMode
Types of modes which Processing widgets can be created for.
Definition qgis.h:3786
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:87
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:113
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....