QGIS API Documentation  3.18.1-Zürich (202f1bf7e5)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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 
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  int index = mLayer->fields().lookupField( mFieldsComboBox->currentField() );
59  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  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  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 
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->setMargin( 0 );
183  hl->setContentsMargins( 0, 0, 0, 0 );
184 
185  mLineEdit = new QLineEdit();
186  mLineEdit->setEnabled( false );
187  hl->addWidget( mLineEdit, 1 );
188 
189  mToolButton = new QToolButton();
190  mToolButton->setText( QString( QChar( 0x2026 ) ) );
191  hl->addWidget( mToolButton );
192 
193  setLayout( hl );
194 
195  updateSummaryText();
196 
197  connect( mToolButton, &QToolButton::clicked, this, &QgsProcessingDxfLayersWidget::showDialog );
198 }
199 
200 void QgsProcessingDxfLayersWidget::setValue( const QVariant &value )
201 {
202  if ( value.isValid() )
203  mValue = value.type() == QVariant::List ? value.toList() : QVariantList() << value;
204  else
205  mValue.clear();
206 
207  updateSummaryText();
208  emit changed();
209 }
210 
211 void QgsProcessingDxfLayersWidget::setProject( QgsProject *project )
212 {
213  mProject = project;
214 }
215 
216 void QgsProcessingDxfLayersWidget::showDialog()
217 {
219  if ( panel && panel->dockMode() )
220  {
221  QgsProcessingDxfLayersPanelWidget *widget = new QgsProcessingDxfLayersPanelWidget( mValue, mProject );
222  widget->setPanelTitle( tr( "Input layers" ) );
223  connect( widget, &QgsProcessingMultipleSelectionPanelWidget::selectionChanged, this, [ = ]()
224  {
225  setValue( widget->selectedOptions() );
226  } );
227  connect( widget, &QgsProcessingMultipleSelectionPanelWidget::acceptClicked, widget, &QgsPanelWidget::acceptPanel );
228  panel->openPanel( widget );
229  }
230  else
231  {
232  QDialog dlg;
233  dlg.setWindowTitle( tr( "Input layers" ) );
234  QVBoxLayout *vLayout = new QVBoxLayout();
235  QgsProcessingDxfLayersPanelWidget *widget = new QgsProcessingDxfLayersPanelWidget( mValue, mProject );
236  vLayout->addWidget( widget );
237  widget->buttonBox()->addButton( QDialogButtonBox::Cancel );
238  connect( widget->buttonBox(), &QDialogButtonBox::accepted, &dlg, &QDialog::accept );
239  connect( widget->buttonBox(), &QDialogButtonBox::rejected, &dlg, &QDialog::reject );
240  dlg.setLayout( vLayout );
241  if ( dlg.exec() )
242  {
243  setValue( widget->selectedOptions() );
244  }
245  }
246 }
247 
248 void QgsProcessingDxfLayersWidget::updateSummaryText()
249 {
250  mLineEdit->setText( tr( "%1 vector layers selected" ).arg( mValue.count() ) );
251 }
252 
253 
254 //
255 // QgsProcessingDxfLayersWidgetWrapper
256 //
257 
258 QgsProcessingDxfLayersWidgetWrapper::QgsProcessingDxfLayersWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type, QWidget *parent )
259  : QgsAbstractProcessingParameterWidgetWrapper( parameter, type, parent )
260 {
261 }
262 
263 QString QgsProcessingDxfLayersWidgetWrapper::parameterType() const
264 {
266 }
267 
268 QgsAbstractProcessingParameterWidgetWrapper *QgsProcessingDxfLayersWidgetWrapper::createWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type )
269 {
270  return new QgsProcessingDxfLayersWidgetWrapper( parameter, type );
271 }
272 
273 QWidget *QgsProcessingDxfLayersWidgetWrapper::createWidget()
274 {
275  mPanel = new QgsProcessingDxfLayersWidget( nullptr );
276  mPanel->setProject( widgetContext().project() );
277  connect( mPanel, &QgsProcessingDxfLayersWidget::changed, this, [ = ]
278  {
279  emit widgetValueHasChanged( this );
280  } );
281  return mPanel;
282 }
283 
284 void QgsProcessingDxfLayersWidgetWrapper::setWidgetContext( const QgsProcessingParameterWidgetContext &context )
285 {
287  if ( mPanel )
288  {
289  mPanel->setProject( context.project() );
290  }
291 }
292 
293 void QgsProcessingDxfLayersWidgetWrapper::setWidgetValue( const QVariant &value, QgsProcessingContext &context )
294 {
295  Q_UNUSED( context )
296  if ( mPanel )
297  {
298  mPanel->setValue( value );
299  }
300 }
301 
302 QVariant QgsProcessingDxfLayersWidgetWrapper::widgetValue() const
303 {
304  return mPanel ? mPanel->value() : QVariant();
305 }
306 
307 QStringList QgsProcessingDxfLayersWidgetWrapper::compatibleParameterTypes() const
308 {
309  return QStringList()
316 }
317 
318 QStringList QgsProcessingDxfLayersWidgetWrapper::compatibleOutputTypes() const
319 {
320  return QStringList()
326 }
327 
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:88
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:99
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:73
QgsVectorLayer * layer() const
Returns the layer.
Definition: qgsdxfexport.h:80
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:87