QGIS API Documentation  3.18.1-Zürich (202f1bf7e5)
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"
19 #include "qgsdataitem.h"
22 #include "qgsvectordataprovider.h"
23 #include "qgsogrdataitems.h"
25 #include "qgseditorwidgetfactory.h"
27 #include "qgssettings.h"
28 #include "qgsmapcanvas.h"
29 #include "qgsgui.h"
30 #include "qgsapplication.h"
31 #include <QMessageBox>
32 #include <QFileDialog>
33 #include <QTextCodec>
34 #include <QSpinBox>
35 #include <QRegularExpression>
36 #include "gdal.h"
37 
38 static const int COLUMN_IDX_NAME = 0;
39 static const int COLUMN_IDX_TYPE = 1;
40 static const int COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE = 2;
41 
42 QgsVectorLayerSaveAsDialog::QgsVectorLayerSaveAsDialog( long srsid, QWidget *parent, Qt::WindowFlags fl )
43  : QDialog( parent, fl )
44  , mSelectedCrs( QgsCoordinateReferenceSystem::fromSrsId( srsid ) )
45  , mAttributeTableItemChangedSlotEnabled( true )
46  , mReplaceRawFieldValuesStateChangedSlotEnabled( true )
47  , mActionOnExistingFile( QgsVectorFileWriter::CreateOrOverwriteFile )
48 {
49  setup();
50 }
51 
52 QgsVectorLayerSaveAsDialog::QgsVectorLayerSaveAsDialog( QgsVectorLayer *layer, int options, QWidget *parent, Qt::WindowFlags fl )
53  : QDialog( parent, fl )
54  , mLayer( layer )
55  , mAttributeTableItemChangedSlotEnabled( true )
56  , mReplaceRawFieldValuesStateChangedSlotEnabled( true )
57  , mActionOnExistingFile( QgsVectorFileWriter::CreateOrOverwriteFile )
58  , mOptions( static_cast< Options >( options ) )
59 {
60  if ( layer )
61  {
62  mSelectedCrs = layer->crs();
63  mLayerExtent = layer->extent();
64  }
65  setup();
66 
67  if ( !( mOptions & Symbology ) )
68  {
69  mSymbologyExportLabel->hide();
70  mSymbologyExportComboBox->hide();
71  mScaleLabel->hide();
72  mScaleWidget->hide();
73  }
74 
75  if ( !( mOptions & DestinationCrs ) )
76  {
77  mCrsLabel->hide();
78  mCrsSelector->hide();
79  }
80  if ( !( mOptions & Fields ) )
81  mAttributesSelection->hide();
82 
83  if ( !( mOptions & SelectedOnly ) )
84  mSelectedOnly->hide();
85 
86  if ( !( mOptions & AddToCanvas ) )
87  mAddToCanvas->hide();
88 
89  if ( !( mOptions & GeometryType ) )
90  mGeometryGroupBox->hide();
91 
92  if ( !( mOptions & Extent ) )
93  mExtentGroupBox->hide();
94 
95  mSelectedOnly->setEnabled( layer && layer->selectedFeatureCount() != 0 );
96  mButtonBox->button( QDialogButtonBox::Ok )->setDisabled( true );
97 }
98 
99 void QgsVectorLayerSaveAsDialog::setup()
100 {
101  setupUi( this );
103 
104  connect( mFormatComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsVectorLayerSaveAsDialog::mFormatComboBox_currentIndexChanged );
105  connect( mCrsSelector, &QgsProjectionSelectionWidget::crsChanged, this, &QgsVectorLayerSaveAsDialog::mCrsSelector_crsChanged );
106  connect( mSymbologyExportComboBox, &QComboBox::currentTextChanged, this, &QgsVectorLayerSaveAsDialog::mSymbologyExportComboBox_currentIndexChanged );
107  connect( mGeometryTypeComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsVectorLayerSaveAsDialog::mGeometryTypeComboBox_currentIndexChanged );
108  connect( mSelectAllAttributes, &QPushButton::clicked, this, &QgsVectorLayerSaveAsDialog::mSelectAllAttributes_clicked );
109  connect( mDeselectAllAttributes, &QPushButton::clicked, this, &QgsVectorLayerSaveAsDialog::mDeselectAllAttributes_clicked );
110  connect( mReplaceRawFieldValues, &QCheckBox::stateChanged, this, &QgsVectorLayerSaveAsDialog::mReplaceRawFieldValues_stateChanged );
111  connect( mAttributeTable, &QTableWidget::itemChanged, this, &QgsVectorLayerSaveAsDialog::mAttributeTable_itemChanged );
112 
113 #ifdef Q_OS_WIN
114  mHelpButtonBox->setVisible( false );
115  mButtonBox->addButton( QDialogButtonBox::Help );
116  connect( mButtonBox, &QDialogButtonBox::helpRequested, this, &QgsVectorLayerSaveAsDialog::showHelp );
117 #else
118  connect( mHelpButtonBox, &QDialogButtonBox::helpRequested, this, &QgsVectorLayerSaveAsDialog::showHelp );
119 #endif
120  connect( mButtonBox, &QDialogButtonBox::accepted, this, &QgsVectorLayerSaveAsDialog::accept );
121  connect( mButtonBox, &QDialogButtonBox::rejected, this, &QgsVectorLayerSaveAsDialog::reject );
122 
123  const QList< QgsVectorFileWriter::DriverDetails > drivers = QgsVectorFileWriter::ogrDriverList();
124  mFormatComboBox->blockSignals( true );
125  for ( const QgsVectorFileWriter::DriverDetails &driver : drivers )
126  {
127  mFormatComboBox->addItem( driver.longName, driver.driverName );
128  }
129 
130  QgsSettings settings;
131  QString format = settings.value( QStringLiteral( "UI/lastVectorFormat" ), "GPKG" ).toString();
132  mFormatComboBox->setCurrentIndex( mFormatComboBox->findData( format ) );
133  mFormatComboBox->blockSignals( false );
134 
135  const auto addGeomItem = [this]( QgsWkbTypes::Type type )
136  {
137  mGeometryTypeComboBox->addItem( QgsLayerItem::iconForWkbType( type ), QgsWkbTypes::translatedDisplayString( type ), type );
138  };
139 
140  //add geometry types to combobox
141  mGeometryTypeComboBox->addItem( tr( "Automatic" ), -1 );
142  addGeomItem( QgsWkbTypes::Point );
143  addGeomItem( QgsWkbTypes::LineString );
144  addGeomItem( QgsWkbTypes::Polygon );
146  addGeomItem( QgsWkbTypes::NoGeometry );
147  mGeometryTypeComboBox->setCurrentIndex( mGeometryTypeComboBox->findData( -1 ) );
148 
149  mEncodingComboBox->addItems( QgsVectorDataProvider::availableEncodings() );
150 
151  QString enc = settings.value( QStringLiteral( "UI/encoding" ), "System" ).toString();
152  int idx = mEncodingComboBox->findText( enc );
153  if ( idx < 0 )
154  {
155  mEncodingComboBox->insertItem( 0, enc );
156  idx = 0;
157  }
158 
159  mCrsSelector->setCrs( mSelectedCrs );
160  mCrsSelector->setLayerCrs( mSelectedCrs );
161  mCrsSelector->setMessage( tr( "Select the coordinate reference system for the vector file. "
162  "The data points will be transformed from the layer coordinate reference system." ) );
163 
164  mEncodingComboBox->setCurrentIndex( idx );
165  mFormatComboBox_currentIndexChanged( mFormatComboBox->currentIndex() );
166 
167  //symbology export combo box
168  mSymbologyExportComboBox->addItem( tr( "No Symbology" ), QgsVectorFileWriter::NoSymbology );
169  mSymbologyExportComboBox->addItem( tr( "Feature Symbology" ), QgsVectorFileWriter::FeatureSymbology );
170  mSymbologyExportComboBox->addItem( tr( "Symbol Layer Symbology" ), QgsVectorFileWriter::SymbolLayerSymbology );
171  mSymbologyExportComboBox_currentIndexChanged( mSymbologyExportComboBox->currentText() );
172 
173  // extent group box
174  mExtentGroupBox->setOutputCrs( mSelectedCrs );
175  mExtentGroupBox->setOriginalExtent( mLayerExtent, mSelectedCrs );
176  mExtentGroupBox->setOutputExtentFromOriginal();
177  mExtentGroupBox->setCheckable( true );
178  mExtentGroupBox->setChecked( false );
179  mExtentGroupBox->setCollapsed( true );
180 
181  mFilename->setStorageMode( QgsFileWidget::SaveFile );
182  mFilename->setDialogTitle( tr( "Save Layer As" ) );
183  mFilename->setDefaultRoot( settings.value( QStringLiteral( "UI/lastVectorFileFilterDir" ), QDir::homePath() ).toString() );
184  mFilename->setConfirmOverwrite( false );
185  connect( mFilename, &QgsFileWidget::fileChanged, this, [ = ]( const QString & filePath )
186  {
187  QgsSettings settings;
188  QFileInfo tmplFileInfo( filePath );
189  settings.setValue( QStringLiteral( "UI/lastVectorFileFilterDir" ), tmplFileInfo.absolutePath() );
190  if ( !filePath.isEmpty() && leLayername->isEnabled() )
191  {
192  QFileInfo fileInfo( filePath );
193  leLayername->setText( fileInfo.completeBaseName() );
194  }
195  mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( !filePath.isEmpty() );
196  } );
197 }
198 
199 QList<QPair<QLabel *, QWidget *> > QgsVectorLayerSaveAsDialog::createControls( const QMap<QString, QgsVectorFileWriter::Option *> &options )
200 {
201  QList<QPair<QLabel *, QWidget *> > controls;
202  QMap<QString, QgsVectorFileWriter::Option *>::ConstIterator it;
203 
204  for ( it = options.constBegin(); it != options.constEnd(); ++it )
205  {
206  QgsVectorFileWriter::Option *option = it.value();
207  QLabel *label = new QLabel( it.key() );
208  QWidget *control = nullptr;
209  switch ( option->type )
210  {
212  {
213  QgsVectorFileWriter::IntOption *opt = dynamic_cast<QgsVectorFileWriter::IntOption *>( option );
214  if ( opt )
215  {
216  QSpinBox *sb = new QSpinBox();
217  sb->setObjectName( it.key() );
218  sb->setValue( opt->defaultValue );
219  control = sb;
220  }
221  break;
222  }
223 
225  {
226  QgsVectorFileWriter::SetOption *opt = dynamic_cast<QgsVectorFileWriter::SetOption *>( option );
227  if ( opt )
228  {
229  QComboBox *cb = new QComboBox();
230  cb->setObjectName( it.key() );
231  for ( const QString &val : qgis::as_const( opt->values ) )
232  {
233  cb->addItem( val, val );
234  }
235  if ( opt->allowNone )
236  cb->addItem( tr( "<Default>" ), QVariant( QVariant::String ) );
237  int idx = cb->findText( opt->defaultValue );
238  if ( idx == -1 )
239  idx = cb->findData( QVariant( QVariant::String ) );
240  cb->setCurrentIndex( idx );
241  control = cb;
242  }
243  break;
244  }
245 
247  {
249  if ( opt )
250  {
251  QLineEdit *le = new QLineEdit( opt->defaultValue );
252  le->setObjectName( it.key() );
253  control = le;
254  }
255  break;
256  }
257 
259  control = nullptr;
260  break;
261  }
262 
263  if ( control )
264  {
265  // Pack the tooltip in some html element, so it gets linebreaks.
266  label->setToolTip( QStringLiteral( "<p>%1</p>" ).arg( option->docString ) );
267  control->setToolTip( QStringLiteral( "<p>%1</p>" ).arg( option->docString ) );
268 
269  controls << QPair<QLabel *, QWidget *>( label, control );
270  }
271  }
272 
273  return controls;
274 }
275 
276 void QgsVectorLayerSaveAsDialog::accept()
277 {
278  if ( QFile::exists( filename() ) )
279  {
280  QgsVectorFileWriter::EditionCapabilities caps =
282  bool layerExists = QgsVectorFileWriter::targetLayerExists( filename(),
283  layername() );
284  QMessageBox msgBox;
285  msgBox.setIcon( QMessageBox::Question );
286  msgBox.setWindowTitle( tr( "Save Vector Layer As" ) );
287  QPushButton *overwriteFileButton = msgBox.addButton( tr( "Overwrite File" ), QMessageBox::ActionRole );
288  QPushButton *overwriteLayerButton = msgBox.addButton( tr( "Overwrite Layer" ), QMessageBox::ActionRole );
289  QPushButton *appendToLayerButton = msgBox.addButton( tr( "Append to Layer" ), QMessageBox::ActionRole );
290  msgBox.setStandardButtons( QMessageBox::Cancel );
291  msgBox.setDefaultButton( QMessageBox::Cancel );
292  overwriteFileButton->hide();
293  overwriteLayerButton->hide();
294  appendToLayerButton->hide();
295  if ( layerExists )
296  {
300  {
301  msgBox.setText( tr( "The layer already exists. Do you want to overwrite the whole file or overwrite the layer?" ) );
302  overwriteFileButton->setVisible( true );
303  overwriteLayerButton->setVisible( true );
304  }
305  else if ( !( caps & QgsVectorFileWriter::CanAppendToExistingLayer ) )
306  {
307  msgBox.setText( tr( "The file already exists. Do you want to overwrite it?" ) );
308  overwriteFileButton->setVisible( true );
309  }
310  else if ( ( caps & QgsVectorFileWriter::CanDeleteLayer ) &&
312  {
313  msgBox.setText( tr( "The layer already exists. Do you want to overwrite the whole file, overwrite the layer or append features to the layer?" ) );
314  appendToLayerButton->setVisible( true );
315  overwriteFileButton->setVisible( true );
316  overwriteLayerButton->setVisible( true );
317  }
318  else
319  {
320  msgBox.setText( tr( "The layer already exists. Do you want to overwrite the whole file or append features to the layer?" ) );
321  appendToLayerButton->setVisible( true );
322  overwriteFileButton->setVisible( true );
323  }
324 
325  int ret = msgBox.exec();
326  if ( ret == QMessageBox::Cancel )
327  return;
328  if ( msgBox.clickedButton() == overwriteFileButton )
329  mActionOnExistingFile = QgsVectorFileWriter::CreateOrOverwriteFile;
330  else if ( msgBox.clickedButton() == overwriteLayerButton )
331  mActionOnExistingFile = QgsVectorFileWriter::CreateOrOverwriteLayer;
332  else if ( msgBox.clickedButton() == appendToLayerButton )
333  mActionOnExistingFile = QgsVectorFileWriter::AppendToLayerNoNewFields;
334  }
335  else // !layerExists
336  {
337  if ( ( caps & QgsVectorFileWriter::CanAddNewLayer ) )
338  {
339  mActionOnExistingFile = QgsVectorFileWriter::CreateOrOverwriteLayer;
340  }
341  else
342  {
343  // should not reach here, layer does not exist and cannot add new layer
344  if ( QMessageBox::question( this,
345  tr( "Save Vector Layer As" ),
346  tr( "The file already exists. Do you want to overwrite it?" ) ) == QMessageBox::NoButton )
347  {
348  return;
349  }
350  mActionOnExistingFile = QgsVectorFileWriter::CreateOrOverwriteFile;
351  }
352  }
353  }
354 
355  if ( mActionOnExistingFile == QgsVectorFileWriter::AppendToLayerNoNewFields )
356  {
358  {
359  if ( QMessageBox::question( this,
360  tr( "Save Vector Layer As" ),
361  tr( "The existing layer has additional fields. Do you want to add the missing fields to the layer?" ) ) == QMessageBox::Yes )
362  {
363  mActionOnExistingFile = QgsVectorFileWriter::AppendToLayerAddFields;
364  }
365  }
366  }
367  else if ( mActionOnExistingFile == QgsVectorFileWriter::CreateOrOverwriteFile && QFile::exists( filename() ) )
368  {
369  try
370  {
371  const QList<QgsOgrDbLayerInfo *> subLayers = QgsOgrLayerItem::subLayers( filename(), format() );
372  QStringList layerList;
373  for ( const QgsOgrDbLayerInfo *layer : subLayers )
374  {
375  layerList.append( layer->name() );
376  }
377  qDeleteAll( subLayers );
378  if ( layerList.length() > 1 )
379  {
380  layerList.sort( Qt::CaseInsensitive );
381  QMessageBox msgBox;
382  msgBox.setIcon( QMessageBox::Warning );
383  msgBox.setWindowTitle( tr( "Overwrite File" ) );
384  msgBox.setText( tr( "This file contains %1 layers that will be lost!\n" ).arg( QString::number( layerList.length() ) ) );
385  msgBox.setDetailedText( tr( "The following layers will be permanently lost:\n\n%1" ).arg( layerList.join( "\n" ) ) );
386  msgBox.setStandardButtons( QMessageBox::Ok | QMessageBox::Cancel );
387  if ( msgBox.exec() == QMessageBox::Cancel )
388  return;
389  }
390  }
391  catch ( QgsOgrLayerNotValidException &ex )
392  {
393  QMessageBox::critical( this,
394  tr( "Save Vector Layer As" ),
395  tr( "Error opening destination file: %1" ).arg( ex.what() ) );
396  return;
397  }
398  }
399 
400  QgsSettings settings;
401  settings.setValue( QStringLiteral( "UI/lastVectorFileFilterDir" ), QFileInfo( filename() ).absolutePath() );
402  settings.setValue( QStringLiteral( "UI/lastVectorFormat" ), format() );
403  settings.setValue( QStringLiteral( "UI/encoding" ), encoding() );
404  QDialog::accept();
405 }
406 
407 void QgsVectorLayerSaveAsDialog::mFormatComboBox_currentIndexChanged( int idx )
408 {
409  Q_UNUSED( idx )
410 
411  mFilename->setEnabled( true );
412  mFilename->setFilter( QgsVectorFileWriter::filterForDriver( format() ) );
413 
414  // if output filename already defined we need to replace old suffix
415  // to avoid double extensions like .gpkg.shp
416  if ( !mFilename->filePath().isEmpty() )
417  {
418  QRegularExpression rx( "\\.(.*?)[\\s]" );
419  QString ext;
420  ext = rx.match( QgsVectorFileWriter::filterForDriver( format() ) ).captured( 1 );
421  if ( !ext.isEmpty() )
422  {
423  QFileInfo fi( mFilename->filePath() );
424  mFilename->setFilePath( QStringLiteral( "%1/%2.%3" ).arg( fi.path() ).arg( fi.baseName() ).arg( ext ) );
425  }
426  }
427 
428  bool selectAllFields = true;
429 
430  // Is it a format for which fields that have attached widgets of types
431  // ValueMap, ValueRelation, etc. should be by default exported with their displayed
432  // values
433  bool isFormatForFieldsAsDisplayedValues = false;
434 
435  const QString sFormat( format() );
436  if ( sFormat == QLatin1String( "DXF" ) || sFormat == QLatin1String( "DGN" ) )
437  {
438  mAttributesSelection->setVisible( false );
439  selectAllFields = false;
440  }
441  else
442  {
443  if ( mOptions & Fields )
444  {
445  mAttributesSelection->setVisible( true );
446  isFormatForFieldsAsDisplayedValues = ( sFormat == QLatin1String( "CSV" ) ||
447  sFormat == QLatin1String( "XLS" ) ||
448  sFormat == QLatin1String( "XLSX" ) ||
449  sFormat == QLatin1String( "ODS" ) );
450  }
451  }
452 
453  // Show symbology options only for some formats
454  if ( QgsVectorFileWriter::supportsFeatureStyles( sFormat ) && ( mOptions & Symbology ) )
455  {
456  mSymbologyExportLabel->setVisible( true );
457  mSymbologyExportComboBox->setVisible( true );
458  mScaleLabel->setVisible( true );
459  mScaleWidget->setVisible( true );
460  }
461  else
462  {
463  mSymbologyExportLabel->hide();
464  mSymbologyExportComboBox->hide();
465  mScaleLabel->hide();
466  mScaleWidget->hide();
467  }
468 
469  leLayername->setEnabled( sFormat == QLatin1String( "KML" ) ||
470  sFormat == QLatin1String( "GPKG" ) ||
471  sFormat == QLatin1String( "XLSX" ) ||
472  sFormat == QLatin1String( "ODS" ) ||
473  sFormat == QLatin1String( "FileGDB" ) ||
474  sFormat == QLatin1String( "SQLite" ) ||
475  sFormat == QLatin1String( "SpatiaLite" ) );
476  if ( !leLayername->isEnabled() )
477  leLayername->setText( QString() );
478  else if ( leLayername->text().isEmpty() &&
479  !mFilename->filePath().isEmpty() )
480  {
481  QString layerName = QFileInfo( mFilename->filePath() ).baseName();
482  leLayername->setText( layerName );
483  }
484 
485  if ( mLayer )
486  {
487  mAttributeTable->setRowCount( mLayer->fields().count() );
488 
489  bool foundFieldThatCanBeExportedAsDisplayedValue = false;
490  for ( int i = 0; i < mLayer->fields().size(); ++i )
491  {
492  const QgsEditorWidgetSetup setup = QgsGui::editorWidgetRegistry()->findBest( mLayer, mLayer->fields()[i].name() );
493  if ( setup.type() != QLatin1String( "TextEdit" ) &&
494  QgsGui::editorWidgetRegistry()->factory( setup.type() ) )
495  {
496  foundFieldThatCanBeExportedAsDisplayedValue = true;
497  break;
498  }
499  }
500  if ( foundFieldThatCanBeExportedAsDisplayedValue )
501  {
502  mAttributeTable->setColumnCount( 3 );
503  mAttributeTable->setHorizontalHeaderLabels( QStringList() << tr( "Name" ) << tr( "Type" ) << tr( "Replace with displayed values" ) );
504  }
505  else
506  {
507  mAttributeTable->setColumnCount( 2 );
508  mAttributeTable->setHorizontalHeaderLabels( QStringList() << tr( "Name" ) << tr( "Type" ) );
509  }
510 
511  mAttributeTableItemChangedSlotEnabled = false;
512 
513  bool checkReplaceRawFieldValues = selectAllFields && isFormatForFieldsAsDisplayedValues;
514  for ( int i = 0; i < mLayer->fields().size(); ++i )
515  {
516  QgsField fld = mLayer->fields().at( i );
517  Qt::ItemFlags flags = mLayer->providerType() != QLatin1String( "oracle" ) || !fld.typeName().contains( QLatin1String( "SDO_GEOMETRY" ) ) ? Qt::ItemIsEnabled : Qt::NoItemFlags;
518  QTableWidgetItem *item = nullptr;
519  item = new QTableWidgetItem( fld.name() );
520  item->setFlags( flags | Qt::ItemIsUserCheckable );
521  item->setCheckState( ( selectAllFields ) ? Qt::Checked : Qt::Unchecked );
522  mAttributeTable->setItem( i, COLUMN_IDX_NAME, item );
523 
524  item = new QTableWidgetItem( fld.typeName() );
525  item->setFlags( flags );
526  mAttributeTable->setItem( i, COLUMN_IDX_TYPE, item );
527 
528  if ( foundFieldThatCanBeExportedAsDisplayedValue )
529  {
530  const QgsEditorWidgetSetup setup = QgsGui::editorWidgetRegistry()->findBest( mLayer, mLayer->fields()[i].name() );
531  QgsEditorWidgetFactory *factory = nullptr;
532  const QString widgetId( setup.type() );
533  if ( flags == Qt::ItemIsEnabled &&
534  widgetId != QLatin1String( "TextEdit" ) &&
535  ( factory = QgsGui::editorWidgetRegistry()->factory( widgetId ) ) )
536  {
537  item = new QTableWidgetItem( tr( "Use %1" ).arg( factory->name() ) );
538  item->setFlags( ( selectAllFields ) ? ( Qt::ItemIsEnabled | Qt::ItemIsUserCheckable ) : Qt::ItemIsUserCheckable );
539  const bool checkItem = ( selectAllFields && isFormatForFieldsAsDisplayedValues &&
540  ( widgetId == QLatin1String( "ValueMap" ) ||
541  widgetId == QLatin1String( "ValueRelation" ) ||
542  widgetId == QLatin1String( "CheckBox" ) ||
543  widgetId == QLatin1String( "RelationReference" ) ) );
544  checkReplaceRawFieldValues &= checkItem;
545  item->setCheckState( checkItem ?
546  Qt::Checked : Qt::Unchecked );
547  mAttributeTable->setItem( i, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE, item );
548  }
549  else
550  {
551  item = new QTableWidgetItem();
552  item->setFlags( Qt::NoItemFlags );
553  mAttributeTable->setItem( i, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE, item );
554  }
555  }
556  }
557 
558  mAttributeTableItemChangedSlotEnabled = true;
559 
560  mReplaceRawFieldValuesStateChangedSlotEnabled = false;
561  mReplaceRawFieldValues->setChecked( checkReplaceRawFieldValues );
562  mReplaceRawFieldValuesStateChangedSlotEnabled = true;
563  mReplaceRawFieldValues->setEnabled( selectAllFields );
564  mReplaceRawFieldValues->setVisible( foundFieldThatCanBeExportedAsDisplayedValue );
565 
566  mAttributeTable->resizeColumnsToContents();
567  }
568 
569  QgsVectorFileWriter::MetaData driverMetaData;
570 
571  while ( mDatasourceOptionsGroupBox->layout()->count() )
572  {
573  QLayoutItem *item = mDatasourceOptionsGroupBox->layout()->takeAt( 0 );
574  delete item->widget();
575  delete item;
576  }
577 
578  while ( mLayerOptionsGroupBox->layout()->count() )
579  {
580  QLayoutItem *item = mLayerOptionsGroupBox->layout()->takeAt( 0 );
581  delete item->widget();
582  delete item;
583  }
584 
585  // workaround so the Q_FOREACH macro does not get confused by the ','
586  typedef QPair<QLabel *, QWidget *> LabelControlPair;
587 
588  if ( QgsVectorFileWriter::driverMetadata( format(), driverMetaData ) )
589  {
590  if ( !driverMetaData.driverOptions.empty() )
591  {
592  mDatasourceOptionsGroupBox->setVisible( true );
593  QList<QPair<QLabel *, QWidget *> > controls = createControls( driverMetaData.driverOptions );
594 
595  QFormLayout *datasourceLayout = dynamic_cast<QFormLayout *>( mDatasourceOptionsGroupBox->layout() );
596 
597  const auto constControls = controls;
598  for ( LabelControlPair control : constControls )
599  {
600  datasourceLayout->addRow( control.first, control.second );
601  }
602  }
603  else
604  {
605  mDatasourceOptionsGroupBox->setVisible( false );
606  }
607 
608  if ( !driverMetaData.layerOptions.empty() )
609  {
610  mLayerOptionsGroupBox->setVisible( true );
611  QList<QPair<QLabel *, QWidget *> > controls = createControls( driverMetaData.layerOptions );
612 
613  QFormLayout *layerOptionsLayout = dynamic_cast<QFormLayout *>( mLayerOptionsGroupBox->layout() );
614 
615  const auto constControls = controls;
616  for ( LabelControlPair control : constControls )
617  {
618  layerOptionsLayout->addRow( control.first, control.second );
619  }
620  }
621  else
622  {
623  mLayerOptionsGroupBox->setVisible( false );
624  }
625 
626  if ( driverMetaData.compulsoryEncoding.isEmpty() )
627  {
628  mEncodingComboBox->setEnabled( true );
629  }
630  else
631  {
632  int idx = mEncodingComboBox->findText( driverMetaData.compulsoryEncoding );
633  if ( idx >= 0 )
634  {
635  mEncodingComboBox->setCurrentIndex( idx );
636  mEncodingComboBox->setDisabled( true );
637  }
638  else
639  {
640  mEncodingComboBox->setEnabled( true );
641  }
642  }
643 
644  }
645  else
646  {
647  mEncodingComboBox->setEnabled( true );
648  }
649 
650  GDALDriverH hDriver = GDALGetDriverByName( format().toUtf8().constData() );
651  if ( hDriver )
652  {
653  mAddToCanvas->setEnabled( GDALGetMetadataItem( hDriver, GDAL_DCAP_OPEN, nullptr ) != nullptr );
654  }
655 }
656 
657 void QgsVectorLayerSaveAsDialog::mReplaceRawFieldValues_stateChanged( int )
658 {
659  if ( !mReplaceRawFieldValuesStateChangedSlotEnabled )
660  return;
661  if ( mAttributeTable->columnCount() != 3 )
662  return;
663  mReplaceRawFieldValuesStateChangedSlotEnabled = false;
664  mAttributeTableItemChangedSlotEnabled = false;
665  if ( mReplaceRawFieldValues->checkState() != Qt::PartiallyChecked )
666  {
667  for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
668  {
669  if ( mAttributeTable->item( i, COLUMN_IDX_NAME )->checkState() == Qt::Checked &&
670  mAttributeTable->item( i, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE ) &&
671  mAttributeTable->item( i, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE )->flags() & Qt::ItemIsEnabled )
672  {
673  mAttributeTable->item( i, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE )->setCheckState( mReplaceRawFieldValues->checkState() );
674  }
675  }
676  }
677  mReplaceRawFieldValues->setTristate( false );
678  mAttributeTableItemChangedSlotEnabled = true;
679  mReplaceRawFieldValuesStateChangedSlotEnabled = true;
680 }
681 
682 void QgsVectorLayerSaveAsDialog::mAttributeTable_itemChanged( QTableWidgetItem *item )
683 {
684  if ( !mAttributeTableItemChangedSlotEnabled )
685  return;
686  mReplaceRawFieldValuesStateChangedSlotEnabled = false;
687  mAttributeTableItemChangedSlotEnabled = false;
688  int row = item->row();
689  int column = item->column();
690  if ( column == COLUMN_IDX_NAME &&
691  mAttributeTable->item( row, column )->checkState() == Qt::Unchecked &&
692  mAttributeTable->columnCount() == 3 &&
693  mAttributeTable->item( row, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE ) &&
694  ( mAttributeTable->item( row, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE )->flags() & Qt::ItemIsUserCheckable ) )
695  {
696  mAttributeTable->item( row, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE )->setCheckState( Qt::Unchecked );
697  mAttributeTable->item( row, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE )->setFlags( Qt::ItemIsUserCheckable );
698  bool checkBoxEnabled = false;
699  for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
700  {
701  if ( mAttributeTable->item( i, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE ) &&
702  mAttributeTable->item( i, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE )->flags() & Qt::ItemIsEnabled )
703  {
704  checkBoxEnabled = true;
705  break;
706  }
707  }
708  mReplaceRawFieldValues->setEnabled( checkBoxEnabled );
709  if ( !checkBoxEnabled )
710  mReplaceRawFieldValues->setCheckState( Qt::Unchecked );
711  }
712  else if ( column == COLUMN_IDX_NAME &&
713  mAttributeTable->item( row, column )->checkState() == Qt::Checked &&
714  mAttributeTable->columnCount() == 3 &&
715  mAttributeTable->item( row, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE ) &&
716  ( mAttributeTable->item( row, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE )->flags() & Qt::ItemIsUserCheckable ) )
717  {
718  mAttributeTable->item( row, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE )->setFlags( Qt::ItemIsUserCheckable | Qt::ItemIsEnabled );
719  mReplaceRawFieldValues->setEnabled( true );
720  }
721  else if ( column == COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE &&
722  ( mAttributeTable->item( row, column )->flags() & Qt::ItemIsUserCheckable ) )
723  {
724  bool allChecked = true;
725  bool allUnchecked = true;
726  for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
727  {
728  if ( mAttributeTable->item( i, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE ) &&
729  mAttributeTable->item( i, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE )->flags() & Qt::ItemIsEnabled )
730  {
731  if ( mAttributeTable->item( i, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE )->checkState() == Qt::Unchecked )
732  allChecked = false;
733  else
734  allUnchecked = false;
735  }
736  }
737  mReplaceRawFieldValues->setCheckState( ( !allChecked && !allUnchecked ) ? Qt::PartiallyChecked : ( allChecked ) ? Qt::Checked : Qt::Unchecked );
738  }
739  mAttributeTableItemChangedSlotEnabled = true;
740  mReplaceRawFieldValuesStateChangedSlotEnabled = true;
741 }
742 
743 void QgsVectorLayerSaveAsDialog::mCrsSelector_crsChanged( const QgsCoordinateReferenceSystem &crs )
744 {
745  mSelectedCrs = crs;
746  mExtentGroupBox->setOutputCrs( mSelectedCrs );
747 }
748 
750 {
751  return mFilename->filePath();
752 }
753 
755 {
756  return leLayername->text();
757 }
758 
760 {
761  return mEncodingComboBox->currentText();
762 }
763 
765 {
766  return mFormatComboBox->currentData().toString();
767 }
768 
770 {
771  return mSelectedCrs.srsid();
772 }
773 
775 {
776  return mSelectedCrs;
777 }
778 
780 {
781  QStringList options;
782 
783  QgsVectorFileWriter::MetaData driverMetaData;
784 
785  if ( QgsVectorFileWriter::driverMetadata( format(), driverMetaData ) )
786  {
787  QMap<QString, QgsVectorFileWriter::Option *>::ConstIterator it;
788 
789  for ( it = driverMetaData.driverOptions.constBegin(); it != driverMetaData.driverOptions.constEnd(); ++it )
790  {
791  switch ( it.value()->type )
792  {
794  {
796  QSpinBox *sb = mDatasourceOptionsGroupBox->findChild<QSpinBox *>( it.key() );
797  if ( opt && sb && sb->value() != opt->defaultValue )
798  options << QStringLiteral( "%1=%2" ).arg( it.key() ).arg( sb->value() );
799  break;
800  }
801 
803  {
805  QComboBox *cb = mDatasourceOptionsGroupBox->findChild<QComboBox *>( it.key() );
806  if ( opt && cb && cb->itemData( cb->currentIndex() ) != opt->defaultValue )
807  options << QStringLiteral( "%1=%2" ).arg( it.key(), cb->currentText() );
808  break;
809  }
810 
812  {
814  QLineEdit *le = mDatasourceOptionsGroupBox->findChild<QLineEdit *>( it.key() );
815  if ( opt && le && le->text() != opt->defaultValue )
816  options << QStringLiteral( "%1=%2" ).arg( it.key(), le->text() );
817  break;
818  }
819 
821  {
823  dynamic_cast<QgsVectorFileWriter::HiddenOption *>( it.value() );
824  options << QStringLiteral( "%1=%2" ).arg( it.key(), opt->mValue );
825  break;
826  }
827  }
828  }
829  }
830 
831  QString plainText = mOgrDatasourceOptions->toPlainText().trimmed();
832  if ( !plainText.isEmpty() )
833  options += plainText.split( '\n' );
834 
835  return options;
836 }
837 
839 {
840  QStringList options;
841 
842  QgsVectorFileWriter::MetaData driverMetaData;
843 
844  if ( QgsVectorFileWriter::driverMetadata( format(), driverMetaData ) )
845  {
846  QMap<QString, QgsVectorFileWriter::Option *>::ConstIterator it;
847 
848  for ( it = driverMetaData.layerOptions.constBegin(); it != driverMetaData.layerOptions.constEnd(); ++it )
849  {
850  switch ( it.value()->type )
851  {
853  {
855  QSpinBox *sb = mLayerOptionsGroupBox->findChild<QSpinBox *>( it.key() );
856  if ( opt && sb && sb->value() != opt->defaultValue )
857  options << QStringLiteral( "%1=%2" ).arg( it.key() ).arg( sb->value() );
858  break;
859  }
860 
862  {
864  QComboBox *cb = mLayerOptionsGroupBox->findChild<QComboBox *>( it.key() );
865  if ( opt && cb && cb->itemData( cb->currentIndex() ) != opt->defaultValue )
866  options << QStringLiteral( "%1=%2" ).arg( it.key(), cb->currentText() );
867  break;
868  }
869 
871  {
873  QLineEdit *le = mLayerOptionsGroupBox->findChild<QLineEdit *>( it.key() );
874  if ( opt && le && le->text() != opt->defaultValue )
875  options << QStringLiteral( "%1=%2" ).arg( it.key(), le->text() );
876  break;
877  }
878 
880  {
882  dynamic_cast<QgsVectorFileWriter::HiddenOption *>( it.value() );
883  options << QStringLiteral( "%1=%2" ).arg( it.key(), opt->mValue );
884  break;
885  }
886  }
887  }
888  }
889 
890  QString plainText = mOgrLayerOptions->toPlainText().trimmed();
891  if ( !plainText.isEmpty() )
892  options += plainText.split( '\n' );
893 
894  return options;
895 }
896 
898 {
899  QgsAttributeList attributes;
900 
901  for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
902  {
903  if ( mAttributeTable->item( i, COLUMN_IDX_NAME )->checkState() == Qt::Checked )
904  {
905  attributes.append( i );
906  }
907  }
908 
909  return attributes;
910 }
911 
913 {
914  QgsAttributeList attributes;
915 
916  for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
917  {
918  if ( mAttributeTable->item( i, COLUMN_IDX_NAME )->checkState() == Qt::Checked &&
919  mAttributeTable->columnCount() == 3 &&
920  mAttributeTable->item( i, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE )->checkState() == Qt::Checked )
921  {
922  attributes.append( i );
923  }
924  }
925 
926  return attributes;
927 }
928 
930 {
931  return mAddToCanvas->isChecked() && mAddToCanvas->isEnabled();
932 }
933 
935 {
936  mAddToCanvas->setChecked( enabled );
937 }
938 
940 {
941  return mSymbologyExportComboBox->currentData().toInt();
942 }
943 
945 {
946  return mScaleWidget->scale();
947 }
948 
950 {
951  mMapCanvas = canvas;
952  mScaleWidget->setMapCanvas( canvas );
953  mScaleWidget->setShowCurrentScaleButton( true );
954  mExtentGroupBox->setCurrentExtent( canvas->mapSettings().visibleExtent(), canvas->mapSettings().destinationCrs() );
955 }
956 
958 {
959  return mExtentGroupBox->isChecked();
960 }
961 
963 {
964  return mExtentGroupBox->outputExtent();
965 }
966 
968 {
969  mSelectedOnly->setChecked( onlySelected );
970 }
971 
973 {
974  return mSelectedOnly->isChecked();
975 }
976 
978 {
979  int currentIndexData = mGeometryTypeComboBox->currentData().toInt();
980  if ( currentIndexData == -1 )
981  {
982  //automatic
983  return QgsWkbTypes::Unknown;
984  }
985 
986  return static_cast< QgsWkbTypes::Type >( currentIndexData );
987 }
988 
990 {
991  int currentIndexData = mGeometryTypeComboBox->currentData().toInt();
992  return currentIndexData == -1;
993 }
994 
996 {
997  return mForceMultiCheckBox->isChecked();
998 }
999 
1001 {
1002  mForceMultiCheckBox->setChecked( checked );
1003 }
1004 
1006 {
1007  return mIncludeZCheckBox->isChecked();
1008 }
1009 
1011 {
1012  return mActionOnExistingFile;
1013 }
1014 
1016 {
1017  mIncludeZCheckBox->setChecked( checked );
1018 }
1019 
1020 void QgsVectorLayerSaveAsDialog::mSymbologyExportComboBox_currentIndexChanged( const QString &text )
1021 {
1022  bool scaleEnabled = true;
1023  if ( text == tr( "No symbology" ) )
1024  {
1025  scaleEnabled = false;
1026  }
1027  mScaleWidget->setEnabled( scaleEnabled );
1028  mScaleLabel->setEnabled( scaleEnabled );
1029 }
1030 
1031 void QgsVectorLayerSaveAsDialog::mGeometryTypeComboBox_currentIndexChanged( int index )
1032 {
1033  int currentIndexData = mGeometryTypeComboBox->itemData( index ).toInt();
1034 
1035  if ( currentIndexData != -1 && currentIndexData != QgsWkbTypes::NoGeometry )
1036  {
1037  mForceMultiCheckBox->setEnabled( true );
1038  mIncludeZCheckBox->setEnabled( true );
1039  }
1040  else
1041  {
1042  mForceMultiCheckBox->setEnabled( false );
1043  mForceMultiCheckBox->setChecked( false );
1044  mIncludeZCheckBox->setEnabled( false );
1045  mIncludeZCheckBox->setChecked( false );
1046  }
1047 }
1048 
1049 void QgsVectorLayerSaveAsDialog::mSelectAllAttributes_clicked()
1050 {
1051  mAttributeTableItemChangedSlotEnabled = false;
1052  mReplaceRawFieldValuesStateChangedSlotEnabled = false;
1053  for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
1054  {
1055  if ( mAttributeTable->item( i, COLUMN_IDX_NAME )->flags() & Qt::ItemIsEnabled )
1056  {
1057  if ( mAttributeTable->columnCount() == 3 &&
1058  ( mAttributeTable->item( i, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE )->flags() & Qt::ItemIsUserCheckable ) )
1059  {
1060  mAttributeTable->item( i, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE )->setFlags( Qt::ItemIsUserCheckable | Qt::ItemIsEnabled );
1061  }
1062  mAttributeTable->item( i, COLUMN_IDX_NAME )->setCheckState( Qt::Checked );
1063  }
1064  }
1065  if ( mAttributeTable->columnCount() == 3 )
1066  {
1067  mReplaceRawFieldValues->setEnabled( true );
1068  }
1069  mAttributeTableItemChangedSlotEnabled = true;
1070  mReplaceRawFieldValuesStateChangedSlotEnabled = true;
1071 }
1072 
1073 void QgsVectorLayerSaveAsDialog::mDeselectAllAttributes_clicked()
1074 {
1075  mAttributeTableItemChangedSlotEnabled = false;
1076  mReplaceRawFieldValuesStateChangedSlotEnabled = false;
1077  for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
1078  {
1079  mAttributeTable->item( i, COLUMN_IDX_NAME )->setCheckState( Qt::Unchecked );
1080  if ( mAttributeTable->columnCount() == 3 &&
1081  ( mAttributeTable->item( i, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE )->flags() & Qt::ItemIsUserCheckable ) )
1082  {
1083  mAttributeTable->item( i, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE )->setFlags( Qt::ItemIsUserCheckable );
1084  mAttributeTable->item( i, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE )->setCheckState( Qt::Unchecked );
1085  }
1086  }
1087  if ( mAttributeTable->columnCount() == 3 )
1088  {
1089  mReplaceRawFieldValues->setCheckState( Qt::Unchecked );
1090  mReplaceRawFieldValues->setEnabled( false );
1091  }
1092  mAttributeTableItemChangedSlotEnabled = true;
1093  mReplaceRawFieldValuesStateChangedSlotEnabled = true;
1094 }
1095 
1096 void QgsVectorLayerSaveAsDialog::showHelp()
1097 {
1098  QgsHelp::openHelp( QStringLiteral( "managing_data_source/create_layers.html#save-layer-from-an-existing-file" ) );
1099 }
This class represents a coordinate reference system (CRS).
long srsid() const
Returns the internal CRS ID, if available.
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
Gets 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.
Definition: qgsdataitem.cpp:57
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:91
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.
void crsChanged(const QgsCoordinateReferenceSystem &)
Emitted when the selected CRS is changed.
A rectangle specified with double values.
Definition: qgsrectangle.h:42
This class is a composition of two QSettings instances:
Definition: qgssettings.h:62
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
static QStringList availableEncodings()
Returns a list of available encodings.
QgsVectorFileWriter::OptionType type
A convenience class for writing vector files to disk.
@ 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.
Options
Bitmask of options to be shown.
@ 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.
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.
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.
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,...