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