QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
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"
27 #include "qgsprocessingoutputs.h"
29 
31 
32 //
33 // QgsProcessingDxfLayerDetailsWidget
34 //
35 
36 QgsProcessingDxfLayerDetailsWidget::QgsProcessingDxfLayerDetailsWidget( const QVariant &value, QgsProject *project )
37 {
38  setupUi( this );
39 
40  mFieldsComboBox->setAllowEmptyFieldName( true );
41 
42  mContext.setProject( project );
43 
44  const QgsDxfExport::DxfLayer layer = QgsProcessingParameterDxfLayers::variantMapAsLayer( value.toMap(), mContext );
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 
56 QVariant 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 
68 QgsProcessingDxfLayersPanelWidget::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 >() );
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 
111 void 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 
153 void 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 
163 QString 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 
178 QgsProcessingDxfLayersWidget::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 
199 void 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 
210 void QgsProcessingDxfLayersWidget::setProject( QgsProject *project )
211 {
212  mProject = project;
213 }
214 
215 void 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 
247 void QgsProcessingDxfLayersWidget::updateSummaryText()
248 {
249  mLineEdit->setText( tr( "%n vector layer(s) selected", nullptr, mValue.count() ) );
250 }
251 
252 
253 //
254 // QgsProcessingDxfLayersWidgetWrapper
255 //
256 
257 QgsProcessingDxfLayersWidgetWrapper::QgsProcessingDxfLayersWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type, QWidget *parent )
258  : QgsAbstractProcessingParameterWidgetWrapper( parameter, type, parent )
259 {
260 }
261 
262 QString QgsProcessingDxfLayersWidgetWrapper::parameterType() const
263 {
265 }
266 
267 QgsAbstractProcessingParameterWidgetWrapper *QgsProcessingDxfLayersWidgetWrapper::createWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type )
268 {
269  return new QgsProcessingDxfLayersWidgetWrapper( parameter, type );
270 }
271 
272 QWidget *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 
283 void QgsProcessingDxfLayersWidgetWrapper::setWidgetContext( const QgsProcessingParameterWidgetContext &context )
284 {
286  if ( mPanel )
287  {
288  mPanel->setProject( context.project() );
289  }
290 }
291 
292 void QgsProcessingDxfLayersWidgetWrapper::setWidgetValue( const QVariant &value, QgsProcessingContext &context )
293 {
294  Q_UNUSED( context )
295  if ( mPanel )
296  {
297  mPanel->setValue( value );
298  }
299 }
300 
301 QVariant QgsProcessingDxfLayersWidgetWrapper::widgetValue() const
302 {
303  return mPanel ? mPanel->value() : QVariant();
304 }
305 
306 QStringList QgsProcessingDxfLayersWidgetWrapper::compatibleParameterTypes() const
307 {
308  return QStringList()
315 }
316 
317 QStringList QgsProcessingDxfLayersWidgetWrapper::compatibleOutputTypes() const
318 {
319  return QStringList()
325 }
326 
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
QgsDxfExport::DxfLayer::layer
QgsVectorLayer * layer() const
Returns the layer.
Definition: qgsdxfexport.h:81
QgsProcessingParameterFile::typeName
static QString typeName()
Returns the type name for the parameter class.
Definition: qgsprocessingparameters.h:1931
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
QgsProcessingParameterMultipleLayers::typeName
static QString typeName()
Returns the type name for the parameter class.
Definition: qgsprocessingparameters.h:2111
QgsProcessingParameterDefinition
Base class for the definition of processing parameters.
Definition: qgsprocessingparameters.h:334
qgsprocessingdxflayerswidgetwrapper.h
QgsProcessingOutputMultipleLayers::typeName
static QString typeName()
Returns the type name for the output class.
Definition: qgsprocessingoutputs.h:280
QgsAbstractProcessingParameterWidgetWrapper
A widget wrapper for Processing parameter value widgets.
Definition: qgsprocessingwidgetwrapper.h:282
QgsProcessingParameterDxfLayers::typeName
static QString typeName()
Returns the type name for the parameter class.
Definition: qgsprocessingparameterdxflayers.h:71
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
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
QgsProcessingOutputMapLayer::typeName
static QString typeName()
Returns the type name for the output class.
Definition: qgsprocessingoutputs.h:168
QgsProcessingContext
Contains information about the context in which a processing algorithm is executed.
Definition: qgsprocessingcontext.h:46
QgsProcessingParameterDxfLayers::layerAsVariantMap
static QVariantMap layerAsVariantMap(const QgsDxfExport::DxfLayer &layer)
Converts a single input layer to QVariant representation (a QVariantMap)
Definition: qgsprocessingparameterdxflayers.cpp:222
QgsPanelWidget::acceptPanel
void acceptPanel()
Accept the panel.
Definition: qgspanelwidget.cpp:112
QgsProcessingParameterString::typeName
static QString typeName()
Returns the type name for the parameter class.
Definition: qgsprocessingparameters.h:2661
QgsPanelWidget::widgetChanged
void widgetChanged()
Emitted when the widget state changes.
QgsProcessingParameterDxfLayers::variantMapAsLayer
static QgsDxfExport::DxfLayer variantMapAsLayer(const QVariantMap &layerVariantMap, QgsProcessingContext &context)
Converts a QVariant value (a QVariantMap) to a single input layer.
Definition: qgsprocessingparameterdxflayers.cpp:200
QgsProcessingOutputVectorLayer::typeName
static QString typeName()
Returns the type name for the output class.
Definition: qgsprocessingoutputs.h:191
QgsProcessingParameterFeatureSource::typeName
static QString typeName()
Returns the type name for the parameter class.
Definition: qgsprocessingparameters.h:3071
QgsDxfExport::DxfLayer::splitLayerAttribute
QString splitLayerAttribute() const
If the split layer attribute is set, the vector layer will be split into several dxf layers,...
Definition: qgsdxfexport.cpp:2393
qgsprocessingoutputs.h
QgsDxfExport::DxfLayer::layerOutputAttributeIndex
int layerOutputAttributeIndex() const
Returns the attribute index used to split into multiple layers.
Definition: qgsdxfexport.h:88
qgsprocessingparameters.h
QgsProcessingOutputString::typeName
static QString typeName()
Returns the type name for the output class.
Definition: qgsprocessingoutputs.h:346
QgsProcessingGui::WidgetType
WidgetType
Types of dialogs which Processing widgets can be created for.
Definition: qgsprocessinggui.h:38
QgsDxfExport::DxfLayer
Layers and optional attribute index to split into multiple layers using attribute value as layer name...
Definition: qgsdxfexport.h:73
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
QgsMapLayer::name
QString name
Definition: qgsmaplayer.h:76
QgsProcessingParameterVectorLayer::typeName
static QString typeName()
Returns the type name for the parameter class.
Definition: qgsprocessingparameters.h:2843
qgspanelwidget.h
qgsprocessingparameterdxflayers.h
QgsFieldComboBox::fieldChanged
void fieldChanged(const QString &fieldName)
Emitted when the currently selected field changes.
QgsProcessingParameterMapLayer::typeName
static QString typeName()
Returns the type name for the parameter class.
Definition: qgsprocessingparameters.h:2915
QgsProcessingOutputFile::typeName
static QString typeName()
Returns the type name for the output class.
Definition: qgsprocessingoutputs.h:413