QGIS API Documentation  3.20.0-Odense (decaadbb31)
qgsvectorlayersaveasdialog.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsvectorlayersaveasdialog.h
3  Dialog to select destination, type and crs for ogr layers
4  -------------------
5  begin : Mon Mar 22 2010
6  copyright : (C) 2010 by Juergen E. Fischer
7  email : jef at norbit dot de
8  ***************************************************************************/
9 
10 /***************************************************************************
11  * *
12  * This program is free software; you can redistribute it and/or modify *
13  * it under the terms of the GNU General Public License as published by *
14  * the Free Software Foundation; either version 2 of the License, or *
15  * (at your option) any later version. *
16  * *
17  ***************************************************************************/
18 #include "qgslogger.h"
21 #include "qgsvectordataprovider.h"
23 #include "qgseditorwidgetfactory.h"
25 #include "qgssettings.h"
26 #include "qgsmapcanvas.h"
27 #include "qgsgui.h"
28 #include "qgsapplication.h"
29 #include "qgsogrdataitems.h"
30 #include <QMessageBox>
31 #include <QFileDialog>
32 #include <QTextCodec>
33 #include <QSpinBox>
34 #include <QRegularExpression>
35 #include "gdal.h"
36 #include "qgsdatums.h"
37 #include "qgsiconutils.h"
38 
39 static const int COLUMN_IDX_NAME = 0;
40 static const int COLUMN_IDX_TYPE = 1;
41 static const int COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE = 2;
42 
43 QgsVectorLayerSaveAsDialog::QgsVectorLayerSaveAsDialog( long srsid, QWidget *parent, Qt::WindowFlags fl )
44  : QDialog( parent, fl )
45  , mSelectedCrs( QgsCoordinateReferenceSystem::fromSrsId( srsid ) )
46  , mAttributeTableItemChangedSlotEnabled( true )
47  , mReplaceRawFieldValuesStateChangedSlotEnabled( true )
48  , mActionOnExistingFile( QgsVectorFileWriter::CreateOrOverwriteFile )
49 {
50  setup();
51 }
52 
53 QgsVectorLayerSaveAsDialog::QgsVectorLayerSaveAsDialog( QgsVectorLayer *layer, Options options, QWidget *parent, Qt::WindowFlags fl )
54  : QDialog( parent, fl )
55  , mLayer( layer )
56  , mAttributeTableItemChangedSlotEnabled( true )
57  , mReplaceRawFieldValuesStateChangedSlotEnabled( true )
58  , mActionOnExistingFile( QgsVectorFileWriter::CreateOrOverwriteFile )
59  , mOptions( options )
60 {
61  if ( layer )
62  {
63  mSelectedCrs = layer->crs();
64  mLayerExtent = layer->extent();
65  }
66  setup();
67 
68  if ( !( mOptions & Symbology ) )
69  {
70  mSymbologyExportLabel->hide();
71  mSymbologyExportComboBox->hide();
72  mScaleLabel->hide();
73  mScaleWidget->hide();
74  }
75 
76  if ( !( mOptions & DestinationCrs ) )
77  {
78  mCrsLabel->hide();
79  mCrsSelector->hide();
80  }
81  if ( !( mOptions & Fields ) )
82  mAttributesSelection->hide();
83 
84  if ( !( mOptions & SelectedOnly ) )
85  mSelectedOnly->hide();
86 
87  if ( !( mOptions & AddToCanvas ) )
88  mAddToCanvas->hide();
89 
90  if ( !( mOptions & GeometryType ) )
91  mGeometryGroupBox->hide();
92 
93  if ( !( mOptions & Extent ) )
94  mExtentGroupBox->hide();
95 
96  if ( !( mOptions & Metadata ) )
97  {
98  mCheckPersistMetadata->setChecked( false );
99  mCheckPersistMetadata->hide();
100  }
101 
102  mSelectedOnly->setEnabled( layer && layer->selectedFeatureCount() != 0 );
103  mButtonBox->button( QDialogButtonBox::Ok )->setDisabled( true );
104 }
105 
106 void QgsVectorLayerSaveAsDialog::setup()
107 {
108  setupUi( this );
110 
111  connect( mFormatComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsVectorLayerSaveAsDialog::mFormatComboBox_currentIndexChanged );
112  connect( mCrsSelector, &QgsProjectionSelectionWidget::crsChanged, this, &QgsVectorLayerSaveAsDialog::mCrsSelector_crsChanged );
113  connect( mSymbologyExportComboBox, &QComboBox::currentTextChanged, this, &QgsVectorLayerSaveAsDialog::mSymbologyExportComboBox_currentIndexChanged );
114  connect( mGeometryTypeComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsVectorLayerSaveAsDialog::mGeometryTypeComboBox_currentIndexChanged );
115  connect( mSelectAllAttributes, &QPushButton::clicked, this, &QgsVectorLayerSaveAsDialog::mSelectAllAttributes_clicked );
116  connect( mDeselectAllAttributes, &QPushButton::clicked, this, &QgsVectorLayerSaveAsDialog::mDeselectAllAttributes_clicked );
117  connect( mReplaceRawFieldValues, &QCheckBox::stateChanged, this, &QgsVectorLayerSaveAsDialog::mReplaceRawFieldValues_stateChanged );
118  connect( mAttributeTable, &QTableWidget::itemChanged, this, &QgsVectorLayerSaveAsDialog::mAttributeTable_itemChanged );
119 
120 #ifdef Q_OS_WIN
121  mHelpButtonBox->setVisible( false );
122  mButtonBox->addButton( QDialogButtonBox::Help );
123  connect( mButtonBox, &QDialogButtonBox::helpRequested, this, &QgsVectorLayerSaveAsDialog::showHelp );
124 #else
125  connect( mHelpButtonBox, &QDialogButtonBox::helpRequested, this, &QgsVectorLayerSaveAsDialog::showHelp );
126 #endif
127  connect( mButtonBox, &QDialogButtonBox::accepted, this, &QgsVectorLayerSaveAsDialog::accept );
128  connect( mButtonBox, &QDialogButtonBox::rejected, this, &QgsVectorLayerSaveAsDialog::reject );
129 
130  const QList< QgsVectorFileWriter::DriverDetails > drivers = QgsVectorFileWriter::ogrDriverList();
131  mFormatComboBox->blockSignals( true );
132  for ( const QgsVectorFileWriter::DriverDetails &driver : drivers )
133  {
134  mFormatComboBox->addItem( driver.longName, driver.driverName );
135  }
136 
137  QgsSettings settings;
138  QString format = settings.value( QStringLiteral( "UI/lastVectorFormat" ), "GPKG" ).toString();
139  mFormatComboBox->setCurrentIndex( mFormatComboBox->findData( format ) );
140  mFormatComboBox->blockSignals( false );
141 
142  const auto addGeomItem = [this]( QgsWkbTypes::Type type )
143  {
144  mGeometryTypeComboBox->addItem( QgsIconUtils::iconForWkbType( type ), QgsWkbTypes::translatedDisplayString( type ), type );
145  };
146 
147  //add geometry types to combobox
148  mGeometryTypeComboBox->addItem( tr( "Automatic" ), -1 );
149  addGeomItem( QgsWkbTypes::Point );
150  addGeomItem( QgsWkbTypes::LineString );
151  addGeomItem( QgsWkbTypes::Polygon );
153  addGeomItem( QgsWkbTypes::NoGeometry );
154  mGeometryTypeComboBox->setCurrentIndex( mGeometryTypeComboBox->findData( -1 ) );
155 
156  mEncodingComboBox->addItems( QgsVectorDataProvider::availableEncodings() );
157 
158  QString enc = settings.value( QStringLiteral( "UI/encoding" ), "System" ).toString();
159  int idx = mEncodingComboBox->findText( enc );
160  if ( idx < 0 )
161  {
162  mEncodingComboBox->insertItem( 0, enc );
163  idx = 0;
164  }
165 
166  mCrsSelector->setCrs( mSelectedCrs );
167  mCrsSelector->setLayerCrs( mSelectedCrs );
168  mCrsSelector->setMessage( tr( "Select the coordinate reference system for the vector file. "
169  "The data points will be transformed from the layer coordinate reference system." ) );
170 
171  mEncodingComboBox->setCurrentIndex( idx );
172  mFormatComboBox_currentIndexChanged( mFormatComboBox->currentIndex() );
173 
174  //symbology export combo box
175  mSymbologyExportComboBox->addItem( tr( "No Symbology" ), QgsVectorFileWriter::NoSymbology );
176  mSymbologyExportComboBox->addItem( tr( "Feature Symbology" ), QgsVectorFileWriter::FeatureSymbology );
177  mSymbologyExportComboBox->addItem( tr( "Symbol Layer Symbology" ), QgsVectorFileWriter::SymbolLayerSymbology );
178  mSymbologyExportComboBox_currentIndexChanged( mSymbologyExportComboBox->currentText() );
179 
180  // extent group box
181  mExtentGroupBox->setOutputCrs( mSelectedCrs );
182  mExtentGroupBox->setOriginalExtent( mLayerExtent, mSelectedCrs );
183  mExtentGroupBox->setOutputExtentFromOriginal();
184  mExtentGroupBox->setCheckable( true );
185  mExtentGroupBox->setChecked( false );
186  mExtentGroupBox->setCollapsed( true );
187 
188  mFilename->setStorageMode( QgsFileWidget::SaveFile );
189  mFilename->setDialogTitle( tr( "Save Layer As" ) );
190  mFilename->setDefaultRoot( settings.value( QStringLiteral( "UI/lastVectorFileFilterDir" ), QDir::homePath() ).toString() );
191  mFilename->setConfirmOverwrite( false );
192  connect( mFilename, &QgsFileWidget::fileChanged, this, [ = ]( const QString & filePath )
193  {
194  QgsSettings settings;
195  QFileInfo tmplFileInfo( filePath );
196  settings.setValue( QStringLiteral( "UI/lastVectorFileFilterDir" ), tmplFileInfo.absolutePath() );
197  if ( !filePath.isEmpty() && leLayername->isEnabled() )
198  {
199  QFileInfo fileInfo( filePath );
200  leLayername->setText( fileInfo.completeBaseName() );
201  }
202  mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( !filePath.isEmpty() );
203  } );
204 
205  try
206  {
207  const QgsDatumEnsemble ensemble = mSelectedCrs.datumEnsemble();
208  if ( ensemble.isValid() )
209  {
210  mCrsSelector->setSourceEnsemble( ensemble.name() );
211  }
212  }
213  catch ( QgsNotSupportedException & )
214  {
215  }
216 
217  mCrsSelector->setShowAccuracyWarnings( true );
218 }
219 
220 QList<QPair<QLabel *, QWidget *> > QgsVectorLayerSaveAsDialog::createControls( const QMap<QString, QgsVectorFileWriter::Option *> &options )
221 {
222  QList<QPair<QLabel *, QWidget *> > controls;
223  QMap<QString, QgsVectorFileWriter::Option *>::ConstIterator it;
224 
225  for ( it = options.constBegin(); it != options.constEnd(); ++it )
226  {
227  QgsVectorFileWriter::Option *option = it.value();
228  QLabel *label = new QLabel( it.key() );
229  QWidget *control = nullptr;
230  switch ( option->type )
231  {
233  {
234  QgsVectorFileWriter::IntOption *opt = dynamic_cast<QgsVectorFileWriter::IntOption *>( option );
235  if ( opt )
236  {
237  QSpinBox *sb = new QSpinBox();
238  sb->setObjectName( it.key() );
239  sb->setValue( opt->defaultValue );
240  control = sb;
241  }
242  break;
243  }
244 
246  {
247  QgsVectorFileWriter::SetOption *opt = dynamic_cast<QgsVectorFileWriter::SetOption *>( option );
248  if ( opt )
249  {
250  QComboBox *cb = new QComboBox();
251  cb->setObjectName( it.key() );
252  for ( const QString &val : std::as_const( opt->values ) )
253  {
254  cb->addItem( val, val );
255  }
256  if ( opt->allowNone )
257  cb->addItem( tr( "<Default>" ), QVariant( QVariant::String ) );
258  int idx = cb->findText( opt->defaultValue );
259  if ( idx == -1 )
260  idx = cb->findData( QVariant( QVariant::String ) );
261  cb->setCurrentIndex( idx );
262  control = cb;
263  }
264  break;
265  }
266 
268  {
270  if ( opt )
271  {
272  QLineEdit *le = new QLineEdit( opt->defaultValue );
273  le->setObjectName( it.key() );
274  control = le;
275  }
276  break;
277  }
278 
280  control = nullptr;
281  break;
282  }
283 
284  if ( control )
285  {
286  // Pack the tooltip in some html element, so it gets linebreaks.
287  label->setToolTip( QStringLiteral( "<p>%1</p>" ).arg( option->docString ) );
288  control->setToolTip( QStringLiteral( "<p>%1</p>" ).arg( option->docString ) );
289 
290  controls << QPair<QLabel *, QWidget *>( label, control );
291  }
292  }
293 
294  return controls;
295 }
296 
297 void QgsVectorLayerSaveAsDialog::accept()
298 {
299  if ( QFile::exists( filename() ) )
300  {
301  QgsVectorFileWriter::EditionCapabilities caps =
303  bool layerExists = QgsVectorFileWriter::targetLayerExists( filename(),
304  layername() );
305  QMessageBox msgBox;
306  msgBox.setIcon( QMessageBox::Question );
307  msgBox.setWindowTitle( tr( "Save Vector Layer As" ) );
308  QPushButton *overwriteFileButton = msgBox.addButton( tr( "Overwrite File" ), QMessageBox::ActionRole );
309  QPushButton *overwriteLayerButton = msgBox.addButton( tr( "Overwrite Layer" ), QMessageBox::ActionRole );
310  QPushButton *appendToLayerButton = msgBox.addButton( tr( "Append to Layer" ), QMessageBox::ActionRole );
311  msgBox.setStandardButtons( QMessageBox::Cancel );
312  msgBox.setDefaultButton( QMessageBox::Cancel );
313  overwriteFileButton->hide();
314  overwriteLayerButton->hide();
315  appendToLayerButton->hide();
316  if ( layerExists )
317  {
321  {
322  msgBox.setText( tr( "The layer already exists. Do you want to overwrite the whole file or overwrite the layer?" ) );
323  overwriteFileButton->setVisible( true );
324  overwriteLayerButton->setVisible( true );
325  }
326  else if ( !( caps & QgsVectorFileWriter::CanAppendToExistingLayer ) )
327  {
328  msgBox.setText( tr( "The file already exists. Do you want to overwrite it?" ) );
329  overwriteFileButton->setVisible( true );
330  }
331  else if ( ( caps & QgsVectorFileWriter::CanDeleteLayer ) &&
333  {
334  msgBox.setText( tr( "The layer already exists. Do you want to overwrite the whole file, overwrite the layer or append features to the layer?" ) );
335  appendToLayerButton->setVisible( true );
336  overwriteFileButton->setVisible( true );
337  overwriteLayerButton->setVisible( true );
338  }
339  else
340  {
341  msgBox.setText( tr( "The layer already exists. Do you want to overwrite the whole file or append features to the layer?" ) );
342  appendToLayerButton->setVisible( true );
343  overwriteFileButton->setVisible( true );
344  }
345 
346  int ret = msgBox.exec();
347  if ( ret == QMessageBox::Cancel )
348  return;
349  if ( msgBox.clickedButton() == overwriteFileButton )
350  mActionOnExistingFile = QgsVectorFileWriter::CreateOrOverwriteFile;
351  else if ( msgBox.clickedButton() == overwriteLayerButton )
352  mActionOnExistingFile = QgsVectorFileWriter::CreateOrOverwriteLayer;
353  else if ( msgBox.clickedButton() == appendToLayerButton )
354  mActionOnExistingFile = QgsVectorFileWriter::AppendToLayerNoNewFields;
355  }
356  else // !layerExists
357  {
358  if ( ( caps & QgsVectorFileWriter::CanAddNewLayer ) )
359  {
360  mActionOnExistingFile = QgsVectorFileWriter::CreateOrOverwriteLayer;
361  }
362  else
363  {
364  // should not reach here, layer does not exist and cannot add new layer
365  if ( QMessageBox::question( this,
366  tr( "Save Vector Layer As" ),
367  tr( "The file already exists. Do you want to overwrite it?" ) ) == QMessageBox::NoButton )
368  {
369  return;
370  }
371  mActionOnExistingFile = QgsVectorFileWriter::CreateOrOverwriteFile;
372  }
373  }
374  }
375 
376  if ( mActionOnExistingFile == QgsVectorFileWriter::AppendToLayerNoNewFields )
377  {
379  {
380  if ( QMessageBox::question( this,
381  tr( "Save Vector Layer As" ),
382  tr( "The existing layer has additional fields. Do you want to add the missing fields to the layer?" ) ) == QMessageBox::Yes )
383  {
384  mActionOnExistingFile = QgsVectorFileWriter::AppendToLayerAddFields;
385  }
386  }
387  }
388  else if ( mActionOnExistingFile == QgsVectorFileWriter::CreateOrOverwriteFile && QFile::exists( filename() ) )
389  {
390  try
391  {
392  const QList<QgsOgrDbLayerInfo *> subLayers = QgsOgrLayerItem::subLayers( filename(), format() );
393  QStringList layerList;
394  for ( const QgsOgrDbLayerInfo *layer : subLayers )
395  {
396  layerList.append( layer->name() );
397  }
398  qDeleteAll( subLayers );
399  if ( layerList.length() > 1 )
400  {
401  layerList.sort( Qt::CaseInsensitive );
402  QMessageBox msgBox;
403  msgBox.setIcon( QMessageBox::Warning );
404  msgBox.setWindowTitle( tr( "Overwrite File" ) );
405  msgBox.setText( tr( "This file contains %1 layers that will be lost!\n" ).arg( QString::number( layerList.length() ) ) );
406  msgBox.setDetailedText( tr( "The following layers will be permanently lost:\n\n%1" ).arg( layerList.join( "\n" ) ) );
407  msgBox.setStandardButtons( QMessageBox::Ok | QMessageBox::Cancel );
408  if ( msgBox.exec() == QMessageBox::Cancel )
409  return;
410  }
411  }
412  catch ( QgsOgrLayerNotValidException &ex )
413  {
414  QMessageBox::critical( this,
415  tr( "Save Vector Layer As" ),
416  tr( "Error opening destination file: %1" ).arg( ex.what() ) );
417  return;
418  }
419  }
420 
421  QgsSettings settings;
422  settings.setValue( QStringLiteral( "UI/lastVectorFileFilterDir" ), QFileInfo( filename() ).absolutePath() );
423  settings.setValue( QStringLiteral( "UI/lastVectorFormat" ), format() );
424  settings.setValue( QStringLiteral( "UI/encoding" ), encoding() );
425  QDialog::accept();
426 }
427 
428 void QgsVectorLayerSaveAsDialog::mFormatComboBox_currentIndexChanged( int idx )
429 {
430  Q_UNUSED( idx )
431 
432  mFilename->setEnabled( true );
433  mFilename->setFilter( QgsVectorFileWriter::filterForDriver( format() ) );
434 
435  // if output filename already defined we need to replace old suffix
436  // to avoid double extensions like .gpkg.shp
437  if ( !mFilename->filePath().isEmpty() )
438  {
439  QRegularExpression rx( "\\.(.*?)[\\s]" );
440  QString ext;
441  ext = rx.match( QgsVectorFileWriter::filterForDriver( format() ) ).captured( 1 );
442  if ( !ext.isEmpty() )
443  {
444  QFileInfo fi( mFilename->filePath() );
445  mFilename->setFilePath( QStringLiteral( "%1/%2.%3" ).arg( fi.path() ).arg( fi.baseName() ).arg( ext ) );
446  }
447  }
448 
449  bool selectAllFields = true;
450 
451  // Is it a format for which fields that have attached widgets of types
452  // ValueMap, ValueRelation, etc. should be by default exported with their displayed
453  // values
454  bool isFormatForFieldsAsDisplayedValues = false;
455 
456  const QString sFormat( format() );
457  if ( sFormat == QLatin1String( "DXF" ) || sFormat == QLatin1String( "DGN" ) )
458  {
459  mAttributesSelection->setVisible( false );
460  selectAllFields = false;
461  }
462  else
463  {
464  if ( mOptions & Fields )
465  {
466  mAttributesSelection->setVisible( true );
467  isFormatForFieldsAsDisplayedValues = ( sFormat == QLatin1String( "CSV" ) ||
468  sFormat == QLatin1String( "XLS" ) ||
469  sFormat == QLatin1String( "XLSX" ) ||
470  sFormat == QLatin1String( "ODS" ) );
471  }
472  }
473 
474  // Show symbology options only for some formats
475  if ( QgsVectorFileWriter::supportsFeatureStyles( sFormat ) && ( mOptions & Symbology ) )
476  {
477  mSymbologyExportLabel->setVisible( true );
478  mSymbologyExportComboBox->setVisible( true );
479  mScaleLabel->setVisible( true );
480  mScaleWidget->setVisible( true );
481  }
482  else
483  {
484  mSymbologyExportLabel->hide();
485  mSymbologyExportComboBox->hide();
486  mScaleLabel->hide();
487  mScaleWidget->hide();
488  }
489 
490  leLayername->setEnabled( sFormat == QLatin1String( "KML" ) ||
491  sFormat == QLatin1String( "GPKG" ) ||
492  sFormat == QLatin1String( "XLSX" ) ||
493  sFormat == QLatin1String( "ODS" ) ||
494  sFormat == QLatin1String( "FileGDB" ) ||
495  sFormat == QLatin1String( "SQLite" ) ||
496  sFormat == QLatin1String( "SpatiaLite" ) );
497  if ( !leLayername->isEnabled() )
498  leLayername->setText( QString() );
499  else if ( leLayername->text().isEmpty() &&
500  !mFilename->filePath().isEmpty() )
501  {
502  QString layerName = QFileInfo( mFilename->filePath() ).baseName();
503  leLayername->setText( layerName );
504  }
505 
506  if ( mLayer )
507  {
508  mAttributeTable->setRowCount( mLayer->fields().count() );
509 
510  bool foundFieldThatCanBeExportedAsDisplayedValue = false;
511  for ( int i = 0; i < mLayer->fields().size(); ++i )
512  {
513  const QgsEditorWidgetSetup setup = QgsGui::editorWidgetRegistry()->findBest( mLayer, mLayer->fields()[i].name() );
514  if ( setup.type() != QLatin1String( "TextEdit" ) &&
515  QgsGui::editorWidgetRegistry()->factory( setup.type() ) )
516  {
517  foundFieldThatCanBeExportedAsDisplayedValue = true;
518  break;
519  }
520  }
521  if ( foundFieldThatCanBeExportedAsDisplayedValue )
522  {
523  mAttributeTable->setColumnCount( 3 );
524  mAttributeTable->setHorizontalHeaderLabels( QStringList() << tr( "Name" ) << tr( "Type" ) << tr( "Replace with displayed values" ) );
525  }
526  else
527  {
528  mAttributeTable->setColumnCount( 2 );
529  mAttributeTable->setHorizontalHeaderLabels( QStringList() << tr( "Name" ) << tr( "Type" ) );
530  }
531 
532  mAttributeTableItemChangedSlotEnabled = false;
533 
534  bool checkReplaceRawFieldValues = selectAllFields && isFormatForFieldsAsDisplayedValues;
535  for ( int i = 0; i < mLayer->fields().size(); ++i )
536  {
537  QgsField fld = mLayer->fields().at( i );
538  Qt::ItemFlags flags = mLayer->providerType() != QLatin1String( "oracle" ) || !fld.typeName().contains( QLatin1String( "SDO_GEOMETRY" ) ) ? Qt::ItemIsEnabled : Qt::NoItemFlags;
539  QTableWidgetItem *item = nullptr;
540  item = new QTableWidgetItem( fld.name() );
541  item->setFlags( flags | Qt::ItemIsUserCheckable );
542  item->setCheckState( ( selectAllFields ) ? Qt::Checked : Qt::Unchecked );
543  mAttributeTable->setItem( i, COLUMN_IDX_NAME, item );
544 
545  item = new QTableWidgetItem( fld.typeName() );
546  item->setFlags( flags );
547  mAttributeTable->setItem( i, COLUMN_IDX_TYPE, item );
548 
549  if ( foundFieldThatCanBeExportedAsDisplayedValue )
550  {
551  const QgsEditorWidgetSetup setup = QgsGui::editorWidgetRegistry()->findBest( mLayer, mLayer->fields()[i].name() );
552  QgsEditorWidgetFactory *factory = nullptr;
553  const QString widgetId( setup.type() );
554  if ( flags == Qt::ItemIsEnabled &&
555  widgetId != QLatin1String( "TextEdit" ) &&
556  ( factory = QgsGui::editorWidgetRegistry()->factory( widgetId ) ) )
557  {
558  item = new QTableWidgetItem( tr( "Use %1" ).arg( factory->name() ) );
559  item->setFlags( ( selectAllFields ) ? ( Qt::ItemIsEnabled | Qt::ItemIsUserCheckable ) : Qt::ItemIsUserCheckable );
560  const bool checkItem = ( selectAllFields && isFormatForFieldsAsDisplayedValues &&
561  ( widgetId == QLatin1String( "ValueMap" ) ||
562  widgetId == QLatin1String( "ValueRelation" ) ||
563  widgetId == QLatin1String( "CheckBox" ) ||
564  widgetId == QLatin1String( "RelationReference" ) ) );
565  checkReplaceRawFieldValues &= checkItem;
566  item->setCheckState( checkItem ?
567  Qt::Checked : Qt::Unchecked );
568  mAttributeTable->setItem( i, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE, item );
569  }
570  else
571  {
572  item = new QTableWidgetItem();
573  item->setFlags( Qt::NoItemFlags );
574  mAttributeTable->setItem( i, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE, item );
575  }
576  }
577  }
578 
579  mAttributeTableItemChangedSlotEnabled = true;
580 
581  mReplaceRawFieldValuesStateChangedSlotEnabled = false;
582  mReplaceRawFieldValues->setChecked( checkReplaceRawFieldValues );
583  mReplaceRawFieldValuesStateChangedSlotEnabled = true;
584  mReplaceRawFieldValues->setEnabled( selectAllFields );
585  mReplaceRawFieldValues->setVisible( foundFieldThatCanBeExportedAsDisplayedValue );
586 
587  mAttributeTable->resizeColumnsToContents();
588  }
589 
590  QgsVectorFileWriter::MetaData driverMetaData;
591 
592  while ( mDatasourceOptionsGroupBox->layout()->count() )
593  {
594  QLayoutItem *item = mDatasourceOptionsGroupBox->layout()->takeAt( 0 );
595  delete item->widget();
596  delete item;
597  }
598 
599  while ( mLayerOptionsGroupBox->layout()->count() )
600  {
601  QLayoutItem *item = mLayerOptionsGroupBox->layout()->takeAt( 0 );
602  delete item->widget();
603  delete item;
604  }
605 
606  typedef QPair<QLabel *, QWidget *> LabelControlPair;
607 
608  if ( QgsVectorFileWriter::driverMetadata( format(), driverMetaData ) )
609  {
610  if ( !driverMetaData.driverOptions.empty() )
611  {
612  mDatasourceOptionsGroupBox->setVisible( true );
613  QList<QPair<QLabel *, QWidget *> > controls = createControls( driverMetaData.driverOptions );
614 
615  QFormLayout *datasourceLayout = dynamic_cast<QFormLayout *>( mDatasourceOptionsGroupBox->layout() );
616 
617  const auto constControls = controls;
618  for ( LabelControlPair control : constControls )
619  {
620  datasourceLayout->addRow( control.first, control.second );
621  }
622  }
623  else
624  {
625  mDatasourceOptionsGroupBox->setVisible( false );
626  }
627 
628  if ( !driverMetaData.layerOptions.empty() )
629  {
630  mLayerOptionsGroupBox->setVisible( true );
631  QList<QPair<QLabel *, QWidget *> > controls = createControls( driverMetaData.layerOptions );
632 
633  QFormLayout *layerOptionsLayout = dynamic_cast<QFormLayout *>( mLayerOptionsGroupBox->layout() );
634 
635  const auto constControls = controls;
636  for ( LabelControlPair control : constControls )
637  {
638  layerOptionsLayout->addRow( control.first, control.second );
639  }
640  }
641  else
642  {
643  mLayerOptionsGroupBox->setVisible( false );
644  }
645 
646  if ( driverMetaData.compulsoryEncoding.isEmpty() )
647  {
648  mEncodingComboBox->setEnabled( true );
649  }
650  else
651  {
652  int idx = mEncodingComboBox->findText( driverMetaData.compulsoryEncoding );
653  if ( idx >= 0 )
654  {
655  mEncodingComboBox->setCurrentIndex( idx );
656  mEncodingComboBox->setDisabled( true );
657  }
658  else
659  {
660  mEncodingComboBox->setEnabled( true );
661  }
662  }
663 
664  }
665  else
666  {
667  mEncodingComboBox->setEnabled( true );
668  }
669 
670  GDALDriverH hDriver = GDALGetDriverByName( format().toUtf8().constData() );
671  if ( hDriver )
672  {
673  mAddToCanvas->setEnabled( GDALGetMetadataItem( hDriver, GDAL_DCAP_OPEN, nullptr ) != nullptr );
674  }
675 }
676 
677 void QgsVectorLayerSaveAsDialog::mReplaceRawFieldValues_stateChanged( int )
678 {
679  if ( !mReplaceRawFieldValuesStateChangedSlotEnabled )
680  return;
681  if ( mAttributeTable->columnCount() != 3 )
682  return;
683  mReplaceRawFieldValuesStateChangedSlotEnabled = false;
684  mAttributeTableItemChangedSlotEnabled = false;
685  if ( mReplaceRawFieldValues->checkState() != Qt::PartiallyChecked )
686  {
687  for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
688  {
689  if ( mAttributeTable->item( i, COLUMN_IDX_NAME )->checkState() == Qt::Checked &&
690  mAttributeTable->item( i, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE ) &&
691  mAttributeTable->item( i, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE )->flags() & Qt::ItemIsEnabled )
692  {
693  mAttributeTable->item( i, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE )->setCheckState( mReplaceRawFieldValues->checkState() );
694  }
695  }
696  }
697  mReplaceRawFieldValues->setTristate( false );
698  mAttributeTableItemChangedSlotEnabled = true;
699  mReplaceRawFieldValuesStateChangedSlotEnabled = true;
700 }
701 
702 void QgsVectorLayerSaveAsDialog::mAttributeTable_itemChanged( QTableWidgetItem *item )
703 {
704  if ( !mAttributeTableItemChangedSlotEnabled )
705  return;
706  mReplaceRawFieldValuesStateChangedSlotEnabled = false;
707  mAttributeTableItemChangedSlotEnabled = false;
708  int row = item->row();
709  int column = item->column();
710  if ( column == COLUMN_IDX_NAME &&
711  mAttributeTable->item( row, column )->checkState() == Qt::Unchecked &&
712  mAttributeTable->columnCount() == 3 &&
713  mAttributeTable->item( row, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE ) &&
714  ( mAttributeTable->item( row, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE )->flags() & Qt::ItemIsUserCheckable ) )
715  {
716  mAttributeTable->item( row, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE )->setCheckState( Qt::Unchecked );
717  mAttributeTable->item( row, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE )->setFlags( Qt::ItemIsUserCheckable );
718  bool checkBoxEnabled = false;
719  for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
720  {
721  if ( mAttributeTable->item( i, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE ) &&
722  mAttributeTable->item( i, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE )->flags() & Qt::ItemIsEnabled )
723  {
724  checkBoxEnabled = true;
725  break;
726  }
727  }
728  mReplaceRawFieldValues->setEnabled( checkBoxEnabled );
729  if ( !checkBoxEnabled )
730  mReplaceRawFieldValues->setCheckState( Qt::Unchecked );
731  }
732  else if ( column == COLUMN_IDX_NAME &&
733  mAttributeTable->item( row, column )->checkState() == Qt::Checked &&
734  mAttributeTable->columnCount() == 3 &&
735  mAttributeTable->item( row, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE ) &&
736  ( mAttributeTable->item( row, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE )->flags() & Qt::ItemIsUserCheckable ) )
737  {
738  mAttributeTable->item( row, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE )->setFlags( Qt::ItemIsUserCheckable | Qt::ItemIsEnabled );
739  mReplaceRawFieldValues->setEnabled( true );
740  }
741  else if ( column == COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE &&
742  ( mAttributeTable->item( row, column )->flags() & Qt::ItemIsUserCheckable ) )
743  {
744  bool allChecked = true;
745  bool allUnchecked = true;
746  for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
747  {
748  if ( mAttributeTable->item( i, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE ) &&
749  mAttributeTable->item( i, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE )->flags() & Qt::ItemIsEnabled )
750  {
751  if ( mAttributeTable->item( i, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE )->checkState() == Qt::Unchecked )
752  allChecked = false;
753  else
754  allUnchecked = false;
755  }
756  }
757  mReplaceRawFieldValues->setCheckState( ( !allChecked && !allUnchecked ) ? Qt::PartiallyChecked : ( allChecked ) ? Qt::Checked : Qt::Unchecked );
758  }
759  mAttributeTableItemChangedSlotEnabled = true;
760  mReplaceRawFieldValuesStateChangedSlotEnabled = true;
761 }
762 
763 void QgsVectorLayerSaveAsDialog::mCrsSelector_crsChanged( const QgsCoordinateReferenceSystem &crs )
764 {
765  mSelectedCrs = crs;
766  mExtentGroupBox->setOutputCrs( mSelectedCrs );
767 }
768 
770 {
771  return mFilename->filePath();
772 }
773 
775 {
776  return leLayername->text();
777 }
778 
780 {
781  return mEncodingComboBox->currentText();
782 }
783 
785 {
786  return mFormatComboBox->currentData().toString();
787 }
788 
790 {
791  return mSelectedCrs.srsid();
792 }
793 
795 {
796  return mSelectedCrs;
797 }
798 
800 {
801  QStringList options;
802 
803  QgsVectorFileWriter::MetaData driverMetaData;
804 
805  if ( QgsVectorFileWriter::driverMetadata( format(), driverMetaData ) )
806  {
807  QMap<QString, QgsVectorFileWriter::Option *>::ConstIterator it;
808 
809  for ( it = driverMetaData.driverOptions.constBegin(); it != driverMetaData.driverOptions.constEnd(); ++it )
810  {
811  switch ( it.value()->type )
812  {
814  {
816  QSpinBox *sb = mDatasourceOptionsGroupBox->findChild<QSpinBox *>( it.key() );
817  if ( opt && sb && sb->value() != opt->defaultValue )
818  options << QStringLiteral( "%1=%2" ).arg( it.key() ).arg( sb->value() );
819  break;
820  }
821 
823  {
825  QComboBox *cb = mDatasourceOptionsGroupBox->findChild<QComboBox *>( it.key() );
826  if ( opt && cb && cb->itemData( cb->currentIndex() ) != opt->defaultValue )
827  options << QStringLiteral( "%1=%2" ).arg( it.key(), cb->currentText() );
828  break;
829  }
830 
832  {
834  QLineEdit *le = mDatasourceOptionsGroupBox->findChild<QLineEdit *>( it.key() );
835  if ( opt && le && le->text() != opt->defaultValue )
836  options << QStringLiteral( "%1=%2" ).arg( it.key(), le->text() );
837  break;
838  }
839 
841  {
843  dynamic_cast<QgsVectorFileWriter::HiddenOption *>( it.value() );
844  options << QStringLiteral( "%1=%2" ).arg( it.key(), opt->mValue );
845  break;
846  }
847  }
848  }
849  }
850 
851  QString plainText = mOgrDatasourceOptions->toPlainText().trimmed();
852  if ( !plainText.isEmpty() )
853  options += plainText.split( '\n' );
854 
855  return options;
856 }
857 
859 {
860  QStringList options;
861 
862  QgsVectorFileWriter::MetaData driverMetaData;
863 
864  if ( QgsVectorFileWriter::driverMetadata( format(), driverMetaData ) )
865  {
866  QMap<QString, QgsVectorFileWriter::Option *>::ConstIterator it;
867 
868  for ( it = driverMetaData.layerOptions.constBegin(); it != driverMetaData.layerOptions.constEnd(); ++it )
869  {
870  switch ( it.value()->type )
871  {
873  {
875  QSpinBox *sb = mLayerOptionsGroupBox->findChild<QSpinBox *>( it.key() );
876  if ( opt && sb && sb->value() != opt->defaultValue )
877  options << QStringLiteral( "%1=%2" ).arg( it.key() ).arg( sb->value() );
878  break;
879  }
880 
882  {
884  QComboBox *cb = mLayerOptionsGroupBox->findChild<QComboBox *>( it.key() );
885  if ( opt && cb && cb->itemData( cb->currentIndex() ) != opt->defaultValue )
886  options << QStringLiteral( "%1=%2" ).arg( it.key(), cb->currentText() );
887  break;
888  }
889 
891  {
893  QLineEdit *le = mLayerOptionsGroupBox->findChild<QLineEdit *>( it.key() );
894  if ( opt && le && le->text() != opt->defaultValue )
895  options << QStringLiteral( "%1=%2" ).arg( it.key(), le->text() );
896  break;
897  }
898 
900  {
902  dynamic_cast<QgsVectorFileWriter::HiddenOption *>( it.value() );
903  options << QStringLiteral( "%1=%2" ).arg( it.key(), opt->mValue );
904  break;
905  }
906  }
907  }
908  }
909 
910  QString plainText = mOgrLayerOptions->toPlainText().trimmed();
911  if ( !plainText.isEmpty() )
912  options += plainText.split( '\n' );
913 
914  return options;
915 }
916 
918 {
919  QgsAttributeList attributes;
920 
921  for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
922  {
923  if ( mAttributeTable->item( i, COLUMN_IDX_NAME )->checkState() == Qt::Checked )
924  {
925  attributes.append( i );
926  }
927  }
928 
929  return attributes;
930 }
931 
933 {
934  QgsAttributeList attributes;
935 
936  for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
937  {
938  if ( mAttributeTable->item( i, COLUMN_IDX_NAME )->checkState() == Qt::Checked &&
939  mAttributeTable->columnCount() == 3 &&
940  mAttributeTable->item( i, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE )->checkState() == Qt::Checked )
941  {
942  attributes.append( i );
943  }
944  }
945 
946  return attributes;
947 }
948 
950 {
951  return mAddToCanvas->isChecked() && mAddToCanvas->isEnabled();
952 }
953 
955 {
956  mAddToCanvas->setChecked( enabled );
957 }
958 
960 {
961  return mSymbologyExportComboBox->currentData().toInt();
962 }
963 
965 {
966  return mScaleWidget->scale();
967 }
968 
970 {
971  mMapCanvas = canvas;
972  mScaleWidget->setMapCanvas( canvas );
973  mScaleWidget->setShowCurrentScaleButton( true );
974  mExtentGroupBox->setCurrentExtent( canvas->mapSettings().visibleExtent(), canvas->mapSettings().destinationCrs() );
975 }
976 
978 {
979  return mExtentGroupBox->isChecked();
980 }
981 
983 {
984  return mExtentGroupBox->outputExtent();
985 }
986 
988 {
989  mSelectedOnly->setChecked( onlySelected );
990 }
991 
993 {
994  return mSelectedOnly->isChecked();
995 }
996 
998 {
999  return mCheckPersistMetadata->isChecked();
1000 }
1001 
1003 {
1004  int currentIndexData = mGeometryTypeComboBox->currentData().toInt();
1005  if ( currentIndexData == -1 )
1006  {
1007  //automatic
1008  return QgsWkbTypes::Unknown;
1009  }
1010 
1011  return static_cast< QgsWkbTypes::Type >( currentIndexData );
1012 }
1013 
1015 {
1016  int currentIndexData = mGeometryTypeComboBox->currentData().toInt();
1017  return currentIndexData == -1;
1018 }
1019 
1021 {
1022  return mForceMultiCheckBox->isChecked();
1023 }
1024 
1026 {
1027  mForceMultiCheckBox->setChecked( checked );
1028 }
1029 
1031 {
1032  return mIncludeZCheckBox->isChecked();
1033 }
1034 
1036 {
1037  return mActionOnExistingFile;
1038 }
1039 
1041 {
1042  mIncludeZCheckBox->setChecked( checked );
1043 }
1044 
1045 void QgsVectorLayerSaveAsDialog::mSymbologyExportComboBox_currentIndexChanged( const QString &text )
1046 {
1047  bool scaleEnabled = true;
1048  if ( text == tr( "No symbology" ) )
1049  {
1050  scaleEnabled = false;
1051  }
1052  mScaleWidget->setEnabled( scaleEnabled );
1053  mScaleLabel->setEnabled( scaleEnabled );
1054 }
1055 
1056 void QgsVectorLayerSaveAsDialog::mGeometryTypeComboBox_currentIndexChanged( int index )
1057 {
1058  int currentIndexData = mGeometryTypeComboBox->itemData( index ).toInt();
1059 
1060  if ( currentIndexData != -1 && currentIndexData != QgsWkbTypes::NoGeometry )
1061  {
1062  mForceMultiCheckBox->setEnabled( true );
1063  mIncludeZCheckBox->setEnabled( true );
1064  }
1065  else
1066  {
1067  mForceMultiCheckBox->setEnabled( false );
1068  mForceMultiCheckBox->setChecked( false );
1069  mIncludeZCheckBox->setEnabled( false );
1070  mIncludeZCheckBox->setChecked( false );
1071  }
1072 }
1073 
1074 void QgsVectorLayerSaveAsDialog::mSelectAllAttributes_clicked()
1075 {
1076  mAttributeTableItemChangedSlotEnabled = false;
1077  mReplaceRawFieldValuesStateChangedSlotEnabled = false;
1078  for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
1079  {
1080  if ( mAttributeTable->item( i, COLUMN_IDX_NAME )->flags() & Qt::ItemIsEnabled )
1081  {
1082  if ( mAttributeTable->columnCount() == 3 &&
1083  ( mAttributeTable->item( i, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE )->flags() & Qt::ItemIsUserCheckable ) )
1084  {
1085  mAttributeTable->item( i, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE )->setFlags( Qt::ItemIsUserCheckable | Qt::ItemIsEnabled );
1086  }
1087  mAttributeTable->item( i, COLUMN_IDX_NAME )->setCheckState( Qt::Checked );
1088  }
1089  }
1090  if ( mAttributeTable->columnCount() == 3 )
1091  {
1092  mReplaceRawFieldValues->setEnabled( true );
1093  }
1094  mAttributeTableItemChangedSlotEnabled = true;
1095  mReplaceRawFieldValuesStateChangedSlotEnabled = true;
1096 }
1097 
1098 void QgsVectorLayerSaveAsDialog::mDeselectAllAttributes_clicked()
1099 {
1100  mAttributeTableItemChangedSlotEnabled = false;
1101  mReplaceRawFieldValuesStateChangedSlotEnabled = false;
1102  for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
1103  {
1104  mAttributeTable->item( i, COLUMN_IDX_NAME )->setCheckState( Qt::Unchecked );
1105  if ( mAttributeTable->columnCount() == 3 &&
1106  ( mAttributeTable->item( i, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE )->flags() & Qt::ItemIsUserCheckable ) )
1107  {
1108  mAttributeTable->item( i, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE )->setFlags( Qt::ItemIsUserCheckable );
1109  mAttributeTable->item( i, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE )->setCheckState( Qt::Unchecked );
1110  }
1111  }
1112  if ( mAttributeTable->columnCount() == 3 )
1113  {
1114  mReplaceRawFieldValues->setCheckState( Qt::Unchecked );
1115  mReplaceRawFieldValues->setEnabled( false );
1116  }
1117  mAttributeTableItemChangedSlotEnabled = true;
1118  mReplaceRawFieldValuesStateChangedSlotEnabled = true;
1119 }
1120 
1121 void QgsVectorLayerSaveAsDialog::showHelp()
1122 {
1123  QgsHelp::openHelp( QStringLiteral( "managing_data_source/create_layers.html#creating-new-layers-from-an-existing-layer" ) );
1124 }
This class represents a coordinate reference system (CRS).
QgsDatumEnsemble datumEnsemble() const SIP_THROW(QgsNotSupportedException)
Attempts to retrieve datum ensemble details from the CRS.
long srsid() const
Returns the internal CRS ID, if available.
Contains information about a datum ensemble.
Definition: qgsdatums.h:95
bool isValid() const
Returns true if the datum ensemble is a valid object, or false if it is a null/invalid object.
Definition: qgsdatums.h:102
QString name() const
Display name of datum ensemble.
Definition: qgsdatums.h:107
Every attribute editor widget needs a factory, which inherits this class.
QString name()
Returns The human readable identifier name of this widget type.
QgsEditorWidgetSetup findBest(const QgsVectorLayer *vl, const QString &fieldName) const
Find the best editor widget and its configuration for a given field.
Holder for the widget type and its configuration for a field.
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:51
QString typeName() const
Gets the field type.
Definition: qgsfield.cpp:138
QString name
Definition: qgsfield.h:60
int count() const
Returns number of items.
Definition: qgsfields.cpp:133
QgsField at(int i) const
Returns the field at particular index (must be in range 0..N-1).
Definition: qgsfields.cpp:163
@ SaveFile
Select a single new or pre-existing file.
Definition: qgsfilewidget.h:69
void fileChanged(const QString &path)
Emitted whenever the current file or directory path is changed.
static QgsEditorWidgetRegistry * editorWidgetRegistry()
Returns the global editor widget registry, used for managing all known edit widget factories.
Definition: qgsgui.cpp:76
static void enableAutoGeometryRestore(QWidget *widget, const QString &key=QString())
Register the widget to allow its position to be automatically saved and restored when open and closed...
Definition: qgsgui.cpp:156
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
Definition: qgshelp.cpp:36
static QIcon iconForWkbType(QgsWkbTypes::Type type)
Returns the icon for a vector layer whose geometry type is provided.
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:86
const QgsMapSettings & mapSettings() const
Gets access to properties used for map rendering.
QString providerType() const
Returns the provider type (provider key) for this layer.
QgsCoordinateReferenceSystem crs
Definition: qgsmaplayer.h:76
QgsRectangle visibleExtent() const
Returns the actual extent derived from requested extent that takes takes output image size into accou...
QgsCoordinateReferenceSystem destinationCrs() const
Returns the destination coordinate reference system for the map render.
Custom exception class which is raised when an operation is not supported.
Definition: qgsexception.h:118
void crsChanged(const QgsCoordinateReferenceSystem &)
Emitted when the selected CRS is changed.
A rectangle specified with double values.
Definition: qgsrectangle.h:42
static QStringList availableEncodings()
Returns a list of available encodings.
QgsVectorFileWriter::OptionType type
A convenience class for writing vector layers to disk based formats (e.g.
@ CanAppendToExistingLayer
Flag to indicate that new features can be added to an existing layer.
@ CanAddNewLayer
Flag to indicate that a new layer can be added to the dataset.
@ CanDeleteLayer
Flag to indicate that an existing layer can be deleted.
static QgsVectorFileWriter::EditionCapabilities editionCapabilities(const QString &datasetName)
Returns edition capabilities for an existing dataset name.
static bool supportsFeatureStyles(const QString &driverName)
Returns true if the specified driverName supports feature styles.
static bool targetLayerExists(const QString &datasetName, const QString &layerName)
Returns whether the target layer already exists.
static bool driverMetadata(const QString &driverName, MetaData &driverMetadata)
static QString filterForDriver(const QString &driverName)
Creates a filter for an OGR driver key.
static bool areThereNewFieldsToCreate(const QString &datasetName, const QString &layerName, QgsVectorLayer *layer, const QgsAttributeList &attributes)
Returns whether there are among the attributes specified some that do not exist yet in the layer.
static QList< QgsVectorFileWriter::DriverDetails > ogrDriverList(VectorFormatOptions options=SortRecommended)
Returns the driver list that can be used for dialogs.
ActionOnExistingFile
Combination of CanAddNewLayer, CanAppendToExistingLayer, CanAddNewFieldsToExistingLayer or CanDeleteL...
@ CreateOrOverwriteLayer
Create or overwrite layer.
@ CreateOrOverwriteFile
Create or overwrite file.
@ AppendToLayerNoNewFields
Append features to existing layer, but do not create new fields.
@ AppendToLayerAddFields
Append features to existing layer, and create new fields if needed.
bool onlySelected() const
Returns whether only selected features will be saved.
bool forceMulti() const
Returns true if force multi geometry type is checked.
QString filename() const
Returns the target filename.
QgsAttributeList selectedAttributes() const
Returns a list of attributes which are selected for saving.
QgsRectangle filterExtent() const
Determines the extent to be exported.
Q_DECL_DEPRECATED long crs() const
Returns the internal CRS ID.
QString format() const
The format in which the export should be written.
QStringList datasourceOptions() const
Returns a list of additional data source options which are passed to OGR.
bool persistMetadata() const
Returns true if the persist metadata (copy source metadata to destination layer) option is checked.
QString encoding() const
The encoding of the target file.
void setIncludeZ(bool checked)
Sets whether the include z dimension checkbox should be checked.
void setOnlySelected(bool onlySelected)
Sets whether only selected features will be saved.
@ DestinationCrs
Show destination CRS (reprojection) option.
@ AddToCanvas
Show add to map option.
@ Symbology
Show symbology options.
@ SelectedOnly
Show selected features only option.
@ Fields
Show field customization group.
bool automaticGeometryType() const
Returns true if geometry type is set to automatic.
QString layername() const
Returns the target layer name.
QgsWkbTypes::Type geometryType() const
Returns the selected flat geometry type for the export.
Q_DECL_DEPRECATED QgsVectorLayerSaveAsDialog(long srsid, QWidget *parent=nullptr, Qt::WindowFlags fl=Qt::WindowFlags())
Construct a new QgsVectorLayerSaveAsDialog.
bool includeZ() const
Returns true if include z dimension is checked.
QgsCoordinateReferenceSystem crsObject() const
Returns the CRS chosen for export.
QStringList layerOptions() const
Returns a list of additional layer options which are passed to OGR.
void setForceMulti(bool checked)
Sets whether the force multi geometry checkbox should be checked.
bool addToCanvas() const
Returns true if the "add to canvas" checkbox is checked.
void setMapCanvas(QgsMapCanvas *canvas)
Sets a map canvas to associate with the dialog.
QgsVectorFileWriter::ActionOnExistingFile creationActionOnExistingFile() const
Returns creation action.
int symbologyExport() const
Returns type of symbology export.
QgsAttributeList attributesAsDisplayedValues() const
Returns selected attributes that must be exported with their displayed values instead of their raw va...
double scale() const
Returns the specified map scale.
bool hasFilterExtent() const
Determines if filtering the export by an extent is activated.
void setAddToCanvas(bool checked)
Sets whether the "add to canvas" checkbox should be checked.
Represents a vector layer which manages a vector based data sets.
QgsFields fields() const FINAL
Returns the list of fields of this layer.
int selectedFeatureCount() const
Returns the number of features that are selected in this layer.
QgsRectangle extent() const FINAL
Returns the extent of the layer.
static QString translatedDisplayString(Type type) SIP_HOLDGIL
Returns a translated display string type for a WKB type, e.g., the geometry name used in WKT geometry...
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:70
@ GeometryCollection
Definition: qgswkbtypes.h:79
QList< int > QgsAttributeList
Definition: qgsfield.h:26
const QgsCoordinateReferenceSystem & crs
Details of available driver formats.
QMap< QString, QgsVectorFileWriter::Option * > driverOptions
QMap< QString, QgsVectorFileWriter::Option * > layerOptions
QString compulsoryEncoding
Some formats require a compulsory encoding, typically UTF-8. If no compulsory encoding,...