QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
qgsprocessingdxflayerswidgetwrapper.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsprocessingdxflayerswidgetwrapper.cpp
3 ---------------------
4 Date : September 2020
5 Copyright : (C) 2020 by Alexander Bruy
6 Email : alexander dot bruy 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"
29
31
32//
33// QgsProcessingDxfLayerDetailsWidget
34//
35
36QgsProcessingDxfLayerDetailsWidget::QgsProcessingDxfLayerDetailsWidget( const QVariant &value, QgsProject *project )
37{
38 setupUi( this );
39
40 mFieldsComboBox->setAllowEmptyFieldName( true );
41
42 mContext.setProject( project );
43
45 mLayer = layer.layer();
46
47 if ( !mLayer )
48 return;
49
50 mFieldsComboBox->setLayer( mLayer );
51 mFieldsComboBox->setCurrentIndex( layer.layerOutputAttributeIndex() );
52
53 connect( mFieldsComboBox, &QgsFieldComboBox::fieldChanged, this, &QgsPanelWidget::widgetChanged );
54}
55
56QVariant QgsProcessingDxfLayerDetailsWidget::value() const
57{
58 const int index = mLayer->fields().lookupField( mFieldsComboBox->currentField() );
59 const QgsDxfExport::DxfLayer layer( mLayer, index );
61}
62
63
64//
65// QgsProcessingDxfLayersPanelWidget
66//
67
68QgsProcessingDxfLayersPanelWidget::QgsProcessingDxfLayersPanelWidget(
69 const QVariant &value,
70 QgsProject *project,
71 QWidget *parent )
72 : QgsProcessingMultipleSelectionPanelWidget( QVariantList(), QVariantList(), parent )
73 , mProject( project )
74{
75 connect( listView(), &QListView::doubleClicked, this, &QgsProcessingDxfLayersPanelWidget::configureLayer );
76
77 QPushButton *configureLayerButton = new QPushButton( tr( "Configure Layer…" ) );
78 connect( configureLayerButton, &QPushButton::clicked, this, &QgsProcessingDxfLayersPanelWidget::configureLayer );
79 buttonBox()->addButton( configureLayerButton, QDialogButtonBox::ActionRole );
80
81 // populate the list: first layers already selected, then layers from project not yet selected
82 mContext.setProject( project );
83
84 QSet<const QgsVectorLayer *> seenVectorLayers;
85 const QVariantList valueList = value.toList();
86 for ( const QVariant &v : valueList )
87 {
89 if ( !layer.layer() )
90 continue; // skip any invalid layers
91
92 addOption( v, titleForLayer( layer ), true );
93 seenVectorLayers.insert( layer.layer() );
94 }
95
96 const QList<QgsVectorLayer *> options = QgsProcessingUtils::compatibleVectorLayers( project, QList< int >() << static_cast<int>( Qgis::ProcessingSourceType::VectorAnyGeometry ) );
97 for ( const QgsVectorLayer *layer : options )
98 {
99 if ( seenVectorLayers.contains( layer ) )
100 continue;
101
102 QVariantMap vm;
103 vm["layer"] = layer->id();
104 vm["attributeIndex"] = -1;
105
106 const QString title = layer->name();
107 addOption( vm, title, false );
108 }
109}
110
111void QgsProcessingDxfLayersPanelWidget::configureLayer()
112{
113 const QModelIndexList selection = listView()->selectionModel()->selectedIndexes();
114 if ( selection.size() != 1 )
115 {
116 QMessageBox::warning( this, tr( "Configure Layer" ), tr( "Please select a single layer." ) );
117 return;
118 }
119
120 QStandardItem *item = mModel->itemFromIndex( selection[0] );
121 const QVariant value = item->data( Qt::UserRole );
122
124 if ( panel && panel->dockMode() )
125 {
126 QgsProcessingDxfLayerDetailsWidget *widget = new QgsProcessingDxfLayerDetailsWidget( value, mProject );
127 widget->setPanelTitle( tr( "Configure Layer" ) );
128 widget->buttonBox()->hide();
129
130 connect( widget, &QgsProcessingDxfLayerDetailsWidget::widgetChanged, this, [ = ]()
131 {
132 setItemValue( item, widget->value() );
133 } );
134 panel->openPanel( widget );
135 }
136 else
137 {
138 QDialog dlg;
139 dlg.setWindowTitle( tr( "Configure Layer" ) );
140 QVBoxLayout *vLayout = new QVBoxLayout();
141 QgsProcessingDxfLayerDetailsWidget *widget = new QgsProcessingDxfLayerDetailsWidget( value, mProject );
142 vLayout->addWidget( widget );
143 connect( widget->buttonBox(), &QDialogButtonBox::accepted, &dlg, &QDialog::accept );
144 connect( widget->buttonBox(), &QDialogButtonBox::rejected, &dlg, &QDialog::reject );
145 dlg.setLayout( vLayout );
146 if ( dlg.exec() )
147 {
148 setItemValue( item, widget->value() );
149 }
150 }
151}
152
153void QgsProcessingDxfLayersPanelWidget::setItemValue( QStandardItem *item, const QVariant &value )
154{
155 mContext.setProject( mProject );
156
157 const QgsDxfExport::DxfLayer layer = QgsProcessingParameterDxfLayers::variantMapAsLayer( value.toMap(), mContext );
158
159 item->setText( titleForLayer( layer ) );
160 item->setData( value, Qt::UserRole );
161}
162
163QString QgsProcessingDxfLayersPanelWidget::titleForLayer( const QgsDxfExport::DxfLayer &layer )
164{
165 QString title = layer.layer()->name();
166
167 if ( layer.layerOutputAttributeIndex() != -1 )
168 title += tr( " [split attribute: %1]" ).arg( layer.splitLayerAttribute() );
169
170 return title;
171}
172
173
174//
175// QgsProcessingDxfLayersWidget
176//
177
178QgsProcessingDxfLayersWidget::QgsProcessingDxfLayersWidget( QWidget *parent )
179 : QWidget( parent )
180{
181 QHBoxLayout *hl = new QHBoxLayout();
182 hl->setContentsMargins( 0, 0, 0, 0 );
183
184 mLineEdit = new QLineEdit();
185 mLineEdit->setEnabled( false );
186 hl->addWidget( mLineEdit, 1 );
187
188 mToolButton = new QToolButton();
189 mToolButton->setText( QString( QChar( 0x2026 ) ) );
190 hl->addWidget( mToolButton );
191
192 setLayout( hl );
193
194 updateSummaryText();
195
196 connect( mToolButton, &QToolButton::clicked, this, &QgsProcessingDxfLayersWidget::showDialog );
197}
198
199void QgsProcessingDxfLayersWidget::setValue( const QVariant &value )
200{
201 if ( value.isValid() )
202 mValue = value.type() == QVariant::List ? value.toList() : QVariantList() << value;
203 else
204 mValue.clear();
205
206 updateSummaryText();
207 emit changed();
208}
209
210void QgsProcessingDxfLayersWidget::setProject( QgsProject *project )
211{
212 mProject = project;
213}
214
215void QgsProcessingDxfLayersWidget::showDialog()
216{
218 if ( panel && panel->dockMode() )
219 {
220 QgsProcessingDxfLayersPanelWidget *widget = new QgsProcessingDxfLayersPanelWidget( mValue, mProject );
221 widget->setPanelTitle( tr( "Input layers" ) );
222 connect( widget, &QgsProcessingMultipleSelectionPanelWidget::selectionChanged, this, [ = ]()
223 {
224 setValue( widget->selectedOptions() );
225 } );
226 connect( widget, &QgsProcessingMultipleSelectionPanelWidget::acceptClicked, widget, &QgsPanelWidget::acceptPanel );
227 panel->openPanel( widget );
228 }
229 else
230 {
231 QDialog dlg;
232 dlg.setWindowTitle( tr( "Input layers" ) );
233 QVBoxLayout *vLayout = new QVBoxLayout();
234 QgsProcessingDxfLayersPanelWidget *widget = new QgsProcessingDxfLayersPanelWidget( mValue, mProject );
235 vLayout->addWidget( widget );
236 widget->buttonBox()->addButton( QDialogButtonBox::Cancel );
237 connect( widget->buttonBox(), &QDialogButtonBox::accepted, &dlg, &QDialog::accept );
238 connect( widget->buttonBox(), &QDialogButtonBox::rejected, &dlg, &QDialog::reject );
239 dlg.setLayout( vLayout );
240 if ( dlg.exec() )
241 {
242 setValue( widget->selectedOptions() );
243 }
244 }
245}
246
247void QgsProcessingDxfLayersWidget::updateSummaryText()
248{
249 mLineEdit->setText( tr( "%n vector layer(s) selected", nullptr, mValue.count() ) );
250}
251
252
253//
254// QgsProcessingDxfLayersWidgetWrapper
255//
256
257QgsProcessingDxfLayersWidgetWrapper::QgsProcessingDxfLayersWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type, QWidget *parent )
258 : QgsAbstractProcessingParameterWidgetWrapper( parameter, type, parent )
259{
260}
261
262QString QgsProcessingDxfLayersWidgetWrapper::parameterType() const
263{
265}
266
267QgsAbstractProcessingParameterWidgetWrapper *QgsProcessingDxfLayersWidgetWrapper::createWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type )
268{
269 return new QgsProcessingDxfLayersWidgetWrapper( parameter, type );
270}
271
272QWidget *QgsProcessingDxfLayersWidgetWrapper::createWidget()
273{
274 mPanel = new QgsProcessingDxfLayersWidget( nullptr );
275 mPanel->setProject( widgetContext().project() );
276 connect( mPanel, &QgsProcessingDxfLayersWidget::changed, this, [ = ]
277 {
278 emit widgetValueHasChanged( this );
279 } );
280 return mPanel;
281}
282
283void QgsProcessingDxfLayersWidgetWrapper::setWidgetContext( const QgsProcessingParameterWidgetContext &context )
284{
286 if ( mPanel )
287 {
288 mPanel->setProject( context.project() );
289 }
290}
291
292void QgsProcessingDxfLayersWidgetWrapper::setWidgetValue( const QVariant &value, QgsProcessingContext &context )
293{
294 Q_UNUSED( context )
295 if ( mPanel )
296 {
297 mPanel->setValue( value );
298 }
299}
300
301QVariant QgsProcessingDxfLayersWidgetWrapper::widgetValue() const
302{
303 return mPanel ? mPanel->value() : QVariant();
304}
305
306QStringList QgsProcessingDxfLayersWidgetWrapper::compatibleParameterTypes() const
307{
308 return QStringList()
315}
316
317QStringList QgsProcessingDxfLayersWidgetWrapper::compatibleOutputTypes() const
318{
319 return QStringList()
325}
326
@ VectorAnyGeometry
Any vector layer with geometry.
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 fieldChanged(const QString &fieldName)
Emitted when the currently selected field changes.
QString name
Definition: qgsmaplayer.h:78
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.
static QString typeName()
Returns the type name for the output class.
static QString typeName()
Returns the type name for the output class.
static QString typeName()
Returns the type name for the output class.
static QString typeName()
Returns the type name for the output class.
static QString typeName()
Returns the type name for the output class.
Base class for the definition of processing parameters.
static QVariantMap layerAsVariantMap(const QgsDxfExport::DxfLayer &layer)
Converts a single input layer to QVariant representation (a QVariantMap)
static QgsDxfExport::DxfLayer variantMapAsLayer(const QVariantMap &layerVariantMap, QgsProcessingContext &context)
Converts a QVariant value (a QVariantMap) to a single input layer.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
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:107
Represents a vector layer which manages a vector based data sets.
Layers and optional attribute index to split into multiple layers using attribute value as layer name...
Definition: qgsdxfexport.h:75
QgsVectorLayer * layer() const
Returns the layer.
Definition: qgsdxfexport.h:84
QString splitLayerAttribute() const
If the split layer attribute is set, the vector layer will be split into several dxf layers,...
int layerOutputAttributeIndex() const
Returns the attribute index used to split into multiple layers.
Definition: qgsdxfexport.h:91