QGIS API Documentation  3.27.0-Master (e113457133)
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 }
This class represents a coordinate reference system (CRS).
QgsDatumEnsemble datumEnsemble() const SIP_THROW(QgsNotSupportedException)
Attempts to retrieve datum ensemble details from the CRS.
long srsid() const
Returns the internal CRS ID, if available.
Contains information about a datum ensemble.
Definition: qgsdatums.h:95
bool isValid() const
Returns true if the datum ensemble is a valid object, or false if it is a null/invalid object.
Definition: qgsdatums.h:102
QString name() const
Display name of datum ensemble.
Definition: qgsdatums.h:107
Every attribute editor widget needs a factory, which inherits this class.
QString name() const
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:139
QString name
Definition: qgsfield.h:60
QString displayName() const
Returns the name to use when displaying this field.
Definition: qgsfield.cpp:89
int count() const
Returns number of items.
Definition: qgsfields.cpp:133
QgsField at(int i) const
Returns the field at particular index (must be in range 0..N-1).
Definition: qgsfields.cpp:163
@ SaveFile
Select a single new or pre-existing file.
Definition: qgsfilewidget.h:71
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:85
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
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
Definition: qgshelp.cpp:36
static QIcon iconForWkbType(QgsWkbTypes::Type type)
Returns the icon for a vector layer whose geometry type is provided.
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:90
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:79
QgsRectangle visibleExtent() const
Returns the actual extent derived from requested extent that takes output image size into account.
QgsCoordinateReferenceSystem destinationCrs() const
Returns the destination coordinate reference system for the map render.
Custom exception class which is raised when an operation is not supported.
Definition: qgsexception.h:118
void crsChanged(const QgsCoordinateReferenceSystem &)
Emitted when the selected CRS is changed.
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...
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance.
Contains details about a sub layer available from a dataset.
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 layers to disk based formats (e.g.
@ CanAppendToExistingLayer
Flag to indicate that new features can be added to an existing layer.
@ CanAddNewLayer
Flag to indicate that a new layer can be added to the dataset.
@ CanDeleteLayer
Flag to indicate that an existing layer can be deleted.
static QgsVectorFileWriter::EditionCapabilities editionCapabilities(const QString &datasetName)
Returns edition capabilities for an existing dataset name.
static bool supportsFeatureStyles(const QString &driverName)
Returns true if the specified driverName supports feature styles.
static bool targetLayerExists(const QString &datasetName, const QString &layerName)
Returns whether the target layer already exists.
static bool driverMetadata(const QString &driverName, MetaData &driverMetadata)
static QString filterForDriver(const QString &driverName)
Creates a filter for an OGR driver key.
static bool areThereNewFieldsToCreate(const QString &datasetName, const QString &layerName, QgsVectorLayer *layer, const QgsAttributeList &attributes)
Returns whether there are among the attributes specified some that do not exist yet in the layer.
static QList< QgsVectorFileWriter::DriverDetails > ogrDriverList(VectorFormatOptions options=SortRecommended)
Returns the driver list that can be used for dialogs.
ActionOnExistingFile
Combination of CanAddNewLayer, CanAppendToExistingLayer, CanAddNewFieldsToExistingLayer or CanDeleteL...
@ CreateOrOverwriteLayer
Create or overwrite layer.
@ CreateOrOverwriteFile
Create or overwrite file.
@ AppendToLayerNoNewFields
Append features to existing layer, but do not create new fields.
@ AppendToLayerAddFields
Append features to existing layer, and create new fields if needed.
bool onlySelected() const
Returns whether only selected features will be saved.
bool forceMulti() const
Returns true if force multi geometry type is checked.
QString filename() const
Returns the target filename.
QgsAttributeList selectedAttributes() const
Returns a list of attributes which are selected for saving.
QgsRectangle filterExtent() const
Determines the extent to be exported.
Q_DECL_DEPRECATED long crs() const
Returns the internal CRS ID.
QString format() const
The format in which the export should be written.
QStringList datasourceOptions() const
Returns a list of additional data source options which are passed to OGR.
bool persistMetadata() const
Returns true if the persist metadata (copy source metadata to destination layer) option is checked.
QString encoding() const
The encoding of the target file.
void setIncludeZ(bool checked)
Sets whether the include z dimension checkbox should be checked.
QStringList attributesExportNames() const
Returns a list of export names for attributes.
void setOnlySelected(bool onlySelected)
Sets whether only selected features will be saved.
@ DestinationCrs
Show destination CRS (reprojection) option.
@ AddToCanvas
Show add to map option.
@ Symbology
Show symbology options.
@ SelectedOnly
Show selected features only option.
@ Fields
Show field customization group.
bool automaticGeometryType() const
Returns true if geometry type is set to automatic.
QString layername() const
Returns the target layer name.
QgsWkbTypes::Type geometryType() const
Returns the selected flat geometry type for the export.
Q_DECL_DEPRECATED QgsVectorLayerSaveAsDialog(long srsid, QWidget *parent=nullptr, Qt::WindowFlags fl=Qt::WindowFlags())
Construct a new QgsVectorLayerSaveAsDialog.
bool includeZ() const
Returns true if include z dimension is checked.
QgsCoordinateReferenceSystem crsObject() const
Returns the CRS chosen for export.
QStringList layerOptions() const
Returns a list of additional layer options which are passed to OGR.
void setForceMulti(bool checked)
Sets whether the force multi geometry checkbox should be checked.
bool addToCanvas() const
Returns true if the "add to canvas" checkbox is checked.
void setMapCanvas(QgsMapCanvas *canvas)
Sets a map canvas to associate with the dialog.
QgsVectorFileWriter::ActionOnExistingFile creationActionOnExistingFile() const
Returns creation action.
int symbologyExport() const
Returns type of symbology export.
QgsAttributeList attributesAsDisplayedValues() const
Returns selected attributes that must be exported with their displayed values instead of their raw va...
double scale() const
Returns the specified map scale.
bool hasFilterExtent() const
Determines if filtering the export by an extent is activated.
void setAddToCanvas(bool checked)
Sets whether the "add to canvas" checkbox should be checked.
Represents a vector layer which manages a vector based data sets.
QgsFields fields() const FINAL
Returns the list of fields of this layer.
int selectedFeatureCount() const
Returns the number of features that are selected in this layer.
QgsRectangle extent() const FINAL
Returns the extent of the layer.
static QString translatedDisplayString(Type type) SIP_HOLDGIL
Returns a translated display string type for a WKB type, e.g., the geometry name used in WKT geometry...
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:70
@ GeometryCollection
Definition: qgswkbtypes.h:79
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition: qgis.h:2186
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,...