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